]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
PR gas/12854
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
6e3d6dc1 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
7a88bc9c 3 2008, 2009, 2010, 2011
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
1b315056 45#include "config.h"
3db64b00 46#include "sysdep.h"
252b5132
RH
47#include <assert.h>
48#include <sys/stat.h>
252b5132 49#include <time.h>
1b315056
CS
50#ifdef HAVE_ZLIB_H
51#include <zlib.h>
52#endif
252b5132 53
a952a375 54#if __GNUC__ >= 2
19936277 55/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 56 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 57 Only do this if we believe that the compiler can support a 64 bit
a952a375 58 data type. For now we only rely on GCC being able to do this. */
19936277 59#define BFD64
a952a375
NC
60#endif
61
3db64b00
AM
62#include "bfd.h"
63#include "bucomm.h"
3284fe0c 64#include "elfcomm.h"
19e6b90e 65#include "dwarf.h"
252b5132
RH
66
67#include "elf/common.h"
68#include "elf/external.h"
69#include "elf/internal.h"
252b5132 70
4b78141a
NC
71
72/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
73 we can obtain the H8 reloc numbers. We need these for the
74 get_reloc_size() function. We include h8.h again after defining
75 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
76
77#include "elf/h8.h"
78#undef _ELF_H8_H
79
80/* Undo the effects of #including reloc-macros.h. */
81
82#undef START_RELOC_NUMBERS
83#undef RELOC_NUMBER
84#undef FAKE_RELOC
85#undef EMPTY_RELOC
86#undef END_RELOC_NUMBERS
87#undef _RELOC_MACROS_H
88
252b5132
RH
89/* The following headers use the elf/reloc-macros.h file to
90 automatically generate relocation recognition functions
91 such as elf_mips_reloc_type() */
92
93#define RELOC_MACROS_GEN_FUNC
94
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
252b5132 106#include "elf/fr30.h"
5c70f934 107#include "elf/frv.h"
3b16e843
NC
108#include "elf/h8.h"
109#include "elf/hppa.h"
110#include "elf/i386.h"
35b1837e 111#include "elf/i370.h"
3b16e843
NC
112#include "elf/i860.h"
113#include "elf/i960.h"
114#include "elf/ia64.h"
1e4cf259 115#include "elf/ip2k.h"
84e94c90 116#include "elf/lm32.h"
1c0d3aa6 117#include "elf/iq2000.h"
49f58d10 118#include "elf/m32c.h"
3b16e843
NC
119#include "elf/m32r.h"
120#include "elf/m68k.h"
75751cd9 121#include "elf/m68hc11.h"
252b5132 122#include "elf/mcore.h"
15ab5209 123#include "elf/mep.h"
7ba29e2a 124#include "elf/microblaze.h"
3b16e843 125#include "elf/mips.h"
3c3bdf30 126#include "elf/mmix.h"
3b16e843
NC
127#include "elf/mn10200.h"
128#include "elf/mn10300.h"
5506d11a 129#include "elf/moxie.h"
4970f871 130#include "elf/mt.h"
2469cfa2 131#include "elf/msp430.h"
3b16e843 132#include "elf/or32.h"
7d466069 133#include "elf/pj.h"
3b16e843 134#include "elf/ppc.h"
c833c019 135#include "elf/ppc64.h"
c7927a3c 136#include "elf/rx.h"
a85d7ed0 137#include "elf/s390.h"
1c0d3aa6 138#include "elf/score.h"
3b16e843
NC
139#include "elf/sh.h"
140#include "elf/sparc.h"
e9f53129 141#include "elf/spu.h"
40b36596 142#include "elf/tic6x.h"
3b16e843 143#include "elf/v850.h"
179d3252 144#include "elf/vax.h"
3b16e843 145#include "elf/x86-64.h"
c29aca4a 146#include "elf/xc16x.h"
93fbbb04 147#include "elf/xstormy16.h"
88da6820 148#include "elf/xtensa.h"
252b5132 149
252b5132 150#include "getopt.h"
566b0d53 151#include "libiberty.h"
09c11c86 152#include "safe-ctype.h"
2cf0635d 153#include "filenames.h"
252b5132 154
2cf0635d 155char * program_name = "readelf";
85b1c36d
BE
156static long archive_file_offset;
157static unsigned long archive_file_size;
158static unsigned long dynamic_addr;
159static bfd_size_type dynamic_size;
160static unsigned int dynamic_nent;
2cf0635d 161static char * dynamic_strings;
85b1c36d 162static unsigned long dynamic_strings_length;
2cf0635d 163static char * string_table;
85b1c36d
BE
164static unsigned long string_table_length;
165static unsigned long num_dynamic_syms;
2cf0635d
NC
166static Elf_Internal_Sym * dynamic_symbols;
167static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
168static unsigned long dynamic_syminfo_offset;
169static unsigned int dynamic_syminfo_nent;
f8eae8b2 170static char program_interpreter[PATH_MAX];
bb8a0291 171static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 172static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
173static bfd_vma version_info[16];
174static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
175static Elf_Internal_Shdr * section_headers;
176static Elf_Internal_Phdr * program_headers;
177static Elf_Internal_Dyn * dynamic_section;
178static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
179static int show_name;
180static int do_dynamic;
181static int do_syms;
2c610e4b 182static int do_dyn_syms;
85b1c36d
BE
183static int do_reloc;
184static int do_sections;
185static int do_section_groups;
5477e8a0 186static int do_section_details;
85b1c36d
BE
187static int do_segments;
188static int do_unwind;
189static int do_using_dynamic;
190static int do_header;
191static int do_dump;
192static int do_version;
85b1c36d
BE
193static int do_histogram;
194static int do_debugging;
85b1c36d
BE
195static int do_arch;
196static int do_notes;
4145f1d5 197static int do_archive_index;
85b1c36d 198static int is_32bit_elf;
252b5132 199
e4b17d5c
L
200struct group_list
201{
2cf0635d 202 struct group_list * next;
e4b17d5c
L
203 unsigned int section_index;
204};
205
206struct group
207{
2cf0635d 208 struct group_list * root;
e4b17d5c
L
209 unsigned int group_index;
210};
211
85b1c36d 212static size_t group_count;
2cf0635d
NC
213static struct group * section_groups;
214static struct group ** section_headers_groups;
e4b17d5c 215
09c11c86
NC
216
217/* Flag bits indicating particular types of dump. */
218#define HEX_DUMP (1 << 0) /* The -x command line switch. */
219#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
220#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
221#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 222#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
223
224typedef unsigned char dump_type;
225
226/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
227struct dump_list_entry
228{
2cf0635d 229 char * name;
09c11c86 230 dump_type type;
2cf0635d 231 struct dump_list_entry * next;
aef1f6d0 232};
2cf0635d 233static struct dump_list_entry * dump_sects_byname;
aef1f6d0 234
09c11c86
NC
235/* A dynamic array of flags indicating for which sections a dump
236 has been requested via command line switches. */
237static dump_type * cmdline_dump_sects = NULL;
238static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
239
240/* A dynamic array of flags indicating for which sections a dump of
241 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
242 basis and then initialised from the cmdline_dump_sects array,
243 the results of interpreting the -w switch, and the
244 dump_sects_byname list. */
09c11c86
NC
245static dump_type * dump_sects = NULL;
246static unsigned int num_dump_sects = 0;
252b5132 247
252b5132 248
c256ffe7 249/* How to print a vma value. */
843dd992
NC
250typedef enum print_mode
251{
252 HEX,
253 DEC,
254 DEC_5,
255 UNSIGNED,
256 PREFIX_HEX,
257 FULL_HEX,
258 LONG_HEX
259}
260print_mode;
261
9c19a809
NC
262#define UNKNOWN -1
263
2b692964
NC
264#define SECTION_NAME(X) \
265 ((X) == NULL ? _("<none>") \
266 : string_table == NULL ? _("<no-name>") \
267 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 268 : string_table + (X)->sh_name))
252b5132 269
ee42cf8c 270#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 271
9ad5cbcf
AM
272#define GET_ELF_SYMBOLS(file, section) \
273 (is_32bit_elf ? get_32bit_elf_symbols (file, section) \
274 : get_64bit_elf_symbols (file, section))
9ea033b2 275
d79b3d50
NC
276#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
277/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
278 already been called and verified that the string exists. */
279#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 280
61865e30
NC
281#define REMOVE_ARCH_BITS(ADDR) \
282 do \
283 { \
284 if (elf_header.e_machine == EM_ARM) \
285 (ADDR) &= ~1; \
286 } \
287 while (0)
d79b3d50 288\f
59245841
NC
289/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
290 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
291 using malloc and fill that. In either case return the pointer to the start of
292 the retrieved data or NULL if something went wrong. If something does go wrong
293 emit an error message using REASON as part of the context. */
294
c256ffe7 295static void *
2cf0635d
NC
296get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
297 const char * reason)
a6e9f9df 298{
2cf0635d 299 void * mvar;
a6e9f9df 300
c256ffe7 301 if (size == 0 || nmemb == 0)
a6e9f9df
AM
302 return NULL;
303
fb52b2f4 304 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 305 {
0fd3a477 306 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 307 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
308 return NULL;
309 }
310
311 mvar = var;
312 if (mvar == NULL)
313 {
c256ffe7
JJ
314 /* Check for overflow. */
315 if (nmemb < (~(size_t) 0 - 1) / size)
316 /* + 1 so that we can '\0' terminate invalid string table sections. */
317 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
318
319 if (mvar == NULL)
320 {
0fd3a477
JW
321 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
322 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
323 return NULL;
324 }
c256ffe7
JJ
325
326 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
327 }
328
c256ffe7 329 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 330 {
0fd3a477
JW
331 error (_("Unable to read in 0x%lx bytes of %s\n"),
332 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
333 if (mvar != var)
334 free (mvar);
335 return NULL;
336 }
337
338 return mvar;
339}
340
14a91970 341/* Print a VMA value. */
cb8f3167 342
66543521 343static int
14a91970 344print_vma (bfd_vma vma, print_mode mode)
66543521 345{
66543521
AM
346 int nc = 0;
347
14a91970 348 switch (mode)
66543521 349 {
14a91970
AM
350 case FULL_HEX:
351 nc = printf ("0x");
352 /* Drop through. */
66543521 353
14a91970 354 case LONG_HEX:
f7a99963 355#ifdef BFD64
14a91970 356 if (is_32bit_elf)
437c2fb7 357 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 358#endif
14a91970
AM
359 printf_vma (vma);
360 return nc + 16;
b19aac67 361
14a91970
AM
362 case DEC_5:
363 if (vma <= 99999)
364 return printf ("%5" BFD_VMA_FMT "d", vma);
365 /* Drop through. */
66543521 366
14a91970
AM
367 case PREFIX_HEX:
368 nc = printf ("0x");
369 /* Drop through. */
66543521 370
14a91970
AM
371 case HEX:
372 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 373
14a91970
AM
374 case DEC:
375 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 376
14a91970
AM
377 case UNSIGNED:
378 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 379 }
66543521 380 return 0;
f7a99963
NC
381}
382
171191ba 383/* Display a symbol on stdout. Handles the display of non-printing characters.
31104126 384
171191ba
NC
385 If DO_WIDE is not true then format the symbol to be at most WIDTH characters,
386 truncating as necessary. If WIDTH is negative then format the string to be
387 exactly - WIDTH characters, truncating or padding as necessary.
388
389 Returns the number of emitted characters. */
390
391static unsigned int
7a88bc9c 392print_symbol (int width, const char *symbol)
31104126 393{
7a88bc9c 394 const char *c;
171191ba
NC
395 bfd_boolean extra_padding = FALSE;
396 unsigned int num_printed = 0;
961c521f 397
31104126 398 if (do_wide)
961c521f 399 {
7a88bc9c
AS
400 /* Set the width to a very large value. This simplifies the
401 code below. */
961c521f
NC
402 width = INT_MAX;
403 }
31104126 404 else if (width < 0)
961c521f 405 {
961c521f
NC
406 /* Keep the width positive. This also helps. */
407 width = - width;
171191ba 408 extra_padding = TRUE;
961c521f
NC
409 }
410
411 while (width)
412 {
413 int len;
414
415 c = symbol;
416
417 /* Look for non-printing symbols inside the symbol's name.
418 This test is triggered in particular by the names generated
419 by the assembler for local labels. */
7a88bc9c 420 while (ISPRINT (*c))
961c521f
NC
421 c++;
422
423 len = c - symbol;
424
425 if (len)
426 {
427 if (len > width)
428 len = width;
cb8f3167 429
171191ba 430 printf ("%.*s", len, symbol);
961c521f
NC
431
432 width -= len;
171191ba 433 num_printed += len;
961c521f
NC
434 }
435
7a88bc9c 436 if (*c == 0 || width == 0)
961c521f
NC
437 break;
438
439 /* Now display the non-printing character, if
440 there is room left in which to dipslay it. */
7a88bc9c 441 if ((unsigned char) *c < 32)
961c521f
NC
442 {
443 if (width < 2)
444 break;
445
446 printf ("^%c", *c + 0x40);
447
448 width -= 2;
171191ba 449 num_printed += 2;
961c521f
NC
450 }
451 else
452 {
453 if (width < 6)
454 break;
cb8f3167 455
7a88bc9c 456 printf ("<0x%.2x>", (unsigned char) *c);
961c521f
NC
457
458 width -= 6;
171191ba 459 num_printed += 6;
961c521f
NC
460 }
461
462 symbol = c + 1;
463 }
171191ba
NC
464
465 if (extra_padding && width > 0)
466 {
467 /* Fill in the remaining spaces. */
468 printf ("%-*s", width, " ");
469 num_printed += 2;
470 }
471
472 return num_printed;
31104126
NC
473}
474
89fac5e3
RS
475/* Return a pointer to section NAME, or NULL if no such section exists. */
476
477static Elf_Internal_Shdr *
2cf0635d 478find_section (const char * name)
89fac5e3
RS
479{
480 unsigned int i;
481
482 for (i = 0; i < elf_header.e_shnum; i++)
483 if (streq (SECTION_NAME (section_headers + i), name))
484 return section_headers + i;
485
486 return NULL;
487}
488
0b6ae522
DJ
489/* Return a pointer to a section containing ADDR, or NULL if no such
490 section exists. */
491
492static Elf_Internal_Shdr *
493find_section_by_address (bfd_vma addr)
494{
495 unsigned int i;
496
497 for (i = 0; i < elf_header.e_shnum; i++)
498 {
499 Elf_Internal_Shdr *sec = section_headers + i;
500 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
501 return sec;
502 }
503
504 return NULL;
505}
506
507/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
508 bytes read. */
509
510static unsigned long
511read_uleb128 (unsigned char *data, unsigned int *length_return)
512{
513 return read_leb128 (data, length_return, 0);
514}
515
28f997cf
TG
516/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
517 This OS has so many departures from the ELF standard that we test it at
518 many places. */
519
520static inline int
521is_ia64_vms (void)
522{
523 return elf_header.e_machine == EM_IA_64
524 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
525}
526
bcedfee6 527/* Guess the relocation size commonly used by the specific machines. */
252b5132 528
252b5132 529static int
2dc4cec1 530guess_is_rela (unsigned int e_machine)
252b5132 531{
9c19a809 532 switch (e_machine)
252b5132
RH
533 {
534 /* Targets that use REL relocations. */
252b5132
RH
535 case EM_386:
536 case EM_486:
63fcb9e9 537 case EM_960:
e9f53129 538 case EM_ARM:
2b0337b0 539 case EM_D10V:
252b5132 540 case EM_CYGNUS_D10V:
e9f53129 541 case EM_DLX:
252b5132 542 case EM_MIPS:
4fe85591 543 case EM_MIPS_RS3_LE:
e9f53129
AM
544 case EM_CYGNUS_M32R:
545 case EM_OPENRISC:
546 case EM_OR32:
1c0d3aa6 547 case EM_SCORE:
9c19a809 548 return FALSE;
103f02d3 549
252b5132
RH
550 /* Targets that use RELA relocations. */
551 case EM_68K:
e9f53129
AM
552 case EM_860:
553 case EM_ALPHA:
554 case EM_ALTERA_NIOS2:
555 case EM_AVR:
556 case EM_AVR_OLD:
557 case EM_BLACKFIN:
60bca95a 558 case EM_CR16:
6c03b1ed 559 case EM_CR16_OLD:
e9f53129
AM
560 case EM_CRIS:
561 case EM_CRX:
2b0337b0 562 case EM_D30V:
252b5132 563 case EM_CYGNUS_D30V:
2b0337b0 564 case EM_FR30:
252b5132 565 case EM_CYGNUS_FR30:
5c70f934 566 case EM_CYGNUS_FRV:
e9f53129
AM
567 case EM_H8S:
568 case EM_H8_300:
569 case EM_H8_300H:
800eeca4 570 case EM_IA_64:
1e4cf259
NC
571 case EM_IP2K:
572 case EM_IP2K_OLD:
3b36097d 573 case EM_IQ2000:
84e94c90 574 case EM_LATTICEMICO32:
ff7eeb89 575 case EM_M32C_OLD:
49f58d10 576 case EM_M32C:
e9f53129
AM
577 case EM_M32R:
578 case EM_MCORE:
15ab5209 579 case EM_CYGNUS_MEP:
e9f53129
AM
580 case EM_MMIX:
581 case EM_MN10200:
582 case EM_CYGNUS_MN10200:
583 case EM_MN10300:
584 case EM_CYGNUS_MN10300:
5506d11a 585 case EM_MOXIE:
e9f53129
AM
586 case EM_MSP430:
587 case EM_MSP430_OLD:
d031aafb 588 case EM_MT:
64fd6348 589 case EM_NIOS32:
e9f53129
AM
590 case EM_PPC64:
591 case EM_PPC:
c7927a3c 592 case EM_RX:
e9f53129
AM
593 case EM_S390:
594 case EM_S390_OLD:
595 case EM_SH:
596 case EM_SPARC:
597 case EM_SPARC32PLUS:
598 case EM_SPARCV9:
599 case EM_SPU:
40b36596 600 case EM_TI_C6000:
e9f53129
AM
601 case EM_V850:
602 case EM_CYGNUS_V850:
603 case EM_VAX:
604 case EM_X86_64:
8a9036a4 605 case EM_L1OM:
e9f53129
AM
606 case EM_XSTORMY16:
607 case EM_XTENSA:
608 case EM_XTENSA_OLD:
7ba29e2a
NC
609 case EM_MICROBLAZE:
610 case EM_MICROBLAZE_OLD:
9c19a809 611 return TRUE;
103f02d3 612
e9f53129
AM
613 case EM_68HC05:
614 case EM_68HC08:
615 case EM_68HC11:
616 case EM_68HC16:
617 case EM_FX66:
618 case EM_ME16:
d1133906 619 case EM_MMA:
d1133906
NC
620 case EM_NCPU:
621 case EM_NDR1:
e9f53129 622 case EM_PCP:
d1133906 623 case EM_ST100:
e9f53129 624 case EM_ST19:
d1133906 625 case EM_ST7:
e9f53129
AM
626 case EM_ST9PLUS:
627 case EM_STARCORE:
d1133906 628 case EM_SVX:
e9f53129 629 case EM_TINYJ:
9c19a809
NC
630 default:
631 warn (_("Don't know about relocations on this machine architecture\n"));
632 return FALSE;
633 }
634}
252b5132 635
9c19a809 636static int
2cf0635d 637slurp_rela_relocs (FILE * file,
d3ba0551
AM
638 unsigned long rel_offset,
639 unsigned long rel_size,
2cf0635d
NC
640 Elf_Internal_Rela ** relasp,
641 unsigned long * nrelasp)
9c19a809 642{
2cf0635d 643 Elf_Internal_Rela * relas;
4d6ed7c8
NC
644 unsigned long nrelas;
645 unsigned int i;
252b5132 646
4d6ed7c8
NC
647 if (is_32bit_elf)
648 {
2cf0635d 649 Elf32_External_Rela * erelas;
103f02d3 650
3f5e193b
NC
651 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
652 rel_size, _("relocs"));
a6e9f9df
AM
653 if (!erelas)
654 return 0;
252b5132 655
4d6ed7c8 656 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 657
3f5e193b
NC
658 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
659 sizeof (Elf_Internal_Rela));
103f02d3 660
4d6ed7c8
NC
661 if (relas == NULL)
662 {
c256ffe7 663 free (erelas);
591a748a 664 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
665 return 0;
666 }
103f02d3 667
4d6ed7c8
NC
668 for (i = 0; i < nrelas; i++)
669 {
670 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
671 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 672 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 673 }
103f02d3 674
4d6ed7c8
NC
675 free (erelas);
676 }
677 else
678 {
2cf0635d 679 Elf64_External_Rela * erelas;
103f02d3 680
3f5e193b
NC
681 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
682 rel_size, _("relocs"));
a6e9f9df
AM
683 if (!erelas)
684 return 0;
4d6ed7c8
NC
685
686 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 687
3f5e193b
NC
688 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
689 sizeof (Elf_Internal_Rela));
103f02d3 690
4d6ed7c8
NC
691 if (relas == NULL)
692 {
c256ffe7 693 free (erelas);
591a748a 694 error (_("out of memory parsing relocs\n"));
4d6ed7c8 695 return 0;
9c19a809 696 }
4d6ed7c8
NC
697
698 for (i = 0; i < nrelas; i++)
9c19a809 699 {
66543521
AM
700 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
701 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 702 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
703
704 /* The #ifdef BFD64 below is to prevent a compile time
705 warning. We know that if we do not have a 64 bit data
706 type that we will never execute this code anyway. */
707#ifdef BFD64
708 if (elf_header.e_machine == EM_MIPS
709 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
710 {
711 /* In little-endian objects, r_info isn't really a
712 64-bit little-endian value: it has a 32-bit
713 little-endian symbol index followed by four
714 individual byte fields. Reorder INFO
715 accordingly. */
91d6fa6a
NC
716 bfd_vma inf = relas[i].r_info;
717 inf = (((inf & 0xffffffff) << 32)
718 | ((inf >> 56) & 0xff)
719 | ((inf >> 40) & 0xff00)
720 | ((inf >> 24) & 0xff0000)
721 | ((inf >> 8) & 0xff000000));
722 relas[i].r_info = inf;
861fb55a
DJ
723 }
724#endif /* BFD64 */
4d6ed7c8 725 }
103f02d3 726
4d6ed7c8
NC
727 free (erelas);
728 }
729 *relasp = relas;
730 *nrelasp = nrelas;
731 return 1;
732}
103f02d3 733
4d6ed7c8 734static int
2cf0635d 735slurp_rel_relocs (FILE * file,
d3ba0551
AM
736 unsigned long rel_offset,
737 unsigned long rel_size,
2cf0635d
NC
738 Elf_Internal_Rela ** relsp,
739 unsigned long * nrelsp)
4d6ed7c8 740{
2cf0635d 741 Elf_Internal_Rela * rels;
4d6ed7c8
NC
742 unsigned long nrels;
743 unsigned int i;
103f02d3 744
4d6ed7c8
NC
745 if (is_32bit_elf)
746 {
2cf0635d 747 Elf32_External_Rel * erels;
103f02d3 748
3f5e193b
NC
749 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
750 rel_size, _("relocs"));
a6e9f9df
AM
751 if (!erels)
752 return 0;
103f02d3 753
4d6ed7c8 754 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 755
3f5e193b 756 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 757
4d6ed7c8
NC
758 if (rels == NULL)
759 {
c256ffe7 760 free (erels);
591a748a 761 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
762 return 0;
763 }
764
765 for (i = 0; i < nrels; i++)
766 {
767 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
768 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 769 rels[i].r_addend = 0;
9ea033b2 770 }
4d6ed7c8
NC
771
772 free (erels);
9c19a809
NC
773 }
774 else
775 {
2cf0635d 776 Elf64_External_Rel * erels;
9ea033b2 777
3f5e193b
NC
778 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
779 rel_size, _("relocs"));
a6e9f9df
AM
780 if (!erels)
781 return 0;
103f02d3 782
4d6ed7c8 783 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 784
3f5e193b 785 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 786
4d6ed7c8 787 if (rels == NULL)
9c19a809 788 {
c256ffe7 789 free (erels);
591a748a 790 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
791 return 0;
792 }
103f02d3 793
4d6ed7c8
NC
794 for (i = 0; i < nrels; i++)
795 {
66543521
AM
796 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
797 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 798 rels[i].r_addend = 0;
861fb55a
DJ
799
800 /* The #ifdef BFD64 below is to prevent a compile time
801 warning. We know that if we do not have a 64 bit data
802 type that we will never execute this code anyway. */
803#ifdef BFD64
804 if (elf_header.e_machine == EM_MIPS
805 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
806 {
807 /* In little-endian objects, r_info isn't really a
808 64-bit little-endian value: it has a 32-bit
809 little-endian symbol index followed by four
810 individual byte fields. Reorder INFO
811 accordingly. */
91d6fa6a
NC
812 bfd_vma inf = rels[i].r_info;
813 inf = (((inf & 0xffffffff) << 32)
814 | ((inf >> 56) & 0xff)
815 | ((inf >> 40) & 0xff00)
816 | ((inf >> 24) & 0xff0000)
817 | ((inf >> 8) & 0xff000000));
818 rels[i].r_info = inf;
861fb55a
DJ
819 }
820#endif /* BFD64 */
4d6ed7c8 821 }
103f02d3 822
4d6ed7c8
NC
823 free (erels);
824 }
825 *relsp = rels;
826 *nrelsp = nrels;
827 return 1;
828}
103f02d3 829
aca88567
NC
830/* Returns the reloc type extracted from the reloc info field. */
831
832static unsigned int
833get_reloc_type (bfd_vma reloc_info)
834{
835 if (is_32bit_elf)
836 return ELF32_R_TYPE (reloc_info);
837
838 switch (elf_header.e_machine)
839 {
840 case EM_MIPS:
841 /* Note: We assume that reloc_info has already been adjusted for us. */
842 return ELF64_MIPS_R_TYPE (reloc_info);
843
844 case EM_SPARCV9:
845 return ELF64_R_TYPE_ID (reloc_info);
846
847 default:
848 return ELF64_R_TYPE (reloc_info);
849 }
850}
851
852/* Return the symbol index extracted from the reloc info field. */
853
854static bfd_vma
855get_reloc_symindex (bfd_vma reloc_info)
856{
857 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
858}
859
d3ba0551
AM
860/* Display the contents of the relocation data found at the specified
861 offset. */
ee42cf8c 862
41e92641 863static void
2cf0635d 864dump_relocations (FILE * file,
d3ba0551
AM
865 unsigned long rel_offset,
866 unsigned long rel_size,
2cf0635d 867 Elf_Internal_Sym * symtab,
d3ba0551 868 unsigned long nsyms,
2cf0635d 869 char * strtab,
d79b3d50 870 unsigned long strtablen,
d3ba0551 871 int is_rela)
4d6ed7c8 872{
b34976b6 873 unsigned int i;
2cf0635d 874 Elf_Internal_Rela * rels;
103f02d3 875
4d6ed7c8
NC
876 if (is_rela == UNKNOWN)
877 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 878
4d6ed7c8
NC
879 if (is_rela)
880 {
c8286bd1 881 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 882 return;
4d6ed7c8
NC
883 }
884 else
885 {
886 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 887 return;
252b5132
RH
888 }
889
410f7a12
L
890 if (is_32bit_elf)
891 {
892 if (is_rela)
2c71103e
NC
893 {
894 if (do_wide)
895 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
896 else
897 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
898 }
410f7a12 899 else
2c71103e
NC
900 {
901 if (do_wide)
902 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
903 else
904 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
905 }
410f7a12 906 }
252b5132 907 else
410f7a12
L
908 {
909 if (is_rela)
2c71103e
NC
910 {
911 if (do_wide)
8beeaeb7 912 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
913 else
914 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
915 }
410f7a12 916 else
2c71103e
NC
917 {
918 if (do_wide)
8beeaeb7 919 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
920 else
921 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
922 }
410f7a12 923 }
252b5132
RH
924
925 for (i = 0; i < rel_size; i++)
926 {
2cf0635d 927 const char * rtype;
b34976b6 928 bfd_vma offset;
91d6fa6a 929 bfd_vma inf;
b34976b6
AM
930 bfd_vma symtab_index;
931 bfd_vma type;
103f02d3 932
b34976b6 933 offset = rels[i].r_offset;
91d6fa6a 934 inf = rels[i].r_info;
103f02d3 935
91d6fa6a
NC
936 type = get_reloc_type (inf);
937 symtab_index = get_reloc_symindex (inf);
252b5132 938
410f7a12
L
939 if (is_32bit_elf)
940 {
39dbeff8
AM
941 printf ("%8.8lx %8.8lx ",
942 (unsigned long) offset & 0xffffffff,
91d6fa6a 943 (unsigned long) inf & 0xffffffff);
410f7a12
L
944 }
945 else
946 {
39dbeff8
AM
947#if BFD_HOST_64BIT_LONG
948 printf (do_wide
949 ? "%16.16lx %16.16lx "
950 : "%12.12lx %12.12lx ",
91d6fa6a 951 offset, inf);
39dbeff8 952#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 953#ifndef __MSVCRT__
39dbeff8
AM
954 printf (do_wide
955 ? "%16.16llx %16.16llx "
956 : "%12.12llx %12.12llx ",
91d6fa6a 957 offset, inf);
6e3d6dc1
NC
958#else
959 printf (do_wide
960 ? "%16.16I64x %16.16I64x "
961 : "%12.12I64x %12.12I64x ",
91d6fa6a 962 offset, inf);
6e3d6dc1 963#endif
39dbeff8 964#else
2c71103e
NC
965 printf (do_wide
966 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
967 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
968 _bfd_int64_high (offset),
969 _bfd_int64_low (offset),
91d6fa6a
NC
970 _bfd_int64_high (inf),
971 _bfd_int64_low (inf));
9ea033b2 972#endif
410f7a12 973 }
103f02d3 974
252b5132
RH
975 switch (elf_header.e_machine)
976 {
977 default:
978 rtype = NULL;
979 break;
980
2b0337b0 981 case EM_M32R:
252b5132 982 case EM_CYGNUS_M32R:
9ea033b2 983 rtype = elf_m32r_reloc_type (type);
252b5132
RH
984 break;
985
986 case EM_386:
987 case EM_486:
9ea033b2 988 rtype = elf_i386_reloc_type (type);
252b5132
RH
989 break;
990
ba2685cc
AM
991 case EM_68HC11:
992 case EM_68HC12:
993 rtype = elf_m68hc11_reloc_type (type);
994 break;
75751cd9 995
252b5132 996 case EM_68K:
9ea033b2 997 rtype = elf_m68k_reloc_type (type);
252b5132
RH
998 break;
999
63fcb9e9 1000 case EM_960:
9ea033b2 1001 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1002 break;
1003
adde6300 1004 case EM_AVR:
2b0337b0 1005 case EM_AVR_OLD:
adde6300
AM
1006 rtype = elf_avr_reloc_type (type);
1007 break;
1008
9ea033b2
NC
1009 case EM_OLD_SPARCV9:
1010 case EM_SPARC32PLUS:
1011 case EM_SPARCV9:
252b5132 1012 case EM_SPARC:
9ea033b2 1013 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1014 break;
1015
e9f53129
AM
1016 case EM_SPU:
1017 rtype = elf_spu_reloc_type (type);
1018 break;
1019
2b0337b0 1020 case EM_V850:
252b5132 1021 case EM_CYGNUS_V850:
9ea033b2 1022 rtype = v850_reloc_type (type);
252b5132
RH
1023 break;
1024
2b0337b0 1025 case EM_D10V:
252b5132 1026 case EM_CYGNUS_D10V:
9ea033b2 1027 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1028 break;
1029
2b0337b0 1030 case EM_D30V:
252b5132 1031 case EM_CYGNUS_D30V:
9ea033b2 1032 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1033 break;
1034
d172d4ba
NC
1035 case EM_DLX:
1036 rtype = elf_dlx_reloc_type (type);
1037 break;
1038
252b5132 1039 case EM_SH:
9ea033b2 1040 rtype = elf_sh_reloc_type (type);
252b5132
RH
1041 break;
1042
2b0337b0 1043 case EM_MN10300:
252b5132 1044 case EM_CYGNUS_MN10300:
9ea033b2 1045 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1046 break;
1047
2b0337b0 1048 case EM_MN10200:
252b5132 1049 case EM_CYGNUS_MN10200:
9ea033b2 1050 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1051 break;
1052
2b0337b0 1053 case EM_FR30:
252b5132 1054 case EM_CYGNUS_FR30:
9ea033b2 1055 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1056 break;
1057
ba2685cc
AM
1058 case EM_CYGNUS_FRV:
1059 rtype = elf_frv_reloc_type (type);
1060 break;
5c70f934 1061
252b5132 1062 case EM_MCORE:
9ea033b2 1063 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1064 break;
1065
3c3bdf30
NC
1066 case EM_MMIX:
1067 rtype = elf_mmix_reloc_type (type);
1068 break;
1069
5506d11a
AM
1070 case EM_MOXIE:
1071 rtype = elf_moxie_reloc_type (type);
1072 break;
1073
2469cfa2
NC
1074 case EM_MSP430:
1075 case EM_MSP430_OLD:
1076 rtype = elf_msp430_reloc_type (type);
1077 break;
1078
252b5132 1079 case EM_PPC:
9ea033b2 1080 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1081 break;
1082
c833c019
AM
1083 case EM_PPC64:
1084 rtype = elf_ppc64_reloc_type (type);
1085 break;
1086
252b5132 1087 case EM_MIPS:
4fe85591 1088 case EM_MIPS_RS3_LE:
9ea033b2 1089 rtype = elf_mips_reloc_type (type);
252b5132
RH
1090 break;
1091
1092 case EM_ALPHA:
9ea033b2 1093 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1094 break;
1095
1096 case EM_ARM:
9ea033b2 1097 rtype = elf_arm_reloc_type (type);
252b5132
RH
1098 break;
1099
584da044 1100 case EM_ARC:
9ea033b2 1101 rtype = elf_arc_reloc_type (type);
252b5132
RH
1102 break;
1103
1104 case EM_PARISC:
69e617ca 1105 rtype = elf_hppa_reloc_type (type);
252b5132 1106 break;
7d466069 1107
b8720f9d
JL
1108 case EM_H8_300:
1109 case EM_H8_300H:
1110 case EM_H8S:
1111 rtype = elf_h8_reloc_type (type);
1112 break;
1113
3b16e843
NC
1114 case EM_OPENRISC:
1115 case EM_OR32:
1116 rtype = elf_or32_reloc_type (type);
1117 break;
1118
7d466069 1119 case EM_PJ:
2b0337b0 1120 case EM_PJ_OLD:
7d466069
ILT
1121 rtype = elf_pj_reloc_type (type);
1122 break;
800eeca4
JW
1123 case EM_IA_64:
1124 rtype = elf_ia64_reloc_type (type);
1125 break;
1b61cf92
HPN
1126
1127 case EM_CRIS:
1128 rtype = elf_cris_reloc_type (type);
1129 break;
535c37ff
JE
1130
1131 case EM_860:
1132 rtype = elf_i860_reloc_type (type);
1133 break;
bcedfee6
NC
1134
1135 case EM_X86_64:
8a9036a4 1136 case EM_L1OM:
bcedfee6
NC
1137 rtype = elf_x86_64_reloc_type (type);
1138 break;
a85d7ed0 1139
35b1837e
AM
1140 case EM_S370:
1141 rtype = i370_reloc_type (type);
1142 break;
1143
53c7db4b
KH
1144 case EM_S390_OLD:
1145 case EM_S390:
1146 rtype = elf_s390_reloc_type (type);
1147 break;
93fbbb04 1148
1c0d3aa6
NC
1149 case EM_SCORE:
1150 rtype = elf_score_reloc_type (type);
1151 break;
1152
93fbbb04
GK
1153 case EM_XSTORMY16:
1154 rtype = elf_xstormy16_reloc_type (type);
1155 break;
179d3252 1156
1fe1f39c
NC
1157 case EM_CRX:
1158 rtype = elf_crx_reloc_type (type);
1159 break;
1160
179d3252
JT
1161 case EM_VAX:
1162 rtype = elf_vax_reloc_type (type);
1163 break;
1e4cf259
NC
1164
1165 case EM_IP2K:
1166 case EM_IP2K_OLD:
1167 rtype = elf_ip2k_reloc_type (type);
1168 break;
3b36097d
SC
1169
1170 case EM_IQ2000:
1171 rtype = elf_iq2000_reloc_type (type);
1172 break;
88da6820
NC
1173
1174 case EM_XTENSA_OLD:
1175 case EM_XTENSA:
1176 rtype = elf_xtensa_reloc_type (type);
1177 break;
a34e3ecb 1178
84e94c90
NC
1179 case EM_LATTICEMICO32:
1180 rtype = elf_lm32_reloc_type (type);
1181 break;
1182
ff7eeb89 1183 case EM_M32C_OLD:
49f58d10
JB
1184 case EM_M32C:
1185 rtype = elf_m32c_reloc_type (type);
1186 break;
1187
d031aafb
NS
1188 case EM_MT:
1189 rtype = elf_mt_reloc_type (type);
a34e3ecb 1190 break;
1d65ded4
CM
1191
1192 case EM_BLACKFIN:
1193 rtype = elf_bfin_reloc_type (type);
1194 break;
15ab5209
DB
1195
1196 case EM_CYGNUS_MEP:
1197 rtype = elf_mep_reloc_type (type);
1198 break;
60bca95a
NC
1199
1200 case EM_CR16:
6c03b1ed 1201 case EM_CR16_OLD:
60bca95a
NC
1202 rtype = elf_cr16_reloc_type (type);
1203 break;
dd24e3da 1204
7ba29e2a
NC
1205 case EM_MICROBLAZE:
1206 case EM_MICROBLAZE_OLD:
1207 rtype = elf_microblaze_reloc_type (type);
1208 break;
c7927a3c
NC
1209
1210 case EM_RX:
1211 rtype = elf_rx_reloc_type (type);
1212 break;
c29aca4a
NC
1213
1214 case EM_XC16X:
1215 case EM_C166:
1216 rtype = elf_xc16x_reloc_type (type);
1217 break;
40b36596
JM
1218
1219 case EM_TI_C6000:
1220 rtype = elf_tic6x_reloc_type (type);
1221 break;
252b5132
RH
1222 }
1223
1224 if (rtype == NULL)
39dbeff8 1225 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1226 else
8beeaeb7 1227 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1228
7ace3541 1229 if (elf_header.e_machine == EM_ALPHA
157c2599 1230 && rtype != NULL
7ace3541
RH
1231 && streq (rtype, "R_ALPHA_LITUSE")
1232 && is_rela)
1233 {
1234 switch (rels[i].r_addend)
1235 {
1236 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1237 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1238 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1239 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1240 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1241 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1242 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1243 default: rtype = NULL;
1244 }
1245 if (rtype)
1246 printf (" (%s)", rtype);
1247 else
1248 {
1249 putchar (' ');
1250 printf (_("<unknown addend: %lx>"),
1251 (unsigned long) rels[i].r_addend);
1252 }
1253 }
1254 else if (symtab_index)
252b5132 1255 {
af3fc3bc 1256 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1257 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1258 else
19936277 1259 {
2cf0635d 1260 Elf_Internal_Sym * psym;
19936277 1261
af3fc3bc 1262 psym = symtab + symtab_index;
103f02d3 1263
af3fc3bc 1264 printf (" ");
171191ba 1265
d8045f23
NC
1266 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1267 {
1268 const char * name;
1269 unsigned int len;
1270 unsigned int width = is_32bit_elf ? 8 : 14;
1271
1272 /* Relocations against GNU_IFUNC symbols do not use the value
1273 of the symbol as the address to relocate against. Instead
1274 they invoke the function named by the symbol and use its
1275 result as the address for relocation.
1276
1277 To indicate this to the user, do not display the value of
1278 the symbol in the "Symbols's Value" field. Instead show
1279 its name followed by () as a hint that the symbol is
1280 invoked. */
1281
1282 if (strtab == NULL
1283 || psym->st_name == 0
1284 || psym->st_name >= strtablen)
1285 name = "??";
1286 else
1287 name = strtab + psym->st_name;
1288
1289 len = print_symbol (width, name);
1290 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1291 }
1292 else
1293 {
1294 print_vma (psym->st_value, LONG_HEX);
171191ba 1295
d8045f23
NC
1296 printf (is_32bit_elf ? " " : " ");
1297 }
103f02d3 1298
af3fc3bc 1299 if (psym->st_name == 0)
f1ef08cb 1300 {
2cf0635d 1301 const char * sec_name = "<null>";
f1ef08cb
AM
1302 char name_buf[40];
1303
1304 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1305 {
4fbb74a6
AM
1306 if (psym->st_shndx < elf_header.e_shnum)
1307 sec_name
1308 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1309 else if (psym->st_shndx == SHN_ABS)
1310 sec_name = "ABS";
1311 else if (psym->st_shndx == SHN_COMMON)
1312 sec_name = "COMMON";
ac145307
BS
1313 else if ((elf_header.e_machine == EM_MIPS
1314 && psym->st_shndx == SHN_MIPS_SCOMMON)
1315 || (elf_header.e_machine == EM_TI_C6000
1316 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1317 sec_name = "SCOMMON";
1318 else if (elf_header.e_machine == EM_MIPS
1319 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1320 sec_name = "SUNDEF";
8a9036a4
L
1321 else if ((elf_header.e_machine == EM_X86_64
1322 || elf_header.e_machine == EM_L1OM)
3b22753a
L
1323 && psym->st_shndx == SHN_X86_64_LCOMMON)
1324 sec_name = "LARGE_COMMON";
9ce701e2
L
1325 else if (elf_header.e_machine == EM_IA_64
1326 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1327 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1328 sec_name = "ANSI_COM";
28f997cf 1329 else if (is_ia64_vms ()
148b93f2
NC
1330 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1331 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1332 else
1333 {
1334 sprintf (name_buf, "<section 0x%x>",
1335 (unsigned int) psym->st_shndx);
1336 sec_name = name_buf;
1337 }
1338 }
1339 print_symbol (22, sec_name);
1340 }
af3fc3bc 1341 else if (strtab == NULL)
d79b3d50 1342 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1343 else if (psym->st_name >= strtablen)
d79b3d50 1344 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1345 else
2c71103e 1346 print_symbol (22, strtab + psym->st_name);
103f02d3 1347
af3fc3bc 1348 if (is_rela)
171191ba 1349 {
598aaa76 1350 bfd_signed_vma off = rels[i].r_addend;
171191ba 1351
91d6fa6a 1352 if (off < 0)
598aaa76 1353 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1354 else
598aaa76 1355 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1356 }
19936277 1357 }
252b5132 1358 }
1b228002 1359 else if (is_rela)
f7a99963 1360 {
18bd398b
NC
1361 printf ("%*c", is_32bit_elf ?
1362 (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
c8286bd1 1363 print_vma (rels[i].r_addend, LONG_HEX);
f7a99963 1364 }
252b5132 1365
157c2599
NC
1366 if (elf_header.e_machine == EM_SPARCV9
1367 && rtype != NULL
1368 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1369 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1370
252b5132 1371 putchar ('\n');
2c71103e 1372
aca88567 1373#ifdef BFD64
53c7db4b 1374 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1375 {
91d6fa6a
NC
1376 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1377 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1378 const char * rtype2 = elf_mips_reloc_type (type2);
1379 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1380
2c71103e
NC
1381 printf (" Type2: ");
1382
1383 if (rtype2 == NULL)
39dbeff8
AM
1384 printf (_("unrecognized: %-7lx"),
1385 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1386 else
1387 printf ("%-17.17s", rtype2);
1388
18bd398b 1389 printf ("\n Type3: ");
2c71103e
NC
1390
1391 if (rtype3 == NULL)
39dbeff8
AM
1392 printf (_("unrecognized: %-7lx"),
1393 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1394 else
1395 printf ("%-17.17s", rtype3);
1396
53c7db4b 1397 putchar ('\n');
2c71103e 1398 }
aca88567 1399#endif /* BFD64 */
252b5132
RH
1400 }
1401
c8286bd1 1402 free (rels);
252b5132
RH
1403}
1404
1405static const char *
d3ba0551 1406get_mips_dynamic_type (unsigned long type)
252b5132
RH
1407{
1408 switch (type)
1409 {
1410 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1411 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1412 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1413 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1414 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1415 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1416 case DT_MIPS_MSYM: return "MIPS_MSYM";
1417 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1418 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1419 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1420 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1421 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1422 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1423 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1424 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1425 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1426 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1427 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1428 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1429 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1430 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1431 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1432 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1433 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1434 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1435 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1436 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1437 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1438 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1439 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1440 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1441 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1442 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1443 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1444 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1445 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1446 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1447 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1448 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1449 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1450 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1451 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1452 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1453 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1454 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1455 default:
1456 return NULL;
1457 }
1458}
1459
9a097730 1460static const char *
d3ba0551 1461get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1462{
1463 switch (type)
1464 {
1465 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1466 default:
1467 return NULL;
1468 }
103f02d3
UD
1469}
1470
7490d522
AM
1471static const char *
1472get_ppc_dynamic_type (unsigned long type)
1473{
1474 switch (type)
1475 {
a7f2871e
AM
1476 case DT_PPC_GOT: return "PPC_GOT";
1477 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1478 default:
1479 return NULL;
1480 }
1481}
1482
f1cb7e17 1483static const char *
d3ba0551 1484get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1485{
1486 switch (type)
1487 {
a7f2871e
AM
1488 case DT_PPC64_GLINK: return "PPC64_GLINK";
1489 case DT_PPC64_OPD: return "PPC64_OPD";
1490 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1491 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1492 default:
1493 return NULL;
1494 }
1495}
1496
103f02d3 1497static const char *
d3ba0551 1498get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1499{
1500 switch (type)
1501 {
1502 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1503 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1504 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1505 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1506 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1507 case DT_HP_PREINIT: return "HP_PREINIT";
1508 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1509 case DT_HP_NEEDED: return "HP_NEEDED";
1510 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1511 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1512 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1513 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1514 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1515 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1516 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1517 case DT_HP_FILTERED: return "HP_FILTERED";
1518 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1519 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1520 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1521 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1522 case DT_PLT: return "PLT";
1523 case DT_PLT_SIZE: return "PLT_SIZE";
1524 case DT_DLT: return "DLT";
1525 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1526 default:
1527 return NULL;
1528 }
1529}
9a097730 1530
ecc51f48 1531static const char *
d3ba0551 1532get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1533{
1534 switch (type)
1535 {
148b93f2
NC
1536 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1537 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1538 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1539 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1540 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1541 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1542 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1543 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1544 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1545 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1546 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1547 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1548 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1549 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1550 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1551 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1552 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1553 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1554 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1555 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1556 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1557 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1558 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1559 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1560 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1561 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1562 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1563 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1564 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1565 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1566 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1567 default:
1568 return NULL;
1569 }
1570}
1571
fabcb361
RH
1572static const char *
1573get_alpha_dynamic_type (unsigned long type)
1574{
1575 switch (type)
1576 {
1577 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1578 default:
1579 return NULL;
1580 }
1581}
1582
1c0d3aa6
NC
1583static const char *
1584get_score_dynamic_type (unsigned long type)
1585{
1586 switch (type)
1587 {
1588 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1589 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1590 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1591 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1592 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1593 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1594 default:
1595 return NULL;
1596 }
1597}
1598
40b36596
JM
1599static const char *
1600get_tic6x_dynamic_type (unsigned long type)
1601{
1602 switch (type)
1603 {
1604 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1605 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1606 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1607 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1608 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1609 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1610 default:
1611 return NULL;
1612 }
1613}
1c0d3aa6 1614
252b5132 1615static const char *
d3ba0551 1616get_dynamic_type (unsigned long type)
252b5132 1617{
e9e44622 1618 static char buff[64];
252b5132
RH
1619
1620 switch (type)
1621 {
1622 case DT_NULL: return "NULL";
1623 case DT_NEEDED: return "NEEDED";
1624 case DT_PLTRELSZ: return "PLTRELSZ";
1625 case DT_PLTGOT: return "PLTGOT";
1626 case DT_HASH: return "HASH";
1627 case DT_STRTAB: return "STRTAB";
1628 case DT_SYMTAB: return "SYMTAB";
1629 case DT_RELA: return "RELA";
1630 case DT_RELASZ: return "RELASZ";
1631 case DT_RELAENT: return "RELAENT";
1632 case DT_STRSZ: return "STRSZ";
1633 case DT_SYMENT: return "SYMENT";
1634 case DT_INIT: return "INIT";
1635 case DT_FINI: return "FINI";
1636 case DT_SONAME: return "SONAME";
1637 case DT_RPATH: return "RPATH";
1638 case DT_SYMBOLIC: return "SYMBOLIC";
1639 case DT_REL: return "REL";
1640 case DT_RELSZ: return "RELSZ";
1641 case DT_RELENT: return "RELENT";
1642 case DT_PLTREL: return "PLTREL";
1643 case DT_DEBUG: return "DEBUG";
1644 case DT_TEXTREL: return "TEXTREL";
1645 case DT_JMPREL: return "JMPREL";
1646 case DT_BIND_NOW: return "BIND_NOW";
1647 case DT_INIT_ARRAY: return "INIT_ARRAY";
1648 case DT_FINI_ARRAY: return "FINI_ARRAY";
1649 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1650 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1651 case DT_RUNPATH: return "RUNPATH";
1652 case DT_FLAGS: return "FLAGS";
2d0e6f43 1653
d1133906
NC
1654 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1655 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1656
05107a46 1657 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1658 case DT_PLTPADSZ: return "PLTPADSZ";
1659 case DT_MOVEENT: return "MOVEENT";
1660 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1661 case DT_FEATURE: return "FEATURE";
252b5132
RH
1662 case DT_POSFLAG_1: return "POSFLAG_1";
1663 case DT_SYMINSZ: return "SYMINSZ";
1664 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1665
252b5132 1666 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1667 case DT_CONFIG: return "CONFIG";
1668 case DT_DEPAUDIT: return "DEPAUDIT";
1669 case DT_AUDIT: return "AUDIT";
1670 case DT_PLTPAD: return "PLTPAD";
1671 case DT_MOVETAB: return "MOVETAB";
252b5132 1672 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1673
252b5132 1674 case DT_VERSYM: return "VERSYM";
103f02d3 1675
67a4f2b7
AO
1676 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1677 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1678 case DT_RELACOUNT: return "RELACOUNT";
1679 case DT_RELCOUNT: return "RELCOUNT";
1680 case DT_FLAGS_1: return "FLAGS_1";
1681 case DT_VERDEF: return "VERDEF";
1682 case DT_VERDEFNUM: return "VERDEFNUM";
1683 case DT_VERNEED: return "VERNEED";
1684 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1685
019148e4 1686 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1687 case DT_USED: return "USED";
1688 case DT_FILTER: return "FILTER";
103f02d3 1689
047b2264
JJ
1690 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1691 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1692 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1693 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1694 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1695 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1696
252b5132
RH
1697 default:
1698 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1699 {
2cf0635d 1700 const char * result;
103f02d3 1701
252b5132
RH
1702 switch (elf_header.e_machine)
1703 {
1704 case EM_MIPS:
4fe85591 1705 case EM_MIPS_RS3_LE:
252b5132
RH
1706 result = get_mips_dynamic_type (type);
1707 break;
9a097730
RH
1708 case EM_SPARCV9:
1709 result = get_sparc64_dynamic_type (type);
1710 break;
7490d522
AM
1711 case EM_PPC:
1712 result = get_ppc_dynamic_type (type);
1713 break;
f1cb7e17
AM
1714 case EM_PPC64:
1715 result = get_ppc64_dynamic_type (type);
1716 break;
ecc51f48
NC
1717 case EM_IA_64:
1718 result = get_ia64_dynamic_type (type);
1719 break;
fabcb361
RH
1720 case EM_ALPHA:
1721 result = get_alpha_dynamic_type (type);
1722 break;
1c0d3aa6
NC
1723 case EM_SCORE:
1724 result = get_score_dynamic_type (type);
1725 break;
40b36596
JM
1726 case EM_TI_C6000:
1727 result = get_tic6x_dynamic_type (type);
1728 break;
252b5132
RH
1729 default:
1730 result = NULL;
1731 break;
1732 }
1733
1734 if (result != NULL)
1735 return result;
1736
e9e44622 1737 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1738 }
eec8f817
DA
1739 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1740 || (elf_header.e_machine == EM_PARISC
1741 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1742 {
2cf0635d 1743 const char * result;
103f02d3
UD
1744
1745 switch (elf_header.e_machine)
1746 {
1747 case EM_PARISC:
1748 result = get_parisc_dynamic_type (type);
1749 break;
148b93f2
NC
1750 case EM_IA_64:
1751 result = get_ia64_dynamic_type (type);
1752 break;
103f02d3
UD
1753 default:
1754 result = NULL;
1755 break;
1756 }
1757
1758 if (result != NULL)
1759 return result;
1760
e9e44622
JJ
1761 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1762 type);
103f02d3 1763 }
252b5132 1764 else
e9e44622 1765 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1766
252b5132
RH
1767 return buff;
1768 }
1769}
1770
1771static char *
d3ba0551 1772get_file_type (unsigned e_type)
252b5132 1773{
b34976b6 1774 static char buff[32];
252b5132
RH
1775
1776 switch (e_type)
1777 {
1778 case ET_NONE: return _("NONE (None)");
1779 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1780 case ET_EXEC: return _("EXEC (Executable file)");
1781 case ET_DYN: return _("DYN (Shared object file)");
1782 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1783
1784 default:
1785 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1786 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1787 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1788 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1789 else
e9e44622 1790 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1791 return buff;
1792 }
1793}
1794
1795static char *
d3ba0551 1796get_machine_name (unsigned e_machine)
252b5132 1797{
b34976b6 1798 static char buff[64]; /* XXX */
252b5132
RH
1799
1800 switch (e_machine)
1801 {
c45021f2
NC
1802 case EM_NONE: return _("None");
1803 case EM_M32: return "WE32100";
1804 case EM_SPARC: return "Sparc";
e9f53129 1805 case EM_SPU: return "SPU";
c45021f2
NC
1806 case EM_386: return "Intel 80386";
1807 case EM_68K: return "MC68000";
1808 case EM_88K: return "MC88000";
1809 case EM_486: return "Intel 80486";
1810 case EM_860: return "Intel 80860";
1811 case EM_MIPS: return "MIPS R3000";
1812 case EM_S370: return "IBM System/370";
7036c0e1 1813 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1814 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1815 case EM_PARISC: return "HPPA";
252b5132 1816 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1817 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1818 case EM_960: return "Intel 90860";
1819 case EM_PPC: return "PowerPC";
285d1771 1820 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1821 case EM_V800: return "NEC V800";
1822 case EM_FR20: return "Fujitsu FR20";
1823 case EM_RH32: return "TRW RH32";
b34976b6 1824 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1825 case EM_ARM: return "ARM";
1826 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1827 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1828 case EM_SPARCV9: return "Sparc v9";
1829 case EM_TRICORE: return "Siemens Tricore";
584da044 1830 case EM_ARC: return "ARC";
c2dcd04e
NC
1831 case EM_H8_300: return "Renesas H8/300";
1832 case EM_H8_300H: return "Renesas H8/300H";
1833 case EM_H8S: return "Renesas H8S";
1834 case EM_H8_500: return "Renesas H8/500";
30800947 1835 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1836 case EM_MIPS_X: return "Stanford MIPS-X";
1837 case EM_COLDFIRE: return "Motorola Coldfire";
1838 case EM_68HC12: return "Motorola M68HC12";
c45021f2 1839 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1840 case EM_CYGNUS_D10V:
1841 case EM_D10V: return "d10v";
1842 case EM_CYGNUS_D30V:
b34976b6 1843 case EM_D30V: return "d30v";
2b0337b0 1844 case EM_CYGNUS_M32R:
26597c86 1845 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1846 case EM_CYGNUS_V850:
8f7e76d0 1847 case EM_V850: return "Renesas v850";
2b0337b0
AO
1848 case EM_CYGNUS_MN10300:
1849 case EM_MN10300: return "mn10300";
1850 case EM_CYGNUS_MN10200:
1851 case EM_MN10200: return "mn10200";
5506d11a 1852 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1853 case EM_CYGNUS_FR30:
1854 case EM_FR30: return "Fujitsu FR30";
b34976b6 1855 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1856 case EM_PJ_OLD:
b34976b6 1857 case EM_PJ: return "picoJava";
7036c0e1
AJ
1858 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1859 case EM_PCP: return "Siemens PCP";
1860 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1861 case EM_NDR1: return "Denso NDR1 microprocesspr";
1862 case EM_STARCORE: return "Motorola Star*Core processor";
1863 case EM_ME16: return "Toyota ME16 processor";
1864 case EM_ST100: return "STMicroelectronics ST100 processor";
1865 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1866 case EM_PDSP: return "Sony DSP processor";
1867 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1868 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1869 case EM_FX66: return "Siemens FX66 microcontroller";
1870 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1871 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1872 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
1873 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1874 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1875 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1876 case EM_SVX: return "Silicon Graphics SVx";
1877 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1878 case EM_VAX: return "Digital VAX";
2b0337b0 1879 case EM_AVR_OLD:
b34976b6 1880 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1881 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1882 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1883 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1884 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1885 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1886 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1887 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1888 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1889 case EM_L1OM: return "Intel L1OM";
b7498e0e 1890 case EM_S390_OLD:
b34976b6 1891 case EM_S390: return "IBM S/390";
1c0d3aa6 1892 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1893 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1894 case EM_OPENRISC:
1895 case EM_OR32: return "OpenRISC";
11636f9e 1896 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1897 case EM_CRX: return "National Semiconductor CRX microprocessor";
d172d4ba 1898 case EM_DLX: return "OpenDLX";
1e4cf259 1899 case EM_IP2K_OLD:
b34976b6 1900 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1901 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1902 case EM_XTENSA_OLD:
1903 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1904 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1905 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1906 case EM_NS32K: return "National Semiconductor 32000 series";
1907 case EM_TPC: return "Tenor Network TPC processor";
1908 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1909 case EM_MAX: return "MAX Processor";
1910 case EM_CR: return "National Semiconductor CompactRISC";
1911 case EM_F2MC16: return "Fujitsu F2MC16";
1912 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1913 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1914 case EM_M32C_OLD:
49f58d10 1915 case EM_M32C: return "Renesas M32c";
d031aafb 1916 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1917 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1918 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1919 case EM_SEP: return "Sharp embedded microprocessor";
1920 case EM_ARCA: return "Arca RISC microprocessor";
1921 case EM_UNICORE: return "Unicore";
1922 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1923 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1924 case EM_NIOS32: return "Altera Nios";
1925 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1926 case EM_C166:
d70c5fc7 1927 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
1928 case EM_M16C: return "Renesas M16C series microprocessors";
1929 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
1930 case EM_CE: return "Freescale Communication Engine RISC core";
1931 case EM_TSK3000: return "Altium TSK3000 core";
1932 case EM_RS08: return "Freescale RS08 embedded processor";
1933 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
1934 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
1935 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
1936 case EM_SE_C17: return "Seiko Epson C17 family";
1937 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
1938 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
1939 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
1940 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
1941 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
1942 case EM_R32C: return "Renesas R32C series microprocessors";
1943 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
1944 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
1945 case EM_8051: return "Intel 8051 and variants";
1946 case EM_STXP7X: return "STMicroelectronics STxP7x family";
1947 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
1948 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
1949 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
1950 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
1951 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
1952 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 1953 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 1954 case EM_CR16:
6c03b1ed 1955 case EM_CR16_OLD: return "National Semiconductor's CR16";
7ba29e2a
NC
1956 case EM_MICROBLAZE: return "Xilinx MicroBlaze";
1957 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
c7927a3c 1958 case EM_RX: return "Renesas RX";
11636f9e
JM
1959 case EM_METAG: return "Imagination Technologies META processor architecture";
1960 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
1961 case EM_ECOG16: return "Cyan Technology eCOG16 family";
1962 case EM_ETPU: return "Freescale Extended Time Processing Unit";
1963 case EM_SLE9X: return "Infineon Technologies SLE9X core";
1964 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
1965 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
1966 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
1967 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
1968 case EM_CUDA: return "NVIDIA CUDA architecture";
252b5132 1969 default:
35d9dd2f 1970 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
1971 return buff;
1972 }
1973}
1974
f3485b74 1975static void
d3ba0551 1976decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
1977{
1978 unsigned eabi;
1979 int unknown = 0;
1980
1981 eabi = EF_ARM_EABI_VERSION (e_flags);
1982 e_flags &= ~ EF_ARM_EABIMASK;
1983
1984 /* Handle "generic" ARM flags. */
1985 if (e_flags & EF_ARM_RELEXEC)
1986 {
1987 strcat (buf, ", relocatable executable");
1988 e_flags &= ~ EF_ARM_RELEXEC;
1989 }
76da6bbe 1990
f3485b74
NC
1991 if (e_flags & EF_ARM_HASENTRY)
1992 {
1993 strcat (buf, ", has entry point");
1994 e_flags &= ~ EF_ARM_HASENTRY;
1995 }
76da6bbe 1996
f3485b74
NC
1997 /* Now handle EABI specific flags. */
1998 switch (eabi)
1999 {
2000 default:
2c71103e 2001 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2002 if (e_flags)
2003 unknown = 1;
2004 break;
2005
2006 case EF_ARM_EABI_VER1:
a5bcd848 2007 strcat (buf, ", Version1 EABI");
f3485b74
NC
2008 while (e_flags)
2009 {
2010 unsigned flag;
76da6bbe 2011
f3485b74
NC
2012 /* Process flags one bit at a time. */
2013 flag = e_flags & - e_flags;
2014 e_flags &= ~ flag;
76da6bbe 2015
f3485b74
NC
2016 switch (flag)
2017 {
a5bcd848 2018 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2019 strcat (buf, ", sorted symbol tables");
2020 break;
76da6bbe 2021
f3485b74
NC
2022 default:
2023 unknown = 1;
2024 break;
2025 }
2026 }
2027 break;
76da6bbe 2028
a5bcd848
PB
2029 case EF_ARM_EABI_VER2:
2030 strcat (buf, ", Version2 EABI");
2031 while (e_flags)
2032 {
2033 unsigned flag;
2034
2035 /* Process flags one bit at a time. */
2036 flag = e_flags & - e_flags;
2037 e_flags &= ~ flag;
2038
2039 switch (flag)
2040 {
2041 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2042 strcat (buf, ", sorted symbol tables");
2043 break;
2044
2045 case EF_ARM_DYNSYMSUSESEGIDX:
2046 strcat (buf, ", dynamic symbols use segment index");
2047 break;
2048
2049 case EF_ARM_MAPSYMSFIRST:
2050 strcat (buf, ", mapping symbols precede others");
2051 break;
2052
2053 default:
2054 unknown = 1;
2055 break;
2056 }
2057 }
2058 break;
2059
d507cf36
PB
2060 case EF_ARM_EABI_VER3:
2061 strcat (buf, ", Version3 EABI");
8cb51566
PB
2062 break;
2063
2064 case EF_ARM_EABI_VER4:
2065 strcat (buf, ", Version4 EABI");
3a4a14e9
PB
2066 goto eabi;
2067
2068 case EF_ARM_EABI_VER5:
2069 strcat (buf, ", Version5 EABI");
2070 eabi:
d507cf36
PB
2071 while (e_flags)
2072 {
2073 unsigned flag;
2074
2075 /* Process flags one bit at a time. */
2076 flag = e_flags & - e_flags;
2077 e_flags &= ~ flag;
2078
2079 switch (flag)
2080 {
2081 case EF_ARM_BE8:
2082 strcat (buf, ", BE8");
2083 break;
2084
2085 case EF_ARM_LE8:
2086 strcat (buf, ", LE8");
2087 break;
2088
2089 default:
2090 unknown = 1;
2091 break;
2092 }
2093 }
2094 break;
2095
f3485b74 2096 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2097 strcat (buf, ", GNU EABI");
f3485b74
NC
2098 while (e_flags)
2099 {
2100 unsigned flag;
76da6bbe 2101
f3485b74
NC
2102 /* Process flags one bit at a time. */
2103 flag = e_flags & - e_flags;
2104 e_flags &= ~ flag;
76da6bbe 2105
f3485b74
NC
2106 switch (flag)
2107 {
a5bcd848 2108 case EF_ARM_INTERWORK:
f3485b74
NC
2109 strcat (buf, ", interworking enabled");
2110 break;
76da6bbe 2111
a5bcd848 2112 case EF_ARM_APCS_26:
f3485b74
NC
2113 strcat (buf, ", uses APCS/26");
2114 break;
76da6bbe 2115
a5bcd848 2116 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2117 strcat (buf, ", uses APCS/float");
2118 break;
76da6bbe 2119
a5bcd848 2120 case EF_ARM_PIC:
f3485b74
NC
2121 strcat (buf, ", position independent");
2122 break;
76da6bbe 2123
a5bcd848 2124 case EF_ARM_ALIGN8:
f3485b74
NC
2125 strcat (buf, ", 8 bit structure alignment");
2126 break;
76da6bbe 2127
a5bcd848 2128 case EF_ARM_NEW_ABI:
f3485b74
NC
2129 strcat (buf, ", uses new ABI");
2130 break;
76da6bbe 2131
a5bcd848 2132 case EF_ARM_OLD_ABI:
f3485b74
NC
2133 strcat (buf, ", uses old ABI");
2134 break;
76da6bbe 2135
a5bcd848 2136 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2137 strcat (buf, ", software FP");
2138 break;
76da6bbe 2139
90e01f86
ILT
2140 case EF_ARM_VFP_FLOAT:
2141 strcat (buf, ", VFP");
2142 break;
2143
fde78edd
NC
2144 case EF_ARM_MAVERICK_FLOAT:
2145 strcat (buf, ", Maverick FP");
2146 break;
2147
f3485b74
NC
2148 default:
2149 unknown = 1;
2150 break;
2151 }
2152 }
2153 }
f3485b74
NC
2154
2155 if (unknown)
2b692964 2156 strcat (buf,_(", <unknown>"));
f3485b74
NC
2157}
2158
252b5132 2159static char *
d3ba0551 2160get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2161{
b34976b6 2162 static char buf[1024];
252b5132
RH
2163
2164 buf[0] = '\0';
76da6bbe 2165
252b5132
RH
2166 if (e_flags)
2167 {
2168 switch (e_machine)
2169 {
2170 default:
2171 break;
2172
f3485b74
NC
2173 case EM_ARM:
2174 decode_ARM_machine_flags (e_flags, buf);
2175 break;
76da6bbe 2176
781303ce
MF
2177 case EM_BLACKFIN:
2178 if (e_flags & EF_BFIN_PIC)
2179 strcat (buf, ", PIC");
2180
2181 if (e_flags & EF_BFIN_FDPIC)
2182 strcat (buf, ", FDPIC");
2183
2184 if (e_flags & EF_BFIN_CODE_IN_L1)
2185 strcat (buf, ", code in L1");
2186
2187 if (e_flags & EF_BFIN_DATA_IN_L1)
2188 strcat (buf, ", data in L1");
2189
2190 break;
2191
ec2dfb42
AO
2192 case EM_CYGNUS_FRV:
2193 switch (e_flags & EF_FRV_CPU_MASK)
2194 {
2195 case EF_FRV_CPU_GENERIC:
2196 break;
2197
2198 default:
2199 strcat (buf, ", fr???");
2200 break;
57346661 2201
ec2dfb42
AO
2202 case EF_FRV_CPU_FR300:
2203 strcat (buf, ", fr300");
2204 break;
2205
2206 case EF_FRV_CPU_FR400:
2207 strcat (buf, ", fr400");
2208 break;
2209 case EF_FRV_CPU_FR405:
2210 strcat (buf, ", fr405");
2211 break;
2212
2213 case EF_FRV_CPU_FR450:
2214 strcat (buf, ", fr450");
2215 break;
2216
2217 case EF_FRV_CPU_FR500:
2218 strcat (buf, ", fr500");
2219 break;
2220 case EF_FRV_CPU_FR550:
2221 strcat (buf, ", fr550");
2222 break;
2223
2224 case EF_FRV_CPU_SIMPLE:
2225 strcat (buf, ", simple");
2226 break;
2227 case EF_FRV_CPU_TOMCAT:
2228 strcat (buf, ", tomcat");
2229 break;
2230 }
1c877e87 2231 break;
ec2dfb42 2232
53c7db4b 2233 case EM_68K:
425c6cb0 2234 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2235 strcat (buf, ", m68000");
425c6cb0 2236 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2237 strcat (buf, ", cpu32");
2238 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2239 strcat (buf, ", fido_a");
425c6cb0 2240 else
266abb8f 2241 {
2cf0635d
NC
2242 char const * isa = _("unknown");
2243 char const * mac = _("unknown mac");
2244 char const * additional = NULL;
0112cd26 2245
c694fd50 2246 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2247 {
c694fd50 2248 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2249 isa = "A";
2250 additional = ", nodiv";
2251 break;
c694fd50 2252 case EF_M68K_CF_ISA_A:
266abb8f
NS
2253 isa = "A";
2254 break;
c694fd50 2255 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2256 isa = "A+";
2257 break;
c694fd50 2258 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2259 isa = "B";
2260 additional = ", nousp";
2261 break;
c694fd50 2262 case EF_M68K_CF_ISA_B:
266abb8f
NS
2263 isa = "B";
2264 break;
f608cd77
NS
2265 case EF_M68K_CF_ISA_C:
2266 isa = "C";
2267 break;
2268 case EF_M68K_CF_ISA_C_NODIV:
2269 isa = "C";
2270 additional = ", nodiv";
2271 break;
266abb8f
NS
2272 }
2273 strcat (buf, ", cf, isa ");
2274 strcat (buf, isa);
0b2e31dc
NS
2275 if (additional)
2276 strcat (buf, additional);
c694fd50 2277 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2278 strcat (buf, ", float");
c694fd50 2279 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2280 {
2281 case 0:
2282 mac = NULL;
2283 break;
c694fd50 2284 case EF_M68K_CF_MAC:
266abb8f
NS
2285 mac = "mac";
2286 break;
c694fd50 2287 case EF_M68K_CF_EMAC:
266abb8f
NS
2288 mac = "emac";
2289 break;
f608cd77
NS
2290 case EF_M68K_CF_EMAC_B:
2291 mac = "emac_b";
2292 break;
266abb8f
NS
2293 }
2294 if (mac)
2295 {
2296 strcat (buf, ", ");
2297 strcat (buf, mac);
2298 }
266abb8f 2299 }
53c7db4b 2300 break;
33c63f9d 2301
252b5132
RH
2302 case EM_PPC:
2303 if (e_flags & EF_PPC_EMB)
2304 strcat (buf, ", emb");
2305
2306 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2307 strcat (buf, _(", relocatable"));
252b5132
RH
2308
2309 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2310 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2311 break;
2312
2b0337b0 2313 case EM_V850:
252b5132
RH
2314 case EM_CYGNUS_V850:
2315 switch (e_flags & EF_V850_ARCH)
2316 {
1cd986c5
NC
2317 case E_V850E2V3_ARCH:
2318 strcat (buf, ", v850e2v3");
2319 break;
2320 case E_V850E2_ARCH:
2321 strcat (buf, ", v850e2");
2322 break;
2323 case E_V850E1_ARCH:
2324 strcat (buf, ", v850e1");
8ad30312 2325 break;
252b5132
RH
2326 case E_V850E_ARCH:
2327 strcat (buf, ", v850e");
2328 break;
252b5132
RH
2329 case E_V850_ARCH:
2330 strcat (buf, ", v850");
2331 break;
2332 default:
2b692964 2333 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2334 break;
2335 }
2336 break;
2337
2b0337b0 2338 case EM_M32R:
252b5132
RH
2339 case EM_CYGNUS_M32R:
2340 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2341 strcat (buf, ", m32r");
252b5132
RH
2342 break;
2343
2344 case EM_MIPS:
4fe85591 2345 case EM_MIPS_RS3_LE:
252b5132
RH
2346 if (e_flags & EF_MIPS_NOREORDER)
2347 strcat (buf, ", noreorder");
2348
2349 if (e_flags & EF_MIPS_PIC)
2350 strcat (buf, ", pic");
2351
2352 if (e_flags & EF_MIPS_CPIC)
2353 strcat (buf, ", cpic");
2354
d1bdd336
TS
2355 if (e_flags & EF_MIPS_UCODE)
2356 strcat (buf, ", ugen_reserved");
2357
252b5132
RH
2358 if (e_flags & EF_MIPS_ABI2)
2359 strcat (buf, ", abi2");
2360
43521d43
TS
2361 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2362 strcat (buf, ", odk first");
2363
a5d22d2a
TS
2364 if (e_flags & EF_MIPS_32BITMODE)
2365 strcat (buf, ", 32bitmode");
2366
156c2f8b
NC
2367 switch ((e_flags & EF_MIPS_MACH))
2368 {
2369 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2370 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2371 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2372 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2373 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2374 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2375 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2376 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2377 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2378 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2379 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2380 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2381 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2382 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2383 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2384 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2385 case 0:
2386 /* We simply ignore the field in this case to avoid confusion:
2387 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2388 extension. */
2389 break;
2b692964 2390 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2391 }
43521d43
TS
2392
2393 switch ((e_flags & EF_MIPS_ABI))
2394 {
2395 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2396 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2397 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2398 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2399 case 0:
2400 /* We simply ignore the field in this case to avoid confusion:
2401 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2402 This means it is likely to be an o32 file, but not for
2403 sure. */
2404 break;
2b692964 2405 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2406 }
2407
2408 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2409 strcat (buf, ", mdmx");
2410
2411 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2412 strcat (buf, ", mips16");
2413
2414 switch ((e_flags & EF_MIPS_ARCH))
2415 {
2416 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2417 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2418 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2419 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2420 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2421 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2422 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2423 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2424 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2425 default: strcat (buf, _(", unknown ISA")); break;
43521d43
TS
2426 }
2427
8e45593f
NC
2428 if (e_flags & EF_SH_PIC)
2429 strcat (buf, ", pic");
2430
2431 if (e_flags & EF_SH_FDPIC)
2432 strcat (buf, ", fdpic");
252b5132 2433 break;
351b4b40 2434
ccde1100
AO
2435 case EM_SH:
2436 switch ((e_flags & EF_SH_MACH_MASK))
2437 {
2438 case EF_SH1: strcat (buf, ", sh1"); break;
2439 case EF_SH2: strcat (buf, ", sh2"); break;
2440 case EF_SH3: strcat (buf, ", sh3"); break;
2441 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2442 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2443 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2444 case EF_SH3E: strcat (buf, ", sh3e"); break;
2445 case EF_SH4: strcat (buf, ", sh4"); break;
2446 case EF_SH5: strcat (buf, ", sh5"); break;
2447 case EF_SH2E: strcat (buf, ", sh2e"); break;
2448 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2449 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2450 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2451 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2452 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2453 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2454 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2455 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2456 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2457 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2458 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2459 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2460 }
2461
2462 break;
57346661 2463
351b4b40
RH
2464 case EM_SPARCV9:
2465 if (e_flags & EF_SPARC_32PLUS)
2466 strcat (buf, ", v8+");
2467
2468 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2469 strcat (buf, ", ultrasparcI");
2470
2471 if (e_flags & EF_SPARC_SUN_US3)
2472 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2473
2474 if (e_flags & EF_SPARC_HAL_R1)
2475 strcat (buf, ", halr1");
2476
2477 if (e_flags & EF_SPARC_LEDATA)
2478 strcat (buf, ", ledata");
2479
2480 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2481 strcat (buf, ", tso");
2482
2483 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2484 strcat (buf, ", pso");
2485
2486 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2487 strcat (buf, ", rmo");
2488 break;
7d466069 2489
103f02d3
UD
2490 case EM_PARISC:
2491 switch (e_flags & EF_PARISC_ARCH)
2492 {
2493 case EFA_PARISC_1_0:
2494 strcpy (buf, ", PA-RISC 1.0");
2495 break;
2496 case EFA_PARISC_1_1:
2497 strcpy (buf, ", PA-RISC 1.1");
2498 break;
2499 case EFA_PARISC_2_0:
2500 strcpy (buf, ", PA-RISC 2.0");
2501 break;
2502 default:
2503 break;
2504 }
2505 if (e_flags & EF_PARISC_TRAPNIL)
2506 strcat (buf, ", trapnil");
2507 if (e_flags & EF_PARISC_EXT)
2508 strcat (buf, ", ext");
2509 if (e_flags & EF_PARISC_LSB)
2510 strcat (buf, ", lsb");
2511 if (e_flags & EF_PARISC_WIDE)
2512 strcat (buf, ", wide");
2513 if (e_flags & EF_PARISC_NO_KABP)
2514 strcat (buf, ", no kabp");
2515 if (e_flags & EF_PARISC_LAZYSWAP)
2516 strcat (buf, ", lazyswap");
30800947 2517 break;
76da6bbe 2518
7d466069 2519 case EM_PJ:
2b0337b0 2520 case EM_PJ_OLD:
7d466069
ILT
2521 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2522 strcat (buf, ", new calling convention");
2523
2524 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2525 strcat (buf, ", gnu calling convention");
2526 break;
4d6ed7c8
NC
2527
2528 case EM_IA_64:
2529 if ((e_flags & EF_IA_64_ABI64))
2530 strcat (buf, ", 64-bit");
2531 else
2532 strcat (buf, ", 32-bit");
2533 if ((e_flags & EF_IA_64_REDUCEDFP))
2534 strcat (buf, ", reduced fp model");
2535 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2536 strcat (buf, ", no function descriptors, constant gp");
2537 else if ((e_flags & EF_IA_64_CONS_GP))
2538 strcat (buf, ", constant gp");
2539 if ((e_flags & EF_IA_64_ABSOLUTE))
2540 strcat (buf, ", absolute");
28f997cf
TG
2541 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2542 {
2543 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2544 strcat (buf, ", vms_linkages");
2545 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2546 {
2547 case EF_IA_64_VMS_COMCOD_SUCCESS:
2548 break;
2549 case EF_IA_64_VMS_COMCOD_WARNING:
2550 strcat (buf, ", warning");
2551 break;
2552 case EF_IA_64_VMS_COMCOD_ERROR:
2553 strcat (buf, ", error");
2554 break;
2555 case EF_IA_64_VMS_COMCOD_ABORT:
2556 strcat (buf, ", abort");
2557 break;
2558 default:
2559 abort ();
2560 }
2561 }
4d6ed7c8 2562 break;
179d3252
JT
2563
2564 case EM_VAX:
2565 if ((e_flags & EF_VAX_NONPIC))
2566 strcat (buf, ", non-PIC");
2567 if ((e_flags & EF_VAX_DFLOAT))
2568 strcat (buf, ", D-Float");
2569 if ((e_flags & EF_VAX_GFLOAT))
2570 strcat (buf, ", G-Float");
2571 break;
c7927a3c
NC
2572
2573 case EM_RX:
2574 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2575 strcat (buf, ", 64-bit doubles");
2576 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2577 strcat (buf, ", dsp");
55786da2
AK
2578
2579 case EM_S390:
2580 if (e_flags & EF_S390_HIGH_GPRS)
2581 strcat (buf, ", highgprs");
40b36596
JM
2582
2583 case EM_TI_C6000:
2584 if ((e_flags & EF_C6000_REL))
2585 strcat (buf, ", relocatable module");
252b5132
RH
2586 }
2587 }
2588
2589 return buf;
2590}
2591
252b5132 2592static const char *
d3ba0551
AM
2593get_osabi_name (unsigned int osabi)
2594{
2595 static char buff[32];
2596
2597 switch (osabi)
2598 {
2599 case ELFOSABI_NONE: return "UNIX - System V";
2600 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2601 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
2602 case ELFOSABI_LINUX: return "UNIX - Linux";
2603 case ELFOSABI_HURD: return "GNU/Hurd";
2604 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2605 case ELFOSABI_AIX: return "UNIX - AIX";
2606 case ELFOSABI_IRIX: return "UNIX - IRIX";
2607 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2608 case ELFOSABI_TRU64: return "UNIX - TRU64";
2609 case ELFOSABI_MODESTO: return "Novell - Modesto";
2610 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2611 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2612 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2613 case ELFOSABI_AROS: return "AROS";
11636f9e 2614 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2615 default:
40b36596
JM
2616 if (osabi >= 64)
2617 switch (elf_header.e_machine)
2618 {
2619 case EM_ARM:
2620 switch (osabi)
2621 {
2622 case ELFOSABI_ARM: return "ARM";
2623 default:
2624 break;
2625 }
2626 break;
2627
2628 case EM_MSP430:
2629 case EM_MSP430_OLD:
2630 switch (osabi)
2631 {
2632 case ELFOSABI_STANDALONE: return _("Standalone App");
2633 default:
2634 break;
2635 }
2636 break;
2637
2638 case EM_TI_C6000:
2639 switch (osabi)
2640 {
2641 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2642 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2643 default:
2644 break;
2645 }
2646 break;
2647
2648 default:
2649 break;
2650 }
e9e44622 2651 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2652 return buff;
2653 }
2654}
2655
b294bdf8
MM
2656static const char *
2657get_arm_segment_type (unsigned long type)
2658{
2659 switch (type)
2660 {
2661 case PT_ARM_EXIDX:
2662 return "EXIDX";
2663 default:
2664 break;
2665 }
2666
2667 return NULL;
2668}
2669
d3ba0551
AM
2670static const char *
2671get_mips_segment_type (unsigned long type)
252b5132
RH
2672{
2673 switch (type)
2674 {
2675 case PT_MIPS_REGINFO:
2676 return "REGINFO";
2677 case PT_MIPS_RTPROC:
2678 return "RTPROC";
2679 case PT_MIPS_OPTIONS:
2680 return "OPTIONS";
2681 default:
2682 break;
2683 }
2684
2685 return NULL;
2686}
2687
103f02d3 2688static const char *
d3ba0551 2689get_parisc_segment_type (unsigned long type)
103f02d3
UD
2690{
2691 switch (type)
2692 {
2693 case PT_HP_TLS: return "HP_TLS";
2694 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2695 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2696 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2697 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2698 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2699 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2700 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2701 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2702 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2703 case PT_HP_PARALLEL: return "HP_PARALLEL";
2704 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2705 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2706 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2707 case PT_HP_STACK: return "HP_STACK";
2708 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2709 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2710 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2711 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2712 default:
2713 break;
2714 }
2715
2716 return NULL;
2717}
2718
4d6ed7c8 2719static const char *
d3ba0551 2720get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2721{
2722 switch (type)
2723 {
2724 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2725 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2726 case PT_HP_TLS: return "HP_TLS";
2727 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2728 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2729 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2730 default:
2731 break;
2732 }
2733
2734 return NULL;
2735}
2736
40b36596
JM
2737static const char *
2738get_tic6x_segment_type (unsigned long type)
2739{
2740 switch (type)
2741 {
2742 case PT_C6000_PHATTR: return "C6000_PHATTR";
2743 default:
2744 break;
2745 }
2746
2747 return NULL;
2748}
2749
252b5132 2750static const char *
d3ba0551 2751get_segment_type (unsigned long p_type)
252b5132 2752{
b34976b6 2753 static char buff[32];
252b5132
RH
2754
2755 switch (p_type)
2756 {
b34976b6
AM
2757 case PT_NULL: return "NULL";
2758 case PT_LOAD: return "LOAD";
252b5132 2759 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2760 case PT_INTERP: return "INTERP";
2761 case PT_NOTE: return "NOTE";
2762 case PT_SHLIB: return "SHLIB";
2763 case PT_PHDR: return "PHDR";
13ae64f3 2764 case PT_TLS: return "TLS";
252b5132 2765
65765700
JJ
2766 case PT_GNU_EH_FRAME:
2767 return "GNU_EH_FRAME";
2b05f1b7 2768 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2769 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2770
252b5132
RH
2771 default:
2772 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2773 {
2cf0635d 2774 const char * result;
103f02d3 2775
252b5132
RH
2776 switch (elf_header.e_machine)
2777 {
b294bdf8
MM
2778 case EM_ARM:
2779 result = get_arm_segment_type (p_type);
2780 break;
252b5132 2781 case EM_MIPS:
4fe85591 2782 case EM_MIPS_RS3_LE:
252b5132
RH
2783 result = get_mips_segment_type (p_type);
2784 break;
103f02d3
UD
2785 case EM_PARISC:
2786 result = get_parisc_segment_type (p_type);
2787 break;
4d6ed7c8
NC
2788 case EM_IA_64:
2789 result = get_ia64_segment_type (p_type);
2790 break;
40b36596
JM
2791 case EM_TI_C6000:
2792 result = get_tic6x_segment_type (p_type);
2793 break;
252b5132
RH
2794 default:
2795 result = NULL;
2796 break;
2797 }
103f02d3 2798
252b5132
RH
2799 if (result != NULL)
2800 return result;
103f02d3 2801
252b5132
RH
2802 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2803 }
2804 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2805 {
2cf0635d 2806 const char * result;
103f02d3
UD
2807
2808 switch (elf_header.e_machine)
2809 {
2810 case EM_PARISC:
2811 result = get_parisc_segment_type (p_type);
2812 break;
00428cca
AM
2813 case EM_IA_64:
2814 result = get_ia64_segment_type (p_type);
2815 break;
103f02d3
UD
2816 default:
2817 result = NULL;
2818 break;
2819 }
2820
2821 if (result != NULL)
2822 return result;
2823
2824 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2825 }
252b5132 2826 else
e9e44622 2827 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2828
2829 return buff;
2830 }
2831}
2832
2833static const char *
d3ba0551 2834get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2835{
2836 switch (sh_type)
2837 {
b34976b6
AM
2838 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2839 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2840 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2841 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2842 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2843 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2844 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2845 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2846 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2847 case SHT_MIPS_RELD: return "MIPS_RELD";
2848 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2849 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2850 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2851 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2852 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2853 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2854 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2855 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2856 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2857 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2858 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2859 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2860 case SHT_MIPS_LINE: return "MIPS_LINE";
2861 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2862 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2863 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2864 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2865 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2866 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2867 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2868 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2869 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2870 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2871 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2872 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2873 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2874 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2875 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2876 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2877 default:
2878 break;
2879 }
2880 return NULL;
2881}
2882
103f02d3 2883static const char *
d3ba0551 2884get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2885{
2886 switch (sh_type)
2887 {
2888 case SHT_PARISC_EXT: return "PARISC_EXT";
2889 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2890 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2891 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2892 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2893 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2894 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2895 default:
2896 break;
2897 }
2898 return NULL;
2899}
2900
4d6ed7c8 2901static const char *
d3ba0551 2902get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2903{
18bd398b 2904 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2905 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2906 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2907
4d6ed7c8
NC
2908 switch (sh_type)
2909 {
148b93f2
NC
2910 case SHT_IA_64_EXT: return "IA_64_EXT";
2911 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2912 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
2913 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
2914 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
2915 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
2916 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
2917 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
2918 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
2919 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
2920 default:
2921 break;
2922 }
2923 return NULL;
2924}
2925
d2b2c203
DJ
2926static const char *
2927get_x86_64_section_type_name (unsigned int sh_type)
2928{
2929 switch (sh_type)
2930 {
2931 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2932 default:
2933 break;
2934 }
2935 return NULL;
2936}
2937
40a18ebd
NC
2938static const char *
2939get_arm_section_type_name (unsigned int sh_type)
2940{
2941 switch (sh_type)
2942 {
7f6fed87
NC
2943 case SHT_ARM_EXIDX: return "ARM_EXIDX";
2944 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
2945 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
2946 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
2947 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
2948 default:
2949 break;
2950 }
2951 return NULL;
2952}
2953
40b36596
JM
2954static const char *
2955get_tic6x_section_type_name (unsigned int sh_type)
2956{
2957 switch (sh_type)
2958 {
2959 case SHT_C6000_UNWIND:
2960 return "C6000_UNWIND";
2961 case SHT_C6000_PREEMPTMAP:
2962 return "C6000_PREEMPTMAP";
2963 case SHT_C6000_ATTRIBUTES:
2964 return "C6000_ATTRIBUTES";
2965 case SHT_TI_ICODE:
2966 return "TI_ICODE";
2967 case SHT_TI_XREF:
2968 return "TI_XREF";
2969 case SHT_TI_HANDLER:
2970 return "TI_HANDLER";
2971 case SHT_TI_INITINFO:
2972 return "TI_INITINFO";
2973 case SHT_TI_PHATTRS:
2974 return "TI_PHATTRS";
2975 default:
2976 break;
2977 }
2978 return NULL;
2979}
2980
252b5132 2981static const char *
d3ba0551 2982get_section_type_name (unsigned int sh_type)
252b5132 2983{
b34976b6 2984 static char buff[32];
252b5132
RH
2985
2986 switch (sh_type)
2987 {
2988 case SHT_NULL: return "NULL";
2989 case SHT_PROGBITS: return "PROGBITS";
2990 case SHT_SYMTAB: return "SYMTAB";
2991 case SHT_STRTAB: return "STRTAB";
2992 case SHT_RELA: return "RELA";
2993 case SHT_HASH: return "HASH";
2994 case SHT_DYNAMIC: return "DYNAMIC";
2995 case SHT_NOTE: return "NOTE";
2996 case SHT_NOBITS: return "NOBITS";
2997 case SHT_REL: return "REL";
2998 case SHT_SHLIB: return "SHLIB";
2999 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3000 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3001 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3002 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3003 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3004 case SHT_GROUP: return "GROUP";
3005 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3006 case SHT_GNU_verdef: return "VERDEF";
3007 case SHT_GNU_verneed: return "VERNEED";
3008 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3009 case 0x6ffffff0: return "VERSYM";
3010 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3011 case 0x7ffffffd: return "AUXILIARY";
3012 case 0x7fffffff: return "FILTER";
047b2264 3013 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3014
3015 default:
3016 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3017 {
2cf0635d 3018 const char * result;
252b5132
RH
3019
3020 switch (elf_header.e_machine)
3021 {
3022 case EM_MIPS:
4fe85591 3023 case EM_MIPS_RS3_LE:
252b5132
RH
3024 result = get_mips_section_type_name (sh_type);
3025 break;
103f02d3
UD
3026 case EM_PARISC:
3027 result = get_parisc_section_type_name (sh_type);
3028 break;
4d6ed7c8
NC
3029 case EM_IA_64:
3030 result = get_ia64_section_type_name (sh_type);
3031 break;
d2b2c203 3032 case EM_X86_64:
8a9036a4 3033 case EM_L1OM:
d2b2c203
DJ
3034 result = get_x86_64_section_type_name (sh_type);
3035 break;
40a18ebd
NC
3036 case EM_ARM:
3037 result = get_arm_section_type_name (sh_type);
3038 break;
40b36596
JM
3039 case EM_TI_C6000:
3040 result = get_tic6x_section_type_name (sh_type);
3041 break;
252b5132
RH
3042 default:
3043 result = NULL;
3044 break;
3045 }
3046
3047 if (result != NULL)
3048 return result;
3049
c91d0dfb 3050 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3051 }
3052 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3053 {
2cf0635d 3054 const char * result;
148b93f2
NC
3055
3056 switch (elf_header.e_machine)
3057 {
3058 case EM_IA_64:
3059 result = get_ia64_section_type_name (sh_type);
3060 break;
3061 default:
3062 result = NULL;
3063 break;
3064 }
3065
3066 if (result != NULL)
3067 return result;
3068
3069 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3070 }
252b5132 3071 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3072 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3073 else
e9e44622 3074 snprintf (buff, sizeof (buff), _("<unknown>: %x"), sh_type);
103f02d3 3075
252b5132
RH
3076 return buff;
3077 }
3078}
3079
2979dc34 3080#define OPTION_DEBUG_DUMP 512
2c610e4b 3081#define OPTION_DYN_SYMS 513
fd2f0033
TT
3082#define OPTION_DWARF_DEPTH 514
3083#define OPTION_DWARF_START 515
2979dc34 3084
85b1c36d 3085static struct option options[] =
252b5132 3086{
b34976b6 3087 {"all", no_argument, 0, 'a'},
252b5132
RH
3088 {"file-header", no_argument, 0, 'h'},
3089 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3090 {"headers", no_argument, 0, 'e'},
3091 {"histogram", no_argument, 0, 'I'},
3092 {"segments", no_argument, 0, 'l'},
3093 {"sections", no_argument, 0, 'S'},
252b5132 3094 {"section-headers", no_argument, 0, 'S'},
f5842774 3095 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3096 {"section-details", no_argument, 0, 't'},
595cf52e 3097 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3098 {"symbols", no_argument, 0, 's'},
3099 {"syms", no_argument, 0, 's'},
2c610e4b 3100 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3101 {"relocs", no_argument, 0, 'r'},
3102 {"notes", no_argument, 0, 'n'},
3103 {"dynamic", no_argument, 0, 'd'},
a952a375 3104 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3105 {"version-info", no_argument, 0, 'V'},
3106 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3107 {"unwind", no_argument, 0, 'u'},
4145f1d5 3108 {"archive-index", no_argument, 0, 'c'},
b34976b6 3109 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3110 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3111 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3112#ifdef SUPPORT_DISASSEMBLY
3113 {"instruction-dump", required_argument, 0, 'i'},
3114#endif
cf13d699 3115 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3116
fd2f0033
TT
3117 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3118 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
3119
b34976b6
AM
3120 {"version", no_argument, 0, 'v'},
3121 {"wide", no_argument, 0, 'W'},
3122 {"help", no_argument, 0, 'H'},
3123 {0, no_argument, 0, 0}
252b5132
RH
3124};
3125
3126static void
2cf0635d 3127usage (FILE * stream)
252b5132 3128{
92f01d61
JM
3129 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3130 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3131 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3132 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3133 -h --file-header Display the ELF file header\n\
3134 -l --program-headers Display the program headers\n\
3135 --segments An alias for --program-headers\n\
3136 -S --section-headers Display the sections' header\n\
3137 --sections An alias for --section-headers\n\
f5842774 3138 -g --section-groups Display the section groups\n\
5477e8a0 3139 -t --section-details Display the section details\n\
8b53311e
NC
3140 -e --headers Equivalent to: -h -l -S\n\
3141 -s --syms Display the symbol table\n\
3f08eb35 3142 --symbols An alias for --syms\n\
2c610e4b 3143 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3144 -n --notes Display the core notes (if present)\n\
3145 -r --relocs Display the relocations (if present)\n\
3146 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3147 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
3148 -V --version-info Display the version sections (if present)\n\
3149 -A --arch-specific Display architecture specific information (if any).\n\
4145f1d5 3150 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3151 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3152 -x --hex-dump=<number|name>\n\
3153 Dump the contents of section <number|name> as bytes\n\
3154 -p --string-dump=<number|name>\n\
3155 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3156 -R --relocated-dump=<number|name>\n\
3157 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3158 -w[lLiaprmfFsoRt] or\n\
1ed06042 3159 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3160 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
5bbdf3d5 3161 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
8b53311e 3162 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3163 fprintf (stream, _("\
3164 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3165 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3166 or deeper\n"));
252b5132 3167#ifdef SUPPORT_DISASSEMBLY
92f01d61 3168 fprintf (stream, _("\
09c11c86
NC
3169 -i --instruction-dump=<number|name>\n\
3170 Disassemble the contents of section <number|name>\n"));
252b5132 3171#endif
92f01d61 3172 fprintf (stream, _("\
8b53311e
NC
3173 -I --histogram Display histogram of bucket list lengths\n\
3174 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3175 @<file> Read options from <file>\n\
8b53311e
NC
3176 -H --help Display this information\n\
3177 -v --version Display the version number of readelf\n"));
1118d252 3178
92f01d61
JM
3179 if (REPORT_BUGS_TO[0] && stream == stdout)
3180 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3181
92f01d61 3182 exit (stream == stdout ? 0 : 1);
252b5132
RH
3183}
3184
18bd398b
NC
3185/* Record the fact that the user wants the contents of section number
3186 SECTION to be displayed using the method(s) encoded as flags bits
3187 in TYPE. Note, TYPE can be zero if we are creating the array for
3188 the first time. */
3189
252b5132 3190static void
09c11c86 3191request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3192{
3193 if (section >= num_dump_sects)
3194 {
2cf0635d 3195 dump_type * new_dump_sects;
252b5132 3196
3f5e193b
NC
3197 new_dump_sects = (dump_type *) calloc (section + 1,
3198 sizeof (* dump_sects));
252b5132
RH
3199
3200 if (new_dump_sects == NULL)
591a748a 3201 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3202 else
3203 {
3204 /* Copy current flag settings. */
09c11c86 3205 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3206
3207 free (dump_sects);
3208
3209 dump_sects = new_dump_sects;
3210 num_dump_sects = section + 1;
3211 }
3212 }
3213
3214 if (dump_sects)
b34976b6 3215 dump_sects[section] |= type;
252b5132
RH
3216
3217 return;
3218}
3219
aef1f6d0
DJ
3220/* Request a dump by section name. */
3221
3222static void
2cf0635d 3223request_dump_byname (const char * section, dump_type type)
aef1f6d0 3224{
2cf0635d 3225 struct dump_list_entry * new_request;
aef1f6d0 3226
3f5e193b
NC
3227 new_request = (struct dump_list_entry *)
3228 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3229 if (!new_request)
591a748a 3230 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3231
3232 new_request->name = strdup (section);
3233 if (!new_request->name)
591a748a 3234 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3235
3236 new_request->type = type;
3237
3238 new_request->next = dump_sects_byname;
3239 dump_sects_byname = new_request;
3240}
3241
cf13d699
NC
3242static inline void
3243request_dump (dump_type type)
3244{
3245 int section;
3246 char * cp;
3247
3248 do_dump++;
3249 section = strtoul (optarg, & cp, 0);
3250
3251 if (! *cp && section >= 0)
3252 request_dump_bynumber (section, type);
3253 else
3254 request_dump_byname (optarg, type);
3255}
3256
3257
252b5132 3258static void
2cf0635d 3259parse_args (int argc, char ** argv)
252b5132
RH
3260{
3261 int c;
3262
3263 if (argc < 2)
92f01d61 3264 usage (stderr);
252b5132
RH
3265
3266 while ((c = getopt_long
cf13d699 3267 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3268 {
252b5132
RH
3269 switch (c)
3270 {
3271 case 0:
3272 /* Long options. */
3273 break;
3274 case 'H':
92f01d61 3275 usage (stdout);
252b5132
RH
3276 break;
3277
3278 case 'a':
b34976b6
AM
3279 do_syms++;
3280 do_reloc++;
3281 do_unwind++;
3282 do_dynamic++;
3283 do_header++;
3284 do_sections++;
f5842774 3285 do_section_groups++;
b34976b6
AM
3286 do_segments++;
3287 do_version++;
3288 do_histogram++;
3289 do_arch++;
3290 do_notes++;
252b5132 3291 break;
f5842774
L
3292 case 'g':
3293 do_section_groups++;
3294 break;
5477e8a0 3295 case 't':
595cf52e 3296 case 'N':
5477e8a0
L
3297 do_sections++;
3298 do_section_details++;
595cf52e 3299 break;
252b5132 3300 case 'e':
b34976b6
AM
3301 do_header++;
3302 do_sections++;
3303 do_segments++;
252b5132 3304 break;
a952a375 3305 case 'A':
b34976b6 3306 do_arch++;
a952a375 3307 break;
252b5132 3308 case 'D':
b34976b6 3309 do_using_dynamic++;
252b5132
RH
3310 break;
3311 case 'r':
b34976b6 3312 do_reloc++;
252b5132 3313 break;
4d6ed7c8 3314 case 'u':
b34976b6 3315 do_unwind++;
4d6ed7c8 3316 break;
252b5132 3317 case 'h':
b34976b6 3318 do_header++;
252b5132
RH
3319 break;
3320 case 'l':
b34976b6 3321 do_segments++;
252b5132
RH
3322 break;
3323 case 's':
b34976b6 3324 do_syms++;
252b5132
RH
3325 break;
3326 case 'S':
b34976b6 3327 do_sections++;
252b5132
RH
3328 break;
3329 case 'd':
b34976b6 3330 do_dynamic++;
252b5132 3331 break;
a952a375 3332 case 'I':
b34976b6 3333 do_histogram++;
a952a375 3334 break;
779fe533 3335 case 'n':
b34976b6 3336 do_notes++;
779fe533 3337 break;
4145f1d5
NC
3338 case 'c':
3339 do_archive_index++;
3340 break;
252b5132 3341 case 'x':
cf13d699 3342 request_dump (HEX_DUMP);
aef1f6d0 3343 break;
09c11c86 3344 case 'p':
cf13d699
NC
3345 request_dump (STRING_DUMP);
3346 break;
3347 case 'R':
3348 request_dump (RELOC_DUMP);
09c11c86 3349 break;
252b5132 3350 case 'w':
b34976b6 3351 do_dump++;
252b5132 3352 if (optarg == 0)
613ff48b
CC
3353 {
3354 do_debugging = 1;
3355 dwarf_select_sections_all ();
3356 }
252b5132
RH
3357 else
3358 {
3359 do_debugging = 0;
4cb93e3b 3360 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3361 }
3362 break;
2979dc34 3363 case OPTION_DEBUG_DUMP:
b34976b6 3364 do_dump++;
2979dc34
JJ
3365 if (optarg == 0)
3366 do_debugging = 1;
3367 else
3368 {
2979dc34 3369 do_debugging = 0;
4cb93e3b 3370 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3371 }
3372 break;
fd2f0033
TT
3373 case OPTION_DWARF_DEPTH:
3374 {
3375 char *cp;
3376
3377 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3378 }
3379 break;
3380 case OPTION_DWARF_START:
3381 {
3382 char *cp;
3383
3384 dwarf_start_die = strtoul (optarg, & cp, 0);
3385 }
3386 break;
2c610e4b
L
3387 case OPTION_DYN_SYMS:
3388 do_dyn_syms++;
3389 break;
252b5132
RH
3390#ifdef SUPPORT_DISASSEMBLY
3391 case 'i':
cf13d699
NC
3392 request_dump (DISASS_DUMP);
3393 break;
252b5132
RH
3394#endif
3395 case 'v':
3396 print_version (program_name);
3397 break;
3398 case 'V':
b34976b6 3399 do_version++;
252b5132 3400 break;
d974e256 3401 case 'W':
b34976b6 3402 do_wide++;
d974e256 3403 break;
252b5132 3404 default:
252b5132
RH
3405 /* xgettext:c-format */
3406 error (_("Invalid option '-%c'\n"), c);
3407 /* Drop through. */
3408 case '?':
92f01d61 3409 usage (stderr);
252b5132
RH
3410 }
3411 }
3412
4d6ed7c8 3413 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3414 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3415 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3416 && !do_section_groups && !do_archive_index
3417 && !do_dyn_syms)
92f01d61 3418 usage (stderr);
252b5132
RH
3419 else if (argc < 3)
3420 {
3421 warn (_("Nothing to do.\n"));
92f01d61 3422 usage (stderr);
252b5132
RH
3423 }
3424}
3425
3426static const char *
d3ba0551 3427get_elf_class (unsigned int elf_class)
252b5132 3428{
b34976b6 3429 static char buff[32];
103f02d3 3430
252b5132
RH
3431 switch (elf_class)
3432 {
3433 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3434 case ELFCLASS32: return "ELF32";
3435 case ELFCLASS64: return "ELF64";
ab5e7794 3436 default:
e9e44622 3437 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3438 return buff;
252b5132
RH
3439 }
3440}
3441
3442static const char *
d3ba0551 3443get_data_encoding (unsigned int encoding)
252b5132 3444{
b34976b6 3445 static char buff[32];
103f02d3 3446
252b5132
RH
3447 switch (encoding)
3448 {
3449 case ELFDATANONE: return _("none");
33c63f9d
CM
3450 case ELFDATA2LSB: return _("2's complement, little endian");
3451 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3452 default:
e9e44622 3453 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3454 return buff;
252b5132
RH
3455 }
3456}
3457
252b5132 3458/* Decode the data held in 'elf_header'. */
ee42cf8c 3459
252b5132 3460static int
d3ba0551 3461process_file_header (void)
252b5132 3462{
b34976b6
AM
3463 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3464 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3465 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3466 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3467 {
3468 error
3469 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3470 return 0;
3471 }
3472
2dc4cec1
L
3473 init_dwarf_regnames (elf_header.e_machine);
3474
252b5132
RH
3475 if (do_header)
3476 {
3477 int i;
3478
3479 printf (_("ELF Header:\n"));
3480 printf (_(" Magic: "));
b34976b6
AM
3481 for (i = 0; i < EI_NIDENT; i++)
3482 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3483 printf ("\n");
3484 printf (_(" Class: %s\n"),
b34976b6 3485 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3486 printf (_(" Data: %s\n"),
b34976b6 3487 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3488 printf (_(" Version: %d %s\n"),
b34976b6
AM
3489 elf_header.e_ident[EI_VERSION],
3490 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3491 ? "(current)"
b34976b6 3492 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3493 ? _("<unknown: %lx>")
789be9f7 3494 : "")));
252b5132 3495 printf (_(" OS/ABI: %s\n"),
b34976b6 3496 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3497 printf (_(" ABI Version: %d\n"),
b34976b6 3498 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3499 printf (_(" Type: %s\n"),
3500 get_file_type (elf_header.e_type));
3501 printf (_(" Machine: %s\n"),
3502 get_machine_name (elf_header.e_machine));
3503 printf (_(" Version: 0x%lx\n"),
3504 (unsigned long) elf_header.e_version);
76da6bbe 3505
f7a99963
NC
3506 printf (_(" Entry point address: "));
3507 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3508 printf (_("\n Start of program headers: "));
3509 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3510 printf (_(" (bytes into file)\n Start of section headers: "));
3511 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3512 printf (_(" (bytes into file)\n"));
76da6bbe 3513
252b5132
RH
3514 printf (_(" Flags: 0x%lx%s\n"),
3515 (unsigned long) elf_header.e_flags,
3516 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3517 printf (_(" Size of this header: %ld (bytes)\n"),
3518 (long) elf_header.e_ehsize);
3519 printf (_(" Size of program headers: %ld (bytes)\n"),
3520 (long) elf_header.e_phentsize);
2046a35d 3521 printf (_(" Number of program headers: %ld"),
252b5132 3522 (long) elf_header.e_phnum);
2046a35d
AM
3523 if (section_headers != NULL
3524 && elf_header.e_phnum == PN_XNUM
3525 && section_headers[0].sh_info != 0)
cc5914eb 3526 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3527 putc ('\n', stdout);
252b5132
RH
3528 printf (_(" Size of section headers: %ld (bytes)\n"),
3529 (long) elf_header.e_shentsize);
560f3c1c 3530 printf (_(" Number of section headers: %ld"),
252b5132 3531 (long) elf_header.e_shnum);
4fbb74a6 3532 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3533 printf (" (%ld)", (long) section_headers[0].sh_size);
3534 putc ('\n', stdout);
3535 printf (_(" Section header string table index: %ld"),
252b5132 3536 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3537 if (section_headers != NULL
3538 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3539 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3540 else if (elf_header.e_shstrndx != SHN_UNDEF
3541 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3542 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3543 putc ('\n', stdout);
3544 }
3545
3546 if (section_headers != NULL)
3547 {
2046a35d
AM
3548 if (elf_header.e_phnum == PN_XNUM
3549 && section_headers[0].sh_info != 0)
3550 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3551 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3552 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3553 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3554 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3555 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3556 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3557 free (section_headers);
3558 section_headers = NULL;
252b5132 3559 }
103f02d3 3560
9ea033b2
NC
3561 return 1;
3562}
3563
252b5132 3564
9ea033b2 3565static int
91d6fa6a 3566get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3567{
2cf0635d
NC
3568 Elf32_External_Phdr * phdrs;
3569 Elf32_External_Phdr * external;
3570 Elf_Internal_Phdr * internal;
b34976b6 3571 unsigned int i;
103f02d3 3572
3f5e193b
NC
3573 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3574 elf_header.e_phentsize,
3575 elf_header.e_phnum,
3576 _("program headers"));
a6e9f9df
AM
3577 if (!phdrs)
3578 return 0;
9ea033b2 3579
91d6fa6a 3580 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3581 i < elf_header.e_phnum;
b34976b6 3582 i++, internal++, external++)
252b5132 3583 {
9ea033b2
NC
3584 internal->p_type = BYTE_GET (external->p_type);
3585 internal->p_offset = BYTE_GET (external->p_offset);
3586 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3587 internal->p_paddr = BYTE_GET (external->p_paddr);
3588 internal->p_filesz = BYTE_GET (external->p_filesz);
3589 internal->p_memsz = BYTE_GET (external->p_memsz);
3590 internal->p_flags = BYTE_GET (external->p_flags);
3591 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3592 }
3593
9ea033b2
NC
3594 free (phdrs);
3595
252b5132
RH
3596 return 1;
3597}
3598
9ea033b2 3599static int
91d6fa6a 3600get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3601{
2cf0635d
NC
3602 Elf64_External_Phdr * phdrs;
3603 Elf64_External_Phdr * external;
3604 Elf_Internal_Phdr * internal;
b34976b6 3605 unsigned int i;
103f02d3 3606
3f5e193b
NC
3607 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3608 elf_header.e_phentsize,
3609 elf_header.e_phnum,
3610 _("program headers"));
a6e9f9df
AM
3611 if (!phdrs)
3612 return 0;
9ea033b2 3613
91d6fa6a 3614 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3615 i < elf_header.e_phnum;
b34976b6 3616 i++, internal++, external++)
9ea033b2
NC
3617 {
3618 internal->p_type = BYTE_GET (external->p_type);
3619 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3620 internal->p_offset = BYTE_GET (external->p_offset);
3621 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3622 internal->p_paddr = BYTE_GET (external->p_paddr);
3623 internal->p_filesz = BYTE_GET (external->p_filesz);
3624 internal->p_memsz = BYTE_GET (external->p_memsz);
3625 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3626 }
3627
3628 free (phdrs);
3629
3630 return 1;
3631}
252b5132 3632
d93f0186
NC
3633/* Returns 1 if the program headers were read into `program_headers'. */
3634
3635static int
2cf0635d 3636get_program_headers (FILE * file)
d93f0186 3637{
2cf0635d 3638 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3639
3640 /* Check cache of prior read. */
3641 if (program_headers != NULL)
3642 return 1;
3643
3f5e193b
NC
3644 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3645 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3646
3647 if (phdrs == NULL)
3648 {
3649 error (_("Out of memory\n"));
3650 return 0;
3651 }
3652
3653 if (is_32bit_elf
3654 ? get_32bit_program_headers (file, phdrs)
3655 : get_64bit_program_headers (file, phdrs))
3656 {
3657 program_headers = phdrs;
3658 return 1;
3659 }
3660
3661 free (phdrs);
3662 return 0;
3663}
3664
2f62977e
NC
3665/* Returns 1 if the program headers were loaded. */
3666
252b5132 3667static int
2cf0635d 3668process_program_headers (FILE * file)
252b5132 3669{
2cf0635d 3670 Elf_Internal_Phdr * segment;
b34976b6 3671 unsigned int i;
252b5132
RH
3672
3673 if (elf_header.e_phnum == 0)
3674 {
82f2dbf7
NC
3675 /* PR binutils/12467. */
3676 if (elf_header.e_phoff != 0)
3677 warn (_("possibly corrupt ELF header - it has a non-zero program"
3678 " header offset, but no program headers"));
3679 else if (do_segments)
252b5132 3680 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3681 return 0;
252b5132
RH
3682 }
3683
3684 if (do_segments && !do_header)
3685 {
f7a99963
NC
3686 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3687 printf (_("Entry point "));
3688 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3689 printf (_("\nThere are %d program headers, starting at offset "),
3690 elf_header.e_phnum);
3691 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3692 printf ("\n");
252b5132
RH
3693 }
3694
d93f0186 3695 if (! get_program_headers (file))
252b5132 3696 return 0;
103f02d3 3697
252b5132
RH
3698 if (do_segments)
3699 {
3a1a2036
NC
3700 if (elf_header.e_phnum > 1)
3701 printf (_("\nProgram Headers:\n"));
3702 else
3703 printf (_("\nProgram Headers:\n"));
76da6bbe 3704
f7a99963
NC
3705 if (is_32bit_elf)
3706 printf
3707 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3708 else if (do_wide)
3709 printf
3710 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3711 else
3712 {
3713 printf
3714 (_(" Type Offset VirtAddr PhysAddr\n"));
3715 printf
3716 (_(" FileSiz MemSiz Flags Align\n"));
3717 }
252b5132
RH
3718 }
3719
252b5132 3720 dynamic_addr = 0;
1b228002 3721 dynamic_size = 0;
252b5132
RH
3722
3723 for (i = 0, segment = program_headers;
3724 i < elf_header.e_phnum;
b34976b6 3725 i++, segment++)
252b5132
RH
3726 {
3727 if (do_segments)
3728 {
103f02d3 3729 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3730
3731 if (is_32bit_elf)
3732 {
3733 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3734 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3735 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3736 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3737 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3738 printf ("%c%c%c ",
3739 (segment->p_flags & PF_R ? 'R' : ' '),
3740 (segment->p_flags & PF_W ? 'W' : ' '),
3741 (segment->p_flags & PF_X ? 'E' : ' '));
3742 printf ("%#lx", (unsigned long) segment->p_align);
3743 }
d974e256
JJ
3744 else if (do_wide)
3745 {
3746 if ((unsigned long) segment->p_offset == segment->p_offset)
3747 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3748 else
3749 {
3750 print_vma (segment->p_offset, FULL_HEX);
3751 putchar (' ');
3752 }
3753
3754 print_vma (segment->p_vaddr, FULL_HEX);
3755 putchar (' ');
3756 print_vma (segment->p_paddr, FULL_HEX);
3757 putchar (' ');
3758
3759 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3760 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3761 else
3762 {
3763 print_vma (segment->p_filesz, FULL_HEX);
3764 putchar (' ');
3765 }
3766
3767 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3768 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3769 else
3770 {
3771 print_vma (segment->p_offset, FULL_HEX);
3772 }
3773
3774 printf (" %c%c%c ",
3775 (segment->p_flags & PF_R ? 'R' : ' '),
3776 (segment->p_flags & PF_W ? 'W' : ' '),
3777 (segment->p_flags & PF_X ? 'E' : ' '));
3778
3779 if ((unsigned long) segment->p_align == segment->p_align)
3780 printf ("%#lx", (unsigned long) segment->p_align);
3781 else
3782 {
3783 print_vma (segment->p_align, PREFIX_HEX);
3784 }
3785 }
f7a99963
NC
3786 else
3787 {
3788 print_vma (segment->p_offset, FULL_HEX);
3789 putchar (' ');
3790 print_vma (segment->p_vaddr, FULL_HEX);
3791 putchar (' ');
3792 print_vma (segment->p_paddr, FULL_HEX);
3793 printf ("\n ");
3794 print_vma (segment->p_filesz, FULL_HEX);
3795 putchar (' ');
3796 print_vma (segment->p_memsz, FULL_HEX);
3797 printf (" %c%c%c ",
3798 (segment->p_flags & PF_R ? 'R' : ' '),
3799 (segment->p_flags & PF_W ? 'W' : ' '),
3800 (segment->p_flags & PF_X ? 'E' : ' '));
3801 print_vma (segment->p_align, HEX);
3802 }
252b5132
RH
3803 }
3804
3805 switch (segment->p_type)
3806 {
252b5132
RH
3807 case PT_DYNAMIC:
3808 if (dynamic_addr)
3809 error (_("more than one dynamic segment\n"));
3810
20737c13
AM
3811 /* By default, assume that the .dynamic section is the first
3812 section in the DYNAMIC segment. */
3813 dynamic_addr = segment->p_offset;
3814 dynamic_size = segment->p_filesz;
3815
b2d38a17
NC
3816 /* Try to locate the .dynamic section. If there is
3817 a section header table, we can easily locate it. */
3818 if (section_headers != NULL)
3819 {
2cf0635d 3820 Elf_Internal_Shdr * sec;
b2d38a17 3821
89fac5e3
RS
3822 sec = find_section (".dynamic");
3823 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3824 {
28f997cf
TG
3825 /* A corresponding .dynamic section is expected, but on
3826 IA-64/OpenVMS it is OK for it to be missing. */
3827 if (!is_ia64_vms ())
3828 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3829 break;
3830 }
3831
42bb2e33 3832 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3833 {
3834 dynamic_size = 0;
3835 break;
3836 }
42bb2e33 3837
b2d38a17
NC
3838 dynamic_addr = sec->sh_offset;
3839 dynamic_size = sec->sh_size;
3840
3841 if (dynamic_addr < segment->p_offset
3842 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3843 warn (_("the .dynamic section is not contained"
3844 " within the dynamic segment\n"));
b2d38a17 3845 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3846 warn (_("the .dynamic section is not the first section"
3847 " in the dynamic segment.\n"));
b2d38a17 3848 }
252b5132
RH
3849 break;
3850
3851 case PT_INTERP:
fb52b2f4
NC
3852 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3853 SEEK_SET))
252b5132
RH
3854 error (_("Unable to find program interpreter name\n"));
3855 else
3856 {
f8eae8b2
L
3857 char fmt [32];
3858 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3859
3860 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3861 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3862
252b5132 3863 program_interpreter[0] = 0;
7bd7b3ef
AM
3864 if (fscanf (file, fmt, program_interpreter) <= 0)
3865 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3866
3867 if (do_segments)
3868 printf (_("\n [Requesting program interpreter: %s]"),
3869 program_interpreter);
3870 }
3871 break;
3872 }
3873
3874 if (do_segments)
3875 putc ('\n', stdout);
3876 }
3877
c256ffe7 3878 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3879 {
3880 printf (_("\n Section to Segment mapping:\n"));
3881 printf (_(" Segment Sections...\n"));
3882
252b5132
RH
3883 for (i = 0; i < elf_header.e_phnum; i++)
3884 {
9ad5cbcf 3885 unsigned int j;
2cf0635d 3886 Elf_Internal_Shdr * section;
252b5132
RH
3887
3888 segment = program_headers + i;
b391a3e3 3889 section = section_headers + 1;
252b5132
RH
3890
3891 printf (" %2.2d ", i);
3892
b34976b6 3893 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3894 {
f4638467
AM
3895 if (!ELF_TBSS_SPECIAL (section, segment)
3896 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
3897 printf ("%s ", SECTION_NAME (section));
3898 }
3899
3900 putc ('\n',stdout);
3901 }
3902 }
3903
252b5132
RH
3904 return 1;
3905}
3906
3907
d93f0186
NC
3908/* Find the file offset corresponding to VMA by using the program headers. */
3909
3910static long
2cf0635d 3911offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 3912{
2cf0635d 3913 Elf_Internal_Phdr * seg;
d93f0186
NC
3914
3915 if (! get_program_headers (file))
3916 {
3917 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3918 return (long) vma;
3919 }
3920
3921 for (seg = program_headers;
3922 seg < program_headers + elf_header.e_phnum;
3923 ++seg)
3924 {
3925 if (seg->p_type != PT_LOAD)
3926 continue;
3927
3928 if (vma >= (seg->p_vaddr & -seg->p_align)
3929 && vma + size <= seg->p_vaddr + seg->p_filesz)
3930 return vma - seg->p_vaddr + seg->p_offset;
3931 }
3932
3933 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 3934 (unsigned long) vma);
d93f0186
NC
3935 return (long) vma;
3936}
3937
3938
252b5132 3939static int
2cf0635d 3940get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 3941{
2cf0635d
NC
3942 Elf32_External_Shdr * shdrs;
3943 Elf_Internal_Shdr * internal;
b34976b6 3944 unsigned int i;
252b5132 3945
3f5e193b
NC
3946 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3947 elf_header.e_shentsize, num,
3948 _("section headers"));
a6e9f9df
AM
3949 if (!shdrs)
3950 return 0;
252b5132 3951
3f5e193b
NC
3952 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3953 sizeof (Elf_Internal_Shdr));
252b5132
RH
3954
3955 if (section_headers == NULL)
3956 {
3957 error (_("Out of memory\n"));
3958 return 0;
3959 }
3960
3961 for (i = 0, internal = section_headers;
560f3c1c 3962 i < num;
b34976b6 3963 i++, internal++)
252b5132
RH
3964 {
3965 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3966 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3967 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3968 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3969 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3970 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3971 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3972 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3973 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3974 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3975 }
3976
3977 free (shdrs);
3978
3979 return 1;
3980}
3981
9ea033b2 3982static int
2cf0635d 3983get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 3984{
2cf0635d
NC
3985 Elf64_External_Shdr * shdrs;
3986 Elf_Internal_Shdr * internal;
b34976b6 3987 unsigned int i;
9ea033b2 3988
3f5e193b
NC
3989 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3990 elf_header.e_shentsize, num,
3991 _("section headers"));
a6e9f9df
AM
3992 if (!shdrs)
3993 return 0;
9ea033b2 3994
3f5e193b
NC
3995 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3996 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
3997
3998 if (section_headers == NULL)
3999 {
4000 error (_("Out of memory\n"));
4001 return 0;
4002 }
4003
4004 for (i = 0, internal = section_headers;
560f3c1c 4005 i < num;
b34976b6 4006 i++, internal++)
9ea033b2
NC
4007 {
4008 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4009 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4010 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4011 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4012 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4013 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4014 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4015 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4016 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4017 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4018 }
4019
4020 free (shdrs);
4021
4022 return 1;
4023}
4024
252b5132 4025static Elf_Internal_Sym *
2cf0635d 4026get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
252b5132 4027{
9ad5cbcf 4028 unsigned long number;
dd24e3da 4029 Elf32_External_Sym * esyms = NULL;
2cf0635d 4030 Elf_External_Sym_Shndx * shndx;
dd24e3da 4031 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4032 Elf_Internal_Sym * psym;
b34976b6 4033 unsigned int j;
252b5132 4034
dd24e3da
NC
4035 /* Run some sanity checks first. */
4036 if (section->sh_entsize == 0)
4037 {
4038 error (_("sh_entsize is zero\n"));
4039 return NULL;
4040 }
4041
4042 number = section->sh_size / section->sh_entsize;
4043
4044 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4045 {
4046 error (_("Invalid sh_entsize\n"));
4047 return NULL;
4048 }
4049
3f5e193b
NC
4050 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4051 section->sh_size, _("symbols"));
dd24e3da 4052 if (esyms == NULL)
a6e9f9df 4053 return NULL;
252b5132 4054
9ad5cbcf
AM
4055 shndx = NULL;
4056 if (symtab_shndx_hdr != NULL
4057 && (symtab_shndx_hdr->sh_link
4fbb74a6 4058 == (unsigned long) (section - section_headers)))
9ad5cbcf 4059 {
3f5e193b
NC
4060 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4061 symtab_shndx_hdr->sh_offset,
4062 1, symtab_shndx_hdr->sh_size,
4063 _("symtab shndx"));
dd24e3da
NC
4064 if (shndx == NULL)
4065 goto exit_point;
9ad5cbcf
AM
4066 }
4067
3f5e193b 4068 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4069
4070 if (isyms == NULL)
4071 {
4072 error (_("Out of memory\n"));
dd24e3da 4073 goto exit_point;
252b5132
RH
4074 }
4075
dd24e3da 4076 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4077 {
4078 psym->st_name = BYTE_GET (esyms[j].st_name);
4079 psym->st_value = BYTE_GET (esyms[j].st_value);
4080 psym->st_size = BYTE_GET (esyms[j].st_size);
4081 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4082 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4083 psym->st_shndx
4084 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4085 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4086 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4087 psym->st_info = BYTE_GET (esyms[j].st_info);
4088 psym->st_other = BYTE_GET (esyms[j].st_other);
4089 }
4090
dd24e3da 4091 exit_point:
9ad5cbcf
AM
4092 if (shndx)
4093 free (shndx);
dd24e3da
NC
4094 if (esyms)
4095 free (esyms);
252b5132
RH
4096
4097 return isyms;
4098}
4099
9ea033b2 4100static Elf_Internal_Sym *
2cf0635d 4101get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
9ea033b2 4102{
9ad5cbcf 4103 unsigned long number;
2cf0635d
NC
4104 Elf64_External_Sym * esyms;
4105 Elf_External_Sym_Shndx * shndx;
4106 Elf_Internal_Sym * isyms;
4107 Elf_Internal_Sym * psym;
b34976b6 4108 unsigned int j;
9ea033b2 4109
dd24e3da
NC
4110 /* Run some sanity checks first. */
4111 if (section->sh_entsize == 0)
4112 {
4113 error (_("sh_entsize is zero\n"));
4114 return NULL;
4115 }
4116
4117 number = section->sh_size / section->sh_entsize;
4118
4119 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4120 {
4121 error (_("Invalid sh_entsize\n"));
4122 return NULL;
4123 }
4124
3f5e193b
NC
4125 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4126 section->sh_size, _("symbols"));
a6e9f9df
AM
4127 if (!esyms)
4128 return NULL;
9ea033b2 4129
9ad5cbcf
AM
4130 shndx = NULL;
4131 if (symtab_shndx_hdr != NULL
4132 && (symtab_shndx_hdr->sh_link
4fbb74a6 4133 == (unsigned long) (section - section_headers)))
9ad5cbcf 4134 {
3f5e193b
NC
4135 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4136 symtab_shndx_hdr->sh_offset,
4137 1, symtab_shndx_hdr->sh_size,
4138 _("symtab shndx"));
9ad5cbcf
AM
4139 if (!shndx)
4140 {
4141 free (esyms);
4142 return NULL;
4143 }
4144 }
4145
3f5e193b 4146 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4147
4148 if (isyms == NULL)
4149 {
4150 error (_("Out of memory\n"));
9ad5cbcf
AM
4151 if (shndx)
4152 free (shndx);
9ea033b2 4153 free (esyms);
9ea033b2
NC
4154 return NULL;
4155 }
4156
4157 for (j = 0, psym = isyms;
4158 j < number;
b34976b6 4159 j++, psym++)
9ea033b2
NC
4160 {
4161 psym->st_name = BYTE_GET (esyms[j].st_name);
4162 psym->st_info = BYTE_GET (esyms[j].st_info);
4163 psym->st_other = BYTE_GET (esyms[j].st_other);
4164 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4165 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4166 psym->st_shndx
4167 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4168 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4169 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
66543521
AM
4170 psym->st_value = BYTE_GET (esyms[j].st_value);
4171 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4172 }
4173
9ad5cbcf
AM
4174 if (shndx)
4175 free (shndx);
9ea033b2
NC
4176 free (esyms);
4177
4178 return isyms;
4179}
4180
d1133906 4181static const char *
d3ba0551 4182get_elf_section_flags (bfd_vma sh_flags)
d1133906 4183{
5477e8a0 4184 static char buff[1024];
2cf0635d 4185 char * p = buff;
8d5ff12c 4186 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4187 int sindex;
4188 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4189 bfd_vma os_flags = 0;
4190 bfd_vma proc_flags = 0;
4191 bfd_vma unknown_flags = 0;
148b93f2 4192 static const struct
5477e8a0 4193 {
2cf0635d 4194 const char * str;
5477e8a0
L
4195 int len;
4196 }
4197 flags [] =
4198 {
cfcac11d
NC
4199 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4200 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4201 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4202 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4203 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4204 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4205 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4206 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4207 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4208 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4209 /* IA-64 specific. */
4210 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4211 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4212 /* IA-64 OpenVMS specific. */
4213 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4214 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4215 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4216 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4217 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4218 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4219 /* Generic. */
cfcac11d 4220 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4221 /* SPARC specific. */
cfcac11d 4222 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4223 };
4224
4225 if (do_section_details)
4226 {
8d5ff12c
L
4227 sprintf (buff, "[%*.*lx]: ",
4228 field_size, field_size, (unsigned long) sh_flags);
4229 p += field_size + 4;
5477e8a0 4230 }
76da6bbe 4231
d1133906
NC
4232 while (sh_flags)
4233 {
4234 bfd_vma flag;
4235
4236 flag = sh_flags & - sh_flags;
4237 sh_flags &= ~ flag;
76da6bbe 4238
5477e8a0 4239 if (do_section_details)
d1133906 4240 {
5477e8a0
L
4241 switch (flag)
4242 {
91d6fa6a
NC
4243 case SHF_WRITE: sindex = 0; break;
4244 case SHF_ALLOC: sindex = 1; break;
4245 case SHF_EXECINSTR: sindex = 2; break;
4246 case SHF_MERGE: sindex = 3; break;
4247 case SHF_STRINGS: sindex = 4; break;
4248 case SHF_INFO_LINK: sindex = 5; break;
4249 case SHF_LINK_ORDER: sindex = 6; break;
4250 case SHF_OS_NONCONFORMING: sindex = 7; break;
4251 case SHF_GROUP: sindex = 8; break;
4252 case SHF_TLS: sindex = 9; break;
18ae9cc1 4253 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4254
5477e8a0 4255 default:
91d6fa6a 4256 sindex = -1;
cfcac11d 4257 switch (elf_header.e_machine)
148b93f2 4258 {
cfcac11d 4259 case EM_IA_64:
148b93f2 4260 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4261 sindex = 10;
148b93f2 4262 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4263 sindex = 11;
148b93f2
NC
4264#ifdef BFD64
4265 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4266 switch (flag)
4267 {
91d6fa6a
NC
4268 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4269 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4270 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4271 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4272 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4273 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4274 default: break;
4275 }
4276#endif
cfcac11d
NC
4277 break;
4278
caa83f8b
NC
4279 case EM_386:
4280 case EM_486:
4281 case EM_X86_64:
7f502d6c 4282 case EM_L1OM:
cfcac11d
NC
4283 case EM_OLD_SPARCV9:
4284 case EM_SPARC32PLUS:
4285 case EM_SPARCV9:
4286 case EM_SPARC:
18ae9cc1 4287 if (flag == SHF_ORDERED)
91d6fa6a 4288 sindex = 19;
cfcac11d
NC
4289 break;
4290 default:
4291 break;
148b93f2 4292 }
5477e8a0
L
4293 }
4294
91d6fa6a 4295 if (sindex != -1)
5477e8a0 4296 {
8d5ff12c
L
4297 if (p != buff + field_size + 4)
4298 {
4299 if (size < (10 + 2))
4300 abort ();
4301 size -= 2;
4302 *p++ = ',';
4303 *p++ = ' ';
4304 }
4305
91d6fa6a
NC
4306 size -= flags [sindex].len;
4307 p = stpcpy (p, flags [sindex].str);
5477e8a0 4308 }
3b22753a 4309 else if (flag & SHF_MASKOS)
8d5ff12c 4310 os_flags |= flag;
d1133906 4311 else if (flag & SHF_MASKPROC)
8d5ff12c 4312 proc_flags |= flag;
d1133906 4313 else
8d5ff12c 4314 unknown_flags |= flag;
5477e8a0
L
4315 }
4316 else
4317 {
4318 switch (flag)
4319 {
4320 case SHF_WRITE: *p = 'W'; break;
4321 case SHF_ALLOC: *p = 'A'; break;
4322 case SHF_EXECINSTR: *p = 'X'; break;
4323 case SHF_MERGE: *p = 'M'; break;
4324 case SHF_STRINGS: *p = 'S'; break;
4325 case SHF_INFO_LINK: *p = 'I'; break;
4326 case SHF_LINK_ORDER: *p = 'L'; break;
4327 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4328 case SHF_GROUP: *p = 'G'; break;
4329 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4330 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4331
4332 default:
8a9036a4
L
4333 if ((elf_header.e_machine == EM_X86_64
4334 || elf_header.e_machine == EM_L1OM)
5477e8a0
L
4335 && flag == SHF_X86_64_LARGE)
4336 *p = 'l';
4337 else if (flag & SHF_MASKOS)
4338 {
4339 *p = 'o';
4340 sh_flags &= ~ SHF_MASKOS;
4341 }
4342 else if (flag & SHF_MASKPROC)
4343 {
4344 *p = 'p';
4345 sh_flags &= ~ SHF_MASKPROC;
4346 }
4347 else
4348 *p = 'x';
4349 break;
4350 }
4351 p++;
d1133906
NC
4352 }
4353 }
76da6bbe 4354
8d5ff12c
L
4355 if (do_section_details)
4356 {
4357 if (os_flags)
4358 {
4359 size -= 5 + field_size;
4360 if (p != buff + field_size + 4)
4361 {
4362 if (size < (2 + 1))
4363 abort ();
4364 size -= 2;
4365 *p++ = ',';
4366 *p++ = ' ';
4367 }
4368 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4369 (unsigned long) os_flags);
4370 p += 5 + field_size;
4371 }
4372 if (proc_flags)
4373 {
4374 size -= 7 + field_size;
4375 if (p != buff + field_size + 4)
4376 {
4377 if (size < (2 + 1))
4378 abort ();
4379 size -= 2;
4380 *p++ = ',';
4381 *p++ = ' ';
4382 }
4383 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4384 (unsigned long) proc_flags);
4385 p += 7 + field_size;
4386 }
4387 if (unknown_flags)
4388 {
4389 size -= 10 + field_size;
4390 if (p != buff + field_size + 4)
4391 {
4392 if (size < (2 + 1))
4393 abort ();
4394 size -= 2;
4395 *p++ = ',';
4396 *p++ = ' ';
4397 }
2b692964 4398 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4399 (unsigned long) unknown_flags);
4400 p += 10 + field_size;
4401 }
4402 }
4403
e9e44622 4404 *p = '\0';
d1133906
NC
4405 return buff;
4406}
4407
252b5132 4408static int
2cf0635d 4409process_section_headers (FILE * file)
252b5132 4410{
2cf0635d 4411 Elf_Internal_Shdr * section;
b34976b6 4412 unsigned int i;
252b5132
RH
4413
4414 section_headers = NULL;
4415
4416 if (elf_header.e_shnum == 0)
4417 {
82f2dbf7
NC
4418 /* PR binutils/12467. */
4419 if (elf_header.e_shoff != 0)
4420 warn (_("possibly corrupt ELF file header - it has a non-zero"
4421 " section header offset, but no section headers\n"));
4422 else if (do_sections)
252b5132
RH
4423 printf (_("\nThere are no sections in this file.\n"));
4424
4425 return 1;
4426 }
4427
4428 if (do_sections && !do_header)
9ea033b2 4429 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4430 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4431
9ea033b2
NC
4432 if (is_32bit_elf)
4433 {
560f3c1c 4434 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4435 return 0;
4436 }
560f3c1c 4437 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4438 return 0;
4439
4440 /* Read in the string table, so that we have names to display. */
0b49d371 4441 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4442 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4443 {
4fbb74a6 4444 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4445
c256ffe7
JJ
4446 if (section->sh_size != 0)
4447 {
3f5e193b
NC
4448 string_table = (char *) get_data (NULL, file, section->sh_offset,
4449 1, section->sh_size,
4450 _("string table"));
0de14b54 4451
c256ffe7
JJ
4452 string_table_length = string_table != NULL ? section->sh_size : 0;
4453 }
252b5132
RH
4454 }
4455
4456 /* Scan the sections for the dynamic symbol table
e3c8793a 4457 and dynamic string table and debug sections. */
252b5132
RH
4458 dynamic_symbols = NULL;
4459 dynamic_strings = NULL;
4460 dynamic_syminfo = NULL;
f1ef08cb 4461 symtab_shndx_hdr = NULL;
103f02d3 4462
89fac5e3
RS
4463 eh_addr_size = is_32bit_elf ? 4 : 8;
4464 switch (elf_header.e_machine)
4465 {
4466 case EM_MIPS:
4467 case EM_MIPS_RS3_LE:
4468 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4469 FDE addresses. However, the ABI also has a semi-official ILP32
4470 variant for which the normal FDE address size rules apply.
4471
4472 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4473 section, where XX is the size of longs in bits. Unfortunately,
4474 earlier compilers provided no way of distinguishing ILP32 objects
4475 from LP64 objects, so if there's any doubt, we should assume that
4476 the official LP64 form is being used. */
4477 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4478 && find_section (".gcc_compiled_long32") == NULL)
4479 eh_addr_size = 8;
4480 break;
0f56a26a
DD
4481
4482 case EM_H8_300:
4483 case EM_H8_300H:
4484 switch (elf_header.e_flags & EF_H8_MACH)
4485 {
4486 case E_H8_MACH_H8300:
4487 case E_H8_MACH_H8300HN:
4488 case E_H8_MACH_H8300SN:
4489 case E_H8_MACH_H8300SXN:
4490 eh_addr_size = 2;
4491 break;
4492 case E_H8_MACH_H8300H:
4493 case E_H8_MACH_H8300S:
4494 case E_H8_MACH_H8300SX:
4495 eh_addr_size = 4;
4496 break;
4497 }
f4236fe4
DD
4498 break;
4499
ff7eeb89 4500 case EM_M32C_OLD:
f4236fe4
DD
4501 case EM_M32C:
4502 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4503 {
4504 case EF_M32C_CPU_M16C:
4505 eh_addr_size = 2;
4506 break;
4507 }
4508 break;
89fac5e3
RS
4509 }
4510
08d8fa11
JJ
4511#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4512 do \
4513 { \
4514 size_t expected_entsize \
4515 = is_32bit_elf ? size32 : size64; \
4516 if (section->sh_entsize != expected_entsize) \
4517 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4518 i, (unsigned long int) section->sh_entsize, \
4519 (unsigned long int) expected_entsize); \
4520 section->sh_entsize = expected_entsize; \
4521 } \
4522 while (0)
4523#define CHECK_ENTSIZE(section, i, type) \
4524 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4525 sizeof (Elf64_External_##type))
4526
252b5132
RH
4527 for (i = 0, section = section_headers;
4528 i < elf_header.e_shnum;
b34976b6 4529 i++, section++)
252b5132 4530 {
2cf0635d 4531 char * name = SECTION_NAME (section);
252b5132
RH
4532
4533 if (section->sh_type == SHT_DYNSYM)
4534 {
4535 if (dynamic_symbols != NULL)
4536 {
4537 error (_("File contains multiple dynamic symbol tables\n"));
4538 continue;
4539 }
4540
08d8fa11 4541 CHECK_ENTSIZE (section, i, Sym);
19936277 4542 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4543 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4544 }
4545 else if (section->sh_type == SHT_STRTAB
18bd398b 4546 && streq (name, ".dynstr"))
252b5132
RH
4547 {
4548 if (dynamic_strings != NULL)
4549 {
4550 error (_("File contains multiple dynamic string tables\n"));
4551 continue;
4552 }
4553
3f5e193b
NC
4554 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4555 1, section->sh_size,
4556 _("dynamic strings"));
59245841 4557 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4558 }
9ad5cbcf
AM
4559 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4560 {
4561 if (symtab_shndx_hdr != NULL)
4562 {
4563 error (_("File contains multiple symtab shndx tables\n"));
4564 continue;
4565 }
4566 symtab_shndx_hdr = section;
4567 }
08d8fa11
JJ
4568 else if (section->sh_type == SHT_SYMTAB)
4569 CHECK_ENTSIZE (section, i, Sym);
4570 else if (section->sh_type == SHT_GROUP)
4571 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4572 else if (section->sh_type == SHT_REL)
4573 CHECK_ENTSIZE (section, i, Rel);
4574 else if (section->sh_type == SHT_RELA)
4575 CHECK_ENTSIZE (section, i, Rela);
252b5132 4576 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4577 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4578 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4579 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4580 && (const_strneq (name, ".debug_")
4581 || const_strneq (name, ".zdebug_")))
252b5132 4582 {
1b315056
CS
4583 if (name[1] == 'z')
4584 name += sizeof (".zdebug_") - 1;
4585 else
4586 name += sizeof (".debug_") - 1;
252b5132
RH
4587
4588 if (do_debugging
18bd398b 4589 || (do_debug_info && streq (name, "info"))
2b6f5997 4590 || (do_debug_info && streq (name, "types"))
18bd398b 4591 || (do_debug_abbrevs && streq (name, "abbrev"))
4cb93e3b 4592 || (do_debug_lines && streq (name, "line"))
18bd398b 4593 || (do_debug_pubnames && streq (name, "pubnames"))
f9f0e732 4594 || (do_debug_pubtypes && streq (name, "pubtypes"))
18bd398b
NC
4595 || (do_debug_aranges && streq (name, "aranges"))
4596 || (do_debug_ranges && streq (name, "ranges"))
4597 || (do_debug_frames && streq (name, "frame"))
4598 || (do_debug_macinfo && streq (name, "macinfo"))
4599 || (do_debug_str && streq (name, "str"))
4600 || (do_debug_loc && streq (name, "loc"))
252b5132 4601 )
09c11c86 4602 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4603 }
a262ae96 4604 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4605 else if ((do_debugging || do_debug_info)
0112cd26 4606 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4607 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4608 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4609 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4610 else if (do_gdb_index && streq (name, ".gdb_index"))
4611 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4612 /* Trace sections for Itanium VMS. */
4613 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4614 || do_trace_aranges)
4615 && const_strneq (name, ".trace_"))
4616 {
4617 name += sizeof (".trace_") - 1;
4618
4619 if (do_debugging
4620 || (do_trace_info && streq (name, "info"))
4621 || (do_trace_abbrevs && streq (name, "abbrev"))
4622 || (do_trace_aranges && streq (name, "aranges"))
4623 )
4624 request_dump_bynumber (i, DEBUG_DUMP);
4625 }
4626
252b5132
RH
4627 }
4628
4629 if (! do_sections)
4630 return 1;
4631
3a1a2036
NC
4632 if (elf_header.e_shnum > 1)
4633 printf (_("\nSection Headers:\n"));
4634 else
4635 printf (_("\nSection Header:\n"));
76da6bbe 4636
f7a99963 4637 if (is_32bit_elf)
595cf52e 4638 {
5477e8a0 4639 if (do_section_details)
595cf52e
L
4640 {
4641 printf (_(" [Nr] Name\n"));
5477e8a0 4642 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4643 }
4644 else
4645 printf
4646 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4647 }
d974e256 4648 else if (do_wide)
595cf52e 4649 {
5477e8a0 4650 if (do_section_details)
595cf52e
L
4651 {
4652 printf (_(" [Nr] Name\n"));
5477e8a0 4653 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4654 }
4655 else
4656 printf
4657 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4658 }
f7a99963
NC
4659 else
4660 {
5477e8a0 4661 if (do_section_details)
595cf52e
L
4662 {
4663 printf (_(" [Nr] Name\n"));
5477e8a0
L
4664 printf (_(" Type Address Offset Link\n"));
4665 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4666 }
4667 else
4668 {
4669 printf (_(" [Nr] Name Type Address Offset\n"));
4670 printf (_(" Size EntSize Flags Link Info Align\n"));
4671 }
f7a99963 4672 }
252b5132 4673
5477e8a0
L
4674 if (do_section_details)
4675 printf (_(" Flags\n"));
4676
252b5132
RH
4677 for (i = 0, section = section_headers;
4678 i < elf_header.e_shnum;
b34976b6 4679 i++, section++)
252b5132 4680 {
5477e8a0 4681 if (do_section_details)
595cf52e
L
4682 {
4683 printf (" [%2u] %s\n",
4fbb74a6 4684 i,
595cf52e
L
4685 SECTION_NAME (section));
4686 if (is_32bit_elf || do_wide)
4687 printf (" %-15.15s ",
4688 get_section_type_name (section->sh_type));
4689 }
4690 else
b9eb56c1
NC
4691 printf ((do_wide ? " [%2u] %-17s %-15s "
4692 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4693 i,
595cf52e
L
4694 SECTION_NAME (section),
4695 get_section_type_name (section->sh_type));
252b5132 4696
f7a99963
NC
4697 if (is_32bit_elf)
4698 {
cfcac11d
NC
4699 const char * link_too_big = NULL;
4700
f7a99963 4701 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4702
f7a99963
NC
4703 printf ( " %6.6lx %6.6lx %2.2lx",
4704 (unsigned long) section->sh_offset,
4705 (unsigned long) section->sh_size,
4706 (unsigned long) section->sh_entsize);
d1133906 4707
5477e8a0
L
4708 if (do_section_details)
4709 fputs (" ", stdout);
4710 else
4711 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4712
cfcac11d
NC
4713 if (section->sh_link >= elf_header.e_shnum)
4714 {
4715 link_too_big = "";
4716 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4717 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4718 switch (elf_header.e_machine)
4719 {
caa83f8b
NC
4720 case EM_386:
4721 case EM_486:
4722 case EM_X86_64:
7f502d6c 4723 case EM_L1OM:
cfcac11d
NC
4724 case EM_OLD_SPARCV9:
4725 case EM_SPARC32PLUS:
4726 case EM_SPARCV9:
4727 case EM_SPARC:
4728 if (section->sh_link == (SHN_BEFORE & 0xffff))
4729 link_too_big = "BEFORE";
4730 else if (section->sh_link == (SHN_AFTER & 0xffff))
4731 link_too_big = "AFTER";
4732 break;
4733 default:
4734 break;
4735 }
4736 }
4737
4738 if (do_section_details)
4739 {
4740 if (link_too_big != NULL && * link_too_big)
4741 printf ("<%s> ", link_too_big);
4742 else
4743 printf ("%2u ", section->sh_link);
4744 printf ("%3u %2lu\n", section->sh_info,
4745 (unsigned long) section->sh_addralign);
4746 }
4747 else
4748 printf ("%2u %3u %2lu\n",
4749 section->sh_link,
4750 section->sh_info,
4751 (unsigned long) section->sh_addralign);
4752
4753 if (link_too_big && ! * link_too_big)
4754 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4755 i, section->sh_link);
f7a99963 4756 }
d974e256
JJ
4757 else if (do_wide)
4758 {
4759 print_vma (section->sh_addr, LONG_HEX);
4760
4761 if ((long) section->sh_offset == section->sh_offset)
4762 printf (" %6.6lx", (unsigned long) section->sh_offset);
4763 else
4764 {
4765 putchar (' ');
4766 print_vma (section->sh_offset, LONG_HEX);
4767 }
4768
4769 if ((unsigned long) section->sh_size == section->sh_size)
4770 printf (" %6.6lx", (unsigned long) section->sh_size);
4771 else
4772 {
4773 putchar (' ');
4774 print_vma (section->sh_size, LONG_HEX);
4775 }
4776
4777 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4778 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4779 else
4780 {
4781 putchar (' ');
4782 print_vma (section->sh_entsize, LONG_HEX);
4783 }
4784
5477e8a0
L
4785 if (do_section_details)
4786 fputs (" ", stdout);
4787 else
4788 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4789
72de5009 4790 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4791
4792 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4793 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4794 else
4795 {
4796 print_vma (section->sh_addralign, DEC);
4797 putchar ('\n');
4798 }
4799 }
5477e8a0 4800 else if (do_section_details)
595cf52e 4801 {
5477e8a0 4802 printf (" %-15.15s ",
595cf52e 4803 get_section_type_name (section->sh_type));
595cf52e
L
4804 print_vma (section->sh_addr, LONG_HEX);
4805 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4806 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4807 else
4808 {
4809 printf (" ");
4810 print_vma (section->sh_offset, LONG_HEX);
4811 }
72de5009 4812 printf (" %u\n ", section->sh_link);
595cf52e 4813 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4814 putchar (' ');
595cf52e
L
4815 print_vma (section->sh_entsize, LONG_HEX);
4816
72de5009
AM
4817 printf (" %-16u %lu\n",
4818 section->sh_info,
595cf52e
L
4819 (unsigned long) section->sh_addralign);
4820 }
f7a99963
NC
4821 else
4822 {
4823 putchar (' ');
4824 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4825 if ((long) section->sh_offset == section->sh_offset)
4826 printf (" %8.8lx", (unsigned long) section->sh_offset);
4827 else
4828 {
4829 printf (" ");
4830 print_vma (section->sh_offset, LONG_HEX);
4831 }
f7a99963
NC
4832 printf ("\n ");
4833 print_vma (section->sh_size, LONG_HEX);
4834 printf (" ");
4835 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4836
d1133906 4837 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4838
72de5009
AM
4839 printf (" %2u %3u %lu\n",
4840 section->sh_link,
4841 section->sh_info,
f7a99963
NC
4842 (unsigned long) section->sh_addralign);
4843 }
5477e8a0
L
4844
4845 if (do_section_details)
4846 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4847 }
4848
5477e8a0 4849 if (!do_section_details)
3dbcc61d
NC
4850 {
4851 if (elf_header.e_machine == EM_X86_64
4852 || elf_header.e_machine == EM_L1OM)
4853 printf (_("Key to Flags:\n\
4854 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
4855 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
4856 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
4857 else
4858 printf (_("Key to Flags:\n\
e3c8793a 4859 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 4860 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 4861 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 4862 }
d1133906 4863
252b5132
RH
4864 return 1;
4865}
4866
f5842774
L
4867static const char *
4868get_group_flags (unsigned int flags)
4869{
4870 static char buff[32];
4871 switch (flags)
4872 {
220453ec
AM
4873 case 0:
4874 return "";
4875
f5842774 4876 case GRP_COMDAT:
220453ec 4877 return "COMDAT ";
f5842774
L
4878
4879 default:
220453ec 4880 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
4881 break;
4882 }
4883 return buff;
4884}
4885
4886static int
2cf0635d 4887process_section_groups (FILE * file)
f5842774 4888{
2cf0635d 4889 Elf_Internal_Shdr * section;
f5842774 4890 unsigned int i;
2cf0635d
NC
4891 struct group * group;
4892 Elf_Internal_Shdr * symtab_sec;
4893 Elf_Internal_Shdr * strtab_sec;
4894 Elf_Internal_Sym * symtab;
4895 char * strtab;
c256ffe7 4896 size_t strtab_size;
d1f5c6e3
L
4897
4898 /* Don't process section groups unless needed. */
4899 if (!do_unwind && !do_section_groups)
4900 return 1;
f5842774
L
4901
4902 if (elf_header.e_shnum == 0)
4903 {
4904 if (do_section_groups)
82f2dbf7 4905 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
4906
4907 return 1;
4908 }
4909
4910 if (section_headers == NULL)
4911 {
4912 error (_("Section headers are not available!\n"));
4913 abort ();
4914 }
4915
3f5e193b
NC
4916 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
4917 sizeof (struct group *));
e4b17d5c
L
4918
4919 if (section_headers_groups == NULL)
4920 {
4921 error (_("Out of memory\n"));
4922 return 0;
4923 }
4924
f5842774 4925 /* Scan the sections for the group section. */
d1f5c6e3 4926 group_count = 0;
f5842774
L
4927 for (i = 0, section = section_headers;
4928 i < elf_header.e_shnum;
4929 i++, section++)
e4b17d5c
L
4930 if (section->sh_type == SHT_GROUP)
4931 group_count++;
4932
d1f5c6e3
L
4933 if (group_count == 0)
4934 {
4935 if (do_section_groups)
4936 printf (_("\nThere are no section groups in this file.\n"));
4937
4938 return 1;
4939 }
4940
3f5e193b 4941 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
4942
4943 if (section_groups == NULL)
4944 {
4945 error (_("Out of memory\n"));
4946 return 0;
4947 }
4948
d1f5c6e3
L
4949 symtab_sec = NULL;
4950 strtab_sec = NULL;
4951 symtab = NULL;
4952 strtab = NULL;
c256ffe7 4953 strtab_size = 0;
e4b17d5c
L
4954 for (i = 0, section = section_headers, group = section_groups;
4955 i < elf_header.e_shnum;
4956 i++, section++)
f5842774
L
4957 {
4958 if (section->sh_type == SHT_GROUP)
4959 {
2cf0635d
NC
4960 char * name = SECTION_NAME (section);
4961 char * group_name;
4962 unsigned char * start;
4963 unsigned char * indices;
f5842774 4964 unsigned int entry, j, size;
2cf0635d
NC
4965 Elf_Internal_Shdr * sec;
4966 Elf_Internal_Sym * sym;
f5842774
L
4967
4968 /* Get the symbol table. */
4fbb74a6
AM
4969 if (section->sh_link >= elf_header.e_shnum
4970 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 4971 != SHT_SYMTAB))
f5842774
L
4972 {
4973 error (_("Bad sh_link in group section `%s'\n"), name);
4974 continue;
4975 }
d1f5c6e3
L
4976
4977 if (symtab_sec != sec)
4978 {
4979 symtab_sec = sec;
4980 if (symtab)
4981 free (symtab);
4982 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4983 }
f5842774 4984
dd24e3da
NC
4985 if (symtab == NULL)
4986 {
4987 error (_("Corrupt header in group section `%s'\n"), name);
4988 continue;
4989 }
4990
f5842774
L
4991 sym = symtab + section->sh_info;
4992
4993 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4994 {
4fbb74a6
AM
4995 if (sym->st_shndx == 0
4996 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
4997 {
4998 error (_("Bad sh_info in group section `%s'\n"), name);
4999 continue;
5000 }
ba2685cc 5001
4fbb74a6 5002 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5003 strtab_sec = NULL;
5004 if (strtab)
5005 free (strtab);
f5842774 5006 strtab = NULL;
c256ffe7 5007 strtab_size = 0;
f5842774
L
5008 }
5009 else
5010 {
5011 /* Get the string table. */
4fbb74a6 5012 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5013 {
5014 strtab_sec = NULL;
5015 if (strtab)
5016 free (strtab);
5017 strtab = NULL;
5018 strtab_size = 0;
5019 }
5020 else if (strtab_sec
4fbb74a6 5021 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5022 {
5023 strtab_sec = sec;
5024 if (strtab)
5025 free (strtab);
3f5e193b
NC
5026 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5027 1, strtab_sec->sh_size,
5028 _("string table"));
c256ffe7 5029 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5030 }
c256ffe7 5031 group_name = sym->st_name < strtab_size
2b692964 5032 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5033 }
5034
3f5e193b
NC
5035 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5036 1, section->sh_size,
5037 _("section data"));
59245841
NC
5038 if (start == NULL)
5039 continue;
f5842774
L
5040
5041 indices = start;
5042 size = (section->sh_size / section->sh_entsize) - 1;
5043 entry = byte_get (indices, 4);
5044 indices += 4;
e4b17d5c
L
5045
5046 if (do_section_groups)
5047 {
2b692964 5048 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5049 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5050
e4b17d5c
L
5051 printf (_(" [Index] Name\n"));
5052 }
5053
5054 group->group_index = i;
5055
f5842774
L
5056 for (j = 0; j < size; j++)
5057 {
2cf0635d 5058 struct group_list * g;
e4b17d5c 5059
f5842774
L
5060 entry = byte_get (indices, 4);
5061 indices += 4;
5062
4fbb74a6 5063 if (entry >= elf_header.e_shnum)
391cb864
L
5064 {
5065 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5066 entry, i, elf_header.e_shnum - 1);
5067 continue;
5068 }
391cb864 5069
4fbb74a6 5070 if (section_headers_groups [entry] != NULL)
e4b17d5c 5071 {
d1f5c6e3
L
5072 if (entry)
5073 {
391cb864
L
5074 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5075 entry, i,
4fbb74a6 5076 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5077 continue;
5078 }
5079 else
5080 {
5081 /* Intel C/C++ compiler may put section 0 in a
5082 section group. We just warn it the first time
5083 and ignore it afterwards. */
5084 static int warned = 0;
5085 if (!warned)
5086 {
5087 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5088 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5089 warned++;
5090 }
5091 }
e4b17d5c
L
5092 }
5093
4fbb74a6 5094 section_headers_groups [entry] = group;
e4b17d5c
L
5095
5096 if (do_section_groups)
5097 {
4fbb74a6 5098 sec = section_headers + entry;
c256ffe7 5099 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5100 }
5101
3f5e193b 5102 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5103 g->section_index = entry;
5104 g->next = group->root;
5105 group->root = g;
f5842774
L
5106 }
5107
f5842774
L
5108 if (start)
5109 free (start);
e4b17d5c
L
5110
5111 group++;
f5842774
L
5112 }
5113 }
5114
d1f5c6e3
L
5115 if (symtab)
5116 free (symtab);
5117 if (strtab)
5118 free (strtab);
f5842774
L
5119 return 1;
5120}
5121
28f997cf
TG
5122/* Data used to display dynamic fixups. */
5123
5124struct ia64_vms_dynfixup
5125{
5126 bfd_vma needed_ident; /* Library ident number. */
5127 bfd_vma needed; /* Index in the dstrtab of the library name. */
5128 bfd_vma fixup_needed; /* Index of the library. */
5129 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5130 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5131};
5132
5133/* Data used to display dynamic relocations. */
5134
5135struct ia64_vms_dynimgrela
5136{
5137 bfd_vma img_rela_cnt; /* Number of relocations. */
5138 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5139};
5140
5141/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5142 library). */
5143
5144static void
5145dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5146 const char *strtab, unsigned int strtab_sz)
5147{
5148 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5149 long i;
5150 const char *lib_name;
5151
5152 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5153 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5154 _("dynamic section image fixups"));
5155 if (!imfs)
5156 return;
5157
5158 if (fixup->needed < strtab_sz)
5159 lib_name = strtab + fixup->needed;
5160 else
5161 {
5162 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5163 (unsigned long) fixup->needed);
28f997cf
TG
5164 lib_name = "???";
5165 }
5166 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5167 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5168 printf
5169 (_("Seg Offset Type SymVec DataType\n"));
5170
5171 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5172 {
5173 unsigned int type;
5174 const char *rtype;
5175
5176 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5177 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5178 type = BYTE_GET (imfs [i].type);
5179 rtype = elf_ia64_reloc_type (type);
5180 if (rtype == NULL)
5181 printf (" 0x%08x ", type);
5182 else
5183 printf (" %-32s ", rtype);
5184 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5185 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5186 }
5187
5188 free (imfs);
5189}
5190
5191/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5192
5193static void
5194dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5195{
5196 Elf64_External_VMS_IMAGE_RELA *imrs;
5197 long i;
5198
5199 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5200 1, imgrela->img_rela_cnt * sizeof (*imrs),
5201 _("dynamic section image relas"));
5202 if (!imrs)
5203 return;
5204
5205 printf (_("\nImage relocs\n"));
5206 printf
5207 (_("Seg Offset Type Addend Seg Sym Off\n"));
5208
5209 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5210 {
5211 unsigned int type;
5212 const char *rtype;
5213
5214 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5215 printf ("%08" BFD_VMA_FMT "x ",
5216 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5217 type = BYTE_GET (imrs [i].type);
5218 rtype = elf_ia64_reloc_type (type);
5219 if (rtype == NULL)
5220 printf ("0x%08x ", type);
5221 else
5222 printf ("%-31s ", rtype);
5223 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5224 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5225 printf ("%08" BFD_VMA_FMT "x\n",
5226 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5227 }
5228
5229 free (imrs);
5230}
5231
5232/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5233
5234static int
5235process_ia64_vms_dynamic_relocs (FILE *file)
5236{
5237 struct ia64_vms_dynfixup fixup;
5238 struct ia64_vms_dynimgrela imgrela;
5239 Elf_Internal_Dyn *entry;
5240 int res = 0;
5241 bfd_vma strtab_off = 0;
5242 bfd_vma strtab_sz = 0;
5243 char *strtab = NULL;
5244
5245 memset (&fixup, 0, sizeof (fixup));
5246 memset (&imgrela, 0, sizeof (imgrela));
5247
5248 /* Note: the order of the entries is specified by the OpenVMS specs. */
5249 for (entry = dynamic_section;
5250 entry < dynamic_section + dynamic_nent;
5251 entry++)
5252 {
5253 switch (entry->d_tag)
5254 {
5255 case DT_IA_64_VMS_STRTAB_OFFSET:
5256 strtab_off = entry->d_un.d_val;
5257 break;
5258 case DT_STRSZ:
5259 strtab_sz = entry->d_un.d_val;
5260 if (strtab == NULL)
5261 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5262 1, strtab_sz, _("dynamic string section"));
5263 break;
5264
5265 case DT_IA_64_VMS_NEEDED_IDENT:
5266 fixup.needed_ident = entry->d_un.d_val;
5267 break;
5268 case DT_NEEDED:
5269 fixup.needed = entry->d_un.d_val;
5270 break;
5271 case DT_IA_64_VMS_FIXUP_NEEDED:
5272 fixup.fixup_needed = entry->d_un.d_val;
5273 break;
5274 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5275 fixup.fixup_rela_cnt = entry->d_un.d_val;
5276 break;
5277 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5278 fixup.fixup_rela_off = entry->d_un.d_val;
5279 res++;
5280 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5281 break;
5282
5283 case DT_IA_64_VMS_IMG_RELA_CNT:
5284 imgrela.img_rela_cnt = entry->d_un.d_val;
5285 break;
5286 case DT_IA_64_VMS_IMG_RELA_OFF:
5287 imgrela.img_rela_off = entry->d_un.d_val;
5288 res++;
5289 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5290 break;
5291
5292 default:
5293 break;
5294 }
5295 }
5296
5297 if (strtab != NULL)
5298 free (strtab);
5299
5300 return res;
5301}
5302
85b1c36d 5303static struct
566b0d53 5304{
2cf0635d 5305 const char * name;
566b0d53
L
5306 int reloc;
5307 int size;
5308 int rela;
5309} dynamic_relocations [] =
5310{
5311 { "REL", DT_REL, DT_RELSZ, FALSE },
5312 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5313 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5314};
5315
252b5132 5316/* Process the reloc section. */
18bd398b 5317
252b5132 5318static int
2cf0635d 5319process_relocs (FILE * file)
252b5132 5320{
b34976b6
AM
5321 unsigned long rel_size;
5322 unsigned long rel_offset;
252b5132
RH
5323
5324
5325 if (!do_reloc)
5326 return 1;
5327
5328 if (do_using_dynamic)
5329 {
566b0d53 5330 int is_rela;
2cf0635d 5331 const char * name;
566b0d53
L
5332 int has_dynamic_reloc;
5333 unsigned int i;
0de14b54 5334
566b0d53 5335 has_dynamic_reloc = 0;
252b5132 5336
566b0d53 5337 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5338 {
566b0d53
L
5339 is_rela = dynamic_relocations [i].rela;
5340 name = dynamic_relocations [i].name;
5341 rel_size = dynamic_info [dynamic_relocations [i].size];
5342 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5343
566b0d53
L
5344 has_dynamic_reloc |= rel_size;
5345
5346 if (is_rela == UNKNOWN)
aa903cfb 5347 {
566b0d53
L
5348 if (dynamic_relocations [i].reloc == DT_JMPREL)
5349 switch (dynamic_info[DT_PLTREL])
5350 {
5351 case DT_REL:
5352 is_rela = FALSE;
5353 break;
5354 case DT_RELA:
5355 is_rela = TRUE;
5356 break;
5357 }
aa903cfb 5358 }
252b5132 5359
566b0d53
L
5360 if (rel_size)
5361 {
5362 printf
5363 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5364 name, rel_offset, rel_size);
252b5132 5365
d93f0186
NC
5366 dump_relocations (file,
5367 offset_from_vma (file, rel_offset, rel_size),
5368 rel_size,
566b0d53 5369 dynamic_symbols, num_dynamic_syms,
d79b3d50 5370 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5371 }
252b5132 5372 }
566b0d53 5373
28f997cf
TG
5374 if (is_ia64_vms ())
5375 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5376
566b0d53 5377 if (! has_dynamic_reloc)
252b5132
RH
5378 printf (_("\nThere are no dynamic relocations in this file.\n"));
5379 }
5380 else
5381 {
2cf0635d 5382 Elf_Internal_Shdr * section;
b34976b6
AM
5383 unsigned long i;
5384 int found = 0;
252b5132
RH
5385
5386 for (i = 0, section = section_headers;
5387 i < elf_header.e_shnum;
b34976b6 5388 i++, section++)
252b5132
RH
5389 {
5390 if ( section->sh_type != SHT_RELA
5391 && section->sh_type != SHT_REL)
5392 continue;
5393
5394 rel_offset = section->sh_offset;
5395 rel_size = section->sh_size;
5396
5397 if (rel_size)
5398 {
2cf0635d 5399 Elf_Internal_Shdr * strsec;
b34976b6 5400 int is_rela;
103f02d3 5401
252b5132
RH
5402 printf (_("\nRelocation section "));
5403
5404 if (string_table == NULL)
19936277 5405 printf ("%d", section->sh_name);
252b5132 5406 else
3a1a2036 5407 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
5408
5409 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5410 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5411
d79b3d50
NC
5412 is_rela = section->sh_type == SHT_RELA;
5413
4fbb74a6
AM
5414 if (section->sh_link != 0
5415 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5416 {
2cf0635d
NC
5417 Elf_Internal_Shdr * symsec;
5418 Elf_Internal_Sym * symtab;
d79b3d50 5419 unsigned long nsyms;
c256ffe7 5420 unsigned long strtablen = 0;
2cf0635d 5421 char * strtab = NULL;
57346661 5422
4fbb74a6 5423 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5424 if (symsec->sh_type != SHT_SYMTAB
5425 && symsec->sh_type != SHT_DYNSYM)
5426 continue;
5427
af3fc3bc 5428 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 5429 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 5430
af3fc3bc
AM
5431 if (symtab == NULL)
5432 continue;
252b5132 5433
4fbb74a6
AM
5434 if (symsec->sh_link != 0
5435 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5436 {
4fbb74a6 5437 strsec = section_headers + symsec->sh_link;
103f02d3 5438
3f5e193b
NC
5439 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5440 1, strsec->sh_size,
5441 _("string table"));
c256ffe7
JJ
5442 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5443 }
252b5132 5444
d79b3d50
NC
5445 dump_relocations (file, rel_offset, rel_size,
5446 symtab, nsyms, strtab, strtablen, is_rela);
5447 if (strtab)
5448 free (strtab);
5449 free (symtab);
5450 }
5451 else
5452 dump_relocations (file, rel_offset, rel_size,
5453 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5454
5455 found = 1;
5456 }
5457 }
5458
5459 if (! found)
5460 printf (_("\nThere are no relocations in this file.\n"));
5461 }
5462
5463 return 1;
5464}
5465
57346661
AM
5466/* Process the unwind section. */
5467
4d6ed7c8
NC
5468#include "unwind-ia64.h"
5469
5470/* An absolute address consists of a section and an offset. If the
5471 section is NULL, the offset itself is the address, otherwise, the
5472 address equals to LOAD_ADDRESS(section) + offset. */
5473
5474struct absaddr
5475 {
5476 unsigned short section;
5477 bfd_vma offset;
5478 };
5479
1949de15
L
5480#define ABSADDR(a) \
5481 ((a).section \
5482 ? section_headers [(a).section].sh_addr + (a).offset \
5483 : (a).offset)
5484
3f5e193b
NC
5485struct ia64_unw_table_entry
5486 {
5487 struct absaddr start;
5488 struct absaddr end;
5489 struct absaddr info;
5490 };
5491
57346661 5492struct ia64_unw_aux_info
4d6ed7c8 5493 {
3f5e193b
NC
5494
5495 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5496 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5497 unsigned char * info; /* Unwind info. */
b34976b6
AM
5498 unsigned long info_size; /* Size of unwind info. */
5499 bfd_vma info_addr; /* starting address of unwind info. */
5500 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5501 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5502 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5503 char * strtab; /* The string table. */
b34976b6 5504 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5505 };
5506
4d6ed7c8 5507static void
2cf0635d 5508find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5509 unsigned long nsyms,
2cf0635d 5510 const char * strtab,
57346661 5511 unsigned long strtab_size,
d3ba0551 5512 struct absaddr addr,
2cf0635d
NC
5513 const char ** symname,
5514 bfd_vma * offset)
4d6ed7c8 5515{
d3ba0551 5516 bfd_vma dist = 0x100000;
2cf0635d
NC
5517 Elf_Internal_Sym * sym;
5518 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5519 unsigned long i;
5520
0b6ae522
DJ
5521 REMOVE_ARCH_BITS (addr.offset);
5522
57346661 5523 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5524 {
0b6ae522
DJ
5525 bfd_vma value = sym->st_value;
5526
5527 REMOVE_ARCH_BITS (value);
5528
4d6ed7c8
NC
5529 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5530 && sym->st_name != 0
5531 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5532 && addr.offset >= value
5533 && addr.offset - value < dist)
4d6ed7c8
NC
5534 {
5535 best = sym;
0b6ae522 5536 dist = addr.offset - value;
4d6ed7c8
NC
5537 if (!dist)
5538 break;
5539 }
5540 }
5541 if (best)
5542 {
57346661 5543 *symname = (best->st_name >= strtab_size
2b692964 5544 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5545 *offset = dist;
5546 return;
5547 }
5548 *symname = NULL;
5549 *offset = addr.offset;
5550}
5551
5552static void
2cf0635d 5553dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5554{
2cf0635d 5555 struct ia64_unw_table_entry * tp;
4d6ed7c8 5556 int in_body;
7036c0e1 5557
4d6ed7c8
NC
5558 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5559 {
5560 bfd_vma stamp;
5561 bfd_vma offset;
2cf0635d
NC
5562 const unsigned char * dp;
5563 const unsigned char * head;
5564 const char * procname;
4d6ed7c8 5565
57346661
AM
5566 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5567 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5568
5569 fputs ("\n<", stdout);
5570
5571 if (procname)
5572 {
5573 fputs (procname, stdout);
5574
5575 if (offset)
5576 printf ("+%lx", (unsigned long) offset);
5577 }
5578
5579 fputs (">: [", stdout);
5580 print_vma (tp->start.offset, PREFIX_HEX);
5581 fputc ('-', stdout);
5582 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5583 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5584 (unsigned long) (tp->info.offset - aux->seg_base));
5585
1949de15 5586 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5587 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5588
86f55779 5589 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5590 (unsigned) UNW_VER (stamp),
5591 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5592 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5593 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5594 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5595
5596 if (UNW_VER (stamp) != 1)
5597 {
2b692964 5598 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5599 continue;
5600 }
5601
5602 in_body = 0;
89fac5e3 5603 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5604 dp = unw_decode (dp, in_body, & in_body);
5605 }
5606}
5607
5608static int
2cf0635d
NC
5609slurp_ia64_unwind_table (FILE * file,
5610 struct ia64_unw_aux_info * aux,
5611 Elf_Internal_Shdr * sec)
4d6ed7c8 5612{
89fac5e3 5613 unsigned long size, nrelas, i;
2cf0635d
NC
5614 Elf_Internal_Phdr * seg;
5615 struct ia64_unw_table_entry * tep;
5616 Elf_Internal_Shdr * relsec;
5617 Elf_Internal_Rela * rela;
5618 Elf_Internal_Rela * rp;
5619 unsigned char * table;
5620 unsigned char * tp;
5621 Elf_Internal_Sym * sym;
5622 const char * relname;
4d6ed7c8 5623
4d6ed7c8
NC
5624 /* First, find the starting address of the segment that includes
5625 this section: */
5626
5627 if (elf_header.e_phnum)
5628 {
d93f0186 5629 if (! get_program_headers (file))
4d6ed7c8 5630 return 0;
4d6ed7c8 5631
d93f0186
NC
5632 for (seg = program_headers;
5633 seg < program_headers + elf_header.e_phnum;
5634 ++seg)
4d6ed7c8
NC
5635 {
5636 if (seg->p_type != PT_LOAD)
5637 continue;
5638
5639 if (sec->sh_addr >= seg->p_vaddr
5640 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5641 {
5642 aux->seg_base = seg->p_vaddr;
5643 break;
5644 }
5645 }
4d6ed7c8
NC
5646 }
5647
5648 /* Second, build the unwind table from the contents of the unwind section: */
5649 size = sec->sh_size;
3f5e193b
NC
5650 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5651 _("unwind table"));
a6e9f9df
AM
5652 if (!table)
5653 return 0;
4d6ed7c8 5654
3f5e193b
NC
5655 aux->table = (struct ia64_unw_table_entry *)
5656 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5657 tep = aux->table;
c6a0c689 5658 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5659 {
5660 tep->start.section = SHN_UNDEF;
5661 tep->end.section = SHN_UNDEF;
5662 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5663 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5664 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5665 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5666 tep->start.offset += aux->seg_base;
5667 tep->end.offset += aux->seg_base;
5668 tep->info.offset += aux->seg_base;
5669 }
5670 free (table);
5671
41e92641 5672 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5673 for (relsec = section_headers;
5674 relsec < section_headers + elf_header.e_shnum;
5675 ++relsec)
5676 {
5677 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5678 || relsec->sh_info >= elf_header.e_shnum
5679 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5680 continue;
5681
5682 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5683 & rela, & nrelas))
5684 return 0;
5685
5686 for (rp = rela; rp < rela + nrelas; ++rp)
5687 {
aca88567
NC
5688 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5689 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5690
0112cd26 5691 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5692 {
e5fb9629 5693 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5694 continue;
5695 }
5696
89fac5e3 5697 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5698
89fac5e3 5699 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5700 {
5701 case 0:
5702 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5703 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5704 break;
5705 case 1:
5706 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5707 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5708 break;
5709 case 2:
5710 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5711 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5712 break;
5713 default:
5714 break;
5715 }
5716 }
5717
5718 free (rela);
5719 }
5720
89fac5e3 5721 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5722 return 1;
5723}
5724
5725static int
2cf0635d 5726ia64_process_unwind (FILE * file)
4d6ed7c8 5727{
2cf0635d
NC
5728 Elf_Internal_Shdr * sec;
5729 Elf_Internal_Shdr * unwsec = NULL;
5730 Elf_Internal_Shdr * strsec;
89fac5e3 5731 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5732 struct ia64_unw_aux_info aux;
f1467e33 5733
4d6ed7c8
NC
5734 memset (& aux, 0, sizeof (aux));
5735
4d6ed7c8
NC
5736 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5737 {
c256ffe7 5738 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5739 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5740 {
5741 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5742 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5743
4fbb74a6 5744 strsec = section_headers + sec->sh_link;
59245841 5745 assert (aux.strtab == NULL);
3f5e193b
NC
5746 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5747 1, strsec->sh_size,
5748 _("string table"));
c256ffe7 5749 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5750 }
5751 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5752 unwcount++;
5753 }
5754
5755 if (!unwcount)
5756 printf (_("\nThere are no unwind sections in this file.\n"));
5757
5758 while (unwcount-- > 0)
5759 {
2cf0635d 5760 char * suffix;
579f31ac
JJ
5761 size_t len, len2;
5762
5763 for (i = unwstart, sec = section_headers + unwstart;
5764 i < elf_header.e_shnum; ++i, ++sec)
5765 if (sec->sh_type == SHT_IA_64_UNWIND)
5766 {
5767 unwsec = sec;
5768 break;
5769 }
5770
5771 unwstart = i + 1;
5772 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5773
e4b17d5c
L
5774 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5775 {
5776 /* We need to find which section group it is in. */
2cf0635d 5777 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5778
5779 for (; g != NULL; g = g->next)
5780 {
4fbb74a6 5781 sec = section_headers + g->section_index;
18bd398b
NC
5782
5783 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5784 break;
e4b17d5c
L
5785 }
5786
5787 if (g == NULL)
5788 i = elf_header.e_shnum;
5789 }
18bd398b 5790 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5791 {
18bd398b 5792 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5793 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5794 suffix = SECTION_NAME (unwsec) + len;
5795 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5796 ++i, ++sec)
18bd398b
NC
5797 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5798 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5799 break;
5800 }
5801 else
5802 {
5803 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5804 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5805 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5806 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5807 suffix = "";
18bd398b 5808 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5809 suffix = SECTION_NAME (unwsec) + len;
5810 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5811 ++i, ++sec)
18bd398b
NC
5812 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5813 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5814 break;
5815 }
5816
5817 if (i == elf_header.e_shnum)
5818 {
5819 printf (_("\nCould not find unwind info section for "));
5820
5821 if (string_table == NULL)
5822 printf ("%d", unwsec->sh_name);
5823 else
3a1a2036 5824 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5825 }
5826 else
4d6ed7c8 5827 {
4d6ed7c8 5828 aux.info_addr = sec->sh_addr;
3f5e193b 5829 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 5830 sec->sh_size,
3f5e193b 5831 _("unwind info"));
59245841 5832 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 5833
579f31ac 5834 printf (_("\nUnwind section "));
4d6ed7c8 5835
579f31ac
JJ
5836 if (string_table == NULL)
5837 printf ("%d", unwsec->sh_name);
5838 else
3a1a2036 5839 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5840
579f31ac 5841 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5842 (unsigned long) unwsec->sh_offset,
89fac5e3 5843 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5844
579f31ac 5845 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5846
579f31ac
JJ
5847 if (aux.table_len > 0)
5848 dump_ia64_unwind (& aux);
5849
5850 if (aux.table)
5851 free ((char *) aux.table);
5852 if (aux.info)
5853 free ((char *) aux.info);
5854 aux.table = NULL;
5855 aux.info = NULL;
5856 }
4d6ed7c8 5857 }
4d6ed7c8 5858
4d6ed7c8
NC
5859 if (aux.symtab)
5860 free (aux.symtab);
5861 if (aux.strtab)
5862 free ((char *) aux.strtab);
5863
5864 return 1;
5865}
5866
3f5e193b
NC
5867struct hppa_unw_table_entry
5868 {
5869 struct absaddr start;
5870 struct absaddr end;
5871 unsigned int Cannot_unwind:1; /* 0 */
5872 unsigned int Millicode:1; /* 1 */
5873 unsigned int Millicode_save_sr0:1; /* 2 */
5874 unsigned int Region_description:2; /* 3..4 */
5875 unsigned int reserved1:1; /* 5 */
5876 unsigned int Entry_SR:1; /* 6 */
5877 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5878 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5879 unsigned int Args_stored:1; /* 16 */
5880 unsigned int Variable_Frame:1; /* 17 */
5881 unsigned int Separate_Package_Body:1; /* 18 */
5882 unsigned int Frame_Extension_Millicode:1; /* 19 */
5883 unsigned int Stack_Overflow_Check:1; /* 20 */
5884 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5885 unsigned int Ada_Region:1; /* 22 */
5886 unsigned int cxx_info:1; /* 23 */
5887 unsigned int cxx_try_catch:1; /* 24 */
5888 unsigned int sched_entry_seq:1; /* 25 */
5889 unsigned int reserved2:1; /* 26 */
5890 unsigned int Save_SP:1; /* 27 */
5891 unsigned int Save_RP:1; /* 28 */
5892 unsigned int Save_MRP_in_frame:1; /* 29 */
5893 unsigned int extn_ptr_defined:1; /* 30 */
5894 unsigned int Cleanup_defined:1; /* 31 */
5895
5896 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5897 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5898 unsigned int Large_frame:1; /* 2 */
5899 unsigned int Pseudo_SP_Set:1; /* 3 */
5900 unsigned int reserved4:1; /* 4 */
5901 unsigned int Total_frame_size:27; /* 5..31 */
5902 };
5903
57346661
AM
5904struct hppa_unw_aux_info
5905 {
3f5e193b 5906 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
5907 unsigned long table_len; /* Length of unwind table. */
5908 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5909 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5910 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5911 char * strtab; /* The string table. */
57346661
AM
5912 unsigned long strtab_size; /* Size of string table. */
5913 };
5914
5915static void
2cf0635d 5916dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5917{
2cf0635d 5918 struct hppa_unw_table_entry * tp;
57346661 5919
57346661
AM
5920 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5921 {
5922 bfd_vma offset;
2cf0635d 5923 const char * procname;
57346661
AM
5924
5925 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5926 aux->strtab_size, tp->start, &procname,
5927 &offset);
5928
5929 fputs ("\n<", stdout);
5930
5931 if (procname)
5932 {
5933 fputs (procname, stdout);
5934
5935 if (offset)
5936 printf ("+%lx", (unsigned long) offset);
5937 }
5938
5939 fputs (">: [", stdout);
5940 print_vma (tp->start.offset, PREFIX_HEX);
5941 fputc ('-', stdout);
5942 print_vma (tp->end.offset, PREFIX_HEX);
5943 printf ("]\n\t");
5944
18bd398b
NC
5945#define PF(_m) if (tp->_m) printf (#_m " ");
5946#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5947 PF(Cannot_unwind);
5948 PF(Millicode);
5949 PF(Millicode_save_sr0);
18bd398b 5950 /* PV(Region_description); */
57346661
AM
5951 PF(Entry_SR);
5952 PV(Entry_FR);
5953 PV(Entry_GR);
5954 PF(Args_stored);
5955 PF(Variable_Frame);
5956 PF(Separate_Package_Body);
5957 PF(Frame_Extension_Millicode);
5958 PF(Stack_Overflow_Check);
5959 PF(Two_Instruction_SP_Increment);
5960 PF(Ada_Region);
5961 PF(cxx_info);
5962 PF(cxx_try_catch);
5963 PF(sched_entry_seq);
5964 PF(Save_SP);
5965 PF(Save_RP);
5966 PF(Save_MRP_in_frame);
5967 PF(extn_ptr_defined);
5968 PF(Cleanup_defined);
5969 PF(MPE_XL_interrupt_marker);
5970 PF(HP_UX_interrupt_marker);
5971 PF(Large_frame);
5972 PF(Pseudo_SP_Set);
5973 PV(Total_frame_size);
5974#undef PF
5975#undef PV
5976 }
5977
18bd398b 5978 printf ("\n");
57346661
AM
5979}
5980
5981static int
2cf0635d
NC
5982slurp_hppa_unwind_table (FILE * file,
5983 struct hppa_unw_aux_info * aux,
5984 Elf_Internal_Shdr * sec)
57346661 5985{
1c0751b2 5986 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
5987 Elf_Internal_Phdr * seg;
5988 struct hppa_unw_table_entry * tep;
5989 Elf_Internal_Shdr * relsec;
5990 Elf_Internal_Rela * rela;
5991 Elf_Internal_Rela * rp;
5992 unsigned char * table;
5993 unsigned char * tp;
5994 Elf_Internal_Sym * sym;
5995 const char * relname;
57346661 5996
57346661
AM
5997 /* First, find the starting address of the segment that includes
5998 this section. */
5999
6000 if (elf_header.e_phnum)
6001 {
6002 if (! get_program_headers (file))
6003 return 0;
6004
6005 for (seg = program_headers;
6006 seg < program_headers + elf_header.e_phnum;
6007 ++seg)
6008 {
6009 if (seg->p_type != PT_LOAD)
6010 continue;
6011
6012 if (sec->sh_addr >= seg->p_vaddr
6013 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6014 {
6015 aux->seg_base = seg->p_vaddr;
6016 break;
6017 }
6018 }
6019 }
6020
6021 /* Second, build the unwind table from the contents of the unwind
6022 section. */
6023 size = sec->sh_size;
3f5e193b
NC
6024 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6025 _("unwind table"));
57346661
AM
6026 if (!table)
6027 return 0;
6028
1c0751b2
DA
6029 unw_ent_size = 16;
6030 nentries = size / unw_ent_size;
6031 size = unw_ent_size * nentries;
57346661 6032
3f5e193b
NC
6033 tep = aux->table = (struct hppa_unw_table_entry *)
6034 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6035
1c0751b2 6036 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6037 {
6038 unsigned int tmp1, tmp2;
6039
6040 tep->start.section = SHN_UNDEF;
6041 tep->end.section = SHN_UNDEF;
6042
1c0751b2
DA
6043 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6044 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6045 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6046 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6047
6048 tep->start.offset += aux->seg_base;
6049 tep->end.offset += aux->seg_base;
57346661
AM
6050
6051 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6052 tep->Millicode = (tmp1 >> 30) & 0x1;
6053 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6054 tep->Region_description = (tmp1 >> 27) & 0x3;
6055 tep->reserved1 = (tmp1 >> 26) & 0x1;
6056 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6057 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6058 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6059 tep->Args_stored = (tmp1 >> 15) & 0x1;
6060 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6061 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6062 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6063 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6064 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6065 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6066 tep->cxx_info = (tmp1 >> 8) & 0x1;
6067 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6068 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6069 tep->reserved2 = (tmp1 >> 5) & 0x1;
6070 tep->Save_SP = (tmp1 >> 4) & 0x1;
6071 tep->Save_RP = (tmp1 >> 3) & 0x1;
6072 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6073 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6074 tep->Cleanup_defined = tmp1 & 0x1;
6075
6076 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6077 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6078 tep->Large_frame = (tmp2 >> 29) & 0x1;
6079 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6080 tep->reserved4 = (tmp2 >> 27) & 0x1;
6081 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6082 }
6083 free (table);
6084
6085 /* Third, apply any relocations to the unwind table. */
57346661
AM
6086 for (relsec = section_headers;
6087 relsec < section_headers + elf_header.e_shnum;
6088 ++relsec)
6089 {
6090 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6091 || relsec->sh_info >= elf_header.e_shnum
6092 || section_headers + relsec->sh_info != sec)
57346661
AM
6093 continue;
6094
6095 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6096 & rela, & nrelas))
6097 return 0;
6098
6099 for (rp = rela; rp < rela + nrelas; ++rp)
6100 {
aca88567
NC
6101 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6102 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6103
6104 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6105 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6106 {
6107 warn (_("Skipping unexpected relocation type %s\n"), relname);
6108 continue;
6109 }
6110
6111 i = rp->r_offset / unw_ent_size;
6112
89fac5e3 6113 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6114 {
6115 case 0:
6116 aux->table[i].start.section = sym->st_shndx;
1e456d54 6117 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6118 break;
6119 case 1:
6120 aux->table[i].end.section = sym->st_shndx;
1e456d54 6121 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6122 break;
6123 default:
6124 break;
6125 }
6126 }
6127
6128 free (rela);
6129 }
6130
1c0751b2 6131 aux->table_len = nentries;
57346661
AM
6132
6133 return 1;
6134}
6135
6136static int
2cf0635d 6137hppa_process_unwind (FILE * file)
57346661 6138{
57346661 6139 struct hppa_unw_aux_info aux;
2cf0635d
NC
6140 Elf_Internal_Shdr * unwsec = NULL;
6141 Elf_Internal_Shdr * strsec;
6142 Elf_Internal_Shdr * sec;
18bd398b 6143 unsigned long i;
57346661
AM
6144
6145 memset (& aux, 0, sizeof (aux));
6146
c256ffe7
JJ
6147 if (string_table == NULL)
6148 return 1;
57346661
AM
6149
6150 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6151 {
c256ffe7 6152 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6153 && sec->sh_link < elf_header.e_shnum)
57346661
AM
6154 {
6155 aux.nsyms = sec->sh_size / sec->sh_entsize;
6156 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6157
4fbb74a6 6158 strsec = section_headers + sec->sh_link;
59245841 6159 assert (aux.strtab == NULL);
3f5e193b
NC
6160 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6161 1, strsec->sh_size,
6162 _("string table"));
c256ffe7 6163 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6164 }
18bd398b 6165 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6166 unwsec = sec;
6167 }
6168
6169 if (!unwsec)
6170 printf (_("\nThere are no unwind sections in this file.\n"));
6171
6172 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6173 {
18bd398b 6174 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6175 {
57346661
AM
6176 printf (_("\nUnwind section "));
6177 printf (_("'%s'"), SECTION_NAME (sec));
6178
6179 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6180 (unsigned long) sec->sh_offset,
89fac5e3 6181 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6182
6183 slurp_hppa_unwind_table (file, &aux, sec);
6184 if (aux.table_len > 0)
6185 dump_hppa_unwind (&aux);
6186
6187 if (aux.table)
6188 free ((char *) aux.table);
6189 aux.table = NULL;
6190 }
6191 }
6192
6193 if (aux.symtab)
6194 free (aux.symtab);
6195 if (aux.strtab)
6196 free ((char *) aux.strtab);
6197
6198 return 1;
6199}
6200
0b6ae522
DJ
6201struct arm_section
6202{
6203 unsigned char *data;
6204
6205 Elf_Internal_Shdr *sec;
6206 Elf_Internal_Rela *rela;
6207 unsigned long nrelas;
6208 unsigned int rel_type;
6209
6210 Elf_Internal_Rela *next_rela;
6211};
6212
6213struct arm_unw_aux_info
6214{
6215 FILE *file;
6216
6217 Elf_Internal_Sym *symtab; /* The symbol table. */
6218 unsigned long nsyms; /* Number of symbols. */
6219 char *strtab; /* The string table. */
6220 unsigned long strtab_size; /* Size of string table. */
6221};
6222
6223static const char *
6224arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6225 bfd_vma fn, struct absaddr addr)
6226{
6227 const char *procname;
6228 bfd_vma sym_offset;
6229
6230 if (addr.section == SHN_UNDEF)
6231 addr.offset = fn;
6232
6233 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6234 aux->strtab_size, addr, &procname,
6235 &sym_offset);
6236
6237 print_vma (fn, PREFIX_HEX);
6238
6239 if (procname)
6240 {
6241 fputs (" <", stdout);
6242 fputs (procname, stdout);
6243
6244 if (sym_offset)
6245 printf ("+0x%lx", (unsigned long) sym_offset);
6246 fputc ('>', stdout);
6247 }
6248
6249 return procname;
6250}
6251
6252static void
6253arm_free_section (struct arm_section *arm_sec)
6254{
6255 if (arm_sec->data != NULL)
6256 free (arm_sec->data);
6257
6258 if (arm_sec->rela != NULL)
6259 free (arm_sec->rela);
6260}
6261
6262static int
6263arm_section_get_word (struct arm_unw_aux_info *aux,
6264 struct arm_section *arm_sec,
6265 Elf_Internal_Shdr *sec, bfd_vma word_offset,
6266 unsigned int *wordp, struct absaddr *addr)
6267{
6268 Elf_Internal_Rela *rp;
6269 Elf_Internal_Sym *sym;
6270 const char * relname;
6271 unsigned int word;
6272 bfd_boolean wrapped;
6273
6274 addr->section = SHN_UNDEF;
6275 addr->offset = 0;
6276
6277 if (sec != arm_sec->sec)
6278 {
6279 Elf_Internal_Shdr *relsec;
6280
6281 arm_free_section (arm_sec);
6282
6283 arm_sec->sec = sec;
6284 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6285 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6286 arm_sec->rela = NULL;
6287 arm_sec->nrelas = 0;
6288
6289 for (relsec = section_headers;
6290 relsec < section_headers + elf_header.e_shnum;
6291 ++relsec)
6292 {
6293 if (relsec->sh_info >= elf_header.e_shnum
6294 || section_headers + relsec->sh_info != sec)
6295 continue;
6296
6297 if (relsec->sh_type == SHT_REL)
6298 {
6299 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6300 relsec->sh_size,
6301 & arm_sec->rela, & arm_sec->nrelas))
6302 return 0;
6303 break;
6304 }
6305 else if (relsec->sh_type == SHT_RELA)
6306 {
6307 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6308 relsec->sh_size,
6309 & arm_sec->rela, & arm_sec->nrelas))
6310 return 0;
6311 break;
6312 }
6313 }
6314
6315 arm_sec->next_rela = arm_sec->rela;
6316 }
6317
6318 if (arm_sec->data == NULL)
6319 return 0;
6320
6321 word = byte_get (arm_sec->data + word_offset, 4);
6322
6323 wrapped = FALSE;
6324 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6325 {
6326 bfd_vma prelval, offset;
6327
6328 if (rp->r_offset > word_offset && !wrapped)
6329 {
6330 rp = arm_sec->rela;
6331 wrapped = TRUE;
6332 }
6333 if (rp->r_offset > word_offset)
6334 break;
6335
6336 if (rp->r_offset & 3)
6337 {
6338 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6339 (unsigned long) rp->r_offset);
6340 continue;
6341 }
6342
6343 if (rp->r_offset < word_offset)
6344 continue;
6345
fa197c1c
PB
6346 switch (elf_header.e_machine)
6347 {
6348 case EM_ARM:
6349 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6350 break;
6351
6352 case EM_TI_C6000:
6353 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6354 break;
6355
6356 default:
6357 abort();
6358 }
0b6ae522 6359
fa197c1c
PB
6360 if (streq (relname, "R_ARM_NONE")
6361 || streq (relname, "R_C6000_NONE"))
0b6ae522
DJ
6362 continue;
6363
fa197c1c
PB
6364 if (!(streq (relname, "R_ARM_PREL31")
6365 || streq (relname, "R_C6000_PREL31")))
0b6ae522
DJ
6366 {
6367 warn (_("Skipping unexpected relocation type %s\n"), relname);
6368 continue;
6369 }
6370
6371 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6372
6373 if (arm_sec->rel_type == SHT_REL)
6374 {
6375 offset = word & 0x7fffffff;
6376 if (offset & 0x40000000)
6377 offset |= ~ (bfd_vma) 0x7fffffff;
6378 }
6379 else
6380 offset = rp->r_addend;
6381
6382 offset += sym->st_value;
6383 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6384
fa197c1c
PB
6385 if (streq (relname, "R_C6000_PREL31"))
6386 prelval >>= 1;
6387
0b6ae522
DJ
6388 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6389 addr->section = sym->st_shndx;
6390 addr->offset = offset;
6391 break;
6392 }
6393
6394 *wordp = word;
6395 arm_sec->next_rela = rp;
6396
6397 return 1;
6398}
6399
fa197c1c
PB
6400static const char *tic6x_unwind_regnames[16] = {
6401 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6402 "A14", "A13", "A12", "A11", "A10",
6403 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"};
6404
0b6ae522 6405static void
fa197c1c 6406decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6407{
fa197c1c
PB
6408 int i;
6409
6410 for (i = 12; mask; mask >>= 1, i--)
6411 {
6412 if (mask & 1)
6413 {
6414 fputs (tic6x_unwind_regnames[i], stdout);
6415 if (mask > 1)
6416 fputs (", ", stdout);
6417 }
6418 }
6419}
0b6ae522
DJ
6420
6421#define ADVANCE \
6422 if (remaining == 0 && more_words) \
6423 { \
6424 data_offset += 4; \
6425 if (!arm_section_get_word (aux, data_arm_sec, data_sec, \
6426 data_offset, &word, &addr)) \
6427 return; \
6428 remaining = 4; \
6429 more_words--; \
6430 } \
6431
6432#define GET_OP(OP) \
6433 ADVANCE; \
6434 if (remaining) \
6435 { \
6436 remaining--; \
6437 (OP) = word >> 24; \
6438 word <<= 8; \
6439 } \
6440 else \
6441 { \
2b692964 6442 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6443 return; \
6444 } \
cc5914eb 6445 printf ("0x%02x ", OP)
0b6ae522 6446
fa197c1c
PB
6447static void
6448decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6449 unsigned int word, unsigned int remaining,
6450 unsigned int more_words,
6451 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6452 struct arm_section *data_arm_sec)
6453{
6454 struct absaddr addr;
0b6ae522
DJ
6455
6456 /* Decode the unwinding instructions. */
6457 while (1)
6458 {
6459 unsigned int op, op2;
6460
6461 ADVANCE;
6462 if (remaining == 0)
6463 break;
6464 remaining--;
6465 op = word >> 24;
6466 word <<= 8;
6467
cc5914eb 6468 printf (" 0x%02x ", op);
0b6ae522
DJ
6469
6470 if ((op & 0xc0) == 0x00)
6471 {
6472 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6473
cc5914eb 6474 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6475 }
6476 else if ((op & 0xc0) == 0x40)
6477 {
6478 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6479
cc5914eb 6480 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6481 }
6482 else if ((op & 0xf0) == 0x80)
6483 {
6484 GET_OP (op2);
6485 if (op == 0x80 && op2 == 0)
6486 printf (_("Refuse to unwind"));
6487 else
6488 {
6489 unsigned int mask = ((op & 0x0f) << 8) | op2;
6490 int first = 1;
6491 int i;
2b692964 6492
0b6ae522
DJ
6493 printf ("pop {");
6494 for (i = 0; i < 12; i++)
6495 if (mask & (1 << i))
6496 {
6497 if (first)
6498 first = 0;
6499 else
6500 printf (", ");
6501 printf ("r%d", 4 + i);
6502 }
6503 printf ("}");
6504 }
6505 }
6506 else if ((op & 0xf0) == 0x90)
6507 {
6508 if (op == 0x9d || op == 0x9f)
6509 printf (_(" [Reserved]"));
6510 else
cc5914eb 6511 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6512 }
6513 else if ((op & 0xf0) == 0xa0)
6514 {
6515 int end = 4 + (op & 0x07);
6516 int first = 1;
6517 int i;
61865e30 6518
0b6ae522
DJ
6519 printf (" pop {");
6520 for (i = 4; i <= end; i++)
6521 {
6522 if (first)
6523 first = 0;
6524 else
6525 printf (", ");
6526 printf ("r%d", i);
6527 }
6528 if (op & 0x08)
6529 {
6530 if (first)
6531 printf (", ");
6532 printf ("r14");
6533 }
6534 printf ("}");
6535 }
6536 else if (op == 0xb0)
6537 printf (_(" finish"));
6538 else if (op == 0xb1)
6539 {
6540 GET_OP (op2);
6541 if (op2 == 0 || (op2 & 0xf0) != 0)
6542 printf (_("[Spare]"));
6543 else
6544 {
6545 unsigned int mask = op2 & 0x0f;
6546 int first = 1;
6547 int i;
61865e30 6548
0b6ae522
DJ
6549 printf ("pop {");
6550 for (i = 0; i < 12; i++)
6551 if (mask & (1 << i))
6552 {
6553 if (first)
6554 first = 0;
6555 else
6556 printf (", ");
6557 printf ("r%d", i);
6558 }
6559 printf ("}");
6560 }
6561 }
6562 else if (op == 0xb2)
6563 {
b115cf96 6564 unsigned char buf[9];
0b6ae522
DJ
6565 unsigned int i, len;
6566 unsigned long offset;
61865e30 6567
b115cf96 6568 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6569 {
6570 GET_OP (buf[i]);
6571 if ((buf[i] & 0x80) == 0)
6572 break;
6573 }
6574 assert (i < sizeof (buf));
6575 offset = read_uleb128 (buf, &len);
6576 assert (len == i + 1);
6577 offset = offset * 4 + 0x204;
cc5914eb 6578 printf ("vsp = vsp + %ld", offset);
0b6ae522 6579 }
61865e30 6580 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6581 {
61865e30
NC
6582 unsigned int first, last;
6583
6584 GET_OP (op2);
6585 first = op2 >> 4;
6586 last = op2 & 0x0f;
6587 if (op == 0xc8)
6588 first = first + 16;
6589 printf ("pop {D%d", first);
6590 if (last)
6591 printf ("-D%d", first + last);
6592 printf ("}");
6593 }
6594 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6595 {
6596 unsigned int count = op & 0x07;
6597
6598 printf ("pop {D8");
6599 if (count)
6600 printf ("-D%d", 8 + count);
6601 printf ("}");
6602 }
6603 else if (op >= 0xc0 && op <= 0xc5)
6604 {
6605 unsigned int count = op & 0x07;
6606
6607 printf (" pop {wR10");
6608 if (count)
6609 printf ("-wR%d", 10 + count);
6610 printf ("}");
6611 }
6612 else if (op == 0xc6)
6613 {
6614 unsigned int first, last;
6615
6616 GET_OP (op2);
6617 first = op2 >> 4;
6618 last = op2 & 0x0f;
6619 printf ("pop {wR%d", first);
6620 if (last)
6621 printf ("-wR%d", first + last);
6622 printf ("}");
6623 }
6624 else if (op == 0xc7)
6625 {
6626 GET_OP (op2);
6627 if (op2 == 0 || (op2 & 0xf0) != 0)
6628 printf (_("[Spare]"));
0b6ae522
DJ
6629 else
6630 {
61865e30
NC
6631 unsigned int mask = op2 & 0x0f;
6632 int first = 1;
6633 int i;
6634
6635 printf ("pop {");
6636 for (i = 0; i < 4; i++)
6637 if (mask & (1 << i))
6638 {
6639 if (first)
6640 first = 0;
6641 else
6642 printf (", ");
6643 printf ("wCGR%d", i);
6644 }
6645 printf ("}");
0b6ae522
DJ
6646 }
6647 }
61865e30
NC
6648 else
6649 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6650 printf ("\n");
6651 }
fa197c1c
PB
6652}
6653
6654static void
6655decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6656 unsigned int word, unsigned int remaining,
6657 unsigned int more_words,
6658 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6659 struct arm_section *data_arm_sec)
6660{
6661 struct absaddr addr;
6662
6663 /* Decode the unwinding instructions. */
6664 while (1)
6665 {
6666 unsigned int op, op2;
6667
6668 ADVANCE;
6669 if (remaining == 0)
6670 break;
6671 remaining--;
6672 op = word >> 24;
6673 word <<= 8;
6674
6675 printf (_(" 0x%02x "), op);
6676
6677 if ((op & 0xc0) == 0x00)
6678 {
6679 int offset = ((op & 0x3f) << 3) + 8;
6680 printf (_(" sp = sp + %d"), offset);
6681 }
6682 else if ((op & 0xc0) == 0x80)
6683 {
6684 GET_OP (op2);
6685 if (op == 0x80 && op2 == 0)
6686 printf (_("Refuse to unwind"));
6687 else
6688 {
6689 unsigned int mask = ((op & 0x1f) << 8) | op2;
6690 if (op & 0x20)
6691 printf ("pop compact {");
6692 else
6693 printf ("pop {");
6694
6695 decode_tic6x_unwind_regmask (mask);
6696 printf("}");
6697 }
6698 }
6699 else if ((op & 0xf0) == 0xc0)
6700 {
6701 unsigned int reg;
6702 unsigned int nregs;
6703 unsigned int i;
6704 const char *name;
6705 struct {
6706 unsigned int offset;
6707 unsigned int reg;
6708 } regpos[16];
6709
6710 /* Scan entire instruction first so that GET_OP output is not
6711 interleaved with disassembly. */
6712 nregs = 0;
6713 for (i = 0; nregs < (op & 0xf); i++)
6714 {
6715 GET_OP (op2);
6716 reg = op2 >> 4;
6717 if (reg != 0xf)
6718 {
6719 regpos[nregs].offset = i * 2;
6720 regpos[nregs].reg = reg;
6721 nregs++;
6722 }
6723
6724 reg = op2 & 0xf;
6725 if (reg != 0xf)
6726 {
6727 regpos[nregs].offset = i * 2 + 1;
6728 regpos[nregs].reg = reg;
6729 nregs++;
6730 }
6731 }
6732
6733 printf (_("pop frame {"));
6734 reg = nregs - 1;
6735 for (i = i * 2; i > 0; i--)
6736 {
6737 if (regpos[reg].offset == i - 1)
6738 {
6739 name = tic6x_unwind_regnames[regpos[reg].reg];
6740 if (reg > 0)
6741 reg--;
6742 }
6743 else
6744 name = _("[pad]");
6745
6746 fputs (name, stdout);
6747 if (i > 1)
6748 printf (", ");
6749 }
6750
6751 printf ("}");
6752 }
6753 else if (op == 0xd0)
6754 printf (" MOV FP, SP");
6755 else if (op == 0xd1)
6756 printf (" __c6xabi_pop_rts");
6757 else if (op == 0xd2)
6758 {
6759 unsigned char buf[9];
6760 unsigned int i, len;
6761 unsigned long offset;
6762 for (i = 0; i < sizeof (buf); i++)
6763 {
6764 GET_OP (buf[i]);
6765 if ((buf[i] & 0x80) == 0)
6766 break;
6767 }
6768 assert (i < sizeof (buf));
6769 offset = read_uleb128 (buf, &len);
6770 assert (len == i + 1);
6771 offset = offset * 8 + 0x408;
6772 printf (_("sp = sp + %ld"), offset);
6773 }
6774 else if ((op & 0xf0) == 0xe0)
6775 {
6776 if ((op & 0x0f) == 7)
6777 printf (" RETURN");
6778 else
6779 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
6780 }
6781 else
6782 {
6783 printf (_(" [unsupported opcode]"));
6784 }
6785 putchar ('\n');
6786 }
6787}
6788
6789static bfd_vma
6790expand_prel31 (bfd_vma word, bfd_vma where)
6791{
6792 bfd_vma offset;
6793
6794 offset = word & 0x7fffffff;
6795 if (offset & 0x40000000)
6796 offset |= ~ (bfd_vma) 0x7fffffff;
6797
6798 if (elf_header.e_machine == EM_TI_C6000)
6799 offset <<= 1;
6800
6801 return offset + where;
6802}
6803
6804static void
6805decode_arm_unwind (struct arm_unw_aux_info *aux,
6806 unsigned int word, unsigned int remaining,
6807 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6808 struct arm_section *data_arm_sec)
6809{
6810 int per_index;
6811 unsigned int more_words = 0;
6812 struct absaddr addr;
6813
6814 if (remaining == 0)
6815 {
6816 /* Fetch the first word. */
6817 if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
6818 &word, &addr))
6819 return;
6820 remaining = 4;
6821 }
6822
6823 if ((word & 0x80000000) == 0)
6824 {
6825 /* Expand prel31 for personality routine. */
6826 bfd_vma fn;
6827 const char *procname;
6828
6829 fn = expand_prel31 (word, data_sec->sh_addr + data_offset);
6830 printf (_(" Personality routine: "));
6831 procname = arm_print_vma_and_name (aux, fn, addr);
6832 fputc ('\n', stdout);
6833
6834 /* The GCC personality routines use the standard compact
6835 encoding, starting with one byte giving the number of
6836 words. */
6837 if (procname != NULL
6838 && (const_strneq (procname, "__gcc_personality_v0")
6839 || const_strneq (procname, "__gxx_personality_v0")
6840 || const_strneq (procname, "__gcj_personality_v0")
6841 || const_strneq (procname, "__gnu_objc_personality_v0")))
6842 {
6843 remaining = 0;
6844 more_words = 1;
6845 ADVANCE;
6846 if (!remaining)
6847 {
6848 printf (_(" [Truncated data]\n"));
6849 return;
6850 }
6851 more_words = word >> 24;
6852 word <<= 8;
6853 remaining--;
6854 per_index = -1;
6855 }
6856 else
6857 return;
6858 }
6859 else
6860 {
6861
6862 per_index = (word >> 24) & 0x7f;
6863 printf (_(" Compact model %d\n"), per_index);
6864 if (per_index == 0)
6865 {
6866 more_words = 0;
6867 word <<= 8;
6868 remaining--;
6869 }
6870 else if (per_index < 3)
6871 {
6872 more_words = (word >> 16) & 0xff;
6873 word <<= 16;
6874 remaining -= 2;
6875 }
6876 }
6877
6878 switch (elf_header.e_machine)
6879 {
6880 case EM_ARM:
6881 if (per_index < 3)
6882 {
6883 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
6884 data_offset, data_sec, data_arm_sec);
6885 }
6886 else
6887 printf (" [reserved]\n");
6888 break;
6889
6890 case EM_TI_C6000:
6891 if (per_index < 3)
6892 {
6893 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
6894 data_offset, data_sec, data_arm_sec);
6895 }
6896 else if (per_index < 5)
6897 {
6898 if (((word >> 17) & 0x7f) == 0x7f)
6899 printf (_(" Restore stack from frame pointer\n"));
6900 else
6901 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
6902 printf (_(" Registers restored: "));
6903 if (per_index == 4)
6904 printf (" (compact) ");
6905 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
6906 putchar ('\n');
6907 printf (_(" Return register: %s\n"),
6908 tic6x_unwind_regnames[word & 0xf]);
6909 }
6910 else
6911 printf (" [reserved]\n");
6912 break;
6913
6914 default:
6915 abort ();
6916 }
0b6ae522
DJ
6917
6918 /* Decode the descriptors. Not implemented. */
6919}
6920
6921static void
6922dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
6923{
6924 struct arm_section exidx_arm_sec, extab_arm_sec;
6925 unsigned int i, exidx_len;
6926
6927 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
6928 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
6929 exidx_len = exidx_sec->sh_size / 8;
6930
6931 for (i = 0; i < exidx_len; i++)
6932 {
6933 unsigned int exidx_fn, exidx_entry;
6934 struct absaddr fn_addr, entry_addr;
6935 bfd_vma fn;
6936
6937 fputc ('\n', stdout);
6938
6939 if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6940 8 * i, &exidx_fn, &fn_addr)
6941 || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6942 8 * i + 4, &exidx_entry, &entry_addr))
6943 {
6944 arm_free_section (&exidx_arm_sec);
6945 arm_free_section (&extab_arm_sec);
6946 return;
6947 }
6948
fa197c1c 6949 fn = expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522
DJ
6950
6951 arm_print_vma_and_name (aux, fn, entry_addr);
6952 fputs (": ", stdout);
6953
6954 if (exidx_entry == 1)
6955 {
6956 print_vma (exidx_entry, PREFIX_HEX);
6957 fputs (" [cantunwind]\n", stdout);
6958 }
6959 else if (exidx_entry & 0x80000000)
6960 {
6961 print_vma (exidx_entry, PREFIX_HEX);
6962 fputc ('\n', stdout);
6963 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
6964 }
6965 else
6966 {
8f73510c 6967 bfd_vma table, table_offset = 0;
0b6ae522
DJ
6968 Elf_Internal_Shdr *table_sec;
6969
6970 fputs ("@", stdout);
fa197c1c 6971 table = expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
6972 print_vma (table, PREFIX_HEX);
6973 printf ("\n");
6974
6975 /* Locate the matching .ARM.extab. */
6976 if (entry_addr.section != SHN_UNDEF
6977 && entry_addr.section < elf_header.e_shnum)
6978 {
6979 table_sec = section_headers + entry_addr.section;
6980 table_offset = entry_addr.offset;
6981 }
6982 else
6983 {
6984 table_sec = find_section_by_address (table);
6985 if (table_sec != NULL)
6986 table_offset = table - table_sec->sh_addr;
6987 }
6988 if (table_sec == NULL)
6989 {
6990 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
6991 (unsigned long) table);
6992 continue;
6993 }
6994 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
6995 &extab_arm_sec);
6996 }
6997 }
6998
6999 printf ("\n");
7000
7001 arm_free_section (&exidx_arm_sec);
7002 arm_free_section (&extab_arm_sec);
7003}
7004
fa197c1c 7005/* Used for both ARM and C6X unwinding tables. */
0b6ae522
DJ
7006static int
7007arm_process_unwind (FILE *file)
7008{
7009 struct arm_unw_aux_info aux;
7010 Elf_Internal_Shdr *unwsec = NULL;
7011 Elf_Internal_Shdr *strsec;
7012 Elf_Internal_Shdr *sec;
7013 unsigned long i;
fa197c1c 7014 unsigned int sec_type;
0b6ae522
DJ
7015
7016 memset (& aux, 0, sizeof (aux));
7017 aux.file = file;
7018
fa197c1c
PB
7019 switch (elf_header.e_machine)
7020 {
7021 case EM_ARM:
7022 sec_type = SHT_ARM_EXIDX;
7023 break;
7024
7025 case EM_TI_C6000:
7026 sec_type = SHT_C6000_UNWIND;
7027 break;
7028
7029 default:
7030 abort();
7031 }
7032
0b6ae522
DJ
7033 if (string_table == NULL)
7034 return 1;
7035
7036 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7037 {
7038 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7039 {
7040 aux.nsyms = sec->sh_size / sec->sh_entsize;
7041 aux.symtab = GET_ELF_SYMBOLS (file, sec);
7042
7043 strsec = section_headers + sec->sh_link;
59245841 7044 assert (aux.strtab == NULL);
0b6ae522
DJ
7045 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7046 1, strsec->sh_size, _("string table"));
7047 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7048 }
fa197c1c 7049 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7050 unwsec = sec;
7051 }
7052
7053 if (!unwsec)
7054 printf (_("\nThere are no unwind sections in this file.\n"));
7055
7056 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7057 {
fa197c1c 7058 if (sec->sh_type == sec_type)
0b6ae522
DJ
7059 {
7060 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7061 SECTION_NAME (sec),
7062 (unsigned long) sec->sh_offset,
7063 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
7064
7065 dump_arm_unwind (&aux, sec);
7066 }
7067 }
7068
7069 if (aux.symtab)
7070 free (aux.symtab);
7071 if (aux.strtab)
7072 free ((char *) aux.strtab);
7073
7074 return 1;
7075}
7076
57346661 7077static int
2cf0635d 7078process_unwind (FILE * file)
57346661 7079{
2cf0635d
NC
7080 struct unwind_handler
7081 {
57346661 7082 int machtype;
2cf0635d
NC
7083 int (* handler)(FILE *);
7084 } handlers[] =
7085 {
0b6ae522 7086 { EM_ARM, arm_process_unwind },
57346661
AM
7087 { EM_IA_64, ia64_process_unwind },
7088 { EM_PARISC, hppa_process_unwind },
fa197c1c 7089 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7090 { 0, 0 }
7091 };
7092 int i;
7093
7094 if (!do_unwind)
7095 return 1;
7096
7097 for (i = 0; handlers[i].handler != NULL; i++)
7098 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7099 return handlers[i].handler (file);
57346661
AM
7100
7101 printf (_("\nThere are no unwind sections in this file.\n"));
7102 return 1;
7103}
7104
252b5132 7105static void
2cf0635d 7106dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7107{
7108 switch (entry->d_tag)
7109 {
7110 case DT_MIPS_FLAGS:
7111 if (entry->d_un.d_val == 0)
2b692964 7112 printf (_("NONE\n"));
252b5132
RH
7113 else
7114 {
7115 static const char * opts[] =
7116 {
7117 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7118 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7119 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7120 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7121 "RLD_ORDER_SAFE"
7122 };
7123 unsigned int cnt;
7124 int first = 1;
2b692964 7125
60bca95a 7126 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7127 if (entry->d_un.d_val & (1 << cnt))
7128 {
7129 printf ("%s%s", first ? "" : " ", opts[cnt]);
7130 first = 0;
7131 }
7132 puts ("");
7133 }
7134 break;
103f02d3 7135
252b5132 7136 case DT_MIPS_IVERSION:
d79b3d50 7137 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
2b692964 7138 printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7139 else
2b692964 7140 printf (_("<corrupt: %ld>\n"), (long) entry->d_un.d_ptr);
252b5132 7141 break;
103f02d3 7142
252b5132
RH
7143 case DT_MIPS_TIME_STAMP:
7144 {
7145 char timebuf[20];
2cf0635d 7146 struct tm * tmp;
50da7a9c 7147
91d6fa6a
NC
7148 time_t atime = entry->d_un.d_val;
7149 tmp = gmtime (&atime);
e9e44622
JJ
7150 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7151 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7152 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
2b692964 7153 printf (_("Time Stamp: %s\n"), timebuf);
252b5132
RH
7154 }
7155 break;
103f02d3 7156
252b5132
RH
7157 case DT_MIPS_RLD_VERSION:
7158 case DT_MIPS_LOCAL_GOTNO:
7159 case DT_MIPS_CONFLICTNO:
7160 case DT_MIPS_LIBLISTNO:
7161 case DT_MIPS_SYMTABNO:
7162 case DT_MIPS_UNREFEXTNO:
7163 case DT_MIPS_HIPAGENO:
7164 case DT_MIPS_DELTA_CLASS_NO:
7165 case DT_MIPS_DELTA_INSTANCE_NO:
7166 case DT_MIPS_DELTA_RELOC_NO:
7167 case DT_MIPS_DELTA_SYM_NO:
7168 case DT_MIPS_DELTA_CLASSSYM_NO:
7169 case DT_MIPS_COMPACT_SIZE:
7170 printf ("%ld\n", (long) entry->d_un.d_ptr);
7171 break;
103f02d3
UD
7172
7173 default:
0af1713e 7174 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
7175 }
7176}
7177
103f02d3 7178static void
2cf0635d 7179dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7180{
7181 switch (entry->d_tag)
7182 {
7183 case DT_HP_DLD_FLAGS:
7184 {
7185 static struct
7186 {
7187 long int bit;
2cf0635d 7188 const char * str;
5e220199
NC
7189 }
7190 flags[] =
7191 {
7192 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7193 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7194 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7195 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7196 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7197 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7198 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7199 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7200 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7201 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7202 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7203 { DT_HP_GST, "HP_GST" },
7204 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7205 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7206 { DT_HP_NODELETE, "HP_NODELETE" },
7207 { DT_HP_GROUP, "HP_GROUP" },
7208 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7209 };
103f02d3 7210 int first = 1;
5e220199 7211 size_t cnt;
f7a99963 7212 bfd_vma val = entry->d_un.d_val;
103f02d3 7213
60bca95a 7214 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7215 if (val & flags[cnt].bit)
30800947
NC
7216 {
7217 if (! first)
7218 putchar (' ');
7219 fputs (flags[cnt].str, stdout);
7220 first = 0;
7221 val ^= flags[cnt].bit;
7222 }
76da6bbe 7223
103f02d3 7224 if (val != 0 || first)
f7a99963
NC
7225 {
7226 if (! first)
7227 putchar (' ');
7228 print_vma (val, HEX);
7229 }
103f02d3
UD
7230 }
7231 break;
76da6bbe 7232
252b5132 7233 default:
f7a99963
NC
7234 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7235 break;
252b5132 7236 }
35b1837e 7237 putchar ('\n');
252b5132
RH
7238}
7239
28f997cf
TG
7240#ifdef BFD64
7241
7242/* VMS vs Unix time offset and factor. */
7243
7244#define VMS_EPOCH_OFFSET 35067168000000000LL
7245#define VMS_GRANULARITY_FACTOR 10000000
7246
7247/* Display a VMS time in a human readable format. */
7248
7249static void
7250print_vms_time (bfd_int64_t vmstime)
7251{
7252 struct tm *tm;
7253 time_t unxtime;
7254
7255 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7256 tm = gmtime (&unxtime);
7257 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7258 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7259 tm->tm_hour, tm->tm_min, tm->tm_sec);
7260}
7261#endif /* BFD64 */
7262
ecc51f48 7263static void
2cf0635d 7264dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7265{
7266 switch (entry->d_tag)
7267 {
0de14b54 7268 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7269 /* First 3 slots reserved. */
ecc51f48
NC
7270 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7271 printf (" -- ");
7272 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7273 break;
7274
28f997cf
TG
7275 case DT_IA_64_VMS_LINKTIME:
7276#ifdef BFD64
7277 print_vms_time (entry->d_un.d_val);
7278#endif
7279 break;
7280
7281 case DT_IA_64_VMS_LNKFLAGS:
7282 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7283 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7284 printf (" CALL_DEBUG");
7285 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7286 printf (" NOP0BUFS");
7287 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7288 printf (" P0IMAGE");
7289 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7290 printf (" MKTHREADS");
7291 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7292 printf (" UPCALLS");
7293 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7294 printf (" IMGSTA");
7295 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7296 printf (" INITIALIZE");
7297 if (entry->d_un.d_val & VMS_LF_MAIN)
7298 printf (" MAIN");
7299 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7300 printf (" EXE_INIT");
7301 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7302 printf (" TBK_IN_IMG");
7303 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7304 printf (" DBG_IN_IMG");
7305 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7306 printf (" TBK_IN_DSF");
7307 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7308 printf (" DBG_IN_DSF");
7309 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7310 printf (" SIGNATURES");
7311 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7312 printf (" REL_SEG_OFF");
7313 break;
7314
bdf4d63a
JJ
7315 default:
7316 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7317 break;
ecc51f48 7318 }
bdf4d63a 7319 putchar ('\n');
ecc51f48
NC
7320}
7321
252b5132 7322static int
2cf0635d 7323get_32bit_dynamic_section (FILE * file)
252b5132 7324{
2cf0635d
NC
7325 Elf32_External_Dyn * edyn;
7326 Elf32_External_Dyn * ext;
7327 Elf_Internal_Dyn * entry;
103f02d3 7328
3f5e193b
NC
7329 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7330 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7331 if (!edyn)
7332 return 0;
103f02d3 7333
ba2685cc
AM
7334/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7335 might not have the luxury of section headers. Look for the DT_NULL
7336 terminator to determine the number of entries. */
7337 for (ext = edyn, dynamic_nent = 0;
7338 (char *) ext < (char *) edyn + dynamic_size;
7339 ext++)
7340 {
7341 dynamic_nent++;
7342 if (BYTE_GET (ext->d_tag) == DT_NULL)
7343 break;
7344 }
252b5132 7345
3f5e193b
NC
7346 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7347 sizeof (* entry));
b2d38a17 7348 if (dynamic_section == NULL)
252b5132 7349 {
9ea033b2
NC
7350 error (_("Out of memory\n"));
7351 free (edyn);
7352 return 0;
7353 }
252b5132 7354
fb514b26 7355 for (ext = edyn, entry = dynamic_section;
ba2685cc 7356 entry < dynamic_section + dynamic_nent;
fb514b26 7357 ext++, entry++)
9ea033b2 7358 {
fb514b26
AM
7359 entry->d_tag = BYTE_GET (ext->d_tag);
7360 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7361 }
7362
9ea033b2
NC
7363 free (edyn);
7364
7365 return 1;
7366}
7367
7368static int
2cf0635d 7369get_64bit_dynamic_section (FILE * file)
9ea033b2 7370{
2cf0635d
NC
7371 Elf64_External_Dyn * edyn;
7372 Elf64_External_Dyn * ext;
7373 Elf_Internal_Dyn * entry;
103f02d3 7374
3f5e193b
NC
7375 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7376 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7377 if (!edyn)
7378 return 0;
103f02d3 7379
ba2685cc
AM
7380/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7381 might not have the luxury of section headers. Look for the DT_NULL
7382 terminator to determine the number of entries. */
7383 for (ext = edyn, dynamic_nent = 0;
7384 (char *) ext < (char *) edyn + dynamic_size;
7385 ext++)
7386 {
7387 dynamic_nent++;
66543521 7388 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7389 break;
7390 }
252b5132 7391
3f5e193b
NC
7392 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7393 sizeof (* entry));
b2d38a17 7394 if (dynamic_section == NULL)
252b5132
RH
7395 {
7396 error (_("Out of memory\n"));
7397 free (edyn);
7398 return 0;
7399 }
7400
fb514b26 7401 for (ext = edyn, entry = dynamic_section;
ba2685cc 7402 entry < dynamic_section + dynamic_nent;
fb514b26 7403 ext++, entry++)
252b5132 7404 {
66543521
AM
7405 entry->d_tag = BYTE_GET (ext->d_tag);
7406 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7407 }
7408
7409 free (edyn);
7410
9ea033b2
NC
7411 return 1;
7412}
7413
e9e44622
JJ
7414static void
7415print_dynamic_flags (bfd_vma flags)
d1133906 7416{
e9e44622 7417 int first = 1;
13ae64f3 7418
d1133906
NC
7419 while (flags)
7420 {
7421 bfd_vma flag;
7422
7423 flag = flags & - flags;
7424 flags &= ~ flag;
7425
e9e44622
JJ
7426 if (first)
7427 first = 0;
7428 else
7429 putc (' ', stdout);
13ae64f3 7430
d1133906
NC
7431 switch (flag)
7432 {
e9e44622
JJ
7433 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7434 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7435 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7436 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7437 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7438 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7439 }
7440 }
e9e44622 7441 puts ("");
d1133906
NC
7442}
7443
b2d38a17
NC
7444/* Parse and display the contents of the dynamic section. */
7445
9ea033b2 7446static int
2cf0635d 7447process_dynamic_section (FILE * file)
9ea033b2 7448{
2cf0635d 7449 Elf_Internal_Dyn * entry;
9ea033b2
NC
7450
7451 if (dynamic_size == 0)
7452 {
7453 if (do_dynamic)
b2d38a17 7454 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7455
7456 return 1;
7457 }
7458
7459 if (is_32bit_elf)
7460 {
b2d38a17 7461 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7462 return 0;
7463 }
b2d38a17 7464 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7465 return 0;
7466
252b5132
RH
7467 /* Find the appropriate symbol table. */
7468 if (dynamic_symbols == NULL)
7469 {
86dba8ee
AM
7470 for (entry = dynamic_section;
7471 entry < dynamic_section + dynamic_nent;
7472 ++entry)
252b5132 7473 {
c8286bd1 7474 Elf_Internal_Shdr section;
252b5132
RH
7475
7476 if (entry->d_tag != DT_SYMTAB)
7477 continue;
7478
7479 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7480
7481 /* Since we do not know how big the symbol table is,
7482 we default to reading in the entire file (!) and
7483 processing that. This is overkill, I know, but it
e3c8793a 7484 should work. */
d93f0186 7485 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7486
fb52b2f4
NC
7487 if (archive_file_offset != 0)
7488 section.sh_size = archive_file_size - section.sh_offset;
7489 else
7490 {
7491 if (fseek (file, 0, SEEK_END))
591a748a 7492 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7493
7494 section.sh_size = ftell (file) - section.sh_offset;
7495 }
252b5132 7496
9ea033b2 7497 if (is_32bit_elf)
9ad5cbcf 7498 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7499 else
9ad5cbcf 7500 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7501
9ad5cbcf 7502 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 7503 if (num_dynamic_syms < 1)
252b5132
RH
7504 {
7505 error (_("Unable to determine the number of symbols to load\n"));
7506 continue;
7507 }
7508
9ad5cbcf 7509 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
7510 }
7511 }
7512
7513 /* Similarly find a string table. */
7514 if (dynamic_strings == NULL)
7515 {
86dba8ee
AM
7516 for (entry = dynamic_section;
7517 entry < dynamic_section + dynamic_nent;
7518 ++entry)
252b5132
RH
7519 {
7520 unsigned long offset;
b34976b6 7521 long str_tab_len;
252b5132
RH
7522
7523 if (entry->d_tag != DT_STRTAB)
7524 continue;
7525
7526 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7527
7528 /* Since we do not know how big the string table is,
7529 we default to reading in the entire file (!) and
7530 processing that. This is overkill, I know, but it
e3c8793a 7531 should work. */
252b5132 7532
d93f0186 7533 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7534
7535 if (archive_file_offset != 0)
7536 str_tab_len = archive_file_size - offset;
7537 else
7538 {
7539 if (fseek (file, 0, SEEK_END))
7540 error (_("Unable to seek to end of file\n"));
7541 str_tab_len = ftell (file) - offset;
7542 }
252b5132
RH
7543
7544 if (str_tab_len < 1)
7545 {
7546 error
7547 (_("Unable to determine the length of the dynamic string table\n"));
7548 continue;
7549 }
7550
3f5e193b
NC
7551 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7552 str_tab_len,
7553 _("dynamic string table"));
59245841 7554 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7555 break;
7556 }
7557 }
7558
7559 /* And find the syminfo section if available. */
7560 if (dynamic_syminfo == NULL)
7561 {
3e8bba36 7562 unsigned long syminsz = 0;
252b5132 7563
86dba8ee
AM
7564 for (entry = dynamic_section;
7565 entry < dynamic_section + dynamic_nent;
7566 ++entry)
252b5132
RH
7567 {
7568 if (entry->d_tag == DT_SYMINENT)
7569 {
7570 /* Note: these braces are necessary to avoid a syntax
7571 error from the SunOS4 C compiler. */
7572 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7573 }
7574 else if (entry->d_tag == DT_SYMINSZ)
7575 syminsz = entry->d_un.d_val;
7576 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7577 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7578 syminsz);
252b5132
RH
7579 }
7580
7581 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7582 {
2cf0635d
NC
7583 Elf_External_Syminfo * extsyminfo;
7584 Elf_External_Syminfo * extsym;
7585 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7586
7587 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7588 extsyminfo = (Elf_External_Syminfo *)
7589 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7590 _("symbol information"));
a6e9f9df
AM
7591 if (!extsyminfo)
7592 return 0;
252b5132 7593
3f5e193b 7594 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7595 if (dynamic_syminfo == NULL)
7596 {
7597 error (_("Out of memory\n"));
7598 return 0;
7599 }
7600
7601 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7602 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7603 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7604 ++syminfo, ++extsym)
252b5132 7605 {
86dba8ee
AM
7606 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7607 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7608 }
7609
7610 free (extsyminfo);
7611 }
7612 }
7613
7614 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7615 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7616 dynamic_addr, dynamic_nent);
252b5132
RH
7617 if (do_dynamic)
7618 printf (_(" Tag Type Name/Value\n"));
7619
86dba8ee
AM
7620 for (entry = dynamic_section;
7621 entry < dynamic_section + dynamic_nent;
7622 entry++)
252b5132
RH
7623 {
7624 if (do_dynamic)
f7a99963 7625 {
2cf0635d 7626 const char * dtype;
e699b9ff 7627
f7a99963
NC
7628 putchar (' ');
7629 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7630 dtype = get_dynamic_type (entry->d_tag);
7631 printf (" (%s)%*s", dtype,
7632 ((is_32bit_elf ? 27 : 19)
7633 - (int) strlen (dtype)),
f7a99963
NC
7634 " ");
7635 }
252b5132
RH
7636
7637 switch (entry->d_tag)
7638 {
d1133906
NC
7639 case DT_FLAGS:
7640 if (do_dynamic)
e9e44622 7641 print_dynamic_flags (entry->d_un.d_val);
d1133906 7642 break;
76da6bbe 7643
252b5132
RH
7644 case DT_AUXILIARY:
7645 case DT_FILTER:
019148e4
L
7646 case DT_CONFIG:
7647 case DT_DEPAUDIT:
7648 case DT_AUDIT:
252b5132
RH
7649 if (do_dynamic)
7650 {
019148e4 7651 switch (entry->d_tag)
b34976b6 7652 {
019148e4
L
7653 case DT_AUXILIARY:
7654 printf (_("Auxiliary library"));
7655 break;
7656
7657 case DT_FILTER:
7658 printf (_("Filter library"));
7659 break;
7660
b34976b6 7661 case DT_CONFIG:
019148e4
L
7662 printf (_("Configuration file"));
7663 break;
7664
7665 case DT_DEPAUDIT:
7666 printf (_("Dependency audit library"));
7667 break;
7668
7669 case DT_AUDIT:
7670 printf (_("Audit library"));
7671 break;
7672 }
252b5132 7673
d79b3d50
NC
7674 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7675 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7676 else
f7a99963
NC
7677 {
7678 printf (": ");
7679 print_vma (entry->d_un.d_val, PREFIX_HEX);
7680 putchar ('\n');
7681 }
252b5132
RH
7682 }
7683 break;
7684
dcefbbbd 7685 case DT_FEATURE:
252b5132
RH
7686 if (do_dynamic)
7687 {
7688 printf (_("Flags:"));
86f55779 7689
252b5132
RH
7690 if (entry->d_un.d_val == 0)
7691 printf (_(" None\n"));
7692 else
7693 {
7694 unsigned long int val = entry->d_un.d_val;
86f55779 7695
252b5132
RH
7696 if (val & DTF_1_PARINIT)
7697 {
7698 printf (" PARINIT");
7699 val ^= DTF_1_PARINIT;
7700 }
dcefbbbd
L
7701 if (val & DTF_1_CONFEXP)
7702 {
7703 printf (" CONFEXP");
7704 val ^= DTF_1_CONFEXP;
7705 }
252b5132
RH
7706 if (val != 0)
7707 printf (" %lx", val);
7708 puts ("");
7709 }
7710 }
7711 break;
7712
7713 case DT_POSFLAG_1:
7714 if (do_dynamic)
7715 {
7716 printf (_("Flags:"));
86f55779 7717
252b5132
RH
7718 if (entry->d_un.d_val == 0)
7719 printf (_(" None\n"));
7720 else
7721 {
7722 unsigned long int val = entry->d_un.d_val;
86f55779 7723
252b5132
RH
7724 if (val & DF_P1_LAZYLOAD)
7725 {
7726 printf (" LAZYLOAD");
7727 val ^= DF_P1_LAZYLOAD;
7728 }
7729 if (val & DF_P1_GROUPPERM)
7730 {
7731 printf (" GROUPPERM");
7732 val ^= DF_P1_GROUPPERM;
7733 }
7734 if (val != 0)
7735 printf (" %lx", val);
7736 puts ("");
7737 }
7738 }
7739 break;
7740
7741 case DT_FLAGS_1:
7742 if (do_dynamic)
7743 {
7744 printf (_("Flags:"));
7745 if (entry->d_un.d_val == 0)
7746 printf (_(" None\n"));
7747 else
7748 {
7749 unsigned long int val = entry->d_un.d_val;
86f55779 7750
252b5132
RH
7751 if (val & DF_1_NOW)
7752 {
7753 printf (" NOW");
7754 val ^= DF_1_NOW;
7755 }
7756 if (val & DF_1_GLOBAL)
7757 {
7758 printf (" GLOBAL");
7759 val ^= DF_1_GLOBAL;
7760 }
7761 if (val & DF_1_GROUP)
7762 {
7763 printf (" GROUP");
7764 val ^= DF_1_GROUP;
7765 }
7766 if (val & DF_1_NODELETE)
7767 {
7768 printf (" NODELETE");
7769 val ^= DF_1_NODELETE;
7770 }
7771 if (val & DF_1_LOADFLTR)
7772 {
7773 printf (" LOADFLTR");
7774 val ^= DF_1_LOADFLTR;
7775 }
7776 if (val & DF_1_INITFIRST)
7777 {
7778 printf (" INITFIRST");
7779 val ^= DF_1_INITFIRST;
7780 }
7781 if (val & DF_1_NOOPEN)
7782 {
7783 printf (" NOOPEN");
7784 val ^= DF_1_NOOPEN;
7785 }
7786 if (val & DF_1_ORIGIN)
7787 {
7788 printf (" ORIGIN");
7789 val ^= DF_1_ORIGIN;
7790 }
7791 if (val & DF_1_DIRECT)
7792 {
7793 printf (" DIRECT");
7794 val ^= DF_1_DIRECT;
7795 }
7796 if (val & DF_1_TRANS)
7797 {
7798 printf (" TRANS");
7799 val ^= DF_1_TRANS;
7800 }
7801 if (val & DF_1_INTERPOSE)
7802 {
7803 printf (" INTERPOSE");
7804 val ^= DF_1_INTERPOSE;
7805 }
f7db6139 7806 if (val & DF_1_NODEFLIB)
dcefbbbd 7807 {
f7db6139
L
7808 printf (" NODEFLIB");
7809 val ^= DF_1_NODEFLIB;
dcefbbbd
L
7810 }
7811 if (val & DF_1_NODUMP)
7812 {
7813 printf (" NODUMP");
7814 val ^= DF_1_NODUMP;
7815 }
7816 if (val & DF_1_CONLFAT)
7817 {
7818 printf (" CONLFAT");
7819 val ^= DF_1_CONLFAT;
7820 }
252b5132
RH
7821 if (val != 0)
7822 printf (" %lx", val);
7823 puts ("");
7824 }
7825 }
7826 break;
7827
7828 case DT_PLTREL:
566b0d53 7829 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7830 if (do_dynamic)
7831 puts (get_dynamic_type (entry->d_un.d_val));
7832 break;
7833
7834 case DT_NULL :
7835 case DT_NEEDED :
7836 case DT_PLTGOT :
7837 case DT_HASH :
7838 case DT_STRTAB :
7839 case DT_SYMTAB :
7840 case DT_RELA :
7841 case DT_INIT :
7842 case DT_FINI :
7843 case DT_SONAME :
7844 case DT_RPATH :
7845 case DT_SYMBOLIC:
7846 case DT_REL :
7847 case DT_DEBUG :
7848 case DT_TEXTREL :
7849 case DT_JMPREL :
019148e4 7850 case DT_RUNPATH :
252b5132
RH
7851 dynamic_info[entry->d_tag] = entry->d_un.d_val;
7852
7853 if (do_dynamic)
7854 {
2cf0635d 7855 char * name;
252b5132 7856
d79b3d50
NC
7857 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7858 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7859 else
d79b3d50 7860 name = NULL;
252b5132
RH
7861
7862 if (name)
7863 {
7864 switch (entry->d_tag)
7865 {
7866 case DT_NEEDED:
7867 printf (_("Shared library: [%s]"), name);
7868
18bd398b 7869 if (streq (name, program_interpreter))
f7a99963 7870 printf (_(" program interpreter"));
252b5132
RH
7871 break;
7872
7873 case DT_SONAME:
f7a99963 7874 printf (_("Library soname: [%s]"), name);
252b5132
RH
7875 break;
7876
7877 case DT_RPATH:
f7a99963 7878 printf (_("Library rpath: [%s]"), name);
252b5132
RH
7879 break;
7880
019148e4
L
7881 case DT_RUNPATH:
7882 printf (_("Library runpath: [%s]"), name);
7883 break;
7884
252b5132 7885 default:
f7a99963
NC
7886 print_vma (entry->d_un.d_val, PREFIX_HEX);
7887 break;
252b5132
RH
7888 }
7889 }
7890 else
f7a99963
NC
7891 print_vma (entry->d_un.d_val, PREFIX_HEX);
7892
7893 putchar ('\n');
252b5132
RH
7894 }
7895 break;
7896
7897 case DT_PLTRELSZ:
7898 case DT_RELASZ :
7899 case DT_STRSZ :
7900 case DT_RELSZ :
7901 case DT_RELAENT :
7902 case DT_SYMENT :
7903 case DT_RELENT :
566b0d53 7904 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7905 case DT_PLTPADSZ:
7906 case DT_MOVEENT :
7907 case DT_MOVESZ :
7908 case DT_INIT_ARRAYSZ:
7909 case DT_FINI_ARRAYSZ:
047b2264
JJ
7910 case DT_GNU_CONFLICTSZ:
7911 case DT_GNU_LIBLISTSZ:
252b5132 7912 if (do_dynamic)
f7a99963
NC
7913 {
7914 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 7915 printf (_(" (bytes)\n"));
f7a99963 7916 }
252b5132
RH
7917 break;
7918
7919 case DT_VERDEFNUM:
7920 case DT_VERNEEDNUM:
7921 case DT_RELACOUNT:
7922 case DT_RELCOUNT:
7923 if (do_dynamic)
f7a99963
NC
7924 {
7925 print_vma (entry->d_un.d_val, UNSIGNED);
7926 putchar ('\n');
7927 }
252b5132
RH
7928 break;
7929
7930 case DT_SYMINSZ:
7931 case DT_SYMINENT:
7932 case DT_SYMINFO:
7933 case DT_USED:
7934 case DT_INIT_ARRAY:
7935 case DT_FINI_ARRAY:
7936 if (do_dynamic)
7937 {
d79b3d50
NC
7938 if (entry->d_tag == DT_USED
7939 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 7940 {
2cf0635d 7941 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7942
b34976b6 7943 if (*name)
252b5132
RH
7944 {
7945 printf (_("Not needed object: [%s]\n"), name);
7946 break;
7947 }
7948 }
103f02d3 7949
f7a99963
NC
7950 print_vma (entry->d_un.d_val, PREFIX_HEX);
7951 putchar ('\n');
252b5132
RH
7952 }
7953 break;
7954
7955 case DT_BIND_NOW:
7956 /* The value of this entry is ignored. */
35b1837e
AM
7957 if (do_dynamic)
7958 putchar ('\n');
252b5132 7959 break;
103f02d3 7960
047b2264
JJ
7961 case DT_GNU_PRELINKED:
7962 if (do_dynamic)
7963 {
2cf0635d 7964 struct tm * tmp;
91d6fa6a 7965 time_t atime = entry->d_un.d_val;
047b2264 7966
91d6fa6a 7967 tmp = gmtime (&atime);
047b2264
JJ
7968 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
7969 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7970 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7971
7972 }
7973 break;
7974
fdc90cb4
JJ
7975 case DT_GNU_HASH:
7976 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
7977 if (do_dynamic)
7978 {
7979 print_vma (entry->d_un.d_val, PREFIX_HEX);
7980 putchar ('\n');
7981 }
7982 break;
7983
252b5132
RH
7984 default:
7985 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 7986 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
7987 entry->d_un.d_val;
7988
7989 if (do_dynamic)
7990 {
7991 switch (elf_header.e_machine)
7992 {
7993 case EM_MIPS:
4fe85591 7994 case EM_MIPS_RS3_LE:
b2d38a17 7995 dynamic_section_mips_val (entry);
252b5132 7996 break;
103f02d3 7997 case EM_PARISC:
b2d38a17 7998 dynamic_section_parisc_val (entry);
103f02d3 7999 break;
ecc51f48 8000 case EM_IA_64:
b2d38a17 8001 dynamic_section_ia64_val (entry);
ecc51f48 8002 break;
252b5132 8003 default:
f7a99963
NC
8004 print_vma (entry->d_un.d_val, PREFIX_HEX);
8005 putchar ('\n');
252b5132
RH
8006 }
8007 }
8008 break;
8009 }
8010 }
8011
8012 return 1;
8013}
8014
8015static char *
d3ba0551 8016get_ver_flags (unsigned int flags)
252b5132 8017{
b34976b6 8018 static char buff[32];
252b5132
RH
8019
8020 buff[0] = 0;
8021
8022 if (flags == 0)
8023 return _("none");
8024
8025 if (flags & VER_FLG_BASE)
8026 strcat (buff, "BASE ");
8027
8028 if (flags & VER_FLG_WEAK)
8029 {
8030 if (flags & VER_FLG_BASE)
8031 strcat (buff, "| ");
8032
8033 strcat (buff, "WEAK ");
8034 }
8035
44ec90b9
RO
8036 if (flags & VER_FLG_INFO)
8037 {
8038 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8039 strcat (buff, "| ");
8040
8041 strcat (buff, "INFO ");
8042 }
8043
8044 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8045 strcat (buff, _("| <unknown>"));
252b5132
RH
8046
8047 return buff;
8048}
8049
8050/* Display the contents of the version sections. */
98fb390a 8051
252b5132 8052static int
2cf0635d 8053process_version_sections (FILE * file)
252b5132 8054{
2cf0635d 8055 Elf_Internal_Shdr * section;
b34976b6
AM
8056 unsigned i;
8057 int found = 0;
252b5132
RH
8058
8059 if (! do_version)
8060 return 1;
8061
8062 for (i = 0, section = section_headers;
8063 i < elf_header.e_shnum;
b34976b6 8064 i++, section++)
252b5132
RH
8065 {
8066 switch (section->sh_type)
8067 {
8068 case SHT_GNU_verdef:
8069 {
2cf0635d 8070 Elf_External_Verdef * edefs;
b34976b6
AM
8071 unsigned int idx;
8072 unsigned int cnt;
2cf0635d 8073 char * endbuf;
252b5132
RH
8074
8075 found = 1;
8076
8077 printf
72de5009 8078 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8079 SECTION_NAME (section), section->sh_info);
8080
8081 printf (_(" Addr: 0x"));
8082 printf_vma (section->sh_addr);
72de5009 8083 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8084 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8085 section->sh_link < elf_header.e_shnum
8086 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8087 : _("<corrupt>"));
252b5132 8088
3f5e193b
NC
8089 edefs = (Elf_External_Verdef *)
8090 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8091 _("version definition section"));
a6e9f9df
AM
8092 if (!edefs)
8093 break;
59245841 8094 endbuf = (char *) edefs + section->sh_size;
252b5132 8095
b34976b6 8096 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8097 {
2cf0635d
NC
8098 char * vstart;
8099 Elf_External_Verdef * edef;
b34976b6 8100 Elf_Internal_Verdef ent;
2cf0635d 8101 Elf_External_Verdaux * eaux;
b34976b6
AM
8102 Elf_Internal_Verdaux aux;
8103 int j;
8104 int isum;
103f02d3 8105
dd24e3da
NC
8106 /* Check for negative or very large indicies. */
8107 if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
8108 break;
8109
252b5132 8110 vstart = ((char *) edefs) + idx;
54806181
AM
8111 if (vstart + sizeof (*edef) > endbuf)
8112 break;
252b5132
RH
8113
8114 edef = (Elf_External_Verdef *) vstart;
8115
8116 ent.vd_version = BYTE_GET (edef->vd_version);
8117 ent.vd_flags = BYTE_GET (edef->vd_flags);
8118 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8119 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8120 ent.vd_hash = BYTE_GET (edef->vd_hash);
8121 ent.vd_aux = BYTE_GET (edef->vd_aux);
8122 ent.vd_next = BYTE_GET (edef->vd_next);
8123
8124 printf (_(" %#06x: Rev: %d Flags: %s"),
8125 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8126
8127 printf (_(" Index: %d Cnt: %d "),
8128 ent.vd_ndx, ent.vd_cnt);
8129
dd24e3da
NC
8130 /* Check for overflow. */
8131 if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
8132 || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
8133 break;
8134
252b5132
RH
8135 vstart += ent.vd_aux;
8136
8137 eaux = (Elf_External_Verdaux *) vstart;
8138
8139 aux.vda_name = BYTE_GET (eaux->vda_name);
8140 aux.vda_next = BYTE_GET (eaux->vda_next);
8141
d79b3d50
NC
8142 if (VALID_DYNAMIC_NAME (aux.vda_name))
8143 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8144 else
8145 printf (_("Name index: %ld\n"), aux.vda_name);
8146
8147 isum = idx + ent.vd_aux;
8148
b34976b6 8149 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8150 {
dd24e3da
NC
8151 /* Check for overflow. */
8152 if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
8153 || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
8154 break;
8155
252b5132
RH
8156 isum += aux.vda_next;
8157 vstart += aux.vda_next;
8158
8159 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8160 if (vstart + sizeof (*eaux) > endbuf)
8161 break;
252b5132
RH
8162
8163 aux.vda_name = BYTE_GET (eaux->vda_name);
8164 aux.vda_next = BYTE_GET (eaux->vda_next);
8165
d79b3d50 8166 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8167 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8168 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8169 else
8170 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8171 isum, j, aux.vda_name);
8172 }
dd24e3da 8173
54806181
AM
8174 if (j < ent.vd_cnt)
8175 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8176
8177 idx += ent.vd_next;
8178 }
dd24e3da 8179
54806181
AM
8180 if (cnt < section->sh_info)
8181 printf (_(" Version definition past end of section\n"));
252b5132
RH
8182
8183 free (edefs);
8184 }
8185 break;
103f02d3 8186
252b5132
RH
8187 case SHT_GNU_verneed:
8188 {
2cf0635d 8189 Elf_External_Verneed * eneed;
b34976b6
AM
8190 unsigned int idx;
8191 unsigned int cnt;
2cf0635d 8192 char * endbuf;
252b5132
RH
8193
8194 found = 1;
8195
72de5009 8196 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8197 SECTION_NAME (section), section->sh_info);
8198
8199 printf (_(" Addr: 0x"));
8200 printf_vma (section->sh_addr);
72de5009 8201 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8202 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8203 section->sh_link < elf_header.e_shnum
8204 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8205 : _("<corrupt>"));
252b5132 8206
3f5e193b
NC
8207 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8208 section->sh_offset, 1,
8209 section->sh_size,
8210 _("version need section"));
a6e9f9df
AM
8211 if (!eneed)
8212 break;
59245841 8213 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8214
8215 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8216 {
2cf0635d 8217 Elf_External_Verneed * entry;
b34976b6
AM
8218 Elf_Internal_Verneed ent;
8219 int j;
8220 int isum;
2cf0635d 8221 char * vstart;
252b5132 8222
dd24e3da
NC
8223 if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
8224 break;
8225
252b5132 8226 vstart = ((char *) eneed) + idx;
54806181
AM
8227 if (vstart + sizeof (*entry) > endbuf)
8228 break;
252b5132
RH
8229
8230 entry = (Elf_External_Verneed *) vstart;
8231
8232 ent.vn_version = BYTE_GET (entry->vn_version);
8233 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8234 ent.vn_file = BYTE_GET (entry->vn_file);
8235 ent.vn_aux = BYTE_GET (entry->vn_aux);
8236 ent.vn_next = BYTE_GET (entry->vn_next);
8237
8238 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8239
d79b3d50
NC
8240 if (VALID_DYNAMIC_NAME (ent.vn_file))
8241 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8242 else
8243 printf (_(" File: %lx"), ent.vn_file);
8244
8245 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8246
dd24e3da
NC
8247 /* Check for overflow. */
8248 if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
8249 || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
8250 break;
8251
252b5132
RH
8252 vstart += ent.vn_aux;
8253
8254 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8255 {
2cf0635d 8256 Elf_External_Vernaux * eaux;
b34976b6 8257 Elf_Internal_Vernaux aux;
252b5132 8258
54806181
AM
8259 if (vstart + sizeof (*eaux) > endbuf)
8260 break;
252b5132
RH
8261 eaux = (Elf_External_Vernaux *) vstart;
8262
8263 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8264 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8265 aux.vna_other = BYTE_GET (eaux->vna_other);
8266 aux.vna_name = BYTE_GET (eaux->vna_name);
8267 aux.vna_next = BYTE_GET (eaux->vna_next);
8268
d79b3d50 8269 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8270 printf (_(" %#06x: Name: %s"),
d79b3d50 8271 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8272 else
ecc2063b 8273 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8274 isum, aux.vna_name);
8275
8276 printf (_(" Flags: %s Version: %d\n"),
8277 get_ver_flags (aux.vna_flags), aux.vna_other);
8278
dd24e3da
NC
8279 /* Check for overflow. */
8280 if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
8281 || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
8282 break;
8283
252b5132
RH
8284 isum += aux.vna_next;
8285 vstart += aux.vna_next;
8286 }
54806181
AM
8287 if (j < ent.vn_cnt)
8288 printf (_(" Version need aux past end of section\n"));
252b5132
RH
8289
8290 idx += ent.vn_next;
8291 }
54806181
AM
8292 if (cnt < section->sh_info)
8293 printf (_(" Version need past end of section\n"));
103f02d3 8294
252b5132
RH
8295 free (eneed);
8296 }
8297 break;
8298
8299 case SHT_GNU_versym:
8300 {
2cf0635d 8301 Elf_Internal_Shdr * link_section;
b34976b6
AM
8302 int total;
8303 int cnt;
2cf0635d
NC
8304 unsigned char * edata;
8305 unsigned short * data;
8306 char * strtab;
8307 Elf_Internal_Sym * symbols;
8308 Elf_Internal_Shdr * string_sec;
d3ba0551 8309 long off;
252b5132 8310
4fbb74a6 8311 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8312 break;
8313
4fbb74a6 8314 link_section = section_headers + section->sh_link;
08d8fa11 8315 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8316
4fbb74a6 8317 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8318 break;
8319
252b5132
RH
8320 found = 1;
8321
9ad5cbcf 8322 symbols = GET_ELF_SYMBOLS (file, link_section);
dd24e3da
NC
8323 if (symbols == NULL)
8324 break;
252b5132 8325
4fbb74a6 8326 string_sec = section_headers + link_section->sh_link;
252b5132 8327
3f5e193b
NC
8328 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8329 string_sec->sh_size,
8330 _("version string table"));
a6e9f9df 8331 if (!strtab)
0429c154
MS
8332 {
8333 free (symbols);
8334 break;
8335 }
252b5132
RH
8336
8337 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8338 SECTION_NAME (section), total);
8339
8340 printf (_(" Addr: "));
8341 printf_vma (section->sh_addr);
72de5009 8342 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8343 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8344 SECTION_NAME (link_section));
8345
d3ba0551
AM
8346 off = offset_from_vma (file,
8347 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8348 total * sizeof (short));
3f5e193b
NC
8349 edata = (unsigned char *) get_data (NULL, file, off, total,
8350 sizeof (short),
8351 _("version symbol data"));
a6e9f9df
AM
8352 if (!edata)
8353 {
8354 free (strtab);
0429c154 8355 free (symbols);
a6e9f9df
AM
8356 break;
8357 }
252b5132 8358
3f5e193b 8359 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8360
8361 for (cnt = total; cnt --;)
b34976b6
AM
8362 data[cnt] = byte_get (edata + cnt * sizeof (short),
8363 sizeof (short));
252b5132
RH
8364
8365 free (edata);
8366
8367 for (cnt = 0; cnt < total; cnt += 4)
8368 {
8369 int j, nn;
00d93f34 8370 int check_def, check_need;
2cf0635d 8371 char * name;
252b5132
RH
8372
8373 printf (" %03x:", cnt);
8374
8375 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8376 switch (data[cnt + j])
252b5132
RH
8377 {
8378 case 0:
8379 fputs (_(" 0 (*local*) "), stdout);
8380 break;
8381
8382 case 1:
8383 fputs (_(" 1 (*global*) "), stdout);
8384 break;
8385
8386 default:
c244d050
NC
8387 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8388 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8389
dd24e3da
NC
8390 /* If this index value is greater than the size of the symbols
8391 array, break to avoid an out-of-bounds read, */
8392 if ((unsigned long)(cnt + j) >=
8393 ((unsigned long)link_section->sh_size /
8394 (unsigned long)link_section->sh_entsize))
8395 {
8396 warn (_("invalid index into symbol array\n"));
8397 break;
8398 }
8399
00d93f34
JJ
8400 check_def = 1;
8401 check_need = 1;
4fbb74a6
AM
8402 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8403 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8404 != SHT_NOBITS)
252b5132 8405 {
b34976b6 8406 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8407 check_def = 0;
8408 else
8409 check_need = 0;
252b5132 8410 }
00d93f34
JJ
8411
8412 if (check_need
b34976b6 8413 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8414 {
b34976b6
AM
8415 Elf_Internal_Verneed ivn;
8416 unsigned long offset;
252b5132 8417
d93f0186
NC
8418 offset = offset_from_vma
8419 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8420 sizeof (Elf_External_Verneed));
252b5132 8421
b34976b6 8422 do
252b5132 8423 {
b34976b6
AM
8424 Elf_Internal_Vernaux ivna;
8425 Elf_External_Verneed evn;
8426 Elf_External_Vernaux evna;
8427 unsigned long a_off;
252b5132 8428
59245841
NC
8429 if (get_data (&evn, file, offset, sizeof (evn), 1,
8430 _("version need")) == NULL)
8431 break;
8432
252b5132
RH
8433 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8434 ivn.vn_next = BYTE_GET (evn.vn_next);
8435
8436 a_off = offset + ivn.vn_aux;
8437
8438 do
8439 {
59245841
NC
8440 if (get_data (&evna, file, a_off, sizeof (evna),
8441 1, _("version need aux (2)")) == NULL)
8442 {
8443 ivna.vna_next = 0;
8444 ivna.vna_other = 0;
8445 }
8446 else
8447 {
8448 ivna.vna_next = BYTE_GET (evna.vna_next);
8449 ivna.vna_other = BYTE_GET (evna.vna_other);
8450 }
252b5132
RH
8451
8452 a_off += ivna.vna_next;
8453 }
b34976b6 8454 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8455 && ivna.vna_next != 0);
8456
b34976b6 8457 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8458 {
8459 ivna.vna_name = BYTE_GET (evna.vna_name);
8460
54806181
AM
8461 if (ivna.vna_name >= string_sec->sh_size)
8462 name = _("*invalid*");
8463 else
8464 name = strtab + ivna.vna_name;
252b5132 8465 nn += printf ("(%s%-*s",
16062207
ILT
8466 name,
8467 12 - (int) strlen (name),
252b5132 8468 ")");
00d93f34 8469 check_def = 0;
252b5132
RH
8470 break;
8471 }
8472
8473 offset += ivn.vn_next;
8474 }
8475 while (ivn.vn_next);
8476 }
00d93f34 8477
b34976b6
AM
8478 if (check_def && data[cnt + j] != 0x8001
8479 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8480 {
b34976b6
AM
8481 Elf_Internal_Verdef ivd;
8482 Elf_External_Verdef evd;
8483 unsigned long offset;
252b5132 8484
d93f0186
NC
8485 offset = offset_from_vma
8486 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8487 sizeof evd);
252b5132
RH
8488
8489 do
8490 {
59245841
NC
8491 if (get_data (&evd, file, offset, sizeof (evd), 1,
8492 _("version def")) == NULL)
8493 {
8494 ivd.vd_next = 0;
8495 ivd.vd_ndx = 0;
8496 }
8497 else
8498 {
8499 ivd.vd_next = BYTE_GET (evd.vd_next);
8500 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8501 }
252b5132
RH
8502
8503 offset += ivd.vd_next;
8504 }
c244d050 8505 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8506 && ivd.vd_next != 0);
8507
c244d050 8508 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8509 {
b34976b6
AM
8510 Elf_External_Verdaux evda;
8511 Elf_Internal_Verdaux ivda;
252b5132
RH
8512
8513 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8514
59245841
NC
8515 if (get_data (&evda, file,
8516 offset - ivd.vd_next + ivd.vd_aux,
8517 sizeof (evda), 1,
8518 _("version def aux")) == NULL)
8519 break;
252b5132
RH
8520
8521 ivda.vda_name = BYTE_GET (evda.vda_name);
8522
54806181
AM
8523 if (ivda.vda_name >= string_sec->sh_size)
8524 name = _("*invalid*");
8525 else
8526 name = strtab + ivda.vda_name;
252b5132 8527 nn += printf ("(%s%-*s",
16062207
ILT
8528 name,
8529 12 - (int) strlen (name),
252b5132
RH
8530 ")");
8531 }
8532 }
8533
8534 if (nn < 18)
8535 printf ("%*c", 18 - nn, ' ');
8536 }
8537
8538 putchar ('\n');
8539 }
8540
8541 free (data);
8542 free (strtab);
8543 free (symbols);
8544 }
8545 break;
103f02d3 8546
252b5132
RH
8547 default:
8548 break;
8549 }
8550 }
8551
8552 if (! found)
8553 printf (_("\nNo version information found in this file.\n"));
8554
8555 return 1;
8556}
8557
d1133906 8558static const char *
d3ba0551 8559get_symbol_binding (unsigned int binding)
252b5132 8560{
b34976b6 8561 static char buff[32];
252b5132
RH
8562
8563 switch (binding)
8564 {
b34976b6
AM
8565 case STB_LOCAL: return "LOCAL";
8566 case STB_GLOBAL: return "GLOBAL";
8567 case STB_WEAK: return "WEAK";
252b5132
RH
8568 default:
8569 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8570 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8571 binding);
252b5132 8572 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8573 {
8574 if (binding == STB_GNU_UNIQUE
8575 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
8576 /* GNU/Linux is still using the default value 0. */
8577 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8578 return "UNIQUE";
8579 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8580 }
252b5132 8581 else
e9e44622 8582 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8583 return buff;
8584 }
8585}
8586
d1133906 8587static const char *
d3ba0551 8588get_symbol_type (unsigned int type)
252b5132 8589{
b34976b6 8590 static char buff[32];
252b5132
RH
8591
8592 switch (type)
8593 {
b34976b6
AM
8594 case STT_NOTYPE: return "NOTYPE";
8595 case STT_OBJECT: return "OBJECT";
8596 case STT_FUNC: return "FUNC";
8597 case STT_SECTION: return "SECTION";
8598 case STT_FILE: return "FILE";
8599 case STT_COMMON: return "COMMON";
8600 case STT_TLS: return "TLS";
15ab5209
DB
8601 case STT_RELC: return "RELC";
8602 case STT_SRELC: return "SRELC";
252b5132
RH
8603 default:
8604 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8605 {
8606 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8607 return "THUMB_FUNC";
8608
351b4b40 8609 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8610 return "REGISTER";
8611
8612 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8613 return "PARISC_MILLI";
8614
e9e44622 8615 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8616 }
252b5132 8617 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8618 {
8619 if (elf_header.e_machine == EM_PARISC)
8620 {
8621 if (type == STT_HP_OPAQUE)
8622 return "HP_OPAQUE";
8623 if (type == STT_HP_STUB)
8624 return "HP_STUB";
8625 }
8626
d8045f23
NC
8627 if (type == STT_GNU_IFUNC
8628 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
8629 /* GNU/Linux is still using the default value 0. */
8630 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8631 return "IFUNC";
8632
e9e44622 8633 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8634 }
252b5132 8635 else
e9e44622 8636 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8637 return buff;
8638 }
8639}
8640
d1133906 8641static const char *
d3ba0551 8642get_symbol_visibility (unsigned int visibility)
d1133906
NC
8643{
8644 switch (visibility)
8645 {
b34976b6
AM
8646 case STV_DEFAULT: return "DEFAULT";
8647 case STV_INTERNAL: return "INTERNAL";
8648 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
8649 case STV_PROTECTED: return "PROTECTED";
8650 default: abort ();
8651 }
8652}
8653
5e2b0d47
NC
8654static const char *
8655get_mips_symbol_other (unsigned int other)
8656{
8657 switch (other)
8658 {
8659 case STO_OPTIONAL: return "OPTIONAL";
8660 case STO_MIPS16: return "MIPS16";
861fb55a
DJ
8661 case STO_MIPS_PLT: return "MIPS PLT";
8662 case STO_MIPS_PIC: return "MIPS PIC";
5e2b0d47
NC
8663 default: return NULL;
8664 }
8665}
8666
28f997cf
TG
8667static const char *
8668get_ia64_symbol_other (unsigned int other)
8669{
8670 if (is_ia64_vms ())
8671 {
8672 static char res[32];
8673
8674 res[0] = 0;
8675
8676 /* Function types is for images and .STB files only. */
8677 switch (elf_header.e_type)
8678 {
8679 case ET_DYN:
8680 case ET_EXEC:
8681 switch (VMS_ST_FUNC_TYPE (other))
8682 {
8683 case VMS_SFT_CODE_ADDR:
8684 strcat (res, " CA");
8685 break;
8686 case VMS_SFT_SYMV_IDX:
8687 strcat (res, " VEC");
8688 break;
8689 case VMS_SFT_FD:
8690 strcat (res, " FD");
8691 break;
8692 case VMS_SFT_RESERVE:
8693 strcat (res, " RSV");
8694 break;
8695 default:
8696 abort ();
8697 }
8698 break;
8699 default:
8700 break;
8701 }
8702 switch (VMS_ST_LINKAGE (other))
8703 {
8704 case VMS_STL_IGNORE:
8705 strcat (res, " IGN");
8706 break;
8707 case VMS_STL_RESERVE:
8708 strcat (res, " RSV");
8709 break;
8710 case VMS_STL_STD:
8711 strcat (res, " STD");
8712 break;
8713 case VMS_STL_LNK:
8714 strcat (res, " LNK");
8715 break;
8716 default:
8717 abort ();
8718 }
8719
8720 if (res[0] != 0)
8721 return res + 1;
8722 else
8723 return res;
8724 }
8725 return NULL;
8726}
8727
5e2b0d47
NC
8728static const char *
8729get_symbol_other (unsigned int other)
8730{
8731 const char * result = NULL;
8732 static char buff [32];
8733
8734 if (other == 0)
8735 return "";
8736
8737 switch (elf_header.e_machine)
8738 {
8739 case EM_MIPS:
8740 result = get_mips_symbol_other (other);
28f997cf
TG
8741 break;
8742 case EM_IA_64:
8743 result = get_ia64_symbol_other (other);
8744 break;
5e2b0d47
NC
8745 default:
8746 break;
8747 }
8748
8749 if (result)
8750 return result;
8751
8752 snprintf (buff, sizeof buff, _("<other>: %x"), other);
8753 return buff;
8754}
8755
d1133906 8756static const char *
d3ba0551 8757get_symbol_index_type (unsigned int type)
252b5132 8758{
b34976b6 8759 static char buff[32];
5cf1065c 8760
252b5132
RH
8761 switch (type)
8762 {
b34976b6
AM
8763 case SHN_UNDEF: return "UND";
8764 case SHN_ABS: return "ABS";
8765 case SHN_COMMON: return "COM";
252b5132 8766 default:
9ce701e2
L
8767 if (type == SHN_IA_64_ANSI_COMMON
8768 && elf_header.e_machine == EM_IA_64
8769 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
8770 return "ANSI_COM";
8a9036a4
L
8771 else if ((elf_header.e_machine == EM_X86_64
8772 || elf_header.e_machine == EM_L1OM)
3b22753a
L
8773 && type == SHN_X86_64_LCOMMON)
8774 return "LARGE_COM";
ac145307
BS
8775 else if ((type == SHN_MIPS_SCOMMON
8776 && elf_header.e_machine == EM_MIPS)
8777 || (type == SHN_TIC6X_SCOMMON
8778 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
8779 return "SCOM";
8780 else if (type == SHN_MIPS_SUNDEFINED
8781 && elf_header.e_machine == EM_MIPS)
8782 return "SUND";
9ce701e2 8783 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 8784 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 8785 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
8786 sprintf (buff, "OS [0x%04x]", type & 0xffff);
8787 else if (type >= SHN_LORESERVE)
8788 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 8789 else
232e7cb8 8790 sprintf (buff, "%3d", type);
5cf1065c 8791 break;
252b5132 8792 }
5cf1065c
NC
8793
8794 return buff;
252b5132
RH
8795}
8796
66543521 8797static bfd_vma *
2cf0635d 8798get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 8799{
2cf0635d
NC
8800 unsigned char * e_data;
8801 bfd_vma * i_data;
252b5132 8802
3f5e193b 8803 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
8804
8805 if (e_data == NULL)
8806 {
8807 error (_("Out of memory\n"));
8808 return NULL;
8809 }
8810
66543521 8811 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
8812 {
8813 error (_("Unable to read in dynamic data\n"));
8814 return NULL;
8815 }
8816
3f5e193b 8817 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
8818
8819 if (i_data == NULL)
8820 {
8821 error (_("Out of memory\n"));
8822 free (e_data);
8823 return NULL;
8824 }
8825
8826 while (number--)
66543521 8827 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
8828
8829 free (e_data);
8830
8831 return i_data;
8832}
8833
6bd1a22c
L
8834static void
8835print_dynamic_symbol (bfd_vma si, unsigned long hn)
8836{
2cf0635d 8837 Elf_Internal_Sym * psym;
6bd1a22c
L
8838 int n;
8839
8840 psym = dynamic_symbols + si;
8841
8842 n = print_vma (si, DEC_5);
8843 if (n < 5)
8844 fputs (" " + n, stdout);
8845 printf (" %3lu: ", hn);
8846 print_vma (psym->st_value, LONG_HEX);
8847 putchar (' ');
8848 print_vma (psym->st_size, DEC_5);
8849
f4be36b3
AM
8850 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8851 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
8852 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
8853 /* Check to see if any other bits in the st_other field are set.
8854 Note - displaying this information disrupts the layout of the
8855 table being generated, but for the moment this case is very
8856 rare. */
8857 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8858 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
8859 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
8860 if (VALID_DYNAMIC_NAME (psym->st_name))
8861 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
8862 else
2b692964 8863 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
8864 putchar ('\n');
8865}
8866
e3c8793a 8867/* Dump the symbol table. */
252b5132 8868static int
2cf0635d 8869process_symbol_table (FILE * file)
252b5132 8870{
2cf0635d 8871 Elf_Internal_Shdr * section;
66543521
AM
8872 bfd_vma nbuckets = 0;
8873 bfd_vma nchains = 0;
2cf0635d
NC
8874 bfd_vma * buckets = NULL;
8875 bfd_vma * chains = NULL;
fdc90cb4 8876 bfd_vma ngnubuckets = 0;
2cf0635d
NC
8877 bfd_vma * gnubuckets = NULL;
8878 bfd_vma * gnuchains = NULL;
6bd1a22c 8879 bfd_vma gnusymidx = 0;
252b5132 8880
2c610e4b 8881 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
8882 return 1;
8883
6bd1a22c
L
8884 if (dynamic_info[DT_HASH]
8885 && (do_histogram
2c610e4b
L
8886 || (do_using_dynamic
8887 && !do_dyn_syms
8888 && dynamic_strings != NULL)))
252b5132 8889 {
66543521
AM
8890 unsigned char nb[8];
8891 unsigned char nc[8];
8892 int hash_ent_size = 4;
8893
8894 if ((elf_header.e_machine == EM_ALPHA
8895 || elf_header.e_machine == EM_S390
8896 || elf_header.e_machine == EM_S390_OLD)
8897 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
8898 hash_ent_size = 8;
8899
fb52b2f4
NC
8900 if (fseek (file,
8901 (archive_file_offset
8902 + offset_from_vma (file, dynamic_info[DT_HASH],
8903 sizeof nb + sizeof nc)),
d93f0186 8904 SEEK_SET))
252b5132 8905 {
591a748a 8906 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8907 goto no_hash;
252b5132
RH
8908 }
8909
66543521 8910 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
8911 {
8912 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8913 goto no_hash;
252b5132
RH
8914 }
8915
66543521 8916 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
8917 {
8918 error (_("Failed to read in number of chains\n"));
d3a44ec6 8919 goto no_hash;
252b5132
RH
8920 }
8921
66543521
AM
8922 nbuckets = byte_get (nb, hash_ent_size);
8923 nchains = byte_get (nc, hash_ent_size);
252b5132 8924
66543521
AM
8925 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
8926 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 8927
d3a44ec6 8928 no_hash:
252b5132 8929 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
8930 {
8931 if (do_using_dynamic)
8932 return 0;
8933 free (buckets);
8934 free (chains);
8935 buckets = NULL;
8936 chains = NULL;
8937 nbuckets = 0;
8938 nchains = 0;
8939 }
252b5132
RH
8940 }
8941
6bd1a22c
L
8942 if (dynamic_info_DT_GNU_HASH
8943 && (do_histogram
2c610e4b
L
8944 || (do_using_dynamic
8945 && !do_dyn_syms
8946 && dynamic_strings != NULL)))
252b5132 8947 {
6bd1a22c
L
8948 unsigned char nb[16];
8949 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
8950 bfd_vma buckets_vma;
8951
8952 if (fseek (file,
8953 (archive_file_offset
8954 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
8955 sizeof nb)),
8956 SEEK_SET))
8957 {
8958 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8959 goto no_gnu_hash;
6bd1a22c 8960 }
252b5132 8961
6bd1a22c
L
8962 if (fread (nb, 16, 1, file) != 1)
8963 {
8964 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8965 goto no_gnu_hash;
6bd1a22c
L
8966 }
8967
8968 ngnubuckets = byte_get (nb, 4);
8969 gnusymidx = byte_get (nb + 4, 4);
8970 bitmaskwords = byte_get (nb + 8, 4);
8971 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 8972 if (is_32bit_elf)
6bd1a22c 8973 buckets_vma += bitmaskwords * 4;
f7a99963 8974 else
6bd1a22c 8975 buckets_vma += bitmaskwords * 8;
252b5132 8976
6bd1a22c
L
8977 if (fseek (file,
8978 (archive_file_offset
8979 + offset_from_vma (file, buckets_vma, 4)),
8980 SEEK_SET))
252b5132 8981 {
6bd1a22c 8982 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8983 goto no_gnu_hash;
6bd1a22c
L
8984 }
8985
8986 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 8987
6bd1a22c 8988 if (gnubuckets == NULL)
d3a44ec6 8989 goto no_gnu_hash;
6bd1a22c
L
8990
8991 for (i = 0; i < ngnubuckets; i++)
8992 if (gnubuckets[i] != 0)
8993 {
8994 if (gnubuckets[i] < gnusymidx)
8995 return 0;
8996
8997 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
8998 maxchain = gnubuckets[i];
8999 }
9000
9001 if (maxchain == 0xffffffff)
d3a44ec6 9002 goto no_gnu_hash;
6bd1a22c
L
9003
9004 maxchain -= gnusymidx;
9005
9006 if (fseek (file,
9007 (archive_file_offset
9008 + offset_from_vma (file, buckets_vma
9009 + 4 * (ngnubuckets + maxchain), 4)),
9010 SEEK_SET))
9011 {
9012 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9013 goto no_gnu_hash;
6bd1a22c
L
9014 }
9015
9016 do
9017 {
9018 if (fread (nb, 4, 1, file) != 1)
252b5132 9019 {
6bd1a22c 9020 error (_("Failed to determine last chain length\n"));
d3a44ec6 9021 goto no_gnu_hash;
6bd1a22c 9022 }
252b5132 9023
6bd1a22c 9024 if (maxchain + 1 == 0)
d3a44ec6 9025 goto no_gnu_hash;
252b5132 9026
6bd1a22c
L
9027 ++maxchain;
9028 }
9029 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9030
6bd1a22c
L
9031 if (fseek (file,
9032 (archive_file_offset
9033 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9034 SEEK_SET))
9035 {
9036 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9037 goto no_gnu_hash;
6bd1a22c
L
9038 }
9039
9040 gnuchains = get_dynamic_data (file, maxchain, 4);
9041
d3a44ec6 9042 no_gnu_hash:
6bd1a22c 9043 if (gnuchains == NULL)
d3a44ec6
JJ
9044 {
9045 free (gnubuckets);
d3a44ec6
JJ
9046 gnubuckets = NULL;
9047 ngnubuckets = 0;
f64fddf1
NC
9048 if (do_using_dynamic)
9049 return 0;
d3a44ec6 9050 }
6bd1a22c
L
9051 }
9052
9053 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9054 && do_syms
9055 && do_using_dynamic
9056 && dynamic_strings != NULL)
9057 {
9058 unsigned long hn;
9059
9060 if (dynamic_info[DT_HASH])
9061 {
9062 bfd_vma si;
9063
9064 printf (_("\nSymbol table for image:\n"));
9065 if (is_32bit_elf)
9066 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9067 else
9068 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9069
9070 for (hn = 0; hn < nbuckets; hn++)
9071 {
9072 if (! buckets[hn])
9073 continue;
9074
9075 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9076 print_dynamic_symbol (si, hn);
252b5132
RH
9077 }
9078 }
6bd1a22c
L
9079
9080 if (dynamic_info_DT_GNU_HASH)
9081 {
9082 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9083 if (is_32bit_elf)
9084 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9085 else
9086 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9087
9088 for (hn = 0; hn < ngnubuckets; ++hn)
9089 if (gnubuckets[hn] != 0)
9090 {
9091 bfd_vma si = gnubuckets[hn];
9092 bfd_vma off = si - gnusymidx;
9093
9094 do
9095 {
9096 print_dynamic_symbol (si, hn);
9097 si++;
9098 }
9099 while ((gnuchains[off++] & 1) == 0);
9100 }
9101 }
252b5132 9102 }
2c610e4b 9103 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9104 {
b34976b6 9105 unsigned int i;
252b5132
RH
9106
9107 for (i = 0, section = section_headers;
9108 i < elf_header.e_shnum;
9109 i++, section++)
9110 {
b34976b6 9111 unsigned int si;
2cf0635d 9112 char * strtab = NULL;
c256ffe7 9113 unsigned long int strtab_size = 0;
2cf0635d
NC
9114 Elf_Internal_Sym * symtab;
9115 Elf_Internal_Sym * psym;
252b5132 9116
2c610e4b
L
9117 if ((section->sh_type != SHT_SYMTAB
9118 && section->sh_type != SHT_DYNSYM)
9119 || (!do_syms
9120 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9121 continue;
9122
dd24e3da
NC
9123 if (section->sh_entsize == 0)
9124 {
9125 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9126 SECTION_NAME (section));
9127 continue;
9128 }
9129
252b5132
RH
9130 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9131 SECTION_NAME (section),
9132 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9133
f7a99963 9134 if (is_32bit_elf)
ca47b30c 9135 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9136 else
ca47b30c 9137 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9138
9ad5cbcf 9139 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
9140 if (symtab == NULL)
9141 continue;
9142
9143 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9144 {
9145 strtab = string_table;
9146 strtab_size = string_table_length;
9147 }
4fbb74a6 9148 else if (section->sh_link < elf_header.e_shnum)
252b5132 9149 {
2cf0635d 9150 Elf_Internal_Shdr * string_sec;
252b5132 9151
4fbb74a6 9152 string_sec = section_headers + section->sh_link;
252b5132 9153
3f5e193b
NC
9154 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9155 1, string_sec->sh_size,
9156 _("string table"));
c256ffe7 9157 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9158 }
9159
9160 for (si = 0, psym = symtab;
9161 si < section->sh_size / section->sh_entsize;
b34976b6 9162 si++, psym++)
252b5132 9163 {
5e220199 9164 printf ("%6d: ", si);
f7a99963
NC
9165 print_vma (psym->st_value, LONG_HEX);
9166 putchar (' ');
9167 print_vma (psym->st_size, DEC_5);
d1133906
NC
9168 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9169 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9170 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9171 /* Check to see if any other bits in the st_other field are set.
9172 Note - displaying this information disrupts the layout of the
9173 table being generated, but for the moment this case is very rare. */
9174 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9175 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9176 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9177 print_symbol (25, psym->st_name < strtab_size
2b692964 9178 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9179
59245841
NC
9180 if (section->sh_type == SHT_DYNSYM
9181 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9182 {
b34976b6
AM
9183 unsigned char data[2];
9184 unsigned short vers_data;
9185 unsigned long offset;
9186 int is_nobits;
9187 int check_def;
252b5132 9188
d93f0186
NC
9189 offset = offset_from_vma
9190 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9191 sizeof data + si * sizeof (vers_data));
252b5132 9192
59245841
NC
9193 if (get_data (&data, file, offset + si * sizeof (vers_data),
9194 sizeof (data), 1, _("version data")) == NULL)
9195 break;
252b5132
RH
9196
9197 vers_data = byte_get (data, 2);
9198
4fbb74a6
AM
9199 is_nobits = (psym->st_shndx < elf_header.e_shnum
9200 && section_headers[psym->st_shndx].sh_type
c256ffe7 9201 == SHT_NOBITS);
252b5132
RH
9202
9203 check_def = (psym->st_shndx != SHN_UNDEF);
9204
c244d050 9205 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9206 {
b34976b6 9207 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9208 && (is_nobits || ! check_def))
252b5132 9209 {
b34976b6
AM
9210 Elf_External_Verneed evn;
9211 Elf_Internal_Verneed ivn;
9212 Elf_Internal_Vernaux ivna;
252b5132
RH
9213
9214 /* We must test both. */
d93f0186
NC
9215 offset = offset_from_vma
9216 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9217 sizeof evn);
252b5132 9218
252b5132
RH
9219 do
9220 {
b34976b6 9221 unsigned long vna_off;
252b5132 9222
59245841
NC
9223 if (get_data (&evn, file, offset, sizeof (evn), 1,
9224 _("version need")) == NULL)
9225 {
9226 ivna.vna_next = 0;
9227 ivna.vna_other = 0;
9228 ivna.vna_name = 0;
9229 break;
9230 }
dd27201e
L
9231
9232 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9233 ivn.vn_next = BYTE_GET (evn.vn_next);
9234
252b5132
RH
9235 vna_off = offset + ivn.vn_aux;
9236
9237 do
9238 {
b34976b6 9239 Elf_External_Vernaux evna;
252b5132 9240
59245841
NC
9241 if (get_data (&evna, file, vna_off,
9242 sizeof (evna), 1,
9243 _("version need aux (3)")) == NULL)
9244 {
9245 ivna.vna_next = 0;
9246 ivna.vna_other = 0;
9247 ivna.vna_name = 0;
9248 }
9249 else
9250 {
9251 ivna.vna_other = BYTE_GET (evna.vna_other);
9252 ivna.vna_next = BYTE_GET (evna.vna_next);
9253 ivna.vna_name = BYTE_GET (evna.vna_name);
9254 }
252b5132
RH
9255
9256 vna_off += ivna.vna_next;
9257 }
9258 while (ivna.vna_other != vers_data
9259 && ivna.vna_next != 0);
9260
9261 if (ivna.vna_other == vers_data)
9262 break;
9263
9264 offset += ivn.vn_next;
9265 }
9266 while (ivn.vn_next != 0);
9267
9268 if (ivna.vna_other == vers_data)
9269 {
9270 printf ("@%s (%d)",
c256ffe7 9271 ivna.vna_name < strtab_size
2b692964 9272 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9273 ivna.vna_other);
252b5132
RH
9274 check_def = 0;
9275 }
9276 else if (! is_nobits)
591a748a 9277 error (_("bad dynamic symbol\n"));
252b5132
RH
9278 else
9279 check_def = 1;
9280 }
9281
9282 if (check_def)
9283 {
00d93f34 9284 if (vers_data != 0x8001
b34976b6 9285 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9286 {
b34976b6
AM
9287 Elf_Internal_Verdef ivd;
9288 Elf_Internal_Verdaux ivda;
9289 Elf_External_Verdaux evda;
91d6fa6a 9290 unsigned long off;
252b5132 9291
91d6fa6a 9292 off = offset_from_vma
d93f0186
NC
9293 (file,
9294 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9295 sizeof (Elf_External_Verdef));
252b5132
RH
9296
9297 do
9298 {
b34976b6 9299 Elf_External_Verdef evd;
252b5132 9300
59245841
NC
9301 if (get_data (&evd, file, off, sizeof (evd),
9302 1, _("version def")) == NULL)
9303 {
9304 ivd.vd_ndx = 0;
9305 ivd.vd_aux = 0;
9306 ivd.vd_next = 0;
9307 }
9308 else
9309 {
9310 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9311 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9312 ivd.vd_next = BYTE_GET (evd.vd_next);
9313 }
252b5132 9314
91d6fa6a 9315 off += ivd.vd_next;
252b5132 9316 }
c244d050 9317 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9318 && ivd.vd_next != 0);
9319
91d6fa6a
NC
9320 off -= ivd.vd_next;
9321 off += ivd.vd_aux;
252b5132 9322
59245841
NC
9323 if (get_data (&evda, file, off, sizeof (evda),
9324 1, _("version def aux")) == NULL)
9325 break;
252b5132
RH
9326
9327 ivda.vda_name = BYTE_GET (evda.vda_name);
9328
9329 if (psym->st_name != ivda.vda_name)
c244d050 9330 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9331 ? "@%s" : "@@%s",
c256ffe7 9332 ivda.vda_name < strtab_size
2b692964 9333 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9334 }
9335 }
9336 }
9337 }
9338
9339 putchar ('\n');
9340 }
9341
9342 free (symtab);
9343 if (strtab != string_table)
9344 free (strtab);
9345 }
9346 }
9347 else if (do_syms)
9348 printf
9349 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9350
9351 if (do_histogram && buckets != NULL)
9352 {
2cf0635d
NC
9353 unsigned long * lengths;
9354 unsigned long * counts;
66543521
AM
9355 unsigned long hn;
9356 bfd_vma si;
9357 unsigned long maxlength = 0;
9358 unsigned long nzero_counts = 0;
9359 unsigned long nsyms = 0;
252b5132 9360
66543521
AM
9361 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9362 (unsigned long) nbuckets);
252b5132
RH
9363 printf (_(" Length Number %% of total Coverage\n"));
9364
3f5e193b 9365 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9366 if (lengths == NULL)
9367 {
591a748a 9368 error (_("Out of memory\n"));
252b5132
RH
9369 return 0;
9370 }
9371 for (hn = 0; hn < nbuckets; ++hn)
9372 {
f7a99963 9373 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9374 {
b34976b6 9375 ++nsyms;
252b5132 9376 if (maxlength < ++lengths[hn])
b34976b6 9377 ++maxlength;
252b5132
RH
9378 }
9379 }
9380
3f5e193b 9381 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9382 if (counts == NULL)
9383 {
591a748a 9384 error (_("Out of memory\n"));
252b5132
RH
9385 return 0;
9386 }
9387
9388 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9389 ++counts[lengths[hn]];
252b5132 9390
103f02d3 9391 if (nbuckets > 0)
252b5132 9392 {
66543521
AM
9393 unsigned long i;
9394 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9395 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9396 for (i = 1; i <= maxlength; ++i)
103f02d3 9397 {
66543521
AM
9398 nzero_counts += counts[i] * i;
9399 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9400 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9401 (nzero_counts * 100.0) / nsyms);
9402 }
252b5132
RH
9403 }
9404
9405 free (counts);
9406 free (lengths);
9407 }
9408
9409 if (buckets != NULL)
9410 {
9411 free (buckets);
9412 free (chains);
9413 }
9414
d3a44ec6 9415 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9416 {
2cf0635d
NC
9417 unsigned long * lengths;
9418 unsigned long * counts;
fdc90cb4
JJ
9419 unsigned long hn;
9420 unsigned long maxlength = 0;
9421 unsigned long nzero_counts = 0;
9422 unsigned long nsyms = 0;
fdc90cb4 9423
3f5e193b 9424 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9425 if (lengths == NULL)
9426 {
591a748a 9427 error (_("Out of memory\n"));
fdc90cb4
JJ
9428 return 0;
9429 }
9430
9431 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9432 (unsigned long) ngnubuckets);
9433 printf (_(" Length Number %% of total Coverage\n"));
9434
9435 for (hn = 0; hn < ngnubuckets; ++hn)
9436 if (gnubuckets[hn] != 0)
9437 {
9438 bfd_vma off, length = 1;
9439
6bd1a22c 9440 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9441 (gnuchains[off] & 1) == 0; ++off)
9442 ++length;
9443 lengths[hn] = length;
9444 if (length > maxlength)
9445 maxlength = length;
9446 nsyms += length;
9447 }
9448
3f5e193b 9449 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9450 if (counts == NULL)
9451 {
591a748a 9452 error (_("Out of memory\n"));
fdc90cb4
JJ
9453 return 0;
9454 }
9455
9456 for (hn = 0; hn < ngnubuckets; ++hn)
9457 ++counts[lengths[hn]];
9458
9459 if (ngnubuckets > 0)
9460 {
9461 unsigned long j;
9462 printf (" 0 %-10lu (%5.1f%%)\n",
9463 counts[0], (counts[0] * 100.0) / ngnubuckets);
9464 for (j = 1; j <= maxlength; ++j)
9465 {
9466 nzero_counts += counts[j] * j;
9467 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9468 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9469 (nzero_counts * 100.0) / nsyms);
9470 }
9471 }
9472
9473 free (counts);
9474 free (lengths);
9475 free (gnubuckets);
9476 free (gnuchains);
9477 }
9478
252b5132
RH
9479 return 1;
9480}
9481
9482static int
2cf0635d 9483process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9484{
b4c96d0d 9485 unsigned int i;
252b5132
RH
9486
9487 if (dynamic_syminfo == NULL
9488 || !do_dynamic)
9489 /* No syminfo, this is ok. */
9490 return 1;
9491
9492 /* There better should be a dynamic symbol section. */
9493 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9494 return 0;
9495
9496 if (dynamic_addr)
9497 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9498 dynamic_syminfo_offset, dynamic_syminfo_nent);
9499
9500 printf (_(" Num: Name BoundTo Flags\n"));
9501 for (i = 0; i < dynamic_syminfo_nent; ++i)
9502 {
9503 unsigned short int flags = dynamic_syminfo[i].si_flags;
9504
31104126 9505 printf ("%4d: ", i);
d79b3d50
NC
9506 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9507 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9508 else
2b692964 9509 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9510 putchar (' ');
252b5132
RH
9511
9512 switch (dynamic_syminfo[i].si_boundto)
9513 {
9514 case SYMINFO_BT_SELF:
9515 fputs ("SELF ", stdout);
9516 break;
9517 case SYMINFO_BT_PARENT:
9518 fputs ("PARENT ", stdout);
9519 break;
9520 default:
9521 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9522 && dynamic_syminfo[i].si_boundto < dynamic_nent
9523 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9524 {
d79b3d50 9525 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9526 putchar (' ' );
9527 }
252b5132
RH
9528 else
9529 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9530 break;
9531 }
9532
9533 if (flags & SYMINFO_FLG_DIRECT)
9534 printf (" DIRECT");
9535 if (flags & SYMINFO_FLG_PASSTHRU)
9536 printf (" PASSTHRU");
9537 if (flags & SYMINFO_FLG_COPY)
9538 printf (" COPY");
9539 if (flags & SYMINFO_FLG_LAZYLOAD)
9540 printf (" LAZYLOAD");
9541
9542 puts ("");
9543 }
9544
9545 return 1;
9546}
9547
cf13d699
NC
9548/* Check to see if the given reloc needs to be handled in a target specific
9549 manner. If so then process the reloc and return TRUE otherwise return
9550 FALSE. */
09c11c86 9551
cf13d699
NC
9552static bfd_boolean
9553target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9554 unsigned char * start,
9555 Elf_Internal_Sym * symtab)
252b5132 9556{
cf13d699 9557 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9558
cf13d699 9559 switch (elf_header.e_machine)
252b5132 9560 {
cf13d699
NC
9561 case EM_MN10300:
9562 case EM_CYGNUS_MN10300:
9563 {
9564 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9565
cf13d699
NC
9566 switch (reloc_type)
9567 {
9568 case 34: /* R_MN10300_ALIGN */
9569 return TRUE;
9570 case 33: /* R_MN10300_SYM_DIFF */
9571 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9572 return TRUE;
9573 case 1: /* R_MN10300_32 */
9574 case 2: /* R_MN10300_16 */
9575 if (saved_sym != NULL)
9576 {
9577 bfd_vma value;
252b5132 9578
cf13d699
NC
9579 value = reloc->r_addend
9580 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9581 - saved_sym->st_value);
252b5132 9582
cf13d699 9583 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9584
cf13d699
NC
9585 saved_sym = NULL;
9586 return TRUE;
9587 }
9588 break;
9589 default:
9590 if (saved_sym != NULL)
9591 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9592 break;
9593 }
9594 break;
9595 }
252b5132
RH
9596 }
9597
cf13d699 9598 return FALSE;
252b5132
RH
9599}
9600
aca88567
NC
9601/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9602 DWARF debug sections. This is a target specific test. Note - we do not
9603 go through the whole including-target-headers-multiple-times route, (as
9604 we have already done with <elf/h8.h>) because this would become very
9605 messy and even then this function would have to contain target specific
9606 information (the names of the relocs instead of their numeric values).
9607 FIXME: This is not the correct way to solve this problem. The proper way
9608 is to have target specific reloc sizing and typing functions created by
9609 the reloc-macros.h header, in the same way that it already creates the
9610 reloc naming functions. */
9611
9612static bfd_boolean
9613is_32bit_abs_reloc (unsigned int reloc_type)
9614{
9615 switch (elf_header.e_machine)
9616 {
41e92641
NC
9617 case EM_386:
9618 case EM_486:
9619 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9620 case EM_68K:
9621 return reloc_type == 1; /* R_68K_32. */
9622 case EM_860:
9623 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9624 case EM_960:
9625 return reloc_type == 2; /* R_960_32. */
aca88567 9626 case EM_ALPHA:
137b6b5f 9627 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
9628 case EM_ARC:
9629 return reloc_type == 1; /* R_ARC_32. */
9630 case EM_ARM:
9631 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 9632 case EM_AVR_OLD:
aca88567
NC
9633 case EM_AVR:
9634 return reloc_type == 1;
9635 case EM_BLACKFIN:
9636 return reloc_type == 0x12; /* R_byte4_data. */
9637 case EM_CRIS:
9638 return reloc_type == 3; /* R_CRIS_32. */
9639 case EM_CR16:
6c03b1ed 9640 case EM_CR16_OLD:
aca88567
NC
9641 return reloc_type == 3; /* R_CR16_NUM32. */
9642 case EM_CRX:
9643 return reloc_type == 15; /* R_CRX_NUM32. */
9644 case EM_CYGNUS_FRV:
9645 return reloc_type == 1;
41e92641
NC
9646 case EM_CYGNUS_D10V:
9647 case EM_D10V:
9648 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
9649 case EM_CYGNUS_D30V:
9650 case EM_D30V:
9651 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
9652 case EM_DLX:
9653 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
9654 case EM_CYGNUS_FR30:
9655 case EM_FR30:
9656 return reloc_type == 3; /* R_FR30_32. */
9657 case EM_H8S:
9658 case EM_H8_300:
9659 case EM_H8_300H:
9660 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
9661 case EM_IA_64:
9662 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
9663 case EM_IP2K_OLD:
9664 case EM_IP2K:
9665 return reloc_type == 2; /* R_IP2K_32. */
9666 case EM_IQ2000:
9667 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
9668 case EM_LATTICEMICO32:
9669 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 9670 case EM_M32C_OLD:
aca88567
NC
9671 case EM_M32C:
9672 return reloc_type == 3; /* R_M32C_32. */
9673 case EM_M32R:
9674 return reloc_type == 34; /* R_M32R_32_RELA. */
9675 case EM_MCORE:
9676 return reloc_type == 1; /* R_MCORE_ADDR32. */
9677 case EM_CYGNUS_MEP:
9678 return reloc_type == 4; /* R_MEP_32. */
137b6b5f
AM
9679 case EM_MICROBLAZE:
9680 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
9681 case EM_MIPS:
9682 return reloc_type == 2; /* R_MIPS_32. */
9683 case EM_MMIX:
9684 return reloc_type == 4; /* R_MMIX_32. */
9685 case EM_CYGNUS_MN10200:
9686 case EM_MN10200:
9687 return reloc_type == 1; /* R_MN10200_32. */
9688 case EM_CYGNUS_MN10300:
9689 case EM_MN10300:
9690 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
9691 case EM_MOXIE:
9692 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
9693 case EM_MSP430_OLD:
9694 case EM_MSP430:
9695 return reloc_type == 1; /* R_MSP43_32. */
9696 case EM_MT:
9697 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
9698 case EM_ALTERA_NIOS2:
9699 case EM_NIOS32:
9700 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
9701 case EM_OPENRISC:
9702 case EM_OR32:
9703 return reloc_type == 1; /* R_OR32_32. */
aca88567 9704 case EM_PARISC:
5fda8eca
NC
9705 return (reloc_type == 1 /* R_PARISC_DIR32. */
9706 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
9707 case EM_PJ:
9708 case EM_PJ_OLD:
9709 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
9710 case EM_PPC64:
9711 return reloc_type == 1; /* R_PPC64_ADDR32. */
9712 case EM_PPC:
9713 return reloc_type == 1; /* R_PPC_ADDR32. */
c7927a3c
NC
9714 case EM_RX:
9715 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
9716 case EM_S370:
9717 return reloc_type == 1; /* R_I370_ADDR31. */
9718 case EM_S390_OLD:
9719 case EM_S390:
9720 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
9721 case EM_SCORE:
9722 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
9723 case EM_SH:
9724 return reloc_type == 1; /* R_SH_DIR32. */
9725 case EM_SPARC32PLUS:
9726 case EM_SPARCV9:
9727 case EM_SPARC:
9728 return reloc_type == 3 /* R_SPARC_32. */
9729 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
9730 case EM_SPU:
9731 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
9732 case EM_TI_C6000:
9733 return reloc_type == 1; /* R_C6000_ABS32. */
aca88567
NC
9734 case EM_CYGNUS_V850:
9735 case EM_V850:
9736 return reloc_type == 6; /* R_V850_ABS32. */
9737 case EM_VAX:
9738 return reloc_type == 1; /* R_VAX_32. */
9739 case EM_X86_64:
8a9036a4 9740 case EM_L1OM:
aca88567 9741 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
9742 case EM_XC16X:
9743 case EM_C166:
9744 return reloc_type == 3; /* R_XC16C_ABS_32. */
aca88567
NC
9745 case EM_XSTORMY16:
9746 return reloc_type == 1; /* R_XSTROMY16_32. */
9747 case EM_XTENSA_OLD:
9748 case EM_XTENSA:
9749 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
9750 default:
9751 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
9752 elf_header.e_machine);
9753 abort ();
9754 }
9755}
9756
9757/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9758 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
9759
9760static bfd_boolean
9761is_32bit_pcrel_reloc (unsigned int reloc_type)
9762{
9763 switch (elf_header.e_machine)
9764 {
41e92641
NC
9765 case EM_386:
9766 case EM_486:
3e0873ac 9767 return reloc_type == 2; /* R_386_PC32. */
aca88567 9768 case EM_68K:
3e0873ac 9769 return reloc_type == 4; /* R_68K_PC32. */
aca88567
NC
9770 case EM_ALPHA:
9771 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 9772 case EM_ARM:
3e0873ac 9773 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
9774 case EM_MICROBLAZE:
9775 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 9776 case EM_PARISC:
85acf597 9777 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
9778 case EM_PPC:
9779 return reloc_type == 26; /* R_PPC_REL32. */
9780 case EM_PPC64:
3e0873ac 9781 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
9782 case EM_S390_OLD:
9783 case EM_S390:
3e0873ac 9784 return reloc_type == 5; /* R_390_PC32. */
aca88567 9785 case EM_SH:
3e0873ac 9786 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
9787 case EM_SPARC32PLUS:
9788 case EM_SPARCV9:
9789 case EM_SPARC:
3e0873ac 9790 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
9791 case EM_SPU:
9792 return reloc_type == 13; /* R_SPU_REL32. */
aca88567 9793 case EM_X86_64:
8a9036a4 9794 case EM_L1OM:
3e0873ac 9795 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
9796 case EM_XTENSA_OLD:
9797 case EM_XTENSA:
9798 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
9799 default:
9800 /* Do not abort or issue an error message here. Not all targets use
9801 pc-relative 32-bit relocs in their DWARF debug information and we
9802 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
9803 more helpful warning message will be generated by apply_relocations
9804 anyway, so just return. */
aca88567
NC
9805 return FALSE;
9806 }
9807}
9808
9809/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9810 a 64-bit absolute RELA relocation used in DWARF debug sections. */
9811
9812static bfd_boolean
9813is_64bit_abs_reloc (unsigned int reloc_type)
9814{
9815 switch (elf_header.e_machine)
9816 {
9817 case EM_ALPHA:
9818 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
9819 case EM_IA_64:
9820 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
9821 case EM_PARISC:
9822 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
9823 case EM_PPC64:
9824 return reloc_type == 38; /* R_PPC64_ADDR64. */
9825 case EM_SPARC32PLUS:
9826 case EM_SPARCV9:
9827 case EM_SPARC:
9828 return reloc_type == 54; /* R_SPARC_UA64. */
9829 case EM_X86_64:
8a9036a4 9830 case EM_L1OM:
aca88567 9831 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
9832 case EM_S390_OLD:
9833 case EM_S390:
9834 return reloc_type == 22; /* R_S390_64 */
85a82265
AM
9835 case EM_MIPS:
9836 return reloc_type == 18; /* R_MIPS_64 */
aca88567
NC
9837 default:
9838 return FALSE;
9839 }
9840}
9841
85acf597
RH
9842/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
9843 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
9844
9845static bfd_boolean
9846is_64bit_pcrel_reloc (unsigned int reloc_type)
9847{
9848 switch (elf_header.e_machine)
9849 {
9850 case EM_ALPHA:
9851 return reloc_type == 11; /* R_ALPHA_SREL64 */
9852 case EM_IA_64:
9853 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB */
9854 case EM_PARISC:
9855 return reloc_type == 72; /* R_PARISC_PCREL64 */
9856 case EM_PPC64:
9857 return reloc_type == 44; /* R_PPC64_REL64 */
9858 case EM_SPARC32PLUS:
9859 case EM_SPARCV9:
9860 case EM_SPARC:
9861 return reloc_type == 46; /* R_SPARC_DISP64 */
9862 case EM_X86_64:
8a9036a4 9863 case EM_L1OM:
85acf597
RH
9864 return reloc_type == 24; /* R_X86_64_PC64 */
9865 case EM_S390_OLD:
9866 case EM_S390:
9867 return reloc_type == 23; /* R_S390_PC64 */
9868 default:
9869 return FALSE;
9870 }
9871}
9872
4dc3c23d
AM
9873/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9874 a 24-bit absolute RELA relocation used in DWARF debug sections. */
9875
9876static bfd_boolean
9877is_24bit_abs_reloc (unsigned int reloc_type)
9878{
9879 switch (elf_header.e_machine)
9880 {
9881 case EM_CYGNUS_MN10200:
9882 case EM_MN10200:
9883 return reloc_type == 4; /* R_MN10200_24. */
9884 default:
9885 return FALSE;
9886 }
9887}
9888
aca88567
NC
9889/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9890 a 16-bit absolute RELA relocation used in DWARF debug sections. */
9891
9892static bfd_boolean
9893is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
9894{
9895 switch (elf_header.e_machine)
9896 {
aca88567
NC
9897 case EM_AVR_OLD:
9898 case EM_AVR:
9899 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
9900 case EM_CYGNUS_D10V:
9901 case EM_D10V:
9902 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
9903 case EM_H8S:
9904 case EM_H8_300:
9905 case EM_H8_300H:
aca88567
NC
9906 return reloc_type == R_H8_DIR16;
9907 case EM_IP2K_OLD:
9908 case EM_IP2K:
9909 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 9910 case EM_M32C_OLD:
f4236fe4
DD
9911 case EM_M32C:
9912 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
9913 case EM_MSP430_OLD:
9914 case EM_MSP430:
9915 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
9916 case EM_ALTERA_NIOS2:
9917 case EM_NIOS32:
9918 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
9919 case EM_TI_C6000:
9920 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
9921 case EM_XC16X:
9922 case EM_C166:
9923 return reloc_type == 2; /* R_XC16C_ABS_16. */
4b78141a 9924 default:
aca88567 9925 return FALSE;
4b78141a
NC
9926 }
9927}
9928
2a7b2e88
JK
9929/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
9930 relocation entries (possibly formerly used for SHT_GROUP sections). */
9931
9932static bfd_boolean
9933is_none_reloc (unsigned int reloc_type)
9934{
9935 switch (elf_header.e_machine)
9936 {
cb8f3167
NC
9937 case EM_68K: /* R_68K_NONE. */
9938 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
9939 case EM_SPARC32PLUS:
9940 case EM_SPARCV9:
cb8f3167
NC
9941 case EM_SPARC: /* R_SPARC_NONE. */
9942 case EM_MIPS: /* R_MIPS_NONE. */
9943 case EM_PARISC: /* R_PARISC_NONE. */
9944 case EM_ALPHA: /* R_ALPHA_NONE. */
9945 case EM_PPC: /* R_PPC_NONE. */
9946 case EM_PPC64: /* R_PPC64_NONE. */
9947 case EM_ARM: /* R_ARM_NONE. */
9948 case EM_IA_64: /* R_IA64_NONE. */
9949 case EM_SH: /* R_SH_NONE. */
2a7b2e88 9950 case EM_S390_OLD:
cb8f3167
NC
9951 case EM_S390: /* R_390_NONE. */
9952 case EM_CRIS: /* R_CRIS_NONE. */
9953 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 9954 case EM_L1OM: /* R_X86_64_NONE. */
cb8f3167 9955 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 9956 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 9957 case EM_M32R: /* R_M32R_NONE. */
40b36596 9958 case EM_TI_C6000:/* R_C6000_NONE. */
c29aca4a
NC
9959 case EM_XC16X:
9960 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 9961 return reloc_type == 0;
58332dda
JK
9962 case EM_XTENSA_OLD:
9963 case EM_XTENSA:
4dc3c23d
AM
9964 return (reloc_type == 0 /* R_XTENSA_NONE. */
9965 || reloc_type == 17 /* R_XTENSA_DIFF8. */
9966 || reloc_type == 18 /* R_XTENSA_DIFF16. */
9967 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
9968 }
9969 return FALSE;
9970}
9971
cf13d699
NC
9972/* Apply relocations to a section.
9973 Note: So far support has been added only for those relocations
9974 which can be found in debug sections.
9975 FIXME: Add support for more relocations ? */
1b315056 9976
cf13d699
NC
9977static void
9978apply_relocations (void * file,
9979 Elf_Internal_Shdr * section,
9980 unsigned char * start)
1b315056 9981{
cf13d699
NC
9982 Elf_Internal_Shdr * relsec;
9983 unsigned char * end = start + section->sh_size;
cb8f3167 9984
cf13d699
NC
9985 if (elf_header.e_type != ET_REL)
9986 return;
1b315056 9987
cf13d699 9988 /* Find the reloc section associated with the section. */
5b18a4bc
NC
9989 for (relsec = section_headers;
9990 relsec < section_headers + elf_header.e_shnum;
9991 ++relsec)
252b5132 9992 {
41e92641
NC
9993 bfd_boolean is_rela;
9994 unsigned long num_relocs;
2cf0635d
NC
9995 Elf_Internal_Rela * relocs;
9996 Elf_Internal_Rela * rp;
9997 Elf_Internal_Shdr * symsec;
9998 Elf_Internal_Sym * symtab;
9999 Elf_Internal_Sym * sym;
252b5132 10000
41e92641 10001 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10002 || relsec->sh_info >= elf_header.e_shnum
10003 || section_headers + relsec->sh_info != section
c256ffe7 10004 || relsec->sh_size == 0
4fbb74a6 10005 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10006 continue;
428409d5 10007
41e92641
NC
10008 is_rela = relsec->sh_type == SHT_RELA;
10009
10010 if (is_rela)
10011 {
3f5e193b
NC
10012 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10013 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10014 return;
10015 }
10016 else
10017 {
3f5e193b
NC
10018 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10019 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10020 return;
10021 }
10022
10023 /* SH uses RELA but uses in place value instead of the addend field. */
10024 if (elf_header.e_machine == EM_SH)
10025 is_rela = FALSE;
428409d5 10026
4fbb74a6 10027 symsec = section_headers + relsec->sh_link;
3f5e193b 10028 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
103f02d3 10029
41e92641 10030 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10031 {
41e92641
NC
10032 bfd_vma addend;
10033 unsigned int reloc_type;
10034 unsigned int reloc_size;
91d6fa6a 10035 unsigned char * rloc;
4b78141a 10036
aca88567 10037 reloc_type = get_reloc_type (rp->r_info);
41e92641 10038
98fb390a 10039 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10040 continue;
98fb390a
NC
10041 else if (is_none_reloc (reloc_type))
10042 continue;
10043 else if (is_32bit_abs_reloc (reloc_type)
10044 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10045 reloc_size = 4;
85acf597
RH
10046 else if (is_64bit_abs_reloc (reloc_type)
10047 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10048 reloc_size = 8;
4dc3c23d
AM
10049 else if (is_24bit_abs_reloc (reloc_type))
10050 reloc_size = 3;
aca88567
NC
10051 else if (is_16bit_abs_reloc (reloc_type))
10052 reloc_size = 2;
10053 else
4b78141a 10054 {
41e92641 10055 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10056 reloc_type, SECTION_NAME (section));
4b78141a
NC
10057 continue;
10058 }
103f02d3 10059
91d6fa6a
NC
10060 rloc = start + rp->r_offset;
10061 if ((rloc + reloc_size) > end)
700dd8b7
L
10062 {
10063 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10064 (unsigned long) rp->r_offset,
10065 SECTION_NAME (section));
10066 continue;
10067 }
103f02d3 10068
41e92641
NC
10069 sym = symtab + get_reloc_symindex (rp->r_info);
10070
10071 /* If the reloc has a symbol associated with it,
55f25fc3
L
10072 make sure that it is of an appropriate type.
10073
10074 Relocations against symbols without type can happen.
10075 Gcc -feliminate-dwarf2-dups may generate symbols
10076 without type for debug info.
10077
10078 Icc generates relocations against function symbols
10079 instead of local labels.
10080
10081 Relocations against object symbols can happen, eg when
10082 referencing a global array. For an example of this see
10083 the _clz.o binary in libgcc.a. */
aca88567 10084 if (sym != symtab
55f25fc3 10085 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10086 {
41e92641 10087 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10088 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10089 (long int)(rp - relocs),
41e92641 10090 SECTION_NAME (relsec));
aca88567 10091 continue;
5b18a4bc 10092 }
252b5132 10093
4dc3c23d
AM
10094 addend = 0;
10095 if (is_rela)
10096 addend += rp->r_addend;
c47320c3
AM
10097 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10098 partial_inplace. */
4dc3c23d
AM
10099 if (!is_rela
10100 || (elf_header.e_machine == EM_XTENSA
10101 && reloc_type == 1)
10102 || ((elf_header.e_machine == EM_PJ
10103 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10104 && reloc_type == 1)
10105 || ((elf_header.e_machine == EM_D30V
10106 || elf_header.e_machine == EM_CYGNUS_D30V)
10107 && reloc_type == 12))
91d6fa6a 10108 addend += byte_get (rloc, reloc_size);
cb8f3167 10109
85acf597
RH
10110 if (is_32bit_pcrel_reloc (reloc_type)
10111 || is_64bit_pcrel_reloc (reloc_type))
10112 {
10113 /* On HPPA, all pc-relative relocations are biased by 8. */
10114 if (elf_header.e_machine == EM_PARISC)
10115 addend -= 8;
91d6fa6a 10116 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10117 reloc_size);
10118 }
41e92641 10119 else
91d6fa6a 10120 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10121 }
252b5132 10122
5b18a4bc 10123 free (symtab);
41e92641 10124 free (relocs);
5b18a4bc
NC
10125 break;
10126 }
5b18a4bc 10127}
103f02d3 10128
cf13d699
NC
10129#ifdef SUPPORT_DISASSEMBLY
10130static int
10131disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10132{
10133 printf (_("\nAssembly dump of section %s\n"),
10134 SECTION_NAME (section));
10135
10136 /* XXX -- to be done --- XXX */
10137
10138 return 1;
10139}
10140#endif
10141
10142/* Reads in the contents of SECTION from FILE, returning a pointer
10143 to a malloc'ed buffer or NULL if something went wrong. */
10144
10145static char *
10146get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10147{
10148 bfd_size_type num_bytes;
10149
10150 num_bytes = section->sh_size;
10151
10152 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10153 {
10154 printf (_("\nSection '%s' has no data to dump.\n"),
10155 SECTION_NAME (section));
10156 return NULL;
10157 }
10158
3f5e193b
NC
10159 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10160 _("section contents"));
cf13d699
NC
10161}
10162
dd24e3da 10163
cf13d699
NC
10164static void
10165dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10166{
10167 Elf_Internal_Shdr * relsec;
10168 bfd_size_type num_bytes;
cf13d699
NC
10169 char * data;
10170 char * end;
10171 char * start;
10172 char * name = SECTION_NAME (section);
10173 bfd_boolean some_strings_shown;
10174
10175 start = get_section_contents (section, file);
10176 if (start == NULL)
10177 return;
10178
10179 printf (_("\nString dump of section '%s':\n"), name);
10180
10181 /* If the section being dumped has relocations against it the user might
10182 be expecting these relocations to have been applied. Check for this
10183 case and issue a warning message in order to avoid confusion.
10184 FIXME: Maybe we ought to have an option that dumps a section with
10185 relocs applied ? */
10186 for (relsec = section_headers;
10187 relsec < section_headers + elf_header.e_shnum;
10188 ++relsec)
10189 {
10190 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10191 || relsec->sh_info >= elf_header.e_shnum
10192 || section_headers + relsec->sh_info != section
10193 || relsec->sh_size == 0
10194 || relsec->sh_link >= elf_header.e_shnum)
10195 continue;
10196
10197 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10198 break;
10199 }
10200
10201 num_bytes = section->sh_size;
cf13d699
NC
10202 data = start;
10203 end = start + num_bytes;
10204 some_strings_shown = FALSE;
10205
10206 while (data < end)
10207 {
10208 while (!ISPRINT (* data))
10209 if (++ data >= end)
10210 break;
10211
10212 if (data < end)
10213 {
10214#ifndef __MSVCRT__
c975cc98
NC
10215 /* PR 11128: Use two separate invocations in order to work
10216 around bugs in the Solaris 8 implementation of printf. */
10217 printf (" [%6tx] ", data - start);
10218 printf ("%s\n", data);
cf13d699
NC
10219#else
10220 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10221#endif
10222 data += strlen (data);
10223 some_strings_shown = TRUE;
10224 }
10225 }
10226
10227 if (! some_strings_shown)
10228 printf (_(" No strings found in this section."));
10229
10230 free (start);
10231
10232 putchar ('\n');
10233}
10234
10235static void
10236dump_section_as_bytes (Elf_Internal_Shdr * section,
10237 FILE * file,
10238 bfd_boolean relocate)
10239{
10240 Elf_Internal_Shdr * relsec;
10241 bfd_size_type bytes;
10242 bfd_vma addr;
10243 unsigned char * data;
10244 unsigned char * start;
10245
10246 start = (unsigned char *) get_section_contents (section, file);
10247 if (start == NULL)
10248 return;
10249
10250 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10251
10252 if (relocate)
10253 {
10254 apply_relocations (file, section, start);
10255 }
10256 else
10257 {
10258 /* If the section being dumped has relocations against it the user might
10259 be expecting these relocations to have been applied. Check for this
10260 case and issue a warning message in order to avoid confusion.
10261 FIXME: Maybe we ought to have an option that dumps a section with
10262 relocs applied ? */
10263 for (relsec = section_headers;
10264 relsec < section_headers + elf_header.e_shnum;
10265 ++relsec)
10266 {
10267 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10268 || relsec->sh_info >= elf_header.e_shnum
10269 || section_headers + relsec->sh_info != section
10270 || relsec->sh_size == 0
10271 || relsec->sh_link >= elf_header.e_shnum)
10272 continue;
10273
10274 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10275 break;
10276 }
10277 }
10278
10279 addr = section->sh_addr;
10280 bytes = section->sh_size;
10281 data = start;
10282
10283 while (bytes)
10284 {
10285 int j;
10286 int k;
10287 int lbytes;
10288
10289 lbytes = (bytes > 16 ? 16 : bytes);
10290
10291 printf (" 0x%8.8lx ", (unsigned long) addr);
10292
10293 for (j = 0; j < 16; j++)
10294 {
10295 if (j < lbytes)
10296 printf ("%2.2x", data[j]);
10297 else
10298 printf (" ");
10299
10300 if ((j & 3) == 3)
10301 printf (" ");
10302 }
10303
10304 for (j = 0; j < lbytes; j++)
10305 {
10306 k = data[j];
10307 if (k >= ' ' && k < 0x7f)
10308 printf ("%c", k);
10309 else
10310 printf (".");
10311 }
10312
10313 putchar ('\n');
10314
10315 data += lbytes;
10316 addr += lbytes;
10317 bytes -= lbytes;
10318 }
10319
10320 free (start);
10321
10322 putchar ('\n');
10323}
10324
4a114e3e 10325/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10326
10327static int
d3dbc530
AM
10328uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10329 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10330{
10331#ifndef HAVE_ZLIB_H
cf13d699
NC
10332 return FALSE;
10333#else
10334 dwarf_size_type compressed_size = *size;
10335 unsigned char * compressed_buffer = *buffer;
10336 dwarf_size_type uncompressed_size;
10337 unsigned char * uncompressed_buffer;
10338 z_stream strm;
10339 int rc;
10340 dwarf_size_type header_size = 12;
10341
10342 /* Read the zlib header. In this case, it should be "ZLIB" followed
10343 by the uncompressed section size, 8 bytes in big-endian order. */
10344 if (compressed_size < header_size
10345 || ! streq ((char *) compressed_buffer, "ZLIB"))
10346 return 0;
10347
10348 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10349 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10350 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10351 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10352 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10353 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10354 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10355 uncompressed_size += compressed_buffer[11];
10356
10357 /* It is possible the section consists of several compressed
10358 buffers concatenated together, so we uncompress in a loop. */
10359 strm.zalloc = NULL;
10360 strm.zfree = NULL;
10361 strm.opaque = NULL;
10362 strm.avail_in = compressed_size - header_size;
10363 strm.next_in = (Bytef *) compressed_buffer + header_size;
10364 strm.avail_out = uncompressed_size;
3f5e193b 10365 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10366
10367 rc = inflateInit (& strm);
10368 while (strm.avail_in > 0)
10369 {
10370 if (rc != Z_OK)
10371 goto fail;
10372 strm.next_out = ((Bytef *) uncompressed_buffer
10373 + (uncompressed_size - strm.avail_out));
10374 rc = inflate (&strm, Z_FINISH);
10375 if (rc != Z_STREAM_END)
10376 goto fail;
10377 rc = inflateReset (& strm);
10378 }
10379 rc = inflateEnd (& strm);
10380 if (rc != Z_OK
10381 || strm.avail_out != 0)
10382 goto fail;
10383
10384 free (compressed_buffer);
10385 *buffer = uncompressed_buffer;
10386 *size = uncompressed_size;
10387 return 1;
10388
10389 fail:
10390 free (uncompressed_buffer);
4a114e3e
L
10391 /* Indicate decompression failure. */
10392 *buffer = NULL;
cf13d699
NC
10393 return 0;
10394#endif /* HAVE_ZLIB_H */
10395}
10396
d966045b
DJ
10397static int
10398load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10399 Elf_Internal_Shdr * sec, void * file)
1007acb3 10400{
2cf0635d 10401 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10402 char buf [64];
1007acb3 10403
19e6b90e
L
10404 /* If it is already loaded, do nothing. */
10405 if (section->start != NULL)
10406 return 1;
1007acb3 10407
19e6b90e
L
10408 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10409 section->address = sec->sh_addr;
3f5e193b
NC
10410 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10411 sec->sh_offset, 1,
10412 sec->sh_size, buf);
59245841
NC
10413 if (section->start == NULL)
10414 section->size = 0;
10415 else
10416 {
10417 section->size = sec->sh_size;
10418 if (uncompress_section_contents (&section->start, &section->size))
10419 sec->sh_size = section->size;
10420 }
4a114e3e 10421
1b315056
CS
10422 if (section->start == NULL)
10423 return 0;
10424
19e6b90e 10425 if (debug_displays [debug].relocate)
3f5e193b 10426 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10427
1b315056 10428 return 1;
1007acb3
L
10429}
10430
d966045b 10431int
2cf0635d 10432load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10433{
2cf0635d
NC
10434 struct dwarf_section * section = &debug_displays [debug].section;
10435 Elf_Internal_Shdr * sec;
d966045b
DJ
10436
10437 /* Locate the debug section. */
10438 sec = find_section (section->uncompressed_name);
10439 if (sec != NULL)
10440 section->name = section->uncompressed_name;
10441 else
10442 {
10443 sec = find_section (section->compressed_name);
10444 if (sec != NULL)
10445 section->name = section->compressed_name;
10446 }
10447 if (sec == NULL)
10448 return 0;
10449
3f5e193b 10450 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10451}
10452
19e6b90e
L
10453void
10454free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10455{
2cf0635d 10456 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10457
19e6b90e
L
10458 if (section->start == NULL)
10459 return;
1007acb3 10460
19e6b90e
L
10461 free ((char *) section->start);
10462 section->start = NULL;
10463 section->address = 0;
10464 section->size = 0;
1007acb3
L
10465}
10466
1007acb3 10467static int
2cf0635d 10468display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 10469{
2cf0635d 10470 char * name = SECTION_NAME (section);
19e6b90e
L
10471 bfd_size_type length;
10472 int result = 1;
3f5e193b 10473 int i;
1007acb3 10474
19e6b90e
L
10475 length = section->sh_size;
10476 if (length == 0)
1007acb3 10477 {
19e6b90e
L
10478 printf (_("\nSection '%s' has no debugging data.\n"), name);
10479 return 0;
1007acb3 10480 }
5dff79d8
NC
10481 if (section->sh_type == SHT_NOBITS)
10482 {
10483 /* There is no point in dumping the contents of a debugging section
10484 which has the NOBITS type - the bits in the file will be random.
10485 This can happen when a file containing a .eh_frame section is
10486 stripped with the --only-keep-debug command line option. */
10487 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10488 return 0;
10489 }
1007acb3 10490
0112cd26 10491 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10492 name = ".debug_info";
1007acb3 10493
19e6b90e
L
10494 /* See if we know how to display the contents of this section. */
10495 for (i = 0; i < max; i++)
1b315056
CS
10496 if (streq (debug_displays[i].section.uncompressed_name, name)
10497 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10498 {
2cf0635d 10499 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10500 int secondary = (section != find_section (name));
10501
10502 if (secondary)
3f5e193b 10503 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10504
2b6f5997 10505 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10506 sec->name = sec->uncompressed_name;
10507 else
10508 sec->name = sec->compressed_name;
3f5e193b
NC
10509 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10510 section, file))
19e6b90e
L
10511 {
10512 result &= debug_displays[i].display (sec, file);
1007acb3 10513
d966045b 10514 if (secondary || (i != info && i != abbrev))
3f5e193b 10515 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10516 }
1007acb3 10517
19e6b90e
L
10518 break;
10519 }
1007acb3 10520
19e6b90e 10521 if (i == max)
1007acb3 10522 {
19e6b90e
L
10523 printf (_("Unrecognized debug section: %s\n"), name);
10524 result = 0;
1007acb3
L
10525 }
10526
19e6b90e 10527 return result;
5b18a4bc 10528}
103f02d3 10529
aef1f6d0
DJ
10530/* Set DUMP_SECTS for all sections where dumps were requested
10531 based on section name. */
10532
10533static void
10534initialise_dumps_byname (void)
10535{
2cf0635d 10536 struct dump_list_entry * cur;
aef1f6d0
DJ
10537
10538 for (cur = dump_sects_byname; cur; cur = cur->next)
10539 {
10540 unsigned int i;
10541 int any;
10542
10543 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10544 if (streq (SECTION_NAME (section_headers + i), cur->name))
10545 {
09c11c86 10546 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10547 any = 1;
10548 }
10549
10550 if (!any)
10551 warn (_("Section '%s' was not dumped because it does not exist!\n"),
10552 cur->name);
10553 }
10554}
10555
5b18a4bc 10556static void
2cf0635d 10557process_section_contents (FILE * file)
5b18a4bc 10558{
2cf0635d 10559 Elf_Internal_Shdr * section;
19e6b90e 10560 unsigned int i;
103f02d3 10561
19e6b90e
L
10562 if (! do_dump)
10563 return;
103f02d3 10564
aef1f6d0
DJ
10565 initialise_dumps_byname ();
10566
19e6b90e
L
10567 for (i = 0, section = section_headers;
10568 i < elf_header.e_shnum && i < num_dump_sects;
10569 i++, section++)
10570 {
10571#ifdef SUPPORT_DISASSEMBLY
10572 if (dump_sects[i] & DISASS_DUMP)
10573 disassemble_section (section, file);
10574#endif
10575 if (dump_sects[i] & HEX_DUMP)
cf13d699 10576 dump_section_as_bytes (section, file, FALSE);
103f02d3 10577
cf13d699
NC
10578 if (dump_sects[i] & RELOC_DUMP)
10579 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
10580
10581 if (dump_sects[i] & STRING_DUMP)
10582 dump_section_as_strings (section, file);
cf13d699
NC
10583
10584 if (dump_sects[i] & DEBUG_DUMP)
10585 display_debug_section (section, file);
5b18a4bc 10586 }
103f02d3 10587
19e6b90e
L
10588 /* Check to see if the user requested a
10589 dump of a section that does not exist. */
10590 while (i++ < num_dump_sects)
10591 if (dump_sects[i])
10592 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 10593}
103f02d3 10594
5b18a4bc 10595static void
19e6b90e 10596process_mips_fpe_exception (int mask)
5b18a4bc 10597{
19e6b90e
L
10598 if (mask)
10599 {
10600 int first = 1;
10601 if (mask & OEX_FPU_INEX)
10602 fputs ("INEX", stdout), first = 0;
10603 if (mask & OEX_FPU_UFLO)
10604 printf ("%sUFLO", first ? "" : "|"), first = 0;
10605 if (mask & OEX_FPU_OFLO)
10606 printf ("%sOFLO", first ? "" : "|"), first = 0;
10607 if (mask & OEX_FPU_DIV0)
10608 printf ("%sDIV0", first ? "" : "|"), first = 0;
10609 if (mask & OEX_FPU_INVAL)
10610 printf ("%sINVAL", first ? "" : "|");
10611 }
5b18a4bc 10612 else
19e6b90e 10613 fputs ("0", stdout);
5b18a4bc 10614}
103f02d3 10615
11c1ff18
PB
10616/* ARM EABI attributes section. */
10617typedef struct
10618{
10619 int tag;
2cf0635d 10620 const char * name;
11c1ff18
PB
10621 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
10622 int type;
2cf0635d 10623 const char ** table;
11c1ff18
PB
10624} arm_attr_public_tag;
10625
2cf0635d 10626static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 10627 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
9e3c6df6 10628 "v6K", "v7", "v6-M", "v6S-M", "v7E-M"};
2cf0635d
NC
10629static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
10630static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 10631 {"No", "Thumb-1", "Thumb-2"};
75375b3e 10632static const char * arm_attr_tag_FP_arch[] =
62f3b8c8 10633 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
2cf0635d 10634static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 10635static const char * arm_attr_tag_Advanced_SIMD_arch[] =
cd21e546 10636 {"No", "NEONv1", "NEONv1 with Fused-MAC"};
2cf0635d 10637static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
10638 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
10639 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 10640static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 10641 {"V6", "SB", "TLS", "Unused"};
2cf0635d 10642static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 10643 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 10644static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 10645 {"Absolute", "PC-relative", "None"};
2cf0635d 10646static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 10647 {"None", "direct", "GOT-indirect"};
2cf0635d 10648static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 10649 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
10650static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
10651static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 10652 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
10653static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
10654static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
10655static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 10656 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 10657static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 10658 {"Unused", "small", "int", "forced to int"};
2cf0635d 10659static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 10660 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 10661static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 10662 {"AAPCS", "VFP registers", "custom"};
2cf0635d 10663static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 10664 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 10665static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
10666 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10667 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 10668static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
10669 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10670 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 10671static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 10672static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 10673 {"Not Allowed", "Allowed"};
2cf0635d 10674static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 10675 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 10676static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
10677 {"Not Allowed", "Allowed"};
10678static const char * arm_attr_tag_DIV_use[] =
dd24e3da 10679 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 10680 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
10681static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
10682static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 10683 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 10684 "TrustZone and Virtualization Extensions"};
dd24e3da 10685static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 10686 {"Not Allowed", "Allowed"};
11c1ff18
PB
10687
10688#define LOOKUP(id, name) \
10689 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 10690static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
10691{
10692 {4, "CPU_raw_name", 1, NULL},
10693 {5, "CPU_name", 1, NULL},
10694 LOOKUP(6, CPU_arch),
10695 {7, "CPU_arch_profile", 0, NULL},
10696 LOOKUP(8, ARM_ISA_use),
10697 LOOKUP(9, THUMB_ISA_use),
75375b3e 10698 LOOKUP(10, FP_arch),
11c1ff18 10699 LOOKUP(11, WMMX_arch),
f5f53991
AS
10700 LOOKUP(12, Advanced_SIMD_arch),
10701 LOOKUP(13, PCS_config),
11c1ff18
PB
10702 LOOKUP(14, ABI_PCS_R9_use),
10703 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 10704 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
10705 LOOKUP(17, ABI_PCS_GOT_use),
10706 LOOKUP(18, ABI_PCS_wchar_t),
10707 LOOKUP(19, ABI_FP_rounding),
10708 LOOKUP(20, ABI_FP_denormal),
10709 LOOKUP(21, ABI_FP_exceptions),
10710 LOOKUP(22, ABI_FP_user_exceptions),
10711 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
10712 {24, "ABI_align_needed", 0, NULL},
10713 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
10714 LOOKUP(26, ABI_enum_size),
10715 LOOKUP(27, ABI_HardFP_use),
10716 LOOKUP(28, ABI_VFP_args),
10717 LOOKUP(29, ABI_WMMX_args),
10718 LOOKUP(30, ABI_optimization_goals),
10719 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 10720 {32, "compatibility", 0, NULL},
f5f53991 10721 LOOKUP(34, CPU_unaligned_access),
75375b3e 10722 LOOKUP(36, FP_HP_extension),
8e79c3df 10723 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
10724 LOOKUP(42, MPextension_use),
10725 LOOKUP(44, DIV_use),
f5f53991
AS
10726 {64, "nodefaults", 0, NULL},
10727 {65, "also_compatible_with", 0, NULL},
10728 LOOKUP(66, T2EE_use),
10729 {67, "conformance", 1, NULL},
10730 LOOKUP(68, Virtualization_use),
cd21e546 10731 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
10732};
10733#undef LOOKUP
10734
11c1ff18 10735static unsigned char *
2cf0635d 10736display_arm_attribute (unsigned char * p)
11c1ff18
PB
10737{
10738 int tag;
10739 unsigned int len;
10740 int val;
2cf0635d 10741 arm_attr_public_tag * attr;
11c1ff18
PB
10742 unsigned i;
10743 int type;
10744
10745 tag = read_uleb128 (p, &len);
10746 p += len;
10747 attr = NULL;
2cf0635d 10748 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
10749 {
10750 if (arm_attr_public_tags[i].tag == tag)
10751 {
10752 attr = &arm_attr_public_tags[i];
10753 break;
10754 }
10755 }
10756
10757 if (attr)
10758 {
10759 printf (" Tag_%s: ", attr->name);
10760 switch (attr->type)
10761 {
10762 case 0:
10763 switch (tag)
10764 {
10765 case 7: /* Tag_CPU_arch_profile. */
10766 val = read_uleb128 (p, &len);
10767 p += len;
10768 switch (val)
10769 {
2b692964
NC
10770 case 0: printf (_("None\n")); break;
10771 case 'A': printf (_("Application\n")); break;
10772 case 'R': printf (_("Realtime\n")); break;
10773 case 'M': printf (_("Microcontroller\n")); break;
10774 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
10775 default: printf ("??? (%d)\n", val); break;
10776 }
10777 break;
10778
75375b3e
MGD
10779 case 24: /* Tag_align_needed. */
10780 val = read_uleb128 (p, &len);
10781 p += len;
10782 switch (val)
10783 {
2b692964
NC
10784 case 0: printf (_("None\n")); break;
10785 case 1: printf (_("8-byte\n")); break;
10786 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
10787 case 3: printf ("??? 3\n"); break;
10788 default:
10789 if (val <= 12)
dd24e3da 10790 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10791 1 << val);
10792 else
10793 printf ("??? (%d)\n", val);
10794 break;
10795 }
10796 break;
10797
10798 case 25: /* Tag_align_preserved. */
10799 val = read_uleb128 (p, &len);
10800 p += len;
10801 switch (val)
10802 {
2b692964
NC
10803 case 0: printf (_("None\n")); break;
10804 case 1: printf (_("8-byte, except leaf SP\n")); break;
10805 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
10806 case 3: printf ("??? 3\n"); break;
10807 default:
10808 if (val <= 12)
dd24e3da 10809 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10810 1 << val);
10811 else
10812 printf ("??? (%d)\n", val);
10813 break;
10814 }
10815 break;
10816
11c1ff18
PB
10817 case 32: /* Tag_compatibility. */
10818 val = read_uleb128 (p, &len);
10819 p += len;
2b692964 10820 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 10821 p += strlen ((char *) p) + 1;
11c1ff18
PB
10822 break;
10823
f5f53991
AS
10824 case 64: /* Tag_nodefaults. */
10825 p++;
2b692964 10826 printf (_("True\n"));
f5f53991
AS
10827 break;
10828
10829 case 65: /* Tag_also_compatible_with. */
10830 val = read_uleb128 (p, &len);
10831 p += len;
10832 if (val == 6 /* Tag_CPU_arch. */)
10833 {
10834 val = read_uleb128 (p, &len);
10835 p += len;
2cf0635d 10836 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
10837 printf ("??? (%d)\n", val);
10838 else
10839 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
10840 }
10841 else
10842 printf ("???\n");
10843 while (*(p++) != '\0' /* NUL terminator. */);
10844 break;
10845
11c1ff18 10846 default:
2cf0635d 10847 abort ();
11c1ff18
PB
10848 }
10849 return p;
10850
10851 case 1:
10852 case 2:
10853 type = attr->type;
10854 break;
10855
10856 default:
10857 assert (attr->type & 0x80);
10858 val = read_uleb128 (p, &len);
10859 p += len;
10860 type = attr->type & 0x7f;
10861 if (val >= type)
10862 printf ("??? (%d)\n", val);
10863 else
10864 printf ("%s\n", attr->table[val]);
10865 return p;
10866 }
10867 }
10868 else
10869 {
10870 if (tag & 1)
10871 type = 1; /* String. */
10872 else
10873 type = 2; /* uleb128. */
10874 printf (" Tag_unknown_%d: ", tag);
10875 }
10876
10877 if (type == 1)
10878 {
10879 printf ("\"%s\"\n", p);
2cf0635d 10880 p += strlen ((char *) p) + 1;
11c1ff18
PB
10881 }
10882 else
10883 {
10884 val = read_uleb128 (p, &len);
10885 p += len;
10886 printf ("%d (0x%x)\n", val, val);
10887 }
10888
10889 return p;
10890}
10891
104d59d1 10892static unsigned char *
60bca95a
NC
10893display_gnu_attribute (unsigned char * p,
10894 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
10895{
10896 int tag;
10897 unsigned int len;
10898 int val;
10899 int type;
10900
10901 tag = read_uleb128 (p, &len);
10902 p += len;
10903
10904 /* Tag_compatibility is the only generic GNU attribute defined at
10905 present. */
10906 if (tag == 32)
10907 {
10908 val = read_uleb128 (p, &len);
10909 p += len;
2b692964 10910 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 10911 p += strlen ((char *) p) + 1;
104d59d1
JM
10912 return p;
10913 }
10914
10915 if ((tag & 2) == 0 && display_proc_gnu_attribute)
10916 return display_proc_gnu_attribute (p, tag);
10917
10918 if (tag & 1)
10919 type = 1; /* String. */
10920 else
10921 type = 2; /* uleb128. */
10922 printf (" Tag_unknown_%d: ", tag);
10923
10924 if (type == 1)
10925 {
10926 printf ("\"%s\"\n", p);
60bca95a 10927 p += strlen ((char *) p) + 1;
104d59d1
JM
10928 }
10929 else
10930 {
10931 val = read_uleb128 (p, &len);
10932 p += len;
10933 printf ("%d (0x%x)\n", val, val);
10934 }
10935
10936 return p;
10937}
10938
34c8bcba 10939static unsigned char *
2cf0635d 10940display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
10941{
10942 int type;
10943 unsigned int len;
10944 int val;
10945
10946 if (tag == Tag_GNU_Power_ABI_FP)
10947 {
10948 val = read_uleb128 (p, &len);
10949 p += len;
10950 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 10951
34c8bcba
JM
10952 switch (val)
10953 {
10954 case 0:
2b692964 10955 printf (_("Hard or soft float\n"));
34c8bcba
JM
10956 break;
10957 case 1:
2b692964 10958 printf (_("Hard float\n"));
34c8bcba
JM
10959 break;
10960 case 2:
2b692964 10961 printf (_("Soft float\n"));
34c8bcba 10962 break;
3c7b9897 10963 case 3:
2b692964 10964 printf (_("Single-precision hard float\n"));
3c7b9897 10965 break;
34c8bcba
JM
10966 default:
10967 printf ("??? (%d)\n", val);
10968 break;
10969 }
10970 return p;
10971 }
10972
c6e65352
DJ
10973 if (tag == Tag_GNU_Power_ABI_Vector)
10974 {
10975 val = read_uleb128 (p, &len);
10976 p += len;
10977 printf (" Tag_GNU_Power_ABI_Vector: ");
10978 switch (val)
10979 {
10980 case 0:
2b692964 10981 printf (_("Any\n"));
c6e65352
DJ
10982 break;
10983 case 1:
2b692964 10984 printf (_("Generic\n"));
c6e65352
DJ
10985 break;
10986 case 2:
10987 printf ("AltiVec\n");
10988 break;
10989 case 3:
10990 printf ("SPE\n");
10991 break;
10992 default:
10993 printf ("??? (%d)\n", val);
10994 break;
10995 }
10996 return p;
10997 }
10998
f82e0623
NF
10999 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11000 {
11001 val = read_uleb128 (p, &len);
11002 p += len;
11003 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11004 switch (val)
11005 {
11006 case 0:
2b692964 11007 printf (_("Any\n"));
f82e0623
NF
11008 break;
11009 case 1:
11010 printf ("r3/r4\n");
11011 break;
11012 case 2:
2b692964 11013 printf (_("Memory\n"));
f82e0623
NF
11014 break;
11015 default:
11016 printf ("??? (%d)\n", val);
11017 break;
11018 }
11019 return p;
11020 }
11021
34c8bcba
JM
11022 if (tag & 1)
11023 type = 1; /* String. */
11024 else
11025 type = 2; /* uleb128. */
11026 printf (" Tag_unknown_%d: ", tag);
11027
11028 if (type == 1)
11029 {
11030 printf ("\"%s\"\n", p);
60bca95a 11031 p += strlen ((char *) p) + 1;
34c8bcba
JM
11032 }
11033 else
11034 {
11035 val = read_uleb128 (p, &len);
11036 p += len;
11037 printf ("%d (0x%x)\n", val, val);
11038 }
11039
11040 return p;
11041}
11042
2cf19d5c 11043static unsigned char *
2cf0635d 11044display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
11045{
11046 int type;
11047 unsigned int len;
11048 int val;
11049
11050 if (tag == Tag_GNU_MIPS_ABI_FP)
11051 {
11052 val = read_uleb128 (p, &len);
11053 p += len;
11054 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11055
2cf19d5c
JM
11056 switch (val)
11057 {
11058 case 0:
2b692964 11059 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11060 break;
11061 case 1:
2b692964 11062 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11063 break;
11064 case 2:
2b692964 11065 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11066 break;
11067 case 3:
2b692964 11068 printf (_("Soft float\n"));
2cf19d5c 11069 break;
42554f6a 11070 case 4:
9eeefea8 11071 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11072 break;
2cf19d5c
JM
11073 default:
11074 printf ("??? (%d)\n", val);
11075 break;
11076 }
11077 return p;
11078 }
11079
11080 if (tag & 1)
11081 type = 1; /* String. */
11082 else
11083 type = 2; /* uleb128. */
11084 printf (" Tag_unknown_%d: ", tag);
11085
11086 if (type == 1)
11087 {
11088 printf ("\"%s\"\n", p);
60bca95a 11089 p += strlen ((char *) p) + 1;
2cf19d5c
JM
11090 }
11091 else
11092 {
11093 val = read_uleb128 (p, &len);
11094 p += len;
11095 printf ("%d (0x%x)\n", val, val);
11096 }
11097
11098 return p;
11099}
11100
59e6276b
JM
11101static unsigned char *
11102display_tic6x_attribute (unsigned char * p)
11103{
11104 int tag;
11105 unsigned int len;
11106 int val;
11107
11108 tag = read_uleb128 (p, &len);
11109 p += len;
11110
11111 switch (tag)
11112 {
75fa6dc1 11113 case Tag_ISA:
59e6276b
JM
11114 val = read_uleb128 (p, &len);
11115 p += len;
75fa6dc1 11116 printf (" Tag_ISA: ");
59e6276b
JM
11117
11118 switch (val)
11119 {
75fa6dc1 11120 case C6XABI_Tag_ISA_none:
59e6276b
JM
11121 printf (_("None\n"));
11122 break;
75fa6dc1 11123 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11124 printf ("C62x\n");
11125 break;
75fa6dc1 11126 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11127 printf ("C67x\n");
11128 break;
75fa6dc1 11129 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11130 printf ("C67x+\n");
11131 break;
75fa6dc1 11132 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11133 printf ("C64x\n");
11134 break;
75fa6dc1 11135 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11136 printf ("C64x+\n");
11137 break;
75fa6dc1 11138 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11139 printf ("C674x\n");
11140 break;
11141 default:
11142 printf ("??? (%d)\n", val);
11143 break;
11144 }
11145 return p;
11146
87779176
JM
11147 case Tag_ABI_wchar_t:
11148 val = read_uleb128 (p, &len);
11149 p += len;
11150 printf (" Tag_ABI_wchar_t: ");
11151 switch (val)
11152 {
11153 case 0:
11154 printf (_("Not used\n"));
11155 break;
11156 case 1:
11157 printf (_("2 bytes\n"));
11158 break;
11159 case 2:
11160 printf (_("4 bytes\n"));
11161 break;
11162 default:
11163 printf ("??? (%d)\n", val);
11164 break;
11165 }
11166 return p;
11167
11168 case Tag_ABI_stack_align_needed:
11169 val = read_uleb128 (p, &len);
11170 p += len;
11171 printf (" Tag_ABI_stack_align_needed: ");
11172 switch (val)
11173 {
11174 case 0:
11175 printf (_("8-byte\n"));
11176 break;
11177 case 1:
11178 printf (_("16-byte\n"));
11179 break;
11180 default:
11181 printf ("??? (%d)\n", val);
11182 break;
11183 }
11184 return p;
11185
11186 case Tag_ABI_stack_align_preserved:
11187 val = read_uleb128 (p, &len);
11188 p += len;
11189 printf (" Tag_ABI_stack_align_preserved: ");
11190 switch (val)
11191 {
11192 case 0:
11193 printf (_("8-byte\n"));
11194 break;
11195 case 1:
11196 printf (_("16-byte\n"));
11197 break;
11198 default:
11199 printf ("??? (%d)\n", val);
11200 break;
11201 }
11202 return p;
11203
b5593623
JM
11204 case Tag_ABI_DSBT:
11205 val = read_uleb128 (p, &len);
11206 p += len;
11207 printf (" Tag_ABI_DSBT: ");
11208 switch (val)
11209 {
11210 case 0:
11211 printf (_("DSBT addressing not used\n"));
11212 break;
11213 case 1:
11214 printf (_("DSBT addressing used\n"));
11215 break;
11216 default:
11217 printf ("??? (%d)\n", val);
11218 break;
11219 }
11220 return p;
11221
87779176
JM
11222 case Tag_ABI_PID:
11223 val = read_uleb128 (p, &len);
11224 p += len;
11225 printf (" Tag_ABI_PID: ");
11226 switch (val)
11227 {
11228 case 0:
11229 printf (_("Data addressing position-dependent\n"));
11230 break;
11231 case 1:
11232 printf (_("Data addressing position-independent, GOT near DP\n"));
11233 break;
11234 case 2:
11235 printf (_("Data addressing position-independent, GOT far from DP\n"));
11236 break;
11237 default:
11238 printf ("??? (%d)\n", val);
11239 break;
11240 }
11241 return p;
11242
11243 case Tag_ABI_PIC:
11244 val = read_uleb128 (p, &len);
11245 p += len;
11246 printf (" Tag_ABI_PIC: ");
11247 switch (val)
11248 {
11249 case 0:
11250 printf (_("Code addressing position-dependent\n"));
11251 break;
11252 case 1:
11253 printf (_("Code addressing position-independent\n"));
11254 break;
11255 default:
11256 printf ("??? (%d)\n", val);
11257 break;
11258 }
11259 return p;
11260
11261 case Tag_ABI_array_object_alignment:
11262 val = read_uleb128 (p, &len);
11263 p += len;
11264 printf (" Tag_ABI_array_object_alignment: ");
11265 switch (val)
11266 {
11267 case 0:
11268 printf (_("8-byte\n"));
11269 break;
11270 case 1:
11271 printf (_("4-byte\n"));
11272 break;
11273 case 2:
11274 printf (_("16-byte\n"));
11275 break;
11276 default:
11277 printf ("??? (%d)\n", val);
11278 break;
11279 }
11280 return p;
11281
11282 case Tag_ABI_array_object_align_expected:
11283 val = read_uleb128 (p, &len);
11284 p += len;
11285 printf (" Tag_ABI_array_object_align_expected: ");
11286 switch (val)
11287 {
11288 case 0:
11289 printf (_("8-byte\n"));
11290 break;
11291 case 1:
11292 printf (_("4-byte\n"));
11293 break;
11294 case 2:
11295 printf (_("16-byte\n"));
11296 break;
11297 default:
11298 printf ("??? (%d)\n", val);
11299 break;
11300 }
11301 return p;
11302
3cbd1c06 11303 case Tag_ABI_compatibility:
59e6276b
JM
11304 val = read_uleb128 (p, &len);
11305 p += len;
3cbd1c06 11306 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11307 printf (_("flag = %d, vendor = %s\n"), val, p);
11308 p += strlen ((char *) p) + 1;
11309 return p;
87779176
JM
11310
11311 case Tag_ABI_conformance:
11312 printf (" Tag_ABI_conformance: ");
11313 printf ("\"%s\"\n", p);
11314 p += strlen ((char *) p) + 1;
11315 return p;
59e6276b
JM
11316 }
11317
11318 printf (" Tag_unknown_%d: ", tag);
11319
87779176
JM
11320 if (tag & 1)
11321 {
11322 printf ("\"%s\"\n", p);
11323 p += strlen ((char *) p) + 1;
11324 }
11325 else
11326 {
11327 val = read_uleb128 (p, &len);
11328 p += len;
11329 printf ("%d (0x%x)\n", val, val);
11330 }
59e6276b
JM
11331
11332 return p;
11333}
11334
11c1ff18 11335static int
60bca95a
NC
11336process_attributes (FILE * file,
11337 const char * public_name,
104d59d1 11338 unsigned int proc_type,
60bca95a
NC
11339 unsigned char * (* display_pub_attribute) (unsigned char *),
11340 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11341{
2cf0635d
NC
11342 Elf_Internal_Shdr * sect;
11343 unsigned char * contents;
11344 unsigned char * p;
11345 unsigned char * end;
11c1ff18
PB
11346 bfd_vma section_len;
11347 bfd_vma len;
11348 unsigned i;
11349
11350 /* Find the section header so that we get the size. */
11351 for (i = 0, sect = section_headers;
11352 i < elf_header.e_shnum;
11353 i++, sect++)
11354 {
104d59d1 11355 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11356 continue;
11357
3f5e193b
NC
11358 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11359 sect->sh_size, _("attributes"));
60bca95a 11360 if (contents == NULL)
11c1ff18 11361 continue;
60bca95a 11362
11c1ff18
PB
11363 p = contents;
11364 if (*p == 'A')
11365 {
11366 len = sect->sh_size - 1;
11367 p++;
60bca95a 11368
11c1ff18
PB
11369 while (len > 0)
11370 {
11371 int namelen;
11372 bfd_boolean public_section;
104d59d1 11373 bfd_boolean gnu_section;
11c1ff18
PB
11374
11375 section_len = byte_get (p, 4);
11376 p += 4;
60bca95a 11377
11c1ff18
PB
11378 if (section_len > len)
11379 {
11380 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11381 (int) section_len, (int) len);
11c1ff18
PB
11382 section_len = len;
11383 }
60bca95a 11384
11c1ff18 11385 len -= section_len;
2b692964 11386 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11387
11388 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11389 public_section = TRUE;
11390 else
11391 public_section = FALSE;
60bca95a
NC
11392
11393 if (streq ((char *) p, "gnu"))
104d59d1
JM
11394 gnu_section = TRUE;
11395 else
11396 gnu_section = FALSE;
60bca95a
NC
11397
11398 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11399 p += namelen;
11400 section_len -= namelen + 4;
60bca95a 11401
11c1ff18
PB
11402 while (section_len > 0)
11403 {
11404 int tag = *(p++);
11405 int val;
11406 bfd_vma size;
60bca95a 11407
11c1ff18
PB
11408 size = byte_get (p, 4);
11409 if (size > section_len)
11410 {
11411 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11412 (int) size, (int) section_len);
11c1ff18
PB
11413 size = section_len;
11414 }
60bca95a 11415
11c1ff18
PB
11416 section_len -= size;
11417 end = p + size - 1;
11418 p += 4;
60bca95a 11419
11c1ff18
PB
11420 switch (tag)
11421 {
11422 case 1:
2b692964 11423 printf (_("File Attributes\n"));
11c1ff18
PB
11424 break;
11425 case 2:
2b692964 11426 printf (_("Section Attributes:"));
11c1ff18
PB
11427 goto do_numlist;
11428 case 3:
2b692964 11429 printf (_("Symbol Attributes:"));
11c1ff18
PB
11430 do_numlist:
11431 for (;;)
11432 {
91d6fa6a 11433 unsigned int j;
60bca95a 11434
91d6fa6a
NC
11435 val = read_uleb128 (p, &j);
11436 p += j;
11c1ff18
PB
11437 if (val == 0)
11438 break;
11439 printf (" %d", val);
11440 }
11441 printf ("\n");
11442 break;
11443 default:
2b692964 11444 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
11445 public_section = FALSE;
11446 break;
11447 }
60bca95a 11448
11c1ff18
PB
11449 if (public_section)
11450 {
11451 while (p < end)
104d59d1
JM
11452 p = display_pub_attribute (p);
11453 }
11454 else if (gnu_section)
11455 {
11456 while (p < end)
11457 p = display_gnu_attribute (p,
11458 display_proc_gnu_attribute);
11c1ff18
PB
11459 }
11460 else
11461 {
11462 /* ??? Do something sensible, like dump hex. */
2b692964 11463 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
11464 p = end;
11465 }
11466 }
11467 }
11468 }
11469 else
60bca95a 11470 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 11471
60bca95a 11472 free (contents);
11c1ff18
PB
11473 }
11474 return 1;
11475}
11476
104d59d1 11477static int
2cf0635d 11478process_arm_specific (FILE * file)
104d59d1
JM
11479{
11480 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
11481 display_arm_attribute, NULL);
11482}
11483
34c8bcba 11484static int
2cf0635d 11485process_power_specific (FILE * file)
34c8bcba
JM
11486{
11487 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11488 display_power_gnu_attribute);
11489}
11490
59e6276b
JM
11491static int
11492process_tic6x_specific (FILE * file)
11493{
11494 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
11495 display_tic6x_attribute, NULL);
11496}
11497
ccb4c951
RS
11498/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
11499 Print the Address, Access and Initial fields of an entry at VMA ADDR
11500 and return the VMA of the next entry. */
11501
11502static bfd_vma
2cf0635d 11503print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
11504{
11505 printf (" ");
11506 print_vma (addr, LONG_HEX);
11507 printf (" ");
11508 if (addr < pltgot + 0xfff0)
11509 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
11510 else
11511 printf ("%10s", "");
11512 printf (" ");
11513 if (data == NULL)
2b692964 11514 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
11515 else
11516 {
11517 bfd_vma entry;
11518
11519 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11520 print_vma (entry, LONG_HEX);
11521 }
11522 return addr + (is_32bit_elf ? 4 : 8);
11523}
11524
861fb55a
DJ
11525/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
11526 PLTGOT. Print the Address and Initial fields of an entry at VMA
11527 ADDR and return the VMA of the next entry. */
11528
11529static bfd_vma
2cf0635d 11530print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
11531{
11532 printf (" ");
11533 print_vma (addr, LONG_HEX);
11534 printf (" ");
11535 if (data == NULL)
2b692964 11536 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
11537 else
11538 {
11539 bfd_vma entry;
11540
11541 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11542 print_vma (entry, LONG_HEX);
11543 }
11544 return addr + (is_32bit_elf ? 4 : 8);
11545}
11546
19e6b90e 11547static int
2cf0635d 11548process_mips_specific (FILE * file)
5b18a4bc 11549{
2cf0635d 11550 Elf_Internal_Dyn * entry;
19e6b90e
L
11551 size_t liblist_offset = 0;
11552 size_t liblistno = 0;
11553 size_t conflictsno = 0;
11554 size_t options_offset = 0;
11555 size_t conflicts_offset = 0;
861fb55a
DJ
11556 size_t pltrelsz = 0;
11557 size_t pltrel = 0;
ccb4c951 11558 bfd_vma pltgot = 0;
861fb55a
DJ
11559 bfd_vma mips_pltgot = 0;
11560 bfd_vma jmprel = 0;
ccb4c951
RS
11561 bfd_vma local_gotno = 0;
11562 bfd_vma gotsym = 0;
11563 bfd_vma symtabno = 0;
103f02d3 11564
2cf19d5c
JM
11565 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11566 display_mips_gnu_attribute);
11567
19e6b90e
L
11568 /* We have a lot of special sections. Thanks SGI! */
11569 if (dynamic_section == NULL)
11570 /* No information available. */
11571 return 0;
252b5132 11572
b2d38a17 11573 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
11574 switch (entry->d_tag)
11575 {
11576 case DT_MIPS_LIBLIST:
d93f0186
NC
11577 liblist_offset
11578 = offset_from_vma (file, entry->d_un.d_val,
11579 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
11580 break;
11581 case DT_MIPS_LIBLISTNO:
11582 liblistno = entry->d_un.d_val;
11583 break;
11584 case DT_MIPS_OPTIONS:
d93f0186 11585 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
11586 break;
11587 case DT_MIPS_CONFLICT:
d93f0186
NC
11588 conflicts_offset
11589 = offset_from_vma (file, entry->d_un.d_val,
11590 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
11591 break;
11592 case DT_MIPS_CONFLICTNO:
11593 conflictsno = entry->d_un.d_val;
11594 break;
ccb4c951 11595 case DT_PLTGOT:
861fb55a
DJ
11596 pltgot = entry->d_un.d_ptr;
11597 break;
ccb4c951
RS
11598 case DT_MIPS_LOCAL_GOTNO:
11599 local_gotno = entry->d_un.d_val;
11600 break;
11601 case DT_MIPS_GOTSYM:
11602 gotsym = entry->d_un.d_val;
11603 break;
11604 case DT_MIPS_SYMTABNO:
11605 symtabno = entry->d_un.d_val;
11606 break;
861fb55a
DJ
11607 case DT_MIPS_PLTGOT:
11608 mips_pltgot = entry->d_un.d_ptr;
11609 break;
11610 case DT_PLTREL:
11611 pltrel = entry->d_un.d_val;
11612 break;
11613 case DT_PLTRELSZ:
11614 pltrelsz = entry->d_un.d_val;
11615 break;
11616 case DT_JMPREL:
11617 jmprel = entry->d_un.d_ptr;
11618 break;
252b5132
RH
11619 default:
11620 break;
11621 }
11622
11623 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
11624 {
2cf0635d 11625 Elf32_External_Lib * elib;
252b5132
RH
11626 size_t cnt;
11627
3f5e193b
NC
11628 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
11629 liblistno,
11630 sizeof (Elf32_External_Lib),
11631 _("liblist"));
a6e9f9df 11632 if (elib)
252b5132 11633 {
2b692964 11634 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 11635 (unsigned long) liblistno);
2b692964 11636 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
11637 stdout);
11638
11639 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 11640 {
a6e9f9df 11641 Elf32_Lib liblist;
91d6fa6a 11642 time_t atime;
a6e9f9df 11643 char timebuf[20];
2cf0635d 11644 struct tm * tmp;
a6e9f9df
AM
11645
11646 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 11647 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
11648 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11649 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11650 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11651
91d6fa6a 11652 tmp = gmtime (&atime);
e9e44622
JJ
11653 snprintf (timebuf, sizeof (timebuf),
11654 "%04u-%02u-%02uT%02u:%02u:%02u",
11655 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11656 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 11657
31104126 11658 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
11659 if (VALID_DYNAMIC_NAME (liblist.l_name))
11660 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
11661 else
2b692964 11662 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
11663 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
11664 liblist.l_version);
a6e9f9df
AM
11665
11666 if (liblist.l_flags == 0)
2b692964 11667 puts (_(" NONE"));
a6e9f9df
AM
11668 else
11669 {
11670 static const struct
252b5132 11671 {
2cf0635d 11672 const char * name;
a6e9f9df 11673 int bit;
252b5132 11674 }
a6e9f9df
AM
11675 l_flags_vals[] =
11676 {
11677 { " EXACT_MATCH", LL_EXACT_MATCH },
11678 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
11679 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
11680 { " EXPORTS", LL_EXPORTS },
11681 { " DELAY_LOAD", LL_DELAY_LOAD },
11682 { " DELTA", LL_DELTA }
11683 };
11684 int flags = liblist.l_flags;
11685 size_t fcnt;
11686
60bca95a 11687 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
11688 if ((flags & l_flags_vals[fcnt].bit) != 0)
11689 {
11690 fputs (l_flags_vals[fcnt].name, stdout);
11691 flags ^= l_flags_vals[fcnt].bit;
11692 }
11693 if (flags != 0)
11694 printf (" %#x", (unsigned int) flags);
252b5132 11695
a6e9f9df
AM
11696 puts ("");
11697 }
252b5132 11698 }
252b5132 11699
a6e9f9df
AM
11700 free (elib);
11701 }
252b5132
RH
11702 }
11703
11704 if (options_offset != 0)
11705 {
2cf0635d
NC
11706 Elf_External_Options * eopt;
11707 Elf_Internal_Shdr * sect = section_headers;
11708 Elf_Internal_Options * iopt;
11709 Elf_Internal_Options * option;
252b5132
RH
11710 size_t offset;
11711 int cnt;
11712
11713 /* Find the section header so that we get the size. */
11714 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 11715 ++sect;
252b5132 11716
3f5e193b
NC
11717 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
11718 sect->sh_size, _("options"));
a6e9f9df 11719 if (eopt)
252b5132 11720 {
3f5e193b
NC
11721 iopt = (Elf_Internal_Options *)
11722 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
11723 if (iopt == NULL)
11724 {
591a748a 11725 error (_("Out of memory\n"));
a6e9f9df
AM
11726 return 0;
11727 }
76da6bbe 11728
a6e9f9df
AM
11729 offset = cnt = 0;
11730 option = iopt;
252b5132 11731
a6e9f9df
AM
11732 while (offset < sect->sh_size)
11733 {
2cf0635d 11734 Elf_External_Options * eoption;
252b5132 11735
a6e9f9df 11736 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 11737
a6e9f9df
AM
11738 option->kind = BYTE_GET (eoption->kind);
11739 option->size = BYTE_GET (eoption->size);
11740 option->section = BYTE_GET (eoption->section);
11741 option->info = BYTE_GET (eoption->info);
76da6bbe 11742
a6e9f9df 11743 offset += option->size;
252b5132 11744
a6e9f9df
AM
11745 ++option;
11746 ++cnt;
11747 }
252b5132 11748
a6e9f9df
AM
11749 printf (_("\nSection '%s' contains %d entries:\n"),
11750 SECTION_NAME (sect), cnt);
76da6bbe 11751
a6e9f9df 11752 option = iopt;
252b5132 11753
a6e9f9df 11754 while (cnt-- > 0)
252b5132 11755 {
a6e9f9df
AM
11756 size_t len;
11757
11758 switch (option->kind)
252b5132 11759 {
a6e9f9df
AM
11760 case ODK_NULL:
11761 /* This shouldn't happen. */
11762 printf (" NULL %d %lx", option->section, option->info);
11763 break;
11764 case ODK_REGINFO:
11765 printf (" REGINFO ");
11766 if (elf_header.e_machine == EM_MIPS)
11767 {
11768 /* 32bit form. */
2cf0635d 11769 Elf32_External_RegInfo * ereg;
b34976b6 11770 Elf32_RegInfo reginfo;
a6e9f9df
AM
11771
11772 ereg = (Elf32_External_RegInfo *) (option + 1);
11773 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11774 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11775 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11776 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11777 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
11778 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
11779
11780 printf ("GPR %08lx GP 0x%lx\n",
11781 reginfo.ri_gprmask,
11782 (unsigned long) reginfo.ri_gp_value);
11783 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11784 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11785 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11786 }
11787 else
11788 {
11789 /* 64 bit form. */
2cf0635d 11790 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
11791 Elf64_Internal_RegInfo reginfo;
11792
11793 ereg = (Elf64_External_RegInfo *) (option + 1);
11794 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11795 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11796 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11797 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11798 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 11799 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
11800
11801 printf ("GPR %08lx GP 0x",
11802 reginfo.ri_gprmask);
11803 printf_vma (reginfo.ri_gp_value);
11804 printf ("\n");
11805
11806 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11807 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11808 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11809 }
11810 ++option;
11811 continue;
11812 case ODK_EXCEPTIONS:
11813 fputs (" EXCEPTIONS fpe_min(", stdout);
11814 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
11815 fputs (") fpe_max(", stdout);
11816 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
11817 fputs (")", stdout);
11818
11819 if (option->info & OEX_PAGE0)
11820 fputs (" PAGE0", stdout);
11821 if (option->info & OEX_SMM)
11822 fputs (" SMM", stdout);
11823 if (option->info & OEX_FPDBUG)
11824 fputs (" FPDBUG", stdout);
11825 if (option->info & OEX_DISMISS)
11826 fputs (" DISMISS", stdout);
11827 break;
11828 case ODK_PAD:
11829 fputs (" PAD ", stdout);
11830 if (option->info & OPAD_PREFIX)
11831 fputs (" PREFIX", stdout);
11832 if (option->info & OPAD_POSTFIX)
11833 fputs (" POSTFIX", stdout);
11834 if (option->info & OPAD_SYMBOL)
11835 fputs (" SYMBOL", stdout);
11836 break;
11837 case ODK_HWPATCH:
11838 fputs (" HWPATCH ", stdout);
11839 if (option->info & OHW_R4KEOP)
11840 fputs (" R4KEOP", stdout);
11841 if (option->info & OHW_R8KPFETCH)
11842 fputs (" R8KPFETCH", stdout);
11843 if (option->info & OHW_R5KEOP)
11844 fputs (" R5KEOP", stdout);
11845 if (option->info & OHW_R5KCVTL)
11846 fputs (" R5KCVTL", stdout);
11847 break;
11848 case ODK_FILL:
11849 fputs (" FILL ", stdout);
11850 /* XXX Print content of info word? */
11851 break;
11852 case ODK_TAGS:
11853 fputs (" TAGS ", stdout);
11854 /* XXX Print content of info word? */
11855 break;
11856 case ODK_HWAND:
11857 fputs (" HWAND ", stdout);
11858 if (option->info & OHWA0_R4KEOP_CHECKED)
11859 fputs (" R4KEOP_CHECKED", stdout);
11860 if (option->info & OHWA0_R4KEOP_CLEAN)
11861 fputs (" R4KEOP_CLEAN", stdout);
11862 break;
11863 case ODK_HWOR:
11864 fputs (" HWOR ", stdout);
11865 if (option->info & OHWA0_R4KEOP_CHECKED)
11866 fputs (" R4KEOP_CHECKED", stdout);
11867 if (option->info & OHWA0_R4KEOP_CLEAN)
11868 fputs (" R4KEOP_CLEAN", stdout);
11869 break;
11870 case ODK_GP_GROUP:
11871 printf (" GP_GROUP %#06lx self-contained %#06lx",
11872 option->info & OGP_GROUP,
11873 (option->info & OGP_SELF) >> 16);
11874 break;
11875 case ODK_IDENT:
11876 printf (" IDENT %#06lx self-contained %#06lx",
11877 option->info & OGP_GROUP,
11878 (option->info & OGP_SELF) >> 16);
11879 break;
11880 default:
11881 /* This shouldn't happen. */
11882 printf (" %3d ??? %d %lx",
11883 option->kind, option->section, option->info);
11884 break;
252b5132 11885 }
a6e9f9df 11886
2cf0635d 11887 len = sizeof (* eopt);
a6e9f9df
AM
11888 while (len < option->size)
11889 if (((char *) option)[len] >= ' '
11890 && ((char *) option)[len] < 0x7f)
11891 printf ("%c", ((char *) option)[len++]);
11892 else
11893 printf ("\\%03o", ((char *) option)[len++]);
11894
11895 fputs ("\n", stdout);
252b5132 11896 ++option;
252b5132
RH
11897 }
11898
a6e9f9df 11899 free (eopt);
252b5132 11900 }
252b5132
RH
11901 }
11902
11903 if (conflicts_offset != 0 && conflictsno != 0)
11904 {
2cf0635d 11905 Elf32_Conflict * iconf;
252b5132
RH
11906 size_t cnt;
11907
11908 if (dynamic_symbols == NULL)
11909 {
591a748a 11910 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
11911 return 0;
11912 }
11913
3f5e193b 11914 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
11915 if (iconf == NULL)
11916 {
591a748a 11917 error (_("Out of memory\n"));
252b5132
RH
11918 return 0;
11919 }
11920
9ea033b2 11921 if (is_32bit_elf)
252b5132 11922 {
2cf0635d 11923 Elf32_External_Conflict * econf32;
a6e9f9df 11924
3f5e193b
NC
11925 econf32 = (Elf32_External_Conflict *)
11926 get_data (NULL, file, conflicts_offset, conflictsno,
11927 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
11928 if (!econf32)
11929 return 0;
252b5132
RH
11930
11931 for (cnt = 0; cnt < conflictsno; ++cnt)
11932 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
11933
11934 free (econf32);
252b5132
RH
11935 }
11936 else
11937 {
2cf0635d 11938 Elf64_External_Conflict * econf64;
a6e9f9df 11939
3f5e193b
NC
11940 econf64 = (Elf64_External_Conflict *)
11941 get_data (NULL, file, conflicts_offset, conflictsno,
11942 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
11943 if (!econf64)
11944 return 0;
252b5132
RH
11945
11946 for (cnt = 0; cnt < conflictsno; ++cnt)
11947 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
11948
11949 free (econf64);
252b5132
RH
11950 }
11951
c7e7ca54
NC
11952 printf (_("\nSection '.conflict' contains %lu entries:\n"),
11953 (unsigned long) conflictsno);
252b5132
RH
11954 puts (_(" Num: Index Value Name"));
11955
11956 for (cnt = 0; cnt < conflictsno; ++cnt)
11957 {
2cf0635d 11958 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 11959
b34976b6 11960 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 11961 print_vma (psym->st_value, FULL_HEX);
31104126 11962 putchar (' ');
d79b3d50
NC
11963 if (VALID_DYNAMIC_NAME (psym->st_name))
11964 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11965 else
2b692964 11966 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 11967 putchar ('\n');
252b5132
RH
11968 }
11969
252b5132
RH
11970 free (iconf);
11971 }
11972
ccb4c951
RS
11973 if (pltgot != 0 && local_gotno != 0)
11974 {
91d6fa6a 11975 bfd_vma ent, local_end, global_end;
bbeee7ea 11976 size_t i, offset;
2cf0635d 11977 unsigned char * data;
bbeee7ea 11978 int addr_size;
ccb4c951 11979
91d6fa6a 11980 ent = pltgot;
ccb4c951
RS
11981 addr_size = (is_32bit_elf ? 4 : 8);
11982 local_end = pltgot + local_gotno * addr_size;
11983 global_end = local_end + (symtabno - gotsym) * addr_size;
11984
11985 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b
NC
11986 data = (unsigned char *) get_data (NULL, file, offset,
11987 global_end - pltgot, 1, _("GOT"));
59245841
NC
11988 if (data == NULL)
11989 return 0;
11990
ccb4c951
RS
11991 printf (_("\nPrimary GOT:\n"));
11992 printf (_(" Canonical gp value: "));
11993 print_vma (pltgot + 0x7ff0, LONG_HEX);
11994 printf ("\n\n");
11995
11996 printf (_(" Reserved entries:\n"));
11997 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
11998 addr_size * 2, _("Address"), _("Access"),
11999 addr_size * 2, _("Initial"));
91d6fa6a 12000 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12001 printf (_(" Lazy resolver\n"));
ccb4c951 12002 if (data
91d6fa6a 12003 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12004 >> (addr_size * 8 - 1)) != 0)
12005 {
91d6fa6a 12006 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12007 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12008 }
12009 printf ("\n");
12010
91d6fa6a 12011 if (ent < local_end)
ccb4c951
RS
12012 {
12013 printf (_(" Local entries:\n"));
cc5914eb 12014 printf (" %*s %10s %*s\n",
2b692964
NC
12015 addr_size * 2, _("Address"), _("Access"),
12016 addr_size * 2, _("Initial"));
91d6fa6a 12017 while (ent < local_end)
ccb4c951 12018 {
91d6fa6a 12019 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12020 printf ("\n");
12021 }
12022 printf ("\n");
12023 }
12024
12025 if (gotsym < symtabno)
12026 {
12027 int sym_width;
12028
12029 printf (_(" Global entries:\n"));
cc5914eb 12030 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
2b692964
NC
12031 addr_size * 2, _("Address"), _("Access"),
12032 addr_size * 2, _("Initial"),
12033 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
ccb4c951
RS
12034 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12035 for (i = gotsym; i < symtabno; i++)
12036 {
2cf0635d 12037 Elf_Internal_Sym * psym;
ccb4c951
RS
12038
12039 psym = dynamic_symbols + i;
91d6fa6a 12040 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12041 printf (" ");
12042 print_vma (psym->st_value, LONG_HEX);
12043 printf (" %-7s %3s ",
12044 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12045 get_symbol_index_type (psym->st_shndx));
12046 if (VALID_DYNAMIC_NAME (psym->st_name))
12047 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12048 else
2b692964 12049 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12050 printf ("\n");
12051 }
12052 printf ("\n");
12053 }
12054
12055 if (data)
12056 free (data);
12057 }
12058
861fb55a
DJ
12059 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12060 {
91d6fa6a 12061 bfd_vma ent, end;
861fb55a
DJ
12062 size_t offset, rel_offset;
12063 unsigned long count, i;
2cf0635d 12064 unsigned char * data;
861fb55a 12065 int addr_size, sym_width;
2cf0635d 12066 Elf_Internal_Rela * rels;
861fb55a
DJ
12067
12068 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12069 if (pltrel == DT_RELA)
12070 {
12071 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12072 return 0;
12073 }
12074 else
12075 {
12076 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12077 return 0;
12078 }
12079
91d6fa6a 12080 ent = mips_pltgot;
861fb55a
DJ
12081 addr_size = (is_32bit_elf ? 4 : 8);
12082 end = mips_pltgot + (2 + count) * addr_size;
12083
12084 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b
NC
12085 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
12086 1, _("PLT GOT"));
59245841
NC
12087 if (data == NULL)
12088 return 0;
12089
861fb55a
DJ
12090 printf (_("\nPLT GOT:\n\n"));
12091 printf (_(" Reserved entries:\n"));
12092 printf (_(" %*s %*s Purpose\n"),
2b692964 12093 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12094 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12095 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12096 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12097 printf (_(" Module pointer\n"));
861fb55a
DJ
12098 printf ("\n");
12099
12100 printf (_(" Entries:\n"));
cc5914eb 12101 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12102 addr_size * 2, _("Address"),
12103 addr_size * 2, _("Initial"),
12104 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12105 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12106 for (i = 0; i < count; i++)
12107 {
2cf0635d 12108 Elf_Internal_Sym * psym;
861fb55a
DJ
12109
12110 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12111 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12112 printf (" ");
12113 print_vma (psym->st_value, LONG_HEX);
12114 printf (" %-7s %3s ",
12115 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12116 get_symbol_index_type (psym->st_shndx));
12117 if (VALID_DYNAMIC_NAME (psym->st_name))
12118 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12119 else
2b692964 12120 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12121 printf ("\n");
12122 }
12123 printf ("\n");
12124
12125 if (data)
12126 free (data);
12127 free (rels);
12128 }
12129
252b5132
RH
12130 return 1;
12131}
12132
047b2264 12133static int
2cf0635d 12134process_gnu_liblist (FILE * file)
047b2264 12135{
2cf0635d
NC
12136 Elf_Internal_Shdr * section;
12137 Elf_Internal_Shdr * string_sec;
12138 Elf32_External_Lib * elib;
12139 char * strtab;
c256ffe7 12140 size_t strtab_size;
047b2264
JJ
12141 size_t cnt;
12142 unsigned i;
12143
12144 if (! do_arch)
12145 return 0;
12146
12147 for (i = 0, section = section_headers;
12148 i < elf_header.e_shnum;
b34976b6 12149 i++, section++)
047b2264
JJ
12150 {
12151 switch (section->sh_type)
12152 {
12153 case SHT_GNU_LIBLIST:
4fbb74a6 12154 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12155 break;
12156
3f5e193b
NC
12157 elib = (Elf32_External_Lib *)
12158 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
12159 _("liblist"));
047b2264
JJ
12160
12161 if (elib == NULL)
12162 break;
4fbb74a6 12163 string_sec = section_headers + section->sh_link;
047b2264 12164
3f5e193b
NC
12165 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12166 string_sec->sh_size,
12167 _("liblist string table"));
047b2264
JJ
12168 if (strtab == NULL
12169 || section->sh_entsize != sizeof (Elf32_External_Lib))
12170 {
12171 free (elib);
2842702f 12172 free (strtab);
047b2264
JJ
12173 break;
12174 }
59245841 12175 strtab_size = string_sec->sh_size;
047b2264
JJ
12176
12177 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12178 SECTION_NAME (section),
0af1713e 12179 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12180
2b692964 12181 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12182
12183 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12184 ++cnt)
12185 {
12186 Elf32_Lib liblist;
91d6fa6a 12187 time_t atime;
047b2264 12188 char timebuf[20];
2cf0635d 12189 struct tm * tmp;
047b2264
JJ
12190
12191 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12192 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12193 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12194 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12195 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12196
91d6fa6a 12197 tmp = gmtime (&atime);
e9e44622
JJ
12198 snprintf (timebuf, sizeof (timebuf),
12199 "%04u-%02u-%02uT%02u:%02u:%02u",
12200 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12201 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12202
12203 printf ("%3lu: ", (unsigned long) cnt);
12204 if (do_wide)
c256ffe7 12205 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12206 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12207 else
c256ffe7 12208 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12209 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12210 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12211 liblist.l_version, liblist.l_flags);
12212 }
12213
12214 free (elib);
2842702f 12215 free (strtab);
047b2264
JJ
12216 }
12217 }
12218
12219 return 1;
12220}
12221
9437c45b 12222static const char *
d3ba0551 12223get_note_type (unsigned e_type)
779fe533
NC
12224{
12225 static char buff[64];
103f02d3 12226
1ec5cd37
NC
12227 if (elf_header.e_type == ET_CORE)
12228 switch (e_type)
12229 {
57346661 12230 case NT_AUXV:
1ec5cd37 12231 return _("NT_AUXV (auxiliary vector)");
57346661 12232 case NT_PRSTATUS:
1ec5cd37 12233 return _("NT_PRSTATUS (prstatus structure)");
57346661 12234 case NT_FPREGSET:
1ec5cd37 12235 return _("NT_FPREGSET (floating point registers)");
57346661 12236 case NT_PRPSINFO:
1ec5cd37 12237 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12238 case NT_TASKSTRUCT:
1ec5cd37 12239 return _("NT_TASKSTRUCT (task structure)");
57346661 12240 case NT_PRXFPREG:
1ec5cd37 12241 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12242 case NT_PPC_VMX:
12243 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12244 case NT_PPC_VSX:
12245 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
12246 case NT_X86_XSTATE:
12247 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12248 case NT_S390_HIGH_GPRS:
12249 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12250 case NT_S390_TIMER:
12251 return _("NT_S390_TIMER (s390 timer register)");
12252 case NT_S390_TODCMP:
12253 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12254 case NT_S390_TODPREG:
12255 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12256 case NT_S390_CTRS:
12257 return _("NT_S390_CTRS (s390 control registers)");
12258 case NT_S390_PREFIX:
12259 return _("NT_S390_PREFIX (s390 prefix register)");
57346661 12260 case NT_PSTATUS:
1ec5cd37 12261 return _("NT_PSTATUS (pstatus structure)");
57346661 12262 case NT_FPREGS:
1ec5cd37 12263 return _("NT_FPREGS (floating point registers)");
57346661 12264 case NT_PSINFO:
1ec5cd37 12265 return _("NT_PSINFO (psinfo structure)");
57346661 12266 case NT_LWPSTATUS:
1ec5cd37 12267 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12268 case NT_LWPSINFO:
1ec5cd37 12269 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12270 case NT_WIN32PSTATUS:
1ec5cd37
NC
12271 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
12272 default:
12273 break;
12274 }
12275 else
12276 switch (e_type)
12277 {
12278 case NT_VERSION:
12279 return _("NT_VERSION (version)");
12280 case NT_ARCH:
12281 return _("NT_ARCH (architecture)");
12282 default:
12283 break;
12284 }
12285
e9e44622 12286 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12287 return buff;
779fe533
NC
12288}
12289
1118d252
RM
12290static const char *
12291get_gnu_elf_note_type (unsigned e_type)
12292{
12293 static char buff[64];
12294
12295 switch (e_type)
12296 {
12297 case NT_GNU_ABI_TAG:
12298 return _("NT_GNU_ABI_TAG (ABI version tag)");
12299 case NT_GNU_HWCAP:
12300 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12301 case NT_GNU_BUILD_ID:
12302 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12303 case NT_GNU_GOLD_VERSION:
12304 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12305 default:
12306 break;
12307 }
12308
12309 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12310 return buff;
12311}
12312
664f90a3
TT
12313static int
12314print_gnu_note (Elf_Internal_Note *pnote)
12315{
12316 switch (pnote->type)
12317 {
12318 case NT_GNU_BUILD_ID:
12319 {
12320 unsigned long i;
12321
12322 printf (_(" Build ID: "));
12323 for (i = 0; i < pnote->descsz; ++i)
12324 printf ("%02x", pnote->descdata[i] & 0xff);
12325 printf (_("\n"));
12326 }
12327 break;
12328
12329 case NT_GNU_ABI_TAG:
12330 {
12331 unsigned long os, major, minor, subminor;
12332 const char *osname;
12333
12334 os = byte_get ((unsigned char *) pnote->descdata, 4);
12335 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
12336 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
12337 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
12338
12339 switch (os)
12340 {
12341 case GNU_ABI_TAG_LINUX:
12342 osname = "Linux";
12343 break;
12344 case GNU_ABI_TAG_HURD:
12345 osname = "Hurd";
12346 break;
12347 case GNU_ABI_TAG_SOLARIS:
12348 osname = "Solaris";
12349 break;
12350 case GNU_ABI_TAG_FREEBSD:
12351 osname = "FreeBSD";
12352 break;
12353 case GNU_ABI_TAG_NETBSD:
12354 osname = "NetBSD";
12355 break;
12356 default:
12357 osname = "Unknown";
12358 break;
12359 }
12360
12361 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
12362 major, minor, subminor);
12363 }
12364 break;
12365 }
12366
12367 return 1;
12368}
12369
9437c45b 12370static const char *
d3ba0551 12371get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
12372{
12373 static char buff[64];
12374
b4db1224 12375 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
12376 {
12377 /* NetBSD core "procinfo" structure. */
12378 return _("NetBSD procinfo structure");
12379 }
12380
12381 /* As of Jan 2002 there are no other machine-independent notes
12382 defined for NetBSD core files. If the note type is less
12383 than the start of the machine-dependent note types, we don't
12384 understand it. */
12385
b4db1224 12386 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 12387 {
e9e44622 12388 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
12389 return buff;
12390 }
12391
12392 switch (elf_header.e_machine)
12393 {
12394 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
12395 and PT_GETFPREGS == mach+2. */
12396
12397 case EM_OLD_ALPHA:
12398 case EM_ALPHA:
12399 case EM_SPARC:
12400 case EM_SPARC32PLUS:
12401 case EM_SPARCV9:
12402 switch (e_type)
12403 {
2b692964 12404 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 12405 return _("PT_GETREGS (reg structure)");
2b692964 12406 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 12407 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12408 default:
12409 break;
12410 }
12411 break;
12412
12413 /* On all other arch's, PT_GETREGS == mach+1 and
12414 PT_GETFPREGS == mach+3. */
12415 default:
12416 switch (e_type)
12417 {
2b692964 12418 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 12419 return _("PT_GETREGS (reg structure)");
2b692964 12420 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 12421 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12422 default:
12423 break;
12424 }
12425 }
12426
e9e44622
JJ
12427 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
12428 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
12429 return buff;
12430}
12431
70616151
TT
12432static const char *
12433get_stapsdt_note_type (unsigned e_type)
12434{
12435 static char buff[64];
12436
12437 switch (e_type)
12438 {
12439 case NT_STAPSDT:
12440 return _("NT_STAPSDT (SystemTap probe descriptors)");
12441
12442 default:
12443 break;
12444 }
12445
12446 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12447 return buff;
12448}
12449
c6a9fc58
TT
12450static int
12451print_stapsdt_note (Elf_Internal_Note *pnote)
12452{
12453 int addr_size = is_32bit_elf ? 4 : 8;
12454 char *data = pnote->descdata;
12455 char *data_end = pnote->descdata + pnote->descsz;
12456 bfd_vma pc, base_addr, semaphore;
12457 char *provider, *probe, *arg_fmt;
12458
12459 pc = byte_get ((unsigned char *) data, addr_size);
12460 data += addr_size;
12461 base_addr = byte_get ((unsigned char *) data, addr_size);
12462 data += addr_size;
12463 semaphore = byte_get ((unsigned char *) data, addr_size);
12464 data += addr_size;
12465
12466 provider = data;
12467 data += strlen (data) + 1;
12468 probe = data;
12469 data += strlen (data) + 1;
12470 arg_fmt = data;
12471 data += strlen (data) + 1;
12472
12473 printf (_(" Provider: %s\n"), provider);
12474 printf (_(" Name: %s\n"), probe);
12475 printf (_(" Location: "));
12476 print_vma (pc, FULL_HEX);
12477 printf (_(", Base: "));
12478 print_vma (base_addr, FULL_HEX);
12479 printf (_(", Semaphore: "));
12480 print_vma (semaphore, FULL_HEX);
12481 printf (_("\n"));
12482 printf (_(" Arguments: %s\n"), arg_fmt);
12483
12484 return data == data_end;
12485}
12486
00e98fc7
TG
12487static const char *
12488get_ia64_vms_note_type (unsigned e_type)
12489{
12490 static char buff[64];
12491
12492 switch (e_type)
12493 {
12494 case NT_VMS_MHD:
12495 return _("NT_VMS_MHD (module header)");
12496 case NT_VMS_LNM:
12497 return _("NT_VMS_LNM (language name)");
12498 case NT_VMS_SRC:
12499 return _("NT_VMS_SRC (source files)");
12500 case NT_VMS_TITLE:
12501 return _("NT_VMS_TITLE");
12502 case NT_VMS_EIDC:
12503 return _("NT_VMS_EIDC (consistency check)");
12504 case NT_VMS_FPMODE:
12505 return _("NT_VMS_FPMODE (FP mode)");
12506 case NT_VMS_LINKTIME:
12507 return _("NT_VMS_LINKTIME");
12508 case NT_VMS_IMGNAM:
12509 return _("NT_VMS_IMGNAM (image name)");
12510 case NT_VMS_IMGID:
12511 return _("NT_VMS_IMGID (image id)");
12512 case NT_VMS_LINKID:
12513 return _("NT_VMS_LINKID (link id)");
12514 case NT_VMS_IMGBID:
12515 return _("NT_VMS_IMGBID (build id)");
12516 case NT_VMS_GSTNAM:
12517 return _("NT_VMS_GSTNAM (sym table name)");
12518 case NT_VMS_ORIG_DYN:
12519 return _("NT_VMS_ORIG_DYN");
12520 case NT_VMS_PATCHTIME:
12521 return _("NT_VMS_PATCHTIME");
12522 default:
12523 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12524 return buff;
12525 }
12526}
12527
12528static int
12529print_ia64_vms_note (Elf_Internal_Note * pnote)
12530{
12531 switch (pnote->type)
12532 {
12533 case NT_VMS_MHD:
12534 if (pnote->descsz > 36)
12535 {
12536 size_t l = strlen (pnote->descdata + 34);
12537 printf (_(" Creation date : %.17s\n"), pnote->descdata);
12538 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
12539 printf (_(" Module name : %s\n"), pnote->descdata + 34);
12540 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
12541 }
12542 else
12543 printf (_(" Invalid size\n"));
12544 break;
12545 case NT_VMS_LNM:
12546 printf (_(" Language: %s\n"), pnote->descdata);
12547 break;
12548#ifdef BFD64
12549 case NT_VMS_FPMODE:
12550 printf (_(" FP mode: 0x%016" BFD_VMA_FMT "x\n"),
12551 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
12552 break;
12553 case NT_VMS_LINKTIME:
12554 printf (_(" Link time: "));
12555 print_vms_time
12556 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12557 printf ("\n");
12558 break;
12559 case NT_VMS_PATCHTIME:
12560 printf (_(" Patch time: "));
12561 print_vms_time
12562 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12563 printf ("\n");
12564 break;
12565 case NT_VMS_ORIG_DYN:
12566 printf (_(" Major id: %u, minor id: %u\n"),
12567 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
12568 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
12569 printf (_(" Manip date : "));
12570 print_vms_time
12571 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
12572 printf (_("\n"
12573 " Link flags : 0x%016" BFD_VMA_FMT "x\n"),
12574 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
12575 printf (_(" Header flags: 0x%08x\n"),
12576 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
12577 printf (_(" Image id : %s\n"), pnote->descdata + 32);
12578 break;
12579#endif
12580 case NT_VMS_IMGNAM:
12581 printf (_(" Image name: %s\n"), pnote->descdata);
12582 break;
12583 case NT_VMS_GSTNAM:
12584 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
12585 break;
12586 case NT_VMS_IMGID:
12587 printf (_(" Image id: %s\n"), pnote->descdata);
12588 break;
12589 case NT_VMS_LINKID:
12590 printf (_(" Linker id: %s\n"), pnote->descdata);
12591 break;
12592 default:
12593 break;
12594 }
12595 return 1;
12596}
12597
6d118b09
NC
12598/* Note that by the ELF standard, the name field is already null byte
12599 terminated, and namesz includes the terminating null byte.
12600 I.E. the value of namesz for the name "FSF" is 4.
12601
e3c8793a 12602 If the value of namesz is zero, there is no name present. */
779fe533 12603static int
2cf0635d 12604process_note (Elf_Internal_Note * pnote)
779fe533 12605{
2cf0635d
NC
12606 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
12607 const char * nt;
9437c45b
JT
12608
12609 if (pnote->namesz == 0)
1ec5cd37
NC
12610 /* If there is no note name, then use the default set of
12611 note type strings. */
12612 nt = get_note_type (pnote->type);
12613
1118d252
RM
12614 else if (const_strneq (pnote->namedata, "GNU"))
12615 /* GNU-specific object file notes. */
12616 nt = get_gnu_elf_note_type (pnote->type);
12617
0112cd26 12618 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
12619 /* NetBSD-specific core file notes. */
12620 nt = get_netbsd_elfcore_note_type (pnote->type);
12621
b15fa79e
AM
12622 else if (strneq (pnote->namedata, "SPU/", 4))
12623 {
12624 /* SPU-specific core file notes. */
12625 nt = pnote->namedata + 4;
12626 name = "SPU";
12627 }
12628
00e98fc7
TG
12629 else if (const_strneq (pnote->namedata, "IPF/VMS"))
12630 /* VMS/ia64-specific file notes. */
12631 nt = get_ia64_vms_note_type (pnote->type);
12632
70616151
TT
12633 else if (const_strneq (pnote->namedata, "stapsdt"))
12634 nt = get_stapsdt_note_type (pnote->type);
12635
9437c45b 12636 else
1ec5cd37
NC
12637 /* Don't recognize this note name; just use the default set of
12638 note type strings. */
00e98fc7 12639 nt = get_note_type (pnote->type);
9437c45b 12640
2aee03ae 12641 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
12642
12643 if (const_strneq (pnote->namedata, "IPF/VMS"))
12644 return print_ia64_vms_note (pnote);
664f90a3
TT
12645 else if (const_strneq (pnote->namedata, "GNU"))
12646 return print_gnu_note (pnote);
c6a9fc58
TT
12647 else if (const_strneq (pnote->namedata, "stapsdt"))
12648 return print_stapsdt_note (pnote);
00e98fc7
TG
12649 else
12650 return 1;
779fe533
NC
12651}
12652
6d118b09 12653
779fe533 12654static int
2cf0635d 12655process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 12656{
2cf0635d
NC
12657 Elf_External_Note * pnotes;
12658 Elf_External_Note * external;
b34976b6 12659 int res = 1;
103f02d3 12660
779fe533
NC
12661 if (length <= 0)
12662 return 0;
103f02d3 12663
3f5e193b
NC
12664 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
12665 _("notes"));
dd24e3da 12666 if (pnotes == NULL)
a6e9f9df 12667 return 0;
779fe533 12668
103f02d3 12669 external = pnotes;
103f02d3 12670
305c7206 12671 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 12672 (unsigned long) offset, (unsigned long) length);
2aee03ae 12673 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 12674
2cf0635d 12675 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 12676 {
2cf0635d 12677 Elf_External_Note * next;
b34976b6 12678 Elf_Internal_Note inote;
2cf0635d 12679 char * temp = NULL;
6d118b09 12680
00e98fc7
TG
12681 if (!is_ia64_vms ())
12682 {
12683 inote.type = BYTE_GET (external->type);
12684 inote.namesz = BYTE_GET (external->namesz);
12685 inote.namedata = external->name;
12686 inote.descsz = BYTE_GET (external->descsz);
12687 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
12688 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12689
12690 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
12691 }
12692 else
12693 {
12694 Elf64_External_VMS_Note *vms_external;
12695
12696 vms_external = (Elf64_External_VMS_Note *)external;
12697 inote.type = BYTE_GET (vms_external->type);
12698 inote.namesz = BYTE_GET (vms_external->namesz);
12699 inote.namedata = vms_external->name;
12700 inote.descsz = BYTE_GET (vms_external->descsz);
12701 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
12702 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12703
12704 next = (Elf_External_Note *)
12705 (inote.descdata + align_power (inote.descsz, 3));
12706 }
3e55a963 12707
dd24e3da
NC
12708 if ( ((char *) next > ((char *) pnotes) + length)
12709 || ((char *) next < (char *) pnotes))
3e55a963 12710 {
0fd3a477 12711 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 12712 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 12713 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
12714 inote.type, inote.namesz, inote.descsz);
12715 break;
12716 }
12717
12718 external = next;
6d118b09 12719
dd24e3da
NC
12720 /* Prevent out-of-bounds indexing. */
12721 if (inote.namedata + inote.namesz >= (char *) pnotes + length
12722 || inote.namedata + inote.namesz < inote.namedata)
12723 {
12724 warn (_("corrupt note found at offset %lx into core notes\n"),
12725 (unsigned long) ((char *) external - (char *) pnotes));
12726 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
12727 inote.type, inote.namesz, inote.descsz);
12728 break;
12729 }
12730
6d118b09
NC
12731 /* Verify that name is null terminated. It appears that at least
12732 one version of Linux (RedHat 6.0) generates corefiles that don't
12733 comply with the ELF spec by failing to include the null byte in
12734 namesz. */
12735 if (inote.namedata[inote.namesz] != '\0')
12736 {
3f5e193b 12737 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 12738
6d118b09
NC
12739 if (temp == NULL)
12740 {
12741 error (_("Out of memory\n"));
12742 res = 0;
12743 break;
12744 }
76da6bbe 12745
6d118b09
NC
12746 strncpy (temp, inote.namedata, inote.namesz);
12747 temp[inote.namesz] = 0;
76da6bbe 12748
6d118b09
NC
12749 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
12750 inote.namedata = temp;
12751 }
12752
12753 res &= process_note (& inote);
103f02d3 12754
6d118b09
NC
12755 if (temp != NULL)
12756 {
12757 free (temp);
12758 temp = NULL;
12759 }
779fe533
NC
12760 }
12761
12762 free (pnotes);
103f02d3 12763
779fe533
NC
12764 return res;
12765}
12766
12767static int
2cf0635d 12768process_corefile_note_segments (FILE * file)
779fe533 12769{
2cf0635d 12770 Elf_Internal_Phdr * segment;
b34976b6
AM
12771 unsigned int i;
12772 int res = 1;
103f02d3 12773
d93f0186 12774 if (! get_program_headers (file))
779fe533 12775 return 0;
103f02d3 12776
779fe533
NC
12777 for (i = 0, segment = program_headers;
12778 i < elf_header.e_phnum;
b34976b6 12779 i++, segment++)
779fe533
NC
12780 {
12781 if (segment->p_type == PT_NOTE)
103f02d3 12782 res &= process_corefile_note_segment (file,
30800947
NC
12783 (bfd_vma) segment->p_offset,
12784 (bfd_vma) segment->p_filesz);
779fe533 12785 }
103f02d3 12786
779fe533
NC
12787 return res;
12788}
12789
12790static int
2cf0635d 12791process_note_sections (FILE * file)
1ec5cd37 12792{
2cf0635d 12793 Elf_Internal_Shdr * section;
1ec5cd37
NC
12794 unsigned long i;
12795 int res = 1;
12796
12797 for (i = 0, section = section_headers;
12798 i < elf_header.e_shnum;
12799 i++, section++)
12800 if (section->sh_type == SHT_NOTE)
12801 res &= process_corefile_note_segment (file,
12802 (bfd_vma) section->sh_offset,
12803 (bfd_vma) section->sh_size);
12804
12805 return res;
12806}
12807
12808static int
2cf0635d 12809process_notes (FILE * file)
779fe533
NC
12810{
12811 /* If we have not been asked to display the notes then do nothing. */
12812 if (! do_notes)
12813 return 1;
103f02d3 12814
779fe533 12815 if (elf_header.e_type != ET_CORE)
1ec5cd37 12816 return process_note_sections (file);
103f02d3 12817
779fe533 12818 /* No program headers means no NOTE segment. */
1ec5cd37
NC
12819 if (elf_header.e_phnum > 0)
12820 return process_corefile_note_segments (file);
779fe533 12821
1ec5cd37
NC
12822 printf (_("No note segments present in the core file.\n"));
12823 return 1;
779fe533
NC
12824}
12825
252b5132 12826static int
2cf0635d 12827process_arch_specific (FILE * file)
252b5132 12828{
a952a375
NC
12829 if (! do_arch)
12830 return 1;
12831
252b5132
RH
12832 switch (elf_header.e_machine)
12833 {
11c1ff18
PB
12834 case EM_ARM:
12835 return process_arm_specific (file);
252b5132 12836 case EM_MIPS:
4fe85591 12837 case EM_MIPS_RS3_LE:
252b5132
RH
12838 return process_mips_specific (file);
12839 break;
34c8bcba
JM
12840 case EM_PPC:
12841 return process_power_specific (file);
12842 break;
59e6276b
JM
12843 case EM_TI_C6000:
12844 return process_tic6x_specific (file);
12845 break;
252b5132
RH
12846 default:
12847 break;
12848 }
12849 return 1;
12850}
12851
12852static int
2cf0635d 12853get_file_header (FILE * file)
252b5132 12854{
9ea033b2
NC
12855 /* Read in the identity array. */
12856 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
12857 return 0;
12858
9ea033b2 12859 /* Determine how to read the rest of the header. */
b34976b6 12860 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
12861 {
12862 default: /* fall through */
12863 case ELFDATANONE: /* fall through */
adab8cdc
AO
12864 case ELFDATA2LSB:
12865 byte_get = byte_get_little_endian;
12866 byte_put = byte_put_little_endian;
12867 break;
12868 case ELFDATA2MSB:
12869 byte_get = byte_get_big_endian;
12870 byte_put = byte_put_big_endian;
12871 break;
9ea033b2
NC
12872 }
12873
12874 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 12875 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
12876
12877 /* Read in the rest of the header. */
12878 if (is_32bit_elf)
12879 {
12880 Elf32_External_Ehdr ehdr32;
252b5132 12881
9ea033b2
NC
12882 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
12883 return 0;
103f02d3 12884
9ea033b2
NC
12885 elf_header.e_type = BYTE_GET (ehdr32.e_type);
12886 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
12887 elf_header.e_version = BYTE_GET (ehdr32.e_version);
12888 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
12889 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
12890 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
12891 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
12892 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
12893 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
12894 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
12895 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
12896 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
12897 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
12898 }
252b5132 12899 else
9ea033b2
NC
12900 {
12901 Elf64_External_Ehdr ehdr64;
a952a375
NC
12902
12903 /* If we have been compiled with sizeof (bfd_vma) == 4, then
12904 we will not be able to cope with the 64bit data found in
12905 64 ELF files. Detect this now and abort before we start
50c2245b 12906 overwriting things. */
a952a375
NC
12907 if (sizeof (bfd_vma) < 8)
12908 {
e3c8793a
NC
12909 error (_("This instance of readelf has been built without support for a\n\
1291064 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
12911 return 0;
12912 }
103f02d3 12913
9ea033b2
NC
12914 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
12915 return 0;
103f02d3 12916
9ea033b2
NC
12917 elf_header.e_type = BYTE_GET (ehdr64.e_type);
12918 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
12919 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
12920 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
12921 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
12922 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
12923 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
12924 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
12925 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
12926 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
12927 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
12928 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
12929 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
12930 }
252b5132 12931
7ece0d85
JJ
12932 if (elf_header.e_shoff)
12933 {
12934 /* There may be some extensions in the first section header. Don't
12935 bomb if we can't read it. */
12936 if (is_32bit_elf)
12937 get_32bit_section_headers (file, 1);
12938 else
12939 get_64bit_section_headers (file, 1);
12940 }
560f3c1c 12941
252b5132
RH
12942 return 1;
12943}
12944
fb52b2f4
NC
12945/* Process one ELF object file according to the command line options.
12946 This file may actually be stored in an archive. The file is
12947 positioned at the start of the ELF object. */
12948
ff78d6d6 12949static int
2cf0635d 12950process_object (char * file_name, FILE * file)
252b5132 12951{
252b5132
RH
12952 unsigned int i;
12953
252b5132
RH
12954 if (! get_file_header (file))
12955 {
12956 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 12957 return 1;
252b5132
RH
12958 }
12959
12960 /* Initialise per file variables. */
60bca95a 12961 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
12962 version_info[i] = 0;
12963
60bca95a 12964 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 12965 dynamic_info[i] = 0;
5115b233 12966 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
12967
12968 /* Process the file. */
12969 if (show_name)
12970 printf (_("\nFile: %s\n"), file_name);
12971
18bd398b
NC
12972 /* Initialise the dump_sects array from the cmdline_dump_sects array.
12973 Note we do this even if cmdline_dump_sects is empty because we
12974 must make sure that the dump_sets array is zeroed out before each
12975 object file is processed. */
12976 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 12977 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
12978
12979 if (num_cmdline_dump_sects > 0)
12980 {
12981 if (num_dump_sects == 0)
12982 /* A sneaky way of allocating the dump_sects array. */
09c11c86 12983 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
12984
12985 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
12986 memcpy (dump_sects, cmdline_dump_sects,
12987 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 12988 }
d70c5fc7 12989
252b5132 12990 if (! process_file_header ())
fb52b2f4 12991 return 1;
252b5132 12992
d1f5c6e3 12993 if (! process_section_headers (file))
2f62977e 12994 {
d1f5c6e3
L
12995 /* Without loaded section headers we cannot process lots of
12996 things. */
2f62977e 12997 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 12998
2f62977e 12999 if (! do_using_dynamic)
2c610e4b 13000 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13001 }
252b5132 13002
d1f5c6e3
L
13003 if (! process_section_groups (file))
13004 {
13005 /* Without loaded section groups we cannot process unwind. */
13006 do_unwind = 0;
13007 }
13008
2f62977e 13009 if (process_program_headers (file))
b2d38a17 13010 process_dynamic_section (file);
252b5132
RH
13011
13012 process_relocs (file);
13013
4d6ed7c8
NC
13014 process_unwind (file);
13015
252b5132
RH
13016 process_symbol_table (file);
13017
13018 process_syminfo (file);
13019
13020 process_version_sections (file);
13021
13022 process_section_contents (file);
f5842774 13023
1ec5cd37 13024 process_notes (file);
103f02d3 13025
047b2264
JJ
13026 process_gnu_liblist (file);
13027
252b5132
RH
13028 process_arch_specific (file);
13029
d93f0186
NC
13030 if (program_headers)
13031 {
13032 free (program_headers);
13033 program_headers = NULL;
13034 }
13035
252b5132
RH
13036 if (section_headers)
13037 {
13038 free (section_headers);
13039 section_headers = NULL;
13040 }
13041
13042 if (string_table)
13043 {
13044 free (string_table);
13045 string_table = NULL;
d40ac9bd 13046 string_table_length = 0;
252b5132
RH
13047 }
13048
13049 if (dynamic_strings)
13050 {
13051 free (dynamic_strings);
13052 dynamic_strings = NULL;
d79b3d50 13053 dynamic_strings_length = 0;
252b5132
RH
13054 }
13055
13056 if (dynamic_symbols)
13057 {
13058 free (dynamic_symbols);
13059 dynamic_symbols = NULL;
19936277 13060 num_dynamic_syms = 0;
252b5132
RH
13061 }
13062
13063 if (dynamic_syminfo)
13064 {
13065 free (dynamic_syminfo);
13066 dynamic_syminfo = NULL;
13067 }
ff78d6d6 13068
293c573e
MR
13069 if (dynamic_section)
13070 {
13071 free (dynamic_section);
13072 dynamic_section = NULL;
13073 }
13074
e4b17d5c
L
13075 if (section_headers_groups)
13076 {
13077 free (section_headers_groups);
13078 section_headers_groups = NULL;
13079 }
13080
13081 if (section_groups)
13082 {
2cf0635d
NC
13083 struct group_list * g;
13084 struct group_list * next;
e4b17d5c
L
13085
13086 for (i = 0; i < group_count; i++)
13087 {
13088 for (g = section_groups [i].root; g != NULL; g = next)
13089 {
13090 next = g->next;
13091 free (g);
13092 }
13093 }
13094
13095 free (section_groups);
13096 section_groups = NULL;
13097 }
13098
19e6b90e 13099 free_debug_memory ();
18bd398b 13100
ff78d6d6 13101 return 0;
252b5132
RH
13102}
13103
2cf0635d
NC
13104/* Process an ELF archive.
13105 On entry the file is positioned just after the ARMAG string. */
13106
13107static int
13108process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13109{
13110 struct archive_info arch;
13111 struct archive_info nested_arch;
13112 size_t got;
2cf0635d
NC
13113 int ret;
13114
13115 show_name = 1;
13116
13117 /* The ARCH structure is used to hold information about this archive. */
13118 arch.file_name = NULL;
13119 arch.file = NULL;
13120 arch.index_array = NULL;
13121 arch.sym_table = NULL;
13122 arch.longnames = NULL;
13123
13124 /* The NESTED_ARCH structure is used as a single-item cache of information
13125 about a nested archive (when members of a thin archive reside within
13126 another regular archive file). */
13127 nested_arch.file_name = NULL;
13128 nested_arch.file = NULL;
13129 nested_arch.index_array = NULL;
13130 nested_arch.sym_table = NULL;
13131 nested_arch.longnames = NULL;
13132
13133 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13134 {
13135 ret = 1;
13136 goto out;
4145f1d5 13137 }
fb52b2f4 13138
4145f1d5
NC
13139 if (do_archive_index)
13140 {
2cf0635d 13141 if (arch.sym_table == NULL)
4145f1d5
NC
13142 error (_("%s: unable to dump the index as none was found\n"), file_name);
13143 else
13144 {
2cf0635d 13145 unsigned int i, l;
4145f1d5
NC
13146 unsigned long current_pos;
13147
13148 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 13149 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
13150 current_pos = ftell (file);
13151
2cf0635d 13152 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13153 {
2cf0635d
NC
13154 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13155 {
13156 char * member_name;
4145f1d5 13157
2cf0635d
NC
13158 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13159
13160 if (member_name != NULL)
13161 {
13162 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13163
13164 if (qualified_name != NULL)
13165 {
13166 printf (_("Binary %s contains:\n"), qualified_name);
13167 free (qualified_name);
13168 }
4145f1d5
NC
13169 }
13170 }
2cf0635d
NC
13171
13172 if (l >= arch.sym_size)
4145f1d5
NC
13173 {
13174 error (_("%s: end of the symbol table reached before the end of the index\n"),
13175 file_name);
cb8f3167 13176 break;
4145f1d5 13177 }
2cf0635d
NC
13178 printf ("\t%s\n", arch.sym_table + l);
13179 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13180 }
13181
2cf0635d
NC
13182 if (l & 01)
13183 ++l;
13184 if (l < arch.sym_size)
4145f1d5
NC
13185 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
13186 file_name);
13187
4145f1d5
NC
13188 if (fseek (file, current_pos, SEEK_SET) != 0)
13189 {
13190 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13191 ret = 1;
13192 goto out;
4145f1d5 13193 }
fb52b2f4 13194 }
4145f1d5
NC
13195
13196 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13197 && !do_segments && !do_header && !do_dump && !do_version
13198 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13199 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13200 {
13201 ret = 0; /* Archive index only. */
13202 goto out;
13203 }
fb52b2f4
NC
13204 }
13205
d989285c 13206 ret = 0;
fb52b2f4
NC
13207
13208 while (1)
13209 {
2cf0635d
NC
13210 char * name;
13211 size_t namelen;
13212 char * qualified_name;
13213
13214 /* Read the next archive header. */
13215 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13216 {
13217 error (_("%s: failed to seek to next archive header\n"), file_name);
13218 return 1;
13219 }
13220 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13221 if (got != sizeof arch.arhdr)
13222 {
13223 if (got == 0)
13224 break;
13225 error (_("%s: failed to read archive header\n"), file_name);
13226 ret = 1;
13227 break;
13228 }
13229 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13230 {
13231 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13232 ret = 1;
13233 break;
13234 }
13235
13236 arch.next_arhdr_offset += sizeof arch.arhdr;
13237
13238 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13239 if (archive_file_size & 01)
13240 ++archive_file_size;
13241
13242 name = get_archive_member_name (&arch, &nested_arch);
13243 if (name == NULL)
fb52b2f4 13244 {
0fd3a477 13245 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13246 ret = 1;
13247 break;
fb52b2f4 13248 }
2cf0635d 13249 namelen = strlen (name);
fb52b2f4 13250
2cf0635d
NC
13251 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13252 if (qualified_name == NULL)
fb52b2f4 13253 {
2cf0635d 13254 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13255 ret = 1;
13256 break;
fb52b2f4
NC
13257 }
13258
2cf0635d
NC
13259 if (is_thin_archive && arch.nested_member_origin == 0)
13260 {
13261 /* This is a proxy for an external member of a thin archive. */
13262 FILE * member_file;
13263 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13264 if (member_file_name == NULL)
13265 {
13266 ret = 1;
13267 break;
13268 }
13269
13270 member_file = fopen (member_file_name, "rb");
13271 if (member_file == NULL)
13272 {
13273 error (_("Input file '%s' is not readable.\n"), member_file_name);
13274 free (member_file_name);
13275 ret = 1;
13276 break;
13277 }
13278
13279 archive_file_offset = arch.nested_member_origin;
13280
13281 ret |= process_object (qualified_name, member_file);
13282
13283 fclose (member_file);
13284 free (member_file_name);
13285 }
13286 else if (is_thin_archive)
13287 {
13288 /* This is a proxy for a member of a nested archive. */
13289 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
13290
13291 /* The nested archive file will have been opened and setup by
13292 get_archive_member_name. */
13293 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
13294 {
13295 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
13296 ret = 1;
13297 break;
13298 }
13299
13300 ret |= process_object (qualified_name, nested_arch.file);
13301 }
13302 else
13303 {
13304 archive_file_offset = arch.next_arhdr_offset;
13305 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 13306
2cf0635d
NC
13307 ret |= process_object (qualified_name, file);
13308 }
fb52b2f4 13309
2b52916e
L
13310 if (dump_sects != NULL)
13311 {
13312 free (dump_sects);
13313 dump_sects = NULL;
13314 num_dump_sects = 0;
13315 }
13316
2cf0635d 13317 free (qualified_name);
fb52b2f4
NC
13318 }
13319
4145f1d5 13320 out:
2cf0635d
NC
13321 if (nested_arch.file != NULL)
13322 fclose (nested_arch.file);
13323 release_archive (&nested_arch);
13324 release_archive (&arch);
fb52b2f4 13325
d989285c 13326 return ret;
fb52b2f4
NC
13327}
13328
13329static int
2cf0635d 13330process_file (char * file_name)
fb52b2f4 13331{
2cf0635d 13332 FILE * file;
fb52b2f4
NC
13333 struct stat statbuf;
13334 char armag[SARMAG];
13335 int ret;
13336
13337 if (stat (file_name, &statbuf) < 0)
13338 {
f24ddbdd
NC
13339 if (errno == ENOENT)
13340 error (_("'%s': No such file\n"), file_name);
13341 else
13342 error (_("Could not locate '%s'. System error message: %s\n"),
13343 file_name, strerror (errno));
13344 return 1;
13345 }
13346
13347 if (! S_ISREG (statbuf.st_mode))
13348 {
13349 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
13350 return 1;
13351 }
13352
13353 file = fopen (file_name, "rb");
13354 if (file == NULL)
13355 {
f24ddbdd 13356 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
13357 return 1;
13358 }
13359
13360 if (fread (armag, SARMAG, 1, file) != 1)
13361 {
4145f1d5 13362 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
13363 fclose (file);
13364 return 1;
13365 }
13366
13367 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
13368 ret = process_archive (file_name, file, FALSE);
13369 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
13370 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
13371 else
13372 {
4145f1d5
NC
13373 if (do_archive_index)
13374 error (_("File %s is not an archive so its index cannot be displayed.\n"),
13375 file_name);
13376
fb52b2f4
NC
13377 rewind (file);
13378 archive_file_size = archive_file_offset = 0;
13379 ret = process_object (file_name, file);
13380 }
13381
13382 fclose (file);
13383
13384 return ret;
13385}
13386
252b5132
RH
13387#ifdef SUPPORT_DISASSEMBLY
13388/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 13389 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 13390 symbols. */
252b5132
RH
13391
13392void
2cf0635d 13393print_address (unsigned int addr, FILE * outfile)
252b5132
RH
13394{
13395 fprintf (outfile,"0x%8.8x", addr);
13396}
13397
e3c8793a 13398/* Needed by the i386 disassembler. */
252b5132
RH
13399void
13400db_task_printsym (unsigned int addr)
13401{
13402 print_address (addr, stderr);
13403}
13404#endif
13405
13406int
2cf0635d 13407main (int argc, char ** argv)
252b5132 13408{
ff78d6d6
L
13409 int err;
13410
252b5132
RH
13411#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
13412 setlocale (LC_MESSAGES, "");
3882b010
L
13413#endif
13414#if defined (HAVE_SETLOCALE)
13415 setlocale (LC_CTYPE, "");
252b5132
RH
13416#endif
13417 bindtextdomain (PACKAGE, LOCALEDIR);
13418 textdomain (PACKAGE);
13419
869b9d07
MM
13420 expandargv (&argc, &argv);
13421
252b5132
RH
13422 parse_args (argc, argv);
13423
18bd398b 13424 if (num_dump_sects > 0)
59f14fc0 13425 {
18bd398b 13426 /* Make a copy of the dump_sects array. */
3f5e193b
NC
13427 cmdline_dump_sects = (dump_type *)
13428 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 13429 if (cmdline_dump_sects == NULL)
591a748a 13430 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
13431 else
13432 {
09c11c86
NC
13433 memcpy (cmdline_dump_sects, dump_sects,
13434 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
13435 num_cmdline_dump_sects = num_dump_sects;
13436 }
13437 }
13438
18bd398b
NC
13439 if (optind < (argc - 1))
13440 show_name = 1;
13441
ff78d6d6 13442 err = 0;
252b5132 13443 while (optind < argc)
18bd398b 13444 err |= process_file (argv[optind++]);
252b5132
RH
13445
13446 if (dump_sects != NULL)
13447 free (dump_sects);
59f14fc0
AS
13448 if (cmdline_dump_sects != NULL)
13449 free (cmdline_dump_sects);
252b5132 13450
ff78d6d6 13451 return err;
252b5132 13452}