]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
gas/
[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:
7a9068fe 610 case EM_K1OM:
e9f53129
AM
611 case EM_XSTORMY16:
612 case EM_XTENSA:
613 case EM_XTENSA_OLD:
7ba29e2a
NC
614 case EM_MICROBLAZE:
615 case EM_MICROBLAZE_OLD:
9c19a809 616 return TRUE;
103f02d3 617
e9f53129
AM
618 case EM_68HC05:
619 case EM_68HC08:
620 case EM_68HC11:
621 case EM_68HC16:
622 case EM_FX66:
623 case EM_ME16:
d1133906 624 case EM_MMA:
d1133906
NC
625 case EM_NCPU:
626 case EM_NDR1:
e9f53129 627 case EM_PCP:
d1133906 628 case EM_ST100:
e9f53129 629 case EM_ST19:
d1133906 630 case EM_ST7:
e9f53129
AM
631 case EM_ST9PLUS:
632 case EM_STARCORE:
d1133906 633 case EM_SVX:
e9f53129 634 case EM_TINYJ:
9c19a809
NC
635 default:
636 warn (_("Don't know about relocations on this machine architecture\n"));
637 return FALSE;
638 }
639}
252b5132 640
9c19a809 641static int
2cf0635d 642slurp_rela_relocs (FILE * file,
d3ba0551
AM
643 unsigned long rel_offset,
644 unsigned long rel_size,
2cf0635d
NC
645 Elf_Internal_Rela ** relasp,
646 unsigned long * nrelasp)
9c19a809 647{
2cf0635d 648 Elf_Internal_Rela * relas;
4d6ed7c8
NC
649 unsigned long nrelas;
650 unsigned int i;
252b5132 651
4d6ed7c8
NC
652 if (is_32bit_elf)
653 {
2cf0635d 654 Elf32_External_Rela * erelas;
103f02d3 655
3f5e193b
NC
656 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
657 rel_size, _("relocs"));
a6e9f9df
AM
658 if (!erelas)
659 return 0;
252b5132 660
4d6ed7c8 661 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 662
3f5e193b
NC
663 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
664 sizeof (Elf_Internal_Rela));
103f02d3 665
4d6ed7c8
NC
666 if (relas == NULL)
667 {
c256ffe7 668 free (erelas);
591a748a 669 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
670 return 0;
671 }
103f02d3 672
4d6ed7c8
NC
673 for (i = 0; i < nrelas; i++)
674 {
675 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
676 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 677 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 678 }
103f02d3 679
4d6ed7c8
NC
680 free (erelas);
681 }
682 else
683 {
2cf0635d 684 Elf64_External_Rela * erelas;
103f02d3 685
3f5e193b
NC
686 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
687 rel_size, _("relocs"));
a6e9f9df
AM
688 if (!erelas)
689 return 0;
4d6ed7c8
NC
690
691 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 692
3f5e193b
NC
693 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
694 sizeof (Elf_Internal_Rela));
103f02d3 695
4d6ed7c8
NC
696 if (relas == NULL)
697 {
c256ffe7 698 free (erelas);
591a748a 699 error (_("out of memory parsing relocs\n"));
4d6ed7c8 700 return 0;
9c19a809 701 }
4d6ed7c8
NC
702
703 for (i = 0; i < nrelas; i++)
9c19a809 704 {
66543521
AM
705 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
706 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 707 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
708
709 /* The #ifdef BFD64 below is to prevent a compile time
710 warning. We know that if we do not have a 64 bit data
711 type that we will never execute this code anyway. */
712#ifdef BFD64
713 if (elf_header.e_machine == EM_MIPS
714 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
715 {
716 /* In little-endian objects, r_info isn't really a
717 64-bit little-endian value: it has a 32-bit
718 little-endian symbol index followed by four
719 individual byte fields. Reorder INFO
720 accordingly. */
91d6fa6a
NC
721 bfd_vma inf = relas[i].r_info;
722 inf = (((inf & 0xffffffff) << 32)
723 | ((inf >> 56) & 0xff)
724 | ((inf >> 40) & 0xff00)
725 | ((inf >> 24) & 0xff0000)
726 | ((inf >> 8) & 0xff000000));
727 relas[i].r_info = inf;
861fb55a
DJ
728 }
729#endif /* BFD64 */
4d6ed7c8 730 }
103f02d3 731
4d6ed7c8
NC
732 free (erelas);
733 }
734 *relasp = relas;
735 *nrelasp = nrelas;
736 return 1;
737}
103f02d3 738
4d6ed7c8 739static int
2cf0635d 740slurp_rel_relocs (FILE * file,
d3ba0551
AM
741 unsigned long rel_offset,
742 unsigned long rel_size,
2cf0635d
NC
743 Elf_Internal_Rela ** relsp,
744 unsigned long * nrelsp)
4d6ed7c8 745{
2cf0635d 746 Elf_Internal_Rela * rels;
4d6ed7c8
NC
747 unsigned long nrels;
748 unsigned int i;
103f02d3 749
4d6ed7c8
NC
750 if (is_32bit_elf)
751 {
2cf0635d 752 Elf32_External_Rel * erels;
103f02d3 753
3f5e193b
NC
754 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
755 rel_size, _("relocs"));
a6e9f9df
AM
756 if (!erels)
757 return 0;
103f02d3 758
4d6ed7c8 759 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 760
3f5e193b 761 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 762
4d6ed7c8
NC
763 if (rels == NULL)
764 {
c256ffe7 765 free (erels);
591a748a 766 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
767 return 0;
768 }
769
770 for (i = 0; i < nrels; i++)
771 {
772 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
773 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 774 rels[i].r_addend = 0;
9ea033b2 775 }
4d6ed7c8
NC
776
777 free (erels);
9c19a809
NC
778 }
779 else
780 {
2cf0635d 781 Elf64_External_Rel * erels;
9ea033b2 782
3f5e193b
NC
783 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
784 rel_size, _("relocs"));
a6e9f9df
AM
785 if (!erels)
786 return 0;
103f02d3 787
4d6ed7c8 788 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 789
3f5e193b 790 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 791
4d6ed7c8 792 if (rels == NULL)
9c19a809 793 {
c256ffe7 794 free (erels);
591a748a 795 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
796 return 0;
797 }
103f02d3 798
4d6ed7c8
NC
799 for (i = 0; i < nrels; i++)
800 {
66543521
AM
801 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
802 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 803 rels[i].r_addend = 0;
861fb55a
DJ
804
805 /* The #ifdef BFD64 below is to prevent a compile time
806 warning. We know that if we do not have a 64 bit data
807 type that we will never execute this code anyway. */
808#ifdef BFD64
809 if (elf_header.e_machine == EM_MIPS
810 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
811 {
812 /* In little-endian objects, r_info isn't really a
813 64-bit little-endian value: it has a 32-bit
814 little-endian symbol index followed by four
815 individual byte fields. Reorder INFO
816 accordingly. */
91d6fa6a
NC
817 bfd_vma inf = rels[i].r_info;
818 inf = (((inf & 0xffffffff) << 32)
819 | ((inf >> 56) & 0xff)
820 | ((inf >> 40) & 0xff00)
821 | ((inf >> 24) & 0xff0000)
822 | ((inf >> 8) & 0xff000000));
823 rels[i].r_info = inf;
861fb55a
DJ
824 }
825#endif /* BFD64 */
4d6ed7c8 826 }
103f02d3 827
4d6ed7c8
NC
828 free (erels);
829 }
830 *relsp = rels;
831 *nrelsp = nrels;
832 return 1;
833}
103f02d3 834
aca88567
NC
835/* Returns the reloc type extracted from the reloc info field. */
836
837static unsigned int
838get_reloc_type (bfd_vma reloc_info)
839{
840 if (is_32bit_elf)
841 return ELF32_R_TYPE (reloc_info);
842
843 switch (elf_header.e_machine)
844 {
845 case EM_MIPS:
846 /* Note: We assume that reloc_info has already been adjusted for us. */
847 return ELF64_MIPS_R_TYPE (reloc_info);
848
849 case EM_SPARCV9:
850 return ELF64_R_TYPE_ID (reloc_info);
851
852 default:
853 return ELF64_R_TYPE (reloc_info);
854 }
855}
856
857/* Return the symbol index extracted from the reloc info field. */
858
859static bfd_vma
860get_reloc_symindex (bfd_vma reloc_info)
861{
862 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
863}
864
d3ba0551
AM
865/* Display the contents of the relocation data found at the specified
866 offset. */
ee42cf8c 867
41e92641 868static void
2cf0635d 869dump_relocations (FILE * file,
d3ba0551
AM
870 unsigned long rel_offset,
871 unsigned long rel_size,
2cf0635d 872 Elf_Internal_Sym * symtab,
d3ba0551 873 unsigned long nsyms,
2cf0635d 874 char * strtab,
d79b3d50 875 unsigned long strtablen,
d3ba0551 876 int is_rela)
4d6ed7c8 877{
b34976b6 878 unsigned int i;
2cf0635d 879 Elf_Internal_Rela * rels;
103f02d3 880
4d6ed7c8
NC
881 if (is_rela == UNKNOWN)
882 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 883
4d6ed7c8
NC
884 if (is_rela)
885 {
c8286bd1 886 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 887 return;
4d6ed7c8
NC
888 }
889 else
890 {
891 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 892 return;
252b5132
RH
893 }
894
410f7a12
L
895 if (is_32bit_elf)
896 {
897 if (is_rela)
2c71103e
NC
898 {
899 if (do_wide)
900 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
901 else
902 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
903 }
410f7a12 904 else
2c71103e
NC
905 {
906 if (do_wide)
907 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
908 else
909 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
910 }
410f7a12 911 }
252b5132 912 else
410f7a12
L
913 {
914 if (is_rela)
2c71103e
NC
915 {
916 if (do_wide)
8beeaeb7 917 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
918 else
919 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
920 }
410f7a12 921 else
2c71103e
NC
922 {
923 if (do_wide)
8beeaeb7 924 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
925 else
926 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
927 }
410f7a12 928 }
252b5132
RH
929
930 for (i = 0; i < rel_size; i++)
931 {
2cf0635d 932 const char * rtype;
b34976b6 933 bfd_vma offset;
91d6fa6a 934 bfd_vma inf;
b34976b6
AM
935 bfd_vma symtab_index;
936 bfd_vma type;
103f02d3 937
b34976b6 938 offset = rels[i].r_offset;
91d6fa6a 939 inf = rels[i].r_info;
103f02d3 940
91d6fa6a
NC
941 type = get_reloc_type (inf);
942 symtab_index = get_reloc_symindex (inf);
252b5132 943
410f7a12
L
944 if (is_32bit_elf)
945 {
39dbeff8
AM
946 printf ("%8.8lx %8.8lx ",
947 (unsigned long) offset & 0xffffffff,
91d6fa6a 948 (unsigned long) inf & 0xffffffff);
410f7a12
L
949 }
950 else
951 {
39dbeff8
AM
952#if BFD_HOST_64BIT_LONG
953 printf (do_wide
954 ? "%16.16lx %16.16lx "
955 : "%12.12lx %12.12lx ",
91d6fa6a 956 offset, inf);
39dbeff8 957#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 958#ifndef __MSVCRT__
39dbeff8
AM
959 printf (do_wide
960 ? "%16.16llx %16.16llx "
961 : "%12.12llx %12.12llx ",
91d6fa6a 962 offset, inf);
6e3d6dc1
NC
963#else
964 printf (do_wide
965 ? "%16.16I64x %16.16I64x "
966 : "%12.12I64x %12.12I64x ",
91d6fa6a 967 offset, inf);
6e3d6dc1 968#endif
39dbeff8 969#else
2c71103e
NC
970 printf (do_wide
971 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
972 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
973 _bfd_int64_high (offset),
974 _bfd_int64_low (offset),
91d6fa6a
NC
975 _bfd_int64_high (inf),
976 _bfd_int64_low (inf));
9ea033b2 977#endif
410f7a12 978 }
103f02d3 979
252b5132
RH
980 switch (elf_header.e_machine)
981 {
982 default:
983 rtype = NULL;
984 break;
985
2b0337b0 986 case EM_M32R:
252b5132 987 case EM_CYGNUS_M32R:
9ea033b2 988 rtype = elf_m32r_reloc_type (type);
252b5132
RH
989 break;
990
991 case EM_386:
992 case EM_486:
9ea033b2 993 rtype = elf_i386_reloc_type (type);
252b5132
RH
994 break;
995
ba2685cc
AM
996 case EM_68HC11:
997 case EM_68HC12:
998 rtype = elf_m68hc11_reloc_type (type);
999 break;
75751cd9 1000
252b5132 1001 case EM_68K:
9ea033b2 1002 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1003 break;
1004
63fcb9e9 1005 case EM_960:
9ea033b2 1006 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1007 break;
1008
adde6300 1009 case EM_AVR:
2b0337b0 1010 case EM_AVR_OLD:
adde6300
AM
1011 rtype = elf_avr_reloc_type (type);
1012 break;
1013
9ea033b2
NC
1014 case EM_OLD_SPARCV9:
1015 case EM_SPARC32PLUS:
1016 case EM_SPARCV9:
252b5132 1017 case EM_SPARC:
9ea033b2 1018 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1019 break;
1020
e9f53129
AM
1021 case EM_SPU:
1022 rtype = elf_spu_reloc_type (type);
1023 break;
1024
2b0337b0 1025 case EM_V850:
252b5132 1026 case EM_CYGNUS_V850:
9ea033b2 1027 rtype = v850_reloc_type (type);
252b5132
RH
1028 break;
1029
2b0337b0 1030 case EM_D10V:
252b5132 1031 case EM_CYGNUS_D10V:
9ea033b2 1032 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1033 break;
1034
2b0337b0 1035 case EM_D30V:
252b5132 1036 case EM_CYGNUS_D30V:
9ea033b2 1037 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1038 break;
1039
d172d4ba
NC
1040 case EM_DLX:
1041 rtype = elf_dlx_reloc_type (type);
1042 break;
1043
252b5132 1044 case EM_SH:
9ea033b2 1045 rtype = elf_sh_reloc_type (type);
252b5132
RH
1046 break;
1047
2b0337b0 1048 case EM_MN10300:
252b5132 1049 case EM_CYGNUS_MN10300:
9ea033b2 1050 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1051 break;
1052
2b0337b0 1053 case EM_MN10200:
252b5132 1054 case EM_CYGNUS_MN10200:
9ea033b2 1055 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1056 break;
1057
2b0337b0 1058 case EM_FR30:
252b5132 1059 case EM_CYGNUS_FR30:
9ea033b2 1060 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1061 break;
1062
ba2685cc
AM
1063 case EM_CYGNUS_FRV:
1064 rtype = elf_frv_reloc_type (type);
1065 break;
5c70f934 1066
252b5132 1067 case EM_MCORE:
9ea033b2 1068 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1069 break;
1070
3c3bdf30
NC
1071 case EM_MMIX:
1072 rtype = elf_mmix_reloc_type (type);
1073 break;
1074
5506d11a
AM
1075 case EM_MOXIE:
1076 rtype = elf_moxie_reloc_type (type);
1077 break;
1078
2469cfa2
NC
1079 case EM_MSP430:
1080 case EM_MSP430_OLD:
1081 rtype = elf_msp430_reloc_type (type);
1082 break;
1083
252b5132 1084 case EM_PPC:
9ea033b2 1085 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1086 break;
1087
c833c019
AM
1088 case EM_PPC64:
1089 rtype = elf_ppc64_reloc_type (type);
1090 break;
1091
252b5132 1092 case EM_MIPS:
4fe85591 1093 case EM_MIPS_RS3_LE:
9ea033b2 1094 rtype = elf_mips_reloc_type (type);
252b5132
RH
1095 break;
1096
1097 case EM_ALPHA:
9ea033b2 1098 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1099 break;
1100
1101 case EM_ARM:
9ea033b2 1102 rtype = elf_arm_reloc_type (type);
252b5132
RH
1103 break;
1104
584da044 1105 case EM_ARC:
9ea033b2 1106 rtype = elf_arc_reloc_type (type);
252b5132
RH
1107 break;
1108
1109 case EM_PARISC:
69e617ca 1110 rtype = elf_hppa_reloc_type (type);
252b5132 1111 break;
7d466069 1112
b8720f9d
JL
1113 case EM_H8_300:
1114 case EM_H8_300H:
1115 case EM_H8S:
1116 rtype = elf_h8_reloc_type (type);
1117 break;
1118
3b16e843
NC
1119 case EM_OPENRISC:
1120 case EM_OR32:
1121 rtype = elf_or32_reloc_type (type);
1122 break;
1123
7d466069 1124 case EM_PJ:
2b0337b0 1125 case EM_PJ_OLD:
7d466069
ILT
1126 rtype = elf_pj_reloc_type (type);
1127 break;
800eeca4
JW
1128 case EM_IA_64:
1129 rtype = elf_ia64_reloc_type (type);
1130 break;
1b61cf92
HPN
1131
1132 case EM_CRIS:
1133 rtype = elf_cris_reloc_type (type);
1134 break;
535c37ff
JE
1135
1136 case EM_860:
1137 rtype = elf_i860_reloc_type (type);
1138 break;
bcedfee6
NC
1139
1140 case EM_X86_64:
8a9036a4 1141 case EM_L1OM:
7a9068fe 1142 case EM_K1OM:
bcedfee6
NC
1143 rtype = elf_x86_64_reloc_type (type);
1144 break;
a85d7ed0 1145
35b1837e
AM
1146 case EM_S370:
1147 rtype = i370_reloc_type (type);
1148 break;
1149
53c7db4b
KH
1150 case EM_S390_OLD:
1151 case EM_S390:
1152 rtype = elf_s390_reloc_type (type);
1153 break;
93fbbb04 1154
1c0d3aa6
NC
1155 case EM_SCORE:
1156 rtype = elf_score_reloc_type (type);
1157 break;
1158
93fbbb04
GK
1159 case EM_XSTORMY16:
1160 rtype = elf_xstormy16_reloc_type (type);
1161 break;
179d3252 1162
1fe1f39c
NC
1163 case EM_CRX:
1164 rtype = elf_crx_reloc_type (type);
1165 break;
1166
179d3252
JT
1167 case EM_VAX:
1168 rtype = elf_vax_reloc_type (type);
1169 break;
1e4cf259
NC
1170
1171 case EM_IP2K:
1172 case EM_IP2K_OLD:
1173 rtype = elf_ip2k_reloc_type (type);
1174 break;
3b36097d
SC
1175
1176 case EM_IQ2000:
1177 rtype = elf_iq2000_reloc_type (type);
1178 break;
88da6820
NC
1179
1180 case EM_XTENSA_OLD:
1181 case EM_XTENSA:
1182 rtype = elf_xtensa_reloc_type (type);
1183 break;
a34e3ecb 1184
84e94c90
NC
1185 case EM_LATTICEMICO32:
1186 rtype = elf_lm32_reloc_type (type);
1187 break;
1188
ff7eeb89 1189 case EM_M32C_OLD:
49f58d10
JB
1190 case EM_M32C:
1191 rtype = elf_m32c_reloc_type (type);
1192 break;
1193
d031aafb
NS
1194 case EM_MT:
1195 rtype = elf_mt_reloc_type (type);
a34e3ecb 1196 break;
1d65ded4
CM
1197
1198 case EM_BLACKFIN:
1199 rtype = elf_bfin_reloc_type (type);
1200 break;
15ab5209
DB
1201
1202 case EM_CYGNUS_MEP:
1203 rtype = elf_mep_reloc_type (type);
1204 break;
60bca95a
NC
1205
1206 case EM_CR16:
6c03b1ed 1207 case EM_CR16_OLD:
60bca95a
NC
1208 rtype = elf_cr16_reloc_type (type);
1209 break;
dd24e3da 1210
7ba29e2a
NC
1211 case EM_MICROBLAZE:
1212 case EM_MICROBLAZE_OLD:
1213 rtype = elf_microblaze_reloc_type (type);
1214 break;
c7927a3c
NC
1215
1216 case EM_RX:
1217 rtype = elf_rx_reloc_type (type);
1218 break;
c29aca4a
NC
1219
1220 case EM_XC16X:
1221 case EM_C166:
1222 rtype = elf_xc16x_reloc_type (type);
1223 break;
40b36596
JM
1224
1225 case EM_TI_C6000:
1226 rtype = elf_tic6x_reloc_type (type);
1227 break;
aa137e4d
NC
1228
1229 case EM_TILEGX:
1230 rtype = elf_tilegx_reloc_type (type);
1231 break;
1232
1233 case EM_TILEPRO:
1234 rtype = elf_tilepro_reloc_type (type);
1235 break;
252b5132
RH
1236 }
1237
1238 if (rtype == NULL)
39dbeff8 1239 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1240 else
8beeaeb7 1241 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1242
7ace3541 1243 if (elf_header.e_machine == EM_ALPHA
157c2599 1244 && rtype != NULL
7ace3541
RH
1245 && streq (rtype, "R_ALPHA_LITUSE")
1246 && is_rela)
1247 {
1248 switch (rels[i].r_addend)
1249 {
1250 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1251 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1252 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1253 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1254 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1255 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1256 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1257 default: rtype = NULL;
1258 }
1259 if (rtype)
1260 printf (" (%s)", rtype);
1261 else
1262 {
1263 putchar (' ');
1264 printf (_("<unknown addend: %lx>"),
1265 (unsigned long) rels[i].r_addend);
1266 }
1267 }
1268 else if (symtab_index)
252b5132 1269 {
af3fc3bc 1270 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1271 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1272 else
19936277 1273 {
2cf0635d 1274 Elf_Internal_Sym * psym;
19936277 1275
af3fc3bc 1276 psym = symtab + symtab_index;
103f02d3 1277
af3fc3bc 1278 printf (" ");
171191ba 1279
d8045f23
NC
1280 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1281 {
1282 const char * name;
1283 unsigned int len;
1284 unsigned int width = is_32bit_elf ? 8 : 14;
1285
1286 /* Relocations against GNU_IFUNC symbols do not use the value
1287 of the symbol as the address to relocate against. Instead
1288 they invoke the function named by the symbol and use its
1289 result as the address for relocation.
1290
1291 To indicate this to the user, do not display the value of
1292 the symbol in the "Symbols's Value" field. Instead show
1293 its name followed by () as a hint that the symbol is
1294 invoked. */
1295
1296 if (strtab == NULL
1297 || psym->st_name == 0
1298 || psym->st_name >= strtablen)
1299 name = "??";
1300 else
1301 name = strtab + psym->st_name;
1302
1303 len = print_symbol (width, name);
1304 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1305 }
1306 else
1307 {
1308 print_vma (psym->st_value, LONG_HEX);
171191ba 1309
d8045f23
NC
1310 printf (is_32bit_elf ? " " : " ");
1311 }
103f02d3 1312
af3fc3bc 1313 if (psym->st_name == 0)
f1ef08cb 1314 {
2cf0635d 1315 const char * sec_name = "<null>";
f1ef08cb
AM
1316 char name_buf[40];
1317
1318 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1319 {
4fbb74a6
AM
1320 if (psym->st_shndx < elf_header.e_shnum)
1321 sec_name
1322 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1323 else if (psym->st_shndx == SHN_ABS)
1324 sec_name = "ABS";
1325 else if (psym->st_shndx == SHN_COMMON)
1326 sec_name = "COMMON";
ac145307
BS
1327 else if ((elf_header.e_machine == EM_MIPS
1328 && psym->st_shndx == SHN_MIPS_SCOMMON)
1329 || (elf_header.e_machine == EM_TI_C6000
1330 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1331 sec_name = "SCOMMON";
1332 else if (elf_header.e_machine == EM_MIPS
1333 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1334 sec_name = "SUNDEF";
8a9036a4 1335 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1336 || elf_header.e_machine == EM_L1OM
1337 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1338 && psym->st_shndx == SHN_X86_64_LCOMMON)
1339 sec_name = "LARGE_COMMON";
9ce701e2
L
1340 else if (elf_header.e_machine == EM_IA_64
1341 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1342 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1343 sec_name = "ANSI_COM";
28f997cf 1344 else if (is_ia64_vms ()
148b93f2
NC
1345 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1346 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1347 else
1348 {
1349 sprintf (name_buf, "<section 0x%x>",
1350 (unsigned int) psym->st_shndx);
1351 sec_name = name_buf;
1352 }
1353 }
1354 print_symbol (22, sec_name);
1355 }
af3fc3bc 1356 else if (strtab == NULL)
d79b3d50 1357 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1358 else if (psym->st_name >= strtablen)
d79b3d50 1359 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1360 else
2c71103e 1361 print_symbol (22, strtab + psym->st_name);
103f02d3 1362
af3fc3bc 1363 if (is_rela)
171191ba 1364 {
598aaa76 1365 bfd_signed_vma off = rels[i].r_addend;
171191ba 1366
91d6fa6a 1367 if (off < 0)
598aaa76 1368 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1369 else
598aaa76 1370 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1371 }
19936277 1372 }
252b5132 1373 }
1b228002 1374 else if (is_rela)
f7a99963 1375 {
18bd398b
NC
1376 printf ("%*c", is_32bit_elf ?
1377 (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
c8286bd1 1378 print_vma (rels[i].r_addend, LONG_HEX);
f7a99963 1379 }
252b5132 1380
157c2599
NC
1381 if (elf_header.e_machine == EM_SPARCV9
1382 && rtype != NULL
1383 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1384 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1385
252b5132 1386 putchar ('\n');
2c71103e 1387
aca88567 1388#ifdef BFD64
53c7db4b 1389 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1390 {
91d6fa6a
NC
1391 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1392 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1393 const char * rtype2 = elf_mips_reloc_type (type2);
1394 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1395
2c71103e
NC
1396 printf (" Type2: ");
1397
1398 if (rtype2 == NULL)
39dbeff8
AM
1399 printf (_("unrecognized: %-7lx"),
1400 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1401 else
1402 printf ("%-17.17s", rtype2);
1403
18bd398b 1404 printf ("\n Type3: ");
2c71103e
NC
1405
1406 if (rtype3 == NULL)
39dbeff8
AM
1407 printf (_("unrecognized: %-7lx"),
1408 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1409 else
1410 printf ("%-17.17s", rtype3);
1411
53c7db4b 1412 putchar ('\n');
2c71103e 1413 }
aca88567 1414#endif /* BFD64 */
252b5132
RH
1415 }
1416
c8286bd1 1417 free (rels);
252b5132
RH
1418}
1419
1420static const char *
d3ba0551 1421get_mips_dynamic_type (unsigned long type)
252b5132
RH
1422{
1423 switch (type)
1424 {
1425 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1426 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1427 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1428 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1429 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1430 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1431 case DT_MIPS_MSYM: return "MIPS_MSYM";
1432 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1433 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1434 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1435 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1436 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1437 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1438 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1439 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1440 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1441 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1442 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1443 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1444 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1445 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1446 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1447 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1448 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1449 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1450 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1451 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1452 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1453 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1454 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1455 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1456 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1457 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1458 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1459 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1460 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1461 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1462 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1463 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1464 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1465 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1466 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1467 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1468 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1469 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1470 default:
1471 return NULL;
1472 }
1473}
1474
9a097730 1475static const char *
d3ba0551 1476get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1477{
1478 switch (type)
1479 {
1480 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1481 default:
1482 return NULL;
1483 }
103f02d3
UD
1484}
1485
7490d522
AM
1486static const char *
1487get_ppc_dynamic_type (unsigned long type)
1488{
1489 switch (type)
1490 {
a7f2871e
AM
1491 case DT_PPC_GOT: return "PPC_GOT";
1492 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1493 default:
1494 return NULL;
1495 }
1496}
1497
f1cb7e17 1498static const char *
d3ba0551 1499get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1500{
1501 switch (type)
1502 {
a7f2871e
AM
1503 case DT_PPC64_GLINK: return "PPC64_GLINK";
1504 case DT_PPC64_OPD: return "PPC64_OPD";
1505 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1506 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1507 default:
1508 return NULL;
1509 }
1510}
1511
103f02d3 1512static const char *
d3ba0551 1513get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1514{
1515 switch (type)
1516 {
1517 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1518 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1519 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1520 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1521 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1522 case DT_HP_PREINIT: return "HP_PREINIT";
1523 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1524 case DT_HP_NEEDED: return "HP_NEEDED";
1525 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1526 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1527 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1528 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1529 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1530 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1531 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1532 case DT_HP_FILTERED: return "HP_FILTERED";
1533 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1534 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1535 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1536 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1537 case DT_PLT: return "PLT";
1538 case DT_PLT_SIZE: return "PLT_SIZE";
1539 case DT_DLT: return "DLT";
1540 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1541 default:
1542 return NULL;
1543 }
1544}
9a097730 1545
ecc51f48 1546static const char *
d3ba0551 1547get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1548{
1549 switch (type)
1550 {
148b93f2
NC
1551 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1552 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1553 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1554 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1555 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1556 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1557 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1558 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1559 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1560 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1561 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1562 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1563 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1564 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1565 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1566 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1567 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1568 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1569 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1570 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1571 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1572 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1573 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1574 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1575 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1576 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1577 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1578 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1579 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1580 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1581 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1582 default:
1583 return NULL;
1584 }
1585}
1586
fabcb361
RH
1587static const char *
1588get_alpha_dynamic_type (unsigned long type)
1589{
1590 switch (type)
1591 {
1592 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1593 default:
1594 return NULL;
1595 }
1596}
1597
1c0d3aa6
NC
1598static const char *
1599get_score_dynamic_type (unsigned long type)
1600{
1601 switch (type)
1602 {
1603 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1604 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1605 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1606 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1607 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1608 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1609 default:
1610 return NULL;
1611 }
1612}
1613
40b36596
JM
1614static const char *
1615get_tic6x_dynamic_type (unsigned long type)
1616{
1617 switch (type)
1618 {
1619 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1620 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1621 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1622 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1623 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1624 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1625 default:
1626 return NULL;
1627 }
1628}
1c0d3aa6 1629
252b5132 1630static const char *
d3ba0551 1631get_dynamic_type (unsigned long type)
252b5132 1632{
e9e44622 1633 static char buff[64];
252b5132
RH
1634
1635 switch (type)
1636 {
1637 case DT_NULL: return "NULL";
1638 case DT_NEEDED: return "NEEDED";
1639 case DT_PLTRELSZ: return "PLTRELSZ";
1640 case DT_PLTGOT: return "PLTGOT";
1641 case DT_HASH: return "HASH";
1642 case DT_STRTAB: return "STRTAB";
1643 case DT_SYMTAB: return "SYMTAB";
1644 case DT_RELA: return "RELA";
1645 case DT_RELASZ: return "RELASZ";
1646 case DT_RELAENT: return "RELAENT";
1647 case DT_STRSZ: return "STRSZ";
1648 case DT_SYMENT: return "SYMENT";
1649 case DT_INIT: return "INIT";
1650 case DT_FINI: return "FINI";
1651 case DT_SONAME: return "SONAME";
1652 case DT_RPATH: return "RPATH";
1653 case DT_SYMBOLIC: return "SYMBOLIC";
1654 case DT_REL: return "REL";
1655 case DT_RELSZ: return "RELSZ";
1656 case DT_RELENT: return "RELENT";
1657 case DT_PLTREL: return "PLTREL";
1658 case DT_DEBUG: return "DEBUG";
1659 case DT_TEXTREL: return "TEXTREL";
1660 case DT_JMPREL: return "JMPREL";
1661 case DT_BIND_NOW: return "BIND_NOW";
1662 case DT_INIT_ARRAY: return "INIT_ARRAY";
1663 case DT_FINI_ARRAY: return "FINI_ARRAY";
1664 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1665 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1666 case DT_RUNPATH: return "RUNPATH";
1667 case DT_FLAGS: return "FLAGS";
2d0e6f43 1668
d1133906
NC
1669 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1670 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1671
05107a46 1672 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1673 case DT_PLTPADSZ: return "PLTPADSZ";
1674 case DT_MOVEENT: return "MOVEENT";
1675 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1676 case DT_FEATURE: return "FEATURE";
252b5132
RH
1677 case DT_POSFLAG_1: return "POSFLAG_1";
1678 case DT_SYMINSZ: return "SYMINSZ";
1679 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1680
252b5132 1681 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1682 case DT_CONFIG: return "CONFIG";
1683 case DT_DEPAUDIT: return "DEPAUDIT";
1684 case DT_AUDIT: return "AUDIT";
1685 case DT_PLTPAD: return "PLTPAD";
1686 case DT_MOVETAB: return "MOVETAB";
252b5132 1687 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1688
252b5132 1689 case DT_VERSYM: return "VERSYM";
103f02d3 1690
67a4f2b7
AO
1691 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1692 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1693 case DT_RELACOUNT: return "RELACOUNT";
1694 case DT_RELCOUNT: return "RELCOUNT";
1695 case DT_FLAGS_1: return "FLAGS_1";
1696 case DT_VERDEF: return "VERDEF";
1697 case DT_VERDEFNUM: return "VERDEFNUM";
1698 case DT_VERNEED: return "VERNEED";
1699 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1700
019148e4 1701 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1702 case DT_USED: return "USED";
1703 case DT_FILTER: return "FILTER";
103f02d3 1704
047b2264
JJ
1705 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1706 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1707 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1708 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1709 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1710 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1711
252b5132
RH
1712 default:
1713 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1714 {
2cf0635d 1715 const char * result;
103f02d3 1716
252b5132
RH
1717 switch (elf_header.e_machine)
1718 {
1719 case EM_MIPS:
4fe85591 1720 case EM_MIPS_RS3_LE:
252b5132
RH
1721 result = get_mips_dynamic_type (type);
1722 break;
9a097730
RH
1723 case EM_SPARCV9:
1724 result = get_sparc64_dynamic_type (type);
1725 break;
7490d522
AM
1726 case EM_PPC:
1727 result = get_ppc_dynamic_type (type);
1728 break;
f1cb7e17
AM
1729 case EM_PPC64:
1730 result = get_ppc64_dynamic_type (type);
1731 break;
ecc51f48
NC
1732 case EM_IA_64:
1733 result = get_ia64_dynamic_type (type);
1734 break;
fabcb361
RH
1735 case EM_ALPHA:
1736 result = get_alpha_dynamic_type (type);
1737 break;
1c0d3aa6
NC
1738 case EM_SCORE:
1739 result = get_score_dynamic_type (type);
1740 break;
40b36596
JM
1741 case EM_TI_C6000:
1742 result = get_tic6x_dynamic_type (type);
1743 break;
252b5132
RH
1744 default:
1745 result = NULL;
1746 break;
1747 }
1748
1749 if (result != NULL)
1750 return result;
1751
e9e44622 1752 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1753 }
eec8f817
DA
1754 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1755 || (elf_header.e_machine == EM_PARISC
1756 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1757 {
2cf0635d 1758 const char * result;
103f02d3
UD
1759
1760 switch (elf_header.e_machine)
1761 {
1762 case EM_PARISC:
1763 result = get_parisc_dynamic_type (type);
1764 break;
148b93f2
NC
1765 case EM_IA_64:
1766 result = get_ia64_dynamic_type (type);
1767 break;
103f02d3
UD
1768 default:
1769 result = NULL;
1770 break;
1771 }
1772
1773 if (result != NULL)
1774 return result;
1775
e9e44622
JJ
1776 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1777 type);
103f02d3 1778 }
252b5132 1779 else
e9e44622 1780 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1781
252b5132
RH
1782 return buff;
1783 }
1784}
1785
1786static char *
d3ba0551 1787get_file_type (unsigned e_type)
252b5132 1788{
b34976b6 1789 static char buff[32];
252b5132
RH
1790
1791 switch (e_type)
1792 {
1793 case ET_NONE: return _("NONE (None)");
1794 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1795 case ET_EXEC: return _("EXEC (Executable file)");
1796 case ET_DYN: return _("DYN (Shared object file)");
1797 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1798
1799 default:
1800 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1801 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1802 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1803 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1804 else
e9e44622 1805 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1806 return buff;
1807 }
1808}
1809
1810static char *
d3ba0551 1811get_machine_name (unsigned e_machine)
252b5132 1812{
b34976b6 1813 static char buff[64]; /* XXX */
252b5132
RH
1814
1815 switch (e_machine)
1816 {
c45021f2
NC
1817 case EM_NONE: return _("None");
1818 case EM_M32: return "WE32100";
1819 case EM_SPARC: return "Sparc";
e9f53129 1820 case EM_SPU: return "SPU";
c45021f2
NC
1821 case EM_386: return "Intel 80386";
1822 case EM_68K: return "MC68000";
1823 case EM_88K: return "MC88000";
1824 case EM_486: return "Intel 80486";
1825 case EM_860: return "Intel 80860";
1826 case EM_MIPS: return "MIPS R3000";
1827 case EM_S370: return "IBM System/370";
7036c0e1 1828 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1829 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1830 case EM_PARISC: return "HPPA";
252b5132 1831 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1832 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1833 case EM_960: return "Intel 90860";
1834 case EM_PPC: return "PowerPC";
285d1771 1835 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1836 case EM_V800: return "NEC V800";
1837 case EM_FR20: return "Fujitsu FR20";
1838 case EM_RH32: return "TRW RH32";
b34976b6 1839 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1840 case EM_ARM: return "ARM";
1841 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1842 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1843 case EM_SPARCV9: return "Sparc v9";
1844 case EM_TRICORE: return "Siemens Tricore";
584da044 1845 case EM_ARC: return "ARC";
c2dcd04e
NC
1846 case EM_H8_300: return "Renesas H8/300";
1847 case EM_H8_300H: return "Renesas H8/300H";
1848 case EM_H8S: return "Renesas H8S";
1849 case EM_H8_500: return "Renesas H8/500";
30800947 1850 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1851 case EM_MIPS_X: return "Stanford MIPS-X";
1852 case EM_COLDFIRE: return "Motorola Coldfire";
1853 case EM_68HC12: return "Motorola M68HC12";
c45021f2 1854 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1855 case EM_CYGNUS_D10V:
1856 case EM_D10V: return "d10v";
1857 case EM_CYGNUS_D30V:
b34976b6 1858 case EM_D30V: return "d30v";
2b0337b0 1859 case EM_CYGNUS_M32R:
26597c86 1860 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1861 case EM_CYGNUS_V850:
8f7e76d0 1862 case EM_V850: return "Renesas v850";
2b0337b0
AO
1863 case EM_CYGNUS_MN10300:
1864 case EM_MN10300: return "mn10300";
1865 case EM_CYGNUS_MN10200:
1866 case EM_MN10200: return "mn10200";
5506d11a 1867 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1868 case EM_CYGNUS_FR30:
1869 case EM_FR30: return "Fujitsu FR30";
b34976b6 1870 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1871 case EM_PJ_OLD:
b34976b6 1872 case EM_PJ: return "picoJava";
7036c0e1
AJ
1873 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1874 case EM_PCP: return "Siemens PCP";
1875 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1876 case EM_NDR1: return "Denso NDR1 microprocesspr";
1877 case EM_STARCORE: return "Motorola Star*Core processor";
1878 case EM_ME16: return "Toyota ME16 processor";
1879 case EM_ST100: return "STMicroelectronics ST100 processor";
1880 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1881 case EM_PDSP: return "Sony DSP processor";
1882 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1883 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1884 case EM_FX66: return "Siemens FX66 microcontroller";
1885 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1886 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1887 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
1888 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1889 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1890 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1891 case EM_SVX: return "Silicon Graphics SVx";
1892 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1893 case EM_VAX: return "Digital VAX";
2b0337b0 1894 case EM_AVR_OLD:
b34976b6 1895 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1896 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1897 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1898 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1899 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1900 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1901 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1902 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1903 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1904 case EM_L1OM: return "Intel L1OM";
7a9068fe 1905 case EM_K1OM: return "Intel K1OM";
b7498e0e 1906 case EM_S390_OLD:
b34976b6 1907 case EM_S390: return "IBM S/390";
1c0d3aa6 1908 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1909 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1910 case EM_OPENRISC:
1911 case EM_OR32: return "OpenRISC";
11636f9e 1912 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1913 case EM_CRX: return "National Semiconductor CRX microprocessor";
d172d4ba 1914 case EM_DLX: return "OpenDLX";
1e4cf259 1915 case EM_IP2K_OLD:
b34976b6 1916 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1917 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1918 case EM_XTENSA_OLD:
1919 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1920 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1921 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1922 case EM_NS32K: return "National Semiconductor 32000 series";
1923 case EM_TPC: return "Tenor Network TPC processor";
1924 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1925 case EM_MAX: return "MAX Processor";
1926 case EM_CR: return "National Semiconductor CompactRISC";
1927 case EM_F2MC16: return "Fujitsu F2MC16";
1928 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1929 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1930 case EM_M32C_OLD:
49f58d10 1931 case EM_M32C: return "Renesas M32c";
d031aafb 1932 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1933 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1934 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1935 case EM_SEP: return "Sharp embedded microprocessor";
1936 case EM_ARCA: return "Arca RISC microprocessor";
1937 case EM_UNICORE: return "Unicore";
1938 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1939 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1940 case EM_NIOS32: return "Altera Nios";
1941 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1942 case EM_C166:
d70c5fc7 1943 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
1944 case EM_M16C: return "Renesas M16C series microprocessors";
1945 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
1946 case EM_CE: return "Freescale Communication Engine RISC core";
1947 case EM_TSK3000: return "Altium TSK3000 core";
1948 case EM_RS08: return "Freescale RS08 embedded processor";
1949 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
1950 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
1951 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
1952 case EM_SE_C17: return "Seiko Epson C17 family";
1953 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
1954 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
1955 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
1956 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
1957 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
1958 case EM_R32C: return "Renesas R32C series microprocessors";
1959 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
1960 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
1961 case EM_8051: return "Intel 8051 and variants";
1962 case EM_STXP7X: return "STMicroelectronics STxP7x family";
1963 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
1964 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
1965 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
1966 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
1967 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
1968 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 1969 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 1970 case EM_CR16:
6c03b1ed 1971 case EM_CR16_OLD: return "National Semiconductor's CR16";
7ba29e2a
NC
1972 case EM_MICROBLAZE: return "Xilinx MicroBlaze";
1973 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
c7927a3c 1974 case EM_RX: return "Renesas RX";
11636f9e
JM
1975 case EM_METAG: return "Imagination Technologies META processor architecture";
1976 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
1977 case EM_ECOG16: return "Cyan Technology eCOG16 family";
1978 case EM_ETPU: return "Freescale Extended Time Processing Unit";
1979 case EM_SLE9X: return "Infineon Technologies SLE9X core";
1980 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
1981 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
1982 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
1983 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 1984 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 1985 case EM_CUDA: return "NVIDIA CUDA architecture";
252b5132 1986 default:
35d9dd2f 1987 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
1988 return buff;
1989 }
1990}
1991
f3485b74 1992static void
d3ba0551 1993decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
1994{
1995 unsigned eabi;
1996 int unknown = 0;
1997
1998 eabi = EF_ARM_EABI_VERSION (e_flags);
1999 e_flags &= ~ EF_ARM_EABIMASK;
2000
2001 /* Handle "generic" ARM flags. */
2002 if (e_flags & EF_ARM_RELEXEC)
2003 {
2004 strcat (buf, ", relocatable executable");
2005 e_flags &= ~ EF_ARM_RELEXEC;
2006 }
76da6bbe 2007
f3485b74
NC
2008 if (e_flags & EF_ARM_HASENTRY)
2009 {
2010 strcat (buf, ", has entry point");
2011 e_flags &= ~ EF_ARM_HASENTRY;
2012 }
76da6bbe 2013
f3485b74
NC
2014 /* Now handle EABI specific flags. */
2015 switch (eabi)
2016 {
2017 default:
2c71103e 2018 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2019 if (e_flags)
2020 unknown = 1;
2021 break;
2022
2023 case EF_ARM_EABI_VER1:
a5bcd848 2024 strcat (buf, ", Version1 EABI");
f3485b74
NC
2025 while (e_flags)
2026 {
2027 unsigned flag;
76da6bbe 2028
f3485b74
NC
2029 /* Process flags one bit at a time. */
2030 flag = e_flags & - e_flags;
2031 e_flags &= ~ flag;
76da6bbe 2032
f3485b74
NC
2033 switch (flag)
2034 {
a5bcd848 2035 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2036 strcat (buf, ", sorted symbol tables");
2037 break;
76da6bbe 2038
f3485b74
NC
2039 default:
2040 unknown = 1;
2041 break;
2042 }
2043 }
2044 break;
76da6bbe 2045
a5bcd848
PB
2046 case EF_ARM_EABI_VER2:
2047 strcat (buf, ", Version2 EABI");
2048 while (e_flags)
2049 {
2050 unsigned flag;
2051
2052 /* Process flags one bit at a time. */
2053 flag = e_flags & - e_flags;
2054 e_flags &= ~ flag;
2055
2056 switch (flag)
2057 {
2058 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2059 strcat (buf, ", sorted symbol tables");
2060 break;
2061
2062 case EF_ARM_DYNSYMSUSESEGIDX:
2063 strcat (buf, ", dynamic symbols use segment index");
2064 break;
2065
2066 case EF_ARM_MAPSYMSFIRST:
2067 strcat (buf, ", mapping symbols precede others");
2068 break;
2069
2070 default:
2071 unknown = 1;
2072 break;
2073 }
2074 }
2075 break;
2076
d507cf36
PB
2077 case EF_ARM_EABI_VER3:
2078 strcat (buf, ", Version3 EABI");
8cb51566
PB
2079 break;
2080
2081 case EF_ARM_EABI_VER4:
2082 strcat (buf, ", Version4 EABI");
3a4a14e9
PB
2083 goto eabi;
2084
2085 case EF_ARM_EABI_VER5:
2086 strcat (buf, ", Version5 EABI");
2087 eabi:
d507cf36
PB
2088 while (e_flags)
2089 {
2090 unsigned flag;
2091
2092 /* Process flags one bit at a time. */
2093 flag = e_flags & - e_flags;
2094 e_flags &= ~ flag;
2095
2096 switch (flag)
2097 {
2098 case EF_ARM_BE8:
2099 strcat (buf, ", BE8");
2100 break;
2101
2102 case EF_ARM_LE8:
2103 strcat (buf, ", LE8");
2104 break;
2105
2106 default:
2107 unknown = 1;
2108 break;
2109 }
2110 }
2111 break;
2112
f3485b74 2113 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2114 strcat (buf, ", GNU EABI");
f3485b74
NC
2115 while (e_flags)
2116 {
2117 unsigned flag;
76da6bbe 2118
f3485b74
NC
2119 /* Process flags one bit at a time. */
2120 flag = e_flags & - e_flags;
2121 e_flags &= ~ flag;
76da6bbe 2122
f3485b74
NC
2123 switch (flag)
2124 {
a5bcd848 2125 case EF_ARM_INTERWORK:
f3485b74
NC
2126 strcat (buf, ", interworking enabled");
2127 break;
76da6bbe 2128
a5bcd848 2129 case EF_ARM_APCS_26:
f3485b74
NC
2130 strcat (buf, ", uses APCS/26");
2131 break;
76da6bbe 2132
a5bcd848 2133 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2134 strcat (buf, ", uses APCS/float");
2135 break;
76da6bbe 2136
a5bcd848 2137 case EF_ARM_PIC:
f3485b74
NC
2138 strcat (buf, ", position independent");
2139 break;
76da6bbe 2140
a5bcd848 2141 case EF_ARM_ALIGN8:
f3485b74
NC
2142 strcat (buf, ", 8 bit structure alignment");
2143 break;
76da6bbe 2144
a5bcd848 2145 case EF_ARM_NEW_ABI:
f3485b74
NC
2146 strcat (buf, ", uses new ABI");
2147 break;
76da6bbe 2148
a5bcd848 2149 case EF_ARM_OLD_ABI:
f3485b74
NC
2150 strcat (buf, ", uses old ABI");
2151 break;
76da6bbe 2152
a5bcd848 2153 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2154 strcat (buf, ", software FP");
2155 break;
76da6bbe 2156
90e01f86
ILT
2157 case EF_ARM_VFP_FLOAT:
2158 strcat (buf, ", VFP");
2159 break;
2160
fde78edd
NC
2161 case EF_ARM_MAVERICK_FLOAT:
2162 strcat (buf, ", Maverick FP");
2163 break;
2164
f3485b74
NC
2165 default:
2166 unknown = 1;
2167 break;
2168 }
2169 }
2170 }
f3485b74
NC
2171
2172 if (unknown)
2b692964 2173 strcat (buf,_(", <unknown>"));
f3485b74
NC
2174}
2175
252b5132 2176static char *
d3ba0551 2177get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2178{
b34976b6 2179 static char buf[1024];
252b5132
RH
2180
2181 buf[0] = '\0';
76da6bbe 2182
252b5132
RH
2183 if (e_flags)
2184 {
2185 switch (e_machine)
2186 {
2187 default:
2188 break;
2189
f3485b74
NC
2190 case EM_ARM:
2191 decode_ARM_machine_flags (e_flags, buf);
2192 break;
76da6bbe 2193
781303ce
MF
2194 case EM_BLACKFIN:
2195 if (e_flags & EF_BFIN_PIC)
2196 strcat (buf, ", PIC");
2197
2198 if (e_flags & EF_BFIN_FDPIC)
2199 strcat (buf, ", FDPIC");
2200
2201 if (e_flags & EF_BFIN_CODE_IN_L1)
2202 strcat (buf, ", code in L1");
2203
2204 if (e_flags & EF_BFIN_DATA_IN_L1)
2205 strcat (buf, ", data in L1");
2206
2207 break;
2208
ec2dfb42
AO
2209 case EM_CYGNUS_FRV:
2210 switch (e_flags & EF_FRV_CPU_MASK)
2211 {
2212 case EF_FRV_CPU_GENERIC:
2213 break;
2214
2215 default:
2216 strcat (buf, ", fr???");
2217 break;
57346661 2218
ec2dfb42
AO
2219 case EF_FRV_CPU_FR300:
2220 strcat (buf, ", fr300");
2221 break;
2222
2223 case EF_FRV_CPU_FR400:
2224 strcat (buf, ", fr400");
2225 break;
2226 case EF_FRV_CPU_FR405:
2227 strcat (buf, ", fr405");
2228 break;
2229
2230 case EF_FRV_CPU_FR450:
2231 strcat (buf, ", fr450");
2232 break;
2233
2234 case EF_FRV_CPU_FR500:
2235 strcat (buf, ", fr500");
2236 break;
2237 case EF_FRV_CPU_FR550:
2238 strcat (buf, ", fr550");
2239 break;
2240
2241 case EF_FRV_CPU_SIMPLE:
2242 strcat (buf, ", simple");
2243 break;
2244 case EF_FRV_CPU_TOMCAT:
2245 strcat (buf, ", tomcat");
2246 break;
2247 }
1c877e87 2248 break;
ec2dfb42 2249
53c7db4b 2250 case EM_68K:
425c6cb0 2251 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2252 strcat (buf, ", m68000");
425c6cb0 2253 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2254 strcat (buf, ", cpu32");
2255 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2256 strcat (buf, ", fido_a");
425c6cb0 2257 else
266abb8f 2258 {
2cf0635d
NC
2259 char const * isa = _("unknown");
2260 char const * mac = _("unknown mac");
2261 char const * additional = NULL;
0112cd26 2262
c694fd50 2263 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2264 {
c694fd50 2265 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2266 isa = "A";
2267 additional = ", nodiv";
2268 break;
c694fd50 2269 case EF_M68K_CF_ISA_A:
266abb8f
NS
2270 isa = "A";
2271 break;
c694fd50 2272 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2273 isa = "A+";
2274 break;
c694fd50 2275 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2276 isa = "B";
2277 additional = ", nousp";
2278 break;
c694fd50 2279 case EF_M68K_CF_ISA_B:
266abb8f
NS
2280 isa = "B";
2281 break;
f608cd77
NS
2282 case EF_M68K_CF_ISA_C:
2283 isa = "C";
2284 break;
2285 case EF_M68K_CF_ISA_C_NODIV:
2286 isa = "C";
2287 additional = ", nodiv";
2288 break;
266abb8f
NS
2289 }
2290 strcat (buf, ", cf, isa ");
2291 strcat (buf, isa);
0b2e31dc
NS
2292 if (additional)
2293 strcat (buf, additional);
c694fd50 2294 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2295 strcat (buf, ", float");
c694fd50 2296 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2297 {
2298 case 0:
2299 mac = NULL;
2300 break;
c694fd50 2301 case EF_M68K_CF_MAC:
266abb8f
NS
2302 mac = "mac";
2303 break;
c694fd50 2304 case EF_M68K_CF_EMAC:
266abb8f
NS
2305 mac = "emac";
2306 break;
f608cd77
NS
2307 case EF_M68K_CF_EMAC_B:
2308 mac = "emac_b";
2309 break;
266abb8f
NS
2310 }
2311 if (mac)
2312 {
2313 strcat (buf, ", ");
2314 strcat (buf, mac);
2315 }
266abb8f 2316 }
53c7db4b 2317 break;
33c63f9d 2318
252b5132
RH
2319 case EM_PPC:
2320 if (e_flags & EF_PPC_EMB)
2321 strcat (buf, ", emb");
2322
2323 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2324 strcat (buf, _(", relocatable"));
252b5132
RH
2325
2326 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2327 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2328 break;
2329
2b0337b0 2330 case EM_V850:
252b5132
RH
2331 case EM_CYGNUS_V850:
2332 switch (e_flags & EF_V850_ARCH)
2333 {
1cd986c5
NC
2334 case E_V850E2V3_ARCH:
2335 strcat (buf, ", v850e2v3");
2336 break;
2337 case E_V850E2_ARCH:
2338 strcat (buf, ", v850e2");
2339 break;
2340 case E_V850E1_ARCH:
2341 strcat (buf, ", v850e1");
8ad30312 2342 break;
252b5132
RH
2343 case E_V850E_ARCH:
2344 strcat (buf, ", v850e");
2345 break;
252b5132
RH
2346 case E_V850_ARCH:
2347 strcat (buf, ", v850");
2348 break;
2349 default:
2b692964 2350 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2351 break;
2352 }
2353 break;
2354
2b0337b0 2355 case EM_M32R:
252b5132
RH
2356 case EM_CYGNUS_M32R:
2357 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2358 strcat (buf, ", m32r");
252b5132
RH
2359 break;
2360
2361 case EM_MIPS:
4fe85591 2362 case EM_MIPS_RS3_LE:
252b5132
RH
2363 if (e_flags & EF_MIPS_NOREORDER)
2364 strcat (buf, ", noreorder");
2365
2366 if (e_flags & EF_MIPS_PIC)
2367 strcat (buf, ", pic");
2368
2369 if (e_flags & EF_MIPS_CPIC)
2370 strcat (buf, ", cpic");
2371
d1bdd336
TS
2372 if (e_flags & EF_MIPS_UCODE)
2373 strcat (buf, ", ugen_reserved");
2374
252b5132
RH
2375 if (e_flags & EF_MIPS_ABI2)
2376 strcat (buf, ", abi2");
2377
43521d43
TS
2378 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2379 strcat (buf, ", odk first");
2380
a5d22d2a
TS
2381 if (e_flags & EF_MIPS_32BITMODE)
2382 strcat (buf, ", 32bitmode");
2383
156c2f8b
NC
2384 switch ((e_flags & EF_MIPS_MACH))
2385 {
2386 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2387 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2388 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2389 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2390 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2391 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2392 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2393 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2394 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2395 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2396 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2397 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2398 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2399 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2400 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2401 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2402 case 0:
2403 /* We simply ignore the field in this case to avoid confusion:
2404 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2405 extension. */
2406 break;
2b692964 2407 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2408 }
43521d43
TS
2409
2410 switch ((e_flags & EF_MIPS_ABI))
2411 {
2412 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2413 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2414 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2415 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2416 case 0:
2417 /* We simply ignore the field in this case to avoid confusion:
2418 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2419 This means it is likely to be an o32 file, but not for
2420 sure. */
2421 break;
2b692964 2422 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2423 }
2424
2425 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2426 strcat (buf, ", mdmx");
2427
2428 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2429 strcat (buf, ", mips16");
2430
2431 switch ((e_flags & EF_MIPS_ARCH))
2432 {
2433 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2434 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2435 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2436 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2437 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2438 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2439 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2440 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2441 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2442 default: strcat (buf, _(", unknown ISA")); break;
43521d43
TS
2443 }
2444
8e45593f
NC
2445 if (e_flags & EF_SH_PIC)
2446 strcat (buf, ", pic");
2447
2448 if (e_flags & EF_SH_FDPIC)
2449 strcat (buf, ", fdpic");
252b5132 2450 break;
351b4b40 2451
ccde1100
AO
2452 case EM_SH:
2453 switch ((e_flags & EF_SH_MACH_MASK))
2454 {
2455 case EF_SH1: strcat (buf, ", sh1"); break;
2456 case EF_SH2: strcat (buf, ", sh2"); break;
2457 case EF_SH3: strcat (buf, ", sh3"); break;
2458 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2459 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2460 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2461 case EF_SH3E: strcat (buf, ", sh3e"); break;
2462 case EF_SH4: strcat (buf, ", sh4"); break;
2463 case EF_SH5: strcat (buf, ", sh5"); break;
2464 case EF_SH2E: strcat (buf, ", sh2e"); break;
2465 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2466 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2467 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2468 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2469 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2470 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2471 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2472 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2473 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2474 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2475 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2476 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2477 }
2478
2479 break;
57346661 2480
351b4b40
RH
2481 case EM_SPARCV9:
2482 if (e_flags & EF_SPARC_32PLUS)
2483 strcat (buf, ", v8+");
2484
2485 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2486 strcat (buf, ", ultrasparcI");
2487
2488 if (e_flags & EF_SPARC_SUN_US3)
2489 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2490
2491 if (e_flags & EF_SPARC_HAL_R1)
2492 strcat (buf, ", halr1");
2493
2494 if (e_flags & EF_SPARC_LEDATA)
2495 strcat (buf, ", ledata");
2496
2497 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2498 strcat (buf, ", tso");
2499
2500 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2501 strcat (buf, ", pso");
2502
2503 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2504 strcat (buf, ", rmo");
2505 break;
7d466069 2506
103f02d3
UD
2507 case EM_PARISC:
2508 switch (e_flags & EF_PARISC_ARCH)
2509 {
2510 case EFA_PARISC_1_0:
2511 strcpy (buf, ", PA-RISC 1.0");
2512 break;
2513 case EFA_PARISC_1_1:
2514 strcpy (buf, ", PA-RISC 1.1");
2515 break;
2516 case EFA_PARISC_2_0:
2517 strcpy (buf, ", PA-RISC 2.0");
2518 break;
2519 default:
2520 break;
2521 }
2522 if (e_flags & EF_PARISC_TRAPNIL)
2523 strcat (buf, ", trapnil");
2524 if (e_flags & EF_PARISC_EXT)
2525 strcat (buf, ", ext");
2526 if (e_flags & EF_PARISC_LSB)
2527 strcat (buf, ", lsb");
2528 if (e_flags & EF_PARISC_WIDE)
2529 strcat (buf, ", wide");
2530 if (e_flags & EF_PARISC_NO_KABP)
2531 strcat (buf, ", no kabp");
2532 if (e_flags & EF_PARISC_LAZYSWAP)
2533 strcat (buf, ", lazyswap");
30800947 2534 break;
76da6bbe 2535
7d466069 2536 case EM_PJ:
2b0337b0 2537 case EM_PJ_OLD:
7d466069
ILT
2538 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2539 strcat (buf, ", new calling convention");
2540
2541 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2542 strcat (buf, ", gnu calling convention");
2543 break;
4d6ed7c8
NC
2544
2545 case EM_IA_64:
2546 if ((e_flags & EF_IA_64_ABI64))
2547 strcat (buf, ", 64-bit");
2548 else
2549 strcat (buf, ", 32-bit");
2550 if ((e_flags & EF_IA_64_REDUCEDFP))
2551 strcat (buf, ", reduced fp model");
2552 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2553 strcat (buf, ", no function descriptors, constant gp");
2554 else if ((e_flags & EF_IA_64_CONS_GP))
2555 strcat (buf, ", constant gp");
2556 if ((e_flags & EF_IA_64_ABSOLUTE))
2557 strcat (buf, ", absolute");
28f997cf
TG
2558 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2559 {
2560 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2561 strcat (buf, ", vms_linkages");
2562 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2563 {
2564 case EF_IA_64_VMS_COMCOD_SUCCESS:
2565 break;
2566 case EF_IA_64_VMS_COMCOD_WARNING:
2567 strcat (buf, ", warning");
2568 break;
2569 case EF_IA_64_VMS_COMCOD_ERROR:
2570 strcat (buf, ", error");
2571 break;
2572 case EF_IA_64_VMS_COMCOD_ABORT:
2573 strcat (buf, ", abort");
2574 break;
2575 default:
2576 abort ();
2577 }
2578 }
4d6ed7c8 2579 break;
179d3252
JT
2580
2581 case EM_VAX:
2582 if ((e_flags & EF_VAX_NONPIC))
2583 strcat (buf, ", non-PIC");
2584 if ((e_flags & EF_VAX_DFLOAT))
2585 strcat (buf, ", D-Float");
2586 if ((e_flags & EF_VAX_GFLOAT))
2587 strcat (buf, ", G-Float");
2588 break;
c7927a3c
NC
2589
2590 case EM_RX:
2591 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2592 strcat (buf, ", 64-bit doubles");
2593 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2594 strcat (buf, ", dsp");
55786da2
AK
2595
2596 case EM_S390:
2597 if (e_flags & EF_S390_HIGH_GPRS)
2598 strcat (buf, ", highgprs");
40b36596
JM
2599
2600 case EM_TI_C6000:
2601 if ((e_flags & EF_C6000_REL))
2602 strcat (buf, ", relocatable module");
252b5132
RH
2603 }
2604 }
2605
2606 return buf;
2607}
2608
252b5132 2609static const char *
d3ba0551
AM
2610get_osabi_name (unsigned int osabi)
2611{
2612 static char buff[32];
2613
2614 switch (osabi)
2615 {
2616 case ELFOSABI_NONE: return "UNIX - System V";
2617 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2618 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2619 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2620 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2621 case ELFOSABI_AIX: return "UNIX - AIX";
2622 case ELFOSABI_IRIX: return "UNIX - IRIX";
2623 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2624 case ELFOSABI_TRU64: return "UNIX - TRU64";
2625 case ELFOSABI_MODESTO: return "Novell - Modesto";
2626 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2627 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2628 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2629 case ELFOSABI_AROS: return "AROS";
11636f9e 2630 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2631 default:
40b36596
JM
2632 if (osabi >= 64)
2633 switch (elf_header.e_machine)
2634 {
2635 case EM_ARM:
2636 switch (osabi)
2637 {
2638 case ELFOSABI_ARM: return "ARM";
2639 default:
2640 break;
2641 }
2642 break;
2643
2644 case EM_MSP430:
2645 case EM_MSP430_OLD:
2646 switch (osabi)
2647 {
2648 case ELFOSABI_STANDALONE: return _("Standalone App");
2649 default:
2650 break;
2651 }
2652 break;
2653
2654 case EM_TI_C6000:
2655 switch (osabi)
2656 {
2657 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2658 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2659 default:
2660 break;
2661 }
2662 break;
2663
2664 default:
2665 break;
2666 }
e9e44622 2667 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2668 return buff;
2669 }
2670}
2671
b294bdf8
MM
2672static const char *
2673get_arm_segment_type (unsigned long type)
2674{
2675 switch (type)
2676 {
2677 case PT_ARM_EXIDX:
2678 return "EXIDX";
2679 default:
2680 break;
2681 }
2682
2683 return NULL;
2684}
2685
d3ba0551
AM
2686static const char *
2687get_mips_segment_type (unsigned long type)
252b5132
RH
2688{
2689 switch (type)
2690 {
2691 case PT_MIPS_REGINFO:
2692 return "REGINFO";
2693 case PT_MIPS_RTPROC:
2694 return "RTPROC";
2695 case PT_MIPS_OPTIONS:
2696 return "OPTIONS";
2697 default:
2698 break;
2699 }
2700
2701 return NULL;
2702}
2703
103f02d3 2704static const char *
d3ba0551 2705get_parisc_segment_type (unsigned long type)
103f02d3
UD
2706{
2707 switch (type)
2708 {
2709 case PT_HP_TLS: return "HP_TLS";
2710 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2711 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2712 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2713 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2714 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2715 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2716 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2717 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2718 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2719 case PT_HP_PARALLEL: return "HP_PARALLEL";
2720 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2721 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2722 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2723 case PT_HP_STACK: return "HP_STACK";
2724 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2725 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2726 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2727 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2728 default:
2729 break;
2730 }
2731
2732 return NULL;
2733}
2734
4d6ed7c8 2735static const char *
d3ba0551 2736get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2737{
2738 switch (type)
2739 {
2740 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2741 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2742 case PT_HP_TLS: return "HP_TLS";
2743 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2744 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2745 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2746 default:
2747 break;
2748 }
2749
2750 return NULL;
2751}
2752
40b36596
JM
2753static const char *
2754get_tic6x_segment_type (unsigned long type)
2755{
2756 switch (type)
2757 {
2758 case PT_C6000_PHATTR: return "C6000_PHATTR";
2759 default:
2760 break;
2761 }
2762
2763 return NULL;
2764}
2765
252b5132 2766static const char *
d3ba0551 2767get_segment_type (unsigned long p_type)
252b5132 2768{
b34976b6 2769 static char buff[32];
252b5132
RH
2770
2771 switch (p_type)
2772 {
b34976b6
AM
2773 case PT_NULL: return "NULL";
2774 case PT_LOAD: return "LOAD";
252b5132 2775 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2776 case PT_INTERP: return "INTERP";
2777 case PT_NOTE: return "NOTE";
2778 case PT_SHLIB: return "SHLIB";
2779 case PT_PHDR: return "PHDR";
13ae64f3 2780 case PT_TLS: return "TLS";
252b5132 2781
65765700
JJ
2782 case PT_GNU_EH_FRAME:
2783 return "GNU_EH_FRAME";
2b05f1b7 2784 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2785 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2786
252b5132
RH
2787 default:
2788 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2789 {
2cf0635d 2790 const char * result;
103f02d3 2791
252b5132
RH
2792 switch (elf_header.e_machine)
2793 {
b294bdf8
MM
2794 case EM_ARM:
2795 result = get_arm_segment_type (p_type);
2796 break;
252b5132 2797 case EM_MIPS:
4fe85591 2798 case EM_MIPS_RS3_LE:
252b5132
RH
2799 result = get_mips_segment_type (p_type);
2800 break;
103f02d3
UD
2801 case EM_PARISC:
2802 result = get_parisc_segment_type (p_type);
2803 break;
4d6ed7c8
NC
2804 case EM_IA_64:
2805 result = get_ia64_segment_type (p_type);
2806 break;
40b36596
JM
2807 case EM_TI_C6000:
2808 result = get_tic6x_segment_type (p_type);
2809 break;
252b5132
RH
2810 default:
2811 result = NULL;
2812 break;
2813 }
103f02d3 2814
252b5132
RH
2815 if (result != NULL)
2816 return result;
103f02d3 2817
252b5132
RH
2818 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2819 }
2820 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2821 {
2cf0635d 2822 const char * result;
103f02d3
UD
2823
2824 switch (elf_header.e_machine)
2825 {
2826 case EM_PARISC:
2827 result = get_parisc_segment_type (p_type);
2828 break;
00428cca
AM
2829 case EM_IA_64:
2830 result = get_ia64_segment_type (p_type);
2831 break;
103f02d3
UD
2832 default:
2833 result = NULL;
2834 break;
2835 }
2836
2837 if (result != NULL)
2838 return result;
2839
2840 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2841 }
252b5132 2842 else
e9e44622 2843 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2844
2845 return buff;
2846 }
2847}
2848
2849static const char *
d3ba0551 2850get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2851{
2852 switch (sh_type)
2853 {
b34976b6
AM
2854 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2855 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2856 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2857 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2858 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2859 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2860 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2861 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2862 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2863 case SHT_MIPS_RELD: return "MIPS_RELD";
2864 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2865 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2866 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2867 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2868 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2869 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2870 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2871 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2872 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2873 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2874 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2875 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2876 case SHT_MIPS_LINE: return "MIPS_LINE";
2877 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2878 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2879 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2880 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2881 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2882 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2883 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2884 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2885 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2886 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2887 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2888 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2889 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2890 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2891 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2892 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2893 default:
2894 break;
2895 }
2896 return NULL;
2897}
2898
103f02d3 2899static const char *
d3ba0551 2900get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2901{
2902 switch (sh_type)
2903 {
2904 case SHT_PARISC_EXT: return "PARISC_EXT";
2905 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2906 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2907 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2908 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2909 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2910 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2911 default:
2912 break;
2913 }
2914 return NULL;
2915}
2916
4d6ed7c8 2917static const char *
d3ba0551 2918get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2919{
18bd398b 2920 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2921 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2922 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2923
4d6ed7c8
NC
2924 switch (sh_type)
2925 {
148b93f2
NC
2926 case SHT_IA_64_EXT: return "IA_64_EXT";
2927 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2928 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
2929 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
2930 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
2931 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
2932 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
2933 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
2934 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
2935 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
2936 default:
2937 break;
2938 }
2939 return NULL;
2940}
2941
d2b2c203
DJ
2942static const char *
2943get_x86_64_section_type_name (unsigned int sh_type)
2944{
2945 switch (sh_type)
2946 {
2947 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2948 default:
2949 break;
2950 }
2951 return NULL;
2952}
2953
40a18ebd
NC
2954static const char *
2955get_arm_section_type_name (unsigned int sh_type)
2956{
2957 switch (sh_type)
2958 {
7f6fed87
NC
2959 case SHT_ARM_EXIDX: return "ARM_EXIDX";
2960 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
2961 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
2962 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
2963 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
2964 default:
2965 break;
2966 }
2967 return NULL;
2968}
2969
40b36596
JM
2970static const char *
2971get_tic6x_section_type_name (unsigned int sh_type)
2972{
2973 switch (sh_type)
2974 {
2975 case SHT_C6000_UNWIND:
2976 return "C6000_UNWIND";
2977 case SHT_C6000_PREEMPTMAP:
2978 return "C6000_PREEMPTMAP";
2979 case SHT_C6000_ATTRIBUTES:
2980 return "C6000_ATTRIBUTES";
2981 case SHT_TI_ICODE:
2982 return "TI_ICODE";
2983 case SHT_TI_XREF:
2984 return "TI_XREF";
2985 case SHT_TI_HANDLER:
2986 return "TI_HANDLER";
2987 case SHT_TI_INITINFO:
2988 return "TI_INITINFO";
2989 case SHT_TI_PHATTRS:
2990 return "TI_PHATTRS";
2991 default:
2992 break;
2993 }
2994 return NULL;
2995}
2996
252b5132 2997static const char *
d3ba0551 2998get_section_type_name (unsigned int sh_type)
252b5132 2999{
b34976b6 3000 static char buff[32];
252b5132
RH
3001
3002 switch (sh_type)
3003 {
3004 case SHT_NULL: return "NULL";
3005 case SHT_PROGBITS: return "PROGBITS";
3006 case SHT_SYMTAB: return "SYMTAB";
3007 case SHT_STRTAB: return "STRTAB";
3008 case SHT_RELA: return "RELA";
3009 case SHT_HASH: return "HASH";
3010 case SHT_DYNAMIC: return "DYNAMIC";
3011 case SHT_NOTE: return "NOTE";
3012 case SHT_NOBITS: return "NOBITS";
3013 case SHT_REL: return "REL";
3014 case SHT_SHLIB: return "SHLIB";
3015 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3016 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3017 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3018 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3019 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3020 case SHT_GROUP: return "GROUP";
3021 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3022 case SHT_GNU_verdef: return "VERDEF";
3023 case SHT_GNU_verneed: return "VERNEED";
3024 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3025 case 0x6ffffff0: return "VERSYM";
3026 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3027 case 0x7ffffffd: return "AUXILIARY";
3028 case 0x7fffffff: return "FILTER";
047b2264 3029 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3030
3031 default:
3032 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3033 {
2cf0635d 3034 const char * result;
252b5132
RH
3035
3036 switch (elf_header.e_machine)
3037 {
3038 case EM_MIPS:
4fe85591 3039 case EM_MIPS_RS3_LE:
252b5132
RH
3040 result = get_mips_section_type_name (sh_type);
3041 break;
103f02d3
UD
3042 case EM_PARISC:
3043 result = get_parisc_section_type_name (sh_type);
3044 break;
4d6ed7c8
NC
3045 case EM_IA_64:
3046 result = get_ia64_section_type_name (sh_type);
3047 break;
d2b2c203 3048 case EM_X86_64:
8a9036a4 3049 case EM_L1OM:
7a9068fe 3050 case EM_K1OM:
d2b2c203
DJ
3051 result = get_x86_64_section_type_name (sh_type);
3052 break;
40a18ebd
NC
3053 case EM_ARM:
3054 result = get_arm_section_type_name (sh_type);
3055 break;
40b36596
JM
3056 case EM_TI_C6000:
3057 result = get_tic6x_section_type_name (sh_type);
3058 break;
252b5132
RH
3059 default:
3060 result = NULL;
3061 break;
3062 }
3063
3064 if (result != NULL)
3065 return result;
3066
c91d0dfb 3067 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3068 }
3069 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3070 {
2cf0635d 3071 const char * result;
148b93f2
NC
3072
3073 switch (elf_header.e_machine)
3074 {
3075 case EM_IA_64:
3076 result = get_ia64_section_type_name (sh_type);
3077 break;
3078 default:
3079 result = NULL;
3080 break;
3081 }
3082
3083 if (result != NULL)
3084 return result;
3085
3086 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3087 }
252b5132 3088 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3089 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3090 else
a7dbfd1c
NC
3091 /* This message is probably going to be displayed in a 15
3092 character wide field, so put the hex value first. */
3093 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3094
252b5132
RH
3095 return buff;
3096 }
3097}
3098
2979dc34 3099#define OPTION_DEBUG_DUMP 512
2c610e4b 3100#define OPTION_DYN_SYMS 513
fd2f0033
TT
3101#define OPTION_DWARF_DEPTH 514
3102#define OPTION_DWARF_START 515
2979dc34 3103
85b1c36d 3104static struct option options[] =
252b5132 3105{
b34976b6 3106 {"all", no_argument, 0, 'a'},
252b5132
RH
3107 {"file-header", no_argument, 0, 'h'},
3108 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3109 {"headers", no_argument, 0, 'e'},
3110 {"histogram", no_argument, 0, 'I'},
3111 {"segments", no_argument, 0, 'l'},
3112 {"sections", no_argument, 0, 'S'},
252b5132 3113 {"section-headers", no_argument, 0, 'S'},
f5842774 3114 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3115 {"section-details", no_argument, 0, 't'},
595cf52e 3116 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3117 {"symbols", no_argument, 0, 's'},
3118 {"syms", no_argument, 0, 's'},
2c610e4b 3119 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3120 {"relocs", no_argument, 0, 'r'},
3121 {"notes", no_argument, 0, 'n'},
3122 {"dynamic", no_argument, 0, 'd'},
a952a375 3123 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3124 {"version-info", no_argument, 0, 'V'},
3125 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3126 {"unwind", no_argument, 0, 'u'},
4145f1d5 3127 {"archive-index", no_argument, 0, 'c'},
b34976b6 3128 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3129 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3130 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3131#ifdef SUPPORT_DISASSEMBLY
3132 {"instruction-dump", required_argument, 0, 'i'},
3133#endif
cf13d699 3134 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3135
fd2f0033
TT
3136 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3137 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
3138
b34976b6
AM
3139 {"version", no_argument, 0, 'v'},
3140 {"wide", no_argument, 0, 'W'},
3141 {"help", no_argument, 0, 'H'},
3142 {0, no_argument, 0, 0}
252b5132
RH
3143};
3144
3145static void
2cf0635d 3146usage (FILE * stream)
252b5132 3147{
92f01d61
JM
3148 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3149 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3150 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3151 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3152 -h --file-header Display the ELF file header\n\
3153 -l --program-headers Display the program headers\n\
3154 --segments An alias for --program-headers\n\
3155 -S --section-headers Display the sections' header\n\
3156 --sections An alias for --section-headers\n\
f5842774 3157 -g --section-groups Display the section groups\n\
5477e8a0 3158 -t --section-details Display the section details\n\
8b53311e
NC
3159 -e --headers Equivalent to: -h -l -S\n\
3160 -s --syms Display the symbol table\n\
3f08eb35 3161 --symbols An alias for --syms\n\
2c610e4b 3162 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3163 -n --notes Display the core notes (if present)\n\
3164 -r --relocs Display the relocations (if present)\n\
3165 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3166 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
3167 -V --version-info Display the version sections (if present)\n\
3168 -A --arch-specific Display architecture specific information (if any).\n\
4145f1d5 3169 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3170 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3171 -x --hex-dump=<number|name>\n\
3172 Dump the contents of section <number|name> as bytes\n\
3173 -p --string-dump=<number|name>\n\
3174 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3175 -R --relocated-dump=<number|name>\n\
3176 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3177 -w[lLiaprmfFsoRt] or\n\
1ed06042 3178 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3179 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
5bbdf3d5 3180 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
8b53311e 3181 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3182 fprintf (stream, _("\
3183 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3184 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3185 or deeper\n"));
252b5132 3186#ifdef SUPPORT_DISASSEMBLY
92f01d61 3187 fprintf (stream, _("\
09c11c86
NC
3188 -i --instruction-dump=<number|name>\n\
3189 Disassemble the contents of section <number|name>\n"));
252b5132 3190#endif
92f01d61 3191 fprintf (stream, _("\
8b53311e
NC
3192 -I --histogram Display histogram of bucket list lengths\n\
3193 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3194 @<file> Read options from <file>\n\
8b53311e
NC
3195 -H --help Display this information\n\
3196 -v --version Display the version number of readelf\n"));
1118d252 3197
92f01d61
JM
3198 if (REPORT_BUGS_TO[0] && stream == stdout)
3199 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3200
92f01d61 3201 exit (stream == stdout ? 0 : 1);
252b5132
RH
3202}
3203
18bd398b
NC
3204/* Record the fact that the user wants the contents of section number
3205 SECTION to be displayed using the method(s) encoded as flags bits
3206 in TYPE. Note, TYPE can be zero if we are creating the array for
3207 the first time. */
3208
252b5132 3209static void
09c11c86 3210request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3211{
3212 if (section >= num_dump_sects)
3213 {
2cf0635d 3214 dump_type * new_dump_sects;
252b5132 3215
3f5e193b
NC
3216 new_dump_sects = (dump_type *) calloc (section + 1,
3217 sizeof (* dump_sects));
252b5132
RH
3218
3219 if (new_dump_sects == NULL)
591a748a 3220 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3221 else
3222 {
3223 /* Copy current flag settings. */
09c11c86 3224 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3225
3226 free (dump_sects);
3227
3228 dump_sects = new_dump_sects;
3229 num_dump_sects = section + 1;
3230 }
3231 }
3232
3233 if (dump_sects)
b34976b6 3234 dump_sects[section] |= type;
252b5132
RH
3235
3236 return;
3237}
3238
aef1f6d0
DJ
3239/* Request a dump by section name. */
3240
3241static void
2cf0635d 3242request_dump_byname (const char * section, dump_type type)
aef1f6d0 3243{
2cf0635d 3244 struct dump_list_entry * new_request;
aef1f6d0 3245
3f5e193b
NC
3246 new_request = (struct dump_list_entry *)
3247 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3248 if (!new_request)
591a748a 3249 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3250
3251 new_request->name = strdup (section);
3252 if (!new_request->name)
591a748a 3253 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3254
3255 new_request->type = type;
3256
3257 new_request->next = dump_sects_byname;
3258 dump_sects_byname = new_request;
3259}
3260
cf13d699
NC
3261static inline void
3262request_dump (dump_type type)
3263{
3264 int section;
3265 char * cp;
3266
3267 do_dump++;
3268 section = strtoul (optarg, & cp, 0);
3269
3270 if (! *cp && section >= 0)
3271 request_dump_bynumber (section, type);
3272 else
3273 request_dump_byname (optarg, type);
3274}
3275
3276
252b5132 3277static void
2cf0635d 3278parse_args (int argc, char ** argv)
252b5132
RH
3279{
3280 int c;
3281
3282 if (argc < 2)
92f01d61 3283 usage (stderr);
252b5132
RH
3284
3285 while ((c = getopt_long
cf13d699 3286 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3287 {
252b5132
RH
3288 switch (c)
3289 {
3290 case 0:
3291 /* Long options. */
3292 break;
3293 case 'H':
92f01d61 3294 usage (stdout);
252b5132
RH
3295 break;
3296
3297 case 'a':
b34976b6
AM
3298 do_syms++;
3299 do_reloc++;
3300 do_unwind++;
3301 do_dynamic++;
3302 do_header++;
3303 do_sections++;
f5842774 3304 do_section_groups++;
b34976b6
AM
3305 do_segments++;
3306 do_version++;
3307 do_histogram++;
3308 do_arch++;
3309 do_notes++;
252b5132 3310 break;
f5842774
L
3311 case 'g':
3312 do_section_groups++;
3313 break;
5477e8a0 3314 case 't':
595cf52e 3315 case 'N':
5477e8a0
L
3316 do_sections++;
3317 do_section_details++;
595cf52e 3318 break;
252b5132 3319 case 'e':
b34976b6
AM
3320 do_header++;
3321 do_sections++;
3322 do_segments++;
252b5132 3323 break;
a952a375 3324 case 'A':
b34976b6 3325 do_arch++;
a952a375 3326 break;
252b5132 3327 case 'D':
b34976b6 3328 do_using_dynamic++;
252b5132
RH
3329 break;
3330 case 'r':
b34976b6 3331 do_reloc++;
252b5132 3332 break;
4d6ed7c8 3333 case 'u':
b34976b6 3334 do_unwind++;
4d6ed7c8 3335 break;
252b5132 3336 case 'h':
b34976b6 3337 do_header++;
252b5132
RH
3338 break;
3339 case 'l':
b34976b6 3340 do_segments++;
252b5132
RH
3341 break;
3342 case 's':
b34976b6 3343 do_syms++;
252b5132
RH
3344 break;
3345 case 'S':
b34976b6 3346 do_sections++;
252b5132
RH
3347 break;
3348 case 'd':
b34976b6 3349 do_dynamic++;
252b5132 3350 break;
a952a375 3351 case 'I':
b34976b6 3352 do_histogram++;
a952a375 3353 break;
779fe533 3354 case 'n':
b34976b6 3355 do_notes++;
779fe533 3356 break;
4145f1d5
NC
3357 case 'c':
3358 do_archive_index++;
3359 break;
252b5132 3360 case 'x':
cf13d699 3361 request_dump (HEX_DUMP);
aef1f6d0 3362 break;
09c11c86 3363 case 'p':
cf13d699
NC
3364 request_dump (STRING_DUMP);
3365 break;
3366 case 'R':
3367 request_dump (RELOC_DUMP);
09c11c86 3368 break;
252b5132 3369 case 'w':
b34976b6 3370 do_dump++;
252b5132 3371 if (optarg == 0)
613ff48b
CC
3372 {
3373 do_debugging = 1;
3374 dwarf_select_sections_all ();
3375 }
252b5132
RH
3376 else
3377 {
3378 do_debugging = 0;
4cb93e3b 3379 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3380 }
3381 break;
2979dc34 3382 case OPTION_DEBUG_DUMP:
b34976b6 3383 do_dump++;
2979dc34
JJ
3384 if (optarg == 0)
3385 do_debugging = 1;
3386 else
3387 {
2979dc34 3388 do_debugging = 0;
4cb93e3b 3389 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3390 }
3391 break;
fd2f0033
TT
3392 case OPTION_DWARF_DEPTH:
3393 {
3394 char *cp;
3395
3396 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3397 }
3398 break;
3399 case OPTION_DWARF_START:
3400 {
3401 char *cp;
3402
3403 dwarf_start_die = strtoul (optarg, & cp, 0);
3404 }
3405 break;
2c610e4b
L
3406 case OPTION_DYN_SYMS:
3407 do_dyn_syms++;
3408 break;
252b5132
RH
3409#ifdef SUPPORT_DISASSEMBLY
3410 case 'i':
cf13d699
NC
3411 request_dump (DISASS_DUMP);
3412 break;
252b5132
RH
3413#endif
3414 case 'v':
3415 print_version (program_name);
3416 break;
3417 case 'V':
b34976b6 3418 do_version++;
252b5132 3419 break;
d974e256 3420 case 'W':
b34976b6 3421 do_wide++;
d974e256 3422 break;
252b5132 3423 default:
252b5132
RH
3424 /* xgettext:c-format */
3425 error (_("Invalid option '-%c'\n"), c);
3426 /* Drop through. */
3427 case '?':
92f01d61 3428 usage (stderr);
252b5132
RH
3429 }
3430 }
3431
4d6ed7c8 3432 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3433 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3434 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3435 && !do_section_groups && !do_archive_index
3436 && !do_dyn_syms)
92f01d61 3437 usage (stderr);
252b5132
RH
3438 else if (argc < 3)
3439 {
3440 warn (_("Nothing to do.\n"));
92f01d61 3441 usage (stderr);
252b5132
RH
3442 }
3443}
3444
3445static const char *
d3ba0551 3446get_elf_class (unsigned int elf_class)
252b5132 3447{
b34976b6 3448 static char buff[32];
103f02d3 3449
252b5132
RH
3450 switch (elf_class)
3451 {
3452 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3453 case ELFCLASS32: return "ELF32";
3454 case ELFCLASS64: return "ELF64";
ab5e7794 3455 default:
e9e44622 3456 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3457 return buff;
252b5132
RH
3458 }
3459}
3460
3461static const char *
d3ba0551 3462get_data_encoding (unsigned int encoding)
252b5132 3463{
b34976b6 3464 static char buff[32];
103f02d3 3465
252b5132
RH
3466 switch (encoding)
3467 {
3468 case ELFDATANONE: return _("none");
33c63f9d
CM
3469 case ELFDATA2LSB: return _("2's complement, little endian");
3470 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3471 default:
e9e44622 3472 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3473 return buff;
252b5132
RH
3474 }
3475}
3476
252b5132 3477/* Decode the data held in 'elf_header'. */
ee42cf8c 3478
252b5132 3479static int
d3ba0551 3480process_file_header (void)
252b5132 3481{
b34976b6
AM
3482 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3483 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3484 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3485 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3486 {
3487 error
3488 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3489 return 0;
3490 }
3491
2dc4cec1
L
3492 init_dwarf_regnames (elf_header.e_machine);
3493
252b5132
RH
3494 if (do_header)
3495 {
3496 int i;
3497
3498 printf (_("ELF Header:\n"));
3499 printf (_(" Magic: "));
b34976b6
AM
3500 for (i = 0; i < EI_NIDENT; i++)
3501 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3502 printf ("\n");
3503 printf (_(" Class: %s\n"),
b34976b6 3504 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3505 printf (_(" Data: %s\n"),
b34976b6 3506 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3507 printf (_(" Version: %d %s\n"),
b34976b6
AM
3508 elf_header.e_ident[EI_VERSION],
3509 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3510 ? "(current)"
b34976b6 3511 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3512 ? _("<unknown: %lx>")
789be9f7 3513 : "")));
252b5132 3514 printf (_(" OS/ABI: %s\n"),
b34976b6 3515 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3516 printf (_(" ABI Version: %d\n"),
b34976b6 3517 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3518 printf (_(" Type: %s\n"),
3519 get_file_type (elf_header.e_type));
3520 printf (_(" Machine: %s\n"),
3521 get_machine_name (elf_header.e_machine));
3522 printf (_(" Version: 0x%lx\n"),
3523 (unsigned long) elf_header.e_version);
76da6bbe 3524
f7a99963
NC
3525 printf (_(" Entry point address: "));
3526 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3527 printf (_("\n Start of program headers: "));
3528 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3529 printf (_(" (bytes into file)\n Start of section headers: "));
3530 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3531 printf (_(" (bytes into file)\n"));
76da6bbe 3532
252b5132
RH
3533 printf (_(" Flags: 0x%lx%s\n"),
3534 (unsigned long) elf_header.e_flags,
3535 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3536 printf (_(" Size of this header: %ld (bytes)\n"),
3537 (long) elf_header.e_ehsize);
3538 printf (_(" Size of program headers: %ld (bytes)\n"),
3539 (long) elf_header.e_phentsize);
2046a35d 3540 printf (_(" Number of program headers: %ld"),
252b5132 3541 (long) elf_header.e_phnum);
2046a35d
AM
3542 if (section_headers != NULL
3543 && elf_header.e_phnum == PN_XNUM
3544 && section_headers[0].sh_info != 0)
cc5914eb 3545 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3546 putc ('\n', stdout);
252b5132
RH
3547 printf (_(" Size of section headers: %ld (bytes)\n"),
3548 (long) elf_header.e_shentsize);
560f3c1c 3549 printf (_(" Number of section headers: %ld"),
252b5132 3550 (long) elf_header.e_shnum);
4fbb74a6 3551 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3552 printf (" (%ld)", (long) section_headers[0].sh_size);
3553 putc ('\n', stdout);
3554 printf (_(" Section header string table index: %ld"),
252b5132 3555 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3556 if (section_headers != NULL
3557 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3558 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3559 else if (elf_header.e_shstrndx != SHN_UNDEF
3560 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3561 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3562 putc ('\n', stdout);
3563 }
3564
3565 if (section_headers != NULL)
3566 {
2046a35d
AM
3567 if (elf_header.e_phnum == PN_XNUM
3568 && section_headers[0].sh_info != 0)
3569 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3570 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3571 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3572 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3573 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3574 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3575 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3576 free (section_headers);
3577 section_headers = NULL;
252b5132 3578 }
103f02d3 3579
9ea033b2
NC
3580 return 1;
3581}
3582
252b5132 3583
9ea033b2 3584static int
91d6fa6a 3585get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3586{
2cf0635d
NC
3587 Elf32_External_Phdr * phdrs;
3588 Elf32_External_Phdr * external;
3589 Elf_Internal_Phdr * internal;
b34976b6 3590 unsigned int i;
103f02d3 3591
3f5e193b
NC
3592 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3593 elf_header.e_phentsize,
3594 elf_header.e_phnum,
3595 _("program headers"));
a6e9f9df
AM
3596 if (!phdrs)
3597 return 0;
9ea033b2 3598
91d6fa6a 3599 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3600 i < elf_header.e_phnum;
b34976b6 3601 i++, internal++, external++)
252b5132 3602 {
9ea033b2
NC
3603 internal->p_type = BYTE_GET (external->p_type);
3604 internal->p_offset = BYTE_GET (external->p_offset);
3605 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3606 internal->p_paddr = BYTE_GET (external->p_paddr);
3607 internal->p_filesz = BYTE_GET (external->p_filesz);
3608 internal->p_memsz = BYTE_GET (external->p_memsz);
3609 internal->p_flags = BYTE_GET (external->p_flags);
3610 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3611 }
3612
9ea033b2
NC
3613 free (phdrs);
3614
252b5132
RH
3615 return 1;
3616}
3617
9ea033b2 3618static int
91d6fa6a 3619get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3620{
2cf0635d
NC
3621 Elf64_External_Phdr * phdrs;
3622 Elf64_External_Phdr * external;
3623 Elf_Internal_Phdr * internal;
b34976b6 3624 unsigned int i;
103f02d3 3625
3f5e193b
NC
3626 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3627 elf_header.e_phentsize,
3628 elf_header.e_phnum,
3629 _("program headers"));
a6e9f9df
AM
3630 if (!phdrs)
3631 return 0;
9ea033b2 3632
91d6fa6a 3633 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3634 i < elf_header.e_phnum;
b34976b6 3635 i++, internal++, external++)
9ea033b2
NC
3636 {
3637 internal->p_type = BYTE_GET (external->p_type);
3638 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3639 internal->p_offset = BYTE_GET (external->p_offset);
3640 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3641 internal->p_paddr = BYTE_GET (external->p_paddr);
3642 internal->p_filesz = BYTE_GET (external->p_filesz);
3643 internal->p_memsz = BYTE_GET (external->p_memsz);
3644 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3645 }
3646
3647 free (phdrs);
3648
3649 return 1;
3650}
252b5132 3651
d93f0186
NC
3652/* Returns 1 if the program headers were read into `program_headers'. */
3653
3654static int
2cf0635d 3655get_program_headers (FILE * file)
d93f0186 3656{
2cf0635d 3657 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3658
3659 /* Check cache of prior read. */
3660 if (program_headers != NULL)
3661 return 1;
3662
3f5e193b
NC
3663 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3664 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3665
3666 if (phdrs == NULL)
3667 {
3668 error (_("Out of memory\n"));
3669 return 0;
3670 }
3671
3672 if (is_32bit_elf
3673 ? get_32bit_program_headers (file, phdrs)
3674 : get_64bit_program_headers (file, phdrs))
3675 {
3676 program_headers = phdrs;
3677 return 1;
3678 }
3679
3680 free (phdrs);
3681 return 0;
3682}
3683
2f62977e
NC
3684/* Returns 1 if the program headers were loaded. */
3685
252b5132 3686static int
2cf0635d 3687process_program_headers (FILE * file)
252b5132 3688{
2cf0635d 3689 Elf_Internal_Phdr * segment;
b34976b6 3690 unsigned int i;
252b5132
RH
3691
3692 if (elf_header.e_phnum == 0)
3693 {
82f2dbf7
NC
3694 /* PR binutils/12467. */
3695 if (elf_header.e_phoff != 0)
3696 warn (_("possibly corrupt ELF header - it has a non-zero program"
3697 " header offset, but no program headers"));
3698 else if (do_segments)
252b5132 3699 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3700 return 0;
252b5132
RH
3701 }
3702
3703 if (do_segments && !do_header)
3704 {
f7a99963
NC
3705 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3706 printf (_("Entry point "));
3707 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3708 printf (_("\nThere are %d program headers, starting at offset "),
3709 elf_header.e_phnum);
3710 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3711 printf ("\n");
252b5132
RH
3712 }
3713
d93f0186 3714 if (! get_program_headers (file))
252b5132 3715 return 0;
103f02d3 3716
252b5132
RH
3717 if (do_segments)
3718 {
3a1a2036
NC
3719 if (elf_header.e_phnum > 1)
3720 printf (_("\nProgram Headers:\n"));
3721 else
3722 printf (_("\nProgram Headers:\n"));
76da6bbe 3723
f7a99963
NC
3724 if (is_32bit_elf)
3725 printf
3726 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3727 else if (do_wide)
3728 printf
3729 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3730 else
3731 {
3732 printf
3733 (_(" Type Offset VirtAddr PhysAddr\n"));
3734 printf
3735 (_(" FileSiz MemSiz Flags Align\n"));
3736 }
252b5132
RH
3737 }
3738
252b5132 3739 dynamic_addr = 0;
1b228002 3740 dynamic_size = 0;
252b5132
RH
3741
3742 for (i = 0, segment = program_headers;
3743 i < elf_header.e_phnum;
b34976b6 3744 i++, segment++)
252b5132
RH
3745 {
3746 if (do_segments)
3747 {
103f02d3 3748 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3749
3750 if (is_32bit_elf)
3751 {
3752 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3753 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3754 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3755 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3756 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3757 printf ("%c%c%c ",
3758 (segment->p_flags & PF_R ? 'R' : ' '),
3759 (segment->p_flags & PF_W ? 'W' : ' '),
3760 (segment->p_flags & PF_X ? 'E' : ' '));
3761 printf ("%#lx", (unsigned long) segment->p_align);
3762 }
d974e256
JJ
3763 else if (do_wide)
3764 {
3765 if ((unsigned long) segment->p_offset == segment->p_offset)
3766 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3767 else
3768 {
3769 print_vma (segment->p_offset, FULL_HEX);
3770 putchar (' ');
3771 }
3772
3773 print_vma (segment->p_vaddr, FULL_HEX);
3774 putchar (' ');
3775 print_vma (segment->p_paddr, FULL_HEX);
3776 putchar (' ');
3777
3778 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3779 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3780 else
3781 {
3782 print_vma (segment->p_filesz, FULL_HEX);
3783 putchar (' ');
3784 }
3785
3786 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3787 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3788 else
3789 {
3790 print_vma (segment->p_offset, FULL_HEX);
3791 }
3792
3793 printf (" %c%c%c ",
3794 (segment->p_flags & PF_R ? 'R' : ' '),
3795 (segment->p_flags & PF_W ? 'W' : ' '),
3796 (segment->p_flags & PF_X ? 'E' : ' '));
3797
3798 if ((unsigned long) segment->p_align == segment->p_align)
3799 printf ("%#lx", (unsigned long) segment->p_align);
3800 else
3801 {
3802 print_vma (segment->p_align, PREFIX_HEX);
3803 }
3804 }
f7a99963
NC
3805 else
3806 {
3807 print_vma (segment->p_offset, FULL_HEX);
3808 putchar (' ');
3809 print_vma (segment->p_vaddr, FULL_HEX);
3810 putchar (' ');
3811 print_vma (segment->p_paddr, FULL_HEX);
3812 printf ("\n ");
3813 print_vma (segment->p_filesz, FULL_HEX);
3814 putchar (' ');
3815 print_vma (segment->p_memsz, FULL_HEX);
3816 printf (" %c%c%c ",
3817 (segment->p_flags & PF_R ? 'R' : ' '),
3818 (segment->p_flags & PF_W ? 'W' : ' '),
3819 (segment->p_flags & PF_X ? 'E' : ' '));
3820 print_vma (segment->p_align, HEX);
3821 }
252b5132
RH
3822 }
3823
3824 switch (segment->p_type)
3825 {
252b5132
RH
3826 case PT_DYNAMIC:
3827 if (dynamic_addr)
3828 error (_("more than one dynamic segment\n"));
3829
20737c13
AM
3830 /* By default, assume that the .dynamic section is the first
3831 section in the DYNAMIC segment. */
3832 dynamic_addr = segment->p_offset;
3833 dynamic_size = segment->p_filesz;
3834
b2d38a17
NC
3835 /* Try to locate the .dynamic section. If there is
3836 a section header table, we can easily locate it. */
3837 if (section_headers != NULL)
3838 {
2cf0635d 3839 Elf_Internal_Shdr * sec;
b2d38a17 3840
89fac5e3
RS
3841 sec = find_section (".dynamic");
3842 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3843 {
28f997cf
TG
3844 /* A corresponding .dynamic section is expected, but on
3845 IA-64/OpenVMS it is OK for it to be missing. */
3846 if (!is_ia64_vms ())
3847 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3848 break;
3849 }
3850
42bb2e33 3851 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3852 {
3853 dynamic_size = 0;
3854 break;
3855 }
42bb2e33 3856
b2d38a17
NC
3857 dynamic_addr = sec->sh_offset;
3858 dynamic_size = sec->sh_size;
3859
3860 if (dynamic_addr < segment->p_offset
3861 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3862 warn (_("the .dynamic section is not contained"
3863 " within the dynamic segment\n"));
b2d38a17 3864 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3865 warn (_("the .dynamic section is not the first section"
3866 " in the dynamic segment.\n"));
b2d38a17 3867 }
252b5132
RH
3868 break;
3869
3870 case PT_INTERP:
fb52b2f4
NC
3871 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3872 SEEK_SET))
252b5132
RH
3873 error (_("Unable to find program interpreter name\n"));
3874 else
3875 {
f8eae8b2
L
3876 char fmt [32];
3877 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3878
3879 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3880 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3881
252b5132 3882 program_interpreter[0] = 0;
7bd7b3ef
AM
3883 if (fscanf (file, fmt, program_interpreter) <= 0)
3884 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3885
3886 if (do_segments)
3887 printf (_("\n [Requesting program interpreter: %s]"),
3888 program_interpreter);
3889 }
3890 break;
3891 }
3892
3893 if (do_segments)
3894 putc ('\n', stdout);
3895 }
3896
c256ffe7 3897 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3898 {
3899 printf (_("\n Section to Segment mapping:\n"));
3900 printf (_(" Segment Sections...\n"));
3901
252b5132
RH
3902 for (i = 0; i < elf_header.e_phnum; i++)
3903 {
9ad5cbcf 3904 unsigned int j;
2cf0635d 3905 Elf_Internal_Shdr * section;
252b5132
RH
3906
3907 segment = program_headers + i;
b391a3e3 3908 section = section_headers + 1;
252b5132
RH
3909
3910 printf (" %2.2d ", i);
3911
b34976b6 3912 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3913 {
f4638467
AM
3914 if (!ELF_TBSS_SPECIAL (section, segment)
3915 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
3916 printf ("%s ", SECTION_NAME (section));
3917 }
3918
3919 putc ('\n',stdout);
3920 }
3921 }
3922
252b5132
RH
3923 return 1;
3924}
3925
3926
d93f0186
NC
3927/* Find the file offset corresponding to VMA by using the program headers. */
3928
3929static long
2cf0635d 3930offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 3931{
2cf0635d 3932 Elf_Internal_Phdr * seg;
d93f0186
NC
3933
3934 if (! get_program_headers (file))
3935 {
3936 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3937 return (long) vma;
3938 }
3939
3940 for (seg = program_headers;
3941 seg < program_headers + elf_header.e_phnum;
3942 ++seg)
3943 {
3944 if (seg->p_type != PT_LOAD)
3945 continue;
3946
3947 if (vma >= (seg->p_vaddr & -seg->p_align)
3948 && vma + size <= seg->p_vaddr + seg->p_filesz)
3949 return vma - seg->p_vaddr + seg->p_offset;
3950 }
3951
3952 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 3953 (unsigned long) vma);
d93f0186
NC
3954 return (long) vma;
3955}
3956
3957
252b5132 3958static int
2cf0635d 3959get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 3960{
2cf0635d
NC
3961 Elf32_External_Shdr * shdrs;
3962 Elf_Internal_Shdr * internal;
b34976b6 3963 unsigned int i;
252b5132 3964
3f5e193b
NC
3965 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3966 elf_header.e_shentsize, num,
3967 _("section headers"));
a6e9f9df
AM
3968 if (!shdrs)
3969 return 0;
252b5132 3970
3f5e193b
NC
3971 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3972 sizeof (Elf_Internal_Shdr));
252b5132
RH
3973
3974 if (section_headers == NULL)
3975 {
3976 error (_("Out of memory\n"));
3977 return 0;
3978 }
3979
3980 for (i = 0, internal = section_headers;
560f3c1c 3981 i < num;
b34976b6 3982 i++, internal++)
252b5132
RH
3983 {
3984 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3985 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3986 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3987 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3988 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3989 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3990 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3991 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3992 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3993 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3994 }
3995
3996 free (shdrs);
3997
3998 return 1;
3999}
4000
9ea033b2 4001static int
2cf0635d 4002get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4003{
2cf0635d
NC
4004 Elf64_External_Shdr * shdrs;
4005 Elf_Internal_Shdr * internal;
b34976b6 4006 unsigned int i;
9ea033b2 4007
3f5e193b
NC
4008 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4009 elf_header.e_shentsize, num,
4010 _("section headers"));
a6e9f9df
AM
4011 if (!shdrs)
4012 return 0;
9ea033b2 4013
3f5e193b
NC
4014 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4015 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4016
4017 if (section_headers == NULL)
4018 {
4019 error (_("Out of memory\n"));
4020 return 0;
4021 }
4022
4023 for (i = 0, internal = section_headers;
560f3c1c 4024 i < num;
b34976b6 4025 i++, internal++)
9ea033b2
NC
4026 {
4027 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4028 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4029 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4030 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4031 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4032 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4033 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4034 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4035 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4036 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4037 }
4038
4039 free (shdrs);
4040
4041 return 1;
4042}
4043
252b5132 4044static Elf_Internal_Sym *
2cf0635d 4045get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
252b5132 4046{
9ad5cbcf 4047 unsigned long number;
dd24e3da 4048 Elf32_External_Sym * esyms = NULL;
2cf0635d 4049 Elf_External_Sym_Shndx * shndx;
dd24e3da 4050 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4051 Elf_Internal_Sym * psym;
b34976b6 4052 unsigned int j;
252b5132 4053
dd24e3da
NC
4054 /* Run some sanity checks first. */
4055 if (section->sh_entsize == 0)
4056 {
4057 error (_("sh_entsize is zero\n"));
4058 return NULL;
4059 }
4060
4061 number = section->sh_size / section->sh_entsize;
4062
4063 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4064 {
4065 error (_("Invalid sh_entsize\n"));
4066 return NULL;
4067 }
4068
3f5e193b
NC
4069 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4070 section->sh_size, _("symbols"));
dd24e3da 4071 if (esyms == NULL)
a6e9f9df 4072 return NULL;
252b5132 4073
9ad5cbcf
AM
4074 shndx = NULL;
4075 if (symtab_shndx_hdr != NULL
4076 && (symtab_shndx_hdr->sh_link
4fbb74a6 4077 == (unsigned long) (section - section_headers)))
9ad5cbcf 4078 {
3f5e193b
NC
4079 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4080 symtab_shndx_hdr->sh_offset,
4081 1, symtab_shndx_hdr->sh_size,
4082 _("symtab shndx"));
dd24e3da
NC
4083 if (shndx == NULL)
4084 goto exit_point;
9ad5cbcf
AM
4085 }
4086
3f5e193b 4087 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4088
4089 if (isyms == NULL)
4090 {
4091 error (_("Out of memory\n"));
dd24e3da 4092 goto exit_point;
252b5132
RH
4093 }
4094
dd24e3da 4095 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4096 {
4097 psym->st_name = BYTE_GET (esyms[j].st_name);
4098 psym->st_value = BYTE_GET (esyms[j].st_value);
4099 psym->st_size = BYTE_GET (esyms[j].st_size);
4100 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4101 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4102 psym->st_shndx
4103 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4104 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4105 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4106 psym->st_info = BYTE_GET (esyms[j].st_info);
4107 psym->st_other = BYTE_GET (esyms[j].st_other);
4108 }
4109
dd24e3da 4110 exit_point:
9ad5cbcf
AM
4111 if (shndx)
4112 free (shndx);
dd24e3da
NC
4113 if (esyms)
4114 free (esyms);
252b5132
RH
4115
4116 return isyms;
4117}
4118
9ea033b2 4119static Elf_Internal_Sym *
2cf0635d 4120get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
9ea033b2 4121{
9ad5cbcf 4122 unsigned long number;
2cf0635d
NC
4123 Elf64_External_Sym * esyms;
4124 Elf_External_Sym_Shndx * shndx;
4125 Elf_Internal_Sym * isyms;
4126 Elf_Internal_Sym * psym;
b34976b6 4127 unsigned int j;
9ea033b2 4128
dd24e3da
NC
4129 /* Run some sanity checks first. */
4130 if (section->sh_entsize == 0)
4131 {
4132 error (_("sh_entsize is zero\n"));
4133 return NULL;
4134 }
4135
4136 number = section->sh_size / section->sh_entsize;
4137
4138 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4139 {
4140 error (_("Invalid sh_entsize\n"));
4141 return NULL;
4142 }
4143
3f5e193b
NC
4144 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4145 section->sh_size, _("symbols"));
a6e9f9df
AM
4146 if (!esyms)
4147 return NULL;
9ea033b2 4148
9ad5cbcf
AM
4149 shndx = NULL;
4150 if (symtab_shndx_hdr != NULL
4151 && (symtab_shndx_hdr->sh_link
4fbb74a6 4152 == (unsigned long) (section - section_headers)))
9ad5cbcf 4153 {
3f5e193b
NC
4154 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4155 symtab_shndx_hdr->sh_offset,
4156 1, symtab_shndx_hdr->sh_size,
4157 _("symtab shndx"));
9ad5cbcf
AM
4158 if (!shndx)
4159 {
4160 free (esyms);
4161 return NULL;
4162 }
4163 }
4164
3f5e193b 4165 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4166
4167 if (isyms == NULL)
4168 {
4169 error (_("Out of memory\n"));
9ad5cbcf
AM
4170 if (shndx)
4171 free (shndx);
9ea033b2 4172 free (esyms);
9ea033b2
NC
4173 return NULL;
4174 }
4175
4176 for (j = 0, psym = isyms;
4177 j < number;
b34976b6 4178 j++, psym++)
9ea033b2
NC
4179 {
4180 psym->st_name = BYTE_GET (esyms[j].st_name);
4181 psym->st_info = BYTE_GET (esyms[j].st_info);
4182 psym->st_other = BYTE_GET (esyms[j].st_other);
4183 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4184 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4185 psym->st_shndx
4186 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4187 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4188 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
66543521
AM
4189 psym->st_value = BYTE_GET (esyms[j].st_value);
4190 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4191 }
4192
9ad5cbcf
AM
4193 if (shndx)
4194 free (shndx);
9ea033b2
NC
4195 free (esyms);
4196
4197 return isyms;
4198}
4199
d1133906 4200static const char *
d3ba0551 4201get_elf_section_flags (bfd_vma sh_flags)
d1133906 4202{
5477e8a0 4203 static char buff[1024];
2cf0635d 4204 char * p = buff;
8d5ff12c 4205 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4206 int sindex;
4207 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4208 bfd_vma os_flags = 0;
4209 bfd_vma proc_flags = 0;
4210 bfd_vma unknown_flags = 0;
148b93f2 4211 static const struct
5477e8a0 4212 {
2cf0635d 4213 const char * str;
5477e8a0
L
4214 int len;
4215 }
4216 flags [] =
4217 {
cfcac11d
NC
4218 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4219 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4220 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4221 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4222 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4223 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4224 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4225 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4226 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4227 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4228 /* IA-64 specific. */
4229 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4230 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4231 /* IA-64 OpenVMS specific. */
4232 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4233 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4234 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4235 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4236 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4237 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4238 /* Generic. */
cfcac11d 4239 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4240 /* SPARC specific. */
cfcac11d 4241 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4242 };
4243
4244 if (do_section_details)
4245 {
8d5ff12c
L
4246 sprintf (buff, "[%*.*lx]: ",
4247 field_size, field_size, (unsigned long) sh_flags);
4248 p += field_size + 4;
5477e8a0 4249 }
76da6bbe 4250
d1133906
NC
4251 while (sh_flags)
4252 {
4253 bfd_vma flag;
4254
4255 flag = sh_flags & - sh_flags;
4256 sh_flags &= ~ flag;
76da6bbe 4257
5477e8a0 4258 if (do_section_details)
d1133906 4259 {
5477e8a0
L
4260 switch (flag)
4261 {
91d6fa6a
NC
4262 case SHF_WRITE: sindex = 0; break;
4263 case SHF_ALLOC: sindex = 1; break;
4264 case SHF_EXECINSTR: sindex = 2; break;
4265 case SHF_MERGE: sindex = 3; break;
4266 case SHF_STRINGS: sindex = 4; break;
4267 case SHF_INFO_LINK: sindex = 5; break;
4268 case SHF_LINK_ORDER: sindex = 6; break;
4269 case SHF_OS_NONCONFORMING: sindex = 7; break;
4270 case SHF_GROUP: sindex = 8; break;
4271 case SHF_TLS: sindex = 9; break;
18ae9cc1 4272 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4273
5477e8a0 4274 default:
91d6fa6a 4275 sindex = -1;
cfcac11d 4276 switch (elf_header.e_machine)
148b93f2 4277 {
cfcac11d 4278 case EM_IA_64:
148b93f2 4279 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4280 sindex = 10;
148b93f2 4281 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4282 sindex = 11;
148b93f2
NC
4283#ifdef BFD64
4284 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4285 switch (flag)
4286 {
91d6fa6a
NC
4287 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4288 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4289 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4290 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4291 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4292 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4293 default: break;
4294 }
4295#endif
cfcac11d
NC
4296 break;
4297
caa83f8b
NC
4298 case EM_386:
4299 case EM_486:
4300 case EM_X86_64:
7f502d6c 4301 case EM_L1OM:
7a9068fe 4302 case EM_K1OM:
cfcac11d
NC
4303 case EM_OLD_SPARCV9:
4304 case EM_SPARC32PLUS:
4305 case EM_SPARCV9:
4306 case EM_SPARC:
18ae9cc1 4307 if (flag == SHF_ORDERED)
91d6fa6a 4308 sindex = 19;
cfcac11d
NC
4309 break;
4310 default:
4311 break;
148b93f2 4312 }
5477e8a0
L
4313 }
4314
91d6fa6a 4315 if (sindex != -1)
5477e8a0 4316 {
8d5ff12c
L
4317 if (p != buff + field_size + 4)
4318 {
4319 if (size < (10 + 2))
4320 abort ();
4321 size -= 2;
4322 *p++ = ',';
4323 *p++ = ' ';
4324 }
4325
91d6fa6a
NC
4326 size -= flags [sindex].len;
4327 p = stpcpy (p, flags [sindex].str);
5477e8a0 4328 }
3b22753a 4329 else if (flag & SHF_MASKOS)
8d5ff12c 4330 os_flags |= flag;
d1133906 4331 else if (flag & SHF_MASKPROC)
8d5ff12c 4332 proc_flags |= flag;
d1133906 4333 else
8d5ff12c 4334 unknown_flags |= flag;
5477e8a0
L
4335 }
4336 else
4337 {
4338 switch (flag)
4339 {
4340 case SHF_WRITE: *p = 'W'; break;
4341 case SHF_ALLOC: *p = 'A'; break;
4342 case SHF_EXECINSTR: *p = 'X'; break;
4343 case SHF_MERGE: *p = 'M'; break;
4344 case SHF_STRINGS: *p = 'S'; break;
4345 case SHF_INFO_LINK: *p = 'I'; break;
4346 case SHF_LINK_ORDER: *p = 'L'; break;
4347 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4348 case SHF_GROUP: *p = 'G'; break;
4349 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4350 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4351
4352 default:
8a9036a4 4353 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4354 || elf_header.e_machine == EM_L1OM
4355 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4356 && flag == SHF_X86_64_LARGE)
4357 *p = 'l';
4358 else if (flag & SHF_MASKOS)
4359 {
4360 *p = 'o';
4361 sh_flags &= ~ SHF_MASKOS;
4362 }
4363 else if (flag & SHF_MASKPROC)
4364 {
4365 *p = 'p';
4366 sh_flags &= ~ SHF_MASKPROC;
4367 }
4368 else
4369 *p = 'x';
4370 break;
4371 }
4372 p++;
d1133906
NC
4373 }
4374 }
76da6bbe 4375
8d5ff12c
L
4376 if (do_section_details)
4377 {
4378 if (os_flags)
4379 {
4380 size -= 5 + field_size;
4381 if (p != buff + field_size + 4)
4382 {
4383 if (size < (2 + 1))
4384 abort ();
4385 size -= 2;
4386 *p++ = ',';
4387 *p++ = ' ';
4388 }
4389 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4390 (unsigned long) os_flags);
4391 p += 5 + field_size;
4392 }
4393 if (proc_flags)
4394 {
4395 size -= 7 + field_size;
4396 if (p != buff + field_size + 4)
4397 {
4398 if (size < (2 + 1))
4399 abort ();
4400 size -= 2;
4401 *p++ = ',';
4402 *p++ = ' ';
4403 }
4404 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4405 (unsigned long) proc_flags);
4406 p += 7 + field_size;
4407 }
4408 if (unknown_flags)
4409 {
4410 size -= 10 + field_size;
4411 if (p != buff + field_size + 4)
4412 {
4413 if (size < (2 + 1))
4414 abort ();
4415 size -= 2;
4416 *p++ = ',';
4417 *p++ = ' ';
4418 }
2b692964 4419 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4420 (unsigned long) unknown_flags);
4421 p += 10 + field_size;
4422 }
4423 }
4424
e9e44622 4425 *p = '\0';
d1133906
NC
4426 return buff;
4427}
4428
252b5132 4429static int
2cf0635d 4430process_section_headers (FILE * file)
252b5132 4431{
2cf0635d 4432 Elf_Internal_Shdr * section;
b34976b6 4433 unsigned int i;
252b5132
RH
4434
4435 section_headers = NULL;
4436
4437 if (elf_header.e_shnum == 0)
4438 {
82f2dbf7
NC
4439 /* PR binutils/12467. */
4440 if (elf_header.e_shoff != 0)
4441 warn (_("possibly corrupt ELF file header - it has a non-zero"
4442 " section header offset, but no section headers\n"));
4443 else if (do_sections)
252b5132
RH
4444 printf (_("\nThere are no sections in this file.\n"));
4445
4446 return 1;
4447 }
4448
4449 if (do_sections && !do_header)
9ea033b2 4450 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4451 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4452
9ea033b2
NC
4453 if (is_32bit_elf)
4454 {
560f3c1c 4455 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4456 return 0;
4457 }
560f3c1c 4458 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4459 return 0;
4460
4461 /* Read in the string table, so that we have names to display. */
0b49d371 4462 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4463 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4464 {
4fbb74a6 4465 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4466
c256ffe7
JJ
4467 if (section->sh_size != 0)
4468 {
3f5e193b
NC
4469 string_table = (char *) get_data (NULL, file, section->sh_offset,
4470 1, section->sh_size,
4471 _("string table"));
0de14b54 4472
c256ffe7
JJ
4473 string_table_length = string_table != NULL ? section->sh_size : 0;
4474 }
252b5132
RH
4475 }
4476
4477 /* Scan the sections for the dynamic symbol table
e3c8793a 4478 and dynamic string table and debug sections. */
252b5132
RH
4479 dynamic_symbols = NULL;
4480 dynamic_strings = NULL;
4481 dynamic_syminfo = NULL;
f1ef08cb 4482 symtab_shndx_hdr = NULL;
103f02d3 4483
89fac5e3
RS
4484 eh_addr_size = is_32bit_elf ? 4 : 8;
4485 switch (elf_header.e_machine)
4486 {
4487 case EM_MIPS:
4488 case EM_MIPS_RS3_LE:
4489 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4490 FDE addresses. However, the ABI also has a semi-official ILP32
4491 variant for which the normal FDE address size rules apply.
4492
4493 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4494 section, where XX is the size of longs in bits. Unfortunately,
4495 earlier compilers provided no way of distinguishing ILP32 objects
4496 from LP64 objects, so if there's any doubt, we should assume that
4497 the official LP64 form is being used. */
4498 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4499 && find_section (".gcc_compiled_long32") == NULL)
4500 eh_addr_size = 8;
4501 break;
0f56a26a
DD
4502
4503 case EM_H8_300:
4504 case EM_H8_300H:
4505 switch (elf_header.e_flags & EF_H8_MACH)
4506 {
4507 case E_H8_MACH_H8300:
4508 case E_H8_MACH_H8300HN:
4509 case E_H8_MACH_H8300SN:
4510 case E_H8_MACH_H8300SXN:
4511 eh_addr_size = 2;
4512 break;
4513 case E_H8_MACH_H8300H:
4514 case E_H8_MACH_H8300S:
4515 case E_H8_MACH_H8300SX:
4516 eh_addr_size = 4;
4517 break;
4518 }
f4236fe4
DD
4519 break;
4520
ff7eeb89 4521 case EM_M32C_OLD:
f4236fe4
DD
4522 case EM_M32C:
4523 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4524 {
4525 case EF_M32C_CPU_M16C:
4526 eh_addr_size = 2;
4527 break;
4528 }
4529 break;
89fac5e3
RS
4530 }
4531
08d8fa11
JJ
4532#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4533 do \
4534 { \
4535 size_t expected_entsize \
4536 = is_32bit_elf ? size32 : size64; \
4537 if (section->sh_entsize != expected_entsize) \
4538 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4539 i, (unsigned long int) section->sh_entsize, \
4540 (unsigned long int) expected_entsize); \
4541 section->sh_entsize = expected_entsize; \
4542 } \
4543 while (0)
4544#define CHECK_ENTSIZE(section, i, type) \
4545 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4546 sizeof (Elf64_External_##type))
4547
252b5132
RH
4548 for (i = 0, section = section_headers;
4549 i < elf_header.e_shnum;
b34976b6 4550 i++, section++)
252b5132 4551 {
2cf0635d 4552 char * name = SECTION_NAME (section);
252b5132
RH
4553
4554 if (section->sh_type == SHT_DYNSYM)
4555 {
4556 if (dynamic_symbols != NULL)
4557 {
4558 error (_("File contains multiple dynamic symbol tables\n"));
4559 continue;
4560 }
4561
08d8fa11 4562 CHECK_ENTSIZE (section, i, Sym);
19936277 4563 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4564 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4565 }
4566 else if (section->sh_type == SHT_STRTAB
18bd398b 4567 && streq (name, ".dynstr"))
252b5132
RH
4568 {
4569 if (dynamic_strings != NULL)
4570 {
4571 error (_("File contains multiple dynamic string tables\n"));
4572 continue;
4573 }
4574
3f5e193b
NC
4575 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4576 1, section->sh_size,
4577 _("dynamic strings"));
59245841 4578 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4579 }
9ad5cbcf
AM
4580 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4581 {
4582 if (symtab_shndx_hdr != NULL)
4583 {
4584 error (_("File contains multiple symtab shndx tables\n"));
4585 continue;
4586 }
4587 symtab_shndx_hdr = section;
4588 }
08d8fa11
JJ
4589 else if (section->sh_type == SHT_SYMTAB)
4590 CHECK_ENTSIZE (section, i, Sym);
4591 else if (section->sh_type == SHT_GROUP)
4592 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4593 else if (section->sh_type == SHT_REL)
4594 CHECK_ENTSIZE (section, i, Rel);
4595 else if (section->sh_type == SHT_RELA)
4596 CHECK_ENTSIZE (section, i, Rela);
252b5132 4597 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4598 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4599 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4600 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4601 && (const_strneq (name, ".debug_")
4602 || const_strneq (name, ".zdebug_")))
252b5132 4603 {
1b315056
CS
4604 if (name[1] == 'z')
4605 name += sizeof (".zdebug_") - 1;
4606 else
4607 name += sizeof (".debug_") - 1;
252b5132
RH
4608
4609 if (do_debugging
18bd398b 4610 || (do_debug_info && streq (name, "info"))
2b6f5997 4611 || (do_debug_info && streq (name, "types"))
18bd398b 4612 || (do_debug_abbrevs && streq (name, "abbrev"))
4cb93e3b 4613 || (do_debug_lines && streq (name, "line"))
18bd398b 4614 || (do_debug_pubnames && streq (name, "pubnames"))
f9f0e732 4615 || (do_debug_pubtypes && streq (name, "pubtypes"))
18bd398b
NC
4616 || (do_debug_aranges && streq (name, "aranges"))
4617 || (do_debug_ranges && streq (name, "ranges"))
4618 || (do_debug_frames && streq (name, "frame"))
4619 || (do_debug_macinfo && streq (name, "macinfo"))
4620 || (do_debug_str && streq (name, "str"))
4621 || (do_debug_loc && streq (name, "loc"))
252b5132 4622 )
09c11c86 4623 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4624 }
a262ae96 4625 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4626 else if ((do_debugging || do_debug_info)
0112cd26 4627 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4628 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4629 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4630 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4631 else if (do_gdb_index && streq (name, ".gdb_index"))
4632 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4633 /* Trace sections for Itanium VMS. */
4634 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4635 || do_trace_aranges)
4636 && const_strneq (name, ".trace_"))
4637 {
4638 name += sizeof (".trace_") - 1;
4639
4640 if (do_debugging
4641 || (do_trace_info && streq (name, "info"))
4642 || (do_trace_abbrevs && streq (name, "abbrev"))
4643 || (do_trace_aranges && streq (name, "aranges"))
4644 )
4645 request_dump_bynumber (i, DEBUG_DUMP);
4646 }
4647
252b5132
RH
4648 }
4649
4650 if (! do_sections)
4651 return 1;
4652
3a1a2036
NC
4653 if (elf_header.e_shnum > 1)
4654 printf (_("\nSection Headers:\n"));
4655 else
4656 printf (_("\nSection Header:\n"));
76da6bbe 4657
f7a99963 4658 if (is_32bit_elf)
595cf52e 4659 {
5477e8a0 4660 if (do_section_details)
595cf52e
L
4661 {
4662 printf (_(" [Nr] Name\n"));
5477e8a0 4663 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4664 }
4665 else
4666 printf
4667 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4668 }
d974e256 4669 else if (do_wide)
595cf52e 4670 {
5477e8a0 4671 if (do_section_details)
595cf52e
L
4672 {
4673 printf (_(" [Nr] Name\n"));
5477e8a0 4674 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4675 }
4676 else
4677 printf
4678 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4679 }
f7a99963
NC
4680 else
4681 {
5477e8a0 4682 if (do_section_details)
595cf52e
L
4683 {
4684 printf (_(" [Nr] Name\n"));
5477e8a0
L
4685 printf (_(" Type Address Offset Link\n"));
4686 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4687 }
4688 else
4689 {
4690 printf (_(" [Nr] Name Type Address Offset\n"));
4691 printf (_(" Size EntSize Flags Link Info Align\n"));
4692 }
f7a99963 4693 }
252b5132 4694
5477e8a0
L
4695 if (do_section_details)
4696 printf (_(" Flags\n"));
4697
252b5132
RH
4698 for (i = 0, section = section_headers;
4699 i < elf_header.e_shnum;
b34976b6 4700 i++, section++)
252b5132 4701 {
5477e8a0 4702 if (do_section_details)
595cf52e
L
4703 {
4704 printf (" [%2u] %s\n",
4fbb74a6 4705 i,
595cf52e
L
4706 SECTION_NAME (section));
4707 if (is_32bit_elf || do_wide)
4708 printf (" %-15.15s ",
4709 get_section_type_name (section->sh_type));
4710 }
4711 else
b9eb56c1
NC
4712 printf ((do_wide ? " [%2u] %-17s %-15s "
4713 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4714 i,
595cf52e
L
4715 SECTION_NAME (section),
4716 get_section_type_name (section->sh_type));
252b5132 4717
f7a99963
NC
4718 if (is_32bit_elf)
4719 {
cfcac11d
NC
4720 const char * link_too_big = NULL;
4721
f7a99963 4722 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4723
f7a99963
NC
4724 printf ( " %6.6lx %6.6lx %2.2lx",
4725 (unsigned long) section->sh_offset,
4726 (unsigned long) section->sh_size,
4727 (unsigned long) section->sh_entsize);
d1133906 4728
5477e8a0
L
4729 if (do_section_details)
4730 fputs (" ", stdout);
4731 else
4732 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4733
cfcac11d
NC
4734 if (section->sh_link >= elf_header.e_shnum)
4735 {
4736 link_too_big = "";
4737 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4738 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4739 switch (elf_header.e_machine)
4740 {
caa83f8b
NC
4741 case EM_386:
4742 case EM_486:
4743 case EM_X86_64:
7f502d6c 4744 case EM_L1OM:
7a9068fe 4745 case EM_K1OM:
cfcac11d
NC
4746 case EM_OLD_SPARCV9:
4747 case EM_SPARC32PLUS:
4748 case EM_SPARCV9:
4749 case EM_SPARC:
4750 if (section->sh_link == (SHN_BEFORE & 0xffff))
4751 link_too_big = "BEFORE";
4752 else if (section->sh_link == (SHN_AFTER & 0xffff))
4753 link_too_big = "AFTER";
4754 break;
4755 default:
4756 break;
4757 }
4758 }
4759
4760 if (do_section_details)
4761 {
4762 if (link_too_big != NULL && * link_too_big)
4763 printf ("<%s> ", link_too_big);
4764 else
4765 printf ("%2u ", section->sh_link);
4766 printf ("%3u %2lu\n", section->sh_info,
4767 (unsigned long) section->sh_addralign);
4768 }
4769 else
4770 printf ("%2u %3u %2lu\n",
4771 section->sh_link,
4772 section->sh_info,
4773 (unsigned long) section->sh_addralign);
4774
4775 if (link_too_big && ! * link_too_big)
4776 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4777 i, section->sh_link);
f7a99963 4778 }
d974e256
JJ
4779 else if (do_wide)
4780 {
4781 print_vma (section->sh_addr, LONG_HEX);
4782
4783 if ((long) section->sh_offset == section->sh_offset)
4784 printf (" %6.6lx", (unsigned long) section->sh_offset);
4785 else
4786 {
4787 putchar (' ');
4788 print_vma (section->sh_offset, LONG_HEX);
4789 }
4790
4791 if ((unsigned long) section->sh_size == section->sh_size)
4792 printf (" %6.6lx", (unsigned long) section->sh_size);
4793 else
4794 {
4795 putchar (' ');
4796 print_vma (section->sh_size, LONG_HEX);
4797 }
4798
4799 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4800 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4801 else
4802 {
4803 putchar (' ');
4804 print_vma (section->sh_entsize, LONG_HEX);
4805 }
4806
5477e8a0
L
4807 if (do_section_details)
4808 fputs (" ", stdout);
4809 else
4810 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4811
72de5009 4812 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4813
4814 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4815 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4816 else
4817 {
4818 print_vma (section->sh_addralign, DEC);
4819 putchar ('\n');
4820 }
4821 }
5477e8a0 4822 else if (do_section_details)
595cf52e 4823 {
5477e8a0 4824 printf (" %-15.15s ",
595cf52e 4825 get_section_type_name (section->sh_type));
595cf52e
L
4826 print_vma (section->sh_addr, LONG_HEX);
4827 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4828 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4829 else
4830 {
4831 printf (" ");
4832 print_vma (section->sh_offset, LONG_HEX);
4833 }
72de5009 4834 printf (" %u\n ", section->sh_link);
595cf52e 4835 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4836 putchar (' ');
595cf52e
L
4837 print_vma (section->sh_entsize, LONG_HEX);
4838
72de5009
AM
4839 printf (" %-16u %lu\n",
4840 section->sh_info,
595cf52e
L
4841 (unsigned long) section->sh_addralign);
4842 }
f7a99963
NC
4843 else
4844 {
4845 putchar (' ');
4846 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4847 if ((long) section->sh_offset == section->sh_offset)
4848 printf (" %8.8lx", (unsigned long) section->sh_offset);
4849 else
4850 {
4851 printf (" ");
4852 print_vma (section->sh_offset, LONG_HEX);
4853 }
f7a99963
NC
4854 printf ("\n ");
4855 print_vma (section->sh_size, LONG_HEX);
4856 printf (" ");
4857 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4858
d1133906 4859 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4860
72de5009
AM
4861 printf (" %2u %3u %lu\n",
4862 section->sh_link,
4863 section->sh_info,
f7a99963
NC
4864 (unsigned long) section->sh_addralign);
4865 }
5477e8a0
L
4866
4867 if (do_section_details)
4868 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4869 }
4870
5477e8a0 4871 if (!do_section_details)
3dbcc61d
NC
4872 {
4873 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
4874 || elf_header.e_machine == EM_L1OM
4875 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
4876 printf (_("Key to Flags:\n\
4877 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
4878 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
4879 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
4880 else
4881 printf (_("Key to Flags:\n\
e3c8793a 4882 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 4883 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 4884 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 4885 }
d1133906 4886
252b5132
RH
4887 return 1;
4888}
4889
f5842774
L
4890static const char *
4891get_group_flags (unsigned int flags)
4892{
4893 static char buff[32];
4894 switch (flags)
4895 {
220453ec
AM
4896 case 0:
4897 return "";
4898
f5842774 4899 case GRP_COMDAT:
220453ec 4900 return "COMDAT ";
f5842774
L
4901
4902 default:
220453ec 4903 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
4904 break;
4905 }
4906 return buff;
4907}
4908
4909static int
2cf0635d 4910process_section_groups (FILE * file)
f5842774 4911{
2cf0635d 4912 Elf_Internal_Shdr * section;
f5842774 4913 unsigned int i;
2cf0635d
NC
4914 struct group * group;
4915 Elf_Internal_Shdr * symtab_sec;
4916 Elf_Internal_Shdr * strtab_sec;
4917 Elf_Internal_Sym * symtab;
4918 char * strtab;
c256ffe7 4919 size_t strtab_size;
d1f5c6e3
L
4920
4921 /* Don't process section groups unless needed. */
4922 if (!do_unwind && !do_section_groups)
4923 return 1;
f5842774
L
4924
4925 if (elf_header.e_shnum == 0)
4926 {
4927 if (do_section_groups)
82f2dbf7 4928 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
4929
4930 return 1;
4931 }
4932
4933 if (section_headers == NULL)
4934 {
4935 error (_("Section headers are not available!\n"));
4936 abort ();
4937 }
4938
3f5e193b
NC
4939 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
4940 sizeof (struct group *));
e4b17d5c
L
4941
4942 if (section_headers_groups == NULL)
4943 {
4944 error (_("Out of memory\n"));
4945 return 0;
4946 }
4947
f5842774 4948 /* Scan the sections for the group section. */
d1f5c6e3 4949 group_count = 0;
f5842774
L
4950 for (i = 0, section = section_headers;
4951 i < elf_header.e_shnum;
4952 i++, section++)
e4b17d5c
L
4953 if (section->sh_type == SHT_GROUP)
4954 group_count++;
4955
d1f5c6e3
L
4956 if (group_count == 0)
4957 {
4958 if (do_section_groups)
4959 printf (_("\nThere are no section groups in this file.\n"));
4960
4961 return 1;
4962 }
4963
3f5e193b 4964 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
4965
4966 if (section_groups == NULL)
4967 {
4968 error (_("Out of memory\n"));
4969 return 0;
4970 }
4971
d1f5c6e3
L
4972 symtab_sec = NULL;
4973 strtab_sec = NULL;
4974 symtab = NULL;
4975 strtab = NULL;
c256ffe7 4976 strtab_size = 0;
e4b17d5c
L
4977 for (i = 0, section = section_headers, group = section_groups;
4978 i < elf_header.e_shnum;
4979 i++, section++)
f5842774
L
4980 {
4981 if (section->sh_type == SHT_GROUP)
4982 {
2cf0635d
NC
4983 char * name = SECTION_NAME (section);
4984 char * group_name;
4985 unsigned char * start;
4986 unsigned char * indices;
f5842774 4987 unsigned int entry, j, size;
2cf0635d
NC
4988 Elf_Internal_Shdr * sec;
4989 Elf_Internal_Sym * sym;
f5842774
L
4990
4991 /* Get the symbol table. */
4fbb74a6
AM
4992 if (section->sh_link >= elf_header.e_shnum
4993 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 4994 != SHT_SYMTAB))
f5842774
L
4995 {
4996 error (_("Bad sh_link in group section `%s'\n"), name);
4997 continue;
4998 }
d1f5c6e3
L
4999
5000 if (symtab_sec != sec)
5001 {
5002 symtab_sec = sec;
5003 if (symtab)
5004 free (symtab);
5005 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
5006 }
f5842774 5007
dd24e3da
NC
5008 if (symtab == NULL)
5009 {
5010 error (_("Corrupt header in group section `%s'\n"), name);
5011 continue;
5012 }
5013
f5842774
L
5014 sym = symtab + section->sh_info;
5015
5016 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5017 {
4fbb74a6
AM
5018 if (sym->st_shndx == 0
5019 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5020 {
5021 error (_("Bad sh_info in group section `%s'\n"), name);
5022 continue;
5023 }
ba2685cc 5024
4fbb74a6 5025 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5026 strtab_sec = NULL;
5027 if (strtab)
5028 free (strtab);
f5842774 5029 strtab = NULL;
c256ffe7 5030 strtab_size = 0;
f5842774
L
5031 }
5032 else
5033 {
5034 /* Get the string table. */
4fbb74a6 5035 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5036 {
5037 strtab_sec = NULL;
5038 if (strtab)
5039 free (strtab);
5040 strtab = NULL;
5041 strtab_size = 0;
5042 }
5043 else if (strtab_sec
4fbb74a6 5044 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5045 {
5046 strtab_sec = sec;
5047 if (strtab)
5048 free (strtab);
3f5e193b
NC
5049 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5050 1, strtab_sec->sh_size,
5051 _("string table"));
c256ffe7 5052 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5053 }
c256ffe7 5054 group_name = sym->st_name < strtab_size
2b692964 5055 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5056 }
5057
3f5e193b
NC
5058 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5059 1, section->sh_size,
5060 _("section data"));
59245841
NC
5061 if (start == NULL)
5062 continue;
f5842774
L
5063
5064 indices = start;
5065 size = (section->sh_size / section->sh_entsize) - 1;
5066 entry = byte_get (indices, 4);
5067 indices += 4;
e4b17d5c
L
5068
5069 if (do_section_groups)
5070 {
2b692964 5071 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5072 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5073
e4b17d5c
L
5074 printf (_(" [Index] Name\n"));
5075 }
5076
5077 group->group_index = i;
5078
f5842774
L
5079 for (j = 0; j < size; j++)
5080 {
2cf0635d 5081 struct group_list * g;
e4b17d5c 5082
f5842774
L
5083 entry = byte_get (indices, 4);
5084 indices += 4;
5085
4fbb74a6 5086 if (entry >= elf_header.e_shnum)
391cb864
L
5087 {
5088 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5089 entry, i, elf_header.e_shnum - 1);
5090 continue;
5091 }
391cb864 5092
4fbb74a6 5093 if (section_headers_groups [entry] != NULL)
e4b17d5c 5094 {
d1f5c6e3
L
5095 if (entry)
5096 {
391cb864
L
5097 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5098 entry, i,
4fbb74a6 5099 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5100 continue;
5101 }
5102 else
5103 {
5104 /* Intel C/C++ compiler may put section 0 in a
5105 section group. We just warn it the first time
5106 and ignore it afterwards. */
5107 static int warned = 0;
5108 if (!warned)
5109 {
5110 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5111 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5112 warned++;
5113 }
5114 }
e4b17d5c
L
5115 }
5116
4fbb74a6 5117 section_headers_groups [entry] = group;
e4b17d5c
L
5118
5119 if (do_section_groups)
5120 {
4fbb74a6 5121 sec = section_headers + entry;
c256ffe7 5122 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5123 }
5124
3f5e193b 5125 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5126 g->section_index = entry;
5127 g->next = group->root;
5128 group->root = g;
f5842774
L
5129 }
5130
f5842774
L
5131 if (start)
5132 free (start);
e4b17d5c
L
5133
5134 group++;
f5842774
L
5135 }
5136 }
5137
d1f5c6e3
L
5138 if (symtab)
5139 free (symtab);
5140 if (strtab)
5141 free (strtab);
f5842774
L
5142 return 1;
5143}
5144
28f997cf
TG
5145/* Data used to display dynamic fixups. */
5146
5147struct ia64_vms_dynfixup
5148{
5149 bfd_vma needed_ident; /* Library ident number. */
5150 bfd_vma needed; /* Index in the dstrtab of the library name. */
5151 bfd_vma fixup_needed; /* Index of the library. */
5152 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5153 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5154};
5155
5156/* Data used to display dynamic relocations. */
5157
5158struct ia64_vms_dynimgrela
5159{
5160 bfd_vma img_rela_cnt; /* Number of relocations. */
5161 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5162};
5163
5164/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5165 library). */
5166
5167static void
5168dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5169 const char *strtab, unsigned int strtab_sz)
5170{
5171 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5172 long i;
5173 const char *lib_name;
5174
5175 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5176 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5177 _("dynamic section image fixups"));
5178 if (!imfs)
5179 return;
5180
5181 if (fixup->needed < strtab_sz)
5182 lib_name = strtab + fixup->needed;
5183 else
5184 {
5185 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5186 (unsigned long) fixup->needed);
28f997cf
TG
5187 lib_name = "???";
5188 }
5189 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5190 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5191 printf
5192 (_("Seg Offset Type SymVec DataType\n"));
5193
5194 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5195 {
5196 unsigned int type;
5197 const char *rtype;
5198
5199 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5200 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5201 type = BYTE_GET (imfs [i].type);
5202 rtype = elf_ia64_reloc_type (type);
5203 if (rtype == NULL)
5204 printf (" 0x%08x ", type);
5205 else
5206 printf (" %-32s ", rtype);
5207 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5208 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5209 }
5210
5211 free (imfs);
5212}
5213
5214/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5215
5216static void
5217dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5218{
5219 Elf64_External_VMS_IMAGE_RELA *imrs;
5220 long i;
5221
5222 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5223 1, imgrela->img_rela_cnt * sizeof (*imrs),
5224 _("dynamic section image relas"));
5225 if (!imrs)
5226 return;
5227
5228 printf (_("\nImage relocs\n"));
5229 printf
5230 (_("Seg Offset Type Addend Seg Sym Off\n"));
5231
5232 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5233 {
5234 unsigned int type;
5235 const char *rtype;
5236
5237 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5238 printf ("%08" BFD_VMA_FMT "x ",
5239 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5240 type = BYTE_GET (imrs [i].type);
5241 rtype = elf_ia64_reloc_type (type);
5242 if (rtype == NULL)
5243 printf ("0x%08x ", type);
5244 else
5245 printf ("%-31s ", rtype);
5246 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5247 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5248 printf ("%08" BFD_VMA_FMT "x\n",
5249 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5250 }
5251
5252 free (imrs);
5253}
5254
5255/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5256
5257static int
5258process_ia64_vms_dynamic_relocs (FILE *file)
5259{
5260 struct ia64_vms_dynfixup fixup;
5261 struct ia64_vms_dynimgrela imgrela;
5262 Elf_Internal_Dyn *entry;
5263 int res = 0;
5264 bfd_vma strtab_off = 0;
5265 bfd_vma strtab_sz = 0;
5266 char *strtab = NULL;
5267
5268 memset (&fixup, 0, sizeof (fixup));
5269 memset (&imgrela, 0, sizeof (imgrela));
5270
5271 /* Note: the order of the entries is specified by the OpenVMS specs. */
5272 for (entry = dynamic_section;
5273 entry < dynamic_section + dynamic_nent;
5274 entry++)
5275 {
5276 switch (entry->d_tag)
5277 {
5278 case DT_IA_64_VMS_STRTAB_OFFSET:
5279 strtab_off = entry->d_un.d_val;
5280 break;
5281 case DT_STRSZ:
5282 strtab_sz = entry->d_un.d_val;
5283 if (strtab == NULL)
5284 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5285 1, strtab_sz, _("dynamic string section"));
5286 break;
5287
5288 case DT_IA_64_VMS_NEEDED_IDENT:
5289 fixup.needed_ident = entry->d_un.d_val;
5290 break;
5291 case DT_NEEDED:
5292 fixup.needed = entry->d_un.d_val;
5293 break;
5294 case DT_IA_64_VMS_FIXUP_NEEDED:
5295 fixup.fixup_needed = entry->d_un.d_val;
5296 break;
5297 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5298 fixup.fixup_rela_cnt = entry->d_un.d_val;
5299 break;
5300 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5301 fixup.fixup_rela_off = entry->d_un.d_val;
5302 res++;
5303 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5304 break;
5305
5306 case DT_IA_64_VMS_IMG_RELA_CNT:
5307 imgrela.img_rela_cnt = entry->d_un.d_val;
5308 break;
5309 case DT_IA_64_VMS_IMG_RELA_OFF:
5310 imgrela.img_rela_off = entry->d_un.d_val;
5311 res++;
5312 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5313 break;
5314
5315 default:
5316 break;
5317 }
5318 }
5319
5320 if (strtab != NULL)
5321 free (strtab);
5322
5323 return res;
5324}
5325
85b1c36d 5326static struct
566b0d53 5327{
2cf0635d 5328 const char * name;
566b0d53
L
5329 int reloc;
5330 int size;
5331 int rela;
5332} dynamic_relocations [] =
5333{
5334 { "REL", DT_REL, DT_RELSZ, FALSE },
5335 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5336 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5337};
5338
252b5132 5339/* Process the reloc section. */
18bd398b 5340
252b5132 5341static int
2cf0635d 5342process_relocs (FILE * file)
252b5132 5343{
b34976b6
AM
5344 unsigned long rel_size;
5345 unsigned long rel_offset;
252b5132
RH
5346
5347
5348 if (!do_reloc)
5349 return 1;
5350
5351 if (do_using_dynamic)
5352 {
566b0d53 5353 int is_rela;
2cf0635d 5354 const char * name;
566b0d53
L
5355 int has_dynamic_reloc;
5356 unsigned int i;
0de14b54 5357
566b0d53 5358 has_dynamic_reloc = 0;
252b5132 5359
566b0d53 5360 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5361 {
566b0d53
L
5362 is_rela = dynamic_relocations [i].rela;
5363 name = dynamic_relocations [i].name;
5364 rel_size = dynamic_info [dynamic_relocations [i].size];
5365 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5366
566b0d53
L
5367 has_dynamic_reloc |= rel_size;
5368
5369 if (is_rela == UNKNOWN)
aa903cfb 5370 {
566b0d53
L
5371 if (dynamic_relocations [i].reloc == DT_JMPREL)
5372 switch (dynamic_info[DT_PLTREL])
5373 {
5374 case DT_REL:
5375 is_rela = FALSE;
5376 break;
5377 case DT_RELA:
5378 is_rela = TRUE;
5379 break;
5380 }
aa903cfb 5381 }
252b5132 5382
566b0d53
L
5383 if (rel_size)
5384 {
5385 printf
5386 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5387 name, rel_offset, rel_size);
252b5132 5388
d93f0186
NC
5389 dump_relocations (file,
5390 offset_from_vma (file, rel_offset, rel_size),
5391 rel_size,
566b0d53 5392 dynamic_symbols, num_dynamic_syms,
d79b3d50 5393 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5394 }
252b5132 5395 }
566b0d53 5396
28f997cf
TG
5397 if (is_ia64_vms ())
5398 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5399
566b0d53 5400 if (! has_dynamic_reloc)
252b5132
RH
5401 printf (_("\nThere are no dynamic relocations in this file.\n"));
5402 }
5403 else
5404 {
2cf0635d 5405 Elf_Internal_Shdr * section;
b34976b6
AM
5406 unsigned long i;
5407 int found = 0;
252b5132
RH
5408
5409 for (i = 0, section = section_headers;
5410 i < elf_header.e_shnum;
b34976b6 5411 i++, section++)
252b5132
RH
5412 {
5413 if ( section->sh_type != SHT_RELA
5414 && section->sh_type != SHT_REL)
5415 continue;
5416
5417 rel_offset = section->sh_offset;
5418 rel_size = section->sh_size;
5419
5420 if (rel_size)
5421 {
2cf0635d 5422 Elf_Internal_Shdr * strsec;
b34976b6 5423 int is_rela;
103f02d3 5424
252b5132
RH
5425 printf (_("\nRelocation section "));
5426
5427 if (string_table == NULL)
19936277 5428 printf ("%d", section->sh_name);
252b5132 5429 else
3a1a2036 5430 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
5431
5432 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5433 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5434
d79b3d50
NC
5435 is_rela = section->sh_type == SHT_RELA;
5436
4fbb74a6
AM
5437 if (section->sh_link != 0
5438 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5439 {
2cf0635d
NC
5440 Elf_Internal_Shdr * symsec;
5441 Elf_Internal_Sym * symtab;
d79b3d50 5442 unsigned long nsyms;
c256ffe7 5443 unsigned long strtablen = 0;
2cf0635d 5444 char * strtab = NULL;
57346661 5445
4fbb74a6 5446 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5447 if (symsec->sh_type != SHT_SYMTAB
5448 && symsec->sh_type != SHT_DYNSYM)
5449 continue;
5450
af3fc3bc 5451 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 5452 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 5453
af3fc3bc
AM
5454 if (symtab == NULL)
5455 continue;
252b5132 5456
4fbb74a6
AM
5457 if (symsec->sh_link != 0
5458 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5459 {
4fbb74a6 5460 strsec = section_headers + symsec->sh_link;
103f02d3 5461
3f5e193b
NC
5462 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5463 1, strsec->sh_size,
5464 _("string table"));
c256ffe7
JJ
5465 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5466 }
252b5132 5467
d79b3d50
NC
5468 dump_relocations (file, rel_offset, rel_size,
5469 symtab, nsyms, strtab, strtablen, is_rela);
5470 if (strtab)
5471 free (strtab);
5472 free (symtab);
5473 }
5474 else
5475 dump_relocations (file, rel_offset, rel_size,
5476 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5477
5478 found = 1;
5479 }
5480 }
5481
5482 if (! found)
5483 printf (_("\nThere are no relocations in this file.\n"));
5484 }
5485
5486 return 1;
5487}
5488
57346661
AM
5489/* Process the unwind section. */
5490
4d6ed7c8
NC
5491#include "unwind-ia64.h"
5492
5493/* An absolute address consists of a section and an offset. If the
5494 section is NULL, the offset itself is the address, otherwise, the
5495 address equals to LOAD_ADDRESS(section) + offset. */
5496
5497struct absaddr
5498 {
5499 unsigned short section;
5500 bfd_vma offset;
5501 };
5502
1949de15
L
5503#define ABSADDR(a) \
5504 ((a).section \
5505 ? section_headers [(a).section].sh_addr + (a).offset \
5506 : (a).offset)
5507
3f5e193b
NC
5508struct ia64_unw_table_entry
5509 {
5510 struct absaddr start;
5511 struct absaddr end;
5512 struct absaddr info;
5513 };
5514
57346661 5515struct ia64_unw_aux_info
4d6ed7c8 5516 {
3f5e193b
NC
5517
5518 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5519 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5520 unsigned char * info; /* Unwind info. */
b34976b6
AM
5521 unsigned long info_size; /* Size of unwind info. */
5522 bfd_vma info_addr; /* starting address of unwind info. */
5523 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5524 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5525 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5526 char * strtab; /* The string table. */
b34976b6 5527 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5528 };
5529
4d6ed7c8 5530static void
2cf0635d 5531find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5532 unsigned long nsyms,
2cf0635d 5533 const char * strtab,
57346661 5534 unsigned long strtab_size,
d3ba0551 5535 struct absaddr addr,
2cf0635d
NC
5536 const char ** symname,
5537 bfd_vma * offset)
4d6ed7c8 5538{
d3ba0551 5539 bfd_vma dist = 0x100000;
2cf0635d
NC
5540 Elf_Internal_Sym * sym;
5541 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5542 unsigned long i;
5543
0b6ae522
DJ
5544 REMOVE_ARCH_BITS (addr.offset);
5545
57346661 5546 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5547 {
0b6ae522
DJ
5548 bfd_vma value = sym->st_value;
5549
5550 REMOVE_ARCH_BITS (value);
5551
4d6ed7c8
NC
5552 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5553 && sym->st_name != 0
5554 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5555 && addr.offset >= value
5556 && addr.offset - value < dist)
4d6ed7c8
NC
5557 {
5558 best = sym;
0b6ae522 5559 dist = addr.offset - value;
4d6ed7c8
NC
5560 if (!dist)
5561 break;
5562 }
5563 }
5564 if (best)
5565 {
57346661 5566 *symname = (best->st_name >= strtab_size
2b692964 5567 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5568 *offset = dist;
5569 return;
5570 }
5571 *symname = NULL;
5572 *offset = addr.offset;
5573}
5574
5575static void
2cf0635d 5576dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5577{
2cf0635d 5578 struct ia64_unw_table_entry * tp;
4d6ed7c8 5579 int in_body;
7036c0e1 5580
4d6ed7c8
NC
5581 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5582 {
5583 bfd_vma stamp;
5584 bfd_vma offset;
2cf0635d
NC
5585 const unsigned char * dp;
5586 const unsigned char * head;
5587 const char * procname;
4d6ed7c8 5588
57346661
AM
5589 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5590 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5591
5592 fputs ("\n<", stdout);
5593
5594 if (procname)
5595 {
5596 fputs (procname, stdout);
5597
5598 if (offset)
5599 printf ("+%lx", (unsigned long) offset);
5600 }
5601
5602 fputs (">: [", stdout);
5603 print_vma (tp->start.offset, PREFIX_HEX);
5604 fputc ('-', stdout);
5605 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5606 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5607 (unsigned long) (tp->info.offset - aux->seg_base));
5608
1949de15 5609 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5610 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5611
86f55779 5612 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5613 (unsigned) UNW_VER (stamp),
5614 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5615 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5616 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5617 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5618
5619 if (UNW_VER (stamp) != 1)
5620 {
2b692964 5621 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5622 continue;
5623 }
5624
5625 in_body = 0;
89fac5e3 5626 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5627 dp = unw_decode (dp, in_body, & in_body);
5628 }
5629}
5630
5631static int
2cf0635d
NC
5632slurp_ia64_unwind_table (FILE * file,
5633 struct ia64_unw_aux_info * aux,
5634 Elf_Internal_Shdr * sec)
4d6ed7c8 5635{
89fac5e3 5636 unsigned long size, nrelas, i;
2cf0635d
NC
5637 Elf_Internal_Phdr * seg;
5638 struct ia64_unw_table_entry * tep;
5639 Elf_Internal_Shdr * relsec;
5640 Elf_Internal_Rela * rela;
5641 Elf_Internal_Rela * rp;
5642 unsigned char * table;
5643 unsigned char * tp;
5644 Elf_Internal_Sym * sym;
5645 const char * relname;
4d6ed7c8 5646
4d6ed7c8
NC
5647 /* First, find the starting address of the segment that includes
5648 this section: */
5649
5650 if (elf_header.e_phnum)
5651 {
d93f0186 5652 if (! get_program_headers (file))
4d6ed7c8 5653 return 0;
4d6ed7c8 5654
d93f0186
NC
5655 for (seg = program_headers;
5656 seg < program_headers + elf_header.e_phnum;
5657 ++seg)
4d6ed7c8
NC
5658 {
5659 if (seg->p_type != PT_LOAD)
5660 continue;
5661
5662 if (sec->sh_addr >= seg->p_vaddr
5663 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5664 {
5665 aux->seg_base = seg->p_vaddr;
5666 break;
5667 }
5668 }
4d6ed7c8
NC
5669 }
5670
5671 /* Second, build the unwind table from the contents of the unwind section: */
5672 size = sec->sh_size;
3f5e193b
NC
5673 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5674 _("unwind table"));
a6e9f9df
AM
5675 if (!table)
5676 return 0;
4d6ed7c8 5677
3f5e193b
NC
5678 aux->table = (struct ia64_unw_table_entry *)
5679 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5680 tep = aux->table;
c6a0c689 5681 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5682 {
5683 tep->start.section = SHN_UNDEF;
5684 tep->end.section = SHN_UNDEF;
5685 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5686 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5687 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5688 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5689 tep->start.offset += aux->seg_base;
5690 tep->end.offset += aux->seg_base;
5691 tep->info.offset += aux->seg_base;
5692 }
5693 free (table);
5694
41e92641 5695 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5696 for (relsec = section_headers;
5697 relsec < section_headers + elf_header.e_shnum;
5698 ++relsec)
5699 {
5700 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5701 || relsec->sh_info >= elf_header.e_shnum
5702 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5703 continue;
5704
5705 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5706 & rela, & nrelas))
5707 return 0;
5708
5709 for (rp = rela; rp < rela + nrelas; ++rp)
5710 {
aca88567
NC
5711 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5712 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5713
0112cd26 5714 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5715 {
e5fb9629 5716 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5717 continue;
5718 }
5719
89fac5e3 5720 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5721
89fac5e3 5722 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5723 {
5724 case 0:
5725 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5726 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5727 break;
5728 case 1:
5729 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5730 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5731 break;
5732 case 2:
5733 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5734 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5735 break;
5736 default:
5737 break;
5738 }
5739 }
5740
5741 free (rela);
5742 }
5743
89fac5e3 5744 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5745 return 1;
5746}
5747
5748static int
2cf0635d 5749ia64_process_unwind (FILE * file)
4d6ed7c8 5750{
2cf0635d
NC
5751 Elf_Internal_Shdr * sec;
5752 Elf_Internal_Shdr * unwsec = NULL;
5753 Elf_Internal_Shdr * strsec;
89fac5e3 5754 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5755 struct ia64_unw_aux_info aux;
f1467e33 5756
4d6ed7c8
NC
5757 memset (& aux, 0, sizeof (aux));
5758
4d6ed7c8
NC
5759 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5760 {
c256ffe7 5761 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5762 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5763 {
5764 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5765 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5766
4fbb74a6 5767 strsec = section_headers + sec->sh_link;
59245841 5768 assert (aux.strtab == NULL);
3f5e193b
NC
5769 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5770 1, strsec->sh_size,
5771 _("string table"));
c256ffe7 5772 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5773 }
5774 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5775 unwcount++;
5776 }
5777
5778 if (!unwcount)
5779 printf (_("\nThere are no unwind sections in this file.\n"));
5780
5781 while (unwcount-- > 0)
5782 {
2cf0635d 5783 char * suffix;
579f31ac
JJ
5784 size_t len, len2;
5785
5786 for (i = unwstart, sec = section_headers + unwstart;
5787 i < elf_header.e_shnum; ++i, ++sec)
5788 if (sec->sh_type == SHT_IA_64_UNWIND)
5789 {
5790 unwsec = sec;
5791 break;
5792 }
5793
5794 unwstart = i + 1;
5795 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5796
e4b17d5c
L
5797 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5798 {
5799 /* We need to find which section group it is in. */
2cf0635d 5800 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5801
5802 for (; g != NULL; g = g->next)
5803 {
4fbb74a6 5804 sec = section_headers + g->section_index;
18bd398b
NC
5805
5806 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5807 break;
e4b17d5c
L
5808 }
5809
5810 if (g == NULL)
5811 i = elf_header.e_shnum;
5812 }
18bd398b 5813 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5814 {
18bd398b 5815 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5816 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5817 suffix = SECTION_NAME (unwsec) + len;
5818 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5819 ++i, ++sec)
18bd398b
NC
5820 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5821 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5822 break;
5823 }
5824 else
5825 {
5826 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5827 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5828 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5829 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5830 suffix = "";
18bd398b 5831 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5832 suffix = SECTION_NAME (unwsec) + len;
5833 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5834 ++i, ++sec)
18bd398b
NC
5835 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5836 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5837 break;
5838 }
5839
5840 if (i == elf_header.e_shnum)
5841 {
5842 printf (_("\nCould not find unwind info section for "));
5843
5844 if (string_table == NULL)
5845 printf ("%d", unwsec->sh_name);
5846 else
3a1a2036 5847 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5848 }
5849 else
4d6ed7c8 5850 {
4d6ed7c8 5851 aux.info_addr = sec->sh_addr;
3f5e193b 5852 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 5853 sec->sh_size,
3f5e193b 5854 _("unwind info"));
59245841 5855 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 5856
579f31ac 5857 printf (_("\nUnwind section "));
4d6ed7c8 5858
579f31ac
JJ
5859 if (string_table == NULL)
5860 printf ("%d", unwsec->sh_name);
5861 else
3a1a2036 5862 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5863
579f31ac 5864 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5865 (unsigned long) unwsec->sh_offset,
89fac5e3 5866 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5867
579f31ac 5868 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5869
579f31ac
JJ
5870 if (aux.table_len > 0)
5871 dump_ia64_unwind (& aux);
5872
5873 if (aux.table)
5874 free ((char *) aux.table);
5875 if (aux.info)
5876 free ((char *) aux.info);
5877 aux.table = NULL;
5878 aux.info = NULL;
5879 }
4d6ed7c8 5880 }
4d6ed7c8 5881
4d6ed7c8
NC
5882 if (aux.symtab)
5883 free (aux.symtab);
5884 if (aux.strtab)
5885 free ((char *) aux.strtab);
5886
5887 return 1;
5888}
5889
3f5e193b
NC
5890struct hppa_unw_table_entry
5891 {
5892 struct absaddr start;
5893 struct absaddr end;
5894 unsigned int Cannot_unwind:1; /* 0 */
5895 unsigned int Millicode:1; /* 1 */
5896 unsigned int Millicode_save_sr0:1; /* 2 */
5897 unsigned int Region_description:2; /* 3..4 */
5898 unsigned int reserved1:1; /* 5 */
5899 unsigned int Entry_SR:1; /* 6 */
5900 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5901 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5902 unsigned int Args_stored:1; /* 16 */
5903 unsigned int Variable_Frame:1; /* 17 */
5904 unsigned int Separate_Package_Body:1; /* 18 */
5905 unsigned int Frame_Extension_Millicode:1; /* 19 */
5906 unsigned int Stack_Overflow_Check:1; /* 20 */
5907 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5908 unsigned int Ada_Region:1; /* 22 */
5909 unsigned int cxx_info:1; /* 23 */
5910 unsigned int cxx_try_catch:1; /* 24 */
5911 unsigned int sched_entry_seq:1; /* 25 */
5912 unsigned int reserved2:1; /* 26 */
5913 unsigned int Save_SP:1; /* 27 */
5914 unsigned int Save_RP:1; /* 28 */
5915 unsigned int Save_MRP_in_frame:1; /* 29 */
5916 unsigned int extn_ptr_defined:1; /* 30 */
5917 unsigned int Cleanup_defined:1; /* 31 */
5918
5919 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5920 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5921 unsigned int Large_frame:1; /* 2 */
5922 unsigned int Pseudo_SP_Set:1; /* 3 */
5923 unsigned int reserved4:1; /* 4 */
5924 unsigned int Total_frame_size:27; /* 5..31 */
5925 };
5926
57346661
AM
5927struct hppa_unw_aux_info
5928 {
3f5e193b 5929 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
5930 unsigned long table_len; /* Length of unwind table. */
5931 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5932 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5933 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5934 char * strtab; /* The string table. */
57346661
AM
5935 unsigned long strtab_size; /* Size of string table. */
5936 };
5937
5938static void
2cf0635d 5939dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5940{
2cf0635d 5941 struct hppa_unw_table_entry * tp;
57346661 5942
57346661
AM
5943 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5944 {
5945 bfd_vma offset;
2cf0635d 5946 const char * procname;
57346661
AM
5947
5948 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5949 aux->strtab_size, tp->start, &procname,
5950 &offset);
5951
5952 fputs ("\n<", stdout);
5953
5954 if (procname)
5955 {
5956 fputs (procname, stdout);
5957
5958 if (offset)
5959 printf ("+%lx", (unsigned long) offset);
5960 }
5961
5962 fputs (">: [", stdout);
5963 print_vma (tp->start.offset, PREFIX_HEX);
5964 fputc ('-', stdout);
5965 print_vma (tp->end.offset, PREFIX_HEX);
5966 printf ("]\n\t");
5967
18bd398b
NC
5968#define PF(_m) if (tp->_m) printf (#_m " ");
5969#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5970 PF(Cannot_unwind);
5971 PF(Millicode);
5972 PF(Millicode_save_sr0);
18bd398b 5973 /* PV(Region_description); */
57346661
AM
5974 PF(Entry_SR);
5975 PV(Entry_FR);
5976 PV(Entry_GR);
5977 PF(Args_stored);
5978 PF(Variable_Frame);
5979 PF(Separate_Package_Body);
5980 PF(Frame_Extension_Millicode);
5981 PF(Stack_Overflow_Check);
5982 PF(Two_Instruction_SP_Increment);
5983 PF(Ada_Region);
5984 PF(cxx_info);
5985 PF(cxx_try_catch);
5986 PF(sched_entry_seq);
5987 PF(Save_SP);
5988 PF(Save_RP);
5989 PF(Save_MRP_in_frame);
5990 PF(extn_ptr_defined);
5991 PF(Cleanup_defined);
5992 PF(MPE_XL_interrupt_marker);
5993 PF(HP_UX_interrupt_marker);
5994 PF(Large_frame);
5995 PF(Pseudo_SP_Set);
5996 PV(Total_frame_size);
5997#undef PF
5998#undef PV
5999 }
6000
18bd398b 6001 printf ("\n");
57346661
AM
6002}
6003
6004static int
2cf0635d
NC
6005slurp_hppa_unwind_table (FILE * file,
6006 struct hppa_unw_aux_info * aux,
6007 Elf_Internal_Shdr * sec)
57346661 6008{
1c0751b2 6009 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6010 Elf_Internal_Phdr * seg;
6011 struct hppa_unw_table_entry * tep;
6012 Elf_Internal_Shdr * relsec;
6013 Elf_Internal_Rela * rela;
6014 Elf_Internal_Rela * rp;
6015 unsigned char * table;
6016 unsigned char * tp;
6017 Elf_Internal_Sym * sym;
6018 const char * relname;
57346661 6019
57346661
AM
6020 /* First, find the starting address of the segment that includes
6021 this section. */
6022
6023 if (elf_header.e_phnum)
6024 {
6025 if (! get_program_headers (file))
6026 return 0;
6027
6028 for (seg = program_headers;
6029 seg < program_headers + elf_header.e_phnum;
6030 ++seg)
6031 {
6032 if (seg->p_type != PT_LOAD)
6033 continue;
6034
6035 if (sec->sh_addr >= seg->p_vaddr
6036 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6037 {
6038 aux->seg_base = seg->p_vaddr;
6039 break;
6040 }
6041 }
6042 }
6043
6044 /* Second, build the unwind table from the contents of the unwind
6045 section. */
6046 size = sec->sh_size;
3f5e193b
NC
6047 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6048 _("unwind table"));
57346661
AM
6049 if (!table)
6050 return 0;
6051
1c0751b2
DA
6052 unw_ent_size = 16;
6053 nentries = size / unw_ent_size;
6054 size = unw_ent_size * nentries;
57346661 6055
3f5e193b
NC
6056 tep = aux->table = (struct hppa_unw_table_entry *)
6057 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6058
1c0751b2 6059 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6060 {
6061 unsigned int tmp1, tmp2;
6062
6063 tep->start.section = SHN_UNDEF;
6064 tep->end.section = SHN_UNDEF;
6065
1c0751b2
DA
6066 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6067 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6068 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6069 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6070
6071 tep->start.offset += aux->seg_base;
6072 tep->end.offset += aux->seg_base;
57346661
AM
6073
6074 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6075 tep->Millicode = (tmp1 >> 30) & 0x1;
6076 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6077 tep->Region_description = (tmp1 >> 27) & 0x3;
6078 tep->reserved1 = (tmp1 >> 26) & 0x1;
6079 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6080 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6081 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6082 tep->Args_stored = (tmp1 >> 15) & 0x1;
6083 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6084 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6085 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6086 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6087 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6088 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6089 tep->cxx_info = (tmp1 >> 8) & 0x1;
6090 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6091 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6092 tep->reserved2 = (tmp1 >> 5) & 0x1;
6093 tep->Save_SP = (tmp1 >> 4) & 0x1;
6094 tep->Save_RP = (tmp1 >> 3) & 0x1;
6095 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6096 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6097 tep->Cleanup_defined = tmp1 & 0x1;
6098
6099 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6100 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6101 tep->Large_frame = (tmp2 >> 29) & 0x1;
6102 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6103 tep->reserved4 = (tmp2 >> 27) & 0x1;
6104 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6105 }
6106 free (table);
6107
6108 /* Third, apply any relocations to the unwind table. */
57346661
AM
6109 for (relsec = section_headers;
6110 relsec < section_headers + elf_header.e_shnum;
6111 ++relsec)
6112 {
6113 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6114 || relsec->sh_info >= elf_header.e_shnum
6115 || section_headers + relsec->sh_info != sec)
57346661
AM
6116 continue;
6117
6118 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6119 & rela, & nrelas))
6120 return 0;
6121
6122 for (rp = rela; rp < rela + nrelas; ++rp)
6123 {
aca88567
NC
6124 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6125 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6126
6127 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6128 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6129 {
6130 warn (_("Skipping unexpected relocation type %s\n"), relname);
6131 continue;
6132 }
6133
6134 i = rp->r_offset / unw_ent_size;
6135
89fac5e3 6136 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6137 {
6138 case 0:
6139 aux->table[i].start.section = sym->st_shndx;
1e456d54 6140 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6141 break;
6142 case 1:
6143 aux->table[i].end.section = sym->st_shndx;
1e456d54 6144 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6145 break;
6146 default:
6147 break;
6148 }
6149 }
6150
6151 free (rela);
6152 }
6153
1c0751b2 6154 aux->table_len = nentries;
57346661
AM
6155
6156 return 1;
6157}
6158
6159static int
2cf0635d 6160hppa_process_unwind (FILE * file)
57346661 6161{
57346661 6162 struct hppa_unw_aux_info aux;
2cf0635d
NC
6163 Elf_Internal_Shdr * unwsec = NULL;
6164 Elf_Internal_Shdr * strsec;
6165 Elf_Internal_Shdr * sec;
18bd398b 6166 unsigned long i;
57346661
AM
6167
6168 memset (& aux, 0, sizeof (aux));
6169
c256ffe7
JJ
6170 if (string_table == NULL)
6171 return 1;
57346661
AM
6172
6173 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6174 {
c256ffe7 6175 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6176 && sec->sh_link < elf_header.e_shnum)
57346661
AM
6177 {
6178 aux.nsyms = sec->sh_size / sec->sh_entsize;
6179 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6180
4fbb74a6 6181 strsec = section_headers + sec->sh_link;
59245841 6182 assert (aux.strtab == NULL);
3f5e193b
NC
6183 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6184 1, strsec->sh_size,
6185 _("string table"));
c256ffe7 6186 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6187 }
18bd398b 6188 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6189 unwsec = sec;
6190 }
6191
6192 if (!unwsec)
6193 printf (_("\nThere are no unwind sections in this file.\n"));
6194
6195 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6196 {
18bd398b 6197 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6198 {
57346661
AM
6199 printf (_("\nUnwind section "));
6200 printf (_("'%s'"), SECTION_NAME (sec));
6201
6202 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6203 (unsigned long) sec->sh_offset,
89fac5e3 6204 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6205
6206 slurp_hppa_unwind_table (file, &aux, sec);
6207 if (aux.table_len > 0)
6208 dump_hppa_unwind (&aux);
6209
6210 if (aux.table)
6211 free ((char *) aux.table);
6212 aux.table = NULL;
6213 }
6214 }
6215
6216 if (aux.symtab)
6217 free (aux.symtab);
6218 if (aux.strtab)
6219 free ((char *) aux.strtab);
6220
6221 return 1;
6222}
6223
0b6ae522
DJ
6224struct arm_section
6225{
6226 unsigned char *data;
6227
6228 Elf_Internal_Shdr *sec;
6229 Elf_Internal_Rela *rela;
6230 unsigned long nrelas;
6231 unsigned int rel_type;
6232
6233 Elf_Internal_Rela *next_rela;
6234};
6235
6236struct arm_unw_aux_info
6237{
6238 FILE *file;
6239
6240 Elf_Internal_Sym *symtab; /* The symbol table. */
6241 unsigned long nsyms; /* Number of symbols. */
6242 char *strtab; /* The string table. */
6243 unsigned long strtab_size; /* Size of string table. */
6244};
6245
6246static const char *
6247arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6248 bfd_vma fn, struct absaddr addr)
6249{
6250 const char *procname;
6251 bfd_vma sym_offset;
6252
6253 if (addr.section == SHN_UNDEF)
6254 addr.offset = fn;
6255
6256 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6257 aux->strtab_size, addr, &procname,
6258 &sym_offset);
6259
6260 print_vma (fn, PREFIX_HEX);
6261
6262 if (procname)
6263 {
6264 fputs (" <", stdout);
6265 fputs (procname, stdout);
6266
6267 if (sym_offset)
6268 printf ("+0x%lx", (unsigned long) sym_offset);
6269 fputc ('>', stdout);
6270 }
6271
6272 return procname;
6273}
6274
6275static void
6276arm_free_section (struct arm_section *arm_sec)
6277{
6278 if (arm_sec->data != NULL)
6279 free (arm_sec->data);
6280
6281 if (arm_sec->rela != NULL)
6282 free (arm_sec->rela);
6283}
6284
6285static int
6286arm_section_get_word (struct arm_unw_aux_info *aux,
6287 struct arm_section *arm_sec,
6288 Elf_Internal_Shdr *sec, bfd_vma word_offset,
6289 unsigned int *wordp, struct absaddr *addr)
6290{
6291 Elf_Internal_Rela *rp;
6292 Elf_Internal_Sym *sym;
6293 const char * relname;
6294 unsigned int word;
6295 bfd_boolean wrapped;
6296
6297 addr->section = SHN_UNDEF;
6298 addr->offset = 0;
6299
6300 if (sec != arm_sec->sec)
6301 {
6302 Elf_Internal_Shdr *relsec;
6303
6304 arm_free_section (arm_sec);
6305
6306 arm_sec->sec = sec;
6307 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6308 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6309 arm_sec->rela = NULL;
6310 arm_sec->nrelas = 0;
6311
6312 for (relsec = section_headers;
6313 relsec < section_headers + elf_header.e_shnum;
6314 ++relsec)
6315 {
6316 if (relsec->sh_info >= elf_header.e_shnum
6317 || section_headers + relsec->sh_info != sec)
6318 continue;
6319
6320 if (relsec->sh_type == SHT_REL)
6321 {
6322 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6323 relsec->sh_size,
6324 & arm_sec->rela, & arm_sec->nrelas))
6325 return 0;
6326 break;
6327 }
6328 else if (relsec->sh_type == SHT_RELA)
6329 {
6330 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6331 relsec->sh_size,
6332 & arm_sec->rela, & arm_sec->nrelas))
6333 return 0;
6334 break;
6335 }
6336 }
6337
6338 arm_sec->next_rela = arm_sec->rela;
6339 }
6340
6341 if (arm_sec->data == NULL)
6342 return 0;
6343
6344 word = byte_get (arm_sec->data + word_offset, 4);
6345
6346 wrapped = FALSE;
6347 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6348 {
6349 bfd_vma prelval, offset;
6350
6351 if (rp->r_offset > word_offset && !wrapped)
6352 {
6353 rp = arm_sec->rela;
6354 wrapped = TRUE;
6355 }
6356 if (rp->r_offset > word_offset)
6357 break;
6358
6359 if (rp->r_offset & 3)
6360 {
6361 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6362 (unsigned long) rp->r_offset);
6363 continue;
6364 }
6365
6366 if (rp->r_offset < word_offset)
6367 continue;
6368
fa197c1c
PB
6369 switch (elf_header.e_machine)
6370 {
6371 case EM_ARM:
6372 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6373 break;
6374
6375 case EM_TI_C6000:
6376 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6377 break;
6378
6379 default:
6380 abort();
6381 }
0b6ae522 6382
fa197c1c
PB
6383 if (streq (relname, "R_ARM_NONE")
6384 || streq (relname, "R_C6000_NONE"))
0b6ae522
DJ
6385 continue;
6386
fa197c1c
PB
6387 if (!(streq (relname, "R_ARM_PREL31")
6388 || streq (relname, "R_C6000_PREL31")))
0b6ae522
DJ
6389 {
6390 warn (_("Skipping unexpected relocation type %s\n"), relname);
6391 continue;
6392 }
6393
6394 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6395
6396 if (arm_sec->rel_type == SHT_REL)
6397 {
6398 offset = word & 0x7fffffff;
6399 if (offset & 0x40000000)
6400 offset |= ~ (bfd_vma) 0x7fffffff;
6401 }
6402 else
6403 offset = rp->r_addend;
6404
6405 offset += sym->st_value;
6406 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6407
fa197c1c
PB
6408 if (streq (relname, "R_C6000_PREL31"))
6409 prelval >>= 1;
6410
0b6ae522
DJ
6411 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6412 addr->section = sym->st_shndx;
6413 addr->offset = offset;
6414 break;
6415 }
6416
6417 *wordp = word;
6418 arm_sec->next_rela = rp;
6419
6420 return 1;
6421}
6422
fa197c1c
PB
6423static const char *tic6x_unwind_regnames[16] = {
6424 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6425 "A14", "A13", "A12", "A11", "A10",
6426 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"};
6427
0b6ae522 6428static void
fa197c1c 6429decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6430{
fa197c1c
PB
6431 int i;
6432
6433 for (i = 12; mask; mask >>= 1, i--)
6434 {
6435 if (mask & 1)
6436 {
6437 fputs (tic6x_unwind_regnames[i], stdout);
6438 if (mask > 1)
6439 fputs (", ", stdout);
6440 }
6441 }
6442}
0b6ae522
DJ
6443
6444#define ADVANCE \
6445 if (remaining == 0 && more_words) \
6446 { \
6447 data_offset += 4; \
6448 if (!arm_section_get_word (aux, data_arm_sec, data_sec, \
6449 data_offset, &word, &addr)) \
6450 return; \
6451 remaining = 4; \
6452 more_words--; \
6453 } \
6454
6455#define GET_OP(OP) \
6456 ADVANCE; \
6457 if (remaining) \
6458 { \
6459 remaining--; \
6460 (OP) = word >> 24; \
6461 word <<= 8; \
6462 } \
6463 else \
6464 { \
2b692964 6465 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6466 return; \
6467 } \
cc5914eb 6468 printf ("0x%02x ", OP)
0b6ae522 6469
fa197c1c
PB
6470static void
6471decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6472 unsigned int word, unsigned int remaining,
6473 unsigned int more_words,
6474 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6475 struct arm_section *data_arm_sec)
6476{
6477 struct absaddr addr;
0b6ae522
DJ
6478
6479 /* Decode the unwinding instructions. */
6480 while (1)
6481 {
6482 unsigned int op, op2;
6483
6484 ADVANCE;
6485 if (remaining == 0)
6486 break;
6487 remaining--;
6488 op = word >> 24;
6489 word <<= 8;
6490
cc5914eb 6491 printf (" 0x%02x ", op);
0b6ae522
DJ
6492
6493 if ((op & 0xc0) == 0x00)
6494 {
6495 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6496
cc5914eb 6497 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6498 }
6499 else if ((op & 0xc0) == 0x40)
6500 {
6501 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6502
cc5914eb 6503 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6504 }
6505 else if ((op & 0xf0) == 0x80)
6506 {
6507 GET_OP (op2);
6508 if (op == 0x80 && op2 == 0)
6509 printf (_("Refuse to unwind"));
6510 else
6511 {
6512 unsigned int mask = ((op & 0x0f) << 8) | op2;
6513 int first = 1;
6514 int i;
2b692964 6515
0b6ae522
DJ
6516 printf ("pop {");
6517 for (i = 0; i < 12; i++)
6518 if (mask & (1 << i))
6519 {
6520 if (first)
6521 first = 0;
6522 else
6523 printf (", ");
6524 printf ("r%d", 4 + i);
6525 }
6526 printf ("}");
6527 }
6528 }
6529 else if ((op & 0xf0) == 0x90)
6530 {
6531 if (op == 0x9d || op == 0x9f)
6532 printf (_(" [Reserved]"));
6533 else
cc5914eb 6534 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6535 }
6536 else if ((op & 0xf0) == 0xa0)
6537 {
6538 int end = 4 + (op & 0x07);
6539 int first = 1;
6540 int i;
61865e30 6541
0b6ae522
DJ
6542 printf (" pop {");
6543 for (i = 4; i <= end; i++)
6544 {
6545 if (first)
6546 first = 0;
6547 else
6548 printf (", ");
6549 printf ("r%d", i);
6550 }
6551 if (op & 0x08)
6552 {
6553 if (first)
6554 printf (", ");
6555 printf ("r14");
6556 }
6557 printf ("}");
6558 }
6559 else if (op == 0xb0)
6560 printf (_(" finish"));
6561 else if (op == 0xb1)
6562 {
6563 GET_OP (op2);
6564 if (op2 == 0 || (op2 & 0xf0) != 0)
6565 printf (_("[Spare]"));
6566 else
6567 {
6568 unsigned int mask = op2 & 0x0f;
6569 int first = 1;
6570 int i;
61865e30 6571
0b6ae522
DJ
6572 printf ("pop {");
6573 for (i = 0; i < 12; i++)
6574 if (mask & (1 << i))
6575 {
6576 if (first)
6577 first = 0;
6578 else
6579 printf (", ");
6580 printf ("r%d", i);
6581 }
6582 printf ("}");
6583 }
6584 }
6585 else if (op == 0xb2)
6586 {
b115cf96 6587 unsigned char buf[9];
0b6ae522
DJ
6588 unsigned int i, len;
6589 unsigned long offset;
61865e30 6590
b115cf96 6591 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6592 {
6593 GET_OP (buf[i]);
6594 if ((buf[i] & 0x80) == 0)
6595 break;
6596 }
6597 assert (i < sizeof (buf));
6598 offset = read_uleb128 (buf, &len);
6599 assert (len == i + 1);
6600 offset = offset * 4 + 0x204;
cc5914eb 6601 printf ("vsp = vsp + %ld", offset);
0b6ae522 6602 }
61865e30 6603 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6604 {
61865e30
NC
6605 unsigned int first, last;
6606
6607 GET_OP (op2);
6608 first = op2 >> 4;
6609 last = op2 & 0x0f;
6610 if (op == 0xc8)
6611 first = first + 16;
6612 printf ("pop {D%d", first);
6613 if (last)
6614 printf ("-D%d", first + last);
6615 printf ("}");
6616 }
6617 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6618 {
6619 unsigned int count = op & 0x07;
6620
6621 printf ("pop {D8");
6622 if (count)
6623 printf ("-D%d", 8 + count);
6624 printf ("}");
6625 }
6626 else if (op >= 0xc0 && op <= 0xc5)
6627 {
6628 unsigned int count = op & 0x07;
6629
6630 printf (" pop {wR10");
6631 if (count)
6632 printf ("-wR%d", 10 + count);
6633 printf ("}");
6634 }
6635 else if (op == 0xc6)
6636 {
6637 unsigned int first, last;
6638
6639 GET_OP (op2);
6640 first = op2 >> 4;
6641 last = op2 & 0x0f;
6642 printf ("pop {wR%d", first);
6643 if (last)
6644 printf ("-wR%d", first + last);
6645 printf ("}");
6646 }
6647 else if (op == 0xc7)
6648 {
6649 GET_OP (op2);
6650 if (op2 == 0 || (op2 & 0xf0) != 0)
6651 printf (_("[Spare]"));
0b6ae522
DJ
6652 else
6653 {
61865e30
NC
6654 unsigned int mask = op2 & 0x0f;
6655 int first = 1;
6656 int i;
6657
6658 printf ("pop {");
6659 for (i = 0; i < 4; i++)
6660 if (mask & (1 << i))
6661 {
6662 if (first)
6663 first = 0;
6664 else
6665 printf (", ");
6666 printf ("wCGR%d", i);
6667 }
6668 printf ("}");
0b6ae522
DJ
6669 }
6670 }
61865e30
NC
6671 else
6672 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6673 printf ("\n");
6674 }
fa197c1c
PB
6675}
6676
6677static void
6678decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6679 unsigned int word, unsigned int remaining,
6680 unsigned int more_words,
6681 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6682 struct arm_section *data_arm_sec)
6683{
6684 struct absaddr addr;
6685
6686 /* Decode the unwinding instructions. */
6687 while (1)
6688 {
6689 unsigned int op, op2;
6690
6691 ADVANCE;
6692 if (remaining == 0)
6693 break;
6694 remaining--;
6695 op = word >> 24;
6696 word <<= 8;
6697
6698 printf (_(" 0x%02x "), op);
6699
6700 if ((op & 0xc0) == 0x00)
6701 {
6702 int offset = ((op & 0x3f) << 3) + 8;
6703 printf (_(" sp = sp + %d"), offset);
6704 }
6705 else if ((op & 0xc0) == 0x80)
6706 {
6707 GET_OP (op2);
6708 if (op == 0x80 && op2 == 0)
6709 printf (_("Refuse to unwind"));
6710 else
6711 {
6712 unsigned int mask = ((op & 0x1f) << 8) | op2;
6713 if (op & 0x20)
6714 printf ("pop compact {");
6715 else
6716 printf ("pop {");
6717
6718 decode_tic6x_unwind_regmask (mask);
6719 printf("}");
6720 }
6721 }
6722 else if ((op & 0xf0) == 0xc0)
6723 {
6724 unsigned int reg;
6725 unsigned int nregs;
6726 unsigned int i;
6727 const char *name;
6728 struct {
6729 unsigned int offset;
6730 unsigned int reg;
6731 } regpos[16];
6732
6733 /* Scan entire instruction first so that GET_OP output is not
6734 interleaved with disassembly. */
6735 nregs = 0;
6736 for (i = 0; nregs < (op & 0xf); i++)
6737 {
6738 GET_OP (op2);
6739 reg = op2 >> 4;
6740 if (reg != 0xf)
6741 {
6742 regpos[nregs].offset = i * 2;
6743 regpos[nregs].reg = reg;
6744 nregs++;
6745 }
6746
6747 reg = op2 & 0xf;
6748 if (reg != 0xf)
6749 {
6750 regpos[nregs].offset = i * 2 + 1;
6751 regpos[nregs].reg = reg;
6752 nregs++;
6753 }
6754 }
6755
6756 printf (_("pop frame {"));
6757 reg = nregs - 1;
6758 for (i = i * 2; i > 0; i--)
6759 {
6760 if (regpos[reg].offset == i - 1)
6761 {
6762 name = tic6x_unwind_regnames[regpos[reg].reg];
6763 if (reg > 0)
6764 reg--;
6765 }
6766 else
6767 name = _("[pad]");
6768
6769 fputs (name, stdout);
6770 if (i > 1)
6771 printf (", ");
6772 }
6773
6774 printf ("}");
6775 }
6776 else if (op == 0xd0)
6777 printf (" MOV FP, SP");
6778 else if (op == 0xd1)
6779 printf (" __c6xabi_pop_rts");
6780 else if (op == 0xd2)
6781 {
6782 unsigned char buf[9];
6783 unsigned int i, len;
6784 unsigned long offset;
6785 for (i = 0; i < sizeof (buf); i++)
6786 {
6787 GET_OP (buf[i]);
6788 if ((buf[i] & 0x80) == 0)
6789 break;
6790 }
6791 assert (i < sizeof (buf));
6792 offset = read_uleb128 (buf, &len);
6793 assert (len == i + 1);
6794 offset = offset * 8 + 0x408;
6795 printf (_("sp = sp + %ld"), offset);
6796 }
6797 else if ((op & 0xf0) == 0xe0)
6798 {
6799 if ((op & 0x0f) == 7)
6800 printf (" RETURN");
6801 else
6802 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
6803 }
6804 else
6805 {
6806 printf (_(" [unsupported opcode]"));
6807 }
6808 putchar ('\n');
6809 }
6810}
6811
6812static bfd_vma
6813expand_prel31 (bfd_vma word, bfd_vma where)
6814{
6815 bfd_vma offset;
6816
6817 offset = word & 0x7fffffff;
6818 if (offset & 0x40000000)
6819 offset |= ~ (bfd_vma) 0x7fffffff;
6820
6821 if (elf_header.e_machine == EM_TI_C6000)
6822 offset <<= 1;
6823
6824 return offset + where;
6825}
6826
6827static void
6828decode_arm_unwind (struct arm_unw_aux_info *aux,
6829 unsigned int word, unsigned int remaining,
6830 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6831 struct arm_section *data_arm_sec)
6832{
6833 int per_index;
6834 unsigned int more_words = 0;
6835 struct absaddr addr;
6836
6837 if (remaining == 0)
6838 {
6839 /* Fetch the first word. */
6840 if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
6841 &word, &addr))
6842 return;
6843 remaining = 4;
6844 }
6845
6846 if ((word & 0x80000000) == 0)
6847 {
6848 /* Expand prel31 for personality routine. */
6849 bfd_vma fn;
6850 const char *procname;
6851
6852 fn = expand_prel31 (word, data_sec->sh_addr + data_offset);
6853 printf (_(" Personality routine: "));
6854 procname = arm_print_vma_and_name (aux, fn, addr);
6855 fputc ('\n', stdout);
6856
6857 /* The GCC personality routines use the standard compact
6858 encoding, starting with one byte giving the number of
6859 words. */
6860 if (procname != NULL
6861 && (const_strneq (procname, "__gcc_personality_v0")
6862 || const_strneq (procname, "__gxx_personality_v0")
6863 || const_strneq (procname, "__gcj_personality_v0")
6864 || const_strneq (procname, "__gnu_objc_personality_v0")))
6865 {
6866 remaining = 0;
6867 more_words = 1;
6868 ADVANCE;
6869 if (!remaining)
6870 {
6871 printf (_(" [Truncated data]\n"));
6872 return;
6873 }
6874 more_words = word >> 24;
6875 word <<= 8;
6876 remaining--;
6877 per_index = -1;
6878 }
6879 else
6880 return;
6881 }
6882 else
6883 {
6884
6885 per_index = (word >> 24) & 0x7f;
6886 printf (_(" Compact model %d\n"), per_index);
6887 if (per_index == 0)
6888 {
6889 more_words = 0;
6890 word <<= 8;
6891 remaining--;
6892 }
6893 else if (per_index < 3)
6894 {
6895 more_words = (word >> 16) & 0xff;
6896 word <<= 16;
6897 remaining -= 2;
6898 }
6899 }
6900
6901 switch (elf_header.e_machine)
6902 {
6903 case EM_ARM:
6904 if (per_index < 3)
6905 {
6906 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
6907 data_offset, data_sec, data_arm_sec);
6908 }
6909 else
6910 printf (" [reserved]\n");
6911 break;
6912
6913 case EM_TI_C6000:
6914 if (per_index < 3)
6915 {
6916 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
6917 data_offset, data_sec, data_arm_sec);
6918 }
6919 else if (per_index < 5)
6920 {
6921 if (((word >> 17) & 0x7f) == 0x7f)
6922 printf (_(" Restore stack from frame pointer\n"));
6923 else
6924 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
6925 printf (_(" Registers restored: "));
6926 if (per_index == 4)
6927 printf (" (compact) ");
6928 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
6929 putchar ('\n');
6930 printf (_(" Return register: %s\n"),
6931 tic6x_unwind_regnames[word & 0xf]);
6932 }
6933 else
6934 printf (" [reserved]\n");
6935 break;
6936
6937 default:
6938 abort ();
6939 }
0b6ae522
DJ
6940
6941 /* Decode the descriptors. Not implemented. */
6942}
6943
6944static void
6945dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
6946{
6947 struct arm_section exidx_arm_sec, extab_arm_sec;
6948 unsigned int i, exidx_len;
6949
6950 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
6951 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
6952 exidx_len = exidx_sec->sh_size / 8;
6953
6954 for (i = 0; i < exidx_len; i++)
6955 {
6956 unsigned int exidx_fn, exidx_entry;
6957 struct absaddr fn_addr, entry_addr;
6958 bfd_vma fn;
6959
6960 fputc ('\n', stdout);
6961
6962 if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6963 8 * i, &exidx_fn, &fn_addr)
6964 || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6965 8 * i + 4, &exidx_entry, &entry_addr))
6966 {
6967 arm_free_section (&exidx_arm_sec);
6968 arm_free_section (&extab_arm_sec);
6969 return;
6970 }
6971
fa197c1c 6972 fn = expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522
DJ
6973
6974 arm_print_vma_and_name (aux, fn, entry_addr);
6975 fputs (": ", stdout);
6976
6977 if (exidx_entry == 1)
6978 {
6979 print_vma (exidx_entry, PREFIX_HEX);
6980 fputs (" [cantunwind]\n", stdout);
6981 }
6982 else if (exidx_entry & 0x80000000)
6983 {
6984 print_vma (exidx_entry, PREFIX_HEX);
6985 fputc ('\n', stdout);
6986 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
6987 }
6988 else
6989 {
8f73510c 6990 bfd_vma table, table_offset = 0;
0b6ae522
DJ
6991 Elf_Internal_Shdr *table_sec;
6992
6993 fputs ("@", stdout);
fa197c1c 6994 table = expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
6995 print_vma (table, PREFIX_HEX);
6996 printf ("\n");
6997
6998 /* Locate the matching .ARM.extab. */
6999 if (entry_addr.section != SHN_UNDEF
7000 && entry_addr.section < elf_header.e_shnum)
7001 {
7002 table_sec = section_headers + entry_addr.section;
7003 table_offset = entry_addr.offset;
7004 }
7005 else
7006 {
7007 table_sec = find_section_by_address (table);
7008 if (table_sec != NULL)
7009 table_offset = table - table_sec->sh_addr;
7010 }
7011 if (table_sec == NULL)
7012 {
7013 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7014 (unsigned long) table);
7015 continue;
7016 }
7017 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7018 &extab_arm_sec);
7019 }
7020 }
7021
7022 printf ("\n");
7023
7024 arm_free_section (&exidx_arm_sec);
7025 arm_free_section (&extab_arm_sec);
7026}
7027
fa197c1c 7028/* Used for both ARM and C6X unwinding tables. */
0b6ae522
DJ
7029static int
7030arm_process_unwind (FILE *file)
7031{
7032 struct arm_unw_aux_info aux;
7033 Elf_Internal_Shdr *unwsec = NULL;
7034 Elf_Internal_Shdr *strsec;
7035 Elf_Internal_Shdr *sec;
7036 unsigned long i;
fa197c1c 7037 unsigned int sec_type;
0b6ae522
DJ
7038
7039 memset (& aux, 0, sizeof (aux));
7040 aux.file = file;
7041
fa197c1c
PB
7042 switch (elf_header.e_machine)
7043 {
7044 case EM_ARM:
7045 sec_type = SHT_ARM_EXIDX;
7046 break;
7047
7048 case EM_TI_C6000:
7049 sec_type = SHT_C6000_UNWIND;
7050 break;
7051
7052 default:
7053 abort();
7054 }
7055
0b6ae522
DJ
7056 if (string_table == NULL)
7057 return 1;
7058
7059 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7060 {
7061 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7062 {
7063 aux.nsyms = sec->sh_size / sec->sh_entsize;
7064 aux.symtab = GET_ELF_SYMBOLS (file, sec);
7065
7066 strsec = section_headers + sec->sh_link;
59245841 7067 assert (aux.strtab == NULL);
0b6ae522
DJ
7068 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7069 1, strsec->sh_size, _("string table"));
7070 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7071 }
fa197c1c 7072 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7073 unwsec = sec;
7074 }
7075
7076 if (!unwsec)
7077 printf (_("\nThere are no unwind sections in this file.\n"));
7078
7079 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7080 {
fa197c1c 7081 if (sec->sh_type == sec_type)
0b6ae522
DJ
7082 {
7083 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7084 SECTION_NAME (sec),
7085 (unsigned long) sec->sh_offset,
7086 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
7087
7088 dump_arm_unwind (&aux, sec);
7089 }
7090 }
7091
7092 if (aux.symtab)
7093 free (aux.symtab);
7094 if (aux.strtab)
7095 free ((char *) aux.strtab);
7096
7097 return 1;
7098}
7099
57346661 7100static int
2cf0635d 7101process_unwind (FILE * file)
57346661 7102{
2cf0635d
NC
7103 struct unwind_handler
7104 {
57346661 7105 int machtype;
2cf0635d
NC
7106 int (* handler)(FILE *);
7107 } handlers[] =
7108 {
0b6ae522 7109 { EM_ARM, arm_process_unwind },
57346661
AM
7110 { EM_IA_64, ia64_process_unwind },
7111 { EM_PARISC, hppa_process_unwind },
fa197c1c 7112 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7113 { 0, 0 }
7114 };
7115 int i;
7116
7117 if (!do_unwind)
7118 return 1;
7119
7120 for (i = 0; handlers[i].handler != NULL; i++)
7121 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7122 return handlers[i].handler (file);
57346661
AM
7123
7124 printf (_("\nThere are no unwind sections in this file.\n"));
7125 return 1;
7126}
7127
252b5132 7128static void
2cf0635d 7129dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7130{
7131 switch (entry->d_tag)
7132 {
7133 case DT_MIPS_FLAGS:
7134 if (entry->d_un.d_val == 0)
2b692964 7135 printf (_("NONE\n"));
252b5132
RH
7136 else
7137 {
7138 static const char * opts[] =
7139 {
7140 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7141 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7142 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7143 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7144 "RLD_ORDER_SAFE"
7145 };
7146 unsigned int cnt;
7147 int first = 1;
2b692964 7148
60bca95a 7149 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7150 if (entry->d_un.d_val & (1 << cnt))
7151 {
7152 printf ("%s%s", first ? "" : " ", opts[cnt]);
7153 first = 0;
7154 }
7155 puts ("");
7156 }
7157 break;
103f02d3 7158
252b5132 7159 case DT_MIPS_IVERSION:
d79b3d50 7160 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
2b692964 7161 printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7162 else
2b692964 7163 printf (_("<corrupt: %ld>\n"), (long) entry->d_un.d_ptr);
252b5132 7164 break;
103f02d3 7165
252b5132
RH
7166 case DT_MIPS_TIME_STAMP:
7167 {
7168 char timebuf[20];
2cf0635d 7169 struct tm * tmp;
50da7a9c 7170
91d6fa6a
NC
7171 time_t atime = entry->d_un.d_val;
7172 tmp = gmtime (&atime);
e9e44622
JJ
7173 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7174 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7175 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
2b692964 7176 printf (_("Time Stamp: %s\n"), timebuf);
252b5132
RH
7177 }
7178 break;
103f02d3 7179
252b5132
RH
7180 case DT_MIPS_RLD_VERSION:
7181 case DT_MIPS_LOCAL_GOTNO:
7182 case DT_MIPS_CONFLICTNO:
7183 case DT_MIPS_LIBLISTNO:
7184 case DT_MIPS_SYMTABNO:
7185 case DT_MIPS_UNREFEXTNO:
7186 case DT_MIPS_HIPAGENO:
7187 case DT_MIPS_DELTA_CLASS_NO:
7188 case DT_MIPS_DELTA_INSTANCE_NO:
7189 case DT_MIPS_DELTA_RELOC_NO:
7190 case DT_MIPS_DELTA_SYM_NO:
7191 case DT_MIPS_DELTA_CLASSSYM_NO:
7192 case DT_MIPS_COMPACT_SIZE:
7193 printf ("%ld\n", (long) entry->d_un.d_ptr);
7194 break;
103f02d3
UD
7195
7196 default:
0af1713e 7197 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
7198 }
7199}
7200
103f02d3 7201static void
2cf0635d 7202dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7203{
7204 switch (entry->d_tag)
7205 {
7206 case DT_HP_DLD_FLAGS:
7207 {
7208 static struct
7209 {
7210 long int bit;
2cf0635d 7211 const char * str;
5e220199
NC
7212 }
7213 flags[] =
7214 {
7215 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7216 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7217 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7218 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7219 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7220 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7221 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7222 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7223 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7224 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7225 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7226 { DT_HP_GST, "HP_GST" },
7227 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7228 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7229 { DT_HP_NODELETE, "HP_NODELETE" },
7230 { DT_HP_GROUP, "HP_GROUP" },
7231 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7232 };
103f02d3 7233 int first = 1;
5e220199 7234 size_t cnt;
f7a99963 7235 bfd_vma val = entry->d_un.d_val;
103f02d3 7236
60bca95a 7237 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7238 if (val & flags[cnt].bit)
30800947
NC
7239 {
7240 if (! first)
7241 putchar (' ');
7242 fputs (flags[cnt].str, stdout);
7243 first = 0;
7244 val ^= flags[cnt].bit;
7245 }
76da6bbe 7246
103f02d3 7247 if (val != 0 || first)
f7a99963
NC
7248 {
7249 if (! first)
7250 putchar (' ');
7251 print_vma (val, HEX);
7252 }
103f02d3
UD
7253 }
7254 break;
76da6bbe 7255
252b5132 7256 default:
f7a99963
NC
7257 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7258 break;
252b5132 7259 }
35b1837e 7260 putchar ('\n');
252b5132
RH
7261}
7262
28f997cf
TG
7263#ifdef BFD64
7264
7265/* VMS vs Unix time offset and factor. */
7266
7267#define VMS_EPOCH_OFFSET 35067168000000000LL
7268#define VMS_GRANULARITY_FACTOR 10000000
7269
7270/* Display a VMS time in a human readable format. */
7271
7272static void
7273print_vms_time (bfd_int64_t vmstime)
7274{
7275 struct tm *tm;
7276 time_t unxtime;
7277
7278 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7279 tm = gmtime (&unxtime);
7280 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7281 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7282 tm->tm_hour, tm->tm_min, tm->tm_sec);
7283}
7284#endif /* BFD64 */
7285
ecc51f48 7286static void
2cf0635d 7287dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7288{
7289 switch (entry->d_tag)
7290 {
0de14b54 7291 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7292 /* First 3 slots reserved. */
ecc51f48
NC
7293 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7294 printf (" -- ");
7295 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7296 break;
7297
28f997cf
TG
7298 case DT_IA_64_VMS_LINKTIME:
7299#ifdef BFD64
7300 print_vms_time (entry->d_un.d_val);
7301#endif
7302 break;
7303
7304 case DT_IA_64_VMS_LNKFLAGS:
7305 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7306 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7307 printf (" CALL_DEBUG");
7308 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7309 printf (" NOP0BUFS");
7310 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7311 printf (" P0IMAGE");
7312 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7313 printf (" MKTHREADS");
7314 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7315 printf (" UPCALLS");
7316 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7317 printf (" IMGSTA");
7318 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7319 printf (" INITIALIZE");
7320 if (entry->d_un.d_val & VMS_LF_MAIN)
7321 printf (" MAIN");
7322 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7323 printf (" EXE_INIT");
7324 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7325 printf (" TBK_IN_IMG");
7326 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7327 printf (" DBG_IN_IMG");
7328 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7329 printf (" TBK_IN_DSF");
7330 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7331 printf (" DBG_IN_DSF");
7332 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7333 printf (" SIGNATURES");
7334 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7335 printf (" REL_SEG_OFF");
7336 break;
7337
bdf4d63a
JJ
7338 default:
7339 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7340 break;
ecc51f48 7341 }
bdf4d63a 7342 putchar ('\n');
ecc51f48
NC
7343}
7344
252b5132 7345static int
2cf0635d 7346get_32bit_dynamic_section (FILE * file)
252b5132 7347{
2cf0635d
NC
7348 Elf32_External_Dyn * edyn;
7349 Elf32_External_Dyn * ext;
7350 Elf_Internal_Dyn * entry;
103f02d3 7351
3f5e193b
NC
7352 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7353 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7354 if (!edyn)
7355 return 0;
103f02d3 7356
ba2685cc
AM
7357/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7358 might not have the luxury of section headers. Look for the DT_NULL
7359 terminator to determine the number of entries. */
7360 for (ext = edyn, dynamic_nent = 0;
7361 (char *) ext < (char *) edyn + dynamic_size;
7362 ext++)
7363 {
7364 dynamic_nent++;
7365 if (BYTE_GET (ext->d_tag) == DT_NULL)
7366 break;
7367 }
252b5132 7368
3f5e193b
NC
7369 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7370 sizeof (* entry));
b2d38a17 7371 if (dynamic_section == NULL)
252b5132 7372 {
9ea033b2
NC
7373 error (_("Out of memory\n"));
7374 free (edyn);
7375 return 0;
7376 }
252b5132 7377
fb514b26 7378 for (ext = edyn, entry = dynamic_section;
ba2685cc 7379 entry < dynamic_section + dynamic_nent;
fb514b26 7380 ext++, entry++)
9ea033b2 7381 {
fb514b26
AM
7382 entry->d_tag = BYTE_GET (ext->d_tag);
7383 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7384 }
7385
9ea033b2
NC
7386 free (edyn);
7387
7388 return 1;
7389}
7390
7391static int
2cf0635d 7392get_64bit_dynamic_section (FILE * file)
9ea033b2 7393{
2cf0635d
NC
7394 Elf64_External_Dyn * edyn;
7395 Elf64_External_Dyn * ext;
7396 Elf_Internal_Dyn * entry;
103f02d3 7397
3f5e193b
NC
7398 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7399 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7400 if (!edyn)
7401 return 0;
103f02d3 7402
ba2685cc
AM
7403/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7404 might not have the luxury of section headers. Look for the DT_NULL
7405 terminator to determine the number of entries. */
7406 for (ext = edyn, dynamic_nent = 0;
7407 (char *) ext < (char *) edyn + dynamic_size;
7408 ext++)
7409 {
7410 dynamic_nent++;
66543521 7411 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7412 break;
7413 }
252b5132 7414
3f5e193b
NC
7415 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7416 sizeof (* entry));
b2d38a17 7417 if (dynamic_section == NULL)
252b5132
RH
7418 {
7419 error (_("Out of memory\n"));
7420 free (edyn);
7421 return 0;
7422 }
7423
fb514b26 7424 for (ext = edyn, entry = dynamic_section;
ba2685cc 7425 entry < dynamic_section + dynamic_nent;
fb514b26 7426 ext++, entry++)
252b5132 7427 {
66543521
AM
7428 entry->d_tag = BYTE_GET (ext->d_tag);
7429 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7430 }
7431
7432 free (edyn);
7433
9ea033b2
NC
7434 return 1;
7435}
7436
e9e44622
JJ
7437static void
7438print_dynamic_flags (bfd_vma flags)
d1133906 7439{
e9e44622 7440 int first = 1;
13ae64f3 7441
d1133906
NC
7442 while (flags)
7443 {
7444 bfd_vma flag;
7445
7446 flag = flags & - flags;
7447 flags &= ~ flag;
7448
e9e44622
JJ
7449 if (first)
7450 first = 0;
7451 else
7452 putc (' ', stdout);
13ae64f3 7453
d1133906
NC
7454 switch (flag)
7455 {
e9e44622
JJ
7456 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7457 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7458 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7459 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7460 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7461 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7462 }
7463 }
e9e44622 7464 puts ("");
d1133906
NC
7465}
7466
b2d38a17
NC
7467/* Parse and display the contents of the dynamic section. */
7468
9ea033b2 7469static int
2cf0635d 7470process_dynamic_section (FILE * file)
9ea033b2 7471{
2cf0635d 7472 Elf_Internal_Dyn * entry;
9ea033b2
NC
7473
7474 if (dynamic_size == 0)
7475 {
7476 if (do_dynamic)
b2d38a17 7477 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7478
7479 return 1;
7480 }
7481
7482 if (is_32bit_elf)
7483 {
b2d38a17 7484 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7485 return 0;
7486 }
b2d38a17 7487 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7488 return 0;
7489
252b5132
RH
7490 /* Find the appropriate symbol table. */
7491 if (dynamic_symbols == NULL)
7492 {
86dba8ee
AM
7493 for (entry = dynamic_section;
7494 entry < dynamic_section + dynamic_nent;
7495 ++entry)
252b5132 7496 {
c8286bd1 7497 Elf_Internal_Shdr section;
252b5132
RH
7498
7499 if (entry->d_tag != DT_SYMTAB)
7500 continue;
7501
7502 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7503
7504 /* Since we do not know how big the symbol table is,
7505 we default to reading in the entire file (!) and
7506 processing that. This is overkill, I know, but it
e3c8793a 7507 should work. */
d93f0186 7508 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7509
fb52b2f4
NC
7510 if (archive_file_offset != 0)
7511 section.sh_size = archive_file_size - section.sh_offset;
7512 else
7513 {
7514 if (fseek (file, 0, SEEK_END))
591a748a 7515 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7516
7517 section.sh_size = ftell (file) - section.sh_offset;
7518 }
252b5132 7519
9ea033b2 7520 if (is_32bit_elf)
9ad5cbcf 7521 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7522 else
9ad5cbcf 7523 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7524
9ad5cbcf 7525 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 7526 if (num_dynamic_syms < 1)
252b5132
RH
7527 {
7528 error (_("Unable to determine the number of symbols to load\n"));
7529 continue;
7530 }
7531
9ad5cbcf 7532 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
7533 }
7534 }
7535
7536 /* Similarly find a string table. */
7537 if (dynamic_strings == NULL)
7538 {
86dba8ee
AM
7539 for (entry = dynamic_section;
7540 entry < dynamic_section + dynamic_nent;
7541 ++entry)
252b5132
RH
7542 {
7543 unsigned long offset;
b34976b6 7544 long str_tab_len;
252b5132
RH
7545
7546 if (entry->d_tag != DT_STRTAB)
7547 continue;
7548
7549 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7550
7551 /* Since we do not know how big the string table is,
7552 we default to reading in the entire file (!) and
7553 processing that. This is overkill, I know, but it
e3c8793a 7554 should work. */
252b5132 7555
d93f0186 7556 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7557
7558 if (archive_file_offset != 0)
7559 str_tab_len = archive_file_size - offset;
7560 else
7561 {
7562 if (fseek (file, 0, SEEK_END))
7563 error (_("Unable to seek to end of file\n"));
7564 str_tab_len = ftell (file) - offset;
7565 }
252b5132
RH
7566
7567 if (str_tab_len < 1)
7568 {
7569 error
7570 (_("Unable to determine the length of the dynamic string table\n"));
7571 continue;
7572 }
7573
3f5e193b
NC
7574 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7575 str_tab_len,
7576 _("dynamic string table"));
59245841 7577 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7578 break;
7579 }
7580 }
7581
7582 /* And find the syminfo section if available. */
7583 if (dynamic_syminfo == NULL)
7584 {
3e8bba36 7585 unsigned long syminsz = 0;
252b5132 7586
86dba8ee
AM
7587 for (entry = dynamic_section;
7588 entry < dynamic_section + dynamic_nent;
7589 ++entry)
252b5132
RH
7590 {
7591 if (entry->d_tag == DT_SYMINENT)
7592 {
7593 /* Note: these braces are necessary to avoid a syntax
7594 error from the SunOS4 C compiler. */
7595 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7596 }
7597 else if (entry->d_tag == DT_SYMINSZ)
7598 syminsz = entry->d_un.d_val;
7599 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7600 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7601 syminsz);
252b5132
RH
7602 }
7603
7604 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7605 {
2cf0635d
NC
7606 Elf_External_Syminfo * extsyminfo;
7607 Elf_External_Syminfo * extsym;
7608 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7609
7610 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7611 extsyminfo = (Elf_External_Syminfo *)
7612 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7613 _("symbol information"));
a6e9f9df
AM
7614 if (!extsyminfo)
7615 return 0;
252b5132 7616
3f5e193b 7617 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7618 if (dynamic_syminfo == NULL)
7619 {
7620 error (_("Out of memory\n"));
7621 return 0;
7622 }
7623
7624 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7625 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7626 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7627 ++syminfo, ++extsym)
252b5132 7628 {
86dba8ee
AM
7629 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7630 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7631 }
7632
7633 free (extsyminfo);
7634 }
7635 }
7636
7637 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7638 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7639 dynamic_addr, dynamic_nent);
252b5132
RH
7640 if (do_dynamic)
7641 printf (_(" Tag Type Name/Value\n"));
7642
86dba8ee
AM
7643 for (entry = dynamic_section;
7644 entry < dynamic_section + dynamic_nent;
7645 entry++)
252b5132
RH
7646 {
7647 if (do_dynamic)
f7a99963 7648 {
2cf0635d 7649 const char * dtype;
e699b9ff 7650
f7a99963
NC
7651 putchar (' ');
7652 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7653 dtype = get_dynamic_type (entry->d_tag);
7654 printf (" (%s)%*s", dtype,
7655 ((is_32bit_elf ? 27 : 19)
7656 - (int) strlen (dtype)),
f7a99963
NC
7657 " ");
7658 }
252b5132
RH
7659
7660 switch (entry->d_tag)
7661 {
d1133906
NC
7662 case DT_FLAGS:
7663 if (do_dynamic)
e9e44622 7664 print_dynamic_flags (entry->d_un.d_val);
d1133906 7665 break;
76da6bbe 7666
252b5132
RH
7667 case DT_AUXILIARY:
7668 case DT_FILTER:
019148e4
L
7669 case DT_CONFIG:
7670 case DT_DEPAUDIT:
7671 case DT_AUDIT:
252b5132
RH
7672 if (do_dynamic)
7673 {
019148e4 7674 switch (entry->d_tag)
b34976b6 7675 {
019148e4
L
7676 case DT_AUXILIARY:
7677 printf (_("Auxiliary library"));
7678 break;
7679
7680 case DT_FILTER:
7681 printf (_("Filter library"));
7682 break;
7683
b34976b6 7684 case DT_CONFIG:
019148e4
L
7685 printf (_("Configuration file"));
7686 break;
7687
7688 case DT_DEPAUDIT:
7689 printf (_("Dependency audit library"));
7690 break;
7691
7692 case DT_AUDIT:
7693 printf (_("Audit library"));
7694 break;
7695 }
252b5132 7696
d79b3d50
NC
7697 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7698 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7699 else
f7a99963
NC
7700 {
7701 printf (": ");
7702 print_vma (entry->d_un.d_val, PREFIX_HEX);
7703 putchar ('\n');
7704 }
252b5132
RH
7705 }
7706 break;
7707
dcefbbbd 7708 case DT_FEATURE:
252b5132
RH
7709 if (do_dynamic)
7710 {
7711 printf (_("Flags:"));
86f55779 7712
252b5132
RH
7713 if (entry->d_un.d_val == 0)
7714 printf (_(" None\n"));
7715 else
7716 {
7717 unsigned long int val = entry->d_un.d_val;
86f55779 7718
252b5132
RH
7719 if (val & DTF_1_PARINIT)
7720 {
7721 printf (" PARINIT");
7722 val ^= DTF_1_PARINIT;
7723 }
dcefbbbd
L
7724 if (val & DTF_1_CONFEXP)
7725 {
7726 printf (" CONFEXP");
7727 val ^= DTF_1_CONFEXP;
7728 }
252b5132
RH
7729 if (val != 0)
7730 printf (" %lx", val);
7731 puts ("");
7732 }
7733 }
7734 break;
7735
7736 case DT_POSFLAG_1:
7737 if (do_dynamic)
7738 {
7739 printf (_("Flags:"));
86f55779 7740
252b5132
RH
7741 if (entry->d_un.d_val == 0)
7742 printf (_(" None\n"));
7743 else
7744 {
7745 unsigned long int val = entry->d_un.d_val;
86f55779 7746
252b5132
RH
7747 if (val & DF_P1_LAZYLOAD)
7748 {
7749 printf (" LAZYLOAD");
7750 val ^= DF_P1_LAZYLOAD;
7751 }
7752 if (val & DF_P1_GROUPPERM)
7753 {
7754 printf (" GROUPPERM");
7755 val ^= DF_P1_GROUPPERM;
7756 }
7757 if (val != 0)
7758 printf (" %lx", val);
7759 puts ("");
7760 }
7761 }
7762 break;
7763
7764 case DT_FLAGS_1:
7765 if (do_dynamic)
7766 {
7767 printf (_("Flags:"));
7768 if (entry->d_un.d_val == 0)
7769 printf (_(" None\n"));
7770 else
7771 {
7772 unsigned long int val = entry->d_un.d_val;
86f55779 7773
252b5132
RH
7774 if (val & DF_1_NOW)
7775 {
7776 printf (" NOW");
7777 val ^= DF_1_NOW;
7778 }
7779 if (val & DF_1_GLOBAL)
7780 {
7781 printf (" GLOBAL");
7782 val ^= DF_1_GLOBAL;
7783 }
7784 if (val & DF_1_GROUP)
7785 {
7786 printf (" GROUP");
7787 val ^= DF_1_GROUP;
7788 }
7789 if (val & DF_1_NODELETE)
7790 {
7791 printf (" NODELETE");
7792 val ^= DF_1_NODELETE;
7793 }
7794 if (val & DF_1_LOADFLTR)
7795 {
7796 printf (" LOADFLTR");
7797 val ^= DF_1_LOADFLTR;
7798 }
7799 if (val & DF_1_INITFIRST)
7800 {
7801 printf (" INITFIRST");
7802 val ^= DF_1_INITFIRST;
7803 }
7804 if (val & DF_1_NOOPEN)
7805 {
7806 printf (" NOOPEN");
7807 val ^= DF_1_NOOPEN;
7808 }
7809 if (val & DF_1_ORIGIN)
7810 {
7811 printf (" ORIGIN");
7812 val ^= DF_1_ORIGIN;
7813 }
7814 if (val & DF_1_DIRECT)
7815 {
7816 printf (" DIRECT");
7817 val ^= DF_1_DIRECT;
7818 }
7819 if (val & DF_1_TRANS)
7820 {
7821 printf (" TRANS");
7822 val ^= DF_1_TRANS;
7823 }
7824 if (val & DF_1_INTERPOSE)
7825 {
7826 printf (" INTERPOSE");
7827 val ^= DF_1_INTERPOSE;
7828 }
f7db6139 7829 if (val & DF_1_NODEFLIB)
dcefbbbd 7830 {
f7db6139
L
7831 printf (" NODEFLIB");
7832 val ^= DF_1_NODEFLIB;
dcefbbbd
L
7833 }
7834 if (val & DF_1_NODUMP)
7835 {
7836 printf (" NODUMP");
7837 val ^= DF_1_NODUMP;
7838 }
7839 if (val & DF_1_CONLFAT)
7840 {
7841 printf (" CONLFAT");
7842 val ^= DF_1_CONLFAT;
7843 }
252b5132
RH
7844 if (val != 0)
7845 printf (" %lx", val);
7846 puts ("");
7847 }
7848 }
7849 break;
7850
7851 case DT_PLTREL:
566b0d53 7852 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7853 if (do_dynamic)
7854 puts (get_dynamic_type (entry->d_un.d_val));
7855 break;
7856
7857 case DT_NULL :
7858 case DT_NEEDED :
7859 case DT_PLTGOT :
7860 case DT_HASH :
7861 case DT_STRTAB :
7862 case DT_SYMTAB :
7863 case DT_RELA :
7864 case DT_INIT :
7865 case DT_FINI :
7866 case DT_SONAME :
7867 case DT_RPATH :
7868 case DT_SYMBOLIC:
7869 case DT_REL :
7870 case DT_DEBUG :
7871 case DT_TEXTREL :
7872 case DT_JMPREL :
019148e4 7873 case DT_RUNPATH :
252b5132
RH
7874 dynamic_info[entry->d_tag] = entry->d_un.d_val;
7875
7876 if (do_dynamic)
7877 {
2cf0635d 7878 char * name;
252b5132 7879
d79b3d50
NC
7880 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7881 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7882 else
d79b3d50 7883 name = NULL;
252b5132
RH
7884
7885 if (name)
7886 {
7887 switch (entry->d_tag)
7888 {
7889 case DT_NEEDED:
7890 printf (_("Shared library: [%s]"), name);
7891
18bd398b 7892 if (streq (name, program_interpreter))
f7a99963 7893 printf (_(" program interpreter"));
252b5132
RH
7894 break;
7895
7896 case DT_SONAME:
f7a99963 7897 printf (_("Library soname: [%s]"), name);
252b5132
RH
7898 break;
7899
7900 case DT_RPATH:
f7a99963 7901 printf (_("Library rpath: [%s]"), name);
252b5132
RH
7902 break;
7903
019148e4
L
7904 case DT_RUNPATH:
7905 printf (_("Library runpath: [%s]"), name);
7906 break;
7907
252b5132 7908 default:
f7a99963
NC
7909 print_vma (entry->d_un.d_val, PREFIX_HEX);
7910 break;
252b5132
RH
7911 }
7912 }
7913 else
f7a99963
NC
7914 print_vma (entry->d_un.d_val, PREFIX_HEX);
7915
7916 putchar ('\n');
252b5132
RH
7917 }
7918 break;
7919
7920 case DT_PLTRELSZ:
7921 case DT_RELASZ :
7922 case DT_STRSZ :
7923 case DT_RELSZ :
7924 case DT_RELAENT :
7925 case DT_SYMENT :
7926 case DT_RELENT :
566b0d53 7927 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7928 case DT_PLTPADSZ:
7929 case DT_MOVEENT :
7930 case DT_MOVESZ :
7931 case DT_INIT_ARRAYSZ:
7932 case DT_FINI_ARRAYSZ:
047b2264
JJ
7933 case DT_GNU_CONFLICTSZ:
7934 case DT_GNU_LIBLISTSZ:
252b5132 7935 if (do_dynamic)
f7a99963
NC
7936 {
7937 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 7938 printf (_(" (bytes)\n"));
f7a99963 7939 }
252b5132
RH
7940 break;
7941
7942 case DT_VERDEFNUM:
7943 case DT_VERNEEDNUM:
7944 case DT_RELACOUNT:
7945 case DT_RELCOUNT:
7946 if (do_dynamic)
f7a99963
NC
7947 {
7948 print_vma (entry->d_un.d_val, UNSIGNED);
7949 putchar ('\n');
7950 }
252b5132
RH
7951 break;
7952
7953 case DT_SYMINSZ:
7954 case DT_SYMINENT:
7955 case DT_SYMINFO:
7956 case DT_USED:
7957 case DT_INIT_ARRAY:
7958 case DT_FINI_ARRAY:
7959 if (do_dynamic)
7960 {
d79b3d50
NC
7961 if (entry->d_tag == DT_USED
7962 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 7963 {
2cf0635d 7964 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7965
b34976b6 7966 if (*name)
252b5132
RH
7967 {
7968 printf (_("Not needed object: [%s]\n"), name);
7969 break;
7970 }
7971 }
103f02d3 7972
f7a99963
NC
7973 print_vma (entry->d_un.d_val, PREFIX_HEX);
7974 putchar ('\n');
252b5132
RH
7975 }
7976 break;
7977
7978 case DT_BIND_NOW:
7979 /* The value of this entry is ignored. */
35b1837e
AM
7980 if (do_dynamic)
7981 putchar ('\n');
252b5132 7982 break;
103f02d3 7983
047b2264
JJ
7984 case DT_GNU_PRELINKED:
7985 if (do_dynamic)
7986 {
2cf0635d 7987 struct tm * tmp;
91d6fa6a 7988 time_t atime = entry->d_un.d_val;
047b2264 7989
91d6fa6a 7990 tmp = gmtime (&atime);
047b2264
JJ
7991 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
7992 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7993 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7994
7995 }
7996 break;
7997
fdc90cb4
JJ
7998 case DT_GNU_HASH:
7999 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8000 if (do_dynamic)
8001 {
8002 print_vma (entry->d_un.d_val, PREFIX_HEX);
8003 putchar ('\n');
8004 }
8005 break;
8006
252b5132
RH
8007 default:
8008 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8009 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8010 entry->d_un.d_val;
8011
8012 if (do_dynamic)
8013 {
8014 switch (elf_header.e_machine)
8015 {
8016 case EM_MIPS:
4fe85591 8017 case EM_MIPS_RS3_LE:
b2d38a17 8018 dynamic_section_mips_val (entry);
252b5132 8019 break;
103f02d3 8020 case EM_PARISC:
b2d38a17 8021 dynamic_section_parisc_val (entry);
103f02d3 8022 break;
ecc51f48 8023 case EM_IA_64:
b2d38a17 8024 dynamic_section_ia64_val (entry);
ecc51f48 8025 break;
252b5132 8026 default:
f7a99963
NC
8027 print_vma (entry->d_un.d_val, PREFIX_HEX);
8028 putchar ('\n');
252b5132
RH
8029 }
8030 }
8031 break;
8032 }
8033 }
8034
8035 return 1;
8036}
8037
8038static char *
d3ba0551 8039get_ver_flags (unsigned int flags)
252b5132 8040{
b34976b6 8041 static char buff[32];
252b5132
RH
8042
8043 buff[0] = 0;
8044
8045 if (flags == 0)
8046 return _("none");
8047
8048 if (flags & VER_FLG_BASE)
8049 strcat (buff, "BASE ");
8050
8051 if (flags & VER_FLG_WEAK)
8052 {
8053 if (flags & VER_FLG_BASE)
8054 strcat (buff, "| ");
8055
8056 strcat (buff, "WEAK ");
8057 }
8058
44ec90b9
RO
8059 if (flags & VER_FLG_INFO)
8060 {
8061 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8062 strcat (buff, "| ");
8063
8064 strcat (buff, "INFO ");
8065 }
8066
8067 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8068 strcat (buff, _("| <unknown>"));
252b5132
RH
8069
8070 return buff;
8071}
8072
8073/* Display the contents of the version sections. */
98fb390a 8074
252b5132 8075static int
2cf0635d 8076process_version_sections (FILE * file)
252b5132 8077{
2cf0635d 8078 Elf_Internal_Shdr * section;
b34976b6
AM
8079 unsigned i;
8080 int found = 0;
252b5132
RH
8081
8082 if (! do_version)
8083 return 1;
8084
8085 for (i = 0, section = section_headers;
8086 i < elf_header.e_shnum;
b34976b6 8087 i++, section++)
252b5132
RH
8088 {
8089 switch (section->sh_type)
8090 {
8091 case SHT_GNU_verdef:
8092 {
2cf0635d 8093 Elf_External_Verdef * edefs;
b34976b6
AM
8094 unsigned int idx;
8095 unsigned int cnt;
2cf0635d 8096 char * endbuf;
252b5132
RH
8097
8098 found = 1;
8099
8100 printf
72de5009 8101 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8102 SECTION_NAME (section), section->sh_info);
8103
8104 printf (_(" Addr: 0x"));
8105 printf_vma (section->sh_addr);
72de5009 8106 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8107 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8108 section->sh_link < elf_header.e_shnum
8109 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8110 : _("<corrupt>"));
252b5132 8111
3f5e193b
NC
8112 edefs = (Elf_External_Verdef *)
8113 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8114 _("version definition section"));
a6e9f9df
AM
8115 if (!edefs)
8116 break;
59245841 8117 endbuf = (char *) edefs + section->sh_size;
252b5132 8118
b34976b6 8119 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8120 {
2cf0635d
NC
8121 char * vstart;
8122 Elf_External_Verdef * edef;
b34976b6 8123 Elf_Internal_Verdef ent;
2cf0635d 8124 Elf_External_Verdaux * eaux;
b34976b6
AM
8125 Elf_Internal_Verdaux aux;
8126 int j;
8127 int isum;
103f02d3 8128
dd24e3da
NC
8129 /* Check for negative or very large indicies. */
8130 if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
8131 break;
8132
252b5132 8133 vstart = ((char *) edefs) + idx;
54806181
AM
8134 if (vstart + sizeof (*edef) > endbuf)
8135 break;
252b5132
RH
8136
8137 edef = (Elf_External_Verdef *) vstart;
8138
8139 ent.vd_version = BYTE_GET (edef->vd_version);
8140 ent.vd_flags = BYTE_GET (edef->vd_flags);
8141 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8142 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8143 ent.vd_hash = BYTE_GET (edef->vd_hash);
8144 ent.vd_aux = BYTE_GET (edef->vd_aux);
8145 ent.vd_next = BYTE_GET (edef->vd_next);
8146
8147 printf (_(" %#06x: Rev: %d Flags: %s"),
8148 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8149
8150 printf (_(" Index: %d Cnt: %d "),
8151 ent.vd_ndx, ent.vd_cnt);
8152
dd24e3da
NC
8153 /* Check for overflow. */
8154 if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
8155 || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
8156 break;
8157
252b5132
RH
8158 vstart += ent.vd_aux;
8159
8160 eaux = (Elf_External_Verdaux *) vstart;
8161
8162 aux.vda_name = BYTE_GET (eaux->vda_name);
8163 aux.vda_next = BYTE_GET (eaux->vda_next);
8164
d79b3d50
NC
8165 if (VALID_DYNAMIC_NAME (aux.vda_name))
8166 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8167 else
8168 printf (_("Name index: %ld\n"), aux.vda_name);
8169
8170 isum = idx + ent.vd_aux;
8171
b34976b6 8172 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8173 {
dd24e3da
NC
8174 /* Check for overflow. */
8175 if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
8176 || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
8177 break;
8178
252b5132
RH
8179 isum += aux.vda_next;
8180 vstart += aux.vda_next;
8181
8182 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8183 if (vstart + sizeof (*eaux) > endbuf)
8184 break;
252b5132
RH
8185
8186 aux.vda_name = BYTE_GET (eaux->vda_name);
8187 aux.vda_next = BYTE_GET (eaux->vda_next);
8188
d79b3d50 8189 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8190 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8191 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8192 else
8193 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8194 isum, j, aux.vda_name);
8195 }
dd24e3da 8196
54806181
AM
8197 if (j < ent.vd_cnt)
8198 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8199
8200 idx += ent.vd_next;
8201 }
dd24e3da 8202
54806181
AM
8203 if (cnt < section->sh_info)
8204 printf (_(" Version definition past end of section\n"));
252b5132
RH
8205
8206 free (edefs);
8207 }
8208 break;
103f02d3 8209
252b5132
RH
8210 case SHT_GNU_verneed:
8211 {
2cf0635d 8212 Elf_External_Verneed * eneed;
b34976b6
AM
8213 unsigned int idx;
8214 unsigned int cnt;
2cf0635d 8215 char * endbuf;
252b5132
RH
8216
8217 found = 1;
8218
72de5009 8219 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8220 SECTION_NAME (section), section->sh_info);
8221
8222 printf (_(" Addr: 0x"));
8223 printf_vma (section->sh_addr);
72de5009 8224 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8225 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8226 section->sh_link < elf_header.e_shnum
8227 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8228 : _("<corrupt>"));
252b5132 8229
3f5e193b
NC
8230 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8231 section->sh_offset, 1,
8232 section->sh_size,
8233 _("version need section"));
a6e9f9df
AM
8234 if (!eneed)
8235 break;
59245841 8236 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8237
8238 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8239 {
2cf0635d 8240 Elf_External_Verneed * entry;
b34976b6
AM
8241 Elf_Internal_Verneed ent;
8242 int j;
8243 int isum;
2cf0635d 8244 char * vstart;
252b5132 8245
dd24e3da
NC
8246 if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
8247 break;
8248
252b5132 8249 vstart = ((char *) eneed) + idx;
54806181
AM
8250 if (vstart + sizeof (*entry) > endbuf)
8251 break;
252b5132
RH
8252
8253 entry = (Elf_External_Verneed *) vstart;
8254
8255 ent.vn_version = BYTE_GET (entry->vn_version);
8256 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8257 ent.vn_file = BYTE_GET (entry->vn_file);
8258 ent.vn_aux = BYTE_GET (entry->vn_aux);
8259 ent.vn_next = BYTE_GET (entry->vn_next);
8260
8261 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8262
d79b3d50
NC
8263 if (VALID_DYNAMIC_NAME (ent.vn_file))
8264 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8265 else
8266 printf (_(" File: %lx"), ent.vn_file);
8267
8268 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8269
dd24e3da
NC
8270 /* Check for overflow. */
8271 if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
8272 || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
8273 break;
8274
252b5132
RH
8275 vstart += ent.vn_aux;
8276
8277 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8278 {
2cf0635d 8279 Elf_External_Vernaux * eaux;
b34976b6 8280 Elf_Internal_Vernaux aux;
252b5132 8281
54806181
AM
8282 if (vstart + sizeof (*eaux) > endbuf)
8283 break;
252b5132
RH
8284 eaux = (Elf_External_Vernaux *) vstart;
8285
8286 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8287 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8288 aux.vna_other = BYTE_GET (eaux->vna_other);
8289 aux.vna_name = BYTE_GET (eaux->vna_name);
8290 aux.vna_next = BYTE_GET (eaux->vna_next);
8291
d79b3d50 8292 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8293 printf (_(" %#06x: Name: %s"),
d79b3d50 8294 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8295 else
ecc2063b 8296 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8297 isum, aux.vna_name);
8298
8299 printf (_(" Flags: %s Version: %d\n"),
8300 get_ver_flags (aux.vna_flags), aux.vna_other);
8301
dd24e3da
NC
8302 /* Check for overflow. */
8303 if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
8304 || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
8305 break;
8306
252b5132
RH
8307 isum += aux.vna_next;
8308 vstart += aux.vna_next;
8309 }
54806181
AM
8310 if (j < ent.vn_cnt)
8311 printf (_(" Version need aux past end of section\n"));
252b5132
RH
8312
8313 idx += ent.vn_next;
8314 }
54806181
AM
8315 if (cnt < section->sh_info)
8316 printf (_(" Version need past end of section\n"));
103f02d3 8317
252b5132
RH
8318 free (eneed);
8319 }
8320 break;
8321
8322 case SHT_GNU_versym:
8323 {
2cf0635d 8324 Elf_Internal_Shdr * link_section;
b34976b6
AM
8325 int total;
8326 int cnt;
2cf0635d
NC
8327 unsigned char * edata;
8328 unsigned short * data;
8329 char * strtab;
8330 Elf_Internal_Sym * symbols;
8331 Elf_Internal_Shdr * string_sec;
d3ba0551 8332 long off;
252b5132 8333
4fbb74a6 8334 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8335 break;
8336
4fbb74a6 8337 link_section = section_headers + section->sh_link;
08d8fa11 8338 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8339
4fbb74a6 8340 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8341 break;
8342
252b5132
RH
8343 found = 1;
8344
9ad5cbcf 8345 symbols = GET_ELF_SYMBOLS (file, link_section);
dd24e3da
NC
8346 if (symbols == NULL)
8347 break;
252b5132 8348
4fbb74a6 8349 string_sec = section_headers + link_section->sh_link;
252b5132 8350
3f5e193b
NC
8351 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8352 string_sec->sh_size,
8353 _("version string table"));
a6e9f9df 8354 if (!strtab)
0429c154
MS
8355 {
8356 free (symbols);
8357 break;
8358 }
252b5132
RH
8359
8360 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8361 SECTION_NAME (section), total);
8362
8363 printf (_(" Addr: "));
8364 printf_vma (section->sh_addr);
72de5009 8365 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8366 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8367 SECTION_NAME (link_section));
8368
d3ba0551
AM
8369 off = offset_from_vma (file,
8370 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8371 total * sizeof (short));
3f5e193b
NC
8372 edata = (unsigned char *) get_data (NULL, file, off, total,
8373 sizeof (short),
8374 _("version symbol data"));
a6e9f9df
AM
8375 if (!edata)
8376 {
8377 free (strtab);
0429c154 8378 free (symbols);
a6e9f9df
AM
8379 break;
8380 }
252b5132 8381
3f5e193b 8382 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8383
8384 for (cnt = total; cnt --;)
b34976b6
AM
8385 data[cnt] = byte_get (edata + cnt * sizeof (short),
8386 sizeof (short));
252b5132
RH
8387
8388 free (edata);
8389
8390 for (cnt = 0; cnt < total; cnt += 4)
8391 {
8392 int j, nn;
00d93f34 8393 int check_def, check_need;
2cf0635d 8394 char * name;
252b5132
RH
8395
8396 printf (" %03x:", cnt);
8397
8398 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8399 switch (data[cnt + j])
252b5132
RH
8400 {
8401 case 0:
8402 fputs (_(" 0 (*local*) "), stdout);
8403 break;
8404
8405 case 1:
8406 fputs (_(" 1 (*global*) "), stdout);
8407 break;
8408
8409 default:
c244d050
NC
8410 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8411 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8412
dd24e3da
NC
8413 /* If this index value is greater than the size of the symbols
8414 array, break to avoid an out-of-bounds read, */
8415 if ((unsigned long)(cnt + j) >=
8416 ((unsigned long)link_section->sh_size /
8417 (unsigned long)link_section->sh_entsize))
8418 {
8419 warn (_("invalid index into symbol array\n"));
8420 break;
8421 }
8422
00d93f34
JJ
8423 check_def = 1;
8424 check_need = 1;
4fbb74a6
AM
8425 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8426 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8427 != SHT_NOBITS)
252b5132 8428 {
b34976b6 8429 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8430 check_def = 0;
8431 else
8432 check_need = 0;
252b5132 8433 }
00d93f34
JJ
8434
8435 if (check_need
b34976b6 8436 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8437 {
b34976b6
AM
8438 Elf_Internal_Verneed ivn;
8439 unsigned long offset;
252b5132 8440
d93f0186
NC
8441 offset = offset_from_vma
8442 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8443 sizeof (Elf_External_Verneed));
252b5132 8444
b34976b6 8445 do
252b5132 8446 {
b34976b6
AM
8447 Elf_Internal_Vernaux ivna;
8448 Elf_External_Verneed evn;
8449 Elf_External_Vernaux evna;
8450 unsigned long a_off;
252b5132 8451
59245841
NC
8452 if (get_data (&evn, file, offset, sizeof (evn), 1,
8453 _("version need")) == NULL)
8454 break;
8455
252b5132
RH
8456 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8457 ivn.vn_next = BYTE_GET (evn.vn_next);
8458
8459 a_off = offset + ivn.vn_aux;
8460
8461 do
8462 {
59245841
NC
8463 if (get_data (&evna, file, a_off, sizeof (evna),
8464 1, _("version need aux (2)")) == NULL)
8465 {
8466 ivna.vna_next = 0;
8467 ivna.vna_other = 0;
8468 }
8469 else
8470 {
8471 ivna.vna_next = BYTE_GET (evna.vna_next);
8472 ivna.vna_other = BYTE_GET (evna.vna_other);
8473 }
252b5132
RH
8474
8475 a_off += ivna.vna_next;
8476 }
b34976b6 8477 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8478 && ivna.vna_next != 0);
8479
b34976b6 8480 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8481 {
8482 ivna.vna_name = BYTE_GET (evna.vna_name);
8483
54806181
AM
8484 if (ivna.vna_name >= string_sec->sh_size)
8485 name = _("*invalid*");
8486 else
8487 name = strtab + ivna.vna_name;
252b5132 8488 nn += printf ("(%s%-*s",
16062207
ILT
8489 name,
8490 12 - (int) strlen (name),
252b5132 8491 ")");
00d93f34 8492 check_def = 0;
252b5132
RH
8493 break;
8494 }
8495
8496 offset += ivn.vn_next;
8497 }
8498 while (ivn.vn_next);
8499 }
00d93f34 8500
b34976b6
AM
8501 if (check_def && data[cnt + j] != 0x8001
8502 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8503 {
b34976b6
AM
8504 Elf_Internal_Verdef ivd;
8505 Elf_External_Verdef evd;
8506 unsigned long offset;
252b5132 8507
d93f0186
NC
8508 offset = offset_from_vma
8509 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8510 sizeof evd);
252b5132
RH
8511
8512 do
8513 {
59245841
NC
8514 if (get_data (&evd, file, offset, sizeof (evd), 1,
8515 _("version def")) == NULL)
8516 {
8517 ivd.vd_next = 0;
8518 ivd.vd_ndx = 0;
8519 }
8520 else
8521 {
8522 ivd.vd_next = BYTE_GET (evd.vd_next);
8523 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8524 }
252b5132
RH
8525
8526 offset += ivd.vd_next;
8527 }
c244d050 8528 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8529 && ivd.vd_next != 0);
8530
c244d050 8531 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8532 {
b34976b6
AM
8533 Elf_External_Verdaux evda;
8534 Elf_Internal_Verdaux ivda;
252b5132
RH
8535
8536 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8537
59245841
NC
8538 if (get_data (&evda, file,
8539 offset - ivd.vd_next + ivd.vd_aux,
8540 sizeof (evda), 1,
8541 _("version def aux")) == NULL)
8542 break;
252b5132
RH
8543
8544 ivda.vda_name = BYTE_GET (evda.vda_name);
8545
54806181
AM
8546 if (ivda.vda_name >= string_sec->sh_size)
8547 name = _("*invalid*");
8548 else
8549 name = strtab + ivda.vda_name;
252b5132 8550 nn += printf ("(%s%-*s",
16062207
ILT
8551 name,
8552 12 - (int) strlen (name),
252b5132
RH
8553 ")");
8554 }
8555 }
8556
8557 if (nn < 18)
8558 printf ("%*c", 18 - nn, ' ');
8559 }
8560
8561 putchar ('\n');
8562 }
8563
8564 free (data);
8565 free (strtab);
8566 free (symbols);
8567 }
8568 break;
103f02d3 8569
252b5132
RH
8570 default:
8571 break;
8572 }
8573 }
8574
8575 if (! found)
8576 printf (_("\nNo version information found in this file.\n"));
8577
8578 return 1;
8579}
8580
d1133906 8581static const char *
d3ba0551 8582get_symbol_binding (unsigned int binding)
252b5132 8583{
b34976b6 8584 static char buff[32];
252b5132
RH
8585
8586 switch (binding)
8587 {
b34976b6
AM
8588 case STB_LOCAL: return "LOCAL";
8589 case STB_GLOBAL: return "GLOBAL";
8590 case STB_WEAK: return "WEAK";
252b5132
RH
8591 default:
8592 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8593 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8594 binding);
252b5132 8595 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8596 {
8597 if (binding == STB_GNU_UNIQUE
9c55345c
TS
8598 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8599 /* GNU is still using the default value 0. */
3e7a7d11
NC
8600 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8601 return "UNIQUE";
8602 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8603 }
252b5132 8604 else
e9e44622 8605 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8606 return buff;
8607 }
8608}
8609
d1133906 8610static const char *
d3ba0551 8611get_symbol_type (unsigned int type)
252b5132 8612{
b34976b6 8613 static char buff[32];
252b5132
RH
8614
8615 switch (type)
8616 {
b34976b6
AM
8617 case STT_NOTYPE: return "NOTYPE";
8618 case STT_OBJECT: return "OBJECT";
8619 case STT_FUNC: return "FUNC";
8620 case STT_SECTION: return "SECTION";
8621 case STT_FILE: return "FILE";
8622 case STT_COMMON: return "COMMON";
8623 case STT_TLS: return "TLS";
15ab5209
DB
8624 case STT_RELC: return "RELC";
8625 case STT_SRELC: return "SRELC";
252b5132
RH
8626 default:
8627 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8628 {
8629 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8630 return "THUMB_FUNC";
8631
351b4b40 8632 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8633 return "REGISTER";
8634
8635 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8636 return "PARISC_MILLI";
8637
e9e44622 8638 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8639 }
252b5132 8640 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8641 {
8642 if (elf_header.e_machine == EM_PARISC)
8643 {
8644 if (type == STT_HP_OPAQUE)
8645 return "HP_OPAQUE";
8646 if (type == STT_HP_STUB)
8647 return "HP_STUB";
8648 }
8649
d8045f23 8650 if (type == STT_GNU_IFUNC
9c55345c
TS
8651 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8652 /* GNU is still using the default value 0. */
d8045f23
NC
8653 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8654 return "IFUNC";
8655
e9e44622 8656 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8657 }
252b5132 8658 else
e9e44622 8659 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8660 return buff;
8661 }
8662}
8663
d1133906 8664static const char *
d3ba0551 8665get_symbol_visibility (unsigned int visibility)
d1133906
NC
8666{
8667 switch (visibility)
8668 {
b34976b6
AM
8669 case STV_DEFAULT: return "DEFAULT";
8670 case STV_INTERNAL: return "INTERNAL";
8671 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
8672 case STV_PROTECTED: return "PROTECTED";
8673 default: abort ();
8674 }
8675}
8676
5e2b0d47
NC
8677static const char *
8678get_mips_symbol_other (unsigned int other)
8679{
8680 switch (other)
8681 {
8682 case STO_OPTIONAL: return "OPTIONAL";
8683 case STO_MIPS16: return "MIPS16";
861fb55a
DJ
8684 case STO_MIPS_PLT: return "MIPS PLT";
8685 case STO_MIPS_PIC: return "MIPS PIC";
5e2b0d47
NC
8686 default: return NULL;
8687 }
8688}
8689
28f997cf
TG
8690static const char *
8691get_ia64_symbol_other (unsigned int other)
8692{
8693 if (is_ia64_vms ())
8694 {
8695 static char res[32];
8696
8697 res[0] = 0;
8698
8699 /* Function types is for images and .STB files only. */
8700 switch (elf_header.e_type)
8701 {
8702 case ET_DYN:
8703 case ET_EXEC:
8704 switch (VMS_ST_FUNC_TYPE (other))
8705 {
8706 case VMS_SFT_CODE_ADDR:
8707 strcat (res, " CA");
8708 break;
8709 case VMS_SFT_SYMV_IDX:
8710 strcat (res, " VEC");
8711 break;
8712 case VMS_SFT_FD:
8713 strcat (res, " FD");
8714 break;
8715 case VMS_SFT_RESERVE:
8716 strcat (res, " RSV");
8717 break;
8718 default:
8719 abort ();
8720 }
8721 break;
8722 default:
8723 break;
8724 }
8725 switch (VMS_ST_LINKAGE (other))
8726 {
8727 case VMS_STL_IGNORE:
8728 strcat (res, " IGN");
8729 break;
8730 case VMS_STL_RESERVE:
8731 strcat (res, " RSV");
8732 break;
8733 case VMS_STL_STD:
8734 strcat (res, " STD");
8735 break;
8736 case VMS_STL_LNK:
8737 strcat (res, " LNK");
8738 break;
8739 default:
8740 abort ();
8741 }
8742
8743 if (res[0] != 0)
8744 return res + 1;
8745 else
8746 return res;
8747 }
8748 return NULL;
8749}
8750
5e2b0d47
NC
8751static const char *
8752get_symbol_other (unsigned int other)
8753{
8754 const char * result = NULL;
8755 static char buff [32];
8756
8757 if (other == 0)
8758 return "";
8759
8760 switch (elf_header.e_machine)
8761 {
8762 case EM_MIPS:
8763 result = get_mips_symbol_other (other);
28f997cf
TG
8764 break;
8765 case EM_IA_64:
8766 result = get_ia64_symbol_other (other);
8767 break;
5e2b0d47
NC
8768 default:
8769 break;
8770 }
8771
8772 if (result)
8773 return result;
8774
8775 snprintf (buff, sizeof buff, _("<other>: %x"), other);
8776 return buff;
8777}
8778
d1133906 8779static const char *
d3ba0551 8780get_symbol_index_type (unsigned int type)
252b5132 8781{
b34976b6 8782 static char buff[32];
5cf1065c 8783
252b5132
RH
8784 switch (type)
8785 {
b34976b6
AM
8786 case SHN_UNDEF: return "UND";
8787 case SHN_ABS: return "ABS";
8788 case SHN_COMMON: return "COM";
252b5132 8789 default:
9ce701e2
L
8790 if (type == SHN_IA_64_ANSI_COMMON
8791 && elf_header.e_machine == EM_IA_64
8792 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
8793 return "ANSI_COM";
8a9036a4 8794 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
8795 || elf_header.e_machine == EM_L1OM
8796 || elf_header.e_machine == EM_K1OM)
3b22753a
L
8797 && type == SHN_X86_64_LCOMMON)
8798 return "LARGE_COM";
ac145307
BS
8799 else if ((type == SHN_MIPS_SCOMMON
8800 && elf_header.e_machine == EM_MIPS)
8801 || (type == SHN_TIC6X_SCOMMON
8802 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
8803 return "SCOM";
8804 else if (type == SHN_MIPS_SUNDEFINED
8805 && elf_header.e_machine == EM_MIPS)
8806 return "SUND";
9ce701e2 8807 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 8808 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 8809 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
8810 sprintf (buff, "OS [0x%04x]", type & 0xffff);
8811 else if (type >= SHN_LORESERVE)
8812 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 8813 else
232e7cb8 8814 sprintf (buff, "%3d", type);
5cf1065c 8815 break;
252b5132 8816 }
5cf1065c
NC
8817
8818 return buff;
252b5132
RH
8819}
8820
66543521 8821static bfd_vma *
2cf0635d 8822get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 8823{
2cf0635d
NC
8824 unsigned char * e_data;
8825 bfd_vma * i_data;
252b5132 8826
3f5e193b 8827 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
8828
8829 if (e_data == NULL)
8830 {
8831 error (_("Out of memory\n"));
8832 return NULL;
8833 }
8834
66543521 8835 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
8836 {
8837 error (_("Unable to read in dynamic data\n"));
8838 return NULL;
8839 }
8840
3f5e193b 8841 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
8842
8843 if (i_data == NULL)
8844 {
8845 error (_("Out of memory\n"));
8846 free (e_data);
8847 return NULL;
8848 }
8849
8850 while (number--)
66543521 8851 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
8852
8853 free (e_data);
8854
8855 return i_data;
8856}
8857
6bd1a22c
L
8858static void
8859print_dynamic_symbol (bfd_vma si, unsigned long hn)
8860{
2cf0635d 8861 Elf_Internal_Sym * psym;
6bd1a22c
L
8862 int n;
8863
8864 psym = dynamic_symbols + si;
8865
8866 n = print_vma (si, DEC_5);
8867 if (n < 5)
8868 fputs (" " + n, stdout);
8869 printf (" %3lu: ", hn);
8870 print_vma (psym->st_value, LONG_HEX);
8871 putchar (' ');
8872 print_vma (psym->st_size, DEC_5);
8873
f4be36b3
AM
8874 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8875 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
8876 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
8877 /* Check to see if any other bits in the st_other field are set.
8878 Note - displaying this information disrupts the layout of the
8879 table being generated, but for the moment this case is very
8880 rare. */
8881 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8882 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
8883 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
8884 if (VALID_DYNAMIC_NAME (psym->st_name))
8885 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
8886 else
2b692964 8887 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
8888 putchar ('\n');
8889}
8890
e3c8793a 8891/* Dump the symbol table. */
252b5132 8892static int
2cf0635d 8893process_symbol_table (FILE * file)
252b5132 8894{
2cf0635d 8895 Elf_Internal_Shdr * section;
66543521
AM
8896 bfd_vma nbuckets = 0;
8897 bfd_vma nchains = 0;
2cf0635d
NC
8898 bfd_vma * buckets = NULL;
8899 bfd_vma * chains = NULL;
fdc90cb4 8900 bfd_vma ngnubuckets = 0;
2cf0635d
NC
8901 bfd_vma * gnubuckets = NULL;
8902 bfd_vma * gnuchains = NULL;
6bd1a22c 8903 bfd_vma gnusymidx = 0;
252b5132 8904
2c610e4b 8905 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
8906 return 1;
8907
6bd1a22c
L
8908 if (dynamic_info[DT_HASH]
8909 && (do_histogram
2c610e4b
L
8910 || (do_using_dynamic
8911 && !do_dyn_syms
8912 && dynamic_strings != NULL)))
252b5132 8913 {
66543521
AM
8914 unsigned char nb[8];
8915 unsigned char nc[8];
8916 int hash_ent_size = 4;
8917
8918 if ((elf_header.e_machine == EM_ALPHA
8919 || elf_header.e_machine == EM_S390
8920 || elf_header.e_machine == EM_S390_OLD)
8921 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
8922 hash_ent_size = 8;
8923
fb52b2f4
NC
8924 if (fseek (file,
8925 (archive_file_offset
8926 + offset_from_vma (file, dynamic_info[DT_HASH],
8927 sizeof nb + sizeof nc)),
d93f0186 8928 SEEK_SET))
252b5132 8929 {
591a748a 8930 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8931 goto no_hash;
252b5132
RH
8932 }
8933
66543521 8934 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
8935 {
8936 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8937 goto no_hash;
252b5132
RH
8938 }
8939
66543521 8940 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
8941 {
8942 error (_("Failed to read in number of chains\n"));
d3a44ec6 8943 goto no_hash;
252b5132
RH
8944 }
8945
66543521
AM
8946 nbuckets = byte_get (nb, hash_ent_size);
8947 nchains = byte_get (nc, hash_ent_size);
252b5132 8948
66543521
AM
8949 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
8950 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 8951
d3a44ec6 8952 no_hash:
252b5132 8953 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
8954 {
8955 if (do_using_dynamic)
8956 return 0;
8957 free (buckets);
8958 free (chains);
8959 buckets = NULL;
8960 chains = NULL;
8961 nbuckets = 0;
8962 nchains = 0;
8963 }
252b5132
RH
8964 }
8965
6bd1a22c
L
8966 if (dynamic_info_DT_GNU_HASH
8967 && (do_histogram
2c610e4b
L
8968 || (do_using_dynamic
8969 && !do_dyn_syms
8970 && dynamic_strings != NULL)))
252b5132 8971 {
6bd1a22c
L
8972 unsigned char nb[16];
8973 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
8974 bfd_vma buckets_vma;
8975
8976 if (fseek (file,
8977 (archive_file_offset
8978 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
8979 sizeof nb)),
8980 SEEK_SET))
8981 {
8982 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8983 goto no_gnu_hash;
6bd1a22c 8984 }
252b5132 8985
6bd1a22c
L
8986 if (fread (nb, 16, 1, file) != 1)
8987 {
8988 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8989 goto no_gnu_hash;
6bd1a22c
L
8990 }
8991
8992 ngnubuckets = byte_get (nb, 4);
8993 gnusymidx = byte_get (nb + 4, 4);
8994 bitmaskwords = byte_get (nb + 8, 4);
8995 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 8996 if (is_32bit_elf)
6bd1a22c 8997 buckets_vma += bitmaskwords * 4;
f7a99963 8998 else
6bd1a22c 8999 buckets_vma += bitmaskwords * 8;
252b5132 9000
6bd1a22c
L
9001 if (fseek (file,
9002 (archive_file_offset
9003 + offset_from_vma (file, buckets_vma, 4)),
9004 SEEK_SET))
252b5132 9005 {
6bd1a22c 9006 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9007 goto no_gnu_hash;
6bd1a22c
L
9008 }
9009
9010 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9011
6bd1a22c 9012 if (gnubuckets == NULL)
d3a44ec6 9013 goto no_gnu_hash;
6bd1a22c
L
9014
9015 for (i = 0; i < ngnubuckets; i++)
9016 if (gnubuckets[i] != 0)
9017 {
9018 if (gnubuckets[i] < gnusymidx)
9019 return 0;
9020
9021 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9022 maxchain = gnubuckets[i];
9023 }
9024
9025 if (maxchain == 0xffffffff)
d3a44ec6 9026 goto no_gnu_hash;
6bd1a22c
L
9027
9028 maxchain -= gnusymidx;
9029
9030 if (fseek (file,
9031 (archive_file_offset
9032 + offset_from_vma (file, buckets_vma
9033 + 4 * (ngnubuckets + maxchain), 4)),
9034 SEEK_SET))
9035 {
9036 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9037 goto no_gnu_hash;
6bd1a22c
L
9038 }
9039
9040 do
9041 {
9042 if (fread (nb, 4, 1, file) != 1)
252b5132 9043 {
6bd1a22c 9044 error (_("Failed to determine last chain length\n"));
d3a44ec6 9045 goto no_gnu_hash;
6bd1a22c 9046 }
252b5132 9047
6bd1a22c 9048 if (maxchain + 1 == 0)
d3a44ec6 9049 goto no_gnu_hash;
252b5132 9050
6bd1a22c
L
9051 ++maxchain;
9052 }
9053 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9054
6bd1a22c
L
9055 if (fseek (file,
9056 (archive_file_offset
9057 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9058 SEEK_SET))
9059 {
9060 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9061 goto no_gnu_hash;
6bd1a22c
L
9062 }
9063
9064 gnuchains = get_dynamic_data (file, maxchain, 4);
9065
d3a44ec6 9066 no_gnu_hash:
6bd1a22c 9067 if (gnuchains == NULL)
d3a44ec6
JJ
9068 {
9069 free (gnubuckets);
d3a44ec6
JJ
9070 gnubuckets = NULL;
9071 ngnubuckets = 0;
f64fddf1
NC
9072 if (do_using_dynamic)
9073 return 0;
d3a44ec6 9074 }
6bd1a22c
L
9075 }
9076
9077 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9078 && do_syms
9079 && do_using_dynamic
9080 && dynamic_strings != NULL)
9081 {
9082 unsigned long hn;
9083
9084 if (dynamic_info[DT_HASH])
9085 {
9086 bfd_vma si;
9087
9088 printf (_("\nSymbol table for image:\n"));
9089 if (is_32bit_elf)
9090 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9091 else
9092 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9093
9094 for (hn = 0; hn < nbuckets; hn++)
9095 {
9096 if (! buckets[hn])
9097 continue;
9098
9099 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9100 print_dynamic_symbol (si, hn);
252b5132
RH
9101 }
9102 }
6bd1a22c
L
9103
9104 if (dynamic_info_DT_GNU_HASH)
9105 {
9106 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9107 if (is_32bit_elf)
9108 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9109 else
9110 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9111
9112 for (hn = 0; hn < ngnubuckets; ++hn)
9113 if (gnubuckets[hn] != 0)
9114 {
9115 bfd_vma si = gnubuckets[hn];
9116 bfd_vma off = si - gnusymidx;
9117
9118 do
9119 {
9120 print_dynamic_symbol (si, hn);
9121 si++;
9122 }
9123 while ((gnuchains[off++] & 1) == 0);
9124 }
9125 }
252b5132 9126 }
2c610e4b 9127 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9128 {
b34976b6 9129 unsigned int i;
252b5132
RH
9130
9131 for (i = 0, section = section_headers;
9132 i < elf_header.e_shnum;
9133 i++, section++)
9134 {
b34976b6 9135 unsigned int si;
2cf0635d 9136 char * strtab = NULL;
c256ffe7 9137 unsigned long int strtab_size = 0;
2cf0635d
NC
9138 Elf_Internal_Sym * symtab;
9139 Elf_Internal_Sym * psym;
252b5132 9140
2c610e4b
L
9141 if ((section->sh_type != SHT_SYMTAB
9142 && section->sh_type != SHT_DYNSYM)
9143 || (!do_syms
9144 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9145 continue;
9146
dd24e3da
NC
9147 if (section->sh_entsize == 0)
9148 {
9149 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9150 SECTION_NAME (section));
9151 continue;
9152 }
9153
252b5132
RH
9154 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9155 SECTION_NAME (section),
9156 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9157
f7a99963 9158 if (is_32bit_elf)
ca47b30c 9159 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9160 else
ca47b30c 9161 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9162
9ad5cbcf 9163 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
9164 if (symtab == NULL)
9165 continue;
9166
9167 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9168 {
9169 strtab = string_table;
9170 strtab_size = string_table_length;
9171 }
4fbb74a6 9172 else if (section->sh_link < elf_header.e_shnum)
252b5132 9173 {
2cf0635d 9174 Elf_Internal_Shdr * string_sec;
252b5132 9175
4fbb74a6 9176 string_sec = section_headers + section->sh_link;
252b5132 9177
3f5e193b
NC
9178 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9179 1, string_sec->sh_size,
9180 _("string table"));
c256ffe7 9181 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9182 }
9183
9184 for (si = 0, psym = symtab;
9185 si < section->sh_size / section->sh_entsize;
b34976b6 9186 si++, psym++)
252b5132 9187 {
5e220199 9188 printf ("%6d: ", si);
f7a99963
NC
9189 print_vma (psym->st_value, LONG_HEX);
9190 putchar (' ');
9191 print_vma (psym->st_size, DEC_5);
d1133906
NC
9192 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9193 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9194 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9195 /* Check to see if any other bits in the st_other field are set.
9196 Note - displaying this information disrupts the layout of the
9197 table being generated, but for the moment this case is very rare. */
9198 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9199 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9200 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9201 print_symbol (25, psym->st_name < strtab_size
2b692964 9202 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9203
59245841
NC
9204 if (section->sh_type == SHT_DYNSYM
9205 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9206 {
b34976b6
AM
9207 unsigned char data[2];
9208 unsigned short vers_data;
9209 unsigned long offset;
9210 int is_nobits;
9211 int check_def;
252b5132 9212
d93f0186
NC
9213 offset = offset_from_vma
9214 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9215 sizeof data + si * sizeof (vers_data));
252b5132 9216
59245841
NC
9217 if (get_data (&data, file, offset + si * sizeof (vers_data),
9218 sizeof (data), 1, _("version data")) == NULL)
9219 break;
252b5132
RH
9220
9221 vers_data = byte_get (data, 2);
9222
4fbb74a6
AM
9223 is_nobits = (psym->st_shndx < elf_header.e_shnum
9224 && section_headers[psym->st_shndx].sh_type
c256ffe7 9225 == SHT_NOBITS);
252b5132
RH
9226
9227 check_def = (psym->st_shndx != SHN_UNDEF);
9228
c244d050 9229 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9230 {
b34976b6 9231 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9232 && (is_nobits || ! check_def))
252b5132 9233 {
b34976b6
AM
9234 Elf_External_Verneed evn;
9235 Elf_Internal_Verneed ivn;
9236 Elf_Internal_Vernaux ivna;
252b5132
RH
9237
9238 /* We must test both. */
d93f0186
NC
9239 offset = offset_from_vma
9240 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9241 sizeof evn);
252b5132 9242
252b5132
RH
9243 do
9244 {
b34976b6 9245 unsigned long vna_off;
252b5132 9246
59245841
NC
9247 if (get_data (&evn, file, offset, sizeof (evn), 1,
9248 _("version need")) == NULL)
9249 {
9250 ivna.vna_next = 0;
9251 ivna.vna_other = 0;
9252 ivna.vna_name = 0;
9253 break;
9254 }
dd27201e
L
9255
9256 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9257 ivn.vn_next = BYTE_GET (evn.vn_next);
9258
252b5132
RH
9259 vna_off = offset + ivn.vn_aux;
9260
9261 do
9262 {
b34976b6 9263 Elf_External_Vernaux evna;
252b5132 9264
59245841
NC
9265 if (get_data (&evna, file, vna_off,
9266 sizeof (evna), 1,
9267 _("version need aux (3)")) == NULL)
9268 {
9269 ivna.vna_next = 0;
9270 ivna.vna_other = 0;
9271 ivna.vna_name = 0;
9272 }
9273 else
9274 {
9275 ivna.vna_other = BYTE_GET (evna.vna_other);
9276 ivna.vna_next = BYTE_GET (evna.vna_next);
9277 ivna.vna_name = BYTE_GET (evna.vna_name);
9278 }
252b5132
RH
9279
9280 vna_off += ivna.vna_next;
9281 }
9282 while (ivna.vna_other != vers_data
9283 && ivna.vna_next != 0);
9284
9285 if (ivna.vna_other == vers_data)
9286 break;
9287
9288 offset += ivn.vn_next;
9289 }
9290 while (ivn.vn_next != 0);
9291
9292 if (ivna.vna_other == vers_data)
9293 {
9294 printf ("@%s (%d)",
c256ffe7 9295 ivna.vna_name < strtab_size
2b692964 9296 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9297 ivna.vna_other);
252b5132
RH
9298 check_def = 0;
9299 }
9300 else if (! is_nobits)
591a748a 9301 error (_("bad dynamic symbol\n"));
252b5132
RH
9302 else
9303 check_def = 1;
9304 }
9305
9306 if (check_def)
9307 {
00d93f34 9308 if (vers_data != 0x8001
b34976b6 9309 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9310 {
b34976b6
AM
9311 Elf_Internal_Verdef ivd;
9312 Elf_Internal_Verdaux ivda;
9313 Elf_External_Verdaux evda;
91d6fa6a 9314 unsigned long off;
252b5132 9315
91d6fa6a 9316 off = offset_from_vma
d93f0186
NC
9317 (file,
9318 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9319 sizeof (Elf_External_Verdef));
252b5132
RH
9320
9321 do
9322 {
b34976b6 9323 Elf_External_Verdef evd;
252b5132 9324
59245841
NC
9325 if (get_data (&evd, file, off, sizeof (evd),
9326 1, _("version def")) == NULL)
9327 {
9328 ivd.vd_ndx = 0;
9329 ivd.vd_aux = 0;
9330 ivd.vd_next = 0;
9331 }
9332 else
9333 {
9334 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9335 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9336 ivd.vd_next = BYTE_GET (evd.vd_next);
9337 }
252b5132 9338
91d6fa6a 9339 off += ivd.vd_next;
252b5132 9340 }
c244d050 9341 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9342 && ivd.vd_next != 0);
9343
91d6fa6a
NC
9344 off -= ivd.vd_next;
9345 off += ivd.vd_aux;
252b5132 9346
59245841
NC
9347 if (get_data (&evda, file, off, sizeof (evda),
9348 1, _("version def aux")) == NULL)
9349 break;
252b5132
RH
9350
9351 ivda.vda_name = BYTE_GET (evda.vda_name);
9352
9353 if (psym->st_name != ivda.vda_name)
c244d050 9354 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9355 ? "@%s" : "@@%s",
c256ffe7 9356 ivda.vda_name < strtab_size
2b692964 9357 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9358 }
9359 }
9360 }
9361 }
9362
9363 putchar ('\n');
9364 }
9365
9366 free (symtab);
9367 if (strtab != string_table)
9368 free (strtab);
9369 }
9370 }
9371 else if (do_syms)
9372 printf
9373 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9374
9375 if (do_histogram && buckets != NULL)
9376 {
2cf0635d
NC
9377 unsigned long * lengths;
9378 unsigned long * counts;
66543521
AM
9379 unsigned long hn;
9380 bfd_vma si;
9381 unsigned long maxlength = 0;
9382 unsigned long nzero_counts = 0;
9383 unsigned long nsyms = 0;
252b5132 9384
66543521
AM
9385 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9386 (unsigned long) nbuckets);
252b5132
RH
9387 printf (_(" Length Number %% of total Coverage\n"));
9388
3f5e193b 9389 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9390 if (lengths == NULL)
9391 {
591a748a 9392 error (_("Out of memory\n"));
252b5132
RH
9393 return 0;
9394 }
9395 for (hn = 0; hn < nbuckets; ++hn)
9396 {
f7a99963 9397 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9398 {
b34976b6 9399 ++nsyms;
252b5132 9400 if (maxlength < ++lengths[hn])
b34976b6 9401 ++maxlength;
252b5132
RH
9402 }
9403 }
9404
3f5e193b 9405 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9406 if (counts == NULL)
9407 {
591a748a 9408 error (_("Out of memory\n"));
252b5132
RH
9409 return 0;
9410 }
9411
9412 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9413 ++counts[lengths[hn]];
252b5132 9414
103f02d3 9415 if (nbuckets > 0)
252b5132 9416 {
66543521
AM
9417 unsigned long i;
9418 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9419 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9420 for (i = 1; i <= maxlength; ++i)
103f02d3 9421 {
66543521
AM
9422 nzero_counts += counts[i] * i;
9423 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9424 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9425 (nzero_counts * 100.0) / nsyms);
9426 }
252b5132
RH
9427 }
9428
9429 free (counts);
9430 free (lengths);
9431 }
9432
9433 if (buckets != NULL)
9434 {
9435 free (buckets);
9436 free (chains);
9437 }
9438
d3a44ec6 9439 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9440 {
2cf0635d
NC
9441 unsigned long * lengths;
9442 unsigned long * counts;
fdc90cb4
JJ
9443 unsigned long hn;
9444 unsigned long maxlength = 0;
9445 unsigned long nzero_counts = 0;
9446 unsigned long nsyms = 0;
fdc90cb4 9447
3f5e193b 9448 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9449 if (lengths == NULL)
9450 {
591a748a 9451 error (_("Out of memory\n"));
fdc90cb4
JJ
9452 return 0;
9453 }
9454
9455 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9456 (unsigned long) ngnubuckets);
9457 printf (_(" Length Number %% of total Coverage\n"));
9458
9459 for (hn = 0; hn < ngnubuckets; ++hn)
9460 if (gnubuckets[hn] != 0)
9461 {
9462 bfd_vma off, length = 1;
9463
6bd1a22c 9464 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9465 (gnuchains[off] & 1) == 0; ++off)
9466 ++length;
9467 lengths[hn] = length;
9468 if (length > maxlength)
9469 maxlength = length;
9470 nsyms += length;
9471 }
9472
3f5e193b 9473 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9474 if (counts == NULL)
9475 {
591a748a 9476 error (_("Out of memory\n"));
fdc90cb4
JJ
9477 return 0;
9478 }
9479
9480 for (hn = 0; hn < ngnubuckets; ++hn)
9481 ++counts[lengths[hn]];
9482
9483 if (ngnubuckets > 0)
9484 {
9485 unsigned long j;
9486 printf (" 0 %-10lu (%5.1f%%)\n",
9487 counts[0], (counts[0] * 100.0) / ngnubuckets);
9488 for (j = 1; j <= maxlength; ++j)
9489 {
9490 nzero_counts += counts[j] * j;
9491 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9492 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9493 (nzero_counts * 100.0) / nsyms);
9494 }
9495 }
9496
9497 free (counts);
9498 free (lengths);
9499 free (gnubuckets);
9500 free (gnuchains);
9501 }
9502
252b5132
RH
9503 return 1;
9504}
9505
9506static int
2cf0635d 9507process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9508{
b4c96d0d 9509 unsigned int i;
252b5132
RH
9510
9511 if (dynamic_syminfo == NULL
9512 || !do_dynamic)
9513 /* No syminfo, this is ok. */
9514 return 1;
9515
9516 /* There better should be a dynamic symbol section. */
9517 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9518 return 0;
9519
9520 if (dynamic_addr)
9521 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9522 dynamic_syminfo_offset, dynamic_syminfo_nent);
9523
9524 printf (_(" Num: Name BoundTo Flags\n"));
9525 for (i = 0; i < dynamic_syminfo_nent; ++i)
9526 {
9527 unsigned short int flags = dynamic_syminfo[i].si_flags;
9528
31104126 9529 printf ("%4d: ", i);
d79b3d50
NC
9530 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9531 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9532 else
2b692964 9533 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9534 putchar (' ');
252b5132
RH
9535
9536 switch (dynamic_syminfo[i].si_boundto)
9537 {
9538 case SYMINFO_BT_SELF:
9539 fputs ("SELF ", stdout);
9540 break;
9541 case SYMINFO_BT_PARENT:
9542 fputs ("PARENT ", stdout);
9543 break;
9544 default:
9545 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9546 && dynamic_syminfo[i].si_boundto < dynamic_nent
9547 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9548 {
d79b3d50 9549 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9550 putchar (' ' );
9551 }
252b5132
RH
9552 else
9553 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9554 break;
9555 }
9556
9557 if (flags & SYMINFO_FLG_DIRECT)
9558 printf (" DIRECT");
9559 if (flags & SYMINFO_FLG_PASSTHRU)
9560 printf (" PASSTHRU");
9561 if (flags & SYMINFO_FLG_COPY)
9562 printf (" COPY");
9563 if (flags & SYMINFO_FLG_LAZYLOAD)
9564 printf (" LAZYLOAD");
9565
9566 puts ("");
9567 }
9568
9569 return 1;
9570}
9571
cf13d699
NC
9572/* Check to see if the given reloc needs to be handled in a target specific
9573 manner. If so then process the reloc and return TRUE otherwise return
9574 FALSE. */
09c11c86 9575
cf13d699
NC
9576static bfd_boolean
9577target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9578 unsigned char * start,
9579 Elf_Internal_Sym * symtab)
252b5132 9580{
cf13d699 9581 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9582
cf13d699 9583 switch (elf_header.e_machine)
252b5132 9584 {
cf13d699
NC
9585 case EM_MN10300:
9586 case EM_CYGNUS_MN10300:
9587 {
9588 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9589
cf13d699
NC
9590 switch (reloc_type)
9591 {
9592 case 34: /* R_MN10300_ALIGN */
9593 return TRUE;
9594 case 33: /* R_MN10300_SYM_DIFF */
9595 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9596 return TRUE;
9597 case 1: /* R_MN10300_32 */
9598 case 2: /* R_MN10300_16 */
9599 if (saved_sym != NULL)
9600 {
9601 bfd_vma value;
252b5132 9602
cf13d699
NC
9603 value = reloc->r_addend
9604 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9605 - saved_sym->st_value);
252b5132 9606
cf13d699 9607 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9608
cf13d699
NC
9609 saved_sym = NULL;
9610 return TRUE;
9611 }
9612 break;
9613 default:
9614 if (saved_sym != NULL)
9615 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9616 break;
9617 }
9618 break;
9619 }
252b5132
RH
9620 }
9621
cf13d699 9622 return FALSE;
252b5132
RH
9623}
9624
aca88567
NC
9625/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9626 DWARF debug sections. This is a target specific test. Note - we do not
9627 go through the whole including-target-headers-multiple-times route, (as
9628 we have already done with <elf/h8.h>) because this would become very
9629 messy and even then this function would have to contain target specific
9630 information (the names of the relocs instead of their numeric values).
9631 FIXME: This is not the correct way to solve this problem. The proper way
9632 is to have target specific reloc sizing and typing functions created by
9633 the reloc-macros.h header, in the same way that it already creates the
9634 reloc naming functions. */
9635
9636static bfd_boolean
9637is_32bit_abs_reloc (unsigned int reloc_type)
9638{
9639 switch (elf_header.e_machine)
9640 {
41e92641
NC
9641 case EM_386:
9642 case EM_486:
9643 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9644 case EM_68K:
9645 return reloc_type == 1; /* R_68K_32. */
9646 case EM_860:
9647 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9648 case EM_960:
9649 return reloc_type == 2; /* R_960_32. */
aca88567 9650 case EM_ALPHA:
137b6b5f 9651 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
9652 case EM_ARC:
9653 return reloc_type == 1; /* R_ARC_32. */
9654 case EM_ARM:
9655 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 9656 case EM_AVR_OLD:
aca88567
NC
9657 case EM_AVR:
9658 return reloc_type == 1;
9659 case EM_BLACKFIN:
9660 return reloc_type == 0x12; /* R_byte4_data. */
9661 case EM_CRIS:
9662 return reloc_type == 3; /* R_CRIS_32. */
9663 case EM_CR16:
6c03b1ed 9664 case EM_CR16_OLD:
aca88567
NC
9665 return reloc_type == 3; /* R_CR16_NUM32. */
9666 case EM_CRX:
9667 return reloc_type == 15; /* R_CRX_NUM32. */
9668 case EM_CYGNUS_FRV:
9669 return reloc_type == 1;
41e92641
NC
9670 case EM_CYGNUS_D10V:
9671 case EM_D10V:
9672 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
9673 case EM_CYGNUS_D30V:
9674 case EM_D30V:
9675 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
9676 case EM_DLX:
9677 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
9678 case EM_CYGNUS_FR30:
9679 case EM_FR30:
9680 return reloc_type == 3; /* R_FR30_32. */
9681 case EM_H8S:
9682 case EM_H8_300:
9683 case EM_H8_300H:
9684 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
9685 case EM_IA_64:
9686 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
9687 case EM_IP2K_OLD:
9688 case EM_IP2K:
9689 return reloc_type == 2; /* R_IP2K_32. */
9690 case EM_IQ2000:
9691 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
9692 case EM_LATTICEMICO32:
9693 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 9694 case EM_M32C_OLD:
aca88567
NC
9695 case EM_M32C:
9696 return reloc_type == 3; /* R_M32C_32. */
9697 case EM_M32R:
9698 return reloc_type == 34; /* R_M32R_32_RELA. */
9699 case EM_MCORE:
9700 return reloc_type == 1; /* R_MCORE_ADDR32. */
9701 case EM_CYGNUS_MEP:
9702 return reloc_type == 4; /* R_MEP_32. */
137b6b5f
AM
9703 case EM_MICROBLAZE:
9704 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
9705 case EM_MIPS:
9706 return reloc_type == 2; /* R_MIPS_32. */
9707 case EM_MMIX:
9708 return reloc_type == 4; /* R_MMIX_32. */
9709 case EM_CYGNUS_MN10200:
9710 case EM_MN10200:
9711 return reloc_type == 1; /* R_MN10200_32. */
9712 case EM_CYGNUS_MN10300:
9713 case EM_MN10300:
9714 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
9715 case EM_MOXIE:
9716 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
9717 case EM_MSP430_OLD:
9718 case EM_MSP430:
9719 return reloc_type == 1; /* R_MSP43_32. */
9720 case EM_MT:
9721 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
9722 case EM_ALTERA_NIOS2:
9723 case EM_NIOS32:
9724 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
9725 case EM_OPENRISC:
9726 case EM_OR32:
9727 return reloc_type == 1; /* R_OR32_32. */
aca88567 9728 case EM_PARISC:
5fda8eca
NC
9729 return (reloc_type == 1 /* R_PARISC_DIR32. */
9730 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
9731 case EM_PJ:
9732 case EM_PJ_OLD:
9733 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
9734 case EM_PPC64:
9735 return reloc_type == 1; /* R_PPC64_ADDR32. */
9736 case EM_PPC:
9737 return reloc_type == 1; /* R_PPC_ADDR32. */
c7927a3c
NC
9738 case EM_RX:
9739 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
9740 case EM_S370:
9741 return reloc_type == 1; /* R_I370_ADDR31. */
9742 case EM_S390_OLD:
9743 case EM_S390:
9744 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
9745 case EM_SCORE:
9746 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
9747 case EM_SH:
9748 return reloc_type == 1; /* R_SH_DIR32. */
9749 case EM_SPARC32PLUS:
9750 case EM_SPARCV9:
9751 case EM_SPARC:
9752 return reloc_type == 3 /* R_SPARC_32. */
9753 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
9754 case EM_SPU:
9755 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
9756 case EM_TI_C6000:
9757 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
9758 case EM_TILEGX:
9759 return reloc_type == 2; /* R_TILEGX_32. */
9760 case EM_TILEPRO:
9761 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
9762 case EM_CYGNUS_V850:
9763 case EM_V850:
9764 return reloc_type == 6; /* R_V850_ABS32. */
9765 case EM_VAX:
9766 return reloc_type == 1; /* R_VAX_32. */
9767 case EM_X86_64:
8a9036a4 9768 case EM_L1OM:
7a9068fe 9769 case EM_K1OM:
aca88567 9770 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
9771 case EM_XC16X:
9772 case EM_C166:
9773 return reloc_type == 3; /* R_XC16C_ABS_32. */
aca88567
NC
9774 case EM_XSTORMY16:
9775 return reloc_type == 1; /* R_XSTROMY16_32. */
9776 case EM_XTENSA_OLD:
9777 case EM_XTENSA:
9778 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
9779 default:
9780 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
9781 elf_header.e_machine);
9782 abort ();
9783 }
9784}
9785
9786/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9787 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
9788
9789static bfd_boolean
9790is_32bit_pcrel_reloc (unsigned int reloc_type)
9791{
9792 switch (elf_header.e_machine)
9793 {
41e92641
NC
9794 case EM_386:
9795 case EM_486:
3e0873ac 9796 return reloc_type == 2; /* R_386_PC32. */
aca88567 9797 case EM_68K:
3e0873ac 9798 return reloc_type == 4; /* R_68K_PC32. */
aca88567
NC
9799 case EM_ALPHA:
9800 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 9801 case EM_ARM:
3e0873ac 9802 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
9803 case EM_MICROBLAZE:
9804 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 9805 case EM_PARISC:
85acf597 9806 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
9807 case EM_PPC:
9808 return reloc_type == 26; /* R_PPC_REL32. */
9809 case EM_PPC64:
3e0873ac 9810 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
9811 case EM_S390_OLD:
9812 case EM_S390:
3e0873ac 9813 return reloc_type == 5; /* R_390_PC32. */
aca88567 9814 case EM_SH:
3e0873ac 9815 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
9816 case EM_SPARC32PLUS:
9817 case EM_SPARCV9:
9818 case EM_SPARC:
3e0873ac 9819 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
9820 case EM_SPU:
9821 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
9822 case EM_TILEGX:
9823 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
9824 case EM_TILEPRO:
9825 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 9826 case EM_X86_64:
8a9036a4 9827 case EM_L1OM:
7a9068fe 9828 case EM_K1OM:
3e0873ac 9829 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
9830 case EM_XTENSA_OLD:
9831 case EM_XTENSA:
9832 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
9833 default:
9834 /* Do not abort or issue an error message here. Not all targets use
9835 pc-relative 32-bit relocs in their DWARF debug information and we
9836 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
9837 more helpful warning message will be generated by apply_relocations
9838 anyway, so just return. */
aca88567
NC
9839 return FALSE;
9840 }
9841}
9842
9843/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9844 a 64-bit absolute RELA relocation used in DWARF debug sections. */
9845
9846static bfd_boolean
9847is_64bit_abs_reloc (unsigned int reloc_type)
9848{
9849 switch (elf_header.e_machine)
9850 {
9851 case EM_ALPHA:
9852 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
9853 case EM_IA_64:
9854 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
9855 case EM_PARISC:
9856 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
9857 case EM_PPC64:
9858 return reloc_type == 38; /* R_PPC64_ADDR64. */
9859 case EM_SPARC32PLUS:
9860 case EM_SPARCV9:
9861 case EM_SPARC:
9862 return reloc_type == 54; /* R_SPARC_UA64. */
9863 case EM_X86_64:
8a9036a4 9864 case EM_L1OM:
7a9068fe 9865 case EM_K1OM:
aca88567 9866 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
9867 case EM_S390_OLD:
9868 case EM_S390:
aa137e4d
NC
9869 return reloc_type == 22; /* R_S390_64. */
9870 case EM_TILEGX:
9871 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 9872 case EM_MIPS:
aa137e4d 9873 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
9874 default:
9875 return FALSE;
9876 }
9877}
9878
85acf597
RH
9879/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
9880 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
9881
9882static bfd_boolean
9883is_64bit_pcrel_reloc (unsigned int reloc_type)
9884{
9885 switch (elf_header.e_machine)
9886 {
9887 case EM_ALPHA:
aa137e4d 9888 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 9889 case EM_IA_64:
aa137e4d 9890 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 9891 case EM_PARISC:
aa137e4d 9892 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 9893 case EM_PPC64:
aa137e4d 9894 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
9895 case EM_SPARC32PLUS:
9896 case EM_SPARCV9:
9897 case EM_SPARC:
aa137e4d 9898 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 9899 case EM_X86_64:
8a9036a4 9900 case EM_L1OM:
7a9068fe 9901 case EM_K1OM:
aa137e4d 9902 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
9903 case EM_S390_OLD:
9904 case EM_S390:
aa137e4d
NC
9905 return reloc_type == 23; /* R_S390_PC64. */
9906 case EM_TILEGX:
9907 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
9908 default:
9909 return FALSE;
9910 }
9911}
9912
4dc3c23d
AM
9913/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9914 a 24-bit absolute RELA relocation used in DWARF debug sections. */
9915
9916static bfd_boolean
9917is_24bit_abs_reloc (unsigned int reloc_type)
9918{
9919 switch (elf_header.e_machine)
9920 {
9921 case EM_CYGNUS_MN10200:
9922 case EM_MN10200:
9923 return reloc_type == 4; /* R_MN10200_24. */
9924 default:
9925 return FALSE;
9926 }
9927}
9928
aca88567
NC
9929/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9930 a 16-bit absolute RELA relocation used in DWARF debug sections. */
9931
9932static bfd_boolean
9933is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
9934{
9935 switch (elf_header.e_machine)
9936 {
aca88567
NC
9937 case EM_AVR_OLD:
9938 case EM_AVR:
9939 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
9940 case EM_CYGNUS_D10V:
9941 case EM_D10V:
9942 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
9943 case EM_H8S:
9944 case EM_H8_300:
9945 case EM_H8_300H:
aca88567
NC
9946 return reloc_type == R_H8_DIR16;
9947 case EM_IP2K_OLD:
9948 case EM_IP2K:
9949 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 9950 case EM_M32C_OLD:
f4236fe4
DD
9951 case EM_M32C:
9952 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
9953 case EM_MSP430_OLD:
9954 case EM_MSP430:
9955 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
9956 case EM_ALTERA_NIOS2:
9957 case EM_NIOS32:
9958 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
9959 case EM_TI_C6000:
9960 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
9961 case EM_XC16X:
9962 case EM_C166:
9963 return reloc_type == 2; /* R_XC16C_ABS_16. */
4b78141a 9964 default:
aca88567 9965 return FALSE;
4b78141a
NC
9966 }
9967}
9968
2a7b2e88
JK
9969/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
9970 relocation entries (possibly formerly used for SHT_GROUP sections). */
9971
9972static bfd_boolean
9973is_none_reloc (unsigned int reloc_type)
9974{
9975 switch (elf_header.e_machine)
9976 {
cb8f3167
NC
9977 case EM_68K: /* R_68K_NONE. */
9978 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
9979 case EM_SPARC32PLUS:
9980 case EM_SPARCV9:
cb8f3167
NC
9981 case EM_SPARC: /* R_SPARC_NONE. */
9982 case EM_MIPS: /* R_MIPS_NONE. */
9983 case EM_PARISC: /* R_PARISC_NONE. */
9984 case EM_ALPHA: /* R_ALPHA_NONE. */
9985 case EM_PPC: /* R_PPC_NONE. */
9986 case EM_PPC64: /* R_PPC64_NONE. */
9987 case EM_ARM: /* R_ARM_NONE. */
9988 case EM_IA_64: /* R_IA64_NONE. */
9989 case EM_SH: /* R_SH_NONE. */
2a7b2e88 9990 case EM_S390_OLD:
cb8f3167
NC
9991 case EM_S390: /* R_390_NONE. */
9992 case EM_CRIS: /* R_CRIS_NONE. */
9993 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 9994 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 9995 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 9996 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 9997 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 9998 case EM_M32R: /* R_M32R_NONE. */
40b36596 9999 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10000 case EM_TILEGX: /* R_TILEGX_NONE. */
10001 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10002 case EM_XC16X:
10003 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 10004 return reloc_type == 0;
58332dda
JK
10005 case EM_XTENSA_OLD:
10006 case EM_XTENSA:
4dc3c23d
AM
10007 return (reloc_type == 0 /* R_XTENSA_NONE. */
10008 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10009 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10010 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
10011 }
10012 return FALSE;
10013}
10014
cf13d699
NC
10015/* Apply relocations to a section.
10016 Note: So far support has been added only for those relocations
10017 which can be found in debug sections.
10018 FIXME: Add support for more relocations ? */
1b315056 10019
cf13d699
NC
10020static void
10021apply_relocations (void * file,
10022 Elf_Internal_Shdr * section,
10023 unsigned char * start)
1b315056 10024{
cf13d699
NC
10025 Elf_Internal_Shdr * relsec;
10026 unsigned char * end = start + section->sh_size;
cb8f3167 10027
cf13d699
NC
10028 if (elf_header.e_type != ET_REL)
10029 return;
1b315056 10030
cf13d699 10031 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10032 for (relsec = section_headers;
10033 relsec < section_headers + elf_header.e_shnum;
10034 ++relsec)
252b5132 10035 {
41e92641
NC
10036 bfd_boolean is_rela;
10037 unsigned long num_relocs;
2cf0635d
NC
10038 Elf_Internal_Rela * relocs;
10039 Elf_Internal_Rela * rp;
10040 Elf_Internal_Shdr * symsec;
10041 Elf_Internal_Sym * symtab;
10042 Elf_Internal_Sym * sym;
252b5132 10043
41e92641 10044 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10045 || relsec->sh_info >= elf_header.e_shnum
10046 || section_headers + relsec->sh_info != section
c256ffe7 10047 || relsec->sh_size == 0
4fbb74a6 10048 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10049 continue;
428409d5 10050
41e92641
NC
10051 is_rela = relsec->sh_type == SHT_RELA;
10052
10053 if (is_rela)
10054 {
3f5e193b
NC
10055 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10056 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10057 return;
10058 }
10059 else
10060 {
3f5e193b
NC
10061 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10062 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10063 return;
10064 }
10065
10066 /* SH uses RELA but uses in place value instead of the addend field. */
10067 if (elf_header.e_machine == EM_SH)
10068 is_rela = FALSE;
428409d5 10069
4fbb74a6 10070 symsec = section_headers + relsec->sh_link;
3f5e193b 10071 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
103f02d3 10072
41e92641 10073 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10074 {
41e92641
NC
10075 bfd_vma addend;
10076 unsigned int reloc_type;
10077 unsigned int reloc_size;
91d6fa6a 10078 unsigned char * rloc;
4b78141a 10079
aca88567 10080 reloc_type = get_reloc_type (rp->r_info);
41e92641 10081
98fb390a 10082 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10083 continue;
98fb390a
NC
10084 else if (is_none_reloc (reloc_type))
10085 continue;
10086 else if (is_32bit_abs_reloc (reloc_type)
10087 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10088 reloc_size = 4;
85acf597
RH
10089 else if (is_64bit_abs_reloc (reloc_type)
10090 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10091 reloc_size = 8;
4dc3c23d
AM
10092 else if (is_24bit_abs_reloc (reloc_type))
10093 reloc_size = 3;
aca88567
NC
10094 else if (is_16bit_abs_reloc (reloc_type))
10095 reloc_size = 2;
10096 else
4b78141a 10097 {
41e92641 10098 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10099 reloc_type, SECTION_NAME (section));
4b78141a
NC
10100 continue;
10101 }
103f02d3 10102
91d6fa6a
NC
10103 rloc = start + rp->r_offset;
10104 if ((rloc + reloc_size) > end)
700dd8b7
L
10105 {
10106 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10107 (unsigned long) rp->r_offset,
10108 SECTION_NAME (section));
10109 continue;
10110 }
103f02d3 10111
41e92641
NC
10112 sym = symtab + get_reloc_symindex (rp->r_info);
10113
10114 /* If the reloc has a symbol associated with it,
55f25fc3
L
10115 make sure that it is of an appropriate type.
10116
10117 Relocations against symbols without type can happen.
10118 Gcc -feliminate-dwarf2-dups may generate symbols
10119 without type for debug info.
10120
10121 Icc generates relocations against function symbols
10122 instead of local labels.
10123
10124 Relocations against object symbols can happen, eg when
10125 referencing a global array. For an example of this see
10126 the _clz.o binary in libgcc.a. */
aca88567 10127 if (sym != symtab
55f25fc3 10128 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10129 {
41e92641 10130 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10131 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10132 (long int)(rp - relocs),
41e92641 10133 SECTION_NAME (relsec));
aca88567 10134 continue;
5b18a4bc 10135 }
252b5132 10136
4dc3c23d
AM
10137 addend = 0;
10138 if (is_rela)
10139 addend += rp->r_addend;
c47320c3
AM
10140 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10141 partial_inplace. */
4dc3c23d
AM
10142 if (!is_rela
10143 || (elf_header.e_machine == EM_XTENSA
10144 && reloc_type == 1)
10145 || ((elf_header.e_machine == EM_PJ
10146 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10147 && reloc_type == 1)
10148 || ((elf_header.e_machine == EM_D30V
10149 || elf_header.e_machine == EM_CYGNUS_D30V)
10150 && reloc_type == 12))
91d6fa6a 10151 addend += byte_get (rloc, reloc_size);
cb8f3167 10152
85acf597
RH
10153 if (is_32bit_pcrel_reloc (reloc_type)
10154 || is_64bit_pcrel_reloc (reloc_type))
10155 {
10156 /* On HPPA, all pc-relative relocations are biased by 8. */
10157 if (elf_header.e_machine == EM_PARISC)
10158 addend -= 8;
91d6fa6a 10159 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10160 reloc_size);
10161 }
41e92641 10162 else
91d6fa6a 10163 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10164 }
252b5132 10165
5b18a4bc 10166 free (symtab);
41e92641 10167 free (relocs);
5b18a4bc
NC
10168 break;
10169 }
5b18a4bc 10170}
103f02d3 10171
cf13d699
NC
10172#ifdef SUPPORT_DISASSEMBLY
10173static int
10174disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10175{
10176 printf (_("\nAssembly dump of section %s\n"),
10177 SECTION_NAME (section));
10178
10179 /* XXX -- to be done --- XXX */
10180
10181 return 1;
10182}
10183#endif
10184
10185/* Reads in the contents of SECTION from FILE, returning a pointer
10186 to a malloc'ed buffer or NULL if something went wrong. */
10187
10188static char *
10189get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10190{
10191 bfd_size_type num_bytes;
10192
10193 num_bytes = section->sh_size;
10194
10195 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10196 {
10197 printf (_("\nSection '%s' has no data to dump.\n"),
10198 SECTION_NAME (section));
10199 return NULL;
10200 }
10201
3f5e193b
NC
10202 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10203 _("section contents"));
cf13d699
NC
10204}
10205
dd24e3da 10206
cf13d699
NC
10207static void
10208dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10209{
10210 Elf_Internal_Shdr * relsec;
10211 bfd_size_type num_bytes;
cf13d699
NC
10212 char * data;
10213 char * end;
10214 char * start;
10215 char * name = SECTION_NAME (section);
10216 bfd_boolean some_strings_shown;
10217
10218 start = get_section_contents (section, file);
10219 if (start == NULL)
10220 return;
10221
10222 printf (_("\nString dump of section '%s':\n"), name);
10223
10224 /* If the section being dumped has relocations against it the user might
10225 be expecting these relocations to have been applied. Check for this
10226 case and issue a warning message in order to avoid confusion.
10227 FIXME: Maybe we ought to have an option that dumps a section with
10228 relocs applied ? */
10229 for (relsec = section_headers;
10230 relsec < section_headers + elf_header.e_shnum;
10231 ++relsec)
10232 {
10233 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10234 || relsec->sh_info >= elf_header.e_shnum
10235 || section_headers + relsec->sh_info != section
10236 || relsec->sh_size == 0
10237 || relsec->sh_link >= elf_header.e_shnum)
10238 continue;
10239
10240 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10241 break;
10242 }
10243
10244 num_bytes = section->sh_size;
cf13d699
NC
10245 data = start;
10246 end = start + num_bytes;
10247 some_strings_shown = FALSE;
10248
10249 while (data < end)
10250 {
10251 while (!ISPRINT (* data))
10252 if (++ data >= end)
10253 break;
10254
10255 if (data < end)
10256 {
10257#ifndef __MSVCRT__
c975cc98
NC
10258 /* PR 11128: Use two separate invocations in order to work
10259 around bugs in the Solaris 8 implementation of printf. */
10260 printf (" [%6tx] ", data - start);
10261 printf ("%s\n", data);
cf13d699
NC
10262#else
10263 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10264#endif
10265 data += strlen (data);
10266 some_strings_shown = TRUE;
10267 }
10268 }
10269
10270 if (! some_strings_shown)
10271 printf (_(" No strings found in this section."));
10272
10273 free (start);
10274
10275 putchar ('\n');
10276}
10277
10278static void
10279dump_section_as_bytes (Elf_Internal_Shdr * section,
10280 FILE * file,
10281 bfd_boolean relocate)
10282{
10283 Elf_Internal_Shdr * relsec;
10284 bfd_size_type bytes;
10285 bfd_vma addr;
10286 unsigned char * data;
10287 unsigned char * start;
10288
10289 start = (unsigned char *) get_section_contents (section, file);
10290 if (start == NULL)
10291 return;
10292
10293 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10294
10295 if (relocate)
10296 {
10297 apply_relocations (file, section, start);
10298 }
10299 else
10300 {
10301 /* If the section being dumped has relocations against it the user might
10302 be expecting these relocations to have been applied. Check for this
10303 case and issue a warning message in order to avoid confusion.
10304 FIXME: Maybe we ought to have an option that dumps a section with
10305 relocs applied ? */
10306 for (relsec = section_headers;
10307 relsec < section_headers + elf_header.e_shnum;
10308 ++relsec)
10309 {
10310 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10311 || relsec->sh_info >= elf_header.e_shnum
10312 || section_headers + relsec->sh_info != section
10313 || relsec->sh_size == 0
10314 || relsec->sh_link >= elf_header.e_shnum)
10315 continue;
10316
10317 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10318 break;
10319 }
10320 }
10321
10322 addr = section->sh_addr;
10323 bytes = section->sh_size;
10324 data = start;
10325
10326 while (bytes)
10327 {
10328 int j;
10329 int k;
10330 int lbytes;
10331
10332 lbytes = (bytes > 16 ? 16 : bytes);
10333
10334 printf (" 0x%8.8lx ", (unsigned long) addr);
10335
10336 for (j = 0; j < 16; j++)
10337 {
10338 if (j < lbytes)
10339 printf ("%2.2x", data[j]);
10340 else
10341 printf (" ");
10342
10343 if ((j & 3) == 3)
10344 printf (" ");
10345 }
10346
10347 for (j = 0; j < lbytes; j++)
10348 {
10349 k = data[j];
10350 if (k >= ' ' && k < 0x7f)
10351 printf ("%c", k);
10352 else
10353 printf (".");
10354 }
10355
10356 putchar ('\n');
10357
10358 data += lbytes;
10359 addr += lbytes;
10360 bytes -= lbytes;
10361 }
10362
10363 free (start);
10364
10365 putchar ('\n');
10366}
10367
4a114e3e 10368/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10369
10370static int
d3dbc530
AM
10371uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10372 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10373{
10374#ifndef HAVE_ZLIB_H
cf13d699
NC
10375 return FALSE;
10376#else
10377 dwarf_size_type compressed_size = *size;
10378 unsigned char * compressed_buffer = *buffer;
10379 dwarf_size_type uncompressed_size;
10380 unsigned char * uncompressed_buffer;
10381 z_stream strm;
10382 int rc;
10383 dwarf_size_type header_size = 12;
10384
10385 /* Read the zlib header. In this case, it should be "ZLIB" followed
10386 by the uncompressed section size, 8 bytes in big-endian order. */
10387 if (compressed_size < header_size
10388 || ! streq ((char *) compressed_buffer, "ZLIB"))
10389 return 0;
10390
10391 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10392 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10393 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10394 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10395 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10396 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10397 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10398 uncompressed_size += compressed_buffer[11];
10399
10400 /* It is possible the section consists of several compressed
10401 buffers concatenated together, so we uncompress in a loop. */
10402 strm.zalloc = NULL;
10403 strm.zfree = NULL;
10404 strm.opaque = NULL;
10405 strm.avail_in = compressed_size - header_size;
10406 strm.next_in = (Bytef *) compressed_buffer + header_size;
10407 strm.avail_out = uncompressed_size;
3f5e193b 10408 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10409
10410 rc = inflateInit (& strm);
10411 while (strm.avail_in > 0)
10412 {
10413 if (rc != Z_OK)
10414 goto fail;
10415 strm.next_out = ((Bytef *) uncompressed_buffer
10416 + (uncompressed_size - strm.avail_out));
10417 rc = inflate (&strm, Z_FINISH);
10418 if (rc != Z_STREAM_END)
10419 goto fail;
10420 rc = inflateReset (& strm);
10421 }
10422 rc = inflateEnd (& strm);
10423 if (rc != Z_OK
10424 || strm.avail_out != 0)
10425 goto fail;
10426
10427 free (compressed_buffer);
10428 *buffer = uncompressed_buffer;
10429 *size = uncompressed_size;
10430 return 1;
10431
10432 fail:
10433 free (uncompressed_buffer);
4a114e3e
L
10434 /* Indicate decompression failure. */
10435 *buffer = NULL;
cf13d699
NC
10436 return 0;
10437#endif /* HAVE_ZLIB_H */
10438}
10439
d966045b
DJ
10440static int
10441load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10442 Elf_Internal_Shdr * sec, void * file)
1007acb3 10443{
2cf0635d 10444 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10445 char buf [64];
1007acb3 10446
19e6b90e
L
10447 /* If it is already loaded, do nothing. */
10448 if (section->start != NULL)
10449 return 1;
1007acb3 10450
19e6b90e
L
10451 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10452 section->address = sec->sh_addr;
3f5e193b
NC
10453 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10454 sec->sh_offset, 1,
10455 sec->sh_size, buf);
59245841
NC
10456 if (section->start == NULL)
10457 section->size = 0;
10458 else
10459 {
10460 section->size = sec->sh_size;
10461 if (uncompress_section_contents (&section->start, &section->size))
10462 sec->sh_size = section->size;
10463 }
4a114e3e 10464
1b315056
CS
10465 if (section->start == NULL)
10466 return 0;
10467
19e6b90e 10468 if (debug_displays [debug].relocate)
3f5e193b 10469 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10470
1b315056 10471 return 1;
1007acb3
L
10472}
10473
d966045b 10474int
2cf0635d 10475load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10476{
2cf0635d
NC
10477 struct dwarf_section * section = &debug_displays [debug].section;
10478 Elf_Internal_Shdr * sec;
d966045b
DJ
10479
10480 /* Locate the debug section. */
10481 sec = find_section (section->uncompressed_name);
10482 if (sec != NULL)
10483 section->name = section->uncompressed_name;
10484 else
10485 {
10486 sec = find_section (section->compressed_name);
10487 if (sec != NULL)
10488 section->name = section->compressed_name;
10489 }
10490 if (sec == NULL)
10491 return 0;
10492
3f5e193b 10493 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10494}
10495
19e6b90e
L
10496void
10497free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10498{
2cf0635d 10499 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10500
19e6b90e
L
10501 if (section->start == NULL)
10502 return;
1007acb3 10503
19e6b90e
L
10504 free ((char *) section->start);
10505 section->start = NULL;
10506 section->address = 0;
10507 section->size = 0;
1007acb3
L
10508}
10509
1007acb3 10510static int
2cf0635d 10511display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 10512{
2cf0635d 10513 char * name = SECTION_NAME (section);
19e6b90e
L
10514 bfd_size_type length;
10515 int result = 1;
3f5e193b 10516 int i;
1007acb3 10517
19e6b90e
L
10518 length = section->sh_size;
10519 if (length == 0)
1007acb3 10520 {
19e6b90e
L
10521 printf (_("\nSection '%s' has no debugging data.\n"), name);
10522 return 0;
1007acb3 10523 }
5dff79d8
NC
10524 if (section->sh_type == SHT_NOBITS)
10525 {
10526 /* There is no point in dumping the contents of a debugging section
10527 which has the NOBITS type - the bits in the file will be random.
10528 This can happen when a file containing a .eh_frame section is
10529 stripped with the --only-keep-debug command line option. */
10530 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10531 return 0;
10532 }
1007acb3 10533
0112cd26 10534 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10535 name = ".debug_info";
1007acb3 10536
19e6b90e
L
10537 /* See if we know how to display the contents of this section. */
10538 for (i = 0; i < max; i++)
1b315056
CS
10539 if (streq (debug_displays[i].section.uncompressed_name, name)
10540 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10541 {
2cf0635d 10542 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10543 int secondary = (section != find_section (name));
10544
10545 if (secondary)
3f5e193b 10546 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10547
2b6f5997 10548 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10549 sec->name = sec->uncompressed_name;
10550 else
10551 sec->name = sec->compressed_name;
3f5e193b
NC
10552 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10553 section, file))
19e6b90e
L
10554 {
10555 result &= debug_displays[i].display (sec, file);
1007acb3 10556
d966045b 10557 if (secondary || (i != info && i != abbrev))
3f5e193b 10558 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10559 }
1007acb3 10560
19e6b90e
L
10561 break;
10562 }
1007acb3 10563
19e6b90e 10564 if (i == max)
1007acb3 10565 {
19e6b90e
L
10566 printf (_("Unrecognized debug section: %s\n"), name);
10567 result = 0;
1007acb3
L
10568 }
10569
19e6b90e 10570 return result;
5b18a4bc 10571}
103f02d3 10572
aef1f6d0
DJ
10573/* Set DUMP_SECTS for all sections where dumps were requested
10574 based on section name. */
10575
10576static void
10577initialise_dumps_byname (void)
10578{
2cf0635d 10579 struct dump_list_entry * cur;
aef1f6d0
DJ
10580
10581 for (cur = dump_sects_byname; cur; cur = cur->next)
10582 {
10583 unsigned int i;
10584 int any;
10585
10586 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10587 if (streq (SECTION_NAME (section_headers + i), cur->name))
10588 {
09c11c86 10589 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10590 any = 1;
10591 }
10592
10593 if (!any)
10594 warn (_("Section '%s' was not dumped because it does not exist!\n"),
10595 cur->name);
10596 }
10597}
10598
5b18a4bc 10599static void
2cf0635d 10600process_section_contents (FILE * file)
5b18a4bc 10601{
2cf0635d 10602 Elf_Internal_Shdr * section;
19e6b90e 10603 unsigned int i;
103f02d3 10604
19e6b90e
L
10605 if (! do_dump)
10606 return;
103f02d3 10607
aef1f6d0
DJ
10608 initialise_dumps_byname ();
10609
19e6b90e
L
10610 for (i = 0, section = section_headers;
10611 i < elf_header.e_shnum && i < num_dump_sects;
10612 i++, section++)
10613 {
10614#ifdef SUPPORT_DISASSEMBLY
10615 if (dump_sects[i] & DISASS_DUMP)
10616 disassemble_section (section, file);
10617#endif
10618 if (dump_sects[i] & HEX_DUMP)
cf13d699 10619 dump_section_as_bytes (section, file, FALSE);
103f02d3 10620
cf13d699
NC
10621 if (dump_sects[i] & RELOC_DUMP)
10622 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
10623
10624 if (dump_sects[i] & STRING_DUMP)
10625 dump_section_as_strings (section, file);
cf13d699
NC
10626
10627 if (dump_sects[i] & DEBUG_DUMP)
10628 display_debug_section (section, file);
5b18a4bc 10629 }
103f02d3 10630
19e6b90e
L
10631 /* Check to see if the user requested a
10632 dump of a section that does not exist. */
10633 while (i++ < num_dump_sects)
10634 if (dump_sects[i])
10635 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 10636}
103f02d3 10637
5b18a4bc 10638static void
19e6b90e 10639process_mips_fpe_exception (int mask)
5b18a4bc 10640{
19e6b90e
L
10641 if (mask)
10642 {
10643 int first = 1;
10644 if (mask & OEX_FPU_INEX)
10645 fputs ("INEX", stdout), first = 0;
10646 if (mask & OEX_FPU_UFLO)
10647 printf ("%sUFLO", first ? "" : "|"), first = 0;
10648 if (mask & OEX_FPU_OFLO)
10649 printf ("%sOFLO", first ? "" : "|"), first = 0;
10650 if (mask & OEX_FPU_DIV0)
10651 printf ("%sDIV0", first ? "" : "|"), first = 0;
10652 if (mask & OEX_FPU_INVAL)
10653 printf ("%sINVAL", first ? "" : "|");
10654 }
5b18a4bc 10655 else
19e6b90e 10656 fputs ("0", stdout);
5b18a4bc 10657}
103f02d3 10658
11c1ff18
PB
10659/* ARM EABI attributes section. */
10660typedef struct
10661{
10662 int tag;
2cf0635d 10663 const char * name;
11c1ff18
PB
10664 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
10665 int type;
2cf0635d 10666 const char ** table;
11c1ff18
PB
10667} arm_attr_public_tag;
10668
2cf0635d 10669static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 10670 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
9e3c6df6 10671 "v6K", "v7", "v6-M", "v6S-M", "v7E-M"};
2cf0635d
NC
10672static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
10673static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 10674 {"No", "Thumb-1", "Thumb-2"};
75375b3e 10675static const char * arm_attr_tag_FP_arch[] =
62f3b8c8 10676 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
2cf0635d 10677static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 10678static const char * arm_attr_tag_Advanced_SIMD_arch[] =
cd21e546 10679 {"No", "NEONv1", "NEONv1 with Fused-MAC"};
2cf0635d 10680static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
10681 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
10682 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 10683static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 10684 {"V6", "SB", "TLS", "Unused"};
2cf0635d 10685static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 10686 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 10687static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 10688 {"Absolute", "PC-relative", "None"};
2cf0635d 10689static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 10690 {"None", "direct", "GOT-indirect"};
2cf0635d 10691static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 10692 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
10693static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
10694static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 10695 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
10696static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
10697static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
10698static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 10699 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 10700static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 10701 {"Unused", "small", "int", "forced to int"};
2cf0635d 10702static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 10703 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 10704static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 10705 {"AAPCS", "VFP registers", "custom"};
2cf0635d 10706static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 10707 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 10708static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
10709 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10710 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 10711static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
10712 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10713 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 10714static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 10715static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 10716 {"Not Allowed", "Allowed"};
2cf0635d 10717static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 10718 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 10719static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
10720 {"Not Allowed", "Allowed"};
10721static const char * arm_attr_tag_DIV_use[] =
dd24e3da 10722 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 10723 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
10724static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
10725static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 10726 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 10727 "TrustZone and Virtualization Extensions"};
dd24e3da 10728static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 10729 {"Not Allowed", "Allowed"};
11c1ff18
PB
10730
10731#define LOOKUP(id, name) \
10732 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 10733static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
10734{
10735 {4, "CPU_raw_name", 1, NULL},
10736 {5, "CPU_name", 1, NULL},
10737 LOOKUP(6, CPU_arch),
10738 {7, "CPU_arch_profile", 0, NULL},
10739 LOOKUP(8, ARM_ISA_use),
10740 LOOKUP(9, THUMB_ISA_use),
75375b3e 10741 LOOKUP(10, FP_arch),
11c1ff18 10742 LOOKUP(11, WMMX_arch),
f5f53991
AS
10743 LOOKUP(12, Advanced_SIMD_arch),
10744 LOOKUP(13, PCS_config),
11c1ff18
PB
10745 LOOKUP(14, ABI_PCS_R9_use),
10746 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 10747 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
10748 LOOKUP(17, ABI_PCS_GOT_use),
10749 LOOKUP(18, ABI_PCS_wchar_t),
10750 LOOKUP(19, ABI_FP_rounding),
10751 LOOKUP(20, ABI_FP_denormal),
10752 LOOKUP(21, ABI_FP_exceptions),
10753 LOOKUP(22, ABI_FP_user_exceptions),
10754 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
10755 {24, "ABI_align_needed", 0, NULL},
10756 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
10757 LOOKUP(26, ABI_enum_size),
10758 LOOKUP(27, ABI_HardFP_use),
10759 LOOKUP(28, ABI_VFP_args),
10760 LOOKUP(29, ABI_WMMX_args),
10761 LOOKUP(30, ABI_optimization_goals),
10762 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 10763 {32, "compatibility", 0, NULL},
f5f53991 10764 LOOKUP(34, CPU_unaligned_access),
75375b3e 10765 LOOKUP(36, FP_HP_extension),
8e79c3df 10766 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
10767 LOOKUP(42, MPextension_use),
10768 LOOKUP(44, DIV_use),
f5f53991
AS
10769 {64, "nodefaults", 0, NULL},
10770 {65, "also_compatible_with", 0, NULL},
10771 LOOKUP(66, T2EE_use),
10772 {67, "conformance", 1, NULL},
10773 LOOKUP(68, Virtualization_use),
cd21e546 10774 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
10775};
10776#undef LOOKUP
10777
11c1ff18 10778static unsigned char *
2cf0635d 10779display_arm_attribute (unsigned char * p)
11c1ff18
PB
10780{
10781 int tag;
10782 unsigned int len;
10783 int val;
2cf0635d 10784 arm_attr_public_tag * attr;
11c1ff18
PB
10785 unsigned i;
10786 int type;
10787
10788 tag = read_uleb128 (p, &len);
10789 p += len;
10790 attr = NULL;
2cf0635d 10791 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
10792 {
10793 if (arm_attr_public_tags[i].tag == tag)
10794 {
10795 attr = &arm_attr_public_tags[i];
10796 break;
10797 }
10798 }
10799
10800 if (attr)
10801 {
10802 printf (" Tag_%s: ", attr->name);
10803 switch (attr->type)
10804 {
10805 case 0:
10806 switch (tag)
10807 {
10808 case 7: /* Tag_CPU_arch_profile. */
10809 val = read_uleb128 (p, &len);
10810 p += len;
10811 switch (val)
10812 {
2b692964
NC
10813 case 0: printf (_("None\n")); break;
10814 case 'A': printf (_("Application\n")); break;
10815 case 'R': printf (_("Realtime\n")); break;
10816 case 'M': printf (_("Microcontroller\n")); break;
10817 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
10818 default: printf ("??? (%d)\n", val); break;
10819 }
10820 break;
10821
75375b3e
MGD
10822 case 24: /* Tag_align_needed. */
10823 val = read_uleb128 (p, &len);
10824 p += len;
10825 switch (val)
10826 {
2b692964
NC
10827 case 0: printf (_("None\n")); break;
10828 case 1: printf (_("8-byte\n")); break;
10829 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
10830 case 3: printf ("??? 3\n"); break;
10831 default:
10832 if (val <= 12)
dd24e3da 10833 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10834 1 << val);
10835 else
10836 printf ("??? (%d)\n", val);
10837 break;
10838 }
10839 break;
10840
10841 case 25: /* Tag_align_preserved. */
10842 val = read_uleb128 (p, &len);
10843 p += len;
10844 switch (val)
10845 {
2b692964
NC
10846 case 0: printf (_("None\n")); break;
10847 case 1: printf (_("8-byte, except leaf SP\n")); break;
10848 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
10849 case 3: printf ("??? 3\n"); break;
10850 default:
10851 if (val <= 12)
dd24e3da 10852 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10853 1 << val);
10854 else
10855 printf ("??? (%d)\n", val);
10856 break;
10857 }
10858 break;
10859
11c1ff18
PB
10860 case 32: /* Tag_compatibility. */
10861 val = read_uleb128 (p, &len);
10862 p += len;
2b692964 10863 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 10864 p += strlen ((char *) p) + 1;
11c1ff18
PB
10865 break;
10866
f5f53991
AS
10867 case 64: /* Tag_nodefaults. */
10868 p++;
2b692964 10869 printf (_("True\n"));
f5f53991
AS
10870 break;
10871
10872 case 65: /* Tag_also_compatible_with. */
10873 val = read_uleb128 (p, &len);
10874 p += len;
10875 if (val == 6 /* Tag_CPU_arch. */)
10876 {
10877 val = read_uleb128 (p, &len);
10878 p += len;
2cf0635d 10879 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
10880 printf ("??? (%d)\n", val);
10881 else
10882 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
10883 }
10884 else
10885 printf ("???\n");
10886 while (*(p++) != '\0' /* NUL terminator. */);
10887 break;
10888
11c1ff18 10889 default:
2cf0635d 10890 abort ();
11c1ff18
PB
10891 }
10892 return p;
10893
10894 case 1:
10895 case 2:
10896 type = attr->type;
10897 break;
10898
10899 default:
10900 assert (attr->type & 0x80);
10901 val = read_uleb128 (p, &len);
10902 p += len;
10903 type = attr->type & 0x7f;
10904 if (val >= type)
10905 printf ("??? (%d)\n", val);
10906 else
10907 printf ("%s\n", attr->table[val]);
10908 return p;
10909 }
10910 }
10911 else
10912 {
10913 if (tag & 1)
10914 type = 1; /* String. */
10915 else
10916 type = 2; /* uleb128. */
10917 printf (" Tag_unknown_%d: ", tag);
10918 }
10919
10920 if (type == 1)
10921 {
10922 printf ("\"%s\"\n", p);
2cf0635d 10923 p += strlen ((char *) p) + 1;
11c1ff18
PB
10924 }
10925 else
10926 {
10927 val = read_uleb128 (p, &len);
10928 p += len;
10929 printf ("%d (0x%x)\n", val, val);
10930 }
10931
10932 return p;
10933}
10934
104d59d1 10935static unsigned char *
60bca95a
NC
10936display_gnu_attribute (unsigned char * p,
10937 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
10938{
10939 int tag;
10940 unsigned int len;
10941 int val;
10942 int type;
10943
10944 tag = read_uleb128 (p, &len);
10945 p += len;
10946
10947 /* Tag_compatibility is the only generic GNU attribute defined at
10948 present. */
10949 if (tag == 32)
10950 {
10951 val = read_uleb128 (p, &len);
10952 p += len;
2b692964 10953 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 10954 p += strlen ((char *) p) + 1;
104d59d1
JM
10955 return p;
10956 }
10957
10958 if ((tag & 2) == 0 && display_proc_gnu_attribute)
10959 return display_proc_gnu_attribute (p, tag);
10960
10961 if (tag & 1)
10962 type = 1; /* String. */
10963 else
10964 type = 2; /* uleb128. */
10965 printf (" Tag_unknown_%d: ", tag);
10966
10967 if (type == 1)
10968 {
10969 printf ("\"%s\"\n", p);
60bca95a 10970 p += strlen ((char *) p) + 1;
104d59d1
JM
10971 }
10972 else
10973 {
10974 val = read_uleb128 (p, &len);
10975 p += len;
10976 printf ("%d (0x%x)\n", val, val);
10977 }
10978
10979 return p;
10980}
10981
34c8bcba 10982static unsigned char *
2cf0635d 10983display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
10984{
10985 int type;
10986 unsigned int len;
10987 int val;
10988
10989 if (tag == Tag_GNU_Power_ABI_FP)
10990 {
10991 val = read_uleb128 (p, &len);
10992 p += len;
10993 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 10994
34c8bcba
JM
10995 switch (val)
10996 {
10997 case 0:
2b692964 10998 printf (_("Hard or soft float\n"));
34c8bcba
JM
10999 break;
11000 case 1:
2b692964 11001 printf (_("Hard float\n"));
34c8bcba
JM
11002 break;
11003 case 2:
2b692964 11004 printf (_("Soft float\n"));
34c8bcba 11005 break;
3c7b9897 11006 case 3:
2b692964 11007 printf (_("Single-precision hard float\n"));
3c7b9897 11008 break;
34c8bcba
JM
11009 default:
11010 printf ("??? (%d)\n", val);
11011 break;
11012 }
11013 return p;
11014 }
11015
c6e65352
DJ
11016 if (tag == Tag_GNU_Power_ABI_Vector)
11017 {
11018 val = read_uleb128 (p, &len);
11019 p += len;
11020 printf (" Tag_GNU_Power_ABI_Vector: ");
11021 switch (val)
11022 {
11023 case 0:
2b692964 11024 printf (_("Any\n"));
c6e65352
DJ
11025 break;
11026 case 1:
2b692964 11027 printf (_("Generic\n"));
c6e65352
DJ
11028 break;
11029 case 2:
11030 printf ("AltiVec\n");
11031 break;
11032 case 3:
11033 printf ("SPE\n");
11034 break;
11035 default:
11036 printf ("??? (%d)\n", val);
11037 break;
11038 }
11039 return p;
11040 }
11041
f82e0623
NF
11042 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11043 {
11044 val = read_uleb128 (p, &len);
11045 p += len;
11046 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11047 switch (val)
11048 {
11049 case 0:
2b692964 11050 printf (_("Any\n"));
f82e0623
NF
11051 break;
11052 case 1:
11053 printf ("r3/r4\n");
11054 break;
11055 case 2:
2b692964 11056 printf (_("Memory\n"));
f82e0623
NF
11057 break;
11058 default:
11059 printf ("??? (%d)\n", val);
11060 break;
11061 }
11062 return p;
11063 }
11064
34c8bcba
JM
11065 if (tag & 1)
11066 type = 1; /* String. */
11067 else
11068 type = 2; /* uleb128. */
11069 printf (" Tag_unknown_%d: ", tag);
11070
11071 if (type == 1)
11072 {
11073 printf ("\"%s\"\n", p);
60bca95a 11074 p += strlen ((char *) p) + 1;
34c8bcba
JM
11075 }
11076 else
11077 {
11078 val = read_uleb128 (p, &len);
11079 p += len;
11080 printf ("%d (0x%x)\n", val, val);
11081 }
11082
11083 return p;
11084}
11085
2cf19d5c 11086static unsigned char *
2cf0635d 11087display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
11088{
11089 int type;
11090 unsigned int len;
11091 int val;
11092
11093 if (tag == Tag_GNU_MIPS_ABI_FP)
11094 {
11095 val = read_uleb128 (p, &len);
11096 p += len;
11097 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11098
2cf19d5c
JM
11099 switch (val)
11100 {
11101 case 0:
2b692964 11102 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11103 break;
11104 case 1:
2b692964 11105 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11106 break;
11107 case 2:
2b692964 11108 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11109 break;
11110 case 3:
2b692964 11111 printf (_("Soft float\n"));
2cf19d5c 11112 break;
42554f6a 11113 case 4:
9eeefea8 11114 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11115 break;
2cf19d5c
JM
11116 default:
11117 printf ("??? (%d)\n", val);
11118 break;
11119 }
11120 return p;
11121 }
11122
11123 if (tag & 1)
11124 type = 1; /* String. */
11125 else
11126 type = 2; /* uleb128. */
11127 printf (" Tag_unknown_%d: ", tag);
11128
11129 if (type == 1)
11130 {
11131 printf ("\"%s\"\n", p);
60bca95a 11132 p += strlen ((char *) p) + 1;
2cf19d5c
JM
11133 }
11134 else
11135 {
11136 val = read_uleb128 (p, &len);
11137 p += len;
11138 printf ("%d (0x%x)\n", val, val);
11139 }
11140
11141 return p;
11142}
11143
59e6276b
JM
11144static unsigned char *
11145display_tic6x_attribute (unsigned char * p)
11146{
11147 int tag;
11148 unsigned int len;
11149 int val;
11150
11151 tag = read_uleb128 (p, &len);
11152 p += len;
11153
11154 switch (tag)
11155 {
75fa6dc1 11156 case Tag_ISA:
59e6276b
JM
11157 val = read_uleb128 (p, &len);
11158 p += len;
75fa6dc1 11159 printf (" Tag_ISA: ");
59e6276b
JM
11160
11161 switch (val)
11162 {
75fa6dc1 11163 case C6XABI_Tag_ISA_none:
59e6276b
JM
11164 printf (_("None\n"));
11165 break;
75fa6dc1 11166 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11167 printf ("C62x\n");
11168 break;
75fa6dc1 11169 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11170 printf ("C67x\n");
11171 break;
75fa6dc1 11172 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11173 printf ("C67x+\n");
11174 break;
75fa6dc1 11175 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11176 printf ("C64x\n");
11177 break;
75fa6dc1 11178 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11179 printf ("C64x+\n");
11180 break;
75fa6dc1 11181 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11182 printf ("C674x\n");
11183 break;
11184 default:
11185 printf ("??? (%d)\n", val);
11186 break;
11187 }
11188 return p;
11189
87779176
JM
11190 case Tag_ABI_wchar_t:
11191 val = read_uleb128 (p, &len);
11192 p += len;
11193 printf (" Tag_ABI_wchar_t: ");
11194 switch (val)
11195 {
11196 case 0:
11197 printf (_("Not used\n"));
11198 break;
11199 case 1:
11200 printf (_("2 bytes\n"));
11201 break;
11202 case 2:
11203 printf (_("4 bytes\n"));
11204 break;
11205 default:
11206 printf ("??? (%d)\n", val);
11207 break;
11208 }
11209 return p;
11210
11211 case Tag_ABI_stack_align_needed:
11212 val = read_uleb128 (p, &len);
11213 p += len;
11214 printf (" Tag_ABI_stack_align_needed: ");
11215 switch (val)
11216 {
11217 case 0:
11218 printf (_("8-byte\n"));
11219 break;
11220 case 1:
11221 printf (_("16-byte\n"));
11222 break;
11223 default:
11224 printf ("??? (%d)\n", val);
11225 break;
11226 }
11227 return p;
11228
11229 case Tag_ABI_stack_align_preserved:
11230 val = read_uleb128 (p, &len);
11231 p += len;
11232 printf (" Tag_ABI_stack_align_preserved: ");
11233 switch (val)
11234 {
11235 case 0:
11236 printf (_("8-byte\n"));
11237 break;
11238 case 1:
11239 printf (_("16-byte\n"));
11240 break;
11241 default:
11242 printf ("??? (%d)\n", val);
11243 break;
11244 }
11245 return p;
11246
b5593623
JM
11247 case Tag_ABI_DSBT:
11248 val = read_uleb128 (p, &len);
11249 p += len;
11250 printf (" Tag_ABI_DSBT: ");
11251 switch (val)
11252 {
11253 case 0:
11254 printf (_("DSBT addressing not used\n"));
11255 break;
11256 case 1:
11257 printf (_("DSBT addressing used\n"));
11258 break;
11259 default:
11260 printf ("??? (%d)\n", val);
11261 break;
11262 }
11263 return p;
11264
87779176
JM
11265 case Tag_ABI_PID:
11266 val = read_uleb128 (p, &len);
11267 p += len;
11268 printf (" Tag_ABI_PID: ");
11269 switch (val)
11270 {
11271 case 0:
11272 printf (_("Data addressing position-dependent\n"));
11273 break;
11274 case 1:
11275 printf (_("Data addressing position-independent, GOT near DP\n"));
11276 break;
11277 case 2:
11278 printf (_("Data addressing position-independent, GOT far from DP\n"));
11279 break;
11280 default:
11281 printf ("??? (%d)\n", val);
11282 break;
11283 }
11284 return p;
11285
11286 case Tag_ABI_PIC:
11287 val = read_uleb128 (p, &len);
11288 p += len;
11289 printf (" Tag_ABI_PIC: ");
11290 switch (val)
11291 {
11292 case 0:
11293 printf (_("Code addressing position-dependent\n"));
11294 break;
11295 case 1:
11296 printf (_("Code addressing position-independent\n"));
11297 break;
11298 default:
11299 printf ("??? (%d)\n", val);
11300 break;
11301 }
11302 return p;
11303
11304 case Tag_ABI_array_object_alignment:
11305 val = read_uleb128 (p, &len);
11306 p += len;
11307 printf (" Tag_ABI_array_object_alignment: ");
11308 switch (val)
11309 {
11310 case 0:
11311 printf (_("8-byte\n"));
11312 break;
11313 case 1:
11314 printf (_("4-byte\n"));
11315 break;
11316 case 2:
11317 printf (_("16-byte\n"));
11318 break;
11319 default:
11320 printf ("??? (%d)\n", val);
11321 break;
11322 }
11323 return p;
11324
11325 case Tag_ABI_array_object_align_expected:
11326 val = read_uleb128 (p, &len);
11327 p += len;
11328 printf (" Tag_ABI_array_object_align_expected: ");
11329 switch (val)
11330 {
11331 case 0:
11332 printf (_("8-byte\n"));
11333 break;
11334 case 1:
11335 printf (_("4-byte\n"));
11336 break;
11337 case 2:
11338 printf (_("16-byte\n"));
11339 break;
11340 default:
11341 printf ("??? (%d)\n", val);
11342 break;
11343 }
11344 return p;
11345
3cbd1c06 11346 case Tag_ABI_compatibility:
59e6276b
JM
11347 val = read_uleb128 (p, &len);
11348 p += len;
3cbd1c06 11349 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11350 printf (_("flag = %d, vendor = %s\n"), val, p);
11351 p += strlen ((char *) p) + 1;
11352 return p;
87779176
JM
11353
11354 case Tag_ABI_conformance:
11355 printf (" Tag_ABI_conformance: ");
11356 printf ("\"%s\"\n", p);
11357 p += strlen ((char *) p) + 1;
11358 return p;
59e6276b
JM
11359 }
11360
11361 printf (" Tag_unknown_%d: ", tag);
11362
87779176
JM
11363 if (tag & 1)
11364 {
11365 printf ("\"%s\"\n", p);
11366 p += strlen ((char *) p) + 1;
11367 }
11368 else
11369 {
11370 val = read_uleb128 (p, &len);
11371 p += len;
11372 printf ("%d (0x%x)\n", val, val);
11373 }
59e6276b
JM
11374
11375 return p;
11376}
11377
11c1ff18 11378static int
60bca95a
NC
11379process_attributes (FILE * file,
11380 const char * public_name,
104d59d1 11381 unsigned int proc_type,
60bca95a
NC
11382 unsigned char * (* display_pub_attribute) (unsigned char *),
11383 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11384{
2cf0635d
NC
11385 Elf_Internal_Shdr * sect;
11386 unsigned char * contents;
11387 unsigned char * p;
11388 unsigned char * end;
11c1ff18
PB
11389 bfd_vma section_len;
11390 bfd_vma len;
11391 unsigned i;
11392
11393 /* Find the section header so that we get the size. */
11394 for (i = 0, sect = section_headers;
11395 i < elf_header.e_shnum;
11396 i++, sect++)
11397 {
104d59d1 11398 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11399 continue;
11400
3f5e193b
NC
11401 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11402 sect->sh_size, _("attributes"));
60bca95a 11403 if (contents == NULL)
11c1ff18 11404 continue;
60bca95a 11405
11c1ff18
PB
11406 p = contents;
11407 if (*p == 'A')
11408 {
11409 len = sect->sh_size - 1;
11410 p++;
60bca95a 11411
11c1ff18
PB
11412 while (len > 0)
11413 {
11414 int namelen;
11415 bfd_boolean public_section;
104d59d1 11416 bfd_boolean gnu_section;
11c1ff18
PB
11417
11418 section_len = byte_get (p, 4);
11419 p += 4;
60bca95a 11420
11c1ff18
PB
11421 if (section_len > len)
11422 {
11423 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11424 (int) section_len, (int) len);
11c1ff18
PB
11425 section_len = len;
11426 }
60bca95a 11427
11c1ff18 11428 len -= section_len;
2b692964 11429 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11430
11431 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11432 public_section = TRUE;
11433 else
11434 public_section = FALSE;
60bca95a
NC
11435
11436 if (streq ((char *) p, "gnu"))
104d59d1
JM
11437 gnu_section = TRUE;
11438 else
11439 gnu_section = FALSE;
60bca95a
NC
11440
11441 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11442 p += namelen;
11443 section_len -= namelen + 4;
60bca95a 11444
11c1ff18
PB
11445 while (section_len > 0)
11446 {
11447 int tag = *(p++);
11448 int val;
11449 bfd_vma size;
60bca95a 11450
11c1ff18
PB
11451 size = byte_get (p, 4);
11452 if (size > section_len)
11453 {
11454 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11455 (int) size, (int) section_len);
11c1ff18
PB
11456 size = section_len;
11457 }
60bca95a 11458
11c1ff18
PB
11459 section_len -= size;
11460 end = p + size - 1;
11461 p += 4;
60bca95a 11462
11c1ff18
PB
11463 switch (tag)
11464 {
11465 case 1:
2b692964 11466 printf (_("File Attributes\n"));
11c1ff18
PB
11467 break;
11468 case 2:
2b692964 11469 printf (_("Section Attributes:"));
11c1ff18
PB
11470 goto do_numlist;
11471 case 3:
2b692964 11472 printf (_("Symbol Attributes:"));
11c1ff18
PB
11473 do_numlist:
11474 for (;;)
11475 {
91d6fa6a 11476 unsigned int j;
60bca95a 11477
91d6fa6a
NC
11478 val = read_uleb128 (p, &j);
11479 p += j;
11c1ff18
PB
11480 if (val == 0)
11481 break;
11482 printf (" %d", val);
11483 }
11484 printf ("\n");
11485 break;
11486 default:
2b692964 11487 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
11488 public_section = FALSE;
11489 break;
11490 }
60bca95a 11491
11c1ff18
PB
11492 if (public_section)
11493 {
11494 while (p < end)
104d59d1
JM
11495 p = display_pub_attribute (p);
11496 }
11497 else if (gnu_section)
11498 {
11499 while (p < end)
11500 p = display_gnu_attribute (p,
11501 display_proc_gnu_attribute);
11c1ff18
PB
11502 }
11503 else
11504 {
11505 /* ??? Do something sensible, like dump hex. */
2b692964 11506 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
11507 p = end;
11508 }
11509 }
11510 }
11511 }
11512 else
60bca95a 11513 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 11514
60bca95a 11515 free (contents);
11c1ff18
PB
11516 }
11517 return 1;
11518}
11519
104d59d1 11520static int
2cf0635d 11521process_arm_specific (FILE * file)
104d59d1
JM
11522{
11523 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
11524 display_arm_attribute, NULL);
11525}
11526
34c8bcba 11527static int
2cf0635d 11528process_power_specific (FILE * file)
34c8bcba
JM
11529{
11530 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11531 display_power_gnu_attribute);
11532}
11533
59e6276b
JM
11534static int
11535process_tic6x_specific (FILE * file)
11536{
11537 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
11538 display_tic6x_attribute, NULL);
11539}
11540
ccb4c951
RS
11541/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
11542 Print the Address, Access and Initial fields of an entry at VMA ADDR
11543 and return the VMA of the next entry. */
11544
11545static bfd_vma
2cf0635d 11546print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
11547{
11548 printf (" ");
11549 print_vma (addr, LONG_HEX);
11550 printf (" ");
11551 if (addr < pltgot + 0xfff0)
11552 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
11553 else
11554 printf ("%10s", "");
11555 printf (" ");
11556 if (data == NULL)
2b692964 11557 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
11558 else
11559 {
11560 bfd_vma entry;
11561
11562 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11563 print_vma (entry, LONG_HEX);
11564 }
11565 return addr + (is_32bit_elf ? 4 : 8);
11566}
11567
861fb55a
DJ
11568/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
11569 PLTGOT. Print the Address and Initial fields of an entry at VMA
11570 ADDR and return the VMA of the next entry. */
11571
11572static bfd_vma
2cf0635d 11573print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
11574{
11575 printf (" ");
11576 print_vma (addr, LONG_HEX);
11577 printf (" ");
11578 if (data == NULL)
2b692964 11579 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
11580 else
11581 {
11582 bfd_vma entry;
11583
11584 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11585 print_vma (entry, LONG_HEX);
11586 }
11587 return addr + (is_32bit_elf ? 4 : 8);
11588}
11589
19e6b90e 11590static int
2cf0635d 11591process_mips_specific (FILE * file)
5b18a4bc 11592{
2cf0635d 11593 Elf_Internal_Dyn * entry;
19e6b90e
L
11594 size_t liblist_offset = 0;
11595 size_t liblistno = 0;
11596 size_t conflictsno = 0;
11597 size_t options_offset = 0;
11598 size_t conflicts_offset = 0;
861fb55a
DJ
11599 size_t pltrelsz = 0;
11600 size_t pltrel = 0;
ccb4c951 11601 bfd_vma pltgot = 0;
861fb55a
DJ
11602 bfd_vma mips_pltgot = 0;
11603 bfd_vma jmprel = 0;
ccb4c951
RS
11604 bfd_vma local_gotno = 0;
11605 bfd_vma gotsym = 0;
11606 bfd_vma symtabno = 0;
103f02d3 11607
2cf19d5c
JM
11608 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11609 display_mips_gnu_attribute);
11610
19e6b90e
L
11611 /* We have a lot of special sections. Thanks SGI! */
11612 if (dynamic_section == NULL)
11613 /* No information available. */
11614 return 0;
252b5132 11615
b2d38a17 11616 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
11617 switch (entry->d_tag)
11618 {
11619 case DT_MIPS_LIBLIST:
d93f0186
NC
11620 liblist_offset
11621 = offset_from_vma (file, entry->d_un.d_val,
11622 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
11623 break;
11624 case DT_MIPS_LIBLISTNO:
11625 liblistno = entry->d_un.d_val;
11626 break;
11627 case DT_MIPS_OPTIONS:
d93f0186 11628 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
11629 break;
11630 case DT_MIPS_CONFLICT:
d93f0186
NC
11631 conflicts_offset
11632 = offset_from_vma (file, entry->d_un.d_val,
11633 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
11634 break;
11635 case DT_MIPS_CONFLICTNO:
11636 conflictsno = entry->d_un.d_val;
11637 break;
ccb4c951 11638 case DT_PLTGOT:
861fb55a
DJ
11639 pltgot = entry->d_un.d_ptr;
11640 break;
ccb4c951
RS
11641 case DT_MIPS_LOCAL_GOTNO:
11642 local_gotno = entry->d_un.d_val;
11643 break;
11644 case DT_MIPS_GOTSYM:
11645 gotsym = entry->d_un.d_val;
11646 break;
11647 case DT_MIPS_SYMTABNO:
11648 symtabno = entry->d_un.d_val;
11649 break;
861fb55a
DJ
11650 case DT_MIPS_PLTGOT:
11651 mips_pltgot = entry->d_un.d_ptr;
11652 break;
11653 case DT_PLTREL:
11654 pltrel = entry->d_un.d_val;
11655 break;
11656 case DT_PLTRELSZ:
11657 pltrelsz = entry->d_un.d_val;
11658 break;
11659 case DT_JMPREL:
11660 jmprel = entry->d_un.d_ptr;
11661 break;
252b5132
RH
11662 default:
11663 break;
11664 }
11665
11666 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
11667 {
2cf0635d 11668 Elf32_External_Lib * elib;
252b5132
RH
11669 size_t cnt;
11670
3f5e193b
NC
11671 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
11672 liblistno,
11673 sizeof (Elf32_External_Lib),
11674 _("liblist"));
a6e9f9df 11675 if (elib)
252b5132 11676 {
2b692964 11677 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 11678 (unsigned long) liblistno);
2b692964 11679 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
11680 stdout);
11681
11682 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 11683 {
a6e9f9df 11684 Elf32_Lib liblist;
91d6fa6a 11685 time_t atime;
a6e9f9df 11686 char timebuf[20];
2cf0635d 11687 struct tm * tmp;
a6e9f9df
AM
11688
11689 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 11690 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
11691 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11692 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11693 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11694
91d6fa6a 11695 tmp = gmtime (&atime);
e9e44622
JJ
11696 snprintf (timebuf, sizeof (timebuf),
11697 "%04u-%02u-%02uT%02u:%02u:%02u",
11698 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11699 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 11700
31104126 11701 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
11702 if (VALID_DYNAMIC_NAME (liblist.l_name))
11703 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
11704 else
2b692964 11705 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
11706 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
11707 liblist.l_version);
a6e9f9df
AM
11708
11709 if (liblist.l_flags == 0)
2b692964 11710 puts (_(" NONE"));
a6e9f9df
AM
11711 else
11712 {
11713 static const struct
252b5132 11714 {
2cf0635d 11715 const char * name;
a6e9f9df 11716 int bit;
252b5132 11717 }
a6e9f9df
AM
11718 l_flags_vals[] =
11719 {
11720 { " EXACT_MATCH", LL_EXACT_MATCH },
11721 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
11722 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
11723 { " EXPORTS", LL_EXPORTS },
11724 { " DELAY_LOAD", LL_DELAY_LOAD },
11725 { " DELTA", LL_DELTA }
11726 };
11727 int flags = liblist.l_flags;
11728 size_t fcnt;
11729
60bca95a 11730 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
11731 if ((flags & l_flags_vals[fcnt].bit) != 0)
11732 {
11733 fputs (l_flags_vals[fcnt].name, stdout);
11734 flags ^= l_flags_vals[fcnt].bit;
11735 }
11736 if (flags != 0)
11737 printf (" %#x", (unsigned int) flags);
252b5132 11738
a6e9f9df
AM
11739 puts ("");
11740 }
252b5132 11741 }
252b5132 11742
a6e9f9df
AM
11743 free (elib);
11744 }
252b5132
RH
11745 }
11746
11747 if (options_offset != 0)
11748 {
2cf0635d
NC
11749 Elf_External_Options * eopt;
11750 Elf_Internal_Shdr * sect = section_headers;
11751 Elf_Internal_Options * iopt;
11752 Elf_Internal_Options * option;
252b5132
RH
11753 size_t offset;
11754 int cnt;
11755
11756 /* Find the section header so that we get the size. */
11757 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 11758 ++sect;
252b5132 11759
3f5e193b
NC
11760 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
11761 sect->sh_size, _("options"));
a6e9f9df 11762 if (eopt)
252b5132 11763 {
3f5e193b
NC
11764 iopt = (Elf_Internal_Options *)
11765 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
11766 if (iopt == NULL)
11767 {
591a748a 11768 error (_("Out of memory\n"));
a6e9f9df
AM
11769 return 0;
11770 }
76da6bbe 11771
a6e9f9df
AM
11772 offset = cnt = 0;
11773 option = iopt;
252b5132 11774
a6e9f9df
AM
11775 while (offset < sect->sh_size)
11776 {
2cf0635d 11777 Elf_External_Options * eoption;
252b5132 11778
a6e9f9df 11779 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 11780
a6e9f9df
AM
11781 option->kind = BYTE_GET (eoption->kind);
11782 option->size = BYTE_GET (eoption->size);
11783 option->section = BYTE_GET (eoption->section);
11784 option->info = BYTE_GET (eoption->info);
76da6bbe 11785
a6e9f9df 11786 offset += option->size;
252b5132 11787
a6e9f9df
AM
11788 ++option;
11789 ++cnt;
11790 }
252b5132 11791
a6e9f9df
AM
11792 printf (_("\nSection '%s' contains %d entries:\n"),
11793 SECTION_NAME (sect), cnt);
76da6bbe 11794
a6e9f9df 11795 option = iopt;
252b5132 11796
a6e9f9df 11797 while (cnt-- > 0)
252b5132 11798 {
a6e9f9df
AM
11799 size_t len;
11800
11801 switch (option->kind)
252b5132 11802 {
a6e9f9df
AM
11803 case ODK_NULL:
11804 /* This shouldn't happen. */
11805 printf (" NULL %d %lx", option->section, option->info);
11806 break;
11807 case ODK_REGINFO:
11808 printf (" REGINFO ");
11809 if (elf_header.e_machine == EM_MIPS)
11810 {
11811 /* 32bit form. */
2cf0635d 11812 Elf32_External_RegInfo * ereg;
b34976b6 11813 Elf32_RegInfo reginfo;
a6e9f9df
AM
11814
11815 ereg = (Elf32_External_RegInfo *) (option + 1);
11816 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11817 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11818 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11819 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11820 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
11821 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
11822
11823 printf ("GPR %08lx GP 0x%lx\n",
11824 reginfo.ri_gprmask,
11825 (unsigned long) reginfo.ri_gp_value);
11826 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11827 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11828 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11829 }
11830 else
11831 {
11832 /* 64 bit form. */
2cf0635d 11833 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
11834 Elf64_Internal_RegInfo reginfo;
11835
11836 ereg = (Elf64_External_RegInfo *) (option + 1);
11837 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11838 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11839 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11840 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11841 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 11842 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
11843
11844 printf ("GPR %08lx GP 0x",
11845 reginfo.ri_gprmask);
11846 printf_vma (reginfo.ri_gp_value);
11847 printf ("\n");
11848
11849 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11850 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11851 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11852 }
11853 ++option;
11854 continue;
11855 case ODK_EXCEPTIONS:
11856 fputs (" EXCEPTIONS fpe_min(", stdout);
11857 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
11858 fputs (") fpe_max(", stdout);
11859 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
11860 fputs (")", stdout);
11861
11862 if (option->info & OEX_PAGE0)
11863 fputs (" PAGE0", stdout);
11864 if (option->info & OEX_SMM)
11865 fputs (" SMM", stdout);
11866 if (option->info & OEX_FPDBUG)
11867 fputs (" FPDBUG", stdout);
11868 if (option->info & OEX_DISMISS)
11869 fputs (" DISMISS", stdout);
11870 break;
11871 case ODK_PAD:
11872 fputs (" PAD ", stdout);
11873 if (option->info & OPAD_PREFIX)
11874 fputs (" PREFIX", stdout);
11875 if (option->info & OPAD_POSTFIX)
11876 fputs (" POSTFIX", stdout);
11877 if (option->info & OPAD_SYMBOL)
11878 fputs (" SYMBOL", stdout);
11879 break;
11880 case ODK_HWPATCH:
11881 fputs (" HWPATCH ", stdout);
11882 if (option->info & OHW_R4KEOP)
11883 fputs (" R4KEOP", stdout);
11884 if (option->info & OHW_R8KPFETCH)
11885 fputs (" R8KPFETCH", stdout);
11886 if (option->info & OHW_R5KEOP)
11887 fputs (" R5KEOP", stdout);
11888 if (option->info & OHW_R5KCVTL)
11889 fputs (" R5KCVTL", stdout);
11890 break;
11891 case ODK_FILL:
11892 fputs (" FILL ", stdout);
11893 /* XXX Print content of info word? */
11894 break;
11895 case ODK_TAGS:
11896 fputs (" TAGS ", stdout);
11897 /* XXX Print content of info word? */
11898 break;
11899 case ODK_HWAND:
11900 fputs (" HWAND ", stdout);
11901 if (option->info & OHWA0_R4KEOP_CHECKED)
11902 fputs (" R4KEOP_CHECKED", stdout);
11903 if (option->info & OHWA0_R4KEOP_CLEAN)
11904 fputs (" R4KEOP_CLEAN", stdout);
11905 break;
11906 case ODK_HWOR:
11907 fputs (" HWOR ", stdout);
11908 if (option->info & OHWA0_R4KEOP_CHECKED)
11909 fputs (" R4KEOP_CHECKED", stdout);
11910 if (option->info & OHWA0_R4KEOP_CLEAN)
11911 fputs (" R4KEOP_CLEAN", stdout);
11912 break;
11913 case ODK_GP_GROUP:
11914 printf (" GP_GROUP %#06lx self-contained %#06lx",
11915 option->info & OGP_GROUP,
11916 (option->info & OGP_SELF) >> 16);
11917 break;
11918 case ODK_IDENT:
11919 printf (" IDENT %#06lx self-contained %#06lx",
11920 option->info & OGP_GROUP,
11921 (option->info & OGP_SELF) >> 16);
11922 break;
11923 default:
11924 /* This shouldn't happen. */
11925 printf (" %3d ??? %d %lx",
11926 option->kind, option->section, option->info);
11927 break;
252b5132 11928 }
a6e9f9df 11929
2cf0635d 11930 len = sizeof (* eopt);
a6e9f9df
AM
11931 while (len < option->size)
11932 if (((char *) option)[len] >= ' '
11933 && ((char *) option)[len] < 0x7f)
11934 printf ("%c", ((char *) option)[len++]);
11935 else
11936 printf ("\\%03o", ((char *) option)[len++]);
11937
11938 fputs ("\n", stdout);
252b5132 11939 ++option;
252b5132
RH
11940 }
11941
a6e9f9df 11942 free (eopt);
252b5132 11943 }
252b5132
RH
11944 }
11945
11946 if (conflicts_offset != 0 && conflictsno != 0)
11947 {
2cf0635d 11948 Elf32_Conflict * iconf;
252b5132
RH
11949 size_t cnt;
11950
11951 if (dynamic_symbols == NULL)
11952 {
591a748a 11953 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
11954 return 0;
11955 }
11956
3f5e193b 11957 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
11958 if (iconf == NULL)
11959 {
591a748a 11960 error (_("Out of memory\n"));
252b5132
RH
11961 return 0;
11962 }
11963
9ea033b2 11964 if (is_32bit_elf)
252b5132 11965 {
2cf0635d 11966 Elf32_External_Conflict * econf32;
a6e9f9df 11967
3f5e193b
NC
11968 econf32 = (Elf32_External_Conflict *)
11969 get_data (NULL, file, conflicts_offset, conflictsno,
11970 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
11971 if (!econf32)
11972 return 0;
252b5132
RH
11973
11974 for (cnt = 0; cnt < conflictsno; ++cnt)
11975 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
11976
11977 free (econf32);
252b5132
RH
11978 }
11979 else
11980 {
2cf0635d 11981 Elf64_External_Conflict * econf64;
a6e9f9df 11982
3f5e193b
NC
11983 econf64 = (Elf64_External_Conflict *)
11984 get_data (NULL, file, conflicts_offset, conflictsno,
11985 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
11986 if (!econf64)
11987 return 0;
252b5132
RH
11988
11989 for (cnt = 0; cnt < conflictsno; ++cnt)
11990 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
11991
11992 free (econf64);
252b5132
RH
11993 }
11994
c7e7ca54
NC
11995 printf (_("\nSection '.conflict' contains %lu entries:\n"),
11996 (unsigned long) conflictsno);
252b5132
RH
11997 puts (_(" Num: Index Value Name"));
11998
11999 for (cnt = 0; cnt < conflictsno; ++cnt)
12000 {
2cf0635d 12001 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12002
b34976b6 12003 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12004 print_vma (psym->st_value, FULL_HEX);
31104126 12005 putchar (' ');
d79b3d50
NC
12006 if (VALID_DYNAMIC_NAME (psym->st_name))
12007 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12008 else
2b692964 12009 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12010 putchar ('\n');
252b5132
RH
12011 }
12012
252b5132
RH
12013 free (iconf);
12014 }
12015
ccb4c951
RS
12016 if (pltgot != 0 && local_gotno != 0)
12017 {
91d6fa6a 12018 bfd_vma ent, local_end, global_end;
bbeee7ea 12019 size_t i, offset;
2cf0635d 12020 unsigned char * data;
bbeee7ea 12021 int addr_size;
ccb4c951 12022
91d6fa6a 12023 ent = pltgot;
ccb4c951
RS
12024 addr_size = (is_32bit_elf ? 4 : 8);
12025 local_end = pltgot + local_gotno * addr_size;
12026 global_end = local_end + (symtabno - gotsym) * addr_size;
12027
12028 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b
NC
12029 data = (unsigned char *) get_data (NULL, file, offset,
12030 global_end - pltgot, 1, _("GOT"));
59245841
NC
12031 if (data == NULL)
12032 return 0;
12033
ccb4c951
RS
12034 printf (_("\nPrimary GOT:\n"));
12035 printf (_(" Canonical gp value: "));
12036 print_vma (pltgot + 0x7ff0, LONG_HEX);
12037 printf ("\n\n");
12038
12039 printf (_(" Reserved entries:\n"));
12040 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12041 addr_size * 2, _("Address"), _("Access"),
12042 addr_size * 2, _("Initial"));
91d6fa6a 12043 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12044 printf (_(" Lazy resolver\n"));
ccb4c951 12045 if (data
91d6fa6a 12046 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12047 >> (addr_size * 8 - 1)) != 0)
12048 {
91d6fa6a 12049 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12050 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12051 }
12052 printf ("\n");
12053
91d6fa6a 12054 if (ent < local_end)
ccb4c951
RS
12055 {
12056 printf (_(" Local entries:\n"));
cc5914eb 12057 printf (" %*s %10s %*s\n",
2b692964
NC
12058 addr_size * 2, _("Address"), _("Access"),
12059 addr_size * 2, _("Initial"));
91d6fa6a 12060 while (ent < local_end)
ccb4c951 12061 {
91d6fa6a 12062 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12063 printf ("\n");
12064 }
12065 printf ("\n");
12066 }
12067
12068 if (gotsym < symtabno)
12069 {
12070 int sym_width;
12071
12072 printf (_(" Global entries:\n"));
cc5914eb 12073 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
2b692964
NC
12074 addr_size * 2, _("Address"), _("Access"),
12075 addr_size * 2, _("Initial"),
12076 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
ccb4c951
RS
12077 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12078 for (i = gotsym; i < symtabno; i++)
12079 {
2cf0635d 12080 Elf_Internal_Sym * psym;
ccb4c951
RS
12081
12082 psym = dynamic_symbols + i;
91d6fa6a 12083 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12084 printf (" ");
12085 print_vma (psym->st_value, LONG_HEX);
12086 printf (" %-7s %3s ",
12087 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12088 get_symbol_index_type (psym->st_shndx));
12089 if (VALID_DYNAMIC_NAME (psym->st_name))
12090 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12091 else
2b692964 12092 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12093 printf ("\n");
12094 }
12095 printf ("\n");
12096 }
12097
12098 if (data)
12099 free (data);
12100 }
12101
861fb55a
DJ
12102 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12103 {
91d6fa6a 12104 bfd_vma ent, end;
861fb55a
DJ
12105 size_t offset, rel_offset;
12106 unsigned long count, i;
2cf0635d 12107 unsigned char * data;
861fb55a 12108 int addr_size, sym_width;
2cf0635d 12109 Elf_Internal_Rela * rels;
861fb55a
DJ
12110
12111 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12112 if (pltrel == DT_RELA)
12113 {
12114 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12115 return 0;
12116 }
12117 else
12118 {
12119 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12120 return 0;
12121 }
12122
91d6fa6a 12123 ent = mips_pltgot;
861fb55a
DJ
12124 addr_size = (is_32bit_elf ? 4 : 8);
12125 end = mips_pltgot + (2 + count) * addr_size;
12126
12127 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b
NC
12128 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
12129 1, _("PLT GOT"));
59245841
NC
12130 if (data == NULL)
12131 return 0;
12132
861fb55a
DJ
12133 printf (_("\nPLT GOT:\n\n"));
12134 printf (_(" Reserved entries:\n"));
12135 printf (_(" %*s %*s Purpose\n"),
2b692964 12136 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12137 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12138 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12139 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12140 printf (_(" Module pointer\n"));
861fb55a
DJ
12141 printf ("\n");
12142
12143 printf (_(" Entries:\n"));
cc5914eb 12144 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12145 addr_size * 2, _("Address"),
12146 addr_size * 2, _("Initial"),
12147 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12148 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12149 for (i = 0; i < count; i++)
12150 {
2cf0635d 12151 Elf_Internal_Sym * psym;
861fb55a
DJ
12152
12153 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12154 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12155 printf (" ");
12156 print_vma (psym->st_value, LONG_HEX);
12157 printf (" %-7s %3s ",
12158 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12159 get_symbol_index_type (psym->st_shndx));
12160 if (VALID_DYNAMIC_NAME (psym->st_name))
12161 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12162 else
2b692964 12163 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12164 printf ("\n");
12165 }
12166 printf ("\n");
12167
12168 if (data)
12169 free (data);
12170 free (rels);
12171 }
12172
252b5132
RH
12173 return 1;
12174}
12175
047b2264 12176static int
2cf0635d 12177process_gnu_liblist (FILE * file)
047b2264 12178{
2cf0635d
NC
12179 Elf_Internal_Shdr * section;
12180 Elf_Internal_Shdr * string_sec;
12181 Elf32_External_Lib * elib;
12182 char * strtab;
c256ffe7 12183 size_t strtab_size;
047b2264
JJ
12184 size_t cnt;
12185 unsigned i;
12186
12187 if (! do_arch)
12188 return 0;
12189
12190 for (i = 0, section = section_headers;
12191 i < elf_header.e_shnum;
b34976b6 12192 i++, section++)
047b2264
JJ
12193 {
12194 switch (section->sh_type)
12195 {
12196 case SHT_GNU_LIBLIST:
4fbb74a6 12197 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12198 break;
12199
3f5e193b
NC
12200 elib = (Elf32_External_Lib *)
12201 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
12202 _("liblist"));
047b2264
JJ
12203
12204 if (elib == NULL)
12205 break;
4fbb74a6 12206 string_sec = section_headers + section->sh_link;
047b2264 12207
3f5e193b
NC
12208 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12209 string_sec->sh_size,
12210 _("liblist string table"));
047b2264
JJ
12211 if (strtab == NULL
12212 || section->sh_entsize != sizeof (Elf32_External_Lib))
12213 {
12214 free (elib);
2842702f 12215 free (strtab);
047b2264
JJ
12216 break;
12217 }
59245841 12218 strtab_size = string_sec->sh_size;
047b2264
JJ
12219
12220 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12221 SECTION_NAME (section),
0af1713e 12222 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12223
2b692964 12224 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12225
12226 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12227 ++cnt)
12228 {
12229 Elf32_Lib liblist;
91d6fa6a 12230 time_t atime;
047b2264 12231 char timebuf[20];
2cf0635d 12232 struct tm * tmp;
047b2264
JJ
12233
12234 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12235 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12236 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12237 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12238 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12239
91d6fa6a 12240 tmp = gmtime (&atime);
e9e44622
JJ
12241 snprintf (timebuf, sizeof (timebuf),
12242 "%04u-%02u-%02uT%02u:%02u:%02u",
12243 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12244 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12245
12246 printf ("%3lu: ", (unsigned long) cnt);
12247 if (do_wide)
c256ffe7 12248 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12249 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12250 else
c256ffe7 12251 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12252 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12253 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12254 liblist.l_version, liblist.l_flags);
12255 }
12256
12257 free (elib);
2842702f 12258 free (strtab);
047b2264
JJ
12259 }
12260 }
12261
12262 return 1;
12263}
12264
9437c45b 12265static const char *
d3ba0551 12266get_note_type (unsigned e_type)
779fe533
NC
12267{
12268 static char buff[64];
103f02d3 12269
1ec5cd37
NC
12270 if (elf_header.e_type == ET_CORE)
12271 switch (e_type)
12272 {
57346661 12273 case NT_AUXV:
1ec5cd37 12274 return _("NT_AUXV (auxiliary vector)");
57346661 12275 case NT_PRSTATUS:
1ec5cd37 12276 return _("NT_PRSTATUS (prstatus structure)");
57346661 12277 case NT_FPREGSET:
1ec5cd37 12278 return _("NT_FPREGSET (floating point registers)");
57346661 12279 case NT_PRPSINFO:
1ec5cd37 12280 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12281 case NT_TASKSTRUCT:
1ec5cd37 12282 return _("NT_TASKSTRUCT (task structure)");
57346661 12283 case NT_PRXFPREG:
1ec5cd37 12284 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12285 case NT_PPC_VMX:
12286 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12287 case NT_PPC_VSX:
12288 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
12289 case NT_X86_XSTATE:
12290 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12291 case NT_S390_HIGH_GPRS:
12292 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12293 case NT_S390_TIMER:
12294 return _("NT_S390_TIMER (s390 timer register)");
12295 case NT_S390_TODCMP:
12296 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12297 case NT_S390_TODPREG:
12298 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12299 case NT_S390_CTRS:
12300 return _("NT_S390_CTRS (s390 control registers)");
12301 case NT_S390_PREFIX:
12302 return _("NT_S390_PREFIX (s390 prefix register)");
faa9a424
UW
12303 case NT_ARM_VFP:
12304 return _("NT_ARM_VFP (arm VFP registers)");
57346661 12305 case NT_PSTATUS:
1ec5cd37 12306 return _("NT_PSTATUS (pstatus structure)");
57346661 12307 case NT_FPREGS:
1ec5cd37 12308 return _("NT_FPREGS (floating point registers)");
57346661 12309 case NT_PSINFO:
1ec5cd37 12310 return _("NT_PSINFO (psinfo structure)");
57346661 12311 case NT_LWPSTATUS:
1ec5cd37 12312 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12313 case NT_LWPSINFO:
1ec5cd37 12314 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12315 case NT_WIN32PSTATUS:
1ec5cd37
NC
12316 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
12317 default:
12318 break;
12319 }
12320 else
12321 switch (e_type)
12322 {
12323 case NT_VERSION:
12324 return _("NT_VERSION (version)");
12325 case NT_ARCH:
12326 return _("NT_ARCH (architecture)");
12327 default:
12328 break;
12329 }
12330
e9e44622 12331 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12332 return buff;
779fe533
NC
12333}
12334
1118d252
RM
12335static const char *
12336get_gnu_elf_note_type (unsigned e_type)
12337{
12338 static char buff[64];
12339
12340 switch (e_type)
12341 {
12342 case NT_GNU_ABI_TAG:
12343 return _("NT_GNU_ABI_TAG (ABI version tag)");
12344 case NT_GNU_HWCAP:
12345 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12346 case NT_GNU_BUILD_ID:
12347 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12348 case NT_GNU_GOLD_VERSION:
12349 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12350 default:
12351 break;
12352 }
12353
12354 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12355 return buff;
12356}
12357
664f90a3
TT
12358static int
12359print_gnu_note (Elf_Internal_Note *pnote)
12360{
12361 switch (pnote->type)
12362 {
12363 case NT_GNU_BUILD_ID:
12364 {
12365 unsigned long i;
12366
12367 printf (_(" Build ID: "));
12368 for (i = 0; i < pnote->descsz; ++i)
12369 printf ("%02x", pnote->descdata[i] & 0xff);
12370 printf (_("\n"));
12371 }
12372 break;
12373
12374 case NT_GNU_ABI_TAG:
12375 {
12376 unsigned long os, major, minor, subminor;
12377 const char *osname;
12378
12379 os = byte_get ((unsigned char *) pnote->descdata, 4);
12380 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
12381 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
12382 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
12383
12384 switch (os)
12385 {
12386 case GNU_ABI_TAG_LINUX:
12387 osname = "Linux";
12388 break;
12389 case GNU_ABI_TAG_HURD:
12390 osname = "Hurd";
12391 break;
12392 case GNU_ABI_TAG_SOLARIS:
12393 osname = "Solaris";
12394 break;
12395 case GNU_ABI_TAG_FREEBSD:
12396 osname = "FreeBSD";
12397 break;
12398 case GNU_ABI_TAG_NETBSD:
12399 osname = "NetBSD";
12400 break;
12401 default:
12402 osname = "Unknown";
12403 break;
12404 }
12405
12406 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
12407 major, minor, subminor);
12408 }
12409 break;
12410 }
12411
12412 return 1;
12413}
12414
9437c45b 12415static const char *
d3ba0551 12416get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
12417{
12418 static char buff[64];
12419
b4db1224 12420 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
12421 {
12422 /* NetBSD core "procinfo" structure. */
12423 return _("NetBSD procinfo structure");
12424 }
12425
12426 /* As of Jan 2002 there are no other machine-independent notes
12427 defined for NetBSD core files. If the note type is less
12428 than the start of the machine-dependent note types, we don't
12429 understand it. */
12430
b4db1224 12431 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 12432 {
e9e44622 12433 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
12434 return buff;
12435 }
12436
12437 switch (elf_header.e_machine)
12438 {
12439 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
12440 and PT_GETFPREGS == mach+2. */
12441
12442 case EM_OLD_ALPHA:
12443 case EM_ALPHA:
12444 case EM_SPARC:
12445 case EM_SPARC32PLUS:
12446 case EM_SPARCV9:
12447 switch (e_type)
12448 {
2b692964 12449 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 12450 return _("PT_GETREGS (reg structure)");
2b692964 12451 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 12452 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12453 default:
12454 break;
12455 }
12456 break;
12457
12458 /* On all other arch's, PT_GETREGS == mach+1 and
12459 PT_GETFPREGS == mach+3. */
12460 default:
12461 switch (e_type)
12462 {
2b692964 12463 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 12464 return _("PT_GETREGS (reg structure)");
2b692964 12465 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 12466 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12467 default:
12468 break;
12469 }
12470 }
12471
e9e44622
JJ
12472 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
12473 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
12474 return buff;
12475}
12476
70616151
TT
12477static const char *
12478get_stapsdt_note_type (unsigned e_type)
12479{
12480 static char buff[64];
12481
12482 switch (e_type)
12483 {
12484 case NT_STAPSDT:
12485 return _("NT_STAPSDT (SystemTap probe descriptors)");
12486
12487 default:
12488 break;
12489 }
12490
12491 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12492 return buff;
12493}
12494
c6a9fc58
TT
12495static int
12496print_stapsdt_note (Elf_Internal_Note *pnote)
12497{
12498 int addr_size = is_32bit_elf ? 4 : 8;
12499 char *data = pnote->descdata;
12500 char *data_end = pnote->descdata + pnote->descsz;
12501 bfd_vma pc, base_addr, semaphore;
12502 char *provider, *probe, *arg_fmt;
12503
12504 pc = byte_get ((unsigned char *) data, addr_size);
12505 data += addr_size;
12506 base_addr = byte_get ((unsigned char *) data, addr_size);
12507 data += addr_size;
12508 semaphore = byte_get ((unsigned char *) data, addr_size);
12509 data += addr_size;
12510
12511 provider = data;
12512 data += strlen (data) + 1;
12513 probe = data;
12514 data += strlen (data) + 1;
12515 arg_fmt = data;
12516 data += strlen (data) + 1;
12517
12518 printf (_(" Provider: %s\n"), provider);
12519 printf (_(" Name: %s\n"), probe);
12520 printf (_(" Location: "));
12521 print_vma (pc, FULL_HEX);
12522 printf (_(", Base: "));
12523 print_vma (base_addr, FULL_HEX);
12524 printf (_(", Semaphore: "));
12525 print_vma (semaphore, FULL_HEX);
12526 printf (_("\n"));
12527 printf (_(" Arguments: %s\n"), arg_fmt);
12528
12529 return data == data_end;
12530}
12531
00e98fc7
TG
12532static const char *
12533get_ia64_vms_note_type (unsigned e_type)
12534{
12535 static char buff[64];
12536
12537 switch (e_type)
12538 {
12539 case NT_VMS_MHD:
12540 return _("NT_VMS_MHD (module header)");
12541 case NT_VMS_LNM:
12542 return _("NT_VMS_LNM (language name)");
12543 case NT_VMS_SRC:
12544 return _("NT_VMS_SRC (source files)");
12545 case NT_VMS_TITLE:
12546 return _("NT_VMS_TITLE");
12547 case NT_VMS_EIDC:
12548 return _("NT_VMS_EIDC (consistency check)");
12549 case NT_VMS_FPMODE:
12550 return _("NT_VMS_FPMODE (FP mode)");
12551 case NT_VMS_LINKTIME:
12552 return _("NT_VMS_LINKTIME");
12553 case NT_VMS_IMGNAM:
12554 return _("NT_VMS_IMGNAM (image name)");
12555 case NT_VMS_IMGID:
12556 return _("NT_VMS_IMGID (image id)");
12557 case NT_VMS_LINKID:
12558 return _("NT_VMS_LINKID (link id)");
12559 case NT_VMS_IMGBID:
12560 return _("NT_VMS_IMGBID (build id)");
12561 case NT_VMS_GSTNAM:
12562 return _("NT_VMS_GSTNAM (sym table name)");
12563 case NT_VMS_ORIG_DYN:
12564 return _("NT_VMS_ORIG_DYN");
12565 case NT_VMS_PATCHTIME:
12566 return _("NT_VMS_PATCHTIME");
12567 default:
12568 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12569 return buff;
12570 }
12571}
12572
12573static int
12574print_ia64_vms_note (Elf_Internal_Note * pnote)
12575{
12576 switch (pnote->type)
12577 {
12578 case NT_VMS_MHD:
12579 if (pnote->descsz > 36)
12580 {
12581 size_t l = strlen (pnote->descdata + 34);
12582 printf (_(" Creation date : %.17s\n"), pnote->descdata);
12583 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
12584 printf (_(" Module name : %s\n"), pnote->descdata + 34);
12585 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
12586 }
12587 else
12588 printf (_(" Invalid size\n"));
12589 break;
12590 case NT_VMS_LNM:
12591 printf (_(" Language: %s\n"), pnote->descdata);
12592 break;
12593#ifdef BFD64
12594 case NT_VMS_FPMODE:
12595 printf (_(" FP mode: 0x%016" BFD_VMA_FMT "x\n"),
12596 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
12597 break;
12598 case NT_VMS_LINKTIME:
12599 printf (_(" Link time: "));
12600 print_vms_time
12601 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12602 printf ("\n");
12603 break;
12604 case NT_VMS_PATCHTIME:
12605 printf (_(" Patch time: "));
12606 print_vms_time
12607 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12608 printf ("\n");
12609 break;
12610 case NT_VMS_ORIG_DYN:
12611 printf (_(" Major id: %u, minor id: %u\n"),
12612 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
12613 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
12614 printf (_(" Manip date : "));
12615 print_vms_time
12616 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
12617 printf (_("\n"
12618 " Link flags : 0x%016" BFD_VMA_FMT "x\n"),
12619 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
12620 printf (_(" Header flags: 0x%08x\n"),
12621 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
12622 printf (_(" Image id : %s\n"), pnote->descdata + 32);
12623 break;
12624#endif
12625 case NT_VMS_IMGNAM:
12626 printf (_(" Image name: %s\n"), pnote->descdata);
12627 break;
12628 case NT_VMS_GSTNAM:
12629 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
12630 break;
12631 case NT_VMS_IMGID:
12632 printf (_(" Image id: %s\n"), pnote->descdata);
12633 break;
12634 case NT_VMS_LINKID:
12635 printf (_(" Linker id: %s\n"), pnote->descdata);
12636 break;
12637 default:
12638 break;
12639 }
12640 return 1;
12641}
12642
6d118b09
NC
12643/* Note that by the ELF standard, the name field is already null byte
12644 terminated, and namesz includes the terminating null byte.
12645 I.E. the value of namesz for the name "FSF" is 4.
12646
e3c8793a 12647 If the value of namesz is zero, there is no name present. */
779fe533 12648static int
2cf0635d 12649process_note (Elf_Internal_Note * pnote)
779fe533 12650{
2cf0635d
NC
12651 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
12652 const char * nt;
9437c45b
JT
12653
12654 if (pnote->namesz == 0)
1ec5cd37
NC
12655 /* If there is no note name, then use the default set of
12656 note type strings. */
12657 nt = get_note_type (pnote->type);
12658
1118d252
RM
12659 else if (const_strneq (pnote->namedata, "GNU"))
12660 /* GNU-specific object file notes. */
12661 nt = get_gnu_elf_note_type (pnote->type);
12662
0112cd26 12663 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
12664 /* NetBSD-specific core file notes. */
12665 nt = get_netbsd_elfcore_note_type (pnote->type);
12666
b15fa79e
AM
12667 else if (strneq (pnote->namedata, "SPU/", 4))
12668 {
12669 /* SPU-specific core file notes. */
12670 nt = pnote->namedata + 4;
12671 name = "SPU";
12672 }
12673
00e98fc7
TG
12674 else if (const_strneq (pnote->namedata, "IPF/VMS"))
12675 /* VMS/ia64-specific file notes. */
12676 nt = get_ia64_vms_note_type (pnote->type);
12677
70616151
TT
12678 else if (const_strneq (pnote->namedata, "stapsdt"))
12679 nt = get_stapsdt_note_type (pnote->type);
12680
9437c45b 12681 else
1ec5cd37
NC
12682 /* Don't recognize this note name; just use the default set of
12683 note type strings. */
00e98fc7 12684 nt = get_note_type (pnote->type);
9437c45b 12685
2aee03ae 12686 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
12687
12688 if (const_strneq (pnote->namedata, "IPF/VMS"))
12689 return print_ia64_vms_note (pnote);
664f90a3
TT
12690 else if (const_strneq (pnote->namedata, "GNU"))
12691 return print_gnu_note (pnote);
c6a9fc58
TT
12692 else if (const_strneq (pnote->namedata, "stapsdt"))
12693 return print_stapsdt_note (pnote);
00e98fc7
TG
12694 else
12695 return 1;
779fe533
NC
12696}
12697
6d118b09 12698
779fe533 12699static int
2cf0635d 12700process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 12701{
2cf0635d
NC
12702 Elf_External_Note * pnotes;
12703 Elf_External_Note * external;
b34976b6 12704 int res = 1;
103f02d3 12705
779fe533
NC
12706 if (length <= 0)
12707 return 0;
103f02d3 12708
3f5e193b
NC
12709 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
12710 _("notes"));
dd24e3da 12711 if (pnotes == NULL)
a6e9f9df 12712 return 0;
779fe533 12713
103f02d3 12714 external = pnotes;
103f02d3 12715
305c7206 12716 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 12717 (unsigned long) offset, (unsigned long) length);
2aee03ae 12718 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 12719
2cf0635d 12720 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 12721 {
2cf0635d 12722 Elf_External_Note * next;
b34976b6 12723 Elf_Internal_Note inote;
2cf0635d 12724 char * temp = NULL;
6d118b09 12725
00e98fc7
TG
12726 if (!is_ia64_vms ())
12727 {
12728 inote.type = BYTE_GET (external->type);
12729 inote.namesz = BYTE_GET (external->namesz);
12730 inote.namedata = external->name;
12731 inote.descsz = BYTE_GET (external->descsz);
12732 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
12733 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12734
12735 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
12736 }
12737 else
12738 {
12739 Elf64_External_VMS_Note *vms_external;
12740
12741 vms_external = (Elf64_External_VMS_Note *)external;
12742 inote.type = BYTE_GET (vms_external->type);
12743 inote.namesz = BYTE_GET (vms_external->namesz);
12744 inote.namedata = vms_external->name;
12745 inote.descsz = BYTE_GET (vms_external->descsz);
12746 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
12747 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12748
12749 next = (Elf_External_Note *)
12750 (inote.descdata + align_power (inote.descsz, 3));
12751 }
3e55a963 12752
dd24e3da
NC
12753 if ( ((char *) next > ((char *) pnotes) + length)
12754 || ((char *) next < (char *) pnotes))
3e55a963 12755 {
0fd3a477 12756 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 12757 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 12758 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
12759 inote.type, inote.namesz, inote.descsz);
12760 break;
12761 }
12762
12763 external = next;
6d118b09 12764
dd24e3da
NC
12765 /* Prevent out-of-bounds indexing. */
12766 if (inote.namedata + inote.namesz >= (char *) pnotes + length
12767 || inote.namedata + inote.namesz < inote.namedata)
12768 {
12769 warn (_("corrupt note found at offset %lx into core notes\n"),
12770 (unsigned long) ((char *) external - (char *) pnotes));
12771 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
12772 inote.type, inote.namesz, inote.descsz);
12773 break;
12774 }
12775
6d118b09
NC
12776 /* Verify that name is null terminated. It appears that at least
12777 one version of Linux (RedHat 6.0) generates corefiles that don't
12778 comply with the ELF spec by failing to include the null byte in
12779 namesz. */
12780 if (inote.namedata[inote.namesz] != '\0')
12781 {
3f5e193b 12782 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 12783
6d118b09
NC
12784 if (temp == NULL)
12785 {
12786 error (_("Out of memory\n"));
12787 res = 0;
12788 break;
12789 }
76da6bbe 12790
6d118b09
NC
12791 strncpy (temp, inote.namedata, inote.namesz);
12792 temp[inote.namesz] = 0;
76da6bbe 12793
6d118b09
NC
12794 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
12795 inote.namedata = temp;
12796 }
12797
12798 res &= process_note (& inote);
103f02d3 12799
6d118b09
NC
12800 if (temp != NULL)
12801 {
12802 free (temp);
12803 temp = NULL;
12804 }
779fe533
NC
12805 }
12806
12807 free (pnotes);
103f02d3 12808
779fe533
NC
12809 return res;
12810}
12811
12812static int
2cf0635d 12813process_corefile_note_segments (FILE * file)
779fe533 12814{
2cf0635d 12815 Elf_Internal_Phdr * segment;
b34976b6
AM
12816 unsigned int i;
12817 int res = 1;
103f02d3 12818
d93f0186 12819 if (! get_program_headers (file))
779fe533 12820 return 0;
103f02d3 12821
779fe533
NC
12822 for (i = 0, segment = program_headers;
12823 i < elf_header.e_phnum;
b34976b6 12824 i++, segment++)
779fe533
NC
12825 {
12826 if (segment->p_type == PT_NOTE)
103f02d3 12827 res &= process_corefile_note_segment (file,
30800947
NC
12828 (bfd_vma) segment->p_offset,
12829 (bfd_vma) segment->p_filesz);
779fe533 12830 }
103f02d3 12831
779fe533
NC
12832 return res;
12833}
12834
12835static int
2cf0635d 12836process_note_sections (FILE * file)
1ec5cd37 12837{
2cf0635d 12838 Elf_Internal_Shdr * section;
1ec5cd37
NC
12839 unsigned long i;
12840 int res = 1;
12841
12842 for (i = 0, section = section_headers;
12843 i < elf_header.e_shnum;
12844 i++, section++)
12845 if (section->sh_type == SHT_NOTE)
12846 res &= process_corefile_note_segment (file,
12847 (bfd_vma) section->sh_offset,
12848 (bfd_vma) section->sh_size);
12849
12850 return res;
12851}
12852
12853static int
2cf0635d 12854process_notes (FILE * file)
779fe533
NC
12855{
12856 /* If we have not been asked to display the notes then do nothing. */
12857 if (! do_notes)
12858 return 1;
103f02d3 12859
779fe533 12860 if (elf_header.e_type != ET_CORE)
1ec5cd37 12861 return process_note_sections (file);
103f02d3 12862
779fe533 12863 /* No program headers means no NOTE segment. */
1ec5cd37
NC
12864 if (elf_header.e_phnum > 0)
12865 return process_corefile_note_segments (file);
779fe533 12866
1ec5cd37
NC
12867 printf (_("No note segments present in the core file.\n"));
12868 return 1;
779fe533
NC
12869}
12870
252b5132 12871static int
2cf0635d 12872process_arch_specific (FILE * file)
252b5132 12873{
a952a375
NC
12874 if (! do_arch)
12875 return 1;
12876
252b5132
RH
12877 switch (elf_header.e_machine)
12878 {
11c1ff18
PB
12879 case EM_ARM:
12880 return process_arm_specific (file);
252b5132 12881 case EM_MIPS:
4fe85591 12882 case EM_MIPS_RS3_LE:
252b5132
RH
12883 return process_mips_specific (file);
12884 break;
34c8bcba
JM
12885 case EM_PPC:
12886 return process_power_specific (file);
12887 break;
59e6276b
JM
12888 case EM_TI_C6000:
12889 return process_tic6x_specific (file);
12890 break;
252b5132
RH
12891 default:
12892 break;
12893 }
12894 return 1;
12895}
12896
12897static int
2cf0635d 12898get_file_header (FILE * file)
252b5132 12899{
9ea033b2
NC
12900 /* Read in the identity array. */
12901 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
12902 return 0;
12903
9ea033b2 12904 /* Determine how to read the rest of the header. */
b34976b6 12905 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
12906 {
12907 default: /* fall through */
12908 case ELFDATANONE: /* fall through */
adab8cdc
AO
12909 case ELFDATA2LSB:
12910 byte_get = byte_get_little_endian;
12911 byte_put = byte_put_little_endian;
12912 break;
12913 case ELFDATA2MSB:
12914 byte_get = byte_get_big_endian;
12915 byte_put = byte_put_big_endian;
12916 break;
9ea033b2
NC
12917 }
12918
12919 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 12920 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
12921
12922 /* Read in the rest of the header. */
12923 if (is_32bit_elf)
12924 {
12925 Elf32_External_Ehdr ehdr32;
252b5132 12926
9ea033b2
NC
12927 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
12928 return 0;
103f02d3 12929
9ea033b2
NC
12930 elf_header.e_type = BYTE_GET (ehdr32.e_type);
12931 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
12932 elf_header.e_version = BYTE_GET (ehdr32.e_version);
12933 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
12934 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
12935 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
12936 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
12937 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
12938 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
12939 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
12940 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
12941 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
12942 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
12943 }
252b5132 12944 else
9ea033b2
NC
12945 {
12946 Elf64_External_Ehdr ehdr64;
a952a375
NC
12947
12948 /* If we have been compiled with sizeof (bfd_vma) == 4, then
12949 we will not be able to cope with the 64bit data found in
12950 64 ELF files. Detect this now and abort before we start
50c2245b 12951 overwriting things. */
a952a375
NC
12952 if (sizeof (bfd_vma) < 8)
12953 {
e3c8793a
NC
12954 error (_("This instance of readelf has been built without support for a\n\
1295564 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
12956 return 0;
12957 }
103f02d3 12958
9ea033b2
NC
12959 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
12960 return 0;
103f02d3 12961
9ea033b2
NC
12962 elf_header.e_type = BYTE_GET (ehdr64.e_type);
12963 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
12964 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
12965 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
12966 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
12967 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
12968 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
12969 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
12970 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
12971 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
12972 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
12973 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
12974 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
12975 }
252b5132 12976
7ece0d85
JJ
12977 if (elf_header.e_shoff)
12978 {
12979 /* There may be some extensions in the first section header. Don't
12980 bomb if we can't read it. */
12981 if (is_32bit_elf)
12982 get_32bit_section_headers (file, 1);
12983 else
12984 get_64bit_section_headers (file, 1);
12985 }
560f3c1c 12986
252b5132
RH
12987 return 1;
12988}
12989
fb52b2f4
NC
12990/* Process one ELF object file according to the command line options.
12991 This file may actually be stored in an archive. The file is
12992 positioned at the start of the ELF object. */
12993
ff78d6d6 12994static int
2cf0635d 12995process_object (char * file_name, FILE * file)
252b5132 12996{
252b5132
RH
12997 unsigned int i;
12998
252b5132
RH
12999 if (! get_file_header (file))
13000 {
13001 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13002 return 1;
252b5132
RH
13003 }
13004
13005 /* Initialise per file variables. */
60bca95a 13006 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13007 version_info[i] = 0;
13008
60bca95a 13009 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13010 dynamic_info[i] = 0;
5115b233 13011 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13012
13013 /* Process the file. */
13014 if (show_name)
13015 printf (_("\nFile: %s\n"), file_name);
13016
18bd398b
NC
13017 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13018 Note we do this even if cmdline_dump_sects is empty because we
13019 must make sure that the dump_sets array is zeroed out before each
13020 object file is processed. */
13021 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13022 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13023
13024 if (num_cmdline_dump_sects > 0)
13025 {
13026 if (num_dump_sects == 0)
13027 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13028 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13029
13030 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13031 memcpy (dump_sects, cmdline_dump_sects,
13032 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13033 }
d70c5fc7 13034
252b5132 13035 if (! process_file_header ())
fb52b2f4 13036 return 1;
252b5132 13037
d1f5c6e3 13038 if (! process_section_headers (file))
2f62977e 13039 {
d1f5c6e3
L
13040 /* Without loaded section headers we cannot process lots of
13041 things. */
2f62977e 13042 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13043
2f62977e 13044 if (! do_using_dynamic)
2c610e4b 13045 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13046 }
252b5132 13047
d1f5c6e3
L
13048 if (! process_section_groups (file))
13049 {
13050 /* Without loaded section groups we cannot process unwind. */
13051 do_unwind = 0;
13052 }
13053
2f62977e 13054 if (process_program_headers (file))
b2d38a17 13055 process_dynamic_section (file);
252b5132
RH
13056
13057 process_relocs (file);
13058
4d6ed7c8
NC
13059 process_unwind (file);
13060
252b5132
RH
13061 process_symbol_table (file);
13062
13063 process_syminfo (file);
13064
13065 process_version_sections (file);
13066
13067 process_section_contents (file);
f5842774 13068
1ec5cd37 13069 process_notes (file);
103f02d3 13070
047b2264
JJ
13071 process_gnu_liblist (file);
13072
252b5132
RH
13073 process_arch_specific (file);
13074
d93f0186
NC
13075 if (program_headers)
13076 {
13077 free (program_headers);
13078 program_headers = NULL;
13079 }
13080
252b5132
RH
13081 if (section_headers)
13082 {
13083 free (section_headers);
13084 section_headers = NULL;
13085 }
13086
13087 if (string_table)
13088 {
13089 free (string_table);
13090 string_table = NULL;
d40ac9bd 13091 string_table_length = 0;
252b5132
RH
13092 }
13093
13094 if (dynamic_strings)
13095 {
13096 free (dynamic_strings);
13097 dynamic_strings = NULL;
d79b3d50 13098 dynamic_strings_length = 0;
252b5132
RH
13099 }
13100
13101 if (dynamic_symbols)
13102 {
13103 free (dynamic_symbols);
13104 dynamic_symbols = NULL;
19936277 13105 num_dynamic_syms = 0;
252b5132
RH
13106 }
13107
13108 if (dynamic_syminfo)
13109 {
13110 free (dynamic_syminfo);
13111 dynamic_syminfo = NULL;
13112 }
ff78d6d6 13113
293c573e
MR
13114 if (dynamic_section)
13115 {
13116 free (dynamic_section);
13117 dynamic_section = NULL;
13118 }
13119
e4b17d5c
L
13120 if (section_headers_groups)
13121 {
13122 free (section_headers_groups);
13123 section_headers_groups = NULL;
13124 }
13125
13126 if (section_groups)
13127 {
2cf0635d
NC
13128 struct group_list * g;
13129 struct group_list * next;
e4b17d5c
L
13130
13131 for (i = 0; i < group_count; i++)
13132 {
13133 for (g = section_groups [i].root; g != NULL; g = next)
13134 {
13135 next = g->next;
13136 free (g);
13137 }
13138 }
13139
13140 free (section_groups);
13141 section_groups = NULL;
13142 }
13143
19e6b90e 13144 free_debug_memory ();
18bd398b 13145
ff78d6d6 13146 return 0;
252b5132
RH
13147}
13148
2cf0635d
NC
13149/* Process an ELF archive.
13150 On entry the file is positioned just after the ARMAG string. */
13151
13152static int
13153process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13154{
13155 struct archive_info arch;
13156 struct archive_info nested_arch;
13157 size_t got;
2cf0635d
NC
13158 int ret;
13159
13160 show_name = 1;
13161
13162 /* The ARCH structure is used to hold information about this archive. */
13163 arch.file_name = NULL;
13164 arch.file = NULL;
13165 arch.index_array = NULL;
13166 arch.sym_table = NULL;
13167 arch.longnames = NULL;
13168
13169 /* The NESTED_ARCH structure is used as a single-item cache of information
13170 about a nested archive (when members of a thin archive reside within
13171 another regular archive file). */
13172 nested_arch.file_name = NULL;
13173 nested_arch.file = NULL;
13174 nested_arch.index_array = NULL;
13175 nested_arch.sym_table = NULL;
13176 nested_arch.longnames = NULL;
13177
13178 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13179 {
13180 ret = 1;
13181 goto out;
4145f1d5 13182 }
fb52b2f4 13183
4145f1d5
NC
13184 if (do_archive_index)
13185 {
2cf0635d 13186 if (arch.sym_table == NULL)
4145f1d5
NC
13187 error (_("%s: unable to dump the index as none was found\n"), file_name);
13188 else
13189 {
2cf0635d 13190 unsigned int i, l;
4145f1d5
NC
13191 unsigned long current_pos;
13192
13193 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 13194 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
13195 current_pos = ftell (file);
13196
2cf0635d 13197 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13198 {
2cf0635d
NC
13199 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13200 {
13201 char * member_name;
4145f1d5 13202
2cf0635d
NC
13203 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13204
13205 if (member_name != NULL)
13206 {
13207 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13208
13209 if (qualified_name != NULL)
13210 {
13211 printf (_("Binary %s contains:\n"), qualified_name);
13212 free (qualified_name);
13213 }
4145f1d5
NC
13214 }
13215 }
2cf0635d
NC
13216
13217 if (l >= arch.sym_size)
4145f1d5
NC
13218 {
13219 error (_("%s: end of the symbol table reached before the end of the index\n"),
13220 file_name);
cb8f3167 13221 break;
4145f1d5 13222 }
2cf0635d
NC
13223 printf ("\t%s\n", arch.sym_table + l);
13224 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13225 }
13226
2cf0635d
NC
13227 if (l & 01)
13228 ++l;
13229 if (l < arch.sym_size)
4145f1d5
NC
13230 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
13231 file_name);
13232
4145f1d5
NC
13233 if (fseek (file, current_pos, SEEK_SET) != 0)
13234 {
13235 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13236 ret = 1;
13237 goto out;
4145f1d5 13238 }
fb52b2f4 13239 }
4145f1d5
NC
13240
13241 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13242 && !do_segments && !do_header && !do_dump && !do_version
13243 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13244 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13245 {
13246 ret = 0; /* Archive index only. */
13247 goto out;
13248 }
fb52b2f4
NC
13249 }
13250
d989285c 13251 ret = 0;
fb52b2f4
NC
13252
13253 while (1)
13254 {
2cf0635d
NC
13255 char * name;
13256 size_t namelen;
13257 char * qualified_name;
13258
13259 /* Read the next archive header. */
13260 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13261 {
13262 error (_("%s: failed to seek to next archive header\n"), file_name);
13263 return 1;
13264 }
13265 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13266 if (got != sizeof arch.arhdr)
13267 {
13268 if (got == 0)
13269 break;
13270 error (_("%s: failed to read archive header\n"), file_name);
13271 ret = 1;
13272 break;
13273 }
13274 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13275 {
13276 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13277 ret = 1;
13278 break;
13279 }
13280
13281 arch.next_arhdr_offset += sizeof arch.arhdr;
13282
13283 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13284 if (archive_file_size & 01)
13285 ++archive_file_size;
13286
13287 name = get_archive_member_name (&arch, &nested_arch);
13288 if (name == NULL)
fb52b2f4 13289 {
0fd3a477 13290 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13291 ret = 1;
13292 break;
fb52b2f4 13293 }
2cf0635d 13294 namelen = strlen (name);
fb52b2f4 13295
2cf0635d
NC
13296 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13297 if (qualified_name == NULL)
fb52b2f4 13298 {
2cf0635d 13299 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13300 ret = 1;
13301 break;
fb52b2f4
NC
13302 }
13303
2cf0635d
NC
13304 if (is_thin_archive && arch.nested_member_origin == 0)
13305 {
13306 /* This is a proxy for an external member of a thin archive. */
13307 FILE * member_file;
13308 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13309 if (member_file_name == NULL)
13310 {
13311 ret = 1;
13312 break;
13313 }
13314
13315 member_file = fopen (member_file_name, "rb");
13316 if (member_file == NULL)
13317 {
13318 error (_("Input file '%s' is not readable.\n"), member_file_name);
13319 free (member_file_name);
13320 ret = 1;
13321 break;
13322 }
13323
13324 archive_file_offset = arch.nested_member_origin;
13325
13326 ret |= process_object (qualified_name, member_file);
13327
13328 fclose (member_file);
13329 free (member_file_name);
13330 }
13331 else if (is_thin_archive)
13332 {
13333 /* This is a proxy for a member of a nested archive. */
13334 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
13335
13336 /* The nested archive file will have been opened and setup by
13337 get_archive_member_name. */
13338 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
13339 {
13340 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
13341 ret = 1;
13342 break;
13343 }
13344
13345 ret |= process_object (qualified_name, nested_arch.file);
13346 }
13347 else
13348 {
13349 archive_file_offset = arch.next_arhdr_offset;
13350 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 13351
2cf0635d
NC
13352 ret |= process_object (qualified_name, file);
13353 }
fb52b2f4 13354
2b52916e
L
13355 if (dump_sects != NULL)
13356 {
13357 free (dump_sects);
13358 dump_sects = NULL;
13359 num_dump_sects = 0;
13360 }
13361
2cf0635d 13362 free (qualified_name);
fb52b2f4
NC
13363 }
13364
4145f1d5 13365 out:
2cf0635d
NC
13366 if (nested_arch.file != NULL)
13367 fclose (nested_arch.file);
13368 release_archive (&nested_arch);
13369 release_archive (&arch);
fb52b2f4 13370
d989285c 13371 return ret;
fb52b2f4
NC
13372}
13373
13374static int
2cf0635d 13375process_file (char * file_name)
fb52b2f4 13376{
2cf0635d 13377 FILE * file;
fb52b2f4
NC
13378 struct stat statbuf;
13379 char armag[SARMAG];
13380 int ret;
13381
13382 if (stat (file_name, &statbuf) < 0)
13383 {
f24ddbdd
NC
13384 if (errno == ENOENT)
13385 error (_("'%s': No such file\n"), file_name);
13386 else
13387 error (_("Could not locate '%s'. System error message: %s\n"),
13388 file_name, strerror (errno));
13389 return 1;
13390 }
13391
13392 if (! S_ISREG (statbuf.st_mode))
13393 {
13394 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
13395 return 1;
13396 }
13397
13398 file = fopen (file_name, "rb");
13399 if (file == NULL)
13400 {
f24ddbdd 13401 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
13402 return 1;
13403 }
13404
13405 if (fread (armag, SARMAG, 1, file) != 1)
13406 {
4145f1d5 13407 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
13408 fclose (file);
13409 return 1;
13410 }
13411
13412 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
13413 ret = process_archive (file_name, file, FALSE);
13414 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
13415 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
13416 else
13417 {
4145f1d5
NC
13418 if (do_archive_index)
13419 error (_("File %s is not an archive so its index cannot be displayed.\n"),
13420 file_name);
13421
fb52b2f4
NC
13422 rewind (file);
13423 archive_file_size = archive_file_offset = 0;
13424 ret = process_object (file_name, file);
13425 }
13426
13427 fclose (file);
13428
13429 return ret;
13430}
13431
252b5132
RH
13432#ifdef SUPPORT_DISASSEMBLY
13433/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 13434 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 13435 symbols. */
252b5132
RH
13436
13437void
2cf0635d 13438print_address (unsigned int addr, FILE * outfile)
252b5132
RH
13439{
13440 fprintf (outfile,"0x%8.8x", addr);
13441}
13442
e3c8793a 13443/* Needed by the i386 disassembler. */
252b5132
RH
13444void
13445db_task_printsym (unsigned int addr)
13446{
13447 print_address (addr, stderr);
13448}
13449#endif
13450
13451int
2cf0635d 13452main (int argc, char ** argv)
252b5132 13453{
ff78d6d6
L
13454 int err;
13455
252b5132
RH
13456#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
13457 setlocale (LC_MESSAGES, "");
3882b010
L
13458#endif
13459#if defined (HAVE_SETLOCALE)
13460 setlocale (LC_CTYPE, "");
252b5132
RH
13461#endif
13462 bindtextdomain (PACKAGE, LOCALEDIR);
13463 textdomain (PACKAGE);
13464
869b9d07
MM
13465 expandargv (&argc, &argv);
13466
252b5132
RH
13467 parse_args (argc, argv);
13468
18bd398b 13469 if (num_dump_sects > 0)
59f14fc0 13470 {
18bd398b 13471 /* Make a copy of the dump_sects array. */
3f5e193b
NC
13472 cmdline_dump_sects = (dump_type *)
13473 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 13474 if (cmdline_dump_sects == NULL)
591a748a 13475 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
13476 else
13477 {
09c11c86
NC
13478 memcpy (cmdline_dump_sects, dump_sects,
13479 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
13480 num_cmdline_dump_sects = num_dump_sects;
13481 }
13482 }
13483
18bd398b
NC
13484 if (optind < (argc - 1))
13485 show_name = 1;
13486
ff78d6d6 13487 err = 0;
252b5132 13488 while (optind < argc)
18bd398b 13489 err |= process_file (argv[optind++]);
252b5132
RH
13490
13491 if (dump_sects != NULL)
13492 free (dump_sects);
59f14fc0
AS
13493 if (cmdline_dump_sects != NULL)
13494 free (cmdline_dump_sects);
252b5132 13495
ff78d6d6 13496 return err;
252b5132 13497}