]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
* Makefile.def (language=c++): Add check-c++0x and
[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"
aa137e4d
NC
143#include "elf/tilegx.h"
144#include "elf/tilepro.h"
3b16e843 145#include "elf/v850.h"
179d3252 146#include "elf/vax.h"
3b16e843 147#include "elf/x86-64.h"
c29aca4a 148#include "elf/xc16x.h"
93fbbb04 149#include "elf/xstormy16.h"
88da6820 150#include "elf/xtensa.h"
252b5132 151
252b5132 152#include "getopt.h"
566b0d53 153#include "libiberty.h"
09c11c86 154#include "safe-ctype.h"
2cf0635d 155#include "filenames.h"
252b5132 156
2cf0635d 157char * program_name = "readelf";
85b1c36d
BE
158static long archive_file_offset;
159static unsigned long archive_file_size;
160static unsigned long dynamic_addr;
161static bfd_size_type dynamic_size;
162static unsigned int dynamic_nent;
2cf0635d 163static char * dynamic_strings;
85b1c36d 164static unsigned long dynamic_strings_length;
2cf0635d 165static char * string_table;
85b1c36d
BE
166static unsigned long string_table_length;
167static unsigned long num_dynamic_syms;
2cf0635d
NC
168static Elf_Internal_Sym * dynamic_symbols;
169static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
170static unsigned long dynamic_syminfo_offset;
171static unsigned int dynamic_syminfo_nent;
f8eae8b2 172static char program_interpreter[PATH_MAX];
bb8a0291 173static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 174static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
175static bfd_vma version_info[16];
176static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
177static Elf_Internal_Shdr * section_headers;
178static Elf_Internal_Phdr * program_headers;
179static Elf_Internal_Dyn * dynamic_section;
180static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
181static int show_name;
182static int do_dynamic;
183static int do_syms;
2c610e4b 184static int do_dyn_syms;
85b1c36d
BE
185static int do_reloc;
186static int do_sections;
187static int do_section_groups;
5477e8a0 188static int do_section_details;
85b1c36d
BE
189static int do_segments;
190static int do_unwind;
191static int do_using_dynamic;
192static int do_header;
193static int do_dump;
194static int do_version;
85b1c36d
BE
195static int do_histogram;
196static int do_debugging;
85b1c36d
BE
197static int do_arch;
198static int do_notes;
4145f1d5 199static int do_archive_index;
85b1c36d 200static int is_32bit_elf;
252b5132 201
e4b17d5c
L
202struct group_list
203{
2cf0635d 204 struct group_list * next;
e4b17d5c
L
205 unsigned int section_index;
206};
207
208struct group
209{
2cf0635d 210 struct group_list * root;
e4b17d5c
L
211 unsigned int group_index;
212};
213
85b1c36d 214static size_t group_count;
2cf0635d
NC
215static struct group * section_groups;
216static struct group ** section_headers_groups;
e4b17d5c 217
09c11c86
NC
218
219/* Flag bits indicating particular types of dump. */
220#define HEX_DUMP (1 << 0) /* The -x command line switch. */
221#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
222#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
223#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 224#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
225
226typedef unsigned char dump_type;
227
228/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
229struct dump_list_entry
230{
2cf0635d 231 char * name;
09c11c86 232 dump_type type;
2cf0635d 233 struct dump_list_entry * next;
aef1f6d0 234};
2cf0635d 235static struct dump_list_entry * dump_sects_byname;
aef1f6d0 236
09c11c86
NC
237/* A dynamic array of flags indicating for which sections a dump
238 has been requested via command line switches. */
239static dump_type * cmdline_dump_sects = NULL;
240static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
241
242/* A dynamic array of flags indicating for which sections a dump of
243 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
244 basis and then initialised from the cmdline_dump_sects array,
245 the results of interpreting the -w switch, and the
246 dump_sects_byname list. */
09c11c86
NC
247static dump_type * dump_sects = NULL;
248static unsigned int num_dump_sects = 0;
252b5132 249
252b5132 250
c256ffe7 251/* How to print a vma value. */
843dd992
NC
252typedef enum print_mode
253{
254 HEX,
255 DEC,
256 DEC_5,
257 UNSIGNED,
258 PREFIX_HEX,
259 FULL_HEX,
260 LONG_HEX
261}
262print_mode;
263
9c19a809
NC
264#define UNKNOWN -1
265
2b692964
NC
266#define SECTION_NAME(X) \
267 ((X) == NULL ? _("<none>") \
268 : string_table == NULL ? _("<no-name>") \
269 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 270 : string_table + (X)->sh_name))
252b5132 271
ee42cf8c 272#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 273
9ad5cbcf
AM
274#define GET_ELF_SYMBOLS(file, section) \
275 (is_32bit_elf ? get_32bit_elf_symbols (file, section) \
276 : get_64bit_elf_symbols (file, section))
9ea033b2 277
d79b3d50
NC
278#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
279/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
280 already been called and verified that the string exists. */
281#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 282
61865e30
NC
283#define REMOVE_ARCH_BITS(ADDR) \
284 do \
285 { \
286 if (elf_header.e_machine == EM_ARM) \
287 (ADDR) &= ~1; \
288 } \
289 while (0)
d79b3d50 290\f
59245841
NC
291/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
292 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
293 using malloc and fill that. In either case return the pointer to the start of
294 the retrieved data or NULL if something went wrong. If something does go wrong
295 emit an error message using REASON as part of the context. */
296
c256ffe7 297static void *
2cf0635d
NC
298get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
299 const char * reason)
a6e9f9df 300{
2cf0635d 301 void * mvar;
a6e9f9df 302
c256ffe7 303 if (size == 0 || nmemb == 0)
a6e9f9df
AM
304 return NULL;
305
fb52b2f4 306 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 307 {
0fd3a477 308 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 309 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
310 return NULL;
311 }
312
313 mvar = var;
314 if (mvar == NULL)
315 {
c256ffe7
JJ
316 /* Check for overflow. */
317 if (nmemb < (~(size_t) 0 - 1) / size)
318 /* + 1 so that we can '\0' terminate invalid string table sections. */
319 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
320
321 if (mvar == NULL)
322 {
0fd3a477
JW
323 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
324 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
325 return NULL;
326 }
c256ffe7
JJ
327
328 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
329 }
330
c256ffe7 331 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 332 {
0fd3a477
JW
333 error (_("Unable to read in 0x%lx bytes of %s\n"),
334 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
335 if (mvar != var)
336 free (mvar);
337 return NULL;
338 }
339
340 return mvar;
341}
342
14a91970 343/* Print a VMA value. */
cb8f3167 344
66543521 345static int
14a91970 346print_vma (bfd_vma vma, print_mode mode)
66543521 347{
66543521
AM
348 int nc = 0;
349
14a91970 350 switch (mode)
66543521 351 {
14a91970
AM
352 case FULL_HEX:
353 nc = printf ("0x");
354 /* Drop through. */
66543521 355
14a91970 356 case LONG_HEX:
f7a99963 357#ifdef BFD64
14a91970 358 if (is_32bit_elf)
437c2fb7 359 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 360#endif
14a91970
AM
361 printf_vma (vma);
362 return nc + 16;
b19aac67 363
14a91970
AM
364 case DEC_5:
365 if (vma <= 99999)
366 return printf ("%5" BFD_VMA_FMT "d", vma);
367 /* Drop through. */
66543521 368
14a91970
AM
369 case PREFIX_HEX:
370 nc = printf ("0x");
371 /* Drop through. */
66543521 372
14a91970
AM
373 case HEX:
374 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 375
14a91970
AM
376 case DEC:
377 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 378
14a91970
AM
379 case UNSIGNED:
380 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 381 }
66543521 382 return 0;
f7a99963
NC
383}
384
171191ba 385/* Display a symbol on stdout. Handles the display of non-printing characters.
31104126 386
171191ba
NC
387 If DO_WIDE is not true then format the symbol to be at most WIDTH characters,
388 truncating as necessary. If WIDTH is negative then format the string to be
389 exactly - WIDTH characters, truncating or padding as necessary.
390
391 Returns the number of emitted characters. */
392
393static unsigned int
7a88bc9c 394print_symbol (int width, const char *symbol)
31104126 395{
7a88bc9c 396 const char *c;
171191ba
NC
397 bfd_boolean extra_padding = FALSE;
398 unsigned int num_printed = 0;
961c521f 399
31104126 400 if (do_wide)
961c521f 401 {
7a88bc9c
AS
402 /* Set the width to a very large value. This simplifies the
403 code below. */
961c521f
NC
404 width = INT_MAX;
405 }
31104126 406 else if (width < 0)
961c521f 407 {
961c521f
NC
408 /* Keep the width positive. This also helps. */
409 width = - width;
171191ba 410 extra_padding = TRUE;
961c521f
NC
411 }
412
413 while (width)
414 {
415 int len;
416
417 c = symbol;
418
419 /* Look for non-printing symbols inside the symbol's name.
420 This test is triggered in particular by the names generated
421 by the assembler for local labels. */
7a88bc9c 422 while (ISPRINT (*c))
961c521f
NC
423 c++;
424
425 len = c - symbol;
426
427 if (len)
428 {
429 if (len > width)
430 len = width;
cb8f3167 431
171191ba 432 printf ("%.*s", len, symbol);
961c521f
NC
433
434 width -= len;
171191ba 435 num_printed += len;
961c521f
NC
436 }
437
7a88bc9c 438 if (*c == 0 || width == 0)
961c521f
NC
439 break;
440
441 /* Now display the non-printing character, if
442 there is room left in which to dipslay it. */
7a88bc9c 443 if ((unsigned char) *c < 32)
961c521f
NC
444 {
445 if (width < 2)
446 break;
447
448 printf ("^%c", *c + 0x40);
449
450 width -= 2;
171191ba 451 num_printed += 2;
961c521f
NC
452 }
453 else
454 {
455 if (width < 6)
456 break;
cb8f3167 457
7a88bc9c 458 printf ("<0x%.2x>", (unsigned char) *c);
961c521f
NC
459
460 width -= 6;
171191ba 461 num_printed += 6;
961c521f
NC
462 }
463
464 symbol = c + 1;
465 }
171191ba
NC
466
467 if (extra_padding && width > 0)
468 {
469 /* Fill in the remaining spaces. */
470 printf ("%-*s", width, " ");
471 num_printed += 2;
472 }
473
474 return num_printed;
31104126
NC
475}
476
89fac5e3
RS
477/* Return a pointer to section NAME, or NULL if no such section exists. */
478
479static Elf_Internal_Shdr *
2cf0635d 480find_section (const char * name)
89fac5e3
RS
481{
482 unsigned int i;
483
484 for (i = 0; i < elf_header.e_shnum; i++)
485 if (streq (SECTION_NAME (section_headers + i), name))
486 return section_headers + i;
487
488 return NULL;
489}
490
0b6ae522
DJ
491/* Return a pointer to a section containing ADDR, or NULL if no such
492 section exists. */
493
494static Elf_Internal_Shdr *
495find_section_by_address (bfd_vma addr)
496{
497 unsigned int i;
498
499 for (i = 0; i < elf_header.e_shnum; i++)
500 {
501 Elf_Internal_Shdr *sec = section_headers + i;
502 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
503 return sec;
504 }
505
506 return NULL;
507}
508
509/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
510 bytes read. */
511
512static unsigned long
513read_uleb128 (unsigned char *data, unsigned int *length_return)
514{
515 return read_leb128 (data, length_return, 0);
516}
517
28f997cf
TG
518/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
519 This OS has so many departures from the ELF standard that we test it at
520 many places. */
521
522static inline int
523is_ia64_vms (void)
524{
525 return elf_header.e_machine == EM_IA_64
526 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
527}
528
bcedfee6 529/* Guess the relocation size commonly used by the specific machines. */
252b5132 530
252b5132 531static int
2dc4cec1 532guess_is_rela (unsigned int e_machine)
252b5132 533{
9c19a809 534 switch (e_machine)
252b5132
RH
535 {
536 /* Targets that use REL relocations. */
252b5132
RH
537 case EM_386:
538 case EM_486:
63fcb9e9 539 case EM_960:
e9f53129 540 case EM_ARM:
2b0337b0 541 case EM_D10V:
252b5132 542 case EM_CYGNUS_D10V:
e9f53129 543 case EM_DLX:
252b5132 544 case EM_MIPS:
4fe85591 545 case EM_MIPS_RS3_LE:
e9f53129
AM
546 case EM_CYGNUS_M32R:
547 case EM_OPENRISC:
548 case EM_OR32:
1c0d3aa6 549 case EM_SCORE:
9c19a809 550 return FALSE;
103f02d3 551
252b5132
RH
552 /* Targets that use RELA relocations. */
553 case EM_68K:
e9f53129
AM
554 case EM_860:
555 case EM_ALPHA:
556 case EM_ALTERA_NIOS2:
557 case EM_AVR:
558 case EM_AVR_OLD:
559 case EM_BLACKFIN:
60bca95a 560 case EM_CR16:
6c03b1ed 561 case EM_CR16_OLD:
e9f53129
AM
562 case EM_CRIS:
563 case EM_CRX:
2b0337b0 564 case EM_D30V:
252b5132 565 case EM_CYGNUS_D30V:
2b0337b0 566 case EM_FR30:
252b5132 567 case EM_CYGNUS_FR30:
5c70f934 568 case EM_CYGNUS_FRV:
e9f53129
AM
569 case EM_H8S:
570 case EM_H8_300:
571 case EM_H8_300H:
800eeca4 572 case EM_IA_64:
1e4cf259
NC
573 case EM_IP2K:
574 case EM_IP2K_OLD:
3b36097d 575 case EM_IQ2000:
84e94c90 576 case EM_LATTICEMICO32:
ff7eeb89 577 case EM_M32C_OLD:
49f58d10 578 case EM_M32C:
e9f53129
AM
579 case EM_M32R:
580 case EM_MCORE:
15ab5209 581 case EM_CYGNUS_MEP:
e9f53129
AM
582 case EM_MMIX:
583 case EM_MN10200:
584 case EM_CYGNUS_MN10200:
585 case EM_MN10300:
586 case EM_CYGNUS_MN10300:
5506d11a 587 case EM_MOXIE:
e9f53129
AM
588 case EM_MSP430:
589 case EM_MSP430_OLD:
d031aafb 590 case EM_MT:
64fd6348 591 case EM_NIOS32:
e9f53129
AM
592 case EM_PPC64:
593 case EM_PPC:
c7927a3c 594 case EM_RX:
e9f53129
AM
595 case EM_S390:
596 case EM_S390_OLD:
597 case EM_SH:
598 case EM_SPARC:
599 case EM_SPARC32PLUS:
600 case EM_SPARCV9:
601 case EM_SPU:
40b36596 602 case EM_TI_C6000:
aa137e4d
NC
603 case EM_TILEGX:
604 case EM_TILEPRO:
e9f53129
AM
605 case EM_V850:
606 case EM_CYGNUS_V850:
607 case EM_VAX:
608 case EM_X86_64:
8a9036a4 609 case EM_L1OM:
e9f53129
AM
610 case EM_XSTORMY16:
611 case EM_XTENSA:
612 case EM_XTENSA_OLD:
7ba29e2a
NC
613 case EM_MICROBLAZE:
614 case EM_MICROBLAZE_OLD:
9c19a809 615 return TRUE;
103f02d3 616
e9f53129
AM
617 case EM_68HC05:
618 case EM_68HC08:
619 case EM_68HC11:
620 case EM_68HC16:
621 case EM_FX66:
622 case EM_ME16:
d1133906 623 case EM_MMA:
d1133906
NC
624 case EM_NCPU:
625 case EM_NDR1:
e9f53129 626 case EM_PCP:
d1133906 627 case EM_ST100:
e9f53129 628 case EM_ST19:
d1133906 629 case EM_ST7:
e9f53129
AM
630 case EM_ST9PLUS:
631 case EM_STARCORE:
d1133906 632 case EM_SVX:
e9f53129 633 case EM_TINYJ:
9c19a809
NC
634 default:
635 warn (_("Don't know about relocations on this machine architecture\n"));
636 return FALSE;
637 }
638}
252b5132 639
9c19a809 640static int
2cf0635d 641slurp_rela_relocs (FILE * file,
d3ba0551
AM
642 unsigned long rel_offset,
643 unsigned long rel_size,
2cf0635d
NC
644 Elf_Internal_Rela ** relasp,
645 unsigned long * nrelasp)
9c19a809 646{
2cf0635d 647 Elf_Internal_Rela * relas;
4d6ed7c8
NC
648 unsigned long nrelas;
649 unsigned int i;
252b5132 650
4d6ed7c8
NC
651 if (is_32bit_elf)
652 {
2cf0635d 653 Elf32_External_Rela * erelas;
103f02d3 654
3f5e193b
NC
655 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
656 rel_size, _("relocs"));
a6e9f9df
AM
657 if (!erelas)
658 return 0;
252b5132 659
4d6ed7c8 660 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 661
3f5e193b
NC
662 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
663 sizeof (Elf_Internal_Rela));
103f02d3 664
4d6ed7c8
NC
665 if (relas == NULL)
666 {
c256ffe7 667 free (erelas);
591a748a 668 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
669 return 0;
670 }
103f02d3 671
4d6ed7c8
NC
672 for (i = 0; i < nrelas; i++)
673 {
674 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
675 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 676 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 677 }
103f02d3 678
4d6ed7c8
NC
679 free (erelas);
680 }
681 else
682 {
2cf0635d 683 Elf64_External_Rela * erelas;
103f02d3 684
3f5e193b
NC
685 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
686 rel_size, _("relocs"));
a6e9f9df
AM
687 if (!erelas)
688 return 0;
4d6ed7c8
NC
689
690 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 691
3f5e193b
NC
692 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
693 sizeof (Elf_Internal_Rela));
103f02d3 694
4d6ed7c8
NC
695 if (relas == NULL)
696 {
c256ffe7 697 free (erelas);
591a748a 698 error (_("out of memory parsing relocs\n"));
4d6ed7c8 699 return 0;
9c19a809 700 }
4d6ed7c8
NC
701
702 for (i = 0; i < nrelas; i++)
9c19a809 703 {
66543521
AM
704 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
705 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 706 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
707
708 /* The #ifdef BFD64 below is to prevent a compile time
709 warning. We know that if we do not have a 64 bit data
710 type that we will never execute this code anyway. */
711#ifdef BFD64
712 if (elf_header.e_machine == EM_MIPS
713 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
714 {
715 /* In little-endian objects, r_info isn't really a
716 64-bit little-endian value: it has a 32-bit
717 little-endian symbol index followed by four
718 individual byte fields. Reorder INFO
719 accordingly. */
91d6fa6a
NC
720 bfd_vma inf = relas[i].r_info;
721 inf = (((inf & 0xffffffff) << 32)
722 | ((inf >> 56) & 0xff)
723 | ((inf >> 40) & 0xff00)
724 | ((inf >> 24) & 0xff0000)
725 | ((inf >> 8) & 0xff000000));
726 relas[i].r_info = inf;
861fb55a
DJ
727 }
728#endif /* BFD64 */
4d6ed7c8 729 }
103f02d3 730
4d6ed7c8
NC
731 free (erelas);
732 }
733 *relasp = relas;
734 *nrelasp = nrelas;
735 return 1;
736}
103f02d3 737
4d6ed7c8 738static int
2cf0635d 739slurp_rel_relocs (FILE * file,
d3ba0551
AM
740 unsigned long rel_offset,
741 unsigned long rel_size,
2cf0635d
NC
742 Elf_Internal_Rela ** relsp,
743 unsigned long * nrelsp)
4d6ed7c8 744{
2cf0635d 745 Elf_Internal_Rela * rels;
4d6ed7c8
NC
746 unsigned long nrels;
747 unsigned int i;
103f02d3 748
4d6ed7c8
NC
749 if (is_32bit_elf)
750 {
2cf0635d 751 Elf32_External_Rel * erels;
103f02d3 752
3f5e193b
NC
753 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
754 rel_size, _("relocs"));
a6e9f9df
AM
755 if (!erels)
756 return 0;
103f02d3 757
4d6ed7c8 758 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 759
3f5e193b 760 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 761
4d6ed7c8
NC
762 if (rels == NULL)
763 {
c256ffe7 764 free (erels);
591a748a 765 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
766 return 0;
767 }
768
769 for (i = 0; i < nrels; i++)
770 {
771 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
772 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 773 rels[i].r_addend = 0;
9ea033b2 774 }
4d6ed7c8
NC
775
776 free (erels);
9c19a809
NC
777 }
778 else
779 {
2cf0635d 780 Elf64_External_Rel * erels;
9ea033b2 781
3f5e193b
NC
782 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
783 rel_size, _("relocs"));
a6e9f9df
AM
784 if (!erels)
785 return 0;
103f02d3 786
4d6ed7c8 787 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 788
3f5e193b 789 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 790
4d6ed7c8 791 if (rels == NULL)
9c19a809 792 {
c256ffe7 793 free (erels);
591a748a 794 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
795 return 0;
796 }
103f02d3 797
4d6ed7c8
NC
798 for (i = 0; i < nrels; i++)
799 {
66543521
AM
800 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
801 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 802 rels[i].r_addend = 0;
861fb55a
DJ
803
804 /* The #ifdef BFD64 below is to prevent a compile time
805 warning. We know that if we do not have a 64 bit data
806 type that we will never execute this code anyway. */
807#ifdef BFD64
808 if (elf_header.e_machine == EM_MIPS
809 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
810 {
811 /* In little-endian objects, r_info isn't really a
812 64-bit little-endian value: it has a 32-bit
813 little-endian symbol index followed by four
814 individual byte fields. Reorder INFO
815 accordingly. */
91d6fa6a
NC
816 bfd_vma inf = rels[i].r_info;
817 inf = (((inf & 0xffffffff) << 32)
818 | ((inf >> 56) & 0xff)
819 | ((inf >> 40) & 0xff00)
820 | ((inf >> 24) & 0xff0000)
821 | ((inf >> 8) & 0xff000000));
822 rels[i].r_info = inf;
861fb55a
DJ
823 }
824#endif /* BFD64 */
4d6ed7c8 825 }
103f02d3 826
4d6ed7c8
NC
827 free (erels);
828 }
829 *relsp = rels;
830 *nrelsp = nrels;
831 return 1;
832}
103f02d3 833
aca88567
NC
834/* Returns the reloc type extracted from the reloc info field. */
835
836static unsigned int
837get_reloc_type (bfd_vma reloc_info)
838{
839 if (is_32bit_elf)
840 return ELF32_R_TYPE (reloc_info);
841
842 switch (elf_header.e_machine)
843 {
844 case EM_MIPS:
845 /* Note: We assume that reloc_info has already been adjusted for us. */
846 return ELF64_MIPS_R_TYPE (reloc_info);
847
848 case EM_SPARCV9:
849 return ELF64_R_TYPE_ID (reloc_info);
850
851 default:
852 return ELF64_R_TYPE (reloc_info);
853 }
854}
855
856/* Return the symbol index extracted from the reloc info field. */
857
858static bfd_vma
859get_reloc_symindex (bfd_vma reloc_info)
860{
861 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
862}
863
d3ba0551
AM
864/* Display the contents of the relocation data found at the specified
865 offset. */
ee42cf8c 866
41e92641 867static void
2cf0635d 868dump_relocations (FILE * file,
d3ba0551
AM
869 unsigned long rel_offset,
870 unsigned long rel_size,
2cf0635d 871 Elf_Internal_Sym * symtab,
d3ba0551 872 unsigned long nsyms,
2cf0635d 873 char * strtab,
d79b3d50 874 unsigned long strtablen,
d3ba0551 875 int is_rela)
4d6ed7c8 876{
b34976b6 877 unsigned int i;
2cf0635d 878 Elf_Internal_Rela * rels;
103f02d3 879
4d6ed7c8
NC
880 if (is_rela == UNKNOWN)
881 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 882
4d6ed7c8
NC
883 if (is_rela)
884 {
c8286bd1 885 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 886 return;
4d6ed7c8
NC
887 }
888 else
889 {
890 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 891 return;
252b5132
RH
892 }
893
410f7a12
L
894 if (is_32bit_elf)
895 {
896 if (is_rela)
2c71103e
NC
897 {
898 if (do_wide)
899 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
900 else
901 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
902 }
410f7a12 903 else
2c71103e
NC
904 {
905 if (do_wide)
906 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
907 else
908 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
909 }
410f7a12 910 }
252b5132 911 else
410f7a12
L
912 {
913 if (is_rela)
2c71103e
NC
914 {
915 if (do_wide)
8beeaeb7 916 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
917 else
918 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
919 }
410f7a12 920 else
2c71103e
NC
921 {
922 if (do_wide)
8beeaeb7 923 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
924 else
925 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
926 }
410f7a12 927 }
252b5132
RH
928
929 for (i = 0; i < rel_size; i++)
930 {
2cf0635d 931 const char * rtype;
b34976b6 932 bfd_vma offset;
91d6fa6a 933 bfd_vma inf;
b34976b6
AM
934 bfd_vma symtab_index;
935 bfd_vma type;
103f02d3 936
b34976b6 937 offset = rels[i].r_offset;
91d6fa6a 938 inf = rels[i].r_info;
103f02d3 939
91d6fa6a
NC
940 type = get_reloc_type (inf);
941 symtab_index = get_reloc_symindex (inf);
252b5132 942
410f7a12
L
943 if (is_32bit_elf)
944 {
39dbeff8
AM
945 printf ("%8.8lx %8.8lx ",
946 (unsigned long) offset & 0xffffffff,
91d6fa6a 947 (unsigned long) inf & 0xffffffff);
410f7a12
L
948 }
949 else
950 {
39dbeff8
AM
951#if BFD_HOST_64BIT_LONG
952 printf (do_wide
953 ? "%16.16lx %16.16lx "
954 : "%12.12lx %12.12lx ",
91d6fa6a 955 offset, inf);
39dbeff8 956#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 957#ifndef __MSVCRT__
39dbeff8
AM
958 printf (do_wide
959 ? "%16.16llx %16.16llx "
960 : "%12.12llx %12.12llx ",
91d6fa6a 961 offset, inf);
6e3d6dc1
NC
962#else
963 printf (do_wide
964 ? "%16.16I64x %16.16I64x "
965 : "%12.12I64x %12.12I64x ",
91d6fa6a 966 offset, inf);
6e3d6dc1 967#endif
39dbeff8 968#else
2c71103e
NC
969 printf (do_wide
970 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
971 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
972 _bfd_int64_high (offset),
973 _bfd_int64_low (offset),
91d6fa6a
NC
974 _bfd_int64_high (inf),
975 _bfd_int64_low (inf));
9ea033b2 976#endif
410f7a12 977 }
103f02d3 978
252b5132
RH
979 switch (elf_header.e_machine)
980 {
981 default:
982 rtype = NULL;
983 break;
984
2b0337b0 985 case EM_M32R:
252b5132 986 case EM_CYGNUS_M32R:
9ea033b2 987 rtype = elf_m32r_reloc_type (type);
252b5132
RH
988 break;
989
990 case EM_386:
991 case EM_486:
9ea033b2 992 rtype = elf_i386_reloc_type (type);
252b5132
RH
993 break;
994
ba2685cc
AM
995 case EM_68HC11:
996 case EM_68HC12:
997 rtype = elf_m68hc11_reloc_type (type);
998 break;
75751cd9 999
252b5132 1000 case EM_68K:
9ea033b2 1001 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1002 break;
1003
63fcb9e9 1004 case EM_960:
9ea033b2 1005 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1006 break;
1007
adde6300 1008 case EM_AVR:
2b0337b0 1009 case EM_AVR_OLD:
adde6300
AM
1010 rtype = elf_avr_reloc_type (type);
1011 break;
1012
9ea033b2
NC
1013 case EM_OLD_SPARCV9:
1014 case EM_SPARC32PLUS:
1015 case EM_SPARCV9:
252b5132 1016 case EM_SPARC:
9ea033b2 1017 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1018 break;
1019
e9f53129
AM
1020 case EM_SPU:
1021 rtype = elf_spu_reloc_type (type);
1022 break;
1023
2b0337b0 1024 case EM_V850:
252b5132 1025 case EM_CYGNUS_V850:
9ea033b2 1026 rtype = v850_reloc_type (type);
252b5132
RH
1027 break;
1028
2b0337b0 1029 case EM_D10V:
252b5132 1030 case EM_CYGNUS_D10V:
9ea033b2 1031 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1032 break;
1033
2b0337b0 1034 case EM_D30V:
252b5132 1035 case EM_CYGNUS_D30V:
9ea033b2 1036 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1037 break;
1038
d172d4ba
NC
1039 case EM_DLX:
1040 rtype = elf_dlx_reloc_type (type);
1041 break;
1042
252b5132 1043 case EM_SH:
9ea033b2 1044 rtype = elf_sh_reloc_type (type);
252b5132
RH
1045 break;
1046
2b0337b0 1047 case EM_MN10300:
252b5132 1048 case EM_CYGNUS_MN10300:
9ea033b2 1049 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1050 break;
1051
2b0337b0 1052 case EM_MN10200:
252b5132 1053 case EM_CYGNUS_MN10200:
9ea033b2 1054 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1055 break;
1056
2b0337b0 1057 case EM_FR30:
252b5132 1058 case EM_CYGNUS_FR30:
9ea033b2 1059 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1060 break;
1061
ba2685cc
AM
1062 case EM_CYGNUS_FRV:
1063 rtype = elf_frv_reloc_type (type);
1064 break;
5c70f934 1065
252b5132 1066 case EM_MCORE:
9ea033b2 1067 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1068 break;
1069
3c3bdf30
NC
1070 case EM_MMIX:
1071 rtype = elf_mmix_reloc_type (type);
1072 break;
1073
5506d11a
AM
1074 case EM_MOXIE:
1075 rtype = elf_moxie_reloc_type (type);
1076 break;
1077
2469cfa2
NC
1078 case EM_MSP430:
1079 case EM_MSP430_OLD:
1080 rtype = elf_msp430_reloc_type (type);
1081 break;
1082
252b5132 1083 case EM_PPC:
9ea033b2 1084 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1085 break;
1086
c833c019
AM
1087 case EM_PPC64:
1088 rtype = elf_ppc64_reloc_type (type);
1089 break;
1090
252b5132 1091 case EM_MIPS:
4fe85591 1092 case EM_MIPS_RS3_LE:
9ea033b2 1093 rtype = elf_mips_reloc_type (type);
252b5132
RH
1094 break;
1095
1096 case EM_ALPHA:
9ea033b2 1097 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1098 break;
1099
1100 case EM_ARM:
9ea033b2 1101 rtype = elf_arm_reloc_type (type);
252b5132
RH
1102 break;
1103
584da044 1104 case EM_ARC:
9ea033b2 1105 rtype = elf_arc_reloc_type (type);
252b5132
RH
1106 break;
1107
1108 case EM_PARISC:
69e617ca 1109 rtype = elf_hppa_reloc_type (type);
252b5132 1110 break;
7d466069 1111
b8720f9d
JL
1112 case EM_H8_300:
1113 case EM_H8_300H:
1114 case EM_H8S:
1115 rtype = elf_h8_reloc_type (type);
1116 break;
1117
3b16e843
NC
1118 case EM_OPENRISC:
1119 case EM_OR32:
1120 rtype = elf_or32_reloc_type (type);
1121 break;
1122
7d466069 1123 case EM_PJ:
2b0337b0 1124 case EM_PJ_OLD:
7d466069
ILT
1125 rtype = elf_pj_reloc_type (type);
1126 break;
800eeca4
JW
1127 case EM_IA_64:
1128 rtype = elf_ia64_reloc_type (type);
1129 break;
1b61cf92
HPN
1130
1131 case EM_CRIS:
1132 rtype = elf_cris_reloc_type (type);
1133 break;
535c37ff
JE
1134
1135 case EM_860:
1136 rtype = elf_i860_reloc_type (type);
1137 break;
bcedfee6
NC
1138
1139 case EM_X86_64:
8a9036a4 1140 case EM_L1OM:
bcedfee6
NC
1141 rtype = elf_x86_64_reloc_type (type);
1142 break;
a85d7ed0 1143
35b1837e
AM
1144 case EM_S370:
1145 rtype = i370_reloc_type (type);
1146 break;
1147
53c7db4b
KH
1148 case EM_S390_OLD:
1149 case EM_S390:
1150 rtype = elf_s390_reloc_type (type);
1151 break;
93fbbb04 1152
1c0d3aa6
NC
1153 case EM_SCORE:
1154 rtype = elf_score_reloc_type (type);
1155 break;
1156
93fbbb04
GK
1157 case EM_XSTORMY16:
1158 rtype = elf_xstormy16_reloc_type (type);
1159 break;
179d3252 1160
1fe1f39c
NC
1161 case EM_CRX:
1162 rtype = elf_crx_reloc_type (type);
1163 break;
1164
179d3252
JT
1165 case EM_VAX:
1166 rtype = elf_vax_reloc_type (type);
1167 break;
1e4cf259
NC
1168
1169 case EM_IP2K:
1170 case EM_IP2K_OLD:
1171 rtype = elf_ip2k_reloc_type (type);
1172 break;
3b36097d
SC
1173
1174 case EM_IQ2000:
1175 rtype = elf_iq2000_reloc_type (type);
1176 break;
88da6820
NC
1177
1178 case EM_XTENSA_OLD:
1179 case EM_XTENSA:
1180 rtype = elf_xtensa_reloc_type (type);
1181 break;
a34e3ecb 1182
84e94c90
NC
1183 case EM_LATTICEMICO32:
1184 rtype = elf_lm32_reloc_type (type);
1185 break;
1186
ff7eeb89 1187 case EM_M32C_OLD:
49f58d10
JB
1188 case EM_M32C:
1189 rtype = elf_m32c_reloc_type (type);
1190 break;
1191
d031aafb
NS
1192 case EM_MT:
1193 rtype = elf_mt_reloc_type (type);
a34e3ecb 1194 break;
1d65ded4
CM
1195
1196 case EM_BLACKFIN:
1197 rtype = elf_bfin_reloc_type (type);
1198 break;
15ab5209
DB
1199
1200 case EM_CYGNUS_MEP:
1201 rtype = elf_mep_reloc_type (type);
1202 break;
60bca95a
NC
1203
1204 case EM_CR16:
6c03b1ed 1205 case EM_CR16_OLD:
60bca95a
NC
1206 rtype = elf_cr16_reloc_type (type);
1207 break;
dd24e3da 1208
7ba29e2a
NC
1209 case EM_MICROBLAZE:
1210 case EM_MICROBLAZE_OLD:
1211 rtype = elf_microblaze_reloc_type (type);
1212 break;
c7927a3c
NC
1213
1214 case EM_RX:
1215 rtype = elf_rx_reloc_type (type);
1216 break;
c29aca4a
NC
1217
1218 case EM_XC16X:
1219 case EM_C166:
1220 rtype = elf_xc16x_reloc_type (type);
1221 break;
40b36596
JM
1222
1223 case EM_TI_C6000:
1224 rtype = elf_tic6x_reloc_type (type);
1225 break;
aa137e4d
NC
1226
1227 case EM_TILEGX:
1228 rtype = elf_tilegx_reloc_type (type);
1229 break;
1230
1231 case EM_TILEPRO:
1232 rtype = elf_tilepro_reloc_type (type);
1233 break;
252b5132
RH
1234 }
1235
1236 if (rtype == NULL)
39dbeff8 1237 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1238 else
8beeaeb7 1239 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1240
7ace3541 1241 if (elf_header.e_machine == EM_ALPHA
157c2599 1242 && rtype != NULL
7ace3541
RH
1243 && streq (rtype, "R_ALPHA_LITUSE")
1244 && is_rela)
1245 {
1246 switch (rels[i].r_addend)
1247 {
1248 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1249 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1250 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1251 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1252 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1253 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1254 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1255 default: rtype = NULL;
1256 }
1257 if (rtype)
1258 printf (" (%s)", rtype);
1259 else
1260 {
1261 putchar (' ');
1262 printf (_("<unknown addend: %lx>"),
1263 (unsigned long) rels[i].r_addend);
1264 }
1265 }
1266 else if (symtab_index)
252b5132 1267 {
af3fc3bc 1268 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1269 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1270 else
19936277 1271 {
2cf0635d 1272 Elf_Internal_Sym * psym;
19936277 1273
af3fc3bc 1274 psym = symtab + symtab_index;
103f02d3 1275
af3fc3bc 1276 printf (" ");
171191ba 1277
d8045f23
NC
1278 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1279 {
1280 const char * name;
1281 unsigned int len;
1282 unsigned int width = is_32bit_elf ? 8 : 14;
1283
1284 /* Relocations against GNU_IFUNC symbols do not use the value
1285 of the symbol as the address to relocate against. Instead
1286 they invoke the function named by the symbol and use its
1287 result as the address for relocation.
1288
1289 To indicate this to the user, do not display the value of
1290 the symbol in the "Symbols's Value" field. Instead show
1291 its name followed by () as a hint that the symbol is
1292 invoked. */
1293
1294 if (strtab == NULL
1295 || psym->st_name == 0
1296 || psym->st_name >= strtablen)
1297 name = "??";
1298 else
1299 name = strtab + psym->st_name;
1300
1301 len = print_symbol (width, name);
1302 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1303 }
1304 else
1305 {
1306 print_vma (psym->st_value, LONG_HEX);
171191ba 1307
d8045f23
NC
1308 printf (is_32bit_elf ? " " : " ");
1309 }
103f02d3 1310
af3fc3bc 1311 if (psym->st_name == 0)
f1ef08cb 1312 {
2cf0635d 1313 const char * sec_name = "<null>";
f1ef08cb
AM
1314 char name_buf[40];
1315
1316 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1317 {
4fbb74a6
AM
1318 if (psym->st_shndx < elf_header.e_shnum)
1319 sec_name
1320 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1321 else if (psym->st_shndx == SHN_ABS)
1322 sec_name = "ABS";
1323 else if (psym->st_shndx == SHN_COMMON)
1324 sec_name = "COMMON";
ac145307
BS
1325 else if ((elf_header.e_machine == EM_MIPS
1326 && psym->st_shndx == SHN_MIPS_SCOMMON)
1327 || (elf_header.e_machine == EM_TI_C6000
1328 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1329 sec_name = "SCOMMON";
1330 else if (elf_header.e_machine == EM_MIPS
1331 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1332 sec_name = "SUNDEF";
8a9036a4
L
1333 else if ((elf_header.e_machine == EM_X86_64
1334 || elf_header.e_machine == EM_L1OM)
3b22753a
L
1335 && psym->st_shndx == SHN_X86_64_LCOMMON)
1336 sec_name = "LARGE_COMMON";
9ce701e2
L
1337 else if (elf_header.e_machine == EM_IA_64
1338 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1339 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1340 sec_name = "ANSI_COM";
28f997cf 1341 else if (is_ia64_vms ()
148b93f2
NC
1342 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1343 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1344 else
1345 {
1346 sprintf (name_buf, "<section 0x%x>",
1347 (unsigned int) psym->st_shndx);
1348 sec_name = name_buf;
1349 }
1350 }
1351 print_symbol (22, sec_name);
1352 }
af3fc3bc 1353 else if (strtab == NULL)
d79b3d50 1354 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1355 else if (psym->st_name >= strtablen)
d79b3d50 1356 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1357 else
2c71103e 1358 print_symbol (22, strtab + psym->st_name);
103f02d3 1359
af3fc3bc 1360 if (is_rela)
171191ba 1361 {
598aaa76 1362 bfd_signed_vma off = rels[i].r_addend;
171191ba 1363
91d6fa6a 1364 if (off < 0)
598aaa76 1365 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1366 else
598aaa76 1367 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1368 }
19936277 1369 }
252b5132 1370 }
1b228002 1371 else if (is_rela)
f7a99963 1372 {
18bd398b
NC
1373 printf ("%*c", is_32bit_elf ?
1374 (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
c8286bd1 1375 print_vma (rels[i].r_addend, LONG_HEX);
f7a99963 1376 }
252b5132 1377
157c2599
NC
1378 if (elf_header.e_machine == EM_SPARCV9
1379 && rtype != NULL
1380 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1381 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1382
252b5132 1383 putchar ('\n');
2c71103e 1384
aca88567 1385#ifdef BFD64
53c7db4b 1386 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1387 {
91d6fa6a
NC
1388 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1389 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1390 const char * rtype2 = elf_mips_reloc_type (type2);
1391 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1392
2c71103e
NC
1393 printf (" Type2: ");
1394
1395 if (rtype2 == NULL)
39dbeff8
AM
1396 printf (_("unrecognized: %-7lx"),
1397 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1398 else
1399 printf ("%-17.17s", rtype2);
1400
18bd398b 1401 printf ("\n Type3: ");
2c71103e
NC
1402
1403 if (rtype3 == NULL)
39dbeff8
AM
1404 printf (_("unrecognized: %-7lx"),
1405 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1406 else
1407 printf ("%-17.17s", rtype3);
1408
53c7db4b 1409 putchar ('\n');
2c71103e 1410 }
aca88567 1411#endif /* BFD64 */
252b5132
RH
1412 }
1413
c8286bd1 1414 free (rels);
252b5132
RH
1415}
1416
1417static const char *
d3ba0551 1418get_mips_dynamic_type (unsigned long type)
252b5132
RH
1419{
1420 switch (type)
1421 {
1422 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1423 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1424 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1425 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1426 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1427 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1428 case DT_MIPS_MSYM: return "MIPS_MSYM";
1429 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1430 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1431 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1432 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1433 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1434 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1435 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1436 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1437 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1438 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1439 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1440 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1441 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1442 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1443 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1444 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1445 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1446 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1447 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1448 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1449 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1450 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1451 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1452 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1453 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1454 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1455 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1456 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1457 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1458 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1459 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1460 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1461 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1462 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1463 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1464 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1465 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1466 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1467 default:
1468 return NULL;
1469 }
1470}
1471
9a097730 1472static const char *
d3ba0551 1473get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1474{
1475 switch (type)
1476 {
1477 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1478 default:
1479 return NULL;
1480 }
103f02d3
UD
1481}
1482
7490d522
AM
1483static const char *
1484get_ppc_dynamic_type (unsigned long type)
1485{
1486 switch (type)
1487 {
a7f2871e
AM
1488 case DT_PPC_GOT: return "PPC_GOT";
1489 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1490 default:
1491 return NULL;
1492 }
1493}
1494
f1cb7e17 1495static const char *
d3ba0551 1496get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1497{
1498 switch (type)
1499 {
a7f2871e
AM
1500 case DT_PPC64_GLINK: return "PPC64_GLINK";
1501 case DT_PPC64_OPD: return "PPC64_OPD";
1502 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1503 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1504 default:
1505 return NULL;
1506 }
1507}
1508
103f02d3 1509static const char *
d3ba0551 1510get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1511{
1512 switch (type)
1513 {
1514 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1515 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1516 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1517 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1518 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1519 case DT_HP_PREINIT: return "HP_PREINIT";
1520 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1521 case DT_HP_NEEDED: return "HP_NEEDED";
1522 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1523 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1524 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1525 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1526 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1527 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1528 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1529 case DT_HP_FILTERED: return "HP_FILTERED";
1530 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1531 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1532 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1533 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1534 case DT_PLT: return "PLT";
1535 case DT_PLT_SIZE: return "PLT_SIZE";
1536 case DT_DLT: return "DLT";
1537 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1538 default:
1539 return NULL;
1540 }
1541}
9a097730 1542
ecc51f48 1543static const char *
d3ba0551 1544get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1545{
1546 switch (type)
1547 {
148b93f2
NC
1548 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1549 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1550 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1551 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1552 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1553 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1554 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1555 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1556 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1557 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1558 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1559 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1560 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1561 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1562 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1563 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1564 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1565 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1566 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1567 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1568 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1569 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1570 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1571 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1572 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1573 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1574 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1575 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1576 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1577 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1578 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1579 default:
1580 return NULL;
1581 }
1582}
1583
fabcb361
RH
1584static const char *
1585get_alpha_dynamic_type (unsigned long type)
1586{
1587 switch (type)
1588 {
1589 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1590 default:
1591 return NULL;
1592 }
1593}
1594
1c0d3aa6
NC
1595static const char *
1596get_score_dynamic_type (unsigned long type)
1597{
1598 switch (type)
1599 {
1600 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1601 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1602 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1603 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1604 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1605 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1606 default:
1607 return NULL;
1608 }
1609}
1610
40b36596
JM
1611static const char *
1612get_tic6x_dynamic_type (unsigned long type)
1613{
1614 switch (type)
1615 {
1616 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1617 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1618 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1619 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1620 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1621 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1622 default:
1623 return NULL;
1624 }
1625}
1c0d3aa6 1626
252b5132 1627static const char *
d3ba0551 1628get_dynamic_type (unsigned long type)
252b5132 1629{
e9e44622 1630 static char buff[64];
252b5132
RH
1631
1632 switch (type)
1633 {
1634 case DT_NULL: return "NULL";
1635 case DT_NEEDED: return "NEEDED";
1636 case DT_PLTRELSZ: return "PLTRELSZ";
1637 case DT_PLTGOT: return "PLTGOT";
1638 case DT_HASH: return "HASH";
1639 case DT_STRTAB: return "STRTAB";
1640 case DT_SYMTAB: return "SYMTAB";
1641 case DT_RELA: return "RELA";
1642 case DT_RELASZ: return "RELASZ";
1643 case DT_RELAENT: return "RELAENT";
1644 case DT_STRSZ: return "STRSZ";
1645 case DT_SYMENT: return "SYMENT";
1646 case DT_INIT: return "INIT";
1647 case DT_FINI: return "FINI";
1648 case DT_SONAME: return "SONAME";
1649 case DT_RPATH: return "RPATH";
1650 case DT_SYMBOLIC: return "SYMBOLIC";
1651 case DT_REL: return "REL";
1652 case DT_RELSZ: return "RELSZ";
1653 case DT_RELENT: return "RELENT";
1654 case DT_PLTREL: return "PLTREL";
1655 case DT_DEBUG: return "DEBUG";
1656 case DT_TEXTREL: return "TEXTREL";
1657 case DT_JMPREL: return "JMPREL";
1658 case DT_BIND_NOW: return "BIND_NOW";
1659 case DT_INIT_ARRAY: return "INIT_ARRAY";
1660 case DT_FINI_ARRAY: return "FINI_ARRAY";
1661 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1662 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1663 case DT_RUNPATH: return "RUNPATH";
1664 case DT_FLAGS: return "FLAGS";
2d0e6f43 1665
d1133906
NC
1666 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1667 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1668
05107a46 1669 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1670 case DT_PLTPADSZ: return "PLTPADSZ";
1671 case DT_MOVEENT: return "MOVEENT";
1672 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1673 case DT_FEATURE: return "FEATURE";
252b5132
RH
1674 case DT_POSFLAG_1: return "POSFLAG_1";
1675 case DT_SYMINSZ: return "SYMINSZ";
1676 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1677
252b5132 1678 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1679 case DT_CONFIG: return "CONFIG";
1680 case DT_DEPAUDIT: return "DEPAUDIT";
1681 case DT_AUDIT: return "AUDIT";
1682 case DT_PLTPAD: return "PLTPAD";
1683 case DT_MOVETAB: return "MOVETAB";
252b5132 1684 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1685
252b5132 1686 case DT_VERSYM: return "VERSYM";
103f02d3 1687
67a4f2b7
AO
1688 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1689 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1690 case DT_RELACOUNT: return "RELACOUNT";
1691 case DT_RELCOUNT: return "RELCOUNT";
1692 case DT_FLAGS_1: return "FLAGS_1";
1693 case DT_VERDEF: return "VERDEF";
1694 case DT_VERDEFNUM: return "VERDEFNUM";
1695 case DT_VERNEED: return "VERNEED";
1696 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1697
019148e4 1698 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1699 case DT_USED: return "USED";
1700 case DT_FILTER: return "FILTER";
103f02d3 1701
047b2264
JJ
1702 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1703 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1704 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1705 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1706 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1707 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1708
252b5132
RH
1709 default:
1710 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1711 {
2cf0635d 1712 const char * result;
103f02d3 1713
252b5132
RH
1714 switch (elf_header.e_machine)
1715 {
1716 case EM_MIPS:
4fe85591 1717 case EM_MIPS_RS3_LE:
252b5132
RH
1718 result = get_mips_dynamic_type (type);
1719 break;
9a097730
RH
1720 case EM_SPARCV9:
1721 result = get_sparc64_dynamic_type (type);
1722 break;
7490d522
AM
1723 case EM_PPC:
1724 result = get_ppc_dynamic_type (type);
1725 break;
f1cb7e17
AM
1726 case EM_PPC64:
1727 result = get_ppc64_dynamic_type (type);
1728 break;
ecc51f48
NC
1729 case EM_IA_64:
1730 result = get_ia64_dynamic_type (type);
1731 break;
fabcb361
RH
1732 case EM_ALPHA:
1733 result = get_alpha_dynamic_type (type);
1734 break;
1c0d3aa6
NC
1735 case EM_SCORE:
1736 result = get_score_dynamic_type (type);
1737 break;
40b36596
JM
1738 case EM_TI_C6000:
1739 result = get_tic6x_dynamic_type (type);
1740 break;
252b5132
RH
1741 default:
1742 result = NULL;
1743 break;
1744 }
1745
1746 if (result != NULL)
1747 return result;
1748
e9e44622 1749 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1750 }
eec8f817
DA
1751 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1752 || (elf_header.e_machine == EM_PARISC
1753 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1754 {
2cf0635d 1755 const char * result;
103f02d3
UD
1756
1757 switch (elf_header.e_machine)
1758 {
1759 case EM_PARISC:
1760 result = get_parisc_dynamic_type (type);
1761 break;
148b93f2
NC
1762 case EM_IA_64:
1763 result = get_ia64_dynamic_type (type);
1764 break;
103f02d3
UD
1765 default:
1766 result = NULL;
1767 break;
1768 }
1769
1770 if (result != NULL)
1771 return result;
1772
e9e44622
JJ
1773 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1774 type);
103f02d3 1775 }
252b5132 1776 else
e9e44622 1777 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1778
252b5132
RH
1779 return buff;
1780 }
1781}
1782
1783static char *
d3ba0551 1784get_file_type (unsigned e_type)
252b5132 1785{
b34976b6 1786 static char buff[32];
252b5132
RH
1787
1788 switch (e_type)
1789 {
1790 case ET_NONE: return _("NONE (None)");
1791 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1792 case ET_EXEC: return _("EXEC (Executable file)");
1793 case ET_DYN: return _("DYN (Shared object file)");
1794 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1795
1796 default:
1797 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1798 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1799 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1800 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1801 else
e9e44622 1802 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1803 return buff;
1804 }
1805}
1806
1807static char *
d3ba0551 1808get_machine_name (unsigned e_machine)
252b5132 1809{
b34976b6 1810 static char buff[64]; /* XXX */
252b5132
RH
1811
1812 switch (e_machine)
1813 {
c45021f2
NC
1814 case EM_NONE: return _("None");
1815 case EM_M32: return "WE32100";
1816 case EM_SPARC: return "Sparc";
e9f53129 1817 case EM_SPU: return "SPU";
c45021f2
NC
1818 case EM_386: return "Intel 80386";
1819 case EM_68K: return "MC68000";
1820 case EM_88K: return "MC88000";
1821 case EM_486: return "Intel 80486";
1822 case EM_860: return "Intel 80860";
1823 case EM_MIPS: return "MIPS R3000";
1824 case EM_S370: return "IBM System/370";
7036c0e1 1825 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1826 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1827 case EM_PARISC: return "HPPA";
252b5132 1828 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1829 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1830 case EM_960: return "Intel 90860";
1831 case EM_PPC: return "PowerPC";
285d1771 1832 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1833 case EM_V800: return "NEC V800";
1834 case EM_FR20: return "Fujitsu FR20";
1835 case EM_RH32: return "TRW RH32";
b34976b6 1836 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1837 case EM_ARM: return "ARM";
1838 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1839 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1840 case EM_SPARCV9: return "Sparc v9";
1841 case EM_TRICORE: return "Siemens Tricore";
584da044 1842 case EM_ARC: return "ARC";
c2dcd04e
NC
1843 case EM_H8_300: return "Renesas H8/300";
1844 case EM_H8_300H: return "Renesas H8/300H";
1845 case EM_H8S: return "Renesas H8S";
1846 case EM_H8_500: return "Renesas H8/500";
30800947 1847 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1848 case EM_MIPS_X: return "Stanford MIPS-X";
1849 case EM_COLDFIRE: return "Motorola Coldfire";
1850 case EM_68HC12: return "Motorola M68HC12";
c45021f2 1851 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1852 case EM_CYGNUS_D10V:
1853 case EM_D10V: return "d10v";
1854 case EM_CYGNUS_D30V:
b34976b6 1855 case EM_D30V: return "d30v";
2b0337b0 1856 case EM_CYGNUS_M32R:
26597c86 1857 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1858 case EM_CYGNUS_V850:
8f7e76d0 1859 case EM_V850: return "Renesas v850";
2b0337b0
AO
1860 case EM_CYGNUS_MN10300:
1861 case EM_MN10300: return "mn10300";
1862 case EM_CYGNUS_MN10200:
1863 case EM_MN10200: return "mn10200";
5506d11a 1864 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1865 case EM_CYGNUS_FR30:
1866 case EM_FR30: return "Fujitsu FR30";
b34976b6 1867 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1868 case EM_PJ_OLD:
b34976b6 1869 case EM_PJ: return "picoJava";
7036c0e1
AJ
1870 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1871 case EM_PCP: return "Siemens PCP";
1872 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1873 case EM_NDR1: return "Denso NDR1 microprocesspr";
1874 case EM_STARCORE: return "Motorola Star*Core processor";
1875 case EM_ME16: return "Toyota ME16 processor";
1876 case EM_ST100: return "STMicroelectronics ST100 processor";
1877 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1878 case EM_PDSP: return "Sony DSP processor";
1879 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1880 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1881 case EM_FX66: return "Siemens FX66 microcontroller";
1882 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1883 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1884 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
1885 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1886 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1887 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1888 case EM_SVX: return "Silicon Graphics SVx";
1889 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1890 case EM_VAX: return "Digital VAX";
2b0337b0 1891 case EM_AVR_OLD:
b34976b6 1892 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1893 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1894 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1895 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1896 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1897 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1898 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1899 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1900 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1901 case EM_L1OM: return "Intel L1OM";
b7498e0e 1902 case EM_S390_OLD:
b34976b6 1903 case EM_S390: return "IBM S/390";
1c0d3aa6 1904 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1905 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1906 case EM_OPENRISC:
1907 case EM_OR32: return "OpenRISC";
11636f9e 1908 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1909 case EM_CRX: return "National Semiconductor CRX microprocessor";
d172d4ba 1910 case EM_DLX: return "OpenDLX";
1e4cf259 1911 case EM_IP2K_OLD:
b34976b6 1912 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1913 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1914 case EM_XTENSA_OLD:
1915 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1916 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1917 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1918 case EM_NS32K: return "National Semiconductor 32000 series";
1919 case EM_TPC: return "Tenor Network TPC processor";
1920 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1921 case EM_MAX: return "MAX Processor";
1922 case EM_CR: return "National Semiconductor CompactRISC";
1923 case EM_F2MC16: return "Fujitsu F2MC16";
1924 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1925 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1926 case EM_M32C_OLD:
49f58d10 1927 case EM_M32C: return "Renesas M32c";
d031aafb 1928 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1929 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1930 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1931 case EM_SEP: return "Sharp embedded microprocessor";
1932 case EM_ARCA: return "Arca RISC microprocessor";
1933 case EM_UNICORE: return "Unicore";
1934 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1935 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1936 case EM_NIOS32: return "Altera Nios";
1937 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1938 case EM_C166:
d70c5fc7 1939 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
1940 case EM_M16C: return "Renesas M16C series microprocessors";
1941 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
1942 case EM_CE: return "Freescale Communication Engine RISC core";
1943 case EM_TSK3000: return "Altium TSK3000 core";
1944 case EM_RS08: return "Freescale RS08 embedded processor";
1945 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
1946 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
1947 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
1948 case EM_SE_C17: return "Seiko Epson C17 family";
1949 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
1950 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
1951 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
1952 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
1953 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
1954 case EM_R32C: return "Renesas R32C series microprocessors";
1955 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
1956 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
1957 case EM_8051: return "Intel 8051 and variants";
1958 case EM_STXP7X: return "STMicroelectronics STxP7x family";
1959 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
1960 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
1961 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
1962 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
1963 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
1964 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 1965 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 1966 case EM_CR16:
6c03b1ed 1967 case EM_CR16_OLD: return "National Semiconductor's CR16";
7ba29e2a
NC
1968 case EM_MICROBLAZE: return "Xilinx MicroBlaze";
1969 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
c7927a3c 1970 case EM_RX: return "Renesas RX";
11636f9e
JM
1971 case EM_METAG: return "Imagination Technologies META processor architecture";
1972 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
1973 case EM_ECOG16: return "Cyan Technology eCOG16 family";
1974 case EM_ETPU: return "Freescale Extended Time Processing Unit";
1975 case EM_SLE9X: return "Infineon Technologies SLE9X core";
1976 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
1977 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
1978 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
1979 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 1980 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 1981 case EM_CUDA: return "NVIDIA CUDA architecture";
252b5132 1982 default:
35d9dd2f 1983 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
1984 return buff;
1985 }
1986}
1987
f3485b74 1988static void
d3ba0551 1989decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
1990{
1991 unsigned eabi;
1992 int unknown = 0;
1993
1994 eabi = EF_ARM_EABI_VERSION (e_flags);
1995 e_flags &= ~ EF_ARM_EABIMASK;
1996
1997 /* Handle "generic" ARM flags. */
1998 if (e_flags & EF_ARM_RELEXEC)
1999 {
2000 strcat (buf, ", relocatable executable");
2001 e_flags &= ~ EF_ARM_RELEXEC;
2002 }
76da6bbe 2003
f3485b74
NC
2004 if (e_flags & EF_ARM_HASENTRY)
2005 {
2006 strcat (buf, ", has entry point");
2007 e_flags &= ~ EF_ARM_HASENTRY;
2008 }
76da6bbe 2009
f3485b74
NC
2010 /* Now handle EABI specific flags. */
2011 switch (eabi)
2012 {
2013 default:
2c71103e 2014 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2015 if (e_flags)
2016 unknown = 1;
2017 break;
2018
2019 case EF_ARM_EABI_VER1:
a5bcd848 2020 strcat (buf, ", Version1 EABI");
f3485b74
NC
2021 while (e_flags)
2022 {
2023 unsigned flag;
76da6bbe 2024
f3485b74
NC
2025 /* Process flags one bit at a time. */
2026 flag = e_flags & - e_flags;
2027 e_flags &= ~ flag;
76da6bbe 2028
f3485b74
NC
2029 switch (flag)
2030 {
a5bcd848 2031 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2032 strcat (buf, ", sorted symbol tables");
2033 break;
76da6bbe 2034
f3485b74
NC
2035 default:
2036 unknown = 1;
2037 break;
2038 }
2039 }
2040 break;
76da6bbe 2041
a5bcd848
PB
2042 case EF_ARM_EABI_VER2:
2043 strcat (buf, ", Version2 EABI");
2044 while (e_flags)
2045 {
2046 unsigned flag;
2047
2048 /* Process flags one bit at a time. */
2049 flag = e_flags & - e_flags;
2050 e_flags &= ~ flag;
2051
2052 switch (flag)
2053 {
2054 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2055 strcat (buf, ", sorted symbol tables");
2056 break;
2057
2058 case EF_ARM_DYNSYMSUSESEGIDX:
2059 strcat (buf, ", dynamic symbols use segment index");
2060 break;
2061
2062 case EF_ARM_MAPSYMSFIRST:
2063 strcat (buf, ", mapping symbols precede others");
2064 break;
2065
2066 default:
2067 unknown = 1;
2068 break;
2069 }
2070 }
2071 break;
2072
d507cf36
PB
2073 case EF_ARM_EABI_VER3:
2074 strcat (buf, ", Version3 EABI");
8cb51566
PB
2075 break;
2076
2077 case EF_ARM_EABI_VER4:
2078 strcat (buf, ", Version4 EABI");
3a4a14e9
PB
2079 goto eabi;
2080
2081 case EF_ARM_EABI_VER5:
2082 strcat (buf, ", Version5 EABI");
2083 eabi:
d507cf36
PB
2084 while (e_flags)
2085 {
2086 unsigned flag;
2087
2088 /* Process flags one bit at a time. */
2089 flag = e_flags & - e_flags;
2090 e_flags &= ~ flag;
2091
2092 switch (flag)
2093 {
2094 case EF_ARM_BE8:
2095 strcat (buf, ", BE8");
2096 break;
2097
2098 case EF_ARM_LE8:
2099 strcat (buf, ", LE8");
2100 break;
2101
2102 default:
2103 unknown = 1;
2104 break;
2105 }
2106 }
2107 break;
2108
f3485b74 2109 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2110 strcat (buf, ", GNU EABI");
f3485b74
NC
2111 while (e_flags)
2112 {
2113 unsigned flag;
76da6bbe 2114
f3485b74
NC
2115 /* Process flags one bit at a time. */
2116 flag = e_flags & - e_flags;
2117 e_flags &= ~ flag;
76da6bbe 2118
f3485b74
NC
2119 switch (flag)
2120 {
a5bcd848 2121 case EF_ARM_INTERWORK:
f3485b74
NC
2122 strcat (buf, ", interworking enabled");
2123 break;
76da6bbe 2124
a5bcd848 2125 case EF_ARM_APCS_26:
f3485b74
NC
2126 strcat (buf, ", uses APCS/26");
2127 break;
76da6bbe 2128
a5bcd848 2129 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2130 strcat (buf, ", uses APCS/float");
2131 break;
76da6bbe 2132
a5bcd848 2133 case EF_ARM_PIC:
f3485b74
NC
2134 strcat (buf, ", position independent");
2135 break;
76da6bbe 2136
a5bcd848 2137 case EF_ARM_ALIGN8:
f3485b74
NC
2138 strcat (buf, ", 8 bit structure alignment");
2139 break;
76da6bbe 2140
a5bcd848 2141 case EF_ARM_NEW_ABI:
f3485b74
NC
2142 strcat (buf, ", uses new ABI");
2143 break;
76da6bbe 2144
a5bcd848 2145 case EF_ARM_OLD_ABI:
f3485b74
NC
2146 strcat (buf, ", uses old ABI");
2147 break;
76da6bbe 2148
a5bcd848 2149 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2150 strcat (buf, ", software FP");
2151 break;
76da6bbe 2152
90e01f86
ILT
2153 case EF_ARM_VFP_FLOAT:
2154 strcat (buf, ", VFP");
2155 break;
2156
fde78edd
NC
2157 case EF_ARM_MAVERICK_FLOAT:
2158 strcat (buf, ", Maverick FP");
2159 break;
2160
f3485b74
NC
2161 default:
2162 unknown = 1;
2163 break;
2164 }
2165 }
2166 }
f3485b74
NC
2167
2168 if (unknown)
2b692964 2169 strcat (buf,_(", <unknown>"));
f3485b74
NC
2170}
2171
252b5132 2172static char *
d3ba0551 2173get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2174{
b34976b6 2175 static char buf[1024];
252b5132
RH
2176
2177 buf[0] = '\0';
76da6bbe 2178
252b5132
RH
2179 if (e_flags)
2180 {
2181 switch (e_machine)
2182 {
2183 default:
2184 break;
2185
f3485b74
NC
2186 case EM_ARM:
2187 decode_ARM_machine_flags (e_flags, buf);
2188 break;
76da6bbe 2189
781303ce
MF
2190 case EM_BLACKFIN:
2191 if (e_flags & EF_BFIN_PIC)
2192 strcat (buf, ", PIC");
2193
2194 if (e_flags & EF_BFIN_FDPIC)
2195 strcat (buf, ", FDPIC");
2196
2197 if (e_flags & EF_BFIN_CODE_IN_L1)
2198 strcat (buf, ", code in L1");
2199
2200 if (e_flags & EF_BFIN_DATA_IN_L1)
2201 strcat (buf, ", data in L1");
2202
2203 break;
2204
ec2dfb42
AO
2205 case EM_CYGNUS_FRV:
2206 switch (e_flags & EF_FRV_CPU_MASK)
2207 {
2208 case EF_FRV_CPU_GENERIC:
2209 break;
2210
2211 default:
2212 strcat (buf, ", fr???");
2213 break;
57346661 2214
ec2dfb42
AO
2215 case EF_FRV_CPU_FR300:
2216 strcat (buf, ", fr300");
2217 break;
2218
2219 case EF_FRV_CPU_FR400:
2220 strcat (buf, ", fr400");
2221 break;
2222 case EF_FRV_CPU_FR405:
2223 strcat (buf, ", fr405");
2224 break;
2225
2226 case EF_FRV_CPU_FR450:
2227 strcat (buf, ", fr450");
2228 break;
2229
2230 case EF_FRV_CPU_FR500:
2231 strcat (buf, ", fr500");
2232 break;
2233 case EF_FRV_CPU_FR550:
2234 strcat (buf, ", fr550");
2235 break;
2236
2237 case EF_FRV_CPU_SIMPLE:
2238 strcat (buf, ", simple");
2239 break;
2240 case EF_FRV_CPU_TOMCAT:
2241 strcat (buf, ", tomcat");
2242 break;
2243 }
1c877e87 2244 break;
ec2dfb42 2245
53c7db4b 2246 case EM_68K:
425c6cb0 2247 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2248 strcat (buf, ", m68000");
425c6cb0 2249 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2250 strcat (buf, ", cpu32");
2251 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2252 strcat (buf, ", fido_a");
425c6cb0 2253 else
266abb8f 2254 {
2cf0635d
NC
2255 char const * isa = _("unknown");
2256 char const * mac = _("unknown mac");
2257 char const * additional = NULL;
0112cd26 2258
c694fd50 2259 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2260 {
c694fd50 2261 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2262 isa = "A";
2263 additional = ", nodiv";
2264 break;
c694fd50 2265 case EF_M68K_CF_ISA_A:
266abb8f
NS
2266 isa = "A";
2267 break;
c694fd50 2268 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2269 isa = "A+";
2270 break;
c694fd50 2271 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2272 isa = "B";
2273 additional = ", nousp";
2274 break;
c694fd50 2275 case EF_M68K_CF_ISA_B:
266abb8f
NS
2276 isa = "B";
2277 break;
f608cd77
NS
2278 case EF_M68K_CF_ISA_C:
2279 isa = "C";
2280 break;
2281 case EF_M68K_CF_ISA_C_NODIV:
2282 isa = "C";
2283 additional = ", nodiv";
2284 break;
266abb8f
NS
2285 }
2286 strcat (buf, ", cf, isa ");
2287 strcat (buf, isa);
0b2e31dc
NS
2288 if (additional)
2289 strcat (buf, additional);
c694fd50 2290 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2291 strcat (buf, ", float");
c694fd50 2292 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2293 {
2294 case 0:
2295 mac = NULL;
2296 break;
c694fd50 2297 case EF_M68K_CF_MAC:
266abb8f
NS
2298 mac = "mac";
2299 break;
c694fd50 2300 case EF_M68K_CF_EMAC:
266abb8f
NS
2301 mac = "emac";
2302 break;
f608cd77
NS
2303 case EF_M68K_CF_EMAC_B:
2304 mac = "emac_b";
2305 break;
266abb8f
NS
2306 }
2307 if (mac)
2308 {
2309 strcat (buf, ", ");
2310 strcat (buf, mac);
2311 }
266abb8f 2312 }
53c7db4b 2313 break;
33c63f9d 2314
252b5132
RH
2315 case EM_PPC:
2316 if (e_flags & EF_PPC_EMB)
2317 strcat (buf, ", emb");
2318
2319 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2320 strcat (buf, _(", relocatable"));
252b5132
RH
2321
2322 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2323 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2324 break;
2325
2b0337b0 2326 case EM_V850:
252b5132
RH
2327 case EM_CYGNUS_V850:
2328 switch (e_flags & EF_V850_ARCH)
2329 {
1cd986c5
NC
2330 case E_V850E2V3_ARCH:
2331 strcat (buf, ", v850e2v3");
2332 break;
2333 case E_V850E2_ARCH:
2334 strcat (buf, ", v850e2");
2335 break;
2336 case E_V850E1_ARCH:
2337 strcat (buf, ", v850e1");
8ad30312 2338 break;
252b5132
RH
2339 case E_V850E_ARCH:
2340 strcat (buf, ", v850e");
2341 break;
252b5132
RH
2342 case E_V850_ARCH:
2343 strcat (buf, ", v850");
2344 break;
2345 default:
2b692964 2346 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2347 break;
2348 }
2349 break;
2350
2b0337b0 2351 case EM_M32R:
252b5132
RH
2352 case EM_CYGNUS_M32R:
2353 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2354 strcat (buf, ", m32r");
252b5132
RH
2355 break;
2356
2357 case EM_MIPS:
4fe85591 2358 case EM_MIPS_RS3_LE:
252b5132
RH
2359 if (e_flags & EF_MIPS_NOREORDER)
2360 strcat (buf, ", noreorder");
2361
2362 if (e_flags & EF_MIPS_PIC)
2363 strcat (buf, ", pic");
2364
2365 if (e_flags & EF_MIPS_CPIC)
2366 strcat (buf, ", cpic");
2367
d1bdd336
TS
2368 if (e_flags & EF_MIPS_UCODE)
2369 strcat (buf, ", ugen_reserved");
2370
252b5132
RH
2371 if (e_flags & EF_MIPS_ABI2)
2372 strcat (buf, ", abi2");
2373
43521d43
TS
2374 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2375 strcat (buf, ", odk first");
2376
a5d22d2a
TS
2377 if (e_flags & EF_MIPS_32BITMODE)
2378 strcat (buf, ", 32bitmode");
2379
156c2f8b
NC
2380 switch ((e_flags & EF_MIPS_MACH))
2381 {
2382 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2383 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2384 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2385 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2386 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2387 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2388 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2389 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2390 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2391 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2392 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2393 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2394 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2395 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2396 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2397 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2398 case 0:
2399 /* We simply ignore the field in this case to avoid confusion:
2400 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2401 extension. */
2402 break;
2b692964 2403 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2404 }
43521d43
TS
2405
2406 switch ((e_flags & EF_MIPS_ABI))
2407 {
2408 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2409 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2410 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2411 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2412 case 0:
2413 /* We simply ignore the field in this case to avoid confusion:
2414 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2415 This means it is likely to be an o32 file, but not for
2416 sure. */
2417 break;
2b692964 2418 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2419 }
2420
2421 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2422 strcat (buf, ", mdmx");
2423
2424 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2425 strcat (buf, ", mips16");
2426
2427 switch ((e_flags & EF_MIPS_ARCH))
2428 {
2429 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2430 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2431 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2432 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2433 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2434 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2435 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2436 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2437 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2438 default: strcat (buf, _(", unknown ISA")); break;
43521d43
TS
2439 }
2440
8e45593f
NC
2441 if (e_flags & EF_SH_PIC)
2442 strcat (buf, ", pic");
2443
2444 if (e_flags & EF_SH_FDPIC)
2445 strcat (buf, ", fdpic");
252b5132 2446 break;
351b4b40 2447
ccde1100
AO
2448 case EM_SH:
2449 switch ((e_flags & EF_SH_MACH_MASK))
2450 {
2451 case EF_SH1: strcat (buf, ", sh1"); break;
2452 case EF_SH2: strcat (buf, ", sh2"); break;
2453 case EF_SH3: strcat (buf, ", sh3"); break;
2454 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2455 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2456 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2457 case EF_SH3E: strcat (buf, ", sh3e"); break;
2458 case EF_SH4: strcat (buf, ", sh4"); break;
2459 case EF_SH5: strcat (buf, ", sh5"); break;
2460 case EF_SH2E: strcat (buf, ", sh2e"); break;
2461 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2462 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2463 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2464 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2465 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2466 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2467 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2468 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2469 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2470 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2471 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2472 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2473 }
2474
2475 break;
57346661 2476
351b4b40
RH
2477 case EM_SPARCV9:
2478 if (e_flags & EF_SPARC_32PLUS)
2479 strcat (buf, ", v8+");
2480
2481 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2482 strcat (buf, ", ultrasparcI");
2483
2484 if (e_flags & EF_SPARC_SUN_US3)
2485 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2486
2487 if (e_flags & EF_SPARC_HAL_R1)
2488 strcat (buf, ", halr1");
2489
2490 if (e_flags & EF_SPARC_LEDATA)
2491 strcat (buf, ", ledata");
2492
2493 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2494 strcat (buf, ", tso");
2495
2496 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2497 strcat (buf, ", pso");
2498
2499 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2500 strcat (buf, ", rmo");
2501 break;
7d466069 2502
103f02d3
UD
2503 case EM_PARISC:
2504 switch (e_flags & EF_PARISC_ARCH)
2505 {
2506 case EFA_PARISC_1_0:
2507 strcpy (buf, ", PA-RISC 1.0");
2508 break;
2509 case EFA_PARISC_1_1:
2510 strcpy (buf, ", PA-RISC 1.1");
2511 break;
2512 case EFA_PARISC_2_0:
2513 strcpy (buf, ", PA-RISC 2.0");
2514 break;
2515 default:
2516 break;
2517 }
2518 if (e_flags & EF_PARISC_TRAPNIL)
2519 strcat (buf, ", trapnil");
2520 if (e_flags & EF_PARISC_EXT)
2521 strcat (buf, ", ext");
2522 if (e_flags & EF_PARISC_LSB)
2523 strcat (buf, ", lsb");
2524 if (e_flags & EF_PARISC_WIDE)
2525 strcat (buf, ", wide");
2526 if (e_flags & EF_PARISC_NO_KABP)
2527 strcat (buf, ", no kabp");
2528 if (e_flags & EF_PARISC_LAZYSWAP)
2529 strcat (buf, ", lazyswap");
30800947 2530 break;
76da6bbe 2531
7d466069 2532 case EM_PJ:
2b0337b0 2533 case EM_PJ_OLD:
7d466069
ILT
2534 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2535 strcat (buf, ", new calling convention");
2536
2537 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2538 strcat (buf, ", gnu calling convention");
2539 break;
4d6ed7c8
NC
2540
2541 case EM_IA_64:
2542 if ((e_flags & EF_IA_64_ABI64))
2543 strcat (buf, ", 64-bit");
2544 else
2545 strcat (buf, ", 32-bit");
2546 if ((e_flags & EF_IA_64_REDUCEDFP))
2547 strcat (buf, ", reduced fp model");
2548 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2549 strcat (buf, ", no function descriptors, constant gp");
2550 else if ((e_flags & EF_IA_64_CONS_GP))
2551 strcat (buf, ", constant gp");
2552 if ((e_flags & EF_IA_64_ABSOLUTE))
2553 strcat (buf, ", absolute");
28f997cf
TG
2554 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2555 {
2556 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2557 strcat (buf, ", vms_linkages");
2558 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2559 {
2560 case EF_IA_64_VMS_COMCOD_SUCCESS:
2561 break;
2562 case EF_IA_64_VMS_COMCOD_WARNING:
2563 strcat (buf, ", warning");
2564 break;
2565 case EF_IA_64_VMS_COMCOD_ERROR:
2566 strcat (buf, ", error");
2567 break;
2568 case EF_IA_64_VMS_COMCOD_ABORT:
2569 strcat (buf, ", abort");
2570 break;
2571 default:
2572 abort ();
2573 }
2574 }
4d6ed7c8 2575 break;
179d3252
JT
2576
2577 case EM_VAX:
2578 if ((e_flags & EF_VAX_NONPIC))
2579 strcat (buf, ", non-PIC");
2580 if ((e_flags & EF_VAX_DFLOAT))
2581 strcat (buf, ", D-Float");
2582 if ((e_flags & EF_VAX_GFLOAT))
2583 strcat (buf, ", G-Float");
2584 break;
c7927a3c
NC
2585
2586 case EM_RX:
2587 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2588 strcat (buf, ", 64-bit doubles");
2589 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2590 strcat (buf, ", dsp");
55786da2
AK
2591
2592 case EM_S390:
2593 if (e_flags & EF_S390_HIGH_GPRS)
2594 strcat (buf, ", highgprs");
40b36596
JM
2595
2596 case EM_TI_C6000:
2597 if ((e_flags & EF_C6000_REL))
2598 strcat (buf, ", relocatable module");
252b5132
RH
2599 }
2600 }
2601
2602 return buf;
2603}
2604
252b5132 2605static const char *
d3ba0551
AM
2606get_osabi_name (unsigned int osabi)
2607{
2608 static char buff[32];
2609
2610 switch (osabi)
2611 {
2612 case ELFOSABI_NONE: return "UNIX - System V";
2613 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2614 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2615 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2616 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2617 case ELFOSABI_AIX: return "UNIX - AIX";
2618 case ELFOSABI_IRIX: return "UNIX - IRIX";
2619 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2620 case ELFOSABI_TRU64: return "UNIX - TRU64";
2621 case ELFOSABI_MODESTO: return "Novell - Modesto";
2622 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2623 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2624 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2625 case ELFOSABI_AROS: return "AROS";
11636f9e 2626 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2627 default:
40b36596
JM
2628 if (osabi >= 64)
2629 switch (elf_header.e_machine)
2630 {
2631 case EM_ARM:
2632 switch (osabi)
2633 {
2634 case ELFOSABI_ARM: return "ARM";
2635 default:
2636 break;
2637 }
2638 break;
2639
2640 case EM_MSP430:
2641 case EM_MSP430_OLD:
2642 switch (osabi)
2643 {
2644 case ELFOSABI_STANDALONE: return _("Standalone App");
2645 default:
2646 break;
2647 }
2648 break;
2649
2650 case EM_TI_C6000:
2651 switch (osabi)
2652 {
2653 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2654 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2655 default:
2656 break;
2657 }
2658 break;
2659
2660 default:
2661 break;
2662 }
e9e44622 2663 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2664 return buff;
2665 }
2666}
2667
b294bdf8
MM
2668static const char *
2669get_arm_segment_type (unsigned long type)
2670{
2671 switch (type)
2672 {
2673 case PT_ARM_EXIDX:
2674 return "EXIDX";
2675 default:
2676 break;
2677 }
2678
2679 return NULL;
2680}
2681
d3ba0551
AM
2682static const char *
2683get_mips_segment_type (unsigned long type)
252b5132
RH
2684{
2685 switch (type)
2686 {
2687 case PT_MIPS_REGINFO:
2688 return "REGINFO";
2689 case PT_MIPS_RTPROC:
2690 return "RTPROC";
2691 case PT_MIPS_OPTIONS:
2692 return "OPTIONS";
2693 default:
2694 break;
2695 }
2696
2697 return NULL;
2698}
2699
103f02d3 2700static const char *
d3ba0551 2701get_parisc_segment_type (unsigned long type)
103f02d3
UD
2702{
2703 switch (type)
2704 {
2705 case PT_HP_TLS: return "HP_TLS";
2706 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2707 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2708 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2709 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2710 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2711 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2712 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2713 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2714 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2715 case PT_HP_PARALLEL: return "HP_PARALLEL";
2716 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2717 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2718 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2719 case PT_HP_STACK: return "HP_STACK";
2720 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2721 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2722 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2723 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2724 default:
2725 break;
2726 }
2727
2728 return NULL;
2729}
2730
4d6ed7c8 2731static const char *
d3ba0551 2732get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2733{
2734 switch (type)
2735 {
2736 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2737 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2738 case PT_HP_TLS: return "HP_TLS";
2739 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2740 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2741 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2742 default:
2743 break;
2744 }
2745
2746 return NULL;
2747}
2748
40b36596
JM
2749static const char *
2750get_tic6x_segment_type (unsigned long type)
2751{
2752 switch (type)
2753 {
2754 case PT_C6000_PHATTR: return "C6000_PHATTR";
2755 default:
2756 break;
2757 }
2758
2759 return NULL;
2760}
2761
252b5132 2762static const char *
d3ba0551 2763get_segment_type (unsigned long p_type)
252b5132 2764{
b34976b6 2765 static char buff[32];
252b5132
RH
2766
2767 switch (p_type)
2768 {
b34976b6
AM
2769 case PT_NULL: return "NULL";
2770 case PT_LOAD: return "LOAD";
252b5132 2771 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2772 case PT_INTERP: return "INTERP";
2773 case PT_NOTE: return "NOTE";
2774 case PT_SHLIB: return "SHLIB";
2775 case PT_PHDR: return "PHDR";
13ae64f3 2776 case PT_TLS: return "TLS";
252b5132 2777
65765700
JJ
2778 case PT_GNU_EH_FRAME:
2779 return "GNU_EH_FRAME";
2b05f1b7 2780 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2781 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2782
252b5132
RH
2783 default:
2784 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2785 {
2cf0635d 2786 const char * result;
103f02d3 2787
252b5132
RH
2788 switch (elf_header.e_machine)
2789 {
b294bdf8
MM
2790 case EM_ARM:
2791 result = get_arm_segment_type (p_type);
2792 break;
252b5132 2793 case EM_MIPS:
4fe85591 2794 case EM_MIPS_RS3_LE:
252b5132
RH
2795 result = get_mips_segment_type (p_type);
2796 break;
103f02d3
UD
2797 case EM_PARISC:
2798 result = get_parisc_segment_type (p_type);
2799 break;
4d6ed7c8
NC
2800 case EM_IA_64:
2801 result = get_ia64_segment_type (p_type);
2802 break;
40b36596
JM
2803 case EM_TI_C6000:
2804 result = get_tic6x_segment_type (p_type);
2805 break;
252b5132
RH
2806 default:
2807 result = NULL;
2808 break;
2809 }
103f02d3 2810
252b5132
RH
2811 if (result != NULL)
2812 return result;
103f02d3 2813
252b5132
RH
2814 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2815 }
2816 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2817 {
2cf0635d 2818 const char * result;
103f02d3
UD
2819
2820 switch (elf_header.e_machine)
2821 {
2822 case EM_PARISC:
2823 result = get_parisc_segment_type (p_type);
2824 break;
00428cca
AM
2825 case EM_IA_64:
2826 result = get_ia64_segment_type (p_type);
2827 break;
103f02d3
UD
2828 default:
2829 result = NULL;
2830 break;
2831 }
2832
2833 if (result != NULL)
2834 return result;
2835
2836 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2837 }
252b5132 2838 else
e9e44622 2839 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2840
2841 return buff;
2842 }
2843}
2844
2845static const char *
d3ba0551 2846get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2847{
2848 switch (sh_type)
2849 {
b34976b6
AM
2850 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2851 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2852 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2853 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2854 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2855 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2856 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2857 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2858 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2859 case SHT_MIPS_RELD: return "MIPS_RELD";
2860 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2861 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2862 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2863 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2864 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2865 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2866 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2867 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2868 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2869 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2870 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2871 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2872 case SHT_MIPS_LINE: return "MIPS_LINE";
2873 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2874 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2875 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2876 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2877 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2878 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2879 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2880 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2881 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2882 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2883 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2884 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2885 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2886 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2887 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2888 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2889 default:
2890 break;
2891 }
2892 return NULL;
2893}
2894
103f02d3 2895static const char *
d3ba0551 2896get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2897{
2898 switch (sh_type)
2899 {
2900 case SHT_PARISC_EXT: return "PARISC_EXT";
2901 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2902 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2903 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2904 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2905 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2906 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2907 default:
2908 break;
2909 }
2910 return NULL;
2911}
2912
4d6ed7c8 2913static const char *
d3ba0551 2914get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2915{
18bd398b 2916 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2917 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2918 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2919
4d6ed7c8
NC
2920 switch (sh_type)
2921 {
148b93f2
NC
2922 case SHT_IA_64_EXT: return "IA_64_EXT";
2923 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2924 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
2925 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
2926 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
2927 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
2928 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
2929 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
2930 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
2931 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
2932 default:
2933 break;
2934 }
2935 return NULL;
2936}
2937
d2b2c203
DJ
2938static const char *
2939get_x86_64_section_type_name (unsigned int sh_type)
2940{
2941 switch (sh_type)
2942 {
2943 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2944 default:
2945 break;
2946 }
2947 return NULL;
2948}
2949
40a18ebd
NC
2950static const char *
2951get_arm_section_type_name (unsigned int sh_type)
2952{
2953 switch (sh_type)
2954 {
7f6fed87
NC
2955 case SHT_ARM_EXIDX: return "ARM_EXIDX";
2956 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
2957 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
2958 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
2959 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
2960 default:
2961 break;
2962 }
2963 return NULL;
2964}
2965
40b36596
JM
2966static const char *
2967get_tic6x_section_type_name (unsigned int sh_type)
2968{
2969 switch (sh_type)
2970 {
2971 case SHT_C6000_UNWIND:
2972 return "C6000_UNWIND";
2973 case SHT_C6000_PREEMPTMAP:
2974 return "C6000_PREEMPTMAP";
2975 case SHT_C6000_ATTRIBUTES:
2976 return "C6000_ATTRIBUTES";
2977 case SHT_TI_ICODE:
2978 return "TI_ICODE";
2979 case SHT_TI_XREF:
2980 return "TI_XREF";
2981 case SHT_TI_HANDLER:
2982 return "TI_HANDLER";
2983 case SHT_TI_INITINFO:
2984 return "TI_INITINFO";
2985 case SHT_TI_PHATTRS:
2986 return "TI_PHATTRS";
2987 default:
2988 break;
2989 }
2990 return NULL;
2991}
2992
252b5132 2993static const char *
d3ba0551 2994get_section_type_name (unsigned int sh_type)
252b5132 2995{
b34976b6 2996 static char buff[32];
252b5132
RH
2997
2998 switch (sh_type)
2999 {
3000 case SHT_NULL: return "NULL";
3001 case SHT_PROGBITS: return "PROGBITS";
3002 case SHT_SYMTAB: return "SYMTAB";
3003 case SHT_STRTAB: return "STRTAB";
3004 case SHT_RELA: return "RELA";
3005 case SHT_HASH: return "HASH";
3006 case SHT_DYNAMIC: return "DYNAMIC";
3007 case SHT_NOTE: return "NOTE";
3008 case SHT_NOBITS: return "NOBITS";
3009 case SHT_REL: return "REL";
3010 case SHT_SHLIB: return "SHLIB";
3011 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3012 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3013 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3014 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3015 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3016 case SHT_GROUP: return "GROUP";
3017 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3018 case SHT_GNU_verdef: return "VERDEF";
3019 case SHT_GNU_verneed: return "VERNEED";
3020 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3021 case 0x6ffffff0: return "VERSYM";
3022 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3023 case 0x7ffffffd: return "AUXILIARY";
3024 case 0x7fffffff: return "FILTER";
047b2264 3025 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3026
3027 default:
3028 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3029 {
2cf0635d 3030 const char * result;
252b5132
RH
3031
3032 switch (elf_header.e_machine)
3033 {
3034 case EM_MIPS:
4fe85591 3035 case EM_MIPS_RS3_LE:
252b5132
RH
3036 result = get_mips_section_type_name (sh_type);
3037 break;
103f02d3
UD
3038 case EM_PARISC:
3039 result = get_parisc_section_type_name (sh_type);
3040 break;
4d6ed7c8
NC
3041 case EM_IA_64:
3042 result = get_ia64_section_type_name (sh_type);
3043 break;
d2b2c203 3044 case EM_X86_64:
8a9036a4 3045 case EM_L1OM:
d2b2c203
DJ
3046 result = get_x86_64_section_type_name (sh_type);
3047 break;
40a18ebd
NC
3048 case EM_ARM:
3049 result = get_arm_section_type_name (sh_type);
3050 break;
40b36596
JM
3051 case EM_TI_C6000:
3052 result = get_tic6x_section_type_name (sh_type);
3053 break;
252b5132
RH
3054 default:
3055 result = NULL;
3056 break;
3057 }
3058
3059 if (result != NULL)
3060 return result;
3061
c91d0dfb 3062 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3063 }
3064 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3065 {
2cf0635d 3066 const char * result;
148b93f2
NC
3067
3068 switch (elf_header.e_machine)
3069 {
3070 case EM_IA_64:
3071 result = get_ia64_section_type_name (sh_type);
3072 break;
3073 default:
3074 result = NULL;
3075 break;
3076 }
3077
3078 if (result != NULL)
3079 return result;
3080
3081 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3082 }
252b5132 3083 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3084 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3085 else
a7dbfd1c
NC
3086 /* This message is probably going to be displayed in a 15
3087 character wide field, so put the hex value first. */
3088 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3089
252b5132
RH
3090 return buff;
3091 }
3092}
3093
2979dc34 3094#define OPTION_DEBUG_DUMP 512
2c610e4b 3095#define OPTION_DYN_SYMS 513
fd2f0033
TT
3096#define OPTION_DWARF_DEPTH 514
3097#define OPTION_DWARF_START 515
2979dc34 3098
85b1c36d 3099static struct option options[] =
252b5132 3100{
b34976b6 3101 {"all", no_argument, 0, 'a'},
252b5132
RH
3102 {"file-header", no_argument, 0, 'h'},
3103 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3104 {"headers", no_argument, 0, 'e'},
3105 {"histogram", no_argument, 0, 'I'},
3106 {"segments", no_argument, 0, 'l'},
3107 {"sections", no_argument, 0, 'S'},
252b5132 3108 {"section-headers", no_argument, 0, 'S'},
f5842774 3109 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3110 {"section-details", no_argument, 0, 't'},
595cf52e 3111 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3112 {"symbols", no_argument, 0, 's'},
3113 {"syms", no_argument, 0, 's'},
2c610e4b 3114 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3115 {"relocs", no_argument, 0, 'r'},
3116 {"notes", no_argument, 0, 'n'},
3117 {"dynamic", no_argument, 0, 'd'},
a952a375 3118 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3119 {"version-info", no_argument, 0, 'V'},
3120 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3121 {"unwind", no_argument, 0, 'u'},
4145f1d5 3122 {"archive-index", no_argument, 0, 'c'},
b34976b6 3123 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3124 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3125 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3126#ifdef SUPPORT_DISASSEMBLY
3127 {"instruction-dump", required_argument, 0, 'i'},
3128#endif
cf13d699 3129 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3130
fd2f0033
TT
3131 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3132 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
3133
b34976b6
AM
3134 {"version", no_argument, 0, 'v'},
3135 {"wide", no_argument, 0, 'W'},
3136 {"help", no_argument, 0, 'H'},
3137 {0, no_argument, 0, 0}
252b5132
RH
3138};
3139
3140static void
2cf0635d 3141usage (FILE * stream)
252b5132 3142{
92f01d61
JM
3143 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3144 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3145 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3146 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3147 -h --file-header Display the ELF file header\n\
3148 -l --program-headers Display the program headers\n\
3149 --segments An alias for --program-headers\n\
3150 -S --section-headers Display the sections' header\n\
3151 --sections An alias for --section-headers\n\
f5842774 3152 -g --section-groups Display the section groups\n\
5477e8a0 3153 -t --section-details Display the section details\n\
8b53311e
NC
3154 -e --headers Equivalent to: -h -l -S\n\
3155 -s --syms Display the symbol table\n\
3f08eb35 3156 --symbols An alias for --syms\n\
2c610e4b 3157 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3158 -n --notes Display the core notes (if present)\n\
3159 -r --relocs Display the relocations (if present)\n\
3160 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3161 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
3162 -V --version-info Display the version sections (if present)\n\
3163 -A --arch-specific Display architecture specific information (if any).\n\
4145f1d5 3164 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3165 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3166 -x --hex-dump=<number|name>\n\
3167 Dump the contents of section <number|name> as bytes\n\
3168 -p --string-dump=<number|name>\n\
3169 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3170 -R --relocated-dump=<number|name>\n\
3171 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3172 -w[lLiaprmfFsoRt] or\n\
1ed06042 3173 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3174 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
5bbdf3d5 3175 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
8b53311e 3176 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3177 fprintf (stream, _("\
3178 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3179 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3180 or deeper\n"));
252b5132 3181#ifdef SUPPORT_DISASSEMBLY
92f01d61 3182 fprintf (stream, _("\
09c11c86
NC
3183 -i --instruction-dump=<number|name>\n\
3184 Disassemble the contents of section <number|name>\n"));
252b5132 3185#endif
92f01d61 3186 fprintf (stream, _("\
8b53311e
NC
3187 -I --histogram Display histogram of bucket list lengths\n\
3188 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3189 @<file> Read options from <file>\n\
8b53311e
NC
3190 -H --help Display this information\n\
3191 -v --version Display the version number of readelf\n"));
1118d252 3192
92f01d61
JM
3193 if (REPORT_BUGS_TO[0] && stream == stdout)
3194 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3195
92f01d61 3196 exit (stream == stdout ? 0 : 1);
252b5132
RH
3197}
3198
18bd398b
NC
3199/* Record the fact that the user wants the contents of section number
3200 SECTION to be displayed using the method(s) encoded as flags bits
3201 in TYPE. Note, TYPE can be zero if we are creating the array for
3202 the first time. */
3203
252b5132 3204static void
09c11c86 3205request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3206{
3207 if (section >= num_dump_sects)
3208 {
2cf0635d 3209 dump_type * new_dump_sects;
252b5132 3210
3f5e193b
NC
3211 new_dump_sects = (dump_type *) calloc (section + 1,
3212 sizeof (* dump_sects));
252b5132
RH
3213
3214 if (new_dump_sects == NULL)
591a748a 3215 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3216 else
3217 {
3218 /* Copy current flag settings. */
09c11c86 3219 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3220
3221 free (dump_sects);
3222
3223 dump_sects = new_dump_sects;
3224 num_dump_sects = section + 1;
3225 }
3226 }
3227
3228 if (dump_sects)
b34976b6 3229 dump_sects[section] |= type;
252b5132
RH
3230
3231 return;
3232}
3233
aef1f6d0
DJ
3234/* Request a dump by section name. */
3235
3236static void
2cf0635d 3237request_dump_byname (const char * section, dump_type type)
aef1f6d0 3238{
2cf0635d 3239 struct dump_list_entry * new_request;
aef1f6d0 3240
3f5e193b
NC
3241 new_request = (struct dump_list_entry *)
3242 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3243 if (!new_request)
591a748a 3244 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3245
3246 new_request->name = strdup (section);
3247 if (!new_request->name)
591a748a 3248 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3249
3250 new_request->type = type;
3251
3252 new_request->next = dump_sects_byname;
3253 dump_sects_byname = new_request;
3254}
3255
cf13d699
NC
3256static inline void
3257request_dump (dump_type type)
3258{
3259 int section;
3260 char * cp;
3261
3262 do_dump++;
3263 section = strtoul (optarg, & cp, 0);
3264
3265 if (! *cp && section >= 0)
3266 request_dump_bynumber (section, type);
3267 else
3268 request_dump_byname (optarg, type);
3269}
3270
3271
252b5132 3272static void
2cf0635d 3273parse_args (int argc, char ** argv)
252b5132
RH
3274{
3275 int c;
3276
3277 if (argc < 2)
92f01d61 3278 usage (stderr);
252b5132
RH
3279
3280 while ((c = getopt_long
cf13d699 3281 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3282 {
252b5132
RH
3283 switch (c)
3284 {
3285 case 0:
3286 /* Long options. */
3287 break;
3288 case 'H':
92f01d61 3289 usage (stdout);
252b5132
RH
3290 break;
3291
3292 case 'a':
b34976b6
AM
3293 do_syms++;
3294 do_reloc++;
3295 do_unwind++;
3296 do_dynamic++;
3297 do_header++;
3298 do_sections++;
f5842774 3299 do_section_groups++;
b34976b6
AM
3300 do_segments++;
3301 do_version++;
3302 do_histogram++;
3303 do_arch++;
3304 do_notes++;
252b5132 3305 break;
f5842774
L
3306 case 'g':
3307 do_section_groups++;
3308 break;
5477e8a0 3309 case 't':
595cf52e 3310 case 'N':
5477e8a0
L
3311 do_sections++;
3312 do_section_details++;
595cf52e 3313 break;
252b5132 3314 case 'e':
b34976b6
AM
3315 do_header++;
3316 do_sections++;
3317 do_segments++;
252b5132 3318 break;
a952a375 3319 case 'A':
b34976b6 3320 do_arch++;
a952a375 3321 break;
252b5132 3322 case 'D':
b34976b6 3323 do_using_dynamic++;
252b5132
RH
3324 break;
3325 case 'r':
b34976b6 3326 do_reloc++;
252b5132 3327 break;
4d6ed7c8 3328 case 'u':
b34976b6 3329 do_unwind++;
4d6ed7c8 3330 break;
252b5132 3331 case 'h':
b34976b6 3332 do_header++;
252b5132
RH
3333 break;
3334 case 'l':
b34976b6 3335 do_segments++;
252b5132
RH
3336 break;
3337 case 's':
b34976b6 3338 do_syms++;
252b5132
RH
3339 break;
3340 case 'S':
b34976b6 3341 do_sections++;
252b5132
RH
3342 break;
3343 case 'd':
b34976b6 3344 do_dynamic++;
252b5132 3345 break;
a952a375 3346 case 'I':
b34976b6 3347 do_histogram++;
a952a375 3348 break;
779fe533 3349 case 'n':
b34976b6 3350 do_notes++;
779fe533 3351 break;
4145f1d5
NC
3352 case 'c':
3353 do_archive_index++;
3354 break;
252b5132 3355 case 'x':
cf13d699 3356 request_dump (HEX_DUMP);
aef1f6d0 3357 break;
09c11c86 3358 case 'p':
cf13d699
NC
3359 request_dump (STRING_DUMP);
3360 break;
3361 case 'R':
3362 request_dump (RELOC_DUMP);
09c11c86 3363 break;
252b5132 3364 case 'w':
b34976b6 3365 do_dump++;
252b5132 3366 if (optarg == 0)
613ff48b
CC
3367 {
3368 do_debugging = 1;
3369 dwarf_select_sections_all ();
3370 }
252b5132
RH
3371 else
3372 {
3373 do_debugging = 0;
4cb93e3b 3374 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3375 }
3376 break;
2979dc34 3377 case OPTION_DEBUG_DUMP:
b34976b6 3378 do_dump++;
2979dc34
JJ
3379 if (optarg == 0)
3380 do_debugging = 1;
3381 else
3382 {
2979dc34 3383 do_debugging = 0;
4cb93e3b 3384 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3385 }
3386 break;
fd2f0033
TT
3387 case OPTION_DWARF_DEPTH:
3388 {
3389 char *cp;
3390
3391 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3392 }
3393 break;
3394 case OPTION_DWARF_START:
3395 {
3396 char *cp;
3397
3398 dwarf_start_die = strtoul (optarg, & cp, 0);
3399 }
3400 break;
2c610e4b
L
3401 case OPTION_DYN_SYMS:
3402 do_dyn_syms++;
3403 break;
252b5132
RH
3404#ifdef SUPPORT_DISASSEMBLY
3405 case 'i':
cf13d699
NC
3406 request_dump (DISASS_DUMP);
3407 break;
252b5132
RH
3408#endif
3409 case 'v':
3410 print_version (program_name);
3411 break;
3412 case 'V':
b34976b6 3413 do_version++;
252b5132 3414 break;
d974e256 3415 case 'W':
b34976b6 3416 do_wide++;
d974e256 3417 break;
252b5132 3418 default:
252b5132
RH
3419 /* xgettext:c-format */
3420 error (_("Invalid option '-%c'\n"), c);
3421 /* Drop through. */
3422 case '?':
92f01d61 3423 usage (stderr);
252b5132
RH
3424 }
3425 }
3426
4d6ed7c8 3427 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3428 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3429 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3430 && !do_section_groups && !do_archive_index
3431 && !do_dyn_syms)
92f01d61 3432 usage (stderr);
252b5132
RH
3433 else if (argc < 3)
3434 {
3435 warn (_("Nothing to do.\n"));
92f01d61 3436 usage (stderr);
252b5132
RH
3437 }
3438}
3439
3440static const char *
d3ba0551 3441get_elf_class (unsigned int elf_class)
252b5132 3442{
b34976b6 3443 static char buff[32];
103f02d3 3444
252b5132
RH
3445 switch (elf_class)
3446 {
3447 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3448 case ELFCLASS32: return "ELF32";
3449 case ELFCLASS64: return "ELF64";
ab5e7794 3450 default:
e9e44622 3451 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3452 return buff;
252b5132
RH
3453 }
3454}
3455
3456static const char *
d3ba0551 3457get_data_encoding (unsigned int encoding)
252b5132 3458{
b34976b6 3459 static char buff[32];
103f02d3 3460
252b5132
RH
3461 switch (encoding)
3462 {
3463 case ELFDATANONE: return _("none");
33c63f9d
CM
3464 case ELFDATA2LSB: return _("2's complement, little endian");
3465 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3466 default:
e9e44622 3467 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3468 return buff;
252b5132
RH
3469 }
3470}
3471
252b5132 3472/* Decode the data held in 'elf_header'. */
ee42cf8c 3473
252b5132 3474static int
d3ba0551 3475process_file_header (void)
252b5132 3476{
b34976b6
AM
3477 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3478 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3479 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3480 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3481 {
3482 error
3483 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3484 return 0;
3485 }
3486
2dc4cec1
L
3487 init_dwarf_regnames (elf_header.e_machine);
3488
252b5132
RH
3489 if (do_header)
3490 {
3491 int i;
3492
3493 printf (_("ELF Header:\n"));
3494 printf (_(" Magic: "));
b34976b6
AM
3495 for (i = 0; i < EI_NIDENT; i++)
3496 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3497 printf ("\n");
3498 printf (_(" Class: %s\n"),
b34976b6 3499 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3500 printf (_(" Data: %s\n"),
b34976b6 3501 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3502 printf (_(" Version: %d %s\n"),
b34976b6
AM
3503 elf_header.e_ident[EI_VERSION],
3504 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3505 ? "(current)"
b34976b6 3506 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3507 ? _("<unknown: %lx>")
789be9f7 3508 : "")));
252b5132 3509 printf (_(" OS/ABI: %s\n"),
b34976b6 3510 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3511 printf (_(" ABI Version: %d\n"),
b34976b6 3512 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3513 printf (_(" Type: %s\n"),
3514 get_file_type (elf_header.e_type));
3515 printf (_(" Machine: %s\n"),
3516 get_machine_name (elf_header.e_machine));
3517 printf (_(" Version: 0x%lx\n"),
3518 (unsigned long) elf_header.e_version);
76da6bbe 3519
f7a99963
NC
3520 printf (_(" Entry point address: "));
3521 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3522 printf (_("\n Start of program headers: "));
3523 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3524 printf (_(" (bytes into file)\n Start of section headers: "));
3525 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3526 printf (_(" (bytes into file)\n"));
76da6bbe 3527
252b5132
RH
3528 printf (_(" Flags: 0x%lx%s\n"),
3529 (unsigned long) elf_header.e_flags,
3530 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3531 printf (_(" Size of this header: %ld (bytes)\n"),
3532 (long) elf_header.e_ehsize);
3533 printf (_(" Size of program headers: %ld (bytes)\n"),
3534 (long) elf_header.e_phentsize);
2046a35d 3535 printf (_(" Number of program headers: %ld"),
252b5132 3536 (long) elf_header.e_phnum);
2046a35d
AM
3537 if (section_headers != NULL
3538 && elf_header.e_phnum == PN_XNUM
3539 && section_headers[0].sh_info != 0)
cc5914eb 3540 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3541 putc ('\n', stdout);
252b5132
RH
3542 printf (_(" Size of section headers: %ld (bytes)\n"),
3543 (long) elf_header.e_shentsize);
560f3c1c 3544 printf (_(" Number of section headers: %ld"),
252b5132 3545 (long) elf_header.e_shnum);
4fbb74a6 3546 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3547 printf (" (%ld)", (long) section_headers[0].sh_size);
3548 putc ('\n', stdout);
3549 printf (_(" Section header string table index: %ld"),
252b5132 3550 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3551 if (section_headers != NULL
3552 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3553 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3554 else if (elf_header.e_shstrndx != SHN_UNDEF
3555 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3556 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3557 putc ('\n', stdout);
3558 }
3559
3560 if (section_headers != NULL)
3561 {
2046a35d
AM
3562 if (elf_header.e_phnum == PN_XNUM
3563 && section_headers[0].sh_info != 0)
3564 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3565 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3566 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3567 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3568 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3569 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3570 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3571 free (section_headers);
3572 section_headers = NULL;
252b5132 3573 }
103f02d3 3574
9ea033b2
NC
3575 return 1;
3576}
3577
252b5132 3578
9ea033b2 3579static int
91d6fa6a 3580get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3581{
2cf0635d
NC
3582 Elf32_External_Phdr * phdrs;
3583 Elf32_External_Phdr * external;
3584 Elf_Internal_Phdr * internal;
b34976b6 3585 unsigned int i;
103f02d3 3586
3f5e193b
NC
3587 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3588 elf_header.e_phentsize,
3589 elf_header.e_phnum,
3590 _("program headers"));
a6e9f9df
AM
3591 if (!phdrs)
3592 return 0;
9ea033b2 3593
91d6fa6a 3594 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3595 i < elf_header.e_phnum;
b34976b6 3596 i++, internal++, external++)
252b5132 3597 {
9ea033b2
NC
3598 internal->p_type = BYTE_GET (external->p_type);
3599 internal->p_offset = BYTE_GET (external->p_offset);
3600 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3601 internal->p_paddr = BYTE_GET (external->p_paddr);
3602 internal->p_filesz = BYTE_GET (external->p_filesz);
3603 internal->p_memsz = BYTE_GET (external->p_memsz);
3604 internal->p_flags = BYTE_GET (external->p_flags);
3605 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3606 }
3607
9ea033b2
NC
3608 free (phdrs);
3609
252b5132
RH
3610 return 1;
3611}
3612
9ea033b2 3613static int
91d6fa6a 3614get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3615{
2cf0635d
NC
3616 Elf64_External_Phdr * phdrs;
3617 Elf64_External_Phdr * external;
3618 Elf_Internal_Phdr * internal;
b34976b6 3619 unsigned int i;
103f02d3 3620
3f5e193b
NC
3621 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3622 elf_header.e_phentsize,
3623 elf_header.e_phnum,
3624 _("program headers"));
a6e9f9df
AM
3625 if (!phdrs)
3626 return 0;
9ea033b2 3627
91d6fa6a 3628 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3629 i < elf_header.e_phnum;
b34976b6 3630 i++, internal++, external++)
9ea033b2
NC
3631 {
3632 internal->p_type = BYTE_GET (external->p_type);
3633 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3634 internal->p_offset = BYTE_GET (external->p_offset);
3635 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3636 internal->p_paddr = BYTE_GET (external->p_paddr);
3637 internal->p_filesz = BYTE_GET (external->p_filesz);
3638 internal->p_memsz = BYTE_GET (external->p_memsz);
3639 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3640 }
3641
3642 free (phdrs);
3643
3644 return 1;
3645}
252b5132 3646
d93f0186
NC
3647/* Returns 1 if the program headers were read into `program_headers'. */
3648
3649static int
2cf0635d 3650get_program_headers (FILE * file)
d93f0186 3651{
2cf0635d 3652 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3653
3654 /* Check cache of prior read. */
3655 if (program_headers != NULL)
3656 return 1;
3657
3f5e193b
NC
3658 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3659 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3660
3661 if (phdrs == NULL)
3662 {
3663 error (_("Out of memory\n"));
3664 return 0;
3665 }
3666
3667 if (is_32bit_elf
3668 ? get_32bit_program_headers (file, phdrs)
3669 : get_64bit_program_headers (file, phdrs))
3670 {
3671 program_headers = phdrs;
3672 return 1;
3673 }
3674
3675 free (phdrs);
3676 return 0;
3677}
3678
2f62977e
NC
3679/* Returns 1 if the program headers were loaded. */
3680
252b5132 3681static int
2cf0635d 3682process_program_headers (FILE * file)
252b5132 3683{
2cf0635d 3684 Elf_Internal_Phdr * segment;
b34976b6 3685 unsigned int i;
252b5132
RH
3686
3687 if (elf_header.e_phnum == 0)
3688 {
82f2dbf7
NC
3689 /* PR binutils/12467. */
3690 if (elf_header.e_phoff != 0)
3691 warn (_("possibly corrupt ELF header - it has a non-zero program"
3692 " header offset, but no program headers"));
3693 else if (do_segments)
252b5132 3694 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3695 return 0;
252b5132
RH
3696 }
3697
3698 if (do_segments && !do_header)
3699 {
f7a99963
NC
3700 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3701 printf (_("Entry point "));
3702 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3703 printf (_("\nThere are %d program headers, starting at offset "),
3704 elf_header.e_phnum);
3705 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3706 printf ("\n");
252b5132
RH
3707 }
3708
d93f0186 3709 if (! get_program_headers (file))
252b5132 3710 return 0;
103f02d3 3711
252b5132
RH
3712 if (do_segments)
3713 {
3a1a2036
NC
3714 if (elf_header.e_phnum > 1)
3715 printf (_("\nProgram Headers:\n"));
3716 else
3717 printf (_("\nProgram Headers:\n"));
76da6bbe 3718
f7a99963
NC
3719 if (is_32bit_elf)
3720 printf
3721 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3722 else if (do_wide)
3723 printf
3724 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3725 else
3726 {
3727 printf
3728 (_(" Type Offset VirtAddr PhysAddr\n"));
3729 printf
3730 (_(" FileSiz MemSiz Flags Align\n"));
3731 }
252b5132
RH
3732 }
3733
252b5132 3734 dynamic_addr = 0;
1b228002 3735 dynamic_size = 0;
252b5132
RH
3736
3737 for (i = 0, segment = program_headers;
3738 i < elf_header.e_phnum;
b34976b6 3739 i++, segment++)
252b5132
RH
3740 {
3741 if (do_segments)
3742 {
103f02d3 3743 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3744
3745 if (is_32bit_elf)
3746 {
3747 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3748 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3749 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3750 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3751 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3752 printf ("%c%c%c ",
3753 (segment->p_flags & PF_R ? 'R' : ' '),
3754 (segment->p_flags & PF_W ? 'W' : ' '),
3755 (segment->p_flags & PF_X ? 'E' : ' '));
3756 printf ("%#lx", (unsigned long) segment->p_align);
3757 }
d974e256
JJ
3758 else if (do_wide)
3759 {
3760 if ((unsigned long) segment->p_offset == segment->p_offset)
3761 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3762 else
3763 {
3764 print_vma (segment->p_offset, FULL_HEX);
3765 putchar (' ');
3766 }
3767
3768 print_vma (segment->p_vaddr, FULL_HEX);
3769 putchar (' ');
3770 print_vma (segment->p_paddr, FULL_HEX);
3771 putchar (' ');
3772
3773 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3774 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3775 else
3776 {
3777 print_vma (segment->p_filesz, FULL_HEX);
3778 putchar (' ');
3779 }
3780
3781 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3782 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3783 else
3784 {
3785 print_vma (segment->p_offset, FULL_HEX);
3786 }
3787
3788 printf (" %c%c%c ",
3789 (segment->p_flags & PF_R ? 'R' : ' '),
3790 (segment->p_flags & PF_W ? 'W' : ' '),
3791 (segment->p_flags & PF_X ? 'E' : ' '));
3792
3793 if ((unsigned long) segment->p_align == segment->p_align)
3794 printf ("%#lx", (unsigned long) segment->p_align);
3795 else
3796 {
3797 print_vma (segment->p_align, PREFIX_HEX);
3798 }
3799 }
f7a99963
NC
3800 else
3801 {
3802 print_vma (segment->p_offset, FULL_HEX);
3803 putchar (' ');
3804 print_vma (segment->p_vaddr, FULL_HEX);
3805 putchar (' ');
3806 print_vma (segment->p_paddr, FULL_HEX);
3807 printf ("\n ");
3808 print_vma (segment->p_filesz, FULL_HEX);
3809 putchar (' ');
3810 print_vma (segment->p_memsz, FULL_HEX);
3811 printf (" %c%c%c ",
3812 (segment->p_flags & PF_R ? 'R' : ' '),
3813 (segment->p_flags & PF_W ? 'W' : ' '),
3814 (segment->p_flags & PF_X ? 'E' : ' '));
3815 print_vma (segment->p_align, HEX);
3816 }
252b5132
RH
3817 }
3818
3819 switch (segment->p_type)
3820 {
252b5132
RH
3821 case PT_DYNAMIC:
3822 if (dynamic_addr)
3823 error (_("more than one dynamic segment\n"));
3824
20737c13
AM
3825 /* By default, assume that the .dynamic section is the first
3826 section in the DYNAMIC segment. */
3827 dynamic_addr = segment->p_offset;
3828 dynamic_size = segment->p_filesz;
3829
b2d38a17
NC
3830 /* Try to locate the .dynamic section. If there is
3831 a section header table, we can easily locate it. */
3832 if (section_headers != NULL)
3833 {
2cf0635d 3834 Elf_Internal_Shdr * sec;
b2d38a17 3835
89fac5e3
RS
3836 sec = find_section (".dynamic");
3837 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3838 {
28f997cf
TG
3839 /* A corresponding .dynamic section is expected, but on
3840 IA-64/OpenVMS it is OK for it to be missing. */
3841 if (!is_ia64_vms ())
3842 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3843 break;
3844 }
3845
42bb2e33 3846 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3847 {
3848 dynamic_size = 0;
3849 break;
3850 }
42bb2e33 3851
b2d38a17
NC
3852 dynamic_addr = sec->sh_offset;
3853 dynamic_size = sec->sh_size;
3854
3855 if (dynamic_addr < segment->p_offset
3856 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3857 warn (_("the .dynamic section is not contained"
3858 " within the dynamic segment\n"));
b2d38a17 3859 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3860 warn (_("the .dynamic section is not the first section"
3861 " in the dynamic segment.\n"));
b2d38a17 3862 }
252b5132
RH
3863 break;
3864
3865 case PT_INTERP:
fb52b2f4
NC
3866 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3867 SEEK_SET))
252b5132
RH
3868 error (_("Unable to find program interpreter name\n"));
3869 else
3870 {
f8eae8b2
L
3871 char fmt [32];
3872 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3873
3874 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3875 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3876
252b5132 3877 program_interpreter[0] = 0;
7bd7b3ef
AM
3878 if (fscanf (file, fmt, program_interpreter) <= 0)
3879 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3880
3881 if (do_segments)
3882 printf (_("\n [Requesting program interpreter: %s]"),
3883 program_interpreter);
3884 }
3885 break;
3886 }
3887
3888 if (do_segments)
3889 putc ('\n', stdout);
3890 }
3891
c256ffe7 3892 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3893 {
3894 printf (_("\n Section to Segment mapping:\n"));
3895 printf (_(" Segment Sections...\n"));
3896
252b5132
RH
3897 for (i = 0; i < elf_header.e_phnum; i++)
3898 {
9ad5cbcf 3899 unsigned int j;
2cf0635d 3900 Elf_Internal_Shdr * section;
252b5132
RH
3901
3902 segment = program_headers + i;
b391a3e3 3903 section = section_headers + 1;
252b5132
RH
3904
3905 printf (" %2.2d ", i);
3906
b34976b6 3907 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3908 {
f4638467
AM
3909 if (!ELF_TBSS_SPECIAL (section, segment)
3910 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
3911 printf ("%s ", SECTION_NAME (section));
3912 }
3913
3914 putc ('\n',stdout);
3915 }
3916 }
3917
252b5132
RH
3918 return 1;
3919}
3920
3921
d93f0186
NC
3922/* Find the file offset corresponding to VMA by using the program headers. */
3923
3924static long
2cf0635d 3925offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 3926{
2cf0635d 3927 Elf_Internal_Phdr * seg;
d93f0186
NC
3928
3929 if (! get_program_headers (file))
3930 {
3931 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3932 return (long) vma;
3933 }
3934
3935 for (seg = program_headers;
3936 seg < program_headers + elf_header.e_phnum;
3937 ++seg)
3938 {
3939 if (seg->p_type != PT_LOAD)
3940 continue;
3941
3942 if (vma >= (seg->p_vaddr & -seg->p_align)
3943 && vma + size <= seg->p_vaddr + seg->p_filesz)
3944 return vma - seg->p_vaddr + seg->p_offset;
3945 }
3946
3947 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 3948 (unsigned long) vma);
d93f0186
NC
3949 return (long) vma;
3950}
3951
3952
252b5132 3953static int
2cf0635d 3954get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 3955{
2cf0635d
NC
3956 Elf32_External_Shdr * shdrs;
3957 Elf_Internal_Shdr * internal;
b34976b6 3958 unsigned int i;
252b5132 3959
3f5e193b
NC
3960 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3961 elf_header.e_shentsize, num,
3962 _("section headers"));
a6e9f9df
AM
3963 if (!shdrs)
3964 return 0;
252b5132 3965
3f5e193b
NC
3966 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3967 sizeof (Elf_Internal_Shdr));
252b5132
RH
3968
3969 if (section_headers == NULL)
3970 {
3971 error (_("Out of memory\n"));
3972 return 0;
3973 }
3974
3975 for (i = 0, internal = section_headers;
560f3c1c 3976 i < num;
b34976b6 3977 i++, internal++)
252b5132
RH
3978 {
3979 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3980 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3981 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3982 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3983 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3984 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3985 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3986 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3987 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3988 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3989 }
3990
3991 free (shdrs);
3992
3993 return 1;
3994}
3995
9ea033b2 3996static int
2cf0635d 3997get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 3998{
2cf0635d
NC
3999 Elf64_External_Shdr * shdrs;
4000 Elf_Internal_Shdr * internal;
b34976b6 4001 unsigned int i;
9ea033b2 4002
3f5e193b
NC
4003 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4004 elf_header.e_shentsize, num,
4005 _("section headers"));
a6e9f9df
AM
4006 if (!shdrs)
4007 return 0;
9ea033b2 4008
3f5e193b
NC
4009 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4010 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4011
4012 if (section_headers == NULL)
4013 {
4014 error (_("Out of memory\n"));
4015 return 0;
4016 }
4017
4018 for (i = 0, internal = section_headers;
560f3c1c 4019 i < num;
b34976b6 4020 i++, internal++)
9ea033b2
NC
4021 {
4022 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4023 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4024 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4025 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4026 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4027 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4028 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4029 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4030 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4031 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4032 }
4033
4034 free (shdrs);
4035
4036 return 1;
4037}
4038
252b5132 4039static Elf_Internal_Sym *
2cf0635d 4040get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
252b5132 4041{
9ad5cbcf 4042 unsigned long number;
dd24e3da 4043 Elf32_External_Sym * esyms = NULL;
2cf0635d 4044 Elf_External_Sym_Shndx * shndx;
dd24e3da 4045 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4046 Elf_Internal_Sym * psym;
b34976b6 4047 unsigned int j;
252b5132 4048
dd24e3da
NC
4049 /* Run some sanity checks first. */
4050 if (section->sh_entsize == 0)
4051 {
4052 error (_("sh_entsize is zero\n"));
4053 return NULL;
4054 }
4055
4056 number = section->sh_size / section->sh_entsize;
4057
4058 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4059 {
4060 error (_("Invalid sh_entsize\n"));
4061 return NULL;
4062 }
4063
3f5e193b
NC
4064 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4065 section->sh_size, _("symbols"));
dd24e3da 4066 if (esyms == NULL)
a6e9f9df 4067 return NULL;
252b5132 4068
9ad5cbcf
AM
4069 shndx = NULL;
4070 if (symtab_shndx_hdr != NULL
4071 && (symtab_shndx_hdr->sh_link
4fbb74a6 4072 == (unsigned long) (section - section_headers)))
9ad5cbcf 4073 {
3f5e193b
NC
4074 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4075 symtab_shndx_hdr->sh_offset,
4076 1, symtab_shndx_hdr->sh_size,
4077 _("symtab shndx"));
dd24e3da
NC
4078 if (shndx == NULL)
4079 goto exit_point;
9ad5cbcf
AM
4080 }
4081
3f5e193b 4082 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4083
4084 if (isyms == NULL)
4085 {
4086 error (_("Out of memory\n"));
dd24e3da 4087 goto exit_point;
252b5132
RH
4088 }
4089
dd24e3da 4090 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4091 {
4092 psym->st_name = BYTE_GET (esyms[j].st_name);
4093 psym->st_value = BYTE_GET (esyms[j].st_value);
4094 psym->st_size = BYTE_GET (esyms[j].st_size);
4095 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4096 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4097 psym->st_shndx
4098 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4099 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4100 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4101 psym->st_info = BYTE_GET (esyms[j].st_info);
4102 psym->st_other = BYTE_GET (esyms[j].st_other);
4103 }
4104
dd24e3da 4105 exit_point:
9ad5cbcf
AM
4106 if (shndx)
4107 free (shndx);
dd24e3da
NC
4108 if (esyms)
4109 free (esyms);
252b5132
RH
4110
4111 return isyms;
4112}
4113
9ea033b2 4114static Elf_Internal_Sym *
2cf0635d 4115get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
9ea033b2 4116{
9ad5cbcf 4117 unsigned long number;
2cf0635d
NC
4118 Elf64_External_Sym * esyms;
4119 Elf_External_Sym_Shndx * shndx;
4120 Elf_Internal_Sym * isyms;
4121 Elf_Internal_Sym * psym;
b34976b6 4122 unsigned int j;
9ea033b2 4123
dd24e3da
NC
4124 /* Run some sanity checks first. */
4125 if (section->sh_entsize == 0)
4126 {
4127 error (_("sh_entsize is zero\n"));
4128 return NULL;
4129 }
4130
4131 number = section->sh_size / section->sh_entsize;
4132
4133 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4134 {
4135 error (_("Invalid sh_entsize\n"));
4136 return NULL;
4137 }
4138
3f5e193b
NC
4139 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4140 section->sh_size, _("symbols"));
a6e9f9df
AM
4141 if (!esyms)
4142 return NULL;
9ea033b2 4143
9ad5cbcf
AM
4144 shndx = NULL;
4145 if (symtab_shndx_hdr != NULL
4146 && (symtab_shndx_hdr->sh_link
4fbb74a6 4147 == (unsigned long) (section - section_headers)))
9ad5cbcf 4148 {
3f5e193b
NC
4149 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4150 symtab_shndx_hdr->sh_offset,
4151 1, symtab_shndx_hdr->sh_size,
4152 _("symtab shndx"));
9ad5cbcf
AM
4153 if (!shndx)
4154 {
4155 free (esyms);
4156 return NULL;
4157 }
4158 }
4159
3f5e193b 4160 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4161
4162 if (isyms == NULL)
4163 {
4164 error (_("Out of memory\n"));
9ad5cbcf
AM
4165 if (shndx)
4166 free (shndx);
9ea033b2 4167 free (esyms);
9ea033b2
NC
4168 return NULL;
4169 }
4170
4171 for (j = 0, psym = isyms;
4172 j < number;
b34976b6 4173 j++, psym++)
9ea033b2
NC
4174 {
4175 psym->st_name = BYTE_GET (esyms[j].st_name);
4176 psym->st_info = BYTE_GET (esyms[j].st_info);
4177 psym->st_other = BYTE_GET (esyms[j].st_other);
4178 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4179 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4180 psym->st_shndx
4181 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4182 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4183 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
66543521
AM
4184 psym->st_value = BYTE_GET (esyms[j].st_value);
4185 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4186 }
4187
9ad5cbcf
AM
4188 if (shndx)
4189 free (shndx);
9ea033b2
NC
4190 free (esyms);
4191
4192 return isyms;
4193}
4194
d1133906 4195static const char *
d3ba0551 4196get_elf_section_flags (bfd_vma sh_flags)
d1133906 4197{
5477e8a0 4198 static char buff[1024];
2cf0635d 4199 char * p = buff;
8d5ff12c 4200 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4201 int sindex;
4202 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4203 bfd_vma os_flags = 0;
4204 bfd_vma proc_flags = 0;
4205 bfd_vma unknown_flags = 0;
148b93f2 4206 static const struct
5477e8a0 4207 {
2cf0635d 4208 const char * str;
5477e8a0
L
4209 int len;
4210 }
4211 flags [] =
4212 {
cfcac11d
NC
4213 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4214 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4215 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4216 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4217 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4218 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4219 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4220 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4221 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4222 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4223 /* IA-64 specific. */
4224 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4225 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4226 /* IA-64 OpenVMS specific. */
4227 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4228 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4229 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4230 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4231 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4232 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4233 /* Generic. */
cfcac11d 4234 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4235 /* SPARC specific. */
cfcac11d 4236 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4237 };
4238
4239 if (do_section_details)
4240 {
8d5ff12c
L
4241 sprintf (buff, "[%*.*lx]: ",
4242 field_size, field_size, (unsigned long) sh_flags);
4243 p += field_size + 4;
5477e8a0 4244 }
76da6bbe 4245
d1133906
NC
4246 while (sh_flags)
4247 {
4248 bfd_vma flag;
4249
4250 flag = sh_flags & - sh_flags;
4251 sh_flags &= ~ flag;
76da6bbe 4252
5477e8a0 4253 if (do_section_details)
d1133906 4254 {
5477e8a0
L
4255 switch (flag)
4256 {
91d6fa6a
NC
4257 case SHF_WRITE: sindex = 0; break;
4258 case SHF_ALLOC: sindex = 1; break;
4259 case SHF_EXECINSTR: sindex = 2; break;
4260 case SHF_MERGE: sindex = 3; break;
4261 case SHF_STRINGS: sindex = 4; break;
4262 case SHF_INFO_LINK: sindex = 5; break;
4263 case SHF_LINK_ORDER: sindex = 6; break;
4264 case SHF_OS_NONCONFORMING: sindex = 7; break;
4265 case SHF_GROUP: sindex = 8; break;
4266 case SHF_TLS: sindex = 9; break;
18ae9cc1 4267 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4268
5477e8a0 4269 default:
91d6fa6a 4270 sindex = -1;
cfcac11d 4271 switch (elf_header.e_machine)
148b93f2 4272 {
cfcac11d 4273 case EM_IA_64:
148b93f2 4274 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4275 sindex = 10;
148b93f2 4276 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4277 sindex = 11;
148b93f2
NC
4278#ifdef BFD64
4279 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4280 switch (flag)
4281 {
91d6fa6a
NC
4282 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4283 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4284 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4285 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4286 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4287 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4288 default: break;
4289 }
4290#endif
cfcac11d
NC
4291 break;
4292
caa83f8b
NC
4293 case EM_386:
4294 case EM_486:
4295 case EM_X86_64:
7f502d6c 4296 case EM_L1OM:
cfcac11d
NC
4297 case EM_OLD_SPARCV9:
4298 case EM_SPARC32PLUS:
4299 case EM_SPARCV9:
4300 case EM_SPARC:
18ae9cc1 4301 if (flag == SHF_ORDERED)
91d6fa6a 4302 sindex = 19;
cfcac11d
NC
4303 break;
4304 default:
4305 break;
148b93f2 4306 }
5477e8a0
L
4307 }
4308
91d6fa6a 4309 if (sindex != -1)
5477e8a0 4310 {
8d5ff12c
L
4311 if (p != buff + field_size + 4)
4312 {
4313 if (size < (10 + 2))
4314 abort ();
4315 size -= 2;
4316 *p++ = ',';
4317 *p++ = ' ';
4318 }
4319
91d6fa6a
NC
4320 size -= flags [sindex].len;
4321 p = stpcpy (p, flags [sindex].str);
5477e8a0 4322 }
3b22753a 4323 else if (flag & SHF_MASKOS)
8d5ff12c 4324 os_flags |= flag;
d1133906 4325 else if (flag & SHF_MASKPROC)
8d5ff12c 4326 proc_flags |= flag;
d1133906 4327 else
8d5ff12c 4328 unknown_flags |= flag;
5477e8a0
L
4329 }
4330 else
4331 {
4332 switch (flag)
4333 {
4334 case SHF_WRITE: *p = 'W'; break;
4335 case SHF_ALLOC: *p = 'A'; break;
4336 case SHF_EXECINSTR: *p = 'X'; break;
4337 case SHF_MERGE: *p = 'M'; break;
4338 case SHF_STRINGS: *p = 'S'; break;
4339 case SHF_INFO_LINK: *p = 'I'; break;
4340 case SHF_LINK_ORDER: *p = 'L'; break;
4341 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4342 case SHF_GROUP: *p = 'G'; break;
4343 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4344 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4345
4346 default:
8a9036a4
L
4347 if ((elf_header.e_machine == EM_X86_64
4348 || elf_header.e_machine == EM_L1OM)
5477e8a0
L
4349 && flag == SHF_X86_64_LARGE)
4350 *p = 'l';
4351 else if (flag & SHF_MASKOS)
4352 {
4353 *p = 'o';
4354 sh_flags &= ~ SHF_MASKOS;
4355 }
4356 else if (flag & SHF_MASKPROC)
4357 {
4358 *p = 'p';
4359 sh_flags &= ~ SHF_MASKPROC;
4360 }
4361 else
4362 *p = 'x';
4363 break;
4364 }
4365 p++;
d1133906
NC
4366 }
4367 }
76da6bbe 4368
8d5ff12c
L
4369 if (do_section_details)
4370 {
4371 if (os_flags)
4372 {
4373 size -= 5 + field_size;
4374 if (p != buff + field_size + 4)
4375 {
4376 if (size < (2 + 1))
4377 abort ();
4378 size -= 2;
4379 *p++ = ',';
4380 *p++ = ' ';
4381 }
4382 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4383 (unsigned long) os_flags);
4384 p += 5 + field_size;
4385 }
4386 if (proc_flags)
4387 {
4388 size -= 7 + field_size;
4389 if (p != buff + field_size + 4)
4390 {
4391 if (size < (2 + 1))
4392 abort ();
4393 size -= 2;
4394 *p++ = ',';
4395 *p++ = ' ';
4396 }
4397 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4398 (unsigned long) proc_flags);
4399 p += 7 + field_size;
4400 }
4401 if (unknown_flags)
4402 {
4403 size -= 10 + field_size;
4404 if (p != buff + field_size + 4)
4405 {
4406 if (size < (2 + 1))
4407 abort ();
4408 size -= 2;
4409 *p++ = ',';
4410 *p++ = ' ';
4411 }
2b692964 4412 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4413 (unsigned long) unknown_flags);
4414 p += 10 + field_size;
4415 }
4416 }
4417
e9e44622 4418 *p = '\0';
d1133906
NC
4419 return buff;
4420}
4421
252b5132 4422static int
2cf0635d 4423process_section_headers (FILE * file)
252b5132 4424{
2cf0635d 4425 Elf_Internal_Shdr * section;
b34976b6 4426 unsigned int i;
252b5132
RH
4427
4428 section_headers = NULL;
4429
4430 if (elf_header.e_shnum == 0)
4431 {
82f2dbf7
NC
4432 /* PR binutils/12467. */
4433 if (elf_header.e_shoff != 0)
4434 warn (_("possibly corrupt ELF file header - it has a non-zero"
4435 " section header offset, but no section headers\n"));
4436 else if (do_sections)
252b5132
RH
4437 printf (_("\nThere are no sections in this file.\n"));
4438
4439 return 1;
4440 }
4441
4442 if (do_sections && !do_header)
9ea033b2 4443 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4444 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4445
9ea033b2
NC
4446 if (is_32bit_elf)
4447 {
560f3c1c 4448 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4449 return 0;
4450 }
560f3c1c 4451 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4452 return 0;
4453
4454 /* Read in the string table, so that we have names to display. */
0b49d371 4455 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4456 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4457 {
4fbb74a6 4458 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4459
c256ffe7
JJ
4460 if (section->sh_size != 0)
4461 {
3f5e193b
NC
4462 string_table = (char *) get_data (NULL, file, section->sh_offset,
4463 1, section->sh_size,
4464 _("string table"));
0de14b54 4465
c256ffe7
JJ
4466 string_table_length = string_table != NULL ? section->sh_size : 0;
4467 }
252b5132
RH
4468 }
4469
4470 /* Scan the sections for the dynamic symbol table
e3c8793a 4471 and dynamic string table and debug sections. */
252b5132
RH
4472 dynamic_symbols = NULL;
4473 dynamic_strings = NULL;
4474 dynamic_syminfo = NULL;
f1ef08cb 4475 symtab_shndx_hdr = NULL;
103f02d3 4476
89fac5e3
RS
4477 eh_addr_size = is_32bit_elf ? 4 : 8;
4478 switch (elf_header.e_machine)
4479 {
4480 case EM_MIPS:
4481 case EM_MIPS_RS3_LE:
4482 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4483 FDE addresses. However, the ABI also has a semi-official ILP32
4484 variant for which the normal FDE address size rules apply.
4485
4486 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4487 section, where XX is the size of longs in bits. Unfortunately,
4488 earlier compilers provided no way of distinguishing ILP32 objects
4489 from LP64 objects, so if there's any doubt, we should assume that
4490 the official LP64 form is being used. */
4491 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4492 && find_section (".gcc_compiled_long32") == NULL)
4493 eh_addr_size = 8;
4494 break;
0f56a26a
DD
4495
4496 case EM_H8_300:
4497 case EM_H8_300H:
4498 switch (elf_header.e_flags & EF_H8_MACH)
4499 {
4500 case E_H8_MACH_H8300:
4501 case E_H8_MACH_H8300HN:
4502 case E_H8_MACH_H8300SN:
4503 case E_H8_MACH_H8300SXN:
4504 eh_addr_size = 2;
4505 break;
4506 case E_H8_MACH_H8300H:
4507 case E_H8_MACH_H8300S:
4508 case E_H8_MACH_H8300SX:
4509 eh_addr_size = 4;
4510 break;
4511 }
f4236fe4
DD
4512 break;
4513
ff7eeb89 4514 case EM_M32C_OLD:
f4236fe4
DD
4515 case EM_M32C:
4516 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4517 {
4518 case EF_M32C_CPU_M16C:
4519 eh_addr_size = 2;
4520 break;
4521 }
4522 break;
89fac5e3
RS
4523 }
4524
08d8fa11
JJ
4525#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4526 do \
4527 { \
4528 size_t expected_entsize \
4529 = is_32bit_elf ? size32 : size64; \
4530 if (section->sh_entsize != expected_entsize) \
4531 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4532 i, (unsigned long int) section->sh_entsize, \
4533 (unsigned long int) expected_entsize); \
4534 section->sh_entsize = expected_entsize; \
4535 } \
4536 while (0)
4537#define CHECK_ENTSIZE(section, i, type) \
4538 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4539 sizeof (Elf64_External_##type))
4540
252b5132
RH
4541 for (i = 0, section = section_headers;
4542 i < elf_header.e_shnum;
b34976b6 4543 i++, section++)
252b5132 4544 {
2cf0635d 4545 char * name = SECTION_NAME (section);
252b5132
RH
4546
4547 if (section->sh_type == SHT_DYNSYM)
4548 {
4549 if (dynamic_symbols != NULL)
4550 {
4551 error (_("File contains multiple dynamic symbol tables\n"));
4552 continue;
4553 }
4554
08d8fa11 4555 CHECK_ENTSIZE (section, i, Sym);
19936277 4556 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4557 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4558 }
4559 else if (section->sh_type == SHT_STRTAB
18bd398b 4560 && streq (name, ".dynstr"))
252b5132
RH
4561 {
4562 if (dynamic_strings != NULL)
4563 {
4564 error (_("File contains multiple dynamic string tables\n"));
4565 continue;
4566 }
4567
3f5e193b
NC
4568 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4569 1, section->sh_size,
4570 _("dynamic strings"));
59245841 4571 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4572 }
9ad5cbcf
AM
4573 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4574 {
4575 if (symtab_shndx_hdr != NULL)
4576 {
4577 error (_("File contains multiple symtab shndx tables\n"));
4578 continue;
4579 }
4580 symtab_shndx_hdr = section;
4581 }
08d8fa11
JJ
4582 else if (section->sh_type == SHT_SYMTAB)
4583 CHECK_ENTSIZE (section, i, Sym);
4584 else if (section->sh_type == SHT_GROUP)
4585 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4586 else if (section->sh_type == SHT_REL)
4587 CHECK_ENTSIZE (section, i, Rel);
4588 else if (section->sh_type == SHT_RELA)
4589 CHECK_ENTSIZE (section, i, Rela);
252b5132 4590 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4591 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4592 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4593 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4594 && (const_strneq (name, ".debug_")
4595 || const_strneq (name, ".zdebug_")))
252b5132 4596 {
1b315056
CS
4597 if (name[1] == 'z')
4598 name += sizeof (".zdebug_") - 1;
4599 else
4600 name += sizeof (".debug_") - 1;
252b5132
RH
4601
4602 if (do_debugging
18bd398b 4603 || (do_debug_info && streq (name, "info"))
2b6f5997 4604 || (do_debug_info && streq (name, "types"))
18bd398b 4605 || (do_debug_abbrevs && streq (name, "abbrev"))
4cb93e3b 4606 || (do_debug_lines && streq (name, "line"))
18bd398b 4607 || (do_debug_pubnames && streq (name, "pubnames"))
f9f0e732 4608 || (do_debug_pubtypes && streq (name, "pubtypes"))
18bd398b
NC
4609 || (do_debug_aranges && streq (name, "aranges"))
4610 || (do_debug_ranges && streq (name, "ranges"))
4611 || (do_debug_frames && streq (name, "frame"))
4612 || (do_debug_macinfo && streq (name, "macinfo"))
4613 || (do_debug_str && streq (name, "str"))
4614 || (do_debug_loc && streq (name, "loc"))
252b5132 4615 )
09c11c86 4616 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4617 }
a262ae96 4618 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4619 else if ((do_debugging || do_debug_info)
0112cd26 4620 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4621 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4622 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4623 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4624 else if (do_gdb_index && streq (name, ".gdb_index"))
4625 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4626 /* Trace sections for Itanium VMS. */
4627 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4628 || do_trace_aranges)
4629 && const_strneq (name, ".trace_"))
4630 {
4631 name += sizeof (".trace_") - 1;
4632
4633 if (do_debugging
4634 || (do_trace_info && streq (name, "info"))
4635 || (do_trace_abbrevs && streq (name, "abbrev"))
4636 || (do_trace_aranges && streq (name, "aranges"))
4637 )
4638 request_dump_bynumber (i, DEBUG_DUMP);
4639 }
4640
252b5132
RH
4641 }
4642
4643 if (! do_sections)
4644 return 1;
4645
3a1a2036
NC
4646 if (elf_header.e_shnum > 1)
4647 printf (_("\nSection Headers:\n"));
4648 else
4649 printf (_("\nSection Header:\n"));
76da6bbe 4650
f7a99963 4651 if (is_32bit_elf)
595cf52e 4652 {
5477e8a0 4653 if (do_section_details)
595cf52e
L
4654 {
4655 printf (_(" [Nr] Name\n"));
5477e8a0 4656 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4657 }
4658 else
4659 printf
4660 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4661 }
d974e256 4662 else if (do_wide)
595cf52e 4663 {
5477e8a0 4664 if (do_section_details)
595cf52e
L
4665 {
4666 printf (_(" [Nr] Name\n"));
5477e8a0 4667 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4668 }
4669 else
4670 printf
4671 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4672 }
f7a99963
NC
4673 else
4674 {
5477e8a0 4675 if (do_section_details)
595cf52e
L
4676 {
4677 printf (_(" [Nr] Name\n"));
5477e8a0
L
4678 printf (_(" Type Address Offset Link\n"));
4679 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4680 }
4681 else
4682 {
4683 printf (_(" [Nr] Name Type Address Offset\n"));
4684 printf (_(" Size EntSize Flags Link Info Align\n"));
4685 }
f7a99963 4686 }
252b5132 4687
5477e8a0
L
4688 if (do_section_details)
4689 printf (_(" Flags\n"));
4690
252b5132
RH
4691 for (i = 0, section = section_headers;
4692 i < elf_header.e_shnum;
b34976b6 4693 i++, section++)
252b5132 4694 {
5477e8a0 4695 if (do_section_details)
595cf52e
L
4696 {
4697 printf (" [%2u] %s\n",
4fbb74a6 4698 i,
595cf52e
L
4699 SECTION_NAME (section));
4700 if (is_32bit_elf || do_wide)
4701 printf (" %-15.15s ",
4702 get_section_type_name (section->sh_type));
4703 }
4704 else
b9eb56c1
NC
4705 printf ((do_wide ? " [%2u] %-17s %-15s "
4706 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4707 i,
595cf52e
L
4708 SECTION_NAME (section),
4709 get_section_type_name (section->sh_type));
252b5132 4710
f7a99963
NC
4711 if (is_32bit_elf)
4712 {
cfcac11d
NC
4713 const char * link_too_big = NULL;
4714
f7a99963 4715 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4716
f7a99963
NC
4717 printf ( " %6.6lx %6.6lx %2.2lx",
4718 (unsigned long) section->sh_offset,
4719 (unsigned long) section->sh_size,
4720 (unsigned long) section->sh_entsize);
d1133906 4721
5477e8a0
L
4722 if (do_section_details)
4723 fputs (" ", stdout);
4724 else
4725 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4726
cfcac11d
NC
4727 if (section->sh_link >= elf_header.e_shnum)
4728 {
4729 link_too_big = "";
4730 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4731 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4732 switch (elf_header.e_machine)
4733 {
caa83f8b
NC
4734 case EM_386:
4735 case EM_486:
4736 case EM_X86_64:
7f502d6c 4737 case EM_L1OM:
cfcac11d
NC
4738 case EM_OLD_SPARCV9:
4739 case EM_SPARC32PLUS:
4740 case EM_SPARCV9:
4741 case EM_SPARC:
4742 if (section->sh_link == (SHN_BEFORE & 0xffff))
4743 link_too_big = "BEFORE";
4744 else if (section->sh_link == (SHN_AFTER & 0xffff))
4745 link_too_big = "AFTER";
4746 break;
4747 default:
4748 break;
4749 }
4750 }
4751
4752 if (do_section_details)
4753 {
4754 if (link_too_big != NULL && * link_too_big)
4755 printf ("<%s> ", link_too_big);
4756 else
4757 printf ("%2u ", section->sh_link);
4758 printf ("%3u %2lu\n", section->sh_info,
4759 (unsigned long) section->sh_addralign);
4760 }
4761 else
4762 printf ("%2u %3u %2lu\n",
4763 section->sh_link,
4764 section->sh_info,
4765 (unsigned long) section->sh_addralign);
4766
4767 if (link_too_big && ! * link_too_big)
4768 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4769 i, section->sh_link);
f7a99963 4770 }
d974e256
JJ
4771 else if (do_wide)
4772 {
4773 print_vma (section->sh_addr, LONG_HEX);
4774
4775 if ((long) section->sh_offset == section->sh_offset)
4776 printf (" %6.6lx", (unsigned long) section->sh_offset);
4777 else
4778 {
4779 putchar (' ');
4780 print_vma (section->sh_offset, LONG_HEX);
4781 }
4782
4783 if ((unsigned long) section->sh_size == section->sh_size)
4784 printf (" %6.6lx", (unsigned long) section->sh_size);
4785 else
4786 {
4787 putchar (' ');
4788 print_vma (section->sh_size, LONG_HEX);
4789 }
4790
4791 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4792 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4793 else
4794 {
4795 putchar (' ');
4796 print_vma (section->sh_entsize, LONG_HEX);
4797 }
4798
5477e8a0
L
4799 if (do_section_details)
4800 fputs (" ", stdout);
4801 else
4802 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4803
72de5009 4804 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4805
4806 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4807 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4808 else
4809 {
4810 print_vma (section->sh_addralign, DEC);
4811 putchar ('\n');
4812 }
4813 }
5477e8a0 4814 else if (do_section_details)
595cf52e 4815 {
5477e8a0 4816 printf (" %-15.15s ",
595cf52e 4817 get_section_type_name (section->sh_type));
595cf52e
L
4818 print_vma (section->sh_addr, LONG_HEX);
4819 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4820 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4821 else
4822 {
4823 printf (" ");
4824 print_vma (section->sh_offset, LONG_HEX);
4825 }
72de5009 4826 printf (" %u\n ", section->sh_link);
595cf52e 4827 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4828 putchar (' ');
595cf52e
L
4829 print_vma (section->sh_entsize, LONG_HEX);
4830
72de5009
AM
4831 printf (" %-16u %lu\n",
4832 section->sh_info,
595cf52e
L
4833 (unsigned long) section->sh_addralign);
4834 }
f7a99963
NC
4835 else
4836 {
4837 putchar (' ');
4838 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4839 if ((long) section->sh_offset == section->sh_offset)
4840 printf (" %8.8lx", (unsigned long) section->sh_offset);
4841 else
4842 {
4843 printf (" ");
4844 print_vma (section->sh_offset, LONG_HEX);
4845 }
f7a99963
NC
4846 printf ("\n ");
4847 print_vma (section->sh_size, LONG_HEX);
4848 printf (" ");
4849 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4850
d1133906 4851 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4852
72de5009
AM
4853 printf (" %2u %3u %lu\n",
4854 section->sh_link,
4855 section->sh_info,
f7a99963
NC
4856 (unsigned long) section->sh_addralign);
4857 }
5477e8a0
L
4858
4859 if (do_section_details)
4860 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4861 }
4862
5477e8a0 4863 if (!do_section_details)
3dbcc61d
NC
4864 {
4865 if (elf_header.e_machine == EM_X86_64
4866 || elf_header.e_machine == EM_L1OM)
4867 printf (_("Key to Flags:\n\
4868 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
4869 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
4870 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
4871 else
4872 printf (_("Key to Flags:\n\
e3c8793a 4873 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 4874 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 4875 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 4876 }
d1133906 4877
252b5132
RH
4878 return 1;
4879}
4880
f5842774
L
4881static const char *
4882get_group_flags (unsigned int flags)
4883{
4884 static char buff[32];
4885 switch (flags)
4886 {
220453ec
AM
4887 case 0:
4888 return "";
4889
f5842774 4890 case GRP_COMDAT:
220453ec 4891 return "COMDAT ";
f5842774
L
4892
4893 default:
220453ec 4894 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
4895 break;
4896 }
4897 return buff;
4898}
4899
4900static int
2cf0635d 4901process_section_groups (FILE * file)
f5842774 4902{
2cf0635d 4903 Elf_Internal_Shdr * section;
f5842774 4904 unsigned int i;
2cf0635d
NC
4905 struct group * group;
4906 Elf_Internal_Shdr * symtab_sec;
4907 Elf_Internal_Shdr * strtab_sec;
4908 Elf_Internal_Sym * symtab;
4909 char * strtab;
c256ffe7 4910 size_t strtab_size;
d1f5c6e3
L
4911
4912 /* Don't process section groups unless needed. */
4913 if (!do_unwind && !do_section_groups)
4914 return 1;
f5842774
L
4915
4916 if (elf_header.e_shnum == 0)
4917 {
4918 if (do_section_groups)
82f2dbf7 4919 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
4920
4921 return 1;
4922 }
4923
4924 if (section_headers == NULL)
4925 {
4926 error (_("Section headers are not available!\n"));
4927 abort ();
4928 }
4929
3f5e193b
NC
4930 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
4931 sizeof (struct group *));
e4b17d5c
L
4932
4933 if (section_headers_groups == NULL)
4934 {
4935 error (_("Out of memory\n"));
4936 return 0;
4937 }
4938
f5842774 4939 /* Scan the sections for the group section. */
d1f5c6e3 4940 group_count = 0;
f5842774
L
4941 for (i = 0, section = section_headers;
4942 i < elf_header.e_shnum;
4943 i++, section++)
e4b17d5c
L
4944 if (section->sh_type == SHT_GROUP)
4945 group_count++;
4946
d1f5c6e3
L
4947 if (group_count == 0)
4948 {
4949 if (do_section_groups)
4950 printf (_("\nThere are no section groups in this file.\n"));
4951
4952 return 1;
4953 }
4954
3f5e193b 4955 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
4956
4957 if (section_groups == NULL)
4958 {
4959 error (_("Out of memory\n"));
4960 return 0;
4961 }
4962
d1f5c6e3
L
4963 symtab_sec = NULL;
4964 strtab_sec = NULL;
4965 symtab = NULL;
4966 strtab = NULL;
c256ffe7 4967 strtab_size = 0;
e4b17d5c
L
4968 for (i = 0, section = section_headers, group = section_groups;
4969 i < elf_header.e_shnum;
4970 i++, section++)
f5842774
L
4971 {
4972 if (section->sh_type == SHT_GROUP)
4973 {
2cf0635d
NC
4974 char * name = SECTION_NAME (section);
4975 char * group_name;
4976 unsigned char * start;
4977 unsigned char * indices;
f5842774 4978 unsigned int entry, j, size;
2cf0635d
NC
4979 Elf_Internal_Shdr * sec;
4980 Elf_Internal_Sym * sym;
f5842774
L
4981
4982 /* Get the symbol table. */
4fbb74a6
AM
4983 if (section->sh_link >= elf_header.e_shnum
4984 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 4985 != SHT_SYMTAB))
f5842774
L
4986 {
4987 error (_("Bad sh_link in group section `%s'\n"), name);
4988 continue;
4989 }
d1f5c6e3
L
4990
4991 if (symtab_sec != sec)
4992 {
4993 symtab_sec = sec;
4994 if (symtab)
4995 free (symtab);
4996 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4997 }
f5842774 4998
dd24e3da
NC
4999 if (symtab == NULL)
5000 {
5001 error (_("Corrupt header in group section `%s'\n"), name);
5002 continue;
5003 }
5004
f5842774
L
5005 sym = symtab + section->sh_info;
5006
5007 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5008 {
4fbb74a6
AM
5009 if (sym->st_shndx == 0
5010 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5011 {
5012 error (_("Bad sh_info in group section `%s'\n"), name);
5013 continue;
5014 }
ba2685cc 5015
4fbb74a6 5016 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5017 strtab_sec = NULL;
5018 if (strtab)
5019 free (strtab);
f5842774 5020 strtab = NULL;
c256ffe7 5021 strtab_size = 0;
f5842774
L
5022 }
5023 else
5024 {
5025 /* Get the string table. */
4fbb74a6 5026 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5027 {
5028 strtab_sec = NULL;
5029 if (strtab)
5030 free (strtab);
5031 strtab = NULL;
5032 strtab_size = 0;
5033 }
5034 else if (strtab_sec
4fbb74a6 5035 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5036 {
5037 strtab_sec = sec;
5038 if (strtab)
5039 free (strtab);
3f5e193b
NC
5040 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5041 1, strtab_sec->sh_size,
5042 _("string table"));
c256ffe7 5043 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5044 }
c256ffe7 5045 group_name = sym->st_name < strtab_size
2b692964 5046 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5047 }
5048
3f5e193b
NC
5049 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5050 1, section->sh_size,
5051 _("section data"));
59245841
NC
5052 if (start == NULL)
5053 continue;
f5842774
L
5054
5055 indices = start;
5056 size = (section->sh_size / section->sh_entsize) - 1;
5057 entry = byte_get (indices, 4);
5058 indices += 4;
e4b17d5c
L
5059
5060 if (do_section_groups)
5061 {
2b692964 5062 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5063 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5064
e4b17d5c
L
5065 printf (_(" [Index] Name\n"));
5066 }
5067
5068 group->group_index = i;
5069
f5842774
L
5070 for (j = 0; j < size; j++)
5071 {
2cf0635d 5072 struct group_list * g;
e4b17d5c 5073
f5842774
L
5074 entry = byte_get (indices, 4);
5075 indices += 4;
5076
4fbb74a6 5077 if (entry >= elf_header.e_shnum)
391cb864
L
5078 {
5079 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5080 entry, i, elf_header.e_shnum - 1);
5081 continue;
5082 }
391cb864 5083
4fbb74a6 5084 if (section_headers_groups [entry] != NULL)
e4b17d5c 5085 {
d1f5c6e3
L
5086 if (entry)
5087 {
391cb864
L
5088 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5089 entry, i,
4fbb74a6 5090 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5091 continue;
5092 }
5093 else
5094 {
5095 /* Intel C/C++ compiler may put section 0 in a
5096 section group. We just warn it the first time
5097 and ignore it afterwards. */
5098 static int warned = 0;
5099 if (!warned)
5100 {
5101 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5102 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5103 warned++;
5104 }
5105 }
e4b17d5c
L
5106 }
5107
4fbb74a6 5108 section_headers_groups [entry] = group;
e4b17d5c
L
5109
5110 if (do_section_groups)
5111 {
4fbb74a6 5112 sec = section_headers + entry;
c256ffe7 5113 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5114 }
5115
3f5e193b 5116 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5117 g->section_index = entry;
5118 g->next = group->root;
5119 group->root = g;
f5842774
L
5120 }
5121
f5842774
L
5122 if (start)
5123 free (start);
e4b17d5c
L
5124
5125 group++;
f5842774
L
5126 }
5127 }
5128
d1f5c6e3
L
5129 if (symtab)
5130 free (symtab);
5131 if (strtab)
5132 free (strtab);
f5842774
L
5133 return 1;
5134}
5135
28f997cf
TG
5136/* Data used to display dynamic fixups. */
5137
5138struct ia64_vms_dynfixup
5139{
5140 bfd_vma needed_ident; /* Library ident number. */
5141 bfd_vma needed; /* Index in the dstrtab of the library name. */
5142 bfd_vma fixup_needed; /* Index of the library. */
5143 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5144 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5145};
5146
5147/* Data used to display dynamic relocations. */
5148
5149struct ia64_vms_dynimgrela
5150{
5151 bfd_vma img_rela_cnt; /* Number of relocations. */
5152 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5153};
5154
5155/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5156 library). */
5157
5158static void
5159dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5160 const char *strtab, unsigned int strtab_sz)
5161{
5162 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5163 long i;
5164 const char *lib_name;
5165
5166 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5167 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5168 _("dynamic section image fixups"));
5169 if (!imfs)
5170 return;
5171
5172 if (fixup->needed < strtab_sz)
5173 lib_name = strtab + fixup->needed;
5174 else
5175 {
5176 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5177 (unsigned long) fixup->needed);
28f997cf
TG
5178 lib_name = "???";
5179 }
5180 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5181 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5182 printf
5183 (_("Seg Offset Type SymVec DataType\n"));
5184
5185 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5186 {
5187 unsigned int type;
5188 const char *rtype;
5189
5190 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5191 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5192 type = BYTE_GET (imfs [i].type);
5193 rtype = elf_ia64_reloc_type (type);
5194 if (rtype == NULL)
5195 printf (" 0x%08x ", type);
5196 else
5197 printf (" %-32s ", rtype);
5198 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5199 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5200 }
5201
5202 free (imfs);
5203}
5204
5205/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5206
5207static void
5208dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5209{
5210 Elf64_External_VMS_IMAGE_RELA *imrs;
5211 long i;
5212
5213 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5214 1, imgrela->img_rela_cnt * sizeof (*imrs),
5215 _("dynamic section image relas"));
5216 if (!imrs)
5217 return;
5218
5219 printf (_("\nImage relocs\n"));
5220 printf
5221 (_("Seg Offset Type Addend Seg Sym Off\n"));
5222
5223 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5224 {
5225 unsigned int type;
5226 const char *rtype;
5227
5228 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5229 printf ("%08" BFD_VMA_FMT "x ",
5230 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5231 type = BYTE_GET (imrs [i].type);
5232 rtype = elf_ia64_reloc_type (type);
5233 if (rtype == NULL)
5234 printf ("0x%08x ", type);
5235 else
5236 printf ("%-31s ", rtype);
5237 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5238 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5239 printf ("%08" BFD_VMA_FMT "x\n",
5240 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5241 }
5242
5243 free (imrs);
5244}
5245
5246/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5247
5248static int
5249process_ia64_vms_dynamic_relocs (FILE *file)
5250{
5251 struct ia64_vms_dynfixup fixup;
5252 struct ia64_vms_dynimgrela imgrela;
5253 Elf_Internal_Dyn *entry;
5254 int res = 0;
5255 bfd_vma strtab_off = 0;
5256 bfd_vma strtab_sz = 0;
5257 char *strtab = NULL;
5258
5259 memset (&fixup, 0, sizeof (fixup));
5260 memset (&imgrela, 0, sizeof (imgrela));
5261
5262 /* Note: the order of the entries is specified by the OpenVMS specs. */
5263 for (entry = dynamic_section;
5264 entry < dynamic_section + dynamic_nent;
5265 entry++)
5266 {
5267 switch (entry->d_tag)
5268 {
5269 case DT_IA_64_VMS_STRTAB_OFFSET:
5270 strtab_off = entry->d_un.d_val;
5271 break;
5272 case DT_STRSZ:
5273 strtab_sz = entry->d_un.d_val;
5274 if (strtab == NULL)
5275 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5276 1, strtab_sz, _("dynamic string section"));
5277 break;
5278
5279 case DT_IA_64_VMS_NEEDED_IDENT:
5280 fixup.needed_ident = entry->d_un.d_val;
5281 break;
5282 case DT_NEEDED:
5283 fixup.needed = entry->d_un.d_val;
5284 break;
5285 case DT_IA_64_VMS_FIXUP_NEEDED:
5286 fixup.fixup_needed = entry->d_un.d_val;
5287 break;
5288 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5289 fixup.fixup_rela_cnt = entry->d_un.d_val;
5290 break;
5291 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5292 fixup.fixup_rela_off = entry->d_un.d_val;
5293 res++;
5294 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5295 break;
5296
5297 case DT_IA_64_VMS_IMG_RELA_CNT:
5298 imgrela.img_rela_cnt = entry->d_un.d_val;
5299 break;
5300 case DT_IA_64_VMS_IMG_RELA_OFF:
5301 imgrela.img_rela_off = entry->d_un.d_val;
5302 res++;
5303 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5304 break;
5305
5306 default:
5307 break;
5308 }
5309 }
5310
5311 if (strtab != NULL)
5312 free (strtab);
5313
5314 return res;
5315}
5316
85b1c36d 5317static struct
566b0d53 5318{
2cf0635d 5319 const char * name;
566b0d53
L
5320 int reloc;
5321 int size;
5322 int rela;
5323} dynamic_relocations [] =
5324{
5325 { "REL", DT_REL, DT_RELSZ, FALSE },
5326 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5327 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5328};
5329
252b5132 5330/* Process the reloc section. */
18bd398b 5331
252b5132 5332static int
2cf0635d 5333process_relocs (FILE * file)
252b5132 5334{
b34976b6
AM
5335 unsigned long rel_size;
5336 unsigned long rel_offset;
252b5132
RH
5337
5338
5339 if (!do_reloc)
5340 return 1;
5341
5342 if (do_using_dynamic)
5343 {
566b0d53 5344 int is_rela;
2cf0635d 5345 const char * name;
566b0d53
L
5346 int has_dynamic_reloc;
5347 unsigned int i;
0de14b54 5348
566b0d53 5349 has_dynamic_reloc = 0;
252b5132 5350
566b0d53 5351 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5352 {
566b0d53
L
5353 is_rela = dynamic_relocations [i].rela;
5354 name = dynamic_relocations [i].name;
5355 rel_size = dynamic_info [dynamic_relocations [i].size];
5356 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5357
566b0d53
L
5358 has_dynamic_reloc |= rel_size;
5359
5360 if (is_rela == UNKNOWN)
aa903cfb 5361 {
566b0d53
L
5362 if (dynamic_relocations [i].reloc == DT_JMPREL)
5363 switch (dynamic_info[DT_PLTREL])
5364 {
5365 case DT_REL:
5366 is_rela = FALSE;
5367 break;
5368 case DT_RELA:
5369 is_rela = TRUE;
5370 break;
5371 }
aa903cfb 5372 }
252b5132 5373
566b0d53
L
5374 if (rel_size)
5375 {
5376 printf
5377 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5378 name, rel_offset, rel_size);
252b5132 5379
d93f0186
NC
5380 dump_relocations (file,
5381 offset_from_vma (file, rel_offset, rel_size),
5382 rel_size,
566b0d53 5383 dynamic_symbols, num_dynamic_syms,
d79b3d50 5384 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5385 }
252b5132 5386 }
566b0d53 5387
28f997cf
TG
5388 if (is_ia64_vms ())
5389 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5390
566b0d53 5391 if (! has_dynamic_reloc)
252b5132
RH
5392 printf (_("\nThere are no dynamic relocations in this file.\n"));
5393 }
5394 else
5395 {
2cf0635d 5396 Elf_Internal_Shdr * section;
b34976b6
AM
5397 unsigned long i;
5398 int found = 0;
252b5132
RH
5399
5400 for (i = 0, section = section_headers;
5401 i < elf_header.e_shnum;
b34976b6 5402 i++, section++)
252b5132
RH
5403 {
5404 if ( section->sh_type != SHT_RELA
5405 && section->sh_type != SHT_REL)
5406 continue;
5407
5408 rel_offset = section->sh_offset;
5409 rel_size = section->sh_size;
5410
5411 if (rel_size)
5412 {
2cf0635d 5413 Elf_Internal_Shdr * strsec;
b34976b6 5414 int is_rela;
103f02d3 5415
252b5132
RH
5416 printf (_("\nRelocation section "));
5417
5418 if (string_table == NULL)
19936277 5419 printf ("%d", section->sh_name);
252b5132 5420 else
3a1a2036 5421 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
5422
5423 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5424 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5425
d79b3d50
NC
5426 is_rela = section->sh_type == SHT_RELA;
5427
4fbb74a6
AM
5428 if (section->sh_link != 0
5429 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5430 {
2cf0635d
NC
5431 Elf_Internal_Shdr * symsec;
5432 Elf_Internal_Sym * symtab;
d79b3d50 5433 unsigned long nsyms;
c256ffe7 5434 unsigned long strtablen = 0;
2cf0635d 5435 char * strtab = NULL;
57346661 5436
4fbb74a6 5437 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5438 if (symsec->sh_type != SHT_SYMTAB
5439 && symsec->sh_type != SHT_DYNSYM)
5440 continue;
5441
af3fc3bc 5442 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 5443 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 5444
af3fc3bc
AM
5445 if (symtab == NULL)
5446 continue;
252b5132 5447
4fbb74a6
AM
5448 if (symsec->sh_link != 0
5449 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5450 {
4fbb74a6 5451 strsec = section_headers + symsec->sh_link;
103f02d3 5452
3f5e193b
NC
5453 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5454 1, strsec->sh_size,
5455 _("string table"));
c256ffe7
JJ
5456 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5457 }
252b5132 5458
d79b3d50
NC
5459 dump_relocations (file, rel_offset, rel_size,
5460 symtab, nsyms, strtab, strtablen, is_rela);
5461 if (strtab)
5462 free (strtab);
5463 free (symtab);
5464 }
5465 else
5466 dump_relocations (file, rel_offset, rel_size,
5467 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5468
5469 found = 1;
5470 }
5471 }
5472
5473 if (! found)
5474 printf (_("\nThere are no relocations in this file.\n"));
5475 }
5476
5477 return 1;
5478}
5479
57346661
AM
5480/* Process the unwind section. */
5481
4d6ed7c8
NC
5482#include "unwind-ia64.h"
5483
5484/* An absolute address consists of a section and an offset. If the
5485 section is NULL, the offset itself is the address, otherwise, the
5486 address equals to LOAD_ADDRESS(section) + offset. */
5487
5488struct absaddr
5489 {
5490 unsigned short section;
5491 bfd_vma offset;
5492 };
5493
1949de15
L
5494#define ABSADDR(a) \
5495 ((a).section \
5496 ? section_headers [(a).section].sh_addr + (a).offset \
5497 : (a).offset)
5498
3f5e193b
NC
5499struct ia64_unw_table_entry
5500 {
5501 struct absaddr start;
5502 struct absaddr end;
5503 struct absaddr info;
5504 };
5505
57346661 5506struct ia64_unw_aux_info
4d6ed7c8 5507 {
3f5e193b
NC
5508
5509 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5510 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5511 unsigned char * info; /* Unwind info. */
b34976b6
AM
5512 unsigned long info_size; /* Size of unwind info. */
5513 bfd_vma info_addr; /* starting address of unwind info. */
5514 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5515 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5516 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5517 char * strtab; /* The string table. */
b34976b6 5518 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5519 };
5520
4d6ed7c8 5521static void
2cf0635d 5522find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5523 unsigned long nsyms,
2cf0635d 5524 const char * strtab,
57346661 5525 unsigned long strtab_size,
d3ba0551 5526 struct absaddr addr,
2cf0635d
NC
5527 const char ** symname,
5528 bfd_vma * offset)
4d6ed7c8 5529{
d3ba0551 5530 bfd_vma dist = 0x100000;
2cf0635d
NC
5531 Elf_Internal_Sym * sym;
5532 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5533 unsigned long i;
5534
0b6ae522
DJ
5535 REMOVE_ARCH_BITS (addr.offset);
5536
57346661 5537 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5538 {
0b6ae522
DJ
5539 bfd_vma value = sym->st_value;
5540
5541 REMOVE_ARCH_BITS (value);
5542
4d6ed7c8
NC
5543 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5544 && sym->st_name != 0
5545 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5546 && addr.offset >= value
5547 && addr.offset - value < dist)
4d6ed7c8
NC
5548 {
5549 best = sym;
0b6ae522 5550 dist = addr.offset - value;
4d6ed7c8
NC
5551 if (!dist)
5552 break;
5553 }
5554 }
5555 if (best)
5556 {
57346661 5557 *symname = (best->st_name >= strtab_size
2b692964 5558 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5559 *offset = dist;
5560 return;
5561 }
5562 *symname = NULL;
5563 *offset = addr.offset;
5564}
5565
5566static void
2cf0635d 5567dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5568{
2cf0635d 5569 struct ia64_unw_table_entry * tp;
4d6ed7c8 5570 int in_body;
7036c0e1 5571
4d6ed7c8
NC
5572 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5573 {
5574 bfd_vma stamp;
5575 bfd_vma offset;
2cf0635d
NC
5576 const unsigned char * dp;
5577 const unsigned char * head;
5578 const char * procname;
4d6ed7c8 5579
57346661
AM
5580 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5581 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5582
5583 fputs ("\n<", stdout);
5584
5585 if (procname)
5586 {
5587 fputs (procname, stdout);
5588
5589 if (offset)
5590 printf ("+%lx", (unsigned long) offset);
5591 }
5592
5593 fputs (">: [", stdout);
5594 print_vma (tp->start.offset, PREFIX_HEX);
5595 fputc ('-', stdout);
5596 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5597 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5598 (unsigned long) (tp->info.offset - aux->seg_base));
5599
1949de15 5600 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5601 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5602
86f55779 5603 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5604 (unsigned) UNW_VER (stamp),
5605 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5606 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5607 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5608 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5609
5610 if (UNW_VER (stamp) != 1)
5611 {
2b692964 5612 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5613 continue;
5614 }
5615
5616 in_body = 0;
89fac5e3 5617 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5618 dp = unw_decode (dp, in_body, & in_body);
5619 }
5620}
5621
5622static int
2cf0635d
NC
5623slurp_ia64_unwind_table (FILE * file,
5624 struct ia64_unw_aux_info * aux,
5625 Elf_Internal_Shdr * sec)
4d6ed7c8 5626{
89fac5e3 5627 unsigned long size, nrelas, i;
2cf0635d
NC
5628 Elf_Internal_Phdr * seg;
5629 struct ia64_unw_table_entry * tep;
5630 Elf_Internal_Shdr * relsec;
5631 Elf_Internal_Rela * rela;
5632 Elf_Internal_Rela * rp;
5633 unsigned char * table;
5634 unsigned char * tp;
5635 Elf_Internal_Sym * sym;
5636 const char * relname;
4d6ed7c8 5637
4d6ed7c8
NC
5638 /* First, find the starting address of the segment that includes
5639 this section: */
5640
5641 if (elf_header.e_phnum)
5642 {
d93f0186 5643 if (! get_program_headers (file))
4d6ed7c8 5644 return 0;
4d6ed7c8 5645
d93f0186
NC
5646 for (seg = program_headers;
5647 seg < program_headers + elf_header.e_phnum;
5648 ++seg)
4d6ed7c8
NC
5649 {
5650 if (seg->p_type != PT_LOAD)
5651 continue;
5652
5653 if (sec->sh_addr >= seg->p_vaddr
5654 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5655 {
5656 aux->seg_base = seg->p_vaddr;
5657 break;
5658 }
5659 }
4d6ed7c8
NC
5660 }
5661
5662 /* Second, build the unwind table from the contents of the unwind section: */
5663 size = sec->sh_size;
3f5e193b
NC
5664 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5665 _("unwind table"));
a6e9f9df
AM
5666 if (!table)
5667 return 0;
4d6ed7c8 5668
3f5e193b
NC
5669 aux->table = (struct ia64_unw_table_entry *)
5670 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5671 tep = aux->table;
c6a0c689 5672 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5673 {
5674 tep->start.section = SHN_UNDEF;
5675 tep->end.section = SHN_UNDEF;
5676 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5677 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5678 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5679 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5680 tep->start.offset += aux->seg_base;
5681 tep->end.offset += aux->seg_base;
5682 tep->info.offset += aux->seg_base;
5683 }
5684 free (table);
5685
41e92641 5686 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5687 for (relsec = section_headers;
5688 relsec < section_headers + elf_header.e_shnum;
5689 ++relsec)
5690 {
5691 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5692 || relsec->sh_info >= elf_header.e_shnum
5693 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5694 continue;
5695
5696 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5697 & rela, & nrelas))
5698 return 0;
5699
5700 for (rp = rela; rp < rela + nrelas; ++rp)
5701 {
aca88567
NC
5702 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5703 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5704
0112cd26 5705 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5706 {
e5fb9629 5707 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5708 continue;
5709 }
5710
89fac5e3 5711 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5712
89fac5e3 5713 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5714 {
5715 case 0:
5716 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5717 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5718 break;
5719 case 1:
5720 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5721 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5722 break;
5723 case 2:
5724 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5725 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5726 break;
5727 default:
5728 break;
5729 }
5730 }
5731
5732 free (rela);
5733 }
5734
89fac5e3 5735 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5736 return 1;
5737}
5738
5739static int
2cf0635d 5740ia64_process_unwind (FILE * file)
4d6ed7c8 5741{
2cf0635d
NC
5742 Elf_Internal_Shdr * sec;
5743 Elf_Internal_Shdr * unwsec = NULL;
5744 Elf_Internal_Shdr * strsec;
89fac5e3 5745 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5746 struct ia64_unw_aux_info aux;
f1467e33 5747
4d6ed7c8
NC
5748 memset (& aux, 0, sizeof (aux));
5749
4d6ed7c8
NC
5750 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5751 {
c256ffe7 5752 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5753 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5754 {
5755 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5756 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5757
4fbb74a6 5758 strsec = section_headers + sec->sh_link;
59245841 5759 assert (aux.strtab == NULL);
3f5e193b
NC
5760 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5761 1, strsec->sh_size,
5762 _("string table"));
c256ffe7 5763 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5764 }
5765 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5766 unwcount++;
5767 }
5768
5769 if (!unwcount)
5770 printf (_("\nThere are no unwind sections in this file.\n"));
5771
5772 while (unwcount-- > 0)
5773 {
2cf0635d 5774 char * suffix;
579f31ac
JJ
5775 size_t len, len2;
5776
5777 for (i = unwstart, sec = section_headers + unwstart;
5778 i < elf_header.e_shnum; ++i, ++sec)
5779 if (sec->sh_type == SHT_IA_64_UNWIND)
5780 {
5781 unwsec = sec;
5782 break;
5783 }
5784
5785 unwstart = i + 1;
5786 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5787
e4b17d5c
L
5788 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5789 {
5790 /* We need to find which section group it is in. */
2cf0635d 5791 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5792
5793 for (; g != NULL; g = g->next)
5794 {
4fbb74a6 5795 sec = section_headers + g->section_index;
18bd398b
NC
5796
5797 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5798 break;
e4b17d5c
L
5799 }
5800
5801 if (g == NULL)
5802 i = elf_header.e_shnum;
5803 }
18bd398b 5804 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5805 {
18bd398b 5806 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5807 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5808 suffix = SECTION_NAME (unwsec) + len;
5809 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5810 ++i, ++sec)
18bd398b
NC
5811 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5812 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5813 break;
5814 }
5815 else
5816 {
5817 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5818 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5819 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5820 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5821 suffix = "";
18bd398b 5822 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5823 suffix = SECTION_NAME (unwsec) + len;
5824 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5825 ++i, ++sec)
18bd398b
NC
5826 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5827 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5828 break;
5829 }
5830
5831 if (i == elf_header.e_shnum)
5832 {
5833 printf (_("\nCould not find unwind info section for "));
5834
5835 if (string_table == NULL)
5836 printf ("%d", unwsec->sh_name);
5837 else
3a1a2036 5838 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5839 }
5840 else
4d6ed7c8 5841 {
4d6ed7c8 5842 aux.info_addr = sec->sh_addr;
3f5e193b 5843 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 5844 sec->sh_size,
3f5e193b 5845 _("unwind info"));
59245841 5846 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 5847
579f31ac 5848 printf (_("\nUnwind section "));
4d6ed7c8 5849
579f31ac
JJ
5850 if (string_table == NULL)
5851 printf ("%d", unwsec->sh_name);
5852 else
3a1a2036 5853 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5854
579f31ac 5855 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5856 (unsigned long) unwsec->sh_offset,
89fac5e3 5857 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5858
579f31ac 5859 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5860
579f31ac
JJ
5861 if (aux.table_len > 0)
5862 dump_ia64_unwind (& aux);
5863
5864 if (aux.table)
5865 free ((char *) aux.table);
5866 if (aux.info)
5867 free ((char *) aux.info);
5868 aux.table = NULL;
5869 aux.info = NULL;
5870 }
4d6ed7c8 5871 }
4d6ed7c8 5872
4d6ed7c8
NC
5873 if (aux.symtab)
5874 free (aux.symtab);
5875 if (aux.strtab)
5876 free ((char *) aux.strtab);
5877
5878 return 1;
5879}
5880
3f5e193b
NC
5881struct hppa_unw_table_entry
5882 {
5883 struct absaddr start;
5884 struct absaddr end;
5885 unsigned int Cannot_unwind:1; /* 0 */
5886 unsigned int Millicode:1; /* 1 */
5887 unsigned int Millicode_save_sr0:1; /* 2 */
5888 unsigned int Region_description:2; /* 3..4 */
5889 unsigned int reserved1:1; /* 5 */
5890 unsigned int Entry_SR:1; /* 6 */
5891 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5892 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5893 unsigned int Args_stored:1; /* 16 */
5894 unsigned int Variable_Frame:1; /* 17 */
5895 unsigned int Separate_Package_Body:1; /* 18 */
5896 unsigned int Frame_Extension_Millicode:1; /* 19 */
5897 unsigned int Stack_Overflow_Check:1; /* 20 */
5898 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5899 unsigned int Ada_Region:1; /* 22 */
5900 unsigned int cxx_info:1; /* 23 */
5901 unsigned int cxx_try_catch:1; /* 24 */
5902 unsigned int sched_entry_seq:1; /* 25 */
5903 unsigned int reserved2:1; /* 26 */
5904 unsigned int Save_SP:1; /* 27 */
5905 unsigned int Save_RP:1; /* 28 */
5906 unsigned int Save_MRP_in_frame:1; /* 29 */
5907 unsigned int extn_ptr_defined:1; /* 30 */
5908 unsigned int Cleanup_defined:1; /* 31 */
5909
5910 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5911 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5912 unsigned int Large_frame:1; /* 2 */
5913 unsigned int Pseudo_SP_Set:1; /* 3 */
5914 unsigned int reserved4:1; /* 4 */
5915 unsigned int Total_frame_size:27; /* 5..31 */
5916 };
5917
57346661
AM
5918struct hppa_unw_aux_info
5919 {
3f5e193b 5920 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
5921 unsigned long table_len; /* Length of unwind table. */
5922 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5923 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5924 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5925 char * strtab; /* The string table. */
57346661
AM
5926 unsigned long strtab_size; /* Size of string table. */
5927 };
5928
5929static void
2cf0635d 5930dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5931{
2cf0635d 5932 struct hppa_unw_table_entry * tp;
57346661 5933
57346661
AM
5934 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5935 {
5936 bfd_vma offset;
2cf0635d 5937 const char * procname;
57346661
AM
5938
5939 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5940 aux->strtab_size, tp->start, &procname,
5941 &offset);
5942
5943 fputs ("\n<", stdout);
5944
5945 if (procname)
5946 {
5947 fputs (procname, stdout);
5948
5949 if (offset)
5950 printf ("+%lx", (unsigned long) offset);
5951 }
5952
5953 fputs (">: [", stdout);
5954 print_vma (tp->start.offset, PREFIX_HEX);
5955 fputc ('-', stdout);
5956 print_vma (tp->end.offset, PREFIX_HEX);
5957 printf ("]\n\t");
5958
18bd398b
NC
5959#define PF(_m) if (tp->_m) printf (#_m " ");
5960#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5961 PF(Cannot_unwind);
5962 PF(Millicode);
5963 PF(Millicode_save_sr0);
18bd398b 5964 /* PV(Region_description); */
57346661
AM
5965 PF(Entry_SR);
5966 PV(Entry_FR);
5967 PV(Entry_GR);
5968 PF(Args_stored);
5969 PF(Variable_Frame);
5970 PF(Separate_Package_Body);
5971 PF(Frame_Extension_Millicode);
5972 PF(Stack_Overflow_Check);
5973 PF(Two_Instruction_SP_Increment);
5974 PF(Ada_Region);
5975 PF(cxx_info);
5976 PF(cxx_try_catch);
5977 PF(sched_entry_seq);
5978 PF(Save_SP);
5979 PF(Save_RP);
5980 PF(Save_MRP_in_frame);
5981 PF(extn_ptr_defined);
5982 PF(Cleanup_defined);
5983 PF(MPE_XL_interrupt_marker);
5984 PF(HP_UX_interrupt_marker);
5985 PF(Large_frame);
5986 PF(Pseudo_SP_Set);
5987 PV(Total_frame_size);
5988#undef PF
5989#undef PV
5990 }
5991
18bd398b 5992 printf ("\n");
57346661
AM
5993}
5994
5995static int
2cf0635d
NC
5996slurp_hppa_unwind_table (FILE * file,
5997 struct hppa_unw_aux_info * aux,
5998 Elf_Internal_Shdr * sec)
57346661 5999{
1c0751b2 6000 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6001 Elf_Internal_Phdr * seg;
6002 struct hppa_unw_table_entry * tep;
6003 Elf_Internal_Shdr * relsec;
6004 Elf_Internal_Rela * rela;
6005 Elf_Internal_Rela * rp;
6006 unsigned char * table;
6007 unsigned char * tp;
6008 Elf_Internal_Sym * sym;
6009 const char * relname;
57346661 6010
57346661
AM
6011 /* First, find the starting address of the segment that includes
6012 this section. */
6013
6014 if (elf_header.e_phnum)
6015 {
6016 if (! get_program_headers (file))
6017 return 0;
6018
6019 for (seg = program_headers;
6020 seg < program_headers + elf_header.e_phnum;
6021 ++seg)
6022 {
6023 if (seg->p_type != PT_LOAD)
6024 continue;
6025
6026 if (sec->sh_addr >= seg->p_vaddr
6027 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6028 {
6029 aux->seg_base = seg->p_vaddr;
6030 break;
6031 }
6032 }
6033 }
6034
6035 /* Second, build the unwind table from the contents of the unwind
6036 section. */
6037 size = sec->sh_size;
3f5e193b
NC
6038 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6039 _("unwind table"));
57346661
AM
6040 if (!table)
6041 return 0;
6042
1c0751b2
DA
6043 unw_ent_size = 16;
6044 nentries = size / unw_ent_size;
6045 size = unw_ent_size * nentries;
57346661 6046
3f5e193b
NC
6047 tep = aux->table = (struct hppa_unw_table_entry *)
6048 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6049
1c0751b2 6050 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6051 {
6052 unsigned int tmp1, tmp2;
6053
6054 tep->start.section = SHN_UNDEF;
6055 tep->end.section = SHN_UNDEF;
6056
1c0751b2
DA
6057 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6058 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6059 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6060 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6061
6062 tep->start.offset += aux->seg_base;
6063 tep->end.offset += aux->seg_base;
57346661
AM
6064
6065 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6066 tep->Millicode = (tmp1 >> 30) & 0x1;
6067 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6068 tep->Region_description = (tmp1 >> 27) & 0x3;
6069 tep->reserved1 = (tmp1 >> 26) & 0x1;
6070 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6071 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6072 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6073 tep->Args_stored = (tmp1 >> 15) & 0x1;
6074 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6075 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6076 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6077 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6078 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6079 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6080 tep->cxx_info = (tmp1 >> 8) & 0x1;
6081 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6082 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6083 tep->reserved2 = (tmp1 >> 5) & 0x1;
6084 tep->Save_SP = (tmp1 >> 4) & 0x1;
6085 tep->Save_RP = (tmp1 >> 3) & 0x1;
6086 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6087 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6088 tep->Cleanup_defined = tmp1 & 0x1;
6089
6090 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6091 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6092 tep->Large_frame = (tmp2 >> 29) & 0x1;
6093 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6094 tep->reserved4 = (tmp2 >> 27) & 0x1;
6095 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6096 }
6097 free (table);
6098
6099 /* Third, apply any relocations to the unwind table. */
57346661
AM
6100 for (relsec = section_headers;
6101 relsec < section_headers + elf_header.e_shnum;
6102 ++relsec)
6103 {
6104 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6105 || relsec->sh_info >= elf_header.e_shnum
6106 || section_headers + relsec->sh_info != sec)
57346661
AM
6107 continue;
6108
6109 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6110 & rela, & nrelas))
6111 return 0;
6112
6113 for (rp = rela; rp < rela + nrelas; ++rp)
6114 {
aca88567
NC
6115 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6116 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6117
6118 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6119 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6120 {
6121 warn (_("Skipping unexpected relocation type %s\n"), relname);
6122 continue;
6123 }
6124
6125 i = rp->r_offset / unw_ent_size;
6126
89fac5e3 6127 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6128 {
6129 case 0:
6130 aux->table[i].start.section = sym->st_shndx;
1e456d54 6131 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6132 break;
6133 case 1:
6134 aux->table[i].end.section = sym->st_shndx;
1e456d54 6135 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6136 break;
6137 default:
6138 break;
6139 }
6140 }
6141
6142 free (rela);
6143 }
6144
1c0751b2 6145 aux->table_len = nentries;
57346661
AM
6146
6147 return 1;
6148}
6149
6150static int
2cf0635d 6151hppa_process_unwind (FILE * file)
57346661 6152{
57346661 6153 struct hppa_unw_aux_info aux;
2cf0635d
NC
6154 Elf_Internal_Shdr * unwsec = NULL;
6155 Elf_Internal_Shdr * strsec;
6156 Elf_Internal_Shdr * sec;
18bd398b 6157 unsigned long i;
57346661
AM
6158
6159 memset (& aux, 0, sizeof (aux));
6160
c256ffe7
JJ
6161 if (string_table == NULL)
6162 return 1;
57346661
AM
6163
6164 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6165 {
c256ffe7 6166 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6167 && sec->sh_link < elf_header.e_shnum)
57346661
AM
6168 {
6169 aux.nsyms = sec->sh_size / sec->sh_entsize;
6170 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6171
4fbb74a6 6172 strsec = section_headers + sec->sh_link;
59245841 6173 assert (aux.strtab == NULL);
3f5e193b
NC
6174 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6175 1, strsec->sh_size,
6176 _("string table"));
c256ffe7 6177 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6178 }
18bd398b 6179 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6180 unwsec = sec;
6181 }
6182
6183 if (!unwsec)
6184 printf (_("\nThere are no unwind sections in this file.\n"));
6185
6186 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6187 {
18bd398b 6188 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6189 {
57346661
AM
6190 printf (_("\nUnwind section "));
6191 printf (_("'%s'"), SECTION_NAME (sec));
6192
6193 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6194 (unsigned long) sec->sh_offset,
89fac5e3 6195 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6196
6197 slurp_hppa_unwind_table (file, &aux, sec);
6198 if (aux.table_len > 0)
6199 dump_hppa_unwind (&aux);
6200
6201 if (aux.table)
6202 free ((char *) aux.table);
6203 aux.table = NULL;
6204 }
6205 }
6206
6207 if (aux.symtab)
6208 free (aux.symtab);
6209 if (aux.strtab)
6210 free ((char *) aux.strtab);
6211
6212 return 1;
6213}
6214
0b6ae522
DJ
6215struct arm_section
6216{
6217 unsigned char *data;
6218
6219 Elf_Internal_Shdr *sec;
6220 Elf_Internal_Rela *rela;
6221 unsigned long nrelas;
6222 unsigned int rel_type;
6223
6224 Elf_Internal_Rela *next_rela;
6225};
6226
6227struct arm_unw_aux_info
6228{
6229 FILE *file;
6230
6231 Elf_Internal_Sym *symtab; /* The symbol table. */
6232 unsigned long nsyms; /* Number of symbols. */
6233 char *strtab; /* The string table. */
6234 unsigned long strtab_size; /* Size of string table. */
6235};
6236
6237static const char *
6238arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6239 bfd_vma fn, struct absaddr addr)
6240{
6241 const char *procname;
6242 bfd_vma sym_offset;
6243
6244 if (addr.section == SHN_UNDEF)
6245 addr.offset = fn;
6246
6247 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6248 aux->strtab_size, addr, &procname,
6249 &sym_offset);
6250
6251 print_vma (fn, PREFIX_HEX);
6252
6253 if (procname)
6254 {
6255 fputs (" <", stdout);
6256 fputs (procname, stdout);
6257
6258 if (sym_offset)
6259 printf ("+0x%lx", (unsigned long) sym_offset);
6260 fputc ('>', stdout);
6261 }
6262
6263 return procname;
6264}
6265
6266static void
6267arm_free_section (struct arm_section *arm_sec)
6268{
6269 if (arm_sec->data != NULL)
6270 free (arm_sec->data);
6271
6272 if (arm_sec->rela != NULL)
6273 free (arm_sec->rela);
6274}
6275
6276static int
6277arm_section_get_word (struct arm_unw_aux_info *aux,
6278 struct arm_section *arm_sec,
6279 Elf_Internal_Shdr *sec, bfd_vma word_offset,
6280 unsigned int *wordp, struct absaddr *addr)
6281{
6282 Elf_Internal_Rela *rp;
6283 Elf_Internal_Sym *sym;
6284 const char * relname;
6285 unsigned int word;
6286 bfd_boolean wrapped;
6287
6288 addr->section = SHN_UNDEF;
6289 addr->offset = 0;
6290
6291 if (sec != arm_sec->sec)
6292 {
6293 Elf_Internal_Shdr *relsec;
6294
6295 arm_free_section (arm_sec);
6296
6297 arm_sec->sec = sec;
6298 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6299 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6300 arm_sec->rela = NULL;
6301 arm_sec->nrelas = 0;
6302
6303 for (relsec = section_headers;
6304 relsec < section_headers + elf_header.e_shnum;
6305 ++relsec)
6306 {
6307 if (relsec->sh_info >= elf_header.e_shnum
6308 || section_headers + relsec->sh_info != sec)
6309 continue;
6310
6311 if (relsec->sh_type == SHT_REL)
6312 {
6313 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6314 relsec->sh_size,
6315 & arm_sec->rela, & arm_sec->nrelas))
6316 return 0;
6317 break;
6318 }
6319 else if (relsec->sh_type == SHT_RELA)
6320 {
6321 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6322 relsec->sh_size,
6323 & arm_sec->rela, & arm_sec->nrelas))
6324 return 0;
6325 break;
6326 }
6327 }
6328
6329 arm_sec->next_rela = arm_sec->rela;
6330 }
6331
6332 if (arm_sec->data == NULL)
6333 return 0;
6334
6335 word = byte_get (arm_sec->data + word_offset, 4);
6336
6337 wrapped = FALSE;
6338 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6339 {
6340 bfd_vma prelval, offset;
6341
6342 if (rp->r_offset > word_offset && !wrapped)
6343 {
6344 rp = arm_sec->rela;
6345 wrapped = TRUE;
6346 }
6347 if (rp->r_offset > word_offset)
6348 break;
6349
6350 if (rp->r_offset & 3)
6351 {
6352 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6353 (unsigned long) rp->r_offset);
6354 continue;
6355 }
6356
6357 if (rp->r_offset < word_offset)
6358 continue;
6359
fa197c1c
PB
6360 switch (elf_header.e_machine)
6361 {
6362 case EM_ARM:
6363 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6364 break;
6365
6366 case EM_TI_C6000:
6367 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6368 break;
6369
6370 default:
6371 abort();
6372 }
0b6ae522 6373
fa197c1c
PB
6374 if (streq (relname, "R_ARM_NONE")
6375 || streq (relname, "R_C6000_NONE"))
0b6ae522
DJ
6376 continue;
6377
fa197c1c
PB
6378 if (!(streq (relname, "R_ARM_PREL31")
6379 || streq (relname, "R_C6000_PREL31")))
0b6ae522
DJ
6380 {
6381 warn (_("Skipping unexpected relocation type %s\n"), relname);
6382 continue;
6383 }
6384
6385 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6386
6387 if (arm_sec->rel_type == SHT_REL)
6388 {
6389 offset = word & 0x7fffffff;
6390 if (offset & 0x40000000)
6391 offset |= ~ (bfd_vma) 0x7fffffff;
6392 }
6393 else
6394 offset = rp->r_addend;
6395
6396 offset += sym->st_value;
6397 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6398
fa197c1c
PB
6399 if (streq (relname, "R_C6000_PREL31"))
6400 prelval >>= 1;
6401
0b6ae522
DJ
6402 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6403 addr->section = sym->st_shndx;
6404 addr->offset = offset;
6405 break;
6406 }
6407
6408 *wordp = word;
6409 arm_sec->next_rela = rp;
6410
6411 return 1;
6412}
6413
fa197c1c
PB
6414static const char *tic6x_unwind_regnames[16] = {
6415 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6416 "A14", "A13", "A12", "A11", "A10",
6417 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"};
6418
0b6ae522 6419static void
fa197c1c 6420decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6421{
fa197c1c
PB
6422 int i;
6423
6424 for (i = 12; mask; mask >>= 1, i--)
6425 {
6426 if (mask & 1)
6427 {
6428 fputs (tic6x_unwind_regnames[i], stdout);
6429 if (mask > 1)
6430 fputs (", ", stdout);
6431 }
6432 }
6433}
0b6ae522
DJ
6434
6435#define ADVANCE \
6436 if (remaining == 0 && more_words) \
6437 { \
6438 data_offset += 4; \
6439 if (!arm_section_get_word (aux, data_arm_sec, data_sec, \
6440 data_offset, &word, &addr)) \
6441 return; \
6442 remaining = 4; \
6443 more_words--; \
6444 } \
6445
6446#define GET_OP(OP) \
6447 ADVANCE; \
6448 if (remaining) \
6449 { \
6450 remaining--; \
6451 (OP) = word >> 24; \
6452 word <<= 8; \
6453 } \
6454 else \
6455 { \
2b692964 6456 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6457 return; \
6458 } \
cc5914eb 6459 printf ("0x%02x ", OP)
0b6ae522 6460
fa197c1c
PB
6461static void
6462decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6463 unsigned int word, unsigned int remaining,
6464 unsigned int more_words,
6465 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6466 struct arm_section *data_arm_sec)
6467{
6468 struct absaddr addr;
0b6ae522
DJ
6469
6470 /* Decode the unwinding instructions. */
6471 while (1)
6472 {
6473 unsigned int op, op2;
6474
6475 ADVANCE;
6476 if (remaining == 0)
6477 break;
6478 remaining--;
6479 op = word >> 24;
6480 word <<= 8;
6481
cc5914eb 6482 printf (" 0x%02x ", op);
0b6ae522
DJ
6483
6484 if ((op & 0xc0) == 0x00)
6485 {
6486 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6487
cc5914eb 6488 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6489 }
6490 else if ((op & 0xc0) == 0x40)
6491 {
6492 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6493
cc5914eb 6494 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6495 }
6496 else if ((op & 0xf0) == 0x80)
6497 {
6498 GET_OP (op2);
6499 if (op == 0x80 && op2 == 0)
6500 printf (_("Refuse to unwind"));
6501 else
6502 {
6503 unsigned int mask = ((op & 0x0f) << 8) | op2;
6504 int first = 1;
6505 int i;
2b692964 6506
0b6ae522
DJ
6507 printf ("pop {");
6508 for (i = 0; i < 12; i++)
6509 if (mask & (1 << i))
6510 {
6511 if (first)
6512 first = 0;
6513 else
6514 printf (", ");
6515 printf ("r%d", 4 + i);
6516 }
6517 printf ("}");
6518 }
6519 }
6520 else if ((op & 0xf0) == 0x90)
6521 {
6522 if (op == 0x9d || op == 0x9f)
6523 printf (_(" [Reserved]"));
6524 else
cc5914eb 6525 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6526 }
6527 else if ((op & 0xf0) == 0xa0)
6528 {
6529 int end = 4 + (op & 0x07);
6530 int first = 1;
6531 int i;
61865e30 6532
0b6ae522
DJ
6533 printf (" pop {");
6534 for (i = 4; i <= end; i++)
6535 {
6536 if (first)
6537 first = 0;
6538 else
6539 printf (", ");
6540 printf ("r%d", i);
6541 }
6542 if (op & 0x08)
6543 {
6544 if (first)
6545 printf (", ");
6546 printf ("r14");
6547 }
6548 printf ("}");
6549 }
6550 else if (op == 0xb0)
6551 printf (_(" finish"));
6552 else if (op == 0xb1)
6553 {
6554 GET_OP (op2);
6555 if (op2 == 0 || (op2 & 0xf0) != 0)
6556 printf (_("[Spare]"));
6557 else
6558 {
6559 unsigned int mask = op2 & 0x0f;
6560 int first = 1;
6561 int i;
61865e30 6562
0b6ae522
DJ
6563 printf ("pop {");
6564 for (i = 0; i < 12; i++)
6565 if (mask & (1 << i))
6566 {
6567 if (first)
6568 first = 0;
6569 else
6570 printf (", ");
6571 printf ("r%d", i);
6572 }
6573 printf ("}");
6574 }
6575 }
6576 else if (op == 0xb2)
6577 {
b115cf96 6578 unsigned char buf[9];
0b6ae522
DJ
6579 unsigned int i, len;
6580 unsigned long offset;
61865e30 6581
b115cf96 6582 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6583 {
6584 GET_OP (buf[i]);
6585 if ((buf[i] & 0x80) == 0)
6586 break;
6587 }
6588 assert (i < sizeof (buf));
6589 offset = read_uleb128 (buf, &len);
6590 assert (len == i + 1);
6591 offset = offset * 4 + 0x204;
cc5914eb 6592 printf ("vsp = vsp + %ld", offset);
0b6ae522 6593 }
61865e30 6594 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6595 {
61865e30
NC
6596 unsigned int first, last;
6597
6598 GET_OP (op2);
6599 first = op2 >> 4;
6600 last = op2 & 0x0f;
6601 if (op == 0xc8)
6602 first = first + 16;
6603 printf ("pop {D%d", first);
6604 if (last)
6605 printf ("-D%d", first + last);
6606 printf ("}");
6607 }
6608 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6609 {
6610 unsigned int count = op & 0x07;
6611
6612 printf ("pop {D8");
6613 if (count)
6614 printf ("-D%d", 8 + count);
6615 printf ("}");
6616 }
6617 else if (op >= 0xc0 && op <= 0xc5)
6618 {
6619 unsigned int count = op & 0x07;
6620
6621 printf (" pop {wR10");
6622 if (count)
6623 printf ("-wR%d", 10 + count);
6624 printf ("}");
6625 }
6626 else if (op == 0xc6)
6627 {
6628 unsigned int first, last;
6629
6630 GET_OP (op2);
6631 first = op2 >> 4;
6632 last = op2 & 0x0f;
6633 printf ("pop {wR%d", first);
6634 if (last)
6635 printf ("-wR%d", first + last);
6636 printf ("}");
6637 }
6638 else if (op == 0xc7)
6639 {
6640 GET_OP (op2);
6641 if (op2 == 0 || (op2 & 0xf0) != 0)
6642 printf (_("[Spare]"));
0b6ae522
DJ
6643 else
6644 {
61865e30
NC
6645 unsigned int mask = op2 & 0x0f;
6646 int first = 1;
6647 int i;
6648
6649 printf ("pop {");
6650 for (i = 0; i < 4; i++)
6651 if (mask & (1 << i))
6652 {
6653 if (first)
6654 first = 0;
6655 else
6656 printf (", ");
6657 printf ("wCGR%d", i);
6658 }
6659 printf ("}");
0b6ae522
DJ
6660 }
6661 }
61865e30
NC
6662 else
6663 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6664 printf ("\n");
6665 }
fa197c1c
PB
6666}
6667
6668static void
6669decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6670 unsigned int word, unsigned int remaining,
6671 unsigned int more_words,
6672 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6673 struct arm_section *data_arm_sec)
6674{
6675 struct absaddr addr;
6676
6677 /* Decode the unwinding instructions. */
6678 while (1)
6679 {
6680 unsigned int op, op2;
6681
6682 ADVANCE;
6683 if (remaining == 0)
6684 break;
6685 remaining--;
6686 op = word >> 24;
6687 word <<= 8;
6688
6689 printf (_(" 0x%02x "), op);
6690
6691 if ((op & 0xc0) == 0x00)
6692 {
6693 int offset = ((op & 0x3f) << 3) + 8;
6694 printf (_(" sp = sp + %d"), offset);
6695 }
6696 else if ((op & 0xc0) == 0x80)
6697 {
6698 GET_OP (op2);
6699 if (op == 0x80 && op2 == 0)
6700 printf (_("Refuse to unwind"));
6701 else
6702 {
6703 unsigned int mask = ((op & 0x1f) << 8) | op2;
6704 if (op & 0x20)
6705 printf ("pop compact {");
6706 else
6707 printf ("pop {");
6708
6709 decode_tic6x_unwind_regmask (mask);
6710 printf("}");
6711 }
6712 }
6713 else if ((op & 0xf0) == 0xc0)
6714 {
6715 unsigned int reg;
6716 unsigned int nregs;
6717 unsigned int i;
6718 const char *name;
6719 struct {
6720 unsigned int offset;
6721 unsigned int reg;
6722 } regpos[16];
6723
6724 /* Scan entire instruction first so that GET_OP output is not
6725 interleaved with disassembly. */
6726 nregs = 0;
6727 for (i = 0; nregs < (op & 0xf); i++)
6728 {
6729 GET_OP (op2);
6730 reg = op2 >> 4;
6731 if (reg != 0xf)
6732 {
6733 regpos[nregs].offset = i * 2;
6734 regpos[nregs].reg = reg;
6735 nregs++;
6736 }
6737
6738 reg = op2 & 0xf;
6739 if (reg != 0xf)
6740 {
6741 regpos[nregs].offset = i * 2 + 1;
6742 regpos[nregs].reg = reg;
6743 nregs++;
6744 }
6745 }
6746
6747 printf (_("pop frame {"));
6748 reg = nregs - 1;
6749 for (i = i * 2; i > 0; i--)
6750 {
6751 if (regpos[reg].offset == i - 1)
6752 {
6753 name = tic6x_unwind_regnames[regpos[reg].reg];
6754 if (reg > 0)
6755 reg--;
6756 }
6757 else
6758 name = _("[pad]");
6759
6760 fputs (name, stdout);
6761 if (i > 1)
6762 printf (", ");
6763 }
6764
6765 printf ("}");
6766 }
6767 else if (op == 0xd0)
6768 printf (" MOV FP, SP");
6769 else if (op == 0xd1)
6770 printf (" __c6xabi_pop_rts");
6771 else if (op == 0xd2)
6772 {
6773 unsigned char buf[9];
6774 unsigned int i, len;
6775 unsigned long offset;
6776 for (i = 0; i < sizeof (buf); i++)
6777 {
6778 GET_OP (buf[i]);
6779 if ((buf[i] & 0x80) == 0)
6780 break;
6781 }
6782 assert (i < sizeof (buf));
6783 offset = read_uleb128 (buf, &len);
6784 assert (len == i + 1);
6785 offset = offset * 8 + 0x408;
6786 printf (_("sp = sp + %ld"), offset);
6787 }
6788 else if ((op & 0xf0) == 0xe0)
6789 {
6790 if ((op & 0x0f) == 7)
6791 printf (" RETURN");
6792 else
6793 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
6794 }
6795 else
6796 {
6797 printf (_(" [unsupported opcode]"));
6798 }
6799 putchar ('\n');
6800 }
6801}
6802
6803static bfd_vma
6804expand_prel31 (bfd_vma word, bfd_vma where)
6805{
6806 bfd_vma offset;
6807
6808 offset = word & 0x7fffffff;
6809 if (offset & 0x40000000)
6810 offset |= ~ (bfd_vma) 0x7fffffff;
6811
6812 if (elf_header.e_machine == EM_TI_C6000)
6813 offset <<= 1;
6814
6815 return offset + where;
6816}
6817
6818static void
6819decode_arm_unwind (struct arm_unw_aux_info *aux,
6820 unsigned int word, unsigned int remaining,
6821 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6822 struct arm_section *data_arm_sec)
6823{
6824 int per_index;
6825 unsigned int more_words = 0;
6826 struct absaddr addr;
6827
6828 if (remaining == 0)
6829 {
6830 /* Fetch the first word. */
6831 if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
6832 &word, &addr))
6833 return;
6834 remaining = 4;
6835 }
6836
6837 if ((word & 0x80000000) == 0)
6838 {
6839 /* Expand prel31 for personality routine. */
6840 bfd_vma fn;
6841 const char *procname;
6842
6843 fn = expand_prel31 (word, data_sec->sh_addr + data_offset);
6844 printf (_(" Personality routine: "));
6845 procname = arm_print_vma_and_name (aux, fn, addr);
6846 fputc ('\n', stdout);
6847
6848 /* The GCC personality routines use the standard compact
6849 encoding, starting with one byte giving the number of
6850 words. */
6851 if (procname != NULL
6852 && (const_strneq (procname, "__gcc_personality_v0")
6853 || const_strneq (procname, "__gxx_personality_v0")
6854 || const_strneq (procname, "__gcj_personality_v0")
6855 || const_strneq (procname, "__gnu_objc_personality_v0")))
6856 {
6857 remaining = 0;
6858 more_words = 1;
6859 ADVANCE;
6860 if (!remaining)
6861 {
6862 printf (_(" [Truncated data]\n"));
6863 return;
6864 }
6865 more_words = word >> 24;
6866 word <<= 8;
6867 remaining--;
6868 per_index = -1;
6869 }
6870 else
6871 return;
6872 }
6873 else
6874 {
6875
6876 per_index = (word >> 24) & 0x7f;
6877 printf (_(" Compact model %d\n"), per_index);
6878 if (per_index == 0)
6879 {
6880 more_words = 0;
6881 word <<= 8;
6882 remaining--;
6883 }
6884 else if (per_index < 3)
6885 {
6886 more_words = (word >> 16) & 0xff;
6887 word <<= 16;
6888 remaining -= 2;
6889 }
6890 }
6891
6892 switch (elf_header.e_machine)
6893 {
6894 case EM_ARM:
6895 if (per_index < 3)
6896 {
6897 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
6898 data_offset, data_sec, data_arm_sec);
6899 }
6900 else
6901 printf (" [reserved]\n");
6902 break;
6903
6904 case EM_TI_C6000:
6905 if (per_index < 3)
6906 {
6907 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
6908 data_offset, data_sec, data_arm_sec);
6909 }
6910 else if (per_index < 5)
6911 {
6912 if (((word >> 17) & 0x7f) == 0x7f)
6913 printf (_(" Restore stack from frame pointer\n"));
6914 else
6915 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
6916 printf (_(" Registers restored: "));
6917 if (per_index == 4)
6918 printf (" (compact) ");
6919 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
6920 putchar ('\n');
6921 printf (_(" Return register: %s\n"),
6922 tic6x_unwind_regnames[word & 0xf]);
6923 }
6924 else
6925 printf (" [reserved]\n");
6926 break;
6927
6928 default:
6929 abort ();
6930 }
0b6ae522
DJ
6931
6932 /* Decode the descriptors. Not implemented. */
6933}
6934
6935static void
6936dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
6937{
6938 struct arm_section exidx_arm_sec, extab_arm_sec;
6939 unsigned int i, exidx_len;
6940
6941 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
6942 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
6943 exidx_len = exidx_sec->sh_size / 8;
6944
6945 for (i = 0; i < exidx_len; i++)
6946 {
6947 unsigned int exidx_fn, exidx_entry;
6948 struct absaddr fn_addr, entry_addr;
6949 bfd_vma fn;
6950
6951 fputc ('\n', stdout);
6952
6953 if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6954 8 * i, &exidx_fn, &fn_addr)
6955 || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6956 8 * i + 4, &exidx_entry, &entry_addr))
6957 {
6958 arm_free_section (&exidx_arm_sec);
6959 arm_free_section (&extab_arm_sec);
6960 return;
6961 }
6962
fa197c1c 6963 fn = expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522
DJ
6964
6965 arm_print_vma_and_name (aux, fn, entry_addr);
6966 fputs (": ", stdout);
6967
6968 if (exidx_entry == 1)
6969 {
6970 print_vma (exidx_entry, PREFIX_HEX);
6971 fputs (" [cantunwind]\n", stdout);
6972 }
6973 else if (exidx_entry & 0x80000000)
6974 {
6975 print_vma (exidx_entry, PREFIX_HEX);
6976 fputc ('\n', stdout);
6977 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
6978 }
6979 else
6980 {
8f73510c 6981 bfd_vma table, table_offset = 0;
0b6ae522
DJ
6982 Elf_Internal_Shdr *table_sec;
6983
6984 fputs ("@", stdout);
fa197c1c 6985 table = expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
6986 print_vma (table, PREFIX_HEX);
6987 printf ("\n");
6988
6989 /* Locate the matching .ARM.extab. */
6990 if (entry_addr.section != SHN_UNDEF
6991 && entry_addr.section < elf_header.e_shnum)
6992 {
6993 table_sec = section_headers + entry_addr.section;
6994 table_offset = entry_addr.offset;
6995 }
6996 else
6997 {
6998 table_sec = find_section_by_address (table);
6999 if (table_sec != NULL)
7000 table_offset = table - table_sec->sh_addr;
7001 }
7002 if (table_sec == NULL)
7003 {
7004 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7005 (unsigned long) table);
7006 continue;
7007 }
7008 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7009 &extab_arm_sec);
7010 }
7011 }
7012
7013 printf ("\n");
7014
7015 arm_free_section (&exidx_arm_sec);
7016 arm_free_section (&extab_arm_sec);
7017}
7018
fa197c1c 7019/* Used for both ARM and C6X unwinding tables. */
0b6ae522
DJ
7020static int
7021arm_process_unwind (FILE *file)
7022{
7023 struct arm_unw_aux_info aux;
7024 Elf_Internal_Shdr *unwsec = NULL;
7025 Elf_Internal_Shdr *strsec;
7026 Elf_Internal_Shdr *sec;
7027 unsigned long i;
fa197c1c 7028 unsigned int sec_type;
0b6ae522
DJ
7029
7030 memset (& aux, 0, sizeof (aux));
7031 aux.file = file;
7032
fa197c1c
PB
7033 switch (elf_header.e_machine)
7034 {
7035 case EM_ARM:
7036 sec_type = SHT_ARM_EXIDX;
7037 break;
7038
7039 case EM_TI_C6000:
7040 sec_type = SHT_C6000_UNWIND;
7041 break;
7042
7043 default:
7044 abort();
7045 }
7046
0b6ae522
DJ
7047 if (string_table == NULL)
7048 return 1;
7049
7050 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7051 {
7052 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7053 {
7054 aux.nsyms = sec->sh_size / sec->sh_entsize;
7055 aux.symtab = GET_ELF_SYMBOLS (file, sec);
7056
7057 strsec = section_headers + sec->sh_link;
59245841 7058 assert (aux.strtab == NULL);
0b6ae522
DJ
7059 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7060 1, strsec->sh_size, _("string table"));
7061 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7062 }
fa197c1c 7063 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7064 unwsec = sec;
7065 }
7066
7067 if (!unwsec)
7068 printf (_("\nThere are no unwind sections in this file.\n"));
7069
7070 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7071 {
fa197c1c 7072 if (sec->sh_type == sec_type)
0b6ae522
DJ
7073 {
7074 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7075 SECTION_NAME (sec),
7076 (unsigned long) sec->sh_offset,
7077 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
7078
7079 dump_arm_unwind (&aux, sec);
7080 }
7081 }
7082
7083 if (aux.symtab)
7084 free (aux.symtab);
7085 if (aux.strtab)
7086 free ((char *) aux.strtab);
7087
7088 return 1;
7089}
7090
57346661 7091static int
2cf0635d 7092process_unwind (FILE * file)
57346661 7093{
2cf0635d
NC
7094 struct unwind_handler
7095 {
57346661 7096 int machtype;
2cf0635d
NC
7097 int (* handler)(FILE *);
7098 } handlers[] =
7099 {
0b6ae522 7100 { EM_ARM, arm_process_unwind },
57346661
AM
7101 { EM_IA_64, ia64_process_unwind },
7102 { EM_PARISC, hppa_process_unwind },
fa197c1c 7103 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7104 { 0, 0 }
7105 };
7106 int i;
7107
7108 if (!do_unwind)
7109 return 1;
7110
7111 for (i = 0; handlers[i].handler != NULL; i++)
7112 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7113 return handlers[i].handler (file);
57346661
AM
7114
7115 printf (_("\nThere are no unwind sections in this file.\n"));
7116 return 1;
7117}
7118
252b5132 7119static void
2cf0635d 7120dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7121{
7122 switch (entry->d_tag)
7123 {
7124 case DT_MIPS_FLAGS:
7125 if (entry->d_un.d_val == 0)
2b692964 7126 printf (_("NONE\n"));
252b5132
RH
7127 else
7128 {
7129 static const char * opts[] =
7130 {
7131 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7132 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7133 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7134 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7135 "RLD_ORDER_SAFE"
7136 };
7137 unsigned int cnt;
7138 int first = 1;
2b692964 7139
60bca95a 7140 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7141 if (entry->d_un.d_val & (1 << cnt))
7142 {
7143 printf ("%s%s", first ? "" : " ", opts[cnt]);
7144 first = 0;
7145 }
7146 puts ("");
7147 }
7148 break;
103f02d3 7149
252b5132 7150 case DT_MIPS_IVERSION:
d79b3d50 7151 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
2b692964 7152 printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7153 else
2b692964 7154 printf (_("<corrupt: %ld>\n"), (long) entry->d_un.d_ptr);
252b5132 7155 break;
103f02d3 7156
252b5132
RH
7157 case DT_MIPS_TIME_STAMP:
7158 {
7159 char timebuf[20];
2cf0635d 7160 struct tm * tmp;
50da7a9c 7161
91d6fa6a
NC
7162 time_t atime = entry->d_un.d_val;
7163 tmp = gmtime (&atime);
e9e44622
JJ
7164 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7165 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7166 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
2b692964 7167 printf (_("Time Stamp: %s\n"), timebuf);
252b5132
RH
7168 }
7169 break;
103f02d3 7170
252b5132
RH
7171 case DT_MIPS_RLD_VERSION:
7172 case DT_MIPS_LOCAL_GOTNO:
7173 case DT_MIPS_CONFLICTNO:
7174 case DT_MIPS_LIBLISTNO:
7175 case DT_MIPS_SYMTABNO:
7176 case DT_MIPS_UNREFEXTNO:
7177 case DT_MIPS_HIPAGENO:
7178 case DT_MIPS_DELTA_CLASS_NO:
7179 case DT_MIPS_DELTA_INSTANCE_NO:
7180 case DT_MIPS_DELTA_RELOC_NO:
7181 case DT_MIPS_DELTA_SYM_NO:
7182 case DT_MIPS_DELTA_CLASSSYM_NO:
7183 case DT_MIPS_COMPACT_SIZE:
7184 printf ("%ld\n", (long) entry->d_un.d_ptr);
7185 break;
103f02d3
UD
7186
7187 default:
0af1713e 7188 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
7189 }
7190}
7191
103f02d3 7192static void
2cf0635d 7193dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7194{
7195 switch (entry->d_tag)
7196 {
7197 case DT_HP_DLD_FLAGS:
7198 {
7199 static struct
7200 {
7201 long int bit;
2cf0635d 7202 const char * str;
5e220199
NC
7203 }
7204 flags[] =
7205 {
7206 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7207 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7208 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7209 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7210 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7211 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7212 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7213 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7214 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7215 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7216 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7217 { DT_HP_GST, "HP_GST" },
7218 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7219 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7220 { DT_HP_NODELETE, "HP_NODELETE" },
7221 { DT_HP_GROUP, "HP_GROUP" },
7222 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7223 };
103f02d3 7224 int first = 1;
5e220199 7225 size_t cnt;
f7a99963 7226 bfd_vma val = entry->d_un.d_val;
103f02d3 7227
60bca95a 7228 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7229 if (val & flags[cnt].bit)
30800947
NC
7230 {
7231 if (! first)
7232 putchar (' ');
7233 fputs (flags[cnt].str, stdout);
7234 first = 0;
7235 val ^= flags[cnt].bit;
7236 }
76da6bbe 7237
103f02d3 7238 if (val != 0 || first)
f7a99963
NC
7239 {
7240 if (! first)
7241 putchar (' ');
7242 print_vma (val, HEX);
7243 }
103f02d3
UD
7244 }
7245 break;
76da6bbe 7246
252b5132 7247 default:
f7a99963
NC
7248 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7249 break;
252b5132 7250 }
35b1837e 7251 putchar ('\n');
252b5132
RH
7252}
7253
28f997cf
TG
7254#ifdef BFD64
7255
7256/* VMS vs Unix time offset and factor. */
7257
7258#define VMS_EPOCH_OFFSET 35067168000000000LL
7259#define VMS_GRANULARITY_FACTOR 10000000
7260
7261/* Display a VMS time in a human readable format. */
7262
7263static void
7264print_vms_time (bfd_int64_t vmstime)
7265{
7266 struct tm *tm;
7267 time_t unxtime;
7268
7269 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7270 tm = gmtime (&unxtime);
7271 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7272 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7273 tm->tm_hour, tm->tm_min, tm->tm_sec);
7274}
7275#endif /* BFD64 */
7276
ecc51f48 7277static void
2cf0635d 7278dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7279{
7280 switch (entry->d_tag)
7281 {
0de14b54 7282 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7283 /* First 3 slots reserved. */
ecc51f48
NC
7284 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7285 printf (" -- ");
7286 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7287 break;
7288
28f997cf
TG
7289 case DT_IA_64_VMS_LINKTIME:
7290#ifdef BFD64
7291 print_vms_time (entry->d_un.d_val);
7292#endif
7293 break;
7294
7295 case DT_IA_64_VMS_LNKFLAGS:
7296 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7297 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7298 printf (" CALL_DEBUG");
7299 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7300 printf (" NOP0BUFS");
7301 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7302 printf (" P0IMAGE");
7303 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7304 printf (" MKTHREADS");
7305 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7306 printf (" UPCALLS");
7307 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7308 printf (" IMGSTA");
7309 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7310 printf (" INITIALIZE");
7311 if (entry->d_un.d_val & VMS_LF_MAIN)
7312 printf (" MAIN");
7313 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7314 printf (" EXE_INIT");
7315 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7316 printf (" TBK_IN_IMG");
7317 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7318 printf (" DBG_IN_IMG");
7319 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7320 printf (" TBK_IN_DSF");
7321 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7322 printf (" DBG_IN_DSF");
7323 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7324 printf (" SIGNATURES");
7325 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7326 printf (" REL_SEG_OFF");
7327 break;
7328
bdf4d63a
JJ
7329 default:
7330 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7331 break;
ecc51f48 7332 }
bdf4d63a 7333 putchar ('\n');
ecc51f48
NC
7334}
7335
252b5132 7336static int
2cf0635d 7337get_32bit_dynamic_section (FILE * file)
252b5132 7338{
2cf0635d
NC
7339 Elf32_External_Dyn * edyn;
7340 Elf32_External_Dyn * ext;
7341 Elf_Internal_Dyn * entry;
103f02d3 7342
3f5e193b
NC
7343 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7344 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7345 if (!edyn)
7346 return 0;
103f02d3 7347
ba2685cc
AM
7348/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7349 might not have the luxury of section headers. Look for the DT_NULL
7350 terminator to determine the number of entries. */
7351 for (ext = edyn, dynamic_nent = 0;
7352 (char *) ext < (char *) edyn + dynamic_size;
7353 ext++)
7354 {
7355 dynamic_nent++;
7356 if (BYTE_GET (ext->d_tag) == DT_NULL)
7357 break;
7358 }
252b5132 7359
3f5e193b
NC
7360 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7361 sizeof (* entry));
b2d38a17 7362 if (dynamic_section == NULL)
252b5132 7363 {
9ea033b2
NC
7364 error (_("Out of memory\n"));
7365 free (edyn);
7366 return 0;
7367 }
252b5132 7368
fb514b26 7369 for (ext = edyn, entry = dynamic_section;
ba2685cc 7370 entry < dynamic_section + dynamic_nent;
fb514b26 7371 ext++, entry++)
9ea033b2 7372 {
fb514b26
AM
7373 entry->d_tag = BYTE_GET (ext->d_tag);
7374 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7375 }
7376
9ea033b2
NC
7377 free (edyn);
7378
7379 return 1;
7380}
7381
7382static int
2cf0635d 7383get_64bit_dynamic_section (FILE * file)
9ea033b2 7384{
2cf0635d
NC
7385 Elf64_External_Dyn * edyn;
7386 Elf64_External_Dyn * ext;
7387 Elf_Internal_Dyn * entry;
103f02d3 7388
3f5e193b
NC
7389 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7390 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7391 if (!edyn)
7392 return 0;
103f02d3 7393
ba2685cc
AM
7394/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7395 might not have the luxury of section headers. Look for the DT_NULL
7396 terminator to determine the number of entries. */
7397 for (ext = edyn, dynamic_nent = 0;
7398 (char *) ext < (char *) edyn + dynamic_size;
7399 ext++)
7400 {
7401 dynamic_nent++;
66543521 7402 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7403 break;
7404 }
252b5132 7405
3f5e193b
NC
7406 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7407 sizeof (* entry));
b2d38a17 7408 if (dynamic_section == NULL)
252b5132
RH
7409 {
7410 error (_("Out of memory\n"));
7411 free (edyn);
7412 return 0;
7413 }
7414
fb514b26 7415 for (ext = edyn, entry = dynamic_section;
ba2685cc 7416 entry < dynamic_section + dynamic_nent;
fb514b26 7417 ext++, entry++)
252b5132 7418 {
66543521
AM
7419 entry->d_tag = BYTE_GET (ext->d_tag);
7420 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7421 }
7422
7423 free (edyn);
7424
9ea033b2
NC
7425 return 1;
7426}
7427
e9e44622
JJ
7428static void
7429print_dynamic_flags (bfd_vma flags)
d1133906 7430{
e9e44622 7431 int first = 1;
13ae64f3 7432
d1133906
NC
7433 while (flags)
7434 {
7435 bfd_vma flag;
7436
7437 flag = flags & - flags;
7438 flags &= ~ flag;
7439
e9e44622
JJ
7440 if (first)
7441 first = 0;
7442 else
7443 putc (' ', stdout);
13ae64f3 7444
d1133906
NC
7445 switch (flag)
7446 {
e9e44622
JJ
7447 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7448 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7449 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7450 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7451 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7452 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7453 }
7454 }
e9e44622 7455 puts ("");
d1133906
NC
7456}
7457
b2d38a17
NC
7458/* Parse and display the contents of the dynamic section. */
7459
9ea033b2 7460static int
2cf0635d 7461process_dynamic_section (FILE * file)
9ea033b2 7462{
2cf0635d 7463 Elf_Internal_Dyn * entry;
9ea033b2
NC
7464
7465 if (dynamic_size == 0)
7466 {
7467 if (do_dynamic)
b2d38a17 7468 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7469
7470 return 1;
7471 }
7472
7473 if (is_32bit_elf)
7474 {
b2d38a17 7475 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7476 return 0;
7477 }
b2d38a17 7478 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7479 return 0;
7480
252b5132
RH
7481 /* Find the appropriate symbol table. */
7482 if (dynamic_symbols == NULL)
7483 {
86dba8ee
AM
7484 for (entry = dynamic_section;
7485 entry < dynamic_section + dynamic_nent;
7486 ++entry)
252b5132 7487 {
c8286bd1 7488 Elf_Internal_Shdr section;
252b5132
RH
7489
7490 if (entry->d_tag != DT_SYMTAB)
7491 continue;
7492
7493 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7494
7495 /* Since we do not know how big the symbol table is,
7496 we default to reading in the entire file (!) and
7497 processing that. This is overkill, I know, but it
e3c8793a 7498 should work. */
d93f0186 7499 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7500
fb52b2f4
NC
7501 if (archive_file_offset != 0)
7502 section.sh_size = archive_file_size - section.sh_offset;
7503 else
7504 {
7505 if (fseek (file, 0, SEEK_END))
591a748a 7506 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7507
7508 section.sh_size = ftell (file) - section.sh_offset;
7509 }
252b5132 7510
9ea033b2 7511 if (is_32bit_elf)
9ad5cbcf 7512 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7513 else
9ad5cbcf 7514 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7515
9ad5cbcf 7516 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 7517 if (num_dynamic_syms < 1)
252b5132
RH
7518 {
7519 error (_("Unable to determine the number of symbols to load\n"));
7520 continue;
7521 }
7522
9ad5cbcf 7523 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
7524 }
7525 }
7526
7527 /* Similarly find a string table. */
7528 if (dynamic_strings == NULL)
7529 {
86dba8ee
AM
7530 for (entry = dynamic_section;
7531 entry < dynamic_section + dynamic_nent;
7532 ++entry)
252b5132
RH
7533 {
7534 unsigned long offset;
b34976b6 7535 long str_tab_len;
252b5132
RH
7536
7537 if (entry->d_tag != DT_STRTAB)
7538 continue;
7539
7540 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7541
7542 /* Since we do not know how big the string table is,
7543 we default to reading in the entire file (!) and
7544 processing that. This is overkill, I know, but it
e3c8793a 7545 should work. */
252b5132 7546
d93f0186 7547 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7548
7549 if (archive_file_offset != 0)
7550 str_tab_len = archive_file_size - offset;
7551 else
7552 {
7553 if (fseek (file, 0, SEEK_END))
7554 error (_("Unable to seek to end of file\n"));
7555 str_tab_len = ftell (file) - offset;
7556 }
252b5132
RH
7557
7558 if (str_tab_len < 1)
7559 {
7560 error
7561 (_("Unable to determine the length of the dynamic string table\n"));
7562 continue;
7563 }
7564
3f5e193b
NC
7565 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7566 str_tab_len,
7567 _("dynamic string table"));
59245841 7568 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7569 break;
7570 }
7571 }
7572
7573 /* And find the syminfo section if available. */
7574 if (dynamic_syminfo == NULL)
7575 {
3e8bba36 7576 unsigned long syminsz = 0;
252b5132 7577
86dba8ee
AM
7578 for (entry = dynamic_section;
7579 entry < dynamic_section + dynamic_nent;
7580 ++entry)
252b5132
RH
7581 {
7582 if (entry->d_tag == DT_SYMINENT)
7583 {
7584 /* Note: these braces are necessary to avoid a syntax
7585 error from the SunOS4 C compiler. */
7586 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7587 }
7588 else if (entry->d_tag == DT_SYMINSZ)
7589 syminsz = entry->d_un.d_val;
7590 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7591 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7592 syminsz);
252b5132
RH
7593 }
7594
7595 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7596 {
2cf0635d
NC
7597 Elf_External_Syminfo * extsyminfo;
7598 Elf_External_Syminfo * extsym;
7599 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7600
7601 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7602 extsyminfo = (Elf_External_Syminfo *)
7603 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7604 _("symbol information"));
a6e9f9df
AM
7605 if (!extsyminfo)
7606 return 0;
252b5132 7607
3f5e193b 7608 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7609 if (dynamic_syminfo == NULL)
7610 {
7611 error (_("Out of memory\n"));
7612 return 0;
7613 }
7614
7615 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7616 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7617 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7618 ++syminfo, ++extsym)
252b5132 7619 {
86dba8ee
AM
7620 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7621 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7622 }
7623
7624 free (extsyminfo);
7625 }
7626 }
7627
7628 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7629 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7630 dynamic_addr, dynamic_nent);
252b5132
RH
7631 if (do_dynamic)
7632 printf (_(" Tag Type Name/Value\n"));
7633
86dba8ee
AM
7634 for (entry = dynamic_section;
7635 entry < dynamic_section + dynamic_nent;
7636 entry++)
252b5132
RH
7637 {
7638 if (do_dynamic)
f7a99963 7639 {
2cf0635d 7640 const char * dtype;
e699b9ff 7641
f7a99963
NC
7642 putchar (' ');
7643 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7644 dtype = get_dynamic_type (entry->d_tag);
7645 printf (" (%s)%*s", dtype,
7646 ((is_32bit_elf ? 27 : 19)
7647 - (int) strlen (dtype)),
f7a99963
NC
7648 " ");
7649 }
252b5132
RH
7650
7651 switch (entry->d_tag)
7652 {
d1133906
NC
7653 case DT_FLAGS:
7654 if (do_dynamic)
e9e44622 7655 print_dynamic_flags (entry->d_un.d_val);
d1133906 7656 break;
76da6bbe 7657
252b5132
RH
7658 case DT_AUXILIARY:
7659 case DT_FILTER:
019148e4
L
7660 case DT_CONFIG:
7661 case DT_DEPAUDIT:
7662 case DT_AUDIT:
252b5132
RH
7663 if (do_dynamic)
7664 {
019148e4 7665 switch (entry->d_tag)
b34976b6 7666 {
019148e4
L
7667 case DT_AUXILIARY:
7668 printf (_("Auxiliary library"));
7669 break;
7670
7671 case DT_FILTER:
7672 printf (_("Filter library"));
7673 break;
7674
b34976b6 7675 case DT_CONFIG:
019148e4
L
7676 printf (_("Configuration file"));
7677 break;
7678
7679 case DT_DEPAUDIT:
7680 printf (_("Dependency audit library"));
7681 break;
7682
7683 case DT_AUDIT:
7684 printf (_("Audit library"));
7685 break;
7686 }
252b5132 7687
d79b3d50
NC
7688 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7689 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7690 else
f7a99963
NC
7691 {
7692 printf (": ");
7693 print_vma (entry->d_un.d_val, PREFIX_HEX);
7694 putchar ('\n');
7695 }
252b5132
RH
7696 }
7697 break;
7698
dcefbbbd 7699 case DT_FEATURE:
252b5132
RH
7700 if (do_dynamic)
7701 {
7702 printf (_("Flags:"));
86f55779 7703
252b5132
RH
7704 if (entry->d_un.d_val == 0)
7705 printf (_(" None\n"));
7706 else
7707 {
7708 unsigned long int val = entry->d_un.d_val;
86f55779 7709
252b5132
RH
7710 if (val & DTF_1_PARINIT)
7711 {
7712 printf (" PARINIT");
7713 val ^= DTF_1_PARINIT;
7714 }
dcefbbbd
L
7715 if (val & DTF_1_CONFEXP)
7716 {
7717 printf (" CONFEXP");
7718 val ^= DTF_1_CONFEXP;
7719 }
252b5132
RH
7720 if (val != 0)
7721 printf (" %lx", val);
7722 puts ("");
7723 }
7724 }
7725 break;
7726
7727 case DT_POSFLAG_1:
7728 if (do_dynamic)
7729 {
7730 printf (_("Flags:"));
86f55779 7731
252b5132
RH
7732 if (entry->d_un.d_val == 0)
7733 printf (_(" None\n"));
7734 else
7735 {
7736 unsigned long int val = entry->d_un.d_val;
86f55779 7737
252b5132
RH
7738 if (val & DF_P1_LAZYLOAD)
7739 {
7740 printf (" LAZYLOAD");
7741 val ^= DF_P1_LAZYLOAD;
7742 }
7743 if (val & DF_P1_GROUPPERM)
7744 {
7745 printf (" GROUPPERM");
7746 val ^= DF_P1_GROUPPERM;
7747 }
7748 if (val != 0)
7749 printf (" %lx", val);
7750 puts ("");
7751 }
7752 }
7753 break;
7754
7755 case DT_FLAGS_1:
7756 if (do_dynamic)
7757 {
7758 printf (_("Flags:"));
7759 if (entry->d_un.d_val == 0)
7760 printf (_(" None\n"));
7761 else
7762 {
7763 unsigned long int val = entry->d_un.d_val;
86f55779 7764
252b5132
RH
7765 if (val & DF_1_NOW)
7766 {
7767 printf (" NOW");
7768 val ^= DF_1_NOW;
7769 }
7770 if (val & DF_1_GLOBAL)
7771 {
7772 printf (" GLOBAL");
7773 val ^= DF_1_GLOBAL;
7774 }
7775 if (val & DF_1_GROUP)
7776 {
7777 printf (" GROUP");
7778 val ^= DF_1_GROUP;
7779 }
7780 if (val & DF_1_NODELETE)
7781 {
7782 printf (" NODELETE");
7783 val ^= DF_1_NODELETE;
7784 }
7785 if (val & DF_1_LOADFLTR)
7786 {
7787 printf (" LOADFLTR");
7788 val ^= DF_1_LOADFLTR;
7789 }
7790 if (val & DF_1_INITFIRST)
7791 {
7792 printf (" INITFIRST");
7793 val ^= DF_1_INITFIRST;
7794 }
7795 if (val & DF_1_NOOPEN)
7796 {
7797 printf (" NOOPEN");
7798 val ^= DF_1_NOOPEN;
7799 }
7800 if (val & DF_1_ORIGIN)
7801 {
7802 printf (" ORIGIN");
7803 val ^= DF_1_ORIGIN;
7804 }
7805 if (val & DF_1_DIRECT)
7806 {
7807 printf (" DIRECT");
7808 val ^= DF_1_DIRECT;
7809 }
7810 if (val & DF_1_TRANS)
7811 {
7812 printf (" TRANS");
7813 val ^= DF_1_TRANS;
7814 }
7815 if (val & DF_1_INTERPOSE)
7816 {
7817 printf (" INTERPOSE");
7818 val ^= DF_1_INTERPOSE;
7819 }
f7db6139 7820 if (val & DF_1_NODEFLIB)
dcefbbbd 7821 {
f7db6139
L
7822 printf (" NODEFLIB");
7823 val ^= DF_1_NODEFLIB;
dcefbbbd
L
7824 }
7825 if (val & DF_1_NODUMP)
7826 {
7827 printf (" NODUMP");
7828 val ^= DF_1_NODUMP;
7829 }
7830 if (val & DF_1_CONLFAT)
7831 {
7832 printf (" CONLFAT");
7833 val ^= DF_1_CONLFAT;
7834 }
252b5132
RH
7835 if (val != 0)
7836 printf (" %lx", val);
7837 puts ("");
7838 }
7839 }
7840 break;
7841
7842 case DT_PLTREL:
566b0d53 7843 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7844 if (do_dynamic)
7845 puts (get_dynamic_type (entry->d_un.d_val));
7846 break;
7847
7848 case DT_NULL :
7849 case DT_NEEDED :
7850 case DT_PLTGOT :
7851 case DT_HASH :
7852 case DT_STRTAB :
7853 case DT_SYMTAB :
7854 case DT_RELA :
7855 case DT_INIT :
7856 case DT_FINI :
7857 case DT_SONAME :
7858 case DT_RPATH :
7859 case DT_SYMBOLIC:
7860 case DT_REL :
7861 case DT_DEBUG :
7862 case DT_TEXTREL :
7863 case DT_JMPREL :
019148e4 7864 case DT_RUNPATH :
252b5132
RH
7865 dynamic_info[entry->d_tag] = entry->d_un.d_val;
7866
7867 if (do_dynamic)
7868 {
2cf0635d 7869 char * name;
252b5132 7870
d79b3d50
NC
7871 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7872 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7873 else
d79b3d50 7874 name = NULL;
252b5132
RH
7875
7876 if (name)
7877 {
7878 switch (entry->d_tag)
7879 {
7880 case DT_NEEDED:
7881 printf (_("Shared library: [%s]"), name);
7882
18bd398b 7883 if (streq (name, program_interpreter))
f7a99963 7884 printf (_(" program interpreter"));
252b5132
RH
7885 break;
7886
7887 case DT_SONAME:
f7a99963 7888 printf (_("Library soname: [%s]"), name);
252b5132
RH
7889 break;
7890
7891 case DT_RPATH:
f7a99963 7892 printf (_("Library rpath: [%s]"), name);
252b5132
RH
7893 break;
7894
019148e4
L
7895 case DT_RUNPATH:
7896 printf (_("Library runpath: [%s]"), name);
7897 break;
7898
252b5132 7899 default:
f7a99963
NC
7900 print_vma (entry->d_un.d_val, PREFIX_HEX);
7901 break;
252b5132
RH
7902 }
7903 }
7904 else
f7a99963
NC
7905 print_vma (entry->d_un.d_val, PREFIX_HEX);
7906
7907 putchar ('\n');
252b5132
RH
7908 }
7909 break;
7910
7911 case DT_PLTRELSZ:
7912 case DT_RELASZ :
7913 case DT_STRSZ :
7914 case DT_RELSZ :
7915 case DT_RELAENT :
7916 case DT_SYMENT :
7917 case DT_RELENT :
566b0d53 7918 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7919 case DT_PLTPADSZ:
7920 case DT_MOVEENT :
7921 case DT_MOVESZ :
7922 case DT_INIT_ARRAYSZ:
7923 case DT_FINI_ARRAYSZ:
047b2264
JJ
7924 case DT_GNU_CONFLICTSZ:
7925 case DT_GNU_LIBLISTSZ:
252b5132 7926 if (do_dynamic)
f7a99963
NC
7927 {
7928 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 7929 printf (_(" (bytes)\n"));
f7a99963 7930 }
252b5132
RH
7931 break;
7932
7933 case DT_VERDEFNUM:
7934 case DT_VERNEEDNUM:
7935 case DT_RELACOUNT:
7936 case DT_RELCOUNT:
7937 if (do_dynamic)
f7a99963
NC
7938 {
7939 print_vma (entry->d_un.d_val, UNSIGNED);
7940 putchar ('\n');
7941 }
252b5132
RH
7942 break;
7943
7944 case DT_SYMINSZ:
7945 case DT_SYMINENT:
7946 case DT_SYMINFO:
7947 case DT_USED:
7948 case DT_INIT_ARRAY:
7949 case DT_FINI_ARRAY:
7950 if (do_dynamic)
7951 {
d79b3d50
NC
7952 if (entry->d_tag == DT_USED
7953 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 7954 {
2cf0635d 7955 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7956
b34976b6 7957 if (*name)
252b5132
RH
7958 {
7959 printf (_("Not needed object: [%s]\n"), name);
7960 break;
7961 }
7962 }
103f02d3 7963
f7a99963
NC
7964 print_vma (entry->d_un.d_val, PREFIX_HEX);
7965 putchar ('\n');
252b5132
RH
7966 }
7967 break;
7968
7969 case DT_BIND_NOW:
7970 /* The value of this entry is ignored. */
35b1837e
AM
7971 if (do_dynamic)
7972 putchar ('\n');
252b5132 7973 break;
103f02d3 7974
047b2264
JJ
7975 case DT_GNU_PRELINKED:
7976 if (do_dynamic)
7977 {
2cf0635d 7978 struct tm * tmp;
91d6fa6a 7979 time_t atime = entry->d_un.d_val;
047b2264 7980
91d6fa6a 7981 tmp = gmtime (&atime);
047b2264
JJ
7982 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
7983 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7984 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7985
7986 }
7987 break;
7988
fdc90cb4
JJ
7989 case DT_GNU_HASH:
7990 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
7991 if (do_dynamic)
7992 {
7993 print_vma (entry->d_un.d_val, PREFIX_HEX);
7994 putchar ('\n');
7995 }
7996 break;
7997
252b5132
RH
7998 default:
7999 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8000 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8001 entry->d_un.d_val;
8002
8003 if (do_dynamic)
8004 {
8005 switch (elf_header.e_machine)
8006 {
8007 case EM_MIPS:
4fe85591 8008 case EM_MIPS_RS3_LE:
b2d38a17 8009 dynamic_section_mips_val (entry);
252b5132 8010 break;
103f02d3 8011 case EM_PARISC:
b2d38a17 8012 dynamic_section_parisc_val (entry);
103f02d3 8013 break;
ecc51f48 8014 case EM_IA_64:
b2d38a17 8015 dynamic_section_ia64_val (entry);
ecc51f48 8016 break;
252b5132 8017 default:
f7a99963
NC
8018 print_vma (entry->d_un.d_val, PREFIX_HEX);
8019 putchar ('\n');
252b5132
RH
8020 }
8021 }
8022 break;
8023 }
8024 }
8025
8026 return 1;
8027}
8028
8029static char *
d3ba0551 8030get_ver_flags (unsigned int flags)
252b5132 8031{
b34976b6 8032 static char buff[32];
252b5132
RH
8033
8034 buff[0] = 0;
8035
8036 if (flags == 0)
8037 return _("none");
8038
8039 if (flags & VER_FLG_BASE)
8040 strcat (buff, "BASE ");
8041
8042 if (flags & VER_FLG_WEAK)
8043 {
8044 if (flags & VER_FLG_BASE)
8045 strcat (buff, "| ");
8046
8047 strcat (buff, "WEAK ");
8048 }
8049
44ec90b9
RO
8050 if (flags & VER_FLG_INFO)
8051 {
8052 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8053 strcat (buff, "| ");
8054
8055 strcat (buff, "INFO ");
8056 }
8057
8058 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8059 strcat (buff, _("| <unknown>"));
252b5132
RH
8060
8061 return buff;
8062}
8063
8064/* Display the contents of the version sections. */
98fb390a 8065
252b5132 8066static int
2cf0635d 8067process_version_sections (FILE * file)
252b5132 8068{
2cf0635d 8069 Elf_Internal_Shdr * section;
b34976b6
AM
8070 unsigned i;
8071 int found = 0;
252b5132
RH
8072
8073 if (! do_version)
8074 return 1;
8075
8076 for (i = 0, section = section_headers;
8077 i < elf_header.e_shnum;
b34976b6 8078 i++, section++)
252b5132
RH
8079 {
8080 switch (section->sh_type)
8081 {
8082 case SHT_GNU_verdef:
8083 {
2cf0635d 8084 Elf_External_Verdef * edefs;
b34976b6
AM
8085 unsigned int idx;
8086 unsigned int cnt;
2cf0635d 8087 char * endbuf;
252b5132
RH
8088
8089 found = 1;
8090
8091 printf
72de5009 8092 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8093 SECTION_NAME (section), section->sh_info);
8094
8095 printf (_(" Addr: 0x"));
8096 printf_vma (section->sh_addr);
72de5009 8097 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8098 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8099 section->sh_link < elf_header.e_shnum
8100 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8101 : _("<corrupt>"));
252b5132 8102
3f5e193b
NC
8103 edefs = (Elf_External_Verdef *)
8104 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8105 _("version definition section"));
a6e9f9df
AM
8106 if (!edefs)
8107 break;
59245841 8108 endbuf = (char *) edefs + section->sh_size;
252b5132 8109
b34976b6 8110 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8111 {
2cf0635d
NC
8112 char * vstart;
8113 Elf_External_Verdef * edef;
b34976b6 8114 Elf_Internal_Verdef ent;
2cf0635d 8115 Elf_External_Verdaux * eaux;
b34976b6
AM
8116 Elf_Internal_Verdaux aux;
8117 int j;
8118 int isum;
103f02d3 8119
dd24e3da
NC
8120 /* Check for negative or very large indicies. */
8121 if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
8122 break;
8123
252b5132 8124 vstart = ((char *) edefs) + idx;
54806181
AM
8125 if (vstart + sizeof (*edef) > endbuf)
8126 break;
252b5132
RH
8127
8128 edef = (Elf_External_Verdef *) vstart;
8129
8130 ent.vd_version = BYTE_GET (edef->vd_version);
8131 ent.vd_flags = BYTE_GET (edef->vd_flags);
8132 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8133 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8134 ent.vd_hash = BYTE_GET (edef->vd_hash);
8135 ent.vd_aux = BYTE_GET (edef->vd_aux);
8136 ent.vd_next = BYTE_GET (edef->vd_next);
8137
8138 printf (_(" %#06x: Rev: %d Flags: %s"),
8139 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8140
8141 printf (_(" Index: %d Cnt: %d "),
8142 ent.vd_ndx, ent.vd_cnt);
8143
dd24e3da
NC
8144 /* Check for overflow. */
8145 if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
8146 || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
8147 break;
8148
252b5132
RH
8149 vstart += ent.vd_aux;
8150
8151 eaux = (Elf_External_Verdaux *) vstart;
8152
8153 aux.vda_name = BYTE_GET (eaux->vda_name);
8154 aux.vda_next = BYTE_GET (eaux->vda_next);
8155
d79b3d50
NC
8156 if (VALID_DYNAMIC_NAME (aux.vda_name))
8157 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8158 else
8159 printf (_("Name index: %ld\n"), aux.vda_name);
8160
8161 isum = idx + ent.vd_aux;
8162
b34976b6 8163 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8164 {
dd24e3da
NC
8165 /* Check for overflow. */
8166 if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
8167 || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
8168 break;
8169
252b5132
RH
8170 isum += aux.vda_next;
8171 vstart += aux.vda_next;
8172
8173 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8174 if (vstart + sizeof (*eaux) > endbuf)
8175 break;
252b5132
RH
8176
8177 aux.vda_name = BYTE_GET (eaux->vda_name);
8178 aux.vda_next = BYTE_GET (eaux->vda_next);
8179
d79b3d50 8180 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8181 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8182 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8183 else
8184 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8185 isum, j, aux.vda_name);
8186 }
dd24e3da 8187
54806181
AM
8188 if (j < ent.vd_cnt)
8189 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8190
8191 idx += ent.vd_next;
8192 }
dd24e3da 8193
54806181
AM
8194 if (cnt < section->sh_info)
8195 printf (_(" Version definition past end of section\n"));
252b5132
RH
8196
8197 free (edefs);
8198 }
8199 break;
103f02d3 8200
252b5132
RH
8201 case SHT_GNU_verneed:
8202 {
2cf0635d 8203 Elf_External_Verneed * eneed;
b34976b6
AM
8204 unsigned int idx;
8205 unsigned int cnt;
2cf0635d 8206 char * endbuf;
252b5132
RH
8207
8208 found = 1;
8209
72de5009 8210 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8211 SECTION_NAME (section), section->sh_info);
8212
8213 printf (_(" Addr: 0x"));
8214 printf_vma (section->sh_addr);
72de5009 8215 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8216 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8217 section->sh_link < elf_header.e_shnum
8218 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8219 : _("<corrupt>"));
252b5132 8220
3f5e193b
NC
8221 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8222 section->sh_offset, 1,
8223 section->sh_size,
8224 _("version need section"));
a6e9f9df
AM
8225 if (!eneed)
8226 break;
59245841 8227 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8228
8229 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8230 {
2cf0635d 8231 Elf_External_Verneed * entry;
b34976b6
AM
8232 Elf_Internal_Verneed ent;
8233 int j;
8234 int isum;
2cf0635d 8235 char * vstart;
252b5132 8236
dd24e3da
NC
8237 if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
8238 break;
8239
252b5132 8240 vstart = ((char *) eneed) + idx;
54806181
AM
8241 if (vstart + sizeof (*entry) > endbuf)
8242 break;
252b5132
RH
8243
8244 entry = (Elf_External_Verneed *) vstart;
8245
8246 ent.vn_version = BYTE_GET (entry->vn_version);
8247 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8248 ent.vn_file = BYTE_GET (entry->vn_file);
8249 ent.vn_aux = BYTE_GET (entry->vn_aux);
8250 ent.vn_next = BYTE_GET (entry->vn_next);
8251
8252 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8253
d79b3d50
NC
8254 if (VALID_DYNAMIC_NAME (ent.vn_file))
8255 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8256 else
8257 printf (_(" File: %lx"), ent.vn_file);
8258
8259 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8260
dd24e3da
NC
8261 /* Check for overflow. */
8262 if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
8263 || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
8264 break;
8265
252b5132
RH
8266 vstart += ent.vn_aux;
8267
8268 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8269 {
2cf0635d 8270 Elf_External_Vernaux * eaux;
b34976b6 8271 Elf_Internal_Vernaux aux;
252b5132 8272
54806181
AM
8273 if (vstart + sizeof (*eaux) > endbuf)
8274 break;
252b5132
RH
8275 eaux = (Elf_External_Vernaux *) vstart;
8276
8277 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8278 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8279 aux.vna_other = BYTE_GET (eaux->vna_other);
8280 aux.vna_name = BYTE_GET (eaux->vna_name);
8281 aux.vna_next = BYTE_GET (eaux->vna_next);
8282
d79b3d50 8283 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8284 printf (_(" %#06x: Name: %s"),
d79b3d50 8285 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8286 else
ecc2063b 8287 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8288 isum, aux.vna_name);
8289
8290 printf (_(" Flags: %s Version: %d\n"),
8291 get_ver_flags (aux.vna_flags), aux.vna_other);
8292
dd24e3da
NC
8293 /* Check for overflow. */
8294 if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
8295 || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
8296 break;
8297
252b5132
RH
8298 isum += aux.vna_next;
8299 vstart += aux.vna_next;
8300 }
54806181
AM
8301 if (j < ent.vn_cnt)
8302 printf (_(" Version need aux past end of section\n"));
252b5132
RH
8303
8304 idx += ent.vn_next;
8305 }
54806181
AM
8306 if (cnt < section->sh_info)
8307 printf (_(" Version need past end of section\n"));
103f02d3 8308
252b5132
RH
8309 free (eneed);
8310 }
8311 break;
8312
8313 case SHT_GNU_versym:
8314 {
2cf0635d 8315 Elf_Internal_Shdr * link_section;
b34976b6
AM
8316 int total;
8317 int cnt;
2cf0635d
NC
8318 unsigned char * edata;
8319 unsigned short * data;
8320 char * strtab;
8321 Elf_Internal_Sym * symbols;
8322 Elf_Internal_Shdr * string_sec;
d3ba0551 8323 long off;
252b5132 8324
4fbb74a6 8325 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8326 break;
8327
4fbb74a6 8328 link_section = section_headers + section->sh_link;
08d8fa11 8329 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8330
4fbb74a6 8331 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8332 break;
8333
252b5132
RH
8334 found = 1;
8335
9ad5cbcf 8336 symbols = GET_ELF_SYMBOLS (file, link_section);
dd24e3da
NC
8337 if (symbols == NULL)
8338 break;
252b5132 8339
4fbb74a6 8340 string_sec = section_headers + link_section->sh_link;
252b5132 8341
3f5e193b
NC
8342 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8343 string_sec->sh_size,
8344 _("version string table"));
a6e9f9df 8345 if (!strtab)
0429c154
MS
8346 {
8347 free (symbols);
8348 break;
8349 }
252b5132
RH
8350
8351 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8352 SECTION_NAME (section), total);
8353
8354 printf (_(" Addr: "));
8355 printf_vma (section->sh_addr);
72de5009 8356 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8357 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8358 SECTION_NAME (link_section));
8359
d3ba0551
AM
8360 off = offset_from_vma (file,
8361 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8362 total * sizeof (short));
3f5e193b
NC
8363 edata = (unsigned char *) get_data (NULL, file, off, total,
8364 sizeof (short),
8365 _("version symbol data"));
a6e9f9df
AM
8366 if (!edata)
8367 {
8368 free (strtab);
0429c154 8369 free (symbols);
a6e9f9df
AM
8370 break;
8371 }
252b5132 8372
3f5e193b 8373 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8374
8375 for (cnt = total; cnt --;)
b34976b6
AM
8376 data[cnt] = byte_get (edata + cnt * sizeof (short),
8377 sizeof (short));
252b5132
RH
8378
8379 free (edata);
8380
8381 for (cnt = 0; cnt < total; cnt += 4)
8382 {
8383 int j, nn;
00d93f34 8384 int check_def, check_need;
2cf0635d 8385 char * name;
252b5132
RH
8386
8387 printf (" %03x:", cnt);
8388
8389 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8390 switch (data[cnt + j])
252b5132
RH
8391 {
8392 case 0:
8393 fputs (_(" 0 (*local*) "), stdout);
8394 break;
8395
8396 case 1:
8397 fputs (_(" 1 (*global*) "), stdout);
8398 break;
8399
8400 default:
c244d050
NC
8401 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8402 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8403
dd24e3da
NC
8404 /* If this index value is greater than the size of the symbols
8405 array, break to avoid an out-of-bounds read, */
8406 if ((unsigned long)(cnt + j) >=
8407 ((unsigned long)link_section->sh_size /
8408 (unsigned long)link_section->sh_entsize))
8409 {
8410 warn (_("invalid index into symbol array\n"));
8411 break;
8412 }
8413
00d93f34
JJ
8414 check_def = 1;
8415 check_need = 1;
4fbb74a6
AM
8416 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8417 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8418 != SHT_NOBITS)
252b5132 8419 {
b34976b6 8420 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8421 check_def = 0;
8422 else
8423 check_need = 0;
252b5132 8424 }
00d93f34
JJ
8425
8426 if (check_need
b34976b6 8427 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8428 {
b34976b6
AM
8429 Elf_Internal_Verneed ivn;
8430 unsigned long offset;
252b5132 8431
d93f0186
NC
8432 offset = offset_from_vma
8433 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8434 sizeof (Elf_External_Verneed));
252b5132 8435
b34976b6 8436 do
252b5132 8437 {
b34976b6
AM
8438 Elf_Internal_Vernaux ivna;
8439 Elf_External_Verneed evn;
8440 Elf_External_Vernaux evna;
8441 unsigned long a_off;
252b5132 8442
59245841
NC
8443 if (get_data (&evn, file, offset, sizeof (evn), 1,
8444 _("version need")) == NULL)
8445 break;
8446
252b5132
RH
8447 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8448 ivn.vn_next = BYTE_GET (evn.vn_next);
8449
8450 a_off = offset + ivn.vn_aux;
8451
8452 do
8453 {
59245841
NC
8454 if (get_data (&evna, file, a_off, sizeof (evna),
8455 1, _("version need aux (2)")) == NULL)
8456 {
8457 ivna.vna_next = 0;
8458 ivna.vna_other = 0;
8459 }
8460 else
8461 {
8462 ivna.vna_next = BYTE_GET (evna.vna_next);
8463 ivna.vna_other = BYTE_GET (evna.vna_other);
8464 }
252b5132
RH
8465
8466 a_off += ivna.vna_next;
8467 }
b34976b6 8468 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8469 && ivna.vna_next != 0);
8470
b34976b6 8471 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8472 {
8473 ivna.vna_name = BYTE_GET (evna.vna_name);
8474
54806181
AM
8475 if (ivna.vna_name >= string_sec->sh_size)
8476 name = _("*invalid*");
8477 else
8478 name = strtab + ivna.vna_name;
252b5132 8479 nn += printf ("(%s%-*s",
16062207
ILT
8480 name,
8481 12 - (int) strlen (name),
252b5132 8482 ")");
00d93f34 8483 check_def = 0;
252b5132
RH
8484 break;
8485 }
8486
8487 offset += ivn.vn_next;
8488 }
8489 while (ivn.vn_next);
8490 }
00d93f34 8491
b34976b6
AM
8492 if (check_def && data[cnt + j] != 0x8001
8493 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8494 {
b34976b6
AM
8495 Elf_Internal_Verdef ivd;
8496 Elf_External_Verdef evd;
8497 unsigned long offset;
252b5132 8498
d93f0186
NC
8499 offset = offset_from_vma
8500 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8501 sizeof evd);
252b5132
RH
8502
8503 do
8504 {
59245841
NC
8505 if (get_data (&evd, file, offset, sizeof (evd), 1,
8506 _("version def")) == NULL)
8507 {
8508 ivd.vd_next = 0;
8509 ivd.vd_ndx = 0;
8510 }
8511 else
8512 {
8513 ivd.vd_next = BYTE_GET (evd.vd_next);
8514 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8515 }
252b5132
RH
8516
8517 offset += ivd.vd_next;
8518 }
c244d050 8519 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8520 && ivd.vd_next != 0);
8521
c244d050 8522 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8523 {
b34976b6
AM
8524 Elf_External_Verdaux evda;
8525 Elf_Internal_Verdaux ivda;
252b5132
RH
8526
8527 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8528
59245841
NC
8529 if (get_data (&evda, file,
8530 offset - ivd.vd_next + ivd.vd_aux,
8531 sizeof (evda), 1,
8532 _("version def aux")) == NULL)
8533 break;
252b5132
RH
8534
8535 ivda.vda_name = BYTE_GET (evda.vda_name);
8536
54806181
AM
8537 if (ivda.vda_name >= string_sec->sh_size)
8538 name = _("*invalid*");
8539 else
8540 name = strtab + ivda.vda_name;
252b5132 8541 nn += printf ("(%s%-*s",
16062207
ILT
8542 name,
8543 12 - (int) strlen (name),
252b5132
RH
8544 ")");
8545 }
8546 }
8547
8548 if (nn < 18)
8549 printf ("%*c", 18 - nn, ' ');
8550 }
8551
8552 putchar ('\n');
8553 }
8554
8555 free (data);
8556 free (strtab);
8557 free (symbols);
8558 }
8559 break;
103f02d3 8560
252b5132
RH
8561 default:
8562 break;
8563 }
8564 }
8565
8566 if (! found)
8567 printf (_("\nNo version information found in this file.\n"));
8568
8569 return 1;
8570}
8571
d1133906 8572static const char *
d3ba0551 8573get_symbol_binding (unsigned int binding)
252b5132 8574{
b34976b6 8575 static char buff[32];
252b5132
RH
8576
8577 switch (binding)
8578 {
b34976b6
AM
8579 case STB_LOCAL: return "LOCAL";
8580 case STB_GLOBAL: return "GLOBAL";
8581 case STB_WEAK: return "WEAK";
252b5132
RH
8582 default:
8583 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8584 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8585 binding);
252b5132 8586 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8587 {
8588 if (binding == STB_GNU_UNIQUE
9c55345c
TS
8589 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8590 /* GNU is still using the default value 0. */
3e7a7d11
NC
8591 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8592 return "UNIQUE";
8593 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8594 }
252b5132 8595 else
e9e44622 8596 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8597 return buff;
8598 }
8599}
8600
d1133906 8601static const char *
d3ba0551 8602get_symbol_type (unsigned int type)
252b5132 8603{
b34976b6 8604 static char buff[32];
252b5132
RH
8605
8606 switch (type)
8607 {
b34976b6
AM
8608 case STT_NOTYPE: return "NOTYPE";
8609 case STT_OBJECT: return "OBJECT";
8610 case STT_FUNC: return "FUNC";
8611 case STT_SECTION: return "SECTION";
8612 case STT_FILE: return "FILE";
8613 case STT_COMMON: return "COMMON";
8614 case STT_TLS: return "TLS";
15ab5209
DB
8615 case STT_RELC: return "RELC";
8616 case STT_SRELC: return "SRELC";
252b5132
RH
8617 default:
8618 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8619 {
8620 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8621 return "THUMB_FUNC";
8622
351b4b40 8623 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8624 return "REGISTER";
8625
8626 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8627 return "PARISC_MILLI";
8628
e9e44622 8629 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8630 }
252b5132 8631 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8632 {
8633 if (elf_header.e_machine == EM_PARISC)
8634 {
8635 if (type == STT_HP_OPAQUE)
8636 return "HP_OPAQUE";
8637 if (type == STT_HP_STUB)
8638 return "HP_STUB";
8639 }
8640
d8045f23 8641 if (type == STT_GNU_IFUNC
9c55345c
TS
8642 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8643 /* GNU is still using the default value 0. */
d8045f23
NC
8644 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8645 return "IFUNC";
8646
e9e44622 8647 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8648 }
252b5132 8649 else
e9e44622 8650 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8651 return buff;
8652 }
8653}
8654
d1133906 8655static const char *
d3ba0551 8656get_symbol_visibility (unsigned int visibility)
d1133906
NC
8657{
8658 switch (visibility)
8659 {
b34976b6
AM
8660 case STV_DEFAULT: return "DEFAULT";
8661 case STV_INTERNAL: return "INTERNAL";
8662 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
8663 case STV_PROTECTED: return "PROTECTED";
8664 default: abort ();
8665 }
8666}
8667
5e2b0d47
NC
8668static const char *
8669get_mips_symbol_other (unsigned int other)
8670{
8671 switch (other)
8672 {
8673 case STO_OPTIONAL: return "OPTIONAL";
8674 case STO_MIPS16: return "MIPS16";
861fb55a
DJ
8675 case STO_MIPS_PLT: return "MIPS PLT";
8676 case STO_MIPS_PIC: return "MIPS PIC";
5e2b0d47
NC
8677 default: return NULL;
8678 }
8679}
8680
28f997cf
TG
8681static const char *
8682get_ia64_symbol_other (unsigned int other)
8683{
8684 if (is_ia64_vms ())
8685 {
8686 static char res[32];
8687
8688 res[0] = 0;
8689
8690 /* Function types is for images and .STB files only. */
8691 switch (elf_header.e_type)
8692 {
8693 case ET_DYN:
8694 case ET_EXEC:
8695 switch (VMS_ST_FUNC_TYPE (other))
8696 {
8697 case VMS_SFT_CODE_ADDR:
8698 strcat (res, " CA");
8699 break;
8700 case VMS_SFT_SYMV_IDX:
8701 strcat (res, " VEC");
8702 break;
8703 case VMS_SFT_FD:
8704 strcat (res, " FD");
8705 break;
8706 case VMS_SFT_RESERVE:
8707 strcat (res, " RSV");
8708 break;
8709 default:
8710 abort ();
8711 }
8712 break;
8713 default:
8714 break;
8715 }
8716 switch (VMS_ST_LINKAGE (other))
8717 {
8718 case VMS_STL_IGNORE:
8719 strcat (res, " IGN");
8720 break;
8721 case VMS_STL_RESERVE:
8722 strcat (res, " RSV");
8723 break;
8724 case VMS_STL_STD:
8725 strcat (res, " STD");
8726 break;
8727 case VMS_STL_LNK:
8728 strcat (res, " LNK");
8729 break;
8730 default:
8731 abort ();
8732 }
8733
8734 if (res[0] != 0)
8735 return res + 1;
8736 else
8737 return res;
8738 }
8739 return NULL;
8740}
8741
5e2b0d47
NC
8742static const char *
8743get_symbol_other (unsigned int other)
8744{
8745 const char * result = NULL;
8746 static char buff [32];
8747
8748 if (other == 0)
8749 return "";
8750
8751 switch (elf_header.e_machine)
8752 {
8753 case EM_MIPS:
8754 result = get_mips_symbol_other (other);
28f997cf
TG
8755 break;
8756 case EM_IA_64:
8757 result = get_ia64_symbol_other (other);
8758 break;
5e2b0d47
NC
8759 default:
8760 break;
8761 }
8762
8763 if (result)
8764 return result;
8765
8766 snprintf (buff, sizeof buff, _("<other>: %x"), other);
8767 return buff;
8768}
8769
d1133906 8770static const char *
d3ba0551 8771get_symbol_index_type (unsigned int type)
252b5132 8772{
b34976b6 8773 static char buff[32];
5cf1065c 8774
252b5132
RH
8775 switch (type)
8776 {
b34976b6
AM
8777 case SHN_UNDEF: return "UND";
8778 case SHN_ABS: return "ABS";
8779 case SHN_COMMON: return "COM";
252b5132 8780 default:
9ce701e2
L
8781 if (type == SHN_IA_64_ANSI_COMMON
8782 && elf_header.e_machine == EM_IA_64
8783 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
8784 return "ANSI_COM";
8a9036a4
L
8785 else if ((elf_header.e_machine == EM_X86_64
8786 || elf_header.e_machine == EM_L1OM)
3b22753a
L
8787 && type == SHN_X86_64_LCOMMON)
8788 return "LARGE_COM";
ac145307
BS
8789 else if ((type == SHN_MIPS_SCOMMON
8790 && elf_header.e_machine == EM_MIPS)
8791 || (type == SHN_TIC6X_SCOMMON
8792 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
8793 return "SCOM";
8794 else if (type == SHN_MIPS_SUNDEFINED
8795 && elf_header.e_machine == EM_MIPS)
8796 return "SUND";
9ce701e2 8797 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 8798 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 8799 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
8800 sprintf (buff, "OS [0x%04x]", type & 0xffff);
8801 else if (type >= SHN_LORESERVE)
8802 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 8803 else
232e7cb8 8804 sprintf (buff, "%3d", type);
5cf1065c 8805 break;
252b5132 8806 }
5cf1065c
NC
8807
8808 return buff;
252b5132
RH
8809}
8810
66543521 8811static bfd_vma *
2cf0635d 8812get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 8813{
2cf0635d
NC
8814 unsigned char * e_data;
8815 bfd_vma * i_data;
252b5132 8816
3f5e193b 8817 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
8818
8819 if (e_data == NULL)
8820 {
8821 error (_("Out of memory\n"));
8822 return NULL;
8823 }
8824
66543521 8825 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
8826 {
8827 error (_("Unable to read in dynamic data\n"));
8828 return NULL;
8829 }
8830
3f5e193b 8831 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
8832
8833 if (i_data == NULL)
8834 {
8835 error (_("Out of memory\n"));
8836 free (e_data);
8837 return NULL;
8838 }
8839
8840 while (number--)
66543521 8841 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
8842
8843 free (e_data);
8844
8845 return i_data;
8846}
8847
6bd1a22c
L
8848static void
8849print_dynamic_symbol (bfd_vma si, unsigned long hn)
8850{
2cf0635d 8851 Elf_Internal_Sym * psym;
6bd1a22c
L
8852 int n;
8853
8854 psym = dynamic_symbols + si;
8855
8856 n = print_vma (si, DEC_5);
8857 if (n < 5)
8858 fputs (" " + n, stdout);
8859 printf (" %3lu: ", hn);
8860 print_vma (psym->st_value, LONG_HEX);
8861 putchar (' ');
8862 print_vma (psym->st_size, DEC_5);
8863
f4be36b3
AM
8864 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8865 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
8866 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
8867 /* Check to see if any other bits in the st_other field are set.
8868 Note - displaying this information disrupts the layout of the
8869 table being generated, but for the moment this case is very
8870 rare. */
8871 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8872 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
8873 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
8874 if (VALID_DYNAMIC_NAME (psym->st_name))
8875 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
8876 else
2b692964 8877 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
8878 putchar ('\n');
8879}
8880
e3c8793a 8881/* Dump the symbol table. */
252b5132 8882static int
2cf0635d 8883process_symbol_table (FILE * file)
252b5132 8884{
2cf0635d 8885 Elf_Internal_Shdr * section;
66543521
AM
8886 bfd_vma nbuckets = 0;
8887 bfd_vma nchains = 0;
2cf0635d
NC
8888 bfd_vma * buckets = NULL;
8889 bfd_vma * chains = NULL;
fdc90cb4 8890 bfd_vma ngnubuckets = 0;
2cf0635d
NC
8891 bfd_vma * gnubuckets = NULL;
8892 bfd_vma * gnuchains = NULL;
6bd1a22c 8893 bfd_vma gnusymidx = 0;
252b5132 8894
2c610e4b 8895 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
8896 return 1;
8897
6bd1a22c
L
8898 if (dynamic_info[DT_HASH]
8899 && (do_histogram
2c610e4b
L
8900 || (do_using_dynamic
8901 && !do_dyn_syms
8902 && dynamic_strings != NULL)))
252b5132 8903 {
66543521
AM
8904 unsigned char nb[8];
8905 unsigned char nc[8];
8906 int hash_ent_size = 4;
8907
8908 if ((elf_header.e_machine == EM_ALPHA
8909 || elf_header.e_machine == EM_S390
8910 || elf_header.e_machine == EM_S390_OLD)
8911 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
8912 hash_ent_size = 8;
8913
fb52b2f4
NC
8914 if (fseek (file,
8915 (archive_file_offset
8916 + offset_from_vma (file, dynamic_info[DT_HASH],
8917 sizeof nb + sizeof nc)),
d93f0186 8918 SEEK_SET))
252b5132 8919 {
591a748a 8920 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8921 goto no_hash;
252b5132
RH
8922 }
8923
66543521 8924 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
8925 {
8926 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8927 goto no_hash;
252b5132
RH
8928 }
8929
66543521 8930 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
8931 {
8932 error (_("Failed to read in number of chains\n"));
d3a44ec6 8933 goto no_hash;
252b5132
RH
8934 }
8935
66543521
AM
8936 nbuckets = byte_get (nb, hash_ent_size);
8937 nchains = byte_get (nc, hash_ent_size);
252b5132 8938
66543521
AM
8939 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
8940 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 8941
d3a44ec6 8942 no_hash:
252b5132 8943 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
8944 {
8945 if (do_using_dynamic)
8946 return 0;
8947 free (buckets);
8948 free (chains);
8949 buckets = NULL;
8950 chains = NULL;
8951 nbuckets = 0;
8952 nchains = 0;
8953 }
252b5132
RH
8954 }
8955
6bd1a22c
L
8956 if (dynamic_info_DT_GNU_HASH
8957 && (do_histogram
2c610e4b
L
8958 || (do_using_dynamic
8959 && !do_dyn_syms
8960 && dynamic_strings != NULL)))
252b5132 8961 {
6bd1a22c
L
8962 unsigned char nb[16];
8963 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
8964 bfd_vma buckets_vma;
8965
8966 if (fseek (file,
8967 (archive_file_offset
8968 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
8969 sizeof nb)),
8970 SEEK_SET))
8971 {
8972 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8973 goto no_gnu_hash;
6bd1a22c 8974 }
252b5132 8975
6bd1a22c
L
8976 if (fread (nb, 16, 1, file) != 1)
8977 {
8978 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8979 goto no_gnu_hash;
6bd1a22c
L
8980 }
8981
8982 ngnubuckets = byte_get (nb, 4);
8983 gnusymidx = byte_get (nb + 4, 4);
8984 bitmaskwords = byte_get (nb + 8, 4);
8985 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 8986 if (is_32bit_elf)
6bd1a22c 8987 buckets_vma += bitmaskwords * 4;
f7a99963 8988 else
6bd1a22c 8989 buckets_vma += bitmaskwords * 8;
252b5132 8990
6bd1a22c
L
8991 if (fseek (file,
8992 (archive_file_offset
8993 + offset_from_vma (file, buckets_vma, 4)),
8994 SEEK_SET))
252b5132 8995 {
6bd1a22c 8996 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8997 goto no_gnu_hash;
6bd1a22c
L
8998 }
8999
9000 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9001
6bd1a22c 9002 if (gnubuckets == NULL)
d3a44ec6 9003 goto no_gnu_hash;
6bd1a22c
L
9004
9005 for (i = 0; i < ngnubuckets; i++)
9006 if (gnubuckets[i] != 0)
9007 {
9008 if (gnubuckets[i] < gnusymidx)
9009 return 0;
9010
9011 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9012 maxchain = gnubuckets[i];
9013 }
9014
9015 if (maxchain == 0xffffffff)
d3a44ec6 9016 goto no_gnu_hash;
6bd1a22c
L
9017
9018 maxchain -= gnusymidx;
9019
9020 if (fseek (file,
9021 (archive_file_offset
9022 + offset_from_vma (file, buckets_vma
9023 + 4 * (ngnubuckets + maxchain), 4)),
9024 SEEK_SET))
9025 {
9026 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9027 goto no_gnu_hash;
6bd1a22c
L
9028 }
9029
9030 do
9031 {
9032 if (fread (nb, 4, 1, file) != 1)
252b5132 9033 {
6bd1a22c 9034 error (_("Failed to determine last chain length\n"));
d3a44ec6 9035 goto no_gnu_hash;
6bd1a22c 9036 }
252b5132 9037
6bd1a22c 9038 if (maxchain + 1 == 0)
d3a44ec6 9039 goto no_gnu_hash;
252b5132 9040
6bd1a22c
L
9041 ++maxchain;
9042 }
9043 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9044
6bd1a22c
L
9045 if (fseek (file,
9046 (archive_file_offset
9047 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9048 SEEK_SET))
9049 {
9050 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9051 goto no_gnu_hash;
6bd1a22c
L
9052 }
9053
9054 gnuchains = get_dynamic_data (file, maxchain, 4);
9055
d3a44ec6 9056 no_gnu_hash:
6bd1a22c 9057 if (gnuchains == NULL)
d3a44ec6
JJ
9058 {
9059 free (gnubuckets);
d3a44ec6
JJ
9060 gnubuckets = NULL;
9061 ngnubuckets = 0;
f64fddf1
NC
9062 if (do_using_dynamic)
9063 return 0;
d3a44ec6 9064 }
6bd1a22c
L
9065 }
9066
9067 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9068 && do_syms
9069 && do_using_dynamic
9070 && dynamic_strings != NULL)
9071 {
9072 unsigned long hn;
9073
9074 if (dynamic_info[DT_HASH])
9075 {
9076 bfd_vma si;
9077
9078 printf (_("\nSymbol table for image:\n"));
9079 if (is_32bit_elf)
9080 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9081 else
9082 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9083
9084 for (hn = 0; hn < nbuckets; hn++)
9085 {
9086 if (! buckets[hn])
9087 continue;
9088
9089 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9090 print_dynamic_symbol (si, hn);
252b5132
RH
9091 }
9092 }
6bd1a22c
L
9093
9094 if (dynamic_info_DT_GNU_HASH)
9095 {
9096 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9097 if (is_32bit_elf)
9098 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9099 else
9100 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9101
9102 for (hn = 0; hn < ngnubuckets; ++hn)
9103 if (gnubuckets[hn] != 0)
9104 {
9105 bfd_vma si = gnubuckets[hn];
9106 bfd_vma off = si - gnusymidx;
9107
9108 do
9109 {
9110 print_dynamic_symbol (si, hn);
9111 si++;
9112 }
9113 while ((gnuchains[off++] & 1) == 0);
9114 }
9115 }
252b5132 9116 }
2c610e4b 9117 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9118 {
b34976b6 9119 unsigned int i;
252b5132
RH
9120
9121 for (i = 0, section = section_headers;
9122 i < elf_header.e_shnum;
9123 i++, section++)
9124 {
b34976b6 9125 unsigned int si;
2cf0635d 9126 char * strtab = NULL;
c256ffe7 9127 unsigned long int strtab_size = 0;
2cf0635d
NC
9128 Elf_Internal_Sym * symtab;
9129 Elf_Internal_Sym * psym;
252b5132 9130
2c610e4b
L
9131 if ((section->sh_type != SHT_SYMTAB
9132 && section->sh_type != SHT_DYNSYM)
9133 || (!do_syms
9134 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9135 continue;
9136
dd24e3da
NC
9137 if (section->sh_entsize == 0)
9138 {
9139 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9140 SECTION_NAME (section));
9141 continue;
9142 }
9143
252b5132
RH
9144 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9145 SECTION_NAME (section),
9146 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9147
f7a99963 9148 if (is_32bit_elf)
ca47b30c 9149 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9150 else
ca47b30c 9151 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9152
9ad5cbcf 9153 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
9154 if (symtab == NULL)
9155 continue;
9156
9157 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9158 {
9159 strtab = string_table;
9160 strtab_size = string_table_length;
9161 }
4fbb74a6 9162 else if (section->sh_link < elf_header.e_shnum)
252b5132 9163 {
2cf0635d 9164 Elf_Internal_Shdr * string_sec;
252b5132 9165
4fbb74a6 9166 string_sec = section_headers + section->sh_link;
252b5132 9167
3f5e193b
NC
9168 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9169 1, string_sec->sh_size,
9170 _("string table"));
c256ffe7 9171 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9172 }
9173
9174 for (si = 0, psym = symtab;
9175 si < section->sh_size / section->sh_entsize;
b34976b6 9176 si++, psym++)
252b5132 9177 {
5e220199 9178 printf ("%6d: ", si);
f7a99963
NC
9179 print_vma (psym->st_value, LONG_HEX);
9180 putchar (' ');
9181 print_vma (psym->st_size, DEC_5);
d1133906
NC
9182 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9183 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9184 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9185 /* Check to see if any other bits in the st_other field are set.
9186 Note - displaying this information disrupts the layout of the
9187 table being generated, but for the moment this case is very rare. */
9188 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9189 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9190 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9191 print_symbol (25, psym->st_name < strtab_size
2b692964 9192 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9193
59245841
NC
9194 if (section->sh_type == SHT_DYNSYM
9195 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9196 {
b34976b6
AM
9197 unsigned char data[2];
9198 unsigned short vers_data;
9199 unsigned long offset;
9200 int is_nobits;
9201 int check_def;
252b5132 9202
d93f0186
NC
9203 offset = offset_from_vma
9204 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9205 sizeof data + si * sizeof (vers_data));
252b5132 9206
59245841
NC
9207 if (get_data (&data, file, offset + si * sizeof (vers_data),
9208 sizeof (data), 1, _("version data")) == NULL)
9209 break;
252b5132
RH
9210
9211 vers_data = byte_get (data, 2);
9212
4fbb74a6
AM
9213 is_nobits = (psym->st_shndx < elf_header.e_shnum
9214 && section_headers[psym->st_shndx].sh_type
c256ffe7 9215 == SHT_NOBITS);
252b5132
RH
9216
9217 check_def = (psym->st_shndx != SHN_UNDEF);
9218
c244d050 9219 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9220 {
b34976b6 9221 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9222 && (is_nobits || ! check_def))
252b5132 9223 {
b34976b6
AM
9224 Elf_External_Verneed evn;
9225 Elf_Internal_Verneed ivn;
9226 Elf_Internal_Vernaux ivna;
252b5132
RH
9227
9228 /* We must test both. */
d93f0186
NC
9229 offset = offset_from_vma
9230 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9231 sizeof evn);
252b5132 9232
252b5132
RH
9233 do
9234 {
b34976b6 9235 unsigned long vna_off;
252b5132 9236
59245841
NC
9237 if (get_data (&evn, file, offset, sizeof (evn), 1,
9238 _("version need")) == NULL)
9239 {
9240 ivna.vna_next = 0;
9241 ivna.vna_other = 0;
9242 ivna.vna_name = 0;
9243 break;
9244 }
dd27201e
L
9245
9246 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9247 ivn.vn_next = BYTE_GET (evn.vn_next);
9248
252b5132
RH
9249 vna_off = offset + ivn.vn_aux;
9250
9251 do
9252 {
b34976b6 9253 Elf_External_Vernaux evna;
252b5132 9254
59245841
NC
9255 if (get_data (&evna, file, vna_off,
9256 sizeof (evna), 1,
9257 _("version need aux (3)")) == NULL)
9258 {
9259 ivna.vna_next = 0;
9260 ivna.vna_other = 0;
9261 ivna.vna_name = 0;
9262 }
9263 else
9264 {
9265 ivna.vna_other = BYTE_GET (evna.vna_other);
9266 ivna.vna_next = BYTE_GET (evna.vna_next);
9267 ivna.vna_name = BYTE_GET (evna.vna_name);
9268 }
252b5132
RH
9269
9270 vna_off += ivna.vna_next;
9271 }
9272 while (ivna.vna_other != vers_data
9273 && ivna.vna_next != 0);
9274
9275 if (ivna.vna_other == vers_data)
9276 break;
9277
9278 offset += ivn.vn_next;
9279 }
9280 while (ivn.vn_next != 0);
9281
9282 if (ivna.vna_other == vers_data)
9283 {
9284 printf ("@%s (%d)",
c256ffe7 9285 ivna.vna_name < strtab_size
2b692964 9286 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9287 ivna.vna_other);
252b5132
RH
9288 check_def = 0;
9289 }
9290 else if (! is_nobits)
591a748a 9291 error (_("bad dynamic symbol\n"));
252b5132
RH
9292 else
9293 check_def = 1;
9294 }
9295
9296 if (check_def)
9297 {
00d93f34 9298 if (vers_data != 0x8001
b34976b6 9299 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9300 {
b34976b6
AM
9301 Elf_Internal_Verdef ivd;
9302 Elf_Internal_Verdaux ivda;
9303 Elf_External_Verdaux evda;
91d6fa6a 9304 unsigned long off;
252b5132 9305
91d6fa6a 9306 off = offset_from_vma
d93f0186
NC
9307 (file,
9308 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9309 sizeof (Elf_External_Verdef));
252b5132
RH
9310
9311 do
9312 {
b34976b6 9313 Elf_External_Verdef evd;
252b5132 9314
59245841
NC
9315 if (get_data (&evd, file, off, sizeof (evd),
9316 1, _("version def")) == NULL)
9317 {
9318 ivd.vd_ndx = 0;
9319 ivd.vd_aux = 0;
9320 ivd.vd_next = 0;
9321 }
9322 else
9323 {
9324 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9325 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9326 ivd.vd_next = BYTE_GET (evd.vd_next);
9327 }
252b5132 9328
91d6fa6a 9329 off += ivd.vd_next;
252b5132 9330 }
c244d050 9331 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9332 && ivd.vd_next != 0);
9333
91d6fa6a
NC
9334 off -= ivd.vd_next;
9335 off += ivd.vd_aux;
252b5132 9336
59245841
NC
9337 if (get_data (&evda, file, off, sizeof (evda),
9338 1, _("version def aux")) == NULL)
9339 break;
252b5132
RH
9340
9341 ivda.vda_name = BYTE_GET (evda.vda_name);
9342
9343 if (psym->st_name != ivda.vda_name)
c244d050 9344 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9345 ? "@%s" : "@@%s",
c256ffe7 9346 ivda.vda_name < strtab_size
2b692964 9347 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9348 }
9349 }
9350 }
9351 }
9352
9353 putchar ('\n');
9354 }
9355
9356 free (symtab);
9357 if (strtab != string_table)
9358 free (strtab);
9359 }
9360 }
9361 else if (do_syms)
9362 printf
9363 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9364
9365 if (do_histogram && buckets != NULL)
9366 {
2cf0635d
NC
9367 unsigned long * lengths;
9368 unsigned long * counts;
66543521
AM
9369 unsigned long hn;
9370 bfd_vma si;
9371 unsigned long maxlength = 0;
9372 unsigned long nzero_counts = 0;
9373 unsigned long nsyms = 0;
252b5132 9374
66543521
AM
9375 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9376 (unsigned long) nbuckets);
252b5132
RH
9377 printf (_(" Length Number %% of total Coverage\n"));
9378
3f5e193b 9379 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9380 if (lengths == NULL)
9381 {
591a748a 9382 error (_("Out of memory\n"));
252b5132
RH
9383 return 0;
9384 }
9385 for (hn = 0; hn < nbuckets; ++hn)
9386 {
f7a99963 9387 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9388 {
b34976b6 9389 ++nsyms;
252b5132 9390 if (maxlength < ++lengths[hn])
b34976b6 9391 ++maxlength;
252b5132
RH
9392 }
9393 }
9394
3f5e193b 9395 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9396 if (counts == NULL)
9397 {
591a748a 9398 error (_("Out of memory\n"));
252b5132
RH
9399 return 0;
9400 }
9401
9402 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9403 ++counts[lengths[hn]];
252b5132 9404
103f02d3 9405 if (nbuckets > 0)
252b5132 9406 {
66543521
AM
9407 unsigned long i;
9408 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9409 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9410 for (i = 1; i <= maxlength; ++i)
103f02d3 9411 {
66543521
AM
9412 nzero_counts += counts[i] * i;
9413 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9414 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9415 (nzero_counts * 100.0) / nsyms);
9416 }
252b5132
RH
9417 }
9418
9419 free (counts);
9420 free (lengths);
9421 }
9422
9423 if (buckets != NULL)
9424 {
9425 free (buckets);
9426 free (chains);
9427 }
9428
d3a44ec6 9429 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9430 {
2cf0635d
NC
9431 unsigned long * lengths;
9432 unsigned long * counts;
fdc90cb4
JJ
9433 unsigned long hn;
9434 unsigned long maxlength = 0;
9435 unsigned long nzero_counts = 0;
9436 unsigned long nsyms = 0;
fdc90cb4 9437
3f5e193b 9438 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9439 if (lengths == NULL)
9440 {
591a748a 9441 error (_("Out of memory\n"));
fdc90cb4
JJ
9442 return 0;
9443 }
9444
9445 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9446 (unsigned long) ngnubuckets);
9447 printf (_(" Length Number %% of total Coverage\n"));
9448
9449 for (hn = 0; hn < ngnubuckets; ++hn)
9450 if (gnubuckets[hn] != 0)
9451 {
9452 bfd_vma off, length = 1;
9453
6bd1a22c 9454 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9455 (gnuchains[off] & 1) == 0; ++off)
9456 ++length;
9457 lengths[hn] = length;
9458 if (length > maxlength)
9459 maxlength = length;
9460 nsyms += length;
9461 }
9462
3f5e193b 9463 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9464 if (counts == NULL)
9465 {
591a748a 9466 error (_("Out of memory\n"));
fdc90cb4
JJ
9467 return 0;
9468 }
9469
9470 for (hn = 0; hn < ngnubuckets; ++hn)
9471 ++counts[lengths[hn]];
9472
9473 if (ngnubuckets > 0)
9474 {
9475 unsigned long j;
9476 printf (" 0 %-10lu (%5.1f%%)\n",
9477 counts[0], (counts[0] * 100.0) / ngnubuckets);
9478 for (j = 1; j <= maxlength; ++j)
9479 {
9480 nzero_counts += counts[j] * j;
9481 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9482 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9483 (nzero_counts * 100.0) / nsyms);
9484 }
9485 }
9486
9487 free (counts);
9488 free (lengths);
9489 free (gnubuckets);
9490 free (gnuchains);
9491 }
9492
252b5132
RH
9493 return 1;
9494}
9495
9496static int
2cf0635d 9497process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9498{
b4c96d0d 9499 unsigned int i;
252b5132
RH
9500
9501 if (dynamic_syminfo == NULL
9502 || !do_dynamic)
9503 /* No syminfo, this is ok. */
9504 return 1;
9505
9506 /* There better should be a dynamic symbol section. */
9507 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9508 return 0;
9509
9510 if (dynamic_addr)
9511 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9512 dynamic_syminfo_offset, dynamic_syminfo_nent);
9513
9514 printf (_(" Num: Name BoundTo Flags\n"));
9515 for (i = 0; i < dynamic_syminfo_nent; ++i)
9516 {
9517 unsigned short int flags = dynamic_syminfo[i].si_flags;
9518
31104126 9519 printf ("%4d: ", i);
d79b3d50
NC
9520 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9521 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9522 else
2b692964 9523 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9524 putchar (' ');
252b5132
RH
9525
9526 switch (dynamic_syminfo[i].si_boundto)
9527 {
9528 case SYMINFO_BT_SELF:
9529 fputs ("SELF ", stdout);
9530 break;
9531 case SYMINFO_BT_PARENT:
9532 fputs ("PARENT ", stdout);
9533 break;
9534 default:
9535 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9536 && dynamic_syminfo[i].si_boundto < dynamic_nent
9537 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9538 {
d79b3d50 9539 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9540 putchar (' ' );
9541 }
252b5132
RH
9542 else
9543 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9544 break;
9545 }
9546
9547 if (flags & SYMINFO_FLG_DIRECT)
9548 printf (" DIRECT");
9549 if (flags & SYMINFO_FLG_PASSTHRU)
9550 printf (" PASSTHRU");
9551 if (flags & SYMINFO_FLG_COPY)
9552 printf (" COPY");
9553 if (flags & SYMINFO_FLG_LAZYLOAD)
9554 printf (" LAZYLOAD");
9555
9556 puts ("");
9557 }
9558
9559 return 1;
9560}
9561
cf13d699
NC
9562/* Check to see if the given reloc needs to be handled in a target specific
9563 manner. If so then process the reloc and return TRUE otherwise return
9564 FALSE. */
09c11c86 9565
cf13d699
NC
9566static bfd_boolean
9567target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9568 unsigned char * start,
9569 Elf_Internal_Sym * symtab)
252b5132 9570{
cf13d699 9571 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9572
cf13d699 9573 switch (elf_header.e_machine)
252b5132 9574 {
cf13d699
NC
9575 case EM_MN10300:
9576 case EM_CYGNUS_MN10300:
9577 {
9578 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9579
cf13d699
NC
9580 switch (reloc_type)
9581 {
9582 case 34: /* R_MN10300_ALIGN */
9583 return TRUE;
9584 case 33: /* R_MN10300_SYM_DIFF */
9585 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9586 return TRUE;
9587 case 1: /* R_MN10300_32 */
9588 case 2: /* R_MN10300_16 */
9589 if (saved_sym != NULL)
9590 {
9591 bfd_vma value;
252b5132 9592
cf13d699
NC
9593 value = reloc->r_addend
9594 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9595 - saved_sym->st_value);
252b5132 9596
cf13d699 9597 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9598
cf13d699
NC
9599 saved_sym = NULL;
9600 return TRUE;
9601 }
9602 break;
9603 default:
9604 if (saved_sym != NULL)
9605 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9606 break;
9607 }
9608 break;
9609 }
252b5132
RH
9610 }
9611
cf13d699 9612 return FALSE;
252b5132
RH
9613}
9614
aca88567
NC
9615/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9616 DWARF debug sections. This is a target specific test. Note - we do not
9617 go through the whole including-target-headers-multiple-times route, (as
9618 we have already done with <elf/h8.h>) because this would become very
9619 messy and even then this function would have to contain target specific
9620 information (the names of the relocs instead of their numeric values).
9621 FIXME: This is not the correct way to solve this problem. The proper way
9622 is to have target specific reloc sizing and typing functions created by
9623 the reloc-macros.h header, in the same way that it already creates the
9624 reloc naming functions. */
9625
9626static bfd_boolean
9627is_32bit_abs_reloc (unsigned int reloc_type)
9628{
9629 switch (elf_header.e_machine)
9630 {
41e92641
NC
9631 case EM_386:
9632 case EM_486:
9633 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9634 case EM_68K:
9635 return reloc_type == 1; /* R_68K_32. */
9636 case EM_860:
9637 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9638 case EM_960:
9639 return reloc_type == 2; /* R_960_32. */
aca88567 9640 case EM_ALPHA:
137b6b5f 9641 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
9642 case EM_ARC:
9643 return reloc_type == 1; /* R_ARC_32. */
9644 case EM_ARM:
9645 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 9646 case EM_AVR_OLD:
aca88567
NC
9647 case EM_AVR:
9648 return reloc_type == 1;
9649 case EM_BLACKFIN:
9650 return reloc_type == 0x12; /* R_byte4_data. */
9651 case EM_CRIS:
9652 return reloc_type == 3; /* R_CRIS_32. */
9653 case EM_CR16:
6c03b1ed 9654 case EM_CR16_OLD:
aca88567
NC
9655 return reloc_type == 3; /* R_CR16_NUM32. */
9656 case EM_CRX:
9657 return reloc_type == 15; /* R_CRX_NUM32. */
9658 case EM_CYGNUS_FRV:
9659 return reloc_type == 1;
41e92641
NC
9660 case EM_CYGNUS_D10V:
9661 case EM_D10V:
9662 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
9663 case EM_CYGNUS_D30V:
9664 case EM_D30V:
9665 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
9666 case EM_DLX:
9667 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
9668 case EM_CYGNUS_FR30:
9669 case EM_FR30:
9670 return reloc_type == 3; /* R_FR30_32. */
9671 case EM_H8S:
9672 case EM_H8_300:
9673 case EM_H8_300H:
9674 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
9675 case EM_IA_64:
9676 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
9677 case EM_IP2K_OLD:
9678 case EM_IP2K:
9679 return reloc_type == 2; /* R_IP2K_32. */
9680 case EM_IQ2000:
9681 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
9682 case EM_LATTICEMICO32:
9683 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 9684 case EM_M32C_OLD:
aca88567
NC
9685 case EM_M32C:
9686 return reloc_type == 3; /* R_M32C_32. */
9687 case EM_M32R:
9688 return reloc_type == 34; /* R_M32R_32_RELA. */
9689 case EM_MCORE:
9690 return reloc_type == 1; /* R_MCORE_ADDR32. */
9691 case EM_CYGNUS_MEP:
9692 return reloc_type == 4; /* R_MEP_32. */
137b6b5f
AM
9693 case EM_MICROBLAZE:
9694 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
9695 case EM_MIPS:
9696 return reloc_type == 2; /* R_MIPS_32. */
9697 case EM_MMIX:
9698 return reloc_type == 4; /* R_MMIX_32. */
9699 case EM_CYGNUS_MN10200:
9700 case EM_MN10200:
9701 return reloc_type == 1; /* R_MN10200_32. */
9702 case EM_CYGNUS_MN10300:
9703 case EM_MN10300:
9704 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
9705 case EM_MOXIE:
9706 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
9707 case EM_MSP430_OLD:
9708 case EM_MSP430:
9709 return reloc_type == 1; /* R_MSP43_32. */
9710 case EM_MT:
9711 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
9712 case EM_ALTERA_NIOS2:
9713 case EM_NIOS32:
9714 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
9715 case EM_OPENRISC:
9716 case EM_OR32:
9717 return reloc_type == 1; /* R_OR32_32. */
aca88567 9718 case EM_PARISC:
5fda8eca
NC
9719 return (reloc_type == 1 /* R_PARISC_DIR32. */
9720 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
9721 case EM_PJ:
9722 case EM_PJ_OLD:
9723 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
9724 case EM_PPC64:
9725 return reloc_type == 1; /* R_PPC64_ADDR32. */
9726 case EM_PPC:
9727 return reloc_type == 1; /* R_PPC_ADDR32. */
c7927a3c
NC
9728 case EM_RX:
9729 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
9730 case EM_S370:
9731 return reloc_type == 1; /* R_I370_ADDR31. */
9732 case EM_S390_OLD:
9733 case EM_S390:
9734 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
9735 case EM_SCORE:
9736 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
9737 case EM_SH:
9738 return reloc_type == 1; /* R_SH_DIR32. */
9739 case EM_SPARC32PLUS:
9740 case EM_SPARCV9:
9741 case EM_SPARC:
9742 return reloc_type == 3 /* R_SPARC_32. */
9743 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
9744 case EM_SPU:
9745 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
9746 case EM_TI_C6000:
9747 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
9748 case EM_TILEGX:
9749 return reloc_type == 2; /* R_TILEGX_32. */
9750 case EM_TILEPRO:
9751 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
9752 case EM_CYGNUS_V850:
9753 case EM_V850:
9754 return reloc_type == 6; /* R_V850_ABS32. */
9755 case EM_VAX:
9756 return reloc_type == 1; /* R_VAX_32. */
9757 case EM_X86_64:
8a9036a4 9758 case EM_L1OM:
aca88567 9759 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
9760 case EM_XC16X:
9761 case EM_C166:
9762 return reloc_type == 3; /* R_XC16C_ABS_32. */
aca88567
NC
9763 case EM_XSTORMY16:
9764 return reloc_type == 1; /* R_XSTROMY16_32. */
9765 case EM_XTENSA_OLD:
9766 case EM_XTENSA:
9767 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
9768 default:
9769 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
9770 elf_header.e_machine);
9771 abort ();
9772 }
9773}
9774
9775/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9776 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
9777
9778static bfd_boolean
9779is_32bit_pcrel_reloc (unsigned int reloc_type)
9780{
9781 switch (elf_header.e_machine)
9782 {
41e92641
NC
9783 case EM_386:
9784 case EM_486:
3e0873ac 9785 return reloc_type == 2; /* R_386_PC32. */
aca88567 9786 case EM_68K:
3e0873ac 9787 return reloc_type == 4; /* R_68K_PC32. */
aca88567
NC
9788 case EM_ALPHA:
9789 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 9790 case EM_ARM:
3e0873ac 9791 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
9792 case EM_MICROBLAZE:
9793 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 9794 case EM_PARISC:
85acf597 9795 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
9796 case EM_PPC:
9797 return reloc_type == 26; /* R_PPC_REL32. */
9798 case EM_PPC64:
3e0873ac 9799 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
9800 case EM_S390_OLD:
9801 case EM_S390:
3e0873ac 9802 return reloc_type == 5; /* R_390_PC32. */
aca88567 9803 case EM_SH:
3e0873ac 9804 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
9805 case EM_SPARC32PLUS:
9806 case EM_SPARCV9:
9807 case EM_SPARC:
3e0873ac 9808 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
9809 case EM_SPU:
9810 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
9811 case EM_TILEGX:
9812 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
9813 case EM_TILEPRO:
9814 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 9815 case EM_X86_64:
8a9036a4 9816 case EM_L1OM:
3e0873ac 9817 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
9818 case EM_XTENSA_OLD:
9819 case EM_XTENSA:
9820 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
9821 default:
9822 /* Do not abort or issue an error message here. Not all targets use
9823 pc-relative 32-bit relocs in their DWARF debug information and we
9824 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
9825 more helpful warning message will be generated by apply_relocations
9826 anyway, so just return. */
aca88567
NC
9827 return FALSE;
9828 }
9829}
9830
9831/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9832 a 64-bit absolute RELA relocation used in DWARF debug sections. */
9833
9834static bfd_boolean
9835is_64bit_abs_reloc (unsigned int reloc_type)
9836{
9837 switch (elf_header.e_machine)
9838 {
9839 case EM_ALPHA:
9840 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
9841 case EM_IA_64:
9842 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
9843 case EM_PARISC:
9844 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
9845 case EM_PPC64:
9846 return reloc_type == 38; /* R_PPC64_ADDR64. */
9847 case EM_SPARC32PLUS:
9848 case EM_SPARCV9:
9849 case EM_SPARC:
9850 return reloc_type == 54; /* R_SPARC_UA64. */
9851 case EM_X86_64:
8a9036a4 9852 case EM_L1OM:
aca88567 9853 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
9854 case EM_S390_OLD:
9855 case EM_S390:
aa137e4d
NC
9856 return reloc_type == 22; /* R_S390_64. */
9857 case EM_TILEGX:
9858 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 9859 case EM_MIPS:
aa137e4d 9860 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
9861 default:
9862 return FALSE;
9863 }
9864}
9865
85acf597
RH
9866/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
9867 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
9868
9869static bfd_boolean
9870is_64bit_pcrel_reloc (unsigned int reloc_type)
9871{
9872 switch (elf_header.e_machine)
9873 {
9874 case EM_ALPHA:
aa137e4d 9875 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 9876 case EM_IA_64:
aa137e4d 9877 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 9878 case EM_PARISC:
aa137e4d 9879 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 9880 case EM_PPC64:
aa137e4d 9881 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
9882 case EM_SPARC32PLUS:
9883 case EM_SPARCV9:
9884 case EM_SPARC:
aa137e4d 9885 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 9886 case EM_X86_64:
8a9036a4 9887 case EM_L1OM:
aa137e4d 9888 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
9889 case EM_S390_OLD:
9890 case EM_S390:
aa137e4d
NC
9891 return reloc_type == 23; /* R_S390_PC64. */
9892 case EM_TILEGX:
9893 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
9894 default:
9895 return FALSE;
9896 }
9897}
9898
4dc3c23d
AM
9899/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9900 a 24-bit absolute RELA relocation used in DWARF debug sections. */
9901
9902static bfd_boolean
9903is_24bit_abs_reloc (unsigned int reloc_type)
9904{
9905 switch (elf_header.e_machine)
9906 {
9907 case EM_CYGNUS_MN10200:
9908 case EM_MN10200:
9909 return reloc_type == 4; /* R_MN10200_24. */
9910 default:
9911 return FALSE;
9912 }
9913}
9914
aca88567
NC
9915/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9916 a 16-bit absolute RELA relocation used in DWARF debug sections. */
9917
9918static bfd_boolean
9919is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
9920{
9921 switch (elf_header.e_machine)
9922 {
aca88567
NC
9923 case EM_AVR_OLD:
9924 case EM_AVR:
9925 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
9926 case EM_CYGNUS_D10V:
9927 case EM_D10V:
9928 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
9929 case EM_H8S:
9930 case EM_H8_300:
9931 case EM_H8_300H:
aca88567
NC
9932 return reloc_type == R_H8_DIR16;
9933 case EM_IP2K_OLD:
9934 case EM_IP2K:
9935 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 9936 case EM_M32C_OLD:
f4236fe4
DD
9937 case EM_M32C:
9938 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
9939 case EM_MSP430_OLD:
9940 case EM_MSP430:
9941 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
9942 case EM_ALTERA_NIOS2:
9943 case EM_NIOS32:
9944 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
9945 case EM_TI_C6000:
9946 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
9947 case EM_XC16X:
9948 case EM_C166:
9949 return reloc_type == 2; /* R_XC16C_ABS_16. */
4b78141a 9950 default:
aca88567 9951 return FALSE;
4b78141a
NC
9952 }
9953}
9954
2a7b2e88
JK
9955/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
9956 relocation entries (possibly formerly used for SHT_GROUP sections). */
9957
9958static bfd_boolean
9959is_none_reloc (unsigned int reloc_type)
9960{
9961 switch (elf_header.e_machine)
9962 {
cb8f3167
NC
9963 case EM_68K: /* R_68K_NONE. */
9964 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
9965 case EM_SPARC32PLUS:
9966 case EM_SPARCV9:
cb8f3167
NC
9967 case EM_SPARC: /* R_SPARC_NONE. */
9968 case EM_MIPS: /* R_MIPS_NONE. */
9969 case EM_PARISC: /* R_PARISC_NONE. */
9970 case EM_ALPHA: /* R_ALPHA_NONE. */
9971 case EM_PPC: /* R_PPC_NONE. */
9972 case EM_PPC64: /* R_PPC64_NONE. */
9973 case EM_ARM: /* R_ARM_NONE. */
9974 case EM_IA_64: /* R_IA64_NONE. */
9975 case EM_SH: /* R_SH_NONE. */
2a7b2e88 9976 case EM_S390_OLD:
cb8f3167
NC
9977 case EM_S390: /* R_390_NONE. */
9978 case EM_CRIS: /* R_CRIS_NONE. */
9979 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 9980 case EM_L1OM: /* R_X86_64_NONE. */
cb8f3167 9981 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 9982 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 9983 case EM_M32R: /* R_M32R_NONE. */
40b36596 9984 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
9985 case EM_TILEGX: /* R_TILEGX_NONE. */
9986 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
9987 case EM_XC16X:
9988 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 9989 return reloc_type == 0;
58332dda
JK
9990 case EM_XTENSA_OLD:
9991 case EM_XTENSA:
4dc3c23d
AM
9992 return (reloc_type == 0 /* R_XTENSA_NONE. */
9993 || reloc_type == 17 /* R_XTENSA_DIFF8. */
9994 || reloc_type == 18 /* R_XTENSA_DIFF16. */
9995 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
9996 }
9997 return FALSE;
9998}
9999
cf13d699
NC
10000/* Apply relocations to a section.
10001 Note: So far support has been added only for those relocations
10002 which can be found in debug sections.
10003 FIXME: Add support for more relocations ? */
1b315056 10004
cf13d699
NC
10005static void
10006apply_relocations (void * file,
10007 Elf_Internal_Shdr * section,
10008 unsigned char * start)
1b315056 10009{
cf13d699
NC
10010 Elf_Internal_Shdr * relsec;
10011 unsigned char * end = start + section->sh_size;
cb8f3167 10012
cf13d699
NC
10013 if (elf_header.e_type != ET_REL)
10014 return;
1b315056 10015
cf13d699 10016 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10017 for (relsec = section_headers;
10018 relsec < section_headers + elf_header.e_shnum;
10019 ++relsec)
252b5132 10020 {
41e92641
NC
10021 bfd_boolean is_rela;
10022 unsigned long num_relocs;
2cf0635d
NC
10023 Elf_Internal_Rela * relocs;
10024 Elf_Internal_Rela * rp;
10025 Elf_Internal_Shdr * symsec;
10026 Elf_Internal_Sym * symtab;
10027 Elf_Internal_Sym * sym;
252b5132 10028
41e92641 10029 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10030 || relsec->sh_info >= elf_header.e_shnum
10031 || section_headers + relsec->sh_info != section
c256ffe7 10032 || relsec->sh_size == 0
4fbb74a6 10033 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10034 continue;
428409d5 10035
41e92641
NC
10036 is_rela = relsec->sh_type == SHT_RELA;
10037
10038 if (is_rela)
10039 {
3f5e193b
NC
10040 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10041 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10042 return;
10043 }
10044 else
10045 {
3f5e193b
NC
10046 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10047 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10048 return;
10049 }
10050
10051 /* SH uses RELA but uses in place value instead of the addend field. */
10052 if (elf_header.e_machine == EM_SH)
10053 is_rela = FALSE;
428409d5 10054
4fbb74a6 10055 symsec = section_headers + relsec->sh_link;
3f5e193b 10056 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
103f02d3 10057
41e92641 10058 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10059 {
41e92641
NC
10060 bfd_vma addend;
10061 unsigned int reloc_type;
10062 unsigned int reloc_size;
91d6fa6a 10063 unsigned char * rloc;
4b78141a 10064
aca88567 10065 reloc_type = get_reloc_type (rp->r_info);
41e92641 10066
98fb390a 10067 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10068 continue;
98fb390a
NC
10069 else if (is_none_reloc (reloc_type))
10070 continue;
10071 else if (is_32bit_abs_reloc (reloc_type)
10072 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10073 reloc_size = 4;
85acf597
RH
10074 else if (is_64bit_abs_reloc (reloc_type)
10075 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10076 reloc_size = 8;
4dc3c23d
AM
10077 else if (is_24bit_abs_reloc (reloc_type))
10078 reloc_size = 3;
aca88567
NC
10079 else if (is_16bit_abs_reloc (reloc_type))
10080 reloc_size = 2;
10081 else
4b78141a 10082 {
41e92641 10083 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10084 reloc_type, SECTION_NAME (section));
4b78141a
NC
10085 continue;
10086 }
103f02d3 10087
91d6fa6a
NC
10088 rloc = start + rp->r_offset;
10089 if ((rloc + reloc_size) > end)
700dd8b7
L
10090 {
10091 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10092 (unsigned long) rp->r_offset,
10093 SECTION_NAME (section));
10094 continue;
10095 }
103f02d3 10096
41e92641
NC
10097 sym = symtab + get_reloc_symindex (rp->r_info);
10098
10099 /* If the reloc has a symbol associated with it,
55f25fc3
L
10100 make sure that it is of an appropriate type.
10101
10102 Relocations against symbols without type can happen.
10103 Gcc -feliminate-dwarf2-dups may generate symbols
10104 without type for debug info.
10105
10106 Icc generates relocations against function symbols
10107 instead of local labels.
10108
10109 Relocations against object symbols can happen, eg when
10110 referencing a global array. For an example of this see
10111 the _clz.o binary in libgcc.a. */
aca88567 10112 if (sym != symtab
55f25fc3 10113 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10114 {
41e92641 10115 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10116 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10117 (long int)(rp - relocs),
41e92641 10118 SECTION_NAME (relsec));
aca88567 10119 continue;
5b18a4bc 10120 }
252b5132 10121
4dc3c23d
AM
10122 addend = 0;
10123 if (is_rela)
10124 addend += rp->r_addend;
c47320c3
AM
10125 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10126 partial_inplace. */
4dc3c23d
AM
10127 if (!is_rela
10128 || (elf_header.e_machine == EM_XTENSA
10129 && reloc_type == 1)
10130 || ((elf_header.e_machine == EM_PJ
10131 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10132 && reloc_type == 1)
10133 || ((elf_header.e_machine == EM_D30V
10134 || elf_header.e_machine == EM_CYGNUS_D30V)
10135 && reloc_type == 12))
91d6fa6a 10136 addend += byte_get (rloc, reloc_size);
cb8f3167 10137
85acf597
RH
10138 if (is_32bit_pcrel_reloc (reloc_type)
10139 || is_64bit_pcrel_reloc (reloc_type))
10140 {
10141 /* On HPPA, all pc-relative relocations are biased by 8. */
10142 if (elf_header.e_machine == EM_PARISC)
10143 addend -= 8;
91d6fa6a 10144 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10145 reloc_size);
10146 }
41e92641 10147 else
91d6fa6a 10148 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10149 }
252b5132 10150
5b18a4bc 10151 free (symtab);
41e92641 10152 free (relocs);
5b18a4bc
NC
10153 break;
10154 }
5b18a4bc 10155}
103f02d3 10156
cf13d699
NC
10157#ifdef SUPPORT_DISASSEMBLY
10158static int
10159disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10160{
10161 printf (_("\nAssembly dump of section %s\n"),
10162 SECTION_NAME (section));
10163
10164 /* XXX -- to be done --- XXX */
10165
10166 return 1;
10167}
10168#endif
10169
10170/* Reads in the contents of SECTION from FILE, returning a pointer
10171 to a malloc'ed buffer or NULL if something went wrong. */
10172
10173static char *
10174get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10175{
10176 bfd_size_type num_bytes;
10177
10178 num_bytes = section->sh_size;
10179
10180 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10181 {
10182 printf (_("\nSection '%s' has no data to dump.\n"),
10183 SECTION_NAME (section));
10184 return NULL;
10185 }
10186
3f5e193b
NC
10187 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10188 _("section contents"));
cf13d699
NC
10189}
10190
dd24e3da 10191
cf13d699
NC
10192static void
10193dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10194{
10195 Elf_Internal_Shdr * relsec;
10196 bfd_size_type num_bytes;
cf13d699
NC
10197 char * data;
10198 char * end;
10199 char * start;
10200 char * name = SECTION_NAME (section);
10201 bfd_boolean some_strings_shown;
10202
10203 start = get_section_contents (section, file);
10204 if (start == NULL)
10205 return;
10206
10207 printf (_("\nString dump of section '%s':\n"), name);
10208
10209 /* If the section being dumped has relocations against it the user might
10210 be expecting these relocations to have been applied. Check for this
10211 case and issue a warning message in order to avoid confusion.
10212 FIXME: Maybe we ought to have an option that dumps a section with
10213 relocs applied ? */
10214 for (relsec = section_headers;
10215 relsec < section_headers + elf_header.e_shnum;
10216 ++relsec)
10217 {
10218 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10219 || relsec->sh_info >= elf_header.e_shnum
10220 || section_headers + relsec->sh_info != section
10221 || relsec->sh_size == 0
10222 || relsec->sh_link >= elf_header.e_shnum)
10223 continue;
10224
10225 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10226 break;
10227 }
10228
10229 num_bytes = section->sh_size;
cf13d699
NC
10230 data = start;
10231 end = start + num_bytes;
10232 some_strings_shown = FALSE;
10233
10234 while (data < end)
10235 {
10236 while (!ISPRINT (* data))
10237 if (++ data >= end)
10238 break;
10239
10240 if (data < end)
10241 {
10242#ifndef __MSVCRT__
c975cc98
NC
10243 /* PR 11128: Use two separate invocations in order to work
10244 around bugs in the Solaris 8 implementation of printf. */
10245 printf (" [%6tx] ", data - start);
10246 printf ("%s\n", data);
cf13d699
NC
10247#else
10248 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10249#endif
10250 data += strlen (data);
10251 some_strings_shown = TRUE;
10252 }
10253 }
10254
10255 if (! some_strings_shown)
10256 printf (_(" No strings found in this section."));
10257
10258 free (start);
10259
10260 putchar ('\n');
10261}
10262
10263static void
10264dump_section_as_bytes (Elf_Internal_Shdr * section,
10265 FILE * file,
10266 bfd_boolean relocate)
10267{
10268 Elf_Internal_Shdr * relsec;
10269 bfd_size_type bytes;
10270 bfd_vma addr;
10271 unsigned char * data;
10272 unsigned char * start;
10273
10274 start = (unsigned char *) get_section_contents (section, file);
10275 if (start == NULL)
10276 return;
10277
10278 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10279
10280 if (relocate)
10281 {
10282 apply_relocations (file, section, start);
10283 }
10284 else
10285 {
10286 /* If the section being dumped has relocations against it the user might
10287 be expecting these relocations to have been applied. Check for this
10288 case and issue a warning message in order to avoid confusion.
10289 FIXME: Maybe we ought to have an option that dumps a section with
10290 relocs applied ? */
10291 for (relsec = section_headers;
10292 relsec < section_headers + elf_header.e_shnum;
10293 ++relsec)
10294 {
10295 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10296 || relsec->sh_info >= elf_header.e_shnum
10297 || section_headers + relsec->sh_info != section
10298 || relsec->sh_size == 0
10299 || relsec->sh_link >= elf_header.e_shnum)
10300 continue;
10301
10302 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10303 break;
10304 }
10305 }
10306
10307 addr = section->sh_addr;
10308 bytes = section->sh_size;
10309 data = start;
10310
10311 while (bytes)
10312 {
10313 int j;
10314 int k;
10315 int lbytes;
10316
10317 lbytes = (bytes > 16 ? 16 : bytes);
10318
10319 printf (" 0x%8.8lx ", (unsigned long) addr);
10320
10321 for (j = 0; j < 16; j++)
10322 {
10323 if (j < lbytes)
10324 printf ("%2.2x", data[j]);
10325 else
10326 printf (" ");
10327
10328 if ((j & 3) == 3)
10329 printf (" ");
10330 }
10331
10332 for (j = 0; j < lbytes; j++)
10333 {
10334 k = data[j];
10335 if (k >= ' ' && k < 0x7f)
10336 printf ("%c", k);
10337 else
10338 printf (".");
10339 }
10340
10341 putchar ('\n');
10342
10343 data += lbytes;
10344 addr += lbytes;
10345 bytes -= lbytes;
10346 }
10347
10348 free (start);
10349
10350 putchar ('\n');
10351}
10352
4a114e3e 10353/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10354
10355static int
d3dbc530
AM
10356uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10357 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10358{
10359#ifndef HAVE_ZLIB_H
cf13d699
NC
10360 return FALSE;
10361#else
10362 dwarf_size_type compressed_size = *size;
10363 unsigned char * compressed_buffer = *buffer;
10364 dwarf_size_type uncompressed_size;
10365 unsigned char * uncompressed_buffer;
10366 z_stream strm;
10367 int rc;
10368 dwarf_size_type header_size = 12;
10369
10370 /* Read the zlib header. In this case, it should be "ZLIB" followed
10371 by the uncompressed section size, 8 bytes in big-endian order. */
10372 if (compressed_size < header_size
10373 || ! streq ((char *) compressed_buffer, "ZLIB"))
10374 return 0;
10375
10376 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10377 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10378 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10379 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10380 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10381 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10382 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10383 uncompressed_size += compressed_buffer[11];
10384
10385 /* It is possible the section consists of several compressed
10386 buffers concatenated together, so we uncompress in a loop. */
10387 strm.zalloc = NULL;
10388 strm.zfree = NULL;
10389 strm.opaque = NULL;
10390 strm.avail_in = compressed_size - header_size;
10391 strm.next_in = (Bytef *) compressed_buffer + header_size;
10392 strm.avail_out = uncompressed_size;
3f5e193b 10393 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10394
10395 rc = inflateInit (& strm);
10396 while (strm.avail_in > 0)
10397 {
10398 if (rc != Z_OK)
10399 goto fail;
10400 strm.next_out = ((Bytef *) uncompressed_buffer
10401 + (uncompressed_size - strm.avail_out));
10402 rc = inflate (&strm, Z_FINISH);
10403 if (rc != Z_STREAM_END)
10404 goto fail;
10405 rc = inflateReset (& strm);
10406 }
10407 rc = inflateEnd (& strm);
10408 if (rc != Z_OK
10409 || strm.avail_out != 0)
10410 goto fail;
10411
10412 free (compressed_buffer);
10413 *buffer = uncompressed_buffer;
10414 *size = uncompressed_size;
10415 return 1;
10416
10417 fail:
10418 free (uncompressed_buffer);
4a114e3e
L
10419 /* Indicate decompression failure. */
10420 *buffer = NULL;
cf13d699
NC
10421 return 0;
10422#endif /* HAVE_ZLIB_H */
10423}
10424
d966045b
DJ
10425static int
10426load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10427 Elf_Internal_Shdr * sec, void * file)
1007acb3 10428{
2cf0635d 10429 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10430 char buf [64];
1007acb3 10431
19e6b90e
L
10432 /* If it is already loaded, do nothing. */
10433 if (section->start != NULL)
10434 return 1;
1007acb3 10435
19e6b90e
L
10436 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10437 section->address = sec->sh_addr;
3f5e193b
NC
10438 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10439 sec->sh_offset, 1,
10440 sec->sh_size, buf);
59245841
NC
10441 if (section->start == NULL)
10442 section->size = 0;
10443 else
10444 {
10445 section->size = sec->sh_size;
10446 if (uncompress_section_contents (&section->start, &section->size))
10447 sec->sh_size = section->size;
10448 }
4a114e3e 10449
1b315056
CS
10450 if (section->start == NULL)
10451 return 0;
10452
19e6b90e 10453 if (debug_displays [debug].relocate)
3f5e193b 10454 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10455
1b315056 10456 return 1;
1007acb3
L
10457}
10458
d966045b 10459int
2cf0635d 10460load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10461{
2cf0635d
NC
10462 struct dwarf_section * section = &debug_displays [debug].section;
10463 Elf_Internal_Shdr * sec;
d966045b
DJ
10464
10465 /* Locate the debug section. */
10466 sec = find_section (section->uncompressed_name);
10467 if (sec != NULL)
10468 section->name = section->uncompressed_name;
10469 else
10470 {
10471 sec = find_section (section->compressed_name);
10472 if (sec != NULL)
10473 section->name = section->compressed_name;
10474 }
10475 if (sec == NULL)
10476 return 0;
10477
3f5e193b 10478 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10479}
10480
19e6b90e
L
10481void
10482free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10483{
2cf0635d 10484 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10485
19e6b90e
L
10486 if (section->start == NULL)
10487 return;
1007acb3 10488
19e6b90e
L
10489 free ((char *) section->start);
10490 section->start = NULL;
10491 section->address = 0;
10492 section->size = 0;
1007acb3
L
10493}
10494
1007acb3 10495static int
2cf0635d 10496display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 10497{
2cf0635d 10498 char * name = SECTION_NAME (section);
19e6b90e
L
10499 bfd_size_type length;
10500 int result = 1;
3f5e193b 10501 int i;
1007acb3 10502
19e6b90e
L
10503 length = section->sh_size;
10504 if (length == 0)
1007acb3 10505 {
19e6b90e
L
10506 printf (_("\nSection '%s' has no debugging data.\n"), name);
10507 return 0;
1007acb3 10508 }
5dff79d8
NC
10509 if (section->sh_type == SHT_NOBITS)
10510 {
10511 /* There is no point in dumping the contents of a debugging section
10512 which has the NOBITS type - the bits in the file will be random.
10513 This can happen when a file containing a .eh_frame section is
10514 stripped with the --only-keep-debug command line option. */
10515 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10516 return 0;
10517 }
1007acb3 10518
0112cd26 10519 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10520 name = ".debug_info";
1007acb3 10521
19e6b90e
L
10522 /* See if we know how to display the contents of this section. */
10523 for (i = 0; i < max; i++)
1b315056
CS
10524 if (streq (debug_displays[i].section.uncompressed_name, name)
10525 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10526 {
2cf0635d 10527 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10528 int secondary = (section != find_section (name));
10529
10530 if (secondary)
3f5e193b 10531 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10532
2b6f5997 10533 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10534 sec->name = sec->uncompressed_name;
10535 else
10536 sec->name = sec->compressed_name;
3f5e193b
NC
10537 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10538 section, file))
19e6b90e
L
10539 {
10540 result &= debug_displays[i].display (sec, file);
1007acb3 10541
d966045b 10542 if (secondary || (i != info && i != abbrev))
3f5e193b 10543 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10544 }
1007acb3 10545
19e6b90e
L
10546 break;
10547 }
1007acb3 10548
19e6b90e 10549 if (i == max)
1007acb3 10550 {
19e6b90e
L
10551 printf (_("Unrecognized debug section: %s\n"), name);
10552 result = 0;
1007acb3
L
10553 }
10554
19e6b90e 10555 return result;
5b18a4bc 10556}
103f02d3 10557
aef1f6d0
DJ
10558/* Set DUMP_SECTS for all sections where dumps were requested
10559 based on section name. */
10560
10561static void
10562initialise_dumps_byname (void)
10563{
2cf0635d 10564 struct dump_list_entry * cur;
aef1f6d0
DJ
10565
10566 for (cur = dump_sects_byname; cur; cur = cur->next)
10567 {
10568 unsigned int i;
10569 int any;
10570
10571 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10572 if (streq (SECTION_NAME (section_headers + i), cur->name))
10573 {
09c11c86 10574 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10575 any = 1;
10576 }
10577
10578 if (!any)
10579 warn (_("Section '%s' was not dumped because it does not exist!\n"),
10580 cur->name);
10581 }
10582}
10583
5b18a4bc 10584static void
2cf0635d 10585process_section_contents (FILE * file)
5b18a4bc 10586{
2cf0635d 10587 Elf_Internal_Shdr * section;
19e6b90e 10588 unsigned int i;
103f02d3 10589
19e6b90e
L
10590 if (! do_dump)
10591 return;
103f02d3 10592
aef1f6d0
DJ
10593 initialise_dumps_byname ();
10594
19e6b90e
L
10595 for (i = 0, section = section_headers;
10596 i < elf_header.e_shnum && i < num_dump_sects;
10597 i++, section++)
10598 {
10599#ifdef SUPPORT_DISASSEMBLY
10600 if (dump_sects[i] & DISASS_DUMP)
10601 disassemble_section (section, file);
10602#endif
10603 if (dump_sects[i] & HEX_DUMP)
cf13d699 10604 dump_section_as_bytes (section, file, FALSE);
103f02d3 10605
cf13d699
NC
10606 if (dump_sects[i] & RELOC_DUMP)
10607 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
10608
10609 if (dump_sects[i] & STRING_DUMP)
10610 dump_section_as_strings (section, file);
cf13d699
NC
10611
10612 if (dump_sects[i] & DEBUG_DUMP)
10613 display_debug_section (section, file);
5b18a4bc 10614 }
103f02d3 10615
19e6b90e
L
10616 /* Check to see if the user requested a
10617 dump of a section that does not exist. */
10618 while (i++ < num_dump_sects)
10619 if (dump_sects[i])
10620 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 10621}
103f02d3 10622
5b18a4bc 10623static void
19e6b90e 10624process_mips_fpe_exception (int mask)
5b18a4bc 10625{
19e6b90e
L
10626 if (mask)
10627 {
10628 int first = 1;
10629 if (mask & OEX_FPU_INEX)
10630 fputs ("INEX", stdout), first = 0;
10631 if (mask & OEX_FPU_UFLO)
10632 printf ("%sUFLO", first ? "" : "|"), first = 0;
10633 if (mask & OEX_FPU_OFLO)
10634 printf ("%sOFLO", first ? "" : "|"), first = 0;
10635 if (mask & OEX_FPU_DIV0)
10636 printf ("%sDIV0", first ? "" : "|"), first = 0;
10637 if (mask & OEX_FPU_INVAL)
10638 printf ("%sINVAL", first ? "" : "|");
10639 }
5b18a4bc 10640 else
19e6b90e 10641 fputs ("0", stdout);
5b18a4bc 10642}
103f02d3 10643
11c1ff18
PB
10644/* ARM EABI attributes section. */
10645typedef struct
10646{
10647 int tag;
2cf0635d 10648 const char * name;
11c1ff18
PB
10649 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
10650 int type;
2cf0635d 10651 const char ** table;
11c1ff18
PB
10652} arm_attr_public_tag;
10653
2cf0635d 10654static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 10655 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
9e3c6df6 10656 "v6K", "v7", "v6-M", "v6S-M", "v7E-M"};
2cf0635d
NC
10657static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
10658static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 10659 {"No", "Thumb-1", "Thumb-2"};
75375b3e 10660static const char * arm_attr_tag_FP_arch[] =
62f3b8c8 10661 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
2cf0635d 10662static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 10663static const char * arm_attr_tag_Advanced_SIMD_arch[] =
cd21e546 10664 {"No", "NEONv1", "NEONv1 with Fused-MAC"};
2cf0635d 10665static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
10666 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
10667 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 10668static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 10669 {"V6", "SB", "TLS", "Unused"};
2cf0635d 10670static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 10671 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 10672static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 10673 {"Absolute", "PC-relative", "None"};
2cf0635d 10674static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 10675 {"None", "direct", "GOT-indirect"};
2cf0635d 10676static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 10677 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
10678static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
10679static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 10680 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
10681static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
10682static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
10683static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 10684 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 10685static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 10686 {"Unused", "small", "int", "forced to int"};
2cf0635d 10687static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 10688 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 10689static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 10690 {"AAPCS", "VFP registers", "custom"};
2cf0635d 10691static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 10692 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 10693static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
10694 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10695 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 10696static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
10697 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10698 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 10699static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 10700static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 10701 {"Not Allowed", "Allowed"};
2cf0635d 10702static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 10703 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 10704static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
10705 {"Not Allowed", "Allowed"};
10706static const char * arm_attr_tag_DIV_use[] =
dd24e3da 10707 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 10708 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
10709static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
10710static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 10711 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 10712 "TrustZone and Virtualization Extensions"};
dd24e3da 10713static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 10714 {"Not Allowed", "Allowed"};
11c1ff18
PB
10715
10716#define LOOKUP(id, name) \
10717 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 10718static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
10719{
10720 {4, "CPU_raw_name", 1, NULL},
10721 {5, "CPU_name", 1, NULL},
10722 LOOKUP(6, CPU_arch),
10723 {7, "CPU_arch_profile", 0, NULL},
10724 LOOKUP(8, ARM_ISA_use),
10725 LOOKUP(9, THUMB_ISA_use),
75375b3e 10726 LOOKUP(10, FP_arch),
11c1ff18 10727 LOOKUP(11, WMMX_arch),
f5f53991
AS
10728 LOOKUP(12, Advanced_SIMD_arch),
10729 LOOKUP(13, PCS_config),
11c1ff18
PB
10730 LOOKUP(14, ABI_PCS_R9_use),
10731 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 10732 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
10733 LOOKUP(17, ABI_PCS_GOT_use),
10734 LOOKUP(18, ABI_PCS_wchar_t),
10735 LOOKUP(19, ABI_FP_rounding),
10736 LOOKUP(20, ABI_FP_denormal),
10737 LOOKUP(21, ABI_FP_exceptions),
10738 LOOKUP(22, ABI_FP_user_exceptions),
10739 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
10740 {24, "ABI_align_needed", 0, NULL},
10741 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
10742 LOOKUP(26, ABI_enum_size),
10743 LOOKUP(27, ABI_HardFP_use),
10744 LOOKUP(28, ABI_VFP_args),
10745 LOOKUP(29, ABI_WMMX_args),
10746 LOOKUP(30, ABI_optimization_goals),
10747 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 10748 {32, "compatibility", 0, NULL},
f5f53991 10749 LOOKUP(34, CPU_unaligned_access),
75375b3e 10750 LOOKUP(36, FP_HP_extension),
8e79c3df 10751 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
10752 LOOKUP(42, MPextension_use),
10753 LOOKUP(44, DIV_use),
f5f53991
AS
10754 {64, "nodefaults", 0, NULL},
10755 {65, "also_compatible_with", 0, NULL},
10756 LOOKUP(66, T2EE_use),
10757 {67, "conformance", 1, NULL},
10758 LOOKUP(68, Virtualization_use),
cd21e546 10759 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
10760};
10761#undef LOOKUP
10762
11c1ff18 10763static unsigned char *
2cf0635d 10764display_arm_attribute (unsigned char * p)
11c1ff18
PB
10765{
10766 int tag;
10767 unsigned int len;
10768 int val;
2cf0635d 10769 arm_attr_public_tag * attr;
11c1ff18
PB
10770 unsigned i;
10771 int type;
10772
10773 tag = read_uleb128 (p, &len);
10774 p += len;
10775 attr = NULL;
2cf0635d 10776 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
10777 {
10778 if (arm_attr_public_tags[i].tag == tag)
10779 {
10780 attr = &arm_attr_public_tags[i];
10781 break;
10782 }
10783 }
10784
10785 if (attr)
10786 {
10787 printf (" Tag_%s: ", attr->name);
10788 switch (attr->type)
10789 {
10790 case 0:
10791 switch (tag)
10792 {
10793 case 7: /* Tag_CPU_arch_profile. */
10794 val = read_uleb128 (p, &len);
10795 p += len;
10796 switch (val)
10797 {
2b692964
NC
10798 case 0: printf (_("None\n")); break;
10799 case 'A': printf (_("Application\n")); break;
10800 case 'R': printf (_("Realtime\n")); break;
10801 case 'M': printf (_("Microcontroller\n")); break;
10802 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
10803 default: printf ("??? (%d)\n", val); break;
10804 }
10805 break;
10806
75375b3e
MGD
10807 case 24: /* Tag_align_needed. */
10808 val = read_uleb128 (p, &len);
10809 p += len;
10810 switch (val)
10811 {
2b692964
NC
10812 case 0: printf (_("None\n")); break;
10813 case 1: printf (_("8-byte\n")); break;
10814 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
10815 case 3: printf ("??? 3\n"); break;
10816 default:
10817 if (val <= 12)
dd24e3da 10818 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10819 1 << val);
10820 else
10821 printf ("??? (%d)\n", val);
10822 break;
10823 }
10824 break;
10825
10826 case 25: /* Tag_align_preserved. */
10827 val = read_uleb128 (p, &len);
10828 p += len;
10829 switch (val)
10830 {
2b692964
NC
10831 case 0: printf (_("None\n")); break;
10832 case 1: printf (_("8-byte, except leaf SP\n")); break;
10833 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
10834 case 3: printf ("??? 3\n"); break;
10835 default:
10836 if (val <= 12)
dd24e3da 10837 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10838 1 << val);
10839 else
10840 printf ("??? (%d)\n", val);
10841 break;
10842 }
10843 break;
10844
11c1ff18
PB
10845 case 32: /* Tag_compatibility. */
10846 val = read_uleb128 (p, &len);
10847 p += len;
2b692964 10848 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 10849 p += strlen ((char *) p) + 1;
11c1ff18
PB
10850 break;
10851
f5f53991
AS
10852 case 64: /* Tag_nodefaults. */
10853 p++;
2b692964 10854 printf (_("True\n"));
f5f53991
AS
10855 break;
10856
10857 case 65: /* Tag_also_compatible_with. */
10858 val = read_uleb128 (p, &len);
10859 p += len;
10860 if (val == 6 /* Tag_CPU_arch. */)
10861 {
10862 val = read_uleb128 (p, &len);
10863 p += len;
2cf0635d 10864 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
10865 printf ("??? (%d)\n", val);
10866 else
10867 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
10868 }
10869 else
10870 printf ("???\n");
10871 while (*(p++) != '\0' /* NUL terminator. */);
10872 break;
10873
11c1ff18 10874 default:
2cf0635d 10875 abort ();
11c1ff18
PB
10876 }
10877 return p;
10878
10879 case 1:
10880 case 2:
10881 type = attr->type;
10882 break;
10883
10884 default:
10885 assert (attr->type & 0x80);
10886 val = read_uleb128 (p, &len);
10887 p += len;
10888 type = attr->type & 0x7f;
10889 if (val >= type)
10890 printf ("??? (%d)\n", val);
10891 else
10892 printf ("%s\n", attr->table[val]);
10893 return p;
10894 }
10895 }
10896 else
10897 {
10898 if (tag & 1)
10899 type = 1; /* String. */
10900 else
10901 type = 2; /* uleb128. */
10902 printf (" Tag_unknown_%d: ", tag);
10903 }
10904
10905 if (type == 1)
10906 {
10907 printf ("\"%s\"\n", p);
2cf0635d 10908 p += strlen ((char *) p) + 1;
11c1ff18
PB
10909 }
10910 else
10911 {
10912 val = read_uleb128 (p, &len);
10913 p += len;
10914 printf ("%d (0x%x)\n", val, val);
10915 }
10916
10917 return p;
10918}
10919
104d59d1 10920static unsigned char *
60bca95a
NC
10921display_gnu_attribute (unsigned char * p,
10922 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
10923{
10924 int tag;
10925 unsigned int len;
10926 int val;
10927 int type;
10928
10929 tag = read_uleb128 (p, &len);
10930 p += len;
10931
10932 /* Tag_compatibility is the only generic GNU attribute defined at
10933 present. */
10934 if (tag == 32)
10935 {
10936 val = read_uleb128 (p, &len);
10937 p += len;
2b692964 10938 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 10939 p += strlen ((char *) p) + 1;
104d59d1
JM
10940 return p;
10941 }
10942
10943 if ((tag & 2) == 0 && display_proc_gnu_attribute)
10944 return display_proc_gnu_attribute (p, tag);
10945
10946 if (tag & 1)
10947 type = 1; /* String. */
10948 else
10949 type = 2; /* uleb128. */
10950 printf (" Tag_unknown_%d: ", tag);
10951
10952 if (type == 1)
10953 {
10954 printf ("\"%s\"\n", p);
60bca95a 10955 p += strlen ((char *) p) + 1;
104d59d1
JM
10956 }
10957 else
10958 {
10959 val = read_uleb128 (p, &len);
10960 p += len;
10961 printf ("%d (0x%x)\n", val, val);
10962 }
10963
10964 return p;
10965}
10966
34c8bcba 10967static unsigned char *
2cf0635d 10968display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
10969{
10970 int type;
10971 unsigned int len;
10972 int val;
10973
10974 if (tag == Tag_GNU_Power_ABI_FP)
10975 {
10976 val = read_uleb128 (p, &len);
10977 p += len;
10978 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 10979
34c8bcba
JM
10980 switch (val)
10981 {
10982 case 0:
2b692964 10983 printf (_("Hard or soft float\n"));
34c8bcba
JM
10984 break;
10985 case 1:
2b692964 10986 printf (_("Hard float\n"));
34c8bcba
JM
10987 break;
10988 case 2:
2b692964 10989 printf (_("Soft float\n"));
34c8bcba 10990 break;
3c7b9897 10991 case 3:
2b692964 10992 printf (_("Single-precision hard float\n"));
3c7b9897 10993 break;
34c8bcba
JM
10994 default:
10995 printf ("??? (%d)\n", val);
10996 break;
10997 }
10998 return p;
10999 }
11000
c6e65352
DJ
11001 if (tag == Tag_GNU_Power_ABI_Vector)
11002 {
11003 val = read_uleb128 (p, &len);
11004 p += len;
11005 printf (" Tag_GNU_Power_ABI_Vector: ");
11006 switch (val)
11007 {
11008 case 0:
2b692964 11009 printf (_("Any\n"));
c6e65352
DJ
11010 break;
11011 case 1:
2b692964 11012 printf (_("Generic\n"));
c6e65352
DJ
11013 break;
11014 case 2:
11015 printf ("AltiVec\n");
11016 break;
11017 case 3:
11018 printf ("SPE\n");
11019 break;
11020 default:
11021 printf ("??? (%d)\n", val);
11022 break;
11023 }
11024 return p;
11025 }
11026
f82e0623
NF
11027 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11028 {
11029 val = read_uleb128 (p, &len);
11030 p += len;
11031 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11032 switch (val)
11033 {
11034 case 0:
2b692964 11035 printf (_("Any\n"));
f82e0623
NF
11036 break;
11037 case 1:
11038 printf ("r3/r4\n");
11039 break;
11040 case 2:
2b692964 11041 printf (_("Memory\n"));
f82e0623
NF
11042 break;
11043 default:
11044 printf ("??? (%d)\n", val);
11045 break;
11046 }
11047 return p;
11048 }
11049
34c8bcba
JM
11050 if (tag & 1)
11051 type = 1; /* String. */
11052 else
11053 type = 2; /* uleb128. */
11054 printf (" Tag_unknown_%d: ", tag);
11055
11056 if (type == 1)
11057 {
11058 printf ("\"%s\"\n", p);
60bca95a 11059 p += strlen ((char *) p) + 1;
34c8bcba
JM
11060 }
11061 else
11062 {
11063 val = read_uleb128 (p, &len);
11064 p += len;
11065 printf ("%d (0x%x)\n", val, val);
11066 }
11067
11068 return p;
11069}
11070
2cf19d5c 11071static unsigned char *
2cf0635d 11072display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
11073{
11074 int type;
11075 unsigned int len;
11076 int val;
11077
11078 if (tag == Tag_GNU_MIPS_ABI_FP)
11079 {
11080 val = read_uleb128 (p, &len);
11081 p += len;
11082 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11083
2cf19d5c
JM
11084 switch (val)
11085 {
11086 case 0:
2b692964 11087 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11088 break;
11089 case 1:
2b692964 11090 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11091 break;
11092 case 2:
2b692964 11093 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11094 break;
11095 case 3:
2b692964 11096 printf (_("Soft float\n"));
2cf19d5c 11097 break;
42554f6a 11098 case 4:
9eeefea8 11099 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11100 break;
2cf19d5c
JM
11101 default:
11102 printf ("??? (%d)\n", val);
11103 break;
11104 }
11105 return p;
11106 }
11107
11108 if (tag & 1)
11109 type = 1; /* String. */
11110 else
11111 type = 2; /* uleb128. */
11112 printf (" Tag_unknown_%d: ", tag);
11113
11114 if (type == 1)
11115 {
11116 printf ("\"%s\"\n", p);
60bca95a 11117 p += strlen ((char *) p) + 1;
2cf19d5c
JM
11118 }
11119 else
11120 {
11121 val = read_uleb128 (p, &len);
11122 p += len;
11123 printf ("%d (0x%x)\n", val, val);
11124 }
11125
11126 return p;
11127}
11128
59e6276b
JM
11129static unsigned char *
11130display_tic6x_attribute (unsigned char * p)
11131{
11132 int tag;
11133 unsigned int len;
11134 int val;
11135
11136 tag = read_uleb128 (p, &len);
11137 p += len;
11138
11139 switch (tag)
11140 {
75fa6dc1 11141 case Tag_ISA:
59e6276b
JM
11142 val = read_uleb128 (p, &len);
11143 p += len;
75fa6dc1 11144 printf (" Tag_ISA: ");
59e6276b
JM
11145
11146 switch (val)
11147 {
75fa6dc1 11148 case C6XABI_Tag_ISA_none:
59e6276b
JM
11149 printf (_("None\n"));
11150 break;
75fa6dc1 11151 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11152 printf ("C62x\n");
11153 break;
75fa6dc1 11154 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11155 printf ("C67x\n");
11156 break;
75fa6dc1 11157 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11158 printf ("C67x+\n");
11159 break;
75fa6dc1 11160 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11161 printf ("C64x\n");
11162 break;
75fa6dc1 11163 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11164 printf ("C64x+\n");
11165 break;
75fa6dc1 11166 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11167 printf ("C674x\n");
11168 break;
11169 default:
11170 printf ("??? (%d)\n", val);
11171 break;
11172 }
11173 return p;
11174
87779176
JM
11175 case Tag_ABI_wchar_t:
11176 val = read_uleb128 (p, &len);
11177 p += len;
11178 printf (" Tag_ABI_wchar_t: ");
11179 switch (val)
11180 {
11181 case 0:
11182 printf (_("Not used\n"));
11183 break;
11184 case 1:
11185 printf (_("2 bytes\n"));
11186 break;
11187 case 2:
11188 printf (_("4 bytes\n"));
11189 break;
11190 default:
11191 printf ("??? (%d)\n", val);
11192 break;
11193 }
11194 return p;
11195
11196 case Tag_ABI_stack_align_needed:
11197 val = read_uleb128 (p, &len);
11198 p += len;
11199 printf (" Tag_ABI_stack_align_needed: ");
11200 switch (val)
11201 {
11202 case 0:
11203 printf (_("8-byte\n"));
11204 break;
11205 case 1:
11206 printf (_("16-byte\n"));
11207 break;
11208 default:
11209 printf ("??? (%d)\n", val);
11210 break;
11211 }
11212 return p;
11213
11214 case Tag_ABI_stack_align_preserved:
11215 val = read_uleb128 (p, &len);
11216 p += len;
11217 printf (" Tag_ABI_stack_align_preserved: ");
11218 switch (val)
11219 {
11220 case 0:
11221 printf (_("8-byte\n"));
11222 break;
11223 case 1:
11224 printf (_("16-byte\n"));
11225 break;
11226 default:
11227 printf ("??? (%d)\n", val);
11228 break;
11229 }
11230 return p;
11231
b5593623
JM
11232 case Tag_ABI_DSBT:
11233 val = read_uleb128 (p, &len);
11234 p += len;
11235 printf (" Tag_ABI_DSBT: ");
11236 switch (val)
11237 {
11238 case 0:
11239 printf (_("DSBT addressing not used\n"));
11240 break;
11241 case 1:
11242 printf (_("DSBT addressing used\n"));
11243 break;
11244 default:
11245 printf ("??? (%d)\n", val);
11246 break;
11247 }
11248 return p;
11249
87779176
JM
11250 case Tag_ABI_PID:
11251 val = read_uleb128 (p, &len);
11252 p += len;
11253 printf (" Tag_ABI_PID: ");
11254 switch (val)
11255 {
11256 case 0:
11257 printf (_("Data addressing position-dependent\n"));
11258 break;
11259 case 1:
11260 printf (_("Data addressing position-independent, GOT near DP\n"));
11261 break;
11262 case 2:
11263 printf (_("Data addressing position-independent, GOT far from DP\n"));
11264 break;
11265 default:
11266 printf ("??? (%d)\n", val);
11267 break;
11268 }
11269 return p;
11270
11271 case Tag_ABI_PIC:
11272 val = read_uleb128 (p, &len);
11273 p += len;
11274 printf (" Tag_ABI_PIC: ");
11275 switch (val)
11276 {
11277 case 0:
11278 printf (_("Code addressing position-dependent\n"));
11279 break;
11280 case 1:
11281 printf (_("Code addressing position-independent\n"));
11282 break;
11283 default:
11284 printf ("??? (%d)\n", val);
11285 break;
11286 }
11287 return p;
11288
11289 case Tag_ABI_array_object_alignment:
11290 val = read_uleb128 (p, &len);
11291 p += len;
11292 printf (" Tag_ABI_array_object_alignment: ");
11293 switch (val)
11294 {
11295 case 0:
11296 printf (_("8-byte\n"));
11297 break;
11298 case 1:
11299 printf (_("4-byte\n"));
11300 break;
11301 case 2:
11302 printf (_("16-byte\n"));
11303 break;
11304 default:
11305 printf ("??? (%d)\n", val);
11306 break;
11307 }
11308 return p;
11309
11310 case Tag_ABI_array_object_align_expected:
11311 val = read_uleb128 (p, &len);
11312 p += len;
11313 printf (" Tag_ABI_array_object_align_expected: ");
11314 switch (val)
11315 {
11316 case 0:
11317 printf (_("8-byte\n"));
11318 break;
11319 case 1:
11320 printf (_("4-byte\n"));
11321 break;
11322 case 2:
11323 printf (_("16-byte\n"));
11324 break;
11325 default:
11326 printf ("??? (%d)\n", val);
11327 break;
11328 }
11329 return p;
11330
3cbd1c06 11331 case Tag_ABI_compatibility:
59e6276b
JM
11332 val = read_uleb128 (p, &len);
11333 p += len;
3cbd1c06 11334 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11335 printf (_("flag = %d, vendor = %s\n"), val, p);
11336 p += strlen ((char *) p) + 1;
11337 return p;
87779176
JM
11338
11339 case Tag_ABI_conformance:
11340 printf (" Tag_ABI_conformance: ");
11341 printf ("\"%s\"\n", p);
11342 p += strlen ((char *) p) + 1;
11343 return p;
59e6276b
JM
11344 }
11345
11346 printf (" Tag_unknown_%d: ", tag);
11347
87779176
JM
11348 if (tag & 1)
11349 {
11350 printf ("\"%s\"\n", p);
11351 p += strlen ((char *) p) + 1;
11352 }
11353 else
11354 {
11355 val = read_uleb128 (p, &len);
11356 p += len;
11357 printf ("%d (0x%x)\n", val, val);
11358 }
59e6276b
JM
11359
11360 return p;
11361}
11362
11c1ff18 11363static int
60bca95a
NC
11364process_attributes (FILE * file,
11365 const char * public_name,
104d59d1 11366 unsigned int proc_type,
60bca95a
NC
11367 unsigned char * (* display_pub_attribute) (unsigned char *),
11368 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11369{
2cf0635d
NC
11370 Elf_Internal_Shdr * sect;
11371 unsigned char * contents;
11372 unsigned char * p;
11373 unsigned char * end;
11c1ff18
PB
11374 bfd_vma section_len;
11375 bfd_vma len;
11376 unsigned i;
11377
11378 /* Find the section header so that we get the size. */
11379 for (i = 0, sect = section_headers;
11380 i < elf_header.e_shnum;
11381 i++, sect++)
11382 {
104d59d1 11383 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11384 continue;
11385
3f5e193b
NC
11386 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11387 sect->sh_size, _("attributes"));
60bca95a 11388 if (contents == NULL)
11c1ff18 11389 continue;
60bca95a 11390
11c1ff18
PB
11391 p = contents;
11392 if (*p == 'A')
11393 {
11394 len = sect->sh_size - 1;
11395 p++;
60bca95a 11396
11c1ff18
PB
11397 while (len > 0)
11398 {
11399 int namelen;
11400 bfd_boolean public_section;
104d59d1 11401 bfd_boolean gnu_section;
11c1ff18
PB
11402
11403 section_len = byte_get (p, 4);
11404 p += 4;
60bca95a 11405
11c1ff18
PB
11406 if (section_len > len)
11407 {
11408 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11409 (int) section_len, (int) len);
11c1ff18
PB
11410 section_len = len;
11411 }
60bca95a 11412
11c1ff18 11413 len -= section_len;
2b692964 11414 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11415
11416 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11417 public_section = TRUE;
11418 else
11419 public_section = FALSE;
60bca95a
NC
11420
11421 if (streq ((char *) p, "gnu"))
104d59d1
JM
11422 gnu_section = TRUE;
11423 else
11424 gnu_section = FALSE;
60bca95a
NC
11425
11426 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11427 p += namelen;
11428 section_len -= namelen + 4;
60bca95a 11429
11c1ff18
PB
11430 while (section_len > 0)
11431 {
11432 int tag = *(p++);
11433 int val;
11434 bfd_vma size;
60bca95a 11435
11c1ff18
PB
11436 size = byte_get (p, 4);
11437 if (size > section_len)
11438 {
11439 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11440 (int) size, (int) section_len);
11c1ff18
PB
11441 size = section_len;
11442 }
60bca95a 11443
11c1ff18
PB
11444 section_len -= size;
11445 end = p + size - 1;
11446 p += 4;
60bca95a 11447
11c1ff18
PB
11448 switch (tag)
11449 {
11450 case 1:
2b692964 11451 printf (_("File Attributes\n"));
11c1ff18
PB
11452 break;
11453 case 2:
2b692964 11454 printf (_("Section Attributes:"));
11c1ff18
PB
11455 goto do_numlist;
11456 case 3:
2b692964 11457 printf (_("Symbol Attributes:"));
11c1ff18
PB
11458 do_numlist:
11459 for (;;)
11460 {
91d6fa6a 11461 unsigned int j;
60bca95a 11462
91d6fa6a
NC
11463 val = read_uleb128 (p, &j);
11464 p += j;
11c1ff18
PB
11465 if (val == 0)
11466 break;
11467 printf (" %d", val);
11468 }
11469 printf ("\n");
11470 break;
11471 default:
2b692964 11472 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
11473 public_section = FALSE;
11474 break;
11475 }
60bca95a 11476
11c1ff18
PB
11477 if (public_section)
11478 {
11479 while (p < end)
104d59d1
JM
11480 p = display_pub_attribute (p);
11481 }
11482 else if (gnu_section)
11483 {
11484 while (p < end)
11485 p = display_gnu_attribute (p,
11486 display_proc_gnu_attribute);
11c1ff18
PB
11487 }
11488 else
11489 {
11490 /* ??? Do something sensible, like dump hex. */
2b692964 11491 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
11492 p = end;
11493 }
11494 }
11495 }
11496 }
11497 else
60bca95a 11498 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 11499
60bca95a 11500 free (contents);
11c1ff18
PB
11501 }
11502 return 1;
11503}
11504
104d59d1 11505static int
2cf0635d 11506process_arm_specific (FILE * file)
104d59d1
JM
11507{
11508 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
11509 display_arm_attribute, NULL);
11510}
11511
34c8bcba 11512static int
2cf0635d 11513process_power_specific (FILE * file)
34c8bcba
JM
11514{
11515 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11516 display_power_gnu_attribute);
11517}
11518
59e6276b
JM
11519static int
11520process_tic6x_specific (FILE * file)
11521{
11522 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
11523 display_tic6x_attribute, NULL);
11524}
11525
ccb4c951
RS
11526/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
11527 Print the Address, Access and Initial fields of an entry at VMA ADDR
11528 and return the VMA of the next entry. */
11529
11530static bfd_vma
2cf0635d 11531print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
11532{
11533 printf (" ");
11534 print_vma (addr, LONG_HEX);
11535 printf (" ");
11536 if (addr < pltgot + 0xfff0)
11537 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
11538 else
11539 printf ("%10s", "");
11540 printf (" ");
11541 if (data == NULL)
2b692964 11542 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
11543 else
11544 {
11545 bfd_vma entry;
11546
11547 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11548 print_vma (entry, LONG_HEX);
11549 }
11550 return addr + (is_32bit_elf ? 4 : 8);
11551}
11552
861fb55a
DJ
11553/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
11554 PLTGOT. Print the Address and Initial fields of an entry at VMA
11555 ADDR and return the VMA of the next entry. */
11556
11557static bfd_vma
2cf0635d 11558print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
11559{
11560 printf (" ");
11561 print_vma (addr, LONG_HEX);
11562 printf (" ");
11563 if (data == NULL)
2b692964 11564 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
11565 else
11566 {
11567 bfd_vma entry;
11568
11569 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11570 print_vma (entry, LONG_HEX);
11571 }
11572 return addr + (is_32bit_elf ? 4 : 8);
11573}
11574
19e6b90e 11575static int
2cf0635d 11576process_mips_specific (FILE * file)
5b18a4bc 11577{
2cf0635d 11578 Elf_Internal_Dyn * entry;
19e6b90e
L
11579 size_t liblist_offset = 0;
11580 size_t liblistno = 0;
11581 size_t conflictsno = 0;
11582 size_t options_offset = 0;
11583 size_t conflicts_offset = 0;
861fb55a
DJ
11584 size_t pltrelsz = 0;
11585 size_t pltrel = 0;
ccb4c951 11586 bfd_vma pltgot = 0;
861fb55a
DJ
11587 bfd_vma mips_pltgot = 0;
11588 bfd_vma jmprel = 0;
ccb4c951
RS
11589 bfd_vma local_gotno = 0;
11590 bfd_vma gotsym = 0;
11591 bfd_vma symtabno = 0;
103f02d3 11592
2cf19d5c
JM
11593 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11594 display_mips_gnu_attribute);
11595
19e6b90e
L
11596 /* We have a lot of special sections. Thanks SGI! */
11597 if (dynamic_section == NULL)
11598 /* No information available. */
11599 return 0;
252b5132 11600
b2d38a17 11601 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
11602 switch (entry->d_tag)
11603 {
11604 case DT_MIPS_LIBLIST:
d93f0186
NC
11605 liblist_offset
11606 = offset_from_vma (file, entry->d_un.d_val,
11607 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
11608 break;
11609 case DT_MIPS_LIBLISTNO:
11610 liblistno = entry->d_un.d_val;
11611 break;
11612 case DT_MIPS_OPTIONS:
d93f0186 11613 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
11614 break;
11615 case DT_MIPS_CONFLICT:
d93f0186
NC
11616 conflicts_offset
11617 = offset_from_vma (file, entry->d_un.d_val,
11618 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
11619 break;
11620 case DT_MIPS_CONFLICTNO:
11621 conflictsno = entry->d_un.d_val;
11622 break;
ccb4c951 11623 case DT_PLTGOT:
861fb55a
DJ
11624 pltgot = entry->d_un.d_ptr;
11625 break;
ccb4c951
RS
11626 case DT_MIPS_LOCAL_GOTNO:
11627 local_gotno = entry->d_un.d_val;
11628 break;
11629 case DT_MIPS_GOTSYM:
11630 gotsym = entry->d_un.d_val;
11631 break;
11632 case DT_MIPS_SYMTABNO:
11633 symtabno = entry->d_un.d_val;
11634 break;
861fb55a
DJ
11635 case DT_MIPS_PLTGOT:
11636 mips_pltgot = entry->d_un.d_ptr;
11637 break;
11638 case DT_PLTREL:
11639 pltrel = entry->d_un.d_val;
11640 break;
11641 case DT_PLTRELSZ:
11642 pltrelsz = entry->d_un.d_val;
11643 break;
11644 case DT_JMPREL:
11645 jmprel = entry->d_un.d_ptr;
11646 break;
252b5132
RH
11647 default:
11648 break;
11649 }
11650
11651 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
11652 {
2cf0635d 11653 Elf32_External_Lib * elib;
252b5132
RH
11654 size_t cnt;
11655
3f5e193b
NC
11656 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
11657 liblistno,
11658 sizeof (Elf32_External_Lib),
11659 _("liblist"));
a6e9f9df 11660 if (elib)
252b5132 11661 {
2b692964 11662 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 11663 (unsigned long) liblistno);
2b692964 11664 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
11665 stdout);
11666
11667 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 11668 {
a6e9f9df 11669 Elf32_Lib liblist;
91d6fa6a 11670 time_t atime;
a6e9f9df 11671 char timebuf[20];
2cf0635d 11672 struct tm * tmp;
a6e9f9df
AM
11673
11674 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 11675 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
11676 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11677 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11678 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11679
91d6fa6a 11680 tmp = gmtime (&atime);
e9e44622
JJ
11681 snprintf (timebuf, sizeof (timebuf),
11682 "%04u-%02u-%02uT%02u:%02u:%02u",
11683 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11684 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 11685
31104126 11686 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
11687 if (VALID_DYNAMIC_NAME (liblist.l_name))
11688 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
11689 else
2b692964 11690 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
11691 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
11692 liblist.l_version);
a6e9f9df
AM
11693
11694 if (liblist.l_flags == 0)
2b692964 11695 puts (_(" NONE"));
a6e9f9df
AM
11696 else
11697 {
11698 static const struct
252b5132 11699 {
2cf0635d 11700 const char * name;
a6e9f9df 11701 int bit;
252b5132 11702 }
a6e9f9df
AM
11703 l_flags_vals[] =
11704 {
11705 { " EXACT_MATCH", LL_EXACT_MATCH },
11706 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
11707 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
11708 { " EXPORTS", LL_EXPORTS },
11709 { " DELAY_LOAD", LL_DELAY_LOAD },
11710 { " DELTA", LL_DELTA }
11711 };
11712 int flags = liblist.l_flags;
11713 size_t fcnt;
11714
60bca95a 11715 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
11716 if ((flags & l_flags_vals[fcnt].bit) != 0)
11717 {
11718 fputs (l_flags_vals[fcnt].name, stdout);
11719 flags ^= l_flags_vals[fcnt].bit;
11720 }
11721 if (flags != 0)
11722 printf (" %#x", (unsigned int) flags);
252b5132 11723
a6e9f9df
AM
11724 puts ("");
11725 }
252b5132 11726 }
252b5132 11727
a6e9f9df
AM
11728 free (elib);
11729 }
252b5132
RH
11730 }
11731
11732 if (options_offset != 0)
11733 {
2cf0635d
NC
11734 Elf_External_Options * eopt;
11735 Elf_Internal_Shdr * sect = section_headers;
11736 Elf_Internal_Options * iopt;
11737 Elf_Internal_Options * option;
252b5132
RH
11738 size_t offset;
11739 int cnt;
11740
11741 /* Find the section header so that we get the size. */
11742 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 11743 ++sect;
252b5132 11744
3f5e193b
NC
11745 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
11746 sect->sh_size, _("options"));
a6e9f9df 11747 if (eopt)
252b5132 11748 {
3f5e193b
NC
11749 iopt = (Elf_Internal_Options *)
11750 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
11751 if (iopt == NULL)
11752 {
591a748a 11753 error (_("Out of memory\n"));
a6e9f9df
AM
11754 return 0;
11755 }
76da6bbe 11756
a6e9f9df
AM
11757 offset = cnt = 0;
11758 option = iopt;
252b5132 11759
a6e9f9df
AM
11760 while (offset < sect->sh_size)
11761 {
2cf0635d 11762 Elf_External_Options * eoption;
252b5132 11763
a6e9f9df 11764 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 11765
a6e9f9df
AM
11766 option->kind = BYTE_GET (eoption->kind);
11767 option->size = BYTE_GET (eoption->size);
11768 option->section = BYTE_GET (eoption->section);
11769 option->info = BYTE_GET (eoption->info);
76da6bbe 11770
a6e9f9df 11771 offset += option->size;
252b5132 11772
a6e9f9df
AM
11773 ++option;
11774 ++cnt;
11775 }
252b5132 11776
a6e9f9df
AM
11777 printf (_("\nSection '%s' contains %d entries:\n"),
11778 SECTION_NAME (sect), cnt);
76da6bbe 11779
a6e9f9df 11780 option = iopt;
252b5132 11781
a6e9f9df 11782 while (cnt-- > 0)
252b5132 11783 {
a6e9f9df
AM
11784 size_t len;
11785
11786 switch (option->kind)
252b5132 11787 {
a6e9f9df
AM
11788 case ODK_NULL:
11789 /* This shouldn't happen. */
11790 printf (" NULL %d %lx", option->section, option->info);
11791 break;
11792 case ODK_REGINFO:
11793 printf (" REGINFO ");
11794 if (elf_header.e_machine == EM_MIPS)
11795 {
11796 /* 32bit form. */
2cf0635d 11797 Elf32_External_RegInfo * ereg;
b34976b6 11798 Elf32_RegInfo reginfo;
a6e9f9df
AM
11799
11800 ereg = (Elf32_External_RegInfo *) (option + 1);
11801 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11802 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11803 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11804 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11805 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
11806 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
11807
11808 printf ("GPR %08lx GP 0x%lx\n",
11809 reginfo.ri_gprmask,
11810 (unsigned long) reginfo.ri_gp_value);
11811 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11812 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11813 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11814 }
11815 else
11816 {
11817 /* 64 bit form. */
2cf0635d 11818 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
11819 Elf64_Internal_RegInfo reginfo;
11820
11821 ereg = (Elf64_External_RegInfo *) (option + 1);
11822 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11823 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11824 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11825 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11826 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 11827 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
11828
11829 printf ("GPR %08lx GP 0x",
11830 reginfo.ri_gprmask);
11831 printf_vma (reginfo.ri_gp_value);
11832 printf ("\n");
11833
11834 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11835 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11836 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11837 }
11838 ++option;
11839 continue;
11840 case ODK_EXCEPTIONS:
11841 fputs (" EXCEPTIONS fpe_min(", stdout);
11842 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
11843 fputs (") fpe_max(", stdout);
11844 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
11845 fputs (")", stdout);
11846
11847 if (option->info & OEX_PAGE0)
11848 fputs (" PAGE0", stdout);
11849 if (option->info & OEX_SMM)
11850 fputs (" SMM", stdout);
11851 if (option->info & OEX_FPDBUG)
11852 fputs (" FPDBUG", stdout);
11853 if (option->info & OEX_DISMISS)
11854 fputs (" DISMISS", stdout);
11855 break;
11856 case ODK_PAD:
11857 fputs (" PAD ", stdout);
11858 if (option->info & OPAD_PREFIX)
11859 fputs (" PREFIX", stdout);
11860 if (option->info & OPAD_POSTFIX)
11861 fputs (" POSTFIX", stdout);
11862 if (option->info & OPAD_SYMBOL)
11863 fputs (" SYMBOL", stdout);
11864 break;
11865 case ODK_HWPATCH:
11866 fputs (" HWPATCH ", stdout);
11867 if (option->info & OHW_R4KEOP)
11868 fputs (" R4KEOP", stdout);
11869 if (option->info & OHW_R8KPFETCH)
11870 fputs (" R8KPFETCH", stdout);
11871 if (option->info & OHW_R5KEOP)
11872 fputs (" R5KEOP", stdout);
11873 if (option->info & OHW_R5KCVTL)
11874 fputs (" R5KCVTL", stdout);
11875 break;
11876 case ODK_FILL:
11877 fputs (" FILL ", stdout);
11878 /* XXX Print content of info word? */
11879 break;
11880 case ODK_TAGS:
11881 fputs (" TAGS ", stdout);
11882 /* XXX Print content of info word? */
11883 break;
11884 case ODK_HWAND:
11885 fputs (" HWAND ", stdout);
11886 if (option->info & OHWA0_R4KEOP_CHECKED)
11887 fputs (" R4KEOP_CHECKED", stdout);
11888 if (option->info & OHWA0_R4KEOP_CLEAN)
11889 fputs (" R4KEOP_CLEAN", stdout);
11890 break;
11891 case ODK_HWOR:
11892 fputs (" HWOR ", stdout);
11893 if (option->info & OHWA0_R4KEOP_CHECKED)
11894 fputs (" R4KEOP_CHECKED", stdout);
11895 if (option->info & OHWA0_R4KEOP_CLEAN)
11896 fputs (" R4KEOP_CLEAN", stdout);
11897 break;
11898 case ODK_GP_GROUP:
11899 printf (" GP_GROUP %#06lx self-contained %#06lx",
11900 option->info & OGP_GROUP,
11901 (option->info & OGP_SELF) >> 16);
11902 break;
11903 case ODK_IDENT:
11904 printf (" IDENT %#06lx self-contained %#06lx",
11905 option->info & OGP_GROUP,
11906 (option->info & OGP_SELF) >> 16);
11907 break;
11908 default:
11909 /* This shouldn't happen. */
11910 printf (" %3d ??? %d %lx",
11911 option->kind, option->section, option->info);
11912 break;
252b5132 11913 }
a6e9f9df 11914
2cf0635d 11915 len = sizeof (* eopt);
a6e9f9df
AM
11916 while (len < option->size)
11917 if (((char *) option)[len] >= ' '
11918 && ((char *) option)[len] < 0x7f)
11919 printf ("%c", ((char *) option)[len++]);
11920 else
11921 printf ("\\%03o", ((char *) option)[len++]);
11922
11923 fputs ("\n", stdout);
252b5132 11924 ++option;
252b5132
RH
11925 }
11926
a6e9f9df 11927 free (eopt);
252b5132 11928 }
252b5132
RH
11929 }
11930
11931 if (conflicts_offset != 0 && conflictsno != 0)
11932 {
2cf0635d 11933 Elf32_Conflict * iconf;
252b5132
RH
11934 size_t cnt;
11935
11936 if (dynamic_symbols == NULL)
11937 {
591a748a 11938 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
11939 return 0;
11940 }
11941
3f5e193b 11942 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
11943 if (iconf == NULL)
11944 {
591a748a 11945 error (_("Out of memory\n"));
252b5132
RH
11946 return 0;
11947 }
11948
9ea033b2 11949 if (is_32bit_elf)
252b5132 11950 {
2cf0635d 11951 Elf32_External_Conflict * econf32;
a6e9f9df 11952
3f5e193b
NC
11953 econf32 = (Elf32_External_Conflict *)
11954 get_data (NULL, file, conflicts_offset, conflictsno,
11955 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
11956 if (!econf32)
11957 return 0;
252b5132
RH
11958
11959 for (cnt = 0; cnt < conflictsno; ++cnt)
11960 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
11961
11962 free (econf32);
252b5132
RH
11963 }
11964 else
11965 {
2cf0635d 11966 Elf64_External_Conflict * econf64;
a6e9f9df 11967
3f5e193b
NC
11968 econf64 = (Elf64_External_Conflict *)
11969 get_data (NULL, file, conflicts_offset, conflictsno,
11970 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
11971 if (!econf64)
11972 return 0;
252b5132
RH
11973
11974 for (cnt = 0; cnt < conflictsno; ++cnt)
11975 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
11976
11977 free (econf64);
252b5132
RH
11978 }
11979
c7e7ca54
NC
11980 printf (_("\nSection '.conflict' contains %lu entries:\n"),
11981 (unsigned long) conflictsno);
252b5132
RH
11982 puts (_(" Num: Index Value Name"));
11983
11984 for (cnt = 0; cnt < conflictsno; ++cnt)
11985 {
2cf0635d 11986 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 11987
b34976b6 11988 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 11989 print_vma (psym->st_value, FULL_HEX);
31104126 11990 putchar (' ');
d79b3d50
NC
11991 if (VALID_DYNAMIC_NAME (psym->st_name))
11992 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11993 else
2b692964 11994 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 11995 putchar ('\n');
252b5132
RH
11996 }
11997
252b5132
RH
11998 free (iconf);
11999 }
12000
ccb4c951
RS
12001 if (pltgot != 0 && local_gotno != 0)
12002 {
91d6fa6a 12003 bfd_vma ent, local_end, global_end;
bbeee7ea 12004 size_t i, offset;
2cf0635d 12005 unsigned char * data;
bbeee7ea 12006 int addr_size;
ccb4c951 12007
91d6fa6a 12008 ent = pltgot;
ccb4c951
RS
12009 addr_size = (is_32bit_elf ? 4 : 8);
12010 local_end = pltgot + local_gotno * addr_size;
12011 global_end = local_end + (symtabno - gotsym) * addr_size;
12012
12013 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b
NC
12014 data = (unsigned char *) get_data (NULL, file, offset,
12015 global_end - pltgot, 1, _("GOT"));
59245841
NC
12016 if (data == NULL)
12017 return 0;
12018
ccb4c951
RS
12019 printf (_("\nPrimary GOT:\n"));
12020 printf (_(" Canonical gp value: "));
12021 print_vma (pltgot + 0x7ff0, LONG_HEX);
12022 printf ("\n\n");
12023
12024 printf (_(" Reserved entries:\n"));
12025 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12026 addr_size * 2, _("Address"), _("Access"),
12027 addr_size * 2, _("Initial"));
91d6fa6a 12028 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12029 printf (_(" Lazy resolver\n"));
ccb4c951 12030 if (data
91d6fa6a 12031 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12032 >> (addr_size * 8 - 1)) != 0)
12033 {
91d6fa6a 12034 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12035 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12036 }
12037 printf ("\n");
12038
91d6fa6a 12039 if (ent < local_end)
ccb4c951
RS
12040 {
12041 printf (_(" Local entries:\n"));
cc5914eb 12042 printf (" %*s %10s %*s\n",
2b692964
NC
12043 addr_size * 2, _("Address"), _("Access"),
12044 addr_size * 2, _("Initial"));
91d6fa6a 12045 while (ent < local_end)
ccb4c951 12046 {
91d6fa6a 12047 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12048 printf ("\n");
12049 }
12050 printf ("\n");
12051 }
12052
12053 if (gotsym < symtabno)
12054 {
12055 int sym_width;
12056
12057 printf (_(" Global entries:\n"));
cc5914eb 12058 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
2b692964
NC
12059 addr_size * 2, _("Address"), _("Access"),
12060 addr_size * 2, _("Initial"),
12061 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
ccb4c951
RS
12062 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12063 for (i = gotsym; i < symtabno; i++)
12064 {
2cf0635d 12065 Elf_Internal_Sym * psym;
ccb4c951
RS
12066
12067 psym = dynamic_symbols + i;
91d6fa6a 12068 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12069 printf (" ");
12070 print_vma (psym->st_value, LONG_HEX);
12071 printf (" %-7s %3s ",
12072 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12073 get_symbol_index_type (psym->st_shndx));
12074 if (VALID_DYNAMIC_NAME (psym->st_name))
12075 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12076 else
2b692964 12077 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12078 printf ("\n");
12079 }
12080 printf ("\n");
12081 }
12082
12083 if (data)
12084 free (data);
12085 }
12086
861fb55a
DJ
12087 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12088 {
91d6fa6a 12089 bfd_vma ent, end;
861fb55a
DJ
12090 size_t offset, rel_offset;
12091 unsigned long count, i;
2cf0635d 12092 unsigned char * data;
861fb55a 12093 int addr_size, sym_width;
2cf0635d 12094 Elf_Internal_Rela * rels;
861fb55a
DJ
12095
12096 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12097 if (pltrel == DT_RELA)
12098 {
12099 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12100 return 0;
12101 }
12102 else
12103 {
12104 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12105 return 0;
12106 }
12107
91d6fa6a 12108 ent = mips_pltgot;
861fb55a
DJ
12109 addr_size = (is_32bit_elf ? 4 : 8);
12110 end = mips_pltgot + (2 + count) * addr_size;
12111
12112 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b
NC
12113 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
12114 1, _("PLT GOT"));
59245841
NC
12115 if (data == NULL)
12116 return 0;
12117
861fb55a
DJ
12118 printf (_("\nPLT GOT:\n\n"));
12119 printf (_(" Reserved entries:\n"));
12120 printf (_(" %*s %*s Purpose\n"),
2b692964 12121 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12122 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12123 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12124 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12125 printf (_(" Module pointer\n"));
861fb55a
DJ
12126 printf ("\n");
12127
12128 printf (_(" Entries:\n"));
cc5914eb 12129 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12130 addr_size * 2, _("Address"),
12131 addr_size * 2, _("Initial"),
12132 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12133 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12134 for (i = 0; i < count; i++)
12135 {
2cf0635d 12136 Elf_Internal_Sym * psym;
861fb55a
DJ
12137
12138 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12139 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12140 printf (" ");
12141 print_vma (psym->st_value, LONG_HEX);
12142 printf (" %-7s %3s ",
12143 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12144 get_symbol_index_type (psym->st_shndx));
12145 if (VALID_DYNAMIC_NAME (psym->st_name))
12146 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12147 else
2b692964 12148 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12149 printf ("\n");
12150 }
12151 printf ("\n");
12152
12153 if (data)
12154 free (data);
12155 free (rels);
12156 }
12157
252b5132
RH
12158 return 1;
12159}
12160
047b2264 12161static int
2cf0635d 12162process_gnu_liblist (FILE * file)
047b2264 12163{
2cf0635d
NC
12164 Elf_Internal_Shdr * section;
12165 Elf_Internal_Shdr * string_sec;
12166 Elf32_External_Lib * elib;
12167 char * strtab;
c256ffe7 12168 size_t strtab_size;
047b2264
JJ
12169 size_t cnt;
12170 unsigned i;
12171
12172 if (! do_arch)
12173 return 0;
12174
12175 for (i = 0, section = section_headers;
12176 i < elf_header.e_shnum;
b34976b6 12177 i++, section++)
047b2264
JJ
12178 {
12179 switch (section->sh_type)
12180 {
12181 case SHT_GNU_LIBLIST:
4fbb74a6 12182 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12183 break;
12184
3f5e193b
NC
12185 elib = (Elf32_External_Lib *)
12186 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
12187 _("liblist"));
047b2264
JJ
12188
12189 if (elib == NULL)
12190 break;
4fbb74a6 12191 string_sec = section_headers + section->sh_link;
047b2264 12192
3f5e193b
NC
12193 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12194 string_sec->sh_size,
12195 _("liblist string table"));
047b2264
JJ
12196 if (strtab == NULL
12197 || section->sh_entsize != sizeof (Elf32_External_Lib))
12198 {
12199 free (elib);
2842702f 12200 free (strtab);
047b2264
JJ
12201 break;
12202 }
59245841 12203 strtab_size = string_sec->sh_size;
047b2264
JJ
12204
12205 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12206 SECTION_NAME (section),
0af1713e 12207 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12208
2b692964 12209 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12210
12211 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12212 ++cnt)
12213 {
12214 Elf32_Lib liblist;
91d6fa6a 12215 time_t atime;
047b2264 12216 char timebuf[20];
2cf0635d 12217 struct tm * tmp;
047b2264
JJ
12218
12219 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12220 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12221 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12222 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12223 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12224
91d6fa6a 12225 tmp = gmtime (&atime);
e9e44622
JJ
12226 snprintf (timebuf, sizeof (timebuf),
12227 "%04u-%02u-%02uT%02u:%02u:%02u",
12228 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12229 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12230
12231 printf ("%3lu: ", (unsigned long) cnt);
12232 if (do_wide)
c256ffe7 12233 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12234 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12235 else
c256ffe7 12236 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12237 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12238 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12239 liblist.l_version, liblist.l_flags);
12240 }
12241
12242 free (elib);
2842702f 12243 free (strtab);
047b2264
JJ
12244 }
12245 }
12246
12247 return 1;
12248}
12249
9437c45b 12250static const char *
d3ba0551 12251get_note_type (unsigned e_type)
779fe533
NC
12252{
12253 static char buff[64];
103f02d3 12254
1ec5cd37
NC
12255 if (elf_header.e_type == ET_CORE)
12256 switch (e_type)
12257 {
57346661 12258 case NT_AUXV:
1ec5cd37 12259 return _("NT_AUXV (auxiliary vector)");
57346661 12260 case NT_PRSTATUS:
1ec5cd37 12261 return _("NT_PRSTATUS (prstatus structure)");
57346661 12262 case NT_FPREGSET:
1ec5cd37 12263 return _("NT_FPREGSET (floating point registers)");
57346661 12264 case NT_PRPSINFO:
1ec5cd37 12265 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12266 case NT_TASKSTRUCT:
1ec5cd37 12267 return _("NT_TASKSTRUCT (task structure)");
57346661 12268 case NT_PRXFPREG:
1ec5cd37 12269 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12270 case NT_PPC_VMX:
12271 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12272 case NT_PPC_VSX:
12273 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
12274 case NT_X86_XSTATE:
12275 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12276 case NT_S390_HIGH_GPRS:
12277 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12278 case NT_S390_TIMER:
12279 return _("NT_S390_TIMER (s390 timer register)");
12280 case NT_S390_TODCMP:
12281 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12282 case NT_S390_TODPREG:
12283 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12284 case NT_S390_CTRS:
12285 return _("NT_S390_CTRS (s390 control registers)");
12286 case NT_S390_PREFIX:
12287 return _("NT_S390_PREFIX (s390 prefix register)");
faa9a424
UW
12288 case NT_ARM_VFP:
12289 return _("NT_ARM_VFP (arm VFP registers)");
57346661 12290 case NT_PSTATUS:
1ec5cd37 12291 return _("NT_PSTATUS (pstatus structure)");
57346661 12292 case NT_FPREGS:
1ec5cd37 12293 return _("NT_FPREGS (floating point registers)");
57346661 12294 case NT_PSINFO:
1ec5cd37 12295 return _("NT_PSINFO (psinfo structure)");
57346661 12296 case NT_LWPSTATUS:
1ec5cd37 12297 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12298 case NT_LWPSINFO:
1ec5cd37 12299 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12300 case NT_WIN32PSTATUS:
1ec5cd37
NC
12301 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
12302 default:
12303 break;
12304 }
12305 else
12306 switch (e_type)
12307 {
12308 case NT_VERSION:
12309 return _("NT_VERSION (version)");
12310 case NT_ARCH:
12311 return _("NT_ARCH (architecture)");
12312 default:
12313 break;
12314 }
12315
e9e44622 12316 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12317 return buff;
779fe533
NC
12318}
12319
1118d252
RM
12320static const char *
12321get_gnu_elf_note_type (unsigned e_type)
12322{
12323 static char buff[64];
12324
12325 switch (e_type)
12326 {
12327 case NT_GNU_ABI_TAG:
12328 return _("NT_GNU_ABI_TAG (ABI version tag)");
12329 case NT_GNU_HWCAP:
12330 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12331 case NT_GNU_BUILD_ID:
12332 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12333 case NT_GNU_GOLD_VERSION:
12334 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12335 default:
12336 break;
12337 }
12338
12339 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12340 return buff;
12341}
12342
664f90a3
TT
12343static int
12344print_gnu_note (Elf_Internal_Note *pnote)
12345{
12346 switch (pnote->type)
12347 {
12348 case NT_GNU_BUILD_ID:
12349 {
12350 unsigned long i;
12351
12352 printf (_(" Build ID: "));
12353 for (i = 0; i < pnote->descsz; ++i)
12354 printf ("%02x", pnote->descdata[i] & 0xff);
12355 printf (_("\n"));
12356 }
12357 break;
12358
12359 case NT_GNU_ABI_TAG:
12360 {
12361 unsigned long os, major, minor, subminor;
12362 const char *osname;
12363
12364 os = byte_get ((unsigned char *) pnote->descdata, 4);
12365 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
12366 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
12367 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
12368
12369 switch (os)
12370 {
12371 case GNU_ABI_TAG_LINUX:
12372 osname = "Linux";
12373 break;
12374 case GNU_ABI_TAG_HURD:
12375 osname = "Hurd";
12376 break;
12377 case GNU_ABI_TAG_SOLARIS:
12378 osname = "Solaris";
12379 break;
12380 case GNU_ABI_TAG_FREEBSD:
12381 osname = "FreeBSD";
12382 break;
12383 case GNU_ABI_TAG_NETBSD:
12384 osname = "NetBSD";
12385 break;
12386 default:
12387 osname = "Unknown";
12388 break;
12389 }
12390
12391 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
12392 major, minor, subminor);
12393 }
12394 break;
12395 }
12396
12397 return 1;
12398}
12399
9437c45b 12400static const char *
d3ba0551 12401get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
12402{
12403 static char buff[64];
12404
b4db1224 12405 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
12406 {
12407 /* NetBSD core "procinfo" structure. */
12408 return _("NetBSD procinfo structure");
12409 }
12410
12411 /* As of Jan 2002 there are no other machine-independent notes
12412 defined for NetBSD core files. If the note type is less
12413 than the start of the machine-dependent note types, we don't
12414 understand it. */
12415
b4db1224 12416 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 12417 {
e9e44622 12418 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
12419 return buff;
12420 }
12421
12422 switch (elf_header.e_machine)
12423 {
12424 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
12425 and PT_GETFPREGS == mach+2. */
12426
12427 case EM_OLD_ALPHA:
12428 case EM_ALPHA:
12429 case EM_SPARC:
12430 case EM_SPARC32PLUS:
12431 case EM_SPARCV9:
12432 switch (e_type)
12433 {
2b692964 12434 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 12435 return _("PT_GETREGS (reg structure)");
2b692964 12436 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 12437 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12438 default:
12439 break;
12440 }
12441 break;
12442
12443 /* On all other arch's, PT_GETREGS == mach+1 and
12444 PT_GETFPREGS == mach+3. */
12445 default:
12446 switch (e_type)
12447 {
2b692964 12448 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 12449 return _("PT_GETREGS (reg structure)");
2b692964 12450 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 12451 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12452 default:
12453 break;
12454 }
12455 }
12456
e9e44622
JJ
12457 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
12458 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
12459 return buff;
12460}
12461
70616151
TT
12462static const char *
12463get_stapsdt_note_type (unsigned e_type)
12464{
12465 static char buff[64];
12466
12467 switch (e_type)
12468 {
12469 case NT_STAPSDT:
12470 return _("NT_STAPSDT (SystemTap probe descriptors)");
12471
12472 default:
12473 break;
12474 }
12475
12476 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12477 return buff;
12478}
12479
c6a9fc58
TT
12480static int
12481print_stapsdt_note (Elf_Internal_Note *pnote)
12482{
12483 int addr_size = is_32bit_elf ? 4 : 8;
12484 char *data = pnote->descdata;
12485 char *data_end = pnote->descdata + pnote->descsz;
12486 bfd_vma pc, base_addr, semaphore;
12487 char *provider, *probe, *arg_fmt;
12488
12489 pc = byte_get ((unsigned char *) data, addr_size);
12490 data += addr_size;
12491 base_addr = byte_get ((unsigned char *) data, addr_size);
12492 data += addr_size;
12493 semaphore = byte_get ((unsigned char *) data, addr_size);
12494 data += addr_size;
12495
12496 provider = data;
12497 data += strlen (data) + 1;
12498 probe = data;
12499 data += strlen (data) + 1;
12500 arg_fmt = data;
12501 data += strlen (data) + 1;
12502
12503 printf (_(" Provider: %s\n"), provider);
12504 printf (_(" Name: %s\n"), probe);
12505 printf (_(" Location: "));
12506 print_vma (pc, FULL_HEX);
12507 printf (_(", Base: "));
12508 print_vma (base_addr, FULL_HEX);
12509 printf (_(", Semaphore: "));
12510 print_vma (semaphore, FULL_HEX);
12511 printf (_("\n"));
12512 printf (_(" Arguments: %s\n"), arg_fmt);
12513
12514 return data == data_end;
12515}
12516
00e98fc7
TG
12517static const char *
12518get_ia64_vms_note_type (unsigned e_type)
12519{
12520 static char buff[64];
12521
12522 switch (e_type)
12523 {
12524 case NT_VMS_MHD:
12525 return _("NT_VMS_MHD (module header)");
12526 case NT_VMS_LNM:
12527 return _("NT_VMS_LNM (language name)");
12528 case NT_VMS_SRC:
12529 return _("NT_VMS_SRC (source files)");
12530 case NT_VMS_TITLE:
12531 return _("NT_VMS_TITLE");
12532 case NT_VMS_EIDC:
12533 return _("NT_VMS_EIDC (consistency check)");
12534 case NT_VMS_FPMODE:
12535 return _("NT_VMS_FPMODE (FP mode)");
12536 case NT_VMS_LINKTIME:
12537 return _("NT_VMS_LINKTIME");
12538 case NT_VMS_IMGNAM:
12539 return _("NT_VMS_IMGNAM (image name)");
12540 case NT_VMS_IMGID:
12541 return _("NT_VMS_IMGID (image id)");
12542 case NT_VMS_LINKID:
12543 return _("NT_VMS_LINKID (link id)");
12544 case NT_VMS_IMGBID:
12545 return _("NT_VMS_IMGBID (build id)");
12546 case NT_VMS_GSTNAM:
12547 return _("NT_VMS_GSTNAM (sym table name)");
12548 case NT_VMS_ORIG_DYN:
12549 return _("NT_VMS_ORIG_DYN");
12550 case NT_VMS_PATCHTIME:
12551 return _("NT_VMS_PATCHTIME");
12552 default:
12553 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12554 return buff;
12555 }
12556}
12557
12558static int
12559print_ia64_vms_note (Elf_Internal_Note * pnote)
12560{
12561 switch (pnote->type)
12562 {
12563 case NT_VMS_MHD:
12564 if (pnote->descsz > 36)
12565 {
12566 size_t l = strlen (pnote->descdata + 34);
12567 printf (_(" Creation date : %.17s\n"), pnote->descdata);
12568 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
12569 printf (_(" Module name : %s\n"), pnote->descdata + 34);
12570 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
12571 }
12572 else
12573 printf (_(" Invalid size\n"));
12574 break;
12575 case NT_VMS_LNM:
12576 printf (_(" Language: %s\n"), pnote->descdata);
12577 break;
12578#ifdef BFD64
12579 case NT_VMS_FPMODE:
12580 printf (_(" FP mode: 0x%016" BFD_VMA_FMT "x\n"),
12581 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
12582 break;
12583 case NT_VMS_LINKTIME:
12584 printf (_(" Link time: "));
12585 print_vms_time
12586 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12587 printf ("\n");
12588 break;
12589 case NT_VMS_PATCHTIME:
12590 printf (_(" Patch time: "));
12591 print_vms_time
12592 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12593 printf ("\n");
12594 break;
12595 case NT_VMS_ORIG_DYN:
12596 printf (_(" Major id: %u, minor id: %u\n"),
12597 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
12598 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
12599 printf (_(" Manip date : "));
12600 print_vms_time
12601 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
12602 printf (_("\n"
12603 " Link flags : 0x%016" BFD_VMA_FMT "x\n"),
12604 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
12605 printf (_(" Header flags: 0x%08x\n"),
12606 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
12607 printf (_(" Image id : %s\n"), pnote->descdata + 32);
12608 break;
12609#endif
12610 case NT_VMS_IMGNAM:
12611 printf (_(" Image name: %s\n"), pnote->descdata);
12612 break;
12613 case NT_VMS_GSTNAM:
12614 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
12615 break;
12616 case NT_VMS_IMGID:
12617 printf (_(" Image id: %s\n"), pnote->descdata);
12618 break;
12619 case NT_VMS_LINKID:
12620 printf (_(" Linker id: %s\n"), pnote->descdata);
12621 break;
12622 default:
12623 break;
12624 }
12625 return 1;
12626}
12627
6d118b09
NC
12628/* Note that by the ELF standard, the name field is already null byte
12629 terminated, and namesz includes the terminating null byte.
12630 I.E. the value of namesz for the name "FSF" is 4.
12631
e3c8793a 12632 If the value of namesz is zero, there is no name present. */
779fe533 12633static int
2cf0635d 12634process_note (Elf_Internal_Note * pnote)
779fe533 12635{
2cf0635d
NC
12636 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
12637 const char * nt;
9437c45b
JT
12638
12639 if (pnote->namesz == 0)
1ec5cd37
NC
12640 /* If there is no note name, then use the default set of
12641 note type strings. */
12642 nt = get_note_type (pnote->type);
12643
1118d252
RM
12644 else if (const_strneq (pnote->namedata, "GNU"))
12645 /* GNU-specific object file notes. */
12646 nt = get_gnu_elf_note_type (pnote->type);
12647
0112cd26 12648 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
12649 /* NetBSD-specific core file notes. */
12650 nt = get_netbsd_elfcore_note_type (pnote->type);
12651
b15fa79e
AM
12652 else if (strneq (pnote->namedata, "SPU/", 4))
12653 {
12654 /* SPU-specific core file notes. */
12655 nt = pnote->namedata + 4;
12656 name = "SPU";
12657 }
12658
00e98fc7
TG
12659 else if (const_strneq (pnote->namedata, "IPF/VMS"))
12660 /* VMS/ia64-specific file notes. */
12661 nt = get_ia64_vms_note_type (pnote->type);
12662
70616151
TT
12663 else if (const_strneq (pnote->namedata, "stapsdt"))
12664 nt = get_stapsdt_note_type (pnote->type);
12665
9437c45b 12666 else
1ec5cd37
NC
12667 /* Don't recognize this note name; just use the default set of
12668 note type strings. */
00e98fc7 12669 nt = get_note_type (pnote->type);
9437c45b 12670
2aee03ae 12671 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
12672
12673 if (const_strneq (pnote->namedata, "IPF/VMS"))
12674 return print_ia64_vms_note (pnote);
664f90a3
TT
12675 else if (const_strneq (pnote->namedata, "GNU"))
12676 return print_gnu_note (pnote);
c6a9fc58
TT
12677 else if (const_strneq (pnote->namedata, "stapsdt"))
12678 return print_stapsdt_note (pnote);
00e98fc7
TG
12679 else
12680 return 1;
779fe533
NC
12681}
12682
6d118b09 12683
779fe533 12684static int
2cf0635d 12685process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 12686{
2cf0635d
NC
12687 Elf_External_Note * pnotes;
12688 Elf_External_Note * external;
b34976b6 12689 int res = 1;
103f02d3 12690
779fe533
NC
12691 if (length <= 0)
12692 return 0;
103f02d3 12693
3f5e193b
NC
12694 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
12695 _("notes"));
dd24e3da 12696 if (pnotes == NULL)
a6e9f9df 12697 return 0;
779fe533 12698
103f02d3 12699 external = pnotes;
103f02d3 12700
305c7206 12701 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 12702 (unsigned long) offset, (unsigned long) length);
2aee03ae 12703 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 12704
2cf0635d 12705 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 12706 {
2cf0635d 12707 Elf_External_Note * next;
b34976b6 12708 Elf_Internal_Note inote;
2cf0635d 12709 char * temp = NULL;
6d118b09 12710
00e98fc7
TG
12711 if (!is_ia64_vms ())
12712 {
12713 inote.type = BYTE_GET (external->type);
12714 inote.namesz = BYTE_GET (external->namesz);
12715 inote.namedata = external->name;
12716 inote.descsz = BYTE_GET (external->descsz);
12717 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
12718 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12719
12720 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
12721 }
12722 else
12723 {
12724 Elf64_External_VMS_Note *vms_external;
12725
12726 vms_external = (Elf64_External_VMS_Note *)external;
12727 inote.type = BYTE_GET (vms_external->type);
12728 inote.namesz = BYTE_GET (vms_external->namesz);
12729 inote.namedata = vms_external->name;
12730 inote.descsz = BYTE_GET (vms_external->descsz);
12731 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
12732 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12733
12734 next = (Elf_External_Note *)
12735 (inote.descdata + align_power (inote.descsz, 3));
12736 }
3e55a963 12737
dd24e3da
NC
12738 if ( ((char *) next > ((char *) pnotes) + length)
12739 || ((char *) next < (char *) pnotes))
3e55a963 12740 {
0fd3a477 12741 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 12742 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 12743 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
12744 inote.type, inote.namesz, inote.descsz);
12745 break;
12746 }
12747
12748 external = next;
6d118b09 12749
dd24e3da
NC
12750 /* Prevent out-of-bounds indexing. */
12751 if (inote.namedata + inote.namesz >= (char *) pnotes + length
12752 || inote.namedata + inote.namesz < inote.namedata)
12753 {
12754 warn (_("corrupt note found at offset %lx into core notes\n"),
12755 (unsigned long) ((char *) external - (char *) pnotes));
12756 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
12757 inote.type, inote.namesz, inote.descsz);
12758 break;
12759 }
12760
6d118b09
NC
12761 /* Verify that name is null terminated. It appears that at least
12762 one version of Linux (RedHat 6.0) generates corefiles that don't
12763 comply with the ELF spec by failing to include the null byte in
12764 namesz. */
12765 if (inote.namedata[inote.namesz] != '\0')
12766 {
3f5e193b 12767 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 12768
6d118b09
NC
12769 if (temp == NULL)
12770 {
12771 error (_("Out of memory\n"));
12772 res = 0;
12773 break;
12774 }
76da6bbe 12775
6d118b09
NC
12776 strncpy (temp, inote.namedata, inote.namesz);
12777 temp[inote.namesz] = 0;
76da6bbe 12778
6d118b09
NC
12779 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
12780 inote.namedata = temp;
12781 }
12782
12783 res &= process_note (& inote);
103f02d3 12784
6d118b09
NC
12785 if (temp != NULL)
12786 {
12787 free (temp);
12788 temp = NULL;
12789 }
779fe533
NC
12790 }
12791
12792 free (pnotes);
103f02d3 12793
779fe533
NC
12794 return res;
12795}
12796
12797static int
2cf0635d 12798process_corefile_note_segments (FILE * file)
779fe533 12799{
2cf0635d 12800 Elf_Internal_Phdr * segment;
b34976b6
AM
12801 unsigned int i;
12802 int res = 1;
103f02d3 12803
d93f0186 12804 if (! get_program_headers (file))
779fe533 12805 return 0;
103f02d3 12806
779fe533
NC
12807 for (i = 0, segment = program_headers;
12808 i < elf_header.e_phnum;
b34976b6 12809 i++, segment++)
779fe533
NC
12810 {
12811 if (segment->p_type == PT_NOTE)
103f02d3 12812 res &= process_corefile_note_segment (file,
30800947
NC
12813 (bfd_vma) segment->p_offset,
12814 (bfd_vma) segment->p_filesz);
779fe533 12815 }
103f02d3 12816
779fe533
NC
12817 return res;
12818}
12819
12820static int
2cf0635d 12821process_note_sections (FILE * file)
1ec5cd37 12822{
2cf0635d 12823 Elf_Internal_Shdr * section;
1ec5cd37
NC
12824 unsigned long i;
12825 int res = 1;
12826
12827 for (i = 0, section = section_headers;
12828 i < elf_header.e_shnum;
12829 i++, section++)
12830 if (section->sh_type == SHT_NOTE)
12831 res &= process_corefile_note_segment (file,
12832 (bfd_vma) section->sh_offset,
12833 (bfd_vma) section->sh_size);
12834
12835 return res;
12836}
12837
12838static int
2cf0635d 12839process_notes (FILE * file)
779fe533
NC
12840{
12841 /* If we have not been asked to display the notes then do nothing. */
12842 if (! do_notes)
12843 return 1;
103f02d3 12844
779fe533 12845 if (elf_header.e_type != ET_CORE)
1ec5cd37 12846 return process_note_sections (file);
103f02d3 12847
779fe533 12848 /* No program headers means no NOTE segment. */
1ec5cd37
NC
12849 if (elf_header.e_phnum > 0)
12850 return process_corefile_note_segments (file);
779fe533 12851
1ec5cd37
NC
12852 printf (_("No note segments present in the core file.\n"));
12853 return 1;
779fe533
NC
12854}
12855
252b5132 12856static int
2cf0635d 12857process_arch_specific (FILE * file)
252b5132 12858{
a952a375
NC
12859 if (! do_arch)
12860 return 1;
12861
252b5132
RH
12862 switch (elf_header.e_machine)
12863 {
11c1ff18
PB
12864 case EM_ARM:
12865 return process_arm_specific (file);
252b5132 12866 case EM_MIPS:
4fe85591 12867 case EM_MIPS_RS3_LE:
252b5132
RH
12868 return process_mips_specific (file);
12869 break;
34c8bcba
JM
12870 case EM_PPC:
12871 return process_power_specific (file);
12872 break;
59e6276b
JM
12873 case EM_TI_C6000:
12874 return process_tic6x_specific (file);
12875 break;
252b5132
RH
12876 default:
12877 break;
12878 }
12879 return 1;
12880}
12881
12882static int
2cf0635d 12883get_file_header (FILE * file)
252b5132 12884{
9ea033b2
NC
12885 /* Read in the identity array. */
12886 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
12887 return 0;
12888
9ea033b2 12889 /* Determine how to read the rest of the header. */
b34976b6 12890 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
12891 {
12892 default: /* fall through */
12893 case ELFDATANONE: /* fall through */
adab8cdc
AO
12894 case ELFDATA2LSB:
12895 byte_get = byte_get_little_endian;
12896 byte_put = byte_put_little_endian;
12897 break;
12898 case ELFDATA2MSB:
12899 byte_get = byte_get_big_endian;
12900 byte_put = byte_put_big_endian;
12901 break;
9ea033b2
NC
12902 }
12903
12904 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 12905 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
12906
12907 /* Read in the rest of the header. */
12908 if (is_32bit_elf)
12909 {
12910 Elf32_External_Ehdr ehdr32;
252b5132 12911
9ea033b2
NC
12912 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
12913 return 0;
103f02d3 12914
9ea033b2
NC
12915 elf_header.e_type = BYTE_GET (ehdr32.e_type);
12916 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
12917 elf_header.e_version = BYTE_GET (ehdr32.e_version);
12918 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
12919 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
12920 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
12921 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
12922 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
12923 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
12924 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
12925 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
12926 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
12927 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
12928 }
252b5132 12929 else
9ea033b2
NC
12930 {
12931 Elf64_External_Ehdr ehdr64;
a952a375
NC
12932
12933 /* If we have been compiled with sizeof (bfd_vma) == 4, then
12934 we will not be able to cope with the 64bit data found in
12935 64 ELF files. Detect this now and abort before we start
50c2245b 12936 overwriting things. */
a952a375
NC
12937 if (sizeof (bfd_vma) < 8)
12938 {
e3c8793a
NC
12939 error (_("This instance of readelf has been built without support for a\n\
1294064 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
12941 return 0;
12942 }
103f02d3 12943
9ea033b2
NC
12944 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
12945 return 0;
103f02d3 12946
9ea033b2
NC
12947 elf_header.e_type = BYTE_GET (ehdr64.e_type);
12948 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
12949 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
12950 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
12951 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
12952 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
12953 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
12954 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
12955 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
12956 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
12957 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
12958 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
12959 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
12960 }
252b5132 12961
7ece0d85
JJ
12962 if (elf_header.e_shoff)
12963 {
12964 /* There may be some extensions in the first section header. Don't
12965 bomb if we can't read it. */
12966 if (is_32bit_elf)
12967 get_32bit_section_headers (file, 1);
12968 else
12969 get_64bit_section_headers (file, 1);
12970 }
560f3c1c 12971
252b5132
RH
12972 return 1;
12973}
12974
fb52b2f4
NC
12975/* Process one ELF object file according to the command line options.
12976 This file may actually be stored in an archive. The file is
12977 positioned at the start of the ELF object. */
12978
ff78d6d6 12979static int
2cf0635d 12980process_object (char * file_name, FILE * file)
252b5132 12981{
252b5132
RH
12982 unsigned int i;
12983
252b5132
RH
12984 if (! get_file_header (file))
12985 {
12986 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 12987 return 1;
252b5132
RH
12988 }
12989
12990 /* Initialise per file variables. */
60bca95a 12991 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
12992 version_info[i] = 0;
12993
60bca95a 12994 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 12995 dynamic_info[i] = 0;
5115b233 12996 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
12997
12998 /* Process the file. */
12999 if (show_name)
13000 printf (_("\nFile: %s\n"), file_name);
13001
18bd398b
NC
13002 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13003 Note we do this even if cmdline_dump_sects is empty because we
13004 must make sure that the dump_sets array is zeroed out before each
13005 object file is processed. */
13006 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13007 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13008
13009 if (num_cmdline_dump_sects > 0)
13010 {
13011 if (num_dump_sects == 0)
13012 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13013 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13014
13015 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13016 memcpy (dump_sects, cmdline_dump_sects,
13017 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13018 }
d70c5fc7 13019
252b5132 13020 if (! process_file_header ())
fb52b2f4 13021 return 1;
252b5132 13022
d1f5c6e3 13023 if (! process_section_headers (file))
2f62977e 13024 {
d1f5c6e3
L
13025 /* Without loaded section headers we cannot process lots of
13026 things. */
2f62977e 13027 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13028
2f62977e 13029 if (! do_using_dynamic)
2c610e4b 13030 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13031 }
252b5132 13032
d1f5c6e3
L
13033 if (! process_section_groups (file))
13034 {
13035 /* Without loaded section groups we cannot process unwind. */
13036 do_unwind = 0;
13037 }
13038
2f62977e 13039 if (process_program_headers (file))
b2d38a17 13040 process_dynamic_section (file);
252b5132
RH
13041
13042 process_relocs (file);
13043
4d6ed7c8
NC
13044 process_unwind (file);
13045
252b5132
RH
13046 process_symbol_table (file);
13047
13048 process_syminfo (file);
13049
13050 process_version_sections (file);
13051
13052 process_section_contents (file);
f5842774 13053
1ec5cd37 13054 process_notes (file);
103f02d3 13055
047b2264
JJ
13056 process_gnu_liblist (file);
13057
252b5132
RH
13058 process_arch_specific (file);
13059
d93f0186
NC
13060 if (program_headers)
13061 {
13062 free (program_headers);
13063 program_headers = NULL;
13064 }
13065
252b5132
RH
13066 if (section_headers)
13067 {
13068 free (section_headers);
13069 section_headers = NULL;
13070 }
13071
13072 if (string_table)
13073 {
13074 free (string_table);
13075 string_table = NULL;
d40ac9bd 13076 string_table_length = 0;
252b5132
RH
13077 }
13078
13079 if (dynamic_strings)
13080 {
13081 free (dynamic_strings);
13082 dynamic_strings = NULL;
d79b3d50 13083 dynamic_strings_length = 0;
252b5132
RH
13084 }
13085
13086 if (dynamic_symbols)
13087 {
13088 free (dynamic_symbols);
13089 dynamic_symbols = NULL;
19936277 13090 num_dynamic_syms = 0;
252b5132
RH
13091 }
13092
13093 if (dynamic_syminfo)
13094 {
13095 free (dynamic_syminfo);
13096 dynamic_syminfo = NULL;
13097 }
ff78d6d6 13098
293c573e
MR
13099 if (dynamic_section)
13100 {
13101 free (dynamic_section);
13102 dynamic_section = NULL;
13103 }
13104
e4b17d5c
L
13105 if (section_headers_groups)
13106 {
13107 free (section_headers_groups);
13108 section_headers_groups = NULL;
13109 }
13110
13111 if (section_groups)
13112 {
2cf0635d
NC
13113 struct group_list * g;
13114 struct group_list * next;
e4b17d5c
L
13115
13116 for (i = 0; i < group_count; i++)
13117 {
13118 for (g = section_groups [i].root; g != NULL; g = next)
13119 {
13120 next = g->next;
13121 free (g);
13122 }
13123 }
13124
13125 free (section_groups);
13126 section_groups = NULL;
13127 }
13128
19e6b90e 13129 free_debug_memory ();
18bd398b 13130
ff78d6d6 13131 return 0;
252b5132
RH
13132}
13133
2cf0635d
NC
13134/* Process an ELF archive.
13135 On entry the file is positioned just after the ARMAG string. */
13136
13137static int
13138process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13139{
13140 struct archive_info arch;
13141 struct archive_info nested_arch;
13142 size_t got;
2cf0635d
NC
13143 int ret;
13144
13145 show_name = 1;
13146
13147 /* The ARCH structure is used to hold information about this archive. */
13148 arch.file_name = NULL;
13149 arch.file = NULL;
13150 arch.index_array = NULL;
13151 arch.sym_table = NULL;
13152 arch.longnames = NULL;
13153
13154 /* The NESTED_ARCH structure is used as a single-item cache of information
13155 about a nested archive (when members of a thin archive reside within
13156 another regular archive file). */
13157 nested_arch.file_name = NULL;
13158 nested_arch.file = NULL;
13159 nested_arch.index_array = NULL;
13160 nested_arch.sym_table = NULL;
13161 nested_arch.longnames = NULL;
13162
13163 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13164 {
13165 ret = 1;
13166 goto out;
4145f1d5 13167 }
fb52b2f4 13168
4145f1d5
NC
13169 if (do_archive_index)
13170 {
2cf0635d 13171 if (arch.sym_table == NULL)
4145f1d5
NC
13172 error (_("%s: unable to dump the index as none was found\n"), file_name);
13173 else
13174 {
2cf0635d 13175 unsigned int i, l;
4145f1d5
NC
13176 unsigned long current_pos;
13177
13178 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 13179 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
13180 current_pos = ftell (file);
13181
2cf0635d 13182 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13183 {
2cf0635d
NC
13184 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13185 {
13186 char * member_name;
4145f1d5 13187
2cf0635d
NC
13188 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13189
13190 if (member_name != NULL)
13191 {
13192 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13193
13194 if (qualified_name != NULL)
13195 {
13196 printf (_("Binary %s contains:\n"), qualified_name);
13197 free (qualified_name);
13198 }
4145f1d5
NC
13199 }
13200 }
2cf0635d
NC
13201
13202 if (l >= arch.sym_size)
4145f1d5
NC
13203 {
13204 error (_("%s: end of the symbol table reached before the end of the index\n"),
13205 file_name);
cb8f3167 13206 break;
4145f1d5 13207 }
2cf0635d
NC
13208 printf ("\t%s\n", arch.sym_table + l);
13209 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13210 }
13211
2cf0635d
NC
13212 if (l & 01)
13213 ++l;
13214 if (l < arch.sym_size)
4145f1d5
NC
13215 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
13216 file_name);
13217
4145f1d5
NC
13218 if (fseek (file, current_pos, SEEK_SET) != 0)
13219 {
13220 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13221 ret = 1;
13222 goto out;
4145f1d5 13223 }
fb52b2f4 13224 }
4145f1d5
NC
13225
13226 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13227 && !do_segments && !do_header && !do_dump && !do_version
13228 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13229 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13230 {
13231 ret = 0; /* Archive index only. */
13232 goto out;
13233 }
fb52b2f4
NC
13234 }
13235
d989285c 13236 ret = 0;
fb52b2f4
NC
13237
13238 while (1)
13239 {
2cf0635d
NC
13240 char * name;
13241 size_t namelen;
13242 char * qualified_name;
13243
13244 /* Read the next archive header. */
13245 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13246 {
13247 error (_("%s: failed to seek to next archive header\n"), file_name);
13248 return 1;
13249 }
13250 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13251 if (got != sizeof arch.arhdr)
13252 {
13253 if (got == 0)
13254 break;
13255 error (_("%s: failed to read archive header\n"), file_name);
13256 ret = 1;
13257 break;
13258 }
13259 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13260 {
13261 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13262 ret = 1;
13263 break;
13264 }
13265
13266 arch.next_arhdr_offset += sizeof arch.arhdr;
13267
13268 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13269 if (archive_file_size & 01)
13270 ++archive_file_size;
13271
13272 name = get_archive_member_name (&arch, &nested_arch);
13273 if (name == NULL)
fb52b2f4 13274 {
0fd3a477 13275 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13276 ret = 1;
13277 break;
fb52b2f4 13278 }
2cf0635d 13279 namelen = strlen (name);
fb52b2f4 13280
2cf0635d
NC
13281 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13282 if (qualified_name == NULL)
fb52b2f4 13283 {
2cf0635d 13284 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13285 ret = 1;
13286 break;
fb52b2f4
NC
13287 }
13288
2cf0635d
NC
13289 if (is_thin_archive && arch.nested_member_origin == 0)
13290 {
13291 /* This is a proxy for an external member of a thin archive. */
13292 FILE * member_file;
13293 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13294 if (member_file_name == NULL)
13295 {
13296 ret = 1;
13297 break;
13298 }
13299
13300 member_file = fopen (member_file_name, "rb");
13301 if (member_file == NULL)
13302 {
13303 error (_("Input file '%s' is not readable.\n"), member_file_name);
13304 free (member_file_name);
13305 ret = 1;
13306 break;
13307 }
13308
13309 archive_file_offset = arch.nested_member_origin;
13310
13311 ret |= process_object (qualified_name, member_file);
13312
13313 fclose (member_file);
13314 free (member_file_name);
13315 }
13316 else if (is_thin_archive)
13317 {
13318 /* This is a proxy for a member of a nested archive. */
13319 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
13320
13321 /* The nested archive file will have been opened and setup by
13322 get_archive_member_name. */
13323 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
13324 {
13325 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
13326 ret = 1;
13327 break;
13328 }
13329
13330 ret |= process_object (qualified_name, nested_arch.file);
13331 }
13332 else
13333 {
13334 archive_file_offset = arch.next_arhdr_offset;
13335 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 13336
2cf0635d
NC
13337 ret |= process_object (qualified_name, file);
13338 }
fb52b2f4 13339
2b52916e
L
13340 if (dump_sects != NULL)
13341 {
13342 free (dump_sects);
13343 dump_sects = NULL;
13344 num_dump_sects = 0;
13345 }
13346
2cf0635d 13347 free (qualified_name);
fb52b2f4
NC
13348 }
13349
4145f1d5 13350 out:
2cf0635d
NC
13351 if (nested_arch.file != NULL)
13352 fclose (nested_arch.file);
13353 release_archive (&nested_arch);
13354 release_archive (&arch);
fb52b2f4 13355
d989285c 13356 return ret;
fb52b2f4
NC
13357}
13358
13359static int
2cf0635d 13360process_file (char * file_name)
fb52b2f4 13361{
2cf0635d 13362 FILE * file;
fb52b2f4
NC
13363 struct stat statbuf;
13364 char armag[SARMAG];
13365 int ret;
13366
13367 if (stat (file_name, &statbuf) < 0)
13368 {
f24ddbdd
NC
13369 if (errno == ENOENT)
13370 error (_("'%s': No such file\n"), file_name);
13371 else
13372 error (_("Could not locate '%s'. System error message: %s\n"),
13373 file_name, strerror (errno));
13374 return 1;
13375 }
13376
13377 if (! S_ISREG (statbuf.st_mode))
13378 {
13379 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
13380 return 1;
13381 }
13382
13383 file = fopen (file_name, "rb");
13384 if (file == NULL)
13385 {
f24ddbdd 13386 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
13387 return 1;
13388 }
13389
13390 if (fread (armag, SARMAG, 1, file) != 1)
13391 {
4145f1d5 13392 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
13393 fclose (file);
13394 return 1;
13395 }
13396
13397 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
13398 ret = process_archive (file_name, file, FALSE);
13399 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
13400 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
13401 else
13402 {
4145f1d5
NC
13403 if (do_archive_index)
13404 error (_("File %s is not an archive so its index cannot be displayed.\n"),
13405 file_name);
13406
fb52b2f4
NC
13407 rewind (file);
13408 archive_file_size = archive_file_offset = 0;
13409 ret = process_object (file_name, file);
13410 }
13411
13412 fclose (file);
13413
13414 return ret;
13415}
13416
252b5132
RH
13417#ifdef SUPPORT_DISASSEMBLY
13418/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 13419 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 13420 symbols. */
252b5132
RH
13421
13422void
2cf0635d 13423print_address (unsigned int addr, FILE * outfile)
252b5132
RH
13424{
13425 fprintf (outfile,"0x%8.8x", addr);
13426}
13427
e3c8793a 13428/* Needed by the i386 disassembler. */
252b5132
RH
13429void
13430db_task_printsym (unsigned int addr)
13431{
13432 print_address (addr, stderr);
13433}
13434#endif
13435
13436int
2cf0635d 13437main (int argc, char ** argv)
252b5132 13438{
ff78d6d6
L
13439 int err;
13440
252b5132
RH
13441#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
13442 setlocale (LC_MESSAGES, "");
3882b010
L
13443#endif
13444#if defined (HAVE_SETLOCALE)
13445 setlocale (LC_CTYPE, "");
252b5132
RH
13446#endif
13447 bindtextdomain (PACKAGE, LOCALEDIR);
13448 textdomain (PACKAGE);
13449
869b9d07
MM
13450 expandargv (&argc, &argv);
13451
252b5132
RH
13452 parse_args (argc, argv);
13453
18bd398b 13454 if (num_dump_sects > 0)
59f14fc0 13455 {
18bd398b 13456 /* Make a copy of the dump_sects array. */
3f5e193b
NC
13457 cmdline_dump_sects = (dump_type *)
13458 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 13459 if (cmdline_dump_sects == NULL)
591a748a 13460 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
13461 else
13462 {
09c11c86
NC
13463 memcpy (cmdline_dump_sects, dump_sects,
13464 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
13465 num_cmdline_dump_sects = num_dump_sects;
13466 }
13467 }
13468
18bd398b
NC
13469 if (optind < (argc - 1))
13470 show_name = 1;
13471
ff78d6d6 13472 err = 0;
252b5132 13473 while (optind < argc)
18bd398b 13474 err |= process_file (argv[optind++]);
252b5132
RH
13475
13476 if (dump_sects != NULL)
13477 free (dump_sects);
59f14fc0
AS
13478 if (cmdline_dump_sects != NULL)
13479 free (cmdline_dump_sects);
252b5132 13480
ff78d6d6 13481 return err;
252b5132 13482}