*** empty log message ***
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
6e3d6dc1 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
8b971f9f 3 2008, 2009, 2010, 2011, 2012
a0f19280 4 Free Software Foundation, Inc.
252b5132
RH
5
6 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 7 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
8
9 This file is part of GNU Binutils.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
32866df7 13 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
b43b5d5f
NC
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
24 02110-1301, USA. */
252b5132 25\f
9eb20dd8 26/* The difference between readelf and objdump:
252b5132 27
74013231 28 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 29 so why does the binutils project have two file dumpers ?
0de14b54 30
9eb20dd8
NC
31 The reason is that objdump sees an ELF file through a BFD filter of the
32 world; if BFD has a bug where, say, it disagrees about a machine constant
33 in e_flags, then the odds are good that it will remain internally
34 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
35 GAS sees it the BFD way. There was need for a tool to go find out what
36 the file actually says.
37
38 This is why the readelf program does not link against the BFD library - it
39 exists as an independent program to help verify the correct working of BFD.
40
41 There is also the case that readelf can provide more information about an
42 ELF file than is provided by objdump. In particular it can display DWARF
43 debugging information which (at the moment) objdump cannot. */
44\f
3db64b00 45#include "sysdep.h"
252b5132 46#include <assert.h>
252b5132 47#include <time.h>
1b315056
CS
48#ifdef HAVE_ZLIB_H
49#include <zlib.h>
50#endif
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:
708e2187 637 case EM_V800:
e9f53129
AM
638 case EM_V850:
639 case EM_CYGNUS_V850:
640 case EM_VAX:
641 case EM_X86_64:
8a9036a4 642 case EM_L1OM:
7a9068fe 643 case EM_K1OM:
e9f53129
AM
644 case EM_XSTORMY16:
645 case EM_XTENSA:
646 case EM_XTENSA_OLD:
7ba29e2a
NC
647 case EM_MICROBLAZE:
648 case EM_MICROBLAZE_OLD:
9c19a809 649 return TRUE;
103f02d3 650
e9f53129
AM
651 case EM_68HC05:
652 case EM_68HC08:
653 case EM_68HC11:
654 case EM_68HC16:
655 case EM_FX66:
656 case EM_ME16:
d1133906 657 case EM_MMA:
d1133906
NC
658 case EM_NCPU:
659 case EM_NDR1:
e9f53129 660 case EM_PCP:
d1133906 661 case EM_ST100:
e9f53129 662 case EM_ST19:
d1133906 663 case EM_ST7:
e9f53129
AM
664 case EM_ST9PLUS:
665 case EM_STARCORE:
d1133906 666 case EM_SVX:
e9f53129 667 case EM_TINYJ:
9c19a809
NC
668 default:
669 warn (_("Don't know about relocations on this machine architecture\n"));
670 return FALSE;
671 }
672}
252b5132 673
9c19a809 674static int
2cf0635d 675slurp_rela_relocs (FILE * file,
d3ba0551
AM
676 unsigned long rel_offset,
677 unsigned long rel_size,
2cf0635d
NC
678 Elf_Internal_Rela ** relasp,
679 unsigned long * nrelasp)
9c19a809 680{
2cf0635d 681 Elf_Internal_Rela * relas;
4d6ed7c8
NC
682 unsigned long nrelas;
683 unsigned int i;
252b5132 684
4d6ed7c8
NC
685 if (is_32bit_elf)
686 {
2cf0635d 687 Elf32_External_Rela * erelas;
103f02d3 688
3f5e193b 689 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 690 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
691 if (!erelas)
692 return 0;
252b5132 693
4d6ed7c8 694 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 695
3f5e193b
NC
696 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
697 sizeof (Elf_Internal_Rela));
103f02d3 698
4d6ed7c8
NC
699 if (relas == NULL)
700 {
c256ffe7 701 free (erelas);
591a748a 702 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
703 return 0;
704 }
103f02d3 705
4d6ed7c8
NC
706 for (i = 0; i < nrelas; i++)
707 {
708 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
709 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 710 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 711 }
103f02d3 712
4d6ed7c8
NC
713 free (erelas);
714 }
715 else
716 {
2cf0635d 717 Elf64_External_Rela * erelas;
103f02d3 718
3f5e193b 719 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 720 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
721 if (!erelas)
722 return 0;
4d6ed7c8
NC
723
724 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 725
3f5e193b
NC
726 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
727 sizeof (Elf_Internal_Rela));
103f02d3 728
4d6ed7c8
NC
729 if (relas == NULL)
730 {
c256ffe7 731 free (erelas);
591a748a 732 error (_("out of memory parsing relocs\n"));
4d6ed7c8 733 return 0;
9c19a809 734 }
4d6ed7c8
NC
735
736 for (i = 0; i < nrelas; i++)
9c19a809 737 {
66543521
AM
738 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
739 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 740 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
741
742 /* The #ifdef BFD64 below is to prevent a compile time
743 warning. We know that if we do not have a 64 bit data
744 type that we will never execute this code anyway. */
745#ifdef BFD64
746 if (elf_header.e_machine == EM_MIPS
747 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
748 {
749 /* In little-endian objects, r_info isn't really a
750 64-bit little-endian value: it has a 32-bit
751 little-endian symbol index followed by four
752 individual byte fields. Reorder INFO
753 accordingly. */
91d6fa6a
NC
754 bfd_vma inf = relas[i].r_info;
755 inf = (((inf & 0xffffffff) << 32)
756 | ((inf >> 56) & 0xff)
757 | ((inf >> 40) & 0xff00)
758 | ((inf >> 24) & 0xff0000)
759 | ((inf >> 8) & 0xff000000));
760 relas[i].r_info = inf;
861fb55a
DJ
761 }
762#endif /* BFD64 */
4d6ed7c8 763 }
103f02d3 764
4d6ed7c8
NC
765 free (erelas);
766 }
767 *relasp = relas;
768 *nrelasp = nrelas;
769 return 1;
770}
103f02d3 771
4d6ed7c8 772static int
2cf0635d 773slurp_rel_relocs (FILE * file,
d3ba0551
AM
774 unsigned long rel_offset,
775 unsigned long rel_size,
2cf0635d
NC
776 Elf_Internal_Rela ** relsp,
777 unsigned long * nrelsp)
4d6ed7c8 778{
2cf0635d 779 Elf_Internal_Rela * rels;
4d6ed7c8
NC
780 unsigned long nrels;
781 unsigned int i;
103f02d3 782
4d6ed7c8
NC
783 if (is_32bit_elf)
784 {
2cf0635d 785 Elf32_External_Rel * erels;
103f02d3 786
3f5e193b 787 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 788 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
789 if (!erels)
790 return 0;
103f02d3 791
4d6ed7c8 792 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 793
3f5e193b 794 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 795
4d6ed7c8
NC
796 if (rels == NULL)
797 {
c256ffe7 798 free (erels);
591a748a 799 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
800 return 0;
801 }
802
803 for (i = 0; i < nrels; i++)
804 {
805 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
806 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 807 rels[i].r_addend = 0;
9ea033b2 808 }
4d6ed7c8
NC
809
810 free (erels);
9c19a809
NC
811 }
812 else
813 {
2cf0635d 814 Elf64_External_Rel * erels;
9ea033b2 815
3f5e193b 816 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 817 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
818 if (!erels)
819 return 0;
103f02d3 820
4d6ed7c8 821 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 822
3f5e193b 823 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 824
4d6ed7c8 825 if (rels == NULL)
9c19a809 826 {
c256ffe7 827 free (erels);
591a748a 828 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
829 return 0;
830 }
103f02d3 831
4d6ed7c8
NC
832 for (i = 0; i < nrels; i++)
833 {
66543521
AM
834 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
835 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 836 rels[i].r_addend = 0;
861fb55a
DJ
837
838 /* The #ifdef BFD64 below is to prevent a compile time
839 warning. We know that if we do not have a 64 bit data
840 type that we will never execute this code anyway. */
841#ifdef BFD64
842 if (elf_header.e_machine == EM_MIPS
843 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
844 {
845 /* In little-endian objects, r_info isn't really a
846 64-bit little-endian value: it has a 32-bit
847 little-endian symbol index followed by four
848 individual byte fields. Reorder INFO
849 accordingly. */
91d6fa6a
NC
850 bfd_vma inf = rels[i].r_info;
851 inf = (((inf & 0xffffffff) << 32)
852 | ((inf >> 56) & 0xff)
853 | ((inf >> 40) & 0xff00)
854 | ((inf >> 24) & 0xff0000)
855 | ((inf >> 8) & 0xff000000));
856 rels[i].r_info = inf;
861fb55a
DJ
857 }
858#endif /* BFD64 */
4d6ed7c8 859 }
103f02d3 860
4d6ed7c8
NC
861 free (erels);
862 }
863 *relsp = rels;
864 *nrelsp = nrels;
865 return 1;
866}
103f02d3 867
aca88567
NC
868/* Returns the reloc type extracted from the reloc info field. */
869
870static unsigned int
871get_reloc_type (bfd_vma reloc_info)
872{
873 if (is_32bit_elf)
874 return ELF32_R_TYPE (reloc_info);
875
876 switch (elf_header.e_machine)
877 {
878 case EM_MIPS:
879 /* Note: We assume that reloc_info has already been adjusted for us. */
880 return ELF64_MIPS_R_TYPE (reloc_info);
881
882 case EM_SPARCV9:
883 return ELF64_R_TYPE_ID (reloc_info);
884
885 default:
886 return ELF64_R_TYPE (reloc_info);
887 }
888}
889
890/* Return the symbol index extracted from the reloc info field. */
891
892static bfd_vma
893get_reloc_symindex (bfd_vma reloc_info)
894{
895 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
896}
897
d3ba0551
AM
898/* Display the contents of the relocation data found at the specified
899 offset. */
ee42cf8c 900
41e92641 901static void
2cf0635d 902dump_relocations (FILE * file,
d3ba0551
AM
903 unsigned long rel_offset,
904 unsigned long rel_size,
2cf0635d 905 Elf_Internal_Sym * symtab,
d3ba0551 906 unsigned long nsyms,
2cf0635d 907 char * strtab,
d79b3d50 908 unsigned long strtablen,
d3ba0551 909 int is_rela)
4d6ed7c8 910{
b34976b6 911 unsigned int i;
2cf0635d 912 Elf_Internal_Rela * rels;
103f02d3 913
4d6ed7c8
NC
914 if (is_rela == UNKNOWN)
915 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 916
4d6ed7c8
NC
917 if (is_rela)
918 {
c8286bd1 919 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 920 return;
4d6ed7c8
NC
921 }
922 else
923 {
924 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 925 return;
252b5132
RH
926 }
927
410f7a12
L
928 if (is_32bit_elf)
929 {
930 if (is_rela)
2c71103e
NC
931 {
932 if (do_wide)
933 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
934 else
935 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
936 }
410f7a12 937 else
2c71103e
NC
938 {
939 if (do_wide)
940 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
941 else
942 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
943 }
410f7a12 944 }
252b5132 945 else
410f7a12
L
946 {
947 if (is_rela)
2c71103e
NC
948 {
949 if (do_wide)
8beeaeb7 950 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
951 else
952 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
953 }
410f7a12 954 else
2c71103e
NC
955 {
956 if (do_wide)
8beeaeb7 957 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
958 else
959 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
960 }
410f7a12 961 }
252b5132
RH
962
963 for (i = 0; i < rel_size; i++)
964 {
2cf0635d 965 const char * rtype;
b34976b6 966 bfd_vma offset;
91d6fa6a 967 bfd_vma inf;
b34976b6
AM
968 bfd_vma symtab_index;
969 bfd_vma type;
103f02d3 970
b34976b6 971 offset = rels[i].r_offset;
91d6fa6a 972 inf = rels[i].r_info;
103f02d3 973
91d6fa6a
NC
974 type = get_reloc_type (inf);
975 symtab_index = get_reloc_symindex (inf);
252b5132 976
410f7a12
L
977 if (is_32bit_elf)
978 {
39dbeff8
AM
979 printf ("%8.8lx %8.8lx ",
980 (unsigned long) offset & 0xffffffff,
91d6fa6a 981 (unsigned long) inf & 0xffffffff);
410f7a12
L
982 }
983 else
984 {
39dbeff8
AM
985#if BFD_HOST_64BIT_LONG
986 printf (do_wide
987 ? "%16.16lx %16.16lx "
988 : "%12.12lx %12.12lx ",
91d6fa6a 989 offset, inf);
39dbeff8 990#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 991#ifndef __MSVCRT__
39dbeff8
AM
992 printf (do_wide
993 ? "%16.16llx %16.16llx "
994 : "%12.12llx %12.12llx ",
91d6fa6a 995 offset, inf);
6e3d6dc1
NC
996#else
997 printf (do_wide
998 ? "%16.16I64x %16.16I64x "
999 : "%12.12I64x %12.12I64x ",
91d6fa6a 1000 offset, inf);
6e3d6dc1 1001#endif
39dbeff8 1002#else
2c71103e
NC
1003 printf (do_wide
1004 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1005 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1006 _bfd_int64_high (offset),
1007 _bfd_int64_low (offset),
91d6fa6a
NC
1008 _bfd_int64_high (inf),
1009 _bfd_int64_low (inf));
9ea033b2 1010#endif
410f7a12 1011 }
103f02d3 1012
252b5132
RH
1013 switch (elf_header.e_machine)
1014 {
1015 default:
1016 rtype = NULL;
1017 break;
1018
a06ea964
NC
1019 case EM_AARCH64:
1020 rtype = elf_aarch64_reloc_type (type);
1021 break;
1022
2b0337b0 1023 case EM_M32R:
252b5132 1024 case EM_CYGNUS_M32R:
9ea033b2 1025 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1026 break;
1027
1028 case EM_386:
1029 case EM_486:
9ea033b2 1030 rtype = elf_i386_reloc_type (type);
252b5132
RH
1031 break;
1032
ba2685cc
AM
1033 case EM_68HC11:
1034 case EM_68HC12:
1035 rtype = elf_m68hc11_reloc_type (type);
1036 break;
75751cd9 1037
252b5132 1038 case EM_68K:
9ea033b2 1039 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1040 break;
1041
63fcb9e9 1042 case EM_960:
9ea033b2 1043 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1044 break;
1045
adde6300 1046 case EM_AVR:
2b0337b0 1047 case EM_AVR_OLD:
adde6300
AM
1048 rtype = elf_avr_reloc_type (type);
1049 break;
1050
9ea033b2
NC
1051 case EM_OLD_SPARCV9:
1052 case EM_SPARC32PLUS:
1053 case EM_SPARCV9:
252b5132 1054 case EM_SPARC:
9ea033b2 1055 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1056 break;
1057
e9f53129
AM
1058 case EM_SPU:
1059 rtype = elf_spu_reloc_type (type);
1060 break;
1061
708e2187
NC
1062 case EM_V800:
1063 rtype = v800_reloc_type (type);
1064 break;
2b0337b0 1065 case EM_V850:
252b5132 1066 case EM_CYGNUS_V850:
9ea033b2 1067 rtype = v850_reloc_type (type);
252b5132
RH
1068 break;
1069
2b0337b0 1070 case EM_D10V:
252b5132 1071 case EM_CYGNUS_D10V:
9ea033b2 1072 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1073 break;
1074
2b0337b0 1075 case EM_D30V:
252b5132 1076 case EM_CYGNUS_D30V:
9ea033b2 1077 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1078 break;
1079
d172d4ba
NC
1080 case EM_DLX:
1081 rtype = elf_dlx_reloc_type (type);
1082 break;
1083
252b5132 1084 case EM_SH:
9ea033b2 1085 rtype = elf_sh_reloc_type (type);
252b5132
RH
1086 break;
1087
2b0337b0 1088 case EM_MN10300:
252b5132 1089 case EM_CYGNUS_MN10300:
9ea033b2 1090 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1091 break;
1092
2b0337b0 1093 case EM_MN10200:
252b5132 1094 case EM_CYGNUS_MN10200:
9ea033b2 1095 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1096 break;
1097
2b0337b0 1098 case EM_FR30:
252b5132 1099 case EM_CYGNUS_FR30:
9ea033b2 1100 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1101 break;
1102
ba2685cc
AM
1103 case EM_CYGNUS_FRV:
1104 rtype = elf_frv_reloc_type (type);
1105 break;
5c70f934 1106
252b5132 1107 case EM_MCORE:
9ea033b2 1108 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1109 break;
1110
3c3bdf30
NC
1111 case EM_MMIX:
1112 rtype = elf_mmix_reloc_type (type);
1113 break;
1114
5506d11a
AM
1115 case EM_MOXIE:
1116 rtype = elf_moxie_reloc_type (type);
1117 break;
1118
2469cfa2
NC
1119 case EM_MSP430:
1120 case EM_MSP430_OLD:
1121 rtype = elf_msp430_reloc_type (type);
1122 break;
1123
252b5132 1124 case EM_PPC:
9ea033b2 1125 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1126 break;
1127
c833c019
AM
1128 case EM_PPC64:
1129 rtype = elf_ppc64_reloc_type (type);
1130 break;
1131
252b5132 1132 case EM_MIPS:
4fe85591 1133 case EM_MIPS_RS3_LE:
9ea033b2 1134 rtype = elf_mips_reloc_type (type);
252b5132
RH
1135 break;
1136
1137 case EM_ALPHA:
9ea033b2 1138 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1139 break;
1140
1141 case EM_ARM:
9ea033b2 1142 rtype = elf_arm_reloc_type (type);
252b5132
RH
1143 break;
1144
584da044 1145 case EM_ARC:
9ea033b2 1146 rtype = elf_arc_reloc_type (type);
252b5132
RH
1147 break;
1148
1149 case EM_PARISC:
69e617ca 1150 rtype = elf_hppa_reloc_type (type);
252b5132 1151 break;
7d466069 1152
b8720f9d
JL
1153 case EM_H8_300:
1154 case EM_H8_300H:
1155 case EM_H8S:
1156 rtype = elf_h8_reloc_type (type);
1157 break;
1158
3b16e843
NC
1159 case EM_OPENRISC:
1160 case EM_OR32:
1161 rtype = elf_or32_reloc_type (type);
1162 break;
1163
7d466069 1164 case EM_PJ:
2b0337b0 1165 case EM_PJ_OLD:
7d466069
ILT
1166 rtype = elf_pj_reloc_type (type);
1167 break;
800eeca4
JW
1168 case EM_IA_64:
1169 rtype = elf_ia64_reloc_type (type);
1170 break;
1b61cf92
HPN
1171
1172 case EM_CRIS:
1173 rtype = elf_cris_reloc_type (type);
1174 break;
535c37ff
JE
1175
1176 case EM_860:
1177 rtype = elf_i860_reloc_type (type);
1178 break;
bcedfee6
NC
1179
1180 case EM_X86_64:
8a9036a4 1181 case EM_L1OM:
7a9068fe 1182 case EM_K1OM:
bcedfee6
NC
1183 rtype = elf_x86_64_reloc_type (type);
1184 break;
a85d7ed0 1185
35b1837e
AM
1186 case EM_S370:
1187 rtype = i370_reloc_type (type);
1188 break;
1189
53c7db4b
KH
1190 case EM_S390_OLD:
1191 case EM_S390:
1192 rtype = elf_s390_reloc_type (type);
1193 break;
93fbbb04 1194
1c0d3aa6
NC
1195 case EM_SCORE:
1196 rtype = elf_score_reloc_type (type);
1197 break;
1198
93fbbb04
GK
1199 case EM_XSTORMY16:
1200 rtype = elf_xstormy16_reloc_type (type);
1201 break;
179d3252 1202
1fe1f39c
NC
1203 case EM_CRX:
1204 rtype = elf_crx_reloc_type (type);
1205 break;
1206
179d3252
JT
1207 case EM_VAX:
1208 rtype = elf_vax_reloc_type (type);
1209 break;
1e4cf259 1210
cfb8c092
NC
1211 case EM_ADAPTEVA_EPIPHANY:
1212 rtype = elf_epiphany_reloc_type (type);
1213 break;
1214
1e4cf259
NC
1215 case EM_IP2K:
1216 case EM_IP2K_OLD:
1217 rtype = elf_ip2k_reloc_type (type);
1218 break;
3b36097d
SC
1219
1220 case EM_IQ2000:
1221 rtype = elf_iq2000_reloc_type (type);
1222 break;
88da6820
NC
1223
1224 case EM_XTENSA_OLD:
1225 case EM_XTENSA:
1226 rtype = elf_xtensa_reloc_type (type);
1227 break;
a34e3ecb 1228
84e94c90
NC
1229 case EM_LATTICEMICO32:
1230 rtype = elf_lm32_reloc_type (type);
1231 break;
1232
ff7eeb89 1233 case EM_M32C_OLD:
49f58d10
JB
1234 case EM_M32C:
1235 rtype = elf_m32c_reloc_type (type);
1236 break;
1237
d031aafb
NS
1238 case EM_MT:
1239 rtype = elf_mt_reloc_type (type);
a34e3ecb 1240 break;
1d65ded4
CM
1241
1242 case EM_BLACKFIN:
1243 rtype = elf_bfin_reloc_type (type);
1244 break;
15ab5209
DB
1245
1246 case EM_CYGNUS_MEP:
1247 rtype = elf_mep_reloc_type (type);
1248 break;
60bca95a
NC
1249
1250 case EM_CR16:
1251 rtype = elf_cr16_reloc_type (type);
1252 break;
dd24e3da 1253
7ba29e2a
NC
1254 case EM_MICROBLAZE:
1255 case EM_MICROBLAZE_OLD:
1256 rtype = elf_microblaze_reloc_type (type);
1257 break;
c7927a3c 1258
99c513f6
DD
1259 case EM_RL78:
1260 rtype = elf_rl78_reloc_type (type);
1261 break;
1262
c7927a3c
NC
1263 case EM_RX:
1264 rtype = elf_rx_reloc_type (type);
1265 break;
c29aca4a
NC
1266
1267 case EM_XC16X:
1268 case EM_C166:
1269 rtype = elf_xc16x_reloc_type (type);
1270 break;
40b36596
JM
1271
1272 case EM_TI_C6000:
1273 rtype = elf_tic6x_reloc_type (type);
1274 break;
aa137e4d
NC
1275
1276 case EM_TILEGX:
1277 rtype = elf_tilegx_reloc_type (type);
1278 break;
1279
1280 case EM_TILEPRO:
1281 rtype = elf_tilepro_reloc_type (type);
1282 break;
f6c1a2d5
NC
1283
1284 case EM_XGATE:
1285 rtype = elf_xgate_reloc_type (type);
1286 break;
252b5132
RH
1287 }
1288
1289 if (rtype == NULL)
39dbeff8 1290 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1291 else
8beeaeb7 1292 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1293
7ace3541 1294 if (elf_header.e_machine == EM_ALPHA
157c2599 1295 && rtype != NULL
7ace3541
RH
1296 && streq (rtype, "R_ALPHA_LITUSE")
1297 && is_rela)
1298 {
1299 switch (rels[i].r_addend)
1300 {
1301 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1302 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1303 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1304 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1305 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1306 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1307 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1308 default: rtype = NULL;
1309 }
1310 if (rtype)
1311 printf (" (%s)", rtype);
1312 else
1313 {
1314 putchar (' ');
1315 printf (_("<unknown addend: %lx>"),
1316 (unsigned long) rels[i].r_addend);
1317 }
1318 }
1319 else if (symtab_index)
252b5132 1320 {
af3fc3bc 1321 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1322 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1323 else
19936277 1324 {
2cf0635d 1325 Elf_Internal_Sym * psym;
19936277 1326
af3fc3bc 1327 psym = symtab + symtab_index;
103f02d3 1328
af3fc3bc 1329 printf (" ");
171191ba 1330
d8045f23
NC
1331 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1332 {
1333 const char * name;
1334 unsigned int len;
1335 unsigned int width = is_32bit_elf ? 8 : 14;
1336
1337 /* Relocations against GNU_IFUNC symbols do not use the value
1338 of the symbol as the address to relocate against. Instead
1339 they invoke the function named by the symbol and use its
1340 result as the address for relocation.
1341
1342 To indicate this to the user, do not display the value of
1343 the symbol in the "Symbols's Value" field. Instead show
1344 its name followed by () as a hint that the symbol is
1345 invoked. */
1346
1347 if (strtab == NULL
1348 || psym->st_name == 0
1349 || psym->st_name >= strtablen)
1350 name = "??";
1351 else
1352 name = strtab + psym->st_name;
1353
1354 len = print_symbol (width, name);
1355 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1356 }
1357 else
1358 {
1359 print_vma (psym->st_value, LONG_HEX);
171191ba 1360
d8045f23
NC
1361 printf (is_32bit_elf ? " " : " ");
1362 }
103f02d3 1363
af3fc3bc 1364 if (psym->st_name == 0)
f1ef08cb 1365 {
2cf0635d 1366 const char * sec_name = "<null>";
f1ef08cb
AM
1367 char name_buf[40];
1368
1369 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1370 {
4fbb74a6
AM
1371 if (psym->st_shndx < elf_header.e_shnum)
1372 sec_name
1373 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1374 else if (psym->st_shndx == SHN_ABS)
1375 sec_name = "ABS";
1376 else if (psym->st_shndx == SHN_COMMON)
1377 sec_name = "COMMON";
ac145307
BS
1378 else if ((elf_header.e_machine == EM_MIPS
1379 && psym->st_shndx == SHN_MIPS_SCOMMON)
1380 || (elf_header.e_machine == EM_TI_C6000
1381 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1382 sec_name = "SCOMMON";
1383 else if (elf_header.e_machine == EM_MIPS
1384 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1385 sec_name = "SUNDEF";
8a9036a4 1386 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1387 || elf_header.e_machine == EM_L1OM
1388 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1389 && psym->st_shndx == SHN_X86_64_LCOMMON)
1390 sec_name = "LARGE_COMMON";
9ce701e2
L
1391 else if (elf_header.e_machine == EM_IA_64
1392 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1393 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1394 sec_name = "ANSI_COM";
28f997cf 1395 else if (is_ia64_vms ()
148b93f2
NC
1396 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1397 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1398 else
1399 {
1400 sprintf (name_buf, "<section 0x%x>",
1401 (unsigned int) psym->st_shndx);
1402 sec_name = name_buf;
1403 }
1404 }
1405 print_symbol (22, sec_name);
1406 }
af3fc3bc 1407 else if (strtab == NULL)
d79b3d50 1408 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1409 else if (psym->st_name >= strtablen)
d79b3d50 1410 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1411 else
2c71103e 1412 print_symbol (22, strtab + psym->st_name);
103f02d3 1413
af3fc3bc 1414 if (is_rela)
171191ba 1415 {
598aaa76 1416 bfd_signed_vma off = rels[i].r_addend;
171191ba 1417
91d6fa6a 1418 if (off < 0)
598aaa76 1419 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1420 else
598aaa76 1421 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1422 }
19936277 1423 }
252b5132 1424 }
1b228002 1425 else if (is_rela)
f7a99963 1426 {
e04d7088
L
1427 bfd_signed_vma off = rels[i].r_addend;
1428
1429 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1430 if (off < 0)
1431 printf ("-%" BFD_VMA_FMT "x", - off);
1432 else
1433 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1434 }
252b5132 1435
157c2599
NC
1436 if (elf_header.e_machine == EM_SPARCV9
1437 && rtype != NULL
1438 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1439 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1440
252b5132 1441 putchar ('\n');
2c71103e 1442
aca88567 1443#ifdef BFD64
53c7db4b 1444 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1445 {
91d6fa6a
NC
1446 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1447 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1448 const char * rtype2 = elf_mips_reloc_type (type2);
1449 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1450
2c71103e
NC
1451 printf (" Type2: ");
1452
1453 if (rtype2 == NULL)
39dbeff8
AM
1454 printf (_("unrecognized: %-7lx"),
1455 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1456 else
1457 printf ("%-17.17s", rtype2);
1458
18bd398b 1459 printf ("\n Type3: ");
2c71103e
NC
1460
1461 if (rtype3 == NULL)
39dbeff8
AM
1462 printf (_("unrecognized: %-7lx"),
1463 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1464 else
1465 printf ("%-17.17s", rtype3);
1466
53c7db4b 1467 putchar ('\n');
2c71103e 1468 }
aca88567 1469#endif /* BFD64 */
252b5132
RH
1470 }
1471
c8286bd1 1472 free (rels);
252b5132
RH
1473}
1474
1475static const char *
d3ba0551 1476get_mips_dynamic_type (unsigned long type)
252b5132
RH
1477{
1478 switch (type)
1479 {
1480 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1481 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1482 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1483 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1484 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1485 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1486 case DT_MIPS_MSYM: return "MIPS_MSYM";
1487 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1488 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1489 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1490 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1491 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1492 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1493 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1494 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1495 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1496 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1497 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1498 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1499 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1500 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1501 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1502 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1503 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1504 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1505 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1506 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1507 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1508 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1509 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1510 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1511 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1512 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1513 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1514 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1515 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1516 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1517 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1518 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1519 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1520 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1521 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1522 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1523 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1524 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1525 default:
1526 return NULL;
1527 }
1528}
1529
9a097730 1530static const char *
d3ba0551 1531get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1532{
1533 switch (type)
1534 {
1535 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1536 default:
1537 return NULL;
1538 }
103f02d3
UD
1539}
1540
7490d522
AM
1541static const char *
1542get_ppc_dynamic_type (unsigned long type)
1543{
1544 switch (type)
1545 {
a7f2871e
AM
1546 case DT_PPC_GOT: return "PPC_GOT";
1547 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1548 default:
1549 return NULL;
1550 }
1551}
1552
f1cb7e17 1553static const char *
d3ba0551 1554get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1555{
1556 switch (type)
1557 {
a7f2871e
AM
1558 case DT_PPC64_GLINK: return "PPC64_GLINK";
1559 case DT_PPC64_OPD: return "PPC64_OPD";
1560 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1561 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1562 default:
1563 return NULL;
1564 }
1565}
1566
103f02d3 1567static const char *
d3ba0551 1568get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1569{
1570 switch (type)
1571 {
1572 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1573 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1574 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1575 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1576 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1577 case DT_HP_PREINIT: return "HP_PREINIT";
1578 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1579 case DT_HP_NEEDED: return "HP_NEEDED";
1580 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1581 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1582 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1583 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1584 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1585 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1586 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1587 case DT_HP_FILTERED: return "HP_FILTERED";
1588 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1589 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1590 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1591 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1592 case DT_PLT: return "PLT";
1593 case DT_PLT_SIZE: return "PLT_SIZE";
1594 case DT_DLT: return "DLT";
1595 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1596 default:
1597 return NULL;
1598 }
1599}
9a097730 1600
ecc51f48 1601static const char *
d3ba0551 1602get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1603{
1604 switch (type)
1605 {
148b93f2
NC
1606 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1607 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1608 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1609 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1610 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1611 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1612 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1613 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1614 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1615 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1616 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1617 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1618 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1619 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1620 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1621 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1622 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1623 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1624 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1625 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1626 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1627 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1628 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1629 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1630 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1631 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1632 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1633 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1634 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1635 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1636 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1637 default:
1638 return NULL;
1639 }
1640}
1641
fabcb361
RH
1642static const char *
1643get_alpha_dynamic_type (unsigned long type)
1644{
1645 switch (type)
1646 {
1647 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1648 default:
1649 return NULL;
1650 }
1651}
1652
1c0d3aa6
NC
1653static const char *
1654get_score_dynamic_type (unsigned long type)
1655{
1656 switch (type)
1657 {
1658 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1659 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1660 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1661 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1662 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1663 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1664 default:
1665 return NULL;
1666 }
1667}
1668
40b36596
JM
1669static const char *
1670get_tic6x_dynamic_type (unsigned long type)
1671{
1672 switch (type)
1673 {
1674 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1675 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1676 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1677 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1678 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1679 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1680 default:
1681 return NULL;
1682 }
1683}
1c0d3aa6 1684
252b5132 1685static const char *
d3ba0551 1686get_dynamic_type (unsigned long type)
252b5132 1687{
e9e44622 1688 static char buff[64];
252b5132
RH
1689
1690 switch (type)
1691 {
1692 case DT_NULL: return "NULL";
1693 case DT_NEEDED: return "NEEDED";
1694 case DT_PLTRELSZ: return "PLTRELSZ";
1695 case DT_PLTGOT: return "PLTGOT";
1696 case DT_HASH: return "HASH";
1697 case DT_STRTAB: return "STRTAB";
1698 case DT_SYMTAB: return "SYMTAB";
1699 case DT_RELA: return "RELA";
1700 case DT_RELASZ: return "RELASZ";
1701 case DT_RELAENT: return "RELAENT";
1702 case DT_STRSZ: return "STRSZ";
1703 case DT_SYMENT: return "SYMENT";
1704 case DT_INIT: return "INIT";
1705 case DT_FINI: return "FINI";
1706 case DT_SONAME: return "SONAME";
1707 case DT_RPATH: return "RPATH";
1708 case DT_SYMBOLIC: return "SYMBOLIC";
1709 case DT_REL: return "REL";
1710 case DT_RELSZ: return "RELSZ";
1711 case DT_RELENT: return "RELENT";
1712 case DT_PLTREL: return "PLTREL";
1713 case DT_DEBUG: return "DEBUG";
1714 case DT_TEXTREL: return "TEXTREL";
1715 case DT_JMPREL: return "JMPREL";
1716 case DT_BIND_NOW: return "BIND_NOW";
1717 case DT_INIT_ARRAY: return "INIT_ARRAY";
1718 case DT_FINI_ARRAY: return "FINI_ARRAY";
1719 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1720 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1721 case DT_RUNPATH: return "RUNPATH";
1722 case DT_FLAGS: return "FLAGS";
2d0e6f43 1723
d1133906
NC
1724 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1725 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1726
05107a46 1727 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1728 case DT_PLTPADSZ: return "PLTPADSZ";
1729 case DT_MOVEENT: return "MOVEENT";
1730 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1731 case DT_FEATURE: return "FEATURE";
252b5132
RH
1732 case DT_POSFLAG_1: return "POSFLAG_1";
1733 case DT_SYMINSZ: return "SYMINSZ";
1734 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1735
252b5132 1736 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1737 case DT_CONFIG: return "CONFIG";
1738 case DT_DEPAUDIT: return "DEPAUDIT";
1739 case DT_AUDIT: return "AUDIT";
1740 case DT_PLTPAD: return "PLTPAD";
1741 case DT_MOVETAB: return "MOVETAB";
252b5132 1742 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1743
252b5132 1744 case DT_VERSYM: return "VERSYM";
103f02d3 1745
67a4f2b7
AO
1746 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1747 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1748 case DT_RELACOUNT: return "RELACOUNT";
1749 case DT_RELCOUNT: return "RELCOUNT";
1750 case DT_FLAGS_1: return "FLAGS_1";
1751 case DT_VERDEF: return "VERDEF";
1752 case DT_VERDEFNUM: return "VERDEFNUM";
1753 case DT_VERNEED: return "VERNEED";
1754 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1755
019148e4 1756 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1757 case DT_USED: return "USED";
1758 case DT_FILTER: return "FILTER";
103f02d3 1759
047b2264
JJ
1760 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1761 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1762 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1763 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1764 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1765 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1766
252b5132
RH
1767 default:
1768 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1769 {
2cf0635d 1770 const char * result;
103f02d3 1771
252b5132
RH
1772 switch (elf_header.e_machine)
1773 {
1774 case EM_MIPS:
4fe85591 1775 case EM_MIPS_RS3_LE:
252b5132
RH
1776 result = get_mips_dynamic_type (type);
1777 break;
9a097730
RH
1778 case EM_SPARCV9:
1779 result = get_sparc64_dynamic_type (type);
1780 break;
7490d522
AM
1781 case EM_PPC:
1782 result = get_ppc_dynamic_type (type);
1783 break;
f1cb7e17
AM
1784 case EM_PPC64:
1785 result = get_ppc64_dynamic_type (type);
1786 break;
ecc51f48
NC
1787 case EM_IA_64:
1788 result = get_ia64_dynamic_type (type);
1789 break;
fabcb361
RH
1790 case EM_ALPHA:
1791 result = get_alpha_dynamic_type (type);
1792 break;
1c0d3aa6
NC
1793 case EM_SCORE:
1794 result = get_score_dynamic_type (type);
1795 break;
40b36596
JM
1796 case EM_TI_C6000:
1797 result = get_tic6x_dynamic_type (type);
1798 break;
252b5132
RH
1799 default:
1800 result = NULL;
1801 break;
1802 }
1803
1804 if (result != NULL)
1805 return result;
1806
e9e44622 1807 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1808 }
eec8f817
DA
1809 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1810 || (elf_header.e_machine == EM_PARISC
1811 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1812 {
2cf0635d 1813 const char * result;
103f02d3
UD
1814
1815 switch (elf_header.e_machine)
1816 {
1817 case EM_PARISC:
1818 result = get_parisc_dynamic_type (type);
1819 break;
148b93f2
NC
1820 case EM_IA_64:
1821 result = get_ia64_dynamic_type (type);
1822 break;
103f02d3
UD
1823 default:
1824 result = NULL;
1825 break;
1826 }
1827
1828 if (result != NULL)
1829 return result;
1830
e9e44622
JJ
1831 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1832 type);
103f02d3 1833 }
252b5132 1834 else
e9e44622 1835 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1836
252b5132
RH
1837 return buff;
1838 }
1839}
1840
1841static char *
d3ba0551 1842get_file_type (unsigned e_type)
252b5132 1843{
b34976b6 1844 static char buff[32];
252b5132
RH
1845
1846 switch (e_type)
1847 {
1848 case ET_NONE: return _("NONE (None)");
1849 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1850 case ET_EXEC: return _("EXEC (Executable file)");
1851 case ET_DYN: return _("DYN (Shared object file)");
1852 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1853
1854 default:
1855 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1856 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1857 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1858 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1859 else
e9e44622 1860 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1861 return buff;
1862 }
1863}
1864
1865static char *
d3ba0551 1866get_machine_name (unsigned e_machine)
252b5132 1867{
b34976b6 1868 static char buff[64]; /* XXX */
252b5132
RH
1869
1870 switch (e_machine)
1871 {
c45021f2 1872 case EM_NONE: return _("None");
a06ea964 1873 case EM_AARCH64: return "AArch64";
c45021f2
NC
1874 case EM_M32: return "WE32100";
1875 case EM_SPARC: return "Sparc";
e9f53129 1876 case EM_SPU: return "SPU";
c45021f2
NC
1877 case EM_386: return "Intel 80386";
1878 case EM_68K: return "MC68000";
1879 case EM_88K: return "MC88000";
1880 case EM_486: return "Intel 80486";
1881 case EM_860: return "Intel 80860";
1882 case EM_MIPS: return "MIPS R3000";
1883 case EM_S370: return "IBM System/370";
7036c0e1 1884 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1885 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1886 case EM_PARISC: return "HPPA";
252b5132 1887 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1888 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1889 case EM_960: return "Intel 90860";
1890 case EM_PPC: return "PowerPC";
285d1771 1891 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1892 case EM_FR20: return "Fujitsu FR20";
1893 case EM_RH32: return "TRW RH32";
b34976b6 1894 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1895 case EM_ARM: return "ARM";
1896 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1897 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1898 case EM_SPARCV9: return "Sparc v9";
1899 case EM_TRICORE: return "Siemens Tricore";
584da044 1900 case EM_ARC: return "ARC";
c2dcd04e
NC
1901 case EM_H8_300: return "Renesas H8/300";
1902 case EM_H8_300H: return "Renesas H8/300H";
1903 case EM_H8S: return "Renesas H8S";
1904 case EM_H8_500: return "Renesas H8/500";
30800947 1905 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1906 case EM_MIPS_X: return "Stanford MIPS-X";
1907 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1908 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1909 case EM_CYGNUS_D10V:
1910 case EM_D10V: return "d10v";
1911 case EM_CYGNUS_D30V:
b34976b6 1912 case EM_D30V: return "d30v";
2b0337b0 1913 case EM_CYGNUS_M32R:
26597c86 1914 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1915 case EM_CYGNUS_V850:
708e2187 1916 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 1917 case EM_V850: return "Renesas V850";
2b0337b0
AO
1918 case EM_CYGNUS_MN10300:
1919 case EM_MN10300: return "mn10300";
1920 case EM_CYGNUS_MN10200:
1921 case EM_MN10200: return "mn10200";
5506d11a 1922 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1923 case EM_CYGNUS_FR30:
1924 case EM_FR30: return "Fujitsu FR30";
b34976b6 1925 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1926 case EM_PJ_OLD:
b34976b6 1927 case EM_PJ: return "picoJava";
7036c0e1
AJ
1928 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1929 case EM_PCP: return "Siemens PCP";
1930 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1931 case EM_NDR1: return "Denso NDR1 microprocesspr";
1932 case EM_STARCORE: return "Motorola Star*Core processor";
1933 case EM_ME16: return "Toyota ME16 processor";
1934 case EM_ST100: return "STMicroelectronics ST100 processor";
1935 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1936 case EM_PDSP: return "Sony DSP processor";
1937 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1938 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1939 case EM_FX66: return "Siemens FX66 microcontroller";
1940 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1941 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1942 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1943 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1944 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1945 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1946 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1947 case EM_SVX: return "Silicon Graphics SVx";
1948 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1949 case EM_VAX: return "Digital VAX";
2b0337b0 1950 case EM_AVR_OLD:
b34976b6 1951 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1952 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1953 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1954 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1955 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1956 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1957 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1958 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1959 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1960 case EM_L1OM: return "Intel L1OM";
7a9068fe 1961 case EM_K1OM: return "Intel K1OM";
b7498e0e 1962 case EM_S390_OLD:
b34976b6 1963 case EM_S390: return "IBM S/390";
1c0d3aa6 1964 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1965 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1966 case EM_OPENRISC:
1967 case EM_OR32: return "OpenRISC";
11636f9e 1968 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1969 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 1970 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 1971 case EM_DLX: return "OpenDLX";
1e4cf259 1972 case EM_IP2K_OLD:
b34976b6 1973 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1974 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1975 case EM_XTENSA_OLD:
1976 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1977 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1978 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1979 case EM_NS32K: return "National Semiconductor 32000 series";
1980 case EM_TPC: return "Tenor Network TPC processor";
1981 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1982 case EM_MAX: return "MAX Processor";
1983 case EM_CR: return "National Semiconductor CompactRISC";
1984 case EM_F2MC16: return "Fujitsu F2MC16";
1985 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1986 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1987 case EM_M32C_OLD:
49f58d10 1988 case EM_M32C: return "Renesas M32c";
d031aafb 1989 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1990 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1991 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1992 case EM_SEP: return "Sharp embedded microprocessor";
1993 case EM_ARCA: return "Arca RISC microprocessor";
1994 case EM_UNICORE: return "Unicore";
1995 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1996 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1997 case EM_NIOS32: return "Altera Nios";
1998 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1999 case EM_C166:
d70c5fc7 2000 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2001 case EM_M16C: return "Renesas M16C series microprocessors";
2002 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2003 case EM_CE: return "Freescale Communication Engine RISC core";
2004 case EM_TSK3000: return "Altium TSK3000 core";
2005 case EM_RS08: return "Freescale RS08 embedded processor";
2006 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2007 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2008 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2009 case EM_SE_C17: return "Seiko Epson C17 family";
2010 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2011 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2012 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2013 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2014 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2015 case EM_R32C: return "Renesas R32C series microprocessors";
2016 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2017 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2018 case EM_8051: return "Intel 8051 and variants";
2019 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2020 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2021 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2022 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2023 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2024 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2025 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2026 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2027 case EM_CR16:
f6c1a2d5 2028 case EM_MICROBLAZE:
7ba29e2a 2029 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2030 case EM_RL78: return "Renesas RL78";
c7927a3c 2031 case EM_RX: return "Renesas RX";
11636f9e
JM
2032 case EM_METAG: return "Imagination Technologies META processor architecture";
2033 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2034 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2035 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2036 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2037 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2038 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2039 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2040 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2041 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2042 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2043 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2044 default:
35d9dd2f 2045 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2046 return buff;
2047 }
2048}
2049
f3485b74 2050static void
d3ba0551 2051decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2052{
2053 unsigned eabi;
2054 int unknown = 0;
2055
2056 eabi = EF_ARM_EABI_VERSION (e_flags);
2057 e_flags &= ~ EF_ARM_EABIMASK;
2058
2059 /* Handle "generic" ARM flags. */
2060 if (e_flags & EF_ARM_RELEXEC)
2061 {
2062 strcat (buf, ", relocatable executable");
2063 e_flags &= ~ EF_ARM_RELEXEC;
2064 }
76da6bbe 2065
f3485b74
NC
2066 if (e_flags & EF_ARM_HASENTRY)
2067 {
2068 strcat (buf, ", has entry point");
2069 e_flags &= ~ EF_ARM_HASENTRY;
2070 }
76da6bbe 2071
f3485b74
NC
2072 /* Now handle EABI specific flags. */
2073 switch (eabi)
2074 {
2075 default:
2c71103e 2076 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2077 if (e_flags)
2078 unknown = 1;
2079 break;
2080
2081 case EF_ARM_EABI_VER1:
a5bcd848 2082 strcat (buf, ", Version1 EABI");
f3485b74
NC
2083 while (e_flags)
2084 {
2085 unsigned flag;
76da6bbe 2086
f3485b74
NC
2087 /* Process flags one bit at a time. */
2088 flag = e_flags & - e_flags;
2089 e_flags &= ~ flag;
76da6bbe 2090
f3485b74
NC
2091 switch (flag)
2092 {
a5bcd848 2093 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2094 strcat (buf, ", sorted symbol tables");
2095 break;
76da6bbe 2096
f3485b74
NC
2097 default:
2098 unknown = 1;
2099 break;
2100 }
2101 }
2102 break;
76da6bbe 2103
a5bcd848
PB
2104 case EF_ARM_EABI_VER2:
2105 strcat (buf, ", Version2 EABI");
2106 while (e_flags)
2107 {
2108 unsigned flag;
2109
2110 /* Process flags one bit at a time. */
2111 flag = e_flags & - e_flags;
2112 e_flags &= ~ flag;
2113
2114 switch (flag)
2115 {
2116 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2117 strcat (buf, ", sorted symbol tables");
2118 break;
2119
2120 case EF_ARM_DYNSYMSUSESEGIDX:
2121 strcat (buf, ", dynamic symbols use segment index");
2122 break;
2123
2124 case EF_ARM_MAPSYMSFIRST:
2125 strcat (buf, ", mapping symbols precede others");
2126 break;
2127
2128 default:
2129 unknown = 1;
2130 break;
2131 }
2132 }
2133 break;
2134
d507cf36
PB
2135 case EF_ARM_EABI_VER3:
2136 strcat (buf, ", Version3 EABI");
8cb51566
PB
2137 break;
2138
2139 case EF_ARM_EABI_VER4:
2140 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2141 while (e_flags)
2142 {
2143 unsigned flag;
2144
2145 /* Process flags one bit at a time. */
2146 flag = e_flags & - e_flags;
2147 e_flags &= ~ flag;
2148
2149 switch (flag)
2150 {
2151 case EF_ARM_BE8:
2152 strcat (buf, ", BE8");
2153 break;
2154
2155 case EF_ARM_LE8:
2156 strcat (buf, ", LE8");
2157 break;
2158
2159 default:
2160 unknown = 1;
2161 break;
2162 }
2163 break;
2164 }
2165 break;
3a4a14e9
PB
2166
2167 case EF_ARM_EABI_VER5:
2168 strcat (buf, ", Version5 EABI");
d507cf36
PB
2169 while (e_flags)
2170 {
2171 unsigned flag;
2172
2173 /* Process flags one bit at a time. */
2174 flag = e_flags & - e_flags;
2175 e_flags &= ~ flag;
2176
2177 switch (flag)
2178 {
2179 case EF_ARM_BE8:
2180 strcat (buf, ", BE8");
2181 break;
2182
2183 case EF_ARM_LE8:
2184 strcat (buf, ", LE8");
2185 break;
2186
3bfcb652
NC
2187 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2188 strcat (buf, ", soft-float ABI");
2189 break;
2190
2191 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2192 strcat (buf, ", hard-float ABI");
2193 break;
2194
d507cf36
PB
2195 default:
2196 unknown = 1;
2197 break;
2198 }
2199 }
2200 break;
2201
f3485b74 2202 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2203 strcat (buf, ", GNU EABI");
f3485b74
NC
2204 while (e_flags)
2205 {
2206 unsigned flag;
76da6bbe 2207
f3485b74
NC
2208 /* Process flags one bit at a time. */
2209 flag = e_flags & - e_flags;
2210 e_flags &= ~ flag;
76da6bbe 2211
f3485b74
NC
2212 switch (flag)
2213 {
a5bcd848 2214 case EF_ARM_INTERWORK:
f3485b74
NC
2215 strcat (buf, ", interworking enabled");
2216 break;
76da6bbe 2217
a5bcd848 2218 case EF_ARM_APCS_26:
f3485b74
NC
2219 strcat (buf, ", uses APCS/26");
2220 break;
76da6bbe 2221
a5bcd848 2222 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2223 strcat (buf, ", uses APCS/float");
2224 break;
76da6bbe 2225
a5bcd848 2226 case EF_ARM_PIC:
f3485b74
NC
2227 strcat (buf, ", position independent");
2228 break;
76da6bbe 2229
a5bcd848 2230 case EF_ARM_ALIGN8:
f3485b74
NC
2231 strcat (buf, ", 8 bit structure alignment");
2232 break;
76da6bbe 2233
a5bcd848 2234 case EF_ARM_NEW_ABI:
f3485b74
NC
2235 strcat (buf, ", uses new ABI");
2236 break;
76da6bbe 2237
a5bcd848 2238 case EF_ARM_OLD_ABI:
f3485b74
NC
2239 strcat (buf, ", uses old ABI");
2240 break;
76da6bbe 2241
a5bcd848 2242 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2243 strcat (buf, ", software FP");
2244 break;
76da6bbe 2245
90e01f86
ILT
2246 case EF_ARM_VFP_FLOAT:
2247 strcat (buf, ", VFP");
2248 break;
2249
fde78edd
NC
2250 case EF_ARM_MAVERICK_FLOAT:
2251 strcat (buf, ", Maverick FP");
2252 break;
2253
f3485b74
NC
2254 default:
2255 unknown = 1;
2256 break;
2257 }
2258 }
2259 }
f3485b74
NC
2260
2261 if (unknown)
2b692964 2262 strcat (buf,_(", <unknown>"));
f3485b74
NC
2263}
2264
252b5132 2265static char *
d3ba0551 2266get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2267{
b34976b6 2268 static char buf[1024];
252b5132
RH
2269
2270 buf[0] = '\0';
76da6bbe 2271
252b5132
RH
2272 if (e_flags)
2273 {
2274 switch (e_machine)
2275 {
2276 default:
2277 break;
2278
f3485b74
NC
2279 case EM_ARM:
2280 decode_ARM_machine_flags (e_flags, buf);
2281 break;
76da6bbe 2282
781303ce
MF
2283 case EM_BLACKFIN:
2284 if (e_flags & EF_BFIN_PIC)
2285 strcat (buf, ", PIC");
2286
2287 if (e_flags & EF_BFIN_FDPIC)
2288 strcat (buf, ", FDPIC");
2289
2290 if (e_flags & EF_BFIN_CODE_IN_L1)
2291 strcat (buf, ", code in L1");
2292
2293 if (e_flags & EF_BFIN_DATA_IN_L1)
2294 strcat (buf, ", data in L1");
2295
2296 break;
2297
ec2dfb42
AO
2298 case EM_CYGNUS_FRV:
2299 switch (e_flags & EF_FRV_CPU_MASK)
2300 {
2301 case EF_FRV_CPU_GENERIC:
2302 break;
2303
2304 default:
2305 strcat (buf, ", fr???");
2306 break;
57346661 2307
ec2dfb42
AO
2308 case EF_FRV_CPU_FR300:
2309 strcat (buf, ", fr300");
2310 break;
2311
2312 case EF_FRV_CPU_FR400:
2313 strcat (buf, ", fr400");
2314 break;
2315 case EF_FRV_CPU_FR405:
2316 strcat (buf, ", fr405");
2317 break;
2318
2319 case EF_FRV_CPU_FR450:
2320 strcat (buf, ", fr450");
2321 break;
2322
2323 case EF_FRV_CPU_FR500:
2324 strcat (buf, ", fr500");
2325 break;
2326 case EF_FRV_CPU_FR550:
2327 strcat (buf, ", fr550");
2328 break;
2329
2330 case EF_FRV_CPU_SIMPLE:
2331 strcat (buf, ", simple");
2332 break;
2333 case EF_FRV_CPU_TOMCAT:
2334 strcat (buf, ", tomcat");
2335 break;
2336 }
1c877e87 2337 break;
ec2dfb42 2338
53c7db4b 2339 case EM_68K:
425c6cb0 2340 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2341 strcat (buf, ", m68000");
425c6cb0 2342 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2343 strcat (buf, ", cpu32");
2344 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2345 strcat (buf, ", fido_a");
425c6cb0 2346 else
266abb8f 2347 {
2cf0635d
NC
2348 char const * isa = _("unknown");
2349 char const * mac = _("unknown mac");
2350 char const * additional = NULL;
0112cd26 2351
c694fd50 2352 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2353 {
c694fd50 2354 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2355 isa = "A";
2356 additional = ", nodiv";
2357 break;
c694fd50 2358 case EF_M68K_CF_ISA_A:
266abb8f
NS
2359 isa = "A";
2360 break;
c694fd50 2361 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2362 isa = "A+";
2363 break;
c694fd50 2364 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2365 isa = "B";
2366 additional = ", nousp";
2367 break;
c694fd50 2368 case EF_M68K_CF_ISA_B:
266abb8f
NS
2369 isa = "B";
2370 break;
f608cd77
NS
2371 case EF_M68K_CF_ISA_C:
2372 isa = "C";
2373 break;
2374 case EF_M68K_CF_ISA_C_NODIV:
2375 isa = "C";
2376 additional = ", nodiv";
2377 break;
266abb8f
NS
2378 }
2379 strcat (buf, ", cf, isa ");
2380 strcat (buf, isa);
0b2e31dc
NS
2381 if (additional)
2382 strcat (buf, additional);
c694fd50 2383 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2384 strcat (buf, ", float");
c694fd50 2385 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2386 {
2387 case 0:
2388 mac = NULL;
2389 break;
c694fd50 2390 case EF_M68K_CF_MAC:
266abb8f
NS
2391 mac = "mac";
2392 break;
c694fd50 2393 case EF_M68K_CF_EMAC:
266abb8f
NS
2394 mac = "emac";
2395 break;
f608cd77
NS
2396 case EF_M68K_CF_EMAC_B:
2397 mac = "emac_b";
2398 break;
266abb8f
NS
2399 }
2400 if (mac)
2401 {
2402 strcat (buf, ", ");
2403 strcat (buf, mac);
2404 }
266abb8f 2405 }
53c7db4b 2406 break;
33c63f9d 2407
252b5132
RH
2408 case EM_PPC:
2409 if (e_flags & EF_PPC_EMB)
2410 strcat (buf, ", emb");
2411
2412 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2413 strcat (buf, _(", relocatable"));
252b5132
RH
2414
2415 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2416 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2417 break;
2418
708e2187
NC
2419 case EM_V800:
2420 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2421 strcat (buf, ", RH850 ABI");
2422
2423 if (e_flags & EF_V800_850E3)
2424 strcat (buf, ", V3 architecture");
2425
2426 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2427 strcat (buf, ", FPU not used");
2428
2429 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2430 strcat (buf, ", regmode: COMMON");
2431
2432 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2433 strcat (buf, ", r4 not used");
2434
2435 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2436 strcat (buf, ", r30 not used");
2437
2438 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2439 strcat (buf, ", r5 not used");
2440
2441 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2442 strcat (buf, ", r2 not used");
2443
2444 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2445 {
2446 switch (e_flags & - e_flags)
2447 {
2448 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2449 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2450 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2451 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2452 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2453 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2454 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2455 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2456 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2457 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2458 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2459 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2460 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2461 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2462 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2463 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2464 default: break;
2465 }
2466 }
2467 break;
2468
2b0337b0 2469 case EM_V850:
252b5132
RH
2470 case EM_CYGNUS_V850:
2471 switch (e_flags & EF_V850_ARCH)
2472 {
1cd986c5
NC
2473 case E_V850E2V3_ARCH:
2474 strcat (buf, ", v850e2v3");
2475 break;
2476 case E_V850E2_ARCH:
2477 strcat (buf, ", v850e2");
2478 break;
2479 case E_V850E1_ARCH:
2480 strcat (buf, ", v850e1");
8ad30312 2481 break;
252b5132
RH
2482 case E_V850E_ARCH:
2483 strcat (buf, ", v850e");
2484 break;
252b5132
RH
2485 case E_V850_ARCH:
2486 strcat (buf, ", v850");
2487 break;
2488 default:
2b692964 2489 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2490 break;
2491 }
2492 break;
2493
2b0337b0 2494 case EM_M32R:
252b5132
RH
2495 case EM_CYGNUS_M32R:
2496 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2497 strcat (buf, ", m32r");
252b5132
RH
2498 break;
2499
2500 case EM_MIPS:
4fe85591 2501 case EM_MIPS_RS3_LE:
252b5132
RH
2502 if (e_flags & EF_MIPS_NOREORDER)
2503 strcat (buf, ", noreorder");
2504
2505 if (e_flags & EF_MIPS_PIC)
2506 strcat (buf, ", pic");
2507
2508 if (e_flags & EF_MIPS_CPIC)
2509 strcat (buf, ", cpic");
2510
d1bdd336
TS
2511 if (e_flags & EF_MIPS_UCODE)
2512 strcat (buf, ", ugen_reserved");
2513
252b5132
RH
2514 if (e_flags & EF_MIPS_ABI2)
2515 strcat (buf, ", abi2");
2516
43521d43
TS
2517 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2518 strcat (buf, ", odk first");
2519
a5d22d2a
TS
2520 if (e_flags & EF_MIPS_32BITMODE)
2521 strcat (buf, ", 32bitmode");
2522
156c2f8b
NC
2523 switch ((e_flags & EF_MIPS_MACH))
2524 {
2525 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2526 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2527 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2528 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2529 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2530 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2531 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2532 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2533 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2534 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2535 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2536 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2537 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2538 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2539 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2540 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2541 case 0:
2542 /* We simply ignore the field in this case to avoid confusion:
2543 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2544 extension. */
2545 break;
2b692964 2546 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2547 }
43521d43
TS
2548
2549 switch ((e_flags & EF_MIPS_ABI))
2550 {
2551 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2552 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2553 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2554 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2555 case 0:
2556 /* We simply ignore the field in this case to avoid confusion:
2557 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2558 This means it is likely to be an o32 file, but not for
2559 sure. */
2560 break;
2b692964 2561 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2562 }
2563
2564 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2565 strcat (buf, ", mdmx");
2566
2567 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2568 strcat (buf, ", mips16");
2569
df58fc94
RS
2570 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2571 strcat (buf, ", micromips");
2572
43521d43
TS
2573 switch ((e_flags & EF_MIPS_ARCH))
2574 {
2575 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2576 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2577 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2578 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2579 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2580 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2581 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2582 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2583 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2584 default: strcat (buf, _(", unknown ISA")); break;
43521d43 2585 }
252b5132 2586 break;
351b4b40 2587
ccde1100
AO
2588 case EM_SH:
2589 switch ((e_flags & EF_SH_MACH_MASK))
2590 {
2591 case EF_SH1: strcat (buf, ", sh1"); break;
2592 case EF_SH2: strcat (buf, ", sh2"); break;
2593 case EF_SH3: strcat (buf, ", sh3"); break;
2594 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2595 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2596 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2597 case EF_SH3E: strcat (buf, ", sh3e"); break;
2598 case EF_SH4: strcat (buf, ", sh4"); break;
2599 case EF_SH5: strcat (buf, ", sh5"); break;
2600 case EF_SH2E: strcat (buf, ", sh2e"); break;
2601 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2602 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2603 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2604 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2605 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2606 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2607 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2608 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2609 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2610 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2611 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2612 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2613 }
2614
cec6a5b8
MR
2615 if (e_flags & EF_SH_PIC)
2616 strcat (buf, ", pic");
2617
2618 if (e_flags & EF_SH_FDPIC)
2619 strcat (buf, ", fdpic");
ccde1100 2620 break;
57346661 2621
351b4b40
RH
2622 case EM_SPARCV9:
2623 if (e_flags & EF_SPARC_32PLUS)
2624 strcat (buf, ", v8+");
2625
2626 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2627 strcat (buf, ", ultrasparcI");
2628
2629 if (e_flags & EF_SPARC_SUN_US3)
2630 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2631
2632 if (e_flags & EF_SPARC_HAL_R1)
2633 strcat (buf, ", halr1");
2634
2635 if (e_flags & EF_SPARC_LEDATA)
2636 strcat (buf, ", ledata");
2637
2638 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2639 strcat (buf, ", tso");
2640
2641 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2642 strcat (buf, ", pso");
2643
2644 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2645 strcat (buf, ", rmo");
2646 break;
7d466069 2647
103f02d3
UD
2648 case EM_PARISC:
2649 switch (e_flags & EF_PARISC_ARCH)
2650 {
2651 case EFA_PARISC_1_0:
2652 strcpy (buf, ", PA-RISC 1.0");
2653 break;
2654 case EFA_PARISC_1_1:
2655 strcpy (buf, ", PA-RISC 1.1");
2656 break;
2657 case EFA_PARISC_2_0:
2658 strcpy (buf, ", PA-RISC 2.0");
2659 break;
2660 default:
2661 break;
2662 }
2663 if (e_flags & EF_PARISC_TRAPNIL)
2664 strcat (buf, ", trapnil");
2665 if (e_flags & EF_PARISC_EXT)
2666 strcat (buf, ", ext");
2667 if (e_flags & EF_PARISC_LSB)
2668 strcat (buf, ", lsb");
2669 if (e_flags & EF_PARISC_WIDE)
2670 strcat (buf, ", wide");
2671 if (e_flags & EF_PARISC_NO_KABP)
2672 strcat (buf, ", no kabp");
2673 if (e_flags & EF_PARISC_LAZYSWAP)
2674 strcat (buf, ", lazyswap");
30800947 2675 break;
76da6bbe 2676
7d466069 2677 case EM_PJ:
2b0337b0 2678 case EM_PJ_OLD:
7d466069
ILT
2679 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2680 strcat (buf, ", new calling convention");
2681
2682 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2683 strcat (buf, ", gnu calling convention");
2684 break;
4d6ed7c8
NC
2685
2686 case EM_IA_64:
2687 if ((e_flags & EF_IA_64_ABI64))
2688 strcat (buf, ", 64-bit");
2689 else
2690 strcat (buf, ", 32-bit");
2691 if ((e_flags & EF_IA_64_REDUCEDFP))
2692 strcat (buf, ", reduced fp model");
2693 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2694 strcat (buf, ", no function descriptors, constant gp");
2695 else if ((e_flags & EF_IA_64_CONS_GP))
2696 strcat (buf, ", constant gp");
2697 if ((e_flags & EF_IA_64_ABSOLUTE))
2698 strcat (buf, ", absolute");
28f997cf
TG
2699 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2700 {
2701 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2702 strcat (buf, ", vms_linkages");
2703 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2704 {
2705 case EF_IA_64_VMS_COMCOD_SUCCESS:
2706 break;
2707 case EF_IA_64_VMS_COMCOD_WARNING:
2708 strcat (buf, ", warning");
2709 break;
2710 case EF_IA_64_VMS_COMCOD_ERROR:
2711 strcat (buf, ", error");
2712 break;
2713 case EF_IA_64_VMS_COMCOD_ABORT:
2714 strcat (buf, ", abort");
2715 break;
2716 default:
2717 abort ();
2718 }
2719 }
4d6ed7c8 2720 break;
179d3252
JT
2721
2722 case EM_VAX:
2723 if ((e_flags & EF_VAX_NONPIC))
2724 strcat (buf, ", non-PIC");
2725 if ((e_flags & EF_VAX_DFLOAT))
2726 strcat (buf, ", D-Float");
2727 if ((e_flags & EF_VAX_GFLOAT))
2728 strcat (buf, ", G-Float");
2729 break;
c7927a3c
NC
2730
2731 case EM_RX:
2732 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2733 strcat (buf, ", 64-bit doubles");
2734 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2735 strcat (buf, ", dsp");
d4cb0ea0
NC
2736 if (e_flags & E_FLAG_RX_PID)
2737 strcat (buf, ", pid");
708e2187
NC
2738 if (e_flags & E_FLAG_RX_ABI)
2739 strcat (buf, ", RX ABI");
d4cb0ea0 2740 break;
55786da2
AK
2741
2742 case EM_S390:
2743 if (e_flags & EF_S390_HIGH_GPRS)
2744 strcat (buf, ", highgprs");
d4cb0ea0 2745 break;
40b36596
JM
2746
2747 case EM_TI_C6000:
2748 if ((e_flags & EF_C6000_REL))
2749 strcat (buf, ", relocatable module");
d4cb0ea0 2750 break;
252b5132
RH
2751 }
2752 }
2753
2754 return buf;
2755}
2756
252b5132 2757static const char *
d3ba0551
AM
2758get_osabi_name (unsigned int osabi)
2759{
2760 static char buff[32];
2761
2762 switch (osabi)
2763 {
2764 case ELFOSABI_NONE: return "UNIX - System V";
2765 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2766 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2767 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2768 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2769 case ELFOSABI_AIX: return "UNIX - AIX";
2770 case ELFOSABI_IRIX: return "UNIX - IRIX";
2771 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2772 case ELFOSABI_TRU64: return "UNIX - TRU64";
2773 case ELFOSABI_MODESTO: return "Novell - Modesto";
2774 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2775 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2776 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2777 case ELFOSABI_AROS: return "AROS";
11636f9e 2778 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2779 default:
40b36596
JM
2780 if (osabi >= 64)
2781 switch (elf_header.e_machine)
2782 {
2783 case EM_ARM:
2784 switch (osabi)
2785 {
2786 case ELFOSABI_ARM: return "ARM";
2787 default:
2788 break;
2789 }
2790 break;
2791
2792 case EM_MSP430:
2793 case EM_MSP430_OLD:
2794 switch (osabi)
2795 {
2796 case ELFOSABI_STANDALONE: return _("Standalone App");
2797 default:
2798 break;
2799 }
2800 break;
2801
2802 case EM_TI_C6000:
2803 switch (osabi)
2804 {
2805 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2806 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2807 default:
2808 break;
2809 }
2810 break;
2811
2812 default:
2813 break;
2814 }
e9e44622 2815 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2816 return buff;
2817 }
2818}
2819
a06ea964
NC
2820static const char *
2821get_aarch64_segment_type (unsigned long type)
2822{
2823 switch (type)
2824 {
2825 case PT_AARCH64_ARCHEXT:
2826 return "AARCH64_ARCHEXT";
2827 default:
2828 break;
2829 }
2830
2831 return NULL;
2832}
2833
b294bdf8
MM
2834static const char *
2835get_arm_segment_type (unsigned long type)
2836{
2837 switch (type)
2838 {
2839 case PT_ARM_EXIDX:
2840 return "EXIDX";
2841 default:
2842 break;
2843 }
2844
2845 return NULL;
2846}
2847
d3ba0551
AM
2848static const char *
2849get_mips_segment_type (unsigned long type)
252b5132
RH
2850{
2851 switch (type)
2852 {
2853 case PT_MIPS_REGINFO:
2854 return "REGINFO";
2855 case PT_MIPS_RTPROC:
2856 return "RTPROC";
2857 case PT_MIPS_OPTIONS:
2858 return "OPTIONS";
2859 default:
2860 break;
2861 }
2862
2863 return NULL;
2864}
2865
103f02d3 2866static const char *
d3ba0551 2867get_parisc_segment_type (unsigned long type)
103f02d3
UD
2868{
2869 switch (type)
2870 {
2871 case PT_HP_TLS: return "HP_TLS";
2872 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2873 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2874 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2875 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2876 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2877 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2878 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2879 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2880 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2881 case PT_HP_PARALLEL: return "HP_PARALLEL";
2882 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2883 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2884 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2885 case PT_HP_STACK: return "HP_STACK";
2886 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2887 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2888 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2889 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2890 default:
2891 break;
2892 }
2893
2894 return NULL;
2895}
2896
4d6ed7c8 2897static const char *
d3ba0551 2898get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2899{
2900 switch (type)
2901 {
2902 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2903 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2904 case PT_HP_TLS: return "HP_TLS";
2905 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2906 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2907 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2908 default:
2909 break;
2910 }
2911
2912 return NULL;
2913}
2914
40b36596
JM
2915static const char *
2916get_tic6x_segment_type (unsigned long type)
2917{
2918 switch (type)
2919 {
2920 case PT_C6000_PHATTR: return "C6000_PHATTR";
2921 default:
2922 break;
2923 }
2924
2925 return NULL;
2926}
2927
252b5132 2928static const char *
d3ba0551 2929get_segment_type (unsigned long p_type)
252b5132 2930{
b34976b6 2931 static char buff[32];
252b5132
RH
2932
2933 switch (p_type)
2934 {
b34976b6
AM
2935 case PT_NULL: return "NULL";
2936 case PT_LOAD: return "LOAD";
252b5132 2937 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2938 case PT_INTERP: return "INTERP";
2939 case PT_NOTE: return "NOTE";
2940 case PT_SHLIB: return "SHLIB";
2941 case PT_PHDR: return "PHDR";
13ae64f3 2942 case PT_TLS: return "TLS";
252b5132 2943
65765700
JJ
2944 case PT_GNU_EH_FRAME:
2945 return "GNU_EH_FRAME";
2b05f1b7 2946 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2947 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2948
252b5132
RH
2949 default:
2950 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2951 {
2cf0635d 2952 const char * result;
103f02d3 2953
252b5132
RH
2954 switch (elf_header.e_machine)
2955 {
a06ea964
NC
2956 case EM_AARCH64:
2957 result = get_aarch64_segment_type (p_type);
2958 break;
b294bdf8
MM
2959 case EM_ARM:
2960 result = get_arm_segment_type (p_type);
2961 break;
252b5132 2962 case EM_MIPS:
4fe85591 2963 case EM_MIPS_RS3_LE:
252b5132
RH
2964 result = get_mips_segment_type (p_type);
2965 break;
103f02d3
UD
2966 case EM_PARISC:
2967 result = get_parisc_segment_type (p_type);
2968 break;
4d6ed7c8
NC
2969 case EM_IA_64:
2970 result = get_ia64_segment_type (p_type);
2971 break;
40b36596
JM
2972 case EM_TI_C6000:
2973 result = get_tic6x_segment_type (p_type);
2974 break;
252b5132
RH
2975 default:
2976 result = NULL;
2977 break;
2978 }
103f02d3 2979
252b5132
RH
2980 if (result != NULL)
2981 return result;
103f02d3 2982
252b5132
RH
2983 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2984 }
2985 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2986 {
2cf0635d 2987 const char * result;
103f02d3
UD
2988
2989 switch (elf_header.e_machine)
2990 {
2991 case EM_PARISC:
2992 result = get_parisc_segment_type (p_type);
2993 break;
00428cca
AM
2994 case EM_IA_64:
2995 result = get_ia64_segment_type (p_type);
2996 break;
103f02d3
UD
2997 default:
2998 result = NULL;
2999 break;
3000 }
3001
3002 if (result != NULL)
3003 return result;
3004
3005 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3006 }
252b5132 3007 else
e9e44622 3008 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3009
3010 return buff;
3011 }
3012}
3013
3014static const char *
d3ba0551 3015get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3016{
3017 switch (sh_type)
3018 {
b34976b6
AM
3019 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3020 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3021 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3022 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3023 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3024 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3025 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3026 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3027 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3028 case SHT_MIPS_RELD: return "MIPS_RELD";
3029 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3030 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3031 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3032 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3033 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3034 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3035 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3036 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3037 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3038 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3039 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3040 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3041 case SHT_MIPS_LINE: return "MIPS_LINE";
3042 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3043 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3044 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3045 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3046 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3047 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3048 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3049 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3050 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3051 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3052 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3053 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3054 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3055 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3056 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
3057 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
3058 default:
3059 break;
3060 }
3061 return NULL;
3062}
3063
103f02d3 3064static const char *
d3ba0551 3065get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3066{
3067 switch (sh_type)
3068 {
3069 case SHT_PARISC_EXT: return "PARISC_EXT";
3070 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3071 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3072 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3073 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3074 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3075 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3076 default:
3077 break;
3078 }
3079 return NULL;
3080}
3081
4d6ed7c8 3082static const char *
d3ba0551 3083get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3084{
18bd398b 3085 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3086 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3087 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3088
4d6ed7c8
NC
3089 switch (sh_type)
3090 {
148b93f2
NC
3091 case SHT_IA_64_EXT: return "IA_64_EXT";
3092 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3093 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3094 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3095 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3096 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3097 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3098 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3099 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3100 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3101 default:
3102 break;
3103 }
3104 return NULL;
3105}
3106
d2b2c203
DJ
3107static const char *
3108get_x86_64_section_type_name (unsigned int sh_type)
3109{
3110 switch (sh_type)
3111 {
3112 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3113 default:
3114 break;
3115 }
3116 return NULL;
3117}
3118
a06ea964
NC
3119static const char *
3120get_aarch64_section_type_name (unsigned int sh_type)
3121{
3122 switch (sh_type)
3123 {
3124 case SHT_AARCH64_ATTRIBUTES:
3125 return "AARCH64_ATTRIBUTES";
3126 default:
3127 break;
3128 }
3129 return NULL;
3130}
3131
40a18ebd
NC
3132static const char *
3133get_arm_section_type_name (unsigned int sh_type)
3134{
3135 switch (sh_type)
3136 {
7f6fed87
NC
3137 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3138 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3139 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3140 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3141 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3142 default:
3143 break;
3144 }
3145 return NULL;
3146}
3147
40b36596
JM
3148static const char *
3149get_tic6x_section_type_name (unsigned int sh_type)
3150{
3151 switch (sh_type)
3152 {
3153 case SHT_C6000_UNWIND:
3154 return "C6000_UNWIND";
3155 case SHT_C6000_PREEMPTMAP:
3156 return "C6000_PREEMPTMAP";
3157 case SHT_C6000_ATTRIBUTES:
3158 return "C6000_ATTRIBUTES";
3159 case SHT_TI_ICODE:
3160 return "TI_ICODE";
3161 case SHT_TI_XREF:
3162 return "TI_XREF";
3163 case SHT_TI_HANDLER:
3164 return "TI_HANDLER";
3165 case SHT_TI_INITINFO:
3166 return "TI_INITINFO";
3167 case SHT_TI_PHATTRS:
3168 return "TI_PHATTRS";
3169 default:
3170 break;
3171 }
3172 return NULL;
3173}
3174
252b5132 3175static const char *
d3ba0551 3176get_section_type_name (unsigned int sh_type)
252b5132 3177{
b34976b6 3178 static char buff[32];
252b5132
RH
3179
3180 switch (sh_type)
3181 {
3182 case SHT_NULL: return "NULL";
3183 case SHT_PROGBITS: return "PROGBITS";
3184 case SHT_SYMTAB: return "SYMTAB";
3185 case SHT_STRTAB: return "STRTAB";
3186 case SHT_RELA: return "RELA";
3187 case SHT_HASH: return "HASH";
3188 case SHT_DYNAMIC: return "DYNAMIC";
3189 case SHT_NOTE: return "NOTE";
3190 case SHT_NOBITS: return "NOBITS";
3191 case SHT_REL: return "REL";
3192 case SHT_SHLIB: return "SHLIB";
3193 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3194 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3195 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3196 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3197 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3198 case SHT_GROUP: return "GROUP";
3199 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3200 case SHT_GNU_verdef: return "VERDEF";
3201 case SHT_GNU_verneed: return "VERNEED";
3202 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3203 case 0x6ffffff0: return "VERSYM";
3204 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3205 case 0x7ffffffd: return "AUXILIARY";
3206 case 0x7fffffff: return "FILTER";
047b2264 3207 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3208
3209 default:
3210 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3211 {
2cf0635d 3212 const char * result;
252b5132
RH
3213
3214 switch (elf_header.e_machine)
3215 {
3216 case EM_MIPS:
4fe85591 3217 case EM_MIPS_RS3_LE:
252b5132
RH
3218 result = get_mips_section_type_name (sh_type);
3219 break;
103f02d3
UD
3220 case EM_PARISC:
3221 result = get_parisc_section_type_name (sh_type);
3222 break;
4d6ed7c8
NC
3223 case EM_IA_64:
3224 result = get_ia64_section_type_name (sh_type);
3225 break;
d2b2c203 3226 case EM_X86_64:
8a9036a4 3227 case EM_L1OM:
7a9068fe 3228 case EM_K1OM:
d2b2c203
DJ
3229 result = get_x86_64_section_type_name (sh_type);
3230 break;
a06ea964
NC
3231 case EM_AARCH64:
3232 result = get_aarch64_section_type_name (sh_type);
3233 break;
40a18ebd
NC
3234 case EM_ARM:
3235 result = get_arm_section_type_name (sh_type);
3236 break;
40b36596
JM
3237 case EM_TI_C6000:
3238 result = get_tic6x_section_type_name (sh_type);
3239 break;
252b5132
RH
3240 default:
3241 result = NULL;
3242 break;
3243 }
3244
3245 if (result != NULL)
3246 return result;
3247
c91d0dfb 3248 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3249 }
3250 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3251 {
2cf0635d 3252 const char * result;
148b93f2
NC
3253
3254 switch (elf_header.e_machine)
3255 {
3256 case EM_IA_64:
3257 result = get_ia64_section_type_name (sh_type);
3258 break;
3259 default:
3260 result = NULL;
3261 break;
3262 }
3263
3264 if (result != NULL)
3265 return result;
3266
3267 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3268 }
252b5132 3269 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3270 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3271 else
a7dbfd1c
NC
3272 /* This message is probably going to be displayed in a 15
3273 character wide field, so put the hex value first. */
3274 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3275
252b5132
RH
3276 return buff;
3277 }
3278}
3279
2979dc34 3280#define OPTION_DEBUG_DUMP 512
2c610e4b 3281#define OPTION_DYN_SYMS 513
fd2f0033
TT
3282#define OPTION_DWARF_DEPTH 514
3283#define OPTION_DWARF_START 515
4723351a 3284#define OPTION_DWARF_CHECK 516
2979dc34 3285
85b1c36d 3286static struct option options[] =
252b5132 3287{
b34976b6 3288 {"all", no_argument, 0, 'a'},
252b5132
RH
3289 {"file-header", no_argument, 0, 'h'},
3290 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3291 {"headers", no_argument, 0, 'e'},
3292 {"histogram", no_argument, 0, 'I'},
3293 {"segments", no_argument, 0, 'l'},
3294 {"sections", no_argument, 0, 'S'},
252b5132 3295 {"section-headers", no_argument, 0, 'S'},
f5842774 3296 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3297 {"section-details", no_argument, 0, 't'},
595cf52e 3298 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3299 {"symbols", no_argument, 0, 's'},
3300 {"syms", no_argument, 0, 's'},
2c610e4b 3301 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3302 {"relocs", no_argument, 0, 'r'},
3303 {"notes", no_argument, 0, 'n'},
3304 {"dynamic", no_argument, 0, 'd'},
a952a375 3305 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3306 {"version-info", no_argument, 0, 'V'},
3307 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3308 {"unwind", no_argument, 0, 'u'},
4145f1d5 3309 {"archive-index", no_argument, 0, 'c'},
b34976b6 3310 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3311 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3312 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3313#ifdef SUPPORT_DISASSEMBLY
3314 {"instruction-dump", required_argument, 0, 'i'},
3315#endif
cf13d699 3316 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3317
fd2f0033
TT
3318 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3319 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3320 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3321
b34976b6
AM
3322 {"version", no_argument, 0, 'v'},
3323 {"wide", no_argument, 0, 'W'},
3324 {"help", no_argument, 0, 'H'},
3325 {0, no_argument, 0, 0}
252b5132
RH
3326};
3327
3328static void
2cf0635d 3329usage (FILE * stream)
252b5132 3330{
92f01d61
JM
3331 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3332 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3333 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3334 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3335 -h --file-header Display the ELF file header\n\
3336 -l --program-headers Display the program headers\n\
3337 --segments An alias for --program-headers\n\
3338 -S --section-headers Display the sections' header\n\
3339 --sections An alias for --section-headers\n\
f5842774 3340 -g --section-groups Display the section groups\n\
5477e8a0 3341 -t --section-details Display the section details\n\
8b53311e
NC
3342 -e --headers Equivalent to: -h -l -S\n\
3343 -s --syms Display the symbol table\n\
3f08eb35 3344 --symbols An alias for --syms\n\
2c610e4b 3345 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3346 -n --notes Display the core notes (if present)\n\
3347 -r --relocs Display the relocations (if present)\n\
3348 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3349 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3350 -V --version-info Display the version sections (if present)\n\
1b31d05e 3351 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3352 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3353 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3354 -x --hex-dump=<number|name>\n\
3355 Dump the contents of section <number|name> as bytes\n\
3356 -p --string-dump=<number|name>\n\
3357 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3358 -R --relocated-dump=<number|name>\n\
3359 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3360 -w[lLiaprmfFsoRt] or\n\
1ed06042 3361 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3362 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3363 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3364 =addr,=cu_index]\n\
8b53311e 3365 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3366 fprintf (stream, _("\
3367 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3368 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3369 or deeper\n"));
252b5132 3370#ifdef SUPPORT_DISASSEMBLY
92f01d61 3371 fprintf (stream, _("\
09c11c86
NC
3372 -i --instruction-dump=<number|name>\n\
3373 Disassemble the contents of section <number|name>\n"));
252b5132 3374#endif
92f01d61 3375 fprintf (stream, _("\
8b53311e
NC
3376 -I --histogram Display histogram of bucket list lengths\n\
3377 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3378 @<file> Read options from <file>\n\
8b53311e
NC
3379 -H --help Display this information\n\
3380 -v --version Display the version number of readelf\n"));
1118d252 3381
92f01d61
JM
3382 if (REPORT_BUGS_TO[0] && stream == stdout)
3383 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3384
92f01d61 3385 exit (stream == stdout ? 0 : 1);
252b5132
RH
3386}
3387
18bd398b
NC
3388/* Record the fact that the user wants the contents of section number
3389 SECTION to be displayed using the method(s) encoded as flags bits
3390 in TYPE. Note, TYPE can be zero if we are creating the array for
3391 the first time. */
3392
252b5132 3393static void
09c11c86 3394request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3395{
3396 if (section >= num_dump_sects)
3397 {
2cf0635d 3398 dump_type * new_dump_sects;
252b5132 3399
3f5e193b
NC
3400 new_dump_sects = (dump_type *) calloc (section + 1,
3401 sizeof (* dump_sects));
252b5132
RH
3402
3403 if (new_dump_sects == NULL)
591a748a 3404 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3405 else
3406 {
3407 /* Copy current flag settings. */
09c11c86 3408 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3409
3410 free (dump_sects);
3411
3412 dump_sects = new_dump_sects;
3413 num_dump_sects = section + 1;
3414 }
3415 }
3416
3417 if (dump_sects)
b34976b6 3418 dump_sects[section] |= type;
252b5132
RH
3419
3420 return;
3421}
3422
aef1f6d0
DJ
3423/* Request a dump by section name. */
3424
3425static void
2cf0635d 3426request_dump_byname (const char * section, dump_type type)
aef1f6d0 3427{
2cf0635d 3428 struct dump_list_entry * new_request;
aef1f6d0 3429
3f5e193b
NC
3430 new_request = (struct dump_list_entry *)
3431 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3432 if (!new_request)
591a748a 3433 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3434
3435 new_request->name = strdup (section);
3436 if (!new_request->name)
591a748a 3437 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3438
3439 new_request->type = type;
3440
3441 new_request->next = dump_sects_byname;
3442 dump_sects_byname = new_request;
3443}
3444
cf13d699
NC
3445static inline void
3446request_dump (dump_type type)
3447{
3448 int section;
3449 char * cp;
3450
3451 do_dump++;
3452 section = strtoul (optarg, & cp, 0);
3453
3454 if (! *cp && section >= 0)
3455 request_dump_bynumber (section, type);
3456 else
3457 request_dump_byname (optarg, type);
3458}
3459
3460
252b5132 3461static void
2cf0635d 3462parse_args (int argc, char ** argv)
252b5132
RH
3463{
3464 int c;
3465
3466 if (argc < 2)
92f01d61 3467 usage (stderr);
252b5132
RH
3468
3469 while ((c = getopt_long
cf13d699 3470 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3471 {
252b5132
RH
3472 switch (c)
3473 {
3474 case 0:
3475 /* Long options. */
3476 break;
3477 case 'H':
92f01d61 3478 usage (stdout);
252b5132
RH
3479 break;
3480
3481 case 'a':
b34976b6
AM
3482 do_syms++;
3483 do_reloc++;
3484 do_unwind++;
3485 do_dynamic++;
3486 do_header++;
3487 do_sections++;
f5842774 3488 do_section_groups++;
b34976b6
AM
3489 do_segments++;
3490 do_version++;
3491 do_histogram++;
3492 do_arch++;
3493 do_notes++;
252b5132 3494 break;
f5842774
L
3495 case 'g':
3496 do_section_groups++;
3497 break;
5477e8a0 3498 case 't':
595cf52e 3499 case 'N':
5477e8a0
L
3500 do_sections++;
3501 do_section_details++;
595cf52e 3502 break;
252b5132 3503 case 'e':
b34976b6
AM
3504 do_header++;
3505 do_sections++;
3506 do_segments++;
252b5132 3507 break;
a952a375 3508 case 'A':
b34976b6 3509 do_arch++;
a952a375 3510 break;
252b5132 3511 case 'D':
b34976b6 3512 do_using_dynamic++;
252b5132
RH
3513 break;
3514 case 'r':
b34976b6 3515 do_reloc++;
252b5132 3516 break;
4d6ed7c8 3517 case 'u':
b34976b6 3518 do_unwind++;
4d6ed7c8 3519 break;
252b5132 3520 case 'h':
b34976b6 3521 do_header++;
252b5132
RH
3522 break;
3523 case 'l':
b34976b6 3524 do_segments++;
252b5132
RH
3525 break;
3526 case 's':
b34976b6 3527 do_syms++;
252b5132
RH
3528 break;
3529 case 'S':
b34976b6 3530 do_sections++;
252b5132
RH
3531 break;
3532 case 'd':
b34976b6 3533 do_dynamic++;
252b5132 3534 break;
a952a375 3535 case 'I':
b34976b6 3536 do_histogram++;
a952a375 3537 break;
779fe533 3538 case 'n':
b34976b6 3539 do_notes++;
779fe533 3540 break;
4145f1d5
NC
3541 case 'c':
3542 do_archive_index++;
3543 break;
252b5132 3544 case 'x':
cf13d699 3545 request_dump (HEX_DUMP);
aef1f6d0 3546 break;
09c11c86 3547 case 'p':
cf13d699
NC
3548 request_dump (STRING_DUMP);
3549 break;
3550 case 'R':
3551 request_dump (RELOC_DUMP);
09c11c86 3552 break;
252b5132 3553 case 'w':
b34976b6 3554 do_dump++;
252b5132 3555 if (optarg == 0)
613ff48b
CC
3556 {
3557 do_debugging = 1;
3558 dwarf_select_sections_all ();
3559 }
252b5132
RH
3560 else
3561 {
3562 do_debugging = 0;
4cb93e3b 3563 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3564 }
3565 break;
2979dc34 3566 case OPTION_DEBUG_DUMP:
b34976b6 3567 do_dump++;
2979dc34
JJ
3568 if (optarg == 0)
3569 do_debugging = 1;
3570 else
3571 {
2979dc34 3572 do_debugging = 0;
4cb93e3b 3573 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3574 }
3575 break;
fd2f0033
TT
3576 case OPTION_DWARF_DEPTH:
3577 {
3578 char *cp;
3579
3580 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3581 }
3582 break;
3583 case OPTION_DWARF_START:
3584 {
3585 char *cp;
3586
3587 dwarf_start_die = strtoul (optarg, & cp, 0);
3588 }
3589 break;
4723351a
CC
3590 case OPTION_DWARF_CHECK:
3591 dwarf_check = 1;
3592 break;
2c610e4b
L
3593 case OPTION_DYN_SYMS:
3594 do_dyn_syms++;
3595 break;
252b5132
RH
3596#ifdef SUPPORT_DISASSEMBLY
3597 case 'i':
cf13d699
NC
3598 request_dump (DISASS_DUMP);
3599 break;
252b5132
RH
3600#endif
3601 case 'v':
3602 print_version (program_name);
3603 break;
3604 case 'V':
b34976b6 3605 do_version++;
252b5132 3606 break;
d974e256 3607 case 'W':
b34976b6 3608 do_wide++;
d974e256 3609 break;
252b5132 3610 default:
252b5132
RH
3611 /* xgettext:c-format */
3612 error (_("Invalid option '-%c'\n"), c);
3613 /* Drop through. */
3614 case '?':
92f01d61 3615 usage (stderr);
252b5132
RH
3616 }
3617 }
3618
4d6ed7c8 3619 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3620 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3621 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3622 && !do_section_groups && !do_archive_index
3623 && !do_dyn_syms)
92f01d61 3624 usage (stderr);
252b5132
RH
3625 else if (argc < 3)
3626 {
3627 warn (_("Nothing to do.\n"));
92f01d61 3628 usage (stderr);
252b5132
RH
3629 }
3630}
3631
3632static const char *
d3ba0551 3633get_elf_class (unsigned int elf_class)
252b5132 3634{
b34976b6 3635 static char buff[32];
103f02d3 3636
252b5132
RH
3637 switch (elf_class)
3638 {
3639 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3640 case ELFCLASS32: return "ELF32";
3641 case ELFCLASS64: return "ELF64";
ab5e7794 3642 default:
e9e44622 3643 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3644 return buff;
252b5132
RH
3645 }
3646}
3647
3648static const char *
d3ba0551 3649get_data_encoding (unsigned int encoding)
252b5132 3650{
b34976b6 3651 static char buff[32];
103f02d3 3652
252b5132
RH
3653 switch (encoding)
3654 {
3655 case ELFDATANONE: return _("none");
33c63f9d
CM
3656 case ELFDATA2LSB: return _("2's complement, little endian");
3657 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3658 default:
e9e44622 3659 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3660 return buff;
252b5132
RH
3661 }
3662}
3663
252b5132 3664/* Decode the data held in 'elf_header'. */
ee42cf8c 3665
252b5132 3666static int
d3ba0551 3667process_file_header (void)
252b5132 3668{
b34976b6
AM
3669 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3670 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3671 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3672 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3673 {
3674 error
3675 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3676 return 0;
3677 }
3678
2dc4cec1
L
3679 init_dwarf_regnames (elf_header.e_machine);
3680
252b5132
RH
3681 if (do_header)
3682 {
3683 int i;
3684
3685 printf (_("ELF Header:\n"));
3686 printf (_(" Magic: "));
b34976b6
AM
3687 for (i = 0; i < EI_NIDENT; i++)
3688 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3689 printf ("\n");
3690 printf (_(" Class: %s\n"),
b34976b6 3691 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3692 printf (_(" Data: %s\n"),
b34976b6 3693 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3694 printf (_(" Version: %d %s\n"),
b34976b6
AM
3695 elf_header.e_ident[EI_VERSION],
3696 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3697 ? "(current)"
b34976b6 3698 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3699 ? _("<unknown: %lx>")
789be9f7 3700 : "")));
252b5132 3701 printf (_(" OS/ABI: %s\n"),
b34976b6 3702 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3703 printf (_(" ABI Version: %d\n"),
b34976b6 3704 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3705 printf (_(" Type: %s\n"),
3706 get_file_type (elf_header.e_type));
3707 printf (_(" Machine: %s\n"),
3708 get_machine_name (elf_header.e_machine));
3709 printf (_(" Version: 0x%lx\n"),
3710 (unsigned long) elf_header.e_version);
76da6bbe 3711
f7a99963
NC
3712 printf (_(" Entry point address: "));
3713 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3714 printf (_("\n Start of program headers: "));
3715 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3716 printf (_(" (bytes into file)\n Start of section headers: "));
3717 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3718 printf (_(" (bytes into file)\n"));
76da6bbe 3719
252b5132
RH
3720 printf (_(" Flags: 0x%lx%s\n"),
3721 (unsigned long) elf_header.e_flags,
3722 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3723 printf (_(" Size of this header: %ld (bytes)\n"),
3724 (long) elf_header.e_ehsize);
3725 printf (_(" Size of program headers: %ld (bytes)\n"),
3726 (long) elf_header.e_phentsize);
2046a35d 3727 printf (_(" Number of program headers: %ld"),
252b5132 3728 (long) elf_header.e_phnum);
2046a35d
AM
3729 if (section_headers != NULL
3730 && elf_header.e_phnum == PN_XNUM
3731 && section_headers[0].sh_info != 0)
cc5914eb 3732 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3733 putc ('\n', stdout);
252b5132
RH
3734 printf (_(" Size of section headers: %ld (bytes)\n"),
3735 (long) elf_header.e_shentsize);
560f3c1c 3736 printf (_(" Number of section headers: %ld"),
252b5132 3737 (long) elf_header.e_shnum);
4fbb74a6 3738 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3739 printf (" (%ld)", (long) section_headers[0].sh_size);
3740 putc ('\n', stdout);
3741 printf (_(" Section header string table index: %ld"),
252b5132 3742 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3743 if (section_headers != NULL
3744 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3745 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3746 else if (elf_header.e_shstrndx != SHN_UNDEF
3747 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3748 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3749 putc ('\n', stdout);
3750 }
3751
3752 if (section_headers != NULL)
3753 {
2046a35d
AM
3754 if (elf_header.e_phnum == PN_XNUM
3755 && section_headers[0].sh_info != 0)
3756 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3757 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3758 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3759 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3760 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3761 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3762 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3763 free (section_headers);
3764 section_headers = NULL;
252b5132 3765 }
103f02d3 3766
9ea033b2
NC
3767 return 1;
3768}
3769
252b5132 3770
9ea033b2 3771static int
91d6fa6a 3772get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3773{
2cf0635d
NC
3774 Elf32_External_Phdr * phdrs;
3775 Elf32_External_Phdr * external;
3776 Elf_Internal_Phdr * internal;
b34976b6 3777 unsigned int i;
103f02d3 3778
3f5e193b
NC
3779 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3780 elf_header.e_phentsize,
3781 elf_header.e_phnum,
3782 _("program headers"));
a6e9f9df
AM
3783 if (!phdrs)
3784 return 0;
9ea033b2 3785
91d6fa6a 3786 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3787 i < elf_header.e_phnum;
b34976b6 3788 i++, internal++, external++)
252b5132 3789 {
9ea033b2
NC
3790 internal->p_type = BYTE_GET (external->p_type);
3791 internal->p_offset = BYTE_GET (external->p_offset);
3792 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3793 internal->p_paddr = BYTE_GET (external->p_paddr);
3794 internal->p_filesz = BYTE_GET (external->p_filesz);
3795 internal->p_memsz = BYTE_GET (external->p_memsz);
3796 internal->p_flags = BYTE_GET (external->p_flags);
3797 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3798 }
3799
9ea033b2
NC
3800 free (phdrs);
3801
252b5132
RH
3802 return 1;
3803}
3804
9ea033b2 3805static int
91d6fa6a 3806get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3807{
2cf0635d
NC
3808 Elf64_External_Phdr * phdrs;
3809 Elf64_External_Phdr * external;
3810 Elf_Internal_Phdr * internal;
b34976b6 3811 unsigned int i;
103f02d3 3812
3f5e193b
NC
3813 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3814 elf_header.e_phentsize,
3815 elf_header.e_phnum,
3816 _("program headers"));
a6e9f9df
AM
3817 if (!phdrs)
3818 return 0;
9ea033b2 3819
91d6fa6a 3820 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3821 i < elf_header.e_phnum;
b34976b6 3822 i++, internal++, external++)
9ea033b2
NC
3823 {
3824 internal->p_type = BYTE_GET (external->p_type);
3825 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3826 internal->p_offset = BYTE_GET (external->p_offset);
3827 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3828 internal->p_paddr = BYTE_GET (external->p_paddr);
3829 internal->p_filesz = BYTE_GET (external->p_filesz);
3830 internal->p_memsz = BYTE_GET (external->p_memsz);
3831 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3832 }
3833
3834 free (phdrs);
3835
3836 return 1;
3837}
252b5132 3838
d93f0186
NC
3839/* Returns 1 if the program headers were read into `program_headers'. */
3840
3841static int
2cf0635d 3842get_program_headers (FILE * file)
d93f0186 3843{
2cf0635d 3844 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3845
3846 /* Check cache of prior read. */
3847 if (program_headers != NULL)
3848 return 1;
3849
3f5e193b
NC
3850 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3851 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3852
3853 if (phdrs == NULL)
3854 {
3855 error (_("Out of memory\n"));
3856 return 0;
3857 }
3858
3859 if (is_32bit_elf
3860 ? get_32bit_program_headers (file, phdrs)
3861 : get_64bit_program_headers (file, phdrs))
3862 {
3863 program_headers = phdrs;
3864 return 1;
3865 }
3866
3867 free (phdrs);
3868 return 0;
3869}
3870
2f62977e
NC
3871/* Returns 1 if the program headers were loaded. */
3872
252b5132 3873static int
2cf0635d 3874process_program_headers (FILE * file)
252b5132 3875{
2cf0635d 3876 Elf_Internal_Phdr * segment;
b34976b6 3877 unsigned int i;
252b5132
RH
3878
3879 if (elf_header.e_phnum == 0)
3880 {
82f2dbf7
NC
3881 /* PR binutils/12467. */
3882 if (elf_header.e_phoff != 0)
3883 warn (_("possibly corrupt ELF header - it has a non-zero program"
3884 " header offset, but no program headers"));
3885 else if (do_segments)
252b5132 3886 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3887 return 0;
252b5132
RH
3888 }
3889
3890 if (do_segments && !do_header)
3891 {
f7a99963
NC
3892 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3893 printf (_("Entry point "));
3894 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3895 printf (_("\nThere are %d program headers, starting at offset "),
3896 elf_header.e_phnum);
3897 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3898 printf ("\n");
252b5132
RH
3899 }
3900
d93f0186 3901 if (! get_program_headers (file))
252b5132 3902 return 0;
103f02d3 3903
252b5132
RH
3904 if (do_segments)
3905 {
3a1a2036
NC
3906 if (elf_header.e_phnum > 1)
3907 printf (_("\nProgram Headers:\n"));
3908 else
3909 printf (_("\nProgram Headers:\n"));
76da6bbe 3910
f7a99963
NC
3911 if (is_32bit_elf)
3912 printf
3913 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3914 else if (do_wide)
3915 printf
3916 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3917 else
3918 {
3919 printf
3920 (_(" Type Offset VirtAddr PhysAddr\n"));
3921 printf
3922 (_(" FileSiz MemSiz Flags Align\n"));
3923 }
252b5132
RH
3924 }
3925
252b5132 3926 dynamic_addr = 0;
1b228002 3927 dynamic_size = 0;
252b5132
RH
3928
3929 for (i = 0, segment = program_headers;
3930 i < elf_header.e_phnum;
b34976b6 3931 i++, segment++)
252b5132
RH
3932 {
3933 if (do_segments)
3934 {
103f02d3 3935 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3936
3937 if (is_32bit_elf)
3938 {
3939 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3940 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3941 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3942 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3943 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3944 printf ("%c%c%c ",
3945 (segment->p_flags & PF_R ? 'R' : ' '),
3946 (segment->p_flags & PF_W ? 'W' : ' '),
3947 (segment->p_flags & PF_X ? 'E' : ' '));
3948 printf ("%#lx", (unsigned long) segment->p_align);
3949 }
d974e256
JJ
3950 else if (do_wide)
3951 {
3952 if ((unsigned long) segment->p_offset == segment->p_offset)
3953 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3954 else
3955 {
3956 print_vma (segment->p_offset, FULL_HEX);
3957 putchar (' ');
3958 }
3959
3960 print_vma (segment->p_vaddr, FULL_HEX);
3961 putchar (' ');
3962 print_vma (segment->p_paddr, FULL_HEX);
3963 putchar (' ');
3964
3965 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3966 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3967 else
3968 {
3969 print_vma (segment->p_filesz, FULL_HEX);
3970 putchar (' ');
3971 }
3972
3973 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3974 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3975 else
3976 {
f48e6c45 3977 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
3978 }
3979
3980 printf (" %c%c%c ",
3981 (segment->p_flags & PF_R ? 'R' : ' '),
3982 (segment->p_flags & PF_W ? 'W' : ' '),
3983 (segment->p_flags & PF_X ? 'E' : ' '));
3984
3985 if ((unsigned long) segment->p_align == segment->p_align)
3986 printf ("%#lx", (unsigned long) segment->p_align);
3987 else
3988 {
3989 print_vma (segment->p_align, PREFIX_HEX);
3990 }
3991 }
f7a99963
NC
3992 else
3993 {
3994 print_vma (segment->p_offset, FULL_HEX);
3995 putchar (' ');
3996 print_vma (segment->p_vaddr, FULL_HEX);
3997 putchar (' ');
3998 print_vma (segment->p_paddr, FULL_HEX);
3999 printf ("\n ");
4000 print_vma (segment->p_filesz, FULL_HEX);
4001 putchar (' ');
4002 print_vma (segment->p_memsz, FULL_HEX);
4003 printf (" %c%c%c ",
4004 (segment->p_flags & PF_R ? 'R' : ' '),
4005 (segment->p_flags & PF_W ? 'W' : ' '),
4006 (segment->p_flags & PF_X ? 'E' : ' '));
4007 print_vma (segment->p_align, HEX);
4008 }
252b5132
RH
4009 }
4010
4011 switch (segment->p_type)
4012 {
252b5132
RH
4013 case PT_DYNAMIC:
4014 if (dynamic_addr)
4015 error (_("more than one dynamic segment\n"));
4016
20737c13
AM
4017 /* By default, assume that the .dynamic section is the first
4018 section in the DYNAMIC segment. */
4019 dynamic_addr = segment->p_offset;
4020 dynamic_size = segment->p_filesz;
4021
b2d38a17
NC
4022 /* Try to locate the .dynamic section. If there is
4023 a section header table, we can easily locate it. */
4024 if (section_headers != NULL)
4025 {
2cf0635d 4026 Elf_Internal_Shdr * sec;
b2d38a17 4027
89fac5e3
RS
4028 sec = find_section (".dynamic");
4029 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4030 {
28f997cf
TG
4031 /* A corresponding .dynamic section is expected, but on
4032 IA-64/OpenVMS it is OK for it to be missing. */
4033 if (!is_ia64_vms ())
4034 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4035 break;
4036 }
4037
42bb2e33 4038 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4039 {
4040 dynamic_size = 0;
4041 break;
4042 }
42bb2e33 4043
b2d38a17
NC
4044 dynamic_addr = sec->sh_offset;
4045 dynamic_size = sec->sh_size;
4046
4047 if (dynamic_addr < segment->p_offset
4048 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4049 warn (_("the .dynamic section is not contained"
4050 " within the dynamic segment\n"));
b2d38a17 4051 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4052 warn (_("the .dynamic section is not the first section"
4053 " in the dynamic segment.\n"));
b2d38a17 4054 }
252b5132
RH
4055 break;
4056
4057 case PT_INTERP:
fb52b2f4
NC
4058 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4059 SEEK_SET))
252b5132
RH
4060 error (_("Unable to find program interpreter name\n"));
4061 else
4062 {
f8eae8b2
L
4063 char fmt [32];
4064 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
4065
4066 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4067 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4068
252b5132 4069 program_interpreter[0] = 0;
7bd7b3ef
AM
4070 if (fscanf (file, fmt, program_interpreter) <= 0)
4071 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4072
4073 if (do_segments)
4074 printf (_("\n [Requesting program interpreter: %s]"),
4075 program_interpreter);
4076 }
4077 break;
4078 }
4079
4080 if (do_segments)
4081 putc ('\n', stdout);
4082 }
4083
c256ffe7 4084 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4085 {
4086 printf (_("\n Section to Segment mapping:\n"));
4087 printf (_(" Segment Sections...\n"));
4088
252b5132
RH
4089 for (i = 0; i < elf_header.e_phnum; i++)
4090 {
9ad5cbcf 4091 unsigned int j;
2cf0635d 4092 Elf_Internal_Shdr * section;
252b5132
RH
4093
4094 segment = program_headers + i;
b391a3e3 4095 section = section_headers + 1;
252b5132
RH
4096
4097 printf (" %2.2d ", i);
4098
b34976b6 4099 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4100 {
f4638467
AM
4101 if (!ELF_TBSS_SPECIAL (section, segment)
4102 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
4103 printf ("%s ", SECTION_NAME (section));
4104 }
4105
4106 putc ('\n',stdout);
4107 }
4108 }
4109
252b5132
RH
4110 return 1;
4111}
4112
4113
d93f0186
NC
4114/* Find the file offset corresponding to VMA by using the program headers. */
4115
4116static long
2cf0635d 4117offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4118{
2cf0635d 4119 Elf_Internal_Phdr * seg;
d93f0186
NC
4120
4121 if (! get_program_headers (file))
4122 {
4123 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4124 return (long) vma;
4125 }
4126
4127 for (seg = program_headers;
4128 seg < program_headers + elf_header.e_phnum;
4129 ++seg)
4130 {
4131 if (seg->p_type != PT_LOAD)
4132 continue;
4133
4134 if (vma >= (seg->p_vaddr & -seg->p_align)
4135 && vma + size <= seg->p_vaddr + seg->p_filesz)
4136 return vma - seg->p_vaddr + seg->p_offset;
4137 }
4138
4139 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4140 (unsigned long) vma);
d93f0186
NC
4141 return (long) vma;
4142}
4143
4144
252b5132 4145static int
2cf0635d 4146get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 4147{
2cf0635d
NC
4148 Elf32_External_Shdr * shdrs;
4149 Elf_Internal_Shdr * internal;
b34976b6 4150 unsigned int i;
252b5132 4151
3f5e193b
NC
4152 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4153 elf_header.e_shentsize, num,
4154 _("section headers"));
a6e9f9df
AM
4155 if (!shdrs)
4156 return 0;
252b5132 4157
3f5e193b
NC
4158 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4159 sizeof (Elf_Internal_Shdr));
252b5132
RH
4160
4161 if (section_headers == NULL)
4162 {
4163 error (_("Out of memory\n"));
4164 return 0;
4165 }
4166
4167 for (i = 0, internal = section_headers;
560f3c1c 4168 i < num;
b34976b6 4169 i++, internal++)
252b5132
RH
4170 {
4171 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4172 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4173 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4174 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4175 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4176 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4177 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4178 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4179 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4180 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4181 }
4182
4183 free (shdrs);
4184
4185 return 1;
4186}
4187
9ea033b2 4188static int
2cf0635d 4189get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4190{
2cf0635d
NC
4191 Elf64_External_Shdr * shdrs;
4192 Elf_Internal_Shdr * internal;
b34976b6 4193 unsigned int i;
9ea033b2 4194
3f5e193b
NC
4195 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4196 elf_header.e_shentsize, num,
4197 _("section headers"));
a6e9f9df
AM
4198 if (!shdrs)
4199 return 0;
9ea033b2 4200
3f5e193b
NC
4201 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4202 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4203
4204 if (section_headers == NULL)
4205 {
4206 error (_("Out of memory\n"));
4207 return 0;
4208 }
4209
4210 for (i = 0, internal = section_headers;
560f3c1c 4211 i < num;
b34976b6 4212 i++, internal++)
9ea033b2
NC
4213 {
4214 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4215 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4216 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4217 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4218 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4219 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4220 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4221 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4222 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4223 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4224 }
4225
4226 free (shdrs);
4227
4228 return 1;
4229}
4230
252b5132 4231static Elf_Internal_Sym *
ba5cdace
NC
4232get_32bit_elf_symbols (FILE * file,
4233 Elf_Internal_Shdr * section,
4234 unsigned long * num_syms_return)
252b5132 4235{
ba5cdace 4236 unsigned long number = 0;
dd24e3da 4237 Elf32_External_Sym * esyms = NULL;
ba5cdace 4238 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4239 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4240 Elf_Internal_Sym * psym;
b34976b6 4241 unsigned int j;
252b5132 4242
dd24e3da
NC
4243 /* Run some sanity checks first. */
4244 if (section->sh_entsize == 0)
4245 {
4246 error (_("sh_entsize is zero\n"));
ba5cdace 4247 goto exit_point;
dd24e3da
NC
4248 }
4249
4250 number = section->sh_size / section->sh_entsize;
4251
4252 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4253 {
4254 error (_("Invalid sh_entsize\n"));
ba5cdace 4255 goto exit_point;
dd24e3da
NC
4256 }
4257
3f5e193b
NC
4258 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4259 section->sh_size, _("symbols"));
dd24e3da 4260 if (esyms == NULL)
ba5cdace 4261 goto exit_point;
252b5132 4262
9ad5cbcf
AM
4263 shndx = NULL;
4264 if (symtab_shndx_hdr != NULL
4265 && (symtab_shndx_hdr->sh_link
4fbb74a6 4266 == (unsigned long) (section - section_headers)))
9ad5cbcf 4267 {
3f5e193b
NC
4268 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4269 symtab_shndx_hdr->sh_offset,
4270 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4271 _("symbol table section indicies"));
dd24e3da
NC
4272 if (shndx == NULL)
4273 goto exit_point;
9ad5cbcf
AM
4274 }
4275
3f5e193b 4276 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4277
4278 if (isyms == NULL)
4279 {
4280 error (_("Out of memory\n"));
dd24e3da 4281 goto exit_point;
252b5132
RH
4282 }
4283
dd24e3da 4284 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4285 {
4286 psym->st_name = BYTE_GET (esyms[j].st_name);
4287 psym->st_value = BYTE_GET (esyms[j].st_value);
4288 psym->st_size = BYTE_GET (esyms[j].st_size);
4289 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4290 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4291 psym->st_shndx
4292 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4293 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4294 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4295 psym->st_info = BYTE_GET (esyms[j].st_info);
4296 psym->st_other = BYTE_GET (esyms[j].st_other);
4297 }
4298
dd24e3da 4299 exit_point:
ba5cdace 4300 if (shndx != NULL)
9ad5cbcf 4301 free (shndx);
ba5cdace 4302 if (esyms != NULL)
dd24e3da 4303 free (esyms);
252b5132 4304
ba5cdace
NC
4305 if (num_syms_return != NULL)
4306 * num_syms_return = isyms == NULL ? 0 : number;
4307
252b5132
RH
4308 return isyms;
4309}
4310
9ea033b2 4311static Elf_Internal_Sym *
ba5cdace
NC
4312get_64bit_elf_symbols (FILE * file,
4313 Elf_Internal_Shdr * section,
4314 unsigned long * num_syms_return)
9ea033b2 4315{
ba5cdace
NC
4316 unsigned long number = 0;
4317 Elf64_External_Sym * esyms = NULL;
4318 Elf_External_Sym_Shndx * shndx = NULL;
4319 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4320 Elf_Internal_Sym * psym;
b34976b6 4321 unsigned int j;
9ea033b2 4322
dd24e3da
NC
4323 /* Run some sanity checks first. */
4324 if (section->sh_entsize == 0)
4325 {
4326 error (_("sh_entsize is zero\n"));
ba5cdace 4327 goto exit_point;
dd24e3da
NC
4328 }
4329
4330 number = section->sh_size / section->sh_entsize;
4331
4332 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4333 {
4334 error (_("Invalid sh_entsize\n"));
ba5cdace 4335 goto exit_point;
dd24e3da
NC
4336 }
4337
3f5e193b
NC
4338 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4339 section->sh_size, _("symbols"));
a6e9f9df 4340 if (!esyms)
ba5cdace 4341 goto exit_point;
9ea033b2 4342
9ad5cbcf
AM
4343 if (symtab_shndx_hdr != NULL
4344 && (symtab_shndx_hdr->sh_link
4fbb74a6 4345 == (unsigned long) (section - section_headers)))
9ad5cbcf 4346 {
3f5e193b
NC
4347 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4348 symtab_shndx_hdr->sh_offset,
4349 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4350 _("symbol table section indicies"));
ba5cdace
NC
4351 if (shndx == NULL)
4352 goto exit_point;
9ad5cbcf
AM
4353 }
4354
3f5e193b 4355 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4356
4357 if (isyms == NULL)
4358 {
4359 error (_("Out of memory\n"));
ba5cdace 4360 goto exit_point;
9ea033b2
NC
4361 }
4362
ba5cdace 4363 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4364 {
4365 psym->st_name = BYTE_GET (esyms[j].st_name);
4366 psym->st_info = BYTE_GET (esyms[j].st_info);
4367 psym->st_other = BYTE_GET (esyms[j].st_other);
4368 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4369
4fbb74a6 4370 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4371 psym->st_shndx
4372 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4373 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4374 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4375
66543521
AM
4376 psym->st_value = BYTE_GET (esyms[j].st_value);
4377 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4378 }
4379
ba5cdace
NC
4380 exit_point:
4381 if (shndx != NULL)
9ad5cbcf 4382 free (shndx);
ba5cdace
NC
4383 if (esyms != NULL)
4384 free (esyms);
4385
4386 if (num_syms_return != NULL)
4387 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4388
4389 return isyms;
4390}
4391
d1133906 4392static const char *
d3ba0551 4393get_elf_section_flags (bfd_vma sh_flags)
d1133906 4394{
5477e8a0 4395 static char buff[1024];
2cf0635d 4396 char * p = buff;
8d5ff12c 4397 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4398 int sindex;
4399 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4400 bfd_vma os_flags = 0;
4401 bfd_vma proc_flags = 0;
4402 bfd_vma unknown_flags = 0;
148b93f2 4403 static const struct
5477e8a0 4404 {
2cf0635d 4405 const char * str;
5477e8a0
L
4406 int len;
4407 }
4408 flags [] =
4409 {
cfcac11d
NC
4410 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4411 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4412 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4413 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4414 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4415 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4416 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4417 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4418 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4419 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4420 /* IA-64 specific. */
4421 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4422 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4423 /* IA-64 OpenVMS specific. */
4424 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4425 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4426 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4427 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4428 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4429 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4430 /* Generic. */
cfcac11d 4431 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4432 /* SPARC specific. */
cfcac11d 4433 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4434 };
4435
4436 if (do_section_details)
4437 {
8d5ff12c
L
4438 sprintf (buff, "[%*.*lx]: ",
4439 field_size, field_size, (unsigned long) sh_flags);
4440 p += field_size + 4;
5477e8a0 4441 }
76da6bbe 4442
d1133906
NC
4443 while (sh_flags)
4444 {
4445 bfd_vma flag;
4446
4447 flag = sh_flags & - sh_flags;
4448 sh_flags &= ~ flag;
76da6bbe 4449
5477e8a0 4450 if (do_section_details)
d1133906 4451 {
5477e8a0
L
4452 switch (flag)
4453 {
91d6fa6a
NC
4454 case SHF_WRITE: sindex = 0; break;
4455 case SHF_ALLOC: sindex = 1; break;
4456 case SHF_EXECINSTR: sindex = 2; break;
4457 case SHF_MERGE: sindex = 3; break;
4458 case SHF_STRINGS: sindex = 4; break;
4459 case SHF_INFO_LINK: sindex = 5; break;
4460 case SHF_LINK_ORDER: sindex = 6; break;
4461 case SHF_OS_NONCONFORMING: sindex = 7; break;
4462 case SHF_GROUP: sindex = 8; break;
4463 case SHF_TLS: sindex = 9; break;
18ae9cc1 4464 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4465
5477e8a0 4466 default:
91d6fa6a 4467 sindex = -1;
cfcac11d 4468 switch (elf_header.e_machine)
148b93f2 4469 {
cfcac11d 4470 case EM_IA_64:
148b93f2 4471 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4472 sindex = 10;
148b93f2 4473 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4474 sindex = 11;
148b93f2
NC
4475#ifdef BFD64
4476 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4477 switch (flag)
4478 {
91d6fa6a
NC
4479 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4480 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4481 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4482 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4483 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4484 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4485 default: break;
4486 }
4487#endif
cfcac11d
NC
4488 break;
4489
caa83f8b
NC
4490 case EM_386:
4491 case EM_486:
4492 case EM_X86_64:
7f502d6c 4493 case EM_L1OM:
7a9068fe 4494 case EM_K1OM:
cfcac11d
NC
4495 case EM_OLD_SPARCV9:
4496 case EM_SPARC32PLUS:
4497 case EM_SPARCV9:
4498 case EM_SPARC:
18ae9cc1 4499 if (flag == SHF_ORDERED)
91d6fa6a 4500 sindex = 19;
cfcac11d
NC
4501 break;
4502 default:
4503 break;
148b93f2 4504 }
5477e8a0
L
4505 }
4506
91d6fa6a 4507 if (sindex != -1)
5477e8a0 4508 {
8d5ff12c
L
4509 if (p != buff + field_size + 4)
4510 {
4511 if (size < (10 + 2))
4512 abort ();
4513 size -= 2;
4514 *p++ = ',';
4515 *p++ = ' ';
4516 }
4517
91d6fa6a
NC
4518 size -= flags [sindex].len;
4519 p = stpcpy (p, flags [sindex].str);
5477e8a0 4520 }
3b22753a 4521 else if (flag & SHF_MASKOS)
8d5ff12c 4522 os_flags |= flag;
d1133906 4523 else if (flag & SHF_MASKPROC)
8d5ff12c 4524 proc_flags |= flag;
d1133906 4525 else
8d5ff12c 4526 unknown_flags |= flag;
5477e8a0
L
4527 }
4528 else
4529 {
4530 switch (flag)
4531 {
4532 case SHF_WRITE: *p = 'W'; break;
4533 case SHF_ALLOC: *p = 'A'; break;
4534 case SHF_EXECINSTR: *p = 'X'; break;
4535 case SHF_MERGE: *p = 'M'; break;
4536 case SHF_STRINGS: *p = 'S'; break;
4537 case SHF_INFO_LINK: *p = 'I'; break;
4538 case SHF_LINK_ORDER: *p = 'L'; break;
4539 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4540 case SHF_GROUP: *p = 'G'; break;
4541 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4542 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4543
4544 default:
8a9036a4 4545 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4546 || elf_header.e_machine == EM_L1OM
4547 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4548 && flag == SHF_X86_64_LARGE)
4549 *p = 'l';
4550 else if (flag & SHF_MASKOS)
4551 {
4552 *p = 'o';
4553 sh_flags &= ~ SHF_MASKOS;
4554 }
4555 else if (flag & SHF_MASKPROC)
4556 {
4557 *p = 'p';
4558 sh_flags &= ~ SHF_MASKPROC;
4559 }
4560 else
4561 *p = 'x';
4562 break;
4563 }
4564 p++;
d1133906
NC
4565 }
4566 }
76da6bbe 4567
8d5ff12c
L
4568 if (do_section_details)
4569 {
4570 if (os_flags)
4571 {
4572 size -= 5 + field_size;
4573 if (p != buff + field_size + 4)
4574 {
4575 if (size < (2 + 1))
4576 abort ();
4577 size -= 2;
4578 *p++ = ',';
4579 *p++ = ' ';
4580 }
4581 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4582 (unsigned long) os_flags);
4583 p += 5 + field_size;
4584 }
4585 if (proc_flags)
4586 {
4587 size -= 7 + field_size;
4588 if (p != buff + field_size + 4)
4589 {
4590 if (size < (2 + 1))
4591 abort ();
4592 size -= 2;
4593 *p++ = ',';
4594 *p++ = ' ';
4595 }
4596 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4597 (unsigned long) proc_flags);
4598 p += 7 + field_size;
4599 }
4600 if (unknown_flags)
4601 {
4602 size -= 10 + field_size;
4603 if (p != buff + field_size + 4)
4604 {
4605 if (size < (2 + 1))
4606 abort ();
4607 size -= 2;
4608 *p++ = ',';
4609 *p++ = ' ';
4610 }
2b692964 4611 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4612 (unsigned long) unknown_flags);
4613 p += 10 + field_size;
4614 }
4615 }
4616
e9e44622 4617 *p = '\0';
d1133906
NC
4618 return buff;
4619}
4620
252b5132 4621static int
2cf0635d 4622process_section_headers (FILE * file)
252b5132 4623{
2cf0635d 4624 Elf_Internal_Shdr * section;
b34976b6 4625 unsigned int i;
252b5132
RH
4626
4627 section_headers = NULL;
4628
4629 if (elf_header.e_shnum == 0)
4630 {
82f2dbf7
NC
4631 /* PR binutils/12467. */
4632 if (elf_header.e_shoff != 0)
4633 warn (_("possibly corrupt ELF file header - it has a non-zero"
4634 " section header offset, but no section headers\n"));
4635 else if (do_sections)
252b5132
RH
4636 printf (_("\nThere are no sections in this file.\n"));
4637
4638 return 1;
4639 }
4640
4641 if (do_sections && !do_header)
9ea033b2 4642 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4643 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4644
9ea033b2
NC
4645 if (is_32bit_elf)
4646 {
560f3c1c 4647 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4648 return 0;
4649 }
560f3c1c 4650 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4651 return 0;
4652
4653 /* Read in the string table, so that we have names to display. */
0b49d371 4654 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4655 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4656 {
4fbb74a6 4657 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4658
c256ffe7
JJ
4659 if (section->sh_size != 0)
4660 {
3f5e193b
NC
4661 string_table = (char *) get_data (NULL, file, section->sh_offset,
4662 1, section->sh_size,
4663 _("string table"));
0de14b54 4664
c256ffe7
JJ
4665 string_table_length = string_table != NULL ? section->sh_size : 0;
4666 }
252b5132
RH
4667 }
4668
4669 /* Scan the sections for the dynamic symbol table
e3c8793a 4670 and dynamic string table and debug sections. */
252b5132
RH
4671 dynamic_symbols = NULL;
4672 dynamic_strings = NULL;
4673 dynamic_syminfo = NULL;
f1ef08cb 4674 symtab_shndx_hdr = NULL;
103f02d3 4675
89fac5e3
RS
4676 eh_addr_size = is_32bit_elf ? 4 : 8;
4677 switch (elf_header.e_machine)
4678 {
4679 case EM_MIPS:
4680 case EM_MIPS_RS3_LE:
4681 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4682 FDE addresses. However, the ABI also has a semi-official ILP32
4683 variant for which the normal FDE address size rules apply.
4684
4685 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4686 section, where XX is the size of longs in bits. Unfortunately,
4687 earlier compilers provided no way of distinguishing ILP32 objects
4688 from LP64 objects, so if there's any doubt, we should assume that
4689 the official LP64 form is being used. */
4690 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4691 && find_section (".gcc_compiled_long32") == NULL)
4692 eh_addr_size = 8;
4693 break;
0f56a26a
DD
4694
4695 case EM_H8_300:
4696 case EM_H8_300H:
4697 switch (elf_header.e_flags & EF_H8_MACH)
4698 {
4699 case E_H8_MACH_H8300:
4700 case E_H8_MACH_H8300HN:
4701 case E_H8_MACH_H8300SN:
4702 case E_H8_MACH_H8300SXN:
4703 eh_addr_size = 2;
4704 break;
4705 case E_H8_MACH_H8300H:
4706 case E_H8_MACH_H8300S:
4707 case E_H8_MACH_H8300SX:
4708 eh_addr_size = 4;
4709 break;
4710 }
f4236fe4
DD
4711 break;
4712
ff7eeb89 4713 case EM_M32C_OLD:
f4236fe4
DD
4714 case EM_M32C:
4715 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4716 {
4717 case EF_M32C_CPU_M16C:
4718 eh_addr_size = 2;
4719 break;
4720 }
4721 break;
89fac5e3
RS
4722 }
4723
08d8fa11
JJ
4724#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4725 do \
4726 { \
4727 size_t expected_entsize \
4728 = is_32bit_elf ? size32 : size64; \
4729 if (section->sh_entsize != expected_entsize) \
4730 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4731 i, (unsigned long int) section->sh_entsize, \
4732 (unsigned long int) expected_entsize); \
4733 section->sh_entsize = expected_entsize; \
4734 } \
4735 while (0)
4736#define CHECK_ENTSIZE(section, i, type) \
4737 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4738 sizeof (Elf64_External_##type))
4739
252b5132
RH
4740 for (i = 0, section = section_headers;
4741 i < elf_header.e_shnum;
b34976b6 4742 i++, section++)
252b5132 4743 {
2cf0635d 4744 char * name = SECTION_NAME (section);
252b5132
RH
4745
4746 if (section->sh_type == SHT_DYNSYM)
4747 {
4748 if (dynamic_symbols != NULL)
4749 {
4750 error (_("File contains multiple dynamic symbol tables\n"));
4751 continue;
4752 }
4753
08d8fa11 4754 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 4755 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
4756 }
4757 else if (section->sh_type == SHT_STRTAB
18bd398b 4758 && streq (name, ".dynstr"))
252b5132
RH
4759 {
4760 if (dynamic_strings != NULL)
4761 {
4762 error (_("File contains multiple dynamic string tables\n"));
4763 continue;
4764 }
4765
3f5e193b
NC
4766 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4767 1, section->sh_size,
4768 _("dynamic strings"));
59245841 4769 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4770 }
9ad5cbcf
AM
4771 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4772 {
4773 if (symtab_shndx_hdr != NULL)
4774 {
4775 error (_("File contains multiple symtab shndx tables\n"));
4776 continue;
4777 }
4778 symtab_shndx_hdr = section;
4779 }
08d8fa11
JJ
4780 else if (section->sh_type == SHT_SYMTAB)
4781 CHECK_ENTSIZE (section, i, Sym);
4782 else if (section->sh_type == SHT_GROUP)
4783 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4784 else if (section->sh_type == SHT_REL)
4785 CHECK_ENTSIZE (section, i, Rel);
4786 else if (section->sh_type == SHT_RELA)
4787 CHECK_ENTSIZE (section, i, Rela);
252b5132 4788 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4789 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4790 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
4791 || do_debug_str || do_debug_loc || do_debug_ranges
4792 || do_debug_addr || do_debug_cu_index)
1b315056
CS
4793 && (const_strneq (name, ".debug_")
4794 || const_strneq (name, ".zdebug_")))
252b5132 4795 {
1b315056
CS
4796 if (name[1] == 'z')
4797 name += sizeof (".zdebug_") - 1;
4798 else
4799 name += sizeof (".debug_") - 1;
252b5132
RH
4800
4801 if (do_debugging
4723351a
CC
4802 || (do_debug_info && const_strneq (name, "info"))
4803 || (do_debug_info && const_strneq (name, "types"))
4804 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
4805 || (do_debug_lines && const_strneq (name, "line"))
4806 || (do_debug_pubnames && const_strneq (name, "pubnames"))
4807 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
4808 || (do_debug_aranges && const_strneq (name, "aranges"))
4809 || (do_debug_ranges && const_strneq (name, "ranges"))
4810 || (do_debug_frames && const_strneq (name, "frame"))
4811 || (do_debug_macinfo && const_strneq (name, "macinfo"))
4812 || (do_debug_macinfo && const_strneq (name, "macro"))
4813 || (do_debug_str && const_strneq (name, "str"))
4814 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
4815 || (do_debug_addr && const_strneq (name, "addr"))
4816 || (do_debug_cu_index && const_strneq (name, "cu_index"))
4817 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 4818 )
09c11c86 4819 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4820 }
a262ae96 4821 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4822 else if ((do_debugging || do_debug_info)
0112cd26 4823 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4824 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4825 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4826 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4827 else if (do_gdb_index && streq (name, ".gdb_index"))
4828 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4829 /* Trace sections for Itanium VMS. */
4830 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4831 || do_trace_aranges)
4832 && const_strneq (name, ".trace_"))
4833 {
4834 name += sizeof (".trace_") - 1;
4835
4836 if (do_debugging
4837 || (do_trace_info && streq (name, "info"))
4838 || (do_trace_abbrevs && streq (name, "abbrev"))
4839 || (do_trace_aranges && streq (name, "aranges"))
4840 )
4841 request_dump_bynumber (i, DEBUG_DUMP);
4842 }
4843
252b5132
RH
4844 }
4845
4846 if (! do_sections)
4847 return 1;
4848
3a1a2036
NC
4849 if (elf_header.e_shnum > 1)
4850 printf (_("\nSection Headers:\n"));
4851 else
4852 printf (_("\nSection Header:\n"));
76da6bbe 4853
f7a99963 4854 if (is_32bit_elf)
595cf52e 4855 {
5477e8a0 4856 if (do_section_details)
595cf52e
L
4857 {
4858 printf (_(" [Nr] Name\n"));
5477e8a0 4859 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4860 }
4861 else
4862 printf
4863 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4864 }
d974e256 4865 else if (do_wide)
595cf52e 4866 {
5477e8a0 4867 if (do_section_details)
595cf52e
L
4868 {
4869 printf (_(" [Nr] Name\n"));
5477e8a0 4870 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4871 }
4872 else
4873 printf
4874 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4875 }
f7a99963
NC
4876 else
4877 {
5477e8a0 4878 if (do_section_details)
595cf52e
L
4879 {
4880 printf (_(" [Nr] Name\n"));
5477e8a0
L
4881 printf (_(" Type Address Offset Link\n"));
4882 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4883 }
4884 else
4885 {
4886 printf (_(" [Nr] Name Type Address Offset\n"));
4887 printf (_(" Size EntSize Flags Link Info Align\n"));
4888 }
f7a99963 4889 }
252b5132 4890
5477e8a0
L
4891 if (do_section_details)
4892 printf (_(" Flags\n"));
4893
252b5132
RH
4894 for (i = 0, section = section_headers;
4895 i < elf_header.e_shnum;
b34976b6 4896 i++, section++)
252b5132 4897 {
7bfd842d 4898 printf (" [%2u] ", i);
5477e8a0 4899 if (do_section_details)
595cf52e 4900 {
7bfd842d 4901 print_symbol (INT_MAX, SECTION_NAME (section));
ea52a088 4902 printf ("\n ");
595cf52e
L
4903 }
4904 else
7bfd842d
NC
4905 {
4906 print_symbol (-17, SECTION_NAME (section));
7bfd842d 4907 }
ea52a088
NC
4908
4909 printf (do_wide ? " %-15s " : " %-15.15s ",
4910 get_section_type_name (section->sh_type));
4911
f7a99963
NC
4912 if (is_32bit_elf)
4913 {
cfcac11d
NC
4914 const char * link_too_big = NULL;
4915
f7a99963 4916 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4917
f7a99963
NC
4918 printf ( " %6.6lx %6.6lx %2.2lx",
4919 (unsigned long) section->sh_offset,
4920 (unsigned long) section->sh_size,
4921 (unsigned long) section->sh_entsize);
d1133906 4922
5477e8a0
L
4923 if (do_section_details)
4924 fputs (" ", stdout);
4925 else
4926 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4927
cfcac11d
NC
4928 if (section->sh_link >= elf_header.e_shnum)
4929 {
4930 link_too_big = "";
4931 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4932 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4933 switch (elf_header.e_machine)
4934 {
caa83f8b
NC
4935 case EM_386:
4936 case EM_486:
4937 case EM_X86_64:
7f502d6c 4938 case EM_L1OM:
7a9068fe 4939 case EM_K1OM:
cfcac11d
NC
4940 case EM_OLD_SPARCV9:
4941 case EM_SPARC32PLUS:
4942 case EM_SPARCV9:
4943 case EM_SPARC:
4944 if (section->sh_link == (SHN_BEFORE & 0xffff))
4945 link_too_big = "BEFORE";
4946 else if (section->sh_link == (SHN_AFTER & 0xffff))
4947 link_too_big = "AFTER";
4948 break;
4949 default:
4950 break;
4951 }
4952 }
4953
4954 if (do_section_details)
4955 {
4956 if (link_too_big != NULL && * link_too_big)
4957 printf ("<%s> ", link_too_big);
4958 else
4959 printf ("%2u ", section->sh_link);
4960 printf ("%3u %2lu\n", section->sh_info,
4961 (unsigned long) section->sh_addralign);
4962 }
4963 else
4964 printf ("%2u %3u %2lu\n",
4965 section->sh_link,
4966 section->sh_info,
4967 (unsigned long) section->sh_addralign);
4968
4969 if (link_too_big && ! * link_too_big)
4970 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4971 i, section->sh_link);
f7a99963 4972 }
d974e256
JJ
4973 else if (do_wide)
4974 {
4975 print_vma (section->sh_addr, LONG_HEX);
4976
4977 if ((long) section->sh_offset == section->sh_offset)
4978 printf (" %6.6lx", (unsigned long) section->sh_offset);
4979 else
4980 {
4981 putchar (' ');
4982 print_vma (section->sh_offset, LONG_HEX);
4983 }
4984
4985 if ((unsigned long) section->sh_size == section->sh_size)
4986 printf (" %6.6lx", (unsigned long) section->sh_size);
4987 else
4988 {
4989 putchar (' ');
4990 print_vma (section->sh_size, LONG_HEX);
4991 }
4992
4993 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4994 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4995 else
4996 {
4997 putchar (' ');
4998 print_vma (section->sh_entsize, LONG_HEX);
4999 }
5000
5477e8a0
L
5001 if (do_section_details)
5002 fputs (" ", stdout);
5003 else
5004 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5005
72de5009 5006 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5007
5008 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5009 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5010 else
5011 {
5012 print_vma (section->sh_addralign, DEC);
5013 putchar ('\n');
5014 }
5015 }
5477e8a0 5016 else if (do_section_details)
595cf52e 5017 {
5477e8a0 5018 printf (" %-15.15s ",
595cf52e 5019 get_section_type_name (section->sh_type));
595cf52e
L
5020 print_vma (section->sh_addr, LONG_HEX);
5021 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5022 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5023 else
5024 {
5025 printf (" ");
5026 print_vma (section->sh_offset, LONG_HEX);
5027 }
72de5009 5028 printf (" %u\n ", section->sh_link);
595cf52e 5029 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5030 putchar (' ');
595cf52e
L
5031 print_vma (section->sh_entsize, LONG_HEX);
5032
72de5009
AM
5033 printf (" %-16u %lu\n",
5034 section->sh_info,
595cf52e
L
5035 (unsigned long) section->sh_addralign);
5036 }
f7a99963
NC
5037 else
5038 {
5039 putchar (' ');
5040 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5041 if ((long) section->sh_offset == section->sh_offset)
5042 printf (" %8.8lx", (unsigned long) section->sh_offset);
5043 else
5044 {
5045 printf (" ");
5046 print_vma (section->sh_offset, LONG_HEX);
5047 }
f7a99963
NC
5048 printf ("\n ");
5049 print_vma (section->sh_size, LONG_HEX);
5050 printf (" ");
5051 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5052
d1133906 5053 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5054
72de5009
AM
5055 printf (" %2u %3u %lu\n",
5056 section->sh_link,
5057 section->sh_info,
f7a99963
NC
5058 (unsigned long) section->sh_addralign);
5059 }
5477e8a0
L
5060
5061 if (do_section_details)
5062 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5063 }
5064
5477e8a0 5065 if (!do_section_details)
3dbcc61d
NC
5066 {
5067 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5068 || elf_header.e_machine == EM_L1OM
5069 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5070 printf (_("Key to Flags:\n\
5071 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5072 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5073 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5074 else
5075 printf (_("Key to Flags:\n\
e3c8793a 5076 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5077 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5078 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 5079 }
d1133906 5080
252b5132
RH
5081 return 1;
5082}
5083
f5842774
L
5084static const char *
5085get_group_flags (unsigned int flags)
5086{
5087 static char buff[32];
5088 switch (flags)
5089 {
220453ec
AM
5090 case 0:
5091 return "";
5092
f5842774 5093 case GRP_COMDAT:
220453ec 5094 return "COMDAT ";
f5842774
L
5095
5096 default:
220453ec 5097 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5098 break;
5099 }
5100 return buff;
5101}
5102
5103static int
2cf0635d 5104process_section_groups (FILE * file)
f5842774 5105{
2cf0635d 5106 Elf_Internal_Shdr * section;
f5842774 5107 unsigned int i;
2cf0635d
NC
5108 struct group * group;
5109 Elf_Internal_Shdr * symtab_sec;
5110 Elf_Internal_Shdr * strtab_sec;
5111 Elf_Internal_Sym * symtab;
ba5cdace 5112 unsigned long num_syms;
2cf0635d 5113 char * strtab;
c256ffe7 5114 size_t strtab_size;
d1f5c6e3
L
5115
5116 /* Don't process section groups unless needed. */
5117 if (!do_unwind && !do_section_groups)
5118 return 1;
f5842774
L
5119
5120 if (elf_header.e_shnum == 0)
5121 {
5122 if (do_section_groups)
82f2dbf7 5123 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5124
5125 return 1;
5126 }
5127
5128 if (section_headers == NULL)
5129 {
5130 error (_("Section headers are not available!\n"));
fa1908fd
NC
5131 /* PR 13622: This can happen with a corrupt ELF header. */
5132 return 0;
f5842774
L
5133 }
5134
3f5e193b
NC
5135 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5136 sizeof (struct group *));
e4b17d5c
L
5137
5138 if (section_headers_groups == NULL)
5139 {
5140 error (_("Out of memory\n"));
5141 return 0;
5142 }
5143
f5842774 5144 /* Scan the sections for the group section. */
d1f5c6e3 5145 group_count = 0;
f5842774
L
5146 for (i = 0, section = section_headers;
5147 i < elf_header.e_shnum;
5148 i++, section++)
e4b17d5c
L
5149 if (section->sh_type == SHT_GROUP)
5150 group_count++;
5151
d1f5c6e3
L
5152 if (group_count == 0)
5153 {
5154 if (do_section_groups)
5155 printf (_("\nThere are no section groups in this file.\n"));
5156
5157 return 1;
5158 }
5159
3f5e193b 5160 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5161
5162 if (section_groups == NULL)
5163 {
5164 error (_("Out of memory\n"));
5165 return 0;
5166 }
5167
d1f5c6e3
L
5168 symtab_sec = NULL;
5169 strtab_sec = NULL;
5170 symtab = NULL;
ba5cdace 5171 num_syms = 0;
d1f5c6e3 5172 strtab = NULL;
c256ffe7 5173 strtab_size = 0;
e4b17d5c
L
5174 for (i = 0, section = section_headers, group = section_groups;
5175 i < elf_header.e_shnum;
5176 i++, section++)
f5842774
L
5177 {
5178 if (section->sh_type == SHT_GROUP)
5179 {
2cf0635d
NC
5180 char * name = SECTION_NAME (section);
5181 char * group_name;
5182 unsigned char * start;
5183 unsigned char * indices;
f5842774 5184 unsigned int entry, j, size;
2cf0635d
NC
5185 Elf_Internal_Shdr * sec;
5186 Elf_Internal_Sym * sym;
f5842774
L
5187
5188 /* Get the symbol table. */
4fbb74a6
AM
5189 if (section->sh_link >= elf_header.e_shnum
5190 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5191 != SHT_SYMTAB))
f5842774
L
5192 {
5193 error (_("Bad sh_link in group section `%s'\n"), name);
5194 continue;
5195 }
d1f5c6e3
L
5196
5197 if (symtab_sec != sec)
5198 {
5199 symtab_sec = sec;
5200 if (symtab)
5201 free (symtab);
ba5cdace 5202 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5203 }
f5842774 5204
dd24e3da
NC
5205 if (symtab == NULL)
5206 {
5207 error (_("Corrupt header in group section `%s'\n"), name);
5208 continue;
5209 }
5210
ba5cdace
NC
5211 if (section->sh_info >= num_syms)
5212 {
5213 error (_("Bad sh_info in group section `%s'\n"), name);
5214 continue;
5215 }
5216
f5842774
L
5217 sym = symtab + section->sh_info;
5218
5219 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5220 {
4fbb74a6
AM
5221 if (sym->st_shndx == 0
5222 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5223 {
5224 error (_("Bad sh_info in group section `%s'\n"), name);
5225 continue;
5226 }
ba2685cc 5227
4fbb74a6 5228 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5229 strtab_sec = NULL;
5230 if (strtab)
5231 free (strtab);
f5842774 5232 strtab = NULL;
c256ffe7 5233 strtab_size = 0;
f5842774
L
5234 }
5235 else
5236 {
5237 /* Get the string table. */
4fbb74a6 5238 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5239 {
5240 strtab_sec = NULL;
5241 if (strtab)
5242 free (strtab);
5243 strtab = NULL;
5244 strtab_size = 0;
5245 }
5246 else if (strtab_sec
4fbb74a6 5247 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5248 {
5249 strtab_sec = sec;
5250 if (strtab)
5251 free (strtab);
3f5e193b
NC
5252 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5253 1, strtab_sec->sh_size,
5254 _("string table"));
c256ffe7 5255 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5256 }
c256ffe7 5257 group_name = sym->st_name < strtab_size
2b692964 5258 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5259 }
5260
3f5e193b
NC
5261 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5262 1, section->sh_size,
5263 _("section data"));
59245841
NC
5264 if (start == NULL)
5265 continue;
f5842774
L
5266
5267 indices = start;
5268 size = (section->sh_size / section->sh_entsize) - 1;
5269 entry = byte_get (indices, 4);
5270 indices += 4;
e4b17d5c
L
5271
5272 if (do_section_groups)
5273 {
2b692964 5274 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5275 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5276
e4b17d5c
L
5277 printf (_(" [Index] Name\n"));
5278 }
5279
5280 group->group_index = i;
5281
f5842774
L
5282 for (j = 0; j < size; j++)
5283 {
2cf0635d 5284 struct group_list * g;
e4b17d5c 5285
f5842774
L
5286 entry = byte_get (indices, 4);
5287 indices += 4;
5288
4fbb74a6 5289 if (entry >= elf_header.e_shnum)
391cb864
L
5290 {
5291 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5292 entry, i, elf_header.e_shnum - 1);
5293 continue;
5294 }
391cb864 5295
4fbb74a6 5296 if (section_headers_groups [entry] != NULL)
e4b17d5c 5297 {
d1f5c6e3
L
5298 if (entry)
5299 {
391cb864
L
5300 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5301 entry, i,
4fbb74a6 5302 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5303 continue;
5304 }
5305 else
5306 {
5307 /* Intel C/C++ compiler may put section 0 in a
5308 section group. We just warn it the first time
5309 and ignore it afterwards. */
5310 static int warned = 0;
5311 if (!warned)
5312 {
5313 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5314 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5315 warned++;
5316 }
5317 }
e4b17d5c
L
5318 }
5319
4fbb74a6 5320 section_headers_groups [entry] = group;
e4b17d5c
L
5321
5322 if (do_section_groups)
5323 {
4fbb74a6 5324 sec = section_headers + entry;
c256ffe7 5325 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5326 }
5327
3f5e193b 5328 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5329 g->section_index = entry;
5330 g->next = group->root;
5331 group->root = g;
f5842774
L
5332 }
5333
f5842774
L
5334 if (start)
5335 free (start);
e4b17d5c
L
5336
5337 group++;
f5842774
L
5338 }
5339 }
5340
d1f5c6e3
L
5341 if (symtab)
5342 free (symtab);
5343 if (strtab)
5344 free (strtab);
f5842774
L
5345 return 1;
5346}
5347
28f997cf
TG
5348/* Data used to display dynamic fixups. */
5349
5350struct ia64_vms_dynfixup
5351{
5352 bfd_vma needed_ident; /* Library ident number. */
5353 bfd_vma needed; /* Index in the dstrtab of the library name. */
5354 bfd_vma fixup_needed; /* Index of the library. */
5355 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5356 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5357};
5358
5359/* Data used to display dynamic relocations. */
5360
5361struct ia64_vms_dynimgrela
5362{
5363 bfd_vma img_rela_cnt; /* Number of relocations. */
5364 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5365};
5366
5367/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5368 library). */
5369
5370static void
5371dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5372 const char *strtab, unsigned int strtab_sz)
5373{
5374 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5375 long i;
5376 const char *lib_name;
5377
5378 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5379 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5380 _("dynamic section image fixups"));
5381 if (!imfs)
5382 return;
5383
5384 if (fixup->needed < strtab_sz)
5385 lib_name = strtab + fixup->needed;
5386 else
5387 {
5388 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5389 (unsigned long) fixup->needed);
28f997cf
TG
5390 lib_name = "???";
5391 }
5392 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5393 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5394 printf
5395 (_("Seg Offset Type SymVec DataType\n"));
5396
5397 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5398 {
5399 unsigned int type;
5400 const char *rtype;
5401
5402 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5403 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5404 type = BYTE_GET (imfs [i].type);
5405 rtype = elf_ia64_reloc_type (type);
5406 if (rtype == NULL)
5407 printf (" 0x%08x ", type);
5408 else
5409 printf (" %-32s ", rtype);
5410 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5411 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5412 }
5413
5414 free (imfs);
5415}
5416
5417/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5418
5419static void
5420dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5421{
5422 Elf64_External_VMS_IMAGE_RELA *imrs;
5423 long i;
5424
5425 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5426 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5427 _("dynamic section image relocations"));
28f997cf
TG
5428 if (!imrs)
5429 return;
5430
5431 printf (_("\nImage relocs\n"));
5432 printf
5433 (_("Seg Offset Type Addend Seg Sym Off\n"));
5434
5435 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5436 {
5437 unsigned int type;
5438 const char *rtype;
5439
5440 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5441 printf ("%08" BFD_VMA_FMT "x ",
5442 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5443 type = BYTE_GET (imrs [i].type);
5444 rtype = elf_ia64_reloc_type (type);
5445 if (rtype == NULL)
5446 printf ("0x%08x ", type);
5447 else
5448 printf ("%-31s ", rtype);
5449 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5450 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5451 printf ("%08" BFD_VMA_FMT "x\n",
5452 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5453 }
5454
5455 free (imrs);
5456}
5457
5458/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5459
5460static int
5461process_ia64_vms_dynamic_relocs (FILE *file)
5462{
5463 struct ia64_vms_dynfixup fixup;
5464 struct ia64_vms_dynimgrela imgrela;
5465 Elf_Internal_Dyn *entry;
5466 int res = 0;
5467 bfd_vma strtab_off = 0;
5468 bfd_vma strtab_sz = 0;
5469 char *strtab = NULL;
5470
5471 memset (&fixup, 0, sizeof (fixup));
5472 memset (&imgrela, 0, sizeof (imgrela));
5473
5474 /* Note: the order of the entries is specified by the OpenVMS specs. */
5475 for (entry = dynamic_section;
5476 entry < dynamic_section + dynamic_nent;
5477 entry++)
5478 {
5479 switch (entry->d_tag)
5480 {
5481 case DT_IA_64_VMS_STRTAB_OFFSET:
5482 strtab_off = entry->d_un.d_val;
5483 break;
5484 case DT_STRSZ:
5485 strtab_sz = entry->d_un.d_val;
5486 if (strtab == NULL)
5487 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5488 1, strtab_sz, _("dynamic string section"));
5489 break;
5490
5491 case DT_IA_64_VMS_NEEDED_IDENT:
5492 fixup.needed_ident = entry->d_un.d_val;
5493 break;
5494 case DT_NEEDED:
5495 fixup.needed = entry->d_un.d_val;
5496 break;
5497 case DT_IA_64_VMS_FIXUP_NEEDED:
5498 fixup.fixup_needed = entry->d_un.d_val;
5499 break;
5500 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5501 fixup.fixup_rela_cnt = entry->d_un.d_val;
5502 break;
5503 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5504 fixup.fixup_rela_off = entry->d_un.d_val;
5505 res++;
5506 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5507 break;
5508
5509 case DT_IA_64_VMS_IMG_RELA_CNT:
5510 imgrela.img_rela_cnt = entry->d_un.d_val;
5511 break;
5512 case DT_IA_64_VMS_IMG_RELA_OFF:
5513 imgrela.img_rela_off = entry->d_un.d_val;
5514 res++;
5515 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5516 break;
5517
5518 default:
5519 break;
5520 }
5521 }
5522
5523 if (strtab != NULL)
5524 free (strtab);
5525
5526 return res;
5527}
5528
85b1c36d 5529static struct
566b0d53 5530{
2cf0635d 5531 const char * name;
566b0d53
L
5532 int reloc;
5533 int size;
5534 int rela;
5535} dynamic_relocations [] =
5536{
5537 { "REL", DT_REL, DT_RELSZ, FALSE },
5538 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5539 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5540};
5541
252b5132 5542/* Process the reloc section. */
18bd398b 5543
252b5132 5544static int
2cf0635d 5545process_relocs (FILE * file)
252b5132 5546{
b34976b6
AM
5547 unsigned long rel_size;
5548 unsigned long rel_offset;
252b5132
RH
5549
5550
5551 if (!do_reloc)
5552 return 1;
5553
5554 if (do_using_dynamic)
5555 {
566b0d53 5556 int is_rela;
2cf0635d 5557 const char * name;
566b0d53
L
5558 int has_dynamic_reloc;
5559 unsigned int i;
0de14b54 5560
566b0d53 5561 has_dynamic_reloc = 0;
252b5132 5562
566b0d53 5563 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5564 {
566b0d53
L
5565 is_rela = dynamic_relocations [i].rela;
5566 name = dynamic_relocations [i].name;
5567 rel_size = dynamic_info [dynamic_relocations [i].size];
5568 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5569
566b0d53
L
5570 has_dynamic_reloc |= rel_size;
5571
5572 if (is_rela == UNKNOWN)
aa903cfb 5573 {
566b0d53
L
5574 if (dynamic_relocations [i].reloc == DT_JMPREL)
5575 switch (dynamic_info[DT_PLTREL])
5576 {
5577 case DT_REL:
5578 is_rela = FALSE;
5579 break;
5580 case DT_RELA:
5581 is_rela = TRUE;
5582 break;
5583 }
aa903cfb 5584 }
252b5132 5585
566b0d53
L
5586 if (rel_size)
5587 {
5588 printf
5589 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5590 name, rel_offset, rel_size);
252b5132 5591
d93f0186
NC
5592 dump_relocations (file,
5593 offset_from_vma (file, rel_offset, rel_size),
5594 rel_size,
566b0d53 5595 dynamic_symbols, num_dynamic_syms,
d79b3d50 5596 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5597 }
252b5132 5598 }
566b0d53 5599
28f997cf
TG
5600 if (is_ia64_vms ())
5601 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5602
566b0d53 5603 if (! has_dynamic_reloc)
252b5132
RH
5604 printf (_("\nThere are no dynamic relocations in this file.\n"));
5605 }
5606 else
5607 {
2cf0635d 5608 Elf_Internal_Shdr * section;
b34976b6
AM
5609 unsigned long i;
5610 int found = 0;
252b5132
RH
5611
5612 for (i = 0, section = section_headers;
5613 i < elf_header.e_shnum;
b34976b6 5614 i++, section++)
252b5132
RH
5615 {
5616 if ( section->sh_type != SHT_RELA
5617 && section->sh_type != SHT_REL)
5618 continue;
5619
5620 rel_offset = section->sh_offset;
5621 rel_size = section->sh_size;
5622
5623 if (rel_size)
5624 {
2cf0635d 5625 Elf_Internal_Shdr * strsec;
b34976b6 5626 int is_rela;
103f02d3 5627
252b5132
RH
5628 printf (_("\nRelocation section "));
5629
5630 if (string_table == NULL)
19936277 5631 printf ("%d", section->sh_name);
252b5132 5632 else
9cf03b7e 5633 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5634
5635 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5636 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5637
d79b3d50
NC
5638 is_rela = section->sh_type == SHT_RELA;
5639
4fbb74a6
AM
5640 if (section->sh_link != 0
5641 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5642 {
2cf0635d
NC
5643 Elf_Internal_Shdr * symsec;
5644 Elf_Internal_Sym * symtab;
d79b3d50 5645 unsigned long nsyms;
c256ffe7 5646 unsigned long strtablen = 0;
2cf0635d 5647 char * strtab = NULL;
57346661 5648
4fbb74a6 5649 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5650 if (symsec->sh_type != SHT_SYMTAB
5651 && symsec->sh_type != SHT_DYNSYM)
5652 continue;
5653
ba5cdace 5654 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5655
af3fc3bc
AM
5656 if (symtab == NULL)
5657 continue;
252b5132 5658
4fbb74a6
AM
5659 if (symsec->sh_link != 0
5660 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5661 {
4fbb74a6 5662 strsec = section_headers + symsec->sh_link;
103f02d3 5663
3f5e193b
NC
5664 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5665 1, strsec->sh_size,
5666 _("string table"));
c256ffe7
JJ
5667 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5668 }
252b5132 5669
d79b3d50
NC
5670 dump_relocations (file, rel_offset, rel_size,
5671 symtab, nsyms, strtab, strtablen, is_rela);
5672 if (strtab)
5673 free (strtab);
5674 free (symtab);
5675 }
5676 else
5677 dump_relocations (file, rel_offset, rel_size,
5678 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5679
5680 found = 1;
5681 }
5682 }
5683
5684 if (! found)
5685 printf (_("\nThere are no relocations in this file.\n"));
5686 }
5687
5688 return 1;
5689}
5690
57346661
AM
5691/* Process the unwind section. */
5692
4d6ed7c8
NC
5693#include "unwind-ia64.h"
5694
5695/* An absolute address consists of a section and an offset. If the
5696 section is NULL, the offset itself is the address, otherwise, the
5697 address equals to LOAD_ADDRESS(section) + offset. */
5698
5699struct absaddr
5700 {
5701 unsigned short section;
5702 bfd_vma offset;
5703 };
5704
1949de15
L
5705#define ABSADDR(a) \
5706 ((a).section \
5707 ? section_headers [(a).section].sh_addr + (a).offset \
5708 : (a).offset)
5709
3f5e193b
NC
5710struct ia64_unw_table_entry
5711 {
5712 struct absaddr start;
5713 struct absaddr end;
5714 struct absaddr info;
5715 };
5716
57346661 5717struct ia64_unw_aux_info
4d6ed7c8 5718 {
3f5e193b
NC
5719
5720 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5721 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5722 unsigned char * info; /* Unwind info. */
b34976b6
AM
5723 unsigned long info_size; /* Size of unwind info. */
5724 bfd_vma info_addr; /* starting address of unwind info. */
5725 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5726 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5727 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5728 char * strtab; /* The string table. */
b34976b6 5729 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5730 };
5731
4d6ed7c8 5732static void
2cf0635d 5733find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5734 unsigned long nsyms,
2cf0635d 5735 const char * strtab,
57346661 5736 unsigned long strtab_size,
d3ba0551 5737 struct absaddr addr,
2cf0635d
NC
5738 const char ** symname,
5739 bfd_vma * offset)
4d6ed7c8 5740{
d3ba0551 5741 bfd_vma dist = 0x100000;
2cf0635d
NC
5742 Elf_Internal_Sym * sym;
5743 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5744 unsigned long i;
5745
0b6ae522
DJ
5746 REMOVE_ARCH_BITS (addr.offset);
5747
57346661 5748 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5749 {
0b6ae522
DJ
5750 bfd_vma value = sym->st_value;
5751
5752 REMOVE_ARCH_BITS (value);
5753
4d6ed7c8
NC
5754 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5755 && sym->st_name != 0
5756 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5757 && addr.offset >= value
5758 && addr.offset - value < dist)
4d6ed7c8
NC
5759 {
5760 best = sym;
0b6ae522 5761 dist = addr.offset - value;
4d6ed7c8
NC
5762 if (!dist)
5763 break;
5764 }
5765 }
1b31d05e 5766
4d6ed7c8
NC
5767 if (best)
5768 {
57346661 5769 *symname = (best->st_name >= strtab_size
2b692964 5770 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5771 *offset = dist;
5772 return;
5773 }
1b31d05e 5774
4d6ed7c8
NC
5775 *symname = NULL;
5776 *offset = addr.offset;
5777}
5778
5779static void
2cf0635d 5780dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5781{
2cf0635d 5782 struct ia64_unw_table_entry * tp;
4d6ed7c8 5783 int in_body;
7036c0e1 5784
4d6ed7c8
NC
5785 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5786 {
5787 bfd_vma stamp;
5788 bfd_vma offset;
2cf0635d
NC
5789 const unsigned char * dp;
5790 const unsigned char * head;
5791 const char * procname;
4d6ed7c8 5792
57346661
AM
5793 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5794 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5795
5796 fputs ("\n<", stdout);
5797
5798 if (procname)
5799 {
5800 fputs (procname, stdout);
5801
5802 if (offset)
5803 printf ("+%lx", (unsigned long) offset);
5804 }
5805
5806 fputs (">: [", stdout);
5807 print_vma (tp->start.offset, PREFIX_HEX);
5808 fputc ('-', stdout);
5809 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5810 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5811 (unsigned long) (tp->info.offset - aux->seg_base));
5812
1949de15 5813 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5814 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5815
86f55779 5816 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5817 (unsigned) UNW_VER (stamp),
5818 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5819 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5820 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5821 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5822
5823 if (UNW_VER (stamp) != 1)
5824 {
2b692964 5825 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5826 continue;
5827 }
5828
5829 in_body = 0;
89fac5e3 5830 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5831 dp = unw_decode (dp, in_body, & in_body);
5832 }
5833}
5834
5835static int
2cf0635d
NC
5836slurp_ia64_unwind_table (FILE * file,
5837 struct ia64_unw_aux_info * aux,
5838 Elf_Internal_Shdr * sec)
4d6ed7c8 5839{
89fac5e3 5840 unsigned long size, nrelas, i;
2cf0635d
NC
5841 Elf_Internal_Phdr * seg;
5842 struct ia64_unw_table_entry * tep;
5843 Elf_Internal_Shdr * relsec;
5844 Elf_Internal_Rela * rela;
5845 Elf_Internal_Rela * rp;
5846 unsigned char * table;
5847 unsigned char * tp;
5848 Elf_Internal_Sym * sym;
5849 const char * relname;
4d6ed7c8 5850
4d6ed7c8
NC
5851 /* First, find the starting address of the segment that includes
5852 this section: */
5853
5854 if (elf_header.e_phnum)
5855 {
d93f0186 5856 if (! get_program_headers (file))
4d6ed7c8 5857 return 0;
4d6ed7c8 5858
d93f0186
NC
5859 for (seg = program_headers;
5860 seg < program_headers + elf_header.e_phnum;
5861 ++seg)
4d6ed7c8
NC
5862 {
5863 if (seg->p_type != PT_LOAD)
5864 continue;
5865
5866 if (sec->sh_addr >= seg->p_vaddr
5867 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5868 {
5869 aux->seg_base = seg->p_vaddr;
5870 break;
5871 }
5872 }
4d6ed7c8
NC
5873 }
5874
5875 /* Second, build the unwind table from the contents of the unwind section: */
5876 size = sec->sh_size;
3f5e193b
NC
5877 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5878 _("unwind table"));
a6e9f9df
AM
5879 if (!table)
5880 return 0;
4d6ed7c8 5881
3f5e193b
NC
5882 aux->table = (struct ia64_unw_table_entry *)
5883 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5884 tep = aux->table;
c6a0c689 5885 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5886 {
5887 tep->start.section = SHN_UNDEF;
5888 tep->end.section = SHN_UNDEF;
5889 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5890 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5891 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5892 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5893 tep->start.offset += aux->seg_base;
5894 tep->end.offset += aux->seg_base;
5895 tep->info.offset += aux->seg_base;
5896 }
5897 free (table);
5898
41e92641 5899 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5900 for (relsec = section_headers;
5901 relsec < section_headers + elf_header.e_shnum;
5902 ++relsec)
5903 {
5904 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5905 || relsec->sh_info >= elf_header.e_shnum
5906 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5907 continue;
5908
5909 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5910 & rela, & nrelas))
5911 return 0;
5912
5913 for (rp = rela; rp < rela + nrelas; ++rp)
5914 {
aca88567
NC
5915 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5916 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5917
0112cd26 5918 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5919 {
e5fb9629 5920 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5921 continue;
5922 }
5923
89fac5e3 5924 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5925
89fac5e3 5926 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5927 {
5928 case 0:
5929 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5930 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5931 break;
5932 case 1:
5933 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5934 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5935 break;
5936 case 2:
5937 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5938 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5939 break;
5940 default:
5941 break;
5942 }
5943 }
5944
5945 free (rela);
5946 }
5947
89fac5e3 5948 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5949 return 1;
5950}
5951
1b31d05e 5952static void
2cf0635d 5953ia64_process_unwind (FILE * file)
4d6ed7c8 5954{
2cf0635d
NC
5955 Elf_Internal_Shdr * sec;
5956 Elf_Internal_Shdr * unwsec = NULL;
5957 Elf_Internal_Shdr * strsec;
89fac5e3 5958 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5959 struct ia64_unw_aux_info aux;
f1467e33 5960
4d6ed7c8
NC
5961 memset (& aux, 0, sizeof (aux));
5962
4d6ed7c8
NC
5963 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5964 {
c256ffe7 5965 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5966 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 5967 {
ba5cdace 5968 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 5969
4fbb74a6 5970 strsec = section_headers + sec->sh_link;
59245841 5971 assert (aux.strtab == NULL);
3f5e193b
NC
5972 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5973 1, strsec->sh_size,
5974 _("string table"));
c256ffe7 5975 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5976 }
5977 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5978 unwcount++;
5979 }
5980
5981 if (!unwcount)
5982 printf (_("\nThere are no unwind sections in this file.\n"));
5983
5984 while (unwcount-- > 0)
5985 {
2cf0635d 5986 char * suffix;
579f31ac
JJ
5987 size_t len, len2;
5988
5989 for (i = unwstart, sec = section_headers + unwstart;
5990 i < elf_header.e_shnum; ++i, ++sec)
5991 if (sec->sh_type == SHT_IA_64_UNWIND)
5992 {
5993 unwsec = sec;
5994 break;
5995 }
5996
5997 unwstart = i + 1;
5998 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5999
e4b17d5c
L
6000 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6001 {
6002 /* We need to find which section group it is in. */
2cf0635d 6003 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
6004
6005 for (; g != NULL; g = g->next)
6006 {
4fbb74a6 6007 sec = section_headers + g->section_index;
18bd398b
NC
6008
6009 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 6010 break;
e4b17d5c
L
6011 }
6012
6013 if (g == NULL)
6014 i = elf_header.e_shnum;
6015 }
18bd398b 6016 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6017 {
18bd398b 6018 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6019 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6020 suffix = SECTION_NAME (unwsec) + len;
6021 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6022 ++i, ++sec)
18bd398b
NC
6023 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6024 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6025 break;
6026 }
6027 else
6028 {
6029 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6030 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6031 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6032 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6033 suffix = "";
18bd398b 6034 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6035 suffix = SECTION_NAME (unwsec) + len;
6036 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6037 ++i, ++sec)
18bd398b
NC
6038 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6039 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6040 break;
6041 }
6042
6043 if (i == elf_header.e_shnum)
6044 {
6045 printf (_("\nCould not find unwind info section for "));
6046
6047 if (string_table == NULL)
6048 printf ("%d", unwsec->sh_name);
6049 else
3a1a2036 6050 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
6051 }
6052 else
4d6ed7c8 6053 {
4d6ed7c8 6054 aux.info_addr = sec->sh_addr;
3f5e193b 6055 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 6056 sec->sh_size,
3f5e193b 6057 _("unwind info"));
59245841 6058 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6059
579f31ac 6060 printf (_("\nUnwind section "));
4d6ed7c8 6061
579f31ac
JJ
6062 if (string_table == NULL)
6063 printf ("%d", unwsec->sh_name);
6064 else
3a1a2036 6065 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 6066
579f31ac 6067 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6068 (unsigned long) unwsec->sh_offset,
89fac5e3 6069 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6070
579f31ac 6071 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 6072
579f31ac
JJ
6073 if (aux.table_len > 0)
6074 dump_ia64_unwind (& aux);
6075
6076 if (aux.table)
6077 free ((char *) aux.table);
6078 if (aux.info)
6079 free ((char *) aux.info);
6080 aux.table = NULL;
6081 aux.info = NULL;
6082 }
4d6ed7c8 6083 }
4d6ed7c8 6084
4d6ed7c8
NC
6085 if (aux.symtab)
6086 free (aux.symtab);
6087 if (aux.strtab)
6088 free ((char *) aux.strtab);
4d6ed7c8
NC
6089}
6090
3f5e193b
NC
6091struct hppa_unw_table_entry
6092 {
6093 struct absaddr start;
6094 struct absaddr end;
6095 unsigned int Cannot_unwind:1; /* 0 */
6096 unsigned int Millicode:1; /* 1 */
6097 unsigned int Millicode_save_sr0:1; /* 2 */
6098 unsigned int Region_description:2; /* 3..4 */
6099 unsigned int reserved1:1; /* 5 */
6100 unsigned int Entry_SR:1; /* 6 */
6101 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6102 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6103 unsigned int Args_stored:1; /* 16 */
6104 unsigned int Variable_Frame:1; /* 17 */
6105 unsigned int Separate_Package_Body:1; /* 18 */
6106 unsigned int Frame_Extension_Millicode:1; /* 19 */
6107 unsigned int Stack_Overflow_Check:1; /* 20 */
6108 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6109 unsigned int Ada_Region:1; /* 22 */
6110 unsigned int cxx_info:1; /* 23 */
6111 unsigned int cxx_try_catch:1; /* 24 */
6112 unsigned int sched_entry_seq:1; /* 25 */
6113 unsigned int reserved2:1; /* 26 */
6114 unsigned int Save_SP:1; /* 27 */
6115 unsigned int Save_RP:1; /* 28 */
6116 unsigned int Save_MRP_in_frame:1; /* 29 */
6117 unsigned int extn_ptr_defined:1; /* 30 */
6118 unsigned int Cleanup_defined:1; /* 31 */
6119
6120 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6121 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6122 unsigned int Large_frame:1; /* 2 */
6123 unsigned int Pseudo_SP_Set:1; /* 3 */
6124 unsigned int reserved4:1; /* 4 */
6125 unsigned int Total_frame_size:27; /* 5..31 */
6126 };
6127
57346661
AM
6128struct hppa_unw_aux_info
6129 {
3f5e193b 6130 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6131 unsigned long table_len; /* Length of unwind table. */
6132 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6133 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6134 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6135 char * strtab; /* The string table. */
57346661
AM
6136 unsigned long strtab_size; /* Size of string table. */
6137 };
6138
6139static void
2cf0635d 6140dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6141{
2cf0635d 6142 struct hppa_unw_table_entry * tp;
57346661 6143
57346661
AM
6144 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6145 {
6146 bfd_vma offset;
2cf0635d 6147 const char * procname;
57346661
AM
6148
6149 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6150 aux->strtab_size, tp->start, &procname,
6151 &offset);
6152
6153 fputs ("\n<", stdout);
6154
6155 if (procname)
6156 {
6157 fputs (procname, stdout);
6158
6159 if (offset)
6160 printf ("+%lx", (unsigned long) offset);
6161 }
6162
6163 fputs (">: [", stdout);
6164 print_vma (tp->start.offset, PREFIX_HEX);
6165 fputc ('-', stdout);
6166 print_vma (tp->end.offset, PREFIX_HEX);
6167 printf ("]\n\t");
6168
18bd398b
NC
6169#define PF(_m) if (tp->_m) printf (#_m " ");
6170#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6171 PF(Cannot_unwind);
6172 PF(Millicode);
6173 PF(Millicode_save_sr0);
18bd398b 6174 /* PV(Region_description); */
57346661
AM
6175 PF(Entry_SR);
6176 PV(Entry_FR);
6177 PV(Entry_GR);
6178 PF(Args_stored);
6179 PF(Variable_Frame);
6180 PF(Separate_Package_Body);
6181 PF(Frame_Extension_Millicode);
6182 PF(Stack_Overflow_Check);
6183 PF(Two_Instruction_SP_Increment);
6184 PF(Ada_Region);
6185 PF(cxx_info);
6186 PF(cxx_try_catch);
6187 PF(sched_entry_seq);
6188 PF(Save_SP);
6189 PF(Save_RP);
6190 PF(Save_MRP_in_frame);
6191 PF(extn_ptr_defined);
6192 PF(Cleanup_defined);
6193 PF(MPE_XL_interrupt_marker);
6194 PF(HP_UX_interrupt_marker);
6195 PF(Large_frame);
6196 PF(Pseudo_SP_Set);
6197 PV(Total_frame_size);
6198#undef PF
6199#undef PV
6200 }
6201
18bd398b 6202 printf ("\n");
57346661
AM
6203}
6204
6205static int
2cf0635d
NC
6206slurp_hppa_unwind_table (FILE * file,
6207 struct hppa_unw_aux_info * aux,
6208 Elf_Internal_Shdr * sec)
57346661 6209{
1c0751b2 6210 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6211 Elf_Internal_Phdr * seg;
6212 struct hppa_unw_table_entry * tep;
6213 Elf_Internal_Shdr * relsec;
6214 Elf_Internal_Rela * rela;
6215 Elf_Internal_Rela * rp;
6216 unsigned char * table;
6217 unsigned char * tp;
6218 Elf_Internal_Sym * sym;
6219 const char * relname;
57346661 6220
57346661
AM
6221 /* First, find the starting address of the segment that includes
6222 this section. */
6223
6224 if (elf_header.e_phnum)
6225 {
6226 if (! get_program_headers (file))
6227 return 0;
6228
6229 for (seg = program_headers;
6230 seg < program_headers + elf_header.e_phnum;
6231 ++seg)
6232 {
6233 if (seg->p_type != PT_LOAD)
6234 continue;
6235
6236 if (sec->sh_addr >= seg->p_vaddr
6237 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6238 {
6239 aux->seg_base = seg->p_vaddr;
6240 break;
6241 }
6242 }
6243 }
6244
6245 /* Second, build the unwind table from the contents of the unwind
6246 section. */
6247 size = sec->sh_size;
3f5e193b
NC
6248 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6249 _("unwind table"));
57346661
AM
6250 if (!table)
6251 return 0;
6252
1c0751b2
DA
6253 unw_ent_size = 16;
6254 nentries = size / unw_ent_size;
6255 size = unw_ent_size * nentries;
57346661 6256
3f5e193b
NC
6257 tep = aux->table = (struct hppa_unw_table_entry *)
6258 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6259
1c0751b2 6260 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6261 {
6262 unsigned int tmp1, tmp2;
6263
6264 tep->start.section = SHN_UNDEF;
6265 tep->end.section = SHN_UNDEF;
6266
1c0751b2
DA
6267 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6268 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6269 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6270 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6271
6272 tep->start.offset += aux->seg_base;
6273 tep->end.offset += aux->seg_base;
57346661
AM
6274
6275 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6276 tep->Millicode = (tmp1 >> 30) & 0x1;
6277 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6278 tep->Region_description = (tmp1 >> 27) & 0x3;
6279 tep->reserved1 = (tmp1 >> 26) & 0x1;
6280 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6281 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6282 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6283 tep->Args_stored = (tmp1 >> 15) & 0x1;
6284 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6285 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6286 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6287 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6288 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6289 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6290 tep->cxx_info = (tmp1 >> 8) & 0x1;
6291 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6292 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6293 tep->reserved2 = (tmp1 >> 5) & 0x1;
6294 tep->Save_SP = (tmp1 >> 4) & 0x1;
6295 tep->Save_RP = (tmp1 >> 3) & 0x1;
6296 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6297 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6298 tep->Cleanup_defined = tmp1 & 0x1;
6299
6300 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6301 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6302 tep->Large_frame = (tmp2 >> 29) & 0x1;
6303 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6304 tep->reserved4 = (tmp2 >> 27) & 0x1;
6305 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6306 }
6307 free (table);
6308
6309 /* Third, apply any relocations to the unwind table. */
57346661
AM
6310 for (relsec = section_headers;
6311 relsec < section_headers + elf_header.e_shnum;
6312 ++relsec)
6313 {
6314 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6315 || relsec->sh_info >= elf_header.e_shnum
6316 || section_headers + relsec->sh_info != sec)
57346661
AM
6317 continue;
6318
6319 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6320 & rela, & nrelas))
6321 return 0;
6322
6323 for (rp = rela; rp < rela + nrelas; ++rp)
6324 {
aca88567
NC
6325 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6326 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6327
6328 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6329 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6330 {
6331 warn (_("Skipping unexpected relocation type %s\n"), relname);
6332 continue;
6333 }
6334
6335 i = rp->r_offset / unw_ent_size;
6336
89fac5e3 6337 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6338 {
6339 case 0:
6340 aux->table[i].start.section = sym->st_shndx;
1e456d54 6341 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6342 break;
6343 case 1:
6344 aux->table[i].end.section = sym->st_shndx;
1e456d54 6345 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6346 break;
6347 default:
6348 break;
6349 }
6350 }
6351
6352 free (rela);
6353 }
6354
1c0751b2 6355 aux->table_len = nentries;
57346661
AM
6356
6357 return 1;
6358}
6359
1b31d05e 6360static void
2cf0635d 6361hppa_process_unwind (FILE * file)
57346661 6362{
57346661 6363 struct hppa_unw_aux_info aux;
2cf0635d
NC
6364 Elf_Internal_Shdr * unwsec = NULL;
6365 Elf_Internal_Shdr * strsec;
6366 Elf_Internal_Shdr * sec;
18bd398b 6367 unsigned long i;
57346661 6368
c256ffe7 6369 if (string_table == NULL)
1b31d05e
NC
6370 return;
6371
6372 memset (& aux, 0, sizeof (aux));
57346661
AM
6373
6374 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6375 {
c256ffe7 6376 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6377 && sec->sh_link < elf_header.e_shnum)
57346661 6378 {
ba5cdace 6379 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6380
4fbb74a6 6381 strsec = section_headers + sec->sh_link;
59245841 6382 assert (aux.strtab == NULL);
3f5e193b
NC
6383 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6384 1, strsec->sh_size,
6385 _("string table"));
c256ffe7 6386 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6387 }
18bd398b 6388 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6389 unwsec = sec;
6390 }
6391
6392 if (!unwsec)
6393 printf (_("\nThere are no unwind sections in this file.\n"));
6394
6395 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6396 {
18bd398b 6397 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6398 {
57346661
AM
6399 printf (_("\nUnwind section "));
6400 printf (_("'%s'"), SECTION_NAME (sec));
6401
6402 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6403 (unsigned long) sec->sh_offset,
89fac5e3 6404 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6405
6406 slurp_hppa_unwind_table (file, &aux, sec);
6407 if (aux.table_len > 0)
6408 dump_hppa_unwind (&aux);
6409
6410 if (aux.table)
6411 free ((char *) aux.table);
6412 aux.table = NULL;
6413 }
6414 }
6415
6416 if (aux.symtab)
6417 free (aux.symtab);
6418 if (aux.strtab)
6419 free ((char *) aux.strtab);
57346661
AM
6420}
6421
0b6ae522
DJ
6422struct arm_section
6423{
a734115a
NC
6424 unsigned char * data; /* The unwind data. */
6425 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6426 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6427 unsigned long nrelas; /* The number of relocations. */
6428 unsigned int rel_type; /* REL or RELA ? */
6429 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6430};
6431
6432struct arm_unw_aux_info
6433{
a734115a
NC
6434 FILE * file; /* The file containing the unwind sections. */
6435 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6436 unsigned long nsyms; /* Number of symbols. */
6437 char * strtab; /* The file's string table. */
6438 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6439};
6440
6441static const char *
6442arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6443 bfd_vma fn, struct absaddr addr)
6444{
6445 const char *procname;
6446 bfd_vma sym_offset;
6447
6448 if (addr.section == SHN_UNDEF)
6449 addr.offset = fn;
6450
6451 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6452 aux->strtab_size, addr, &procname,
6453 &sym_offset);
6454
6455 print_vma (fn, PREFIX_HEX);
6456
6457 if (procname)
6458 {
6459 fputs (" <", stdout);
6460 fputs (procname, stdout);
6461
6462 if (sym_offset)
6463 printf ("+0x%lx", (unsigned long) sym_offset);
6464 fputc ('>', stdout);
6465 }
6466
6467 return procname;
6468}
6469
6470static void
6471arm_free_section (struct arm_section *arm_sec)
6472{
6473 if (arm_sec->data != NULL)
6474 free (arm_sec->data);
6475
6476 if (arm_sec->rela != NULL)
6477 free (arm_sec->rela);
6478}
6479
a734115a
NC
6480/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6481 cached section and install SEC instead.
6482 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6483 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6484 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6485 relocation's offset in ADDR.
1b31d05e
NC
6486 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6487 into the string table of the symbol associated with the reloc. If no
6488 reloc was applied store -1 there.
6489 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6490
6491static bfd_boolean
1b31d05e
NC
6492get_unwind_section_word (struct arm_unw_aux_info * aux,
6493 struct arm_section * arm_sec,
6494 Elf_Internal_Shdr * sec,
6495 bfd_vma word_offset,
6496 unsigned int * wordp,
6497 struct absaddr * addr,
6498 bfd_vma * sym_name)
0b6ae522
DJ
6499{
6500 Elf_Internal_Rela *rp;
6501 Elf_Internal_Sym *sym;
6502 const char * relname;
6503 unsigned int word;
6504 bfd_boolean wrapped;
6505
6506 addr->section = SHN_UNDEF;
6507 addr->offset = 0;
6508
1b31d05e
NC
6509 if (sym_name != NULL)
6510 *sym_name = (bfd_vma) -1;
6511
a734115a 6512 /* If necessary, update the section cache. */
0b6ae522
DJ
6513 if (sec != arm_sec->sec)
6514 {
6515 Elf_Internal_Shdr *relsec;
6516
6517 arm_free_section (arm_sec);
6518
6519 arm_sec->sec = sec;
6520 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6521 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6522 arm_sec->rela = NULL;
6523 arm_sec->nrelas = 0;
6524
6525 for (relsec = section_headers;
6526 relsec < section_headers + elf_header.e_shnum;
6527 ++relsec)
6528 {
6529 if (relsec->sh_info >= elf_header.e_shnum
6530 || section_headers + relsec->sh_info != sec)
6531 continue;
6532
a734115a 6533 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6534 if (relsec->sh_type == SHT_REL)
6535 {
6536 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6537 relsec->sh_size,
6538 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6539 return FALSE;
0b6ae522
DJ
6540 break;
6541 }
6542 else if (relsec->sh_type == SHT_RELA)
6543 {
6544 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6545 relsec->sh_size,
6546 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6547 return FALSE;
0b6ae522
DJ
6548 break;
6549 }
a734115a
NC
6550 else
6551 warn (_("unexpected relocation type (%d) for section %d"),
6552 relsec->sh_type, relsec->sh_info);
0b6ae522
DJ
6553 }
6554
6555 arm_sec->next_rela = arm_sec->rela;
6556 }
6557
a734115a 6558 /* If there is no unwind data we can do nothing. */
0b6ae522 6559 if (arm_sec->data == NULL)
a734115a 6560 return FALSE;
0b6ae522 6561
a734115a 6562 /* Get the word at the required offset. */
0b6ae522
DJ
6563 word = byte_get (arm_sec->data + word_offset, 4);
6564
a734115a 6565 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6566 wrapped = FALSE;
6567 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6568 {
6569 bfd_vma prelval, offset;
6570
6571 if (rp->r_offset > word_offset && !wrapped)
6572 {
6573 rp = arm_sec->rela;
6574 wrapped = TRUE;
6575 }
6576 if (rp->r_offset > word_offset)
6577 break;
6578
6579 if (rp->r_offset & 3)
6580 {
6581 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6582 (unsigned long) rp->r_offset);
6583 continue;
6584 }
6585
6586 if (rp->r_offset < word_offset)
6587 continue;
6588
0b6ae522
DJ
6589 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6590
6591 if (arm_sec->rel_type == SHT_REL)
6592 {
6593 offset = word & 0x7fffffff;
6594 if (offset & 0x40000000)
6595 offset |= ~ (bfd_vma) 0x7fffffff;
6596 }
a734115a 6597 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6598 offset = rp->r_addend;
a734115a
NC
6599 else
6600 abort ();
0b6ae522
DJ
6601
6602 offset += sym->st_value;
6603 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6604
a734115a
NC
6605 /* Check that we are processing the expected reloc type. */
6606 if (elf_header.e_machine == EM_ARM)
6607 {
6608 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6609
6610 if (streq (relname, "R_ARM_NONE"))
6611 continue;
6612
6613 if (! streq (relname, "R_ARM_PREL31"))
6614 {
6615 warn (_("Skipping unexpected relocation type %s\n"), relname);
6616 continue;
6617 }
6618 }
6619 else if (elf_header.e_machine == EM_TI_C6000)
6620 {
6621 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6622
6623 if (streq (relname, "R_C6000_NONE"))
6624 continue;
6625
6626 if (! streq (relname, "R_C6000_PREL31"))
6627 {
6628 warn (_("Skipping unexpected relocation type %s\n"), relname);
6629 continue;
6630 }
6631
6632 prelval >>= 1;
6633 }
6634 else
6635 /* This function currently only supports ARM and TI unwinders. */
6636 abort ();
fa197c1c 6637
0b6ae522
DJ
6638 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6639 addr->section = sym->st_shndx;
6640 addr->offset = offset;
1b31d05e
NC
6641 if (sym_name)
6642 * sym_name = sym->st_name;
0b6ae522
DJ
6643 break;
6644 }
6645
6646 *wordp = word;
6647 arm_sec->next_rela = rp;
6648
a734115a 6649 return TRUE;
0b6ae522
DJ
6650}
6651
a734115a
NC
6652static const char *tic6x_unwind_regnames[16] =
6653{
6654 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6655 "A14", "A13", "A12", "A11", "A10",
6656 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6657};
fa197c1c 6658
0b6ae522 6659static void
fa197c1c 6660decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6661{
fa197c1c
PB
6662 int i;
6663
6664 for (i = 12; mask; mask >>= 1, i--)
6665 {
6666 if (mask & 1)
6667 {
6668 fputs (tic6x_unwind_regnames[i], stdout);
6669 if (mask > 1)
6670 fputs (", ", stdout);
6671 }
6672 }
6673}
0b6ae522
DJ
6674
6675#define ADVANCE \
6676 if (remaining == 0 && more_words) \
6677 { \
6678 data_offset += 4; \
1b31d05e
NC
6679 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
6680 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
6681 return; \
6682 remaining = 4; \
6683 more_words--; \
6684 } \
6685
6686#define GET_OP(OP) \
6687 ADVANCE; \
6688 if (remaining) \
6689 { \
6690 remaining--; \
6691 (OP) = word >> 24; \
6692 word <<= 8; \
6693 } \
6694 else \
6695 { \
2b692964 6696 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6697 return; \
6698 } \
cc5914eb 6699 printf ("0x%02x ", OP)
0b6ae522 6700
fa197c1c
PB
6701static void
6702decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6703 unsigned int word, unsigned int remaining,
6704 unsigned int more_words,
6705 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6706 struct arm_section *data_arm_sec)
6707{
6708 struct absaddr addr;
0b6ae522
DJ
6709
6710 /* Decode the unwinding instructions. */
6711 while (1)
6712 {
6713 unsigned int op, op2;
6714
6715 ADVANCE;
6716 if (remaining == 0)
6717 break;
6718 remaining--;
6719 op = word >> 24;
6720 word <<= 8;
6721
cc5914eb 6722 printf (" 0x%02x ", op);
0b6ae522
DJ
6723
6724 if ((op & 0xc0) == 0x00)
6725 {
6726 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6727
cc5914eb 6728 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6729 }
6730 else if ((op & 0xc0) == 0x40)
6731 {
6732 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6733
cc5914eb 6734 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6735 }
6736 else if ((op & 0xf0) == 0x80)
6737 {
6738 GET_OP (op2);
6739 if (op == 0x80 && op2 == 0)
6740 printf (_("Refuse to unwind"));
6741 else
6742 {
6743 unsigned int mask = ((op & 0x0f) << 8) | op2;
6744 int first = 1;
6745 int i;
2b692964 6746
0b6ae522
DJ
6747 printf ("pop {");
6748 for (i = 0; i < 12; i++)
6749 if (mask & (1 << i))
6750 {
6751 if (first)
6752 first = 0;
6753 else
6754 printf (", ");
6755 printf ("r%d", 4 + i);
6756 }
6757 printf ("}");
6758 }
6759 }
6760 else if ((op & 0xf0) == 0x90)
6761 {
6762 if (op == 0x9d || op == 0x9f)
6763 printf (_(" [Reserved]"));
6764 else
cc5914eb 6765 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6766 }
6767 else if ((op & 0xf0) == 0xa0)
6768 {
6769 int end = 4 + (op & 0x07);
6770 int first = 1;
6771 int i;
61865e30 6772
0b6ae522
DJ
6773 printf (" pop {");
6774 for (i = 4; i <= end; i++)
6775 {
6776 if (first)
6777 first = 0;
6778 else
6779 printf (", ");
6780 printf ("r%d", i);
6781 }
6782 if (op & 0x08)
6783 {
1b31d05e 6784 if (!first)
0b6ae522
DJ
6785 printf (", ");
6786 printf ("r14");
6787 }
6788 printf ("}");
6789 }
6790 else if (op == 0xb0)
6791 printf (_(" finish"));
6792 else if (op == 0xb1)
6793 {
6794 GET_OP (op2);
6795 if (op2 == 0 || (op2 & 0xf0) != 0)
6796 printf (_("[Spare]"));
6797 else
6798 {
6799 unsigned int mask = op2 & 0x0f;
6800 int first = 1;
6801 int i;
61865e30 6802
0b6ae522
DJ
6803 printf ("pop {");
6804 for (i = 0; i < 12; i++)
6805 if (mask & (1 << i))
6806 {
6807 if (first)
6808 first = 0;
6809 else
6810 printf (", ");
6811 printf ("r%d", i);
6812 }
6813 printf ("}");
6814 }
6815 }
6816 else if (op == 0xb2)
6817 {
b115cf96 6818 unsigned char buf[9];
0b6ae522
DJ
6819 unsigned int i, len;
6820 unsigned long offset;
61865e30 6821
b115cf96 6822 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6823 {
6824 GET_OP (buf[i]);
6825 if ((buf[i] & 0x80) == 0)
6826 break;
6827 }
6828 assert (i < sizeof (buf));
6829 offset = read_uleb128 (buf, &len);
6830 assert (len == i + 1);
6831 offset = offset * 4 + 0x204;
cc5914eb 6832 printf ("vsp = vsp + %ld", offset);
0b6ae522 6833 }
61865e30 6834 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6835 {
61865e30
NC
6836 unsigned int first, last;
6837
6838 GET_OP (op2);
6839 first = op2 >> 4;
6840 last = op2 & 0x0f;
6841 if (op == 0xc8)
6842 first = first + 16;
6843 printf ("pop {D%d", first);
6844 if (last)
6845 printf ("-D%d", first + last);
6846 printf ("}");
6847 }
6848 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6849 {
6850 unsigned int count = op & 0x07;
6851
6852 printf ("pop {D8");
6853 if (count)
6854 printf ("-D%d", 8 + count);
6855 printf ("}");
6856 }
6857 else if (op >= 0xc0 && op <= 0xc5)
6858 {
6859 unsigned int count = op & 0x07;
6860
6861 printf (" pop {wR10");
6862 if (count)
6863 printf ("-wR%d", 10 + count);
6864 printf ("}");
6865 }
6866 else if (op == 0xc6)
6867 {
6868 unsigned int first, last;
6869
6870 GET_OP (op2);
6871 first = op2 >> 4;
6872 last = op2 & 0x0f;
6873 printf ("pop {wR%d", first);
6874 if (last)
6875 printf ("-wR%d", first + last);
6876 printf ("}");
6877 }
6878 else if (op == 0xc7)
6879 {
6880 GET_OP (op2);
6881 if (op2 == 0 || (op2 & 0xf0) != 0)
6882 printf (_("[Spare]"));
0b6ae522
DJ
6883 else
6884 {
61865e30
NC
6885 unsigned int mask = op2 & 0x0f;
6886 int first = 1;
6887 int i;
6888
6889 printf ("pop {");
6890 for (i = 0; i < 4; i++)
6891 if (mask & (1 << i))
6892 {
6893 if (first)
6894 first = 0;
6895 else
6896 printf (", ");
6897 printf ("wCGR%d", i);
6898 }
6899 printf ("}");
0b6ae522
DJ
6900 }
6901 }
61865e30
NC
6902 else
6903 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6904 printf ("\n");
6905 }
fa197c1c
PB
6906}
6907
6908static void
6909decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6910 unsigned int word, unsigned int remaining,
6911 unsigned int more_words,
6912 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6913 struct arm_section *data_arm_sec)
6914{
6915 struct absaddr addr;
6916
6917 /* Decode the unwinding instructions. */
6918 while (1)
6919 {
6920 unsigned int op, op2;
6921
6922 ADVANCE;
6923 if (remaining == 0)
6924 break;
6925 remaining--;
6926 op = word >> 24;
6927 word <<= 8;
6928
9cf03b7e 6929 printf (" 0x%02x ", op);
fa197c1c
PB
6930
6931 if ((op & 0xc0) == 0x00)
6932 {
6933 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 6934 printf (" sp = sp + %d", offset);
fa197c1c
PB
6935 }
6936 else if ((op & 0xc0) == 0x80)
6937 {
6938 GET_OP (op2);
6939 if (op == 0x80 && op2 == 0)
6940 printf (_("Refuse to unwind"));
6941 else
6942 {
6943 unsigned int mask = ((op & 0x1f) << 8) | op2;
6944 if (op & 0x20)
6945 printf ("pop compact {");
6946 else
6947 printf ("pop {");
6948
6949 decode_tic6x_unwind_regmask (mask);
6950 printf("}");
6951 }
6952 }
6953 else if ((op & 0xf0) == 0xc0)
6954 {
6955 unsigned int reg;
6956 unsigned int nregs;
6957 unsigned int i;
6958 const char *name;
a734115a
NC
6959 struct
6960 {
fa197c1c
PB
6961 unsigned int offset;
6962 unsigned int reg;
6963 } regpos[16];
6964
6965 /* Scan entire instruction first so that GET_OP output is not
6966 interleaved with disassembly. */
6967 nregs = 0;
6968 for (i = 0; nregs < (op & 0xf); i++)
6969 {
6970 GET_OP (op2);
6971 reg = op2 >> 4;
6972 if (reg != 0xf)
6973 {
6974 regpos[nregs].offset = i * 2;
6975 regpos[nregs].reg = reg;
6976 nregs++;
6977 }
6978
6979 reg = op2 & 0xf;
6980 if (reg != 0xf)
6981 {
6982 regpos[nregs].offset = i * 2 + 1;
6983 regpos[nregs].reg = reg;
6984 nregs++;
6985 }
6986 }
6987
6988 printf (_("pop frame {"));
6989 reg = nregs - 1;
6990 for (i = i * 2; i > 0; i--)
6991 {
6992 if (regpos[reg].offset == i - 1)
6993 {
6994 name = tic6x_unwind_regnames[regpos[reg].reg];
6995 if (reg > 0)
6996 reg--;
6997 }
6998 else
6999 name = _("[pad]");
7000
7001 fputs (name, stdout);
7002 if (i > 1)
7003 printf (", ");
7004 }
7005
7006 printf ("}");
7007 }
7008 else if (op == 0xd0)
7009 printf (" MOV FP, SP");
7010 else if (op == 0xd1)
7011 printf (" __c6xabi_pop_rts");
7012 else if (op == 0xd2)
7013 {
7014 unsigned char buf[9];
7015 unsigned int i, len;
7016 unsigned long offset;
a734115a 7017
fa197c1c
PB
7018 for (i = 0; i < sizeof (buf); i++)
7019 {
7020 GET_OP (buf[i]);
7021 if ((buf[i] & 0x80) == 0)
7022 break;
7023 }
7024 assert (i < sizeof (buf));
7025 offset = read_uleb128 (buf, &len);
7026 assert (len == i + 1);
7027 offset = offset * 8 + 0x408;
7028 printf (_("sp = sp + %ld"), offset);
7029 }
7030 else if ((op & 0xf0) == 0xe0)
7031 {
7032 if ((op & 0x0f) == 7)
7033 printf (" RETURN");
7034 else
7035 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7036 }
7037 else
7038 {
7039 printf (_(" [unsupported opcode]"));
7040 }
7041 putchar ('\n');
7042 }
7043}
7044
7045static bfd_vma
a734115a 7046arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7047{
7048 bfd_vma offset;
7049
7050 offset = word & 0x7fffffff;
7051 if (offset & 0x40000000)
7052 offset |= ~ (bfd_vma) 0x7fffffff;
7053
7054 if (elf_header.e_machine == EM_TI_C6000)
7055 offset <<= 1;
7056
7057 return offset + where;
7058}
7059
7060static void
1b31d05e
NC
7061decode_arm_unwind (struct arm_unw_aux_info * aux,
7062 unsigned int word,
7063 unsigned int remaining,
7064 bfd_vma data_offset,
7065 Elf_Internal_Shdr * data_sec,
7066 struct arm_section * data_arm_sec)
fa197c1c
PB
7067{
7068 int per_index;
7069 unsigned int more_words = 0;
7070 struct absaddr addr;
1b31d05e 7071 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7072
7073 if (remaining == 0)
7074 {
1b31d05e
NC
7075 /* Fetch the first word.
7076 Note - when decoding an object file the address extracted
7077 here will always be 0. So we also pass in the sym_name
7078 parameter so that we can find the symbol associated with
7079 the personality routine. */
7080 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7081 & word, & addr, & sym_name))
fa197c1c 7082 return;
1b31d05e 7083
fa197c1c
PB
7084 remaining = 4;
7085 }
7086
7087 if ((word & 0x80000000) == 0)
7088 {
7089 /* Expand prel31 for personality routine. */
7090 bfd_vma fn;
7091 const char *procname;
7092
a734115a 7093 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7094 printf (_(" Personality routine: "));
1b31d05e
NC
7095 if (fn == 0
7096 && addr.section == SHN_UNDEF && addr.offset == 0
7097 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7098 {
7099 procname = aux->strtab + sym_name;
7100 print_vma (fn, PREFIX_HEX);
7101 if (procname)
7102 {
7103 fputs (" <", stdout);
7104 fputs (procname, stdout);
7105 fputc ('>', stdout);
7106 }
7107 }
7108 else
7109 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7110 fputc ('\n', stdout);
7111
7112 /* The GCC personality routines use the standard compact
7113 encoding, starting with one byte giving the number of
7114 words. */
7115 if (procname != NULL
7116 && (const_strneq (procname, "__gcc_personality_v0")
7117 || const_strneq (procname, "__gxx_personality_v0")
7118 || const_strneq (procname, "__gcj_personality_v0")
7119 || const_strneq (procname, "__gnu_objc_personality_v0")))
7120 {
7121 remaining = 0;
7122 more_words = 1;
7123 ADVANCE;
7124 if (!remaining)
7125 {
7126 printf (_(" [Truncated data]\n"));
7127 return;
7128 }
7129 more_words = word >> 24;
7130 word <<= 8;
7131 remaining--;
7132 per_index = -1;
7133 }
7134 else
7135 return;
7136 }
7137 else
7138 {
1b31d05e
NC
7139 /* ARM EHABI Section 6.3:
7140
7141 An exception-handling table entry for the compact model looks like:
7142
7143 31 30-28 27-24 23-0
7144 -- ----- ----- ----
7145 1 0 index Data for personalityRoutine[index] */
7146
7147 if (elf_header.e_machine == EM_ARM
7148 && (word & 0x70000000))
83c257ca 7149 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 7150
fa197c1c 7151 per_index = (word >> 24) & 0x7f;
1b31d05e 7152 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
7153 if (per_index == 0)
7154 {
7155 more_words = 0;
7156 word <<= 8;
7157 remaining--;
7158 }
7159 else if (per_index < 3)
7160 {
7161 more_words = (word >> 16) & 0xff;
7162 word <<= 16;
7163 remaining -= 2;
7164 }
7165 }
7166
7167 switch (elf_header.e_machine)
7168 {
7169 case EM_ARM:
7170 if (per_index < 3)
7171 {
7172 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7173 data_offset, data_sec, data_arm_sec);
7174 }
7175 else
1b31d05e
NC
7176 {
7177 warn (_("Unknown ARM compact model index encountered\n"));
7178 printf (_(" [reserved]\n"));
7179 }
fa197c1c
PB
7180 break;
7181
7182 case EM_TI_C6000:
7183 if (per_index < 3)
7184 {
7185 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7186 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7187 }
7188 else if (per_index < 5)
7189 {
7190 if (((word >> 17) & 0x7f) == 0x7f)
7191 printf (_(" Restore stack from frame pointer\n"));
7192 else
7193 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7194 printf (_(" Registers restored: "));
7195 if (per_index == 4)
7196 printf (" (compact) ");
7197 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7198 putchar ('\n');
7199 printf (_(" Return register: %s\n"),
7200 tic6x_unwind_regnames[word & 0xf]);
7201 }
7202 else
1b31d05e 7203 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7204 break;
7205
7206 default:
1b31d05e
NC
7207 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7208 elf_header.e_machine);
fa197c1c 7209 }
0b6ae522
DJ
7210
7211 /* Decode the descriptors. Not implemented. */
7212}
7213
7214static void
7215dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7216{
7217 struct arm_section exidx_arm_sec, extab_arm_sec;
7218 unsigned int i, exidx_len;
7219
7220 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7221 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7222 exidx_len = exidx_sec->sh_size / 8;
7223
7224 for (i = 0; i < exidx_len; i++)
7225 {
7226 unsigned int exidx_fn, exidx_entry;
7227 struct absaddr fn_addr, entry_addr;
7228 bfd_vma fn;
7229
7230 fputc ('\n', stdout);
7231
1b31d05e
NC
7232 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7233 8 * i, & exidx_fn, & fn_addr, NULL)
7234 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7235 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7236 {
1b31d05e
NC
7237 arm_free_section (& exidx_arm_sec);
7238 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7239 return;
7240 }
7241
83c257ca
NC
7242 /* ARM EHABI, Section 5:
7243 An index table entry consists of 2 words.
7244 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7245 if (exidx_fn & 0x80000000)
7246 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7247
a734115a 7248 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7249
a734115a 7250 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7251 fputs (": ", stdout);
7252
7253 if (exidx_entry == 1)
7254 {
7255 print_vma (exidx_entry, PREFIX_HEX);
7256 fputs (" [cantunwind]\n", stdout);
7257 }
7258 else if (exidx_entry & 0x80000000)
7259 {
7260 print_vma (exidx_entry, PREFIX_HEX);
7261 fputc ('\n', stdout);
7262 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7263 }
7264 else
7265 {
8f73510c 7266 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7267 Elf_Internal_Shdr *table_sec;
7268
7269 fputs ("@", stdout);
a734115a 7270 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7271 print_vma (table, PREFIX_HEX);
7272 printf ("\n");
7273
7274 /* Locate the matching .ARM.extab. */
7275 if (entry_addr.section != SHN_UNDEF
7276 && entry_addr.section < elf_header.e_shnum)
7277 {
7278 table_sec = section_headers + entry_addr.section;
7279 table_offset = entry_addr.offset;
7280 }
7281 else
7282 {
7283 table_sec = find_section_by_address (table);
7284 if (table_sec != NULL)
7285 table_offset = table - table_sec->sh_addr;
7286 }
7287 if (table_sec == NULL)
7288 {
7289 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7290 (unsigned long) table);
7291 continue;
7292 }
7293 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7294 &extab_arm_sec);
7295 }
7296 }
7297
7298 printf ("\n");
7299
7300 arm_free_section (&exidx_arm_sec);
7301 arm_free_section (&extab_arm_sec);
7302}
7303
fa197c1c 7304/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7305
7306static void
0b6ae522
DJ
7307arm_process_unwind (FILE *file)
7308{
7309 struct arm_unw_aux_info aux;
7310 Elf_Internal_Shdr *unwsec = NULL;
7311 Elf_Internal_Shdr *strsec;
7312 Elf_Internal_Shdr *sec;
7313 unsigned long i;
fa197c1c 7314 unsigned int sec_type;
0b6ae522 7315
fa197c1c
PB
7316 switch (elf_header.e_machine)
7317 {
7318 case EM_ARM:
7319 sec_type = SHT_ARM_EXIDX;
7320 break;
7321
7322 case EM_TI_C6000:
7323 sec_type = SHT_C6000_UNWIND;
7324 break;
7325
1b31d05e
NC
7326 default:
7327 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7328 elf_header.e_machine);
7329 return;
fa197c1c
PB
7330 }
7331
0b6ae522 7332 if (string_table == NULL)
1b31d05e
NC
7333 return;
7334
7335 memset (& aux, 0, sizeof (aux));
7336 aux.file = file;
0b6ae522
DJ
7337
7338 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7339 {
7340 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7341 {
ba5cdace 7342 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7343
7344 strsec = section_headers + sec->sh_link;
59245841 7345 assert (aux.strtab == NULL);
0b6ae522
DJ
7346 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7347 1, strsec->sh_size, _("string table"));
7348 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7349 }
fa197c1c 7350 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7351 unwsec = sec;
7352 }
7353
1b31d05e 7354 if (unwsec == NULL)
0b6ae522 7355 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7356 else
7357 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7358 {
7359 if (sec->sh_type == sec_type)
7360 {
7361 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7362 SECTION_NAME (sec),
7363 (unsigned long) sec->sh_offset,
7364 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7365
1b31d05e
NC
7366 dump_arm_unwind (&aux, sec);
7367 }
7368 }
0b6ae522
DJ
7369
7370 if (aux.symtab)
7371 free (aux.symtab);
7372 if (aux.strtab)
7373 free ((char *) aux.strtab);
0b6ae522
DJ
7374}
7375
1b31d05e 7376static void
2cf0635d 7377process_unwind (FILE * file)
57346661 7378{
2cf0635d
NC
7379 struct unwind_handler
7380 {
57346661 7381 int machtype;
1b31d05e 7382 void (* handler)(FILE *);
2cf0635d
NC
7383 } handlers[] =
7384 {
0b6ae522 7385 { EM_ARM, arm_process_unwind },
57346661
AM
7386 { EM_IA_64, ia64_process_unwind },
7387 { EM_PARISC, hppa_process_unwind },
fa197c1c 7388 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7389 { 0, 0 }
7390 };
7391 int i;
7392
7393 if (!do_unwind)
1b31d05e 7394 return;
57346661
AM
7395
7396 for (i = 0; handlers[i].handler != NULL; i++)
7397 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7398 return handlers[i].handler (file);
57346661 7399
1b31d05e
NC
7400 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7401 get_machine_name (elf_header.e_machine));
57346661
AM
7402}
7403
252b5132 7404static void
2cf0635d 7405dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7406{
7407 switch (entry->d_tag)
7408 {
7409 case DT_MIPS_FLAGS:
7410 if (entry->d_un.d_val == 0)
4b68bca3 7411 printf (_("NONE"));
252b5132
RH
7412 else
7413 {
7414 static const char * opts[] =
7415 {
7416 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7417 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7418 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7419 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7420 "RLD_ORDER_SAFE"
7421 };
7422 unsigned int cnt;
7423 int first = 1;
2b692964 7424
60bca95a 7425 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7426 if (entry->d_un.d_val & (1 << cnt))
7427 {
7428 printf ("%s%s", first ? "" : " ", opts[cnt]);
7429 first = 0;
7430 }
252b5132
RH
7431 }
7432 break;
103f02d3 7433
252b5132 7434 case DT_MIPS_IVERSION:
d79b3d50 7435 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7436 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7437 else
4b68bca3 7438 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7439 break;
103f02d3 7440
252b5132
RH
7441 case DT_MIPS_TIME_STAMP:
7442 {
7443 char timebuf[20];
2cf0635d 7444 struct tm * tmp;
50da7a9c 7445
91d6fa6a
NC
7446 time_t atime = entry->d_un.d_val;
7447 tmp = gmtime (&atime);
e9e44622
JJ
7448 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7449 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7450 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7451 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7452 }
7453 break;
103f02d3 7454
252b5132
RH
7455 case DT_MIPS_RLD_VERSION:
7456 case DT_MIPS_LOCAL_GOTNO:
7457 case DT_MIPS_CONFLICTNO:
7458 case DT_MIPS_LIBLISTNO:
7459 case DT_MIPS_SYMTABNO:
7460 case DT_MIPS_UNREFEXTNO:
7461 case DT_MIPS_HIPAGENO:
7462 case DT_MIPS_DELTA_CLASS_NO:
7463 case DT_MIPS_DELTA_INSTANCE_NO:
7464 case DT_MIPS_DELTA_RELOC_NO:
7465 case DT_MIPS_DELTA_SYM_NO:
7466 case DT_MIPS_DELTA_CLASSSYM_NO:
7467 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7468 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7469 break;
103f02d3
UD
7470
7471 default:
4b68bca3 7472 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7473 }
4b68bca3 7474 putchar ('\n');
103f02d3
UD
7475}
7476
103f02d3 7477static void
2cf0635d 7478dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7479{
7480 switch (entry->d_tag)
7481 {
7482 case DT_HP_DLD_FLAGS:
7483 {
7484 static struct
7485 {
7486 long int bit;
2cf0635d 7487 const char * str;
5e220199
NC
7488 }
7489 flags[] =
7490 {
7491 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7492 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7493 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7494 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7495 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7496 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7497 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7498 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7499 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7500 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7501 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7502 { DT_HP_GST, "HP_GST" },
7503 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7504 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7505 { DT_HP_NODELETE, "HP_NODELETE" },
7506 { DT_HP_GROUP, "HP_GROUP" },
7507 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7508 };
103f02d3 7509 int first = 1;
5e220199 7510 size_t cnt;
f7a99963 7511 bfd_vma val = entry->d_un.d_val;
103f02d3 7512
60bca95a 7513 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7514 if (val & flags[cnt].bit)
30800947
NC
7515 {
7516 if (! first)
7517 putchar (' ');
7518 fputs (flags[cnt].str, stdout);
7519 first = 0;
7520 val ^= flags[cnt].bit;
7521 }
76da6bbe 7522
103f02d3 7523 if (val != 0 || first)
f7a99963
NC
7524 {
7525 if (! first)
7526 putchar (' ');
7527 print_vma (val, HEX);
7528 }
103f02d3
UD
7529 }
7530 break;
76da6bbe 7531
252b5132 7532 default:
f7a99963
NC
7533 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7534 break;
252b5132 7535 }
35b1837e 7536 putchar ('\n');
252b5132
RH
7537}
7538
28f997cf
TG
7539#ifdef BFD64
7540
7541/* VMS vs Unix time offset and factor. */
7542
7543#define VMS_EPOCH_OFFSET 35067168000000000LL
7544#define VMS_GRANULARITY_FACTOR 10000000
7545
7546/* Display a VMS time in a human readable format. */
7547
7548static void
7549print_vms_time (bfd_int64_t vmstime)
7550{
7551 struct tm *tm;
7552 time_t unxtime;
7553
7554 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7555 tm = gmtime (&unxtime);
7556 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7557 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7558 tm->tm_hour, tm->tm_min, tm->tm_sec);
7559}
7560#endif /* BFD64 */
7561
ecc51f48 7562static void
2cf0635d 7563dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7564{
7565 switch (entry->d_tag)
7566 {
0de14b54 7567 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7568 /* First 3 slots reserved. */
ecc51f48
NC
7569 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7570 printf (" -- ");
7571 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7572 break;
7573
28f997cf
TG
7574 case DT_IA_64_VMS_LINKTIME:
7575#ifdef BFD64
7576 print_vms_time (entry->d_un.d_val);
7577#endif
7578 break;
7579
7580 case DT_IA_64_VMS_LNKFLAGS:
7581 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7582 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7583 printf (" CALL_DEBUG");
7584 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7585 printf (" NOP0BUFS");
7586 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7587 printf (" P0IMAGE");
7588 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7589 printf (" MKTHREADS");
7590 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7591 printf (" UPCALLS");
7592 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7593 printf (" IMGSTA");
7594 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7595 printf (" INITIALIZE");
7596 if (entry->d_un.d_val & VMS_LF_MAIN)
7597 printf (" MAIN");
7598 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7599 printf (" EXE_INIT");
7600 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7601 printf (" TBK_IN_IMG");
7602 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7603 printf (" DBG_IN_IMG");
7604 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7605 printf (" TBK_IN_DSF");
7606 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7607 printf (" DBG_IN_DSF");
7608 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7609 printf (" SIGNATURES");
7610 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7611 printf (" REL_SEG_OFF");
7612 break;
7613
bdf4d63a
JJ
7614 default:
7615 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7616 break;
ecc51f48 7617 }
bdf4d63a 7618 putchar ('\n');
ecc51f48
NC
7619}
7620
252b5132 7621static int
2cf0635d 7622get_32bit_dynamic_section (FILE * file)
252b5132 7623{
2cf0635d
NC
7624 Elf32_External_Dyn * edyn;
7625 Elf32_External_Dyn * ext;
7626 Elf_Internal_Dyn * entry;
103f02d3 7627
3f5e193b
NC
7628 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7629 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7630 if (!edyn)
7631 return 0;
103f02d3 7632
ba2685cc
AM
7633/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7634 might not have the luxury of section headers. Look for the DT_NULL
7635 terminator to determine the number of entries. */
7636 for (ext = edyn, dynamic_nent = 0;
7637 (char *) ext < (char *) edyn + dynamic_size;
7638 ext++)
7639 {
7640 dynamic_nent++;
7641 if (BYTE_GET (ext->d_tag) == DT_NULL)
7642 break;
7643 }
252b5132 7644
3f5e193b
NC
7645 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7646 sizeof (* entry));
b2d38a17 7647 if (dynamic_section == NULL)
252b5132 7648 {
9ea033b2
NC
7649 error (_("Out of memory\n"));
7650 free (edyn);
7651 return 0;
7652 }
252b5132 7653
fb514b26 7654 for (ext = edyn, entry = dynamic_section;
ba2685cc 7655 entry < dynamic_section + dynamic_nent;
fb514b26 7656 ext++, entry++)
9ea033b2 7657 {
fb514b26
AM
7658 entry->d_tag = BYTE_GET (ext->d_tag);
7659 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7660 }
7661
9ea033b2
NC
7662 free (edyn);
7663
7664 return 1;
7665}
7666
7667static int
2cf0635d 7668get_64bit_dynamic_section (FILE * file)
9ea033b2 7669{
2cf0635d
NC
7670 Elf64_External_Dyn * edyn;
7671 Elf64_External_Dyn * ext;
7672 Elf_Internal_Dyn * entry;
103f02d3 7673
3f5e193b
NC
7674 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7675 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7676 if (!edyn)
7677 return 0;
103f02d3 7678
ba2685cc
AM
7679/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7680 might not have the luxury of section headers. Look for the DT_NULL
7681 terminator to determine the number of entries. */
7682 for (ext = edyn, dynamic_nent = 0;
7683 (char *) ext < (char *) edyn + dynamic_size;
7684 ext++)
7685 {
7686 dynamic_nent++;
66543521 7687 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7688 break;
7689 }
252b5132 7690
3f5e193b
NC
7691 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7692 sizeof (* entry));
b2d38a17 7693 if (dynamic_section == NULL)
252b5132
RH
7694 {
7695 error (_("Out of memory\n"));
7696 free (edyn);
7697 return 0;
7698 }
7699
fb514b26 7700 for (ext = edyn, entry = dynamic_section;
ba2685cc 7701 entry < dynamic_section + dynamic_nent;
fb514b26 7702 ext++, entry++)
252b5132 7703 {
66543521
AM
7704 entry->d_tag = BYTE_GET (ext->d_tag);
7705 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7706 }
7707
7708 free (edyn);
7709
9ea033b2
NC
7710 return 1;
7711}
7712
e9e44622
JJ
7713static void
7714print_dynamic_flags (bfd_vma flags)
d1133906 7715{
e9e44622 7716 int first = 1;
13ae64f3 7717
d1133906
NC
7718 while (flags)
7719 {
7720 bfd_vma flag;
7721
7722 flag = flags & - flags;
7723 flags &= ~ flag;
7724
e9e44622
JJ
7725 if (first)
7726 first = 0;
7727 else
7728 putc (' ', stdout);
13ae64f3 7729
d1133906
NC
7730 switch (flag)
7731 {
e9e44622
JJ
7732 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7733 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7734 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7735 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7736 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7737 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7738 }
7739 }
e9e44622 7740 puts ("");
d1133906
NC
7741}
7742
b2d38a17
NC
7743/* Parse and display the contents of the dynamic section. */
7744
9ea033b2 7745static int
2cf0635d 7746process_dynamic_section (FILE * file)
9ea033b2 7747{
2cf0635d 7748 Elf_Internal_Dyn * entry;
9ea033b2
NC
7749
7750 if (dynamic_size == 0)
7751 {
7752 if (do_dynamic)
b2d38a17 7753 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7754
7755 return 1;
7756 }
7757
7758 if (is_32bit_elf)
7759 {
b2d38a17 7760 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7761 return 0;
7762 }
b2d38a17 7763 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7764 return 0;
7765
252b5132
RH
7766 /* Find the appropriate symbol table. */
7767 if (dynamic_symbols == NULL)
7768 {
86dba8ee
AM
7769 for (entry = dynamic_section;
7770 entry < dynamic_section + dynamic_nent;
7771 ++entry)
252b5132 7772 {
c8286bd1 7773 Elf_Internal_Shdr section;
252b5132
RH
7774
7775 if (entry->d_tag != DT_SYMTAB)
7776 continue;
7777
7778 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7779
7780 /* Since we do not know how big the symbol table is,
7781 we default to reading in the entire file (!) and
7782 processing that. This is overkill, I know, but it
e3c8793a 7783 should work. */
d93f0186 7784 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7785
fb52b2f4
NC
7786 if (archive_file_offset != 0)
7787 section.sh_size = archive_file_size - section.sh_offset;
7788 else
7789 {
7790 if (fseek (file, 0, SEEK_END))
591a748a 7791 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7792
7793 section.sh_size = ftell (file) - section.sh_offset;
7794 }
252b5132 7795
9ea033b2 7796 if (is_32bit_elf)
9ad5cbcf 7797 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7798 else
9ad5cbcf 7799 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7800
ba5cdace 7801 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 7802 if (num_dynamic_syms < 1)
252b5132
RH
7803 {
7804 error (_("Unable to determine the number of symbols to load\n"));
7805 continue;
7806 }
252b5132
RH
7807 }
7808 }
7809
7810 /* Similarly find a string table. */
7811 if (dynamic_strings == NULL)
7812 {
86dba8ee
AM
7813 for (entry = dynamic_section;
7814 entry < dynamic_section + dynamic_nent;
7815 ++entry)
252b5132
RH
7816 {
7817 unsigned long offset;
b34976b6 7818 long str_tab_len;
252b5132
RH
7819
7820 if (entry->d_tag != DT_STRTAB)
7821 continue;
7822
7823 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7824
7825 /* Since we do not know how big the string table is,
7826 we default to reading in the entire file (!) and
7827 processing that. This is overkill, I know, but it
e3c8793a 7828 should work. */
252b5132 7829
d93f0186 7830 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7831
7832 if (archive_file_offset != 0)
7833 str_tab_len = archive_file_size - offset;
7834 else
7835 {
7836 if (fseek (file, 0, SEEK_END))
7837 error (_("Unable to seek to end of file\n"));
7838 str_tab_len = ftell (file) - offset;
7839 }
252b5132
RH
7840
7841 if (str_tab_len < 1)
7842 {
7843 error
7844 (_("Unable to determine the length of the dynamic string table\n"));
7845 continue;
7846 }
7847
3f5e193b
NC
7848 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7849 str_tab_len,
7850 _("dynamic string table"));
59245841 7851 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7852 break;
7853 }
7854 }
7855
7856 /* And find the syminfo section if available. */
7857 if (dynamic_syminfo == NULL)
7858 {
3e8bba36 7859 unsigned long syminsz = 0;
252b5132 7860
86dba8ee
AM
7861 for (entry = dynamic_section;
7862 entry < dynamic_section + dynamic_nent;
7863 ++entry)
252b5132
RH
7864 {
7865 if (entry->d_tag == DT_SYMINENT)
7866 {
7867 /* Note: these braces are necessary to avoid a syntax
7868 error from the SunOS4 C compiler. */
7869 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7870 }
7871 else if (entry->d_tag == DT_SYMINSZ)
7872 syminsz = entry->d_un.d_val;
7873 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7874 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7875 syminsz);
252b5132
RH
7876 }
7877
7878 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7879 {
2cf0635d
NC
7880 Elf_External_Syminfo * extsyminfo;
7881 Elf_External_Syminfo * extsym;
7882 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7883
7884 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7885 extsyminfo = (Elf_External_Syminfo *)
7886 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7887 _("symbol information"));
a6e9f9df
AM
7888 if (!extsyminfo)
7889 return 0;
252b5132 7890
3f5e193b 7891 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7892 if (dynamic_syminfo == NULL)
7893 {
7894 error (_("Out of memory\n"));
7895 return 0;
7896 }
7897
7898 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7899 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7900 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7901 ++syminfo, ++extsym)
252b5132 7902 {
86dba8ee
AM
7903 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7904 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7905 }
7906
7907 free (extsyminfo);
7908 }
7909 }
7910
7911 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7912 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7913 dynamic_addr, dynamic_nent);
252b5132
RH
7914 if (do_dynamic)
7915 printf (_(" Tag Type Name/Value\n"));
7916
86dba8ee
AM
7917 for (entry = dynamic_section;
7918 entry < dynamic_section + dynamic_nent;
7919 entry++)
252b5132
RH
7920 {
7921 if (do_dynamic)
f7a99963 7922 {
2cf0635d 7923 const char * dtype;
e699b9ff 7924
f7a99963
NC
7925 putchar (' ');
7926 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7927 dtype = get_dynamic_type (entry->d_tag);
7928 printf (" (%s)%*s", dtype,
7929 ((is_32bit_elf ? 27 : 19)
7930 - (int) strlen (dtype)),
f7a99963
NC
7931 " ");
7932 }
252b5132
RH
7933
7934 switch (entry->d_tag)
7935 {
d1133906
NC
7936 case DT_FLAGS:
7937 if (do_dynamic)
e9e44622 7938 print_dynamic_flags (entry->d_un.d_val);
d1133906 7939 break;
76da6bbe 7940
252b5132
RH
7941 case DT_AUXILIARY:
7942 case DT_FILTER:
019148e4
L
7943 case DT_CONFIG:
7944 case DT_DEPAUDIT:
7945 case DT_AUDIT:
252b5132
RH
7946 if (do_dynamic)
7947 {
019148e4 7948 switch (entry->d_tag)
b34976b6 7949 {
019148e4
L
7950 case DT_AUXILIARY:
7951 printf (_("Auxiliary library"));
7952 break;
7953
7954 case DT_FILTER:
7955 printf (_("Filter library"));
7956 break;
7957
b34976b6 7958 case DT_CONFIG:
019148e4
L
7959 printf (_("Configuration file"));
7960 break;
7961
7962 case DT_DEPAUDIT:
7963 printf (_("Dependency audit library"));
7964 break;
7965
7966 case DT_AUDIT:
7967 printf (_("Audit library"));
7968 break;
7969 }
252b5132 7970
d79b3d50
NC
7971 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7972 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7973 else
f7a99963
NC
7974 {
7975 printf (": ");
7976 print_vma (entry->d_un.d_val, PREFIX_HEX);
7977 putchar ('\n');
7978 }
252b5132
RH
7979 }
7980 break;
7981
dcefbbbd 7982 case DT_FEATURE:
252b5132
RH
7983 if (do_dynamic)
7984 {
7985 printf (_("Flags:"));
86f55779 7986
252b5132
RH
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 & DTF_1_PARINIT)
7994 {
7995 printf (" PARINIT");
7996 val ^= DTF_1_PARINIT;
7997 }
dcefbbbd
L
7998 if (val & DTF_1_CONFEXP)
7999 {
8000 printf (" CONFEXP");
8001 val ^= DTF_1_CONFEXP;
8002 }
252b5132
RH
8003 if (val != 0)
8004 printf (" %lx", val);
8005 puts ("");
8006 }
8007 }
8008 break;
8009
8010 case DT_POSFLAG_1:
8011 if (do_dynamic)
8012 {
8013 printf (_("Flags:"));
86f55779 8014
252b5132
RH
8015 if (entry->d_un.d_val == 0)
8016 printf (_(" None\n"));
8017 else
8018 {
8019 unsigned long int val = entry->d_un.d_val;
86f55779 8020
252b5132
RH
8021 if (val & DF_P1_LAZYLOAD)
8022 {
8023 printf (" LAZYLOAD");
8024 val ^= DF_P1_LAZYLOAD;
8025 }
8026 if (val & DF_P1_GROUPPERM)
8027 {
8028 printf (" GROUPPERM");
8029 val ^= DF_P1_GROUPPERM;
8030 }
8031 if (val != 0)
8032 printf (" %lx", val);
8033 puts ("");
8034 }
8035 }
8036 break;
8037
8038 case DT_FLAGS_1:
8039 if (do_dynamic)
8040 {
8041 printf (_("Flags:"));
8042 if (entry->d_un.d_val == 0)
8043 printf (_(" None\n"));
8044 else
8045 {
8046 unsigned long int val = entry->d_un.d_val;
86f55779 8047
252b5132
RH
8048 if (val & DF_1_NOW)
8049 {
8050 printf (" NOW");
8051 val ^= DF_1_NOW;
8052 }
8053 if (val & DF_1_GLOBAL)
8054 {
8055 printf (" GLOBAL");
8056 val ^= DF_1_GLOBAL;
8057 }
8058 if (val & DF_1_GROUP)
8059 {
8060 printf (" GROUP");
8061 val ^= DF_1_GROUP;
8062 }
8063 if (val & DF_1_NODELETE)
8064 {
8065 printf (" NODELETE");
8066 val ^= DF_1_NODELETE;
8067 }
8068 if (val & DF_1_LOADFLTR)
8069 {
8070 printf (" LOADFLTR");
8071 val ^= DF_1_LOADFLTR;
8072 }
8073 if (val & DF_1_INITFIRST)
8074 {
8075 printf (" INITFIRST");
8076 val ^= DF_1_INITFIRST;
8077 }
8078 if (val & DF_1_NOOPEN)
8079 {
8080 printf (" NOOPEN");
8081 val ^= DF_1_NOOPEN;
8082 }
8083 if (val & DF_1_ORIGIN)
8084 {
8085 printf (" ORIGIN");
8086 val ^= DF_1_ORIGIN;
8087 }
8088 if (val & DF_1_DIRECT)
8089 {
8090 printf (" DIRECT");
8091 val ^= DF_1_DIRECT;
8092 }
8093 if (val & DF_1_TRANS)
8094 {
8095 printf (" TRANS");
8096 val ^= DF_1_TRANS;
8097 }
8098 if (val & DF_1_INTERPOSE)
8099 {
8100 printf (" INTERPOSE");
8101 val ^= DF_1_INTERPOSE;
8102 }
f7db6139 8103 if (val & DF_1_NODEFLIB)
dcefbbbd 8104 {
f7db6139
L
8105 printf (" NODEFLIB");
8106 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8107 }
8108 if (val & DF_1_NODUMP)
8109 {
8110 printf (" NODUMP");
8111 val ^= DF_1_NODUMP;
8112 }
34b60028 8113 if (val & DF_1_CONFALT)
dcefbbbd 8114 {
34b60028
L
8115 printf (" CONFALT");
8116 val ^= DF_1_CONFALT;
8117 }
8118 if (val & DF_1_ENDFILTEE)
8119 {
8120 printf (" ENDFILTEE");
8121 val ^= DF_1_ENDFILTEE;
8122 }
8123 if (val & DF_1_DISPRELDNE)
8124 {
8125 printf (" DISPRELDNE");
8126 val ^= DF_1_DISPRELDNE;
8127 }
8128 if (val & DF_1_DISPRELPND)
8129 {
8130 printf (" DISPRELPND");
8131 val ^= DF_1_DISPRELPND;
8132 }
8133 if (val & DF_1_NODIRECT)
8134 {
8135 printf (" NODIRECT");
8136 val ^= DF_1_NODIRECT;
8137 }
8138 if (val & DF_1_IGNMULDEF)
8139 {
8140 printf (" IGNMULDEF");
8141 val ^= DF_1_IGNMULDEF;
8142 }
8143 if (val & DF_1_NOKSYMS)
8144 {
8145 printf (" NOKSYMS");
8146 val ^= DF_1_NOKSYMS;
8147 }
8148 if (val & DF_1_NOHDR)
8149 {
8150 printf (" NOHDR");
8151 val ^= DF_1_NOHDR;
8152 }
8153 if (val & DF_1_EDITED)
8154 {
8155 printf (" EDITED");
8156 val ^= DF_1_EDITED;
8157 }
8158 if (val & DF_1_NORELOC)
8159 {
8160 printf (" NORELOC");
8161 val ^= DF_1_NORELOC;
8162 }
8163 if (val & DF_1_SYMINTPOSE)
8164 {
8165 printf (" SYMINTPOSE");
8166 val ^= DF_1_SYMINTPOSE;
8167 }
8168 if (val & DF_1_GLOBAUDIT)
8169 {
8170 printf (" GLOBAUDIT");
8171 val ^= DF_1_GLOBAUDIT;
8172 }
8173 if (val & DF_1_SINGLETON)
8174 {
8175 printf (" SINGLETON");
8176 val ^= DF_1_SINGLETON;
dcefbbbd 8177 }
252b5132
RH
8178 if (val != 0)
8179 printf (" %lx", val);
8180 puts ("");
8181 }
8182 }
8183 break;
8184
8185 case DT_PLTREL:
566b0d53 8186 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8187 if (do_dynamic)
8188 puts (get_dynamic_type (entry->d_un.d_val));
8189 break;
8190
8191 case DT_NULL :
8192 case DT_NEEDED :
8193 case DT_PLTGOT :
8194 case DT_HASH :
8195 case DT_STRTAB :
8196 case DT_SYMTAB :
8197 case DT_RELA :
8198 case DT_INIT :
8199 case DT_FINI :
8200 case DT_SONAME :
8201 case DT_RPATH :
8202 case DT_SYMBOLIC:
8203 case DT_REL :
8204 case DT_DEBUG :
8205 case DT_TEXTREL :
8206 case DT_JMPREL :
019148e4 8207 case DT_RUNPATH :
252b5132
RH
8208 dynamic_info[entry->d_tag] = entry->d_un.d_val;
8209
8210 if (do_dynamic)
8211 {
2cf0635d 8212 char * name;
252b5132 8213
d79b3d50
NC
8214 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8215 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8216 else
d79b3d50 8217 name = NULL;
252b5132
RH
8218
8219 if (name)
8220 {
8221 switch (entry->d_tag)
8222 {
8223 case DT_NEEDED:
8224 printf (_("Shared library: [%s]"), name);
8225
18bd398b 8226 if (streq (name, program_interpreter))
f7a99963 8227 printf (_(" program interpreter"));
252b5132
RH
8228 break;
8229
8230 case DT_SONAME:
f7a99963 8231 printf (_("Library soname: [%s]"), name);
252b5132
RH
8232 break;
8233
8234 case DT_RPATH:
f7a99963 8235 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8236 break;
8237
019148e4
L
8238 case DT_RUNPATH:
8239 printf (_("Library runpath: [%s]"), name);
8240 break;
8241
252b5132 8242 default:
f7a99963
NC
8243 print_vma (entry->d_un.d_val, PREFIX_HEX);
8244 break;
252b5132
RH
8245 }
8246 }
8247 else
f7a99963
NC
8248 print_vma (entry->d_un.d_val, PREFIX_HEX);
8249
8250 putchar ('\n');
252b5132
RH
8251 }
8252 break;
8253
8254 case DT_PLTRELSZ:
8255 case DT_RELASZ :
8256 case DT_STRSZ :
8257 case DT_RELSZ :
8258 case DT_RELAENT :
8259 case DT_SYMENT :
8260 case DT_RELENT :
566b0d53 8261 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8262 case DT_PLTPADSZ:
8263 case DT_MOVEENT :
8264 case DT_MOVESZ :
8265 case DT_INIT_ARRAYSZ:
8266 case DT_FINI_ARRAYSZ:
047b2264
JJ
8267 case DT_GNU_CONFLICTSZ:
8268 case DT_GNU_LIBLISTSZ:
252b5132 8269 if (do_dynamic)
f7a99963
NC
8270 {
8271 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8272 printf (_(" (bytes)\n"));
f7a99963 8273 }
252b5132
RH
8274 break;
8275
8276 case DT_VERDEFNUM:
8277 case DT_VERNEEDNUM:
8278 case DT_RELACOUNT:
8279 case DT_RELCOUNT:
8280 if (do_dynamic)
f7a99963
NC
8281 {
8282 print_vma (entry->d_un.d_val, UNSIGNED);
8283 putchar ('\n');
8284 }
252b5132
RH
8285 break;
8286
8287 case DT_SYMINSZ:
8288 case DT_SYMINENT:
8289 case DT_SYMINFO:
8290 case DT_USED:
8291 case DT_INIT_ARRAY:
8292 case DT_FINI_ARRAY:
8293 if (do_dynamic)
8294 {
d79b3d50
NC
8295 if (entry->d_tag == DT_USED
8296 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8297 {
2cf0635d 8298 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8299
b34976b6 8300 if (*name)
252b5132
RH
8301 {
8302 printf (_("Not needed object: [%s]\n"), name);
8303 break;
8304 }
8305 }
103f02d3 8306
f7a99963
NC
8307 print_vma (entry->d_un.d_val, PREFIX_HEX);
8308 putchar ('\n');
252b5132
RH
8309 }
8310 break;
8311
8312 case DT_BIND_NOW:
8313 /* The value of this entry is ignored. */
35b1837e
AM
8314 if (do_dynamic)
8315 putchar ('\n');
252b5132 8316 break;
103f02d3 8317
047b2264
JJ
8318 case DT_GNU_PRELINKED:
8319 if (do_dynamic)
8320 {
2cf0635d 8321 struct tm * tmp;
91d6fa6a 8322 time_t atime = entry->d_un.d_val;
047b2264 8323
91d6fa6a 8324 tmp = gmtime (&atime);
047b2264
JJ
8325 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8326 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8327 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8328
8329 }
8330 break;
8331
fdc90cb4
JJ
8332 case DT_GNU_HASH:
8333 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8334 if (do_dynamic)
8335 {
8336 print_vma (entry->d_un.d_val, PREFIX_HEX);
8337 putchar ('\n');
8338 }
8339 break;
8340
252b5132
RH
8341 default:
8342 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8343 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8344 entry->d_un.d_val;
8345
8346 if (do_dynamic)
8347 {
8348 switch (elf_header.e_machine)
8349 {
8350 case EM_MIPS:
4fe85591 8351 case EM_MIPS_RS3_LE:
b2d38a17 8352 dynamic_section_mips_val (entry);
252b5132 8353 break;
103f02d3 8354 case EM_PARISC:
b2d38a17 8355 dynamic_section_parisc_val (entry);
103f02d3 8356 break;
ecc51f48 8357 case EM_IA_64:
b2d38a17 8358 dynamic_section_ia64_val (entry);
ecc51f48 8359 break;
252b5132 8360 default:
f7a99963
NC
8361 print_vma (entry->d_un.d_val, PREFIX_HEX);
8362 putchar ('\n');
252b5132
RH
8363 }
8364 }
8365 break;
8366 }
8367 }
8368
8369 return 1;
8370}
8371
8372static char *
d3ba0551 8373get_ver_flags (unsigned int flags)
252b5132 8374{
b34976b6 8375 static char buff[32];
252b5132
RH
8376
8377 buff[0] = 0;
8378
8379 if (flags == 0)
8380 return _("none");
8381
8382 if (flags & VER_FLG_BASE)
8383 strcat (buff, "BASE ");
8384
8385 if (flags & VER_FLG_WEAK)
8386 {
8387 if (flags & VER_FLG_BASE)
8388 strcat (buff, "| ");
8389
8390 strcat (buff, "WEAK ");
8391 }
8392
44ec90b9
RO
8393 if (flags & VER_FLG_INFO)
8394 {
8395 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8396 strcat (buff, "| ");
8397
8398 strcat (buff, "INFO ");
8399 }
8400
8401 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8402 strcat (buff, _("| <unknown>"));
252b5132
RH
8403
8404 return buff;
8405}
8406
8407/* Display the contents of the version sections. */
98fb390a 8408
252b5132 8409static int
2cf0635d 8410process_version_sections (FILE * file)
252b5132 8411{
2cf0635d 8412 Elf_Internal_Shdr * section;
b34976b6
AM
8413 unsigned i;
8414 int found = 0;
252b5132
RH
8415
8416 if (! do_version)
8417 return 1;
8418
8419 for (i = 0, section = section_headers;
8420 i < elf_header.e_shnum;
b34976b6 8421 i++, section++)
252b5132
RH
8422 {
8423 switch (section->sh_type)
8424 {
8425 case SHT_GNU_verdef:
8426 {
2cf0635d 8427 Elf_External_Verdef * edefs;
b34976b6
AM
8428 unsigned int idx;
8429 unsigned int cnt;
2cf0635d 8430 char * endbuf;
252b5132
RH
8431
8432 found = 1;
8433
8434 printf
72de5009 8435 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8436 SECTION_NAME (section), section->sh_info);
8437
8438 printf (_(" Addr: 0x"));
8439 printf_vma (section->sh_addr);
72de5009 8440 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8441 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8442 section->sh_link < elf_header.e_shnum
8443 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8444 : _("<corrupt>"));
252b5132 8445
3f5e193b
NC
8446 edefs = (Elf_External_Verdef *)
8447 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8448 _("version definition section"));
a6e9f9df
AM
8449 if (!edefs)
8450 break;
59245841 8451 endbuf = (char *) edefs + section->sh_size;
252b5132 8452
b34976b6 8453 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8454 {
2cf0635d
NC
8455 char * vstart;
8456 Elf_External_Verdef * edef;
b34976b6 8457 Elf_Internal_Verdef ent;
2cf0635d 8458 Elf_External_Verdaux * eaux;
b34976b6
AM
8459 Elf_Internal_Verdaux aux;
8460 int j;
8461 int isum;
103f02d3 8462
dd24e3da
NC
8463 /* Check for negative or very large indicies. */
8464 if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
8465 break;
8466
252b5132 8467 vstart = ((char *) edefs) + idx;
54806181
AM
8468 if (vstart + sizeof (*edef) > endbuf)
8469 break;
252b5132
RH
8470
8471 edef = (Elf_External_Verdef *) vstart;
8472
8473 ent.vd_version = BYTE_GET (edef->vd_version);
8474 ent.vd_flags = BYTE_GET (edef->vd_flags);
8475 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8476 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8477 ent.vd_hash = BYTE_GET (edef->vd_hash);
8478 ent.vd_aux = BYTE_GET (edef->vd_aux);
8479 ent.vd_next = BYTE_GET (edef->vd_next);
8480
8481 printf (_(" %#06x: Rev: %d Flags: %s"),
8482 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8483
8484 printf (_(" Index: %d Cnt: %d "),
8485 ent.vd_ndx, ent.vd_cnt);
8486
dd24e3da
NC
8487 /* Check for overflow. */
8488 if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
8489 || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
8490 break;
8491
252b5132
RH
8492 vstart += ent.vd_aux;
8493
8494 eaux = (Elf_External_Verdaux *) vstart;
8495
8496 aux.vda_name = BYTE_GET (eaux->vda_name);
8497 aux.vda_next = BYTE_GET (eaux->vda_next);
8498
d79b3d50
NC
8499 if (VALID_DYNAMIC_NAME (aux.vda_name))
8500 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8501 else
8502 printf (_("Name index: %ld\n"), aux.vda_name);
8503
8504 isum = idx + ent.vd_aux;
8505
b34976b6 8506 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8507 {
dd24e3da
NC
8508 /* Check for overflow. */
8509 if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
8510 || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
8511 break;
8512
252b5132
RH
8513 isum += aux.vda_next;
8514 vstart += aux.vda_next;
8515
8516 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8517 if (vstart + sizeof (*eaux) > endbuf)
8518 break;
252b5132
RH
8519
8520 aux.vda_name = BYTE_GET (eaux->vda_name);
8521 aux.vda_next = BYTE_GET (eaux->vda_next);
8522
d79b3d50 8523 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8524 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8525 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8526 else
8527 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8528 isum, j, aux.vda_name);
8529 }
dd24e3da 8530
54806181
AM
8531 if (j < ent.vd_cnt)
8532 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8533
8534 idx += ent.vd_next;
8535 }
dd24e3da 8536
54806181
AM
8537 if (cnt < section->sh_info)
8538 printf (_(" Version definition past end of section\n"));
252b5132
RH
8539
8540 free (edefs);
8541 }
8542 break;
103f02d3 8543
252b5132
RH
8544 case SHT_GNU_verneed:
8545 {
2cf0635d 8546 Elf_External_Verneed * eneed;
b34976b6
AM
8547 unsigned int idx;
8548 unsigned int cnt;
2cf0635d 8549 char * endbuf;
252b5132
RH
8550
8551 found = 1;
8552
72de5009 8553 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8554 SECTION_NAME (section), section->sh_info);
8555
8556 printf (_(" Addr: 0x"));
8557 printf_vma (section->sh_addr);
72de5009 8558 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8559 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8560 section->sh_link < elf_header.e_shnum
8561 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8562 : _("<corrupt>"));
252b5132 8563
3f5e193b
NC
8564 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8565 section->sh_offset, 1,
8566 section->sh_size,
9cf03b7e 8567 _("Version Needs section"));
a6e9f9df
AM
8568 if (!eneed)
8569 break;
59245841 8570 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8571
8572 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8573 {
2cf0635d 8574 Elf_External_Verneed * entry;
b34976b6
AM
8575 Elf_Internal_Verneed ent;
8576 int j;
8577 int isum;
2cf0635d 8578 char * vstart;
252b5132 8579
dd24e3da
NC
8580 if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
8581 break;
8582
252b5132 8583 vstart = ((char *) eneed) + idx;
54806181
AM
8584 if (vstart + sizeof (*entry) > endbuf)
8585 break;
252b5132
RH
8586
8587 entry = (Elf_External_Verneed *) vstart;
8588
8589 ent.vn_version = BYTE_GET (entry->vn_version);
8590 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8591 ent.vn_file = BYTE_GET (entry->vn_file);
8592 ent.vn_aux = BYTE_GET (entry->vn_aux);
8593 ent.vn_next = BYTE_GET (entry->vn_next);
8594
8595 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8596
d79b3d50
NC
8597 if (VALID_DYNAMIC_NAME (ent.vn_file))
8598 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8599 else
8600 printf (_(" File: %lx"), ent.vn_file);
8601
8602 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8603
dd24e3da
NC
8604 /* Check for overflow. */
8605 if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
8606 || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
8607 break;
8608
252b5132
RH
8609 vstart += ent.vn_aux;
8610
8611 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8612 {
2cf0635d 8613 Elf_External_Vernaux * eaux;
b34976b6 8614 Elf_Internal_Vernaux aux;
252b5132 8615
54806181
AM
8616 if (vstart + sizeof (*eaux) > endbuf)
8617 break;
252b5132
RH
8618 eaux = (Elf_External_Vernaux *) vstart;
8619
8620 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8621 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8622 aux.vna_other = BYTE_GET (eaux->vna_other);
8623 aux.vna_name = BYTE_GET (eaux->vna_name);
8624 aux.vna_next = BYTE_GET (eaux->vna_next);
8625
d79b3d50 8626 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8627 printf (_(" %#06x: Name: %s"),
d79b3d50 8628 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8629 else
ecc2063b 8630 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8631 isum, aux.vna_name);
8632
8633 printf (_(" Flags: %s Version: %d\n"),
8634 get_ver_flags (aux.vna_flags), aux.vna_other);
8635
dd24e3da
NC
8636 /* Check for overflow. */
8637 if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
8638 || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
8639 break;
8640
252b5132
RH
8641 isum += aux.vna_next;
8642 vstart += aux.vna_next;
8643 }
9cf03b7e 8644
54806181 8645 if (j < ent.vn_cnt)
9cf03b7e 8646 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8647
8648 idx += ent.vn_next;
8649 }
9cf03b7e 8650
54806181 8651 if (cnt < section->sh_info)
9cf03b7e 8652 warn (_("Missing Version Needs information\n"));
103f02d3 8653
252b5132
RH
8654 free (eneed);
8655 }
8656 break;
8657
8658 case SHT_GNU_versym:
8659 {
2cf0635d 8660 Elf_Internal_Shdr * link_section;
b34976b6
AM
8661 int total;
8662 int cnt;
2cf0635d
NC
8663 unsigned char * edata;
8664 unsigned short * data;
8665 char * strtab;
8666 Elf_Internal_Sym * symbols;
8667 Elf_Internal_Shdr * string_sec;
ba5cdace 8668 unsigned long num_syms;
d3ba0551 8669 long off;
252b5132 8670
4fbb74a6 8671 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8672 break;
8673
4fbb74a6 8674 link_section = section_headers + section->sh_link;
08d8fa11 8675 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8676
4fbb74a6 8677 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8678 break;
8679
252b5132
RH
8680 found = 1;
8681
ba5cdace 8682 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
8683 if (symbols == NULL)
8684 break;
252b5132 8685
4fbb74a6 8686 string_sec = section_headers + link_section->sh_link;
252b5132 8687
3f5e193b
NC
8688 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8689 string_sec->sh_size,
8690 _("version string table"));
a6e9f9df 8691 if (!strtab)
0429c154
MS
8692 {
8693 free (symbols);
8694 break;
8695 }
252b5132
RH
8696
8697 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8698 SECTION_NAME (section), total);
8699
8700 printf (_(" Addr: "));
8701 printf_vma (section->sh_addr);
72de5009 8702 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8703 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8704 SECTION_NAME (link_section));
8705
d3ba0551
AM
8706 off = offset_from_vma (file,
8707 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8708 total * sizeof (short));
3f5e193b
NC
8709 edata = (unsigned char *) get_data (NULL, file, off, total,
8710 sizeof (short),
8711 _("version symbol data"));
a6e9f9df
AM
8712 if (!edata)
8713 {
8714 free (strtab);
0429c154 8715 free (symbols);
a6e9f9df
AM
8716 break;
8717 }
252b5132 8718
3f5e193b 8719 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8720
8721 for (cnt = total; cnt --;)
b34976b6
AM
8722 data[cnt] = byte_get (edata + cnt * sizeof (short),
8723 sizeof (short));
252b5132
RH
8724
8725 free (edata);
8726
8727 for (cnt = 0; cnt < total; cnt += 4)
8728 {
8729 int j, nn;
00d93f34 8730 int check_def, check_need;
2cf0635d 8731 char * name;
252b5132
RH
8732
8733 printf (" %03x:", cnt);
8734
8735 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8736 switch (data[cnt + j])
252b5132
RH
8737 {
8738 case 0:
8739 fputs (_(" 0 (*local*) "), stdout);
8740 break;
8741
8742 case 1:
8743 fputs (_(" 1 (*global*) "), stdout);
8744 break;
8745
8746 default:
c244d050
NC
8747 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8748 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8749
dd24e3da 8750 /* If this index value is greater than the size of the symbols
ba5cdace
NC
8751 array, break to avoid an out-of-bounds read. */
8752 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
8753 {
8754 warn (_("invalid index into symbol array\n"));
8755 break;
8756 }
8757
00d93f34
JJ
8758 check_def = 1;
8759 check_need = 1;
4fbb74a6
AM
8760 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8761 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8762 != SHT_NOBITS)
252b5132 8763 {
b34976b6 8764 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8765 check_def = 0;
8766 else
8767 check_need = 0;
252b5132 8768 }
00d93f34
JJ
8769
8770 if (check_need
b34976b6 8771 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8772 {
b34976b6
AM
8773 Elf_Internal_Verneed ivn;
8774 unsigned long offset;
252b5132 8775
d93f0186
NC
8776 offset = offset_from_vma
8777 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8778 sizeof (Elf_External_Verneed));
252b5132 8779
b34976b6 8780 do
252b5132 8781 {
b34976b6
AM
8782 Elf_Internal_Vernaux ivna;
8783 Elf_External_Verneed evn;
8784 Elf_External_Vernaux evna;
8785 unsigned long a_off;
252b5132 8786
59245841
NC
8787 if (get_data (&evn, file, offset, sizeof (evn), 1,
8788 _("version need")) == NULL)
8789 break;
8790
252b5132
RH
8791 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8792 ivn.vn_next = BYTE_GET (evn.vn_next);
8793
8794 a_off = offset + ivn.vn_aux;
8795
8796 do
8797 {
59245841
NC
8798 if (get_data (&evna, file, a_off, sizeof (evna),
8799 1, _("version need aux (2)")) == NULL)
8800 {
8801 ivna.vna_next = 0;
8802 ivna.vna_other = 0;
8803 }
8804 else
8805 {
8806 ivna.vna_next = BYTE_GET (evna.vna_next);
8807 ivna.vna_other = BYTE_GET (evna.vna_other);
8808 }
252b5132
RH
8809
8810 a_off += ivna.vna_next;
8811 }
b34976b6 8812 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8813 && ivna.vna_next != 0);
8814
b34976b6 8815 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8816 {
8817 ivna.vna_name = BYTE_GET (evna.vna_name);
8818
54806181
AM
8819 if (ivna.vna_name >= string_sec->sh_size)
8820 name = _("*invalid*");
8821 else
8822 name = strtab + ivna.vna_name;
252b5132 8823 nn += printf ("(%s%-*s",
16062207
ILT
8824 name,
8825 12 - (int) strlen (name),
252b5132 8826 ")");
00d93f34 8827 check_def = 0;
252b5132
RH
8828 break;
8829 }
8830
8831 offset += ivn.vn_next;
8832 }
8833 while (ivn.vn_next);
8834 }
00d93f34 8835
b34976b6
AM
8836 if (check_def && data[cnt + j] != 0x8001
8837 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8838 {
b34976b6
AM
8839 Elf_Internal_Verdef ivd;
8840 Elf_External_Verdef evd;
8841 unsigned long offset;
252b5132 8842
d93f0186
NC
8843 offset = offset_from_vma
8844 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8845 sizeof evd);
252b5132
RH
8846
8847 do
8848 {
59245841
NC
8849 if (get_data (&evd, file, offset, sizeof (evd), 1,
8850 _("version def")) == NULL)
8851 {
8852 ivd.vd_next = 0;
8853 ivd.vd_ndx = 0;
8854 }
8855 else
8856 {
8857 ivd.vd_next = BYTE_GET (evd.vd_next);
8858 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8859 }
252b5132
RH
8860
8861 offset += ivd.vd_next;
8862 }
c244d050 8863 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8864 && ivd.vd_next != 0);
8865
c244d050 8866 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8867 {
b34976b6
AM
8868 Elf_External_Verdaux evda;
8869 Elf_Internal_Verdaux ivda;
252b5132
RH
8870
8871 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8872
59245841
NC
8873 if (get_data (&evda, file,
8874 offset - ivd.vd_next + ivd.vd_aux,
8875 sizeof (evda), 1,
8876 _("version def aux")) == NULL)
8877 break;
252b5132
RH
8878
8879 ivda.vda_name = BYTE_GET (evda.vda_name);
8880
54806181
AM
8881 if (ivda.vda_name >= string_sec->sh_size)
8882 name = _("*invalid*");
8883 else
8884 name = strtab + ivda.vda_name;
252b5132 8885 nn += printf ("(%s%-*s",
16062207
ILT
8886 name,
8887 12 - (int) strlen (name),
252b5132
RH
8888 ")");
8889 }
8890 }
8891
8892 if (nn < 18)
8893 printf ("%*c", 18 - nn, ' ');
8894 }
8895
8896 putchar ('\n');
8897 }
8898
8899 free (data);
8900 free (strtab);
8901 free (symbols);
8902 }
8903 break;
103f02d3 8904
252b5132
RH
8905 default:
8906 break;
8907 }
8908 }
8909
8910 if (! found)
8911 printf (_("\nNo version information found in this file.\n"));
8912
8913 return 1;
8914}
8915
d1133906 8916static const char *
d3ba0551 8917get_symbol_binding (unsigned int binding)
252b5132 8918{
b34976b6 8919 static char buff[32];
252b5132
RH
8920
8921 switch (binding)
8922 {
b34976b6
AM
8923 case STB_LOCAL: return "LOCAL";
8924 case STB_GLOBAL: return "GLOBAL";
8925 case STB_WEAK: return "WEAK";
252b5132
RH
8926 default:
8927 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8928 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8929 binding);
252b5132 8930 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8931 {
8932 if (binding == STB_GNU_UNIQUE
9c55345c
TS
8933 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8934 /* GNU is still using the default value 0. */
3e7a7d11
NC
8935 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8936 return "UNIQUE";
8937 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8938 }
252b5132 8939 else
e9e44622 8940 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8941 return buff;
8942 }
8943}
8944
d1133906 8945static const char *
d3ba0551 8946get_symbol_type (unsigned int type)
252b5132 8947{
b34976b6 8948 static char buff[32];
252b5132
RH
8949
8950 switch (type)
8951 {
b34976b6
AM
8952 case STT_NOTYPE: return "NOTYPE";
8953 case STT_OBJECT: return "OBJECT";
8954 case STT_FUNC: return "FUNC";
8955 case STT_SECTION: return "SECTION";
8956 case STT_FILE: return "FILE";
8957 case STT_COMMON: return "COMMON";
8958 case STT_TLS: return "TLS";
15ab5209
DB
8959 case STT_RELC: return "RELC";
8960 case STT_SRELC: return "SRELC";
252b5132
RH
8961 default:
8962 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8963 {
8964 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8965 return "THUMB_FUNC";
8966
351b4b40 8967 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8968 return "REGISTER";
8969
8970 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8971 return "PARISC_MILLI";
8972
e9e44622 8973 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8974 }
252b5132 8975 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8976 {
8977 if (elf_header.e_machine == EM_PARISC)
8978 {
8979 if (type == STT_HP_OPAQUE)
8980 return "HP_OPAQUE";
8981 if (type == STT_HP_STUB)
8982 return "HP_STUB";
8983 }
8984
d8045f23 8985 if (type == STT_GNU_IFUNC
9c55345c 8986 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 8987 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 8988 /* GNU is still using the default value 0. */
d8045f23
NC
8989 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8990 return "IFUNC";
8991
e9e44622 8992 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8993 }
252b5132 8994 else
e9e44622 8995 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8996 return buff;
8997 }
8998}
8999
d1133906 9000static const char *
d3ba0551 9001get_symbol_visibility (unsigned int visibility)
d1133906
NC
9002{
9003 switch (visibility)
9004 {
b34976b6
AM
9005 case STV_DEFAULT: return "DEFAULT";
9006 case STV_INTERNAL: return "INTERNAL";
9007 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
9008 case STV_PROTECTED: return "PROTECTED";
9009 default: abort ();
9010 }
9011}
9012
5e2b0d47
NC
9013static const char *
9014get_mips_symbol_other (unsigned int other)
9015{
9016 switch (other)
9017 {
df58fc94
RS
9018 case STO_OPTIONAL:
9019 return "OPTIONAL";
9020 case STO_MIPS_PLT:
9021 return "MIPS PLT";
9022 case STO_MIPS_PIC:
9023 return "MIPS PIC";
9024 case STO_MICROMIPS:
9025 return "MICROMIPS";
9026 case STO_MICROMIPS | STO_MIPS_PIC:
9027 return "MICROMIPS, MIPS PIC";
9028 case STO_MIPS16:
9029 return "MIPS16";
9030 default:
9031 return NULL;
5e2b0d47
NC
9032 }
9033}
9034
28f997cf
TG
9035static const char *
9036get_ia64_symbol_other (unsigned int other)
9037{
9038 if (is_ia64_vms ())
9039 {
9040 static char res[32];
9041
9042 res[0] = 0;
9043
9044 /* Function types is for images and .STB files only. */
9045 switch (elf_header.e_type)
9046 {
9047 case ET_DYN:
9048 case ET_EXEC:
9049 switch (VMS_ST_FUNC_TYPE (other))
9050 {
9051 case VMS_SFT_CODE_ADDR:
9052 strcat (res, " CA");
9053 break;
9054 case VMS_SFT_SYMV_IDX:
9055 strcat (res, " VEC");
9056 break;
9057 case VMS_SFT_FD:
9058 strcat (res, " FD");
9059 break;
9060 case VMS_SFT_RESERVE:
9061 strcat (res, " RSV");
9062 break;
9063 default:
9064 abort ();
9065 }
9066 break;
9067 default:
9068 break;
9069 }
9070 switch (VMS_ST_LINKAGE (other))
9071 {
9072 case VMS_STL_IGNORE:
9073 strcat (res, " IGN");
9074 break;
9075 case VMS_STL_RESERVE:
9076 strcat (res, " RSV");
9077 break;
9078 case VMS_STL_STD:
9079 strcat (res, " STD");
9080 break;
9081 case VMS_STL_LNK:
9082 strcat (res, " LNK");
9083 break;
9084 default:
9085 abort ();
9086 }
9087
9088 if (res[0] != 0)
9089 return res + 1;
9090 else
9091 return res;
9092 }
9093 return NULL;
9094}
9095
5e2b0d47
NC
9096static const char *
9097get_symbol_other (unsigned int other)
9098{
9099 const char * result = NULL;
9100 static char buff [32];
9101
9102 if (other == 0)
9103 return "";
9104
9105 switch (elf_header.e_machine)
9106 {
9107 case EM_MIPS:
9108 result = get_mips_symbol_other (other);
28f997cf
TG
9109 break;
9110 case EM_IA_64:
9111 result = get_ia64_symbol_other (other);
9112 break;
5e2b0d47
NC
9113 default:
9114 break;
9115 }
9116
9117 if (result)
9118 return result;
9119
9120 snprintf (buff, sizeof buff, _("<other>: %x"), other);
9121 return buff;
9122}
9123
d1133906 9124static const char *
d3ba0551 9125get_symbol_index_type (unsigned int type)
252b5132 9126{
b34976b6 9127 static char buff[32];
5cf1065c 9128
252b5132
RH
9129 switch (type)
9130 {
b34976b6
AM
9131 case SHN_UNDEF: return "UND";
9132 case SHN_ABS: return "ABS";
9133 case SHN_COMMON: return "COM";
252b5132 9134 default:
9ce701e2
L
9135 if (type == SHN_IA_64_ANSI_COMMON
9136 && elf_header.e_machine == EM_IA_64
9137 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
9138 return "ANSI_COM";
8a9036a4 9139 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
9140 || elf_header.e_machine == EM_L1OM
9141 || elf_header.e_machine == EM_K1OM)
3b22753a
L
9142 && type == SHN_X86_64_LCOMMON)
9143 return "LARGE_COM";
ac145307
BS
9144 else if ((type == SHN_MIPS_SCOMMON
9145 && elf_header.e_machine == EM_MIPS)
9146 || (type == SHN_TIC6X_SCOMMON
9147 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
9148 return "SCOM";
9149 else if (type == SHN_MIPS_SUNDEFINED
9150 && elf_header.e_machine == EM_MIPS)
9151 return "SUND";
9ce701e2 9152 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 9153 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 9154 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
9155 sprintf (buff, "OS [0x%04x]", type & 0xffff);
9156 else if (type >= SHN_LORESERVE)
9157 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4
L
9158 else if (type >= elf_header.e_shnum)
9159 sprintf (buff, "bad section index[%3d]", type);
252b5132 9160 else
232e7cb8 9161 sprintf (buff, "%3d", type);
5cf1065c 9162 break;
252b5132 9163 }
5cf1065c
NC
9164
9165 return buff;
252b5132
RH
9166}
9167
66543521 9168static bfd_vma *
2cf0635d 9169get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 9170{
2cf0635d
NC
9171 unsigned char * e_data;
9172 bfd_vma * i_data;
252b5132 9173
3f5e193b 9174 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
9175
9176 if (e_data == NULL)
9177 {
9178 error (_("Out of memory\n"));
9179 return NULL;
9180 }
9181
66543521 9182 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
9183 {
9184 error (_("Unable to read in dynamic data\n"));
9185 return NULL;
9186 }
9187
3f5e193b 9188 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
9189
9190 if (i_data == NULL)
9191 {
9192 error (_("Out of memory\n"));
9193 free (e_data);
9194 return NULL;
9195 }
9196
9197 while (number--)
66543521 9198 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
9199
9200 free (e_data);
9201
9202 return i_data;
9203}
9204
6bd1a22c
L
9205static void
9206print_dynamic_symbol (bfd_vma si, unsigned long hn)
9207{
2cf0635d 9208 Elf_Internal_Sym * psym;
6bd1a22c
L
9209 int n;
9210
9211 psym = dynamic_symbols + si;
9212
9213 n = print_vma (si, DEC_5);
9214 if (n < 5)
9215 fputs (" " + n, stdout);
9216 printf (" %3lu: ", hn);
9217 print_vma (psym->st_value, LONG_HEX);
9218 putchar (' ');
9219 print_vma (psym->st_size, DEC_5);
9220
f4be36b3
AM
9221 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9222 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9223 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9224 /* Check to see if any other bits in the st_other field are set.
9225 Note - displaying this information disrupts the layout of the
9226 table being generated, but for the moment this case is very
9227 rare. */
9228 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9229 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9230 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9231 if (VALID_DYNAMIC_NAME (psym->st_name))
9232 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9233 else
2b692964 9234 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9235 putchar ('\n');
9236}
9237
e3c8793a 9238/* Dump the symbol table. */
252b5132 9239static int
2cf0635d 9240process_symbol_table (FILE * file)
252b5132 9241{
2cf0635d 9242 Elf_Internal_Shdr * section;
66543521
AM
9243 bfd_vma nbuckets = 0;
9244 bfd_vma nchains = 0;
2cf0635d
NC
9245 bfd_vma * buckets = NULL;
9246 bfd_vma * chains = NULL;
fdc90cb4 9247 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9248 bfd_vma * gnubuckets = NULL;
9249 bfd_vma * gnuchains = NULL;
6bd1a22c 9250 bfd_vma gnusymidx = 0;
252b5132 9251
2c610e4b 9252 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9253 return 1;
9254
6bd1a22c
L
9255 if (dynamic_info[DT_HASH]
9256 && (do_histogram
2c610e4b
L
9257 || (do_using_dynamic
9258 && !do_dyn_syms
9259 && dynamic_strings != NULL)))
252b5132 9260 {
66543521
AM
9261 unsigned char nb[8];
9262 unsigned char nc[8];
9263 int hash_ent_size = 4;
9264
9265 if ((elf_header.e_machine == EM_ALPHA
9266 || elf_header.e_machine == EM_S390
9267 || elf_header.e_machine == EM_S390_OLD)
9268 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9269 hash_ent_size = 8;
9270
fb52b2f4
NC
9271 if (fseek (file,
9272 (archive_file_offset
9273 + offset_from_vma (file, dynamic_info[DT_HASH],
9274 sizeof nb + sizeof nc)),
d93f0186 9275 SEEK_SET))
252b5132 9276 {
591a748a 9277 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9278 goto no_hash;
252b5132
RH
9279 }
9280
66543521 9281 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9282 {
9283 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9284 goto no_hash;
252b5132
RH
9285 }
9286
66543521 9287 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9288 {
9289 error (_("Failed to read in number of chains\n"));
d3a44ec6 9290 goto no_hash;
252b5132
RH
9291 }
9292
66543521
AM
9293 nbuckets = byte_get (nb, hash_ent_size);
9294 nchains = byte_get (nc, hash_ent_size);
252b5132 9295
66543521
AM
9296 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9297 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9298
d3a44ec6 9299 no_hash:
252b5132 9300 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9301 {
9302 if (do_using_dynamic)
9303 return 0;
9304 free (buckets);
9305 free (chains);
9306 buckets = NULL;
9307 chains = NULL;
9308 nbuckets = 0;
9309 nchains = 0;
9310 }
252b5132
RH
9311 }
9312
6bd1a22c
L
9313 if (dynamic_info_DT_GNU_HASH
9314 && (do_histogram
2c610e4b
L
9315 || (do_using_dynamic
9316 && !do_dyn_syms
9317 && dynamic_strings != NULL)))
252b5132 9318 {
6bd1a22c
L
9319 unsigned char nb[16];
9320 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9321 bfd_vma buckets_vma;
9322
9323 if (fseek (file,
9324 (archive_file_offset
9325 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9326 sizeof nb)),
9327 SEEK_SET))
9328 {
9329 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9330 goto no_gnu_hash;
6bd1a22c 9331 }
252b5132 9332
6bd1a22c
L
9333 if (fread (nb, 16, 1, file) != 1)
9334 {
9335 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9336 goto no_gnu_hash;
6bd1a22c
L
9337 }
9338
9339 ngnubuckets = byte_get (nb, 4);
9340 gnusymidx = byte_get (nb + 4, 4);
9341 bitmaskwords = byte_get (nb + 8, 4);
9342 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9343 if (is_32bit_elf)
6bd1a22c 9344 buckets_vma += bitmaskwords * 4;
f7a99963 9345 else
6bd1a22c 9346 buckets_vma += bitmaskwords * 8;
252b5132 9347
6bd1a22c
L
9348 if (fseek (file,
9349 (archive_file_offset
9350 + offset_from_vma (file, buckets_vma, 4)),
9351 SEEK_SET))
252b5132 9352 {
6bd1a22c 9353 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9354 goto no_gnu_hash;
6bd1a22c
L
9355 }
9356
9357 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9358
6bd1a22c 9359 if (gnubuckets == NULL)
d3a44ec6 9360 goto no_gnu_hash;
6bd1a22c
L
9361
9362 for (i = 0; i < ngnubuckets; i++)
9363 if (gnubuckets[i] != 0)
9364 {
9365 if (gnubuckets[i] < gnusymidx)
9366 return 0;
9367
9368 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9369 maxchain = gnubuckets[i];
9370 }
9371
9372 if (maxchain == 0xffffffff)
d3a44ec6 9373 goto no_gnu_hash;
6bd1a22c
L
9374
9375 maxchain -= gnusymidx;
9376
9377 if (fseek (file,
9378 (archive_file_offset
9379 + offset_from_vma (file, buckets_vma
9380 + 4 * (ngnubuckets + maxchain), 4)),
9381 SEEK_SET))
9382 {
9383 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9384 goto no_gnu_hash;
6bd1a22c
L
9385 }
9386
9387 do
9388 {
9389 if (fread (nb, 4, 1, file) != 1)
252b5132 9390 {
6bd1a22c 9391 error (_("Failed to determine last chain length\n"));
d3a44ec6 9392 goto no_gnu_hash;
6bd1a22c 9393 }
252b5132 9394
6bd1a22c 9395 if (maxchain + 1 == 0)
d3a44ec6 9396 goto no_gnu_hash;
252b5132 9397
6bd1a22c
L
9398 ++maxchain;
9399 }
9400 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9401
6bd1a22c
L
9402 if (fseek (file,
9403 (archive_file_offset
9404 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9405 SEEK_SET))
9406 {
9407 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9408 goto no_gnu_hash;
6bd1a22c
L
9409 }
9410
9411 gnuchains = get_dynamic_data (file, maxchain, 4);
9412
d3a44ec6 9413 no_gnu_hash:
6bd1a22c 9414 if (gnuchains == NULL)
d3a44ec6
JJ
9415 {
9416 free (gnubuckets);
d3a44ec6
JJ
9417 gnubuckets = NULL;
9418 ngnubuckets = 0;
f64fddf1
NC
9419 if (do_using_dynamic)
9420 return 0;
d3a44ec6 9421 }
6bd1a22c
L
9422 }
9423
9424 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9425 && do_syms
9426 && do_using_dynamic
9427 && dynamic_strings != NULL)
9428 {
9429 unsigned long hn;
9430
9431 if (dynamic_info[DT_HASH])
9432 {
9433 bfd_vma si;
9434
9435 printf (_("\nSymbol table for image:\n"));
9436 if (is_32bit_elf)
9437 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9438 else
9439 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9440
9441 for (hn = 0; hn < nbuckets; hn++)
9442 {
9443 if (! buckets[hn])
9444 continue;
9445
9446 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9447 print_dynamic_symbol (si, hn);
252b5132
RH
9448 }
9449 }
6bd1a22c
L
9450
9451 if (dynamic_info_DT_GNU_HASH)
9452 {
9453 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9454 if (is_32bit_elf)
9455 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9456 else
9457 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9458
9459 for (hn = 0; hn < ngnubuckets; ++hn)
9460 if (gnubuckets[hn] != 0)
9461 {
9462 bfd_vma si = gnubuckets[hn];
9463 bfd_vma off = si - gnusymidx;
9464
9465 do
9466 {
9467 print_dynamic_symbol (si, hn);
9468 si++;
9469 }
9470 while ((gnuchains[off++] & 1) == 0);
9471 }
9472 }
252b5132 9473 }
2c610e4b 9474 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9475 {
b34976b6 9476 unsigned int i;
252b5132
RH
9477
9478 for (i = 0, section = section_headers;
9479 i < elf_header.e_shnum;
9480 i++, section++)
9481 {
b34976b6 9482 unsigned int si;
2cf0635d 9483 char * strtab = NULL;
c256ffe7 9484 unsigned long int strtab_size = 0;
2cf0635d
NC
9485 Elf_Internal_Sym * symtab;
9486 Elf_Internal_Sym * psym;
ba5cdace 9487 unsigned long num_syms;
252b5132 9488
2c610e4b
L
9489 if ((section->sh_type != SHT_SYMTAB
9490 && section->sh_type != SHT_DYNSYM)
9491 || (!do_syms
9492 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9493 continue;
9494
dd24e3da
NC
9495 if (section->sh_entsize == 0)
9496 {
9497 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9498 SECTION_NAME (section));
9499 continue;
9500 }
9501
252b5132
RH
9502 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9503 SECTION_NAME (section),
9504 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9505
f7a99963 9506 if (is_32bit_elf)
ca47b30c 9507 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9508 else
ca47b30c 9509 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9510
ba5cdace 9511 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9512 if (symtab == NULL)
9513 continue;
9514
9515 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9516 {
9517 strtab = string_table;
9518 strtab_size = string_table_length;
9519 }
4fbb74a6 9520 else if (section->sh_link < elf_header.e_shnum)
252b5132 9521 {
2cf0635d 9522 Elf_Internal_Shdr * string_sec;
252b5132 9523
4fbb74a6 9524 string_sec = section_headers + section->sh_link;
252b5132 9525
3f5e193b
NC
9526 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9527 1, string_sec->sh_size,
9528 _("string table"));
c256ffe7 9529 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9530 }
9531
ba5cdace 9532 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9533 {
5e220199 9534 printf ("%6d: ", si);
f7a99963
NC
9535 print_vma (psym->st_value, LONG_HEX);
9536 putchar (' ');
9537 print_vma (psym->st_size, DEC_5);
d1133906
NC
9538 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9539 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9540 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9541 /* Check to see if any other bits in the st_other field are set.
9542 Note - displaying this information disrupts the layout of the
9543 table being generated, but for the moment this case is very rare. */
9544 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9545 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9546 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9547 print_symbol (25, psym->st_name < strtab_size
2b692964 9548 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9549
59245841
NC
9550 if (section->sh_type == SHT_DYNSYM
9551 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9552 {
b34976b6
AM
9553 unsigned char data[2];
9554 unsigned short vers_data;
9555 unsigned long offset;
9556 int is_nobits;
9557 int check_def;
252b5132 9558
d93f0186
NC
9559 offset = offset_from_vma
9560 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9561 sizeof data + si * sizeof (vers_data));
252b5132 9562
59245841
NC
9563 if (get_data (&data, file, offset + si * sizeof (vers_data),
9564 sizeof (data), 1, _("version data")) == NULL)
9565 break;
252b5132
RH
9566
9567 vers_data = byte_get (data, 2);
9568
4fbb74a6
AM
9569 is_nobits = (psym->st_shndx < elf_header.e_shnum
9570 && section_headers[psym->st_shndx].sh_type
c256ffe7 9571 == SHT_NOBITS);
252b5132
RH
9572
9573 check_def = (psym->st_shndx != SHN_UNDEF);
9574
c244d050 9575 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9576 {
b34976b6 9577 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9578 && (is_nobits || ! check_def))
252b5132 9579 {
b34976b6
AM
9580 Elf_External_Verneed evn;
9581 Elf_Internal_Verneed ivn;
9582 Elf_Internal_Vernaux ivna;
252b5132
RH
9583
9584 /* We must test both. */
d93f0186
NC
9585 offset = offset_from_vma
9586 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9587 sizeof evn);
252b5132 9588
252b5132
RH
9589 do
9590 {
b34976b6 9591 unsigned long vna_off;
252b5132 9592
59245841
NC
9593 if (get_data (&evn, file, offset, sizeof (evn), 1,
9594 _("version need")) == NULL)
9595 {
9596 ivna.vna_next = 0;
9597 ivna.vna_other = 0;
9598 ivna.vna_name = 0;
9599 break;
9600 }
dd27201e
L
9601
9602 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9603 ivn.vn_next = BYTE_GET (evn.vn_next);
9604
252b5132
RH
9605 vna_off = offset + ivn.vn_aux;
9606
9607 do
9608 {
b34976b6 9609 Elf_External_Vernaux evna;
252b5132 9610
59245841
NC
9611 if (get_data (&evna, file, vna_off,
9612 sizeof (evna), 1,
9613 _("version need aux (3)")) == NULL)
9614 {
9615 ivna.vna_next = 0;
9616 ivna.vna_other = 0;
9617 ivna.vna_name = 0;
9618 }
9619 else
9620 {
9621 ivna.vna_other = BYTE_GET (evna.vna_other);
9622 ivna.vna_next = BYTE_GET (evna.vna_next);
9623 ivna.vna_name = BYTE_GET (evna.vna_name);
9624 }
252b5132
RH
9625
9626 vna_off += ivna.vna_next;
9627 }
9628 while (ivna.vna_other != vers_data
9629 && ivna.vna_next != 0);
9630
9631 if (ivna.vna_other == vers_data)
9632 break;
9633
9634 offset += ivn.vn_next;
9635 }
9636 while (ivn.vn_next != 0);
9637
9638 if (ivna.vna_other == vers_data)
9639 {
9640 printf ("@%s (%d)",
c256ffe7 9641 ivna.vna_name < strtab_size
2b692964 9642 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9643 ivna.vna_other);
252b5132
RH
9644 check_def = 0;
9645 }
9646 else if (! is_nobits)
591a748a 9647 error (_("bad dynamic symbol\n"));
252b5132
RH
9648 else
9649 check_def = 1;
9650 }
9651
9652 if (check_def)
9653 {
00d93f34 9654 if (vers_data != 0x8001
b34976b6 9655 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9656 {
b34976b6
AM
9657 Elf_Internal_Verdef ivd;
9658 Elf_Internal_Verdaux ivda;
9659 Elf_External_Verdaux evda;
91d6fa6a 9660 unsigned long off;
252b5132 9661
91d6fa6a 9662 off = offset_from_vma
d93f0186
NC
9663 (file,
9664 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9665 sizeof (Elf_External_Verdef));
252b5132
RH
9666
9667 do
9668 {
b34976b6 9669 Elf_External_Verdef evd;
252b5132 9670
59245841
NC
9671 if (get_data (&evd, file, off, sizeof (evd),
9672 1, _("version def")) == NULL)
9673 {
9674 ivd.vd_ndx = 0;
9675 ivd.vd_aux = 0;
9676 ivd.vd_next = 0;
9677 }
9678 else
9679 {
9680 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9681 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9682 ivd.vd_next = BYTE_GET (evd.vd_next);
9683 }
252b5132 9684
91d6fa6a 9685 off += ivd.vd_next;
252b5132 9686 }
c244d050 9687 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9688 && ivd.vd_next != 0);
9689
91d6fa6a
NC
9690 off -= ivd.vd_next;
9691 off += ivd.vd_aux;
252b5132 9692
59245841
NC
9693 if (get_data (&evda, file, off, sizeof (evda),
9694 1, _("version def aux")) == NULL)
9695 break;
252b5132
RH
9696
9697 ivda.vda_name = BYTE_GET (evda.vda_name);
9698
9699 if (psym->st_name != ivda.vda_name)
c244d050 9700 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9701 ? "@%s" : "@@%s",
c256ffe7 9702 ivda.vda_name < strtab_size
2b692964 9703 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9704 }
9705 }
9706 }
9707 }
9708
9709 putchar ('\n');
9710 }
9711
9712 free (symtab);
9713 if (strtab != string_table)
9714 free (strtab);
9715 }
9716 }
9717 else if (do_syms)
9718 printf
9719 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9720
9721 if (do_histogram && buckets != NULL)
9722 {
2cf0635d
NC
9723 unsigned long * lengths;
9724 unsigned long * counts;
66543521
AM
9725 unsigned long hn;
9726 bfd_vma si;
9727 unsigned long maxlength = 0;
9728 unsigned long nzero_counts = 0;
9729 unsigned long nsyms = 0;
252b5132 9730
66543521
AM
9731 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9732 (unsigned long) nbuckets);
252b5132
RH
9733 printf (_(" Length Number %% of total Coverage\n"));
9734
3f5e193b 9735 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9736 if (lengths == NULL)
9737 {
591a748a 9738 error (_("Out of memory\n"));
252b5132
RH
9739 return 0;
9740 }
9741 for (hn = 0; hn < nbuckets; ++hn)
9742 {
f7a99963 9743 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9744 {
b34976b6 9745 ++nsyms;
252b5132 9746 if (maxlength < ++lengths[hn])
b34976b6 9747 ++maxlength;
252b5132
RH
9748 }
9749 }
9750
3f5e193b 9751 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9752 if (counts == NULL)
9753 {
591a748a 9754 error (_("Out of memory\n"));
252b5132
RH
9755 return 0;
9756 }
9757
9758 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9759 ++counts[lengths[hn]];
252b5132 9760
103f02d3 9761 if (nbuckets > 0)
252b5132 9762 {
66543521
AM
9763 unsigned long i;
9764 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9765 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9766 for (i = 1; i <= maxlength; ++i)
103f02d3 9767 {
66543521
AM
9768 nzero_counts += counts[i] * i;
9769 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9770 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9771 (nzero_counts * 100.0) / nsyms);
9772 }
252b5132
RH
9773 }
9774
9775 free (counts);
9776 free (lengths);
9777 }
9778
9779 if (buckets != NULL)
9780 {
9781 free (buckets);
9782 free (chains);
9783 }
9784
d3a44ec6 9785 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9786 {
2cf0635d
NC
9787 unsigned long * lengths;
9788 unsigned long * counts;
fdc90cb4
JJ
9789 unsigned long hn;
9790 unsigned long maxlength = 0;
9791 unsigned long nzero_counts = 0;
9792 unsigned long nsyms = 0;
fdc90cb4 9793
3f5e193b 9794 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9795 if (lengths == NULL)
9796 {
591a748a 9797 error (_("Out of memory\n"));
fdc90cb4
JJ
9798 return 0;
9799 }
9800
9801 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9802 (unsigned long) ngnubuckets);
9803 printf (_(" Length Number %% of total Coverage\n"));
9804
9805 for (hn = 0; hn < ngnubuckets; ++hn)
9806 if (gnubuckets[hn] != 0)
9807 {
9808 bfd_vma off, length = 1;
9809
6bd1a22c 9810 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9811 (gnuchains[off] & 1) == 0; ++off)
9812 ++length;
9813 lengths[hn] = length;
9814 if (length > maxlength)
9815 maxlength = length;
9816 nsyms += length;
9817 }
9818
3f5e193b 9819 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9820 if (counts == NULL)
9821 {
591a748a 9822 error (_("Out of memory\n"));
fdc90cb4
JJ
9823 return 0;
9824 }
9825
9826 for (hn = 0; hn < ngnubuckets; ++hn)
9827 ++counts[lengths[hn]];
9828
9829 if (ngnubuckets > 0)
9830 {
9831 unsigned long j;
9832 printf (" 0 %-10lu (%5.1f%%)\n",
9833 counts[0], (counts[0] * 100.0) / ngnubuckets);
9834 for (j = 1; j <= maxlength; ++j)
9835 {
9836 nzero_counts += counts[j] * j;
9837 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9838 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9839 (nzero_counts * 100.0) / nsyms);
9840 }
9841 }
9842
9843 free (counts);
9844 free (lengths);
9845 free (gnubuckets);
9846 free (gnuchains);
9847 }
9848
252b5132
RH
9849 return 1;
9850}
9851
9852static int
2cf0635d 9853process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9854{
b4c96d0d 9855 unsigned int i;
252b5132
RH
9856
9857 if (dynamic_syminfo == NULL
9858 || !do_dynamic)
9859 /* No syminfo, this is ok. */
9860 return 1;
9861
9862 /* There better should be a dynamic symbol section. */
9863 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9864 return 0;
9865
9866 if (dynamic_addr)
9867 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9868 dynamic_syminfo_offset, dynamic_syminfo_nent);
9869
9870 printf (_(" Num: Name BoundTo Flags\n"));
9871 for (i = 0; i < dynamic_syminfo_nent; ++i)
9872 {
9873 unsigned short int flags = dynamic_syminfo[i].si_flags;
9874
31104126 9875 printf ("%4d: ", i);
d79b3d50
NC
9876 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9877 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9878 else
2b692964 9879 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9880 putchar (' ');
252b5132
RH
9881
9882 switch (dynamic_syminfo[i].si_boundto)
9883 {
9884 case SYMINFO_BT_SELF:
9885 fputs ("SELF ", stdout);
9886 break;
9887 case SYMINFO_BT_PARENT:
9888 fputs ("PARENT ", stdout);
9889 break;
9890 default:
9891 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9892 && dynamic_syminfo[i].si_boundto < dynamic_nent
9893 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9894 {
d79b3d50 9895 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9896 putchar (' ' );
9897 }
252b5132
RH
9898 else
9899 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9900 break;
9901 }
9902
9903 if (flags & SYMINFO_FLG_DIRECT)
9904 printf (" DIRECT");
9905 if (flags & SYMINFO_FLG_PASSTHRU)
9906 printf (" PASSTHRU");
9907 if (flags & SYMINFO_FLG_COPY)
9908 printf (" COPY");
9909 if (flags & SYMINFO_FLG_LAZYLOAD)
9910 printf (" LAZYLOAD");
9911
9912 puts ("");
9913 }
9914
9915 return 1;
9916}
9917
cf13d699
NC
9918/* Check to see if the given reloc needs to be handled in a target specific
9919 manner. If so then process the reloc and return TRUE otherwise return
9920 FALSE. */
09c11c86 9921
cf13d699
NC
9922static bfd_boolean
9923target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9924 unsigned char * start,
9925 Elf_Internal_Sym * symtab)
252b5132 9926{
cf13d699 9927 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9928
cf13d699 9929 switch (elf_header.e_machine)
252b5132 9930 {
cf13d699
NC
9931 case EM_MN10300:
9932 case EM_CYGNUS_MN10300:
9933 {
9934 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9935
cf13d699
NC
9936 switch (reloc_type)
9937 {
9938 case 34: /* R_MN10300_ALIGN */
9939 return TRUE;
9940 case 33: /* R_MN10300_SYM_DIFF */
9941 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9942 return TRUE;
9943 case 1: /* R_MN10300_32 */
9944 case 2: /* R_MN10300_16 */
9945 if (saved_sym != NULL)
9946 {
9947 bfd_vma value;
252b5132 9948
cf13d699
NC
9949 value = reloc->r_addend
9950 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9951 - saved_sym->st_value);
252b5132 9952
cf13d699 9953 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9954
cf13d699
NC
9955 saved_sym = NULL;
9956 return TRUE;
9957 }
9958 break;
9959 default:
9960 if (saved_sym != NULL)
9961 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9962 break;
9963 }
9964 break;
9965 }
252b5132
RH
9966 }
9967
cf13d699 9968 return FALSE;
252b5132
RH
9969}
9970
aca88567
NC
9971/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9972 DWARF debug sections. This is a target specific test. Note - we do not
9973 go through the whole including-target-headers-multiple-times route, (as
9974 we have already done with <elf/h8.h>) because this would become very
9975 messy and even then this function would have to contain target specific
9976 information (the names of the relocs instead of their numeric values).
9977 FIXME: This is not the correct way to solve this problem. The proper way
9978 is to have target specific reloc sizing and typing functions created by
9979 the reloc-macros.h header, in the same way that it already creates the
9980 reloc naming functions. */
9981
9982static bfd_boolean
9983is_32bit_abs_reloc (unsigned int reloc_type)
9984{
9985 switch (elf_header.e_machine)
9986 {
41e92641
NC
9987 case EM_386:
9988 case EM_486:
9989 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9990 case EM_68K:
9991 return reloc_type == 1; /* R_68K_32. */
9992 case EM_860:
9993 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9994 case EM_960:
9995 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
9996 case EM_AARCH64:
9997 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 9998 case EM_ALPHA:
137b6b5f 9999 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
10000 case EM_ARC:
10001 return reloc_type == 1; /* R_ARC_32. */
10002 case EM_ARM:
10003 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 10004 case EM_AVR_OLD:
aca88567
NC
10005 case EM_AVR:
10006 return reloc_type == 1;
cfb8c092
NC
10007 case EM_ADAPTEVA_EPIPHANY:
10008 return reloc_type == 3;
aca88567
NC
10009 case EM_BLACKFIN:
10010 return reloc_type == 0x12; /* R_byte4_data. */
10011 case EM_CRIS:
10012 return reloc_type == 3; /* R_CRIS_32. */
10013 case EM_CR16:
10014 return reloc_type == 3; /* R_CR16_NUM32. */
10015 case EM_CRX:
10016 return reloc_type == 15; /* R_CRX_NUM32. */
10017 case EM_CYGNUS_FRV:
10018 return reloc_type == 1;
41e92641
NC
10019 case EM_CYGNUS_D10V:
10020 case EM_D10V:
10021 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
10022 case EM_CYGNUS_D30V:
10023 case EM_D30V:
10024 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
10025 case EM_DLX:
10026 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
10027 case EM_CYGNUS_FR30:
10028 case EM_FR30:
10029 return reloc_type == 3; /* R_FR30_32. */
10030 case EM_H8S:
10031 case EM_H8_300:
10032 case EM_H8_300H:
10033 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
10034 case EM_IA_64:
10035 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
10036 case EM_IP2K_OLD:
10037 case EM_IP2K:
10038 return reloc_type == 2; /* R_IP2K_32. */
10039 case EM_IQ2000:
10040 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
10041 case EM_LATTICEMICO32:
10042 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 10043 case EM_M32C_OLD:
aca88567
NC
10044 case EM_M32C:
10045 return reloc_type == 3; /* R_M32C_32. */
10046 case EM_M32R:
10047 return reloc_type == 34; /* R_M32R_32_RELA. */
10048 case EM_MCORE:
10049 return reloc_type == 1; /* R_MCORE_ADDR32. */
10050 case EM_CYGNUS_MEP:
10051 return reloc_type == 4; /* R_MEP_32. */
137b6b5f
AM
10052 case EM_MICROBLAZE:
10053 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
10054 case EM_MIPS:
10055 return reloc_type == 2; /* R_MIPS_32. */
10056 case EM_MMIX:
10057 return reloc_type == 4; /* R_MMIX_32. */
10058 case EM_CYGNUS_MN10200:
10059 case EM_MN10200:
10060 return reloc_type == 1; /* R_MN10200_32. */
10061 case EM_CYGNUS_MN10300:
10062 case EM_MN10300:
10063 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
10064 case EM_MOXIE:
10065 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
10066 case EM_MSP430_OLD:
10067 case EM_MSP430:
10068 return reloc_type == 1; /* R_MSP43_32. */
10069 case EM_MT:
10070 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
10071 case EM_ALTERA_NIOS2:
10072 case EM_NIOS32:
10073 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
10074 case EM_OPENRISC:
10075 case EM_OR32:
10076 return reloc_type == 1; /* R_OR32_32. */
aca88567 10077 case EM_PARISC:
5fda8eca
NC
10078 return (reloc_type == 1 /* R_PARISC_DIR32. */
10079 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
10080 case EM_PJ:
10081 case EM_PJ_OLD:
10082 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
10083 case EM_PPC64:
10084 return reloc_type == 1; /* R_PPC64_ADDR32. */
10085 case EM_PPC:
10086 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
10087 case EM_RL78:
10088 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
10089 case EM_RX:
10090 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
10091 case EM_S370:
10092 return reloc_type == 1; /* R_I370_ADDR31. */
10093 case EM_S390_OLD:
10094 case EM_S390:
10095 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
10096 case EM_SCORE:
10097 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
10098 case EM_SH:
10099 return reloc_type == 1; /* R_SH_DIR32. */
10100 case EM_SPARC32PLUS:
10101 case EM_SPARCV9:
10102 case EM_SPARC:
10103 return reloc_type == 3 /* R_SPARC_32. */
10104 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
10105 case EM_SPU:
10106 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
10107 case EM_TI_C6000:
10108 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
10109 case EM_TILEGX:
10110 return reloc_type == 2; /* R_TILEGX_32. */
10111 case EM_TILEPRO:
10112 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
10113 case EM_CYGNUS_V850:
10114 case EM_V850:
10115 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
10116 case EM_V800:
10117 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
10118 case EM_VAX:
10119 return reloc_type == 1; /* R_VAX_32. */
10120 case EM_X86_64:
8a9036a4 10121 case EM_L1OM:
7a9068fe 10122 case EM_K1OM:
aca88567 10123 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
10124 case EM_XC16X:
10125 case EM_C166:
10126 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
10127 case EM_XGATE:
10128 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
10129 case EM_XSTORMY16:
10130 return reloc_type == 1; /* R_XSTROMY16_32. */
10131 case EM_XTENSA_OLD:
10132 case EM_XTENSA:
10133 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
10134 default:
10135 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
10136 elf_header.e_machine);
10137 abort ();
10138 }
10139}
10140
10141/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10142 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
10143
10144static bfd_boolean
10145is_32bit_pcrel_reloc (unsigned int reloc_type)
10146{
10147 switch (elf_header.e_machine)
10148 {
41e92641
NC
10149 case EM_386:
10150 case EM_486:
3e0873ac 10151 return reloc_type == 2; /* R_386_PC32. */
aca88567 10152 case EM_68K:
3e0873ac 10153 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
10154 case EM_AARCH64:
10155 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
10156 case EM_ADAPTEVA_EPIPHANY:
10157 return reloc_type == 6;
aca88567
NC
10158 case EM_ALPHA:
10159 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 10160 case EM_ARM:
3e0873ac 10161 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
10162 case EM_MICROBLAZE:
10163 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 10164 case EM_PARISC:
85acf597 10165 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
10166 case EM_PPC:
10167 return reloc_type == 26; /* R_PPC_REL32. */
10168 case EM_PPC64:
3e0873ac 10169 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
10170 case EM_S390_OLD:
10171 case EM_S390:
3e0873ac 10172 return reloc_type == 5; /* R_390_PC32. */
aca88567 10173 case EM_SH:
3e0873ac 10174 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
10175 case EM_SPARC32PLUS:
10176 case EM_SPARCV9:
10177 case EM_SPARC:
3e0873ac 10178 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
10179 case EM_SPU:
10180 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
10181 case EM_TILEGX:
10182 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
10183 case EM_TILEPRO:
10184 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 10185 case EM_X86_64:
8a9036a4 10186 case EM_L1OM:
7a9068fe 10187 case EM_K1OM:
3e0873ac 10188 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
10189 case EM_XTENSA_OLD:
10190 case EM_XTENSA:
10191 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
10192 default:
10193 /* Do not abort or issue an error message here. Not all targets use
10194 pc-relative 32-bit relocs in their DWARF debug information and we
10195 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
10196 more helpful warning message will be generated by apply_relocations
10197 anyway, so just return. */
aca88567
NC
10198 return FALSE;
10199 }
10200}
10201
10202/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10203 a 64-bit absolute RELA relocation used in DWARF debug sections. */
10204
10205static bfd_boolean
10206is_64bit_abs_reloc (unsigned int reloc_type)
10207{
10208 switch (elf_header.e_machine)
10209 {
a06ea964
NC
10210 case EM_AARCH64:
10211 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
10212 case EM_ALPHA:
10213 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
10214 case EM_IA_64:
10215 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
10216 case EM_PARISC:
10217 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
10218 case EM_PPC64:
10219 return reloc_type == 38; /* R_PPC64_ADDR64. */
10220 case EM_SPARC32PLUS:
10221 case EM_SPARCV9:
10222 case EM_SPARC:
10223 return reloc_type == 54; /* R_SPARC_UA64. */
10224 case EM_X86_64:
8a9036a4 10225 case EM_L1OM:
7a9068fe 10226 case EM_K1OM:
aca88567 10227 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10228 case EM_S390_OLD:
10229 case EM_S390:
aa137e4d
NC
10230 return reloc_type == 22; /* R_S390_64. */
10231 case EM_TILEGX:
10232 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10233 case EM_MIPS:
aa137e4d 10234 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10235 default:
10236 return FALSE;
10237 }
10238}
10239
85acf597
RH
10240/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10241 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10242
10243static bfd_boolean
10244is_64bit_pcrel_reloc (unsigned int reloc_type)
10245{
10246 switch (elf_header.e_machine)
10247 {
a06ea964
NC
10248 case EM_AARCH64:
10249 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 10250 case EM_ALPHA:
aa137e4d 10251 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10252 case EM_IA_64:
aa137e4d 10253 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10254 case EM_PARISC:
aa137e4d 10255 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10256 case EM_PPC64:
aa137e4d 10257 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10258 case EM_SPARC32PLUS:
10259 case EM_SPARCV9:
10260 case EM_SPARC:
aa137e4d 10261 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10262 case EM_X86_64:
8a9036a4 10263 case EM_L1OM:
7a9068fe 10264 case EM_K1OM:
aa137e4d 10265 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10266 case EM_S390_OLD:
10267 case EM_S390:
aa137e4d
NC
10268 return reloc_type == 23; /* R_S390_PC64. */
10269 case EM_TILEGX:
10270 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10271 default:
10272 return FALSE;
10273 }
10274}
10275
4dc3c23d
AM
10276/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10277 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10278
10279static bfd_boolean
10280is_24bit_abs_reloc (unsigned int reloc_type)
10281{
10282 switch (elf_header.e_machine)
10283 {
10284 case EM_CYGNUS_MN10200:
10285 case EM_MN10200:
10286 return reloc_type == 4; /* R_MN10200_24. */
10287 default:
10288 return FALSE;
10289 }
10290}
10291
aca88567
NC
10292/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10293 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10294
10295static bfd_boolean
10296is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10297{
10298 switch (elf_header.e_machine)
10299 {
aca88567
NC
10300 case EM_AVR_OLD:
10301 case EM_AVR:
10302 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10303 case EM_ADAPTEVA_EPIPHANY:
10304 return reloc_type == 5;
41e92641
NC
10305 case EM_CYGNUS_D10V:
10306 case EM_D10V:
10307 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10308 case EM_H8S:
10309 case EM_H8_300:
10310 case EM_H8_300H:
aca88567
NC
10311 return reloc_type == R_H8_DIR16;
10312 case EM_IP2K_OLD:
10313 case EM_IP2K:
10314 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10315 case EM_M32C_OLD:
f4236fe4
DD
10316 case EM_M32C:
10317 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
10318 case EM_MSP430_OLD:
10319 case EM_MSP430:
10320 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
10321 case EM_ALTERA_NIOS2:
10322 case EM_NIOS32:
10323 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10324 case EM_TI_C6000:
10325 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10326 case EM_XC16X:
10327 case EM_C166:
10328 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
10329 case EM_CYGNUS_MN10200:
10330 case EM_MN10200:
10331 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
10332 case EM_CYGNUS_MN10300:
10333 case EM_MN10300:
10334 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10335 case EM_XGATE:
10336 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10337 default:
aca88567 10338 return FALSE;
4b78141a
NC
10339 }
10340}
10341
2a7b2e88
JK
10342/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10343 relocation entries (possibly formerly used for SHT_GROUP sections). */
10344
10345static bfd_boolean
10346is_none_reloc (unsigned int reloc_type)
10347{
10348 switch (elf_header.e_machine)
10349 {
cb8f3167
NC
10350 case EM_68K: /* R_68K_NONE. */
10351 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10352 case EM_SPARC32PLUS:
10353 case EM_SPARCV9:
cb8f3167
NC
10354 case EM_SPARC: /* R_SPARC_NONE. */
10355 case EM_MIPS: /* R_MIPS_NONE. */
10356 case EM_PARISC: /* R_PARISC_NONE. */
10357 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10358 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10359 case EM_PPC: /* R_PPC_NONE. */
10360 case EM_PPC64: /* R_PPC64_NONE. */
10361 case EM_ARM: /* R_ARM_NONE. */
10362 case EM_IA_64: /* R_IA64_NONE. */
10363 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10364 case EM_S390_OLD:
cb8f3167
NC
10365 case EM_S390: /* R_390_NONE. */
10366 case EM_CRIS: /* R_CRIS_NONE. */
10367 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10368 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10369 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10370 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10371 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10372 case EM_M32R: /* R_M32R_NONE. */
40b36596 10373 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10374 case EM_TILEGX: /* R_TILEGX_NONE. */
10375 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10376 case EM_XC16X:
10377 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 10378 return reloc_type == 0;
a06ea964
NC
10379 case EM_AARCH64:
10380 return reloc_type == 0 || reloc_type == 256;
58332dda
JK
10381 case EM_XTENSA_OLD:
10382 case EM_XTENSA:
4dc3c23d
AM
10383 return (reloc_type == 0 /* R_XTENSA_NONE. */
10384 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10385 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10386 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
10387 }
10388 return FALSE;
10389}
10390
cf13d699
NC
10391/* Apply relocations to a section.
10392 Note: So far support has been added only for those relocations
10393 which can be found in debug sections.
10394 FIXME: Add support for more relocations ? */
1b315056 10395
cf13d699
NC
10396static void
10397apply_relocations (void * file,
10398 Elf_Internal_Shdr * section,
10399 unsigned char * start)
1b315056 10400{
cf13d699
NC
10401 Elf_Internal_Shdr * relsec;
10402 unsigned char * end = start + section->sh_size;
cb8f3167 10403
cf13d699
NC
10404 if (elf_header.e_type != ET_REL)
10405 return;
1b315056 10406
cf13d699 10407 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10408 for (relsec = section_headers;
10409 relsec < section_headers + elf_header.e_shnum;
10410 ++relsec)
252b5132 10411 {
41e92641
NC
10412 bfd_boolean is_rela;
10413 unsigned long num_relocs;
2cf0635d
NC
10414 Elf_Internal_Rela * relocs;
10415 Elf_Internal_Rela * rp;
10416 Elf_Internal_Shdr * symsec;
10417 Elf_Internal_Sym * symtab;
ba5cdace 10418 unsigned long num_syms;
2cf0635d 10419 Elf_Internal_Sym * sym;
252b5132 10420
41e92641 10421 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10422 || relsec->sh_info >= elf_header.e_shnum
10423 || section_headers + relsec->sh_info != section
c256ffe7 10424 || relsec->sh_size == 0
4fbb74a6 10425 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10426 continue;
428409d5 10427
41e92641
NC
10428 is_rela = relsec->sh_type == SHT_RELA;
10429
10430 if (is_rela)
10431 {
3f5e193b
NC
10432 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10433 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10434 return;
10435 }
10436 else
10437 {
3f5e193b
NC
10438 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10439 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10440 return;
10441 }
10442
10443 /* SH uses RELA but uses in place value instead of the addend field. */
10444 if (elf_header.e_machine == EM_SH)
10445 is_rela = FALSE;
428409d5 10446
4fbb74a6 10447 symsec = section_headers + relsec->sh_link;
ba5cdace 10448 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10449
41e92641 10450 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10451 {
41e92641
NC
10452 bfd_vma addend;
10453 unsigned int reloc_type;
10454 unsigned int reloc_size;
91d6fa6a 10455 unsigned char * rloc;
ba5cdace 10456 unsigned long sym_index;
4b78141a 10457
aca88567 10458 reloc_type = get_reloc_type (rp->r_info);
41e92641 10459
98fb390a 10460 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10461 continue;
98fb390a
NC
10462 else if (is_none_reloc (reloc_type))
10463 continue;
10464 else if (is_32bit_abs_reloc (reloc_type)
10465 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10466 reloc_size = 4;
85acf597
RH
10467 else if (is_64bit_abs_reloc (reloc_type)
10468 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10469 reloc_size = 8;
4dc3c23d
AM
10470 else if (is_24bit_abs_reloc (reloc_type))
10471 reloc_size = 3;
aca88567
NC
10472 else if (is_16bit_abs_reloc (reloc_type))
10473 reloc_size = 2;
10474 else
4b78141a 10475 {
41e92641 10476 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10477 reloc_type, SECTION_NAME (section));
4b78141a
NC
10478 continue;
10479 }
103f02d3 10480
91d6fa6a
NC
10481 rloc = start + rp->r_offset;
10482 if ((rloc + reloc_size) > end)
700dd8b7
L
10483 {
10484 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10485 (unsigned long) rp->r_offset,
10486 SECTION_NAME (section));
10487 continue;
10488 }
103f02d3 10489
ba5cdace
NC
10490 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10491 if (sym_index >= num_syms)
10492 {
10493 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10494 sym_index, SECTION_NAME (section));
10495 continue;
10496 }
10497 sym = symtab + sym_index;
41e92641
NC
10498
10499 /* If the reloc has a symbol associated with it,
55f25fc3
L
10500 make sure that it is of an appropriate type.
10501
10502 Relocations against symbols without type can happen.
10503 Gcc -feliminate-dwarf2-dups may generate symbols
10504 without type for debug info.
10505
10506 Icc generates relocations against function symbols
10507 instead of local labels.
10508
10509 Relocations against object symbols can happen, eg when
10510 referencing a global array. For an example of this see
10511 the _clz.o binary in libgcc.a. */
aca88567 10512 if (sym != symtab
55f25fc3 10513 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10514 {
41e92641 10515 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10516 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10517 (long int)(rp - relocs),
41e92641 10518 SECTION_NAME (relsec));
aca88567 10519 continue;
5b18a4bc 10520 }
252b5132 10521
4dc3c23d
AM
10522 addend = 0;
10523 if (is_rela)
10524 addend += rp->r_addend;
c47320c3
AM
10525 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10526 partial_inplace. */
4dc3c23d
AM
10527 if (!is_rela
10528 || (elf_header.e_machine == EM_XTENSA
10529 && reloc_type == 1)
10530 || ((elf_header.e_machine == EM_PJ
10531 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10532 && reloc_type == 1)
10533 || ((elf_header.e_machine == EM_D30V
10534 || elf_header.e_machine == EM_CYGNUS_D30V)
10535 && reloc_type == 12))
91d6fa6a 10536 addend += byte_get (rloc, reloc_size);
cb8f3167 10537
85acf597
RH
10538 if (is_32bit_pcrel_reloc (reloc_type)
10539 || is_64bit_pcrel_reloc (reloc_type))
10540 {
10541 /* On HPPA, all pc-relative relocations are biased by 8. */
10542 if (elf_header.e_machine == EM_PARISC)
10543 addend -= 8;
91d6fa6a 10544 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10545 reloc_size);
10546 }
41e92641 10547 else
91d6fa6a 10548 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10549 }
252b5132 10550
5b18a4bc 10551 free (symtab);
41e92641 10552 free (relocs);
5b18a4bc
NC
10553 break;
10554 }
5b18a4bc 10555}
103f02d3 10556
cf13d699
NC
10557#ifdef SUPPORT_DISASSEMBLY
10558static int
10559disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10560{
10561 printf (_("\nAssembly dump of section %s\n"),
10562 SECTION_NAME (section));
10563
10564 /* XXX -- to be done --- XXX */
10565
10566 return 1;
10567}
10568#endif
10569
10570/* Reads in the contents of SECTION from FILE, returning a pointer
10571 to a malloc'ed buffer or NULL if something went wrong. */
10572
10573static char *
10574get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10575{
10576 bfd_size_type num_bytes;
10577
10578 num_bytes = section->sh_size;
10579
10580 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10581 {
10582 printf (_("\nSection '%s' has no data to dump.\n"),
10583 SECTION_NAME (section));
10584 return NULL;
10585 }
10586
3f5e193b
NC
10587 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10588 _("section contents"));
cf13d699
NC
10589}
10590
dd24e3da 10591
cf13d699
NC
10592static void
10593dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10594{
10595 Elf_Internal_Shdr * relsec;
10596 bfd_size_type num_bytes;
cf13d699
NC
10597 char * data;
10598 char * end;
10599 char * start;
10600 char * name = SECTION_NAME (section);
10601 bfd_boolean some_strings_shown;
10602
10603 start = get_section_contents (section, file);
10604 if (start == NULL)
10605 return;
10606
10607 printf (_("\nString dump of section '%s':\n"), name);
10608
10609 /* If the section being dumped has relocations against it the user might
10610 be expecting these relocations to have been applied. Check for this
10611 case and issue a warning message in order to avoid confusion.
10612 FIXME: Maybe we ought to have an option that dumps a section with
10613 relocs applied ? */
10614 for (relsec = section_headers;
10615 relsec < section_headers + elf_header.e_shnum;
10616 ++relsec)
10617 {
10618 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10619 || relsec->sh_info >= elf_header.e_shnum
10620 || section_headers + relsec->sh_info != section
10621 || relsec->sh_size == 0
10622 || relsec->sh_link >= elf_header.e_shnum)
10623 continue;
10624
10625 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10626 break;
10627 }
10628
10629 num_bytes = section->sh_size;
cf13d699
NC
10630 data = start;
10631 end = start + num_bytes;
10632 some_strings_shown = FALSE;
10633
10634 while (data < end)
10635 {
10636 while (!ISPRINT (* data))
10637 if (++ data >= end)
10638 break;
10639
10640 if (data < end)
10641 {
10642#ifndef __MSVCRT__
c975cc98
NC
10643 /* PR 11128: Use two separate invocations in order to work
10644 around bugs in the Solaris 8 implementation of printf. */
10645 printf (" [%6tx] ", data - start);
10646 printf ("%s\n", data);
cf13d699
NC
10647#else
10648 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10649#endif
10650 data += strlen (data);
10651 some_strings_shown = TRUE;
10652 }
10653 }
10654
10655 if (! some_strings_shown)
10656 printf (_(" No strings found in this section."));
10657
10658 free (start);
10659
10660 putchar ('\n');
10661}
10662
10663static void
10664dump_section_as_bytes (Elf_Internal_Shdr * section,
10665 FILE * file,
10666 bfd_boolean relocate)
10667{
10668 Elf_Internal_Shdr * relsec;
10669 bfd_size_type bytes;
10670 bfd_vma addr;
10671 unsigned char * data;
10672 unsigned char * start;
10673
10674 start = (unsigned char *) get_section_contents (section, file);
10675 if (start == NULL)
10676 return;
10677
10678 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10679
10680 if (relocate)
10681 {
10682 apply_relocations (file, section, start);
10683 }
10684 else
10685 {
10686 /* If the section being dumped has relocations against it the user might
10687 be expecting these relocations to have been applied. Check for this
10688 case and issue a warning message in order to avoid confusion.
10689 FIXME: Maybe we ought to have an option that dumps a section with
10690 relocs applied ? */
10691 for (relsec = section_headers;
10692 relsec < section_headers + elf_header.e_shnum;
10693 ++relsec)
10694 {
10695 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10696 || relsec->sh_info >= elf_header.e_shnum
10697 || section_headers + relsec->sh_info != section
10698 || relsec->sh_size == 0
10699 || relsec->sh_link >= elf_header.e_shnum)
10700 continue;
10701
10702 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10703 break;
10704 }
10705 }
10706
10707 addr = section->sh_addr;
10708 bytes = section->sh_size;
10709 data = start;
10710
10711 while (bytes)
10712 {
10713 int j;
10714 int k;
10715 int lbytes;
10716
10717 lbytes = (bytes > 16 ? 16 : bytes);
10718
10719 printf (" 0x%8.8lx ", (unsigned long) addr);
10720
10721 for (j = 0; j < 16; j++)
10722 {
10723 if (j < lbytes)
10724 printf ("%2.2x", data[j]);
10725 else
10726 printf (" ");
10727
10728 if ((j & 3) == 3)
10729 printf (" ");
10730 }
10731
10732 for (j = 0; j < lbytes; j++)
10733 {
10734 k = data[j];
10735 if (k >= ' ' && k < 0x7f)
10736 printf ("%c", k);
10737 else
10738 printf (".");
10739 }
10740
10741 putchar ('\n');
10742
10743 data += lbytes;
10744 addr += lbytes;
10745 bytes -= lbytes;
10746 }
10747
10748 free (start);
10749
10750 putchar ('\n');
10751}
10752
4a114e3e 10753/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10754
10755static int
d3dbc530
AM
10756uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10757 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10758{
10759#ifndef HAVE_ZLIB_H
cf13d699
NC
10760 return FALSE;
10761#else
10762 dwarf_size_type compressed_size = *size;
10763 unsigned char * compressed_buffer = *buffer;
10764 dwarf_size_type uncompressed_size;
10765 unsigned char * uncompressed_buffer;
10766 z_stream strm;
10767 int rc;
10768 dwarf_size_type header_size = 12;
10769
10770 /* Read the zlib header. In this case, it should be "ZLIB" followed
10771 by the uncompressed section size, 8 bytes in big-endian order. */
10772 if (compressed_size < header_size
10773 || ! streq ((char *) compressed_buffer, "ZLIB"))
10774 return 0;
10775
10776 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10777 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10778 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10779 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10780 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10781 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10782 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10783 uncompressed_size += compressed_buffer[11];
10784
10785 /* It is possible the section consists of several compressed
10786 buffers concatenated together, so we uncompress in a loop. */
10787 strm.zalloc = NULL;
10788 strm.zfree = NULL;
10789 strm.opaque = NULL;
10790 strm.avail_in = compressed_size - header_size;
10791 strm.next_in = (Bytef *) compressed_buffer + header_size;
10792 strm.avail_out = uncompressed_size;
3f5e193b 10793 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10794
10795 rc = inflateInit (& strm);
10796 while (strm.avail_in > 0)
10797 {
10798 if (rc != Z_OK)
10799 goto fail;
10800 strm.next_out = ((Bytef *) uncompressed_buffer
10801 + (uncompressed_size - strm.avail_out));
10802 rc = inflate (&strm, Z_FINISH);
10803 if (rc != Z_STREAM_END)
10804 goto fail;
10805 rc = inflateReset (& strm);
10806 }
10807 rc = inflateEnd (& strm);
10808 if (rc != Z_OK
10809 || strm.avail_out != 0)
10810 goto fail;
10811
10812 free (compressed_buffer);
10813 *buffer = uncompressed_buffer;
10814 *size = uncompressed_size;
10815 return 1;
10816
10817 fail:
10818 free (uncompressed_buffer);
4a114e3e
L
10819 /* Indicate decompression failure. */
10820 *buffer = NULL;
cf13d699
NC
10821 return 0;
10822#endif /* HAVE_ZLIB_H */
10823}
10824
d966045b
DJ
10825static int
10826load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10827 Elf_Internal_Shdr * sec, void * file)
1007acb3 10828{
2cf0635d 10829 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10830 char buf [64];
1007acb3 10831
19e6b90e
L
10832 /* If it is already loaded, do nothing. */
10833 if (section->start != NULL)
10834 return 1;
1007acb3 10835
19e6b90e
L
10836 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10837 section->address = sec->sh_addr;
3f5e193b
NC
10838 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10839 sec->sh_offset, 1,
10840 sec->sh_size, buf);
59245841
NC
10841 if (section->start == NULL)
10842 section->size = 0;
10843 else
10844 {
10845 section->size = sec->sh_size;
10846 if (uncompress_section_contents (&section->start, &section->size))
10847 sec->sh_size = section->size;
10848 }
4a114e3e 10849
1b315056
CS
10850 if (section->start == NULL)
10851 return 0;
10852
19e6b90e 10853 if (debug_displays [debug].relocate)
3f5e193b 10854 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10855
1b315056 10856 return 1;
1007acb3
L
10857}
10858
657d0d47
CC
10859/* If this is not NULL, load_debug_section will only look for sections
10860 within the list of sections given here. */
10861unsigned int *section_subset = NULL;
10862
d966045b 10863int
2cf0635d 10864load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10865{
2cf0635d
NC
10866 struct dwarf_section * section = &debug_displays [debug].section;
10867 Elf_Internal_Shdr * sec;
d966045b
DJ
10868
10869 /* Locate the debug section. */
657d0d47 10870 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
10871 if (sec != NULL)
10872 section->name = section->uncompressed_name;
10873 else
10874 {
657d0d47 10875 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
10876 if (sec != NULL)
10877 section->name = section->compressed_name;
10878 }
10879 if (sec == NULL)
10880 return 0;
10881
657d0d47
CC
10882 /* If we're loading from a subset of sections, and we've loaded
10883 a section matching this name before, it's likely that it's a
10884 different one. */
10885 if (section_subset != NULL)
10886 free_debug_section (debug);
10887
3f5e193b 10888 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10889}
10890
19e6b90e
L
10891void
10892free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10893{
2cf0635d 10894 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10895
19e6b90e
L
10896 if (section->start == NULL)
10897 return;
1007acb3 10898
19e6b90e
L
10899 free ((char *) section->start);
10900 section->start = NULL;
10901 section->address = 0;
10902 section->size = 0;
1007acb3
L
10903}
10904
1007acb3 10905static int
657d0d47 10906display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 10907{
2cf0635d 10908 char * name = SECTION_NAME (section);
19e6b90e
L
10909 bfd_size_type length;
10910 int result = 1;
3f5e193b 10911 int i;
1007acb3 10912
19e6b90e
L
10913 length = section->sh_size;
10914 if (length == 0)
1007acb3 10915 {
19e6b90e
L
10916 printf (_("\nSection '%s' has no debugging data.\n"), name);
10917 return 0;
1007acb3 10918 }
5dff79d8
NC
10919 if (section->sh_type == SHT_NOBITS)
10920 {
10921 /* There is no point in dumping the contents of a debugging section
10922 which has the NOBITS type - the bits in the file will be random.
10923 This can happen when a file containing a .eh_frame section is
10924 stripped with the --only-keep-debug command line option. */
10925 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10926 return 0;
10927 }
1007acb3 10928
0112cd26 10929 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10930 name = ".debug_info";
1007acb3 10931
19e6b90e
L
10932 /* See if we know how to display the contents of this section. */
10933 for (i = 0; i < max; i++)
1b315056
CS
10934 if (streq (debug_displays[i].section.uncompressed_name, name)
10935 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10936 {
2cf0635d 10937 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10938 int secondary = (section != find_section (name));
10939
10940 if (secondary)
3f5e193b 10941 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10942
2b6f5997 10943 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10944 sec->name = sec->uncompressed_name;
10945 else
10946 sec->name = sec->compressed_name;
3f5e193b
NC
10947 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10948 section, file))
19e6b90e 10949 {
657d0d47
CC
10950 /* If this debug section is part of a CU/TU set in a .dwp file,
10951 restrict load_debug_section to the sections in that set. */
10952 section_subset = find_cu_tu_set (file, shndx);
10953
19e6b90e 10954 result &= debug_displays[i].display (sec, file);
1007acb3 10955
657d0d47
CC
10956 section_subset = NULL;
10957
d966045b 10958 if (secondary || (i != info && i != abbrev))
3f5e193b 10959 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10960 }
1007acb3 10961
19e6b90e
L
10962 break;
10963 }
1007acb3 10964
19e6b90e 10965 if (i == max)
1007acb3 10966 {
19e6b90e
L
10967 printf (_("Unrecognized debug section: %s\n"), name);
10968 result = 0;
1007acb3
L
10969 }
10970
19e6b90e 10971 return result;
5b18a4bc 10972}
103f02d3 10973
aef1f6d0
DJ
10974/* Set DUMP_SECTS for all sections where dumps were requested
10975 based on section name. */
10976
10977static void
10978initialise_dumps_byname (void)
10979{
2cf0635d 10980 struct dump_list_entry * cur;
aef1f6d0
DJ
10981
10982 for (cur = dump_sects_byname; cur; cur = cur->next)
10983 {
10984 unsigned int i;
10985 int any;
10986
10987 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10988 if (streq (SECTION_NAME (section_headers + i), cur->name))
10989 {
09c11c86 10990 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10991 any = 1;
10992 }
10993
10994 if (!any)
10995 warn (_("Section '%s' was not dumped because it does not exist!\n"),
10996 cur->name);
10997 }
10998}
10999
5b18a4bc 11000static void
2cf0635d 11001process_section_contents (FILE * file)
5b18a4bc 11002{
2cf0635d 11003 Elf_Internal_Shdr * section;
19e6b90e 11004 unsigned int i;
103f02d3 11005
19e6b90e
L
11006 if (! do_dump)
11007 return;
103f02d3 11008
aef1f6d0
DJ
11009 initialise_dumps_byname ();
11010
19e6b90e
L
11011 for (i = 0, section = section_headers;
11012 i < elf_header.e_shnum && i < num_dump_sects;
11013 i++, section++)
11014 {
11015#ifdef SUPPORT_DISASSEMBLY
11016 if (dump_sects[i] & DISASS_DUMP)
11017 disassemble_section (section, file);
11018#endif
11019 if (dump_sects[i] & HEX_DUMP)
cf13d699 11020 dump_section_as_bytes (section, file, FALSE);
103f02d3 11021
cf13d699
NC
11022 if (dump_sects[i] & RELOC_DUMP)
11023 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
11024
11025 if (dump_sects[i] & STRING_DUMP)
11026 dump_section_as_strings (section, file);
cf13d699
NC
11027
11028 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 11029 display_debug_section (i, section, file);
5b18a4bc 11030 }
103f02d3 11031
19e6b90e
L
11032 /* Check to see if the user requested a
11033 dump of a section that does not exist. */
11034 while (i++ < num_dump_sects)
11035 if (dump_sects[i])
11036 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 11037}
103f02d3 11038
5b18a4bc 11039static void
19e6b90e 11040process_mips_fpe_exception (int mask)
5b18a4bc 11041{
19e6b90e
L
11042 if (mask)
11043 {
11044 int first = 1;
11045 if (mask & OEX_FPU_INEX)
11046 fputs ("INEX", stdout), first = 0;
11047 if (mask & OEX_FPU_UFLO)
11048 printf ("%sUFLO", first ? "" : "|"), first = 0;
11049 if (mask & OEX_FPU_OFLO)
11050 printf ("%sOFLO", first ? "" : "|"), first = 0;
11051 if (mask & OEX_FPU_DIV0)
11052 printf ("%sDIV0", first ? "" : "|"), first = 0;
11053 if (mask & OEX_FPU_INVAL)
11054 printf ("%sINVAL", first ? "" : "|");
11055 }
5b18a4bc 11056 else
19e6b90e 11057 fputs ("0", stdout);
5b18a4bc 11058}
103f02d3 11059
11c1ff18
PB
11060/* ARM EABI attributes section. */
11061typedef struct
11062{
11063 int tag;
2cf0635d 11064 const char * name;
11c1ff18
PB
11065 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
11066 int type;
2cf0635d 11067 const char ** table;
11c1ff18
PB
11068} arm_attr_public_tag;
11069
2cf0635d 11070static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 11071 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 11072 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
11073static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
11074static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 11075 {"No", "Thumb-1", "Thumb-2"};
75375b3e 11076static const char * arm_attr_tag_FP_arch[] =
bca38921
MGD
11077 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
11078 "FP for ARMv8"};
2cf0635d 11079static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 11080static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 11081 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 11082static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
11083 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
11084 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 11085static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 11086 {"V6", "SB", "TLS", "Unused"};
2cf0635d 11087static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 11088 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 11089static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 11090 {"Absolute", "PC-relative", "None"};
2cf0635d 11091static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 11092 {"None", "direct", "GOT-indirect"};
2cf0635d 11093static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 11094 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
11095static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
11096static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 11097 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
11098static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
11099static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
11100static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 11101 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 11102static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 11103 {"Unused", "small", "int", "forced to int"};
2cf0635d 11104static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 11105 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 11106static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 11107 {"AAPCS", "VFP registers", "custom"};
2cf0635d 11108static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 11109 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 11110static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
11111 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11112 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 11113static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
11114 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
11115 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 11116static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 11117static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 11118 {"Not Allowed", "Allowed"};
2cf0635d 11119static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 11120 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 11121static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
11122 {"Not Allowed", "Allowed"};
11123static const char * arm_attr_tag_DIV_use[] =
dd24e3da 11124 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 11125 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
11126static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
11127static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 11128 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 11129 "TrustZone and Virtualization Extensions"};
dd24e3da 11130static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 11131 {"Not Allowed", "Allowed"};
11c1ff18
PB
11132
11133#define LOOKUP(id, name) \
11134 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 11135static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
11136{
11137 {4, "CPU_raw_name", 1, NULL},
11138 {5, "CPU_name", 1, NULL},
11139 LOOKUP(6, CPU_arch),
11140 {7, "CPU_arch_profile", 0, NULL},
11141 LOOKUP(8, ARM_ISA_use),
11142 LOOKUP(9, THUMB_ISA_use),
75375b3e 11143 LOOKUP(10, FP_arch),
11c1ff18 11144 LOOKUP(11, WMMX_arch),
f5f53991
AS
11145 LOOKUP(12, Advanced_SIMD_arch),
11146 LOOKUP(13, PCS_config),
11c1ff18
PB
11147 LOOKUP(14, ABI_PCS_R9_use),
11148 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 11149 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
11150 LOOKUP(17, ABI_PCS_GOT_use),
11151 LOOKUP(18, ABI_PCS_wchar_t),
11152 LOOKUP(19, ABI_FP_rounding),
11153 LOOKUP(20, ABI_FP_denormal),
11154 LOOKUP(21, ABI_FP_exceptions),
11155 LOOKUP(22, ABI_FP_user_exceptions),
11156 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
11157 {24, "ABI_align_needed", 0, NULL},
11158 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
11159 LOOKUP(26, ABI_enum_size),
11160 LOOKUP(27, ABI_HardFP_use),
11161 LOOKUP(28, ABI_VFP_args),
11162 LOOKUP(29, ABI_WMMX_args),
11163 LOOKUP(30, ABI_optimization_goals),
11164 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 11165 {32, "compatibility", 0, NULL},
f5f53991 11166 LOOKUP(34, CPU_unaligned_access),
75375b3e 11167 LOOKUP(36, FP_HP_extension),
8e79c3df 11168 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
11169 LOOKUP(42, MPextension_use),
11170 LOOKUP(44, DIV_use),
f5f53991
AS
11171 {64, "nodefaults", 0, NULL},
11172 {65, "also_compatible_with", 0, NULL},
11173 LOOKUP(66, T2EE_use),
11174 {67, "conformance", 1, NULL},
11175 LOOKUP(68, Virtualization_use),
cd21e546 11176 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
11177};
11178#undef LOOKUP
11179
11c1ff18 11180static unsigned char *
2cf0635d 11181display_arm_attribute (unsigned char * p)
11c1ff18
PB
11182{
11183 int tag;
11184 unsigned int len;
11185 int val;
2cf0635d 11186 arm_attr_public_tag * attr;
11c1ff18
PB
11187 unsigned i;
11188 int type;
11189
11190 tag = read_uleb128 (p, &len);
11191 p += len;
11192 attr = NULL;
2cf0635d 11193 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
11194 {
11195 if (arm_attr_public_tags[i].tag == tag)
11196 {
11197 attr = &arm_attr_public_tags[i];
11198 break;
11199 }
11200 }
11201
11202 if (attr)
11203 {
11204 printf (" Tag_%s: ", attr->name);
11205 switch (attr->type)
11206 {
11207 case 0:
11208 switch (tag)
11209 {
11210 case 7: /* Tag_CPU_arch_profile. */
11211 val = read_uleb128 (p, &len);
11212 p += len;
11213 switch (val)
11214 {
2b692964
NC
11215 case 0: printf (_("None\n")); break;
11216 case 'A': printf (_("Application\n")); break;
11217 case 'R': printf (_("Realtime\n")); break;
11218 case 'M': printf (_("Microcontroller\n")); break;
11219 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
11220 default: printf ("??? (%d)\n", val); break;
11221 }
11222 break;
11223
75375b3e
MGD
11224 case 24: /* Tag_align_needed. */
11225 val = read_uleb128 (p, &len);
11226 p += len;
11227 switch (val)
11228 {
2b692964
NC
11229 case 0: printf (_("None\n")); break;
11230 case 1: printf (_("8-byte\n")); break;
11231 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
11232 case 3: printf ("??? 3\n"); break;
11233 default:
11234 if (val <= 12)
dd24e3da 11235 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11236 1 << val);
11237 else
11238 printf ("??? (%d)\n", val);
11239 break;
11240 }
11241 break;
11242
11243 case 25: /* Tag_align_preserved. */
11244 val = read_uleb128 (p, &len);
11245 p += len;
11246 switch (val)
11247 {
2b692964
NC
11248 case 0: printf (_("None\n")); break;
11249 case 1: printf (_("8-byte, except leaf SP\n")); break;
11250 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11251 case 3: printf ("??? 3\n"); break;
11252 default:
11253 if (val <= 12)
dd24e3da 11254 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11255 1 << val);
11256 else
11257 printf ("??? (%d)\n", val);
11258 break;
11259 }
11260 break;
11261
11c1ff18
PB
11262 case 32: /* Tag_compatibility. */
11263 val = read_uleb128 (p, &len);
11264 p += len;
2b692964 11265 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11266 p += strlen ((char *) p) + 1;
11c1ff18
PB
11267 break;
11268
f5f53991
AS
11269 case 64: /* Tag_nodefaults. */
11270 p++;
2b692964 11271 printf (_("True\n"));
f5f53991
AS
11272 break;
11273
11274 case 65: /* Tag_also_compatible_with. */
11275 val = read_uleb128 (p, &len);
11276 p += len;
11277 if (val == 6 /* Tag_CPU_arch. */)
11278 {
11279 val = read_uleb128 (p, &len);
11280 p += len;
2cf0635d 11281 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11282 printf ("??? (%d)\n", val);
11283 else
11284 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11285 }
11286 else
11287 printf ("???\n");
11288 while (*(p++) != '\0' /* NUL terminator. */);
11289 break;
11290
11c1ff18 11291 default:
2cf0635d 11292 abort ();
11c1ff18
PB
11293 }
11294 return p;
11295
11296 case 1:
11297 case 2:
11298 type = attr->type;
11299 break;
11300
11301 default:
11302 assert (attr->type & 0x80);
11303 val = read_uleb128 (p, &len);
11304 p += len;
11305 type = attr->type & 0x7f;
11306 if (val >= type)
11307 printf ("??? (%d)\n", val);
11308 else
11309 printf ("%s\n", attr->table[val]);
11310 return p;
11311 }
11312 }
11313 else
11314 {
11315 if (tag & 1)
11316 type = 1; /* String. */
11317 else
11318 type = 2; /* uleb128. */
11319 printf (" Tag_unknown_%d: ", tag);
11320 }
11321
11322 if (type == 1)
11323 {
11324 printf ("\"%s\"\n", p);
2cf0635d 11325 p += strlen ((char *) p) + 1;
11c1ff18
PB
11326 }
11327 else
11328 {
11329 val = read_uleb128 (p, &len);
11330 p += len;
11331 printf ("%d (0x%x)\n", val, val);
11332 }
11333
11334 return p;
11335}
11336
104d59d1 11337static unsigned char *
60bca95a
NC
11338display_gnu_attribute (unsigned char * p,
11339 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
11340{
11341 int tag;
11342 unsigned int len;
11343 int val;
11344 int type;
11345
11346 tag = read_uleb128 (p, &len);
11347 p += len;
11348
11349 /* Tag_compatibility is the only generic GNU attribute defined at
11350 present. */
11351 if (tag == 32)
11352 {
11353 val = read_uleb128 (p, &len);
11354 p += len;
2b692964 11355 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 11356 p += strlen ((char *) p) + 1;
104d59d1
JM
11357 return p;
11358 }
11359
11360 if ((tag & 2) == 0 && display_proc_gnu_attribute)
11361 return display_proc_gnu_attribute (p, tag);
11362
11363 if (tag & 1)
11364 type = 1; /* String. */
11365 else
11366 type = 2; /* uleb128. */
11367 printf (" Tag_unknown_%d: ", tag);
11368
11369 if (type == 1)
11370 {
11371 printf ("\"%s\"\n", p);
60bca95a 11372 p += strlen ((char *) p) + 1;
104d59d1
JM
11373 }
11374 else
11375 {
11376 val = read_uleb128 (p, &len);
11377 p += len;
11378 printf ("%d (0x%x)\n", val, val);
11379 }
11380
11381 return p;
11382}
11383
34c8bcba 11384static unsigned char *
2cf0635d 11385display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
11386{
11387 int type;
11388 unsigned int len;
11389 int val;
11390
11391 if (tag == Tag_GNU_Power_ABI_FP)
11392 {
11393 val = read_uleb128 (p, &len);
11394 p += len;
11395 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11396
34c8bcba
JM
11397 switch (val)
11398 {
11399 case 0:
2b692964 11400 printf (_("Hard or soft float\n"));
34c8bcba
JM
11401 break;
11402 case 1:
2b692964 11403 printf (_("Hard float\n"));
34c8bcba
JM
11404 break;
11405 case 2:
2b692964 11406 printf (_("Soft float\n"));
34c8bcba 11407 break;
3c7b9897 11408 case 3:
2b692964 11409 printf (_("Single-precision hard float\n"));
3c7b9897 11410 break;
34c8bcba
JM
11411 default:
11412 printf ("??? (%d)\n", val);
11413 break;
11414 }
11415 return p;
11416 }
11417
c6e65352
DJ
11418 if (tag == Tag_GNU_Power_ABI_Vector)
11419 {
11420 val = read_uleb128 (p, &len);
11421 p += len;
11422 printf (" Tag_GNU_Power_ABI_Vector: ");
11423 switch (val)
11424 {
11425 case 0:
2b692964 11426 printf (_("Any\n"));
c6e65352
DJ
11427 break;
11428 case 1:
2b692964 11429 printf (_("Generic\n"));
c6e65352
DJ
11430 break;
11431 case 2:
11432 printf ("AltiVec\n");
11433 break;
11434 case 3:
11435 printf ("SPE\n");
11436 break;
11437 default:
11438 printf ("??? (%d)\n", val);
11439 break;
11440 }
11441 return p;
11442 }
11443
f82e0623
NF
11444 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11445 {
11446 val = read_uleb128 (p, &len);
11447 p += len;
11448 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11449 switch (val)
11450 {
11451 case 0:
2b692964 11452 printf (_("Any\n"));
f82e0623
NF
11453 break;
11454 case 1:
11455 printf ("r3/r4\n");
11456 break;
11457 case 2:
2b692964 11458 printf (_("Memory\n"));
f82e0623
NF
11459 break;
11460 default:
11461 printf ("??? (%d)\n", val);
11462 break;
11463 }
11464 return p;
11465 }
11466
34c8bcba
JM
11467 if (tag & 1)
11468 type = 1; /* String. */
11469 else
11470 type = 2; /* uleb128. */
11471 printf (" Tag_unknown_%d: ", tag);
11472
11473 if (type == 1)
11474 {
11475 printf ("\"%s\"\n", p);
60bca95a 11476 p += strlen ((char *) p) + 1;
34c8bcba
JM
11477 }
11478 else
11479 {
11480 val = read_uleb128 (p, &len);
11481 p += len;
11482 printf ("%d (0x%x)\n", val, val);
11483 }
11484
11485 return p;
11486}
11487
9e8c70f9
DM
11488static void
11489display_sparc_hwcaps (int mask)
11490{
11491 if (mask)
11492 {
11493 int first = 1;
11494 if (mask & ELF_SPARC_HWCAP_MUL32)
11495 fputs ("mul32", stdout), first = 0;
11496 if (mask & ELF_SPARC_HWCAP_DIV32)
11497 printf ("%sdiv32", first ? "" : "|"), first = 0;
11498 if (mask & ELF_SPARC_HWCAP_FSMULD)
11499 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11500 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11501 printf ("%sv8plus", first ? "" : "|"), first = 0;
11502 if (mask & ELF_SPARC_HWCAP_POPC)
11503 printf ("%spopc", first ? "" : "|"), first = 0;
11504 if (mask & ELF_SPARC_HWCAP_VIS)
11505 printf ("%svis", first ? "" : "|"), first = 0;
11506 if (mask & ELF_SPARC_HWCAP_VIS2)
11507 printf ("%svis2", first ? "" : "|"), first = 0;
11508 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11509 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11510 if (mask & ELF_SPARC_HWCAP_FMAF)
11511 printf ("%sfmaf", first ? "" : "|"), first = 0;
11512 if (mask & ELF_SPARC_HWCAP_VIS3)
11513 printf ("%svis3", first ? "" : "|"), first = 0;
11514 if (mask & ELF_SPARC_HWCAP_HPC)
11515 printf ("%shpc", first ? "" : "|"), first = 0;
11516 if (mask & ELF_SPARC_HWCAP_RANDOM)
11517 printf ("%srandom", first ? "" : "|"), first = 0;
11518 if (mask & ELF_SPARC_HWCAP_TRANS)
11519 printf ("%strans", first ? "" : "|"), first = 0;
11520 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11521 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11522 if (mask & ELF_SPARC_HWCAP_IMA)
11523 printf ("%sima", first ? "" : "|"), first = 0;
11524 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11525 printf ("%scspare", first ? "" : "|"), first = 0;
11526 }
11527 else
11528 fputc('0', stdout);
11529 fputc('\n', stdout);
11530}
11531
11532static unsigned char *
11533display_sparc_gnu_attribute (unsigned char * p, int tag)
11534{
11535 int type;
11536 unsigned int len;
11537 int val;
11538
11539 if (tag == Tag_GNU_Sparc_HWCAPS)
11540 {
11541 val = read_uleb128 (p, &len);
11542 p += len;
11543 printf (" Tag_GNU_Sparc_HWCAPS: ");
11544
11545 display_sparc_hwcaps (val);
11546 return p;
11547 }
11548
11549 if (tag & 1)
11550 type = 1; /* String. */
11551 else
11552 type = 2; /* uleb128. */
11553 printf (" Tag_unknown_%d: ", tag);
11554
11555 if (type == 1)
11556 {
11557 printf ("\"%s\"\n", p);
11558 p += strlen ((char *) p) + 1;
11559 }
11560 else
11561 {
11562 val = read_uleb128 (p, &len);
11563 p += len;
11564 printf ("%d (0x%x)\n", val, val);
11565 }
11566
11567 return p;
11568}
11569
2cf19d5c 11570static unsigned char *
2cf0635d 11571display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
11572{
11573 int type;
11574 unsigned int len;
11575 int val;
11576
11577 if (tag == Tag_GNU_MIPS_ABI_FP)
11578 {
11579 val = read_uleb128 (p, &len);
11580 p += len;
11581 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11582
2cf19d5c
JM
11583 switch (val)
11584 {
11585 case 0:
2b692964 11586 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11587 break;
11588 case 1:
2b692964 11589 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11590 break;
11591 case 2:
2b692964 11592 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11593 break;
11594 case 3:
2b692964 11595 printf (_("Soft float\n"));
2cf19d5c 11596 break;
42554f6a 11597 case 4:
9eeefea8 11598 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11599 break;
2cf19d5c
JM
11600 default:
11601 printf ("??? (%d)\n", val);
11602 break;
11603 }
11604 return p;
11605 }
11606
11607 if (tag & 1)
11608 type = 1; /* String. */
11609 else
11610 type = 2; /* uleb128. */
11611 printf (" Tag_unknown_%d: ", tag);
11612
11613 if (type == 1)
11614 {
11615 printf ("\"%s\"\n", p);
60bca95a 11616 p += strlen ((char *) p) + 1;
2cf19d5c
JM
11617 }
11618 else
11619 {
11620 val = read_uleb128 (p, &len);
11621 p += len;
11622 printf ("%d (0x%x)\n", val, val);
11623 }
11624
11625 return p;
11626}
11627
59e6276b
JM
11628static unsigned char *
11629display_tic6x_attribute (unsigned char * p)
11630{
11631 int tag;
11632 unsigned int len;
11633 int val;
11634
11635 tag = read_uleb128 (p, &len);
11636 p += len;
11637
11638 switch (tag)
11639 {
75fa6dc1 11640 case Tag_ISA:
59e6276b
JM
11641 val = read_uleb128 (p, &len);
11642 p += len;
75fa6dc1 11643 printf (" Tag_ISA: ");
59e6276b
JM
11644
11645 switch (val)
11646 {
75fa6dc1 11647 case C6XABI_Tag_ISA_none:
59e6276b
JM
11648 printf (_("None\n"));
11649 break;
75fa6dc1 11650 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11651 printf ("C62x\n");
11652 break;
75fa6dc1 11653 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11654 printf ("C67x\n");
11655 break;
75fa6dc1 11656 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11657 printf ("C67x+\n");
11658 break;
75fa6dc1 11659 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11660 printf ("C64x\n");
11661 break;
75fa6dc1 11662 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11663 printf ("C64x+\n");
11664 break;
75fa6dc1 11665 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11666 printf ("C674x\n");
11667 break;
11668 default:
11669 printf ("??? (%d)\n", val);
11670 break;
11671 }
11672 return p;
11673
87779176
JM
11674 case Tag_ABI_wchar_t:
11675 val = read_uleb128 (p, &len);
11676 p += len;
11677 printf (" Tag_ABI_wchar_t: ");
11678 switch (val)
11679 {
11680 case 0:
11681 printf (_("Not used\n"));
11682 break;
11683 case 1:
11684 printf (_("2 bytes\n"));
11685 break;
11686 case 2:
11687 printf (_("4 bytes\n"));
11688 break;
11689 default:
11690 printf ("??? (%d)\n", val);
11691 break;
11692 }
11693 return p;
11694
11695 case Tag_ABI_stack_align_needed:
11696 val = read_uleb128 (p, &len);
11697 p += len;
11698 printf (" Tag_ABI_stack_align_needed: ");
11699 switch (val)
11700 {
11701 case 0:
11702 printf (_("8-byte\n"));
11703 break;
11704 case 1:
11705 printf (_("16-byte\n"));
11706 break;
11707 default:
11708 printf ("??? (%d)\n", val);
11709 break;
11710 }
11711 return p;
11712
11713 case Tag_ABI_stack_align_preserved:
11714 val = read_uleb128 (p, &len);
11715 p += len;
11716 printf (" Tag_ABI_stack_align_preserved: ");
11717 switch (val)
11718 {
11719 case 0:
11720 printf (_("8-byte\n"));
11721 break;
11722 case 1:
11723 printf (_("16-byte\n"));
11724 break;
11725 default:
11726 printf ("??? (%d)\n", val);
11727 break;
11728 }
11729 return p;
11730
b5593623
JM
11731 case Tag_ABI_DSBT:
11732 val = read_uleb128 (p, &len);
11733 p += len;
11734 printf (" Tag_ABI_DSBT: ");
11735 switch (val)
11736 {
11737 case 0:
11738 printf (_("DSBT addressing not used\n"));
11739 break;
11740 case 1:
11741 printf (_("DSBT addressing used\n"));
11742 break;
11743 default:
11744 printf ("??? (%d)\n", val);
11745 break;
11746 }
11747 return p;
11748
87779176
JM
11749 case Tag_ABI_PID:
11750 val = read_uleb128 (p, &len);
11751 p += len;
11752 printf (" Tag_ABI_PID: ");
11753 switch (val)
11754 {
11755 case 0:
11756 printf (_("Data addressing position-dependent\n"));
11757 break;
11758 case 1:
11759 printf (_("Data addressing position-independent, GOT near DP\n"));
11760 break;
11761 case 2:
11762 printf (_("Data addressing position-independent, GOT far from DP\n"));
11763 break;
11764 default:
11765 printf ("??? (%d)\n", val);
11766 break;
11767 }
11768 return p;
11769
11770 case Tag_ABI_PIC:
11771 val = read_uleb128 (p, &len);
11772 p += len;
11773 printf (" Tag_ABI_PIC: ");
11774 switch (val)
11775 {
11776 case 0:
11777 printf (_("Code addressing position-dependent\n"));
11778 break;
11779 case 1:
11780 printf (_("Code addressing position-independent\n"));
11781 break;
11782 default:
11783 printf ("??? (%d)\n", val);
11784 break;
11785 }
11786 return p;
11787
11788 case Tag_ABI_array_object_alignment:
11789 val = read_uleb128 (p, &len);
11790 p += len;
11791 printf (" Tag_ABI_array_object_alignment: ");
11792 switch (val)
11793 {
11794 case 0:
11795 printf (_("8-byte\n"));
11796 break;
11797 case 1:
11798 printf (_("4-byte\n"));
11799 break;
11800 case 2:
11801 printf (_("16-byte\n"));
11802 break;
11803 default:
11804 printf ("??? (%d)\n", val);
11805 break;
11806 }
11807 return p;
11808
11809 case Tag_ABI_array_object_align_expected:
11810 val = read_uleb128 (p, &len);
11811 p += len;
11812 printf (" Tag_ABI_array_object_align_expected: ");
11813 switch (val)
11814 {
11815 case 0:
11816 printf (_("8-byte\n"));
11817 break;
11818 case 1:
11819 printf (_("4-byte\n"));
11820 break;
11821 case 2:
11822 printf (_("16-byte\n"));
11823 break;
11824 default:
11825 printf ("??? (%d)\n", val);
11826 break;
11827 }
11828 return p;
11829
3cbd1c06 11830 case Tag_ABI_compatibility:
59e6276b
JM
11831 val = read_uleb128 (p, &len);
11832 p += len;
3cbd1c06 11833 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11834 printf (_("flag = %d, vendor = %s\n"), val, p);
11835 p += strlen ((char *) p) + 1;
11836 return p;
87779176
JM
11837
11838 case Tag_ABI_conformance:
11839 printf (" Tag_ABI_conformance: ");
11840 printf ("\"%s\"\n", p);
11841 p += strlen ((char *) p) + 1;
11842 return p;
59e6276b
JM
11843 }
11844
11845 printf (" Tag_unknown_%d: ", tag);
11846
87779176
JM
11847 if (tag & 1)
11848 {
11849 printf ("\"%s\"\n", p);
11850 p += strlen ((char *) p) + 1;
11851 }
11852 else
11853 {
11854 val = read_uleb128 (p, &len);
11855 p += len;
11856 printf ("%d (0x%x)\n", val, val);
11857 }
59e6276b
JM
11858
11859 return p;
11860}
11861
11c1ff18 11862static int
60bca95a
NC
11863process_attributes (FILE * file,
11864 const char * public_name,
104d59d1 11865 unsigned int proc_type,
60bca95a
NC
11866 unsigned char * (* display_pub_attribute) (unsigned char *),
11867 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11868{
2cf0635d
NC
11869 Elf_Internal_Shdr * sect;
11870 unsigned char * contents;
11871 unsigned char * p;
11872 unsigned char * end;
11c1ff18
PB
11873 bfd_vma section_len;
11874 bfd_vma len;
11875 unsigned i;
11876
11877 /* Find the section header so that we get the size. */
11878 for (i = 0, sect = section_headers;
11879 i < elf_header.e_shnum;
11880 i++, sect++)
11881 {
104d59d1 11882 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11883 continue;
11884
3f5e193b
NC
11885 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11886 sect->sh_size, _("attributes"));
60bca95a 11887 if (contents == NULL)
11c1ff18 11888 continue;
60bca95a 11889
11c1ff18
PB
11890 p = contents;
11891 if (*p == 'A')
11892 {
11893 len = sect->sh_size - 1;
11894 p++;
60bca95a 11895
11c1ff18
PB
11896 while (len > 0)
11897 {
11898 int namelen;
11899 bfd_boolean public_section;
104d59d1 11900 bfd_boolean gnu_section;
11c1ff18
PB
11901
11902 section_len = byte_get (p, 4);
11903 p += 4;
60bca95a 11904
11c1ff18
PB
11905 if (section_len > len)
11906 {
11907 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11908 (int) section_len, (int) len);
11c1ff18
PB
11909 section_len = len;
11910 }
60bca95a 11911
11c1ff18 11912 len -= section_len;
2b692964 11913 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11914
11915 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11916 public_section = TRUE;
11917 else
11918 public_section = FALSE;
60bca95a
NC
11919
11920 if (streq ((char *) p, "gnu"))
104d59d1
JM
11921 gnu_section = TRUE;
11922 else
11923 gnu_section = FALSE;
60bca95a
NC
11924
11925 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11926 p += namelen;
11927 section_len -= namelen + 4;
60bca95a 11928
11c1ff18
PB
11929 while (section_len > 0)
11930 {
11931 int tag = *(p++);
11932 int val;
11933 bfd_vma size;
60bca95a 11934
11c1ff18
PB
11935 size = byte_get (p, 4);
11936 if (size > section_len)
11937 {
11938 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11939 (int) size, (int) section_len);
11c1ff18
PB
11940 size = section_len;
11941 }
60bca95a 11942
11c1ff18
PB
11943 section_len -= size;
11944 end = p + size - 1;
11945 p += 4;
60bca95a 11946
11c1ff18
PB
11947 switch (tag)
11948 {
11949 case 1:
2b692964 11950 printf (_("File Attributes\n"));
11c1ff18
PB
11951 break;
11952 case 2:
2b692964 11953 printf (_("Section Attributes:"));
11c1ff18
PB
11954 goto do_numlist;
11955 case 3:
2b692964 11956 printf (_("Symbol Attributes:"));
11c1ff18
PB
11957 do_numlist:
11958 for (;;)
11959 {
91d6fa6a 11960 unsigned int j;
60bca95a 11961
91d6fa6a
NC
11962 val = read_uleb128 (p, &j);
11963 p += j;
11c1ff18
PB
11964 if (val == 0)
11965 break;
11966 printf (" %d", val);
11967 }
11968 printf ("\n");
11969 break;
11970 default:
2b692964 11971 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
11972 public_section = FALSE;
11973 break;
11974 }
60bca95a 11975
11c1ff18
PB
11976 if (public_section)
11977 {
11978 while (p < end)
104d59d1
JM
11979 p = display_pub_attribute (p);
11980 }
11981 else if (gnu_section)
11982 {
11983 while (p < end)
11984 p = display_gnu_attribute (p,
11985 display_proc_gnu_attribute);
11c1ff18
PB
11986 }
11987 else
11988 {
11989 /* ??? Do something sensible, like dump hex. */
2b692964 11990 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
11991 p = end;
11992 }
11993 }
11994 }
11995 }
11996 else
60bca95a 11997 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 11998
60bca95a 11999 free (contents);
11c1ff18
PB
12000 }
12001 return 1;
12002}
12003
104d59d1 12004static int
2cf0635d 12005process_arm_specific (FILE * file)
104d59d1
JM
12006{
12007 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
12008 display_arm_attribute, NULL);
12009}
12010
34c8bcba 12011static int
2cf0635d 12012process_power_specific (FILE * file)
34c8bcba
JM
12013{
12014 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12015 display_power_gnu_attribute);
12016}
12017
9e8c70f9
DM
12018static int
12019process_sparc_specific (FILE * file)
12020{
12021 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12022 display_sparc_gnu_attribute);
12023}
12024
59e6276b
JM
12025static int
12026process_tic6x_specific (FILE * file)
12027{
12028 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
12029 display_tic6x_attribute, NULL);
12030}
12031
ccb4c951
RS
12032/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
12033 Print the Address, Access and Initial fields of an entry at VMA ADDR
12034 and return the VMA of the next entry. */
12035
12036static bfd_vma
2cf0635d 12037print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
12038{
12039 printf (" ");
12040 print_vma (addr, LONG_HEX);
12041 printf (" ");
12042 if (addr < pltgot + 0xfff0)
12043 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
12044 else
12045 printf ("%10s", "");
12046 printf (" ");
12047 if (data == NULL)
2b692964 12048 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
12049 else
12050 {
12051 bfd_vma entry;
12052
12053 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12054 print_vma (entry, LONG_HEX);
12055 }
12056 return addr + (is_32bit_elf ? 4 : 8);
12057}
12058
861fb55a
DJ
12059/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
12060 PLTGOT. Print the Address and Initial fields of an entry at VMA
12061 ADDR and return the VMA of the next entry. */
12062
12063static bfd_vma
2cf0635d 12064print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
12065{
12066 printf (" ");
12067 print_vma (addr, LONG_HEX);
12068 printf (" ");
12069 if (data == NULL)
2b692964 12070 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
12071 else
12072 {
12073 bfd_vma entry;
12074
12075 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
12076 print_vma (entry, LONG_HEX);
12077 }
12078 return addr + (is_32bit_elf ? 4 : 8);
12079}
12080
19e6b90e 12081static int
2cf0635d 12082process_mips_specific (FILE * file)
5b18a4bc 12083{
2cf0635d 12084 Elf_Internal_Dyn * entry;
19e6b90e
L
12085 size_t liblist_offset = 0;
12086 size_t liblistno = 0;
12087 size_t conflictsno = 0;
12088 size_t options_offset = 0;
12089 size_t conflicts_offset = 0;
861fb55a
DJ
12090 size_t pltrelsz = 0;
12091 size_t pltrel = 0;
ccb4c951 12092 bfd_vma pltgot = 0;
861fb55a
DJ
12093 bfd_vma mips_pltgot = 0;
12094 bfd_vma jmprel = 0;
ccb4c951
RS
12095 bfd_vma local_gotno = 0;
12096 bfd_vma gotsym = 0;
12097 bfd_vma symtabno = 0;
103f02d3 12098
2cf19d5c
JM
12099 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
12100 display_mips_gnu_attribute);
12101
19e6b90e
L
12102 /* We have a lot of special sections. Thanks SGI! */
12103 if (dynamic_section == NULL)
12104 /* No information available. */
12105 return 0;
252b5132 12106
b2d38a17 12107 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
12108 switch (entry->d_tag)
12109 {
12110 case DT_MIPS_LIBLIST:
d93f0186
NC
12111 liblist_offset
12112 = offset_from_vma (file, entry->d_un.d_val,
12113 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
12114 break;
12115 case DT_MIPS_LIBLISTNO:
12116 liblistno = entry->d_un.d_val;
12117 break;
12118 case DT_MIPS_OPTIONS:
d93f0186 12119 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
12120 break;
12121 case DT_MIPS_CONFLICT:
d93f0186
NC
12122 conflicts_offset
12123 = offset_from_vma (file, entry->d_un.d_val,
12124 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
12125 break;
12126 case DT_MIPS_CONFLICTNO:
12127 conflictsno = entry->d_un.d_val;
12128 break;
ccb4c951 12129 case DT_PLTGOT:
861fb55a
DJ
12130 pltgot = entry->d_un.d_ptr;
12131 break;
ccb4c951
RS
12132 case DT_MIPS_LOCAL_GOTNO:
12133 local_gotno = entry->d_un.d_val;
12134 break;
12135 case DT_MIPS_GOTSYM:
12136 gotsym = entry->d_un.d_val;
12137 break;
12138 case DT_MIPS_SYMTABNO:
12139 symtabno = entry->d_un.d_val;
12140 break;
861fb55a
DJ
12141 case DT_MIPS_PLTGOT:
12142 mips_pltgot = entry->d_un.d_ptr;
12143 break;
12144 case DT_PLTREL:
12145 pltrel = entry->d_un.d_val;
12146 break;
12147 case DT_PLTRELSZ:
12148 pltrelsz = entry->d_un.d_val;
12149 break;
12150 case DT_JMPREL:
12151 jmprel = entry->d_un.d_ptr;
12152 break;
252b5132
RH
12153 default:
12154 break;
12155 }
12156
12157 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
12158 {
2cf0635d 12159 Elf32_External_Lib * elib;
252b5132
RH
12160 size_t cnt;
12161
3f5e193b
NC
12162 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
12163 liblistno,
12164 sizeof (Elf32_External_Lib),
9cf03b7e 12165 _("liblist section data"));
a6e9f9df 12166 if (elib)
252b5132 12167 {
2b692964 12168 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 12169 (unsigned long) liblistno);
2b692964 12170 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
12171 stdout);
12172
12173 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 12174 {
a6e9f9df 12175 Elf32_Lib liblist;
91d6fa6a 12176 time_t atime;
a6e9f9df 12177 char timebuf[20];
2cf0635d 12178 struct tm * tmp;
a6e9f9df
AM
12179
12180 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12181 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
12182 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12183 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12184 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12185
91d6fa6a 12186 tmp = gmtime (&atime);
e9e44622
JJ
12187 snprintf (timebuf, sizeof (timebuf),
12188 "%04u-%02u-%02uT%02u:%02u:%02u",
12189 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12190 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 12191
31104126 12192 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
12193 if (VALID_DYNAMIC_NAME (liblist.l_name))
12194 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
12195 else
2b692964 12196 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
12197 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
12198 liblist.l_version);
a6e9f9df
AM
12199
12200 if (liblist.l_flags == 0)
2b692964 12201 puts (_(" NONE"));
a6e9f9df
AM
12202 else
12203 {
12204 static const struct
252b5132 12205 {
2cf0635d 12206 const char * name;
a6e9f9df 12207 int bit;
252b5132 12208 }
a6e9f9df
AM
12209 l_flags_vals[] =
12210 {
12211 { " EXACT_MATCH", LL_EXACT_MATCH },
12212 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
12213 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
12214 { " EXPORTS", LL_EXPORTS },
12215 { " DELAY_LOAD", LL_DELAY_LOAD },
12216 { " DELTA", LL_DELTA }
12217 };
12218 int flags = liblist.l_flags;
12219 size_t fcnt;
12220
60bca95a 12221 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
12222 if ((flags & l_flags_vals[fcnt].bit) != 0)
12223 {
12224 fputs (l_flags_vals[fcnt].name, stdout);
12225 flags ^= l_flags_vals[fcnt].bit;
12226 }
12227 if (flags != 0)
12228 printf (" %#x", (unsigned int) flags);
252b5132 12229
a6e9f9df
AM
12230 puts ("");
12231 }
252b5132 12232 }
252b5132 12233
a6e9f9df
AM
12234 free (elib);
12235 }
252b5132
RH
12236 }
12237
12238 if (options_offset != 0)
12239 {
2cf0635d
NC
12240 Elf_External_Options * eopt;
12241 Elf_Internal_Shdr * sect = section_headers;
12242 Elf_Internal_Options * iopt;
12243 Elf_Internal_Options * option;
252b5132
RH
12244 size_t offset;
12245 int cnt;
12246
12247 /* Find the section header so that we get the size. */
12248 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 12249 ++sect;
252b5132 12250
3f5e193b
NC
12251 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12252 sect->sh_size, _("options"));
a6e9f9df 12253 if (eopt)
252b5132 12254 {
3f5e193b
NC
12255 iopt = (Elf_Internal_Options *)
12256 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12257 if (iopt == NULL)
12258 {
591a748a 12259 error (_("Out of memory\n"));
a6e9f9df
AM
12260 return 0;
12261 }
76da6bbe 12262
a6e9f9df
AM
12263 offset = cnt = 0;
12264 option = iopt;
252b5132 12265
a6e9f9df
AM
12266 while (offset < sect->sh_size)
12267 {
2cf0635d 12268 Elf_External_Options * eoption;
252b5132 12269
a6e9f9df 12270 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12271
a6e9f9df
AM
12272 option->kind = BYTE_GET (eoption->kind);
12273 option->size = BYTE_GET (eoption->size);
12274 option->section = BYTE_GET (eoption->section);
12275 option->info = BYTE_GET (eoption->info);
76da6bbe 12276
a6e9f9df 12277 offset += option->size;
252b5132 12278
a6e9f9df
AM
12279 ++option;
12280 ++cnt;
12281 }
252b5132 12282
a6e9f9df
AM
12283 printf (_("\nSection '%s' contains %d entries:\n"),
12284 SECTION_NAME (sect), cnt);
76da6bbe 12285
a6e9f9df 12286 option = iopt;
252b5132 12287
a6e9f9df 12288 while (cnt-- > 0)
252b5132 12289 {
a6e9f9df
AM
12290 size_t len;
12291
12292 switch (option->kind)
252b5132 12293 {
a6e9f9df
AM
12294 case ODK_NULL:
12295 /* This shouldn't happen. */
12296 printf (" NULL %d %lx", option->section, option->info);
12297 break;
12298 case ODK_REGINFO:
12299 printf (" REGINFO ");
12300 if (elf_header.e_machine == EM_MIPS)
12301 {
12302 /* 32bit form. */
2cf0635d 12303 Elf32_External_RegInfo * ereg;
b34976b6 12304 Elf32_RegInfo reginfo;
a6e9f9df
AM
12305
12306 ereg = (Elf32_External_RegInfo *) (option + 1);
12307 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12308 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12309 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12310 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12311 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12312 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12313
12314 printf ("GPR %08lx GP 0x%lx\n",
12315 reginfo.ri_gprmask,
12316 (unsigned long) reginfo.ri_gp_value);
12317 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12318 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12319 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12320 }
12321 else
12322 {
12323 /* 64 bit form. */
2cf0635d 12324 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12325 Elf64_Internal_RegInfo reginfo;
12326
12327 ereg = (Elf64_External_RegInfo *) (option + 1);
12328 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12329 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12330 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12331 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12332 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12333 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12334
12335 printf ("GPR %08lx GP 0x",
12336 reginfo.ri_gprmask);
12337 printf_vma (reginfo.ri_gp_value);
12338 printf ("\n");
12339
12340 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12341 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12342 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12343 }
12344 ++option;
12345 continue;
12346 case ODK_EXCEPTIONS:
12347 fputs (" EXCEPTIONS fpe_min(", stdout);
12348 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12349 fputs (") fpe_max(", stdout);
12350 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12351 fputs (")", stdout);
12352
12353 if (option->info & OEX_PAGE0)
12354 fputs (" PAGE0", stdout);
12355 if (option->info & OEX_SMM)
12356 fputs (" SMM", stdout);
12357 if (option->info & OEX_FPDBUG)
12358 fputs (" FPDBUG", stdout);
12359 if (option->info & OEX_DISMISS)
12360 fputs (" DISMISS", stdout);
12361 break;
12362 case ODK_PAD:
12363 fputs (" PAD ", stdout);
12364 if (option->info & OPAD_PREFIX)
12365 fputs (" PREFIX", stdout);
12366 if (option->info & OPAD_POSTFIX)
12367 fputs (" POSTFIX", stdout);
12368 if (option->info & OPAD_SYMBOL)
12369 fputs (" SYMBOL", stdout);
12370 break;
12371 case ODK_HWPATCH:
12372 fputs (" HWPATCH ", stdout);
12373 if (option->info & OHW_R4KEOP)
12374 fputs (" R4KEOP", stdout);
12375 if (option->info & OHW_R8KPFETCH)
12376 fputs (" R8KPFETCH", stdout);
12377 if (option->info & OHW_R5KEOP)
12378 fputs (" R5KEOP", stdout);
12379 if (option->info & OHW_R5KCVTL)
12380 fputs (" R5KCVTL", stdout);
12381 break;
12382 case ODK_FILL:
12383 fputs (" FILL ", stdout);
12384 /* XXX Print content of info word? */
12385 break;
12386 case ODK_TAGS:
12387 fputs (" TAGS ", stdout);
12388 /* XXX Print content of info word? */
12389 break;
12390 case ODK_HWAND:
12391 fputs (" HWAND ", stdout);
12392 if (option->info & OHWA0_R4KEOP_CHECKED)
12393 fputs (" R4KEOP_CHECKED", stdout);
12394 if (option->info & OHWA0_R4KEOP_CLEAN)
12395 fputs (" R4KEOP_CLEAN", stdout);
12396 break;
12397 case ODK_HWOR:
12398 fputs (" HWOR ", stdout);
12399 if (option->info & OHWA0_R4KEOP_CHECKED)
12400 fputs (" R4KEOP_CHECKED", stdout);
12401 if (option->info & OHWA0_R4KEOP_CLEAN)
12402 fputs (" R4KEOP_CLEAN", stdout);
12403 break;
12404 case ODK_GP_GROUP:
12405 printf (" GP_GROUP %#06lx self-contained %#06lx",
12406 option->info & OGP_GROUP,
12407 (option->info & OGP_SELF) >> 16);
12408 break;
12409 case ODK_IDENT:
12410 printf (" IDENT %#06lx self-contained %#06lx",
12411 option->info & OGP_GROUP,
12412 (option->info & OGP_SELF) >> 16);
12413 break;
12414 default:
12415 /* This shouldn't happen. */
12416 printf (" %3d ??? %d %lx",
12417 option->kind, option->section, option->info);
12418 break;
252b5132 12419 }
a6e9f9df 12420
2cf0635d 12421 len = sizeof (* eopt);
a6e9f9df
AM
12422 while (len < option->size)
12423 if (((char *) option)[len] >= ' '
12424 && ((char *) option)[len] < 0x7f)
12425 printf ("%c", ((char *) option)[len++]);
12426 else
12427 printf ("\\%03o", ((char *) option)[len++]);
12428
12429 fputs ("\n", stdout);
252b5132 12430 ++option;
252b5132
RH
12431 }
12432
a6e9f9df 12433 free (eopt);
252b5132 12434 }
252b5132
RH
12435 }
12436
12437 if (conflicts_offset != 0 && conflictsno != 0)
12438 {
2cf0635d 12439 Elf32_Conflict * iconf;
252b5132
RH
12440 size_t cnt;
12441
12442 if (dynamic_symbols == NULL)
12443 {
591a748a 12444 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12445 return 0;
12446 }
12447
3f5e193b 12448 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12449 if (iconf == NULL)
12450 {
591a748a 12451 error (_("Out of memory\n"));
252b5132
RH
12452 return 0;
12453 }
12454
9ea033b2 12455 if (is_32bit_elf)
252b5132 12456 {
2cf0635d 12457 Elf32_External_Conflict * econf32;
a6e9f9df 12458
3f5e193b
NC
12459 econf32 = (Elf32_External_Conflict *)
12460 get_data (NULL, file, conflicts_offset, conflictsno,
12461 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12462 if (!econf32)
12463 return 0;
252b5132
RH
12464
12465 for (cnt = 0; cnt < conflictsno; ++cnt)
12466 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12467
12468 free (econf32);
252b5132
RH
12469 }
12470 else
12471 {
2cf0635d 12472 Elf64_External_Conflict * econf64;
a6e9f9df 12473
3f5e193b
NC
12474 econf64 = (Elf64_External_Conflict *)
12475 get_data (NULL, file, conflicts_offset, conflictsno,
12476 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12477 if (!econf64)
12478 return 0;
252b5132
RH
12479
12480 for (cnt = 0; cnt < conflictsno; ++cnt)
12481 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12482
12483 free (econf64);
252b5132
RH
12484 }
12485
c7e7ca54
NC
12486 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12487 (unsigned long) conflictsno);
252b5132
RH
12488 puts (_(" Num: Index Value Name"));
12489
12490 for (cnt = 0; cnt < conflictsno; ++cnt)
12491 {
2cf0635d 12492 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12493
b34976b6 12494 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12495 print_vma (psym->st_value, FULL_HEX);
31104126 12496 putchar (' ');
d79b3d50
NC
12497 if (VALID_DYNAMIC_NAME (psym->st_name))
12498 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12499 else
2b692964 12500 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12501 putchar ('\n');
252b5132
RH
12502 }
12503
252b5132
RH
12504 free (iconf);
12505 }
12506
ccb4c951
RS
12507 if (pltgot != 0 && local_gotno != 0)
12508 {
91d6fa6a 12509 bfd_vma ent, local_end, global_end;
bbeee7ea 12510 size_t i, offset;
2cf0635d 12511 unsigned char * data;
bbeee7ea 12512 int addr_size;
ccb4c951 12513
91d6fa6a 12514 ent = pltgot;
ccb4c951
RS
12515 addr_size = (is_32bit_elf ? 4 : 8);
12516 local_end = pltgot + local_gotno * addr_size;
12517 global_end = local_end + (symtabno - gotsym) * addr_size;
12518
12519 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 12520 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
12521 global_end - pltgot, 1,
12522 _("Global Offset Table data"));
59245841
NC
12523 if (data == NULL)
12524 return 0;
12525
ccb4c951
RS
12526 printf (_("\nPrimary GOT:\n"));
12527 printf (_(" Canonical gp value: "));
12528 print_vma (pltgot + 0x7ff0, LONG_HEX);
12529 printf ("\n\n");
12530
12531 printf (_(" Reserved entries:\n"));
12532 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12533 addr_size * 2, _("Address"), _("Access"),
12534 addr_size * 2, _("Initial"));
91d6fa6a 12535 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12536 printf (_(" Lazy resolver\n"));
ccb4c951 12537 if (data
91d6fa6a 12538 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12539 >> (addr_size * 8 - 1)) != 0)
12540 {
91d6fa6a 12541 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12542 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12543 }
12544 printf ("\n");
12545
91d6fa6a 12546 if (ent < local_end)
ccb4c951
RS
12547 {
12548 printf (_(" Local entries:\n"));
cc5914eb 12549 printf (" %*s %10s %*s\n",
2b692964
NC
12550 addr_size * 2, _("Address"), _("Access"),
12551 addr_size * 2, _("Initial"));
91d6fa6a 12552 while (ent < local_end)
ccb4c951 12553 {
91d6fa6a 12554 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12555 printf ("\n");
12556 }
12557 printf ("\n");
12558 }
12559
12560 if (gotsym < symtabno)
12561 {
12562 int sym_width;
12563
12564 printf (_(" Global entries:\n"));
cc5914eb 12565 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
12566 addr_size * 2, _("Address"),
12567 _("Access"),
2b692964 12568 addr_size * 2, _("Initial"),
9cf03b7e
NC
12569 addr_size * 2, _("Sym.Val."),
12570 _("Type"),
12571 /* Note for translators: "Ndx" = abbreviated form of "Index". */
12572 _("Ndx"), _("Name"));
12573
ccb4c951
RS
12574 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12575 for (i = gotsym; i < symtabno; i++)
12576 {
2cf0635d 12577 Elf_Internal_Sym * psym;
ccb4c951
RS
12578
12579 psym = dynamic_symbols + i;
91d6fa6a 12580 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12581 printf (" ");
12582 print_vma (psym->st_value, LONG_HEX);
12583 printf (" %-7s %3s ",
12584 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12585 get_symbol_index_type (psym->st_shndx));
12586 if (VALID_DYNAMIC_NAME (psym->st_name))
12587 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12588 else
2b692964 12589 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12590 printf ("\n");
12591 }
12592 printf ("\n");
12593 }
12594
12595 if (data)
12596 free (data);
12597 }
12598
861fb55a
DJ
12599 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12600 {
91d6fa6a 12601 bfd_vma ent, end;
861fb55a
DJ
12602 size_t offset, rel_offset;
12603 unsigned long count, i;
2cf0635d 12604 unsigned char * data;
861fb55a 12605 int addr_size, sym_width;
2cf0635d 12606 Elf_Internal_Rela * rels;
861fb55a
DJ
12607
12608 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12609 if (pltrel == DT_RELA)
12610 {
12611 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12612 return 0;
12613 }
12614 else
12615 {
12616 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12617 return 0;
12618 }
12619
91d6fa6a 12620 ent = mips_pltgot;
861fb55a
DJ
12621 addr_size = (is_32bit_elf ? 4 : 8);
12622 end = mips_pltgot + (2 + count) * addr_size;
12623
12624 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 12625 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 12626 1, _("Procedure Linkage Table data"));
59245841
NC
12627 if (data == NULL)
12628 return 0;
12629
9cf03b7e 12630 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
12631 printf (_(" Reserved entries:\n"));
12632 printf (_(" %*s %*s Purpose\n"),
2b692964 12633 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12634 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12635 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12636 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12637 printf (_(" Module pointer\n"));
861fb55a
DJ
12638 printf ("\n");
12639
12640 printf (_(" Entries:\n"));
cc5914eb 12641 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12642 addr_size * 2, _("Address"),
12643 addr_size * 2, _("Initial"),
12644 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12645 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12646 for (i = 0; i < count; i++)
12647 {
2cf0635d 12648 Elf_Internal_Sym * psym;
861fb55a
DJ
12649
12650 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12651 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12652 printf (" ");
12653 print_vma (psym->st_value, LONG_HEX);
12654 printf (" %-7s %3s ",
12655 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12656 get_symbol_index_type (psym->st_shndx));
12657 if (VALID_DYNAMIC_NAME (psym->st_name))
12658 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12659 else
2b692964 12660 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12661 printf ("\n");
12662 }
12663 printf ("\n");
12664
12665 if (data)
12666 free (data);
12667 free (rels);
12668 }
12669
252b5132
RH
12670 return 1;
12671}
12672
047b2264 12673static int
2cf0635d 12674process_gnu_liblist (FILE * file)
047b2264 12675{
2cf0635d
NC
12676 Elf_Internal_Shdr * section;
12677 Elf_Internal_Shdr * string_sec;
12678 Elf32_External_Lib * elib;
12679 char * strtab;
c256ffe7 12680 size_t strtab_size;
047b2264
JJ
12681 size_t cnt;
12682 unsigned i;
12683
12684 if (! do_arch)
12685 return 0;
12686
12687 for (i = 0, section = section_headers;
12688 i < elf_header.e_shnum;
b34976b6 12689 i++, section++)
047b2264
JJ
12690 {
12691 switch (section->sh_type)
12692 {
12693 case SHT_GNU_LIBLIST:
4fbb74a6 12694 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12695 break;
12696
3f5e193b
NC
12697 elib = (Elf32_External_Lib *)
12698 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 12699 _("liblist section data"));
047b2264
JJ
12700
12701 if (elib == NULL)
12702 break;
4fbb74a6 12703 string_sec = section_headers + section->sh_link;
047b2264 12704
3f5e193b
NC
12705 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12706 string_sec->sh_size,
12707 _("liblist string table"));
047b2264
JJ
12708 if (strtab == NULL
12709 || section->sh_entsize != sizeof (Elf32_External_Lib))
12710 {
12711 free (elib);
2842702f 12712 free (strtab);
047b2264
JJ
12713 break;
12714 }
59245841 12715 strtab_size = string_sec->sh_size;
047b2264
JJ
12716
12717 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12718 SECTION_NAME (section),
0af1713e 12719 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12720
2b692964 12721 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12722
12723 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12724 ++cnt)
12725 {
12726 Elf32_Lib liblist;
91d6fa6a 12727 time_t atime;
047b2264 12728 char timebuf[20];
2cf0635d 12729 struct tm * tmp;
047b2264
JJ
12730
12731 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12732 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12733 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12734 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12735 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12736
91d6fa6a 12737 tmp = gmtime (&atime);
e9e44622
JJ
12738 snprintf (timebuf, sizeof (timebuf),
12739 "%04u-%02u-%02uT%02u:%02u:%02u",
12740 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12741 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12742
12743 printf ("%3lu: ", (unsigned long) cnt);
12744 if (do_wide)
c256ffe7 12745 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12746 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12747 else
c256ffe7 12748 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12749 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12750 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12751 liblist.l_version, liblist.l_flags);
12752 }
12753
12754 free (elib);
2842702f 12755 free (strtab);
047b2264
JJ
12756 }
12757 }
12758
12759 return 1;
12760}
12761
9437c45b 12762static const char *
d3ba0551 12763get_note_type (unsigned e_type)
779fe533
NC
12764{
12765 static char buff[64];
103f02d3 12766
1ec5cd37
NC
12767 if (elf_header.e_type == ET_CORE)
12768 switch (e_type)
12769 {
57346661 12770 case NT_AUXV:
1ec5cd37 12771 return _("NT_AUXV (auxiliary vector)");
57346661 12772 case NT_PRSTATUS:
1ec5cd37 12773 return _("NT_PRSTATUS (prstatus structure)");
57346661 12774 case NT_FPREGSET:
1ec5cd37 12775 return _("NT_FPREGSET (floating point registers)");
57346661 12776 case NT_PRPSINFO:
1ec5cd37 12777 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12778 case NT_TASKSTRUCT:
1ec5cd37 12779 return _("NT_TASKSTRUCT (task structure)");
57346661 12780 case NT_PRXFPREG:
1ec5cd37 12781 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12782 case NT_PPC_VMX:
12783 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12784 case NT_PPC_VSX:
12785 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
12786 case NT_386_TLS:
12787 return _("NT_386_TLS (x86 TLS information)");
12788 case NT_386_IOPERM:
12789 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
12790 case NT_X86_XSTATE:
12791 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12792 case NT_S390_HIGH_GPRS:
12793 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12794 case NT_S390_TIMER:
12795 return _("NT_S390_TIMER (s390 timer register)");
12796 case NT_S390_TODCMP:
12797 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12798 case NT_S390_TODPREG:
12799 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12800 case NT_S390_CTRS:
12801 return _("NT_S390_CTRS (s390 control registers)");
12802 case NT_S390_PREFIX:
12803 return _("NT_S390_PREFIX (s390 prefix register)");
faa9a424
UW
12804 case NT_ARM_VFP:
12805 return _("NT_ARM_VFP (arm VFP registers)");
57346661 12806 case NT_PSTATUS:
1ec5cd37 12807 return _("NT_PSTATUS (pstatus structure)");
57346661 12808 case NT_FPREGS:
1ec5cd37 12809 return _("NT_FPREGS (floating point registers)");
57346661 12810 case NT_PSINFO:
1ec5cd37 12811 return _("NT_PSINFO (psinfo structure)");
57346661 12812 case NT_LWPSTATUS:
1ec5cd37 12813 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12814 case NT_LWPSINFO:
1ec5cd37 12815 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12816 case NT_WIN32PSTATUS:
1ec5cd37 12817 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
12818 case NT_SIGINFO:
12819 return _("NT_SIGINFO (siginfo_t data)");
12820 case NT_FILE:
12821 return _("NT_FILE (mapped files)");
1ec5cd37
NC
12822 default:
12823 break;
12824 }
12825 else
12826 switch (e_type)
12827 {
12828 case NT_VERSION:
12829 return _("NT_VERSION (version)");
12830 case NT_ARCH:
12831 return _("NT_ARCH (architecture)");
12832 default:
12833 break;
12834 }
12835
e9e44622 12836 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12837 return buff;
779fe533
NC
12838}
12839
9ece1fa9
TT
12840static int
12841print_core_note (Elf_Internal_Note *pnote)
12842{
12843 unsigned int addr_size = is_32bit_elf ? 4 : 8;
12844 bfd_vma count, page_size;
12845 unsigned char *descdata, *filenames, *descend;
12846
12847 if (pnote->type != NT_FILE)
12848 return 1;
12849
12850#ifndef BFD64
12851 if (!is_32bit_elf)
12852 {
12853 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
12854 /* Still "successful". */
12855 return 1;
12856 }
12857#endif
12858
12859 if (pnote->descsz < 2 * addr_size)
12860 {
12861 printf (_(" Malformed note - too short for header\n"));
12862 return 0;
12863 }
12864
12865 descdata = (unsigned char *) pnote->descdata;
12866 descend = descdata + pnote->descsz;
12867
12868 if (descdata[pnote->descsz - 1] != '\0')
12869 {
12870 printf (_(" Malformed note - does not end with \\0\n"));
12871 return 0;
12872 }
12873
12874 count = byte_get (descdata, addr_size);
12875 descdata += addr_size;
12876
12877 page_size = byte_get (descdata, addr_size);
12878 descdata += addr_size;
12879
12880 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
12881 {
12882 printf (_(" Malformed note - too short for supplied file count\n"));
12883 return 0;
12884 }
12885
12886 printf (_(" Page size: "));
12887 print_vma (page_size, DEC);
12888 printf ("\n");
12889
12890 printf (_(" %*s%*s%*s\n"),
12891 (int) (2 + 2 * addr_size), _("Start"),
12892 (int) (4 + 2 * addr_size), _("End"),
12893 (int) (4 + 2 * addr_size), _("Page Offset"));
12894 filenames = descdata + count * 3 * addr_size;
12895 while (--count > 0)
12896 {
12897 bfd_vma start, end, file_ofs;
12898
12899 if (filenames == descend)
12900 {
12901 printf (_(" Malformed note - filenames end too early\n"));
12902 return 0;
12903 }
12904
12905 start = byte_get (descdata, addr_size);
12906 descdata += addr_size;
12907 end = byte_get (descdata, addr_size);
12908 descdata += addr_size;
12909 file_ofs = byte_get (descdata, addr_size);
12910 descdata += addr_size;
12911
12912 printf (" ");
12913 print_vma (start, FULL_HEX);
12914 printf (" ");
12915 print_vma (end, FULL_HEX);
12916 printf (" ");
12917 print_vma (file_ofs, FULL_HEX);
12918 printf ("\n %s\n", filenames);
12919
12920 filenames += 1 + strlen ((char *) filenames);
12921 }
12922
12923 return 1;
12924}
12925
1118d252
RM
12926static const char *
12927get_gnu_elf_note_type (unsigned e_type)
12928{
12929 static char buff[64];
12930
12931 switch (e_type)
12932 {
12933 case NT_GNU_ABI_TAG:
12934 return _("NT_GNU_ABI_TAG (ABI version tag)");
12935 case NT_GNU_HWCAP:
12936 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12937 case NT_GNU_BUILD_ID:
12938 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12939 case NT_GNU_GOLD_VERSION:
12940 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12941 default:
12942 break;
12943 }
12944
12945 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12946 return buff;
12947}
12948
664f90a3
TT
12949static int
12950print_gnu_note (Elf_Internal_Note *pnote)
12951{
12952 switch (pnote->type)
12953 {
12954 case NT_GNU_BUILD_ID:
12955 {
12956 unsigned long i;
12957
12958 printf (_(" Build ID: "));
12959 for (i = 0; i < pnote->descsz; ++i)
12960 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 12961 printf ("\n");
664f90a3
TT
12962 }
12963 break;
12964
12965 case NT_GNU_ABI_TAG:
12966 {
12967 unsigned long os, major, minor, subminor;
12968 const char *osname;
12969
12970 os = byte_get ((unsigned char *) pnote->descdata, 4);
12971 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
12972 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
12973 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
12974
12975 switch (os)
12976 {
12977 case GNU_ABI_TAG_LINUX:
12978 osname = "Linux";
12979 break;
12980 case GNU_ABI_TAG_HURD:
12981 osname = "Hurd";
12982 break;
12983 case GNU_ABI_TAG_SOLARIS:
12984 osname = "Solaris";
12985 break;
12986 case GNU_ABI_TAG_FREEBSD:
12987 osname = "FreeBSD";
12988 break;
12989 case GNU_ABI_TAG_NETBSD:
12990 osname = "NetBSD";
12991 break;
12992 default:
12993 osname = "Unknown";
12994 break;
12995 }
12996
12997 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
12998 major, minor, subminor);
12999 }
13000 break;
13001 }
13002
13003 return 1;
13004}
13005
9437c45b 13006static const char *
d3ba0551 13007get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
13008{
13009 static char buff[64];
13010
b4db1224 13011 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
13012 {
13013 /* NetBSD core "procinfo" structure. */
13014 return _("NetBSD procinfo structure");
13015 }
13016
13017 /* As of Jan 2002 there are no other machine-independent notes
13018 defined for NetBSD core files. If the note type is less
13019 than the start of the machine-dependent note types, we don't
13020 understand it. */
13021
b4db1224 13022 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 13023 {
e9e44622 13024 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
13025 return buff;
13026 }
13027
13028 switch (elf_header.e_machine)
13029 {
13030 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
13031 and PT_GETFPREGS == mach+2. */
13032
13033 case EM_OLD_ALPHA:
13034 case EM_ALPHA:
13035 case EM_SPARC:
13036 case EM_SPARC32PLUS:
13037 case EM_SPARCV9:
13038 switch (e_type)
13039 {
2b692964 13040 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 13041 return _("PT_GETREGS (reg structure)");
2b692964 13042 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 13043 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13044 default:
13045 break;
13046 }
13047 break;
13048
13049 /* On all other arch's, PT_GETREGS == mach+1 and
13050 PT_GETFPREGS == mach+3. */
13051 default:
13052 switch (e_type)
13053 {
2b692964 13054 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 13055 return _("PT_GETREGS (reg structure)");
2b692964 13056 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 13057 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
13058 default:
13059 break;
13060 }
13061 }
13062
9cf03b7e 13063 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 13064 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
13065 return buff;
13066}
13067
70616151
TT
13068static const char *
13069get_stapsdt_note_type (unsigned e_type)
13070{
13071 static char buff[64];
13072
13073 switch (e_type)
13074 {
13075 case NT_STAPSDT:
13076 return _("NT_STAPSDT (SystemTap probe descriptors)");
13077
13078 default:
13079 break;
13080 }
13081
13082 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13083 return buff;
13084}
13085
c6a9fc58
TT
13086static int
13087print_stapsdt_note (Elf_Internal_Note *pnote)
13088{
13089 int addr_size = is_32bit_elf ? 4 : 8;
13090 char *data = pnote->descdata;
13091 char *data_end = pnote->descdata + pnote->descsz;
13092 bfd_vma pc, base_addr, semaphore;
13093 char *provider, *probe, *arg_fmt;
13094
13095 pc = byte_get ((unsigned char *) data, addr_size);
13096 data += addr_size;
13097 base_addr = byte_get ((unsigned char *) data, addr_size);
13098 data += addr_size;
13099 semaphore = byte_get ((unsigned char *) data, addr_size);
13100 data += addr_size;
13101
13102 provider = data;
13103 data += strlen (data) + 1;
13104 probe = data;
13105 data += strlen (data) + 1;
13106 arg_fmt = data;
13107 data += strlen (data) + 1;
13108
13109 printf (_(" Provider: %s\n"), provider);
13110 printf (_(" Name: %s\n"), probe);
13111 printf (_(" Location: "));
13112 print_vma (pc, FULL_HEX);
13113 printf (_(", Base: "));
13114 print_vma (base_addr, FULL_HEX);
13115 printf (_(", Semaphore: "));
13116 print_vma (semaphore, FULL_HEX);
9cf03b7e 13117 printf ("\n");
c6a9fc58
TT
13118 printf (_(" Arguments: %s\n"), arg_fmt);
13119
13120 return data == data_end;
13121}
13122
00e98fc7
TG
13123static const char *
13124get_ia64_vms_note_type (unsigned e_type)
13125{
13126 static char buff[64];
13127
13128 switch (e_type)
13129 {
13130 case NT_VMS_MHD:
13131 return _("NT_VMS_MHD (module header)");
13132 case NT_VMS_LNM:
13133 return _("NT_VMS_LNM (language name)");
13134 case NT_VMS_SRC:
13135 return _("NT_VMS_SRC (source files)");
13136 case NT_VMS_TITLE:
9cf03b7e 13137 return "NT_VMS_TITLE";
00e98fc7
TG
13138 case NT_VMS_EIDC:
13139 return _("NT_VMS_EIDC (consistency check)");
13140 case NT_VMS_FPMODE:
13141 return _("NT_VMS_FPMODE (FP mode)");
13142 case NT_VMS_LINKTIME:
9cf03b7e 13143 return "NT_VMS_LINKTIME";
00e98fc7
TG
13144 case NT_VMS_IMGNAM:
13145 return _("NT_VMS_IMGNAM (image name)");
13146 case NT_VMS_IMGID:
13147 return _("NT_VMS_IMGID (image id)");
13148 case NT_VMS_LINKID:
13149 return _("NT_VMS_LINKID (link id)");
13150 case NT_VMS_IMGBID:
13151 return _("NT_VMS_IMGBID (build id)");
13152 case NT_VMS_GSTNAM:
13153 return _("NT_VMS_GSTNAM (sym table name)");
13154 case NT_VMS_ORIG_DYN:
9cf03b7e 13155 return "NT_VMS_ORIG_DYN";
00e98fc7 13156 case NT_VMS_PATCHTIME:
9cf03b7e 13157 return "NT_VMS_PATCHTIME";
00e98fc7
TG
13158 default:
13159 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
13160 return buff;
13161 }
13162}
13163
13164static int
13165print_ia64_vms_note (Elf_Internal_Note * pnote)
13166{
13167 switch (pnote->type)
13168 {
13169 case NT_VMS_MHD:
13170 if (pnote->descsz > 36)
13171 {
13172 size_t l = strlen (pnote->descdata + 34);
13173 printf (_(" Creation date : %.17s\n"), pnote->descdata);
13174 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
13175 printf (_(" Module name : %s\n"), pnote->descdata + 34);
13176 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
13177 }
13178 else
13179 printf (_(" Invalid size\n"));
13180 break;
13181 case NT_VMS_LNM:
13182 printf (_(" Language: %s\n"), pnote->descdata);
13183 break;
13184#ifdef BFD64
13185 case NT_VMS_FPMODE:
9cf03b7e 13186 printf (_(" Floating Point mode: "));
4a5cb34f 13187 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13188 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
13189 break;
13190 case NT_VMS_LINKTIME:
13191 printf (_(" Link time: "));
13192 print_vms_time
13193 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13194 printf ("\n");
13195 break;
13196 case NT_VMS_PATCHTIME:
13197 printf (_(" Patch time: "));
13198 print_vms_time
13199 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
13200 printf ("\n");
13201 break;
13202 case NT_VMS_ORIG_DYN:
13203 printf (_(" Major id: %u, minor id: %u\n"),
13204 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
13205 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 13206 printf (_(" Last modified : "));
00e98fc7
TG
13207 print_vms_time
13208 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 13209 printf (_("\n Link flags : "));
4a5cb34f 13210 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
13211 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
13212 printf (_(" Header flags: 0x%08x\n"),
13213 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
13214 printf (_(" Image id : %s\n"), pnote->descdata + 32);
13215 break;
13216#endif
13217 case NT_VMS_IMGNAM:
13218 printf (_(" Image name: %s\n"), pnote->descdata);
13219 break;
13220 case NT_VMS_GSTNAM:
13221 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
13222 break;
13223 case NT_VMS_IMGID:
13224 printf (_(" Image id: %s\n"), pnote->descdata);
13225 break;
13226 case NT_VMS_LINKID:
13227 printf (_(" Linker id: %s\n"), pnote->descdata);
13228 break;
13229 default:
13230 break;
13231 }
13232 return 1;
13233}
13234
6d118b09
NC
13235/* Note that by the ELF standard, the name field is already null byte
13236 terminated, and namesz includes the terminating null byte.
13237 I.E. the value of namesz for the name "FSF" is 4.
13238
e3c8793a 13239 If the value of namesz is zero, there is no name present. */
779fe533 13240static int
2cf0635d 13241process_note (Elf_Internal_Note * pnote)
779fe533 13242{
2cf0635d
NC
13243 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
13244 const char * nt;
9437c45b
JT
13245
13246 if (pnote->namesz == 0)
1ec5cd37
NC
13247 /* If there is no note name, then use the default set of
13248 note type strings. */
13249 nt = get_note_type (pnote->type);
13250
1118d252
RM
13251 else if (const_strneq (pnote->namedata, "GNU"))
13252 /* GNU-specific object file notes. */
13253 nt = get_gnu_elf_note_type (pnote->type);
13254
0112cd26 13255 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
13256 /* NetBSD-specific core file notes. */
13257 nt = get_netbsd_elfcore_note_type (pnote->type);
13258
b15fa79e
AM
13259 else if (strneq (pnote->namedata, "SPU/", 4))
13260 {
13261 /* SPU-specific core file notes. */
13262 nt = pnote->namedata + 4;
13263 name = "SPU";
13264 }
13265
00e98fc7
TG
13266 else if (const_strneq (pnote->namedata, "IPF/VMS"))
13267 /* VMS/ia64-specific file notes. */
13268 nt = get_ia64_vms_note_type (pnote->type);
13269
70616151
TT
13270 else if (const_strneq (pnote->namedata, "stapsdt"))
13271 nt = get_stapsdt_note_type (pnote->type);
13272
9437c45b 13273 else
1ec5cd37
NC
13274 /* Don't recognize this note name; just use the default set of
13275 note type strings. */
00e98fc7 13276 nt = get_note_type (pnote->type);
9437c45b 13277
2aee03ae 13278 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
13279
13280 if (const_strneq (pnote->namedata, "IPF/VMS"))
13281 return print_ia64_vms_note (pnote);
664f90a3
TT
13282 else if (const_strneq (pnote->namedata, "GNU"))
13283 return print_gnu_note (pnote);
c6a9fc58
TT
13284 else if (const_strneq (pnote->namedata, "stapsdt"))
13285 return print_stapsdt_note (pnote);
9ece1fa9
TT
13286 else if (const_strneq (pnote->namedata, "CORE"))
13287 return print_core_note (pnote);
00e98fc7
TG
13288 else
13289 return 1;
779fe533
NC
13290}
13291
6d118b09 13292
779fe533 13293static int
2cf0635d 13294process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 13295{
2cf0635d
NC
13296 Elf_External_Note * pnotes;
13297 Elf_External_Note * external;
b34976b6 13298 int res = 1;
103f02d3 13299
779fe533
NC
13300 if (length <= 0)
13301 return 0;
103f02d3 13302
3f5e193b
NC
13303 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
13304 _("notes"));
dd24e3da 13305 if (pnotes == NULL)
a6e9f9df 13306 return 0;
779fe533 13307
103f02d3 13308 external = pnotes;
103f02d3 13309
305c7206 13310 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 13311 (unsigned long) offset, (unsigned long) length);
2aee03ae 13312 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 13313
2cf0635d 13314 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 13315 {
2cf0635d 13316 Elf_External_Note * next;
b34976b6 13317 Elf_Internal_Note inote;
2cf0635d 13318 char * temp = NULL;
6d118b09 13319
00e98fc7
TG
13320 if (!is_ia64_vms ())
13321 {
13322 inote.type = BYTE_GET (external->type);
13323 inote.namesz = BYTE_GET (external->namesz);
13324 inote.namedata = external->name;
13325 inote.descsz = BYTE_GET (external->descsz);
13326 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
13327 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13328
13329 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
13330 }
13331 else
13332 {
13333 Elf64_External_VMS_Note *vms_external;
13334
13335 vms_external = (Elf64_External_VMS_Note *)external;
13336 inote.type = BYTE_GET (vms_external->type);
13337 inote.namesz = BYTE_GET (vms_external->namesz);
13338 inote.namedata = vms_external->name;
13339 inote.descsz = BYTE_GET (vms_external->descsz);
13340 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
13341 inote.descpos = offset + (inote.descdata - (char *) pnotes);
13342
13343 next = (Elf_External_Note *)
13344 (inote.descdata + align_power (inote.descsz, 3));
13345 }
3e55a963 13346
dd24e3da
NC
13347 if ( ((char *) next > ((char *) pnotes) + length)
13348 || ((char *) next < (char *) pnotes))
3e55a963 13349 {
0fd3a477 13350 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 13351 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 13352 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
13353 inote.type, inote.namesz, inote.descsz);
13354 break;
13355 }
13356
13357 external = next;
6d118b09 13358
dd24e3da 13359 /* Prevent out-of-bounds indexing. */
8b971f9f 13360 if (inote.namedata + inote.namesz > (char *) pnotes + length
dd24e3da
NC
13361 || inote.namedata + inote.namesz < inote.namedata)
13362 {
13363 warn (_("corrupt note found at offset %lx into core notes\n"),
13364 (unsigned long) ((char *) external - (char *) pnotes));
13365 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
13366 inote.type, inote.namesz, inote.descsz);
13367 break;
13368 }
13369
6d118b09
NC
13370 /* Verify that name is null terminated. It appears that at least
13371 one version of Linux (RedHat 6.0) generates corefiles that don't
13372 comply with the ELF spec by failing to include the null byte in
13373 namesz. */
8b971f9f 13374 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13375 {
3f5e193b 13376 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13377
6d118b09
NC
13378 if (temp == NULL)
13379 {
13380 error (_("Out of memory\n"));
13381 res = 0;
13382 break;
13383 }
76da6bbe 13384
6d118b09
NC
13385 strncpy (temp, inote.namedata, inote.namesz);
13386 temp[inote.namesz] = 0;
76da6bbe 13387
6d118b09
NC
13388 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13389 inote.namedata = temp;
13390 }
13391
13392 res &= process_note (& inote);
103f02d3 13393
6d118b09
NC
13394 if (temp != NULL)
13395 {
13396 free (temp);
13397 temp = NULL;
13398 }
779fe533
NC
13399 }
13400
13401 free (pnotes);
103f02d3 13402
779fe533
NC
13403 return res;
13404}
13405
13406static int
2cf0635d 13407process_corefile_note_segments (FILE * file)
779fe533 13408{
2cf0635d 13409 Elf_Internal_Phdr * segment;
b34976b6
AM
13410 unsigned int i;
13411 int res = 1;
103f02d3 13412
d93f0186 13413 if (! get_program_headers (file))
779fe533 13414 return 0;
103f02d3 13415
779fe533
NC
13416 for (i = 0, segment = program_headers;
13417 i < elf_header.e_phnum;
b34976b6 13418 i++, segment++)
779fe533
NC
13419 {
13420 if (segment->p_type == PT_NOTE)
103f02d3 13421 res &= process_corefile_note_segment (file,
30800947
NC
13422 (bfd_vma) segment->p_offset,
13423 (bfd_vma) segment->p_filesz);
779fe533 13424 }
103f02d3 13425
779fe533
NC
13426 return res;
13427}
13428
13429static int
2cf0635d 13430process_note_sections (FILE * file)
1ec5cd37 13431{
2cf0635d 13432 Elf_Internal_Shdr * section;
1ec5cd37
NC
13433 unsigned long i;
13434 int res = 1;
13435
13436 for (i = 0, section = section_headers;
fa1908fd 13437 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
13438 i++, section++)
13439 if (section->sh_type == SHT_NOTE)
13440 res &= process_corefile_note_segment (file,
13441 (bfd_vma) section->sh_offset,
13442 (bfd_vma) section->sh_size);
13443
13444 return res;
13445}
13446
13447static int
2cf0635d 13448process_notes (FILE * file)
779fe533
NC
13449{
13450 /* If we have not been asked to display the notes then do nothing. */
13451 if (! do_notes)
13452 return 1;
103f02d3 13453
779fe533 13454 if (elf_header.e_type != ET_CORE)
1ec5cd37 13455 return process_note_sections (file);
103f02d3 13456
779fe533 13457 /* No program headers means no NOTE segment. */
1ec5cd37
NC
13458 if (elf_header.e_phnum > 0)
13459 return process_corefile_note_segments (file);
779fe533 13460
1ec5cd37
NC
13461 printf (_("No note segments present in the core file.\n"));
13462 return 1;
779fe533
NC
13463}
13464
252b5132 13465static int
2cf0635d 13466process_arch_specific (FILE * file)
252b5132 13467{
a952a375
NC
13468 if (! do_arch)
13469 return 1;
13470
252b5132
RH
13471 switch (elf_header.e_machine)
13472 {
11c1ff18
PB
13473 case EM_ARM:
13474 return process_arm_specific (file);
252b5132 13475 case EM_MIPS:
4fe85591 13476 case EM_MIPS_RS3_LE:
252b5132
RH
13477 return process_mips_specific (file);
13478 break;
34c8bcba
JM
13479 case EM_PPC:
13480 return process_power_specific (file);
13481 break;
9e8c70f9
DM
13482 case EM_SPARC:
13483 case EM_SPARC32PLUS:
13484 case EM_SPARCV9:
13485 return process_sparc_specific (file);
13486 break;
59e6276b
JM
13487 case EM_TI_C6000:
13488 return process_tic6x_specific (file);
13489 break;
252b5132
RH
13490 default:
13491 break;
13492 }
13493 return 1;
13494}
13495
13496static int
2cf0635d 13497get_file_header (FILE * file)
252b5132 13498{
9ea033b2
NC
13499 /* Read in the identity array. */
13500 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13501 return 0;
13502
9ea033b2 13503 /* Determine how to read the rest of the header. */
b34976b6 13504 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13505 {
13506 default: /* fall through */
13507 case ELFDATANONE: /* fall through */
adab8cdc
AO
13508 case ELFDATA2LSB:
13509 byte_get = byte_get_little_endian;
13510 byte_put = byte_put_little_endian;
13511 break;
13512 case ELFDATA2MSB:
13513 byte_get = byte_get_big_endian;
13514 byte_put = byte_put_big_endian;
13515 break;
9ea033b2
NC
13516 }
13517
13518 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13519 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13520
13521 /* Read in the rest of the header. */
13522 if (is_32bit_elf)
13523 {
13524 Elf32_External_Ehdr ehdr32;
252b5132 13525
9ea033b2
NC
13526 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13527 return 0;
103f02d3 13528
9ea033b2
NC
13529 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13530 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13531 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13532 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13533 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13534 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13535 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13536 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13537 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13538 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13539 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13540 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13541 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13542 }
252b5132 13543 else
9ea033b2
NC
13544 {
13545 Elf64_External_Ehdr ehdr64;
a952a375
NC
13546
13547 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13548 we will not be able to cope with the 64bit data found in
13549 64 ELF files. Detect this now and abort before we start
50c2245b 13550 overwriting things. */
a952a375
NC
13551 if (sizeof (bfd_vma) < 8)
13552 {
e3c8793a
NC
13553 error (_("This instance of readelf has been built without support for a\n\
1355464 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13555 return 0;
13556 }
103f02d3 13557
9ea033b2
NC
13558 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13559 return 0;
103f02d3 13560
9ea033b2
NC
13561 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13562 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13563 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13564 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13565 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13566 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13567 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13568 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13569 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13570 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13571 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13572 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13573 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13574 }
252b5132 13575
7ece0d85
JJ
13576 if (elf_header.e_shoff)
13577 {
13578 /* There may be some extensions in the first section header. Don't
13579 bomb if we can't read it. */
13580 if (is_32bit_elf)
13581 get_32bit_section_headers (file, 1);
13582 else
13583 get_64bit_section_headers (file, 1);
13584 }
560f3c1c 13585
252b5132
RH
13586 return 1;
13587}
13588
fb52b2f4
NC
13589/* Process one ELF object file according to the command line options.
13590 This file may actually be stored in an archive. The file is
13591 positioned at the start of the ELF object. */
13592
ff78d6d6 13593static int
2cf0635d 13594process_object (char * file_name, FILE * file)
252b5132 13595{
252b5132
RH
13596 unsigned int i;
13597
252b5132
RH
13598 if (! get_file_header (file))
13599 {
13600 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13601 return 1;
252b5132
RH
13602 }
13603
13604 /* Initialise per file variables. */
60bca95a 13605 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13606 version_info[i] = 0;
13607
60bca95a 13608 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13609 dynamic_info[i] = 0;
5115b233 13610 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13611
13612 /* Process the file. */
13613 if (show_name)
13614 printf (_("\nFile: %s\n"), file_name);
13615
18bd398b
NC
13616 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13617 Note we do this even if cmdline_dump_sects is empty because we
13618 must make sure that the dump_sets array is zeroed out before each
13619 object file is processed. */
13620 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13621 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13622
13623 if (num_cmdline_dump_sects > 0)
13624 {
13625 if (num_dump_sects == 0)
13626 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13627 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13628
13629 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13630 memcpy (dump_sects, cmdline_dump_sects,
13631 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13632 }
d70c5fc7 13633
252b5132 13634 if (! process_file_header ())
fb52b2f4 13635 return 1;
252b5132 13636
d1f5c6e3 13637 if (! process_section_headers (file))
2f62977e 13638 {
d1f5c6e3
L
13639 /* Without loaded section headers we cannot process lots of
13640 things. */
2f62977e 13641 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13642
2f62977e 13643 if (! do_using_dynamic)
2c610e4b 13644 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13645 }
252b5132 13646
d1f5c6e3
L
13647 if (! process_section_groups (file))
13648 {
13649 /* Without loaded section groups we cannot process unwind. */
13650 do_unwind = 0;
13651 }
13652
2f62977e 13653 if (process_program_headers (file))
b2d38a17 13654 process_dynamic_section (file);
252b5132
RH
13655
13656 process_relocs (file);
13657
4d6ed7c8
NC
13658 process_unwind (file);
13659
252b5132
RH
13660 process_symbol_table (file);
13661
13662 process_syminfo (file);
13663
13664 process_version_sections (file);
13665
13666 process_section_contents (file);
f5842774 13667
1ec5cd37 13668 process_notes (file);
103f02d3 13669
047b2264
JJ
13670 process_gnu_liblist (file);
13671
252b5132
RH
13672 process_arch_specific (file);
13673
d93f0186
NC
13674 if (program_headers)
13675 {
13676 free (program_headers);
13677 program_headers = NULL;
13678 }
13679
252b5132
RH
13680 if (section_headers)
13681 {
13682 free (section_headers);
13683 section_headers = NULL;
13684 }
13685
13686 if (string_table)
13687 {
13688 free (string_table);
13689 string_table = NULL;
d40ac9bd 13690 string_table_length = 0;
252b5132
RH
13691 }
13692
13693 if (dynamic_strings)
13694 {
13695 free (dynamic_strings);
13696 dynamic_strings = NULL;
d79b3d50 13697 dynamic_strings_length = 0;
252b5132
RH
13698 }
13699
13700 if (dynamic_symbols)
13701 {
13702 free (dynamic_symbols);
13703 dynamic_symbols = NULL;
19936277 13704 num_dynamic_syms = 0;
252b5132
RH
13705 }
13706
13707 if (dynamic_syminfo)
13708 {
13709 free (dynamic_syminfo);
13710 dynamic_syminfo = NULL;
13711 }
ff78d6d6 13712
293c573e
MR
13713 if (dynamic_section)
13714 {
13715 free (dynamic_section);
13716 dynamic_section = NULL;
13717 }
13718
e4b17d5c
L
13719 if (section_headers_groups)
13720 {
13721 free (section_headers_groups);
13722 section_headers_groups = NULL;
13723 }
13724
13725 if (section_groups)
13726 {
2cf0635d
NC
13727 struct group_list * g;
13728 struct group_list * next;
e4b17d5c
L
13729
13730 for (i = 0; i < group_count; i++)
13731 {
13732 for (g = section_groups [i].root; g != NULL; g = next)
13733 {
13734 next = g->next;
13735 free (g);
13736 }
13737 }
13738
13739 free (section_groups);
13740 section_groups = NULL;
13741 }
13742
19e6b90e 13743 free_debug_memory ();
18bd398b 13744
ff78d6d6 13745 return 0;
252b5132
RH
13746}
13747
2cf0635d
NC
13748/* Process an ELF archive.
13749 On entry the file is positioned just after the ARMAG string. */
13750
13751static int
13752process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13753{
13754 struct archive_info arch;
13755 struct archive_info nested_arch;
13756 size_t got;
2cf0635d
NC
13757 int ret;
13758
13759 show_name = 1;
13760
13761 /* The ARCH structure is used to hold information about this archive. */
13762 arch.file_name = NULL;
13763 arch.file = NULL;
13764 arch.index_array = NULL;
13765 arch.sym_table = NULL;
13766 arch.longnames = NULL;
13767
13768 /* The NESTED_ARCH structure is used as a single-item cache of information
13769 about a nested archive (when members of a thin archive reside within
13770 another regular archive file). */
13771 nested_arch.file_name = NULL;
13772 nested_arch.file = NULL;
13773 nested_arch.index_array = NULL;
13774 nested_arch.sym_table = NULL;
13775 nested_arch.longnames = NULL;
13776
13777 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13778 {
13779 ret = 1;
13780 goto out;
4145f1d5 13781 }
fb52b2f4 13782
4145f1d5
NC
13783 if (do_archive_index)
13784 {
2cf0635d 13785 if (arch.sym_table == NULL)
4145f1d5
NC
13786 error (_("%s: unable to dump the index as none was found\n"), file_name);
13787 else
13788 {
2cf0635d 13789 unsigned int i, l;
4145f1d5
NC
13790 unsigned long current_pos;
13791
13792 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
c2a7d3f5 13793 file_name, (long) arch.index_num, arch.sym_size);
4145f1d5
NC
13794 current_pos = ftell (file);
13795
2cf0635d 13796 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13797 {
2cf0635d
NC
13798 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13799 {
13800 char * member_name;
4145f1d5 13801
2cf0635d
NC
13802 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13803
13804 if (member_name != NULL)
13805 {
13806 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13807
13808 if (qualified_name != NULL)
13809 {
c2a7d3f5
NC
13810 printf (_("Contents of binary %s at offset "), qualified_name);
13811 (void) print_vma (arch.index_array[i], PREFIX_HEX);
13812 putchar ('\n');
2cf0635d
NC
13813 free (qualified_name);
13814 }
4145f1d5
NC
13815 }
13816 }
2cf0635d
NC
13817
13818 if (l >= arch.sym_size)
4145f1d5
NC
13819 {
13820 error (_("%s: end of the symbol table reached before the end of the index\n"),
13821 file_name);
cb8f3167 13822 break;
4145f1d5 13823 }
2cf0635d
NC
13824 printf ("\t%s\n", arch.sym_table + l);
13825 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13826 }
13827
c2a7d3f5
NC
13828 if (arch.uses_64bit_indicies)
13829 l = (l + 7) & ~ 7;
13830 else
13831 l += l & 1;
13832
2cf0635d 13833 if (l < arch.sym_size)
c2a7d3f5
NC
13834 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
13835 file_name, arch.sym_size - l);
4145f1d5 13836
4145f1d5
NC
13837 if (fseek (file, current_pos, SEEK_SET) != 0)
13838 {
13839 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13840 ret = 1;
13841 goto out;
4145f1d5 13842 }
fb52b2f4 13843 }
4145f1d5
NC
13844
13845 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13846 && !do_segments && !do_header && !do_dump && !do_version
13847 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13848 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13849 {
13850 ret = 0; /* Archive index only. */
13851 goto out;
13852 }
fb52b2f4
NC
13853 }
13854
d989285c 13855 ret = 0;
fb52b2f4
NC
13856
13857 while (1)
13858 {
2cf0635d
NC
13859 char * name;
13860 size_t namelen;
13861 char * qualified_name;
13862
13863 /* Read the next archive header. */
13864 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13865 {
13866 error (_("%s: failed to seek to next archive header\n"), file_name);
13867 return 1;
13868 }
13869 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13870 if (got != sizeof arch.arhdr)
13871 {
13872 if (got == 0)
13873 break;
13874 error (_("%s: failed to read archive header\n"), file_name);
13875 ret = 1;
13876 break;
13877 }
13878 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13879 {
13880 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13881 ret = 1;
13882 break;
13883 }
13884
13885 arch.next_arhdr_offset += sizeof arch.arhdr;
13886
13887 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13888 if (archive_file_size & 01)
13889 ++archive_file_size;
13890
13891 name = get_archive_member_name (&arch, &nested_arch);
13892 if (name == NULL)
fb52b2f4 13893 {
0fd3a477 13894 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13895 ret = 1;
13896 break;
fb52b2f4 13897 }
2cf0635d 13898 namelen = strlen (name);
fb52b2f4 13899
2cf0635d
NC
13900 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13901 if (qualified_name == NULL)
fb52b2f4 13902 {
2cf0635d 13903 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13904 ret = 1;
13905 break;
fb52b2f4
NC
13906 }
13907
2cf0635d
NC
13908 if (is_thin_archive && arch.nested_member_origin == 0)
13909 {
13910 /* This is a proxy for an external member of a thin archive. */
13911 FILE * member_file;
13912 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13913 if (member_file_name == NULL)
13914 {
13915 ret = 1;
13916 break;
13917 }
13918
13919 member_file = fopen (member_file_name, "rb");
13920 if (member_file == NULL)
13921 {
13922 error (_("Input file '%s' is not readable.\n"), member_file_name);
13923 free (member_file_name);
13924 ret = 1;
13925 break;
13926 }
13927
13928 archive_file_offset = arch.nested_member_origin;
13929
13930 ret |= process_object (qualified_name, member_file);
13931
13932 fclose (member_file);
13933 free (member_file_name);
13934 }
13935 else if (is_thin_archive)
13936 {
13937 /* This is a proxy for a member of a nested archive. */
13938 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
13939
13940 /* The nested archive file will have been opened and setup by
13941 get_archive_member_name. */
13942 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
13943 {
13944 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
13945 ret = 1;
13946 break;
13947 }
13948
13949 ret |= process_object (qualified_name, nested_arch.file);
13950 }
13951 else
13952 {
13953 archive_file_offset = arch.next_arhdr_offset;
13954 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 13955
2cf0635d
NC
13956 ret |= process_object (qualified_name, file);
13957 }
fb52b2f4 13958
2b52916e
L
13959 if (dump_sects != NULL)
13960 {
13961 free (dump_sects);
13962 dump_sects = NULL;
13963 num_dump_sects = 0;
13964 }
13965
2cf0635d 13966 free (qualified_name);
fb52b2f4
NC
13967 }
13968
4145f1d5 13969 out:
2cf0635d
NC
13970 if (nested_arch.file != NULL)
13971 fclose (nested_arch.file);
13972 release_archive (&nested_arch);
13973 release_archive (&arch);
fb52b2f4 13974
d989285c 13975 return ret;
fb52b2f4
NC
13976}
13977
13978static int
2cf0635d 13979process_file (char * file_name)
fb52b2f4 13980{
2cf0635d 13981 FILE * file;
fb52b2f4
NC
13982 struct stat statbuf;
13983 char armag[SARMAG];
13984 int ret;
13985
13986 if (stat (file_name, &statbuf) < 0)
13987 {
f24ddbdd
NC
13988 if (errno == ENOENT)
13989 error (_("'%s': No such file\n"), file_name);
13990 else
13991 error (_("Could not locate '%s'. System error message: %s\n"),
13992 file_name, strerror (errno));
13993 return 1;
13994 }
13995
13996 if (! S_ISREG (statbuf.st_mode))
13997 {
13998 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
13999 return 1;
14000 }
14001
14002 file = fopen (file_name, "rb");
14003 if (file == NULL)
14004 {
f24ddbdd 14005 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
14006 return 1;
14007 }
14008
14009 if (fread (armag, SARMAG, 1, file) != 1)
14010 {
4145f1d5 14011 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
14012 fclose (file);
14013 return 1;
14014 }
14015
14016 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
14017 ret = process_archive (file_name, file, FALSE);
14018 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
14019 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
14020 else
14021 {
4145f1d5
NC
14022 if (do_archive_index)
14023 error (_("File %s is not an archive so its index cannot be displayed.\n"),
14024 file_name);
14025
fb52b2f4
NC
14026 rewind (file);
14027 archive_file_size = archive_file_offset = 0;
14028 ret = process_object (file_name, file);
14029 }
14030
14031 fclose (file);
14032
14033 return ret;
14034}
14035
252b5132
RH
14036#ifdef SUPPORT_DISASSEMBLY
14037/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 14038 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 14039 symbols. */
252b5132
RH
14040
14041void
2cf0635d 14042print_address (unsigned int addr, FILE * outfile)
252b5132
RH
14043{
14044 fprintf (outfile,"0x%8.8x", addr);
14045}
14046
e3c8793a 14047/* Needed by the i386 disassembler. */
252b5132
RH
14048void
14049db_task_printsym (unsigned int addr)
14050{
14051 print_address (addr, stderr);
14052}
14053#endif
14054
14055int
2cf0635d 14056main (int argc, char ** argv)
252b5132 14057{
ff78d6d6
L
14058 int err;
14059
252b5132
RH
14060#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
14061 setlocale (LC_MESSAGES, "");
3882b010
L
14062#endif
14063#if defined (HAVE_SETLOCALE)
14064 setlocale (LC_CTYPE, "");
252b5132
RH
14065#endif
14066 bindtextdomain (PACKAGE, LOCALEDIR);
14067 textdomain (PACKAGE);
14068
869b9d07
MM
14069 expandargv (&argc, &argv);
14070
252b5132
RH
14071 parse_args (argc, argv);
14072
18bd398b 14073 if (num_dump_sects > 0)
59f14fc0 14074 {
18bd398b 14075 /* Make a copy of the dump_sects array. */
3f5e193b
NC
14076 cmdline_dump_sects = (dump_type *)
14077 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 14078 if (cmdline_dump_sects == NULL)
591a748a 14079 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
14080 else
14081 {
09c11c86
NC
14082 memcpy (cmdline_dump_sects, dump_sects,
14083 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
14084 num_cmdline_dump_sects = num_dump_sects;
14085 }
14086 }
14087
18bd398b
NC
14088 if (optind < (argc - 1))
14089 show_name = 1;
14090
ff78d6d6 14091 err = 0;
252b5132 14092 while (optind < argc)
18bd398b 14093 err |= process_file (argv[optind++]);
252b5132
RH
14094
14095 if (dump_sects != NULL)
14096 free (dump_sects);
59f14fc0
AS
14097 if (cmdline_dump_sects != NULL)
14098 free (cmdline_dump_sects);
252b5132 14099
ff78d6d6 14100 return err;
252b5132 14101}
This page took 1.911561 seconds and 4 git commands to generate.