gdb/
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
6e3d6dc1 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
8b971f9f 3 2008, 2009, 2010, 2011, 2012
a0f19280 4 Free Software Foundation, Inc.
252b5132
RH
5
6 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 7 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
8
9 This file is part of GNU Binutils.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
32866df7 13 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
b43b5d5f
NC
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
24 02110-1301, USA. */
252b5132 25\f
9eb20dd8 26/* The difference between readelf and objdump:
252b5132 27
74013231 28 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 29 so why does the binutils project have two file dumpers ?
0de14b54 30
9eb20dd8
NC
31 The reason is that objdump sees an ELF file through a BFD filter of the
32 world; if BFD has a bug where, say, it disagrees about a machine constant
33 in e_flags, then the odds are good that it will remain internally
34 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
35 GAS sees it the BFD way. There was need for a tool to go find out what
36 the file actually says.
37
38 This is why the readelf program does not link against the BFD library - it
39 exists as an independent program to help verify the correct working of BFD.
40
41 There is also the case that readelf can provide more information about an
42 ELF file than is provided by objdump. In particular it can display DWARF
43 debugging information which (at the moment) objdump cannot. */
44\f
3db64b00 45#include "sysdep.h"
252b5132 46#include <assert.h>
252b5132 47#include <time.h>
1b315056
CS
48#ifdef HAVE_ZLIB_H
49#include <zlib.h>
50#endif
252b5132 51
a952a375 52#if __GNUC__ >= 2
19936277 53/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 54 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 55 Only do this if we believe that the compiler can support a 64 bit
a952a375 56 data type. For now we only rely on GCC being able to do this. */
19936277 57#define BFD64
a952a375
NC
58#endif
59
3db64b00
AM
60#include "bfd.h"
61#include "bucomm.h"
3284fe0c 62#include "elfcomm.h"
19e6b90e 63#include "dwarf.h"
252b5132
RH
64
65#include "elf/common.h"
66#include "elf/external.h"
67#include "elf/internal.h"
252b5132 68
4b78141a
NC
69
70/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
71 we can obtain the H8 reloc numbers. We need these for the
72 get_reloc_size() function. We include h8.h again after defining
73 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
74
75#include "elf/h8.h"
76#undef _ELF_H8_H
77
78/* Undo the effects of #including reloc-macros.h. */
79
80#undef START_RELOC_NUMBERS
81#undef RELOC_NUMBER
82#undef FAKE_RELOC
83#undef EMPTY_RELOC
84#undef END_RELOC_NUMBERS
85#undef _RELOC_MACROS_H
86
252b5132
RH
87/* The following headers use the elf/reloc-macros.h file to
88 automatically generate relocation recognition functions
89 such as elf_mips_reloc_type() */
90
91#define RELOC_MACROS_GEN_FUNC
92
252b5132 93#include "elf/alpha.h"
3b16e843 94#include "elf/arc.h"
252b5132 95#include "elf/arm.h"
3b16e843 96#include "elf/avr.h"
1d65ded4 97#include "elf/bfin.h"
60bca95a 98#include "elf/cr16.h"
3b16e843 99#include "elf/cris.h"
1c0d3aa6 100#include "elf/crx.h"
252b5132
RH
101#include "elf/d10v.h"
102#include "elf/d30v.h"
d172d4ba 103#include "elf/dlx.h"
cfb8c092 104#include "elf/epiphany.h"
252b5132 105#include "elf/fr30.h"
5c70f934 106#include "elf/frv.h"
3b16e843
NC
107#include "elf/h8.h"
108#include "elf/hppa.h"
109#include "elf/i386.h"
35b1837e 110#include "elf/i370.h"
3b16e843
NC
111#include "elf/i860.h"
112#include "elf/i960.h"
113#include "elf/ia64.h"
1e4cf259 114#include "elf/ip2k.h"
84e94c90 115#include "elf/lm32.h"
1c0d3aa6 116#include "elf/iq2000.h"
49f58d10 117#include "elf/m32c.h"
3b16e843
NC
118#include "elf/m32r.h"
119#include "elf/m68k.h"
75751cd9 120#include "elf/m68hc11.h"
252b5132 121#include "elf/mcore.h"
15ab5209 122#include "elf/mep.h"
7ba29e2a 123#include "elf/microblaze.h"
3b16e843 124#include "elf/mips.h"
3c3bdf30 125#include "elf/mmix.h"
3b16e843
NC
126#include "elf/mn10200.h"
127#include "elf/mn10300.h"
5506d11a 128#include "elf/moxie.h"
4970f871 129#include "elf/mt.h"
2469cfa2 130#include "elf/msp430.h"
3b16e843 131#include "elf/or32.h"
7d466069 132#include "elf/pj.h"
3b16e843 133#include "elf/ppc.h"
c833c019 134#include "elf/ppc64.h"
99c513f6 135#include "elf/rl78.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"
f6c1a2d5 149#include "elf/xgate.h"
93fbbb04 150#include "elf/xstormy16.h"
88da6820 151#include "elf/xtensa.h"
252b5132 152
252b5132 153#include "getopt.h"
566b0d53 154#include "libiberty.h"
09c11c86 155#include "safe-ctype.h"
2cf0635d 156#include "filenames.h"
252b5132 157
2cf0635d 158char * program_name = "readelf";
85b1c36d
BE
159static long archive_file_offset;
160static unsigned long archive_file_size;
161static unsigned long dynamic_addr;
162static bfd_size_type dynamic_size;
163static unsigned int dynamic_nent;
2cf0635d 164static char * dynamic_strings;
85b1c36d 165static unsigned long dynamic_strings_length;
2cf0635d 166static char * string_table;
85b1c36d
BE
167static unsigned long string_table_length;
168static unsigned long num_dynamic_syms;
2cf0635d
NC
169static Elf_Internal_Sym * dynamic_symbols;
170static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
171static unsigned long dynamic_syminfo_offset;
172static unsigned int dynamic_syminfo_nent;
f8eae8b2 173static char program_interpreter[PATH_MAX];
bb8a0291 174static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 175static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
176static bfd_vma version_info[16];
177static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
178static Elf_Internal_Shdr * section_headers;
179static Elf_Internal_Phdr * program_headers;
180static Elf_Internal_Dyn * dynamic_section;
181static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
182static int show_name;
183static int do_dynamic;
184static int do_syms;
2c610e4b 185static int do_dyn_syms;
85b1c36d
BE
186static int do_reloc;
187static int do_sections;
188static int do_section_groups;
5477e8a0 189static int do_section_details;
85b1c36d
BE
190static int do_segments;
191static int do_unwind;
192static int do_using_dynamic;
193static int do_header;
194static int do_dump;
195static int do_version;
85b1c36d
BE
196static int do_histogram;
197static int do_debugging;
85b1c36d
BE
198static int do_arch;
199static int do_notes;
4145f1d5 200static int do_archive_index;
85b1c36d 201static int is_32bit_elf;
252b5132 202
e4b17d5c
L
203struct group_list
204{
2cf0635d 205 struct group_list * next;
e4b17d5c
L
206 unsigned int section_index;
207};
208
209struct group
210{
2cf0635d 211 struct group_list * root;
e4b17d5c
L
212 unsigned int group_index;
213};
214
85b1c36d 215static size_t group_count;
2cf0635d
NC
216static struct group * section_groups;
217static struct group ** section_headers_groups;
e4b17d5c 218
09c11c86
NC
219
220/* Flag bits indicating particular types of dump. */
221#define HEX_DUMP (1 << 0) /* The -x command line switch. */
222#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
223#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
224#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 225#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
226
227typedef unsigned char dump_type;
228
229/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
230struct dump_list_entry
231{
2cf0635d 232 char * name;
09c11c86 233 dump_type type;
2cf0635d 234 struct dump_list_entry * next;
aef1f6d0 235};
2cf0635d 236static struct dump_list_entry * dump_sects_byname;
aef1f6d0 237
09c11c86
NC
238/* A dynamic array of flags indicating for which sections a dump
239 has been requested via command line switches. */
240static dump_type * cmdline_dump_sects = NULL;
241static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
242
243/* A dynamic array of flags indicating for which sections a dump of
244 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
245 basis and then initialised from the cmdline_dump_sects array,
246 the results of interpreting the -w switch, and the
247 dump_sects_byname list. */
09c11c86
NC
248static dump_type * dump_sects = NULL;
249static unsigned int num_dump_sects = 0;
252b5132 250
252b5132 251
c256ffe7 252/* How to print a vma value. */
843dd992
NC
253typedef enum print_mode
254{
255 HEX,
256 DEC,
257 DEC_5,
258 UNSIGNED,
259 PREFIX_HEX,
260 FULL_HEX,
261 LONG_HEX
262}
263print_mode;
264
9c19a809
NC
265#define UNKNOWN -1
266
2b692964
NC
267#define SECTION_NAME(X) \
268 ((X) == NULL ? _("<none>") \
269 : string_table == NULL ? _("<no-name>") \
270 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 271 : string_table + (X)->sh_name))
252b5132 272
ee42cf8c 273#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 274
ba5cdace
NC
275#define GET_ELF_SYMBOLS(file, section, sym_count) \
276 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
277 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 278
d79b3d50
NC
279#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
280/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
281 already been called and verified that the string exists. */
282#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 283
61865e30
NC
284#define REMOVE_ARCH_BITS(ADDR) \
285 do \
286 { \
287 if (elf_header.e_machine == EM_ARM) \
288 (ADDR) &= ~1; \
289 } \
290 while (0)
d79b3d50 291\f
59245841
NC
292/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
293 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
294 using malloc and fill that. In either case return the pointer to the start of
295 the retrieved data or NULL if something went wrong. If something does go wrong
296 emit an error message using REASON as part of the context. */
297
c256ffe7 298static void *
2cf0635d
NC
299get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
300 const char * reason)
a6e9f9df 301{
2cf0635d 302 void * mvar;
a6e9f9df 303
c256ffe7 304 if (size == 0 || nmemb == 0)
a6e9f9df
AM
305 return NULL;
306
fb52b2f4 307 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 308 {
0fd3a477 309 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 310 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
311 return NULL;
312 }
313
314 mvar = var;
315 if (mvar == NULL)
316 {
c256ffe7
JJ
317 /* Check for overflow. */
318 if (nmemb < (~(size_t) 0 - 1) / size)
319 /* + 1 so that we can '\0' terminate invalid string table sections. */
320 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
321
322 if (mvar == NULL)
323 {
0fd3a477
JW
324 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
325 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
326 return NULL;
327 }
c256ffe7
JJ
328
329 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
330 }
331
c256ffe7 332 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 333 {
0fd3a477
JW
334 error (_("Unable to read in 0x%lx bytes of %s\n"),
335 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
336 if (mvar != var)
337 free (mvar);
338 return NULL;
339 }
340
341 return mvar;
342}
343
14a91970 344/* Print a VMA value. */
cb8f3167 345
66543521 346static int
14a91970 347print_vma (bfd_vma vma, print_mode mode)
66543521 348{
66543521
AM
349 int nc = 0;
350
14a91970 351 switch (mode)
66543521 352 {
14a91970
AM
353 case FULL_HEX:
354 nc = printf ("0x");
355 /* Drop through. */
66543521 356
14a91970 357 case LONG_HEX:
f7a99963 358#ifdef BFD64
14a91970 359 if (is_32bit_elf)
437c2fb7 360 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 361#endif
14a91970
AM
362 printf_vma (vma);
363 return nc + 16;
b19aac67 364
14a91970
AM
365 case DEC_5:
366 if (vma <= 99999)
367 return printf ("%5" BFD_VMA_FMT "d", vma);
368 /* Drop through. */
66543521 369
14a91970
AM
370 case PREFIX_HEX:
371 nc = printf ("0x");
372 /* Drop through. */
66543521 373
14a91970
AM
374 case HEX:
375 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 376
14a91970
AM
377 case DEC:
378 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 379
14a91970
AM
380 case UNSIGNED:
381 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 382 }
66543521 383 return 0;
f7a99963
NC
384}
385
171191ba 386/* Display a symbol on stdout. Handles the display of non-printing characters.
31104126 387
171191ba
NC
388 If DO_WIDE is not true then format the symbol to be at most WIDTH characters,
389 truncating as necessary. If WIDTH is negative then format the string to be
390 exactly - WIDTH characters, truncating or padding as necessary.
391
392 Returns the number of emitted characters. */
393
394static unsigned int
7a88bc9c 395print_symbol (int width, const char *symbol)
31104126 396{
7a88bc9c 397 const char *c;
171191ba
NC
398 bfd_boolean extra_padding = FALSE;
399 unsigned int num_printed = 0;
961c521f 400
31104126 401 if (do_wide)
961c521f 402 {
7a88bc9c
AS
403 /* Set the width to a very large value. This simplifies the
404 code below. */
961c521f
NC
405 width = INT_MAX;
406 }
31104126 407 else if (width < 0)
961c521f 408 {
961c521f
NC
409 /* Keep the width positive. This also helps. */
410 width = - width;
171191ba 411 extra_padding = TRUE;
961c521f
NC
412 }
413
414 while (width)
415 {
416 int len;
417
418 c = symbol;
419
420 /* Look for non-printing symbols inside the symbol's name.
421 This test is triggered in particular by the names generated
422 by the assembler for local labels. */
7a88bc9c 423 while (ISPRINT (*c))
961c521f
NC
424 c++;
425
426 len = c - symbol;
427
428 if (len)
429 {
430 if (len > width)
431 len = width;
cb8f3167 432
171191ba 433 printf ("%.*s", len, symbol);
961c521f
NC
434
435 width -= len;
171191ba 436 num_printed += len;
961c521f
NC
437 }
438
7a88bc9c 439 if (*c == 0 || width == 0)
961c521f
NC
440 break;
441
442 /* Now display the non-printing character, if
443 there is room left in which to dipslay it. */
7a88bc9c 444 if ((unsigned char) *c < 32)
961c521f
NC
445 {
446 if (width < 2)
447 break;
448
449 printf ("^%c", *c + 0x40);
450
451 width -= 2;
171191ba 452 num_printed += 2;
961c521f
NC
453 }
454 else
455 {
456 if (width < 6)
457 break;
cb8f3167 458
7a88bc9c 459 printf ("<0x%.2x>", (unsigned char) *c);
961c521f
NC
460
461 width -= 6;
171191ba 462 num_printed += 6;
961c521f
NC
463 }
464
465 symbol = c + 1;
466 }
171191ba
NC
467
468 if (extra_padding && width > 0)
469 {
470 /* Fill in the remaining spaces. */
471 printf ("%-*s", width, " ");
472 num_printed += 2;
473 }
474
475 return num_printed;
31104126
NC
476}
477
89fac5e3
RS
478/* Return a pointer to section NAME, or NULL if no such section exists. */
479
480static Elf_Internal_Shdr *
2cf0635d 481find_section (const char * name)
89fac5e3
RS
482{
483 unsigned int i;
484
485 for (i = 0; i < elf_header.e_shnum; i++)
486 if (streq (SECTION_NAME (section_headers + i), name))
487 return section_headers + i;
488
489 return NULL;
490}
491
0b6ae522
DJ
492/* Return a pointer to a section containing ADDR, or NULL if no such
493 section exists. */
494
495static Elf_Internal_Shdr *
496find_section_by_address (bfd_vma addr)
497{
498 unsigned int i;
499
500 for (i = 0; i < elf_header.e_shnum; i++)
501 {
502 Elf_Internal_Shdr *sec = section_headers + i;
503 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
504 return sec;
505 }
506
507 return NULL;
508}
509
510/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
511 bytes read. */
512
513static unsigned long
514read_uleb128 (unsigned char *data, unsigned int *length_return)
515{
516 return read_leb128 (data, length_return, 0);
517}
518
28f997cf
TG
519/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
520 This OS has so many departures from the ELF standard that we test it at
521 many places. */
522
523static inline int
524is_ia64_vms (void)
525{
526 return elf_header.e_machine == EM_IA_64
527 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
528}
529
bcedfee6 530/* Guess the relocation size commonly used by the specific machines. */
252b5132 531
252b5132 532static int
2dc4cec1 533guess_is_rela (unsigned int e_machine)
252b5132 534{
9c19a809 535 switch (e_machine)
252b5132
RH
536 {
537 /* Targets that use REL relocations. */
252b5132
RH
538 case EM_386:
539 case EM_486:
63fcb9e9 540 case EM_960:
e9f53129 541 case EM_ARM:
2b0337b0 542 case EM_D10V:
252b5132 543 case EM_CYGNUS_D10V:
e9f53129 544 case EM_DLX:
252b5132 545 case EM_MIPS:
4fe85591 546 case EM_MIPS_RS3_LE:
e9f53129
AM
547 case EM_CYGNUS_M32R:
548 case EM_OPENRISC:
549 case EM_OR32:
1c0d3aa6 550 case EM_SCORE:
f6c1a2d5 551 case EM_XGATE:
9c19a809 552 return FALSE;
103f02d3 553
252b5132
RH
554 /* Targets that use RELA relocations. */
555 case EM_68K:
e9f53129 556 case EM_860:
cfb8c092 557 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
558 case EM_ALPHA:
559 case EM_ALTERA_NIOS2:
560 case EM_AVR:
561 case EM_AVR_OLD:
562 case EM_BLACKFIN:
60bca95a 563 case EM_CR16:
e9f53129
AM
564 case EM_CRIS:
565 case EM_CRX:
2b0337b0 566 case EM_D30V:
252b5132 567 case EM_CYGNUS_D30V:
2b0337b0 568 case EM_FR30:
252b5132 569 case EM_CYGNUS_FR30:
5c70f934 570 case EM_CYGNUS_FRV:
e9f53129
AM
571 case EM_H8S:
572 case EM_H8_300:
573 case EM_H8_300H:
800eeca4 574 case EM_IA_64:
1e4cf259
NC
575 case EM_IP2K:
576 case EM_IP2K_OLD:
3b36097d 577 case EM_IQ2000:
84e94c90 578 case EM_LATTICEMICO32:
ff7eeb89 579 case EM_M32C_OLD:
49f58d10 580 case EM_M32C:
e9f53129
AM
581 case EM_M32R:
582 case EM_MCORE:
15ab5209 583 case EM_CYGNUS_MEP:
e9f53129
AM
584 case EM_MMIX:
585 case EM_MN10200:
586 case EM_CYGNUS_MN10200:
587 case EM_MN10300:
588 case EM_CYGNUS_MN10300:
5506d11a 589 case EM_MOXIE:
e9f53129
AM
590 case EM_MSP430:
591 case EM_MSP430_OLD:
d031aafb 592 case EM_MT:
64fd6348 593 case EM_NIOS32:
e9f53129
AM
594 case EM_PPC64:
595 case EM_PPC:
99c513f6 596 case EM_RL78:
c7927a3c 597 case EM_RX:
e9f53129
AM
598 case EM_S390:
599 case EM_S390_OLD:
600 case EM_SH:
601 case EM_SPARC:
602 case EM_SPARC32PLUS:
603 case EM_SPARCV9:
604 case EM_SPU:
40b36596 605 case EM_TI_C6000:
aa137e4d
NC
606 case EM_TILEGX:
607 case EM_TILEPRO:
e9f53129
AM
608 case EM_V850:
609 case EM_CYGNUS_V850:
610 case EM_VAX:
611 case EM_X86_64:
8a9036a4 612 case EM_L1OM:
7a9068fe 613 case EM_K1OM:
e9f53129
AM
614 case EM_XSTORMY16:
615 case EM_XTENSA:
616 case EM_XTENSA_OLD:
7ba29e2a
NC
617 case EM_MICROBLAZE:
618 case EM_MICROBLAZE_OLD:
9c19a809 619 return TRUE;
103f02d3 620
e9f53129
AM
621 case EM_68HC05:
622 case EM_68HC08:
623 case EM_68HC11:
624 case EM_68HC16:
625 case EM_FX66:
626 case EM_ME16:
d1133906 627 case EM_MMA:
d1133906
NC
628 case EM_NCPU:
629 case EM_NDR1:
e9f53129 630 case EM_PCP:
d1133906 631 case EM_ST100:
e9f53129 632 case EM_ST19:
d1133906 633 case EM_ST7:
e9f53129
AM
634 case EM_ST9PLUS:
635 case EM_STARCORE:
d1133906 636 case EM_SVX:
e9f53129 637 case EM_TINYJ:
9c19a809
NC
638 default:
639 warn (_("Don't know about relocations on this machine architecture\n"));
640 return FALSE;
641 }
642}
252b5132 643
9c19a809 644static int
2cf0635d 645slurp_rela_relocs (FILE * file,
d3ba0551
AM
646 unsigned long rel_offset,
647 unsigned long rel_size,
2cf0635d
NC
648 Elf_Internal_Rela ** relasp,
649 unsigned long * nrelasp)
9c19a809 650{
2cf0635d 651 Elf_Internal_Rela * relas;
4d6ed7c8
NC
652 unsigned long nrelas;
653 unsigned int i;
252b5132 654
4d6ed7c8
NC
655 if (is_32bit_elf)
656 {
2cf0635d 657 Elf32_External_Rela * erelas;
103f02d3 658
3f5e193b 659 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 660 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
661 if (!erelas)
662 return 0;
252b5132 663
4d6ed7c8 664 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 665
3f5e193b
NC
666 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
667 sizeof (Elf_Internal_Rela));
103f02d3 668
4d6ed7c8
NC
669 if (relas == NULL)
670 {
c256ffe7 671 free (erelas);
591a748a 672 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
673 return 0;
674 }
103f02d3 675
4d6ed7c8
NC
676 for (i = 0; i < nrelas; i++)
677 {
678 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
679 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 680 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 681 }
103f02d3 682
4d6ed7c8
NC
683 free (erelas);
684 }
685 else
686 {
2cf0635d 687 Elf64_External_Rela * erelas;
103f02d3 688
3f5e193b 689 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 690 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
691 if (!erelas)
692 return 0;
4d6ed7c8
NC
693
694 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 695
3f5e193b
NC
696 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
697 sizeof (Elf_Internal_Rela));
103f02d3 698
4d6ed7c8
NC
699 if (relas == NULL)
700 {
c256ffe7 701 free (erelas);
591a748a 702 error (_("out of memory parsing relocs\n"));
4d6ed7c8 703 return 0;
9c19a809 704 }
4d6ed7c8
NC
705
706 for (i = 0; i < nrelas; i++)
9c19a809 707 {
66543521
AM
708 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
709 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 710 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
711
712 /* The #ifdef BFD64 below is to prevent a compile time
713 warning. We know that if we do not have a 64 bit data
714 type that we will never execute this code anyway. */
715#ifdef BFD64
716 if (elf_header.e_machine == EM_MIPS
717 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
718 {
719 /* In little-endian objects, r_info isn't really a
720 64-bit little-endian value: it has a 32-bit
721 little-endian symbol index followed by four
722 individual byte fields. Reorder INFO
723 accordingly. */
91d6fa6a
NC
724 bfd_vma inf = relas[i].r_info;
725 inf = (((inf & 0xffffffff) << 32)
726 | ((inf >> 56) & 0xff)
727 | ((inf >> 40) & 0xff00)
728 | ((inf >> 24) & 0xff0000)
729 | ((inf >> 8) & 0xff000000));
730 relas[i].r_info = inf;
861fb55a
DJ
731 }
732#endif /* BFD64 */
4d6ed7c8 733 }
103f02d3 734
4d6ed7c8
NC
735 free (erelas);
736 }
737 *relasp = relas;
738 *nrelasp = nrelas;
739 return 1;
740}
103f02d3 741
4d6ed7c8 742static int
2cf0635d 743slurp_rel_relocs (FILE * file,
d3ba0551
AM
744 unsigned long rel_offset,
745 unsigned long rel_size,
2cf0635d
NC
746 Elf_Internal_Rela ** relsp,
747 unsigned long * nrelsp)
4d6ed7c8 748{
2cf0635d 749 Elf_Internal_Rela * rels;
4d6ed7c8
NC
750 unsigned long nrels;
751 unsigned int i;
103f02d3 752
4d6ed7c8
NC
753 if (is_32bit_elf)
754 {
2cf0635d 755 Elf32_External_Rel * erels;
103f02d3 756
3f5e193b 757 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 758 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
759 if (!erels)
760 return 0;
103f02d3 761
4d6ed7c8 762 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 763
3f5e193b 764 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 765
4d6ed7c8
NC
766 if (rels == NULL)
767 {
c256ffe7 768 free (erels);
591a748a 769 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
770 return 0;
771 }
772
773 for (i = 0; i < nrels; i++)
774 {
775 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
776 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 777 rels[i].r_addend = 0;
9ea033b2 778 }
4d6ed7c8
NC
779
780 free (erels);
9c19a809
NC
781 }
782 else
783 {
2cf0635d 784 Elf64_External_Rel * erels;
9ea033b2 785
3f5e193b 786 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 787 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
788 if (!erels)
789 return 0;
103f02d3 790
4d6ed7c8 791 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 792
3f5e193b 793 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 794
4d6ed7c8 795 if (rels == NULL)
9c19a809 796 {
c256ffe7 797 free (erels);
591a748a 798 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
799 return 0;
800 }
103f02d3 801
4d6ed7c8
NC
802 for (i = 0; i < nrels; i++)
803 {
66543521
AM
804 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
805 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 806 rels[i].r_addend = 0;
861fb55a
DJ
807
808 /* The #ifdef BFD64 below is to prevent a compile time
809 warning. We know that if we do not have a 64 bit data
810 type that we will never execute this code anyway. */
811#ifdef BFD64
812 if (elf_header.e_machine == EM_MIPS
813 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
814 {
815 /* In little-endian objects, r_info isn't really a
816 64-bit little-endian value: it has a 32-bit
817 little-endian symbol index followed by four
818 individual byte fields. Reorder INFO
819 accordingly. */
91d6fa6a
NC
820 bfd_vma inf = rels[i].r_info;
821 inf = (((inf & 0xffffffff) << 32)
822 | ((inf >> 56) & 0xff)
823 | ((inf >> 40) & 0xff00)
824 | ((inf >> 24) & 0xff0000)
825 | ((inf >> 8) & 0xff000000));
826 rels[i].r_info = inf;
861fb55a
DJ
827 }
828#endif /* BFD64 */
4d6ed7c8 829 }
103f02d3 830
4d6ed7c8
NC
831 free (erels);
832 }
833 *relsp = rels;
834 *nrelsp = nrels;
835 return 1;
836}
103f02d3 837
aca88567
NC
838/* Returns the reloc type extracted from the reloc info field. */
839
840static unsigned int
841get_reloc_type (bfd_vma reloc_info)
842{
843 if (is_32bit_elf)
844 return ELF32_R_TYPE (reloc_info);
845
846 switch (elf_header.e_machine)
847 {
848 case EM_MIPS:
849 /* Note: We assume that reloc_info has already been adjusted for us. */
850 return ELF64_MIPS_R_TYPE (reloc_info);
851
852 case EM_SPARCV9:
853 return ELF64_R_TYPE_ID (reloc_info);
854
855 default:
856 return ELF64_R_TYPE (reloc_info);
857 }
858}
859
860/* Return the symbol index extracted from the reloc info field. */
861
862static bfd_vma
863get_reloc_symindex (bfd_vma reloc_info)
864{
865 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
866}
867
d3ba0551
AM
868/* Display the contents of the relocation data found at the specified
869 offset. */
ee42cf8c 870
41e92641 871static void
2cf0635d 872dump_relocations (FILE * file,
d3ba0551
AM
873 unsigned long rel_offset,
874 unsigned long rel_size,
2cf0635d 875 Elf_Internal_Sym * symtab,
d3ba0551 876 unsigned long nsyms,
2cf0635d 877 char * strtab,
d79b3d50 878 unsigned long strtablen,
d3ba0551 879 int is_rela)
4d6ed7c8 880{
b34976b6 881 unsigned int i;
2cf0635d 882 Elf_Internal_Rela * rels;
103f02d3 883
4d6ed7c8
NC
884 if (is_rela == UNKNOWN)
885 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 886
4d6ed7c8
NC
887 if (is_rela)
888 {
c8286bd1 889 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 890 return;
4d6ed7c8
NC
891 }
892 else
893 {
894 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 895 return;
252b5132
RH
896 }
897
410f7a12
L
898 if (is_32bit_elf)
899 {
900 if (is_rela)
2c71103e
NC
901 {
902 if (do_wide)
903 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
904 else
905 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
906 }
410f7a12 907 else
2c71103e
NC
908 {
909 if (do_wide)
910 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
911 else
912 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
913 }
410f7a12 914 }
252b5132 915 else
410f7a12
L
916 {
917 if (is_rela)
2c71103e
NC
918 {
919 if (do_wide)
8beeaeb7 920 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
921 else
922 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
923 }
410f7a12 924 else
2c71103e
NC
925 {
926 if (do_wide)
8beeaeb7 927 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
928 else
929 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
930 }
410f7a12 931 }
252b5132
RH
932
933 for (i = 0; i < rel_size; i++)
934 {
2cf0635d 935 const char * rtype;
b34976b6 936 bfd_vma offset;
91d6fa6a 937 bfd_vma inf;
b34976b6
AM
938 bfd_vma symtab_index;
939 bfd_vma type;
103f02d3 940
b34976b6 941 offset = rels[i].r_offset;
91d6fa6a 942 inf = rels[i].r_info;
103f02d3 943
91d6fa6a
NC
944 type = get_reloc_type (inf);
945 symtab_index = get_reloc_symindex (inf);
252b5132 946
410f7a12
L
947 if (is_32bit_elf)
948 {
39dbeff8
AM
949 printf ("%8.8lx %8.8lx ",
950 (unsigned long) offset & 0xffffffff,
91d6fa6a 951 (unsigned long) inf & 0xffffffff);
410f7a12
L
952 }
953 else
954 {
39dbeff8
AM
955#if BFD_HOST_64BIT_LONG
956 printf (do_wide
957 ? "%16.16lx %16.16lx "
958 : "%12.12lx %12.12lx ",
91d6fa6a 959 offset, inf);
39dbeff8 960#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 961#ifndef __MSVCRT__
39dbeff8
AM
962 printf (do_wide
963 ? "%16.16llx %16.16llx "
964 : "%12.12llx %12.12llx ",
91d6fa6a 965 offset, inf);
6e3d6dc1
NC
966#else
967 printf (do_wide
968 ? "%16.16I64x %16.16I64x "
969 : "%12.12I64x %12.12I64x ",
91d6fa6a 970 offset, inf);
6e3d6dc1 971#endif
39dbeff8 972#else
2c71103e
NC
973 printf (do_wide
974 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
975 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
976 _bfd_int64_high (offset),
977 _bfd_int64_low (offset),
91d6fa6a
NC
978 _bfd_int64_high (inf),
979 _bfd_int64_low (inf));
9ea033b2 980#endif
410f7a12 981 }
103f02d3 982
252b5132
RH
983 switch (elf_header.e_machine)
984 {
985 default:
986 rtype = NULL;
987 break;
988
2b0337b0 989 case EM_M32R:
252b5132 990 case EM_CYGNUS_M32R:
9ea033b2 991 rtype = elf_m32r_reloc_type (type);
252b5132
RH
992 break;
993
994 case EM_386:
995 case EM_486:
9ea033b2 996 rtype = elf_i386_reloc_type (type);
252b5132
RH
997 break;
998
ba2685cc
AM
999 case EM_68HC11:
1000 case EM_68HC12:
1001 rtype = elf_m68hc11_reloc_type (type);
1002 break;
75751cd9 1003
252b5132 1004 case EM_68K:
9ea033b2 1005 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1006 break;
1007
63fcb9e9 1008 case EM_960:
9ea033b2 1009 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1010 break;
1011
adde6300 1012 case EM_AVR:
2b0337b0 1013 case EM_AVR_OLD:
adde6300
AM
1014 rtype = elf_avr_reloc_type (type);
1015 break;
1016
9ea033b2
NC
1017 case EM_OLD_SPARCV9:
1018 case EM_SPARC32PLUS:
1019 case EM_SPARCV9:
252b5132 1020 case EM_SPARC:
9ea033b2 1021 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1022 break;
1023
e9f53129
AM
1024 case EM_SPU:
1025 rtype = elf_spu_reloc_type (type);
1026 break;
1027
2b0337b0 1028 case EM_V850:
252b5132 1029 case EM_CYGNUS_V850:
9ea033b2 1030 rtype = v850_reloc_type (type);
252b5132
RH
1031 break;
1032
2b0337b0 1033 case EM_D10V:
252b5132 1034 case EM_CYGNUS_D10V:
9ea033b2 1035 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1036 break;
1037
2b0337b0 1038 case EM_D30V:
252b5132 1039 case EM_CYGNUS_D30V:
9ea033b2 1040 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1041 break;
1042
d172d4ba
NC
1043 case EM_DLX:
1044 rtype = elf_dlx_reloc_type (type);
1045 break;
1046
252b5132 1047 case EM_SH:
9ea033b2 1048 rtype = elf_sh_reloc_type (type);
252b5132
RH
1049 break;
1050
2b0337b0 1051 case EM_MN10300:
252b5132 1052 case EM_CYGNUS_MN10300:
9ea033b2 1053 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1054 break;
1055
2b0337b0 1056 case EM_MN10200:
252b5132 1057 case EM_CYGNUS_MN10200:
9ea033b2 1058 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1059 break;
1060
2b0337b0 1061 case EM_FR30:
252b5132 1062 case EM_CYGNUS_FR30:
9ea033b2 1063 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1064 break;
1065
ba2685cc
AM
1066 case EM_CYGNUS_FRV:
1067 rtype = elf_frv_reloc_type (type);
1068 break;
5c70f934 1069
252b5132 1070 case EM_MCORE:
9ea033b2 1071 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1072 break;
1073
3c3bdf30
NC
1074 case EM_MMIX:
1075 rtype = elf_mmix_reloc_type (type);
1076 break;
1077
5506d11a
AM
1078 case EM_MOXIE:
1079 rtype = elf_moxie_reloc_type (type);
1080 break;
1081
2469cfa2
NC
1082 case EM_MSP430:
1083 case EM_MSP430_OLD:
1084 rtype = elf_msp430_reloc_type (type);
1085 break;
1086
252b5132 1087 case EM_PPC:
9ea033b2 1088 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1089 break;
1090
c833c019
AM
1091 case EM_PPC64:
1092 rtype = elf_ppc64_reloc_type (type);
1093 break;
1094
252b5132 1095 case EM_MIPS:
4fe85591 1096 case EM_MIPS_RS3_LE:
9ea033b2 1097 rtype = elf_mips_reloc_type (type);
252b5132
RH
1098 break;
1099
1100 case EM_ALPHA:
9ea033b2 1101 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1102 break;
1103
1104 case EM_ARM:
9ea033b2 1105 rtype = elf_arm_reloc_type (type);
252b5132
RH
1106 break;
1107
584da044 1108 case EM_ARC:
9ea033b2 1109 rtype = elf_arc_reloc_type (type);
252b5132
RH
1110 break;
1111
1112 case EM_PARISC:
69e617ca 1113 rtype = elf_hppa_reloc_type (type);
252b5132 1114 break;
7d466069 1115
b8720f9d
JL
1116 case EM_H8_300:
1117 case EM_H8_300H:
1118 case EM_H8S:
1119 rtype = elf_h8_reloc_type (type);
1120 break;
1121
3b16e843
NC
1122 case EM_OPENRISC:
1123 case EM_OR32:
1124 rtype = elf_or32_reloc_type (type);
1125 break;
1126
7d466069 1127 case EM_PJ:
2b0337b0 1128 case EM_PJ_OLD:
7d466069
ILT
1129 rtype = elf_pj_reloc_type (type);
1130 break;
800eeca4
JW
1131 case EM_IA_64:
1132 rtype = elf_ia64_reloc_type (type);
1133 break;
1b61cf92
HPN
1134
1135 case EM_CRIS:
1136 rtype = elf_cris_reloc_type (type);
1137 break;
535c37ff
JE
1138
1139 case EM_860:
1140 rtype = elf_i860_reloc_type (type);
1141 break;
bcedfee6
NC
1142
1143 case EM_X86_64:
8a9036a4 1144 case EM_L1OM:
7a9068fe 1145 case EM_K1OM:
bcedfee6
NC
1146 rtype = elf_x86_64_reloc_type (type);
1147 break;
a85d7ed0 1148
35b1837e
AM
1149 case EM_S370:
1150 rtype = i370_reloc_type (type);
1151 break;
1152
53c7db4b
KH
1153 case EM_S390_OLD:
1154 case EM_S390:
1155 rtype = elf_s390_reloc_type (type);
1156 break;
93fbbb04 1157
1c0d3aa6
NC
1158 case EM_SCORE:
1159 rtype = elf_score_reloc_type (type);
1160 break;
1161
93fbbb04
GK
1162 case EM_XSTORMY16:
1163 rtype = elf_xstormy16_reloc_type (type);
1164 break;
179d3252 1165
1fe1f39c
NC
1166 case EM_CRX:
1167 rtype = elf_crx_reloc_type (type);
1168 break;
1169
179d3252
JT
1170 case EM_VAX:
1171 rtype = elf_vax_reloc_type (type);
1172 break;
1e4cf259 1173
cfb8c092
NC
1174 case EM_ADAPTEVA_EPIPHANY:
1175 rtype = elf_epiphany_reloc_type (type);
1176 break;
1177
1e4cf259
NC
1178 case EM_IP2K:
1179 case EM_IP2K_OLD:
1180 rtype = elf_ip2k_reloc_type (type);
1181 break;
3b36097d
SC
1182
1183 case EM_IQ2000:
1184 rtype = elf_iq2000_reloc_type (type);
1185 break;
88da6820
NC
1186
1187 case EM_XTENSA_OLD:
1188 case EM_XTENSA:
1189 rtype = elf_xtensa_reloc_type (type);
1190 break;
a34e3ecb 1191
84e94c90
NC
1192 case EM_LATTICEMICO32:
1193 rtype = elf_lm32_reloc_type (type);
1194 break;
1195
ff7eeb89 1196 case EM_M32C_OLD:
49f58d10
JB
1197 case EM_M32C:
1198 rtype = elf_m32c_reloc_type (type);
1199 break;
1200
d031aafb
NS
1201 case EM_MT:
1202 rtype = elf_mt_reloc_type (type);
a34e3ecb 1203 break;
1d65ded4
CM
1204
1205 case EM_BLACKFIN:
1206 rtype = elf_bfin_reloc_type (type);
1207 break;
15ab5209
DB
1208
1209 case EM_CYGNUS_MEP:
1210 rtype = elf_mep_reloc_type (type);
1211 break;
60bca95a
NC
1212
1213 case EM_CR16:
1214 rtype = elf_cr16_reloc_type (type);
1215 break;
dd24e3da 1216
7ba29e2a
NC
1217 case EM_MICROBLAZE:
1218 case EM_MICROBLAZE_OLD:
1219 rtype = elf_microblaze_reloc_type (type);
1220 break;
c7927a3c 1221
99c513f6
DD
1222 case EM_RL78:
1223 rtype = elf_rl78_reloc_type (type);
1224 break;
1225
c7927a3c
NC
1226 case EM_RX:
1227 rtype = elf_rx_reloc_type (type);
1228 break;
c29aca4a
NC
1229
1230 case EM_XC16X:
1231 case EM_C166:
1232 rtype = elf_xc16x_reloc_type (type);
1233 break;
40b36596
JM
1234
1235 case EM_TI_C6000:
1236 rtype = elf_tic6x_reloc_type (type);
1237 break;
aa137e4d
NC
1238
1239 case EM_TILEGX:
1240 rtype = elf_tilegx_reloc_type (type);
1241 break;
1242
1243 case EM_TILEPRO:
1244 rtype = elf_tilepro_reloc_type (type);
1245 break;
f6c1a2d5
NC
1246
1247 case EM_XGATE:
1248 rtype = elf_xgate_reloc_type (type);
1249 break;
252b5132
RH
1250 }
1251
1252 if (rtype == NULL)
39dbeff8 1253 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1254 else
8beeaeb7 1255 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1256
7ace3541 1257 if (elf_header.e_machine == EM_ALPHA
157c2599 1258 && rtype != NULL
7ace3541
RH
1259 && streq (rtype, "R_ALPHA_LITUSE")
1260 && is_rela)
1261 {
1262 switch (rels[i].r_addend)
1263 {
1264 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1265 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1266 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1267 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1268 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1269 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1270 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1271 default: rtype = NULL;
1272 }
1273 if (rtype)
1274 printf (" (%s)", rtype);
1275 else
1276 {
1277 putchar (' ');
1278 printf (_("<unknown addend: %lx>"),
1279 (unsigned long) rels[i].r_addend);
1280 }
1281 }
1282 else if (symtab_index)
252b5132 1283 {
af3fc3bc 1284 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1285 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1286 else
19936277 1287 {
2cf0635d 1288 Elf_Internal_Sym * psym;
19936277 1289
af3fc3bc 1290 psym = symtab + symtab_index;
103f02d3 1291
af3fc3bc 1292 printf (" ");
171191ba 1293
d8045f23
NC
1294 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1295 {
1296 const char * name;
1297 unsigned int len;
1298 unsigned int width = is_32bit_elf ? 8 : 14;
1299
1300 /* Relocations against GNU_IFUNC symbols do not use the value
1301 of the symbol as the address to relocate against. Instead
1302 they invoke the function named by the symbol and use its
1303 result as the address for relocation.
1304
1305 To indicate this to the user, do not display the value of
1306 the symbol in the "Symbols's Value" field. Instead show
1307 its name followed by () as a hint that the symbol is
1308 invoked. */
1309
1310 if (strtab == NULL
1311 || psym->st_name == 0
1312 || psym->st_name >= strtablen)
1313 name = "??";
1314 else
1315 name = strtab + psym->st_name;
1316
1317 len = print_symbol (width, name);
1318 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1319 }
1320 else
1321 {
1322 print_vma (psym->st_value, LONG_HEX);
171191ba 1323
d8045f23
NC
1324 printf (is_32bit_elf ? " " : " ");
1325 }
103f02d3 1326
af3fc3bc 1327 if (psym->st_name == 0)
f1ef08cb 1328 {
2cf0635d 1329 const char * sec_name = "<null>";
f1ef08cb
AM
1330 char name_buf[40];
1331
1332 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1333 {
4fbb74a6
AM
1334 if (psym->st_shndx < elf_header.e_shnum)
1335 sec_name
1336 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1337 else if (psym->st_shndx == SHN_ABS)
1338 sec_name = "ABS";
1339 else if (psym->st_shndx == SHN_COMMON)
1340 sec_name = "COMMON";
ac145307
BS
1341 else if ((elf_header.e_machine == EM_MIPS
1342 && psym->st_shndx == SHN_MIPS_SCOMMON)
1343 || (elf_header.e_machine == EM_TI_C6000
1344 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1345 sec_name = "SCOMMON";
1346 else if (elf_header.e_machine == EM_MIPS
1347 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1348 sec_name = "SUNDEF";
8a9036a4 1349 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1350 || elf_header.e_machine == EM_L1OM
1351 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1352 && psym->st_shndx == SHN_X86_64_LCOMMON)
1353 sec_name = "LARGE_COMMON";
9ce701e2
L
1354 else if (elf_header.e_machine == EM_IA_64
1355 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1356 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1357 sec_name = "ANSI_COM";
28f997cf 1358 else if (is_ia64_vms ()
148b93f2
NC
1359 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1360 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1361 else
1362 {
1363 sprintf (name_buf, "<section 0x%x>",
1364 (unsigned int) psym->st_shndx);
1365 sec_name = name_buf;
1366 }
1367 }
1368 print_symbol (22, sec_name);
1369 }
af3fc3bc 1370 else if (strtab == NULL)
d79b3d50 1371 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1372 else if (psym->st_name >= strtablen)
d79b3d50 1373 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1374 else
2c71103e 1375 print_symbol (22, strtab + psym->st_name);
103f02d3 1376
af3fc3bc 1377 if (is_rela)
171191ba 1378 {
598aaa76 1379 bfd_signed_vma off = rels[i].r_addend;
171191ba 1380
91d6fa6a 1381 if (off < 0)
598aaa76 1382 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1383 else
598aaa76 1384 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1385 }
19936277 1386 }
252b5132 1387 }
1b228002 1388 else if (is_rela)
f7a99963 1389 {
e04d7088
L
1390 bfd_signed_vma off = rels[i].r_addend;
1391
1392 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1393 if (off < 0)
1394 printf ("-%" BFD_VMA_FMT "x", - off);
1395 else
1396 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1397 }
252b5132 1398
157c2599
NC
1399 if (elf_header.e_machine == EM_SPARCV9
1400 && rtype != NULL
1401 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1402 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1403
252b5132 1404 putchar ('\n');
2c71103e 1405
aca88567 1406#ifdef BFD64
53c7db4b 1407 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1408 {
91d6fa6a
NC
1409 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1410 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1411 const char * rtype2 = elf_mips_reloc_type (type2);
1412 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1413
2c71103e
NC
1414 printf (" Type2: ");
1415
1416 if (rtype2 == NULL)
39dbeff8
AM
1417 printf (_("unrecognized: %-7lx"),
1418 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1419 else
1420 printf ("%-17.17s", rtype2);
1421
18bd398b 1422 printf ("\n Type3: ");
2c71103e
NC
1423
1424 if (rtype3 == NULL)
39dbeff8
AM
1425 printf (_("unrecognized: %-7lx"),
1426 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1427 else
1428 printf ("%-17.17s", rtype3);
1429
53c7db4b 1430 putchar ('\n');
2c71103e 1431 }
aca88567 1432#endif /* BFD64 */
252b5132
RH
1433 }
1434
c8286bd1 1435 free (rels);
252b5132
RH
1436}
1437
1438static const char *
d3ba0551 1439get_mips_dynamic_type (unsigned long type)
252b5132
RH
1440{
1441 switch (type)
1442 {
1443 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1444 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1445 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1446 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1447 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1448 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1449 case DT_MIPS_MSYM: return "MIPS_MSYM";
1450 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1451 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1452 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1453 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1454 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1455 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1456 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1457 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1458 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1459 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1460 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1461 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1462 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1463 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1464 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1465 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1466 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1467 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1468 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1469 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1470 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1471 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1472 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1473 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1474 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1475 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1476 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1477 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1478 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1479 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1480 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1481 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1482 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1483 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1484 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1485 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1486 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1487 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1488 default:
1489 return NULL;
1490 }
1491}
1492
9a097730 1493static const char *
d3ba0551 1494get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1495{
1496 switch (type)
1497 {
1498 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1499 default:
1500 return NULL;
1501 }
103f02d3
UD
1502}
1503
7490d522
AM
1504static const char *
1505get_ppc_dynamic_type (unsigned long type)
1506{
1507 switch (type)
1508 {
a7f2871e
AM
1509 case DT_PPC_GOT: return "PPC_GOT";
1510 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1511 default:
1512 return NULL;
1513 }
1514}
1515
f1cb7e17 1516static const char *
d3ba0551 1517get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1518{
1519 switch (type)
1520 {
a7f2871e
AM
1521 case DT_PPC64_GLINK: return "PPC64_GLINK";
1522 case DT_PPC64_OPD: return "PPC64_OPD";
1523 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1524 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1525 default:
1526 return NULL;
1527 }
1528}
1529
103f02d3 1530static const char *
d3ba0551 1531get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1532{
1533 switch (type)
1534 {
1535 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1536 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1537 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1538 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1539 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1540 case DT_HP_PREINIT: return "HP_PREINIT";
1541 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1542 case DT_HP_NEEDED: return "HP_NEEDED";
1543 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1544 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1545 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1546 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1547 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1548 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1549 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1550 case DT_HP_FILTERED: return "HP_FILTERED";
1551 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1552 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1553 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1554 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1555 case DT_PLT: return "PLT";
1556 case DT_PLT_SIZE: return "PLT_SIZE";
1557 case DT_DLT: return "DLT";
1558 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1559 default:
1560 return NULL;
1561 }
1562}
9a097730 1563
ecc51f48 1564static const char *
d3ba0551 1565get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1566{
1567 switch (type)
1568 {
148b93f2
NC
1569 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1570 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1571 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1572 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1573 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1574 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1575 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1576 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1577 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1578 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1579 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1580 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1581 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1582 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1583 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1584 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1585 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1586 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1587 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1588 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1589 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1590 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1591 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1592 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1593 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1594 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1595 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1596 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1597 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1598 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1599 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1600 default:
1601 return NULL;
1602 }
1603}
1604
fabcb361
RH
1605static const char *
1606get_alpha_dynamic_type (unsigned long type)
1607{
1608 switch (type)
1609 {
1610 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1611 default:
1612 return NULL;
1613 }
1614}
1615
1c0d3aa6
NC
1616static const char *
1617get_score_dynamic_type (unsigned long type)
1618{
1619 switch (type)
1620 {
1621 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1622 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1623 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1624 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1625 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1626 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1627 default:
1628 return NULL;
1629 }
1630}
1631
40b36596
JM
1632static const char *
1633get_tic6x_dynamic_type (unsigned long type)
1634{
1635 switch (type)
1636 {
1637 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1638 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1639 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1640 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1641 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1642 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1643 default:
1644 return NULL;
1645 }
1646}
1c0d3aa6 1647
252b5132 1648static const char *
d3ba0551 1649get_dynamic_type (unsigned long type)
252b5132 1650{
e9e44622 1651 static char buff[64];
252b5132
RH
1652
1653 switch (type)
1654 {
1655 case DT_NULL: return "NULL";
1656 case DT_NEEDED: return "NEEDED";
1657 case DT_PLTRELSZ: return "PLTRELSZ";
1658 case DT_PLTGOT: return "PLTGOT";
1659 case DT_HASH: return "HASH";
1660 case DT_STRTAB: return "STRTAB";
1661 case DT_SYMTAB: return "SYMTAB";
1662 case DT_RELA: return "RELA";
1663 case DT_RELASZ: return "RELASZ";
1664 case DT_RELAENT: return "RELAENT";
1665 case DT_STRSZ: return "STRSZ";
1666 case DT_SYMENT: return "SYMENT";
1667 case DT_INIT: return "INIT";
1668 case DT_FINI: return "FINI";
1669 case DT_SONAME: return "SONAME";
1670 case DT_RPATH: return "RPATH";
1671 case DT_SYMBOLIC: return "SYMBOLIC";
1672 case DT_REL: return "REL";
1673 case DT_RELSZ: return "RELSZ";
1674 case DT_RELENT: return "RELENT";
1675 case DT_PLTREL: return "PLTREL";
1676 case DT_DEBUG: return "DEBUG";
1677 case DT_TEXTREL: return "TEXTREL";
1678 case DT_JMPREL: return "JMPREL";
1679 case DT_BIND_NOW: return "BIND_NOW";
1680 case DT_INIT_ARRAY: return "INIT_ARRAY";
1681 case DT_FINI_ARRAY: return "FINI_ARRAY";
1682 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1683 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1684 case DT_RUNPATH: return "RUNPATH";
1685 case DT_FLAGS: return "FLAGS";
2d0e6f43 1686
d1133906
NC
1687 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1688 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1689
05107a46 1690 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1691 case DT_PLTPADSZ: return "PLTPADSZ";
1692 case DT_MOVEENT: return "MOVEENT";
1693 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1694 case DT_FEATURE: return "FEATURE";
252b5132
RH
1695 case DT_POSFLAG_1: return "POSFLAG_1";
1696 case DT_SYMINSZ: return "SYMINSZ";
1697 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1698
252b5132 1699 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1700 case DT_CONFIG: return "CONFIG";
1701 case DT_DEPAUDIT: return "DEPAUDIT";
1702 case DT_AUDIT: return "AUDIT";
1703 case DT_PLTPAD: return "PLTPAD";
1704 case DT_MOVETAB: return "MOVETAB";
252b5132 1705 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1706
252b5132 1707 case DT_VERSYM: return "VERSYM";
103f02d3 1708
67a4f2b7
AO
1709 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1710 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1711 case DT_RELACOUNT: return "RELACOUNT";
1712 case DT_RELCOUNT: return "RELCOUNT";
1713 case DT_FLAGS_1: return "FLAGS_1";
1714 case DT_VERDEF: return "VERDEF";
1715 case DT_VERDEFNUM: return "VERDEFNUM";
1716 case DT_VERNEED: return "VERNEED";
1717 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1718
019148e4 1719 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1720 case DT_USED: return "USED";
1721 case DT_FILTER: return "FILTER";
103f02d3 1722
047b2264
JJ
1723 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1724 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1725 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1726 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1727 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1728 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1729
252b5132
RH
1730 default:
1731 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1732 {
2cf0635d 1733 const char * result;
103f02d3 1734
252b5132
RH
1735 switch (elf_header.e_machine)
1736 {
1737 case EM_MIPS:
4fe85591 1738 case EM_MIPS_RS3_LE:
252b5132
RH
1739 result = get_mips_dynamic_type (type);
1740 break;
9a097730
RH
1741 case EM_SPARCV9:
1742 result = get_sparc64_dynamic_type (type);
1743 break;
7490d522
AM
1744 case EM_PPC:
1745 result = get_ppc_dynamic_type (type);
1746 break;
f1cb7e17
AM
1747 case EM_PPC64:
1748 result = get_ppc64_dynamic_type (type);
1749 break;
ecc51f48
NC
1750 case EM_IA_64:
1751 result = get_ia64_dynamic_type (type);
1752 break;
fabcb361
RH
1753 case EM_ALPHA:
1754 result = get_alpha_dynamic_type (type);
1755 break;
1c0d3aa6
NC
1756 case EM_SCORE:
1757 result = get_score_dynamic_type (type);
1758 break;
40b36596
JM
1759 case EM_TI_C6000:
1760 result = get_tic6x_dynamic_type (type);
1761 break;
252b5132
RH
1762 default:
1763 result = NULL;
1764 break;
1765 }
1766
1767 if (result != NULL)
1768 return result;
1769
e9e44622 1770 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1771 }
eec8f817
DA
1772 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1773 || (elf_header.e_machine == EM_PARISC
1774 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1775 {
2cf0635d 1776 const char * result;
103f02d3
UD
1777
1778 switch (elf_header.e_machine)
1779 {
1780 case EM_PARISC:
1781 result = get_parisc_dynamic_type (type);
1782 break;
148b93f2
NC
1783 case EM_IA_64:
1784 result = get_ia64_dynamic_type (type);
1785 break;
103f02d3
UD
1786 default:
1787 result = NULL;
1788 break;
1789 }
1790
1791 if (result != NULL)
1792 return result;
1793
e9e44622
JJ
1794 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1795 type);
103f02d3 1796 }
252b5132 1797 else
e9e44622 1798 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1799
252b5132
RH
1800 return buff;
1801 }
1802}
1803
1804static char *
d3ba0551 1805get_file_type (unsigned e_type)
252b5132 1806{
b34976b6 1807 static char buff[32];
252b5132
RH
1808
1809 switch (e_type)
1810 {
1811 case ET_NONE: return _("NONE (None)");
1812 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1813 case ET_EXEC: return _("EXEC (Executable file)");
1814 case ET_DYN: return _("DYN (Shared object file)");
1815 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1816
1817 default:
1818 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1819 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1820 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1821 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1822 else
e9e44622 1823 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1824 return buff;
1825 }
1826}
1827
1828static char *
d3ba0551 1829get_machine_name (unsigned e_machine)
252b5132 1830{
b34976b6 1831 static char buff[64]; /* XXX */
252b5132
RH
1832
1833 switch (e_machine)
1834 {
c45021f2
NC
1835 case EM_NONE: return _("None");
1836 case EM_M32: return "WE32100";
1837 case EM_SPARC: return "Sparc";
e9f53129 1838 case EM_SPU: return "SPU";
c45021f2
NC
1839 case EM_386: return "Intel 80386";
1840 case EM_68K: return "MC68000";
1841 case EM_88K: return "MC88000";
1842 case EM_486: return "Intel 80486";
1843 case EM_860: return "Intel 80860";
1844 case EM_MIPS: return "MIPS R3000";
1845 case EM_S370: return "IBM System/370";
7036c0e1 1846 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1847 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1848 case EM_PARISC: return "HPPA";
252b5132 1849 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1850 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1851 case EM_960: return "Intel 90860";
1852 case EM_PPC: return "PowerPC";
285d1771 1853 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1854 case EM_V800: return "NEC V800";
1855 case EM_FR20: return "Fujitsu FR20";
1856 case EM_RH32: return "TRW RH32";
b34976b6 1857 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1858 case EM_ARM: return "ARM";
1859 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1860 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1861 case EM_SPARCV9: return "Sparc v9";
1862 case EM_TRICORE: return "Siemens Tricore";
584da044 1863 case EM_ARC: return "ARC";
c2dcd04e
NC
1864 case EM_H8_300: return "Renesas H8/300";
1865 case EM_H8_300H: return "Renesas H8/300H";
1866 case EM_H8S: return "Renesas H8S";
1867 case EM_H8_500: return "Renesas H8/500";
30800947 1868 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1869 case EM_MIPS_X: return "Stanford MIPS-X";
1870 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 1871 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1872 case EM_CYGNUS_D10V:
1873 case EM_D10V: return "d10v";
1874 case EM_CYGNUS_D30V:
b34976b6 1875 case EM_D30V: return "d30v";
2b0337b0 1876 case EM_CYGNUS_M32R:
26597c86 1877 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1878 case EM_CYGNUS_V850:
f6c1a2d5 1879 case EM_V850: return "Renesas V850";
2b0337b0
AO
1880 case EM_CYGNUS_MN10300:
1881 case EM_MN10300: return "mn10300";
1882 case EM_CYGNUS_MN10200:
1883 case EM_MN10200: return "mn10200";
5506d11a 1884 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1885 case EM_CYGNUS_FR30:
1886 case EM_FR30: return "Fujitsu FR30";
b34976b6 1887 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1888 case EM_PJ_OLD:
b34976b6 1889 case EM_PJ: return "picoJava";
7036c0e1
AJ
1890 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1891 case EM_PCP: return "Siemens PCP";
1892 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1893 case EM_NDR1: return "Denso NDR1 microprocesspr";
1894 case EM_STARCORE: return "Motorola Star*Core processor";
1895 case EM_ME16: return "Toyota ME16 processor";
1896 case EM_ST100: return "STMicroelectronics ST100 processor";
1897 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1898 case EM_PDSP: return "Sony DSP processor";
1899 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1900 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1901 case EM_FX66: return "Siemens FX66 microcontroller";
1902 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1903 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1904 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 1905 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
1906 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1907 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1908 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1909 case EM_SVX: return "Silicon Graphics SVx";
1910 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1911 case EM_VAX: return "Digital VAX";
2b0337b0 1912 case EM_AVR_OLD:
b34976b6 1913 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1914 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1915 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1916 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1917 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1918 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1919 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1920 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1921 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1922 case EM_L1OM: return "Intel L1OM";
7a9068fe 1923 case EM_K1OM: return "Intel K1OM";
b7498e0e 1924 case EM_S390_OLD:
b34976b6 1925 case EM_S390: return "IBM S/390";
1c0d3aa6 1926 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1927 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1928 case EM_OPENRISC:
1929 case EM_OR32: return "OpenRISC";
11636f9e 1930 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1931 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 1932 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 1933 case EM_DLX: return "OpenDLX";
1e4cf259 1934 case EM_IP2K_OLD:
b34976b6 1935 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1936 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1937 case EM_XTENSA_OLD:
1938 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1939 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1940 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1941 case EM_NS32K: return "National Semiconductor 32000 series";
1942 case EM_TPC: return "Tenor Network TPC processor";
1943 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1944 case EM_MAX: return "MAX Processor";
1945 case EM_CR: return "National Semiconductor CompactRISC";
1946 case EM_F2MC16: return "Fujitsu F2MC16";
1947 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1948 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1949 case EM_M32C_OLD:
49f58d10 1950 case EM_M32C: return "Renesas M32c";
d031aafb 1951 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1952 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1953 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1954 case EM_SEP: return "Sharp embedded microprocessor";
1955 case EM_ARCA: return "Arca RISC microprocessor";
1956 case EM_UNICORE: return "Unicore";
1957 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1958 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1959 case EM_NIOS32: return "Altera Nios";
1960 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1961 case EM_C166:
d70c5fc7 1962 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
1963 case EM_M16C: return "Renesas M16C series microprocessors";
1964 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
1965 case EM_CE: return "Freescale Communication Engine RISC core";
1966 case EM_TSK3000: return "Altium TSK3000 core";
1967 case EM_RS08: return "Freescale RS08 embedded processor";
1968 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
1969 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
1970 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
1971 case EM_SE_C17: return "Seiko Epson C17 family";
1972 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
1973 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
1974 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
1975 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
1976 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
1977 case EM_R32C: return "Renesas R32C series microprocessors";
1978 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
1979 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
1980 case EM_8051: return "Intel 8051 and variants";
1981 case EM_STXP7X: return "STMicroelectronics STxP7x family";
1982 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
1983 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
1984 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
1985 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
1986 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
1987 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 1988 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 1989 case EM_CR16:
f6c1a2d5 1990 case EM_MICROBLAZE:
7ba29e2a 1991 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 1992 case EM_RL78: return "Renesas RL78";
c7927a3c 1993 case EM_RX: return "Renesas RX";
11636f9e
JM
1994 case EM_METAG: return "Imagination Technologies META processor architecture";
1995 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
1996 case EM_ECOG16: return "Cyan Technology eCOG16 family";
1997 case EM_ETPU: return "Freescale Extended Time Processing Unit";
1998 case EM_SLE9X: return "Infineon Technologies SLE9X core";
1999 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2000 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2001 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2002 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2003 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2004 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2005 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2006 default:
35d9dd2f 2007 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2008 return buff;
2009 }
2010}
2011
f3485b74 2012static void
d3ba0551 2013decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2014{
2015 unsigned eabi;
2016 int unknown = 0;
2017
2018 eabi = EF_ARM_EABI_VERSION (e_flags);
2019 e_flags &= ~ EF_ARM_EABIMASK;
2020
2021 /* Handle "generic" ARM flags. */
2022 if (e_flags & EF_ARM_RELEXEC)
2023 {
2024 strcat (buf, ", relocatable executable");
2025 e_flags &= ~ EF_ARM_RELEXEC;
2026 }
76da6bbe 2027
f3485b74
NC
2028 if (e_flags & EF_ARM_HASENTRY)
2029 {
2030 strcat (buf, ", has entry point");
2031 e_flags &= ~ EF_ARM_HASENTRY;
2032 }
76da6bbe 2033
f3485b74
NC
2034 /* Now handle EABI specific flags. */
2035 switch (eabi)
2036 {
2037 default:
2c71103e 2038 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2039 if (e_flags)
2040 unknown = 1;
2041 break;
2042
2043 case EF_ARM_EABI_VER1:
a5bcd848 2044 strcat (buf, ", Version1 EABI");
f3485b74
NC
2045 while (e_flags)
2046 {
2047 unsigned flag;
76da6bbe 2048
f3485b74
NC
2049 /* Process flags one bit at a time. */
2050 flag = e_flags & - e_flags;
2051 e_flags &= ~ flag;
76da6bbe 2052
f3485b74
NC
2053 switch (flag)
2054 {
a5bcd848 2055 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2056 strcat (buf, ", sorted symbol tables");
2057 break;
76da6bbe 2058
f3485b74
NC
2059 default:
2060 unknown = 1;
2061 break;
2062 }
2063 }
2064 break;
76da6bbe 2065
a5bcd848
PB
2066 case EF_ARM_EABI_VER2:
2067 strcat (buf, ", Version2 EABI");
2068 while (e_flags)
2069 {
2070 unsigned flag;
2071
2072 /* Process flags one bit at a time. */
2073 flag = e_flags & - e_flags;
2074 e_flags &= ~ flag;
2075
2076 switch (flag)
2077 {
2078 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2079 strcat (buf, ", sorted symbol tables");
2080 break;
2081
2082 case EF_ARM_DYNSYMSUSESEGIDX:
2083 strcat (buf, ", dynamic symbols use segment index");
2084 break;
2085
2086 case EF_ARM_MAPSYMSFIRST:
2087 strcat (buf, ", mapping symbols precede others");
2088 break;
2089
2090 default:
2091 unknown = 1;
2092 break;
2093 }
2094 }
2095 break;
2096
d507cf36
PB
2097 case EF_ARM_EABI_VER3:
2098 strcat (buf, ", Version3 EABI");
8cb51566
PB
2099 break;
2100
2101 case EF_ARM_EABI_VER4:
2102 strcat (buf, ", Version4 EABI");
3a4a14e9
PB
2103 goto eabi;
2104
2105 case EF_ARM_EABI_VER5:
2106 strcat (buf, ", Version5 EABI");
2107 eabi:
d507cf36
PB
2108 while (e_flags)
2109 {
2110 unsigned flag;
2111
2112 /* Process flags one bit at a time. */
2113 flag = e_flags & - e_flags;
2114 e_flags &= ~ flag;
2115
2116 switch (flag)
2117 {
2118 case EF_ARM_BE8:
2119 strcat (buf, ", BE8");
2120 break;
2121
2122 case EF_ARM_LE8:
2123 strcat (buf, ", LE8");
2124 break;
2125
2126 default:
2127 unknown = 1;
2128 break;
2129 }
2130 }
2131 break;
2132
f3485b74 2133 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2134 strcat (buf, ", GNU EABI");
f3485b74
NC
2135 while (e_flags)
2136 {
2137 unsigned flag;
76da6bbe 2138
f3485b74
NC
2139 /* Process flags one bit at a time. */
2140 flag = e_flags & - e_flags;
2141 e_flags &= ~ flag;
76da6bbe 2142
f3485b74
NC
2143 switch (flag)
2144 {
a5bcd848 2145 case EF_ARM_INTERWORK:
f3485b74
NC
2146 strcat (buf, ", interworking enabled");
2147 break;
76da6bbe 2148
a5bcd848 2149 case EF_ARM_APCS_26:
f3485b74
NC
2150 strcat (buf, ", uses APCS/26");
2151 break;
76da6bbe 2152
a5bcd848 2153 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2154 strcat (buf, ", uses APCS/float");
2155 break;
76da6bbe 2156
a5bcd848 2157 case EF_ARM_PIC:
f3485b74
NC
2158 strcat (buf, ", position independent");
2159 break;
76da6bbe 2160
a5bcd848 2161 case EF_ARM_ALIGN8:
f3485b74
NC
2162 strcat (buf, ", 8 bit structure alignment");
2163 break;
76da6bbe 2164
a5bcd848 2165 case EF_ARM_NEW_ABI:
f3485b74
NC
2166 strcat (buf, ", uses new ABI");
2167 break;
76da6bbe 2168
a5bcd848 2169 case EF_ARM_OLD_ABI:
f3485b74
NC
2170 strcat (buf, ", uses old ABI");
2171 break;
76da6bbe 2172
a5bcd848 2173 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2174 strcat (buf, ", software FP");
2175 break;
76da6bbe 2176
90e01f86
ILT
2177 case EF_ARM_VFP_FLOAT:
2178 strcat (buf, ", VFP");
2179 break;
2180
fde78edd
NC
2181 case EF_ARM_MAVERICK_FLOAT:
2182 strcat (buf, ", Maverick FP");
2183 break;
2184
f3485b74
NC
2185 default:
2186 unknown = 1;
2187 break;
2188 }
2189 }
2190 }
f3485b74
NC
2191
2192 if (unknown)
2b692964 2193 strcat (buf,_(", <unknown>"));
f3485b74
NC
2194}
2195
252b5132 2196static char *
d3ba0551 2197get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2198{
b34976b6 2199 static char buf[1024];
252b5132
RH
2200
2201 buf[0] = '\0';
76da6bbe 2202
252b5132
RH
2203 if (e_flags)
2204 {
2205 switch (e_machine)
2206 {
2207 default:
2208 break;
2209
f3485b74
NC
2210 case EM_ARM:
2211 decode_ARM_machine_flags (e_flags, buf);
2212 break;
76da6bbe 2213
781303ce
MF
2214 case EM_BLACKFIN:
2215 if (e_flags & EF_BFIN_PIC)
2216 strcat (buf, ", PIC");
2217
2218 if (e_flags & EF_BFIN_FDPIC)
2219 strcat (buf, ", FDPIC");
2220
2221 if (e_flags & EF_BFIN_CODE_IN_L1)
2222 strcat (buf, ", code in L1");
2223
2224 if (e_flags & EF_BFIN_DATA_IN_L1)
2225 strcat (buf, ", data in L1");
2226
2227 break;
2228
ec2dfb42
AO
2229 case EM_CYGNUS_FRV:
2230 switch (e_flags & EF_FRV_CPU_MASK)
2231 {
2232 case EF_FRV_CPU_GENERIC:
2233 break;
2234
2235 default:
2236 strcat (buf, ", fr???");
2237 break;
57346661 2238
ec2dfb42
AO
2239 case EF_FRV_CPU_FR300:
2240 strcat (buf, ", fr300");
2241 break;
2242
2243 case EF_FRV_CPU_FR400:
2244 strcat (buf, ", fr400");
2245 break;
2246 case EF_FRV_CPU_FR405:
2247 strcat (buf, ", fr405");
2248 break;
2249
2250 case EF_FRV_CPU_FR450:
2251 strcat (buf, ", fr450");
2252 break;
2253
2254 case EF_FRV_CPU_FR500:
2255 strcat (buf, ", fr500");
2256 break;
2257 case EF_FRV_CPU_FR550:
2258 strcat (buf, ", fr550");
2259 break;
2260
2261 case EF_FRV_CPU_SIMPLE:
2262 strcat (buf, ", simple");
2263 break;
2264 case EF_FRV_CPU_TOMCAT:
2265 strcat (buf, ", tomcat");
2266 break;
2267 }
1c877e87 2268 break;
ec2dfb42 2269
53c7db4b 2270 case EM_68K:
425c6cb0 2271 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2272 strcat (buf, ", m68000");
425c6cb0 2273 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2274 strcat (buf, ", cpu32");
2275 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2276 strcat (buf, ", fido_a");
425c6cb0 2277 else
266abb8f 2278 {
2cf0635d
NC
2279 char const * isa = _("unknown");
2280 char const * mac = _("unknown mac");
2281 char const * additional = NULL;
0112cd26 2282
c694fd50 2283 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2284 {
c694fd50 2285 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2286 isa = "A";
2287 additional = ", nodiv";
2288 break;
c694fd50 2289 case EF_M68K_CF_ISA_A:
266abb8f
NS
2290 isa = "A";
2291 break;
c694fd50 2292 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2293 isa = "A+";
2294 break;
c694fd50 2295 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2296 isa = "B";
2297 additional = ", nousp";
2298 break;
c694fd50 2299 case EF_M68K_CF_ISA_B:
266abb8f
NS
2300 isa = "B";
2301 break;
f608cd77
NS
2302 case EF_M68K_CF_ISA_C:
2303 isa = "C";
2304 break;
2305 case EF_M68K_CF_ISA_C_NODIV:
2306 isa = "C";
2307 additional = ", nodiv";
2308 break;
266abb8f
NS
2309 }
2310 strcat (buf, ", cf, isa ");
2311 strcat (buf, isa);
0b2e31dc
NS
2312 if (additional)
2313 strcat (buf, additional);
c694fd50 2314 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2315 strcat (buf, ", float");
c694fd50 2316 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2317 {
2318 case 0:
2319 mac = NULL;
2320 break;
c694fd50 2321 case EF_M68K_CF_MAC:
266abb8f
NS
2322 mac = "mac";
2323 break;
c694fd50 2324 case EF_M68K_CF_EMAC:
266abb8f
NS
2325 mac = "emac";
2326 break;
f608cd77
NS
2327 case EF_M68K_CF_EMAC_B:
2328 mac = "emac_b";
2329 break;
266abb8f
NS
2330 }
2331 if (mac)
2332 {
2333 strcat (buf, ", ");
2334 strcat (buf, mac);
2335 }
266abb8f 2336 }
53c7db4b 2337 break;
33c63f9d 2338
252b5132
RH
2339 case EM_PPC:
2340 if (e_flags & EF_PPC_EMB)
2341 strcat (buf, ", emb");
2342
2343 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2344 strcat (buf, _(", relocatable"));
252b5132
RH
2345
2346 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2347 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2348 break;
2349
2b0337b0 2350 case EM_V850:
252b5132
RH
2351 case EM_CYGNUS_V850:
2352 switch (e_flags & EF_V850_ARCH)
2353 {
1cd986c5
NC
2354 case E_V850E2V3_ARCH:
2355 strcat (buf, ", v850e2v3");
2356 break;
2357 case E_V850E2_ARCH:
2358 strcat (buf, ", v850e2");
2359 break;
2360 case E_V850E1_ARCH:
2361 strcat (buf, ", v850e1");
8ad30312 2362 break;
252b5132
RH
2363 case E_V850E_ARCH:
2364 strcat (buf, ", v850e");
2365 break;
252b5132
RH
2366 case E_V850_ARCH:
2367 strcat (buf, ", v850");
2368 break;
2369 default:
2b692964 2370 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2371 break;
2372 }
2373 break;
2374
2b0337b0 2375 case EM_M32R:
252b5132
RH
2376 case EM_CYGNUS_M32R:
2377 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2378 strcat (buf, ", m32r");
252b5132
RH
2379 break;
2380
2381 case EM_MIPS:
4fe85591 2382 case EM_MIPS_RS3_LE:
252b5132
RH
2383 if (e_flags & EF_MIPS_NOREORDER)
2384 strcat (buf, ", noreorder");
2385
2386 if (e_flags & EF_MIPS_PIC)
2387 strcat (buf, ", pic");
2388
2389 if (e_flags & EF_MIPS_CPIC)
2390 strcat (buf, ", cpic");
2391
d1bdd336
TS
2392 if (e_flags & EF_MIPS_UCODE)
2393 strcat (buf, ", ugen_reserved");
2394
252b5132
RH
2395 if (e_flags & EF_MIPS_ABI2)
2396 strcat (buf, ", abi2");
2397
43521d43
TS
2398 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2399 strcat (buf, ", odk first");
2400
a5d22d2a
TS
2401 if (e_flags & EF_MIPS_32BITMODE)
2402 strcat (buf, ", 32bitmode");
2403
156c2f8b
NC
2404 switch ((e_flags & EF_MIPS_MACH))
2405 {
2406 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2407 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2408 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2409 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2410 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2411 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2412 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2413 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2414 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2415 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2416 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2417 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2418 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2419 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2420 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2421 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2422 case 0:
2423 /* We simply ignore the field in this case to avoid confusion:
2424 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2425 extension. */
2426 break;
2b692964 2427 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2428 }
43521d43
TS
2429
2430 switch ((e_flags & EF_MIPS_ABI))
2431 {
2432 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2433 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2434 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2435 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2436 case 0:
2437 /* We simply ignore the field in this case to avoid confusion:
2438 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2439 This means it is likely to be an o32 file, but not for
2440 sure. */
2441 break;
2b692964 2442 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2443 }
2444
2445 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2446 strcat (buf, ", mdmx");
2447
2448 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2449 strcat (buf, ", mips16");
2450
df58fc94
RS
2451 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2452 strcat (buf, ", micromips");
2453
43521d43
TS
2454 switch ((e_flags & EF_MIPS_ARCH))
2455 {
2456 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2457 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2458 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2459 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2460 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2461 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2462 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2463 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2464 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2465 default: strcat (buf, _(", unknown ISA")); break;
43521d43
TS
2466 }
2467
8e45593f
NC
2468 if (e_flags & EF_SH_PIC)
2469 strcat (buf, ", pic");
2470
2471 if (e_flags & EF_SH_FDPIC)
2472 strcat (buf, ", fdpic");
252b5132 2473 break;
351b4b40 2474
ccde1100
AO
2475 case EM_SH:
2476 switch ((e_flags & EF_SH_MACH_MASK))
2477 {
2478 case EF_SH1: strcat (buf, ", sh1"); break;
2479 case EF_SH2: strcat (buf, ", sh2"); break;
2480 case EF_SH3: strcat (buf, ", sh3"); break;
2481 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2482 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2483 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2484 case EF_SH3E: strcat (buf, ", sh3e"); break;
2485 case EF_SH4: strcat (buf, ", sh4"); break;
2486 case EF_SH5: strcat (buf, ", sh5"); break;
2487 case EF_SH2E: strcat (buf, ", sh2e"); break;
2488 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2489 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2490 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2491 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2492 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2493 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2494 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2495 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2496 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2497 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2498 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2499 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2500 }
2501
2502 break;
57346661 2503
351b4b40
RH
2504 case EM_SPARCV9:
2505 if (e_flags & EF_SPARC_32PLUS)
2506 strcat (buf, ", v8+");
2507
2508 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2509 strcat (buf, ", ultrasparcI");
2510
2511 if (e_flags & EF_SPARC_SUN_US3)
2512 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2513
2514 if (e_flags & EF_SPARC_HAL_R1)
2515 strcat (buf, ", halr1");
2516
2517 if (e_flags & EF_SPARC_LEDATA)
2518 strcat (buf, ", ledata");
2519
2520 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2521 strcat (buf, ", tso");
2522
2523 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2524 strcat (buf, ", pso");
2525
2526 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2527 strcat (buf, ", rmo");
2528 break;
7d466069 2529
103f02d3
UD
2530 case EM_PARISC:
2531 switch (e_flags & EF_PARISC_ARCH)
2532 {
2533 case EFA_PARISC_1_0:
2534 strcpy (buf, ", PA-RISC 1.0");
2535 break;
2536 case EFA_PARISC_1_1:
2537 strcpy (buf, ", PA-RISC 1.1");
2538 break;
2539 case EFA_PARISC_2_0:
2540 strcpy (buf, ", PA-RISC 2.0");
2541 break;
2542 default:
2543 break;
2544 }
2545 if (e_flags & EF_PARISC_TRAPNIL)
2546 strcat (buf, ", trapnil");
2547 if (e_flags & EF_PARISC_EXT)
2548 strcat (buf, ", ext");
2549 if (e_flags & EF_PARISC_LSB)
2550 strcat (buf, ", lsb");
2551 if (e_flags & EF_PARISC_WIDE)
2552 strcat (buf, ", wide");
2553 if (e_flags & EF_PARISC_NO_KABP)
2554 strcat (buf, ", no kabp");
2555 if (e_flags & EF_PARISC_LAZYSWAP)
2556 strcat (buf, ", lazyswap");
30800947 2557 break;
76da6bbe 2558
7d466069 2559 case EM_PJ:
2b0337b0 2560 case EM_PJ_OLD:
7d466069
ILT
2561 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2562 strcat (buf, ", new calling convention");
2563
2564 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2565 strcat (buf, ", gnu calling convention");
2566 break;
4d6ed7c8
NC
2567
2568 case EM_IA_64:
2569 if ((e_flags & EF_IA_64_ABI64))
2570 strcat (buf, ", 64-bit");
2571 else
2572 strcat (buf, ", 32-bit");
2573 if ((e_flags & EF_IA_64_REDUCEDFP))
2574 strcat (buf, ", reduced fp model");
2575 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2576 strcat (buf, ", no function descriptors, constant gp");
2577 else if ((e_flags & EF_IA_64_CONS_GP))
2578 strcat (buf, ", constant gp");
2579 if ((e_flags & EF_IA_64_ABSOLUTE))
2580 strcat (buf, ", absolute");
28f997cf
TG
2581 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2582 {
2583 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2584 strcat (buf, ", vms_linkages");
2585 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2586 {
2587 case EF_IA_64_VMS_COMCOD_SUCCESS:
2588 break;
2589 case EF_IA_64_VMS_COMCOD_WARNING:
2590 strcat (buf, ", warning");
2591 break;
2592 case EF_IA_64_VMS_COMCOD_ERROR:
2593 strcat (buf, ", error");
2594 break;
2595 case EF_IA_64_VMS_COMCOD_ABORT:
2596 strcat (buf, ", abort");
2597 break;
2598 default:
2599 abort ();
2600 }
2601 }
4d6ed7c8 2602 break;
179d3252
JT
2603
2604 case EM_VAX:
2605 if ((e_flags & EF_VAX_NONPIC))
2606 strcat (buf, ", non-PIC");
2607 if ((e_flags & EF_VAX_DFLOAT))
2608 strcat (buf, ", D-Float");
2609 if ((e_flags & EF_VAX_GFLOAT))
2610 strcat (buf, ", G-Float");
2611 break;
c7927a3c
NC
2612
2613 case EM_RX:
2614 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2615 strcat (buf, ", 64-bit doubles");
2616 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2617 strcat (buf, ", dsp");
d4cb0ea0
NC
2618 if (e_flags & E_FLAG_RX_PID)
2619 strcat (buf, ", pid");
2620 break;
55786da2
AK
2621
2622 case EM_S390:
2623 if (e_flags & EF_S390_HIGH_GPRS)
2624 strcat (buf, ", highgprs");
d4cb0ea0 2625 break;
40b36596
JM
2626
2627 case EM_TI_C6000:
2628 if ((e_flags & EF_C6000_REL))
2629 strcat (buf, ", relocatable module");
d4cb0ea0 2630 break;
252b5132
RH
2631 }
2632 }
2633
2634 return buf;
2635}
2636
252b5132 2637static const char *
d3ba0551
AM
2638get_osabi_name (unsigned int osabi)
2639{
2640 static char buff[32];
2641
2642 switch (osabi)
2643 {
2644 case ELFOSABI_NONE: return "UNIX - System V";
2645 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2646 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2647 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2648 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2649 case ELFOSABI_AIX: return "UNIX - AIX";
2650 case ELFOSABI_IRIX: return "UNIX - IRIX";
2651 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2652 case ELFOSABI_TRU64: return "UNIX - TRU64";
2653 case ELFOSABI_MODESTO: return "Novell - Modesto";
2654 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2655 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2656 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2657 case ELFOSABI_AROS: return "AROS";
11636f9e 2658 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2659 default:
40b36596
JM
2660 if (osabi >= 64)
2661 switch (elf_header.e_machine)
2662 {
2663 case EM_ARM:
2664 switch (osabi)
2665 {
2666 case ELFOSABI_ARM: return "ARM";
2667 default:
2668 break;
2669 }
2670 break;
2671
2672 case EM_MSP430:
2673 case EM_MSP430_OLD:
2674 switch (osabi)
2675 {
2676 case ELFOSABI_STANDALONE: return _("Standalone App");
2677 default:
2678 break;
2679 }
2680 break;
2681
2682 case EM_TI_C6000:
2683 switch (osabi)
2684 {
2685 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2686 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2687 default:
2688 break;
2689 }
2690 break;
2691
2692 default:
2693 break;
2694 }
e9e44622 2695 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2696 return buff;
2697 }
2698}
2699
b294bdf8
MM
2700static const char *
2701get_arm_segment_type (unsigned long type)
2702{
2703 switch (type)
2704 {
2705 case PT_ARM_EXIDX:
2706 return "EXIDX";
2707 default:
2708 break;
2709 }
2710
2711 return NULL;
2712}
2713
d3ba0551
AM
2714static const char *
2715get_mips_segment_type (unsigned long type)
252b5132
RH
2716{
2717 switch (type)
2718 {
2719 case PT_MIPS_REGINFO:
2720 return "REGINFO";
2721 case PT_MIPS_RTPROC:
2722 return "RTPROC";
2723 case PT_MIPS_OPTIONS:
2724 return "OPTIONS";
2725 default:
2726 break;
2727 }
2728
2729 return NULL;
2730}
2731
103f02d3 2732static const char *
d3ba0551 2733get_parisc_segment_type (unsigned long type)
103f02d3
UD
2734{
2735 switch (type)
2736 {
2737 case PT_HP_TLS: return "HP_TLS";
2738 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2739 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2740 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2741 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2742 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2743 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2744 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2745 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2746 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2747 case PT_HP_PARALLEL: return "HP_PARALLEL";
2748 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2749 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2750 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2751 case PT_HP_STACK: return "HP_STACK";
2752 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2753 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2754 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2755 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2756 default:
2757 break;
2758 }
2759
2760 return NULL;
2761}
2762
4d6ed7c8 2763static const char *
d3ba0551 2764get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2765{
2766 switch (type)
2767 {
2768 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2769 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2770 case PT_HP_TLS: return "HP_TLS";
2771 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2772 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2773 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2774 default:
2775 break;
2776 }
2777
2778 return NULL;
2779}
2780
40b36596
JM
2781static const char *
2782get_tic6x_segment_type (unsigned long type)
2783{
2784 switch (type)
2785 {
2786 case PT_C6000_PHATTR: return "C6000_PHATTR";
2787 default:
2788 break;
2789 }
2790
2791 return NULL;
2792}
2793
252b5132 2794static const char *
d3ba0551 2795get_segment_type (unsigned long p_type)
252b5132 2796{
b34976b6 2797 static char buff[32];
252b5132
RH
2798
2799 switch (p_type)
2800 {
b34976b6
AM
2801 case PT_NULL: return "NULL";
2802 case PT_LOAD: return "LOAD";
252b5132 2803 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2804 case PT_INTERP: return "INTERP";
2805 case PT_NOTE: return "NOTE";
2806 case PT_SHLIB: return "SHLIB";
2807 case PT_PHDR: return "PHDR";
13ae64f3 2808 case PT_TLS: return "TLS";
252b5132 2809
65765700
JJ
2810 case PT_GNU_EH_FRAME:
2811 return "GNU_EH_FRAME";
2b05f1b7 2812 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2813 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2814
252b5132
RH
2815 default:
2816 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2817 {
2cf0635d 2818 const char * result;
103f02d3 2819
252b5132
RH
2820 switch (elf_header.e_machine)
2821 {
b294bdf8
MM
2822 case EM_ARM:
2823 result = get_arm_segment_type (p_type);
2824 break;
252b5132 2825 case EM_MIPS:
4fe85591 2826 case EM_MIPS_RS3_LE:
252b5132
RH
2827 result = get_mips_segment_type (p_type);
2828 break;
103f02d3
UD
2829 case EM_PARISC:
2830 result = get_parisc_segment_type (p_type);
2831 break;
4d6ed7c8
NC
2832 case EM_IA_64:
2833 result = get_ia64_segment_type (p_type);
2834 break;
40b36596
JM
2835 case EM_TI_C6000:
2836 result = get_tic6x_segment_type (p_type);
2837 break;
252b5132
RH
2838 default:
2839 result = NULL;
2840 break;
2841 }
103f02d3 2842
252b5132
RH
2843 if (result != NULL)
2844 return result;
103f02d3 2845
252b5132
RH
2846 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2847 }
2848 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2849 {
2cf0635d 2850 const char * result;
103f02d3
UD
2851
2852 switch (elf_header.e_machine)
2853 {
2854 case EM_PARISC:
2855 result = get_parisc_segment_type (p_type);
2856 break;
00428cca
AM
2857 case EM_IA_64:
2858 result = get_ia64_segment_type (p_type);
2859 break;
103f02d3
UD
2860 default:
2861 result = NULL;
2862 break;
2863 }
2864
2865 if (result != NULL)
2866 return result;
2867
2868 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2869 }
252b5132 2870 else
e9e44622 2871 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2872
2873 return buff;
2874 }
2875}
2876
2877static const char *
d3ba0551 2878get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2879{
2880 switch (sh_type)
2881 {
b34976b6
AM
2882 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2883 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2884 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2885 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2886 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2887 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2888 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2889 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2890 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2891 case SHT_MIPS_RELD: return "MIPS_RELD";
2892 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2893 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2894 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2895 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2896 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2897 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2898 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2899 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2900 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2901 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2902 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2903 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2904 case SHT_MIPS_LINE: return "MIPS_LINE";
2905 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2906 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2907 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2908 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2909 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2910 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2911 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2912 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2913 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2914 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2915 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2916 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2917 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2918 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2919 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2920 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2921 default:
2922 break;
2923 }
2924 return NULL;
2925}
2926
103f02d3 2927static const char *
d3ba0551 2928get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2929{
2930 switch (sh_type)
2931 {
2932 case SHT_PARISC_EXT: return "PARISC_EXT";
2933 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2934 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2935 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2936 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2937 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2938 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2939 default:
2940 break;
2941 }
2942 return NULL;
2943}
2944
4d6ed7c8 2945static const char *
d3ba0551 2946get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2947{
18bd398b 2948 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2949 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2950 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2951
4d6ed7c8
NC
2952 switch (sh_type)
2953 {
148b93f2
NC
2954 case SHT_IA_64_EXT: return "IA_64_EXT";
2955 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2956 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
2957 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
2958 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
2959 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
2960 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
2961 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
2962 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
2963 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
2964 default:
2965 break;
2966 }
2967 return NULL;
2968}
2969
d2b2c203
DJ
2970static const char *
2971get_x86_64_section_type_name (unsigned int sh_type)
2972{
2973 switch (sh_type)
2974 {
2975 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2976 default:
2977 break;
2978 }
2979 return NULL;
2980}
2981
40a18ebd
NC
2982static const char *
2983get_arm_section_type_name (unsigned int sh_type)
2984{
2985 switch (sh_type)
2986 {
7f6fed87
NC
2987 case SHT_ARM_EXIDX: return "ARM_EXIDX";
2988 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
2989 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
2990 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
2991 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
2992 default:
2993 break;
2994 }
2995 return NULL;
2996}
2997
40b36596
JM
2998static const char *
2999get_tic6x_section_type_name (unsigned int sh_type)
3000{
3001 switch (sh_type)
3002 {
3003 case SHT_C6000_UNWIND:
3004 return "C6000_UNWIND";
3005 case SHT_C6000_PREEMPTMAP:
3006 return "C6000_PREEMPTMAP";
3007 case SHT_C6000_ATTRIBUTES:
3008 return "C6000_ATTRIBUTES";
3009 case SHT_TI_ICODE:
3010 return "TI_ICODE";
3011 case SHT_TI_XREF:
3012 return "TI_XREF";
3013 case SHT_TI_HANDLER:
3014 return "TI_HANDLER";
3015 case SHT_TI_INITINFO:
3016 return "TI_INITINFO";
3017 case SHT_TI_PHATTRS:
3018 return "TI_PHATTRS";
3019 default:
3020 break;
3021 }
3022 return NULL;
3023}
3024
252b5132 3025static const char *
d3ba0551 3026get_section_type_name (unsigned int sh_type)
252b5132 3027{
b34976b6 3028 static char buff[32];
252b5132
RH
3029
3030 switch (sh_type)
3031 {
3032 case SHT_NULL: return "NULL";
3033 case SHT_PROGBITS: return "PROGBITS";
3034 case SHT_SYMTAB: return "SYMTAB";
3035 case SHT_STRTAB: return "STRTAB";
3036 case SHT_RELA: return "RELA";
3037 case SHT_HASH: return "HASH";
3038 case SHT_DYNAMIC: return "DYNAMIC";
3039 case SHT_NOTE: return "NOTE";
3040 case SHT_NOBITS: return "NOBITS";
3041 case SHT_REL: return "REL";
3042 case SHT_SHLIB: return "SHLIB";
3043 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3044 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3045 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3046 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3047 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3048 case SHT_GROUP: return "GROUP";
3049 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3050 case SHT_GNU_verdef: return "VERDEF";
3051 case SHT_GNU_verneed: return "VERNEED";
3052 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3053 case 0x6ffffff0: return "VERSYM";
3054 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3055 case 0x7ffffffd: return "AUXILIARY";
3056 case 0x7fffffff: return "FILTER";
047b2264 3057 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3058
3059 default:
3060 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3061 {
2cf0635d 3062 const char * result;
252b5132
RH
3063
3064 switch (elf_header.e_machine)
3065 {
3066 case EM_MIPS:
4fe85591 3067 case EM_MIPS_RS3_LE:
252b5132
RH
3068 result = get_mips_section_type_name (sh_type);
3069 break;
103f02d3
UD
3070 case EM_PARISC:
3071 result = get_parisc_section_type_name (sh_type);
3072 break;
4d6ed7c8
NC
3073 case EM_IA_64:
3074 result = get_ia64_section_type_name (sh_type);
3075 break;
d2b2c203 3076 case EM_X86_64:
8a9036a4 3077 case EM_L1OM:
7a9068fe 3078 case EM_K1OM:
d2b2c203
DJ
3079 result = get_x86_64_section_type_name (sh_type);
3080 break;
40a18ebd
NC
3081 case EM_ARM:
3082 result = get_arm_section_type_name (sh_type);
3083 break;
40b36596
JM
3084 case EM_TI_C6000:
3085 result = get_tic6x_section_type_name (sh_type);
3086 break;
252b5132
RH
3087 default:
3088 result = NULL;
3089 break;
3090 }
3091
3092 if (result != NULL)
3093 return result;
3094
c91d0dfb 3095 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3096 }
3097 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3098 {
2cf0635d 3099 const char * result;
148b93f2
NC
3100
3101 switch (elf_header.e_machine)
3102 {
3103 case EM_IA_64:
3104 result = get_ia64_section_type_name (sh_type);
3105 break;
3106 default:
3107 result = NULL;
3108 break;
3109 }
3110
3111 if (result != NULL)
3112 return result;
3113
3114 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3115 }
252b5132 3116 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3117 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3118 else
a7dbfd1c
NC
3119 /* This message is probably going to be displayed in a 15
3120 character wide field, so put the hex value first. */
3121 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3122
252b5132
RH
3123 return buff;
3124 }
3125}
3126
2979dc34 3127#define OPTION_DEBUG_DUMP 512
2c610e4b 3128#define OPTION_DYN_SYMS 513
fd2f0033
TT
3129#define OPTION_DWARF_DEPTH 514
3130#define OPTION_DWARF_START 515
4723351a 3131#define OPTION_DWARF_CHECK 516
2979dc34 3132
85b1c36d 3133static struct option options[] =
252b5132 3134{
b34976b6 3135 {"all", no_argument, 0, 'a'},
252b5132
RH
3136 {"file-header", no_argument, 0, 'h'},
3137 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3138 {"headers", no_argument, 0, 'e'},
3139 {"histogram", no_argument, 0, 'I'},
3140 {"segments", no_argument, 0, 'l'},
3141 {"sections", no_argument, 0, 'S'},
252b5132 3142 {"section-headers", no_argument, 0, 'S'},
f5842774 3143 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3144 {"section-details", no_argument, 0, 't'},
595cf52e 3145 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3146 {"symbols", no_argument, 0, 's'},
3147 {"syms", no_argument, 0, 's'},
2c610e4b 3148 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3149 {"relocs", no_argument, 0, 'r'},
3150 {"notes", no_argument, 0, 'n'},
3151 {"dynamic", no_argument, 0, 'd'},
a952a375 3152 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3153 {"version-info", no_argument, 0, 'V'},
3154 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3155 {"unwind", no_argument, 0, 'u'},
4145f1d5 3156 {"archive-index", no_argument, 0, 'c'},
b34976b6 3157 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3158 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3159 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3160#ifdef SUPPORT_DISASSEMBLY
3161 {"instruction-dump", required_argument, 0, 'i'},
3162#endif
cf13d699 3163 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3164
fd2f0033
TT
3165 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3166 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3167 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3168
b34976b6
AM
3169 {"version", no_argument, 0, 'v'},
3170 {"wide", no_argument, 0, 'W'},
3171 {"help", no_argument, 0, 'H'},
3172 {0, no_argument, 0, 0}
252b5132
RH
3173};
3174
3175static void
2cf0635d 3176usage (FILE * stream)
252b5132 3177{
92f01d61
JM
3178 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3179 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3180 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3181 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3182 -h --file-header Display the ELF file header\n\
3183 -l --program-headers Display the program headers\n\
3184 --segments An alias for --program-headers\n\
3185 -S --section-headers Display the sections' header\n\
3186 --sections An alias for --section-headers\n\
f5842774 3187 -g --section-groups Display the section groups\n\
5477e8a0 3188 -t --section-details Display the section details\n\
8b53311e
NC
3189 -e --headers Equivalent to: -h -l -S\n\
3190 -s --syms Display the symbol table\n\
3f08eb35 3191 --symbols An alias for --syms\n\
2c610e4b 3192 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3193 -n --notes Display the core notes (if present)\n\
3194 -r --relocs Display the relocations (if present)\n\
3195 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3196 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3197 -V --version-info Display the version sections (if present)\n\
1b31d05e 3198 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3199 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3200 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3201 -x --hex-dump=<number|name>\n\
3202 Dump the contents of section <number|name> as bytes\n\
3203 -p --string-dump=<number|name>\n\
3204 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3205 -R --relocated-dump=<number|name>\n\
3206 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3207 -w[lLiaprmfFsoRt] or\n\
1ed06042 3208 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3209 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
5bbdf3d5 3210 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
8b53311e 3211 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3212 fprintf (stream, _("\
3213 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3214 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3215 or deeper\n"));
252b5132 3216#ifdef SUPPORT_DISASSEMBLY
92f01d61 3217 fprintf (stream, _("\
09c11c86
NC
3218 -i --instruction-dump=<number|name>\n\
3219 Disassemble the contents of section <number|name>\n"));
252b5132 3220#endif
92f01d61 3221 fprintf (stream, _("\
8b53311e
NC
3222 -I --histogram Display histogram of bucket list lengths\n\
3223 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3224 @<file> Read options from <file>\n\
8b53311e
NC
3225 -H --help Display this information\n\
3226 -v --version Display the version number of readelf\n"));
1118d252 3227
92f01d61
JM
3228 if (REPORT_BUGS_TO[0] && stream == stdout)
3229 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3230
92f01d61 3231 exit (stream == stdout ? 0 : 1);
252b5132
RH
3232}
3233
18bd398b
NC
3234/* Record the fact that the user wants the contents of section number
3235 SECTION to be displayed using the method(s) encoded as flags bits
3236 in TYPE. Note, TYPE can be zero if we are creating the array for
3237 the first time. */
3238
252b5132 3239static void
09c11c86 3240request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3241{
3242 if (section >= num_dump_sects)
3243 {
2cf0635d 3244 dump_type * new_dump_sects;
252b5132 3245
3f5e193b
NC
3246 new_dump_sects = (dump_type *) calloc (section + 1,
3247 sizeof (* dump_sects));
252b5132
RH
3248
3249 if (new_dump_sects == NULL)
591a748a 3250 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3251 else
3252 {
3253 /* Copy current flag settings. */
09c11c86 3254 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3255
3256 free (dump_sects);
3257
3258 dump_sects = new_dump_sects;
3259 num_dump_sects = section + 1;
3260 }
3261 }
3262
3263 if (dump_sects)
b34976b6 3264 dump_sects[section] |= type;
252b5132
RH
3265
3266 return;
3267}
3268
aef1f6d0
DJ
3269/* Request a dump by section name. */
3270
3271static void
2cf0635d 3272request_dump_byname (const char * section, dump_type type)
aef1f6d0 3273{
2cf0635d 3274 struct dump_list_entry * new_request;
aef1f6d0 3275
3f5e193b
NC
3276 new_request = (struct dump_list_entry *)
3277 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3278 if (!new_request)
591a748a 3279 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3280
3281 new_request->name = strdup (section);
3282 if (!new_request->name)
591a748a 3283 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3284
3285 new_request->type = type;
3286
3287 new_request->next = dump_sects_byname;
3288 dump_sects_byname = new_request;
3289}
3290
cf13d699
NC
3291static inline void
3292request_dump (dump_type type)
3293{
3294 int section;
3295 char * cp;
3296
3297 do_dump++;
3298 section = strtoul (optarg, & cp, 0);
3299
3300 if (! *cp && section >= 0)
3301 request_dump_bynumber (section, type);
3302 else
3303 request_dump_byname (optarg, type);
3304}
3305
3306
252b5132 3307static void
2cf0635d 3308parse_args (int argc, char ** argv)
252b5132
RH
3309{
3310 int c;
3311
3312 if (argc < 2)
92f01d61 3313 usage (stderr);
252b5132
RH
3314
3315 while ((c = getopt_long
cf13d699 3316 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3317 {
252b5132
RH
3318 switch (c)
3319 {
3320 case 0:
3321 /* Long options. */
3322 break;
3323 case 'H':
92f01d61 3324 usage (stdout);
252b5132
RH
3325 break;
3326
3327 case 'a':
b34976b6
AM
3328 do_syms++;
3329 do_reloc++;
3330 do_unwind++;
3331 do_dynamic++;
3332 do_header++;
3333 do_sections++;
f5842774 3334 do_section_groups++;
b34976b6
AM
3335 do_segments++;
3336 do_version++;
3337 do_histogram++;
3338 do_arch++;
3339 do_notes++;
252b5132 3340 break;
f5842774
L
3341 case 'g':
3342 do_section_groups++;
3343 break;
5477e8a0 3344 case 't':
595cf52e 3345 case 'N':
5477e8a0
L
3346 do_sections++;
3347 do_section_details++;
595cf52e 3348 break;
252b5132 3349 case 'e':
b34976b6
AM
3350 do_header++;
3351 do_sections++;
3352 do_segments++;
252b5132 3353 break;
a952a375 3354 case 'A':
b34976b6 3355 do_arch++;
a952a375 3356 break;
252b5132 3357 case 'D':
b34976b6 3358 do_using_dynamic++;
252b5132
RH
3359 break;
3360 case 'r':
b34976b6 3361 do_reloc++;
252b5132 3362 break;
4d6ed7c8 3363 case 'u':
b34976b6 3364 do_unwind++;
4d6ed7c8 3365 break;
252b5132 3366 case 'h':
b34976b6 3367 do_header++;
252b5132
RH
3368 break;
3369 case 'l':
b34976b6 3370 do_segments++;
252b5132
RH
3371 break;
3372 case 's':
b34976b6 3373 do_syms++;
252b5132
RH
3374 break;
3375 case 'S':
b34976b6 3376 do_sections++;
252b5132
RH
3377 break;
3378 case 'd':
b34976b6 3379 do_dynamic++;
252b5132 3380 break;
a952a375 3381 case 'I':
b34976b6 3382 do_histogram++;
a952a375 3383 break;
779fe533 3384 case 'n':
b34976b6 3385 do_notes++;
779fe533 3386 break;
4145f1d5
NC
3387 case 'c':
3388 do_archive_index++;
3389 break;
252b5132 3390 case 'x':
cf13d699 3391 request_dump (HEX_DUMP);
aef1f6d0 3392 break;
09c11c86 3393 case 'p':
cf13d699
NC
3394 request_dump (STRING_DUMP);
3395 break;
3396 case 'R':
3397 request_dump (RELOC_DUMP);
09c11c86 3398 break;
252b5132 3399 case 'w':
b34976b6 3400 do_dump++;
252b5132 3401 if (optarg == 0)
613ff48b
CC
3402 {
3403 do_debugging = 1;
3404 dwarf_select_sections_all ();
3405 }
252b5132
RH
3406 else
3407 {
3408 do_debugging = 0;
4cb93e3b 3409 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3410 }
3411 break;
2979dc34 3412 case OPTION_DEBUG_DUMP:
b34976b6 3413 do_dump++;
2979dc34
JJ
3414 if (optarg == 0)
3415 do_debugging = 1;
3416 else
3417 {
2979dc34 3418 do_debugging = 0;
4cb93e3b 3419 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3420 }
3421 break;
fd2f0033
TT
3422 case OPTION_DWARF_DEPTH:
3423 {
3424 char *cp;
3425
3426 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3427 }
3428 break;
3429 case OPTION_DWARF_START:
3430 {
3431 char *cp;
3432
3433 dwarf_start_die = strtoul (optarg, & cp, 0);
3434 }
3435 break;
4723351a
CC
3436 case OPTION_DWARF_CHECK:
3437 dwarf_check = 1;
3438 break;
2c610e4b
L
3439 case OPTION_DYN_SYMS:
3440 do_dyn_syms++;
3441 break;
252b5132
RH
3442#ifdef SUPPORT_DISASSEMBLY
3443 case 'i':
cf13d699
NC
3444 request_dump (DISASS_DUMP);
3445 break;
252b5132
RH
3446#endif
3447 case 'v':
3448 print_version (program_name);
3449 break;
3450 case 'V':
b34976b6 3451 do_version++;
252b5132 3452 break;
d974e256 3453 case 'W':
b34976b6 3454 do_wide++;
d974e256 3455 break;
252b5132 3456 default:
252b5132
RH
3457 /* xgettext:c-format */
3458 error (_("Invalid option '-%c'\n"), c);
3459 /* Drop through. */
3460 case '?':
92f01d61 3461 usage (stderr);
252b5132
RH
3462 }
3463 }
3464
4d6ed7c8 3465 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3466 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3467 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3468 && !do_section_groups && !do_archive_index
3469 && !do_dyn_syms)
92f01d61 3470 usage (stderr);
252b5132
RH
3471 else if (argc < 3)
3472 {
3473 warn (_("Nothing to do.\n"));
92f01d61 3474 usage (stderr);
252b5132
RH
3475 }
3476}
3477
3478static const char *
d3ba0551 3479get_elf_class (unsigned int elf_class)
252b5132 3480{
b34976b6 3481 static char buff[32];
103f02d3 3482
252b5132
RH
3483 switch (elf_class)
3484 {
3485 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3486 case ELFCLASS32: return "ELF32";
3487 case ELFCLASS64: return "ELF64";
ab5e7794 3488 default:
e9e44622 3489 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3490 return buff;
252b5132
RH
3491 }
3492}
3493
3494static const char *
d3ba0551 3495get_data_encoding (unsigned int encoding)
252b5132 3496{
b34976b6 3497 static char buff[32];
103f02d3 3498
252b5132
RH
3499 switch (encoding)
3500 {
3501 case ELFDATANONE: return _("none");
33c63f9d
CM
3502 case ELFDATA2LSB: return _("2's complement, little endian");
3503 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3504 default:
e9e44622 3505 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3506 return buff;
252b5132
RH
3507 }
3508}
3509
252b5132 3510/* Decode the data held in 'elf_header'. */
ee42cf8c 3511
252b5132 3512static int
d3ba0551 3513process_file_header (void)
252b5132 3514{
b34976b6
AM
3515 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3516 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3517 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3518 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3519 {
3520 error
3521 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3522 return 0;
3523 }
3524
2dc4cec1
L
3525 init_dwarf_regnames (elf_header.e_machine);
3526
252b5132
RH
3527 if (do_header)
3528 {
3529 int i;
3530
3531 printf (_("ELF Header:\n"));
3532 printf (_(" Magic: "));
b34976b6
AM
3533 for (i = 0; i < EI_NIDENT; i++)
3534 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3535 printf ("\n");
3536 printf (_(" Class: %s\n"),
b34976b6 3537 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3538 printf (_(" Data: %s\n"),
b34976b6 3539 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3540 printf (_(" Version: %d %s\n"),
b34976b6
AM
3541 elf_header.e_ident[EI_VERSION],
3542 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3543 ? "(current)"
b34976b6 3544 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3545 ? _("<unknown: %lx>")
789be9f7 3546 : "")));
252b5132 3547 printf (_(" OS/ABI: %s\n"),
b34976b6 3548 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3549 printf (_(" ABI Version: %d\n"),
b34976b6 3550 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3551 printf (_(" Type: %s\n"),
3552 get_file_type (elf_header.e_type));
3553 printf (_(" Machine: %s\n"),
3554 get_machine_name (elf_header.e_machine));
3555 printf (_(" Version: 0x%lx\n"),
3556 (unsigned long) elf_header.e_version);
76da6bbe 3557
f7a99963
NC
3558 printf (_(" Entry point address: "));
3559 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3560 printf (_("\n Start of program headers: "));
3561 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3562 printf (_(" (bytes into file)\n Start of section headers: "));
3563 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3564 printf (_(" (bytes into file)\n"));
76da6bbe 3565
252b5132
RH
3566 printf (_(" Flags: 0x%lx%s\n"),
3567 (unsigned long) elf_header.e_flags,
3568 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3569 printf (_(" Size of this header: %ld (bytes)\n"),
3570 (long) elf_header.e_ehsize);
3571 printf (_(" Size of program headers: %ld (bytes)\n"),
3572 (long) elf_header.e_phentsize);
2046a35d 3573 printf (_(" Number of program headers: %ld"),
252b5132 3574 (long) elf_header.e_phnum);
2046a35d
AM
3575 if (section_headers != NULL
3576 && elf_header.e_phnum == PN_XNUM
3577 && section_headers[0].sh_info != 0)
cc5914eb 3578 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3579 putc ('\n', stdout);
252b5132
RH
3580 printf (_(" Size of section headers: %ld (bytes)\n"),
3581 (long) elf_header.e_shentsize);
560f3c1c 3582 printf (_(" Number of section headers: %ld"),
252b5132 3583 (long) elf_header.e_shnum);
4fbb74a6 3584 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3585 printf (" (%ld)", (long) section_headers[0].sh_size);
3586 putc ('\n', stdout);
3587 printf (_(" Section header string table index: %ld"),
252b5132 3588 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3589 if (section_headers != NULL
3590 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3591 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3592 else if (elf_header.e_shstrndx != SHN_UNDEF
3593 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3594 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3595 putc ('\n', stdout);
3596 }
3597
3598 if (section_headers != NULL)
3599 {
2046a35d
AM
3600 if (elf_header.e_phnum == PN_XNUM
3601 && section_headers[0].sh_info != 0)
3602 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3603 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3604 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3605 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3606 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3607 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3608 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3609 free (section_headers);
3610 section_headers = NULL;
252b5132 3611 }
103f02d3 3612
9ea033b2
NC
3613 return 1;
3614}
3615
252b5132 3616
9ea033b2 3617static int
91d6fa6a 3618get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3619{
2cf0635d
NC
3620 Elf32_External_Phdr * phdrs;
3621 Elf32_External_Phdr * external;
3622 Elf_Internal_Phdr * internal;
b34976b6 3623 unsigned int i;
103f02d3 3624
3f5e193b
NC
3625 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3626 elf_header.e_phentsize,
3627 elf_header.e_phnum,
3628 _("program headers"));
a6e9f9df
AM
3629 if (!phdrs)
3630 return 0;
9ea033b2 3631
91d6fa6a 3632 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3633 i < elf_header.e_phnum;
b34976b6 3634 i++, internal++, external++)
252b5132 3635 {
9ea033b2
NC
3636 internal->p_type = BYTE_GET (external->p_type);
3637 internal->p_offset = BYTE_GET (external->p_offset);
3638 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3639 internal->p_paddr = BYTE_GET (external->p_paddr);
3640 internal->p_filesz = BYTE_GET (external->p_filesz);
3641 internal->p_memsz = BYTE_GET (external->p_memsz);
3642 internal->p_flags = BYTE_GET (external->p_flags);
3643 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3644 }
3645
9ea033b2
NC
3646 free (phdrs);
3647
252b5132
RH
3648 return 1;
3649}
3650
9ea033b2 3651static int
91d6fa6a 3652get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3653{
2cf0635d
NC
3654 Elf64_External_Phdr * phdrs;
3655 Elf64_External_Phdr * external;
3656 Elf_Internal_Phdr * internal;
b34976b6 3657 unsigned int i;
103f02d3 3658
3f5e193b
NC
3659 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3660 elf_header.e_phentsize,
3661 elf_header.e_phnum,
3662 _("program headers"));
a6e9f9df
AM
3663 if (!phdrs)
3664 return 0;
9ea033b2 3665
91d6fa6a 3666 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3667 i < elf_header.e_phnum;
b34976b6 3668 i++, internal++, external++)
9ea033b2
NC
3669 {
3670 internal->p_type = BYTE_GET (external->p_type);
3671 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3672 internal->p_offset = BYTE_GET (external->p_offset);
3673 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3674 internal->p_paddr = BYTE_GET (external->p_paddr);
3675 internal->p_filesz = BYTE_GET (external->p_filesz);
3676 internal->p_memsz = BYTE_GET (external->p_memsz);
3677 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3678 }
3679
3680 free (phdrs);
3681
3682 return 1;
3683}
252b5132 3684
d93f0186
NC
3685/* Returns 1 if the program headers were read into `program_headers'. */
3686
3687static int
2cf0635d 3688get_program_headers (FILE * file)
d93f0186 3689{
2cf0635d 3690 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3691
3692 /* Check cache of prior read. */
3693 if (program_headers != NULL)
3694 return 1;
3695
3f5e193b
NC
3696 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3697 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3698
3699 if (phdrs == NULL)
3700 {
3701 error (_("Out of memory\n"));
3702 return 0;
3703 }
3704
3705 if (is_32bit_elf
3706 ? get_32bit_program_headers (file, phdrs)
3707 : get_64bit_program_headers (file, phdrs))
3708 {
3709 program_headers = phdrs;
3710 return 1;
3711 }
3712
3713 free (phdrs);
3714 return 0;
3715}
3716
2f62977e
NC
3717/* Returns 1 if the program headers were loaded. */
3718
252b5132 3719static int
2cf0635d 3720process_program_headers (FILE * file)
252b5132 3721{
2cf0635d 3722 Elf_Internal_Phdr * segment;
b34976b6 3723 unsigned int i;
252b5132
RH
3724
3725 if (elf_header.e_phnum == 0)
3726 {
82f2dbf7
NC
3727 /* PR binutils/12467. */
3728 if (elf_header.e_phoff != 0)
3729 warn (_("possibly corrupt ELF header - it has a non-zero program"
3730 " header offset, but no program headers"));
3731 else if (do_segments)
252b5132 3732 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3733 return 0;
252b5132
RH
3734 }
3735
3736 if (do_segments && !do_header)
3737 {
f7a99963
NC
3738 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3739 printf (_("Entry point "));
3740 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3741 printf (_("\nThere are %d program headers, starting at offset "),
3742 elf_header.e_phnum);
3743 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3744 printf ("\n");
252b5132
RH
3745 }
3746
d93f0186 3747 if (! get_program_headers (file))
252b5132 3748 return 0;
103f02d3 3749
252b5132
RH
3750 if (do_segments)
3751 {
3a1a2036
NC
3752 if (elf_header.e_phnum > 1)
3753 printf (_("\nProgram Headers:\n"));
3754 else
3755 printf (_("\nProgram Headers:\n"));
76da6bbe 3756
f7a99963
NC
3757 if (is_32bit_elf)
3758 printf
3759 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3760 else if (do_wide)
3761 printf
3762 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3763 else
3764 {
3765 printf
3766 (_(" Type Offset VirtAddr PhysAddr\n"));
3767 printf
3768 (_(" FileSiz MemSiz Flags Align\n"));
3769 }
252b5132
RH
3770 }
3771
252b5132 3772 dynamic_addr = 0;
1b228002 3773 dynamic_size = 0;
252b5132
RH
3774
3775 for (i = 0, segment = program_headers;
3776 i < elf_header.e_phnum;
b34976b6 3777 i++, segment++)
252b5132
RH
3778 {
3779 if (do_segments)
3780 {
103f02d3 3781 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3782
3783 if (is_32bit_elf)
3784 {
3785 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3786 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3787 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3788 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3789 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3790 printf ("%c%c%c ",
3791 (segment->p_flags & PF_R ? 'R' : ' '),
3792 (segment->p_flags & PF_W ? 'W' : ' '),
3793 (segment->p_flags & PF_X ? 'E' : ' '));
3794 printf ("%#lx", (unsigned long) segment->p_align);
3795 }
d974e256
JJ
3796 else if (do_wide)
3797 {
3798 if ((unsigned long) segment->p_offset == segment->p_offset)
3799 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3800 else
3801 {
3802 print_vma (segment->p_offset, FULL_HEX);
3803 putchar (' ');
3804 }
3805
3806 print_vma (segment->p_vaddr, FULL_HEX);
3807 putchar (' ');
3808 print_vma (segment->p_paddr, FULL_HEX);
3809 putchar (' ');
3810
3811 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3812 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3813 else
3814 {
3815 print_vma (segment->p_filesz, FULL_HEX);
3816 putchar (' ');
3817 }
3818
3819 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3820 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3821 else
3822 {
f48e6c45 3823 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
3824 }
3825
3826 printf (" %c%c%c ",
3827 (segment->p_flags & PF_R ? 'R' : ' '),
3828 (segment->p_flags & PF_W ? 'W' : ' '),
3829 (segment->p_flags & PF_X ? 'E' : ' '));
3830
3831 if ((unsigned long) segment->p_align == segment->p_align)
3832 printf ("%#lx", (unsigned long) segment->p_align);
3833 else
3834 {
3835 print_vma (segment->p_align, PREFIX_HEX);
3836 }
3837 }
f7a99963
NC
3838 else
3839 {
3840 print_vma (segment->p_offset, FULL_HEX);
3841 putchar (' ');
3842 print_vma (segment->p_vaddr, FULL_HEX);
3843 putchar (' ');
3844 print_vma (segment->p_paddr, FULL_HEX);
3845 printf ("\n ");
3846 print_vma (segment->p_filesz, FULL_HEX);
3847 putchar (' ');
3848 print_vma (segment->p_memsz, FULL_HEX);
3849 printf (" %c%c%c ",
3850 (segment->p_flags & PF_R ? 'R' : ' '),
3851 (segment->p_flags & PF_W ? 'W' : ' '),
3852 (segment->p_flags & PF_X ? 'E' : ' '));
3853 print_vma (segment->p_align, HEX);
3854 }
252b5132
RH
3855 }
3856
3857 switch (segment->p_type)
3858 {
252b5132
RH
3859 case PT_DYNAMIC:
3860 if (dynamic_addr)
3861 error (_("more than one dynamic segment\n"));
3862
20737c13
AM
3863 /* By default, assume that the .dynamic section is the first
3864 section in the DYNAMIC segment. */
3865 dynamic_addr = segment->p_offset;
3866 dynamic_size = segment->p_filesz;
3867
b2d38a17
NC
3868 /* Try to locate the .dynamic section. If there is
3869 a section header table, we can easily locate it. */
3870 if (section_headers != NULL)
3871 {
2cf0635d 3872 Elf_Internal_Shdr * sec;
b2d38a17 3873
89fac5e3
RS
3874 sec = find_section (".dynamic");
3875 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3876 {
28f997cf
TG
3877 /* A corresponding .dynamic section is expected, but on
3878 IA-64/OpenVMS it is OK for it to be missing. */
3879 if (!is_ia64_vms ())
3880 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3881 break;
3882 }
3883
42bb2e33 3884 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3885 {
3886 dynamic_size = 0;
3887 break;
3888 }
42bb2e33 3889
b2d38a17
NC
3890 dynamic_addr = sec->sh_offset;
3891 dynamic_size = sec->sh_size;
3892
3893 if (dynamic_addr < segment->p_offset
3894 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3895 warn (_("the .dynamic section is not contained"
3896 " within the dynamic segment\n"));
b2d38a17 3897 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3898 warn (_("the .dynamic section is not the first section"
3899 " in the dynamic segment.\n"));
b2d38a17 3900 }
252b5132
RH
3901 break;
3902
3903 case PT_INTERP:
fb52b2f4
NC
3904 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3905 SEEK_SET))
252b5132
RH
3906 error (_("Unable to find program interpreter name\n"));
3907 else
3908 {
f8eae8b2
L
3909 char fmt [32];
3910 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3911
3912 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3913 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3914
252b5132 3915 program_interpreter[0] = 0;
7bd7b3ef
AM
3916 if (fscanf (file, fmt, program_interpreter) <= 0)
3917 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3918
3919 if (do_segments)
3920 printf (_("\n [Requesting program interpreter: %s]"),
3921 program_interpreter);
3922 }
3923 break;
3924 }
3925
3926 if (do_segments)
3927 putc ('\n', stdout);
3928 }
3929
c256ffe7 3930 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3931 {
3932 printf (_("\n Section to Segment mapping:\n"));
3933 printf (_(" Segment Sections...\n"));
3934
252b5132
RH
3935 for (i = 0; i < elf_header.e_phnum; i++)
3936 {
9ad5cbcf 3937 unsigned int j;
2cf0635d 3938 Elf_Internal_Shdr * section;
252b5132
RH
3939
3940 segment = program_headers + i;
b391a3e3 3941 section = section_headers + 1;
252b5132
RH
3942
3943 printf (" %2.2d ", i);
3944
b34976b6 3945 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3946 {
f4638467
AM
3947 if (!ELF_TBSS_SPECIAL (section, segment)
3948 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
3949 printf ("%s ", SECTION_NAME (section));
3950 }
3951
3952 putc ('\n',stdout);
3953 }
3954 }
3955
252b5132
RH
3956 return 1;
3957}
3958
3959
d93f0186
NC
3960/* Find the file offset corresponding to VMA by using the program headers. */
3961
3962static long
2cf0635d 3963offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 3964{
2cf0635d 3965 Elf_Internal_Phdr * seg;
d93f0186
NC
3966
3967 if (! get_program_headers (file))
3968 {
3969 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3970 return (long) vma;
3971 }
3972
3973 for (seg = program_headers;
3974 seg < program_headers + elf_header.e_phnum;
3975 ++seg)
3976 {
3977 if (seg->p_type != PT_LOAD)
3978 continue;
3979
3980 if (vma >= (seg->p_vaddr & -seg->p_align)
3981 && vma + size <= seg->p_vaddr + seg->p_filesz)
3982 return vma - seg->p_vaddr + seg->p_offset;
3983 }
3984
3985 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 3986 (unsigned long) vma);
d93f0186
NC
3987 return (long) vma;
3988}
3989
3990
252b5132 3991static int
2cf0635d 3992get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 3993{
2cf0635d
NC
3994 Elf32_External_Shdr * shdrs;
3995 Elf_Internal_Shdr * internal;
b34976b6 3996 unsigned int i;
252b5132 3997
3f5e193b
NC
3998 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3999 elf_header.e_shentsize, num,
4000 _("section headers"));
a6e9f9df
AM
4001 if (!shdrs)
4002 return 0;
252b5132 4003
3f5e193b
NC
4004 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4005 sizeof (Elf_Internal_Shdr));
252b5132
RH
4006
4007 if (section_headers == NULL)
4008 {
4009 error (_("Out of memory\n"));
4010 return 0;
4011 }
4012
4013 for (i = 0, internal = section_headers;
560f3c1c 4014 i < num;
b34976b6 4015 i++, internal++)
252b5132
RH
4016 {
4017 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4018 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4019 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4020 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4021 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4022 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4023 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4024 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4025 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4026 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4027 }
4028
4029 free (shdrs);
4030
4031 return 1;
4032}
4033
9ea033b2 4034static int
2cf0635d 4035get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4036{
2cf0635d
NC
4037 Elf64_External_Shdr * shdrs;
4038 Elf_Internal_Shdr * internal;
b34976b6 4039 unsigned int i;
9ea033b2 4040
3f5e193b
NC
4041 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4042 elf_header.e_shentsize, num,
4043 _("section headers"));
a6e9f9df
AM
4044 if (!shdrs)
4045 return 0;
9ea033b2 4046
3f5e193b
NC
4047 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4048 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4049
4050 if (section_headers == NULL)
4051 {
4052 error (_("Out of memory\n"));
4053 return 0;
4054 }
4055
4056 for (i = 0, internal = section_headers;
560f3c1c 4057 i < num;
b34976b6 4058 i++, internal++)
9ea033b2
NC
4059 {
4060 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4061 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4062 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4063 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4064 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4065 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4066 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4067 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4068 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4069 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4070 }
4071
4072 free (shdrs);
4073
4074 return 1;
4075}
4076
252b5132 4077static Elf_Internal_Sym *
ba5cdace
NC
4078get_32bit_elf_symbols (FILE * file,
4079 Elf_Internal_Shdr * section,
4080 unsigned long * num_syms_return)
252b5132 4081{
ba5cdace 4082 unsigned long number = 0;
dd24e3da 4083 Elf32_External_Sym * esyms = NULL;
ba5cdace 4084 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4085 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4086 Elf_Internal_Sym * psym;
b34976b6 4087 unsigned int j;
252b5132 4088
dd24e3da
NC
4089 /* Run some sanity checks first. */
4090 if (section->sh_entsize == 0)
4091 {
4092 error (_("sh_entsize is zero\n"));
ba5cdace 4093 goto exit_point;
dd24e3da
NC
4094 }
4095
4096 number = section->sh_size / section->sh_entsize;
4097
4098 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4099 {
4100 error (_("Invalid sh_entsize\n"));
ba5cdace 4101 goto exit_point;
dd24e3da
NC
4102 }
4103
3f5e193b
NC
4104 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4105 section->sh_size, _("symbols"));
dd24e3da 4106 if (esyms == NULL)
ba5cdace 4107 goto exit_point;
252b5132 4108
9ad5cbcf
AM
4109 shndx = NULL;
4110 if (symtab_shndx_hdr != NULL
4111 && (symtab_shndx_hdr->sh_link
4fbb74a6 4112 == (unsigned long) (section - section_headers)))
9ad5cbcf 4113 {
3f5e193b
NC
4114 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4115 symtab_shndx_hdr->sh_offset,
4116 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4117 _("symbol table section indicies"));
dd24e3da
NC
4118 if (shndx == NULL)
4119 goto exit_point;
9ad5cbcf
AM
4120 }
4121
3f5e193b 4122 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4123
4124 if (isyms == NULL)
4125 {
4126 error (_("Out of memory\n"));
dd24e3da 4127 goto exit_point;
252b5132
RH
4128 }
4129
dd24e3da 4130 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4131 {
4132 psym->st_name = BYTE_GET (esyms[j].st_name);
4133 psym->st_value = BYTE_GET (esyms[j].st_value);
4134 psym->st_size = BYTE_GET (esyms[j].st_size);
4135 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4136 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4137 psym->st_shndx
4138 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4139 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4140 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4141 psym->st_info = BYTE_GET (esyms[j].st_info);
4142 psym->st_other = BYTE_GET (esyms[j].st_other);
4143 }
4144
dd24e3da 4145 exit_point:
ba5cdace 4146 if (shndx != NULL)
9ad5cbcf 4147 free (shndx);
ba5cdace 4148 if (esyms != NULL)
dd24e3da 4149 free (esyms);
252b5132 4150
ba5cdace
NC
4151 if (num_syms_return != NULL)
4152 * num_syms_return = isyms == NULL ? 0 : number;
4153
252b5132
RH
4154 return isyms;
4155}
4156
9ea033b2 4157static Elf_Internal_Sym *
ba5cdace
NC
4158get_64bit_elf_symbols (FILE * file,
4159 Elf_Internal_Shdr * section,
4160 unsigned long * num_syms_return)
9ea033b2 4161{
ba5cdace
NC
4162 unsigned long number = 0;
4163 Elf64_External_Sym * esyms = NULL;
4164 Elf_External_Sym_Shndx * shndx = NULL;
4165 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4166 Elf_Internal_Sym * psym;
b34976b6 4167 unsigned int j;
9ea033b2 4168
dd24e3da
NC
4169 /* Run some sanity checks first. */
4170 if (section->sh_entsize == 0)
4171 {
4172 error (_("sh_entsize is zero\n"));
ba5cdace 4173 goto exit_point;
dd24e3da
NC
4174 }
4175
4176 number = section->sh_size / section->sh_entsize;
4177
4178 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4179 {
4180 error (_("Invalid sh_entsize\n"));
ba5cdace 4181 goto exit_point;
dd24e3da
NC
4182 }
4183
3f5e193b
NC
4184 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4185 section->sh_size, _("symbols"));
a6e9f9df 4186 if (!esyms)
ba5cdace 4187 goto exit_point;
9ea033b2 4188
9ad5cbcf
AM
4189 if (symtab_shndx_hdr != NULL
4190 && (symtab_shndx_hdr->sh_link
4fbb74a6 4191 == (unsigned long) (section - section_headers)))
9ad5cbcf 4192 {
3f5e193b
NC
4193 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4194 symtab_shndx_hdr->sh_offset,
4195 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4196 _("symbol table section indicies"));
ba5cdace
NC
4197 if (shndx == NULL)
4198 goto exit_point;
9ad5cbcf
AM
4199 }
4200
3f5e193b 4201 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4202
4203 if (isyms == NULL)
4204 {
4205 error (_("Out of memory\n"));
ba5cdace 4206 goto exit_point;
9ea033b2
NC
4207 }
4208
ba5cdace 4209 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
4210 {
4211 psym->st_name = BYTE_GET (esyms[j].st_name);
4212 psym->st_info = BYTE_GET (esyms[j].st_info);
4213 psym->st_other = BYTE_GET (esyms[j].st_other);
4214 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 4215
4fbb74a6 4216 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4217 psym->st_shndx
4218 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4219 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4220 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 4221
66543521
AM
4222 psym->st_value = BYTE_GET (esyms[j].st_value);
4223 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4224 }
4225
ba5cdace
NC
4226 exit_point:
4227 if (shndx != NULL)
9ad5cbcf 4228 free (shndx);
ba5cdace
NC
4229 if (esyms != NULL)
4230 free (esyms);
4231
4232 if (num_syms_return != NULL)
4233 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
4234
4235 return isyms;
4236}
4237
d1133906 4238static const char *
d3ba0551 4239get_elf_section_flags (bfd_vma sh_flags)
d1133906 4240{
5477e8a0 4241 static char buff[1024];
2cf0635d 4242 char * p = buff;
8d5ff12c 4243 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4244 int sindex;
4245 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4246 bfd_vma os_flags = 0;
4247 bfd_vma proc_flags = 0;
4248 bfd_vma unknown_flags = 0;
148b93f2 4249 static const struct
5477e8a0 4250 {
2cf0635d 4251 const char * str;
5477e8a0
L
4252 int len;
4253 }
4254 flags [] =
4255 {
cfcac11d
NC
4256 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4257 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4258 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4259 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4260 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4261 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4262 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4263 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4264 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4265 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4266 /* IA-64 specific. */
4267 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4268 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4269 /* IA-64 OpenVMS specific. */
4270 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4271 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4272 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4273 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4274 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4275 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4276 /* Generic. */
cfcac11d 4277 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4278 /* SPARC specific. */
cfcac11d 4279 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4280 };
4281
4282 if (do_section_details)
4283 {
8d5ff12c
L
4284 sprintf (buff, "[%*.*lx]: ",
4285 field_size, field_size, (unsigned long) sh_flags);
4286 p += field_size + 4;
5477e8a0 4287 }
76da6bbe 4288
d1133906
NC
4289 while (sh_flags)
4290 {
4291 bfd_vma flag;
4292
4293 flag = sh_flags & - sh_flags;
4294 sh_flags &= ~ flag;
76da6bbe 4295
5477e8a0 4296 if (do_section_details)
d1133906 4297 {
5477e8a0
L
4298 switch (flag)
4299 {
91d6fa6a
NC
4300 case SHF_WRITE: sindex = 0; break;
4301 case SHF_ALLOC: sindex = 1; break;
4302 case SHF_EXECINSTR: sindex = 2; break;
4303 case SHF_MERGE: sindex = 3; break;
4304 case SHF_STRINGS: sindex = 4; break;
4305 case SHF_INFO_LINK: sindex = 5; break;
4306 case SHF_LINK_ORDER: sindex = 6; break;
4307 case SHF_OS_NONCONFORMING: sindex = 7; break;
4308 case SHF_GROUP: sindex = 8; break;
4309 case SHF_TLS: sindex = 9; break;
18ae9cc1 4310 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4311
5477e8a0 4312 default:
91d6fa6a 4313 sindex = -1;
cfcac11d 4314 switch (elf_header.e_machine)
148b93f2 4315 {
cfcac11d 4316 case EM_IA_64:
148b93f2 4317 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4318 sindex = 10;
148b93f2 4319 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4320 sindex = 11;
148b93f2
NC
4321#ifdef BFD64
4322 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4323 switch (flag)
4324 {
91d6fa6a
NC
4325 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4326 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4327 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4328 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4329 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4330 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4331 default: break;
4332 }
4333#endif
cfcac11d
NC
4334 break;
4335
caa83f8b
NC
4336 case EM_386:
4337 case EM_486:
4338 case EM_X86_64:
7f502d6c 4339 case EM_L1OM:
7a9068fe 4340 case EM_K1OM:
cfcac11d
NC
4341 case EM_OLD_SPARCV9:
4342 case EM_SPARC32PLUS:
4343 case EM_SPARCV9:
4344 case EM_SPARC:
18ae9cc1 4345 if (flag == SHF_ORDERED)
91d6fa6a 4346 sindex = 19;
cfcac11d
NC
4347 break;
4348 default:
4349 break;
148b93f2 4350 }
5477e8a0
L
4351 }
4352
91d6fa6a 4353 if (sindex != -1)
5477e8a0 4354 {
8d5ff12c
L
4355 if (p != buff + field_size + 4)
4356 {
4357 if (size < (10 + 2))
4358 abort ();
4359 size -= 2;
4360 *p++ = ',';
4361 *p++ = ' ';
4362 }
4363
91d6fa6a
NC
4364 size -= flags [sindex].len;
4365 p = stpcpy (p, flags [sindex].str);
5477e8a0 4366 }
3b22753a 4367 else if (flag & SHF_MASKOS)
8d5ff12c 4368 os_flags |= flag;
d1133906 4369 else if (flag & SHF_MASKPROC)
8d5ff12c 4370 proc_flags |= flag;
d1133906 4371 else
8d5ff12c 4372 unknown_flags |= flag;
5477e8a0
L
4373 }
4374 else
4375 {
4376 switch (flag)
4377 {
4378 case SHF_WRITE: *p = 'W'; break;
4379 case SHF_ALLOC: *p = 'A'; break;
4380 case SHF_EXECINSTR: *p = 'X'; break;
4381 case SHF_MERGE: *p = 'M'; break;
4382 case SHF_STRINGS: *p = 'S'; break;
4383 case SHF_INFO_LINK: *p = 'I'; break;
4384 case SHF_LINK_ORDER: *p = 'L'; break;
4385 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4386 case SHF_GROUP: *p = 'G'; break;
4387 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4388 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4389
4390 default:
8a9036a4 4391 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4392 || elf_header.e_machine == EM_L1OM
4393 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4394 && flag == SHF_X86_64_LARGE)
4395 *p = 'l';
4396 else if (flag & SHF_MASKOS)
4397 {
4398 *p = 'o';
4399 sh_flags &= ~ SHF_MASKOS;
4400 }
4401 else if (flag & SHF_MASKPROC)
4402 {
4403 *p = 'p';
4404 sh_flags &= ~ SHF_MASKPROC;
4405 }
4406 else
4407 *p = 'x';
4408 break;
4409 }
4410 p++;
d1133906
NC
4411 }
4412 }
76da6bbe 4413
8d5ff12c
L
4414 if (do_section_details)
4415 {
4416 if (os_flags)
4417 {
4418 size -= 5 + field_size;
4419 if (p != buff + field_size + 4)
4420 {
4421 if (size < (2 + 1))
4422 abort ();
4423 size -= 2;
4424 *p++ = ',';
4425 *p++ = ' ';
4426 }
4427 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4428 (unsigned long) os_flags);
4429 p += 5 + field_size;
4430 }
4431 if (proc_flags)
4432 {
4433 size -= 7 + field_size;
4434 if (p != buff + field_size + 4)
4435 {
4436 if (size < (2 + 1))
4437 abort ();
4438 size -= 2;
4439 *p++ = ',';
4440 *p++ = ' ';
4441 }
4442 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4443 (unsigned long) proc_flags);
4444 p += 7 + field_size;
4445 }
4446 if (unknown_flags)
4447 {
4448 size -= 10 + field_size;
4449 if (p != buff + field_size + 4)
4450 {
4451 if (size < (2 + 1))
4452 abort ();
4453 size -= 2;
4454 *p++ = ',';
4455 *p++ = ' ';
4456 }
2b692964 4457 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4458 (unsigned long) unknown_flags);
4459 p += 10 + field_size;
4460 }
4461 }
4462
e9e44622 4463 *p = '\0';
d1133906
NC
4464 return buff;
4465}
4466
252b5132 4467static int
2cf0635d 4468process_section_headers (FILE * file)
252b5132 4469{
2cf0635d 4470 Elf_Internal_Shdr * section;
b34976b6 4471 unsigned int i;
252b5132
RH
4472
4473 section_headers = NULL;
4474
4475 if (elf_header.e_shnum == 0)
4476 {
82f2dbf7
NC
4477 /* PR binutils/12467. */
4478 if (elf_header.e_shoff != 0)
4479 warn (_("possibly corrupt ELF file header - it has a non-zero"
4480 " section header offset, but no section headers\n"));
4481 else if (do_sections)
252b5132
RH
4482 printf (_("\nThere are no sections in this file.\n"));
4483
4484 return 1;
4485 }
4486
4487 if (do_sections && !do_header)
9ea033b2 4488 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4489 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4490
9ea033b2
NC
4491 if (is_32bit_elf)
4492 {
560f3c1c 4493 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4494 return 0;
4495 }
560f3c1c 4496 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4497 return 0;
4498
4499 /* Read in the string table, so that we have names to display. */
0b49d371 4500 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4501 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4502 {
4fbb74a6 4503 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4504
c256ffe7
JJ
4505 if (section->sh_size != 0)
4506 {
3f5e193b
NC
4507 string_table = (char *) get_data (NULL, file, section->sh_offset,
4508 1, section->sh_size,
4509 _("string table"));
0de14b54 4510
c256ffe7
JJ
4511 string_table_length = string_table != NULL ? section->sh_size : 0;
4512 }
252b5132
RH
4513 }
4514
4515 /* Scan the sections for the dynamic symbol table
e3c8793a 4516 and dynamic string table and debug sections. */
252b5132
RH
4517 dynamic_symbols = NULL;
4518 dynamic_strings = NULL;
4519 dynamic_syminfo = NULL;
f1ef08cb 4520 symtab_shndx_hdr = NULL;
103f02d3 4521
89fac5e3
RS
4522 eh_addr_size = is_32bit_elf ? 4 : 8;
4523 switch (elf_header.e_machine)
4524 {
4525 case EM_MIPS:
4526 case EM_MIPS_RS3_LE:
4527 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4528 FDE addresses. However, the ABI also has a semi-official ILP32
4529 variant for which the normal FDE address size rules apply.
4530
4531 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4532 section, where XX is the size of longs in bits. Unfortunately,
4533 earlier compilers provided no way of distinguishing ILP32 objects
4534 from LP64 objects, so if there's any doubt, we should assume that
4535 the official LP64 form is being used. */
4536 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4537 && find_section (".gcc_compiled_long32") == NULL)
4538 eh_addr_size = 8;
4539 break;
0f56a26a
DD
4540
4541 case EM_H8_300:
4542 case EM_H8_300H:
4543 switch (elf_header.e_flags & EF_H8_MACH)
4544 {
4545 case E_H8_MACH_H8300:
4546 case E_H8_MACH_H8300HN:
4547 case E_H8_MACH_H8300SN:
4548 case E_H8_MACH_H8300SXN:
4549 eh_addr_size = 2;
4550 break;
4551 case E_H8_MACH_H8300H:
4552 case E_H8_MACH_H8300S:
4553 case E_H8_MACH_H8300SX:
4554 eh_addr_size = 4;
4555 break;
4556 }
f4236fe4
DD
4557 break;
4558
ff7eeb89 4559 case EM_M32C_OLD:
f4236fe4
DD
4560 case EM_M32C:
4561 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4562 {
4563 case EF_M32C_CPU_M16C:
4564 eh_addr_size = 2;
4565 break;
4566 }
4567 break;
89fac5e3
RS
4568 }
4569
08d8fa11
JJ
4570#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4571 do \
4572 { \
4573 size_t expected_entsize \
4574 = is_32bit_elf ? size32 : size64; \
4575 if (section->sh_entsize != expected_entsize) \
4576 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4577 i, (unsigned long int) section->sh_entsize, \
4578 (unsigned long int) expected_entsize); \
4579 section->sh_entsize = expected_entsize; \
4580 } \
4581 while (0)
4582#define CHECK_ENTSIZE(section, i, type) \
4583 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4584 sizeof (Elf64_External_##type))
4585
252b5132
RH
4586 for (i = 0, section = section_headers;
4587 i < elf_header.e_shnum;
b34976b6 4588 i++, section++)
252b5132 4589 {
2cf0635d 4590 char * name = SECTION_NAME (section);
252b5132
RH
4591
4592 if (section->sh_type == SHT_DYNSYM)
4593 {
4594 if (dynamic_symbols != NULL)
4595 {
4596 error (_("File contains multiple dynamic symbol tables\n"));
4597 continue;
4598 }
4599
08d8fa11 4600 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 4601 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
4602 }
4603 else if (section->sh_type == SHT_STRTAB
18bd398b 4604 && streq (name, ".dynstr"))
252b5132
RH
4605 {
4606 if (dynamic_strings != NULL)
4607 {
4608 error (_("File contains multiple dynamic string tables\n"));
4609 continue;
4610 }
4611
3f5e193b
NC
4612 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4613 1, section->sh_size,
4614 _("dynamic strings"));
59245841 4615 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4616 }
9ad5cbcf
AM
4617 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4618 {
4619 if (symtab_shndx_hdr != NULL)
4620 {
4621 error (_("File contains multiple symtab shndx tables\n"));
4622 continue;
4623 }
4624 symtab_shndx_hdr = section;
4625 }
08d8fa11
JJ
4626 else if (section->sh_type == SHT_SYMTAB)
4627 CHECK_ENTSIZE (section, i, Sym);
4628 else if (section->sh_type == SHT_GROUP)
4629 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4630 else if (section->sh_type == SHT_REL)
4631 CHECK_ENTSIZE (section, i, Rel);
4632 else if (section->sh_type == SHT_RELA)
4633 CHECK_ENTSIZE (section, i, Rela);
252b5132 4634 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4635 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4636 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4637 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4638 && (const_strneq (name, ".debug_")
4639 || const_strneq (name, ".zdebug_")))
252b5132 4640 {
1b315056
CS
4641 if (name[1] == 'z')
4642 name += sizeof (".zdebug_") - 1;
4643 else
4644 name += sizeof (".debug_") - 1;
252b5132
RH
4645
4646 if (do_debugging
4723351a
CC
4647 || (do_debug_info && const_strneq (name, "info"))
4648 || (do_debug_info && const_strneq (name, "types"))
4649 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
4650 || (do_debug_lines && const_strneq (name, "line"))
4651 || (do_debug_pubnames && const_strneq (name, "pubnames"))
4652 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
4653 || (do_debug_aranges && const_strneq (name, "aranges"))
4654 || (do_debug_ranges && const_strneq (name, "ranges"))
4655 || (do_debug_frames && const_strneq (name, "frame"))
4656 || (do_debug_macinfo && const_strneq (name, "macinfo"))
4657 || (do_debug_macinfo && const_strneq (name, "macro"))
4658 || (do_debug_str && const_strneq (name, "str"))
4659 || (do_debug_loc && const_strneq (name, "loc"))
252b5132 4660 )
09c11c86 4661 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4662 }
a262ae96 4663 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4664 else if ((do_debugging || do_debug_info)
0112cd26 4665 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4666 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4667 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4668 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4669 else if (do_gdb_index && streq (name, ".gdb_index"))
4670 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4671 /* Trace sections for Itanium VMS. */
4672 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4673 || do_trace_aranges)
4674 && const_strneq (name, ".trace_"))
4675 {
4676 name += sizeof (".trace_") - 1;
4677
4678 if (do_debugging
4679 || (do_trace_info && streq (name, "info"))
4680 || (do_trace_abbrevs && streq (name, "abbrev"))
4681 || (do_trace_aranges && streq (name, "aranges"))
4682 )
4683 request_dump_bynumber (i, DEBUG_DUMP);
4684 }
4685
252b5132
RH
4686 }
4687
4688 if (! do_sections)
4689 return 1;
4690
3a1a2036
NC
4691 if (elf_header.e_shnum > 1)
4692 printf (_("\nSection Headers:\n"));
4693 else
4694 printf (_("\nSection Header:\n"));
76da6bbe 4695
f7a99963 4696 if (is_32bit_elf)
595cf52e 4697 {
5477e8a0 4698 if (do_section_details)
595cf52e
L
4699 {
4700 printf (_(" [Nr] Name\n"));
5477e8a0 4701 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4702 }
4703 else
4704 printf
4705 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4706 }
d974e256 4707 else if (do_wide)
595cf52e 4708 {
5477e8a0 4709 if (do_section_details)
595cf52e
L
4710 {
4711 printf (_(" [Nr] Name\n"));
5477e8a0 4712 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4713 }
4714 else
4715 printf
4716 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4717 }
f7a99963
NC
4718 else
4719 {
5477e8a0 4720 if (do_section_details)
595cf52e
L
4721 {
4722 printf (_(" [Nr] Name\n"));
5477e8a0
L
4723 printf (_(" Type Address Offset Link\n"));
4724 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4725 }
4726 else
4727 {
4728 printf (_(" [Nr] Name Type Address Offset\n"));
4729 printf (_(" Size EntSize Flags Link Info Align\n"));
4730 }
f7a99963 4731 }
252b5132 4732
5477e8a0
L
4733 if (do_section_details)
4734 printf (_(" Flags\n"));
4735
252b5132
RH
4736 for (i = 0, section = section_headers;
4737 i < elf_header.e_shnum;
b34976b6 4738 i++, section++)
252b5132 4739 {
5477e8a0 4740 if (do_section_details)
595cf52e
L
4741 {
4742 printf (" [%2u] %s\n",
4fbb74a6 4743 i,
595cf52e
L
4744 SECTION_NAME (section));
4745 if (is_32bit_elf || do_wide)
4746 printf (" %-15.15s ",
4747 get_section_type_name (section->sh_type));
4748 }
4749 else
b9eb56c1
NC
4750 printf ((do_wide ? " [%2u] %-17s %-15s "
4751 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4752 i,
595cf52e
L
4753 SECTION_NAME (section),
4754 get_section_type_name (section->sh_type));
252b5132 4755
f7a99963
NC
4756 if (is_32bit_elf)
4757 {
cfcac11d
NC
4758 const char * link_too_big = NULL;
4759
f7a99963 4760 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4761
f7a99963
NC
4762 printf ( " %6.6lx %6.6lx %2.2lx",
4763 (unsigned long) section->sh_offset,
4764 (unsigned long) section->sh_size,
4765 (unsigned long) section->sh_entsize);
d1133906 4766
5477e8a0
L
4767 if (do_section_details)
4768 fputs (" ", stdout);
4769 else
4770 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4771
cfcac11d
NC
4772 if (section->sh_link >= elf_header.e_shnum)
4773 {
4774 link_too_big = "";
4775 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4776 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4777 switch (elf_header.e_machine)
4778 {
caa83f8b
NC
4779 case EM_386:
4780 case EM_486:
4781 case EM_X86_64:
7f502d6c 4782 case EM_L1OM:
7a9068fe 4783 case EM_K1OM:
cfcac11d
NC
4784 case EM_OLD_SPARCV9:
4785 case EM_SPARC32PLUS:
4786 case EM_SPARCV9:
4787 case EM_SPARC:
4788 if (section->sh_link == (SHN_BEFORE & 0xffff))
4789 link_too_big = "BEFORE";
4790 else if (section->sh_link == (SHN_AFTER & 0xffff))
4791 link_too_big = "AFTER";
4792 break;
4793 default:
4794 break;
4795 }
4796 }
4797
4798 if (do_section_details)
4799 {
4800 if (link_too_big != NULL && * link_too_big)
4801 printf ("<%s> ", link_too_big);
4802 else
4803 printf ("%2u ", section->sh_link);
4804 printf ("%3u %2lu\n", section->sh_info,
4805 (unsigned long) section->sh_addralign);
4806 }
4807 else
4808 printf ("%2u %3u %2lu\n",
4809 section->sh_link,
4810 section->sh_info,
4811 (unsigned long) section->sh_addralign);
4812
4813 if (link_too_big && ! * link_too_big)
4814 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4815 i, section->sh_link);
f7a99963 4816 }
d974e256
JJ
4817 else if (do_wide)
4818 {
4819 print_vma (section->sh_addr, LONG_HEX);
4820
4821 if ((long) section->sh_offset == section->sh_offset)
4822 printf (" %6.6lx", (unsigned long) section->sh_offset);
4823 else
4824 {
4825 putchar (' ');
4826 print_vma (section->sh_offset, LONG_HEX);
4827 }
4828
4829 if ((unsigned long) section->sh_size == section->sh_size)
4830 printf (" %6.6lx", (unsigned long) section->sh_size);
4831 else
4832 {
4833 putchar (' ');
4834 print_vma (section->sh_size, LONG_HEX);
4835 }
4836
4837 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4838 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4839 else
4840 {
4841 putchar (' ');
4842 print_vma (section->sh_entsize, LONG_HEX);
4843 }
4844
5477e8a0
L
4845 if (do_section_details)
4846 fputs (" ", stdout);
4847 else
4848 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4849
72de5009 4850 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4851
4852 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4853 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4854 else
4855 {
4856 print_vma (section->sh_addralign, DEC);
4857 putchar ('\n');
4858 }
4859 }
5477e8a0 4860 else if (do_section_details)
595cf52e 4861 {
5477e8a0 4862 printf (" %-15.15s ",
595cf52e 4863 get_section_type_name (section->sh_type));
595cf52e
L
4864 print_vma (section->sh_addr, LONG_HEX);
4865 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4866 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4867 else
4868 {
4869 printf (" ");
4870 print_vma (section->sh_offset, LONG_HEX);
4871 }
72de5009 4872 printf (" %u\n ", section->sh_link);
595cf52e 4873 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4874 putchar (' ');
595cf52e
L
4875 print_vma (section->sh_entsize, LONG_HEX);
4876
72de5009
AM
4877 printf (" %-16u %lu\n",
4878 section->sh_info,
595cf52e
L
4879 (unsigned long) section->sh_addralign);
4880 }
f7a99963
NC
4881 else
4882 {
4883 putchar (' ');
4884 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4885 if ((long) section->sh_offset == section->sh_offset)
4886 printf (" %8.8lx", (unsigned long) section->sh_offset);
4887 else
4888 {
4889 printf (" ");
4890 print_vma (section->sh_offset, LONG_HEX);
4891 }
f7a99963
NC
4892 printf ("\n ");
4893 print_vma (section->sh_size, LONG_HEX);
4894 printf (" ");
4895 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4896
d1133906 4897 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4898
72de5009
AM
4899 printf (" %2u %3u %lu\n",
4900 section->sh_link,
4901 section->sh_info,
f7a99963
NC
4902 (unsigned long) section->sh_addralign);
4903 }
5477e8a0
L
4904
4905 if (do_section_details)
4906 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4907 }
4908
5477e8a0 4909 if (!do_section_details)
3dbcc61d
NC
4910 {
4911 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
4912 || elf_header.e_machine == EM_L1OM
4913 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
4914 printf (_("Key to Flags:\n\
4915 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
4916 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
4917 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
4918 else
4919 printf (_("Key to Flags:\n\
e3c8793a 4920 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 4921 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 4922 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 4923 }
d1133906 4924
252b5132
RH
4925 return 1;
4926}
4927
f5842774
L
4928static const char *
4929get_group_flags (unsigned int flags)
4930{
4931 static char buff[32];
4932 switch (flags)
4933 {
220453ec
AM
4934 case 0:
4935 return "";
4936
f5842774 4937 case GRP_COMDAT:
220453ec 4938 return "COMDAT ";
f5842774
L
4939
4940 default:
220453ec 4941 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
4942 break;
4943 }
4944 return buff;
4945}
4946
4947static int
2cf0635d 4948process_section_groups (FILE * file)
f5842774 4949{
2cf0635d 4950 Elf_Internal_Shdr * section;
f5842774 4951 unsigned int i;
2cf0635d
NC
4952 struct group * group;
4953 Elf_Internal_Shdr * symtab_sec;
4954 Elf_Internal_Shdr * strtab_sec;
4955 Elf_Internal_Sym * symtab;
ba5cdace 4956 unsigned long num_syms;
2cf0635d 4957 char * strtab;
c256ffe7 4958 size_t strtab_size;
d1f5c6e3
L
4959
4960 /* Don't process section groups unless needed. */
4961 if (!do_unwind && !do_section_groups)
4962 return 1;
f5842774
L
4963
4964 if (elf_header.e_shnum == 0)
4965 {
4966 if (do_section_groups)
82f2dbf7 4967 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
4968
4969 return 1;
4970 }
4971
4972 if (section_headers == NULL)
4973 {
4974 error (_("Section headers are not available!\n"));
fa1908fd
NC
4975 /* PR 13622: This can happen with a corrupt ELF header. */
4976 return 0;
f5842774
L
4977 }
4978
3f5e193b
NC
4979 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
4980 sizeof (struct group *));
e4b17d5c
L
4981
4982 if (section_headers_groups == NULL)
4983 {
4984 error (_("Out of memory\n"));
4985 return 0;
4986 }
4987
f5842774 4988 /* Scan the sections for the group section. */
d1f5c6e3 4989 group_count = 0;
f5842774
L
4990 for (i = 0, section = section_headers;
4991 i < elf_header.e_shnum;
4992 i++, section++)
e4b17d5c
L
4993 if (section->sh_type == SHT_GROUP)
4994 group_count++;
4995
d1f5c6e3
L
4996 if (group_count == 0)
4997 {
4998 if (do_section_groups)
4999 printf (_("\nThere are no section groups in this file.\n"));
5000
5001 return 1;
5002 }
5003
3f5e193b 5004 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5005
5006 if (section_groups == NULL)
5007 {
5008 error (_("Out of memory\n"));
5009 return 0;
5010 }
5011
d1f5c6e3
L
5012 symtab_sec = NULL;
5013 strtab_sec = NULL;
5014 symtab = NULL;
ba5cdace 5015 num_syms = 0;
d1f5c6e3 5016 strtab = NULL;
c256ffe7 5017 strtab_size = 0;
e4b17d5c
L
5018 for (i = 0, section = section_headers, group = section_groups;
5019 i < elf_header.e_shnum;
5020 i++, section++)
f5842774
L
5021 {
5022 if (section->sh_type == SHT_GROUP)
5023 {
2cf0635d
NC
5024 char * name = SECTION_NAME (section);
5025 char * group_name;
5026 unsigned char * start;
5027 unsigned char * indices;
f5842774 5028 unsigned int entry, j, size;
2cf0635d
NC
5029 Elf_Internal_Shdr * sec;
5030 Elf_Internal_Sym * sym;
f5842774
L
5031
5032 /* Get the symbol table. */
4fbb74a6
AM
5033 if (section->sh_link >= elf_header.e_shnum
5034 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5035 != SHT_SYMTAB))
f5842774
L
5036 {
5037 error (_("Bad sh_link in group section `%s'\n"), name);
5038 continue;
5039 }
d1f5c6e3
L
5040
5041 if (symtab_sec != sec)
5042 {
5043 symtab_sec = sec;
5044 if (symtab)
5045 free (symtab);
ba5cdace 5046 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5047 }
f5842774 5048
dd24e3da
NC
5049 if (symtab == NULL)
5050 {
5051 error (_("Corrupt header in group section `%s'\n"), name);
5052 continue;
5053 }
5054
ba5cdace
NC
5055 if (section->sh_info >= num_syms)
5056 {
5057 error (_("Bad sh_info in group section `%s'\n"), name);
5058 continue;
5059 }
5060
f5842774
L
5061 sym = symtab + section->sh_info;
5062
5063 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5064 {
4fbb74a6
AM
5065 if (sym->st_shndx == 0
5066 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5067 {
5068 error (_("Bad sh_info in group section `%s'\n"), name);
5069 continue;
5070 }
ba2685cc 5071
4fbb74a6 5072 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5073 strtab_sec = NULL;
5074 if (strtab)
5075 free (strtab);
f5842774 5076 strtab = NULL;
c256ffe7 5077 strtab_size = 0;
f5842774
L
5078 }
5079 else
5080 {
5081 /* Get the string table. */
4fbb74a6 5082 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5083 {
5084 strtab_sec = NULL;
5085 if (strtab)
5086 free (strtab);
5087 strtab = NULL;
5088 strtab_size = 0;
5089 }
5090 else if (strtab_sec
4fbb74a6 5091 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5092 {
5093 strtab_sec = sec;
5094 if (strtab)
5095 free (strtab);
3f5e193b
NC
5096 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5097 1, strtab_sec->sh_size,
5098 _("string table"));
c256ffe7 5099 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5100 }
c256ffe7 5101 group_name = sym->st_name < strtab_size
2b692964 5102 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5103 }
5104
3f5e193b
NC
5105 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5106 1, section->sh_size,
5107 _("section data"));
59245841
NC
5108 if (start == NULL)
5109 continue;
f5842774
L
5110
5111 indices = start;
5112 size = (section->sh_size / section->sh_entsize) - 1;
5113 entry = byte_get (indices, 4);
5114 indices += 4;
e4b17d5c
L
5115
5116 if (do_section_groups)
5117 {
2b692964 5118 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5119 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5120
e4b17d5c
L
5121 printf (_(" [Index] Name\n"));
5122 }
5123
5124 group->group_index = i;
5125
f5842774
L
5126 for (j = 0; j < size; j++)
5127 {
2cf0635d 5128 struct group_list * g;
e4b17d5c 5129
f5842774
L
5130 entry = byte_get (indices, 4);
5131 indices += 4;
5132
4fbb74a6 5133 if (entry >= elf_header.e_shnum)
391cb864
L
5134 {
5135 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5136 entry, i, elf_header.e_shnum - 1);
5137 continue;
5138 }
391cb864 5139
4fbb74a6 5140 if (section_headers_groups [entry] != NULL)
e4b17d5c 5141 {
d1f5c6e3
L
5142 if (entry)
5143 {
391cb864
L
5144 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5145 entry, i,
4fbb74a6 5146 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5147 continue;
5148 }
5149 else
5150 {
5151 /* Intel C/C++ compiler may put section 0 in a
5152 section group. We just warn it the first time
5153 and ignore it afterwards. */
5154 static int warned = 0;
5155 if (!warned)
5156 {
5157 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5158 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5159 warned++;
5160 }
5161 }
e4b17d5c
L
5162 }
5163
4fbb74a6 5164 section_headers_groups [entry] = group;
e4b17d5c
L
5165
5166 if (do_section_groups)
5167 {
4fbb74a6 5168 sec = section_headers + entry;
c256ffe7 5169 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5170 }
5171
3f5e193b 5172 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5173 g->section_index = entry;
5174 g->next = group->root;
5175 group->root = g;
f5842774
L
5176 }
5177
f5842774
L
5178 if (start)
5179 free (start);
e4b17d5c
L
5180
5181 group++;
f5842774
L
5182 }
5183 }
5184
d1f5c6e3
L
5185 if (symtab)
5186 free (symtab);
5187 if (strtab)
5188 free (strtab);
f5842774
L
5189 return 1;
5190}
5191
28f997cf
TG
5192/* Data used to display dynamic fixups. */
5193
5194struct ia64_vms_dynfixup
5195{
5196 bfd_vma needed_ident; /* Library ident number. */
5197 bfd_vma needed; /* Index in the dstrtab of the library name. */
5198 bfd_vma fixup_needed; /* Index of the library. */
5199 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5200 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5201};
5202
5203/* Data used to display dynamic relocations. */
5204
5205struct ia64_vms_dynimgrela
5206{
5207 bfd_vma img_rela_cnt; /* Number of relocations. */
5208 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5209};
5210
5211/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5212 library). */
5213
5214static void
5215dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5216 const char *strtab, unsigned int strtab_sz)
5217{
5218 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5219 long i;
5220 const char *lib_name;
5221
5222 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5223 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5224 _("dynamic section image fixups"));
5225 if (!imfs)
5226 return;
5227
5228 if (fixup->needed < strtab_sz)
5229 lib_name = strtab + fixup->needed;
5230 else
5231 {
5232 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5233 (unsigned long) fixup->needed);
28f997cf
TG
5234 lib_name = "???";
5235 }
5236 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5237 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5238 printf
5239 (_("Seg Offset Type SymVec DataType\n"));
5240
5241 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5242 {
5243 unsigned int type;
5244 const char *rtype;
5245
5246 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5247 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5248 type = BYTE_GET (imfs [i].type);
5249 rtype = elf_ia64_reloc_type (type);
5250 if (rtype == NULL)
5251 printf (" 0x%08x ", type);
5252 else
5253 printf (" %-32s ", rtype);
5254 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5255 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5256 }
5257
5258 free (imfs);
5259}
5260
5261/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5262
5263static void
5264dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5265{
5266 Elf64_External_VMS_IMAGE_RELA *imrs;
5267 long i;
5268
5269 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5270 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 5271 _("dynamic section image relocations"));
28f997cf
TG
5272 if (!imrs)
5273 return;
5274
5275 printf (_("\nImage relocs\n"));
5276 printf
5277 (_("Seg Offset Type Addend Seg Sym Off\n"));
5278
5279 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5280 {
5281 unsigned int type;
5282 const char *rtype;
5283
5284 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5285 printf ("%08" BFD_VMA_FMT "x ",
5286 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5287 type = BYTE_GET (imrs [i].type);
5288 rtype = elf_ia64_reloc_type (type);
5289 if (rtype == NULL)
5290 printf ("0x%08x ", type);
5291 else
5292 printf ("%-31s ", rtype);
5293 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5294 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5295 printf ("%08" BFD_VMA_FMT "x\n",
5296 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5297 }
5298
5299 free (imrs);
5300}
5301
5302/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5303
5304static int
5305process_ia64_vms_dynamic_relocs (FILE *file)
5306{
5307 struct ia64_vms_dynfixup fixup;
5308 struct ia64_vms_dynimgrela imgrela;
5309 Elf_Internal_Dyn *entry;
5310 int res = 0;
5311 bfd_vma strtab_off = 0;
5312 bfd_vma strtab_sz = 0;
5313 char *strtab = NULL;
5314
5315 memset (&fixup, 0, sizeof (fixup));
5316 memset (&imgrela, 0, sizeof (imgrela));
5317
5318 /* Note: the order of the entries is specified by the OpenVMS specs. */
5319 for (entry = dynamic_section;
5320 entry < dynamic_section + dynamic_nent;
5321 entry++)
5322 {
5323 switch (entry->d_tag)
5324 {
5325 case DT_IA_64_VMS_STRTAB_OFFSET:
5326 strtab_off = entry->d_un.d_val;
5327 break;
5328 case DT_STRSZ:
5329 strtab_sz = entry->d_un.d_val;
5330 if (strtab == NULL)
5331 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5332 1, strtab_sz, _("dynamic string section"));
5333 break;
5334
5335 case DT_IA_64_VMS_NEEDED_IDENT:
5336 fixup.needed_ident = entry->d_un.d_val;
5337 break;
5338 case DT_NEEDED:
5339 fixup.needed = entry->d_un.d_val;
5340 break;
5341 case DT_IA_64_VMS_FIXUP_NEEDED:
5342 fixup.fixup_needed = entry->d_un.d_val;
5343 break;
5344 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5345 fixup.fixup_rela_cnt = entry->d_un.d_val;
5346 break;
5347 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5348 fixup.fixup_rela_off = entry->d_un.d_val;
5349 res++;
5350 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5351 break;
5352
5353 case DT_IA_64_VMS_IMG_RELA_CNT:
5354 imgrela.img_rela_cnt = entry->d_un.d_val;
5355 break;
5356 case DT_IA_64_VMS_IMG_RELA_OFF:
5357 imgrela.img_rela_off = entry->d_un.d_val;
5358 res++;
5359 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5360 break;
5361
5362 default:
5363 break;
5364 }
5365 }
5366
5367 if (strtab != NULL)
5368 free (strtab);
5369
5370 return res;
5371}
5372
85b1c36d 5373static struct
566b0d53 5374{
2cf0635d 5375 const char * name;
566b0d53
L
5376 int reloc;
5377 int size;
5378 int rela;
5379} dynamic_relocations [] =
5380{
5381 { "REL", DT_REL, DT_RELSZ, FALSE },
5382 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5383 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5384};
5385
252b5132 5386/* Process the reloc section. */
18bd398b 5387
252b5132 5388static int
2cf0635d 5389process_relocs (FILE * file)
252b5132 5390{
b34976b6
AM
5391 unsigned long rel_size;
5392 unsigned long rel_offset;
252b5132
RH
5393
5394
5395 if (!do_reloc)
5396 return 1;
5397
5398 if (do_using_dynamic)
5399 {
566b0d53 5400 int is_rela;
2cf0635d 5401 const char * name;
566b0d53
L
5402 int has_dynamic_reloc;
5403 unsigned int i;
0de14b54 5404
566b0d53 5405 has_dynamic_reloc = 0;
252b5132 5406
566b0d53 5407 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5408 {
566b0d53
L
5409 is_rela = dynamic_relocations [i].rela;
5410 name = dynamic_relocations [i].name;
5411 rel_size = dynamic_info [dynamic_relocations [i].size];
5412 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5413
566b0d53
L
5414 has_dynamic_reloc |= rel_size;
5415
5416 if (is_rela == UNKNOWN)
aa903cfb 5417 {
566b0d53
L
5418 if (dynamic_relocations [i].reloc == DT_JMPREL)
5419 switch (dynamic_info[DT_PLTREL])
5420 {
5421 case DT_REL:
5422 is_rela = FALSE;
5423 break;
5424 case DT_RELA:
5425 is_rela = TRUE;
5426 break;
5427 }
aa903cfb 5428 }
252b5132 5429
566b0d53
L
5430 if (rel_size)
5431 {
5432 printf
5433 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5434 name, rel_offset, rel_size);
252b5132 5435
d93f0186
NC
5436 dump_relocations (file,
5437 offset_from_vma (file, rel_offset, rel_size),
5438 rel_size,
566b0d53 5439 dynamic_symbols, num_dynamic_syms,
d79b3d50 5440 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5441 }
252b5132 5442 }
566b0d53 5443
28f997cf
TG
5444 if (is_ia64_vms ())
5445 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5446
566b0d53 5447 if (! has_dynamic_reloc)
252b5132
RH
5448 printf (_("\nThere are no dynamic relocations in this file.\n"));
5449 }
5450 else
5451 {
2cf0635d 5452 Elf_Internal_Shdr * section;
b34976b6
AM
5453 unsigned long i;
5454 int found = 0;
252b5132
RH
5455
5456 for (i = 0, section = section_headers;
5457 i < elf_header.e_shnum;
b34976b6 5458 i++, section++)
252b5132
RH
5459 {
5460 if ( section->sh_type != SHT_RELA
5461 && section->sh_type != SHT_REL)
5462 continue;
5463
5464 rel_offset = section->sh_offset;
5465 rel_size = section->sh_size;
5466
5467 if (rel_size)
5468 {
2cf0635d 5469 Elf_Internal_Shdr * strsec;
b34976b6 5470 int is_rela;
103f02d3 5471
252b5132
RH
5472 printf (_("\nRelocation section "));
5473
5474 if (string_table == NULL)
19936277 5475 printf ("%d", section->sh_name);
252b5132 5476 else
9cf03b7e 5477 printf ("'%s'", SECTION_NAME (section));
252b5132
RH
5478
5479 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5480 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5481
d79b3d50
NC
5482 is_rela = section->sh_type == SHT_RELA;
5483
4fbb74a6
AM
5484 if (section->sh_link != 0
5485 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5486 {
2cf0635d
NC
5487 Elf_Internal_Shdr * symsec;
5488 Elf_Internal_Sym * symtab;
d79b3d50 5489 unsigned long nsyms;
c256ffe7 5490 unsigned long strtablen = 0;
2cf0635d 5491 char * strtab = NULL;
57346661 5492
4fbb74a6 5493 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5494 if (symsec->sh_type != SHT_SYMTAB
5495 && symsec->sh_type != SHT_DYNSYM)
5496 continue;
5497
ba5cdace 5498 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 5499
af3fc3bc
AM
5500 if (symtab == NULL)
5501 continue;
252b5132 5502
4fbb74a6
AM
5503 if (symsec->sh_link != 0
5504 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5505 {
4fbb74a6 5506 strsec = section_headers + symsec->sh_link;
103f02d3 5507
3f5e193b
NC
5508 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5509 1, strsec->sh_size,
5510 _("string table"));
c256ffe7
JJ
5511 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5512 }
252b5132 5513
d79b3d50
NC
5514 dump_relocations (file, rel_offset, rel_size,
5515 symtab, nsyms, strtab, strtablen, is_rela);
5516 if (strtab)
5517 free (strtab);
5518 free (symtab);
5519 }
5520 else
5521 dump_relocations (file, rel_offset, rel_size,
5522 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5523
5524 found = 1;
5525 }
5526 }
5527
5528 if (! found)
5529 printf (_("\nThere are no relocations in this file.\n"));
5530 }
5531
5532 return 1;
5533}
5534
57346661
AM
5535/* Process the unwind section. */
5536
4d6ed7c8
NC
5537#include "unwind-ia64.h"
5538
5539/* An absolute address consists of a section and an offset. If the
5540 section is NULL, the offset itself is the address, otherwise, the
5541 address equals to LOAD_ADDRESS(section) + offset. */
5542
5543struct absaddr
5544 {
5545 unsigned short section;
5546 bfd_vma offset;
5547 };
5548
1949de15
L
5549#define ABSADDR(a) \
5550 ((a).section \
5551 ? section_headers [(a).section].sh_addr + (a).offset \
5552 : (a).offset)
5553
3f5e193b
NC
5554struct ia64_unw_table_entry
5555 {
5556 struct absaddr start;
5557 struct absaddr end;
5558 struct absaddr info;
5559 };
5560
57346661 5561struct ia64_unw_aux_info
4d6ed7c8 5562 {
3f5e193b
NC
5563
5564 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5565 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5566 unsigned char * info; /* Unwind info. */
b34976b6
AM
5567 unsigned long info_size; /* Size of unwind info. */
5568 bfd_vma info_addr; /* starting address of unwind info. */
5569 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5570 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5571 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5572 char * strtab; /* The string table. */
b34976b6 5573 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5574 };
5575
4d6ed7c8 5576static void
2cf0635d 5577find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5578 unsigned long nsyms,
2cf0635d 5579 const char * strtab,
57346661 5580 unsigned long strtab_size,
d3ba0551 5581 struct absaddr addr,
2cf0635d
NC
5582 const char ** symname,
5583 bfd_vma * offset)
4d6ed7c8 5584{
d3ba0551 5585 bfd_vma dist = 0x100000;
2cf0635d
NC
5586 Elf_Internal_Sym * sym;
5587 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5588 unsigned long i;
5589
0b6ae522
DJ
5590 REMOVE_ARCH_BITS (addr.offset);
5591
57346661 5592 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5593 {
0b6ae522
DJ
5594 bfd_vma value = sym->st_value;
5595
5596 REMOVE_ARCH_BITS (value);
5597
4d6ed7c8
NC
5598 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5599 && sym->st_name != 0
5600 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5601 && addr.offset >= value
5602 && addr.offset - value < dist)
4d6ed7c8
NC
5603 {
5604 best = sym;
0b6ae522 5605 dist = addr.offset - value;
4d6ed7c8
NC
5606 if (!dist)
5607 break;
5608 }
5609 }
1b31d05e 5610
4d6ed7c8
NC
5611 if (best)
5612 {
57346661 5613 *symname = (best->st_name >= strtab_size
2b692964 5614 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5615 *offset = dist;
5616 return;
5617 }
1b31d05e 5618
4d6ed7c8
NC
5619 *symname = NULL;
5620 *offset = addr.offset;
5621}
5622
5623static void
2cf0635d 5624dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5625{
2cf0635d 5626 struct ia64_unw_table_entry * tp;
4d6ed7c8 5627 int in_body;
7036c0e1 5628
4d6ed7c8
NC
5629 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5630 {
5631 bfd_vma stamp;
5632 bfd_vma offset;
2cf0635d
NC
5633 const unsigned char * dp;
5634 const unsigned char * head;
5635 const char * procname;
4d6ed7c8 5636
57346661
AM
5637 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5638 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5639
5640 fputs ("\n<", stdout);
5641
5642 if (procname)
5643 {
5644 fputs (procname, stdout);
5645
5646 if (offset)
5647 printf ("+%lx", (unsigned long) offset);
5648 }
5649
5650 fputs (">: [", stdout);
5651 print_vma (tp->start.offset, PREFIX_HEX);
5652 fputc ('-', stdout);
5653 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5654 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5655 (unsigned long) (tp->info.offset - aux->seg_base));
5656
1949de15 5657 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5658 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5659
86f55779 5660 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5661 (unsigned) UNW_VER (stamp),
5662 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5663 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5664 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5665 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5666
5667 if (UNW_VER (stamp) != 1)
5668 {
2b692964 5669 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5670 continue;
5671 }
5672
5673 in_body = 0;
89fac5e3 5674 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5675 dp = unw_decode (dp, in_body, & in_body);
5676 }
5677}
5678
5679static int
2cf0635d
NC
5680slurp_ia64_unwind_table (FILE * file,
5681 struct ia64_unw_aux_info * aux,
5682 Elf_Internal_Shdr * sec)
4d6ed7c8 5683{
89fac5e3 5684 unsigned long size, nrelas, i;
2cf0635d
NC
5685 Elf_Internal_Phdr * seg;
5686 struct ia64_unw_table_entry * tep;
5687 Elf_Internal_Shdr * relsec;
5688 Elf_Internal_Rela * rela;
5689 Elf_Internal_Rela * rp;
5690 unsigned char * table;
5691 unsigned char * tp;
5692 Elf_Internal_Sym * sym;
5693 const char * relname;
4d6ed7c8 5694
4d6ed7c8
NC
5695 /* First, find the starting address of the segment that includes
5696 this section: */
5697
5698 if (elf_header.e_phnum)
5699 {
d93f0186 5700 if (! get_program_headers (file))
4d6ed7c8 5701 return 0;
4d6ed7c8 5702
d93f0186
NC
5703 for (seg = program_headers;
5704 seg < program_headers + elf_header.e_phnum;
5705 ++seg)
4d6ed7c8
NC
5706 {
5707 if (seg->p_type != PT_LOAD)
5708 continue;
5709
5710 if (sec->sh_addr >= seg->p_vaddr
5711 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5712 {
5713 aux->seg_base = seg->p_vaddr;
5714 break;
5715 }
5716 }
4d6ed7c8
NC
5717 }
5718
5719 /* Second, build the unwind table from the contents of the unwind section: */
5720 size = sec->sh_size;
3f5e193b
NC
5721 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5722 _("unwind table"));
a6e9f9df
AM
5723 if (!table)
5724 return 0;
4d6ed7c8 5725
3f5e193b
NC
5726 aux->table = (struct ia64_unw_table_entry *)
5727 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5728 tep = aux->table;
c6a0c689 5729 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5730 {
5731 tep->start.section = SHN_UNDEF;
5732 tep->end.section = SHN_UNDEF;
5733 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5734 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5735 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5736 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5737 tep->start.offset += aux->seg_base;
5738 tep->end.offset += aux->seg_base;
5739 tep->info.offset += aux->seg_base;
5740 }
5741 free (table);
5742
41e92641 5743 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5744 for (relsec = section_headers;
5745 relsec < section_headers + elf_header.e_shnum;
5746 ++relsec)
5747 {
5748 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5749 || relsec->sh_info >= elf_header.e_shnum
5750 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5751 continue;
5752
5753 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5754 & rela, & nrelas))
5755 return 0;
5756
5757 for (rp = rela; rp < rela + nrelas; ++rp)
5758 {
aca88567
NC
5759 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5760 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5761
0112cd26 5762 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5763 {
e5fb9629 5764 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5765 continue;
5766 }
5767
89fac5e3 5768 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5769
89fac5e3 5770 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5771 {
5772 case 0:
5773 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5774 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5775 break;
5776 case 1:
5777 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5778 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5779 break;
5780 case 2:
5781 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5782 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5783 break;
5784 default:
5785 break;
5786 }
5787 }
5788
5789 free (rela);
5790 }
5791
89fac5e3 5792 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5793 return 1;
5794}
5795
1b31d05e 5796static void
2cf0635d 5797ia64_process_unwind (FILE * file)
4d6ed7c8 5798{
2cf0635d
NC
5799 Elf_Internal_Shdr * sec;
5800 Elf_Internal_Shdr * unwsec = NULL;
5801 Elf_Internal_Shdr * strsec;
89fac5e3 5802 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5803 struct ia64_unw_aux_info aux;
f1467e33 5804
4d6ed7c8
NC
5805 memset (& aux, 0, sizeof (aux));
5806
4d6ed7c8
NC
5807 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5808 {
c256ffe7 5809 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5810 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 5811 {
ba5cdace 5812 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 5813
4fbb74a6 5814 strsec = section_headers + sec->sh_link;
59245841 5815 assert (aux.strtab == NULL);
3f5e193b
NC
5816 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5817 1, strsec->sh_size,
5818 _("string table"));
c256ffe7 5819 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5820 }
5821 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5822 unwcount++;
5823 }
5824
5825 if (!unwcount)
5826 printf (_("\nThere are no unwind sections in this file.\n"));
5827
5828 while (unwcount-- > 0)
5829 {
2cf0635d 5830 char * suffix;
579f31ac
JJ
5831 size_t len, len2;
5832
5833 for (i = unwstart, sec = section_headers + unwstart;
5834 i < elf_header.e_shnum; ++i, ++sec)
5835 if (sec->sh_type == SHT_IA_64_UNWIND)
5836 {
5837 unwsec = sec;
5838 break;
5839 }
5840
5841 unwstart = i + 1;
5842 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5843
e4b17d5c
L
5844 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5845 {
5846 /* We need to find which section group it is in. */
2cf0635d 5847 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5848
5849 for (; g != NULL; g = g->next)
5850 {
4fbb74a6 5851 sec = section_headers + g->section_index;
18bd398b
NC
5852
5853 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5854 break;
e4b17d5c
L
5855 }
5856
5857 if (g == NULL)
5858 i = elf_header.e_shnum;
5859 }
18bd398b 5860 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5861 {
18bd398b 5862 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5863 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5864 suffix = SECTION_NAME (unwsec) + len;
5865 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5866 ++i, ++sec)
18bd398b
NC
5867 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5868 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5869 break;
5870 }
5871 else
5872 {
5873 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5874 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5875 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5876 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5877 suffix = "";
18bd398b 5878 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5879 suffix = SECTION_NAME (unwsec) + len;
5880 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5881 ++i, ++sec)
18bd398b
NC
5882 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5883 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5884 break;
5885 }
5886
5887 if (i == elf_header.e_shnum)
5888 {
5889 printf (_("\nCould not find unwind info section for "));
5890
5891 if (string_table == NULL)
5892 printf ("%d", unwsec->sh_name);
5893 else
3a1a2036 5894 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5895 }
5896 else
4d6ed7c8 5897 {
4d6ed7c8 5898 aux.info_addr = sec->sh_addr;
3f5e193b 5899 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 5900 sec->sh_size,
3f5e193b 5901 _("unwind info"));
59245841 5902 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 5903
579f31ac 5904 printf (_("\nUnwind section "));
4d6ed7c8 5905
579f31ac
JJ
5906 if (string_table == NULL)
5907 printf ("%d", unwsec->sh_name);
5908 else
3a1a2036 5909 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5910
579f31ac 5911 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5912 (unsigned long) unwsec->sh_offset,
89fac5e3 5913 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5914
579f31ac 5915 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5916
579f31ac
JJ
5917 if (aux.table_len > 0)
5918 dump_ia64_unwind (& aux);
5919
5920 if (aux.table)
5921 free ((char *) aux.table);
5922 if (aux.info)
5923 free ((char *) aux.info);
5924 aux.table = NULL;
5925 aux.info = NULL;
5926 }
4d6ed7c8 5927 }
4d6ed7c8 5928
4d6ed7c8
NC
5929 if (aux.symtab)
5930 free (aux.symtab);
5931 if (aux.strtab)
5932 free ((char *) aux.strtab);
4d6ed7c8
NC
5933}
5934
3f5e193b
NC
5935struct hppa_unw_table_entry
5936 {
5937 struct absaddr start;
5938 struct absaddr end;
5939 unsigned int Cannot_unwind:1; /* 0 */
5940 unsigned int Millicode:1; /* 1 */
5941 unsigned int Millicode_save_sr0:1; /* 2 */
5942 unsigned int Region_description:2; /* 3..4 */
5943 unsigned int reserved1:1; /* 5 */
5944 unsigned int Entry_SR:1; /* 6 */
5945 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5946 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5947 unsigned int Args_stored:1; /* 16 */
5948 unsigned int Variable_Frame:1; /* 17 */
5949 unsigned int Separate_Package_Body:1; /* 18 */
5950 unsigned int Frame_Extension_Millicode:1; /* 19 */
5951 unsigned int Stack_Overflow_Check:1; /* 20 */
5952 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5953 unsigned int Ada_Region:1; /* 22 */
5954 unsigned int cxx_info:1; /* 23 */
5955 unsigned int cxx_try_catch:1; /* 24 */
5956 unsigned int sched_entry_seq:1; /* 25 */
5957 unsigned int reserved2:1; /* 26 */
5958 unsigned int Save_SP:1; /* 27 */
5959 unsigned int Save_RP:1; /* 28 */
5960 unsigned int Save_MRP_in_frame:1; /* 29 */
5961 unsigned int extn_ptr_defined:1; /* 30 */
5962 unsigned int Cleanup_defined:1; /* 31 */
5963
5964 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5965 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5966 unsigned int Large_frame:1; /* 2 */
5967 unsigned int Pseudo_SP_Set:1; /* 3 */
5968 unsigned int reserved4:1; /* 4 */
5969 unsigned int Total_frame_size:27; /* 5..31 */
5970 };
5971
57346661
AM
5972struct hppa_unw_aux_info
5973 {
3f5e193b 5974 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
5975 unsigned long table_len; /* Length of unwind table. */
5976 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5977 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5978 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5979 char * strtab; /* The string table. */
57346661
AM
5980 unsigned long strtab_size; /* Size of string table. */
5981 };
5982
5983static void
2cf0635d 5984dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5985{
2cf0635d 5986 struct hppa_unw_table_entry * tp;
57346661 5987
57346661
AM
5988 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5989 {
5990 bfd_vma offset;
2cf0635d 5991 const char * procname;
57346661
AM
5992
5993 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5994 aux->strtab_size, tp->start, &procname,
5995 &offset);
5996
5997 fputs ("\n<", stdout);
5998
5999 if (procname)
6000 {
6001 fputs (procname, stdout);
6002
6003 if (offset)
6004 printf ("+%lx", (unsigned long) offset);
6005 }
6006
6007 fputs (">: [", stdout);
6008 print_vma (tp->start.offset, PREFIX_HEX);
6009 fputc ('-', stdout);
6010 print_vma (tp->end.offset, PREFIX_HEX);
6011 printf ("]\n\t");
6012
18bd398b
NC
6013#define PF(_m) if (tp->_m) printf (#_m " ");
6014#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6015 PF(Cannot_unwind);
6016 PF(Millicode);
6017 PF(Millicode_save_sr0);
18bd398b 6018 /* PV(Region_description); */
57346661
AM
6019 PF(Entry_SR);
6020 PV(Entry_FR);
6021 PV(Entry_GR);
6022 PF(Args_stored);
6023 PF(Variable_Frame);
6024 PF(Separate_Package_Body);
6025 PF(Frame_Extension_Millicode);
6026 PF(Stack_Overflow_Check);
6027 PF(Two_Instruction_SP_Increment);
6028 PF(Ada_Region);
6029 PF(cxx_info);
6030 PF(cxx_try_catch);
6031 PF(sched_entry_seq);
6032 PF(Save_SP);
6033 PF(Save_RP);
6034 PF(Save_MRP_in_frame);
6035 PF(extn_ptr_defined);
6036 PF(Cleanup_defined);
6037 PF(MPE_XL_interrupt_marker);
6038 PF(HP_UX_interrupt_marker);
6039 PF(Large_frame);
6040 PF(Pseudo_SP_Set);
6041 PV(Total_frame_size);
6042#undef PF
6043#undef PV
6044 }
6045
18bd398b 6046 printf ("\n");
57346661
AM
6047}
6048
6049static int
2cf0635d
NC
6050slurp_hppa_unwind_table (FILE * file,
6051 struct hppa_unw_aux_info * aux,
6052 Elf_Internal_Shdr * sec)
57346661 6053{
1c0751b2 6054 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6055 Elf_Internal_Phdr * seg;
6056 struct hppa_unw_table_entry * tep;
6057 Elf_Internal_Shdr * relsec;
6058 Elf_Internal_Rela * rela;
6059 Elf_Internal_Rela * rp;
6060 unsigned char * table;
6061 unsigned char * tp;
6062 Elf_Internal_Sym * sym;
6063 const char * relname;
57346661 6064
57346661
AM
6065 /* First, find the starting address of the segment that includes
6066 this section. */
6067
6068 if (elf_header.e_phnum)
6069 {
6070 if (! get_program_headers (file))
6071 return 0;
6072
6073 for (seg = program_headers;
6074 seg < program_headers + elf_header.e_phnum;
6075 ++seg)
6076 {
6077 if (seg->p_type != PT_LOAD)
6078 continue;
6079
6080 if (sec->sh_addr >= seg->p_vaddr
6081 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6082 {
6083 aux->seg_base = seg->p_vaddr;
6084 break;
6085 }
6086 }
6087 }
6088
6089 /* Second, build the unwind table from the contents of the unwind
6090 section. */
6091 size = sec->sh_size;
3f5e193b
NC
6092 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6093 _("unwind table"));
57346661
AM
6094 if (!table)
6095 return 0;
6096
1c0751b2
DA
6097 unw_ent_size = 16;
6098 nentries = size / unw_ent_size;
6099 size = unw_ent_size * nentries;
57346661 6100
3f5e193b
NC
6101 tep = aux->table = (struct hppa_unw_table_entry *)
6102 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6103
1c0751b2 6104 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6105 {
6106 unsigned int tmp1, tmp2;
6107
6108 tep->start.section = SHN_UNDEF;
6109 tep->end.section = SHN_UNDEF;
6110
1c0751b2
DA
6111 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6112 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6113 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6114 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6115
6116 tep->start.offset += aux->seg_base;
6117 tep->end.offset += aux->seg_base;
57346661
AM
6118
6119 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6120 tep->Millicode = (tmp1 >> 30) & 0x1;
6121 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6122 tep->Region_description = (tmp1 >> 27) & 0x3;
6123 tep->reserved1 = (tmp1 >> 26) & 0x1;
6124 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6125 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6126 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6127 tep->Args_stored = (tmp1 >> 15) & 0x1;
6128 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6129 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6130 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6131 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6132 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6133 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6134 tep->cxx_info = (tmp1 >> 8) & 0x1;
6135 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6136 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6137 tep->reserved2 = (tmp1 >> 5) & 0x1;
6138 tep->Save_SP = (tmp1 >> 4) & 0x1;
6139 tep->Save_RP = (tmp1 >> 3) & 0x1;
6140 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6141 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6142 tep->Cleanup_defined = tmp1 & 0x1;
6143
6144 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6145 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6146 tep->Large_frame = (tmp2 >> 29) & 0x1;
6147 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6148 tep->reserved4 = (tmp2 >> 27) & 0x1;
6149 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6150 }
6151 free (table);
6152
6153 /* Third, apply any relocations to the unwind table. */
57346661
AM
6154 for (relsec = section_headers;
6155 relsec < section_headers + elf_header.e_shnum;
6156 ++relsec)
6157 {
6158 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6159 || relsec->sh_info >= elf_header.e_shnum
6160 || section_headers + relsec->sh_info != sec)
57346661
AM
6161 continue;
6162
6163 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6164 & rela, & nrelas))
6165 return 0;
6166
6167 for (rp = rela; rp < rela + nrelas; ++rp)
6168 {
aca88567
NC
6169 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6170 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6171
6172 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6173 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6174 {
6175 warn (_("Skipping unexpected relocation type %s\n"), relname);
6176 continue;
6177 }
6178
6179 i = rp->r_offset / unw_ent_size;
6180
89fac5e3 6181 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6182 {
6183 case 0:
6184 aux->table[i].start.section = sym->st_shndx;
1e456d54 6185 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6186 break;
6187 case 1:
6188 aux->table[i].end.section = sym->st_shndx;
1e456d54 6189 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6190 break;
6191 default:
6192 break;
6193 }
6194 }
6195
6196 free (rela);
6197 }
6198
1c0751b2 6199 aux->table_len = nentries;
57346661
AM
6200
6201 return 1;
6202}
6203
1b31d05e 6204static void
2cf0635d 6205hppa_process_unwind (FILE * file)
57346661 6206{
57346661 6207 struct hppa_unw_aux_info aux;
2cf0635d
NC
6208 Elf_Internal_Shdr * unwsec = NULL;
6209 Elf_Internal_Shdr * strsec;
6210 Elf_Internal_Shdr * sec;
18bd398b 6211 unsigned long i;
57346661 6212
c256ffe7 6213 if (string_table == NULL)
1b31d05e
NC
6214 return;
6215
6216 memset (& aux, 0, sizeof (aux));
57346661
AM
6217
6218 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6219 {
c256ffe7 6220 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6221 && sec->sh_link < elf_header.e_shnum)
57346661 6222 {
ba5cdace 6223 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 6224
4fbb74a6 6225 strsec = section_headers + sec->sh_link;
59245841 6226 assert (aux.strtab == NULL);
3f5e193b
NC
6227 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6228 1, strsec->sh_size,
6229 _("string table"));
c256ffe7 6230 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6231 }
18bd398b 6232 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6233 unwsec = sec;
6234 }
6235
6236 if (!unwsec)
6237 printf (_("\nThere are no unwind sections in this file.\n"));
6238
6239 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6240 {
18bd398b 6241 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6242 {
57346661
AM
6243 printf (_("\nUnwind section "));
6244 printf (_("'%s'"), SECTION_NAME (sec));
6245
6246 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6247 (unsigned long) sec->sh_offset,
89fac5e3 6248 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6249
6250 slurp_hppa_unwind_table (file, &aux, sec);
6251 if (aux.table_len > 0)
6252 dump_hppa_unwind (&aux);
6253
6254 if (aux.table)
6255 free ((char *) aux.table);
6256 aux.table = NULL;
6257 }
6258 }
6259
6260 if (aux.symtab)
6261 free (aux.symtab);
6262 if (aux.strtab)
6263 free ((char *) aux.strtab);
57346661
AM
6264}
6265
0b6ae522
DJ
6266struct arm_section
6267{
a734115a
NC
6268 unsigned char * data; /* The unwind data. */
6269 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
6270 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
6271 unsigned long nrelas; /* The number of relocations. */
6272 unsigned int rel_type; /* REL or RELA ? */
6273 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
6274};
6275
6276struct arm_unw_aux_info
6277{
a734115a
NC
6278 FILE * file; /* The file containing the unwind sections. */
6279 Elf_Internal_Sym * symtab; /* The file's symbol table. */
6280 unsigned long nsyms; /* Number of symbols. */
6281 char * strtab; /* The file's string table. */
6282 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
6283};
6284
6285static const char *
6286arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6287 bfd_vma fn, struct absaddr addr)
6288{
6289 const char *procname;
6290 bfd_vma sym_offset;
6291
6292 if (addr.section == SHN_UNDEF)
6293 addr.offset = fn;
6294
6295 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6296 aux->strtab_size, addr, &procname,
6297 &sym_offset);
6298
6299 print_vma (fn, PREFIX_HEX);
6300
6301 if (procname)
6302 {
6303 fputs (" <", stdout);
6304 fputs (procname, stdout);
6305
6306 if (sym_offset)
6307 printf ("+0x%lx", (unsigned long) sym_offset);
6308 fputc ('>', stdout);
6309 }
6310
6311 return procname;
6312}
6313
6314static void
6315arm_free_section (struct arm_section *arm_sec)
6316{
6317 if (arm_sec->data != NULL)
6318 free (arm_sec->data);
6319
6320 if (arm_sec->rela != NULL)
6321 free (arm_sec->rela);
6322}
6323
a734115a
NC
6324/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
6325 cached section and install SEC instead.
6326 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
6327 and return its valued in * WORDP, relocating if necessary.
1b31d05e 6328 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 6329 relocation's offset in ADDR.
1b31d05e
NC
6330 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
6331 into the string table of the symbol associated with the reloc. If no
6332 reloc was applied store -1 there.
6333 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
6334
6335static bfd_boolean
1b31d05e
NC
6336get_unwind_section_word (struct arm_unw_aux_info * aux,
6337 struct arm_section * arm_sec,
6338 Elf_Internal_Shdr * sec,
6339 bfd_vma word_offset,
6340 unsigned int * wordp,
6341 struct absaddr * addr,
6342 bfd_vma * sym_name)
0b6ae522
DJ
6343{
6344 Elf_Internal_Rela *rp;
6345 Elf_Internal_Sym *sym;
6346 const char * relname;
6347 unsigned int word;
6348 bfd_boolean wrapped;
6349
6350 addr->section = SHN_UNDEF;
6351 addr->offset = 0;
6352
1b31d05e
NC
6353 if (sym_name != NULL)
6354 *sym_name = (bfd_vma) -1;
6355
a734115a 6356 /* If necessary, update the section cache. */
0b6ae522
DJ
6357 if (sec != arm_sec->sec)
6358 {
6359 Elf_Internal_Shdr *relsec;
6360
6361 arm_free_section (arm_sec);
6362
6363 arm_sec->sec = sec;
6364 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6365 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6366 arm_sec->rela = NULL;
6367 arm_sec->nrelas = 0;
6368
6369 for (relsec = section_headers;
6370 relsec < section_headers + elf_header.e_shnum;
6371 ++relsec)
6372 {
6373 if (relsec->sh_info >= elf_header.e_shnum
6374 || section_headers + relsec->sh_info != sec)
6375 continue;
6376
a734115a 6377 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
6378 if (relsec->sh_type == SHT_REL)
6379 {
6380 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6381 relsec->sh_size,
6382 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6383 return FALSE;
0b6ae522
DJ
6384 break;
6385 }
6386 else if (relsec->sh_type == SHT_RELA)
6387 {
6388 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6389 relsec->sh_size,
6390 & arm_sec->rela, & arm_sec->nrelas))
a734115a 6391 return FALSE;
0b6ae522
DJ
6392 break;
6393 }
a734115a
NC
6394 else
6395 warn (_("unexpected relocation type (%d) for section %d"),
6396 relsec->sh_type, relsec->sh_info);
0b6ae522
DJ
6397 }
6398
6399 arm_sec->next_rela = arm_sec->rela;
6400 }
6401
a734115a 6402 /* If there is no unwind data we can do nothing. */
0b6ae522 6403 if (arm_sec->data == NULL)
a734115a 6404 return FALSE;
0b6ae522 6405
a734115a 6406 /* Get the word at the required offset. */
0b6ae522
DJ
6407 word = byte_get (arm_sec->data + word_offset, 4);
6408
a734115a 6409 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
6410 wrapped = FALSE;
6411 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6412 {
6413 bfd_vma prelval, offset;
6414
6415 if (rp->r_offset > word_offset && !wrapped)
6416 {
6417 rp = arm_sec->rela;
6418 wrapped = TRUE;
6419 }
6420 if (rp->r_offset > word_offset)
6421 break;
6422
6423 if (rp->r_offset & 3)
6424 {
6425 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6426 (unsigned long) rp->r_offset);
6427 continue;
6428 }
6429
6430 if (rp->r_offset < word_offset)
6431 continue;
6432
0b6ae522
DJ
6433 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6434
6435 if (arm_sec->rel_type == SHT_REL)
6436 {
6437 offset = word & 0x7fffffff;
6438 if (offset & 0x40000000)
6439 offset |= ~ (bfd_vma) 0x7fffffff;
6440 }
a734115a 6441 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 6442 offset = rp->r_addend;
a734115a
NC
6443 else
6444 abort ();
0b6ae522
DJ
6445
6446 offset += sym->st_value;
6447 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6448
a734115a
NC
6449 /* Check that we are processing the expected reloc type. */
6450 if (elf_header.e_machine == EM_ARM)
6451 {
6452 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6453
6454 if (streq (relname, "R_ARM_NONE"))
6455 continue;
6456
6457 if (! streq (relname, "R_ARM_PREL31"))
6458 {
6459 warn (_("Skipping unexpected relocation type %s\n"), relname);
6460 continue;
6461 }
6462 }
6463 else if (elf_header.e_machine == EM_TI_C6000)
6464 {
6465 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6466
6467 if (streq (relname, "R_C6000_NONE"))
6468 continue;
6469
6470 if (! streq (relname, "R_C6000_PREL31"))
6471 {
6472 warn (_("Skipping unexpected relocation type %s\n"), relname);
6473 continue;
6474 }
6475
6476 prelval >>= 1;
6477 }
6478 else
6479 /* This function currently only supports ARM and TI unwinders. */
6480 abort ();
fa197c1c 6481
0b6ae522
DJ
6482 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6483 addr->section = sym->st_shndx;
6484 addr->offset = offset;
1b31d05e
NC
6485 if (sym_name)
6486 * sym_name = sym->st_name;
0b6ae522
DJ
6487 break;
6488 }
6489
6490 *wordp = word;
6491 arm_sec->next_rela = rp;
6492
a734115a 6493 return TRUE;
0b6ae522
DJ
6494}
6495
a734115a
NC
6496static const char *tic6x_unwind_regnames[16] =
6497{
6498 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6499 "A14", "A13", "A12", "A11", "A10",
6500 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
6501};
fa197c1c 6502
0b6ae522 6503static void
fa197c1c 6504decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6505{
fa197c1c
PB
6506 int i;
6507
6508 for (i = 12; mask; mask >>= 1, i--)
6509 {
6510 if (mask & 1)
6511 {
6512 fputs (tic6x_unwind_regnames[i], stdout);
6513 if (mask > 1)
6514 fputs (", ", stdout);
6515 }
6516 }
6517}
0b6ae522
DJ
6518
6519#define ADVANCE \
6520 if (remaining == 0 && more_words) \
6521 { \
6522 data_offset += 4; \
1b31d05e
NC
6523 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
6524 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
6525 return; \
6526 remaining = 4; \
6527 more_words--; \
6528 } \
6529
6530#define GET_OP(OP) \
6531 ADVANCE; \
6532 if (remaining) \
6533 { \
6534 remaining--; \
6535 (OP) = word >> 24; \
6536 word <<= 8; \
6537 } \
6538 else \
6539 { \
2b692964 6540 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6541 return; \
6542 } \
cc5914eb 6543 printf ("0x%02x ", OP)
0b6ae522 6544
fa197c1c
PB
6545static void
6546decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6547 unsigned int word, unsigned int remaining,
6548 unsigned int more_words,
6549 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6550 struct arm_section *data_arm_sec)
6551{
6552 struct absaddr addr;
0b6ae522
DJ
6553
6554 /* Decode the unwinding instructions. */
6555 while (1)
6556 {
6557 unsigned int op, op2;
6558
6559 ADVANCE;
6560 if (remaining == 0)
6561 break;
6562 remaining--;
6563 op = word >> 24;
6564 word <<= 8;
6565
cc5914eb 6566 printf (" 0x%02x ", op);
0b6ae522
DJ
6567
6568 if ((op & 0xc0) == 0x00)
6569 {
6570 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6571
cc5914eb 6572 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6573 }
6574 else if ((op & 0xc0) == 0x40)
6575 {
6576 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6577
cc5914eb 6578 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6579 }
6580 else if ((op & 0xf0) == 0x80)
6581 {
6582 GET_OP (op2);
6583 if (op == 0x80 && op2 == 0)
6584 printf (_("Refuse to unwind"));
6585 else
6586 {
6587 unsigned int mask = ((op & 0x0f) << 8) | op2;
6588 int first = 1;
6589 int i;
2b692964 6590
0b6ae522
DJ
6591 printf ("pop {");
6592 for (i = 0; i < 12; i++)
6593 if (mask & (1 << i))
6594 {
6595 if (first)
6596 first = 0;
6597 else
6598 printf (", ");
6599 printf ("r%d", 4 + i);
6600 }
6601 printf ("}");
6602 }
6603 }
6604 else if ((op & 0xf0) == 0x90)
6605 {
6606 if (op == 0x9d || op == 0x9f)
6607 printf (_(" [Reserved]"));
6608 else
cc5914eb 6609 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6610 }
6611 else if ((op & 0xf0) == 0xa0)
6612 {
6613 int end = 4 + (op & 0x07);
6614 int first = 1;
6615 int i;
61865e30 6616
0b6ae522
DJ
6617 printf (" pop {");
6618 for (i = 4; i <= end; i++)
6619 {
6620 if (first)
6621 first = 0;
6622 else
6623 printf (", ");
6624 printf ("r%d", i);
6625 }
6626 if (op & 0x08)
6627 {
1b31d05e 6628 if (!first)
0b6ae522
DJ
6629 printf (", ");
6630 printf ("r14");
6631 }
6632 printf ("}");
6633 }
6634 else if (op == 0xb0)
6635 printf (_(" finish"));
6636 else if (op == 0xb1)
6637 {
6638 GET_OP (op2);
6639 if (op2 == 0 || (op2 & 0xf0) != 0)
6640 printf (_("[Spare]"));
6641 else
6642 {
6643 unsigned int mask = op2 & 0x0f;
6644 int first = 1;
6645 int i;
61865e30 6646
0b6ae522
DJ
6647 printf ("pop {");
6648 for (i = 0; i < 12; i++)
6649 if (mask & (1 << i))
6650 {
6651 if (first)
6652 first = 0;
6653 else
6654 printf (", ");
6655 printf ("r%d", i);
6656 }
6657 printf ("}");
6658 }
6659 }
6660 else if (op == 0xb2)
6661 {
b115cf96 6662 unsigned char buf[9];
0b6ae522
DJ
6663 unsigned int i, len;
6664 unsigned long offset;
61865e30 6665
b115cf96 6666 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6667 {
6668 GET_OP (buf[i]);
6669 if ((buf[i] & 0x80) == 0)
6670 break;
6671 }
6672 assert (i < sizeof (buf));
6673 offset = read_uleb128 (buf, &len);
6674 assert (len == i + 1);
6675 offset = offset * 4 + 0x204;
cc5914eb 6676 printf ("vsp = vsp + %ld", offset);
0b6ae522 6677 }
61865e30 6678 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6679 {
61865e30
NC
6680 unsigned int first, last;
6681
6682 GET_OP (op2);
6683 first = op2 >> 4;
6684 last = op2 & 0x0f;
6685 if (op == 0xc8)
6686 first = first + 16;
6687 printf ("pop {D%d", first);
6688 if (last)
6689 printf ("-D%d", first + last);
6690 printf ("}");
6691 }
6692 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6693 {
6694 unsigned int count = op & 0x07;
6695
6696 printf ("pop {D8");
6697 if (count)
6698 printf ("-D%d", 8 + count);
6699 printf ("}");
6700 }
6701 else if (op >= 0xc0 && op <= 0xc5)
6702 {
6703 unsigned int count = op & 0x07;
6704
6705 printf (" pop {wR10");
6706 if (count)
6707 printf ("-wR%d", 10 + count);
6708 printf ("}");
6709 }
6710 else if (op == 0xc6)
6711 {
6712 unsigned int first, last;
6713
6714 GET_OP (op2);
6715 first = op2 >> 4;
6716 last = op2 & 0x0f;
6717 printf ("pop {wR%d", first);
6718 if (last)
6719 printf ("-wR%d", first + last);
6720 printf ("}");
6721 }
6722 else if (op == 0xc7)
6723 {
6724 GET_OP (op2);
6725 if (op2 == 0 || (op2 & 0xf0) != 0)
6726 printf (_("[Spare]"));
0b6ae522
DJ
6727 else
6728 {
61865e30
NC
6729 unsigned int mask = op2 & 0x0f;
6730 int first = 1;
6731 int i;
6732
6733 printf ("pop {");
6734 for (i = 0; i < 4; i++)
6735 if (mask & (1 << i))
6736 {
6737 if (first)
6738 first = 0;
6739 else
6740 printf (", ");
6741 printf ("wCGR%d", i);
6742 }
6743 printf ("}");
0b6ae522
DJ
6744 }
6745 }
61865e30
NC
6746 else
6747 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6748 printf ("\n");
6749 }
fa197c1c
PB
6750}
6751
6752static void
6753decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6754 unsigned int word, unsigned int remaining,
6755 unsigned int more_words,
6756 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6757 struct arm_section *data_arm_sec)
6758{
6759 struct absaddr addr;
6760
6761 /* Decode the unwinding instructions. */
6762 while (1)
6763 {
6764 unsigned int op, op2;
6765
6766 ADVANCE;
6767 if (remaining == 0)
6768 break;
6769 remaining--;
6770 op = word >> 24;
6771 word <<= 8;
6772
9cf03b7e 6773 printf (" 0x%02x ", op);
fa197c1c
PB
6774
6775 if ((op & 0xc0) == 0x00)
6776 {
6777 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 6778 printf (" sp = sp + %d", offset);
fa197c1c
PB
6779 }
6780 else if ((op & 0xc0) == 0x80)
6781 {
6782 GET_OP (op2);
6783 if (op == 0x80 && op2 == 0)
6784 printf (_("Refuse to unwind"));
6785 else
6786 {
6787 unsigned int mask = ((op & 0x1f) << 8) | op2;
6788 if (op & 0x20)
6789 printf ("pop compact {");
6790 else
6791 printf ("pop {");
6792
6793 decode_tic6x_unwind_regmask (mask);
6794 printf("}");
6795 }
6796 }
6797 else if ((op & 0xf0) == 0xc0)
6798 {
6799 unsigned int reg;
6800 unsigned int nregs;
6801 unsigned int i;
6802 const char *name;
a734115a
NC
6803 struct
6804 {
fa197c1c
PB
6805 unsigned int offset;
6806 unsigned int reg;
6807 } regpos[16];
6808
6809 /* Scan entire instruction first so that GET_OP output is not
6810 interleaved with disassembly. */
6811 nregs = 0;
6812 for (i = 0; nregs < (op & 0xf); i++)
6813 {
6814 GET_OP (op2);
6815 reg = op2 >> 4;
6816 if (reg != 0xf)
6817 {
6818 regpos[nregs].offset = i * 2;
6819 regpos[nregs].reg = reg;
6820 nregs++;
6821 }
6822
6823 reg = op2 & 0xf;
6824 if (reg != 0xf)
6825 {
6826 regpos[nregs].offset = i * 2 + 1;
6827 regpos[nregs].reg = reg;
6828 nregs++;
6829 }
6830 }
6831
6832 printf (_("pop frame {"));
6833 reg = nregs - 1;
6834 for (i = i * 2; i > 0; i--)
6835 {
6836 if (regpos[reg].offset == i - 1)
6837 {
6838 name = tic6x_unwind_regnames[regpos[reg].reg];
6839 if (reg > 0)
6840 reg--;
6841 }
6842 else
6843 name = _("[pad]");
6844
6845 fputs (name, stdout);
6846 if (i > 1)
6847 printf (", ");
6848 }
6849
6850 printf ("}");
6851 }
6852 else if (op == 0xd0)
6853 printf (" MOV FP, SP");
6854 else if (op == 0xd1)
6855 printf (" __c6xabi_pop_rts");
6856 else if (op == 0xd2)
6857 {
6858 unsigned char buf[9];
6859 unsigned int i, len;
6860 unsigned long offset;
a734115a 6861
fa197c1c
PB
6862 for (i = 0; i < sizeof (buf); i++)
6863 {
6864 GET_OP (buf[i]);
6865 if ((buf[i] & 0x80) == 0)
6866 break;
6867 }
6868 assert (i < sizeof (buf));
6869 offset = read_uleb128 (buf, &len);
6870 assert (len == i + 1);
6871 offset = offset * 8 + 0x408;
6872 printf (_("sp = sp + %ld"), offset);
6873 }
6874 else if ((op & 0xf0) == 0xe0)
6875 {
6876 if ((op & 0x0f) == 7)
6877 printf (" RETURN");
6878 else
6879 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
6880 }
6881 else
6882 {
6883 printf (_(" [unsupported opcode]"));
6884 }
6885 putchar ('\n');
6886 }
6887}
6888
6889static bfd_vma
a734115a 6890arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
6891{
6892 bfd_vma offset;
6893
6894 offset = word & 0x7fffffff;
6895 if (offset & 0x40000000)
6896 offset |= ~ (bfd_vma) 0x7fffffff;
6897
6898 if (elf_header.e_machine == EM_TI_C6000)
6899 offset <<= 1;
6900
6901 return offset + where;
6902}
6903
6904static void
1b31d05e
NC
6905decode_arm_unwind (struct arm_unw_aux_info * aux,
6906 unsigned int word,
6907 unsigned int remaining,
6908 bfd_vma data_offset,
6909 Elf_Internal_Shdr * data_sec,
6910 struct arm_section * data_arm_sec)
fa197c1c
PB
6911{
6912 int per_index;
6913 unsigned int more_words = 0;
6914 struct absaddr addr;
1b31d05e 6915 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
6916
6917 if (remaining == 0)
6918 {
1b31d05e
NC
6919 /* Fetch the first word.
6920 Note - when decoding an object file the address extracted
6921 here will always be 0. So we also pass in the sym_name
6922 parameter so that we can find the symbol associated with
6923 the personality routine. */
6924 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
6925 & word, & addr, & sym_name))
fa197c1c 6926 return;
1b31d05e 6927
fa197c1c
PB
6928 remaining = 4;
6929 }
6930
6931 if ((word & 0x80000000) == 0)
6932 {
6933 /* Expand prel31 for personality routine. */
6934 bfd_vma fn;
6935 const char *procname;
6936
a734115a 6937 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 6938 printf (_(" Personality routine: "));
1b31d05e
NC
6939 if (fn == 0
6940 && addr.section == SHN_UNDEF && addr.offset == 0
6941 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
6942 {
6943 procname = aux->strtab + sym_name;
6944 print_vma (fn, PREFIX_HEX);
6945 if (procname)
6946 {
6947 fputs (" <", stdout);
6948 fputs (procname, stdout);
6949 fputc ('>', stdout);
6950 }
6951 }
6952 else
6953 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
6954 fputc ('\n', stdout);
6955
6956 /* The GCC personality routines use the standard compact
6957 encoding, starting with one byte giving the number of
6958 words. */
6959 if (procname != NULL
6960 && (const_strneq (procname, "__gcc_personality_v0")
6961 || const_strneq (procname, "__gxx_personality_v0")
6962 || const_strneq (procname, "__gcj_personality_v0")
6963 || const_strneq (procname, "__gnu_objc_personality_v0")))
6964 {
6965 remaining = 0;
6966 more_words = 1;
6967 ADVANCE;
6968 if (!remaining)
6969 {
6970 printf (_(" [Truncated data]\n"));
6971 return;
6972 }
6973 more_words = word >> 24;
6974 word <<= 8;
6975 remaining--;
6976 per_index = -1;
6977 }
6978 else
6979 return;
6980 }
6981 else
6982 {
1b31d05e
NC
6983 /* ARM EHABI Section 6.3:
6984
6985 An exception-handling table entry for the compact model looks like:
6986
6987 31 30-28 27-24 23-0
6988 -- ----- ----- ----
6989 1 0 index Data for personalityRoutine[index] */
6990
6991 if (elf_header.e_machine == EM_ARM
6992 && (word & 0x70000000))
83c257ca 6993 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 6994
fa197c1c 6995 per_index = (word >> 24) & 0x7f;
1b31d05e 6996 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
6997 if (per_index == 0)
6998 {
6999 more_words = 0;
7000 word <<= 8;
7001 remaining--;
7002 }
7003 else if (per_index < 3)
7004 {
7005 more_words = (word >> 16) & 0xff;
7006 word <<= 16;
7007 remaining -= 2;
7008 }
7009 }
7010
7011 switch (elf_header.e_machine)
7012 {
7013 case EM_ARM:
7014 if (per_index < 3)
7015 {
7016 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
7017 data_offset, data_sec, data_arm_sec);
7018 }
7019 else
1b31d05e
NC
7020 {
7021 warn (_("Unknown ARM compact model index encountered\n"));
7022 printf (_(" [reserved]\n"));
7023 }
fa197c1c
PB
7024 break;
7025
7026 case EM_TI_C6000:
7027 if (per_index < 3)
7028 {
7029 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 7030 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
7031 }
7032 else if (per_index < 5)
7033 {
7034 if (((word >> 17) & 0x7f) == 0x7f)
7035 printf (_(" Restore stack from frame pointer\n"));
7036 else
7037 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
7038 printf (_(" Registers restored: "));
7039 if (per_index == 4)
7040 printf (" (compact) ");
7041 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
7042 putchar ('\n');
7043 printf (_(" Return register: %s\n"),
7044 tic6x_unwind_regnames[word & 0xf]);
7045 }
7046 else
1b31d05e 7047 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
7048 break;
7049
7050 default:
1b31d05e
NC
7051 error (_("Unsupported architecture type %d encountered when decoding unwind table"),
7052 elf_header.e_machine);
fa197c1c 7053 }
0b6ae522
DJ
7054
7055 /* Decode the descriptors. Not implemented. */
7056}
7057
7058static void
7059dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
7060{
7061 struct arm_section exidx_arm_sec, extab_arm_sec;
7062 unsigned int i, exidx_len;
7063
7064 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
7065 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
7066 exidx_len = exidx_sec->sh_size / 8;
7067
7068 for (i = 0; i < exidx_len; i++)
7069 {
7070 unsigned int exidx_fn, exidx_entry;
7071 struct absaddr fn_addr, entry_addr;
7072 bfd_vma fn;
7073
7074 fputc ('\n', stdout);
7075
1b31d05e
NC
7076 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7077 8 * i, & exidx_fn, & fn_addr, NULL)
7078 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
7079 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 7080 {
1b31d05e
NC
7081 arm_free_section (& exidx_arm_sec);
7082 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
7083 return;
7084 }
7085
83c257ca
NC
7086 /* ARM EHABI, Section 5:
7087 An index table entry consists of 2 words.
7088 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
7089 if (exidx_fn & 0x80000000)
7090 warn (_("corrupt index table entry: %x\n"), exidx_fn);
7091
a734115a 7092 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 7093
a734115a 7094 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
7095 fputs (": ", stdout);
7096
7097 if (exidx_entry == 1)
7098 {
7099 print_vma (exidx_entry, PREFIX_HEX);
7100 fputs (" [cantunwind]\n", stdout);
7101 }
7102 else if (exidx_entry & 0x80000000)
7103 {
7104 print_vma (exidx_entry, PREFIX_HEX);
7105 fputc ('\n', stdout);
7106 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
7107 }
7108 else
7109 {
8f73510c 7110 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7111 Elf_Internal_Shdr *table_sec;
7112
7113 fputs ("@", stdout);
a734115a 7114 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7115 print_vma (table, PREFIX_HEX);
7116 printf ("\n");
7117
7118 /* Locate the matching .ARM.extab. */
7119 if (entry_addr.section != SHN_UNDEF
7120 && entry_addr.section < elf_header.e_shnum)
7121 {
7122 table_sec = section_headers + entry_addr.section;
7123 table_offset = entry_addr.offset;
7124 }
7125 else
7126 {
7127 table_sec = find_section_by_address (table);
7128 if (table_sec != NULL)
7129 table_offset = table - table_sec->sh_addr;
7130 }
7131 if (table_sec == NULL)
7132 {
7133 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7134 (unsigned long) table);
7135 continue;
7136 }
7137 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7138 &extab_arm_sec);
7139 }
7140 }
7141
7142 printf ("\n");
7143
7144 arm_free_section (&exidx_arm_sec);
7145 arm_free_section (&extab_arm_sec);
7146}
7147
fa197c1c 7148/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
7149
7150static void
0b6ae522
DJ
7151arm_process_unwind (FILE *file)
7152{
7153 struct arm_unw_aux_info aux;
7154 Elf_Internal_Shdr *unwsec = NULL;
7155 Elf_Internal_Shdr *strsec;
7156 Elf_Internal_Shdr *sec;
7157 unsigned long i;
fa197c1c 7158 unsigned int sec_type;
0b6ae522 7159
fa197c1c
PB
7160 switch (elf_header.e_machine)
7161 {
7162 case EM_ARM:
7163 sec_type = SHT_ARM_EXIDX;
7164 break;
7165
7166 case EM_TI_C6000:
7167 sec_type = SHT_C6000_UNWIND;
7168 break;
7169
1b31d05e
NC
7170 default:
7171 error (_("Unsupported architecture type %d encountered when processing unwind table"),
7172 elf_header.e_machine);
7173 return;
fa197c1c
PB
7174 }
7175
0b6ae522 7176 if (string_table == NULL)
1b31d05e
NC
7177 return;
7178
7179 memset (& aux, 0, sizeof (aux));
7180 aux.file = file;
0b6ae522
DJ
7181
7182 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7183 {
7184 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7185 {
ba5cdace 7186 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
7187
7188 strsec = section_headers + sec->sh_link;
59245841 7189 assert (aux.strtab == NULL);
0b6ae522
DJ
7190 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7191 1, strsec->sh_size, _("string table"));
7192 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7193 }
fa197c1c 7194 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7195 unwsec = sec;
7196 }
7197
1b31d05e 7198 if (unwsec == NULL)
0b6ae522 7199 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
7200 else
7201 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7202 {
7203 if (sec->sh_type == sec_type)
7204 {
7205 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7206 SECTION_NAME (sec),
7207 (unsigned long) sec->sh_offset,
7208 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 7209
1b31d05e
NC
7210 dump_arm_unwind (&aux, sec);
7211 }
7212 }
0b6ae522
DJ
7213
7214 if (aux.symtab)
7215 free (aux.symtab);
7216 if (aux.strtab)
7217 free ((char *) aux.strtab);
0b6ae522
DJ
7218}
7219
1b31d05e 7220static void
2cf0635d 7221process_unwind (FILE * file)
57346661 7222{
2cf0635d
NC
7223 struct unwind_handler
7224 {
57346661 7225 int machtype;
1b31d05e 7226 void (* handler)(FILE *);
2cf0635d
NC
7227 } handlers[] =
7228 {
0b6ae522 7229 { EM_ARM, arm_process_unwind },
57346661
AM
7230 { EM_IA_64, ia64_process_unwind },
7231 { EM_PARISC, hppa_process_unwind },
fa197c1c 7232 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7233 { 0, 0 }
7234 };
7235 int i;
7236
7237 if (!do_unwind)
1b31d05e 7238 return;
57346661
AM
7239
7240 for (i = 0; handlers[i].handler != NULL; i++)
7241 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7242 return handlers[i].handler (file);
57346661 7243
1b31d05e
NC
7244 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
7245 get_machine_name (elf_header.e_machine));
57346661
AM
7246}
7247
252b5132 7248static void
2cf0635d 7249dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7250{
7251 switch (entry->d_tag)
7252 {
7253 case DT_MIPS_FLAGS:
7254 if (entry->d_un.d_val == 0)
4b68bca3 7255 printf (_("NONE"));
252b5132
RH
7256 else
7257 {
7258 static const char * opts[] =
7259 {
7260 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7261 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7262 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7263 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7264 "RLD_ORDER_SAFE"
7265 };
7266 unsigned int cnt;
7267 int first = 1;
2b692964 7268
60bca95a 7269 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7270 if (entry->d_un.d_val & (1 << cnt))
7271 {
7272 printf ("%s%s", first ? "" : " ", opts[cnt]);
7273 first = 0;
7274 }
252b5132
RH
7275 }
7276 break;
103f02d3 7277
252b5132 7278 case DT_MIPS_IVERSION:
d79b3d50 7279 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 7280 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7281 else
4b68bca3 7282 printf (_("<corrupt: %" BFD_VMA_FMT "d>"), entry->d_un.d_ptr);
252b5132 7283 break;
103f02d3 7284
252b5132
RH
7285 case DT_MIPS_TIME_STAMP:
7286 {
7287 char timebuf[20];
2cf0635d 7288 struct tm * tmp;
50da7a9c 7289
91d6fa6a
NC
7290 time_t atime = entry->d_un.d_val;
7291 tmp = gmtime (&atime);
e9e44622
JJ
7292 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7293 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7294 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 7295 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
7296 }
7297 break;
103f02d3 7298
252b5132
RH
7299 case DT_MIPS_RLD_VERSION:
7300 case DT_MIPS_LOCAL_GOTNO:
7301 case DT_MIPS_CONFLICTNO:
7302 case DT_MIPS_LIBLISTNO:
7303 case DT_MIPS_SYMTABNO:
7304 case DT_MIPS_UNREFEXTNO:
7305 case DT_MIPS_HIPAGENO:
7306 case DT_MIPS_DELTA_CLASS_NO:
7307 case DT_MIPS_DELTA_INSTANCE_NO:
7308 case DT_MIPS_DELTA_RELOC_NO:
7309 case DT_MIPS_DELTA_SYM_NO:
7310 case DT_MIPS_DELTA_CLASSSYM_NO:
7311 case DT_MIPS_COMPACT_SIZE:
4b68bca3 7312 print_vma (entry->d_un.d_ptr, DEC);
252b5132 7313 break;
103f02d3
UD
7314
7315 default:
4b68bca3 7316 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 7317 }
4b68bca3 7318 putchar ('\n');
103f02d3
UD
7319}
7320
103f02d3 7321static void
2cf0635d 7322dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7323{
7324 switch (entry->d_tag)
7325 {
7326 case DT_HP_DLD_FLAGS:
7327 {
7328 static struct
7329 {
7330 long int bit;
2cf0635d 7331 const char * str;
5e220199
NC
7332 }
7333 flags[] =
7334 {
7335 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7336 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7337 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7338 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7339 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7340 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7341 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7342 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7343 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7344 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7345 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7346 { DT_HP_GST, "HP_GST" },
7347 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7348 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7349 { DT_HP_NODELETE, "HP_NODELETE" },
7350 { DT_HP_GROUP, "HP_GROUP" },
7351 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7352 };
103f02d3 7353 int first = 1;
5e220199 7354 size_t cnt;
f7a99963 7355 bfd_vma val = entry->d_un.d_val;
103f02d3 7356
60bca95a 7357 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7358 if (val & flags[cnt].bit)
30800947
NC
7359 {
7360 if (! first)
7361 putchar (' ');
7362 fputs (flags[cnt].str, stdout);
7363 first = 0;
7364 val ^= flags[cnt].bit;
7365 }
76da6bbe 7366
103f02d3 7367 if (val != 0 || first)
f7a99963
NC
7368 {
7369 if (! first)
7370 putchar (' ');
7371 print_vma (val, HEX);
7372 }
103f02d3
UD
7373 }
7374 break;
76da6bbe 7375
252b5132 7376 default:
f7a99963
NC
7377 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7378 break;
252b5132 7379 }
35b1837e 7380 putchar ('\n');
252b5132
RH
7381}
7382
28f997cf
TG
7383#ifdef BFD64
7384
7385/* VMS vs Unix time offset and factor. */
7386
7387#define VMS_EPOCH_OFFSET 35067168000000000LL
7388#define VMS_GRANULARITY_FACTOR 10000000
7389
7390/* Display a VMS time in a human readable format. */
7391
7392static void
7393print_vms_time (bfd_int64_t vmstime)
7394{
7395 struct tm *tm;
7396 time_t unxtime;
7397
7398 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7399 tm = gmtime (&unxtime);
7400 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7401 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7402 tm->tm_hour, tm->tm_min, tm->tm_sec);
7403}
7404#endif /* BFD64 */
7405
ecc51f48 7406static void
2cf0635d 7407dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7408{
7409 switch (entry->d_tag)
7410 {
0de14b54 7411 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7412 /* First 3 slots reserved. */
ecc51f48
NC
7413 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7414 printf (" -- ");
7415 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7416 break;
7417
28f997cf
TG
7418 case DT_IA_64_VMS_LINKTIME:
7419#ifdef BFD64
7420 print_vms_time (entry->d_un.d_val);
7421#endif
7422 break;
7423
7424 case DT_IA_64_VMS_LNKFLAGS:
7425 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7426 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7427 printf (" CALL_DEBUG");
7428 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7429 printf (" NOP0BUFS");
7430 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7431 printf (" P0IMAGE");
7432 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7433 printf (" MKTHREADS");
7434 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7435 printf (" UPCALLS");
7436 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7437 printf (" IMGSTA");
7438 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7439 printf (" INITIALIZE");
7440 if (entry->d_un.d_val & VMS_LF_MAIN)
7441 printf (" MAIN");
7442 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7443 printf (" EXE_INIT");
7444 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7445 printf (" TBK_IN_IMG");
7446 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7447 printf (" DBG_IN_IMG");
7448 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7449 printf (" TBK_IN_DSF");
7450 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7451 printf (" DBG_IN_DSF");
7452 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7453 printf (" SIGNATURES");
7454 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7455 printf (" REL_SEG_OFF");
7456 break;
7457
bdf4d63a
JJ
7458 default:
7459 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7460 break;
ecc51f48 7461 }
bdf4d63a 7462 putchar ('\n');
ecc51f48
NC
7463}
7464
252b5132 7465static int
2cf0635d 7466get_32bit_dynamic_section (FILE * file)
252b5132 7467{
2cf0635d
NC
7468 Elf32_External_Dyn * edyn;
7469 Elf32_External_Dyn * ext;
7470 Elf_Internal_Dyn * entry;
103f02d3 7471
3f5e193b
NC
7472 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7473 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7474 if (!edyn)
7475 return 0;
103f02d3 7476
ba2685cc
AM
7477/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7478 might not have the luxury of section headers. Look for the DT_NULL
7479 terminator to determine the number of entries. */
7480 for (ext = edyn, dynamic_nent = 0;
7481 (char *) ext < (char *) edyn + dynamic_size;
7482 ext++)
7483 {
7484 dynamic_nent++;
7485 if (BYTE_GET (ext->d_tag) == DT_NULL)
7486 break;
7487 }
252b5132 7488
3f5e193b
NC
7489 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7490 sizeof (* entry));
b2d38a17 7491 if (dynamic_section == NULL)
252b5132 7492 {
9ea033b2
NC
7493 error (_("Out of memory\n"));
7494 free (edyn);
7495 return 0;
7496 }
252b5132 7497
fb514b26 7498 for (ext = edyn, entry = dynamic_section;
ba2685cc 7499 entry < dynamic_section + dynamic_nent;
fb514b26 7500 ext++, entry++)
9ea033b2 7501 {
fb514b26
AM
7502 entry->d_tag = BYTE_GET (ext->d_tag);
7503 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7504 }
7505
9ea033b2
NC
7506 free (edyn);
7507
7508 return 1;
7509}
7510
7511static int
2cf0635d 7512get_64bit_dynamic_section (FILE * file)
9ea033b2 7513{
2cf0635d
NC
7514 Elf64_External_Dyn * edyn;
7515 Elf64_External_Dyn * ext;
7516 Elf_Internal_Dyn * entry;
103f02d3 7517
3f5e193b
NC
7518 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7519 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7520 if (!edyn)
7521 return 0;
103f02d3 7522
ba2685cc
AM
7523/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7524 might not have the luxury of section headers. Look for the DT_NULL
7525 terminator to determine the number of entries. */
7526 for (ext = edyn, dynamic_nent = 0;
7527 (char *) ext < (char *) edyn + dynamic_size;
7528 ext++)
7529 {
7530 dynamic_nent++;
66543521 7531 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7532 break;
7533 }
252b5132 7534
3f5e193b
NC
7535 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7536 sizeof (* entry));
b2d38a17 7537 if (dynamic_section == NULL)
252b5132
RH
7538 {
7539 error (_("Out of memory\n"));
7540 free (edyn);
7541 return 0;
7542 }
7543
fb514b26 7544 for (ext = edyn, entry = dynamic_section;
ba2685cc 7545 entry < dynamic_section + dynamic_nent;
fb514b26 7546 ext++, entry++)
252b5132 7547 {
66543521
AM
7548 entry->d_tag = BYTE_GET (ext->d_tag);
7549 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7550 }
7551
7552 free (edyn);
7553
9ea033b2
NC
7554 return 1;
7555}
7556
e9e44622
JJ
7557static void
7558print_dynamic_flags (bfd_vma flags)
d1133906 7559{
e9e44622 7560 int first = 1;
13ae64f3 7561
d1133906
NC
7562 while (flags)
7563 {
7564 bfd_vma flag;
7565
7566 flag = flags & - flags;
7567 flags &= ~ flag;
7568
e9e44622
JJ
7569 if (first)
7570 first = 0;
7571 else
7572 putc (' ', stdout);
13ae64f3 7573
d1133906
NC
7574 switch (flag)
7575 {
e9e44622
JJ
7576 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7577 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7578 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7579 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7580 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7581 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7582 }
7583 }
e9e44622 7584 puts ("");
d1133906
NC
7585}
7586
b2d38a17
NC
7587/* Parse and display the contents of the dynamic section. */
7588
9ea033b2 7589static int
2cf0635d 7590process_dynamic_section (FILE * file)
9ea033b2 7591{
2cf0635d 7592 Elf_Internal_Dyn * entry;
9ea033b2
NC
7593
7594 if (dynamic_size == 0)
7595 {
7596 if (do_dynamic)
b2d38a17 7597 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7598
7599 return 1;
7600 }
7601
7602 if (is_32bit_elf)
7603 {
b2d38a17 7604 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7605 return 0;
7606 }
b2d38a17 7607 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7608 return 0;
7609
252b5132
RH
7610 /* Find the appropriate symbol table. */
7611 if (dynamic_symbols == NULL)
7612 {
86dba8ee
AM
7613 for (entry = dynamic_section;
7614 entry < dynamic_section + dynamic_nent;
7615 ++entry)
252b5132 7616 {
c8286bd1 7617 Elf_Internal_Shdr section;
252b5132
RH
7618
7619 if (entry->d_tag != DT_SYMTAB)
7620 continue;
7621
7622 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7623
7624 /* Since we do not know how big the symbol table is,
7625 we default to reading in the entire file (!) and
7626 processing that. This is overkill, I know, but it
e3c8793a 7627 should work. */
d93f0186 7628 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7629
fb52b2f4
NC
7630 if (archive_file_offset != 0)
7631 section.sh_size = archive_file_size - section.sh_offset;
7632 else
7633 {
7634 if (fseek (file, 0, SEEK_END))
591a748a 7635 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7636
7637 section.sh_size = ftell (file) - section.sh_offset;
7638 }
252b5132 7639
9ea033b2 7640 if (is_32bit_elf)
9ad5cbcf 7641 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7642 else
9ad5cbcf 7643 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7644
ba5cdace 7645 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 7646 if (num_dynamic_syms < 1)
252b5132
RH
7647 {
7648 error (_("Unable to determine the number of symbols to load\n"));
7649 continue;
7650 }
252b5132
RH
7651 }
7652 }
7653
7654 /* Similarly find a string table. */
7655 if (dynamic_strings == NULL)
7656 {
86dba8ee
AM
7657 for (entry = dynamic_section;
7658 entry < dynamic_section + dynamic_nent;
7659 ++entry)
252b5132
RH
7660 {
7661 unsigned long offset;
b34976b6 7662 long str_tab_len;
252b5132
RH
7663
7664 if (entry->d_tag != DT_STRTAB)
7665 continue;
7666
7667 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7668
7669 /* Since we do not know how big the string table is,
7670 we default to reading in the entire file (!) and
7671 processing that. This is overkill, I know, but it
e3c8793a 7672 should work. */
252b5132 7673
d93f0186 7674 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7675
7676 if (archive_file_offset != 0)
7677 str_tab_len = archive_file_size - offset;
7678 else
7679 {
7680 if (fseek (file, 0, SEEK_END))
7681 error (_("Unable to seek to end of file\n"));
7682 str_tab_len = ftell (file) - offset;
7683 }
252b5132
RH
7684
7685 if (str_tab_len < 1)
7686 {
7687 error
7688 (_("Unable to determine the length of the dynamic string table\n"));
7689 continue;
7690 }
7691
3f5e193b
NC
7692 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7693 str_tab_len,
7694 _("dynamic string table"));
59245841 7695 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7696 break;
7697 }
7698 }
7699
7700 /* And find the syminfo section if available. */
7701 if (dynamic_syminfo == NULL)
7702 {
3e8bba36 7703 unsigned long syminsz = 0;
252b5132 7704
86dba8ee
AM
7705 for (entry = dynamic_section;
7706 entry < dynamic_section + dynamic_nent;
7707 ++entry)
252b5132
RH
7708 {
7709 if (entry->d_tag == DT_SYMINENT)
7710 {
7711 /* Note: these braces are necessary to avoid a syntax
7712 error from the SunOS4 C compiler. */
7713 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7714 }
7715 else if (entry->d_tag == DT_SYMINSZ)
7716 syminsz = entry->d_un.d_val;
7717 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7718 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7719 syminsz);
252b5132
RH
7720 }
7721
7722 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7723 {
2cf0635d
NC
7724 Elf_External_Syminfo * extsyminfo;
7725 Elf_External_Syminfo * extsym;
7726 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7727
7728 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7729 extsyminfo = (Elf_External_Syminfo *)
7730 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7731 _("symbol information"));
a6e9f9df
AM
7732 if (!extsyminfo)
7733 return 0;
252b5132 7734
3f5e193b 7735 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7736 if (dynamic_syminfo == NULL)
7737 {
7738 error (_("Out of memory\n"));
7739 return 0;
7740 }
7741
7742 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7743 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7744 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7745 ++syminfo, ++extsym)
252b5132 7746 {
86dba8ee
AM
7747 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7748 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7749 }
7750
7751 free (extsyminfo);
7752 }
7753 }
7754
7755 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7756 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7757 dynamic_addr, dynamic_nent);
252b5132
RH
7758 if (do_dynamic)
7759 printf (_(" Tag Type Name/Value\n"));
7760
86dba8ee
AM
7761 for (entry = dynamic_section;
7762 entry < dynamic_section + dynamic_nent;
7763 entry++)
252b5132
RH
7764 {
7765 if (do_dynamic)
f7a99963 7766 {
2cf0635d 7767 const char * dtype;
e699b9ff 7768
f7a99963
NC
7769 putchar (' ');
7770 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7771 dtype = get_dynamic_type (entry->d_tag);
7772 printf (" (%s)%*s", dtype,
7773 ((is_32bit_elf ? 27 : 19)
7774 - (int) strlen (dtype)),
f7a99963
NC
7775 " ");
7776 }
252b5132
RH
7777
7778 switch (entry->d_tag)
7779 {
d1133906
NC
7780 case DT_FLAGS:
7781 if (do_dynamic)
e9e44622 7782 print_dynamic_flags (entry->d_un.d_val);
d1133906 7783 break;
76da6bbe 7784
252b5132
RH
7785 case DT_AUXILIARY:
7786 case DT_FILTER:
019148e4
L
7787 case DT_CONFIG:
7788 case DT_DEPAUDIT:
7789 case DT_AUDIT:
252b5132
RH
7790 if (do_dynamic)
7791 {
019148e4 7792 switch (entry->d_tag)
b34976b6 7793 {
019148e4
L
7794 case DT_AUXILIARY:
7795 printf (_("Auxiliary library"));
7796 break;
7797
7798 case DT_FILTER:
7799 printf (_("Filter library"));
7800 break;
7801
b34976b6 7802 case DT_CONFIG:
019148e4
L
7803 printf (_("Configuration file"));
7804 break;
7805
7806 case DT_DEPAUDIT:
7807 printf (_("Dependency audit library"));
7808 break;
7809
7810 case DT_AUDIT:
7811 printf (_("Audit library"));
7812 break;
7813 }
252b5132 7814
d79b3d50
NC
7815 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7816 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7817 else
f7a99963
NC
7818 {
7819 printf (": ");
7820 print_vma (entry->d_un.d_val, PREFIX_HEX);
7821 putchar ('\n');
7822 }
252b5132
RH
7823 }
7824 break;
7825
dcefbbbd 7826 case DT_FEATURE:
252b5132
RH
7827 if (do_dynamic)
7828 {
7829 printf (_("Flags:"));
86f55779 7830
252b5132
RH
7831 if (entry->d_un.d_val == 0)
7832 printf (_(" None\n"));
7833 else
7834 {
7835 unsigned long int val = entry->d_un.d_val;
86f55779 7836
252b5132
RH
7837 if (val & DTF_1_PARINIT)
7838 {
7839 printf (" PARINIT");
7840 val ^= DTF_1_PARINIT;
7841 }
dcefbbbd
L
7842 if (val & DTF_1_CONFEXP)
7843 {
7844 printf (" CONFEXP");
7845 val ^= DTF_1_CONFEXP;
7846 }
252b5132
RH
7847 if (val != 0)
7848 printf (" %lx", val);
7849 puts ("");
7850 }
7851 }
7852 break;
7853
7854 case DT_POSFLAG_1:
7855 if (do_dynamic)
7856 {
7857 printf (_("Flags:"));
86f55779 7858
252b5132
RH
7859 if (entry->d_un.d_val == 0)
7860 printf (_(" None\n"));
7861 else
7862 {
7863 unsigned long int val = entry->d_un.d_val;
86f55779 7864
252b5132
RH
7865 if (val & DF_P1_LAZYLOAD)
7866 {
7867 printf (" LAZYLOAD");
7868 val ^= DF_P1_LAZYLOAD;
7869 }
7870 if (val & DF_P1_GROUPPERM)
7871 {
7872 printf (" GROUPPERM");
7873 val ^= DF_P1_GROUPPERM;
7874 }
7875 if (val != 0)
7876 printf (" %lx", val);
7877 puts ("");
7878 }
7879 }
7880 break;
7881
7882 case DT_FLAGS_1:
7883 if (do_dynamic)
7884 {
7885 printf (_("Flags:"));
7886 if (entry->d_un.d_val == 0)
7887 printf (_(" None\n"));
7888 else
7889 {
7890 unsigned long int val = entry->d_un.d_val;
86f55779 7891
252b5132
RH
7892 if (val & DF_1_NOW)
7893 {
7894 printf (" NOW");
7895 val ^= DF_1_NOW;
7896 }
7897 if (val & DF_1_GLOBAL)
7898 {
7899 printf (" GLOBAL");
7900 val ^= DF_1_GLOBAL;
7901 }
7902 if (val & DF_1_GROUP)
7903 {
7904 printf (" GROUP");
7905 val ^= DF_1_GROUP;
7906 }
7907 if (val & DF_1_NODELETE)
7908 {
7909 printf (" NODELETE");
7910 val ^= DF_1_NODELETE;
7911 }
7912 if (val & DF_1_LOADFLTR)
7913 {
7914 printf (" LOADFLTR");
7915 val ^= DF_1_LOADFLTR;
7916 }
7917 if (val & DF_1_INITFIRST)
7918 {
7919 printf (" INITFIRST");
7920 val ^= DF_1_INITFIRST;
7921 }
7922 if (val & DF_1_NOOPEN)
7923 {
7924 printf (" NOOPEN");
7925 val ^= DF_1_NOOPEN;
7926 }
7927 if (val & DF_1_ORIGIN)
7928 {
7929 printf (" ORIGIN");
7930 val ^= DF_1_ORIGIN;
7931 }
7932 if (val & DF_1_DIRECT)
7933 {
7934 printf (" DIRECT");
7935 val ^= DF_1_DIRECT;
7936 }
7937 if (val & DF_1_TRANS)
7938 {
7939 printf (" TRANS");
7940 val ^= DF_1_TRANS;
7941 }
7942 if (val & DF_1_INTERPOSE)
7943 {
7944 printf (" INTERPOSE");
7945 val ^= DF_1_INTERPOSE;
7946 }
f7db6139 7947 if (val & DF_1_NODEFLIB)
dcefbbbd 7948 {
f7db6139
L
7949 printf (" NODEFLIB");
7950 val ^= DF_1_NODEFLIB;
dcefbbbd
L
7951 }
7952 if (val & DF_1_NODUMP)
7953 {
7954 printf (" NODUMP");
7955 val ^= DF_1_NODUMP;
7956 }
7957 if (val & DF_1_CONLFAT)
7958 {
7959 printf (" CONLFAT");
7960 val ^= DF_1_CONLFAT;
7961 }
252b5132
RH
7962 if (val != 0)
7963 printf (" %lx", val);
7964 puts ("");
7965 }
7966 }
7967 break;
7968
7969 case DT_PLTREL:
566b0d53 7970 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7971 if (do_dynamic)
7972 puts (get_dynamic_type (entry->d_un.d_val));
7973 break;
7974
7975 case DT_NULL :
7976 case DT_NEEDED :
7977 case DT_PLTGOT :
7978 case DT_HASH :
7979 case DT_STRTAB :
7980 case DT_SYMTAB :
7981 case DT_RELA :
7982 case DT_INIT :
7983 case DT_FINI :
7984 case DT_SONAME :
7985 case DT_RPATH :
7986 case DT_SYMBOLIC:
7987 case DT_REL :
7988 case DT_DEBUG :
7989 case DT_TEXTREL :
7990 case DT_JMPREL :
019148e4 7991 case DT_RUNPATH :
252b5132
RH
7992 dynamic_info[entry->d_tag] = entry->d_un.d_val;
7993
7994 if (do_dynamic)
7995 {
2cf0635d 7996 char * name;
252b5132 7997
d79b3d50
NC
7998 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7999 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8000 else
d79b3d50 8001 name = NULL;
252b5132
RH
8002
8003 if (name)
8004 {
8005 switch (entry->d_tag)
8006 {
8007 case DT_NEEDED:
8008 printf (_("Shared library: [%s]"), name);
8009
18bd398b 8010 if (streq (name, program_interpreter))
f7a99963 8011 printf (_(" program interpreter"));
252b5132
RH
8012 break;
8013
8014 case DT_SONAME:
f7a99963 8015 printf (_("Library soname: [%s]"), name);
252b5132
RH
8016 break;
8017
8018 case DT_RPATH:
f7a99963 8019 printf (_("Library rpath: [%s]"), name);
252b5132
RH
8020 break;
8021
019148e4
L
8022 case DT_RUNPATH:
8023 printf (_("Library runpath: [%s]"), name);
8024 break;
8025
252b5132 8026 default:
f7a99963
NC
8027 print_vma (entry->d_un.d_val, PREFIX_HEX);
8028 break;
252b5132
RH
8029 }
8030 }
8031 else
f7a99963
NC
8032 print_vma (entry->d_un.d_val, PREFIX_HEX);
8033
8034 putchar ('\n');
252b5132
RH
8035 }
8036 break;
8037
8038 case DT_PLTRELSZ:
8039 case DT_RELASZ :
8040 case DT_STRSZ :
8041 case DT_RELSZ :
8042 case DT_RELAENT :
8043 case DT_SYMENT :
8044 case DT_RELENT :
566b0d53 8045 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
8046 case DT_PLTPADSZ:
8047 case DT_MOVEENT :
8048 case DT_MOVESZ :
8049 case DT_INIT_ARRAYSZ:
8050 case DT_FINI_ARRAYSZ:
047b2264
JJ
8051 case DT_GNU_CONFLICTSZ:
8052 case DT_GNU_LIBLISTSZ:
252b5132 8053 if (do_dynamic)
f7a99963
NC
8054 {
8055 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 8056 printf (_(" (bytes)\n"));
f7a99963 8057 }
252b5132
RH
8058 break;
8059
8060 case DT_VERDEFNUM:
8061 case DT_VERNEEDNUM:
8062 case DT_RELACOUNT:
8063 case DT_RELCOUNT:
8064 if (do_dynamic)
f7a99963
NC
8065 {
8066 print_vma (entry->d_un.d_val, UNSIGNED);
8067 putchar ('\n');
8068 }
252b5132
RH
8069 break;
8070
8071 case DT_SYMINSZ:
8072 case DT_SYMINENT:
8073 case DT_SYMINFO:
8074 case DT_USED:
8075 case DT_INIT_ARRAY:
8076 case DT_FINI_ARRAY:
8077 if (do_dynamic)
8078 {
d79b3d50
NC
8079 if (entry->d_tag == DT_USED
8080 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 8081 {
2cf0635d 8082 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 8083
b34976b6 8084 if (*name)
252b5132
RH
8085 {
8086 printf (_("Not needed object: [%s]\n"), name);
8087 break;
8088 }
8089 }
103f02d3 8090
f7a99963
NC
8091 print_vma (entry->d_un.d_val, PREFIX_HEX);
8092 putchar ('\n');
252b5132
RH
8093 }
8094 break;
8095
8096 case DT_BIND_NOW:
8097 /* The value of this entry is ignored. */
35b1837e
AM
8098 if (do_dynamic)
8099 putchar ('\n');
252b5132 8100 break;
103f02d3 8101
047b2264
JJ
8102 case DT_GNU_PRELINKED:
8103 if (do_dynamic)
8104 {
2cf0635d 8105 struct tm * tmp;
91d6fa6a 8106 time_t atime = entry->d_un.d_val;
047b2264 8107
91d6fa6a 8108 tmp = gmtime (&atime);
047b2264
JJ
8109 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8110 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8111 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8112
8113 }
8114 break;
8115
fdc90cb4
JJ
8116 case DT_GNU_HASH:
8117 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8118 if (do_dynamic)
8119 {
8120 print_vma (entry->d_un.d_val, PREFIX_HEX);
8121 putchar ('\n');
8122 }
8123 break;
8124
252b5132
RH
8125 default:
8126 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8127 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8128 entry->d_un.d_val;
8129
8130 if (do_dynamic)
8131 {
8132 switch (elf_header.e_machine)
8133 {
8134 case EM_MIPS:
4fe85591 8135 case EM_MIPS_RS3_LE:
b2d38a17 8136 dynamic_section_mips_val (entry);
252b5132 8137 break;
103f02d3 8138 case EM_PARISC:
b2d38a17 8139 dynamic_section_parisc_val (entry);
103f02d3 8140 break;
ecc51f48 8141 case EM_IA_64:
b2d38a17 8142 dynamic_section_ia64_val (entry);
ecc51f48 8143 break;
252b5132 8144 default:
f7a99963
NC
8145 print_vma (entry->d_un.d_val, PREFIX_HEX);
8146 putchar ('\n');
252b5132
RH
8147 }
8148 }
8149 break;
8150 }
8151 }
8152
8153 return 1;
8154}
8155
8156static char *
d3ba0551 8157get_ver_flags (unsigned int flags)
252b5132 8158{
b34976b6 8159 static char buff[32];
252b5132
RH
8160
8161 buff[0] = 0;
8162
8163 if (flags == 0)
8164 return _("none");
8165
8166 if (flags & VER_FLG_BASE)
8167 strcat (buff, "BASE ");
8168
8169 if (flags & VER_FLG_WEAK)
8170 {
8171 if (flags & VER_FLG_BASE)
8172 strcat (buff, "| ");
8173
8174 strcat (buff, "WEAK ");
8175 }
8176
44ec90b9
RO
8177 if (flags & VER_FLG_INFO)
8178 {
8179 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8180 strcat (buff, "| ");
8181
8182 strcat (buff, "INFO ");
8183 }
8184
8185 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8186 strcat (buff, _("| <unknown>"));
252b5132
RH
8187
8188 return buff;
8189}
8190
8191/* Display the contents of the version sections. */
98fb390a 8192
252b5132 8193static int
2cf0635d 8194process_version_sections (FILE * file)
252b5132 8195{
2cf0635d 8196 Elf_Internal_Shdr * section;
b34976b6
AM
8197 unsigned i;
8198 int found = 0;
252b5132
RH
8199
8200 if (! do_version)
8201 return 1;
8202
8203 for (i = 0, section = section_headers;
8204 i < elf_header.e_shnum;
b34976b6 8205 i++, section++)
252b5132
RH
8206 {
8207 switch (section->sh_type)
8208 {
8209 case SHT_GNU_verdef:
8210 {
2cf0635d 8211 Elf_External_Verdef * edefs;
b34976b6
AM
8212 unsigned int idx;
8213 unsigned int cnt;
2cf0635d 8214 char * endbuf;
252b5132
RH
8215
8216 found = 1;
8217
8218 printf
72de5009 8219 (_("\nVersion definition 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 edefs = (Elf_External_Verdef *)
8231 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8232 _("version definition section"));
a6e9f9df
AM
8233 if (!edefs)
8234 break;
59245841 8235 endbuf = (char *) edefs + section->sh_size;
252b5132 8236
b34976b6 8237 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8238 {
2cf0635d
NC
8239 char * vstart;
8240 Elf_External_Verdef * edef;
b34976b6 8241 Elf_Internal_Verdef ent;
2cf0635d 8242 Elf_External_Verdaux * eaux;
b34976b6
AM
8243 Elf_Internal_Verdaux aux;
8244 int j;
8245 int isum;
103f02d3 8246
dd24e3da
NC
8247 /* Check for negative or very large indicies. */
8248 if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
8249 break;
8250
252b5132 8251 vstart = ((char *) edefs) + idx;
54806181
AM
8252 if (vstart + sizeof (*edef) > endbuf)
8253 break;
252b5132
RH
8254
8255 edef = (Elf_External_Verdef *) vstart;
8256
8257 ent.vd_version = BYTE_GET (edef->vd_version);
8258 ent.vd_flags = BYTE_GET (edef->vd_flags);
8259 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8260 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8261 ent.vd_hash = BYTE_GET (edef->vd_hash);
8262 ent.vd_aux = BYTE_GET (edef->vd_aux);
8263 ent.vd_next = BYTE_GET (edef->vd_next);
8264
8265 printf (_(" %#06x: Rev: %d Flags: %s"),
8266 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8267
8268 printf (_(" Index: %d Cnt: %d "),
8269 ent.vd_ndx, ent.vd_cnt);
8270
dd24e3da
NC
8271 /* Check for overflow. */
8272 if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
8273 || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
8274 break;
8275
252b5132
RH
8276 vstart += ent.vd_aux;
8277
8278 eaux = (Elf_External_Verdaux *) vstart;
8279
8280 aux.vda_name = BYTE_GET (eaux->vda_name);
8281 aux.vda_next = BYTE_GET (eaux->vda_next);
8282
d79b3d50
NC
8283 if (VALID_DYNAMIC_NAME (aux.vda_name))
8284 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8285 else
8286 printf (_("Name index: %ld\n"), aux.vda_name);
8287
8288 isum = idx + ent.vd_aux;
8289
b34976b6 8290 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8291 {
dd24e3da
NC
8292 /* Check for overflow. */
8293 if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
8294 || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
8295 break;
8296
252b5132
RH
8297 isum += aux.vda_next;
8298 vstart += aux.vda_next;
8299
8300 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8301 if (vstart + sizeof (*eaux) > endbuf)
8302 break;
252b5132
RH
8303
8304 aux.vda_name = BYTE_GET (eaux->vda_name);
8305 aux.vda_next = BYTE_GET (eaux->vda_next);
8306
d79b3d50 8307 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8308 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8309 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8310 else
8311 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8312 isum, j, aux.vda_name);
8313 }
dd24e3da 8314
54806181
AM
8315 if (j < ent.vd_cnt)
8316 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8317
8318 idx += ent.vd_next;
8319 }
dd24e3da 8320
54806181
AM
8321 if (cnt < section->sh_info)
8322 printf (_(" Version definition past end of section\n"));
252b5132
RH
8323
8324 free (edefs);
8325 }
8326 break;
103f02d3 8327
252b5132
RH
8328 case SHT_GNU_verneed:
8329 {
2cf0635d 8330 Elf_External_Verneed * eneed;
b34976b6
AM
8331 unsigned int idx;
8332 unsigned int cnt;
2cf0635d 8333 char * endbuf;
252b5132
RH
8334
8335 found = 1;
8336
72de5009 8337 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8338 SECTION_NAME (section), section->sh_info);
8339
8340 printf (_(" Addr: 0x"));
8341 printf_vma (section->sh_addr);
72de5009 8342 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8343 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8344 section->sh_link < elf_header.e_shnum
8345 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8346 : _("<corrupt>"));
252b5132 8347
3f5e193b
NC
8348 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8349 section->sh_offset, 1,
8350 section->sh_size,
9cf03b7e 8351 _("Version Needs section"));
a6e9f9df
AM
8352 if (!eneed)
8353 break;
59245841 8354 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8355
8356 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8357 {
2cf0635d 8358 Elf_External_Verneed * entry;
b34976b6
AM
8359 Elf_Internal_Verneed ent;
8360 int j;
8361 int isum;
2cf0635d 8362 char * vstart;
252b5132 8363
dd24e3da
NC
8364 if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
8365 break;
8366
252b5132 8367 vstart = ((char *) eneed) + idx;
54806181
AM
8368 if (vstart + sizeof (*entry) > endbuf)
8369 break;
252b5132
RH
8370
8371 entry = (Elf_External_Verneed *) vstart;
8372
8373 ent.vn_version = BYTE_GET (entry->vn_version);
8374 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8375 ent.vn_file = BYTE_GET (entry->vn_file);
8376 ent.vn_aux = BYTE_GET (entry->vn_aux);
8377 ent.vn_next = BYTE_GET (entry->vn_next);
8378
8379 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8380
d79b3d50
NC
8381 if (VALID_DYNAMIC_NAME (ent.vn_file))
8382 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8383 else
8384 printf (_(" File: %lx"), ent.vn_file);
8385
8386 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8387
dd24e3da
NC
8388 /* Check for overflow. */
8389 if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
8390 || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
8391 break;
8392
252b5132
RH
8393 vstart += ent.vn_aux;
8394
8395 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8396 {
2cf0635d 8397 Elf_External_Vernaux * eaux;
b34976b6 8398 Elf_Internal_Vernaux aux;
252b5132 8399
54806181
AM
8400 if (vstart + sizeof (*eaux) > endbuf)
8401 break;
252b5132
RH
8402 eaux = (Elf_External_Vernaux *) vstart;
8403
8404 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8405 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8406 aux.vna_other = BYTE_GET (eaux->vna_other);
8407 aux.vna_name = BYTE_GET (eaux->vna_name);
8408 aux.vna_next = BYTE_GET (eaux->vna_next);
8409
d79b3d50 8410 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8411 printf (_(" %#06x: Name: %s"),
d79b3d50 8412 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8413 else
ecc2063b 8414 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8415 isum, aux.vna_name);
8416
8417 printf (_(" Flags: %s Version: %d\n"),
8418 get_ver_flags (aux.vna_flags), aux.vna_other);
8419
dd24e3da
NC
8420 /* Check for overflow. */
8421 if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
8422 || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
8423 break;
8424
252b5132
RH
8425 isum += aux.vna_next;
8426 vstart += aux.vna_next;
8427 }
9cf03b7e 8428
54806181 8429 if (j < ent.vn_cnt)
9cf03b7e 8430 warn (_("Missing Version Needs auxillary information\n"));
252b5132
RH
8431
8432 idx += ent.vn_next;
8433 }
9cf03b7e 8434
54806181 8435 if (cnt < section->sh_info)
9cf03b7e 8436 warn (_("Missing Version Needs information\n"));
103f02d3 8437
252b5132
RH
8438 free (eneed);
8439 }
8440 break;
8441
8442 case SHT_GNU_versym:
8443 {
2cf0635d 8444 Elf_Internal_Shdr * link_section;
b34976b6
AM
8445 int total;
8446 int cnt;
2cf0635d
NC
8447 unsigned char * edata;
8448 unsigned short * data;
8449 char * strtab;
8450 Elf_Internal_Sym * symbols;
8451 Elf_Internal_Shdr * string_sec;
ba5cdace 8452 unsigned long num_syms;
d3ba0551 8453 long off;
252b5132 8454
4fbb74a6 8455 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8456 break;
8457
4fbb74a6 8458 link_section = section_headers + section->sh_link;
08d8fa11 8459 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8460
4fbb74a6 8461 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8462 break;
8463
252b5132
RH
8464 found = 1;
8465
ba5cdace 8466 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
8467 if (symbols == NULL)
8468 break;
252b5132 8469
4fbb74a6 8470 string_sec = section_headers + link_section->sh_link;
252b5132 8471
3f5e193b
NC
8472 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8473 string_sec->sh_size,
8474 _("version string table"));
a6e9f9df 8475 if (!strtab)
0429c154
MS
8476 {
8477 free (symbols);
8478 break;
8479 }
252b5132
RH
8480
8481 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8482 SECTION_NAME (section), total);
8483
8484 printf (_(" Addr: "));
8485 printf_vma (section->sh_addr);
72de5009 8486 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8487 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8488 SECTION_NAME (link_section));
8489
d3ba0551
AM
8490 off = offset_from_vma (file,
8491 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8492 total * sizeof (short));
3f5e193b
NC
8493 edata = (unsigned char *) get_data (NULL, file, off, total,
8494 sizeof (short),
8495 _("version symbol data"));
a6e9f9df
AM
8496 if (!edata)
8497 {
8498 free (strtab);
0429c154 8499 free (symbols);
a6e9f9df
AM
8500 break;
8501 }
252b5132 8502
3f5e193b 8503 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8504
8505 for (cnt = total; cnt --;)
b34976b6
AM
8506 data[cnt] = byte_get (edata + cnt * sizeof (short),
8507 sizeof (short));
252b5132
RH
8508
8509 free (edata);
8510
8511 for (cnt = 0; cnt < total; cnt += 4)
8512 {
8513 int j, nn;
00d93f34 8514 int check_def, check_need;
2cf0635d 8515 char * name;
252b5132
RH
8516
8517 printf (" %03x:", cnt);
8518
8519 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8520 switch (data[cnt + j])
252b5132
RH
8521 {
8522 case 0:
8523 fputs (_(" 0 (*local*) "), stdout);
8524 break;
8525
8526 case 1:
8527 fputs (_(" 1 (*global*) "), stdout);
8528 break;
8529
8530 default:
c244d050
NC
8531 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8532 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8533
dd24e3da 8534 /* If this index value is greater than the size of the symbols
ba5cdace
NC
8535 array, break to avoid an out-of-bounds read. */
8536 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
8537 {
8538 warn (_("invalid index into symbol array\n"));
8539 break;
8540 }
8541
00d93f34
JJ
8542 check_def = 1;
8543 check_need = 1;
4fbb74a6
AM
8544 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8545 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8546 != SHT_NOBITS)
252b5132 8547 {
b34976b6 8548 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8549 check_def = 0;
8550 else
8551 check_need = 0;
252b5132 8552 }
00d93f34
JJ
8553
8554 if (check_need
b34976b6 8555 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8556 {
b34976b6
AM
8557 Elf_Internal_Verneed ivn;
8558 unsigned long offset;
252b5132 8559
d93f0186
NC
8560 offset = offset_from_vma
8561 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8562 sizeof (Elf_External_Verneed));
252b5132 8563
b34976b6 8564 do
252b5132 8565 {
b34976b6
AM
8566 Elf_Internal_Vernaux ivna;
8567 Elf_External_Verneed evn;
8568 Elf_External_Vernaux evna;
8569 unsigned long a_off;
252b5132 8570
59245841
NC
8571 if (get_data (&evn, file, offset, sizeof (evn), 1,
8572 _("version need")) == NULL)
8573 break;
8574
252b5132
RH
8575 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8576 ivn.vn_next = BYTE_GET (evn.vn_next);
8577
8578 a_off = offset + ivn.vn_aux;
8579
8580 do
8581 {
59245841
NC
8582 if (get_data (&evna, file, a_off, sizeof (evna),
8583 1, _("version need aux (2)")) == NULL)
8584 {
8585 ivna.vna_next = 0;
8586 ivna.vna_other = 0;
8587 }
8588 else
8589 {
8590 ivna.vna_next = BYTE_GET (evna.vna_next);
8591 ivna.vna_other = BYTE_GET (evna.vna_other);
8592 }
252b5132
RH
8593
8594 a_off += ivna.vna_next;
8595 }
b34976b6 8596 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8597 && ivna.vna_next != 0);
8598
b34976b6 8599 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8600 {
8601 ivna.vna_name = BYTE_GET (evna.vna_name);
8602
54806181
AM
8603 if (ivna.vna_name >= string_sec->sh_size)
8604 name = _("*invalid*");
8605 else
8606 name = strtab + ivna.vna_name;
252b5132 8607 nn += printf ("(%s%-*s",
16062207
ILT
8608 name,
8609 12 - (int) strlen (name),
252b5132 8610 ")");
00d93f34 8611 check_def = 0;
252b5132
RH
8612 break;
8613 }
8614
8615 offset += ivn.vn_next;
8616 }
8617 while (ivn.vn_next);
8618 }
00d93f34 8619
b34976b6
AM
8620 if (check_def && data[cnt + j] != 0x8001
8621 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8622 {
b34976b6
AM
8623 Elf_Internal_Verdef ivd;
8624 Elf_External_Verdef evd;
8625 unsigned long offset;
252b5132 8626
d93f0186
NC
8627 offset = offset_from_vma
8628 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8629 sizeof evd);
252b5132
RH
8630
8631 do
8632 {
59245841
NC
8633 if (get_data (&evd, file, offset, sizeof (evd), 1,
8634 _("version def")) == NULL)
8635 {
8636 ivd.vd_next = 0;
8637 ivd.vd_ndx = 0;
8638 }
8639 else
8640 {
8641 ivd.vd_next = BYTE_GET (evd.vd_next);
8642 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8643 }
252b5132
RH
8644
8645 offset += ivd.vd_next;
8646 }
c244d050 8647 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8648 && ivd.vd_next != 0);
8649
c244d050 8650 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8651 {
b34976b6
AM
8652 Elf_External_Verdaux evda;
8653 Elf_Internal_Verdaux ivda;
252b5132
RH
8654
8655 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8656
59245841
NC
8657 if (get_data (&evda, file,
8658 offset - ivd.vd_next + ivd.vd_aux,
8659 sizeof (evda), 1,
8660 _("version def aux")) == NULL)
8661 break;
252b5132
RH
8662
8663 ivda.vda_name = BYTE_GET (evda.vda_name);
8664
54806181
AM
8665 if (ivda.vda_name >= string_sec->sh_size)
8666 name = _("*invalid*");
8667 else
8668 name = strtab + ivda.vda_name;
252b5132 8669 nn += printf ("(%s%-*s",
16062207
ILT
8670 name,
8671 12 - (int) strlen (name),
252b5132
RH
8672 ")");
8673 }
8674 }
8675
8676 if (nn < 18)
8677 printf ("%*c", 18 - nn, ' ');
8678 }
8679
8680 putchar ('\n');
8681 }
8682
8683 free (data);
8684 free (strtab);
8685 free (symbols);
8686 }
8687 break;
103f02d3 8688
252b5132
RH
8689 default:
8690 break;
8691 }
8692 }
8693
8694 if (! found)
8695 printf (_("\nNo version information found in this file.\n"));
8696
8697 return 1;
8698}
8699
d1133906 8700static const char *
d3ba0551 8701get_symbol_binding (unsigned int binding)
252b5132 8702{
b34976b6 8703 static char buff[32];
252b5132
RH
8704
8705 switch (binding)
8706 {
b34976b6
AM
8707 case STB_LOCAL: return "LOCAL";
8708 case STB_GLOBAL: return "GLOBAL";
8709 case STB_WEAK: return "WEAK";
252b5132
RH
8710 default:
8711 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8712 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8713 binding);
252b5132 8714 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8715 {
8716 if (binding == STB_GNU_UNIQUE
9c55345c
TS
8717 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8718 /* GNU is still using the default value 0. */
3e7a7d11
NC
8719 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8720 return "UNIQUE";
8721 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8722 }
252b5132 8723 else
e9e44622 8724 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8725 return buff;
8726 }
8727}
8728
d1133906 8729static const char *
d3ba0551 8730get_symbol_type (unsigned int type)
252b5132 8731{
b34976b6 8732 static char buff[32];
252b5132
RH
8733
8734 switch (type)
8735 {
b34976b6
AM
8736 case STT_NOTYPE: return "NOTYPE";
8737 case STT_OBJECT: return "OBJECT";
8738 case STT_FUNC: return "FUNC";
8739 case STT_SECTION: return "SECTION";
8740 case STT_FILE: return "FILE";
8741 case STT_COMMON: return "COMMON";
8742 case STT_TLS: return "TLS";
15ab5209
DB
8743 case STT_RELC: return "RELC";
8744 case STT_SRELC: return "SRELC";
252b5132
RH
8745 default:
8746 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8747 {
8748 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8749 return "THUMB_FUNC";
8750
351b4b40 8751 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8752 return "REGISTER";
8753
8754 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8755 return "PARISC_MILLI";
8756
e9e44622 8757 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8758 }
252b5132 8759 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8760 {
8761 if (elf_header.e_machine == EM_PARISC)
8762 {
8763 if (type == STT_HP_OPAQUE)
8764 return "HP_OPAQUE";
8765 if (type == STT_HP_STUB)
8766 return "HP_STUB";
8767 }
8768
d8045f23 8769 if (type == STT_GNU_IFUNC
9c55345c 8770 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 8771 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 8772 /* GNU is still using the default value 0. */
d8045f23
NC
8773 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8774 return "IFUNC";
8775
e9e44622 8776 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8777 }
252b5132 8778 else
e9e44622 8779 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8780 return buff;
8781 }
8782}
8783
d1133906 8784static const char *
d3ba0551 8785get_symbol_visibility (unsigned int visibility)
d1133906
NC
8786{
8787 switch (visibility)
8788 {
b34976b6
AM
8789 case STV_DEFAULT: return "DEFAULT";
8790 case STV_INTERNAL: return "INTERNAL";
8791 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
8792 case STV_PROTECTED: return "PROTECTED";
8793 default: abort ();
8794 }
8795}
8796
5e2b0d47
NC
8797static const char *
8798get_mips_symbol_other (unsigned int other)
8799{
8800 switch (other)
8801 {
df58fc94
RS
8802 case STO_OPTIONAL:
8803 return "OPTIONAL";
8804 case STO_MIPS_PLT:
8805 return "MIPS PLT";
8806 case STO_MIPS_PIC:
8807 return "MIPS PIC";
8808 case STO_MICROMIPS:
8809 return "MICROMIPS";
8810 case STO_MICROMIPS | STO_MIPS_PIC:
8811 return "MICROMIPS, MIPS PIC";
8812 case STO_MIPS16:
8813 return "MIPS16";
8814 default:
8815 return NULL;
5e2b0d47
NC
8816 }
8817}
8818
28f997cf
TG
8819static const char *
8820get_ia64_symbol_other (unsigned int other)
8821{
8822 if (is_ia64_vms ())
8823 {
8824 static char res[32];
8825
8826 res[0] = 0;
8827
8828 /* Function types is for images and .STB files only. */
8829 switch (elf_header.e_type)
8830 {
8831 case ET_DYN:
8832 case ET_EXEC:
8833 switch (VMS_ST_FUNC_TYPE (other))
8834 {
8835 case VMS_SFT_CODE_ADDR:
8836 strcat (res, " CA");
8837 break;
8838 case VMS_SFT_SYMV_IDX:
8839 strcat (res, " VEC");
8840 break;
8841 case VMS_SFT_FD:
8842 strcat (res, " FD");
8843 break;
8844 case VMS_SFT_RESERVE:
8845 strcat (res, " RSV");
8846 break;
8847 default:
8848 abort ();
8849 }
8850 break;
8851 default:
8852 break;
8853 }
8854 switch (VMS_ST_LINKAGE (other))
8855 {
8856 case VMS_STL_IGNORE:
8857 strcat (res, " IGN");
8858 break;
8859 case VMS_STL_RESERVE:
8860 strcat (res, " RSV");
8861 break;
8862 case VMS_STL_STD:
8863 strcat (res, " STD");
8864 break;
8865 case VMS_STL_LNK:
8866 strcat (res, " LNK");
8867 break;
8868 default:
8869 abort ();
8870 }
8871
8872 if (res[0] != 0)
8873 return res + 1;
8874 else
8875 return res;
8876 }
8877 return NULL;
8878}
8879
5e2b0d47
NC
8880static const char *
8881get_symbol_other (unsigned int other)
8882{
8883 const char * result = NULL;
8884 static char buff [32];
8885
8886 if (other == 0)
8887 return "";
8888
8889 switch (elf_header.e_machine)
8890 {
8891 case EM_MIPS:
8892 result = get_mips_symbol_other (other);
28f997cf
TG
8893 break;
8894 case EM_IA_64:
8895 result = get_ia64_symbol_other (other);
8896 break;
5e2b0d47
NC
8897 default:
8898 break;
8899 }
8900
8901 if (result)
8902 return result;
8903
8904 snprintf (buff, sizeof buff, _("<other>: %x"), other);
8905 return buff;
8906}
8907
d1133906 8908static const char *
d3ba0551 8909get_symbol_index_type (unsigned int type)
252b5132 8910{
b34976b6 8911 static char buff[32];
5cf1065c 8912
252b5132
RH
8913 switch (type)
8914 {
b34976b6
AM
8915 case SHN_UNDEF: return "UND";
8916 case SHN_ABS: return "ABS";
8917 case SHN_COMMON: return "COM";
252b5132 8918 default:
9ce701e2
L
8919 if (type == SHN_IA_64_ANSI_COMMON
8920 && elf_header.e_machine == EM_IA_64
8921 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
8922 return "ANSI_COM";
8a9036a4 8923 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
8924 || elf_header.e_machine == EM_L1OM
8925 || elf_header.e_machine == EM_K1OM)
3b22753a
L
8926 && type == SHN_X86_64_LCOMMON)
8927 return "LARGE_COM";
ac145307
BS
8928 else if ((type == SHN_MIPS_SCOMMON
8929 && elf_header.e_machine == EM_MIPS)
8930 || (type == SHN_TIC6X_SCOMMON
8931 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
8932 return "SCOM";
8933 else if (type == SHN_MIPS_SUNDEFINED
8934 && elf_header.e_machine == EM_MIPS)
8935 return "SUND";
9ce701e2 8936 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 8937 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 8938 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
8939 sprintf (buff, "OS [0x%04x]", type & 0xffff);
8940 else if (type >= SHN_LORESERVE)
8941 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 8942 else
232e7cb8 8943 sprintf (buff, "%3d", type);
5cf1065c 8944 break;
252b5132 8945 }
5cf1065c
NC
8946
8947 return buff;
252b5132
RH
8948}
8949
66543521 8950static bfd_vma *
2cf0635d 8951get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 8952{
2cf0635d
NC
8953 unsigned char * e_data;
8954 bfd_vma * i_data;
252b5132 8955
3f5e193b 8956 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
8957
8958 if (e_data == NULL)
8959 {
8960 error (_("Out of memory\n"));
8961 return NULL;
8962 }
8963
66543521 8964 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
8965 {
8966 error (_("Unable to read in dynamic data\n"));
8967 return NULL;
8968 }
8969
3f5e193b 8970 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
8971
8972 if (i_data == NULL)
8973 {
8974 error (_("Out of memory\n"));
8975 free (e_data);
8976 return NULL;
8977 }
8978
8979 while (number--)
66543521 8980 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
8981
8982 free (e_data);
8983
8984 return i_data;
8985}
8986
6bd1a22c
L
8987static void
8988print_dynamic_symbol (bfd_vma si, unsigned long hn)
8989{
2cf0635d 8990 Elf_Internal_Sym * psym;
6bd1a22c
L
8991 int n;
8992
8993 psym = dynamic_symbols + si;
8994
8995 n = print_vma (si, DEC_5);
8996 if (n < 5)
8997 fputs (" " + n, stdout);
8998 printf (" %3lu: ", hn);
8999 print_vma (psym->st_value, LONG_HEX);
9000 putchar (' ');
9001 print_vma (psym->st_size, DEC_5);
9002
f4be36b3
AM
9003 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9004 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
9005 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
9006 /* Check to see if any other bits in the st_other field are set.
9007 Note - displaying this information disrupts the layout of the
9008 table being generated, but for the moment this case is very
9009 rare. */
9010 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9011 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
9012 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
9013 if (VALID_DYNAMIC_NAME (psym->st_name))
9014 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9015 else
2b692964 9016 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
9017 putchar ('\n');
9018}
9019
e3c8793a 9020/* Dump the symbol table. */
252b5132 9021static int
2cf0635d 9022process_symbol_table (FILE * file)
252b5132 9023{
2cf0635d 9024 Elf_Internal_Shdr * section;
66543521
AM
9025 bfd_vma nbuckets = 0;
9026 bfd_vma nchains = 0;
2cf0635d
NC
9027 bfd_vma * buckets = NULL;
9028 bfd_vma * chains = NULL;
fdc90cb4 9029 bfd_vma ngnubuckets = 0;
2cf0635d
NC
9030 bfd_vma * gnubuckets = NULL;
9031 bfd_vma * gnuchains = NULL;
6bd1a22c 9032 bfd_vma gnusymidx = 0;
252b5132 9033
2c610e4b 9034 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
9035 return 1;
9036
6bd1a22c
L
9037 if (dynamic_info[DT_HASH]
9038 && (do_histogram
2c610e4b
L
9039 || (do_using_dynamic
9040 && !do_dyn_syms
9041 && dynamic_strings != NULL)))
252b5132 9042 {
66543521
AM
9043 unsigned char nb[8];
9044 unsigned char nc[8];
9045 int hash_ent_size = 4;
9046
9047 if ((elf_header.e_machine == EM_ALPHA
9048 || elf_header.e_machine == EM_S390
9049 || elf_header.e_machine == EM_S390_OLD)
9050 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
9051 hash_ent_size = 8;
9052
fb52b2f4
NC
9053 if (fseek (file,
9054 (archive_file_offset
9055 + offset_from_vma (file, dynamic_info[DT_HASH],
9056 sizeof nb + sizeof nc)),
d93f0186 9057 SEEK_SET))
252b5132 9058 {
591a748a 9059 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9060 goto no_hash;
252b5132
RH
9061 }
9062
66543521 9063 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
9064 {
9065 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9066 goto no_hash;
252b5132
RH
9067 }
9068
66543521 9069 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
9070 {
9071 error (_("Failed to read in number of chains\n"));
d3a44ec6 9072 goto no_hash;
252b5132
RH
9073 }
9074
66543521
AM
9075 nbuckets = byte_get (nb, hash_ent_size);
9076 nchains = byte_get (nc, hash_ent_size);
252b5132 9077
66543521
AM
9078 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
9079 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 9080
d3a44ec6 9081 no_hash:
252b5132 9082 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
9083 {
9084 if (do_using_dynamic)
9085 return 0;
9086 free (buckets);
9087 free (chains);
9088 buckets = NULL;
9089 chains = NULL;
9090 nbuckets = 0;
9091 nchains = 0;
9092 }
252b5132
RH
9093 }
9094
6bd1a22c
L
9095 if (dynamic_info_DT_GNU_HASH
9096 && (do_histogram
2c610e4b
L
9097 || (do_using_dynamic
9098 && !do_dyn_syms
9099 && dynamic_strings != NULL)))
252b5132 9100 {
6bd1a22c
L
9101 unsigned char nb[16];
9102 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
9103 bfd_vma buckets_vma;
9104
9105 if (fseek (file,
9106 (archive_file_offset
9107 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
9108 sizeof nb)),
9109 SEEK_SET))
9110 {
9111 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9112 goto no_gnu_hash;
6bd1a22c 9113 }
252b5132 9114
6bd1a22c
L
9115 if (fread (nb, 16, 1, file) != 1)
9116 {
9117 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9118 goto no_gnu_hash;
6bd1a22c
L
9119 }
9120
9121 ngnubuckets = byte_get (nb, 4);
9122 gnusymidx = byte_get (nb + 4, 4);
9123 bitmaskwords = byte_get (nb + 8, 4);
9124 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9125 if (is_32bit_elf)
6bd1a22c 9126 buckets_vma += bitmaskwords * 4;
f7a99963 9127 else
6bd1a22c 9128 buckets_vma += bitmaskwords * 8;
252b5132 9129
6bd1a22c
L
9130 if (fseek (file,
9131 (archive_file_offset
9132 + offset_from_vma (file, buckets_vma, 4)),
9133 SEEK_SET))
252b5132 9134 {
6bd1a22c 9135 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9136 goto no_gnu_hash;
6bd1a22c
L
9137 }
9138
9139 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9140
6bd1a22c 9141 if (gnubuckets == NULL)
d3a44ec6 9142 goto no_gnu_hash;
6bd1a22c
L
9143
9144 for (i = 0; i < ngnubuckets; i++)
9145 if (gnubuckets[i] != 0)
9146 {
9147 if (gnubuckets[i] < gnusymidx)
9148 return 0;
9149
9150 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9151 maxchain = gnubuckets[i];
9152 }
9153
9154 if (maxchain == 0xffffffff)
d3a44ec6 9155 goto no_gnu_hash;
6bd1a22c
L
9156
9157 maxchain -= gnusymidx;
9158
9159 if (fseek (file,
9160 (archive_file_offset
9161 + offset_from_vma (file, buckets_vma
9162 + 4 * (ngnubuckets + maxchain), 4)),
9163 SEEK_SET))
9164 {
9165 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9166 goto no_gnu_hash;
6bd1a22c
L
9167 }
9168
9169 do
9170 {
9171 if (fread (nb, 4, 1, file) != 1)
252b5132 9172 {
6bd1a22c 9173 error (_("Failed to determine last chain length\n"));
d3a44ec6 9174 goto no_gnu_hash;
6bd1a22c 9175 }
252b5132 9176
6bd1a22c 9177 if (maxchain + 1 == 0)
d3a44ec6 9178 goto no_gnu_hash;
252b5132 9179
6bd1a22c
L
9180 ++maxchain;
9181 }
9182 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9183
6bd1a22c
L
9184 if (fseek (file,
9185 (archive_file_offset
9186 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9187 SEEK_SET))
9188 {
9189 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9190 goto no_gnu_hash;
6bd1a22c
L
9191 }
9192
9193 gnuchains = get_dynamic_data (file, maxchain, 4);
9194
d3a44ec6 9195 no_gnu_hash:
6bd1a22c 9196 if (gnuchains == NULL)
d3a44ec6
JJ
9197 {
9198 free (gnubuckets);
d3a44ec6
JJ
9199 gnubuckets = NULL;
9200 ngnubuckets = 0;
f64fddf1
NC
9201 if (do_using_dynamic)
9202 return 0;
d3a44ec6 9203 }
6bd1a22c
L
9204 }
9205
9206 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9207 && do_syms
9208 && do_using_dynamic
9209 && dynamic_strings != NULL)
9210 {
9211 unsigned long hn;
9212
9213 if (dynamic_info[DT_HASH])
9214 {
9215 bfd_vma si;
9216
9217 printf (_("\nSymbol table for image:\n"));
9218 if (is_32bit_elf)
9219 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9220 else
9221 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9222
9223 for (hn = 0; hn < nbuckets; hn++)
9224 {
9225 if (! buckets[hn])
9226 continue;
9227
9228 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9229 print_dynamic_symbol (si, hn);
252b5132
RH
9230 }
9231 }
6bd1a22c
L
9232
9233 if (dynamic_info_DT_GNU_HASH)
9234 {
9235 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9236 if (is_32bit_elf)
9237 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9238 else
9239 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9240
9241 for (hn = 0; hn < ngnubuckets; ++hn)
9242 if (gnubuckets[hn] != 0)
9243 {
9244 bfd_vma si = gnubuckets[hn];
9245 bfd_vma off = si - gnusymidx;
9246
9247 do
9248 {
9249 print_dynamic_symbol (si, hn);
9250 si++;
9251 }
9252 while ((gnuchains[off++] & 1) == 0);
9253 }
9254 }
252b5132 9255 }
2c610e4b 9256 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9257 {
b34976b6 9258 unsigned int i;
252b5132
RH
9259
9260 for (i = 0, section = section_headers;
9261 i < elf_header.e_shnum;
9262 i++, section++)
9263 {
b34976b6 9264 unsigned int si;
2cf0635d 9265 char * strtab = NULL;
c256ffe7 9266 unsigned long int strtab_size = 0;
2cf0635d
NC
9267 Elf_Internal_Sym * symtab;
9268 Elf_Internal_Sym * psym;
ba5cdace 9269 unsigned long num_syms;
252b5132 9270
2c610e4b
L
9271 if ((section->sh_type != SHT_SYMTAB
9272 && section->sh_type != SHT_DYNSYM)
9273 || (!do_syms
9274 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9275 continue;
9276
dd24e3da
NC
9277 if (section->sh_entsize == 0)
9278 {
9279 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9280 SECTION_NAME (section));
9281 continue;
9282 }
9283
252b5132
RH
9284 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9285 SECTION_NAME (section),
9286 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9287
f7a99963 9288 if (is_32bit_elf)
ca47b30c 9289 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9290 else
ca47b30c 9291 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9292
ba5cdace 9293 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
9294 if (symtab == NULL)
9295 continue;
9296
9297 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9298 {
9299 strtab = string_table;
9300 strtab_size = string_table_length;
9301 }
4fbb74a6 9302 else if (section->sh_link < elf_header.e_shnum)
252b5132 9303 {
2cf0635d 9304 Elf_Internal_Shdr * string_sec;
252b5132 9305
4fbb74a6 9306 string_sec = section_headers + section->sh_link;
252b5132 9307
3f5e193b
NC
9308 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9309 1, string_sec->sh_size,
9310 _("string table"));
c256ffe7 9311 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9312 }
9313
ba5cdace 9314 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 9315 {
5e220199 9316 printf ("%6d: ", si);
f7a99963
NC
9317 print_vma (psym->st_value, LONG_HEX);
9318 putchar (' ');
9319 print_vma (psym->st_size, DEC_5);
d1133906
NC
9320 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9321 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9322 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9323 /* Check to see if any other bits in the st_other field are set.
9324 Note - displaying this information disrupts the layout of the
9325 table being generated, but for the moment this case is very rare. */
9326 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9327 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9328 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9329 print_symbol (25, psym->st_name < strtab_size
2b692964 9330 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9331
59245841
NC
9332 if (section->sh_type == SHT_DYNSYM
9333 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9334 {
b34976b6
AM
9335 unsigned char data[2];
9336 unsigned short vers_data;
9337 unsigned long offset;
9338 int is_nobits;
9339 int check_def;
252b5132 9340
d93f0186
NC
9341 offset = offset_from_vma
9342 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9343 sizeof data + si * sizeof (vers_data));
252b5132 9344
59245841
NC
9345 if (get_data (&data, file, offset + si * sizeof (vers_data),
9346 sizeof (data), 1, _("version data")) == NULL)
9347 break;
252b5132
RH
9348
9349 vers_data = byte_get (data, 2);
9350
4fbb74a6
AM
9351 is_nobits = (psym->st_shndx < elf_header.e_shnum
9352 && section_headers[psym->st_shndx].sh_type
c256ffe7 9353 == SHT_NOBITS);
252b5132
RH
9354
9355 check_def = (psym->st_shndx != SHN_UNDEF);
9356
c244d050 9357 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9358 {
b34976b6 9359 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9360 && (is_nobits || ! check_def))
252b5132 9361 {
b34976b6
AM
9362 Elf_External_Verneed evn;
9363 Elf_Internal_Verneed ivn;
9364 Elf_Internal_Vernaux ivna;
252b5132
RH
9365
9366 /* We must test both. */
d93f0186
NC
9367 offset = offset_from_vma
9368 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9369 sizeof evn);
252b5132 9370
252b5132
RH
9371 do
9372 {
b34976b6 9373 unsigned long vna_off;
252b5132 9374
59245841
NC
9375 if (get_data (&evn, file, offset, sizeof (evn), 1,
9376 _("version need")) == NULL)
9377 {
9378 ivna.vna_next = 0;
9379 ivna.vna_other = 0;
9380 ivna.vna_name = 0;
9381 break;
9382 }
dd27201e
L
9383
9384 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9385 ivn.vn_next = BYTE_GET (evn.vn_next);
9386
252b5132
RH
9387 vna_off = offset + ivn.vn_aux;
9388
9389 do
9390 {
b34976b6 9391 Elf_External_Vernaux evna;
252b5132 9392
59245841
NC
9393 if (get_data (&evna, file, vna_off,
9394 sizeof (evna), 1,
9395 _("version need aux (3)")) == NULL)
9396 {
9397 ivna.vna_next = 0;
9398 ivna.vna_other = 0;
9399 ivna.vna_name = 0;
9400 }
9401 else
9402 {
9403 ivna.vna_other = BYTE_GET (evna.vna_other);
9404 ivna.vna_next = BYTE_GET (evna.vna_next);
9405 ivna.vna_name = BYTE_GET (evna.vna_name);
9406 }
252b5132
RH
9407
9408 vna_off += ivna.vna_next;
9409 }
9410 while (ivna.vna_other != vers_data
9411 && ivna.vna_next != 0);
9412
9413 if (ivna.vna_other == vers_data)
9414 break;
9415
9416 offset += ivn.vn_next;
9417 }
9418 while (ivn.vn_next != 0);
9419
9420 if (ivna.vna_other == vers_data)
9421 {
9422 printf ("@%s (%d)",
c256ffe7 9423 ivna.vna_name < strtab_size
2b692964 9424 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9425 ivna.vna_other);
252b5132
RH
9426 check_def = 0;
9427 }
9428 else if (! is_nobits)
591a748a 9429 error (_("bad dynamic symbol\n"));
252b5132
RH
9430 else
9431 check_def = 1;
9432 }
9433
9434 if (check_def)
9435 {
00d93f34 9436 if (vers_data != 0x8001
b34976b6 9437 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9438 {
b34976b6
AM
9439 Elf_Internal_Verdef ivd;
9440 Elf_Internal_Verdaux ivda;
9441 Elf_External_Verdaux evda;
91d6fa6a 9442 unsigned long off;
252b5132 9443
91d6fa6a 9444 off = offset_from_vma
d93f0186
NC
9445 (file,
9446 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9447 sizeof (Elf_External_Verdef));
252b5132
RH
9448
9449 do
9450 {
b34976b6 9451 Elf_External_Verdef evd;
252b5132 9452
59245841
NC
9453 if (get_data (&evd, file, off, sizeof (evd),
9454 1, _("version def")) == NULL)
9455 {
9456 ivd.vd_ndx = 0;
9457 ivd.vd_aux = 0;
9458 ivd.vd_next = 0;
9459 }
9460 else
9461 {
9462 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9463 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9464 ivd.vd_next = BYTE_GET (evd.vd_next);
9465 }
252b5132 9466
91d6fa6a 9467 off += ivd.vd_next;
252b5132 9468 }
c244d050 9469 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9470 && ivd.vd_next != 0);
9471
91d6fa6a
NC
9472 off -= ivd.vd_next;
9473 off += ivd.vd_aux;
252b5132 9474
59245841
NC
9475 if (get_data (&evda, file, off, sizeof (evda),
9476 1, _("version def aux")) == NULL)
9477 break;
252b5132
RH
9478
9479 ivda.vda_name = BYTE_GET (evda.vda_name);
9480
9481 if (psym->st_name != ivda.vda_name)
c244d050 9482 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9483 ? "@%s" : "@@%s",
c256ffe7 9484 ivda.vda_name < strtab_size
2b692964 9485 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9486 }
9487 }
9488 }
9489 }
9490
9491 putchar ('\n');
9492 }
9493
9494 free (symtab);
9495 if (strtab != string_table)
9496 free (strtab);
9497 }
9498 }
9499 else if (do_syms)
9500 printf
9501 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9502
9503 if (do_histogram && buckets != NULL)
9504 {
2cf0635d
NC
9505 unsigned long * lengths;
9506 unsigned long * counts;
66543521
AM
9507 unsigned long hn;
9508 bfd_vma si;
9509 unsigned long maxlength = 0;
9510 unsigned long nzero_counts = 0;
9511 unsigned long nsyms = 0;
252b5132 9512
66543521
AM
9513 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9514 (unsigned long) nbuckets);
252b5132
RH
9515 printf (_(" Length Number %% of total Coverage\n"));
9516
3f5e193b 9517 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9518 if (lengths == NULL)
9519 {
591a748a 9520 error (_("Out of memory\n"));
252b5132
RH
9521 return 0;
9522 }
9523 for (hn = 0; hn < nbuckets; ++hn)
9524 {
f7a99963 9525 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9526 {
b34976b6 9527 ++nsyms;
252b5132 9528 if (maxlength < ++lengths[hn])
b34976b6 9529 ++maxlength;
252b5132
RH
9530 }
9531 }
9532
3f5e193b 9533 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9534 if (counts == NULL)
9535 {
591a748a 9536 error (_("Out of memory\n"));
252b5132
RH
9537 return 0;
9538 }
9539
9540 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9541 ++counts[lengths[hn]];
252b5132 9542
103f02d3 9543 if (nbuckets > 0)
252b5132 9544 {
66543521
AM
9545 unsigned long i;
9546 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9547 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9548 for (i = 1; i <= maxlength; ++i)
103f02d3 9549 {
66543521
AM
9550 nzero_counts += counts[i] * i;
9551 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9552 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9553 (nzero_counts * 100.0) / nsyms);
9554 }
252b5132
RH
9555 }
9556
9557 free (counts);
9558 free (lengths);
9559 }
9560
9561 if (buckets != NULL)
9562 {
9563 free (buckets);
9564 free (chains);
9565 }
9566
d3a44ec6 9567 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9568 {
2cf0635d
NC
9569 unsigned long * lengths;
9570 unsigned long * counts;
fdc90cb4
JJ
9571 unsigned long hn;
9572 unsigned long maxlength = 0;
9573 unsigned long nzero_counts = 0;
9574 unsigned long nsyms = 0;
fdc90cb4 9575
3f5e193b 9576 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9577 if (lengths == NULL)
9578 {
591a748a 9579 error (_("Out of memory\n"));
fdc90cb4
JJ
9580 return 0;
9581 }
9582
9583 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9584 (unsigned long) ngnubuckets);
9585 printf (_(" Length Number %% of total Coverage\n"));
9586
9587 for (hn = 0; hn < ngnubuckets; ++hn)
9588 if (gnubuckets[hn] != 0)
9589 {
9590 bfd_vma off, length = 1;
9591
6bd1a22c 9592 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9593 (gnuchains[off] & 1) == 0; ++off)
9594 ++length;
9595 lengths[hn] = length;
9596 if (length > maxlength)
9597 maxlength = length;
9598 nsyms += length;
9599 }
9600
3f5e193b 9601 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9602 if (counts == NULL)
9603 {
591a748a 9604 error (_("Out of memory\n"));
fdc90cb4
JJ
9605 return 0;
9606 }
9607
9608 for (hn = 0; hn < ngnubuckets; ++hn)
9609 ++counts[lengths[hn]];
9610
9611 if (ngnubuckets > 0)
9612 {
9613 unsigned long j;
9614 printf (" 0 %-10lu (%5.1f%%)\n",
9615 counts[0], (counts[0] * 100.0) / ngnubuckets);
9616 for (j = 1; j <= maxlength; ++j)
9617 {
9618 nzero_counts += counts[j] * j;
9619 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9620 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9621 (nzero_counts * 100.0) / nsyms);
9622 }
9623 }
9624
9625 free (counts);
9626 free (lengths);
9627 free (gnubuckets);
9628 free (gnuchains);
9629 }
9630
252b5132
RH
9631 return 1;
9632}
9633
9634static int
2cf0635d 9635process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9636{
b4c96d0d 9637 unsigned int i;
252b5132
RH
9638
9639 if (dynamic_syminfo == NULL
9640 || !do_dynamic)
9641 /* No syminfo, this is ok. */
9642 return 1;
9643
9644 /* There better should be a dynamic symbol section. */
9645 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9646 return 0;
9647
9648 if (dynamic_addr)
9649 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9650 dynamic_syminfo_offset, dynamic_syminfo_nent);
9651
9652 printf (_(" Num: Name BoundTo Flags\n"));
9653 for (i = 0; i < dynamic_syminfo_nent; ++i)
9654 {
9655 unsigned short int flags = dynamic_syminfo[i].si_flags;
9656
31104126 9657 printf ("%4d: ", i);
d79b3d50
NC
9658 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9659 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9660 else
2b692964 9661 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9662 putchar (' ');
252b5132
RH
9663
9664 switch (dynamic_syminfo[i].si_boundto)
9665 {
9666 case SYMINFO_BT_SELF:
9667 fputs ("SELF ", stdout);
9668 break;
9669 case SYMINFO_BT_PARENT:
9670 fputs ("PARENT ", stdout);
9671 break;
9672 default:
9673 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9674 && dynamic_syminfo[i].si_boundto < dynamic_nent
9675 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9676 {
d79b3d50 9677 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9678 putchar (' ' );
9679 }
252b5132
RH
9680 else
9681 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9682 break;
9683 }
9684
9685 if (flags & SYMINFO_FLG_DIRECT)
9686 printf (" DIRECT");
9687 if (flags & SYMINFO_FLG_PASSTHRU)
9688 printf (" PASSTHRU");
9689 if (flags & SYMINFO_FLG_COPY)
9690 printf (" COPY");
9691 if (flags & SYMINFO_FLG_LAZYLOAD)
9692 printf (" LAZYLOAD");
9693
9694 puts ("");
9695 }
9696
9697 return 1;
9698}
9699
cf13d699
NC
9700/* Check to see if the given reloc needs to be handled in a target specific
9701 manner. If so then process the reloc and return TRUE otherwise return
9702 FALSE. */
09c11c86 9703
cf13d699
NC
9704static bfd_boolean
9705target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9706 unsigned char * start,
9707 Elf_Internal_Sym * symtab)
252b5132 9708{
cf13d699 9709 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9710
cf13d699 9711 switch (elf_header.e_machine)
252b5132 9712 {
cf13d699
NC
9713 case EM_MN10300:
9714 case EM_CYGNUS_MN10300:
9715 {
9716 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9717
cf13d699
NC
9718 switch (reloc_type)
9719 {
9720 case 34: /* R_MN10300_ALIGN */
9721 return TRUE;
9722 case 33: /* R_MN10300_SYM_DIFF */
9723 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9724 return TRUE;
9725 case 1: /* R_MN10300_32 */
9726 case 2: /* R_MN10300_16 */
9727 if (saved_sym != NULL)
9728 {
9729 bfd_vma value;
252b5132 9730
cf13d699
NC
9731 value = reloc->r_addend
9732 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9733 - saved_sym->st_value);
252b5132 9734
cf13d699 9735 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9736
cf13d699
NC
9737 saved_sym = NULL;
9738 return TRUE;
9739 }
9740 break;
9741 default:
9742 if (saved_sym != NULL)
9743 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9744 break;
9745 }
9746 break;
9747 }
252b5132
RH
9748 }
9749
cf13d699 9750 return FALSE;
252b5132
RH
9751}
9752
aca88567
NC
9753/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9754 DWARF debug sections. This is a target specific test. Note - we do not
9755 go through the whole including-target-headers-multiple-times route, (as
9756 we have already done with <elf/h8.h>) because this would become very
9757 messy and even then this function would have to contain target specific
9758 information (the names of the relocs instead of their numeric values).
9759 FIXME: This is not the correct way to solve this problem. The proper way
9760 is to have target specific reloc sizing and typing functions created by
9761 the reloc-macros.h header, in the same way that it already creates the
9762 reloc naming functions. */
9763
9764static bfd_boolean
9765is_32bit_abs_reloc (unsigned int reloc_type)
9766{
9767 switch (elf_header.e_machine)
9768 {
41e92641
NC
9769 case EM_386:
9770 case EM_486:
9771 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9772 case EM_68K:
9773 return reloc_type == 1; /* R_68K_32. */
9774 case EM_860:
9775 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9776 case EM_960:
9777 return reloc_type == 2; /* R_960_32. */
aca88567 9778 case EM_ALPHA:
137b6b5f 9779 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
9780 case EM_ARC:
9781 return reloc_type == 1; /* R_ARC_32. */
9782 case EM_ARM:
9783 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 9784 case EM_AVR_OLD:
aca88567
NC
9785 case EM_AVR:
9786 return reloc_type == 1;
cfb8c092
NC
9787 case EM_ADAPTEVA_EPIPHANY:
9788 return reloc_type == 3;
aca88567
NC
9789 case EM_BLACKFIN:
9790 return reloc_type == 0x12; /* R_byte4_data. */
9791 case EM_CRIS:
9792 return reloc_type == 3; /* R_CRIS_32. */
9793 case EM_CR16:
9794 return reloc_type == 3; /* R_CR16_NUM32. */
9795 case EM_CRX:
9796 return reloc_type == 15; /* R_CRX_NUM32. */
9797 case EM_CYGNUS_FRV:
9798 return reloc_type == 1;
41e92641
NC
9799 case EM_CYGNUS_D10V:
9800 case EM_D10V:
9801 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
9802 case EM_CYGNUS_D30V:
9803 case EM_D30V:
9804 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
9805 case EM_DLX:
9806 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
9807 case EM_CYGNUS_FR30:
9808 case EM_FR30:
9809 return reloc_type == 3; /* R_FR30_32. */
9810 case EM_H8S:
9811 case EM_H8_300:
9812 case EM_H8_300H:
9813 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
9814 case EM_IA_64:
9815 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
9816 case EM_IP2K_OLD:
9817 case EM_IP2K:
9818 return reloc_type == 2; /* R_IP2K_32. */
9819 case EM_IQ2000:
9820 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
9821 case EM_LATTICEMICO32:
9822 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 9823 case EM_M32C_OLD:
aca88567
NC
9824 case EM_M32C:
9825 return reloc_type == 3; /* R_M32C_32. */
9826 case EM_M32R:
9827 return reloc_type == 34; /* R_M32R_32_RELA. */
9828 case EM_MCORE:
9829 return reloc_type == 1; /* R_MCORE_ADDR32. */
9830 case EM_CYGNUS_MEP:
9831 return reloc_type == 4; /* R_MEP_32. */
137b6b5f
AM
9832 case EM_MICROBLAZE:
9833 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
9834 case EM_MIPS:
9835 return reloc_type == 2; /* R_MIPS_32. */
9836 case EM_MMIX:
9837 return reloc_type == 4; /* R_MMIX_32. */
9838 case EM_CYGNUS_MN10200:
9839 case EM_MN10200:
9840 return reloc_type == 1; /* R_MN10200_32. */
9841 case EM_CYGNUS_MN10300:
9842 case EM_MN10300:
9843 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
9844 case EM_MOXIE:
9845 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
9846 case EM_MSP430_OLD:
9847 case EM_MSP430:
9848 return reloc_type == 1; /* R_MSP43_32. */
9849 case EM_MT:
9850 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
9851 case EM_ALTERA_NIOS2:
9852 case EM_NIOS32:
9853 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
9854 case EM_OPENRISC:
9855 case EM_OR32:
9856 return reloc_type == 1; /* R_OR32_32. */
aca88567 9857 case EM_PARISC:
5fda8eca
NC
9858 return (reloc_type == 1 /* R_PARISC_DIR32. */
9859 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
9860 case EM_PJ:
9861 case EM_PJ_OLD:
9862 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
9863 case EM_PPC64:
9864 return reloc_type == 1; /* R_PPC64_ADDR32. */
9865 case EM_PPC:
9866 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
9867 case EM_RL78:
9868 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
9869 case EM_RX:
9870 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
9871 case EM_S370:
9872 return reloc_type == 1; /* R_I370_ADDR31. */
9873 case EM_S390_OLD:
9874 case EM_S390:
9875 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
9876 case EM_SCORE:
9877 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
9878 case EM_SH:
9879 return reloc_type == 1; /* R_SH_DIR32. */
9880 case EM_SPARC32PLUS:
9881 case EM_SPARCV9:
9882 case EM_SPARC:
9883 return reloc_type == 3 /* R_SPARC_32. */
9884 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
9885 case EM_SPU:
9886 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
9887 case EM_TI_C6000:
9888 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
9889 case EM_TILEGX:
9890 return reloc_type == 2; /* R_TILEGX_32. */
9891 case EM_TILEPRO:
9892 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
9893 case EM_CYGNUS_V850:
9894 case EM_V850:
9895 return reloc_type == 6; /* R_V850_ABS32. */
9896 case EM_VAX:
9897 return reloc_type == 1; /* R_VAX_32. */
9898 case EM_X86_64:
8a9036a4 9899 case EM_L1OM:
7a9068fe 9900 case EM_K1OM:
aca88567 9901 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
9902 case EM_XC16X:
9903 case EM_C166:
9904 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
9905 case EM_XGATE:
9906 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
9907 case EM_XSTORMY16:
9908 return reloc_type == 1; /* R_XSTROMY16_32. */
9909 case EM_XTENSA_OLD:
9910 case EM_XTENSA:
9911 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
9912 default:
9913 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
9914 elf_header.e_machine);
9915 abort ();
9916 }
9917}
9918
9919/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9920 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
9921
9922static bfd_boolean
9923is_32bit_pcrel_reloc (unsigned int reloc_type)
9924{
9925 switch (elf_header.e_machine)
9926 {
41e92641
NC
9927 case EM_386:
9928 case EM_486:
3e0873ac 9929 return reloc_type == 2; /* R_386_PC32. */
aca88567 9930 case EM_68K:
3e0873ac 9931 return reloc_type == 4; /* R_68K_PC32. */
cfb8c092
NC
9932 case EM_ADAPTEVA_EPIPHANY:
9933 return reloc_type == 6;
aca88567
NC
9934 case EM_ALPHA:
9935 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 9936 case EM_ARM:
3e0873ac 9937 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
9938 case EM_MICROBLAZE:
9939 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 9940 case EM_PARISC:
85acf597 9941 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
9942 case EM_PPC:
9943 return reloc_type == 26; /* R_PPC_REL32. */
9944 case EM_PPC64:
3e0873ac 9945 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
9946 case EM_S390_OLD:
9947 case EM_S390:
3e0873ac 9948 return reloc_type == 5; /* R_390_PC32. */
aca88567 9949 case EM_SH:
3e0873ac 9950 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
9951 case EM_SPARC32PLUS:
9952 case EM_SPARCV9:
9953 case EM_SPARC:
3e0873ac 9954 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
9955 case EM_SPU:
9956 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
9957 case EM_TILEGX:
9958 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
9959 case EM_TILEPRO:
9960 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 9961 case EM_X86_64:
8a9036a4 9962 case EM_L1OM:
7a9068fe 9963 case EM_K1OM:
3e0873ac 9964 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
9965 case EM_XTENSA_OLD:
9966 case EM_XTENSA:
9967 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
9968 default:
9969 /* Do not abort or issue an error message here. Not all targets use
9970 pc-relative 32-bit relocs in their DWARF debug information and we
9971 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
9972 more helpful warning message will be generated by apply_relocations
9973 anyway, so just return. */
aca88567
NC
9974 return FALSE;
9975 }
9976}
9977
9978/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9979 a 64-bit absolute RELA relocation used in DWARF debug sections. */
9980
9981static bfd_boolean
9982is_64bit_abs_reloc (unsigned int reloc_type)
9983{
9984 switch (elf_header.e_machine)
9985 {
9986 case EM_ALPHA:
9987 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
9988 case EM_IA_64:
9989 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
9990 case EM_PARISC:
9991 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
9992 case EM_PPC64:
9993 return reloc_type == 38; /* R_PPC64_ADDR64. */
9994 case EM_SPARC32PLUS:
9995 case EM_SPARCV9:
9996 case EM_SPARC:
9997 return reloc_type == 54; /* R_SPARC_UA64. */
9998 case EM_X86_64:
8a9036a4 9999 case EM_L1OM:
7a9068fe 10000 case EM_K1OM:
aca88567 10001 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
10002 case EM_S390_OLD:
10003 case EM_S390:
aa137e4d
NC
10004 return reloc_type == 22; /* R_S390_64. */
10005 case EM_TILEGX:
10006 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 10007 case EM_MIPS:
aa137e4d 10008 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
10009 default:
10010 return FALSE;
10011 }
10012}
10013
85acf597
RH
10014/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
10015 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
10016
10017static bfd_boolean
10018is_64bit_pcrel_reloc (unsigned int reloc_type)
10019{
10020 switch (elf_header.e_machine)
10021 {
10022 case EM_ALPHA:
aa137e4d 10023 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 10024 case EM_IA_64:
aa137e4d 10025 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 10026 case EM_PARISC:
aa137e4d 10027 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 10028 case EM_PPC64:
aa137e4d 10029 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
10030 case EM_SPARC32PLUS:
10031 case EM_SPARCV9:
10032 case EM_SPARC:
aa137e4d 10033 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 10034 case EM_X86_64:
8a9036a4 10035 case EM_L1OM:
7a9068fe 10036 case EM_K1OM:
aa137e4d 10037 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
10038 case EM_S390_OLD:
10039 case EM_S390:
aa137e4d
NC
10040 return reloc_type == 23; /* R_S390_PC64. */
10041 case EM_TILEGX:
10042 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
10043 default:
10044 return FALSE;
10045 }
10046}
10047
4dc3c23d
AM
10048/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10049 a 24-bit absolute RELA relocation used in DWARF debug sections. */
10050
10051static bfd_boolean
10052is_24bit_abs_reloc (unsigned int reloc_type)
10053{
10054 switch (elf_header.e_machine)
10055 {
10056 case EM_CYGNUS_MN10200:
10057 case EM_MN10200:
10058 return reloc_type == 4; /* R_MN10200_24. */
10059 default:
10060 return FALSE;
10061 }
10062}
10063
aca88567
NC
10064/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
10065 a 16-bit absolute RELA relocation used in DWARF debug sections. */
10066
10067static bfd_boolean
10068is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
10069{
10070 switch (elf_header.e_machine)
10071 {
aca88567
NC
10072 case EM_AVR_OLD:
10073 case EM_AVR:
10074 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
10075 case EM_ADAPTEVA_EPIPHANY:
10076 return reloc_type == 5;
41e92641
NC
10077 case EM_CYGNUS_D10V:
10078 case EM_D10V:
10079 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
10080 case EM_H8S:
10081 case EM_H8_300:
10082 case EM_H8_300H:
aca88567
NC
10083 return reloc_type == R_H8_DIR16;
10084 case EM_IP2K_OLD:
10085 case EM_IP2K:
10086 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 10087 case EM_M32C_OLD:
f4236fe4
DD
10088 case EM_M32C:
10089 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
10090 case EM_MSP430_OLD:
10091 case EM_MSP430:
10092 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
10093 case EM_ALTERA_NIOS2:
10094 case EM_NIOS32:
10095 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
10096 case EM_TI_C6000:
10097 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
10098 case EM_XC16X:
10099 case EM_C166:
10100 return reloc_type == 2; /* R_XC16C_ABS_16. */
0a22ae8e
NC
10101 case EM_CYGNUS_MN10300:
10102 case EM_MN10300:
10103 return reloc_type == 2; /* R_MN10300_16. */
f6c1a2d5
NC
10104 case EM_XGATE:
10105 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 10106 default:
aca88567 10107 return FALSE;
4b78141a
NC
10108 }
10109}
10110
2a7b2e88
JK
10111/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
10112 relocation entries (possibly formerly used for SHT_GROUP sections). */
10113
10114static bfd_boolean
10115is_none_reloc (unsigned int reloc_type)
10116{
10117 switch (elf_header.e_machine)
10118 {
cb8f3167
NC
10119 case EM_68K: /* R_68K_NONE. */
10120 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
10121 case EM_SPARC32PLUS:
10122 case EM_SPARCV9:
cb8f3167
NC
10123 case EM_SPARC: /* R_SPARC_NONE. */
10124 case EM_MIPS: /* R_MIPS_NONE. */
10125 case EM_PARISC: /* R_PARISC_NONE. */
10126 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 10127 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
10128 case EM_PPC: /* R_PPC_NONE. */
10129 case EM_PPC64: /* R_PPC64_NONE. */
10130 case EM_ARM: /* R_ARM_NONE. */
10131 case EM_IA_64: /* R_IA64_NONE. */
10132 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10133 case EM_S390_OLD:
cb8f3167
NC
10134 case EM_S390: /* R_390_NONE. */
10135 case EM_CRIS: /* R_CRIS_NONE. */
10136 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10137 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10138 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10139 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10140 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10141 case EM_M32R: /* R_M32R_NONE. */
40b36596 10142 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10143 case EM_TILEGX: /* R_TILEGX_NONE. */
10144 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10145 case EM_XC16X:
10146 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 10147 return reloc_type == 0;
58332dda
JK
10148 case EM_XTENSA_OLD:
10149 case EM_XTENSA:
4dc3c23d
AM
10150 return (reloc_type == 0 /* R_XTENSA_NONE. */
10151 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10152 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10153 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
10154 }
10155 return FALSE;
10156}
10157
cf13d699
NC
10158/* Apply relocations to a section.
10159 Note: So far support has been added only for those relocations
10160 which can be found in debug sections.
10161 FIXME: Add support for more relocations ? */
1b315056 10162
cf13d699
NC
10163static void
10164apply_relocations (void * file,
10165 Elf_Internal_Shdr * section,
10166 unsigned char * start)
1b315056 10167{
cf13d699
NC
10168 Elf_Internal_Shdr * relsec;
10169 unsigned char * end = start + section->sh_size;
cb8f3167 10170
cf13d699
NC
10171 if (elf_header.e_type != ET_REL)
10172 return;
1b315056 10173
cf13d699 10174 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10175 for (relsec = section_headers;
10176 relsec < section_headers + elf_header.e_shnum;
10177 ++relsec)
252b5132 10178 {
41e92641
NC
10179 bfd_boolean is_rela;
10180 unsigned long num_relocs;
2cf0635d
NC
10181 Elf_Internal_Rela * relocs;
10182 Elf_Internal_Rela * rp;
10183 Elf_Internal_Shdr * symsec;
10184 Elf_Internal_Sym * symtab;
ba5cdace 10185 unsigned long num_syms;
2cf0635d 10186 Elf_Internal_Sym * sym;
252b5132 10187
41e92641 10188 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10189 || relsec->sh_info >= elf_header.e_shnum
10190 || section_headers + relsec->sh_info != section
c256ffe7 10191 || relsec->sh_size == 0
4fbb74a6 10192 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10193 continue;
428409d5 10194
41e92641
NC
10195 is_rela = relsec->sh_type == SHT_RELA;
10196
10197 if (is_rela)
10198 {
3f5e193b
NC
10199 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10200 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10201 return;
10202 }
10203 else
10204 {
3f5e193b
NC
10205 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10206 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10207 return;
10208 }
10209
10210 /* SH uses RELA but uses in place value instead of the addend field. */
10211 if (elf_header.e_machine == EM_SH)
10212 is_rela = FALSE;
428409d5 10213
4fbb74a6 10214 symsec = section_headers + relsec->sh_link;
ba5cdace 10215 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 10216
41e92641 10217 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10218 {
41e92641
NC
10219 bfd_vma addend;
10220 unsigned int reloc_type;
10221 unsigned int reloc_size;
91d6fa6a 10222 unsigned char * rloc;
ba5cdace 10223 unsigned long sym_index;
4b78141a 10224
aca88567 10225 reloc_type = get_reloc_type (rp->r_info);
41e92641 10226
98fb390a 10227 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10228 continue;
98fb390a
NC
10229 else if (is_none_reloc (reloc_type))
10230 continue;
10231 else if (is_32bit_abs_reloc (reloc_type)
10232 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10233 reloc_size = 4;
85acf597
RH
10234 else if (is_64bit_abs_reloc (reloc_type)
10235 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10236 reloc_size = 8;
4dc3c23d
AM
10237 else if (is_24bit_abs_reloc (reloc_type))
10238 reloc_size = 3;
aca88567
NC
10239 else if (is_16bit_abs_reloc (reloc_type))
10240 reloc_size = 2;
10241 else
4b78141a 10242 {
41e92641 10243 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10244 reloc_type, SECTION_NAME (section));
4b78141a
NC
10245 continue;
10246 }
103f02d3 10247
91d6fa6a
NC
10248 rloc = start + rp->r_offset;
10249 if ((rloc + reloc_size) > end)
700dd8b7
L
10250 {
10251 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10252 (unsigned long) rp->r_offset,
10253 SECTION_NAME (section));
10254 continue;
10255 }
103f02d3 10256
ba5cdace
NC
10257 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
10258 if (sym_index >= num_syms)
10259 {
10260 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
10261 sym_index, SECTION_NAME (section));
10262 continue;
10263 }
10264 sym = symtab + sym_index;
41e92641
NC
10265
10266 /* If the reloc has a symbol associated with it,
55f25fc3
L
10267 make sure that it is of an appropriate type.
10268
10269 Relocations against symbols without type can happen.
10270 Gcc -feliminate-dwarf2-dups may generate symbols
10271 without type for debug info.
10272
10273 Icc generates relocations against function symbols
10274 instead of local labels.
10275
10276 Relocations against object symbols can happen, eg when
10277 referencing a global array. For an example of this see
10278 the _clz.o binary in libgcc.a. */
aca88567 10279 if (sym != symtab
55f25fc3 10280 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10281 {
41e92641 10282 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10283 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10284 (long int)(rp - relocs),
41e92641 10285 SECTION_NAME (relsec));
aca88567 10286 continue;
5b18a4bc 10287 }
252b5132 10288
4dc3c23d
AM
10289 addend = 0;
10290 if (is_rela)
10291 addend += rp->r_addend;
c47320c3
AM
10292 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10293 partial_inplace. */
4dc3c23d
AM
10294 if (!is_rela
10295 || (elf_header.e_machine == EM_XTENSA
10296 && reloc_type == 1)
10297 || ((elf_header.e_machine == EM_PJ
10298 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10299 && reloc_type == 1)
10300 || ((elf_header.e_machine == EM_D30V
10301 || elf_header.e_machine == EM_CYGNUS_D30V)
10302 && reloc_type == 12))
91d6fa6a 10303 addend += byte_get (rloc, reloc_size);
cb8f3167 10304
85acf597
RH
10305 if (is_32bit_pcrel_reloc (reloc_type)
10306 || is_64bit_pcrel_reloc (reloc_type))
10307 {
10308 /* On HPPA, all pc-relative relocations are biased by 8. */
10309 if (elf_header.e_machine == EM_PARISC)
10310 addend -= 8;
91d6fa6a 10311 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10312 reloc_size);
10313 }
41e92641 10314 else
91d6fa6a 10315 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10316 }
252b5132 10317
5b18a4bc 10318 free (symtab);
41e92641 10319 free (relocs);
5b18a4bc
NC
10320 break;
10321 }
5b18a4bc 10322}
103f02d3 10323
cf13d699
NC
10324#ifdef SUPPORT_DISASSEMBLY
10325static int
10326disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10327{
10328 printf (_("\nAssembly dump of section %s\n"),
10329 SECTION_NAME (section));
10330
10331 /* XXX -- to be done --- XXX */
10332
10333 return 1;
10334}
10335#endif
10336
10337/* Reads in the contents of SECTION from FILE, returning a pointer
10338 to a malloc'ed buffer or NULL if something went wrong. */
10339
10340static char *
10341get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10342{
10343 bfd_size_type num_bytes;
10344
10345 num_bytes = section->sh_size;
10346
10347 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10348 {
10349 printf (_("\nSection '%s' has no data to dump.\n"),
10350 SECTION_NAME (section));
10351 return NULL;
10352 }
10353
3f5e193b
NC
10354 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10355 _("section contents"));
cf13d699
NC
10356}
10357
dd24e3da 10358
cf13d699
NC
10359static void
10360dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10361{
10362 Elf_Internal_Shdr * relsec;
10363 bfd_size_type num_bytes;
cf13d699
NC
10364 char * data;
10365 char * end;
10366 char * start;
10367 char * name = SECTION_NAME (section);
10368 bfd_boolean some_strings_shown;
10369
10370 start = get_section_contents (section, file);
10371 if (start == NULL)
10372 return;
10373
10374 printf (_("\nString dump of section '%s':\n"), name);
10375
10376 /* If the section being dumped has relocations against it the user might
10377 be expecting these relocations to have been applied. Check for this
10378 case and issue a warning message in order to avoid confusion.
10379 FIXME: Maybe we ought to have an option that dumps a section with
10380 relocs applied ? */
10381 for (relsec = section_headers;
10382 relsec < section_headers + elf_header.e_shnum;
10383 ++relsec)
10384 {
10385 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10386 || relsec->sh_info >= elf_header.e_shnum
10387 || section_headers + relsec->sh_info != section
10388 || relsec->sh_size == 0
10389 || relsec->sh_link >= elf_header.e_shnum)
10390 continue;
10391
10392 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10393 break;
10394 }
10395
10396 num_bytes = section->sh_size;
cf13d699
NC
10397 data = start;
10398 end = start + num_bytes;
10399 some_strings_shown = FALSE;
10400
10401 while (data < end)
10402 {
10403 while (!ISPRINT (* data))
10404 if (++ data >= end)
10405 break;
10406
10407 if (data < end)
10408 {
10409#ifndef __MSVCRT__
c975cc98
NC
10410 /* PR 11128: Use two separate invocations in order to work
10411 around bugs in the Solaris 8 implementation of printf. */
10412 printf (" [%6tx] ", data - start);
10413 printf ("%s\n", data);
cf13d699
NC
10414#else
10415 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10416#endif
10417 data += strlen (data);
10418 some_strings_shown = TRUE;
10419 }
10420 }
10421
10422 if (! some_strings_shown)
10423 printf (_(" No strings found in this section."));
10424
10425 free (start);
10426
10427 putchar ('\n');
10428}
10429
10430static void
10431dump_section_as_bytes (Elf_Internal_Shdr * section,
10432 FILE * file,
10433 bfd_boolean relocate)
10434{
10435 Elf_Internal_Shdr * relsec;
10436 bfd_size_type bytes;
10437 bfd_vma addr;
10438 unsigned char * data;
10439 unsigned char * start;
10440
10441 start = (unsigned char *) get_section_contents (section, file);
10442 if (start == NULL)
10443 return;
10444
10445 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10446
10447 if (relocate)
10448 {
10449 apply_relocations (file, section, start);
10450 }
10451 else
10452 {
10453 /* If the section being dumped has relocations against it the user might
10454 be expecting these relocations to have been applied. Check for this
10455 case and issue a warning message in order to avoid confusion.
10456 FIXME: Maybe we ought to have an option that dumps a section with
10457 relocs applied ? */
10458 for (relsec = section_headers;
10459 relsec < section_headers + elf_header.e_shnum;
10460 ++relsec)
10461 {
10462 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10463 || relsec->sh_info >= elf_header.e_shnum
10464 || section_headers + relsec->sh_info != section
10465 || relsec->sh_size == 0
10466 || relsec->sh_link >= elf_header.e_shnum)
10467 continue;
10468
10469 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10470 break;
10471 }
10472 }
10473
10474 addr = section->sh_addr;
10475 bytes = section->sh_size;
10476 data = start;
10477
10478 while (bytes)
10479 {
10480 int j;
10481 int k;
10482 int lbytes;
10483
10484 lbytes = (bytes > 16 ? 16 : bytes);
10485
10486 printf (" 0x%8.8lx ", (unsigned long) addr);
10487
10488 for (j = 0; j < 16; j++)
10489 {
10490 if (j < lbytes)
10491 printf ("%2.2x", data[j]);
10492 else
10493 printf (" ");
10494
10495 if ((j & 3) == 3)
10496 printf (" ");
10497 }
10498
10499 for (j = 0; j < lbytes; j++)
10500 {
10501 k = data[j];
10502 if (k >= ' ' && k < 0x7f)
10503 printf ("%c", k);
10504 else
10505 printf (".");
10506 }
10507
10508 putchar ('\n');
10509
10510 data += lbytes;
10511 addr += lbytes;
10512 bytes -= lbytes;
10513 }
10514
10515 free (start);
10516
10517 putchar ('\n');
10518}
10519
4a114e3e 10520/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10521
10522static int
d3dbc530
AM
10523uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10524 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10525{
10526#ifndef HAVE_ZLIB_H
cf13d699
NC
10527 return FALSE;
10528#else
10529 dwarf_size_type compressed_size = *size;
10530 unsigned char * compressed_buffer = *buffer;
10531 dwarf_size_type uncompressed_size;
10532 unsigned char * uncompressed_buffer;
10533 z_stream strm;
10534 int rc;
10535 dwarf_size_type header_size = 12;
10536
10537 /* Read the zlib header. In this case, it should be "ZLIB" followed
10538 by the uncompressed section size, 8 bytes in big-endian order. */
10539 if (compressed_size < header_size
10540 || ! streq ((char *) compressed_buffer, "ZLIB"))
10541 return 0;
10542
10543 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10544 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10545 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10546 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10547 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10548 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10549 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10550 uncompressed_size += compressed_buffer[11];
10551
10552 /* It is possible the section consists of several compressed
10553 buffers concatenated together, so we uncompress in a loop. */
10554 strm.zalloc = NULL;
10555 strm.zfree = NULL;
10556 strm.opaque = NULL;
10557 strm.avail_in = compressed_size - header_size;
10558 strm.next_in = (Bytef *) compressed_buffer + header_size;
10559 strm.avail_out = uncompressed_size;
3f5e193b 10560 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10561
10562 rc = inflateInit (& strm);
10563 while (strm.avail_in > 0)
10564 {
10565 if (rc != Z_OK)
10566 goto fail;
10567 strm.next_out = ((Bytef *) uncompressed_buffer
10568 + (uncompressed_size - strm.avail_out));
10569 rc = inflate (&strm, Z_FINISH);
10570 if (rc != Z_STREAM_END)
10571 goto fail;
10572 rc = inflateReset (& strm);
10573 }
10574 rc = inflateEnd (& strm);
10575 if (rc != Z_OK
10576 || strm.avail_out != 0)
10577 goto fail;
10578
10579 free (compressed_buffer);
10580 *buffer = uncompressed_buffer;
10581 *size = uncompressed_size;
10582 return 1;
10583
10584 fail:
10585 free (uncompressed_buffer);
4a114e3e
L
10586 /* Indicate decompression failure. */
10587 *buffer = NULL;
cf13d699
NC
10588 return 0;
10589#endif /* HAVE_ZLIB_H */
10590}
10591
d966045b
DJ
10592static int
10593load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10594 Elf_Internal_Shdr * sec, void * file)
1007acb3 10595{
2cf0635d 10596 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10597 char buf [64];
1007acb3 10598
19e6b90e
L
10599 /* If it is already loaded, do nothing. */
10600 if (section->start != NULL)
10601 return 1;
1007acb3 10602
19e6b90e
L
10603 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10604 section->address = sec->sh_addr;
3f5e193b
NC
10605 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10606 sec->sh_offset, 1,
10607 sec->sh_size, buf);
59245841
NC
10608 if (section->start == NULL)
10609 section->size = 0;
10610 else
10611 {
10612 section->size = sec->sh_size;
10613 if (uncompress_section_contents (&section->start, &section->size))
10614 sec->sh_size = section->size;
10615 }
4a114e3e 10616
1b315056
CS
10617 if (section->start == NULL)
10618 return 0;
10619
19e6b90e 10620 if (debug_displays [debug].relocate)
3f5e193b 10621 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10622
1b315056 10623 return 1;
1007acb3
L
10624}
10625
d966045b 10626int
2cf0635d 10627load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10628{
2cf0635d
NC
10629 struct dwarf_section * section = &debug_displays [debug].section;
10630 Elf_Internal_Shdr * sec;
d966045b
DJ
10631
10632 /* Locate the debug section. */
10633 sec = find_section (section->uncompressed_name);
10634 if (sec != NULL)
10635 section->name = section->uncompressed_name;
10636 else
10637 {
10638 sec = find_section (section->compressed_name);
10639 if (sec != NULL)
10640 section->name = section->compressed_name;
10641 }
10642 if (sec == NULL)
10643 return 0;
10644
3f5e193b 10645 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10646}
10647
19e6b90e
L
10648void
10649free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10650{
2cf0635d 10651 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10652
19e6b90e
L
10653 if (section->start == NULL)
10654 return;
1007acb3 10655
19e6b90e
L
10656 free ((char *) section->start);
10657 section->start = NULL;
10658 section->address = 0;
10659 section->size = 0;
1007acb3
L
10660}
10661
1007acb3 10662static int
2cf0635d 10663display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 10664{
2cf0635d 10665 char * name = SECTION_NAME (section);
19e6b90e
L
10666 bfd_size_type length;
10667 int result = 1;
3f5e193b 10668 int i;
1007acb3 10669
19e6b90e
L
10670 length = section->sh_size;
10671 if (length == 0)
1007acb3 10672 {
19e6b90e
L
10673 printf (_("\nSection '%s' has no debugging data.\n"), name);
10674 return 0;
1007acb3 10675 }
5dff79d8
NC
10676 if (section->sh_type == SHT_NOBITS)
10677 {
10678 /* There is no point in dumping the contents of a debugging section
10679 which has the NOBITS type - the bits in the file will be random.
10680 This can happen when a file containing a .eh_frame section is
10681 stripped with the --only-keep-debug command line option. */
10682 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10683 return 0;
10684 }
1007acb3 10685
0112cd26 10686 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10687 name = ".debug_info";
1007acb3 10688
19e6b90e
L
10689 /* See if we know how to display the contents of this section. */
10690 for (i = 0; i < max; i++)
1b315056
CS
10691 if (streq (debug_displays[i].section.uncompressed_name, name)
10692 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10693 {
2cf0635d 10694 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10695 int secondary = (section != find_section (name));
10696
10697 if (secondary)
3f5e193b 10698 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10699
2b6f5997 10700 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10701 sec->name = sec->uncompressed_name;
10702 else
10703 sec->name = sec->compressed_name;
3f5e193b
NC
10704 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10705 section, file))
19e6b90e
L
10706 {
10707 result &= debug_displays[i].display (sec, file);
1007acb3 10708
d966045b 10709 if (secondary || (i != info && i != abbrev))
3f5e193b 10710 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10711 }
1007acb3 10712
19e6b90e
L
10713 break;
10714 }
1007acb3 10715
19e6b90e 10716 if (i == max)
1007acb3 10717 {
19e6b90e
L
10718 printf (_("Unrecognized debug section: %s\n"), name);
10719 result = 0;
1007acb3
L
10720 }
10721
19e6b90e 10722 return result;
5b18a4bc 10723}
103f02d3 10724
aef1f6d0
DJ
10725/* Set DUMP_SECTS for all sections where dumps were requested
10726 based on section name. */
10727
10728static void
10729initialise_dumps_byname (void)
10730{
2cf0635d 10731 struct dump_list_entry * cur;
aef1f6d0
DJ
10732
10733 for (cur = dump_sects_byname; cur; cur = cur->next)
10734 {
10735 unsigned int i;
10736 int any;
10737
10738 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10739 if (streq (SECTION_NAME (section_headers + i), cur->name))
10740 {
09c11c86 10741 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10742 any = 1;
10743 }
10744
10745 if (!any)
10746 warn (_("Section '%s' was not dumped because it does not exist!\n"),
10747 cur->name);
10748 }
10749}
10750
5b18a4bc 10751static void
2cf0635d 10752process_section_contents (FILE * file)
5b18a4bc 10753{
2cf0635d 10754 Elf_Internal_Shdr * section;
19e6b90e 10755 unsigned int i;
103f02d3 10756
19e6b90e
L
10757 if (! do_dump)
10758 return;
103f02d3 10759
aef1f6d0
DJ
10760 initialise_dumps_byname ();
10761
19e6b90e
L
10762 for (i = 0, section = section_headers;
10763 i < elf_header.e_shnum && i < num_dump_sects;
10764 i++, section++)
10765 {
10766#ifdef SUPPORT_DISASSEMBLY
10767 if (dump_sects[i] & DISASS_DUMP)
10768 disassemble_section (section, file);
10769#endif
10770 if (dump_sects[i] & HEX_DUMP)
cf13d699 10771 dump_section_as_bytes (section, file, FALSE);
103f02d3 10772
cf13d699
NC
10773 if (dump_sects[i] & RELOC_DUMP)
10774 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
10775
10776 if (dump_sects[i] & STRING_DUMP)
10777 dump_section_as_strings (section, file);
cf13d699
NC
10778
10779 if (dump_sects[i] & DEBUG_DUMP)
10780 display_debug_section (section, file);
5b18a4bc 10781 }
103f02d3 10782
19e6b90e
L
10783 /* Check to see if the user requested a
10784 dump of a section that does not exist. */
10785 while (i++ < num_dump_sects)
10786 if (dump_sects[i])
10787 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 10788}
103f02d3 10789
5b18a4bc 10790static void
19e6b90e 10791process_mips_fpe_exception (int mask)
5b18a4bc 10792{
19e6b90e
L
10793 if (mask)
10794 {
10795 int first = 1;
10796 if (mask & OEX_FPU_INEX)
10797 fputs ("INEX", stdout), first = 0;
10798 if (mask & OEX_FPU_UFLO)
10799 printf ("%sUFLO", first ? "" : "|"), first = 0;
10800 if (mask & OEX_FPU_OFLO)
10801 printf ("%sOFLO", first ? "" : "|"), first = 0;
10802 if (mask & OEX_FPU_DIV0)
10803 printf ("%sDIV0", first ? "" : "|"), first = 0;
10804 if (mask & OEX_FPU_INVAL)
10805 printf ("%sINVAL", first ? "" : "|");
10806 }
5b18a4bc 10807 else
19e6b90e 10808 fputs ("0", stdout);
5b18a4bc 10809}
103f02d3 10810
11c1ff18
PB
10811/* ARM EABI attributes section. */
10812typedef struct
10813{
10814 int tag;
2cf0635d 10815 const char * name;
11c1ff18
PB
10816 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
10817 int type;
2cf0635d 10818 const char ** table;
11c1ff18
PB
10819} arm_attr_public_tag;
10820
2cf0635d 10821static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 10822 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
9e3c6df6 10823 "v6K", "v7", "v6-M", "v6S-M", "v7E-M"};
2cf0635d
NC
10824static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
10825static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 10826 {"No", "Thumb-1", "Thumb-2"};
75375b3e 10827static const char * arm_attr_tag_FP_arch[] =
62f3b8c8 10828 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
2cf0635d 10829static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 10830static const char * arm_attr_tag_Advanced_SIMD_arch[] =
cd21e546 10831 {"No", "NEONv1", "NEONv1 with Fused-MAC"};
2cf0635d 10832static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
10833 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
10834 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 10835static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 10836 {"V6", "SB", "TLS", "Unused"};
2cf0635d 10837static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 10838 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 10839static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 10840 {"Absolute", "PC-relative", "None"};
2cf0635d 10841static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 10842 {"None", "direct", "GOT-indirect"};
2cf0635d 10843static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 10844 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
10845static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
10846static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 10847 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
10848static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
10849static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
10850static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 10851 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 10852static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 10853 {"Unused", "small", "int", "forced to int"};
2cf0635d 10854static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 10855 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 10856static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 10857 {"AAPCS", "VFP registers", "custom"};
2cf0635d 10858static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 10859 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 10860static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
10861 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10862 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 10863static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
10864 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10865 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 10866static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 10867static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 10868 {"Not Allowed", "Allowed"};
2cf0635d 10869static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 10870 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 10871static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
10872 {"Not Allowed", "Allowed"};
10873static const char * arm_attr_tag_DIV_use[] =
dd24e3da 10874 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 10875 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
10876static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
10877static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 10878 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 10879 "TrustZone and Virtualization Extensions"};
dd24e3da 10880static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 10881 {"Not Allowed", "Allowed"};
11c1ff18
PB
10882
10883#define LOOKUP(id, name) \
10884 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 10885static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
10886{
10887 {4, "CPU_raw_name", 1, NULL},
10888 {5, "CPU_name", 1, NULL},
10889 LOOKUP(6, CPU_arch),
10890 {7, "CPU_arch_profile", 0, NULL},
10891 LOOKUP(8, ARM_ISA_use),
10892 LOOKUP(9, THUMB_ISA_use),
75375b3e 10893 LOOKUP(10, FP_arch),
11c1ff18 10894 LOOKUP(11, WMMX_arch),
f5f53991
AS
10895 LOOKUP(12, Advanced_SIMD_arch),
10896 LOOKUP(13, PCS_config),
11c1ff18
PB
10897 LOOKUP(14, ABI_PCS_R9_use),
10898 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 10899 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
10900 LOOKUP(17, ABI_PCS_GOT_use),
10901 LOOKUP(18, ABI_PCS_wchar_t),
10902 LOOKUP(19, ABI_FP_rounding),
10903 LOOKUP(20, ABI_FP_denormal),
10904 LOOKUP(21, ABI_FP_exceptions),
10905 LOOKUP(22, ABI_FP_user_exceptions),
10906 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
10907 {24, "ABI_align_needed", 0, NULL},
10908 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
10909 LOOKUP(26, ABI_enum_size),
10910 LOOKUP(27, ABI_HardFP_use),
10911 LOOKUP(28, ABI_VFP_args),
10912 LOOKUP(29, ABI_WMMX_args),
10913 LOOKUP(30, ABI_optimization_goals),
10914 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 10915 {32, "compatibility", 0, NULL},
f5f53991 10916 LOOKUP(34, CPU_unaligned_access),
75375b3e 10917 LOOKUP(36, FP_HP_extension),
8e79c3df 10918 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
10919 LOOKUP(42, MPextension_use),
10920 LOOKUP(44, DIV_use),
f5f53991
AS
10921 {64, "nodefaults", 0, NULL},
10922 {65, "also_compatible_with", 0, NULL},
10923 LOOKUP(66, T2EE_use),
10924 {67, "conformance", 1, NULL},
10925 LOOKUP(68, Virtualization_use),
cd21e546 10926 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
10927};
10928#undef LOOKUP
10929
11c1ff18 10930static unsigned char *
2cf0635d 10931display_arm_attribute (unsigned char * p)
11c1ff18
PB
10932{
10933 int tag;
10934 unsigned int len;
10935 int val;
2cf0635d 10936 arm_attr_public_tag * attr;
11c1ff18
PB
10937 unsigned i;
10938 int type;
10939
10940 tag = read_uleb128 (p, &len);
10941 p += len;
10942 attr = NULL;
2cf0635d 10943 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
10944 {
10945 if (arm_attr_public_tags[i].tag == tag)
10946 {
10947 attr = &arm_attr_public_tags[i];
10948 break;
10949 }
10950 }
10951
10952 if (attr)
10953 {
10954 printf (" Tag_%s: ", attr->name);
10955 switch (attr->type)
10956 {
10957 case 0:
10958 switch (tag)
10959 {
10960 case 7: /* Tag_CPU_arch_profile. */
10961 val = read_uleb128 (p, &len);
10962 p += len;
10963 switch (val)
10964 {
2b692964
NC
10965 case 0: printf (_("None\n")); break;
10966 case 'A': printf (_("Application\n")); break;
10967 case 'R': printf (_("Realtime\n")); break;
10968 case 'M': printf (_("Microcontroller\n")); break;
10969 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
10970 default: printf ("??? (%d)\n", val); break;
10971 }
10972 break;
10973
75375b3e
MGD
10974 case 24: /* Tag_align_needed. */
10975 val = read_uleb128 (p, &len);
10976 p += len;
10977 switch (val)
10978 {
2b692964
NC
10979 case 0: printf (_("None\n")); break;
10980 case 1: printf (_("8-byte\n")); break;
10981 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
10982 case 3: printf ("??? 3\n"); break;
10983 default:
10984 if (val <= 12)
dd24e3da 10985 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10986 1 << val);
10987 else
10988 printf ("??? (%d)\n", val);
10989 break;
10990 }
10991 break;
10992
10993 case 25: /* Tag_align_preserved. */
10994 val = read_uleb128 (p, &len);
10995 p += len;
10996 switch (val)
10997 {
2b692964
NC
10998 case 0: printf (_("None\n")); break;
10999 case 1: printf (_("8-byte, except leaf SP\n")); break;
11000 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
11001 case 3: printf ("??? 3\n"); break;
11002 default:
11003 if (val <= 12)
dd24e3da 11004 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
11005 1 << val);
11006 else
11007 printf ("??? (%d)\n", val);
11008 break;
11009 }
11010 break;
11011
11c1ff18
PB
11012 case 32: /* Tag_compatibility. */
11013 val = read_uleb128 (p, &len);
11014 p += len;
2b692964 11015 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 11016 p += strlen ((char *) p) + 1;
11c1ff18
PB
11017 break;
11018
f5f53991
AS
11019 case 64: /* Tag_nodefaults. */
11020 p++;
2b692964 11021 printf (_("True\n"));
f5f53991
AS
11022 break;
11023
11024 case 65: /* Tag_also_compatible_with. */
11025 val = read_uleb128 (p, &len);
11026 p += len;
11027 if (val == 6 /* Tag_CPU_arch. */)
11028 {
11029 val = read_uleb128 (p, &len);
11030 p += len;
2cf0635d 11031 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
11032 printf ("??? (%d)\n", val);
11033 else
11034 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
11035 }
11036 else
11037 printf ("???\n");
11038 while (*(p++) != '\0' /* NUL terminator. */);
11039 break;
11040
11c1ff18 11041 default:
2cf0635d 11042 abort ();
11c1ff18
PB
11043 }
11044 return p;
11045
11046 case 1:
11047 case 2:
11048 type = attr->type;
11049 break;
11050
11051 default:
11052 assert (attr->type & 0x80);
11053 val = read_uleb128 (p, &len);
11054 p += len;
11055 type = attr->type & 0x7f;
11056 if (val >= type)
11057 printf ("??? (%d)\n", val);
11058 else
11059 printf ("%s\n", attr->table[val]);
11060 return p;
11061 }
11062 }
11063 else
11064 {
11065 if (tag & 1)
11066 type = 1; /* String. */
11067 else
11068 type = 2; /* uleb128. */
11069 printf (" Tag_unknown_%d: ", tag);
11070 }
11071
11072 if (type == 1)
11073 {
11074 printf ("\"%s\"\n", p);
2cf0635d 11075 p += strlen ((char *) p) + 1;
11c1ff18
PB
11076 }
11077 else
11078 {
11079 val = read_uleb128 (p, &len);
11080 p += len;
11081 printf ("%d (0x%x)\n", val, val);
11082 }
11083
11084 return p;
11085}
11086
104d59d1 11087static unsigned char *
60bca95a
NC
11088display_gnu_attribute (unsigned char * p,
11089 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
11090{
11091 int tag;
11092 unsigned int len;
11093 int val;
11094 int type;
11095
11096 tag = read_uleb128 (p, &len);
11097 p += len;
11098
11099 /* Tag_compatibility is the only generic GNU attribute defined at
11100 present. */
11101 if (tag == 32)
11102 {
11103 val = read_uleb128 (p, &len);
11104 p += len;
2b692964 11105 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 11106 p += strlen ((char *) p) + 1;
104d59d1
JM
11107 return p;
11108 }
11109
11110 if ((tag & 2) == 0 && display_proc_gnu_attribute)
11111 return display_proc_gnu_attribute (p, tag);
11112
11113 if (tag & 1)
11114 type = 1; /* String. */
11115 else
11116 type = 2; /* uleb128. */
11117 printf (" Tag_unknown_%d: ", tag);
11118
11119 if (type == 1)
11120 {
11121 printf ("\"%s\"\n", p);
60bca95a 11122 p += strlen ((char *) p) + 1;
104d59d1
JM
11123 }
11124 else
11125 {
11126 val = read_uleb128 (p, &len);
11127 p += len;
11128 printf ("%d (0x%x)\n", val, val);
11129 }
11130
11131 return p;
11132}
11133
34c8bcba 11134static unsigned char *
2cf0635d 11135display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
11136{
11137 int type;
11138 unsigned int len;
11139 int val;
11140
11141 if (tag == Tag_GNU_Power_ABI_FP)
11142 {
11143 val = read_uleb128 (p, &len);
11144 p += len;
11145 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11146
34c8bcba
JM
11147 switch (val)
11148 {
11149 case 0:
2b692964 11150 printf (_("Hard or soft float\n"));
34c8bcba
JM
11151 break;
11152 case 1:
2b692964 11153 printf (_("Hard float\n"));
34c8bcba
JM
11154 break;
11155 case 2:
2b692964 11156 printf (_("Soft float\n"));
34c8bcba 11157 break;
3c7b9897 11158 case 3:
2b692964 11159 printf (_("Single-precision hard float\n"));
3c7b9897 11160 break;
34c8bcba
JM
11161 default:
11162 printf ("??? (%d)\n", val);
11163 break;
11164 }
11165 return p;
11166 }
11167
c6e65352
DJ
11168 if (tag == Tag_GNU_Power_ABI_Vector)
11169 {
11170 val = read_uleb128 (p, &len);
11171 p += len;
11172 printf (" Tag_GNU_Power_ABI_Vector: ");
11173 switch (val)
11174 {
11175 case 0:
2b692964 11176 printf (_("Any\n"));
c6e65352
DJ
11177 break;
11178 case 1:
2b692964 11179 printf (_("Generic\n"));
c6e65352
DJ
11180 break;
11181 case 2:
11182 printf ("AltiVec\n");
11183 break;
11184 case 3:
11185 printf ("SPE\n");
11186 break;
11187 default:
11188 printf ("??? (%d)\n", val);
11189 break;
11190 }
11191 return p;
11192 }
11193
f82e0623
NF
11194 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11195 {
11196 val = read_uleb128 (p, &len);
11197 p += len;
11198 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11199 switch (val)
11200 {
11201 case 0:
2b692964 11202 printf (_("Any\n"));
f82e0623
NF
11203 break;
11204 case 1:
11205 printf ("r3/r4\n");
11206 break;
11207 case 2:
2b692964 11208 printf (_("Memory\n"));
f82e0623
NF
11209 break;
11210 default:
11211 printf ("??? (%d)\n", val);
11212 break;
11213 }
11214 return p;
11215 }
11216
34c8bcba
JM
11217 if (tag & 1)
11218 type = 1; /* String. */
11219 else
11220 type = 2; /* uleb128. */
11221 printf (" Tag_unknown_%d: ", tag);
11222
11223 if (type == 1)
11224 {
11225 printf ("\"%s\"\n", p);
60bca95a 11226 p += strlen ((char *) p) + 1;
34c8bcba
JM
11227 }
11228 else
11229 {
11230 val = read_uleb128 (p, &len);
11231 p += len;
11232 printf ("%d (0x%x)\n", val, val);
11233 }
11234
11235 return p;
11236}
11237
9e8c70f9
DM
11238static void
11239display_sparc_hwcaps (int mask)
11240{
11241 if (mask)
11242 {
11243 int first = 1;
11244 if (mask & ELF_SPARC_HWCAP_MUL32)
11245 fputs ("mul32", stdout), first = 0;
11246 if (mask & ELF_SPARC_HWCAP_DIV32)
11247 printf ("%sdiv32", first ? "" : "|"), first = 0;
11248 if (mask & ELF_SPARC_HWCAP_FSMULD)
11249 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11250 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11251 printf ("%sv8plus", first ? "" : "|"), first = 0;
11252 if (mask & ELF_SPARC_HWCAP_POPC)
11253 printf ("%spopc", first ? "" : "|"), first = 0;
11254 if (mask & ELF_SPARC_HWCAP_VIS)
11255 printf ("%svis", first ? "" : "|"), first = 0;
11256 if (mask & ELF_SPARC_HWCAP_VIS2)
11257 printf ("%svis2", first ? "" : "|"), first = 0;
11258 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11259 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11260 if (mask & ELF_SPARC_HWCAP_FMAF)
11261 printf ("%sfmaf", first ? "" : "|"), first = 0;
11262 if (mask & ELF_SPARC_HWCAP_VIS3)
11263 printf ("%svis3", first ? "" : "|"), first = 0;
11264 if (mask & ELF_SPARC_HWCAP_HPC)
11265 printf ("%shpc", first ? "" : "|"), first = 0;
11266 if (mask & ELF_SPARC_HWCAP_RANDOM)
11267 printf ("%srandom", first ? "" : "|"), first = 0;
11268 if (mask & ELF_SPARC_HWCAP_TRANS)
11269 printf ("%strans", first ? "" : "|"), first = 0;
11270 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11271 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11272 if (mask & ELF_SPARC_HWCAP_IMA)
11273 printf ("%sima", first ? "" : "|"), first = 0;
11274 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11275 printf ("%scspare", first ? "" : "|"), first = 0;
11276 }
11277 else
11278 fputc('0', stdout);
11279 fputc('\n', stdout);
11280}
11281
11282static unsigned char *
11283display_sparc_gnu_attribute (unsigned char * p, int tag)
11284{
11285 int type;
11286 unsigned int len;
11287 int val;
11288
11289 if (tag == Tag_GNU_Sparc_HWCAPS)
11290 {
11291 val = read_uleb128 (p, &len);
11292 p += len;
11293 printf (" Tag_GNU_Sparc_HWCAPS: ");
11294
11295 display_sparc_hwcaps (val);
11296 return p;
11297 }
11298
11299 if (tag & 1)
11300 type = 1; /* String. */
11301 else
11302 type = 2; /* uleb128. */
11303 printf (" Tag_unknown_%d: ", tag);
11304
11305 if (type == 1)
11306 {
11307 printf ("\"%s\"\n", p);
11308 p += strlen ((char *) p) + 1;
11309 }
11310 else
11311 {
11312 val = read_uleb128 (p, &len);
11313 p += len;
11314 printf ("%d (0x%x)\n", val, val);
11315 }
11316
11317 return p;
11318}
11319
2cf19d5c 11320static unsigned char *
2cf0635d 11321display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
11322{
11323 int type;
11324 unsigned int len;
11325 int val;
11326
11327 if (tag == Tag_GNU_MIPS_ABI_FP)
11328 {
11329 val = read_uleb128 (p, &len);
11330 p += len;
11331 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11332
2cf19d5c
JM
11333 switch (val)
11334 {
11335 case 0:
2b692964 11336 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11337 break;
11338 case 1:
2b692964 11339 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11340 break;
11341 case 2:
2b692964 11342 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11343 break;
11344 case 3:
2b692964 11345 printf (_("Soft float\n"));
2cf19d5c 11346 break;
42554f6a 11347 case 4:
9eeefea8 11348 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11349 break;
2cf19d5c
JM
11350 default:
11351 printf ("??? (%d)\n", val);
11352 break;
11353 }
11354 return p;
11355 }
11356
11357 if (tag & 1)
11358 type = 1; /* String. */
11359 else
11360 type = 2; /* uleb128. */
11361 printf (" Tag_unknown_%d: ", tag);
11362
11363 if (type == 1)
11364 {
11365 printf ("\"%s\"\n", p);
60bca95a 11366 p += strlen ((char *) p) + 1;
2cf19d5c
JM
11367 }
11368 else
11369 {
11370 val = read_uleb128 (p, &len);
11371 p += len;
11372 printf ("%d (0x%x)\n", val, val);
11373 }
11374
11375 return p;
11376}
11377
59e6276b
JM
11378static unsigned char *
11379display_tic6x_attribute (unsigned char * p)
11380{
11381 int tag;
11382 unsigned int len;
11383 int val;
11384
11385 tag = read_uleb128 (p, &len);
11386 p += len;
11387
11388 switch (tag)
11389 {
75fa6dc1 11390 case Tag_ISA:
59e6276b
JM
11391 val = read_uleb128 (p, &len);
11392 p += len;
75fa6dc1 11393 printf (" Tag_ISA: ");
59e6276b
JM
11394
11395 switch (val)
11396 {
75fa6dc1 11397 case C6XABI_Tag_ISA_none:
59e6276b
JM
11398 printf (_("None\n"));
11399 break;
75fa6dc1 11400 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11401 printf ("C62x\n");
11402 break;
75fa6dc1 11403 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11404 printf ("C67x\n");
11405 break;
75fa6dc1 11406 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11407 printf ("C67x+\n");
11408 break;
75fa6dc1 11409 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11410 printf ("C64x\n");
11411 break;
75fa6dc1 11412 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11413 printf ("C64x+\n");
11414 break;
75fa6dc1 11415 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11416 printf ("C674x\n");
11417 break;
11418 default:
11419 printf ("??? (%d)\n", val);
11420 break;
11421 }
11422 return p;
11423
87779176
JM
11424 case Tag_ABI_wchar_t:
11425 val = read_uleb128 (p, &len);
11426 p += len;
11427 printf (" Tag_ABI_wchar_t: ");
11428 switch (val)
11429 {
11430 case 0:
11431 printf (_("Not used\n"));
11432 break;
11433 case 1:
11434 printf (_("2 bytes\n"));
11435 break;
11436 case 2:
11437 printf (_("4 bytes\n"));
11438 break;
11439 default:
11440 printf ("??? (%d)\n", val);
11441 break;
11442 }
11443 return p;
11444
11445 case Tag_ABI_stack_align_needed:
11446 val = read_uleb128 (p, &len);
11447 p += len;
11448 printf (" Tag_ABI_stack_align_needed: ");
11449 switch (val)
11450 {
11451 case 0:
11452 printf (_("8-byte\n"));
11453 break;
11454 case 1:
11455 printf (_("16-byte\n"));
11456 break;
11457 default:
11458 printf ("??? (%d)\n", val);
11459 break;
11460 }
11461 return p;
11462
11463 case Tag_ABI_stack_align_preserved:
11464 val = read_uleb128 (p, &len);
11465 p += len;
11466 printf (" Tag_ABI_stack_align_preserved: ");
11467 switch (val)
11468 {
11469 case 0:
11470 printf (_("8-byte\n"));
11471 break;
11472 case 1:
11473 printf (_("16-byte\n"));
11474 break;
11475 default:
11476 printf ("??? (%d)\n", val);
11477 break;
11478 }
11479 return p;
11480
b5593623
JM
11481 case Tag_ABI_DSBT:
11482 val = read_uleb128 (p, &len);
11483 p += len;
11484 printf (" Tag_ABI_DSBT: ");
11485 switch (val)
11486 {
11487 case 0:
11488 printf (_("DSBT addressing not used\n"));
11489 break;
11490 case 1:
11491 printf (_("DSBT addressing used\n"));
11492 break;
11493 default:
11494 printf ("??? (%d)\n", val);
11495 break;
11496 }
11497 return p;
11498
87779176
JM
11499 case Tag_ABI_PID:
11500 val = read_uleb128 (p, &len);
11501 p += len;
11502 printf (" Tag_ABI_PID: ");
11503 switch (val)
11504 {
11505 case 0:
11506 printf (_("Data addressing position-dependent\n"));
11507 break;
11508 case 1:
11509 printf (_("Data addressing position-independent, GOT near DP\n"));
11510 break;
11511 case 2:
11512 printf (_("Data addressing position-independent, GOT far from DP\n"));
11513 break;
11514 default:
11515 printf ("??? (%d)\n", val);
11516 break;
11517 }
11518 return p;
11519
11520 case Tag_ABI_PIC:
11521 val = read_uleb128 (p, &len);
11522 p += len;
11523 printf (" Tag_ABI_PIC: ");
11524 switch (val)
11525 {
11526 case 0:
11527 printf (_("Code addressing position-dependent\n"));
11528 break;
11529 case 1:
11530 printf (_("Code addressing position-independent\n"));
11531 break;
11532 default:
11533 printf ("??? (%d)\n", val);
11534 break;
11535 }
11536 return p;
11537
11538 case Tag_ABI_array_object_alignment:
11539 val = read_uleb128 (p, &len);
11540 p += len;
11541 printf (" Tag_ABI_array_object_alignment: ");
11542 switch (val)
11543 {
11544 case 0:
11545 printf (_("8-byte\n"));
11546 break;
11547 case 1:
11548 printf (_("4-byte\n"));
11549 break;
11550 case 2:
11551 printf (_("16-byte\n"));
11552 break;
11553 default:
11554 printf ("??? (%d)\n", val);
11555 break;
11556 }
11557 return p;
11558
11559 case Tag_ABI_array_object_align_expected:
11560 val = read_uleb128 (p, &len);
11561 p += len;
11562 printf (" Tag_ABI_array_object_align_expected: ");
11563 switch (val)
11564 {
11565 case 0:
11566 printf (_("8-byte\n"));
11567 break;
11568 case 1:
11569 printf (_("4-byte\n"));
11570 break;
11571 case 2:
11572 printf (_("16-byte\n"));
11573 break;
11574 default:
11575 printf ("??? (%d)\n", val);
11576 break;
11577 }
11578 return p;
11579
3cbd1c06 11580 case Tag_ABI_compatibility:
59e6276b
JM
11581 val = read_uleb128 (p, &len);
11582 p += len;
3cbd1c06 11583 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11584 printf (_("flag = %d, vendor = %s\n"), val, p);
11585 p += strlen ((char *) p) + 1;
11586 return p;
87779176
JM
11587
11588 case Tag_ABI_conformance:
11589 printf (" Tag_ABI_conformance: ");
11590 printf ("\"%s\"\n", p);
11591 p += strlen ((char *) p) + 1;
11592 return p;
59e6276b
JM
11593 }
11594
11595 printf (" Tag_unknown_%d: ", tag);
11596
87779176
JM
11597 if (tag & 1)
11598 {
11599 printf ("\"%s\"\n", p);
11600 p += strlen ((char *) p) + 1;
11601 }
11602 else
11603 {
11604 val = read_uleb128 (p, &len);
11605 p += len;
11606 printf ("%d (0x%x)\n", val, val);
11607 }
59e6276b
JM
11608
11609 return p;
11610}
11611
11c1ff18 11612static int
60bca95a
NC
11613process_attributes (FILE * file,
11614 const char * public_name,
104d59d1 11615 unsigned int proc_type,
60bca95a
NC
11616 unsigned char * (* display_pub_attribute) (unsigned char *),
11617 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11618{
2cf0635d
NC
11619 Elf_Internal_Shdr * sect;
11620 unsigned char * contents;
11621 unsigned char * p;
11622 unsigned char * end;
11c1ff18
PB
11623 bfd_vma section_len;
11624 bfd_vma len;
11625 unsigned i;
11626
11627 /* Find the section header so that we get the size. */
11628 for (i = 0, sect = section_headers;
11629 i < elf_header.e_shnum;
11630 i++, sect++)
11631 {
104d59d1 11632 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11633 continue;
11634
3f5e193b
NC
11635 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11636 sect->sh_size, _("attributes"));
60bca95a 11637 if (contents == NULL)
11c1ff18 11638 continue;
60bca95a 11639
11c1ff18
PB
11640 p = contents;
11641 if (*p == 'A')
11642 {
11643 len = sect->sh_size - 1;
11644 p++;
60bca95a 11645
11c1ff18
PB
11646 while (len > 0)
11647 {
11648 int namelen;
11649 bfd_boolean public_section;
104d59d1 11650 bfd_boolean gnu_section;
11c1ff18
PB
11651
11652 section_len = byte_get (p, 4);
11653 p += 4;
60bca95a 11654
11c1ff18
PB
11655 if (section_len > len)
11656 {
11657 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11658 (int) section_len, (int) len);
11c1ff18
PB
11659 section_len = len;
11660 }
60bca95a 11661
11c1ff18 11662 len -= section_len;
2b692964 11663 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11664
11665 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11666 public_section = TRUE;
11667 else
11668 public_section = FALSE;
60bca95a
NC
11669
11670 if (streq ((char *) p, "gnu"))
104d59d1
JM
11671 gnu_section = TRUE;
11672 else
11673 gnu_section = FALSE;
60bca95a
NC
11674
11675 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11676 p += namelen;
11677 section_len -= namelen + 4;
60bca95a 11678
11c1ff18
PB
11679 while (section_len > 0)
11680 {
11681 int tag = *(p++);
11682 int val;
11683 bfd_vma size;
60bca95a 11684
11c1ff18
PB
11685 size = byte_get (p, 4);
11686 if (size > section_len)
11687 {
11688 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11689 (int) size, (int) section_len);
11c1ff18
PB
11690 size = section_len;
11691 }
60bca95a 11692
11c1ff18
PB
11693 section_len -= size;
11694 end = p + size - 1;
11695 p += 4;
60bca95a 11696
11c1ff18
PB
11697 switch (tag)
11698 {
11699 case 1:
2b692964 11700 printf (_("File Attributes\n"));
11c1ff18
PB
11701 break;
11702 case 2:
2b692964 11703 printf (_("Section Attributes:"));
11c1ff18
PB
11704 goto do_numlist;
11705 case 3:
2b692964 11706 printf (_("Symbol Attributes:"));
11c1ff18
PB
11707 do_numlist:
11708 for (;;)
11709 {
91d6fa6a 11710 unsigned int j;
60bca95a 11711
91d6fa6a
NC
11712 val = read_uleb128 (p, &j);
11713 p += j;
11c1ff18
PB
11714 if (val == 0)
11715 break;
11716 printf (" %d", val);
11717 }
11718 printf ("\n");
11719 break;
11720 default:
2b692964 11721 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
11722 public_section = FALSE;
11723 break;
11724 }
60bca95a 11725
11c1ff18
PB
11726 if (public_section)
11727 {
11728 while (p < end)
104d59d1
JM
11729 p = display_pub_attribute (p);
11730 }
11731 else if (gnu_section)
11732 {
11733 while (p < end)
11734 p = display_gnu_attribute (p,
11735 display_proc_gnu_attribute);
11c1ff18
PB
11736 }
11737 else
11738 {
11739 /* ??? Do something sensible, like dump hex. */
2b692964 11740 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
11741 p = end;
11742 }
11743 }
11744 }
11745 }
11746 else
60bca95a 11747 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 11748
60bca95a 11749 free (contents);
11c1ff18
PB
11750 }
11751 return 1;
11752}
11753
104d59d1 11754static int
2cf0635d 11755process_arm_specific (FILE * file)
104d59d1
JM
11756{
11757 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
11758 display_arm_attribute, NULL);
11759}
11760
34c8bcba 11761static int
2cf0635d 11762process_power_specific (FILE * file)
34c8bcba
JM
11763{
11764 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11765 display_power_gnu_attribute);
11766}
11767
9e8c70f9
DM
11768static int
11769process_sparc_specific (FILE * file)
11770{
11771 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11772 display_sparc_gnu_attribute);
11773}
11774
59e6276b
JM
11775static int
11776process_tic6x_specific (FILE * file)
11777{
11778 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
11779 display_tic6x_attribute, NULL);
11780}
11781
ccb4c951
RS
11782/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
11783 Print the Address, Access and Initial fields of an entry at VMA ADDR
11784 and return the VMA of the next entry. */
11785
11786static bfd_vma
2cf0635d 11787print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
11788{
11789 printf (" ");
11790 print_vma (addr, LONG_HEX);
11791 printf (" ");
11792 if (addr < pltgot + 0xfff0)
11793 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
11794 else
11795 printf ("%10s", "");
11796 printf (" ");
11797 if (data == NULL)
2b692964 11798 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
11799 else
11800 {
11801 bfd_vma entry;
11802
11803 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11804 print_vma (entry, LONG_HEX);
11805 }
11806 return addr + (is_32bit_elf ? 4 : 8);
11807}
11808
861fb55a
DJ
11809/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
11810 PLTGOT. Print the Address and Initial fields of an entry at VMA
11811 ADDR and return the VMA of the next entry. */
11812
11813static bfd_vma
2cf0635d 11814print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
11815{
11816 printf (" ");
11817 print_vma (addr, LONG_HEX);
11818 printf (" ");
11819 if (data == NULL)
2b692964 11820 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
11821 else
11822 {
11823 bfd_vma entry;
11824
11825 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11826 print_vma (entry, LONG_HEX);
11827 }
11828 return addr + (is_32bit_elf ? 4 : 8);
11829}
11830
19e6b90e 11831static int
2cf0635d 11832process_mips_specific (FILE * file)
5b18a4bc 11833{
2cf0635d 11834 Elf_Internal_Dyn * entry;
19e6b90e
L
11835 size_t liblist_offset = 0;
11836 size_t liblistno = 0;
11837 size_t conflictsno = 0;
11838 size_t options_offset = 0;
11839 size_t conflicts_offset = 0;
861fb55a
DJ
11840 size_t pltrelsz = 0;
11841 size_t pltrel = 0;
ccb4c951 11842 bfd_vma pltgot = 0;
861fb55a
DJ
11843 bfd_vma mips_pltgot = 0;
11844 bfd_vma jmprel = 0;
ccb4c951
RS
11845 bfd_vma local_gotno = 0;
11846 bfd_vma gotsym = 0;
11847 bfd_vma symtabno = 0;
103f02d3 11848
2cf19d5c
JM
11849 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11850 display_mips_gnu_attribute);
11851
19e6b90e
L
11852 /* We have a lot of special sections. Thanks SGI! */
11853 if (dynamic_section == NULL)
11854 /* No information available. */
11855 return 0;
252b5132 11856
b2d38a17 11857 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
11858 switch (entry->d_tag)
11859 {
11860 case DT_MIPS_LIBLIST:
d93f0186
NC
11861 liblist_offset
11862 = offset_from_vma (file, entry->d_un.d_val,
11863 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
11864 break;
11865 case DT_MIPS_LIBLISTNO:
11866 liblistno = entry->d_un.d_val;
11867 break;
11868 case DT_MIPS_OPTIONS:
d93f0186 11869 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
11870 break;
11871 case DT_MIPS_CONFLICT:
d93f0186
NC
11872 conflicts_offset
11873 = offset_from_vma (file, entry->d_un.d_val,
11874 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
11875 break;
11876 case DT_MIPS_CONFLICTNO:
11877 conflictsno = entry->d_un.d_val;
11878 break;
ccb4c951 11879 case DT_PLTGOT:
861fb55a
DJ
11880 pltgot = entry->d_un.d_ptr;
11881 break;
ccb4c951
RS
11882 case DT_MIPS_LOCAL_GOTNO:
11883 local_gotno = entry->d_un.d_val;
11884 break;
11885 case DT_MIPS_GOTSYM:
11886 gotsym = entry->d_un.d_val;
11887 break;
11888 case DT_MIPS_SYMTABNO:
11889 symtabno = entry->d_un.d_val;
11890 break;
861fb55a
DJ
11891 case DT_MIPS_PLTGOT:
11892 mips_pltgot = entry->d_un.d_ptr;
11893 break;
11894 case DT_PLTREL:
11895 pltrel = entry->d_un.d_val;
11896 break;
11897 case DT_PLTRELSZ:
11898 pltrelsz = entry->d_un.d_val;
11899 break;
11900 case DT_JMPREL:
11901 jmprel = entry->d_un.d_ptr;
11902 break;
252b5132
RH
11903 default:
11904 break;
11905 }
11906
11907 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
11908 {
2cf0635d 11909 Elf32_External_Lib * elib;
252b5132
RH
11910 size_t cnt;
11911
3f5e193b
NC
11912 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
11913 liblistno,
11914 sizeof (Elf32_External_Lib),
9cf03b7e 11915 _("liblist section data"));
a6e9f9df 11916 if (elib)
252b5132 11917 {
2b692964 11918 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 11919 (unsigned long) liblistno);
2b692964 11920 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
11921 stdout);
11922
11923 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 11924 {
a6e9f9df 11925 Elf32_Lib liblist;
91d6fa6a 11926 time_t atime;
a6e9f9df 11927 char timebuf[20];
2cf0635d 11928 struct tm * tmp;
a6e9f9df
AM
11929
11930 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 11931 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
11932 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11933 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11934 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11935
91d6fa6a 11936 tmp = gmtime (&atime);
e9e44622
JJ
11937 snprintf (timebuf, sizeof (timebuf),
11938 "%04u-%02u-%02uT%02u:%02u:%02u",
11939 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11940 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 11941
31104126 11942 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
11943 if (VALID_DYNAMIC_NAME (liblist.l_name))
11944 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
11945 else
2b692964 11946 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
11947 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
11948 liblist.l_version);
a6e9f9df
AM
11949
11950 if (liblist.l_flags == 0)
2b692964 11951 puts (_(" NONE"));
a6e9f9df
AM
11952 else
11953 {
11954 static const struct
252b5132 11955 {
2cf0635d 11956 const char * name;
a6e9f9df 11957 int bit;
252b5132 11958 }
a6e9f9df
AM
11959 l_flags_vals[] =
11960 {
11961 { " EXACT_MATCH", LL_EXACT_MATCH },
11962 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
11963 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
11964 { " EXPORTS", LL_EXPORTS },
11965 { " DELAY_LOAD", LL_DELAY_LOAD },
11966 { " DELTA", LL_DELTA }
11967 };
11968 int flags = liblist.l_flags;
11969 size_t fcnt;
11970
60bca95a 11971 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
11972 if ((flags & l_flags_vals[fcnt].bit) != 0)
11973 {
11974 fputs (l_flags_vals[fcnt].name, stdout);
11975 flags ^= l_flags_vals[fcnt].bit;
11976 }
11977 if (flags != 0)
11978 printf (" %#x", (unsigned int) flags);
252b5132 11979
a6e9f9df
AM
11980 puts ("");
11981 }
252b5132 11982 }
252b5132 11983
a6e9f9df
AM
11984 free (elib);
11985 }
252b5132
RH
11986 }
11987
11988 if (options_offset != 0)
11989 {
2cf0635d
NC
11990 Elf_External_Options * eopt;
11991 Elf_Internal_Shdr * sect = section_headers;
11992 Elf_Internal_Options * iopt;
11993 Elf_Internal_Options * option;
252b5132
RH
11994 size_t offset;
11995 int cnt;
11996
11997 /* Find the section header so that we get the size. */
11998 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 11999 ++sect;
252b5132 12000
3f5e193b
NC
12001 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
12002 sect->sh_size, _("options"));
a6e9f9df 12003 if (eopt)
252b5132 12004 {
3f5e193b
NC
12005 iopt = (Elf_Internal_Options *)
12006 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
12007 if (iopt == NULL)
12008 {
591a748a 12009 error (_("Out of memory\n"));
a6e9f9df
AM
12010 return 0;
12011 }
76da6bbe 12012
a6e9f9df
AM
12013 offset = cnt = 0;
12014 option = iopt;
252b5132 12015
a6e9f9df
AM
12016 while (offset < sect->sh_size)
12017 {
2cf0635d 12018 Elf_External_Options * eoption;
252b5132 12019
a6e9f9df 12020 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 12021
a6e9f9df
AM
12022 option->kind = BYTE_GET (eoption->kind);
12023 option->size = BYTE_GET (eoption->size);
12024 option->section = BYTE_GET (eoption->section);
12025 option->info = BYTE_GET (eoption->info);
76da6bbe 12026
a6e9f9df 12027 offset += option->size;
252b5132 12028
a6e9f9df
AM
12029 ++option;
12030 ++cnt;
12031 }
252b5132 12032
a6e9f9df
AM
12033 printf (_("\nSection '%s' contains %d entries:\n"),
12034 SECTION_NAME (sect), cnt);
76da6bbe 12035
a6e9f9df 12036 option = iopt;
252b5132 12037
a6e9f9df 12038 while (cnt-- > 0)
252b5132 12039 {
a6e9f9df
AM
12040 size_t len;
12041
12042 switch (option->kind)
252b5132 12043 {
a6e9f9df
AM
12044 case ODK_NULL:
12045 /* This shouldn't happen. */
12046 printf (" NULL %d %lx", option->section, option->info);
12047 break;
12048 case ODK_REGINFO:
12049 printf (" REGINFO ");
12050 if (elf_header.e_machine == EM_MIPS)
12051 {
12052 /* 32bit form. */
2cf0635d 12053 Elf32_External_RegInfo * ereg;
b34976b6 12054 Elf32_RegInfo reginfo;
a6e9f9df
AM
12055
12056 ereg = (Elf32_External_RegInfo *) (option + 1);
12057 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12058 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12059 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12060 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12061 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
12062 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
12063
12064 printf ("GPR %08lx GP 0x%lx\n",
12065 reginfo.ri_gprmask,
12066 (unsigned long) reginfo.ri_gp_value);
12067 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12068 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12069 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12070 }
12071 else
12072 {
12073 /* 64 bit form. */
2cf0635d 12074 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
12075 Elf64_Internal_RegInfo reginfo;
12076
12077 ereg = (Elf64_External_RegInfo *) (option + 1);
12078 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
12079 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
12080 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
12081 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
12082 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 12083 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
12084
12085 printf ("GPR %08lx GP 0x",
12086 reginfo.ri_gprmask);
12087 printf_vma (reginfo.ri_gp_value);
12088 printf ("\n");
12089
12090 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
12091 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
12092 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
12093 }
12094 ++option;
12095 continue;
12096 case ODK_EXCEPTIONS:
12097 fputs (" EXCEPTIONS fpe_min(", stdout);
12098 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
12099 fputs (") fpe_max(", stdout);
12100 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
12101 fputs (")", stdout);
12102
12103 if (option->info & OEX_PAGE0)
12104 fputs (" PAGE0", stdout);
12105 if (option->info & OEX_SMM)
12106 fputs (" SMM", stdout);
12107 if (option->info & OEX_FPDBUG)
12108 fputs (" FPDBUG", stdout);
12109 if (option->info & OEX_DISMISS)
12110 fputs (" DISMISS", stdout);
12111 break;
12112 case ODK_PAD:
12113 fputs (" PAD ", stdout);
12114 if (option->info & OPAD_PREFIX)
12115 fputs (" PREFIX", stdout);
12116 if (option->info & OPAD_POSTFIX)
12117 fputs (" POSTFIX", stdout);
12118 if (option->info & OPAD_SYMBOL)
12119 fputs (" SYMBOL", stdout);
12120 break;
12121 case ODK_HWPATCH:
12122 fputs (" HWPATCH ", stdout);
12123 if (option->info & OHW_R4KEOP)
12124 fputs (" R4KEOP", stdout);
12125 if (option->info & OHW_R8KPFETCH)
12126 fputs (" R8KPFETCH", stdout);
12127 if (option->info & OHW_R5KEOP)
12128 fputs (" R5KEOP", stdout);
12129 if (option->info & OHW_R5KCVTL)
12130 fputs (" R5KCVTL", stdout);
12131 break;
12132 case ODK_FILL:
12133 fputs (" FILL ", stdout);
12134 /* XXX Print content of info word? */
12135 break;
12136 case ODK_TAGS:
12137 fputs (" TAGS ", stdout);
12138 /* XXX Print content of info word? */
12139 break;
12140 case ODK_HWAND:
12141 fputs (" HWAND ", stdout);
12142 if (option->info & OHWA0_R4KEOP_CHECKED)
12143 fputs (" R4KEOP_CHECKED", stdout);
12144 if (option->info & OHWA0_R4KEOP_CLEAN)
12145 fputs (" R4KEOP_CLEAN", stdout);
12146 break;
12147 case ODK_HWOR:
12148 fputs (" HWOR ", stdout);
12149 if (option->info & OHWA0_R4KEOP_CHECKED)
12150 fputs (" R4KEOP_CHECKED", stdout);
12151 if (option->info & OHWA0_R4KEOP_CLEAN)
12152 fputs (" R4KEOP_CLEAN", stdout);
12153 break;
12154 case ODK_GP_GROUP:
12155 printf (" GP_GROUP %#06lx self-contained %#06lx",
12156 option->info & OGP_GROUP,
12157 (option->info & OGP_SELF) >> 16);
12158 break;
12159 case ODK_IDENT:
12160 printf (" IDENT %#06lx self-contained %#06lx",
12161 option->info & OGP_GROUP,
12162 (option->info & OGP_SELF) >> 16);
12163 break;
12164 default:
12165 /* This shouldn't happen. */
12166 printf (" %3d ??? %d %lx",
12167 option->kind, option->section, option->info);
12168 break;
252b5132 12169 }
a6e9f9df 12170
2cf0635d 12171 len = sizeof (* eopt);
a6e9f9df
AM
12172 while (len < option->size)
12173 if (((char *) option)[len] >= ' '
12174 && ((char *) option)[len] < 0x7f)
12175 printf ("%c", ((char *) option)[len++]);
12176 else
12177 printf ("\\%03o", ((char *) option)[len++]);
12178
12179 fputs ("\n", stdout);
252b5132 12180 ++option;
252b5132
RH
12181 }
12182
a6e9f9df 12183 free (eopt);
252b5132 12184 }
252b5132
RH
12185 }
12186
12187 if (conflicts_offset != 0 && conflictsno != 0)
12188 {
2cf0635d 12189 Elf32_Conflict * iconf;
252b5132
RH
12190 size_t cnt;
12191
12192 if (dynamic_symbols == NULL)
12193 {
591a748a 12194 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12195 return 0;
12196 }
12197
3f5e193b 12198 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12199 if (iconf == NULL)
12200 {
591a748a 12201 error (_("Out of memory\n"));
252b5132
RH
12202 return 0;
12203 }
12204
9ea033b2 12205 if (is_32bit_elf)
252b5132 12206 {
2cf0635d 12207 Elf32_External_Conflict * econf32;
a6e9f9df 12208
3f5e193b
NC
12209 econf32 = (Elf32_External_Conflict *)
12210 get_data (NULL, file, conflicts_offset, conflictsno,
12211 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12212 if (!econf32)
12213 return 0;
252b5132
RH
12214
12215 for (cnt = 0; cnt < conflictsno; ++cnt)
12216 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12217
12218 free (econf32);
252b5132
RH
12219 }
12220 else
12221 {
2cf0635d 12222 Elf64_External_Conflict * econf64;
a6e9f9df 12223
3f5e193b
NC
12224 econf64 = (Elf64_External_Conflict *)
12225 get_data (NULL, file, conflicts_offset, conflictsno,
12226 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12227 if (!econf64)
12228 return 0;
252b5132
RH
12229
12230 for (cnt = 0; cnt < conflictsno; ++cnt)
12231 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12232
12233 free (econf64);
252b5132
RH
12234 }
12235
c7e7ca54
NC
12236 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12237 (unsigned long) conflictsno);
252b5132
RH
12238 puts (_(" Num: Index Value Name"));
12239
12240 for (cnt = 0; cnt < conflictsno; ++cnt)
12241 {
2cf0635d 12242 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12243
b34976b6 12244 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12245 print_vma (psym->st_value, FULL_HEX);
31104126 12246 putchar (' ');
d79b3d50
NC
12247 if (VALID_DYNAMIC_NAME (psym->st_name))
12248 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12249 else
2b692964 12250 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12251 putchar ('\n');
252b5132
RH
12252 }
12253
252b5132
RH
12254 free (iconf);
12255 }
12256
ccb4c951
RS
12257 if (pltgot != 0 && local_gotno != 0)
12258 {
91d6fa6a 12259 bfd_vma ent, local_end, global_end;
bbeee7ea 12260 size_t i, offset;
2cf0635d 12261 unsigned char * data;
bbeee7ea 12262 int addr_size;
ccb4c951 12263
91d6fa6a 12264 ent = pltgot;
ccb4c951
RS
12265 addr_size = (is_32bit_elf ? 4 : 8);
12266 local_end = pltgot + local_gotno * addr_size;
12267 global_end = local_end + (symtabno - gotsym) * addr_size;
12268
12269 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 12270 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
12271 global_end - pltgot, 1,
12272 _("Global Offset Table data"));
59245841
NC
12273 if (data == NULL)
12274 return 0;
12275
ccb4c951
RS
12276 printf (_("\nPrimary GOT:\n"));
12277 printf (_(" Canonical gp value: "));
12278 print_vma (pltgot + 0x7ff0, LONG_HEX);
12279 printf ("\n\n");
12280
12281 printf (_(" Reserved entries:\n"));
12282 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12283 addr_size * 2, _("Address"), _("Access"),
12284 addr_size * 2, _("Initial"));
91d6fa6a 12285 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12286 printf (_(" Lazy resolver\n"));
ccb4c951 12287 if (data
91d6fa6a 12288 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12289 >> (addr_size * 8 - 1)) != 0)
12290 {
91d6fa6a 12291 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12292 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12293 }
12294 printf ("\n");
12295
91d6fa6a 12296 if (ent < local_end)
ccb4c951
RS
12297 {
12298 printf (_(" Local entries:\n"));
cc5914eb 12299 printf (" %*s %10s %*s\n",
2b692964
NC
12300 addr_size * 2, _("Address"), _("Access"),
12301 addr_size * 2, _("Initial"));
91d6fa6a 12302 while (ent < local_end)
ccb4c951 12303 {
91d6fa6a 12304 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12305 printf ("\n");
12306 }
12307 printf ("\n");
12308 }
12309
12310 if (gotsym < symtabno)
12311 {
12312 int sym_width;
12313
12314 printf (_(" Global entries:\n"));
cc5914eb 12315 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
12316 addr_size * 2, _("Address"),
12317 _("Access"),
2b692964 12318 addr_size * 2, _("Initial"),
9cf03b7e
NC
12319 addr_size * 2, _("Sym.Val."),
12320 _("Type"),
12321 /* Note for translators: "Ndx" = abbreviated form of "Index". */
12322 _("Ndx"), _("Name"));
12323
ccb4c951
RS
12324 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12325 for (i = gotsym; i < symtabno; i++)
12326 {
2cf0635d 12327 Elf_Internal_Sym * psym;
ccb4c951
RS
12328
12329 psym = dynamic_symbols + i;
91d6fa6a 12330 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12331 printf (" ");
12332 print_vma (psym->st_value, LONG_HEX);
12333 printf (" %-7s %3s ",
12334 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12335 get_symbol_index_type (psym->st_shndx));
12336 if (VALID_DYNAMIC_NAME (psym->st_name))
12337 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12338 else
2b692964 12339 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12340 printf ("\n");
12341 }
12342 printf ("\n");
12343 }
12344
12345 if (data)
12346 free (data);
12347 }
12348
861fb55a
DJ
12349 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12350 {
91d6fa6a 12351 bfd_vma ent, end;
861fb55a
DJ
12352 size_t offset, rel_offset;
12353 unsigned long count, i;
2cf0635d 12354 unsigned char * data;
861fb55a 12355 int addr_size, sym_width;
2cf0635d 12356 Elf_Internal_Rela * rels;
861fb55a
DJ
12357
12358 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12359 if (pltrel == DT_RELA)
12360 {
12361 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12362 return 0;
12363 }
12364 else
12365 {
12366 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12367 return 0;
12368 }
12369
91d6fa6a 12370 ent = mips_pltgot;
861fb55a
DJ
12371 addr_size = (is_32bit_elf ? 4 : 8);
12372 end = mips_pltgot + (2 + count) * addr_size;
12373
12374 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 12375 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 12376 1, _("Procedure Linkage Table data"));
59245841
NC
12377 if (data == NULL)
12378 return 0;
12379
9cf03b7e 12380 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
12381 printf (_(" Reserved entries:\n"));
12382 printf (_(" %*s %*s Purpose\n"),
2b692964 12383 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12384 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12385 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12386 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12387 printf (_(" Module pointer\n"));
861fb55a
DJ
12388 printf ("\n");
12389
12390 printf (_(" Entries:\n"));
cc5914eb 12391 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12392 addr_size * 2, _("Address"),
12393 addr_size * 2, _("Initial"),
12394 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12395 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12396 for (i = 0; i < count; i++)
12397 {
2cf0635d 12398 Elf_Internal_Sym * psym;
861fb55a
DJ
12399
12400 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12401 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12402 printf (" ");
12403 print_vma (psym->st_value, LONG_HEX);
12404 printf (" %-7s %3s ",
12405 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12406 get_symbol_index_type (psym->st_shndx));
12407 if (VALID_DYNAMIC_NAME (psym->st_name))
12408 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12409 else
2b692964 12410 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12411 printf ("\n");
12412 }
12413 printf ("\n");
12414
12415 if (data)
12416 free (data);
12417 free (rels);
12418 }
12419
252b5132
RH
12420 return 1;
12421}
12422
047b2264 12423static int
2cf0635d 12424process_gnu_liblist (FILE * file)
047b2264 12425{
2cf0635d
NC
12426 Elf_Internal_Shdr * section;
12427 Elf_Internal_Shdr * string_sec;
12428 Elf32_External_Lib * elib;
12429 char * strtab;
c256ffe7 12430 size_t strtab_size;
047b2264
JJ
12431 size_t cnt;
12432 unsigned i;
12433
12434 if (! do_arch)
12435 return 0;
12436
12437 for (i = 0, section = section_headers;
12438 i < elf_header.e_shnum;
b34976b6 12439 i++, section++)
047b2264
JJ
12440 {
12441 switch (section->sh_type)
12442 {
12443 case SHT_GNU_LIBLIST:
4fbb74a6 12444 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12445 break;
12446
3f5e193b
NC
12447 elib = (Elf32_External_Lib *)
12448 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 12449 _("liblist section data"));
047b2264
JJ
12450
12451 if (elib == NULL)
12452 break;
4fbb74a6 12453 string_sec = section_headers + section->sh_link;
047b2264 12454
3f5e193b
NC
12455 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12456 string_sec->sh_size,
12457 _("liblist string table"));
047b2264
JJ
12458 if (strtab == NULL
12459 || section->sh_entsize != sizeof (Elf32_External_Lib))
12460 {
12461 free (elib);
2842702f 12462 free (strtab);
047b2264
JJ
12463 break;
12464 }
59245841 12465 strtab_size = string_sec->sh_size;
047b2264
JJ
12466
12467 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12468 SECTION_NAME (section),
0af1713e 12469 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12470
2b692964 12471 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12472
12473 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12474 ++cnt)
12475 {
12476 Elf32_Lib liblist;
91d6fa6a 12477 time_t atime;
047b2264 12478 char timebuf[20];
2cf0635d 12479 struct tm * tmp;
047b2264
JJ
12480
12481 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12482 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12483 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12484 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12485 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12486
91d6fa6a 12487 tmp = gmtime (&atime);
e9e44622
JJ
12488 snprintf (timebuf, sizeof (timebuf),
12489 "%04u-%02u-%02uT%02u:%02u:%02u",
12490 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12491 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12492
12493 printf ("%3lu: ", (unsigned long) cnt);
12494 if (do_wide)
c256ffe7 12495 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12496 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12497 else
c256ffe7 12498 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12499 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12500 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12501 liblist.l_version, liblist.l_flags);
12502 }
12503
12504 free (elib);
2842702f 12505 free (strtab);
047b2264
JJ
12506 }
12507 }
12508
12509 return 1;
12510}
12511
9437c45b 12512static const char *
d3ba0551 12513get_note_type (unsigned e_type)
779fe533
NC
12514{
12515 static char buff[64];
103f02d3 12516
1ec5cd37
NC
12517 if (elf_header.e_type == ET_CORE)
12518 switch (e_type)
12519 {
57346661 12520 case NT_AUXV:
1ec5cd37 12521 return _("NT_AUXV (auxiliary vector)");
57346661 12522 case NT_PRSTATUS:
1ec5cd37 12523 return _("NT_PRSTATUS (prstatus structure)");
57346661 12524 case NT_FPREGSET:
1ec5cd37 12525 return _("NT_FPREGSET (floating point registers)");
57346661 12526 case NT_PRPSINFO:
1ec5cd37 12527 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12528 case NT_TASKSTRUCT:
1ec5cd37 12529 return _("NT_TASKSTRUCT (task structure)");
57346661 12530 case NT_PRXFPREG:
1ec5cd37 12531 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12532 case NT_PPC_VMX:
12533 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12534 case NT_PPC_VSX:
12535 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
12536 case NT_X86_XSTATE:
12537 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12538 case NT_S390_HIGH_GPRS:
12539 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12540 case NT_S390_TIMER:
12541 return _("NT_S390_TIMER (s390 timer register)");
12542 case NT_S390_TODCMP:
12543 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12544 case NT_S390_TODPREG:
12545 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12546 case NT_S390_CTRS:
12547 return _("NT_S390_CTRS (s390 control registers)");
12548 case NT_S390_PREFIX:
12549 return _("NT_S390_PREFIX (s390 prefix register)");
faa9a424
UW
12550 case NT_ARM_VFP:
12551 return _("NT_ARM_VFP (arm VFP registers)");
57346661 12552 case NT_PSTATUS:
1ec5cd37 12553 return _("NT_PSTATUS (pstatus structure)");
57346661 12554 case NT_FPREGS:
1ec5cd37 12555 return _("NT_FPREGS (floating point registers)");
57346661 12556 case NT_PSINFO:
1ec5cd37 12557 return _("NT_PSINFO (psinfo structure)");
57346661 12558 case NT_LWPSTATUS:
1ec5cd37 12559 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12560 case NT_LWPSINFO:
1ec5cd37 12561 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12562 case NT_WIN32PSTATUS:
1ec5cd37
NC
12563 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
12564 default:
12565 break;
12566 }
12567 else
12568 switch (e_type)
12569 {
12570 case NT_VERSION:
12571 return _("NT_VERSION (version)");
12572 case NT_ARCH:
12573 return _("NT_ARCH (architecture)");
12574 default:
12575 break;
12576 }
12577
e9e44622 12578 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12579 return buff;
779fe533
NC
12580}
12581
1118d252
RM
12582static const char *
12583get_gnu_elf_note_type (unsigned e_type)
12584{
12585 static char buff[64];
12586
12587 switch (e_type)
12588 {
12589 case NT_GNU_ABI_TAG:
12590 return _("NT_GNU_ABI_TAG (ABI version tag)");
12591 case NT_GNU_HWCAP:
12592 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12593 case NT_GNU_BUILD_ID:
12594 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12595 case NT_GNU_GOLD_VERSION:
12596 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12597 default:
12598 break;
12599 }
12600
12601 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12602 return buff;
12603}
12604
664f90a3
TT
12605static int
12606print_gnu_note (Elf_Internal_Note *pnote)
12607{
12608 switch (pnote->type)
12609 {
12610 case NT_GNU_BUILD_ID:
12611 {
12612 unsigned long i;
12613
12614 printf (_(" Build ID: "));
12615 for (i = 0; i < pnote->descsz; ++i)
12616 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 12617 printf ("\n");
664f90a3
TT
12618 }
12619 break;
12620
12621 case NT_GNU_ABI_TAG:
12622 {
12623 unsigned long os, major, minor, subminor;
12624 const char *osname;
12625
12626 os = byte_get ((unsigned char *) pnote->descdata, 4);
12627 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
12628 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
12629 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
12630
12631 switch (os)
12632 {
12633 case GNU_ABI_TAG_LINUX:
12634 osname = "Linux";
12635 break;
12636 case GNU_ABI_TAG_HURD:
12637 osname = "Hurd";
12638 break;
12639 case GNU_ABI_TAG_SOLARIS:
12640 osname = "Solaris";
12641 break;
12642 case GNU_ABI_TAG_FREEBSD:
12643 osname = "FreeBSD";
12644 break;
12645 case GNU_ABI_TAG_NETBSD:
12646 osname = "NetBSD";
12647 break;
12648 default:
12649 osname = "Unknown";
12650 break;
12651 }
12652
12653 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
12654 major, minor, subminor);
12655 }
12656 break;
12657 }
12658
12659 return 1;
12660}
12661
9437c45b 12662static const char *
d3ba0551 12663get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
12664{
12665 static char buff[64];
12666
b4db1224 12667 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
12668 {
12669 /* NetBSD core "procinfo" structure. */
12670 return _("NetBSD procinfo structure");
12671 }
12672
12673 /* As of Jan 2002 there are no other machine-independent notes
12674 defined for NetBSD core files. If the note type is less
12675 than the start of the machine-dependent note types, we don't
12676 understand it. */
12677
b4db1224 12678 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 12679 {
e9e44622 12680 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
12681 return buff;
12682 }
12683
12684 switch (elf_header.e_machine)
12685 {
12686 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
12687 and PT_GETFPREGS == mach+2. */
12688
12689 case EM_OLD_ALPHA:
12690 case EM_ALPHA:
12691 case EM_SPARC:
12692 case EM_SPARC32PLUS:
12693 case EM_SPARCV9:
12694 switch (e_type)
12695 {
2b692964 12696 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 12697 return _("PT_GETREGS (reg structure)");
2b692964 12698 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 12699 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12700 default:
12701 break;
12702 }
12703 break;
12704
12705 /* On all other arch's, PT_GETREGS == mach+1 and
12706 PT_GETFPREGS == mach+3. */
12707 default:
12708 switch (e_type)
12709 {
2b692964 12710 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 12711 return _("PT_GETREGS (reg structure)");
2b692964 12712 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 12713 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12714 default:
12715 break;
12716 }
12717 }
12718
9cf03b7e 12719 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 12720 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
12721 return buff;
12722}
12723
70616151
TT
12724static const char *
12725get_stapsdt_note_type (unsigned e_type)
12726{
12727 static char buff[64];
12728
12729 switch (e_type)
12730 {
12731 case NT_STAPSDT:
12732 return _("NT_STAPSDT (SystemTap probe descriptors)");
12733
12734 default:
12735 break;
12736 }
12737
12738 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12739 return buff;
12740}
12741
c6a9fc58
TT
12742static int
12743print_stapsdt_note (Elf_Internal_Note *pnote)
12744{
12745 int addr_size = is_32bit_elf ? 4 : 8;
12746 char *data = pnote->descdata;
12747 char *data_end = pnote->descdata + pnote->descsz;
12748 bfd_vma pc, base_addr, semaphore;
12749 char *provider, *probe, *arg_fmt;
12750
12751 pc = byte_get ((unsigned char *) data, addr_size);
12752 data += addr_size;
12753 base_addr = byte_get ((unsigned char *) data, addr_size);
12754 data += addr_size;
12755 semaphore = byte_get ((unsigned char *) data, addr_size);
12756 data += addr_size;
12757
12758 provider = data;
12759 data += strlen (data) + 1;
12760 probe = data;
12761 data += strlen (data) + 1;
12762 arg_fmt = data;
12763 data += strlen (data) + 1;
12764
12765 printf (_(" Provider: %s\n"), provider);
12766 printf (_(" Name: %s\n"), probe);
12767 printf (_(" Location: "));
12768 print_vma (pc, FULL_HEX);
12769 printf (_(", Base: "));
12770 print_vma (base_addr, FULL_HEX);
12771 printf (_(", Semaphore: "));
12772 print_vma (semaphore, FULL_HEX);
9cf03b7e 12773 printf ("\n");
c6a9fc58
TT
12774 printf (_(" Arguments: %s\n"), arg_fmt);
12775
12776 return data == data_end;
12777}
12778
00e98fc7
TG
12779static const char *
12780get_ia64_vms_note_type (unsigned e_type)
12781{
12782 static char buff[64];
12783
12784 switch (e_type)
12785 {
12786 case NT_VMS_MHD:
12787 return _("NT_VMS_MHD (module header)");
12788 case NT_VMS_LNM:
12789 return _("NT_VMS_LNM (language name)");
12790 case NT_VMS_SRC:
12791 return _("NT_VMS_SRC (source files)");
12792 case NT_VMS_TITLE:
9cf03b7e 12793 return "NT_VMS_TITLE";
00e98fc7
TG
12794 case NT_VMS_EIDC:
12795 return _("NT_VMS_EIDC (consistency check)");
12796 case NT_VMS_FPMODE:
12797 return _("NT_VMS_FPMODE (FP mode)");
12798 case NT_VMS_LINKTIME:
9cf03b7e 12799 return "NT_VMS_LINKTIME";
00e98fc7
TG
12800 case NT_VMS_IMGNAM:
12801 return _("NT_VMS_IMGNAM (image name)");
12802 case NT_VMS_IMGID:
12803 return _("NT_VMS_IMGID (image id)");
12804 case NT_VMS_LINKID:
12805 return _("NT_VMS_LINKID (link id)");
12806 case NT_VMS_IMGBID:
12807 return _("NT_VMS_IMGBID (build id)");
12808 case NT_VMS_GSTNAM:
12809 return _("NT_VMS_GSTNAM (sym table name)");
12810 case NT_VMS_ORIG_DYN:
9cf03b7e 12811 return "NT_VMS_ORIG_DYN";
00e98fc7 12812 case NT_VMS_PATCHTIME:
9cf03b7e 12813 return "NT_VMS_PATCHTIME";
00e98fc7
TG
12814 default:
12815 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12816 return buff;
12817 }
12818}
12819
12820static int
12821print_ia64_vms_note (Elf_Internal_Note * pnote)
12822{
12823 switch (pnote->type)
12824 {
12825 case NT_VMS_MHD:
12826 if (pnote->descsz > 36)
12827 {
12828 size_t l = strlen (pnote->descdata + 34);
12829 printf (_(" Creation date : %.17s\n"), pnote->descdata);
12830 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
12831 printf (_(" Module name : %s\n"), pnote->descdata + 34);
12832 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
12833 }
12834 else
12835 printf (_(" Invalid size\n"));
12836 break;
12837 case NT_VMS_LNM:
12838 printf (_(" Language: %s\n"), pnote->descdata);
12839 break;
12840#ifdef BFD64
12841 case NT_VMS_FPMODE:
9cf03b7e 12842 printf (_(" Floating Point mode: "));
4a5cb34f 12843 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
12844 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
12845 break;
12846 case NT_VMS_LINKTIME:
12847 printf (_(" Link time: "));
12848 print_vms_time
12849 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12850 printf ("\n");
12851 break;
12852 case NT_VMS_PATCHTIME:
12853 printf (_(" Patch time: "));
12854 print_vms_time
12855 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12856 printf ("\n");
12857 break;
12858 case NT_VMS_ORIG_DYN:
12859 printf (_(" Major id: %u, minor id: %u\n"),
12860 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
12861 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 12862 printf (_(" Last modified : "));
00e98fc7
TG
12863 print_vms_time
12864 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 12865 printf (_("\n Link flags : "));
4a5cb34f 12866 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
12867 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
12868 printf (_(" Header flags: 0x%08x\n"),
12869 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
12870 printf (_(" Image id : %s\n"), pnote->descdata + 32);
12871 break;
12872#endif
12873 case NT_VMS_IMGNAM:
12874 printf (_(" Image name: %s\n"), pnote->descdata);
12875 break;
12876 case NT_VMS_GSTNAM:
12877 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
12878 break;
12879 case NT_VMS_IMGID:
12880 printf (_(" Image id: %s\n"), pnote->descdata);
12881 break;
12882 case NT_VMS_LINKID:
12883 printf (_(" Linker id: %s\n"), pnote->descdata);
12884 break;
12885 default:
12886 break;
12887 }
12888 return 1;
12889}
12890
6d118b09
NC
12891/* Note that by the ELF standard, the name field is already null byte
12892 terminated, and namesz includes the terminating null byte.
12893 I.E. the value of namesz for the name "FSF" is 4.
12894
e3c8793a 12895 If the value of namesz is zero, there is no name present. */
779fe533 12896static int
2cf0635d 12897process_note (Elf_Internal_Note * pnote)
779fe533 12898{
2cf0635d
NC
12899 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
12900 const char * nt;
9437c45b
JT
12901
12902 if (pnote->namesz == 0)
1ec5cd37
NC
12903 /* If there is no note name, then use the default set of
12904 note type strings. */
12905 nt = get_note_type (pnote->type);
12906
1118d252
RM
12907 else if (const_strneq (pnote->namedata, "GNU"))
12908 /* GNU-specific object file notes. */
12909 nt = get_gnu_elf_note_type (pnote->type);
12910
0112cd26 12911 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
12912 /* NetBSD-specific core file notes. */
12913 nt = get_netbsd_elfcore_note_type (pnote->type);
12914
b15fa79e
AM
12915 else if (strneq (pnote->namedata, "SPU/", 4))
12916 {
12917 /* SPU-specific core file notes. */
12918 nt = pnote->namedata + 4;
12919 name = "SPU";
12920 }
12921
00e98fc7
TG
12922 else if (const_strneq (pnote->namedata, "IPF/VMS"))
12923 /* VMS/ia64-specific file notes. */
12924 nt = get_ia64_vms_note_type (pnote->type);
12925
70616151
TT
12926 else if (const_strneq (pnote->namedata, "stapsdt"))
12927 nt = get_stapsdt_note_type (pnote->type);
12928
9437c45b 12929 else
1ec5cd37
NC
12930 /* Don't recognize this note name; just use the default set of
12931 note type strings. */
00e98fc7 12932 nt = get_note_type (pnote->type);
9437c45b 12933
2aee03ae 12934 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
12935
12936 if (const_strneq (pnote->namedata, "IPF/VMS"))
12937 return print_ia64_vms_note (pnote);
664f90a3
TT
12938 else if (const_strneq (pnote->namedata, "GNU"))
12939 return print_gnu_note (pnote);
c6a9fc58
TT
12940 else if (const_strneq (pnote->namedata, "stapsdt"))
12941 return print_stapsdt_note (pnote);
00e98fc7
TG
12942 else
12943 return 1;
779fe533
NC
12944}
12945
6d118b09 12946
779fe533 12947static int
2cf0635d 12948process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 12949{
2cf0635d
NC
12950 Elf_External_Note * pnotes;
12951 Elf_External_Note * external;
b34976b6 12952 int res = 1;
103f02d3 12953
779fe533
NC
12954 if (length <= 0)
12955 return 0;
103f02d3 12956
3f5e193b
NC
12957 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
12958 _("notes"));
dd24e3da 12959 if (pnotes == NULL)
a6e9f9df 12960 return 0;
779fe533 12961
103f02d3 12962 external = pnotes;
103f02d3 12963
305c7206 12964 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 12965 (unsigned long) offset, (unsigned long) length);
2aee03ae 12966 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 12967
2cf0635d 12968 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 12969 {
2cf0635d 12970 Elf_External_Note * next;
b34976b6 12971 Elf_Internal_Note inote;
2cf0635d 12972 char * temp = NULL;
6d118b09 12973
00e98fc7
TG
12974 if (!is_ia64_vms ())
12975 {
12976 inote.type = BYTE_GET (external->type);
12977 inote.namesz = BYTE_GET (external->namesz);
12978 inote.namedata = external->name;
12979 inote.descsz = BYTE_GET (external->descsz);
12980 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
12981 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12982
12983 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
12984 }
12985 else
12986 {
12987 Elf64_External_VMS_Note *vms_external;
12988
12989 vms_external = (Elf64_External_VMS_Note *)external;
12990 inote.type = BYTE_GET (vms_external->type);
12991 inote.namesz = BYTE_GET (vms_external->namesz);
12992 inote.namedata = vms_external->name;
12993 inote.descsz = BYTE_GET (vms_external->descsz);
12994 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
12995 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12996
12997 next = (Elf_External_Note *)
12998 (inote.descdata + align_power (inote.descsz, 3));
12999 }
3e55a963 13000
dd24e3da
NC
13001 if ( ((char *) next > ((char *) pnotes) + length)
13002 || ((char *) next < (char *) pnotes))
3e55a963 13003 {
0fd3a477 13004 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 13005 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 13006 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
13007 inote.type, inote.namesz, inote.descsz);
13008 break;
13009 }
13010
13011 external = next;
6d118b09 13012
dd24e3da 13013 /* Prevent out-of-bounds indexing. */
8b971f9f 13014 if (inote.namedata + inote.namesz > (char *) pnotes + length
dd24e3da
NC
13015 || inote.namedata + inote.namesz < inote.namedata)
13016 {
13017 warn (_("corrupt note found at offset %lx into core notes\n"),
13018 (unsigned long) ((char *) external - (char *) pnotes));
13019 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
13020 inote.type, inote.namesz, inote.descsz);
13021 break;
13022 }
13023
6d118b09
NC
13024 /* Verify that name is null terminated. It appears that at least
13025 one version of Linux (RedHat 6.0) generates corefiles that don't
13026 comply with the ELF spec by failing to include the null byte in
13027 namesz. */
8b971f9f 13028 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 13029 {
3f5e193b 13030 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 13031
6d118b09
NC
13032 if (temp == NULL)
13033 {
13034 error (_("Out of memory\n"));
13035 res = 0;
13036 break;
13037 }
76da6bbe 13038
6d118b09
NC
13039 strncpy (temp, inote.namedata, inote.namesz);
13040 temp[inote.namesz] = 0;
76da6bbe 13041
6d118b09
NC
13042 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
13043 inote.namedata = temp;
13044 }
13045
13046 res &= process_note (& inote);
103f02d3 13047
6d118b09
NC
13048 if (temp != NULL)
13049 {
13050 free (temp);
13051 temp = NULL;
13052 }
779fe533
NC
13053 }
13054
13055 free (pnotes);
103f02d3 13056
779fe533
NC
13057 return res;
13058}
13059
13060static int
2cf0635d 13061process_corefile_note_segments (FILE * file)
779fe533 13062{
2cf0635d 13063 Elf_Internal_Phdr * segment;
b34976b6
AM
13064 unsigned int i;
13065 int res = 1;
103f02d3 13066
d93f0186 13067 if (! get_program_headers (file))
779fe533 13068 return 0;
103f02d3 13069
779fe533
NC
13070 for (i = 0, segment = program_headers;
13071 i < elf_header.e_phnum;
b34976b6 13072 i++, segment++)
779fe533
NC
13073 {
13074 if (segment->p_type == PT_NOTE)
103f02d3 13075 res &= process_corefile_note_segment (file,
30800947
NC
13076 (bfd_vma) segment->p_offset,
13077 (bfd_vma) segment->p_filesz);
779fe533 13078 }
103f02d3 13079
779fe533
NC
13080 return res;
13081}
13082
13083static int
2cf0635d 13084process_note_sections (FILE * file)
1ec5cd37 13085{
2cf0635d 13086 Elf_Internal_Shdr * section;
1ec5cd37
NC
13087 unsigned long i;
13088 int res = 1;
13089
13090 for (i = 0, section = section_headers;
fa1908fd 13091 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
13092 i++, section++)
13093 if (section->sh_type == SHT_NOTE)
13094 res &= process_corefile_note_segment (file,
13095 (bfd_vma) section->sh_offset,
13096 (bfd_vma) section->sh_size);
13097
13098 return res;
13099}
13100
13101static int
2cf0635d 13102process_notes (FILE * file)
779fe533
NC
13103{
13104 /* If we have not been asked to display the notes then do nothing. */
13105 if (! do_notes)
13106 return 1;
103f02d3 13107
779fe533 13108 if (elf_header.e_type != ET_CORE)
1ec5cd37 13109 return process_note_sections (file);
103f02d3 13110
779fe533 13111 /* No program headers means no NOTE segment. */
1ec5cd37
NC
13112 if (elf_header.e_phnum > 0)
13113 return process_corefile_note_segments (file);
779fe533 13114
1ec5cd37
NC
13115 printf (_("No note segments present in the core file.\n"));
13116 return 1;
779fe533
NC
13117}
13118
252b5132 13119static int
2cf0635d 13120process_arch_specific (FILE * file)
252b5132 13121{
a952a375
NC
13122 if (! do_arch)
13123 return 1;
13124
252b5132
RH
13125 switch (elf_header.e_machine)
13126 {
11c1ff18
PB
13127 case EM_ARM:
13128 return process_arm_specific (file);
252b5132 13129 case EM_MIPS:
4fe85591 13130 case EM_MIPS_RS3_LE:
252b5132
RH
13131 return process_mips_specific (file);
13132 break;
34c8bcba
JM
13133 case EM_PPC:
13134 return process_power_specific (file);
13135 break;
9e8c70f9
DM
13136 case EM_SPARC:
13137 case EM_SPARC32PLUS:
13138 case EM_SPARCV9:
13139 return process_sparc_specific (file);
13140 break;
59e6276b
JM
13141 case EM_TI_C6000:
13142 return process_tic6x_specific (file);
13143 break;
252b5132
RH
13144 default:
13145 break;
13146 }
13147 return 1;
13148}
13149
13150static int
2cf0635d 13151get_file_header (FILE * file)
252b5132 13152{
9ea033b2
NC
13153 /* Read in the identity array. */
13154 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13155 return 0;
13156
9ea033b2 13157 /* Determine how to read the rest of the header. */
b34976b6 13158 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13159 {
13160 default: /* fall through */
13161 case ELFDATANONE: /* fall through */
adab8cdc
AO
13162 case ELFDATA2LSB:
13163 byte_get = byte_get_little_endian;
13164 byte_put = byte_put_little_endian;
13165 break;
13166 case ELFDATA2MSB:
13167 byte_get = byte_get_big_endian;
13168 byte_put = byte_put_big_endian;
13169 break;
9ea033b2
NC
13170 }
13171
13172 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13173 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13174
13175 /* Read in the rest of the header. */
13176 if (is_32bit_elf)
13177 {
13178 Elf32_External_Ehdr ehdr32;
252b5132 13179
9ea033b2
NC
13180 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13181 return 0;
103f02d3 13182
9ea033b2
NC
13183 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13184 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13185 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13186 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13187 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13188 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13189 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13190 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13191 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13192 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13193 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13194 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13195 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13196 }
252b5132 13197 else
9ea033b2
NC
13198 {
13199 Elf64_External_Ehdr ehdr64;
a952a375
NC
13200
13201 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13202 we will not be able to cope with the 64bit data found in
13203 64 ELF files. Detect this now and abort before we start
50c2245b 13204 overwriting things. */
a952a375
NC
13205 if (sizeof (bfd_vma) < 8)
13206 {
e3c8793a
NC
13207 error (_("This instance of readelf has been built without support for a\n\
1320864 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13209 return 0;
13210 }
103f02d3 13211
9ea033b2
NC
13212 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13213 return 0;
103f02d3 13214
9ea033b2
NC
13215 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13216 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13217 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13218 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13219 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13220 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13221 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13222 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13223 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13224 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13225 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13226 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13227 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13228 }
252b5132 13229
7ece0d85
JJ
13230 if (elf_header.e_shoff)
13231 {
13232 /* There may be some extensions in the first section header. Don't
13233 bomb if we can't read it. */
13234 if (is_32bit_elf)
13235 get_32bit_section_headers (file, 1);
13236 else
13237 get_64bit_section_headers (file, 1);
13238 }
560f3c1c 13239
252b5132
RH
13240 return 1;
13241}
13242
fb52b2f4
NC
13243/* Process one ELF object file according to the command line options.
13244 This file may actually be stored in an archive. The file is
13245 positioned at the start of the ELF object. */
13246
ff78d6d6 13247static int
2cf0635d 13248process_object (char * file_name, FILE * file)
252b5132 13249{
252b5132
RH
13250 unsigned int i;
13251
252b5132
RH
13252 if (! get_file_header (file))
13253 {
13254 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13255 return 1;
252b5132
RH
13256 }
13257
13258 /* Initialise per file variables. */
60bca95a 13259 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13260 version_info[i] = 0;
13261
60bca95a 13262 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13263 dynamic_info[i] = 0;
5115b233 13264 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13265
13266 /* Process the file. */
13267 if (show_name)
13268 printf (_("\nFile: %s\n"), file_name);
13269
18bd398b
NC
13270 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13271 Note we do this even if cmdline_dump_sects is empty because we
13272 must make sure that the dump_sets array is zeroed out before each
13273 object file is processed. */
13274 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13275 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13276
13277 if (num_cmdline_dump_sects > 0)
13278 {
13279 if (num_dump_sects == 0)
13280 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13281 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13282
13283 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13284 memcpy (dump_sects, cmdline_dump_sects,
13285 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13286 }
d70c5fc7 13287
252b5132 13288 if (! process_file_header ())
fb52b2f4 13289 return 1;
252b5132 13290
d1f5c6e3 13291 if (! process_section_headers (file))
2f62977e 13292 {
d1f5c6e3
L
13293 /* Without loaded section headers we cannot process lots of
13294 things. */
2f62977e 13295 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13296
2f62977e 13297 if (! do_using_dynamic)
2c610e4b 13298 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13299 }
252b5132 13300
d1f5c6e3
L
13301 if (! process_section_groups (file))
13302 {
13303 /* Without loaded section groups we cannot process unwind. */
13304 do_unwind = 0;
13305 }
13306
2f62977e 13307 if (process_program_headers (file))
b2d38a17 13308 process_dynamic_section (file);
252b5132
RH
13309
13310 process_relocs (file);
13311
4d6ed7c8
NC
13312 process_unwind (file);
13313
252b5132
RH
13314 process_symbol_table (file);
13315
13316 process_syminfo (file);
13317
13318 process_version_sections (file);
13319
13320 process_section_contents (file);
f5842774 13321
1ec5cd37 13322 process_notes (file);
103f02d3 13323
047b2264
JJ
13324 process_gnu_liblist (file);
13325
252b5132
RH
13326 process_arch_specific (file);
13327
d93f0186
NC
13328 if (program_headers)
13329 {
13330 free (program_headers);
13331 program_headers = NULL;
13332 }
13333
252b5132
RH
13334 if (section_headers)
13335 {
13336 free (section_headers);
13337 section_headers = NULL;
13338 }
13339
13340 if (string_table)
13341 {
13342 free (string_table);
13343 string_table = NULL;
d40ac9bd 13344 string_table_length = 0;
252b5132
RH
13345 }
13346
13347 if (dynamic_strings)
13348 {
13349 free (dynamic_strings);
13350 dynamic_strings = NULL;
d79b3d50 13351 dynamic_strings_length = 0;
252b5132
RH
13352 }
13353
13354 if (dynamic_symbols)
13355 {
13356 free (dynamic_symbols);
13357 dynamic_symbols = NULL;
19936277 13358 num_dynamic_syms = 0;
252b5132
RH
13359 }
13360
13361 if (dynamic_syminfo)
13362 {
13363 free (dynamic_syminfo);
13364 dynamic_syminfo = NULL;
13365 }
ff78d6d6 13366
293c573e
MR
13367 if (dynamic_section)
13368 {
13369 free (dynamic_section);
13370 dynamic_section = NULL;
13371 }
13372
e4b17d5c
L
13373 if (section_headers_groups)
13374 {
13375 free (section_headers_groups);
13376 section_headers_groups = NULL;
13377 }
13378
13379 if (section_groups)
13380 {
2cf0635d
NC
13381 struct group_list * g;
13382 struct group_list * next;
e4b17d5c
L
13383
13384 for (i = 0; i < group_count; i++)
13385 {
13386 for (g = section_groups [i].root; g != NULL; g = next)
13387 {
13388 next = g->next;
13389 free (g);
13390 }
13391 }
13392
13393 free (section_groups);
13394 section_groups = NULL;
13395 }
13396
19e6b90e 13397 free_debug_memory ();
18bd398b 13398
ff78d6d6 13399 return 0;
252b5132
RH
13400}
13401
2cf0635d
NC
13402/* Process an ELF archive.
13403 On entry the file is positioned just after the ARMAG string. */
13404
13405static int
13406process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13407{
13408 struct archive_info arch;
13409 struct archive_info nested_arch;
13410 size_t got;
2cf0635d
NC
13411 int ret;
13412
13413 show_name = 1;
13414
13415 /* The ARCH structure is used to hold information about this archive. */
13416 arch.file_name = NULL;
13417 arch.file = NULL;
13418 arch.index_array = NULL;
13419 arch.sym_table = NULL;
13420 arch.longnames = NULL;
13421
13422 /* The NESTED_ARCH structure is used as a single-item cache of information
13423 about a nested archive (when members of a thin archive reside within
13424 another regular archive file). */
13425 nested_arch.file_name = NULL;
13426 nested_arch.file = NULL;
13427 nested_arch.index_array = NULL;
13428 nested_arch.sym_table = NULL;
13429 nested_arch.longnames = NULL;
13430
13431 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13432 {
13433 ret = 1;
13434 goto out;
4145f1d5 13435 }
fb52b2f4 13436
4145f1d5
NC
13437 if (do_archive_index)
13438 {
2cf0635d 13439 if (arch.sym_table == NULL)
4145f1d5
NC
13440 error (_("%s: unable to dump the index as none was found\n"), file_name);
13441 else
13442 {
2cf0635d 13443 unsigned int i, l;
4145f1d5
NC
13444 unsigned long current_pos;
13445
13446 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 13447 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
13448 current_pos = ftell (file);
13449
2cf0635d 13450 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13451 {
2cf0635d
NC
13452 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13453 {
13454 char * member_name;
4145f1d5 13455
2cf0635d
NC
13456 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13457
13458 if (member_name != NULL)
13459 {
13460 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13461
13462 if (qualified_name != NULL)
13463 {
13464 printf (_("Binary %s contains:\n"), qualified_name);
13465 free (qualified_name);
13466 }
4145f1d5
NC
13467 }
13468 }
2cf0635d
NC
13469
13470 if (l >= arch.sym_size)
4145f1d5
NC
13471 {
13472 error (_("%s: end of the symbol table reached before the end of the index\n"),
13473 file_name);
cb8f3167 13474 break;
4145f1d5 13475 }
2cf0635d
NC
13476 printf ("\t%s\n", arch.sym_table + l);
13477 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13478 }
13479
2cf0635d
NC
13480 if (l & 01)
13481 ++l;
13482 if (l < arch.sym_size)
4145f1d5
NC
13483 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
13484 file_name);
13485
4145f1d5
NC
13486 if (fseek (file, current_pos, SEEK_SET) != 0)
13487 {
13488 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13489 ret = 1;
13490 goto out;
4145f1d5 13491 }
fb52b2f4 13492 }
4145f1d5
NC
13493
13494 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13495 && !do_segments && !do_header && !do_dump && !do_version
13496 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13497 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13498 {
13499 ret = 0; /* Archive index only. */
13500 goto out;
13501 }
fb52b2f4
NC
13502 }
13503
d989285c 13504 ret = 0;
fb52b2f4
NC
13505
13506 while (1)
13507 {
2cf0635d
NC
13508 char * name;
13509 size_t namelen;
13510 char * qualified_name;
13511
13512 /* Read the next archive header. */
13513 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13514 {
13515 error (_("%s: failed to seek to next archive header\n"), file_name);
13516 return 1;
13517 }
13518 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13519 if (got != sizeof arch.arhdr)
13520 {
13521 if (got == 0)
13522 break;
13523 error (_("%s: failed to read archive header\n"), file_name);
13524 ret = 1;
13525 break;
13526 }
13527 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13528 {
13529 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13530 ret = 1;
13531 break;
13532 }
13533
13534 arch.next_arhdr_offset += sizeof arch.arhdr;
13535
13536 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13537 if (archive_file_size & 01)
13538 ++archive_file_size;
13539
13540 name = get_archive_member_name (&arch, &nested_arch);
13541 if (name == NULL)
fb52b2f4 13542 {
0fd3a477 13543 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13544 ret = 1;
13545 break;
fb52b2f4 13546 }
2cf0635d 13547 namelen = strlen (name);
fb52b2f4 13548
2cf0635d
NC
13549 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13550 if (qualified_name == NULL)
fb52b2f4 13551 {
2cf0635d 13552 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13553 ret = 1;
13554 break;
fb52b2f4
NC
13555 }
13556
2cf0635d
NC
13557 if (is_thin_archive && arch.nested_member_origin == 0)
13558 {
13559 /* This is a proxy for an external member of a thin archive. */
13560 FILE * member_file;
13561 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13562 if (member_file_name == NULL)
13563 {
13564 ret = 1;
13565 break;
13566 }
13567
13568 member_file = fopen (member_file_name, "rb");
13569 if (member_file == NULL)
13570 {
13571 error (_("Input file '%s' is not readable.\n"), member_file_name);
13572 free (member_file_name);
13573 ret = 1;
13574 break;
13575 }
13576
13577 archive_file_offset = arch.nested_member_origin;
13578
13579 ret |= process_object (qualified_name, member_file);
13580
13581 fclose (member_file);
13582 free (member_file_name);
13583 }
13584 else if (is_thin_archive)
13585 {
13586 /* This is a proxy for a member of a nested archive. */
13587 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
13588
13589 /* The nested archive file will have been opened and setup by
13590 get_archive_member_name. */
13591 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
13592 {
13593 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
13594 ret = 1;
13595 break;
13596 }
13597
13598 ret |= process_object (qualified_name, nested_arch.file);
13599 }
13600 else
13601 {
13602 archive_file_offset = arch.next_arhdr_offset;
13603 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 13604
2cf0635d
NC
13605 ret |= process_object (qualified_name, file);
13606 }
fb52b2f4 13607
2b52916e
L
13608 if (dump_sects != NULL)
13609 {
13610 free (dump_sects);
13611 dump_sects = NULL;
13612 num_dump_sects = 0;
13613 }
13614
2cf0635d 13615 free (qualified_name);
fb52b2f4
NC
13616 }
13617
4145f1d5 13618 out:
2cf0635d
NC
13619 if (nested_arch.file != NULL)
13620 fclose (nested_arch.file);
13621 release_archive (&nested_arch);
13622 release_archive (&arch);
fb52b2f4 13623
d989285c 13624 return ret;
fb52b2f4
NC
13625}
13626
13627static int
2cf0635d 13628process_file (char * file_name)
fb52b2f4 13629{
2cf0635d 13630 FILE * file;
fb52b2f4
NC
13631 struct stat statbuf;
13632 char armag[SARMAG];
13633 int ret;
13634
13635 if (stat (file_name, &statbuf) < 0)
13636 {
f24ddbdd
NC
13637 if (errno == ENOENT)
13638 error (_("'%s': No such file\n"), file_name);
13639 else
13640 error (_("Could not locate '%s'. System error message: %s\n"),
13641 file_name, strerror (errno));
13642 return 1;
13643 }
13644
13645 if (! S_ISREG (statbuf.st_mode))
13646 {
13647 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
13648 return 1;
13649 }
13650
13651 file = fopen (file_name, "rb");
13652 if (file == NULL)
13653 {
f24ddbdd 13654 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
13655 return 1;
13656 }
13657
13658 if (fread (armag, SARMAG, 1, file) != 1)
13659 {
4145f1d5 13660 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
13661 fclose (file);
13662 return 1;
13663 }
13664
13665 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
13666 ret = process_archive (file_name, file, FALSE);
13667 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
13668 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
13669 else
13670 {
4145f1d5
NC
13671 if (do_archive_index)
13672 error (_("File %s is not an archive so its index cannot be displayed.\n"),
13673 file_name);
13674
fb52b2f4
NC
13675 rewind (file);
13676 archive_file_size = archive_file_offset = 0;
13677 ret = process_object (file_name, file);
13678 }
13679
13680 fclose (file);
13681
13682 return ret;
13683}
13684
252b5132
RH
13685#ifdef SUPPORT_DISASSEMBLY
13686/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 13687 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 13688 symbols. */
252b5132
RH
13689
13690void
2cf0635d 13691print_address (unsigned int addr, FILE * outfile)
252b5132
RH
13692{
13693 fprintf (outfile,"0x%8.8x", addr);
13694}
13695
e3c8793a 13696/* Needed by the i386 disassembler. */
252b5132
RH
13697void
13698db_task_printsym (unsigned int addr)
13699{
13700 print_address (addr, stderr);
13701}
13702#endif
13703
13704int
2cf0635d 13705main (int argc, char ** argv)
252b5132 13706{
ff78d6d6
L
13707 int err;
13708
252b5132
RH
13709#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
13710 setlocale (LC_MESSAGES, "");
3882b010
L
13711#endif
13712#if defined (HAVE_SETLOCALE)
13713 setlocale (LC_CTYPE, "");
252b5132
RH
13714#endif
13715 bindtextdomain (PACKAGE, LOCALEDIR);
13716 textdomain (PACKAGE);
13717
869b9d07
MM
13718 expandargv (&argc, &argv);
13719
252b5132
RH
13720 parse_args (argc, argv);
13721
18bd398b 13722 if (num_dump_sects > 0)
59f14fc0 13723 {
18bd398b 13724 /* Make a copy of the dump_sects array. */
3f5e193b
NC
13725 cmdline_dump_sects = (dump_type *)
13726 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 13727 if (cmdline_dump_sects == NULL)
591a748a 13728 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
13729 else
13730 {
09c11c86
NC
13731 memcpy (cmdline_dump_sects, dump_sects,
13732 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
13733 num_cmdline_dump_sects = num_dump_sects;
13734 }
13735 }
13736
18bd398b
NC
13737 if (optind < (argc - 1))
13738 show_name = 1;
13739
ff78d6d6 13740 err = 0;
252b5132 13741 while (optind < argc)
18bd398b 13742 err |= process_file (argv[optind++]);
252b5132
RH
13743
13744 if (dump_sects != NULL)
13745 free (dump_sects);
59f14fc0
AS
13746 if (cmdline_dump_sects != NULL)
13747 free (cmdline_dump_sects);
252b5132 13748
ff78d6d6 13749 return err;
252b5132 13750}
This page took 1.869003 seconds and 4 git commands to generate.