]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
2011-04-07 Paul Brook <paul@codesourcery.com>
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
6e3d6dc1 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
7a88bc9c 3 2008, 2009, 2010, 2011
a0f19280 4 Free Software Foundation, Inc.
252b5132
RH
5
6 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 7 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
8
9 This file is part of GNU Binutils.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
32866df7 13 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
b43b5d5f
NC
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
24 02110-1301, USA. */
252b5132 25\f
9eb20dd8 26/* The difference between readelf and objdump:
252b5132 27
74013231 28 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 29 so why does the binutils project have two file dumpers ?
0de14b54 30
9eb20dd8
NC
31 The reason is that objdump sees an ELF file through a BFD filter of the
32 world; if BFD has a bug where, say, it disagrees about a machine constant
33 in e_flags, then the odds are good that it will remain internally
34 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
35 GAS sees it the BFD way. There was need for a tool to go find out what
36 the file actually says.
37
38 This is why the readelf program does not link against the BFD library - it
39 exists as an independent program to help verify the correct working of BFD.
40
41 There is also the case that readelf can provide more information about an
42 ELF file than is provided by objdump. In particular it can display DWARF
43 debugging information which (at the moment) objdump cannot. */
44\f
1b315056 45#include "config.h"
3db64b00 46#include "sysdep.h"
252b5132
RH
47#include <assert.h>
48#include <sys/stat.h>
252b5132 49#include <time.h>
1b315056
CS
50#ifdef HAVE_ZLIB_H
51#include <zlib.h>
52#endif
252b5132 53
a952a375 54#if __GNUC__ >= 2
19936277 55/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 56 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 57 Only do this if we believe that the compiler can support a 64 bit
a952a375 58 data type. For now we only rely on GCC being able to do this. */
19936277 59#define BFD64
a952a375
NC
60#endif
61
3db64b00
AM
62#include "bfd.h"
63#include "bucomm.h"
3284fe0c 64#include "elfcomm.h"
19e6b90e 65#include "dwarf.h"
252b5132
RH
66
67#include "elf/common.h"
68#include "elf/external.h"
69#include "elf/internal.h"
252b5132 70
4b78141a
NC
71
72/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
73 we can obtain the H8 reloc numbers. We need these for the
74 get_reloc_size() function. We include h8.h again after defining
75 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
76
77#include "elf/h8.h"
78#undef _ELF_H8_H
79
80/* Undo the effects of #including reloc-macros.h. */
81
82#undef START_RELOC_NUMBERS
83#undef RELOC_NUMBER
84#undef FAKE_RELOC
85#undef EMPTY_RELOC
86#undef END_RELOC_NUMBERS
87#undef _RELOC_MACROS_H
88
252b5132
RH
89/* The following headers use the elf/reloc-macros.h file to
90 automatically generate relocation recognition functions
91 such as elf_mips_reloc_type() */
92
93#define RELOC_MACROS_GEN_FUNC
94
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
252b5132 106#include "elf/fr30.h"
5c70f934 107#include "elf/frv.h"
3b16e843
NC
108#include "elf/h8.h"
109#include "elf/hppa.h"
110#include "elf/i386.h"
35b1837e 111#include "elf/i370.h"
3b16e843
NC
112#include "elf/i860.h"
113#include "elf/i960.h"
114#include "elf/ia64.h"
1e4cf259 115#include "elf/ip2k.h"
84e94c90 116#include "elf/lm32.h"
1c0d3aa6 117#include "elf/iq2000.h"
49f58d10 118#include "elf/m32c.h"
3b16e843
NC
119#include "elf/m32r.h"
120#include "elf/m68k.h"
75751cd9 121#include "elf/m68hc11.h"
252b5132 122#include "elf/mcore.h"
15ab5209 123#include "elf/mep.h"
7ba29e2a 124#include "elf/microblaze.h"
3b16e843 125#include "elf/mips.h"
3c3bdf30 126#include "elf/mmix.h"
3b16e843
NC
127#include "elf/mn10200.h"
128#include "elf/mn10300.h"
5506d11a 129#include "elf/moxie.h"
4970f871 130#include "elf/mt.h"
2469cfa2 131#include "elf/msp430.h"
3b16e843 132#include "elf/or32.h"
7d466069 133#include "elf/pj.h"
3b16e843 134#include "elf/ppc.h"
c833c019 135#include "elf/ppc64.h"
c7927a3c 136#include "elf/rx.h"
a85d7ed0 137#include "elf/s390.h"
1c0d3aa6 138#include "elf/score.h"
3b16e843
NC
139#include "elf/sh.h"
140#include "elf/sparc.h"
e9f53129 141#include "elf/spu.h"
40b36596 142#include "elf/tic6x.h"
3b16e843 143#include "elf/v850.h"
179d3252 144#include "elf/vax.h"
3b16e843 145#include "elf/x86-64.h"
c29aca4a 146#include "elf/xc16x.h"
93fbbb04 147#include "elf/xstormy16.h"
88da6820 148#include "elf/xtensa.h"
252b5132 149
252b5132 150#include "getopt.h"
566b0d53 151#include "libiberty.h"
09c11c86 152#include "safe-ctype.h"
2cf0635d 153#include "filenames.h"
252b5132 154
2cf0635d 155char * program_name = "readelf";
85b1c36d
BE
156static long archive_file_offset;
157static unsigned long archive_file_size;
158static unsigned long dynamic_addr;
159static bfd_size_type dynamic_size;
160static unsigned int dynamic_nent;
2cf0635d 161static char * dynamic_strings;
85b1c36d 162static unsigned long dynamic_strings_length;
2cf0635d 163static char * string_table;
85b1c36d
BE
164static unsigned long string_table_length;
165static unsigned long num_dynamic_syms;
2cf0635d
NC
166static Elf_Internal_Sym * dynamic_symbols;
167static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
168static unsigned long dynamic_syminfo_offset;
169static unsigned int dynamic_syminfo_nent;
f8eae8b2 170static char program_interpreter[PATH_MAX];
bb8a0291 171static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 172static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
173static bfd_vma version_info[16];
174static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
175static Elf_Internal_Shdr * section_headers;
176static Elf_Internal_Phdr * program_headers;
177static Elf_Internal_Dyn * dynamic_section;
178static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
179static int show_name;
180static int do_dynamic;
181static int do_syms;
2c610e4b 182static int do_dyn_syms;
85b1c36d
BE
183static int do_reloc;
184static int do_sections;
185static int do_section_groups;
5477e8a0 186static int do_section_details;
85b1c36d
BE
187static int do_segments;
188static int do_unwind;
189static int do_using_dynamic;
190static int do_header;
191static int do_dump;
192static int do_version;
85b1c36d
BE
193static int do_histogram;
194static int do_debugging;
85b1c36d
BE
195static int do_arch;
196static int do_notes;
4145f1d5 197static int do_archive_index;
85b1c36d 198static int is_32bit_elf;
252b5132 199
e4b17d5c
L
200struct group_list
201{
2cf0635d 202 struct group_list * next;
e4b17d5c
L
203 unsigned int section_index;
204};
205
206struct group
207{
2cf0635d 208 struct group_list * root;
e4b17d5c
L
209 unsigned int group_index;
210};
211
85b1c36d 212static size_t group_count;
2cf0635d
NC
213static struct group * section_groups;
214static struct group ** section_headers_groups;
e4b17d5c 215
09c11c86
NC
216
217/* Flag bits indicating particular types of dump. */
218#define HEX_DUMP (1 << 0) /* The -x command line switch. */
219#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
220#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
221#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 222#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
223
224typedef unsigned char dump_type;
225
226/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
227struct dump_list_entry
228{
2cf0635d 229 char * name;
09c11c86 230 dump_type type;
2cf0635d 231 struct dump_list_entry * next;
aef1f6d0 232};
2cf0635d 233static struct dump_list_entry * dump_sects_byname;
aef1f6d0 234
09c11c86
NC
235/* A dynamic array of flags indicating for which sections a dump
236 has been requested via command line switches. */
237static dump_type * cmdline_dump_sects = NULL;
238static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
239
240/* A dynamic array of flags indicating for which sections a dump of
241 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
242 basis and then initialised from the cmdline_dump_sects array,
243 the results of interpreting the -w switch, and the
244 dump_sects_byname list. */
09c11c86
NC
245static dump_type * dump_sects = NULL;
246static unsigned int num_dump_sects = 0;
252b5132 247
252b5132 248
c256ffe7 249/* How to print a vma value. */
843dd992
NC
250typedef enum print_mode
251{
252 HEX,
253 DEC,
254 DEC_5,
255 UNSIGNED,
256 PREFIX_HEX,
257 FULL_HEX,
258 LONG_HEX
259}
260print_mode;
261
9c19a809
NC
262#define UNKNOWN -1
263
2b692964
NC
264#define SECTION_NAME(X) \
265 ((X) == NULL ? _("<none>") \
266 : string_table == NULL ? _("<no-name>") \
267 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 268 : string_table + (X)->sh_name))
252b5132 269
ee42cf8c 270#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 271
9ad5cbcf
AM
272#define GET_ELF_SYMBOLS(file, section) \
273 (is_32bit_elf ? get_32bit_elf_symbols (file, section) \
274 : get_64bit_elf_symbols (file, section))
9ea033b2 275
d79b3d50
NC
276#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
277/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
278 already been called and verified that the string exists. */
279#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 280
61865e30
NC
281#define REMOVE_ARCH_BITS(ADDR) \
282 do \
283 { \
284 if (elf_header.e_machine == EM_ARM) \
285 (ADDR) &= ~1; \
286 } \
287 while (0)
d79b3d50 288\f
c256ffe7 289static void *
2cf0635d
NC
290get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
291 const char * reason)
a6e9f9df 292{
2cf0635d 293 void * mvar;
a6e9f9df 294
c256ffe7 295 if (size == 0 || nmemb == 0)
a6e9f9df
AM
296 return NULL;
297
fb52b2f4 298 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 299 {
0fd3a477 300 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 301 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
302 return NULL;
303 }
304
305 mvar = var;
306 if (mvar == NULL)
307 {
c256ffe7
JJ
308 /* Check for overflow. */
309 if (nmemb < (~(size_t) 0 - 1) / size)
310 /* + 1 so that we can '\0' terminate invalid string table sections. */
311 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
312
313 if (mvar == NULL)
314 {
0fd3a477
JW
315 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
316 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
317 return NULL;
318 }
c256ffe7
JJ
319
320 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
321 }
322
c256ffe7 323 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 324 {
0fd3a477
JW
325 error (_("Unable to read in 0x%lx bytes of %s\n"),
326 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
327 if (mvar != var)
328 free (mvar);
329 return NULL;
330 }
331
332 return mvar;
333}
334
14a91970 335/* Print a VMA value. */
cb8f3167 336
66543521 337static int
14a91970 338print_vma (bfd_vma vma, print_mode mode)
66543521 339{
66543521
AM
340 int nc = 0;
341
14a91970 342 switch (mode)
66543521 343 {
14a91970
AM
344 case FULL_HEX:
345 nc = printf ("0x");
346 /* Drop through. */
66543521 347
14a91970 348 case LONG_HEX:
f7a99963 349#ifdef BFD64
14a91970 350 if (is_32bit_elf)
437c2fb7 351 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 352#endif
14a91970
AM
353 printf_vma (vma);
354 return nc + 16;
b19aac67 355
14a91970
AM
356 case DEC_5:
357 if (vma <= 99999)
358 return printf ("%5" BFD_VMA_FMT "d", vma);
359 /* Drop through. */
66543521 360
14a91970
AM
361 case PREFIX_HEX:
362 nc = printf ("0x");
363 /* Drop through. */
66543521 364
14a91970
AM
365 case HEX:
366 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 367
14a91970
AM
368 case DEC:
369 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 370
14a91970
AM
371 case UNSIGNED:
372 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 373 }
66543521 374 return 0;
f7a99963
NC
375}
376
171191ba 377/* Display a symbol on stdout. Handles the display of non-printing characters.
31104126 378
171191ba
NC
379 If DO_WIDE is not true then format the symbol to be at most WIDTH characters,
380 truncating as necessary. If WIDTH is negative then format the string to be
381 exactly - WIDTH characters, truncating or padding as necessary.
382
383 Returns the number of emitted characters. */
384
385static unsigned int
7a88bc9c 386print_symbol (int width, const char *symbol)
31104126 387{
7a88bc9c 388 const char *c;
171191ba
NC
389 bfd_boolean extra_padding = FALSE;
390 unsigned int num_printed = 0;
961c521f 391
31104126 392 if (do_wide)
961c521f 393 {
7a88bc9c
AS
394 /* Set the width to a very large value. This simplifies the
395 code below. */
961c521f
NC
396 width = INT_MAX;
397 }
31104126 398 else if (width < 0)
961c521f 399 {
961c521f
NC
400 /* Keep the width positive. This also helps. */
401 width = - width;
171191ba 402 extra_padding = TRUE;
961c521f
NC
403 }
404
405 while (width)
406 {
407 int len;
408
409 c = symbol;
410
411 /* Look for non-printing symbols inside the symbol's name.
412 This test is triggered in particular by the names generated
413 by the assembler for local labels. */
7a88bc9c 414 while (ISPRINT (*c))
961c521f
NC
415 c++;
416
417 len = c - symbol;
418
419 if (len)
420 {
421 if (len > width)
422 len = width;
cb8f3167 423
171191ba 424 printf ("%.*s", len, symbol);
961c521f
NC
425
426 width -= len;
171191ba 427 num_printed += len;
961c521f
NC
428 }
429
7a88bc9c 430 if (*c == 0 || width == 0)
961c521f
NC
431 break;
432
433 /* Now display the non-printing character, if
434 there is room left in which to dipslay it. */
7a88bc9c 435 if ((unsigned char) *c < 32)
961c521f
NC
436 {
437 if (width < 2)
438 break;
439
440 printf ("^%c", *c + 0x40);
441
442 width -= 2;
171191ba 443 num_printed += 2;
961c521f
NC
444 }
445 else
446 {
447 if (width < 6)
448 break;
cb8f3167 449
7a88bc9c 450 printf ("<0x%.2x>", (unsigned char) *c);
961c521f
NC
451
452 width -= 6;
171191ba 453 num_printed += 6;
961c521f
NC
454 }
455
456 symbol = c + 1;
457 }
171191ba
NC
458
459 if (extra_padding && width > 0)
460 {
461 /* Fill in the remaining spaces. */
462 printf ("%-*s", width, " ");
463 num_printed += 2;
464 }
465
466 return num_printed;
31104126
NC
467}
468
89fac5e3
RS
469/* Return a pointer to section NAME, or NULL if no such section exists. */
470
471static Elf_Internal_Shdr *
2cf0635d 472find_section (const char * name)
89fac5e3
RS
473{
474 unsigned int i;
475
476 for (i = 0; i < elf_header.e_shnum; i++)
477 if (streq (SECTION_NAME (section_headers + i), name))
478 return section_headers + i;
479
480 return NULL;
481}
482
0b6ae522
DJ
483/* Return a pointer to a section containing ADDR, or NULL if no such
484 section exists. */
485
486static Elf_Internal_Shdr *
487find_section_by_address (bfd_vma addr)
488{
489 unsigned int i;
490
491 for (i = 0; i < elf_header.e_shnum; i++)
492 {
493 Elf_Internal_Shdr *sec = section_headers + i;
494 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
495 return sec;
496 }
497
498 return NULL;
499}
500
501/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
502 bytes read. */
503
504static unsigned long
505read_uleb128 (unsigned char *data, unsigned int *length_return)
506{
507 return read_leb128 (data, length_return, 0);
508}
509
28f997cf
TG
510/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
511 This OS has so many departures from the ELF standard that we test it at
512 many places. */
513
514static inline int
515is_ia64_vms (void)
516{
517 return elf_header.e_machine == EM_IA_64
518 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
519}
520
bcedfee6 521/* Guess the relocation size commonly used by the specific machines. */
252b5132 522
252b5132 523static int
2dc4cec1 524guess_is_rela (unsigned int e_machine)
252b5132 525{
9c19a809 526 switch (e_machine)
252b5132
RH
527 {
528 /* Targets that use REL relocations. */
252b5132
RH
529 case EM_386:
530 case EM_486:
63fcb9e9 531 case EM_960:
e9f53129 532 case EM_ARM:
2b0337b0 533 case EM_D10V:
252b5132 534 case EM_CYGNUS_D10V:
e9f53129 535 case EM_DLX:
252b5132 536 case EM_MIPS:
4fe85591 537 case EM_MIPS_RS3_LE:
e9f53129
AM
538 case EM_CYGNUS_M32R:
539 case EM_OPENRISC:
540 case EM_OR32:
1c0d3aa6 541 case EM_SCORE:
9c19a809 542 return FALSE;
103f02d3 543
252b5132
RH
544 /* Targets that use RELA relocations. */
545 case EM_68K:
e9f53129
AM
546 case EM_860:
547 case EM_ALPHA:
548 case EM_ALTERA_NIOS2:
549 case EM_AVR:
550 case EM_AVR_OLD:
551 case EM_BLACKFIN:
60bca95a 552 case EM_CR16:
6c03b1ed 553 case EM_CR16_OLD:
e9f53129
AM
554 case EM_CRIS:
555 case EM_CRX:
2b0337b0 556 case EM_D30V:
252b5132 557 case EM_CYGNUS_D30V:
2b0337b0 558 case EM_FR30:
252b5132 559 case EM_CYGNUS_FR30:
5c70f934 560 case EM_CYGNUS_FRV:
e9f53129
AM
561 case EM_H8S:
562 case EM_H8_300:
563 case EM_H8_300H:
800eeca4 564 case EM_IA_64:
1e4cf259
NC
565 case EM_IP2K:
566 case EM_IP2K_OLD:
3b36097d 567 case EM_IQ2000:
84e94c90 568 case EM_LATTICEMICO32:
ff7eeb89 569 case EM_M32C_OLD:
49f58d10 570 case EM_M32C:
e9f53129
AM
571 case EM_M32R:
572 case EM_MCORE:
15ab5209 573 case EM_CYGNUS_MEP:
e9f53129
AM
574 case EM_MMIX:
575 case EM_MN10200:
576 case EM_CYGNUS_MN10200:
577 case EM_MN10300:
578 case EM_CYGNUS_MN10300:
5506d11a 579 case EM_MOXIE:
e9f53129
AM
580 case EM_MSP430:
581 case EM_MSP430_OLD:
d031aafb 582 case EM_MT:
64fd6348 583 case EM_NIOS32:
e9f53129
AM
584 case EM_PPC64:
585 case EM_PPC:
c7927a3c 586 case EM_RX:
e9f53129
AM
587 case EM_S390:
588 case EM_S390_OLD:
589 case EM_SH:
590 case EM_SPARC:
591 case EM_SPARC32PLUS:
592 case EM_SPARCV9:
593 case EM_SPU:
40b36596 594 case EM_TI_C6000:
e9f53129
AM
595 case EM_V850:
596 case EM_CYGNUS_V850:
597 case EM_VAX:
598 case EM_X86_64:
8a9036a4 599 case EM_L1OM:
e9f53129
AM
600 case EM_XSTORMY16:
601 case EM_XTENSA:
602 case EM_XTENSA_OLD:
7ba29e2a
NC
603 case EM_MICROBLAZE:
604 case EM_MICROBLAZE_OLD:
9c19a809 605 return TRUE;
103f02d3 606
e9f53129
AM
607 case EM_68HC05:
608 case EM_68HC08:
609 case EM_68HC11:
610 case EM_68HC16:
611 case EM_FX66:
612 case EM_ME16:
d1133906 613 case EM_MMA:
d1133906
NC
614 case EM_NCPU:
615 case EM_NDR1:
e9f53129 616 case EM_PCP:
d1133906 617 case EM_ST100:
e9f53129 618 case EM_ST19:
d1133906 619 case EM_ST7:
e9f53129
AM
620 case EM_ST9PLUS:
621 case EM_STARCORE:
d1133906 622 case EM_SVX:
e9f53129 623 case EM_TINYJ:
9c19a809
NC
624 default:
625 warn (_("Don't know about relocations on this machine architecture\n"));
626 return FALSE;
627 }
628}
252b5132 629
9c19a809 630static int
2cf0635d 631slurp_rela_relocs (FILE * file,
d3ba0551
AM
632 unsigned long rel_offset,
633 unsigned long rel_size,
2cf0635d
NC
634 Elf_Internal_Rela ** relasp,
635 unsigned long * nrelasp)
9c19a809 636{
2cf0635d 637 Elf_Internal_Rela * relas;
4d6ed7c8
NC
638 unsigned long nrelas;
639 unsigned int i;
252b5132 640
4d6ed7c8
NC
641 if (is_32bit_elf)
642 {
2cf0635d 643 Elf32_External_Rela * erelas;
103f02d3 644
3f5e193b
NC
645 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
646 rel_size, _("relocs"));
a6e9f9df
AM
647 if (!erelas)
648 return 0;
252b5132 649
4d6ed7c8 650 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 651
3f5e193b
NC
652 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
653 sizeof (Elf_Internal_Rela));
103f02d3 654
4d6ed7c8
NC
655 if (relas == NULL)
656 {
c256ffe7 657 free (erelas);
591a748a 658 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
659 return 0;
660 }
103f02d3 661
4d6ed7c8
NC
662 for (i = 0; i < nrelas; i++)
663 {
664 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
665 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 666 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 667 }
103f02d3 668
4d6ed7c8
NC
669 free (erelas);
670 }
671 else
672 {
2cf0635d 673 Elf64_External_Rela * erelas;
103f02d3 674
3f5e193b
NC
675 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
676 rel_size, _("relocs"));
a6e9f9df
AM
677 if (!erelas)
678 return 0;
4d6ed7c8
NC
679
680 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 681
3f5e193b
NC
682 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
683 sizeof (Elf_Internal_Rela));
103f02d3 684
4d6ed7c8
NC
685 if (relas == NULL)
686 {
c256ffe7 687 free (erelas);
591a748a 688 error (_("out of memory parsing relocs\n"));
4d6ed7c8 689 return 0;
9c19a809 690 }
4d6ed7c8
NC
691
692 for (i = 0; i < nrelas; i++)
9c19a809 693 {
66543521
AM
694 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
695 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 696 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
697
698 /* The #ifdef BFD64 below is to prevent a compile time
699 warning. We know that if we do not have a 64 bit data
700 type that we will never execute this code anyway. */
701#ifdef BFD64
702 if (elf_header.e_machine == EM_MIPS
703 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
704 {
705 /* In little-endian objects, r_info isn't really a
706 64-bit little-endian value: it has a 32-bit
707 little-endian symbol index followed by four
708 individual byte fields. Reorder INFO
709 accordingly. */
91d6fa6a
NC
710 bfd_vma inf = relas[i].r_info;
711 inf = (((inf & 0xffffffff) << 32)
712 | ((inf >> 56) & 0xff)
713 | ((inf >> 40) & 0xff00)
714 | ((inf >> 24) & 0xff0000)
715 | ((inf >> 8) & 0xff000000));
716 relas[i].r_info = inf;
861fb55a
DJ
717 }
718#endif /* BFD64 */
4d6ed7c8 719 }
103f02d3 720
4d6ed7c8
NC
721 free (erelas);
722 }
723 *relasp = relas;
724 *nrelasp = nrelas;
725 return 1;
726}
103f02d3 727
4d6ed7c8 728static int
2cf0635d 729slurp_rel_relocs (FILE * file,
d3ba0551
AM
730 unsigned long rel_offset,
731 unsigned long rel_size,
2cf0635d
NC
732 Elf_Internal_Rela ** relsp,
733 unsigned long * nrelsp)
4d6ed7c8 734{
2cf0635d 735 Elf_Internal_Rela * rels;
4d6ed7c8
NC
736 unsigned long nrels;
737 unsigned int i;
103f02d3 738
4d6ed7c8
NC
739 if (is_32bit_elf)
740 {
2cf0635d 741 Elf32_External_Rel * erels;
103f02d3 742
3f5e193b
NC
743 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
744 rel_size, _("relocs"));
a6e9f9df
AM
745 if (!erels)
746 return 0;
103f02d3 747
4d6ed7c8 748 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 749
3f5e193b 750 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 751
4d6ed7c8
NC
752 if (rels == NULL)
753 {
c256ffe7 754 free (erels);
591a748a 755 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
756 return 0;
757 }
758
759 for (i = 0; i < nrels; i++)
760 {
761 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
762 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 763 rels[i].r_addend = 0;
9ea033b2 764 }
4d6ed7c8
NC
765
766 free (erels);
9c19a809
NC
767 }
768 else
769 {
2cf0635d 770 Elf64_External_Rel * erels;
9ea033b2 771
3f5e193b
NC
772 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
773 rel_size, _("relocs"));
a6e9f9df
AM
774 if (!erels)
775 return 0;
103f02d3 776
4d6ed7c8 777 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 778
3f5e193b 779 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 780
4d6ed7c8 781 if (rels == NULL)
9c19a809 782 {
c256ffe7 783 free (erels);
591a748a 784 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
785 return 0;
786 }
103f02d3 787
4d6ed7c8
NC
788 for (i = 0; i < nrels; i++)
789 {
66543521
AM
790 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
791 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 792 rels[i].r_addend = 0;
861fb55a
DJ
793
794 /* The #ifdef BFD64 below is to prevent a compile time
795 warning. We know that if we do not have a 64 bit data
796 type that we will never execute this code anyway. */
797#ifdef BFD64
798 if (elf_header.e_machine == EM_MIPS
799 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
800 {
801 /* In little-endian objects, r_info isn't really a
802 64-bit little-endian value: it has a 32-bit
803 little-endian symbol index followed by four
804 individual byte fields. Reorder INFO
805 accordingly. */
91d6fa6a
NC
806 bfd_vma inf = rels[i].r_info;
807 inf = (((inf & 0xffffffff) << 32)
808 | ((inf >> 56) & 0xff)
809 | ((inf >> 40) & 0xff00)
810 | ((inf >> 24) & 0xff0000)
811 | ((inf >> 8) & 0xff000000));
812 rels[i].r_info = inf;
861fb55a
DJ
813 }
814#endif /* BFD64 */
4d6ed7c8 815 }
103f02d3 816
4d6ed7c8
NC
817 free (erels);
818 }
819 *relsp = rels;
820 *nrelsp = nrels;
821 return 1;
822}
103f02d3 823
aca88567
NC
824/* Returns the reloc type extracted from the reloc info field. */
825
826static unsigned int
827get_reloc_type (bfd_vma reloc_info)
828{
829 if (is_32bit_elf)
830 return ELF32_R_TYPE (reloc_info);
831
832 switch (elf_header.e_machine)
833 {
834 case EM_MIPS:
835 /* Note: We assume that reloc_info has already been adjusted for us. */
836 return ELF64_MIPS_R_TYPE (reloc_info);
837
838 case EM_SPARCV9:
839 return ELF64_R_TYPE_ID (reloc_info);
840
841 default:
842 return ELF64_R_TYPE (reloc_info);
843 }
844}
845
846/* Return the symbol index extracted from the reloc info field. */
847
848static bfd_vma
849get_reloc_symindex (bfd_vma reloc_info)
850{
851 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
852}
853
d3ba0551
AM
854/* Display the contents of the relocation data found at the specified
855 offset. */
ee42cf8c 856
41e92641 857static void
2cf0635d 858dump_relocations (FILE * file,
d3ba0551
AM
859 unsigned long rel_offset,
860 unsigned long rel_size,
2cf0635d 861 Elf_Internal_Sym * symtab,
d3ba0551 862 unsigned long nsyms,
2cf0635d 863 char * strtab,
d79b3d50 864 unsigned long strtablen,
d3ba0551 865 int is_rela)
4d6ed7c8 866{
b34976b6 867 unsigned int i;
2cf0635d 868 Elf_Internal_Rela * rels;
103f02d3 869
4d6ed7c8
NC
870 if (is_rela == UNKNOWN)
871 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 872
4d6ed7c8
NC
873 if (is_rela)
874 {
c8286bd1 875 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 876 return;
4d6ed7c8
NC
877 }
878 else
879 {
880 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 881 return;
252b5132
RH
882 }
883
410f7a12
L
884 if (is_32bit_elf)
885 {
886 if (is_rela)
2c71103e
NC
887 {
888 if (do_wide)
889 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
890 else
891 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
892 }
410f7a12 893 else
2c71103e
NC
894 {
895 if (do_wide)
896 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
897 else
898 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
899 }
410f7a12 900 }
252b5132 901 else
410f7a12
L
902 {
903 if (is_rela)
2c71103e
NC
904 {
905 if (do_wide)
8beeaeb7 906 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
907 else
908 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
909 }
410f7a12 910 else
2c71103e
NC
911 {
912 if (do_wide)
8beeaeb7 913 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
914 else
915 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
916 }
410f7a12 917 }
252b5132
RH
918
919 for (i = 0; i < rel_size; i++)
920 {
2cf0635d 921 const char * rtype;
b34976b6 922 bfd_vma offset;
91d6fa6a 923 bfd_vma inf;
b34976b6
AM
924 bfd_vma symtab_index;
925 bfd_vma type;
103f02d3 926
b34976b6 927 offset = rels[i].r_offset;
91d6fa6a 928 inf = rels[i].r_info;
103f02d3 929
91d6fa6a
NC
930 type = get_reloc_type (inf);
931 symtab_index = get_reloc_symindex (inf);
252b5132 932
410f7a12
L
933 if (is_32bit_elf)
934 {
39dbeff8
AM
935 printf ("%8.8lx %8.8lx ",
936 (unsigned long) offset & 0xffffffff,
91d6fa6a 937 (unsigned long) inf & 0xffffffff);
410f7a12
L
938 }
939 else
940 {
39dbeff8
AM
941#if BFD_HOST_64BIT_LONG
942 printf (do_wide
943 ? "%16.16lx %16.16lx "
944 : "%12.12lx %12.12lx ",
91d6fa6a 945 offset, inf);
39dbeff8 946#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 947#ifndef __MSVCRT__
39dbeff8
AM
948 printf (do_wide
949 ? "%16.16llx %16.16llx "
950 : "%12.12llx %12.12llx ",
91d6fa6a 951 offset, inf);
6e3d6dc1
NC
952#else
953 printf (do_wide
954 ? "%16.16I64x %16.16I64x "
955 : "%12.12I64x %12.12I64x ",
91d6fa6a 956 offset, inf);
6e3d6dc1 957#endif
39dbeff8 958#else
2c71103e
NC
959 printf (do_wide
960 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
961 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
962 _bfd_int64_high (offset),
963 _bfd_int64_low (offset),
91d6fa6a
NC
964 _bfd_int64_high (inf),
965 _bfd_int64_low (inf));
9ea033b2 966#endif
410f7a12 967 }
103f02d3 968
252b5132
RH
969 switch (elf_header.e_machine)
970 {
971 default:
972 rtype = NULL;
973 break;
974
2b0337b0 975 case EM_M32R:
252b5132 976 case EM_CYGNUS_M32R:
9ea033b2 977 rtype = elf_m32r_reloc_type (type);
252b5132
RH
978 break;
979
980 case EM_386:
981 case EM_486:
9ea033b2 982 rtype = elf_i386_reloc_type (type);
252b5132
RH
983 break;
984
ba2685cc
AM
985 case EM_68HC11:
986 case EM_68HC12:
987 rtype = elf_m68hc11_reloc_type (type);
988 break;
75751cd9 989
252b5132 990 case EM_68K:
9ea033b2 991 rtype = elf_m68k_reloc_type (type);
252b5132
RH
992 break;
993
63fcb9e9 994 case EM_960:
9ea033b2 995 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
996 break;
997
adde6300 998 case EM_AVR:
2b0337b0 999 case EM_AVR_OLD:
adde6300
AM
1000 rtype = elf_avr_reloc_type (type);
1001 break;
1002
9ea033b2
NC
1003 case EM_OLD_SPARCV9:
1004 case EM_SPARC32PLUS:
1005 case EM_SPARCV9:
252b5132 1006 case EM_SPARC:
9ea033b2 1007 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1008 break;
1009
e9f53129
AM
1010 case EM_SPU:
1011 rtype = elf_spu_reloc_type (type);
1012 break;
1013
2b0337b0 1014 case EM_V850:
252b5132 1015 case EM_CYGNUS_V850:
9ea033b2 1016 rtype = v850_reloc_type (type);
252b5132
RH
1017 break;
1018
2b0337b0 1019 case EM_D10V:
252b5132 1020 case EM_CYGNUS_D10V:
9ea033b2 1021 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1022 break;
1023
2b0337b0 1024 case EM_D30V:
252b5132 1025 case EM_CYGNUS_D30V:
9ea033b2 1026 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1027 break;
1028
d172d4ba
NC
1029 case EM_DLX:
1030 rtype = elf_dlx_reloc_type (type);
1031 break;
1032
252b5132 1033 case EM_SH:
9ea033b2 1034 rtype = elf_sh_reloc_type (type);
252b5132
RH
1035 break;
1036
2b0337b0 1037 case EM_MN10300:
252b5132 1038 case EM_CYGNUS_MN10300:
9ea033b2 1039 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1040 break;
1041
2b0337b0 1042 case EM_MN10200:
252b5132 1043 case EM_CYGNUS_MN10200:
9ea033b2 1044 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1045 break;
1046
2b0337b0 1047 case EM_FR30:
252b5132 1048 case EM_CYGNUS_FR30:
9ea033b2 1049 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1050 break;
1051
ba2685cc
AM
1052 case EM_CYGNUS_FRV:
1053 rtype = elf_frv_reloc_type (type);
1054 break;
5c70f934 1055
252b5132 1056 case EM_MCORE:
9ea033b2 1057 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1058 break;
1059
3c3bdf30
NC
1060 case EM_MMIX:
1061 rtype = elf_mmix_reloc_type (type);
1062 break;
1063
5506d11a
AM
1064 case EM_MOXIE:
1065 rtype = elf_moxie_reloc_type (type);
1066 break;
1067
2469cfa2
NC
1068 case EM_MSP430:
1069 case EM_MSP430_OLD:
1070 rtype = elf_msp430_reloc_type (type);
1071 break;
1072
252b5132 1073 case EM_PPC:
9ea033b2 1074 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1075 break;
1076
c833c019
AM
1077 case EM_PPC64:
1078 rtype = elf_ppc64_reloc_type (type);
1079 break;
1080
252b5132 1081 case EM_MIPS:
4fe85591 1082 case EM_MIPS_RS3_LE:
9ea033b2 1083 rtype = elf_mips_reloc_type (type);
252b5132
RH
1084 break;
1085
1086 case EM_ALPHA:
9ea033b2 1087 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1088 break;
1089
1090 case EM_ARM:
9ea033b2 1091 rtype = elf_arm_reloc_type (type);
252b5132
RH
1092 break;
1093
584da044 1094 case EM_ARC:
9ea033b2 1095 rtype = elf_arc_reloc_type (type);
252b5132
RH
1096 break;
1097
1098 case EM_PARISC:
69e617ca 1099 rtype = elf_hppa_reloc_type (type);
252b5132 1100 break;
7d466069 1101
b8720f9d
JL
1102 case EM_H8_300:
1103 case EM_H8_300H:
1104 case EM_H8S:
1105 rtype = elf_h8_reloc_type (type);
1106 break;
1107
3b16e843
NC
1108 case EM_OPENRISC:
1109 case EM_OR32:
1110 rtype = elf_or32_reloc_type (type);
1111 break;
1112
7d466069 1113 case EM_PJ:
2b0337b0 1114 case EM_PJ_OLD:
7d466069
ILT
1115 rtype = elf_pj_reloc_type (type);
1116 break;
800eeca4
JW
1117 case EM_IA_64:
1118 rtype = elf_ia64_reloc_type (type);
1119 break;
1b61cf92
HPN
1120
1121 case EM_CRIS:
1122 rtype = elf_cris_reloc_type (type);
1123 break;
535c37ff
JE
1124
1125 case EM_860:
1126 rtype = elf_i860_reloc_type (type);
1127 break;
bcedfee6
NC
1128
1129 case EM_X86_64:
8a9036a4 1130 case EM_L1OM:
bcedfee6
NC
1131 rtype = elf_x86_64_reloc_type (type);
1132 break;
a85d7ed0 1133
35b1837e
AM
1134 case EM_S370:
1135 rtype = i370_reloc_type (type);
1136 break;
1137
53c7db4b
KH
1138 case EM_S390_OLD:
1139 case EM_S390:
1140 rtype = elf_s390_reloc_type (type);
1141 break;
93fbbb04 1142
1c0d3aa6
NC
1143 case EM_SCORE:
1144 rtype = elf_score_reloc_type (type);
1145 break;
1146
93fbbb04
GK
1147 case EM_XSTORMY16:
1148 rtype = elf_xstormy16_reloc_type (type);
1149 break;
179d3252 1150
1fe1f39c
NC
1151 case EM_CRX:
1152 rtype = elf_crx_reloc_type (type);
1153 break;
1154
179d3252
JT
1155 case EM_VAX:
1156 rtype = elf_vax_reloc_type (type);
1157 break;
1e4cf259
NC
1158
1159 case EM_IP2K:
1160 case EM_IP2K_OLD:
1161 rtype = elf_ip2k_reloc_type (type);
1162 break;
3b36097d
SC
1163
1164 case EM_IQ2000:
1165 rtype = elf_iq2000_reloc_type (type);
1166 break;
88da6820
NC
1167
1168 case EM_XTENSA_OLD:
1169 case EM_XTENSA:
1170 rtype = elf_xtensa_reloc_type (type);
1171 break;
a34e3ecb 1172
84e94c90
NC
1173 case EM_LATTICEMICO32:
1174 rtype = elf_lm32_reloc_type (type);
1175 break;
1176
ff7eeb89 1177 case EM_M32C_OLD:
49f58d10
JB
1178 case EM_M32C:
1179 rtype = elf_m32c_reloc_type (type);
1180 break;
1181
d031aafb
NS
1182 case EM_MT:
1183 rtype = elf_mt_reloc_type (type);
a34e3ecb 1184 break;
1d65ded4
CM
1185
1186 case EM_BLACKFIN:
1187 rtype = elf_bfin_reloc_type (type);
1188 break;
15ab5209
DB
1189
1190 case EM_CYGNUS_MEP:
1191 rtype = elf_mep_reloc_type (type);
1192 break;
60bca95a
NC
1193
1194 case EM_CR16:
6c03b1ed 1195 case EM_CR16_OLD:
60bca95a
NC
1196 rtype = elf_cr16_reloc_type (type);
1197 break;
dd24e3da 1198
7ba29e2a
NC
1199 case EM_MICROBLAZE:
1200 case EM_MICROBLAZE_OLD:
1201 rtype = elf_microblaze_reloc_type (type);
1202 break;
c7927a3c
NC
1203
1204 case EM_RX:
1205 rtype = elf_rx_reloc_type (type);
1206 break;
c29aca4a
NC
1207
1208 case EM_XC16X:
1209 case EM_C166:
1210 rtype = elf_xc16x_reloc_type (type);
1211 break;
40b36596
JM
1212
1213 case EM_TI_C6000:
1214 rtype = elf_tic6x_reloc_type (type);
1215 break;
252b5132
RH
1216 }
1217
1218 if (rtype == NULL)
39dbeff8 1219 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1220 else
8beeaeb7 1221 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1222
7ace3541 1223 if (elf_header.e_machine == EM_ALPHA
157c2599 1224 && rtype != NULL
7ace3541
RH
1225 && streq (rtype, "R_ALPHA_LITUSE")
1226 && is_rela)
1227 {
1228 switch (rels[i].r_addend)
1229 {
1230 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1231 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1232 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1233 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1234 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1235 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1236 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1237 default: rtype = NULL;
1238 }
1239 if (rtype)
1240 printf (" (%s)", rtype);
1241 else
1242 {
1243 putchar (' ');
1244 printf (_("<unknown addend: %lx>"),
1245 (unsigned long) rels[i].r_addend);
1246 }
1247 }
1248 else if (symtab_index)
252b5132 1249 {
af3fc3bc 1250 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1251 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1252 else
19936277 1253 {
2cf0635d 1254 Elf_Internal_Sym * psym;
19936277 1255
af3fc3bc 1256 psym = symtab + symtab_index;
103f02d3 1257
af3fc3bc 1258 printf (" ");
171191ba 1259
d8045f23
NC
1260 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1261 {
1262 const char * name;
1263 unsigned int len;
1264 unsigned int width = is_32bit_elf ? 8 : 14;
1265
1266 /* Relocations against GNU_IFUNC symbols do not use the value
1267 of the symbol as the address to relocate against. Instead
1268 they invoke the function named by the symbol and use its
1269 result as the address for relocation.
1270
1271 To indicate this to the user, do not display the value of
1272 the symbol in the "Symbols's Value" field. Instead show
1273 its name followed by () as a hint that the symbol is
1274 invoked. */
1275
1276 if (strtab == NULL
1277 || psym->st_name == 0
1278 || psym->st_name >= strtablen)
1279 name = "??";
1280 else
1281 name = strtab + psym->st_name;
1282
1283 len = print_symbol (width, name);
1284 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1285 }
1286 else
1287 {
1288 print_vma (psym->st_value, LONG_HEX);
171191ba 1289
d8045f23
NC
1290 printf (is_32bit_elf ? " " : " ");
1291 }
103f02d3 1292
af3fc3bc 1293 if (psym->st_name == 0)
f1ef08cb 1294 {
2cf0635d 1295 const char * sec_name = "<null>";
f1ef08cb
AM
1296 char name_buf[40];
1297
1298 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1299 {
4fbb74a6
AM
1300 if (psym->st_shndx < elf_header.e_shnum)
1301 sec_name
1302 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1303 else if (psym->st_shndx == SHN_ABS)
1304 sec_name = "ABS";
1305 else if (psym->st_shndx == SHN_COMMON)
1306 sec_name = "COMMON";
ac145307
BS
1307 else if ((elf_header.e_machine == EM_MIPS
1308 && psym->st_shndx == SHN_MIPS_SCOMMON)
1309 || (elf_header.e_machine == EM_TI_C6000
1310 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1311 sec_name = "SCOMMON";
1312 else if (elf_header.e_machine == EM_MIPS
1313 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1314 sec_name = "SUNDEF";
8a9036a4
L
1315 else if ((elf_header.e_machine == EM_X86_64
1316 || elf_header.e_machine == EM_L1OM)
3b22753a
L
1317 && psym->st_shndx == SHN_X86_64_LCOMMON)
1318 sec_name = "LARGE_COMMON";
9ce701e2
L
1319 else if (elf_header.e_machine == EM_IA_64
1320 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1321 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1322 sec_name = "ANSI_COM";
28f997cf 1323 else if (is_ia64_vms ()
148b93f2
NC
1324 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1325 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1326 else
1327 {
1328 sprintf (name_buf, "<section 0x%x>",
1329 (unsigned int) psym->st_shndx);
1330 sec_name = name_buf;
1331 }
1332 }
1333 print_symbol (22, sec_name);
1334 }
af3fc3bc 1335 else if (strtab == NULL)
d79b3d50 1336 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1337 else if (psym->st_name >= strtablen)
d79b3d50 1338 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1339 else
2c71103e 1340 print_symbol (22, strtab + psym->st_name);
103f02d3 1341
af3fc3bc 1342 if (is_rela)
171191ba 1343 {
598aaa76 1344 bfd_signed_vma off = rels[i].r_addend;
171191ba 1345
91d6fa6a 1346 if (off < 0)
598aaa76 1347 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1348 else
598aaa76 1349 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1350 }
19936277 1351 }
252b5132 1352 }
1b228002 1353 else if (is_rela)
f7a99963 1354 {
18bd398b
NC
1355 printf ("%*c", is_32bit_elf ?
1356 (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
c8286bd1 1357 print_vma (rels[i].r_addend, LONG_HEX);
f7a99963 1358 }
252b5132 1359
157c2599
NC
1360 if (elf_header.e_machine == EM_SPARCV9
1361 && rtype != NULL
1362 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1363 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1364
252b5132 1365 putchar ('\n');
2c71103e 1366
aca88567 1367#ifdef BFD64
53c7db4b 1368 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1369 {
91d6fa6a
NC
1370 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1371 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1372 const char * rtype2 = elf_mips_reloc_type (type2);
1373 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1374
2c71103e
NC
1375 printf (" Type2: ");
1376
1377 if (rtype2 == NULL)
39dbeff8
AM
1378 printf (_("unrecognized: %-7lx"),
1379 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1380 else
1381 printf ("%-17.17s", rtype2);
1382
18bd398b 1383 printf ("\n Type3: ");
2c71103e
NC
1384
1385 if (rtype3 == NULL)
39dbeff8
AM
1386 printf (_("unrecognized: %-7lx"),
1387 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1388 else
1389 printf ("%-17.17s", rtype3);
1390
53c7db4b 1391 putchar ('\n');
2c71103e 1392 }
aca88567 1393#endif /* BFD64 */
252b5132
RH
1394 }
1395
c8286bd1 1396 free (rels);
252b5132
RH
1397}
1398
1399static const char *
d3ba0551 1400get_mips_dynamic_type (unsigned long type)
252b5132
RH
1401{
1402 switch (type)
1403 {
1404 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1405 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1406 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1407 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1408 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1409 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1410 case DT_MIPS_MSYM: return "MIPS_MSYM";
1411 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1412 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1413 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1414 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1415 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1416 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1417 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1418 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1419 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1420 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1421 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1422 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1423 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1424 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1425 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1426 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1427 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1428 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1429 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1430 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1431 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1432 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1433 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1434 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1435 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1436 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1437 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1438 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1439 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1440 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1441 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1442 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1443 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1444 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1445 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1446 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1447 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1448 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1449 default:
1450 return NULL;
1451 }
1452}
1453
9a097730 1454static const char *
d3ba0551 1455get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1456{
1457 switch (type)
1458 {
1459 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1460 default:
1461 return NULL;
1462 }
103f02d3
UD
1463}
1464
7490d522
AM
1465static const char *
1466get_ppc_dynamic_type (unsigned long type)
1467{
1468 switch (type)
1469 {
a7f2871e
AM
1470 case DT_PPC_GOT: return "PPC_GOT";
1471 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1472 default:
1473 return NULL;
1474 }
1475}
1476
f1cb7e17 1477static const char *
d3ba0551 1478get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1479{
1480 switch (type)
1481 {
a7f2871e
AM
1482 case DT_PPC64_GLINK: return "PPC64_GLINK";
1483 case DT_PPC64_OPD: return "PPC64_OPD";
1484 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1485 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1486 default:
1487 return NULL;
1488 }
1489}
1490
103f02d3 1491static const char *
d3ba0551 1492get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1493{
1494 switch (type)
1495 {
1496 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1497 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1498 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1499 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1500 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1501 case DT_HP_PREINIT: return "HP_PREINIT";
1502 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1503 case DT_HP_NEEDED: return "HP_NEEDED";
1504 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1505 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1506 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1507 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1508 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1509 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1510 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1511 case DT_HP_FILTERED: return "HP_FILTERED";
1512 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1513 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1514 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1515 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1516 case DT_PLT: return "PLT";
1517 case DT_PLT_SIZE: return "PLT_SIZE";
1518 case DT_DLT: return "DLT";
1519 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1520 default:
1521 return NULL;
1522 }
1523}
9a097730 1524
ecc51f48 1525static const char *
d3ba0551 1526get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1527{
1528 switch (type)
1529 {
148b93f2
NC
1530 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1531 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1532 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1533 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1534 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1535 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1536 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1537 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1538 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1539 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1540 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1541 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1542 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1543 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1544 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1545 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1546 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1547 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1548 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1549 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1550 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1551 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1552 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1553 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1554 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1555 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1556 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1557 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1558 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1559 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1560 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1561 default:
1562 return NULL;
1563 }
1564}
1565
fabcb361
RH
1566static const char *
1567get_alpha_dynamic_type (unsigned long type)
1568{
1569 switch (type)
1570 {
1571 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1572 default:
1573 return NULL;
1574 }
1575}
1576
1c0d3aa6
NC
1577static const char *
1578get_score_dynamic_type (unsigned long type)
1579{
1580 switch (type)
1581 {
1582 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1583 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1584 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1585 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1586 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1587 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1588 default:
1589 return NULL;
1590 }
1591}
1592
40b36596
JM
1593static const char *
1594get_tic6x_dynamic_type (unsigned long type)
1595{
1596 switch (type)
1597 {
1598 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1599 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1600 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1601 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1602 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1603 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1604 default:
1605 return NULL;
1606 }
1607}
1c0d3aa6 1608
252b5132 1609static const char *
d3ba0551 1610get_dynamic_type (unsigned long type)
252b5132 1611{
e9e44622 1612 static char buff[64];
252b5132
RH
1613
1614 switch (type)
1615 {
1616 case DT_NULL: return "NULL";
1617 case DT_NEEDED: return "NEEDED";
1618 case DT_PLTRELSZ: return "PLTRELSZ";
1619 case DT_PLTGOT: return "PLTGOT";
1620 case DT_HASH: return "HASH";
1621 case DT_STRTAB: return "STRTAB";
1622 case DT_SYMTAB: return "SYMTAB";
1623 case DT_RELA: return "RELA";
1624 case DT_RELASZ: return "RELASZ";
1625 case DT_RELAENT: return "RELAENT";
1626 case DT_STRSZ: return "STRSZ";
1627 case DT_SYMENT: return "SYMENT";
1628 case DT_INIT: return "INIT";
1629 case DT_FINI: return "FINI";
1630 case DT_SONAME: return "SONAME";
1631 case DT_RPATH: return "RPATH";
1632 case DT_SYMBOLIC: return "SYMBOLIC";
1633 case DT_REL: return "REL";
1634 case DT_RELSZ: return "RELSZ";
1635 case DT_RELENT: return "RELENT";
1636 case DT_PLTREL: return "PLTREL";
1637 case DT_DEBUG: return "DEBUG";
1638 case DT_TEXTREL: return "TEXTREL";
1639 case DT_JMPREL: return "JMPREL";
1640 case DT_BIND_NOW: return "BIND_NOW";
1641 case DT_INIT_ARRAY: return "INIT_ARRAY";
1642 case DT_FINI_ARRAY: return "FINI_ARRAY";
1643 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1644 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1645 case DT_RUNPATH: return "RUNPATH";
1646 case DT_FLAGS: return "FLAGS";
2d0e6f43 1647
d1133906
NC
1648 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1649 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1650
05107a46 1651 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1652 case DT_PLTPADSZ: return "PLTPADSZ";
1653 case DT_MOVEENT: return "MOVEENT";
1654 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1655 case DT_FEATURE: return "FEATURE";
252b5132
RH
1656 case DT_POSFLAG_1: return "POSFLAG_1";
1657 case DT_SYMINSZ: return "SYMINSZ";
1658 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1659
252b5132 1660 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1661 case DT_CONFIG: return "CONFIG";
1662 case DT_DEPAUDIT: return "DEPAUDIT";
1663 case DT_AUDIT: return "AUDIT";
1664 case DT_PLTPAD: return "PLTPAD";
1665 case DT_MOVETAB: return "MOVETAB";
252b5132 1666 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1667
252b5132 1668 case DT_VERSYM: return "VERSYM";
103f02d3 1669
67a4f2b7
AO
1670 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1671 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1672 case DT_RELACOUNT: return "RELACOUNT";
1673 case DT_RELCOUNT: return "RELCOUNT";
1674 case DT_FLAGS_1: return "FLAGS_1";
1675 case DT_VERDEF: return "VERDEF";
1676 case DT_VERDEFNUM: return "VERDEFNUM";
1677 case DT_VERNEED: return "VERNEED";
1678 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1679
019148e4 1680 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1681 case DT_USED: return "USED";
1682 case DT_FILTER: return "FILTER";
103f02d3 1683
047b2264
JJ
1684 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1685 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1686 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1687 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1688 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1689 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1690
252b5132
RH
1691 default:
1692 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1693 {
2cf0635d 1694 const char * result;
103f02d3 1695
252b5132
RH
1696 switch (elf_header.e_machine)
1697 {
1698 case EM_MIPS:
4fe85591 1699 case EM_MIPS_RS3_LE:
252b5132
RH
1700 result = get_mips_dynamic_type (type);
1701 break;
9a097730
RH
1702 case EM_SPARCV9:
1703 result = get_sparc64_dynamic_type (type);
1704 break;
7490d522
AM
1705 case EM_PPC:
1706 result = get_ppc_dynamic_type (type);
1707 break;
f1cb7e17
AM
1708 case EM_PPC64:
1709 result = get_ppc64_dynamic_type (type);
1710 break;
ecc51f48
NC
1711 case EM_IA_64:
1712 result = get_ia64_dynamic_type (type);
1713 break;
fabcb361
RH
1714 case EM_ALPHA:
1715 result = get_alpha_dynamic_type (type);
1716 break;
1c0d3aa6
NC
1717 case EM_SCORE:
1718 result = get_score_dynamic_type (type);
1719 break;
40b36596
JM
1720 case EM_TI_C6000:
1721 result = get_tic6x_dynamic_type (type);
1722 break;
252b5132
RH
1723 default:
1724 result = NULL;
1725 break;
1726 }
1727
1728 if (result != NULL)
1729 return result;
1730
e9e44622 1731 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1732 }
eec8f817
DA
1733 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1734 || (elf_header.e_machine == EM_PARISC
1735 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1736 {
2cf0635d 1737 const char * result;
103f02d3
UD
1738
1739 switch (elf_header.e_machine)
1740 {
1741 case EM_PARISC:
1742 result = get_parisc_dynamic_type (type);
1743 break;
148b93f2
NC
1744 case EM_IA_64:
1745 result = get_ia64_dynamic_type (type);
1746 break;
103f02d3
UD
1747 default:
1748 result = NULL;
1749 break;
1750 }
1751
1752 if (result != NULL)
1753 return result;
1754
e9e44622
JJ
1755 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1756 type);
103f02d3 1757 }
252b5132 1758 else
e9e44622 1759 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1760
252b5132
RH
1761 return buff;
1762 }
1763}
1764
1765static char *
d3ba0551 1766get_file_type (unsigned e_type)
252b5132 1767{
b34976b6 1768 static char buff[32];
252b5132
RH
1769
1770 switch (e_type)
1771 {
1772 case ET_NONE: return _("NONE (None)");
1773 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1774 case ET_EXEC: return _("EXEC (Executable file)");
1775 case ET_DYN: return _("DYN (Shared object file)");
1776 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1777
1778 default:
1779 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1780 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1781 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1782 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1783 else
e9e44622 1784 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1785 return buff;
1786 }
1787}
1788
1789static char *
d3ba0551 1790get_machine_name (unsigned e_machine)
252b5132 1791{
b34976b6 1792 static char buff[64]; /* XXX */
252b5132
RH
1793
1794 switch (e_machine)
1795 {
c45021f2
NC
1796 case EM_NONE: return _("None");
1797 case EM_M32: return "WE32100";
1798 case EM_SPARC: return "Sparc";
e9f53129 1799 case EM_SPU: return "SPU";
c45021f2
NC
1800 case EM_386: return "Intel 80386";
1801 case EM_68K: return "MC68000";
1802 case EM_88K: return "MC88000";
1803 case EM_486: return "Intel 80486";
1804 case EM_860: return "Intel 80860";
1805 case EM_MIPS: return "MIPS R3000";
1806 case EM_S370: return "IBM System/370";
7036c0e1 1807 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1808 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1809 case EM_PARISC: return "HPPA";
252b5132 1810 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1811 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1812 case EM_960: return "Intel 90860";
1813 case EM_PPC: return "PowerPC";
285d1771 1814 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1815 case EM_V800: return "NEC V800";
1816 case EM_FR20: return "Fujitsu FR20";
1817 case EM_RH32: return "TRW RH32";
b34976b6 1818 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1819 case EM_ARM: return "ARM";
1820 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1821 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1822 case EM_SPARCV9: return "Sparc v9";
1823 case EM_TRICORE: return "Siemens Tricore";
584da044 1824 case EM_ARC: return "ARC";
c2dcd04e
NC
1825 case EM_H8_300: return "Renesas H8/300";
1826 case EM_H8_300H: return "Renesas H8/300H";
1827 case EM_H8S: return "Renesas H8S";
1828 case EM_H8_500: return "Renesas H8/500";
30800947 1829 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1830 case EM_MIPS_X: return "Stanford MIPS-X";
1831 case EM_COLDFIRE: return "Motorola Coldfire";
1832 case EM_68HC12: return "Motorola M68HC12";
c45021f2 1833 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1834 case EM_CYGNUS_D10V:
1835 case EM_D10V: return "d10v";
1836 case EM_CYGNUS_D30V:
b34976b6 1837 case EM_D30V: return "d30v";
2b0337b0 1838 case EM_CYGNUS_M32R:
26597c86 1839 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1840 case EM_CYGNUS_V850:
8f7e76d0 1841 case EM_V850: return "Renesas v850";
2b0337b0
AO
1842 case EM_CYGNUS_MN10300:
1843 case EM_MN10300: return "mn10300";
1844 case EM_CYGNUS_MN10200:
1845 case EM_MN10200: return "mn10200";
5506d11a 1846 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1847 case EM_CYGNUS_FR30:
1848 case EM_FR30: return "Fujitsu FR30";
b34976b6 1849 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1850 case EM_PJ_OLD:
b34976b6 1851 case EM_PJ: return "picoJava";
7036c0e1
AJ
1852 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1853 case EM_PCP: return "Siemens PCP";
1854 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1855 case EM_NDR1: return "Denso NDR1 microprocesspr";
1856 case EM_STARCORE: return "Motorola Star*Core processor";
1857 case EM_ME16: return "Toyota ME16 processor";
1858 case EM_ST100: return "STMicroelectronics ST100 processor";
1859 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1860 case EM_PDSP: return "Sony DSP processor";
1861 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1862 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1863 case EM_FX66: return "Siemens FX66 microcontroller";
1864 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1865 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1866 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
1867 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1868 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1869 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1870 case EM_SVX: return "Silicon Graphics SVx";
1871 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1872 case EM_VAX: return "Digital VAX";
2b0337b0 1873 case EM_AVR_OLD:
b34976b6 1874 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1875 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1876 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1877 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1878 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1879 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1880 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1881 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1882 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1883 case EM_L1OM: return "Intel L1OM";
b7498e0e 1884 case EM_S390_OLD:
b34976b6 1885 case EM_S390: return "IBM S/390";
1c0d3aa6 1886 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1887 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1888 case EM_OPENRISC:
1889 case EM_OR32: return "OpenRISC";
11636f9e 1890 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1891 case EM_CRX: return "National Semiconductor CRX microprocessor";
d172d4ba 1892 case EM_DLX: return "OpenDLX";
1e4cf259 1893 case EM_IP2K_OLD:
b34976b6 1894 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1895 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1896 case EM_XTENSA_OLD:
1897 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1898 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1899 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1900 case EM_NS32K: return "National Semiconductor 32000 series";
1901 case EM_TPC: return "Tenor Network TPC processor";
1902 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1903 case EM_MAX: return "MAX Processor";
1904 case EM_CR: return "National Semiconductor CompactRISC";
1905 case EM_F2MC16: return "Fujitsu F2MC16";
1906 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1907 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1908 case EM_M32C_OLD:
49f58d10 1909 case EM_M32C: return "Renesas M32c";
d031aafb 1910 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1911 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1912 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1913 case EM_SEP: return "Sharp embedded microprocessor";
1914 case EM_ARCA: return "Arca RISC microprocessor";
1915 case EM_UNICORE: return "Unicore";
1916 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1917 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1918 case EM_NIOS32: return "Altera Nios";
1919 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1920 case EM_C166:
d70c5fc7 1921 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
1922 case EM_M16C: return "Renesas M16C series microprocessors";
1923 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
1924 case EM_CE: return "Freescale Communication Engine RISC core";
1925 case EM_TSK3000: return "Altium TSK3000 core";
1926 case EM_RS08: return "Freescale RS08 embedded processor";
1927 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
1928 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
1929 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
1930 case EM_SE_C17: return "Seiko Epson C17 family";
1931 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
1932 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
1933 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
1934 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
1935 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
1936 case EM_R32C: return "Renesas R32C series microprocessors";
1937 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
1938 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
1939 case EM_8051: return "Intel 8051 and variants";
1940 case EM_STXP7X: return "STMicroelectronics STxP7x family";
1941 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
1942 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
1943 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
1944 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
1945 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
1946 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 1947 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 1948 case EM_CR16:
6c03b1ed 1949 case EM_CR16_OLD: return "National Semiconductor's CR16";
7ba29e2a
NC
1950 case EM_MICROBLAZE: return "Xilinx MicroBlaze";
1951 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
c7927a3c 1952 case EM_RX: return "Renesas RX";
11636f9e
JM
1953 case EM_METAG: return "Imagination Technologies META processor architecture";
1954 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
1955 case EM_ECOG16: return "Cyan Technology eCOG16 family";
1956 case EM_ETPU: return "Freescale Extended Time Processing Unit";
1957 case EM_SLE9X: return "Infineon Technologies SLE9X core";
1958 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
1959 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
1960 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
1961 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
1962 case EM_CUDA: return "NVIDIA CUDA architecture";
252b5132 1963 default:
35d9dd2f 1964 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
1965 return buff;
1966 }
1967}
1968
f3485b74 1969static void
d3ba0551 1970decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
1971{
1972 unsigned eabi;
1973 int unknown = 0;
1974
1975 eabi = EF_ARM_EABI_VERSION (e_flags);
1976 e_flags &= ~ EF_ARM_EABIMASK;
1977
1978 /* Handle "generic" ARM flags. */
1979 if (e_flags & EF_ARM_RELEXEC)
1980 {
1981 strcat (buf, ", relocatable executable");
1982 e_flags &= ~ EF_ARM_RELEXEC;
1983 }
76da6bbe 1984
f3485b74
NC
1985 if (e_flags & EF_ARM_HASENTRY)
1986 {
1987 strcat (buf, ", has entry point");
1988 e_flags &= ~ EF_ARM_HASENTRY;
1989 }
76da6bbe 1990
f3485b74
NC
1991 /* Now handle EABI specific flags. */
1992 switch (eabi)
1993 {
1994 default:
2c71103e 1995 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
1996 if (e_flags)
1997 unknown = 1;
1998 break;
1999
2000 case EF_ARM_EABI_VER1:
a5bcd848 2001 strcat (buf, ", Version1 EABI");
f3485b74
NC
2002 while (e_flags)
2003 {
2004 unsigned flag;
76da6bbe 2005
f3485b74
NC
2006 /* Process flags one bit at a time. */
2007 flag = e_flags & - e_flags;
2008 e_flags &= ~ flag;
76da6bbe 2009
f3485b74
NC
2010 switch (flag)
2011 {
a5bcd848 2012 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2013 strcat (buf, ", sorted symbol tables");
2014 break;
76da6bbe 2015
f3485b74
NC
2016 default:
2017 unknown = 1;
2018 break;
2019 }
2020 }
2021 break;
76da6bbe 2022
a5bcd848
PB
2023 case EF_ARM_EABI_VER2:
2024 strcat (buf, ", Version2 EABI");
2025 while (e_flags)
2026 {
2027 unsigned flag;
2028
2029 /* Process flags one bit at a time. */
2030 flag = e_flags & - e_flags;
2031 e_flags &= ~ flag;
2032
2033 switch (flag)
2034 {
2035 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2036 strcat (buf, ", sorted symbol tables");
2037 break;
2038
2039 case EF_ARM_DYNSYMSUSESEGIDX:
2040 strcat (buf, ", dynamic symbols use segment index");
2041 break;
2042
2043 case EF_ARM_MAPSYMSFIRST:
2044 strcat (buf, ", mapping symbols precede others");
2045 break;
2046
2047 default:
2048 unknown = 1;
2049 break;
2050 }
2051 }
2052 break;
2053
d507cf36
PB
2054 case EF_ARM_EABI_VER3:
2055 strcat (buf, ", Version3 EABI");
8cb51566
PB
2056 break;
2057
2058 case EF_ARM_EABI_VER4:
2059 strcat (buf, ", Version4 EABI");
3a4a14e9
PB
2060 goto eabi;
2061
2062 case EF_ARM_EABI_VER5:
2063 strcat (buf, ", Version5 EABI");
2064 eabi:
d507cf36
PB
2065 while (e_flags)
2066 {
2067 unsigned flag;
2068
2069 /* Process flags one bit at a time. */
2070 flag = e_flags & - e_flags;
2071 e_flags &= ~ flag;
2072
2073 switch (flag)
2074 {
2075 case EF_ARM_BE8:
2076 strcat (buf, ", BE8");
2077 break;
2078
2079 case EF_ARM_LE8:
2080 strcat (buf, ", LE8");
2081 break;
2082
2083 default:
2084 unknown = 1;
2085 break;
2086 }
2087 }
2088 break;
2089
f3485b74 2090 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2091 strcat (buf, ", GNU EABI");
f3485b74
NC
2092 while (e_flags)
2093 {
2094 unsigned flag;
76da6bbe 2095
f3485b74
NC
2096 /* Process flags one bit at a time. */
2097 flag = e_flags & - e_flags;
2098 e_flags &= ~ flag;
76da6bbe 2099
f3485b74
NC
2100 switch (flag)
2101 {
a5bcd848 2102 case EF_ARM_INTERWORK:
f3485b74
NC
2103 strcat (buf, ", interworking enabled");
2104 break;
76da6bbe 2105
a5bcd848 2106 case EF_ARM_APCS_26:
f3485b74
NC
2107 strcat (buf, ", uses APCS/26");
2108 break;
76da6bbe 2109
a5bcd848 2110 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2111 strcat (buf, ", uses APCS/float");
2112 break;
76da6bbe 2113
a5bcd848 2114 case EF_ARM_PIC:
f3485b74
NC
2115 strcat (buf, ", position independent");
2116 break;
76da6bbe 2117
a5bcd848 2118 case EF_ARM_ALIGN8:
f3485b74
NC
2119 strcat (buf, ", 8 bit structure alignment");
2120 break;
76da6bbe 2121
a5bcd848 2122 case EF_ARM_NEW_ABI:
f3485b74
NC
2123 strcat (buf, ", uses new ABI");
2124 break;
76da6bbe 2125
a5bcd848 2126 case EF_ARM_OLD_ABI:
f3485b74
NC
2127 strcat (buf, ", uses old ABI");
2128 break;
76da6bbe 2129
a5bcd848 2130 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2131 strcat (buf, ", software FP");
2132 break;
76da6bbe 2133
90e01f86
ILT
2134 case EF_ARM_VFP_FLOAT:
2135 strcat (buf, ", VFP");
2136 break;
2137
fde78edd
NC
2138 case EF_ARM_MAVERICK_FLOAT:
2139 strcat (buf, ", Maverick FP");
2140 break;
2141
f3485b74
NC
2142 default:
2143 unknown = 1;
2144 break;
2145 }
2146 }
2147 }
f3485b74
NC
2148
2149 if (unknown)
2b692964 2150 strcat (buf,_(", <unknown>"));
f3485b74
NC
2151}
2152
252b5132 2153static char *
d3ba0551 2154get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2155{
b34976b6 2156 static char buf[1024];
252b5132
RH
2157
2158 buf[0] = '\0';
76da6bbe 2159
252b5132
RH
2160 if (e_flags)
2161 {
2162 switch (e_machine)
2163 {
2164 default:
2165 break;
2166
f3485b74
NC
2167 case EM_ARM:
2168 decode_ARM_machine_flags (e_flags, buf);
2169 break;
76da6bbe 2170
781303ce
MF
2171 case EM_BLACKFIN:
2172 if (e_flags & EF_BFIN_PIC)
2173 strcat (buf, ", PIC");
2174
2175 if (e_flags & EF_BFIN_FDPIC)
2176 strcat (buf, ", FDPIC");
2177
2178 if (e_flags & EF_BFIN_CODE_IN_L1)
2179 strcat (buf, ", code in L1");
2180
2181 if (e_flags & EF_BFIN_DATA_IN_L1)
2182 strcat (buf, ", data in L1");
2183
2184 break;
2185
ec2dfb42
AO
2186 case EM_CYGNUS_FRV:
2187 switch (e_flags & EF_FRV_CPU_MASK)
2188 {
2189 case EF_FRV_CPU_GENERIC:
2190 break;
2191
2192 default:
2193 strcat (buf, ", fr???");
2194 break;
57346661 2195
ec2dfb42
AO
2196 case EF_FRV_CPU_FR300:
2197 strcat (buf, ", fr300");
2198 break;
2199
2200 case EF_FRV_CPU_FR400:
2201 strcat (buf, ", fr400");
2202 break;
2203 case EF_FRV_CPU_FR405:
2204 strcat (buf, ", fr405");
2205 break;
2206
2207 case EF_FRV_CPU_FR450:
2208 strcat (buf, ", fr450");
2209 break;
2210
2211 case EF_FRV_CPU_FR500:
2212 strcat (buf, ", fr500");
2213 break;
2214 case EF_FRV_CPU_FR550:
2215 strcat (buf, ", fr550");
2216 break;
2217
2218 case EF_FRV_CPU_SIMPLE:
2219 strcat (buf, ", simple");
2220 break;
2221 case EF_FRV_CPU_TOMCAT:
2222 strcat (buf, ", tomcat");
2223 break;
2224 }
1c877e87 2225 break;
ec2dfb42 2226
53c7db4b 2227 case EM_68K:
425c6cb0 2228 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2229 strcat (buf, ", m68000");
425c6cb0 2230 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2231 strcat (buf, ", cpu32");
2232 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2233 strcat (buf, ", fido_a");
425c6cb0 2234 else
266abb8f 2235 {
2cf0635d
NC
2236 char const * isa = _("unknown");
2237 char const * mac = _("unknown mac");
2238 char const * additional = NULL;
0112cd26 2239
c694fd50 2240 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2241 {
c694fd50 2242 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2243 isa = "A";
2244 additional = ", nodiv";
2245 break;
c694fd50 2246 case EF_M68K_CF_ISA_A:
266abb8f
NS
2247 isa = "A";
2248 break;
c694fd50 2249 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2250 isa = "A+";
2251 break;
c694fd50 2252 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2253 isa = "B";
2254 additional = ", nousp";
2255 break;
c694fd50 2256 case EF_M68K_CF_ISA_B:
266abb8f
NS
2257 isa = "B";
2258 break;
f608cd77
NS
2259 case EF_M68K_CF_ISA_C:
2260 isa = "C";
2261 break;
2262 case EF_M68K_CF_ISA_C_NODIV:
2263 isa = "C";
2264 additional = ", nodiv";
2265 break;
266abb8f
NS
2266 }
2267 strcat (buf, ", cf, isa ");
2268 strcat (buf, isa);
0b2e31dc
NS
2269 if (additional)
2270 strcat (buf, additional);
c694fd50 2271 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2272 strcat (buf, ", float");
c694fd50 2273 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2274 {
2275 case 0:
2276 mac = NULL;
2277 break;
c694fd50 2278 case EF_M68K_CF_MAC:
266abb8f
NS
2279 mac = "mac";
2280 break;
c694fd50 2281 case EF_M68K_CF_EMAC:
266abb8f
NS
2282 mac = "emac";
2283 break;
f608cd77
NS
2284 case EF_M68K_CF_EMAC_B:
2285 mac = "emac_b";
2286 break;
266abb8f
NS
2287 }
2288 if (mac)
2289 {
2290 strcat (buf, ", ");
2291 strcat (buf, mac);
2292 }
266abb8f 2293 }
53c7db4b 2294 break;
33c63f9d 2295
252b5132
RH
2296 case EM_PPC:
2297 if (e_flags & EF_PPC_EMB)
2298 strcat (buf, ", emb");
2299
2300 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2301 strcat (buf, _(", relocatable"));
252b5132
RH
2302
2303 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2304 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2305 break;
2306
2b0337b0 2307 case EM_V850:
252b5132
RH
2308 case EM_CYGNUS_V850:
2309 switch (e_flags & EF_V850_ARCH)
2310 {
1cd986c5
NC
2311 case E_V850E2V3_ARCH:
2312 strcat (buf, ", v850e2v3");
2313 break;
2314 case E_V850E2_ARCH:
2315 strcat (buf, ", v850e2");
2316 break;
2317 case E_V850E1_ARCH:
2318 strcat (buf, ", v850e1");
8ad30312 2319 break;
252b5132
RH
2320 case E_V850E_ARCH:
2321 strcat (buf, ", v850e");
2322 break;
252b5132
RH
2323 case E_V850_ARCH:
2324 strcat (buf, ", v850");
2325 break;
2326 default:
2b692964 2327 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2328 break;
2329 }
2330 break;
2331
2b0337b0 2332 case EM_M32R:
252b5132
RH
2333 case EM_CYGNUS_M32R:
2334 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2335 strcat (buf, ", m32r");
252b5132
RH
2336 break;
2337
2338 case EM_MIPS:
4fe85591 2339 case EM_MIPS_RS3_LE:
252b5132
RH
2340 if (e_flags & EF_MIPS_NOREORDER)
2341 strcat (buf, ", noreorder");
2342
2343 if (e_flags & EF_MIPS_PIC)
2344 strcat (buf, ", pic");
2345
2346 if (e_flags & EF_MIPS_CPIC)
2347 strcat (buf, ", cpic");
2348
d1bdd336
TS
2349 if (e_flags & EF_MIPS_UCODE)
2350 strcat (buf, ", ugen_reserved");
2351
252b5132
RH
2352 if (e_flags & EF_MIPS_ABI2)
2353 strcat (buf, ", abi2");
2354
43521d43
TS
2355 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2356 strcat (buf, ", odk first");
2357
a5d22d2a
TS
2358 if (e_flags & EF_MIPS_32BITMODE)
2359 strcat (buf, ", 32bitmode");
2360
156c2f8b
NC
2361 switch ((e_flags & EF_MIPS_MACH))
2362 {
2363 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2364 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2365 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2366 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2367 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2368 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2369 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2370 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2371 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2372 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2373 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2374 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2375 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2376 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2377 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2378 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2379 case 0:
2380 /* We simply ignore the field in this case to avoid confusion:
2381 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2382 extension. */
2383 break;
2b692964 2384 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2385 }
43521d43
TS
2386
2387 switch ((e_flags & EF_MIPS_ABI))
2388 {
2389 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2390 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2391 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2392 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2393 case 0:
2394 /* We simply ignore the field in this case to avoid confusion:
2395 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2396 This means it is likely to be an o32 file, but not for
2397 sure. */
2398 break;
2b692964 2399 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2400 }
2401
2402 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2403 strcat (buf, ", mdmx");
2404
2405 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2406 strcat (buf, ", mips16");
2407
2408 switch ((e_flags & EF_MIPS_ARCH))
2409 {
2410 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2411 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2412 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2413 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2414 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2415 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2416 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2417 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2418 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2419 default: strcat (buf, _(", unknown ISA")); break;
43521d43
TS
2420 }
2421
8e45593f
NC
2422 if (e_flags & EF_SH_PIC)
2423 strcat (buf, ", pic");
2424
2425 if (e_flags & EF_SH_FDPIC)
2426 strcat (buf, ", fdpic");
252b5132 2427 break;
351b4b40 2428
ccde1100
AO
2429 case EM_SH:
2430 switch ((e_flags & EF_SH_MACH_MASK))
2431 {
2432 case EF_SH1: strcat (buf, ", sh1"); break;
2433 case EF_SH2: strcat (buf, ", sh2"); break;
2434 case EF_SH3: strcat (buf, ", sh3"); break;
2435 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2436 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2437 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2438 case EF_SH3E: strcat (buf, ", sh3e"); break;
2439 case EF_SH4: strcat (buf, ", sh4"); break;
2440 case EF_SH5: strcat (buf, ", sh5"); break;
2441 case EF_SH2E: strcat (buf, ", sh2e"); break;
2442 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2443 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2444 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2445 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2446 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2447 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2448 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2449 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2450 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2451 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2452 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2453 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2454 }
2455
2456 break;
57346661 2457
351b4b40
RH
2458 case EM_SPARCV9:
2459 if (e_flags & EF_SPARC_32PLUS)
2460 strcat (buf, ", v8+");
2461
2462 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2463 strcat (buf, ", ultrasparcI");
2464
2465 if (e_flags & EF_SPARC_SUN_US3)
2466 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2467
2468 if (e_flags & EF_SPARC_HAL_R1)
2469 strcat (buf, ", halr1");
2470
2471 if (e_flags & EF_SPARC_LEDATA)
2472 strcat (buf, ", ledata");
2473
2474 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2475 strcat (buf, ", tso");
2476
2477 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2478 strcat (buf, ", pso");
2479
2480 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2481 strcat (buf, ", rmo");
2482 break;
7d466069 2483
103f02d3
UD
2484 case EM_PARISC:
2485 switch (e_flags & EF_PARISC_ARCH)
2486 {
2487 case EFA_PARISC_1_0:
2488 strcpy (buf, ", PA-RISC 1.0");
2489 break;
2490 case EFA_PARISC_1_1:
2491 strcpy (buf, ", PA-RISC 1.1");
2492 break;
2493 case EFA_PARISC_2_0:
2494 strcpy (buf, ", PA-RISC 2.0");
2495 break;
2496 default:
2497 break;
2498 }
2499 if (e_flags & EF_PARISC_TRAPNIL)
2500 strcat (buf, ", trapnil");
2501 if (e_flags & EF_PARISC_EXT)
2502 strcat (buf, ", ext");
2503 if (e_flags & EF_PARISC_LSB)
2504 strcat (buf, ", lsb");
2505 if (e_flags & EF_PARISC_WIDE)
2506 strcat (buf, ", wide");
2507 if (e_flags & EF_PARISC_NO_KABP)
2508 strcat (buf, ", no kabp");
2509 if (e_flags & EF_PARISC_LAZYSWAP)
2510 strcat (buf, ", lazyswap");
30800947 2511 break;
76da6bbe 2512
7d466069 2513 case EM_PJ:
2b0337b0 2514 case EM_PJ_OLD:
7d466069
ILT
2515 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2516 strcat (buf, ", new calling convention");
2517
2518 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2519 strcat (buf, ", gnu calling convention");
2520 break;
4d6ed7c8
NC
2521
2522 case EM_IA_64:
2523 if ((e_flags & EF_IA_64_ABI64))
2524 strcat (buf, ", 64-bit");
2525 else
2526 strcat (buf, ", 32-bit");
2527 if ((e_flags & EF_IA_64_REDUCEDFP))
2528 strcat (buf, ", reduced fp model");
2529 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2530 strcat (buf, ", no function descriptors, constant gp");
2531 else if ((e_flags & EF_IA_64_CONS_GP))
2532 strcat (buf, ", constant gp");
2533 if ((e_flags & EF_IA_64_ABSOLUTE))
2534 strcat (buf, ", absolute");
28f997cf
TG
2535 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2536 {
2537 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2538 strcat (buf, ", vms_linkages");
2539 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2540 {
2541 case EF_IA_64_VMS_COMCOD_SUCCESS:
2542 break;
2543 case EF_IA_64_VMS_COMCOD_WARNING:
2544 strcat (buf, ", warning");
2545 break;
2546 case EF_IA_64_VMS_COMCOD_ERROR:
2547 strcat (buf, ", error");
2548 break;
2549 case EF_IA_64_VMS_COMCOD_ABORT:
2550 strcat (buf, ", abort");
2551 break;
2552 default:
2553 abort ();
2554 }
2555 }
4d6ed7c8 2556 break;
179d3252
JT
2557
2558 case EM_VAX:
2559 if ((e_flags & EF_VAX_NONPIC))
2560 strcat (buf, ", non-PIC");
2561 if ((e_flags & EF_VAX_DFLOAT))
2562 strcat (buf, ", D-Float");
2563 if ((e_flags & EF_VAX_GFLOAT))
2564 strcat (buf, ", G-Float");
2565 break;
c7927a3c
NC
2566
2567 case EM_RX:
2568 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2569 strcat (buf, ", 64-bit doubles");
2570 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2571 strcat (buf, ", dsp");
55786da2
AK
2572
2573 case EM_S390:
2574 if (e_flags & EF_S390_HIGH_GPRS)
2575 strcat (buf, ", highgprs");
40b36596
JM
2576
2577 case EM_TI_C6000:
2578 if ((e_flags & EF_C6000_REL))
2579 strcat (buf, ", relocatable module");
252b5132
RH
2580 }
2581 }
2582
2583 return buf;
2584}
2585
252b5132 2586static const char *
d3ba0551
AM
2587get_osabi_name (unsigned int osabi)
2588{
2589 static char buff[32];
2590
2591 switch (osabi)
2592 {
2593 case ELFOSABI_NONE: return "UNIX - System V";
2594 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2595 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
2596 case ELFOSABI_LINUX: return "UNIX - Linux";
2597 case ELFOSABI_HURD: return "GNU/Hurd";
2598 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2599 case ELFOSABI_AIX: return "UNIX - AIX";
2600 case ELFOSABI_IRIX: return "UNIX - IRIX";
2601 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2602 case ELFOSABI_TRU64: return "UNIX - TRU64";
2603 case ELFOSABI_MODESTO: return "Novell - Modesto";
2604 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2605 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2606 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2607 case ELFOSABI_AROS: return "AROS";
11636f9e 2608 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2609 default:
40b36596
JM
2610 if (osabi >= 64)
2611 switch (elf_header.e_machine)
2612 {
2613 case EM_ARM:
2614 switch (osabi)
2615 {
2616 case ELFOSABI_ARM: return "ARM";
2617 default:
2618 break;
2619 }
2620 break;
2621
2622 case EM_MSP430:
2623 case EM_MSP430_OLD:
2624 switch (osabi)
2625 {
2626 case ELFOSABI_STANDALONE: return _("Standalone App");
2627 default:
2628 break;
2629 }
2630 break;
2631
2632 case EM_TI_C6000:
2633 switch (osabi)
2634 {
2635 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2636 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2637 default:
2638 break;
2639 }
2640 break;
2641
2642 default:
2643 break;
2644 }
e9e44622 2645 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2646 return buff;
2647 }
2648}
2649
b294bdf8
MM
2650static const char *
2651get_arm_segment_type (unsigned long type)
2652{
2653 switch (type)
2654 {
2655 case PT_ARM_EXIDX:
2656 return "EXIDX";
2657 default:
2658 break;
2659 }
2660
2661 return NULL;
2662}
2663
d3ba0551
AM
2664static const char *
2665get_mips_segment_type (unsigned long type)
252b5132
RH
2666{
2667 switch (type)
2668 {
2669 case PT_MIPS_REGINFO:
2670 return "REGINFO";
2671 case PT_MIPS_RTPROC:
2672 return "RTPROC";
2673 case PT_MIPS_OPTIONS:
2674 return "OPTIONS";
2675 default:
2676 break;
2677 }
2678
2679 return NULL;
2680}
2681
103f02d3 2682static const char *
d3ba0551 2683get_parisc_segment_type (unsigned long type)
103f02d3
UD
2684{
2685 switch (type)
2686 {
2687 case PT_HP_TLS: return "HP_TLS";
2688 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2689 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2690 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2691 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2692 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2693 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2694 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2695 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2696 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2697 case PT_HP_PARALLEL: return "HP_PARALLEL";
2698 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2699 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2700 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2701 case PT_HP_STACK: return "HP_STACK";
2702 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2703 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2704 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2705 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2706 default:
2707 break;
2708 }
2709
2710 return NULL;
2711}
2712
4d6ed7c8 2713static const char *
d3ba0551 2714get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2715{
2716 switch (type)
2717 {
2718 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2719 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2720 case PT_HP_TLS: return "HP_TLS";
2721 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2722 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2723 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2724 default:
2725 break;
2726 }
2727
2728 return NULL;
2729}
2730
40b36596
JM
2731static const char *
2732get_tic6x_segment_type (unsigned long type)
2733{
2734 switch (type)
2735 {
2736 case PT_C6000_PHATTR: return "C6000_PHATTR";
2737 default:
2738 break;
2739 }
2740
2741 return NULL;
2742}
2743
252b5132 2744static const char *
d3ba0551 2745get_segment_type (unsigned long p_type)
252b5132 2746{
b34976b6 2747 static char buff[32];
252b5132
RH
2748
2749 switch (p_type)
2750 {
b34976b6
AM
2751 case PT_NULL: return "NULL";
2752 case PT_LOAD: return "LOAD";
252b5132 2753 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2754 case PT_INTERP: return "INTERP";
2755 case PT_NOTE: return "NOTE";
2756 case PT_SHLIB: return "SHLIB";
2757 case PT_PHDR: return "PHDR";
13ae64f3 2758 case PT_TLS: return "TLS";
252b5132 2759
65765700
JJ
2760 case PT_GNU_EH_FRAME:
2761 return "GNU_EH_FRAME";
2b05f1b7 2762 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2763 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2764
252b5132
RH
2765 default:
2766 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2767 {
2cf0635d 2768 const char * result;
103f02d3 2769
252b5132
RH
2770 switch (elf_header.e_machine)
2771 {
b294bdf8
MM
2772 case EM_ARM:
2773 result = get_arm_segment_type (p_type);
2774 break;
252b5132 2775 case EM_MIPS:
4fe85591 2776 case EM_MIPS_RS3_LE:
252b5132
RH
2777 result = get_mips_segment_type (p_type);
2778 break;
103f02d3
UD
2779 case EM_PARISC:
2780 result = get_parisc_segment_type (p_type);
2781 break;
4d6ed7c8
NC
2782 case EM_IA_64:
2783 result = get_ia64_segment_type (p_type);
2784 break;
40b36596
JM
2785 case EM_TI_C6000:
2786 result = get_tic6x_segment_type (p_type);
2787 break;
252b5132
RH
2788 default:
2789 result = NULL;
2790 break;
2791 }
103f02d3 2792
252b5132
RH
2793 if (result != NULL)
2794 return result;
103f02d3 2795
252b5132
RH
2796 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2797 }
2798 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2799 {
2cf0635d 2800 const char * result;
103f02d3
UD
2801
2802 switch (elf_header.e_machine)
2803 {
2804 case EM_PARISC:
2805 result = get_parisc_segment_type (p_type);
2806 break;
00428cca
AM
2807 case EM_IA_64:
2808 result = get_ia64_segment_type (p_type);
2809 break;
103f02d3
UD
2810 default:
2811 result = NULL;
2812 break;
2813 }
2814
2815 if (result != NULL)
2816 return result;
2817
2818 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2819 }
252b5132 2820 else
e9e44622 2821 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2822
2823 return buff;
2824 }
2825}
2826
2827static const char *
d3ba0551 2828get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2829{
2830 switch (sh_type)
2831 {
b34976b6
AM
2832 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2833 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2834 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2835 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2836 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2837 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2838 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2839 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2840 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2841 case SHT_MIPS_RELD: return "MIPS_RELD";
2842 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2843 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2844 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2845 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2846 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2847 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2848 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2849 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2850 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2851 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2852 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2853 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2854 case SHT_MIPS_LINE: return "MIPS_LINE";
2855 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2856 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2857 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2858 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2859 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2860 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2861 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2862 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2863 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2864 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2865 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2866 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2867 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2868 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2869 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2870 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2871 default:
2872 break;
2873 }
2874 return NULL;
2875}
2876
103f02d3 2877static const char *
d3ba0551 2878get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2879{
2880 switch (sh_type)
2881 {
2882 case SHT_PARISC_EXT: return "PARISC_EXT";
2883 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2884 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2885 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2886 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2887 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2888 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2889 default:
2890 break;
2891 }
2892 return NULL;
2893}
2894
4d6ed7c8 2895static const char *
d3ba0551 2896get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2897{
18bd398b 2898 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2899 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2900 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2901
4d6ed7c8
NC
2902 switch (sh_type)
2903 {
148b93f2
NC
2904 case SHT_IA_64_EXT: return "IA_64_EXT";
2905 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2906 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
2907 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
2908 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
2909 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
2910 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
2911 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
2912 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
2913 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
2914 default:
2915 break;
2916 }
2917 return NULL;
2918}
2919
d2b2c203
DJ
2920static const char *
2921get_x86_64_section_type_name (unsigned int sh_type)
2922{
2923 switch (sh_type)
2924 {
2925 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2926 default:
2927 break;
2928 }
2929 return NULL;
2930}
2931
40a18ebd
NC
2932static const char *
2933get_arm_section_type_name (unsigned int sh_type)
2934{
2935 switch (sh_type)
2936 {
7f6fed87
NC
2937 case SHT_ARM_EXIDX: return "ARM_EXIDX";
2938 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
2939 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
2940 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
2941 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
2942 default:
2943 break;
2944 }
2945 return NULL;
2946}
2947
40b36596
JM
2948static const char *
2949get_tic6x_section_type_name (unsigned int sh_type)
2950{
2951 switch (sh_type)
2952 {
2953 case SHT_C6000_UNWIND:
2954 return "C6000_UNWIND";
2955 case SHT_C6000_PREEMPTMAP:
2956 return "C6000_PREEMPTMAP";
2957 case SHT_C6000_ATTRIBUTES:
2958 return "C6000_ATTRIBUTES";
2959 case SHT_TI_ICODE:
2960 return "TI_ICODE";
2961 case SHT_TI_XREF:
2962 return "TI_XREF";
2963 case SHT_TI_HANDLER:
2964 return "TI_HANDLER";
2965 case SHT_TI_INITINFO:
2966 return "TI_INITINFO";
2967 case SHT_TI_PHATTRS:
2968 return "TI_PHATTRS";
2969 default:
2970 break;
2971 }
2972 return NULL;
2973}
2974
252b5132 2975static const char *
d3ba0551 2976get_section_type_name (unsigned int sh_type)
252b5132 2977{
b34976b6 2978 static char buff[32];
252b5132
RH
2979
2980 switch (sh_type)
2981 {
2982 case SHT_NULL: return "NULL";
2983 case SHT_PROGBITS: return "PROGBITS";
2984 case SHT_SYMTAB: return "SYMTAB";
2985 case SHT_STRTAB: return "STRTAB";
2986 case SHT_RELA: return "RELA";
2987 case SHT_HASH: return "HASH";
2988 case SHT_DYNAMIC: return "DYNAMIC";
2989 case SHT_NOTE: return "NOTE";
2990 case SHT_NOBITS: return "NOBITS";
2991 case SHT_REL: return "REL";
2992 case SHT_SHLIB: return "SHLIB";
2993 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
2994 case SHT_INIT_ARRAY: return "INIT_ARRAY";
2995 case SHT_FINI_ARRAY: return "FINI_ARRAY";
2996 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 2997 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
2998 case SHT_GROUP: return "GROUP";
2999 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3000 case SHT_GNU_verdef: return "VERDEF";
3001 case SHT_GNU_verneed: return "VERNEED";
3002 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3003 case 0x6ffffff0: return "VERSYM";
3004 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3005 case 0x7ffffffd: return "AUXILIARY";
3006 case 0x7fffffff: return "FILTER";
047b2264 3007 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3008
3009 default:
3010 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3011 {
2cf0635d 3012 const char * result;
252b5132
RH
3013
3014 switch (elf_header.e_machine)
3015 {
3016 case EM_MIPS:
4fe85591 3017 case EM_MIPS_RS3_LE:
252b5132
RH
3018 result = get_mips_section_type_name (sh_type);
3019 break;
103f02d3
UD
3020 case EM_PARISC:
3021 result = get_parisc_section_type_name (sh_type);
3022 break;
4d6ed7c8
NC
3023 case EM_IA_64:
3024 result = get_ia64_section_type_name (sh_type);
3025 break;
d2b2c203 3026 case EM_X86_64:
8a9036a4 3027 case EM_L1OM:
d2b2c203
DJ
3028 result = get_x86_64_section_type_name (sh_type);
3029 break;
40a18ebd
NC
3030 case EM_ARM:
3031 result = get_arm_section_type_name (sh_type);
3032 break;
40b36596
JM
3033 case EM_TI_C6000:
3034 result = get_tic6x_section_type_name (sh_type);
3035 break;
252b5132
RH
3036 default:
3037 result = NULL;
3038 break;
3039 }
3040
3041 if (result != NULL)
3042 return result;
3043
c91d0dfb 3044 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3045 }
3046 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3047 {
2cf0635d 3048 const char * result;
148b93f2
NC
3049
3050 switch (elf_header.e_machine)
3051 {
3052 case EM_IA_64:
3053 result = get_ia64_section_type_name (sh_type);
3054 break;
3055 default:
3056 result = NULL;
3057 break;
3058 }
3059
3060 if (result != NULL)
3061 return result;
3062
3063 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3064 }
252b5132 3065 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3066 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3067 else
e9e44622 3068 snprintf (buff, sizeof (buff), _("<unknown>: %x"), sh_type);
103f02d3 3069
252b5132
RH
3070 return buff;
3071 }
3072}
3073
2979dc34 3074#define OPTION_DEBUG_DUMP 512
2c610e4b 3075#define OPTION_DYN_SYMS 513
2979dc34 3076
85b1c36d 3077static struct option options[] =
252b5132 3078{
b34976b6 3079 {"all", no_argument, 0, 'a'},
252b5132
RH
3080 {"file-header", no_argument, 0, 'h'},
3081 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3082 {"headers", no_argument, 0, 'e'},
3083 {"histogram", no_argument, 0, 'I'},
3084 {"segments", no_argument, 0, 'l'},
3085 {"sections", no_argument, 0, 'S'},
252b5132 3086 {"section-headers", no_argument, 0, 'S'},
f5842774 3087 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3088 {"section-details", no_argument, 0, 't'},
595cf52e 3089 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3090 {"symbols", no_argument, 0, 's'},
3091 {"syms", no_argument, 0, 's'},
2c610e4b 3092 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3093 {"relocs", no_argument, 0, 'r'},
3094 {"notes", no_argument, 0, 'n'},
3095 {"dynamic", no_argument, 0, 'd'},
a952a375 3096 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3097 {"version-info", no_argument, 0, 'V'},
3098 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3099 {"unwind", no_argument, 0, 'u'},
4145f1d5 3100 {"archive-index", no_argument, 0, 'c'},
b34976b6 3101 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3102 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3103 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3104#ifdef SUPPORT_DISASSEMBLY
3105 {"instruction-dump", required_argument, 0, 'i'},
3106#endif
cf13d699 3107 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3108
b34976b6
AM
3109 {"version", no_argument, 0, 'v'},
3110 {"wide", no_argument, 0, 'W'},
3111 {"help", no_argument, 0, 'H'},
3112 {0, no_argument, 0, 0}
252b5132
RH
3113};
3114
3115static void
2cf0635d 3116usage (FILE * stream)
252b5132 3117{
92f01d61
JM
3118 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3119 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3120 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3121 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3122 -h --file-header Display the ELF file header\n\
3123 -l --program-headers Display the program headers\n\
3124 --segments An alias for --program-headers\n\
3125 -S --section-headers Display the sections' header\n\
3126 --sections An alias for --section-headers\n\
f5842774 3127 -g --section-groups Display the section groups\n\
5477e8a0 3128 -t --section-details Display the section details\n\
8b53311e
NC
3129 -e --headers Equivalent to: -h -l -S\n\
3130 -s --syms Display the symbol table\n\
3f08eb35 3131 --symbols An alias for --syms\n\
2c610e4b 3132 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3133 -n --notes Display the core notes (if present)\n\
3134 -r --relocs Display the relocations (if present)\n\
3135 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3136 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
3137 -V --version-info Display the version sections (if present)\n\
3138 -A --arch-specific Display architecture specific information (if any).\n\
4145f1d5 3139 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3140 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3141 -x --hex-dump=<number|name>\n\
3142 Dump the contents of section <number|name> as bytes\n\
3143 -p --string-dump=<number|name>\n\
3144 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3145 -R --relocated-dump=<number|name>\n\
3146 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3147 -w[lLiaprmfFsoRt] or\n\
1ed06042 3148 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3149 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
5bbdf3d5 3150 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
8b53311e 3151 Display the contents of DWARF2 debug sections\n"));
252b5132 3152#ifdef SUPPORT_DISASSEMBLY
92f01d61 3153 fprintf (stream, _("\
09c11c86
NC
3154 -i --instruction-dump=<number|name>\n\
3155 Disassemble the contents of section <number|name>\n"));
252b5132 3156#endif
92f01d61 3157 fprintf (stream, _("\
8b53311e
NC
3158 -I --histogram Display histogram of bucket list lengths\n\
3159 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3160 @<file> Read options from <file>\n\
8b53311e
NC
3161 -H --help Display this information\n\
3162 -v --version Display the version number of readelf\n"));
1118d252 3163
92f01d61
JM
3164 if (REPORT_BUGS_TO[0] && stream == stdout)
3165 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3166
92f01d61 3167 exit (stream == stdout ? 0 : 1);
252b5132
RH
3168}
3169
18bd398b
NC
3170/* Record the fact that the user wants the contents of section number
3171 SECTION to be displayed using the method(s) encoded as flags bits
3172 in TYPE. Note, TYPE can be zero if we are creating the array for
3173 the first time. */
3174
252b5132 3175static void
09c11c86 3176request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3177{
3178 if (section >= num_dump_sects)
3179 {
2cf0635d 3180 dump_type * new_dump_sects;
252b5132 3181
3f5e193b
NC
3182 new_dump_sects = (dump_type *) calloc (section + 1,
3183 sizeof (* dump_sects));
252b5132
RH
3184
3185 if (new_dump_sects == NULL)
591a748a 3186 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3187 else
3188 {
3189 /* Copy current flag settings. */
09c11c86 3190 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3191
3192 free (dump_sects);
3193
3194 dump_sects = new_dump_sects;
3195 num_dump_sects = section + 1;
3196 }
3197 }
3198
3199 if (dump_sects)
b34976b6 3200 dump_sects[section] |= type;
252b5132
RH
3201
3202 return;
3203}
3204
aef1f6d0
DJ
3205/* Request a dump by section name. */
3206
3207static void
2cf0635d 3208request_dump_byname (const char * section, dump_type type)
aef1f6d0 3209{
2cf0635d 3210 struct dump_list_entry * new_request;
aef1f6d0 3211
3f5e193b
NC
3212 new_request = (struct dump_list_entry *)
3213 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3214 if (!new_request)
591a748a 3215 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3216
3217 new_request->name = strdup (section);
3218 if (!new_request->name)
591a748a 3219 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3220
3221 new_request->type = type;
3222
3223 new_request->next = dump_sects_byname;
3224 dump_sects_byname = new_request;
3225}
3226
cf13d699
NC
3227static inline void
3228request_dump (dump_type type)
3229{
3230 int section;
3231 char * cp;
3232
3233 do_dump++;
3234 section = strtoul (optarg, & cp, 0);
3235
3236 if (! *cp && section >= 0)
3237 request_dump_bynumber (section, type);
3238 else
3239 request_dump_byname (optarg, type);
3240}
3241
3242
252b5132 3243static void
2cf0635d 3244parse_args (int argc, char ** argv)
252b5132
RH
3245{
3246 int c;
3247
3248 if (argc < 2)
92f01d61 3249 usage (stderr);
252b5132
RH
3250
3251 while ((c = getopt_long
cf13d699 3252 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3253 {
252b5132
RH
3254 switch (c)
3255 {
3256 case 0:
3257 /* Long options. */
3258 break;
3259 case 'H':
92f01d61 3260 usage (stdout);
252b5132
RH
3261 break;
3262
3263 case 'a':
b34976b6
AM
3264 do_syms++;
3265 do_reloc++;
3266 do_unwind++;
3267 do_dynamic++;
3268 do_header++;
3269 do_sections++;
f5842774 3270 do_section_groups++;
b34976b6
AM
3271 do_segments++;
3272 do_version++;
3273 do_histogram++;
3274 do_arch++;
3275 do_notes++;
252b5132 3276 break;
f5842774
L
3277 case 'g':
3278 do_section_groups++;
3279 break;
5477e8a0 3280 case 't':
595cf52e 3281 case 'N':
5477e8a0
L
3282 do_sections++;
3283 do_section_details++;
595cf52e 3284 break;
252b5132 3285 case 'e':
b34976b6
AM
3286 do_header++;
3287 do_sections++;
3288 do_segments++;
252b5132 3289 break;
a952a375 3290 case 'A':
b34976b6 3291 do_arch++;
a952a375 3292 break;
252b5132 3293 case 'D':
b34976b6 3294 do_using_dynamic++;
252b5132
RH
3295 break;
3296 case 'r':
b34976b6 3297 do_reloc++;
252b5132 3298 break;
4d6ed7c8 3299 case 'u':
b34976b6 3300 do_unwind++;
4d6ed7c8 3301 break;
252b5132 3302 case 'h':
b34976b6 3303 do_header++;
252b5132
RH
3304 break;
3305 case 'l':
b34976b6 3306 do_segments++;
252b5132
RH
3307 break;
3308 case 's':
b34976b6 3309 do_syms++;
252b5132
RH
3310 break;
3311 case 'S':
b34976b6 3312 do_sections++;
252b5132
RH
3313 break;
3314 case 'd':
b34976b6 3315 do_dynamic++;
252b5132 3316 break;
a952a375 3317 case 'I':
b34976b6 3318 do_histogram++;
a952a375 3319 break;
779fe533 3320 case 'n':
b34976b6 3321 do_notes++;
779fe533 3322 break;
4145f1d5
NC
3323 case 'c':
3324 do_archive_index++;
3325 break;
252b5132 3326 case 'x':
cf13d699 3327 request_dump (HEX_DUMP);
aef1f6d0 3328 break;
09c11c86 3329 case 'p':
cf13d699
NC
3330 request_dump (STRING_DUMP);
3331 break;
3332 case 'R':
3333 request_dump (RELOC_DUMP);
09c11c86 3334 break;
252b5132 3335 case 'w':
b34976b6 3336 do_dump++;
252b5132 3337 if (optarg == 0)
613ff48b
CC
3338 {
3339 do_debugging = 1;
3340 dwarf_select_sections_all ();
3341 }
252b5132
RH
3342 else
3343 {
3344 do_debugging = 0;
4cb93e3b 3345 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3346 }
3347 break;
2979dc34 3348 case OPTION_DEBUG_DUMP:
b34976b6 3349 do_dump++;
2979dc34
JJ
3350 if (optarg == 0)
3351 do_debugging = 1;
3352 else
3353 {
2979dc34 3354 do_debugging = 0;
4cb93e3b 3355 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3356 }
3357 break;
2c610e4b
L
3358 case OPTION_DYN_SYMS:
3359 do_dyn_syms++;
3360 break;
252b5132
RH
3361#ifdef SUPPORT_DISASSEMBLY
3362 case 'i':
cf13d699
NC
3363 request_dump (DISASS_DUMP);
3364 break;
252b5132
RH
3365#endif
3366 case 'v':
3367 print_version (program_name);
3368 break;
3369 case 'V':
b34976b6 3370 do_version++;
252b5132 3371 break;
d974e256 3372 case 'W':
b34976b6 3373 do_wide++;
d974e256 3374 break;
252b5132 3375 default:
252b5132
RH
3376 /* xgettext:c-format */
3377 error (_("Invalid option '-%c'\n"), c);
3378 /* Drop through. */
3379 case '?':
92f01d61 3380 usage (stderr);
252b5132
RH
3381 }
3382 }
3383
4d6ed7c8 3384 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3385 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3386 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3387 && !do_section_groups && !do_archive_index
3388 && !do_dyn_syms)
92f01d61 3389 usage (stderr);
252b5132
RH
3390 else if (argc < 3)
3391 {
3392 warn (_("Nothing to do.\n"));
92f01d61 3393 usage (stderr);
252b5132
RH
3394 }
3395}
3396
3397static const char *
d3ba0551 3398get_elf_class (unsigned int elf_class)
252b5132 3399{
b34976b6 3400 static char buff[32];
103f02d3 3401
252b5132
RH
3402 switch (elf_class)
3403 {
3404 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3405 case ELFCLASS32: return "ELF32";
3406 case ELFCLASS64: return "ELF64";
ab5e7794 3407 default:
e9e44622 3408 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3409 return buff;
252b5132
RH
3410 }
3411}
3412
3413static const char *
d3ba0551 3414get_data_encoding (unsigned int encoding)
252b5132 3415{
b34976b6 3416 static char buff[32];
103f02d3 3417
252b5132
RH
3418 switch (encoding)
3419 {
3420 case ELFDATANONE: return _("none");
33c63f9d
CM
3421 case ELFDATA2LSB: return _("2's complement, little endian");
3422 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3423 default:
e9e44622 3424 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3425 return buff;
252b5132
RH
3426 }
3427}
3428
252b5132 3429/* Decode the data held in 'elf_header'. */
ee42cf8c 3430
252b5132 3431static int
d3ba0551 3432process_file_header (void)
252b5132 3433{
b34976b6
AM
3434 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3435 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3436 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3437 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3438 {
3439 error
3440 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3441 return 0;
3442 }
3443
2dc4cec1
L
3444 init_dwarf_regnames (elf_header.e_machine);
3445
252b5132
RH
3446 if (do_header)
3447 {
3448 int i;
3449
3450 printf (_("ELF Header:\n"));
3451 printf (_(" Magic: "));
b34976b6
AM
3452 for (i = 0; i < EI_NIDENT; i++)
3453 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3454 printf ("\n");
3455 printf (_(" Class: %s\n"),
b34976b6 3456 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3457 printf (_(" Data: %s\n"),
b34976b6 3458 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3459 printf (_(" Version: %d %s\n"),
b34976b6
AM
3460 elf_header.e_ident[EI_VERSION],
3461 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3462 ? "(current)"
b34976b6 3463 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3464 ? _("<unknown: %lx>")
789be9f7 3465 : "")));
252b5132 3466 printf (_(" OS/ABI: %s\n"),
b34976b6 3467 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3468 printf (_(" ABI Version: %d\n"),
b34976b6 3469 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3470 printf (_(" Type: %s\n"),
3471 get_file_type (elf_header.e_type));
3472 printf (_(" Machine: %s\n"),
3473 get_machine_name (elf_header.e_machine));
3474 printf (_(" Version: 0x%lx\n"),
3475 (unsigned long) elf_header.e_version);
76da6bbe 3476
f7a99963
NC
3477 printf (_(" Entry point address: "));
3478 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3479 printf (_("\n Start of program headers: "));
3480 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3481 printf (_(" (bytes into file)\n Start of section headers: "));
3482 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3483 printf (_(" (bytes into file)\n"));
76da6bbe 3484
252b5132
RH
3485 printf (_(" Flags: 0x%lx%s\n"),
3486 (unsigned long) elf_header.e_flags,
3487 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3488 printf (_(" Size of this header: %ld (bytes)\n"),
3489 (long) elf_header.e_ehsize);
3490 printf (_(" Size of program headers: %ld (bytes)\n"),
3491 (long) elf_header.e_phentsize);
2046a35d 3492 printf (_(" Number of program headers: %ld"),
252b5132 3493 (long) elf_header.e_phnum);
2046a35d
AM
3494 if (section_headers != NULL
3495 && elf_header.e_phnum == PN_XNUM
3496 && section_headers[0].sh_info != 0)
cc5914eb 3497 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3498 putc ('\n', stdout);
252b5132
RH
3499 printf (_(" Size of section headers: %ld (bytes)\n"),
3500 (long) elf_header.e_shentsize);
560f3c1c 3501 printf (_(" Number of section headers: %ld"),
252b5132 3502 (long) elf_header.e_shnum);
4fbb74a6 3503 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3504 printf (" (%ld)", (long) section_headers[0].sh_size);
3505 putc ('\n', stdout);
3506 printf (_(" Section header string table index: %ld"),
252b5132 3507 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3508 if (section_headers != NULL
3509 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3510 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3511 else if (elf_header.e_shstrndx != SHN_UNDEF
3512 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3513 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3514 putc ('\n', stdout);
3515 }
3516
3517 if (section_headers != NULL)
3518 {
2046a35d
AM
3519 if (elf_header.e_phnum == PN_XNUM
3520 && section_headers[0].sh_info != 0)
3521 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3522 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3523 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3524 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3525 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3526 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3527 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3528 free (section_headers);
3529 section_headers = NULL;
252b5132 3530 }
103f02d3 3531
9ea033b2
NC
3532 return 1;
3533}
3534
252b5132 3535
9ea033b2 3536static int
91d6fa6a 3537get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3538{
2cf0635d
NC
3539 Elf32_External_Phdr * phdrs;
3540 Elf32_External_Phdr * external;
3541 Elf_Internal_Phdr * internal;
b34976b6 3542 unsigned int i;
103f02d3 3543
3f5e193b
NC
3544 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3545 elf_header.e_phentsize,
3546 elf_header.e_phnum,
3547 _("program headers"));
a6e9f9df
AM
3548 if (!phdrs)
3549 return 0;
9ea033b2 3550
91d6fa6a 3551 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3552 i < elf_header.e_phnum;
b34976b6 3553 i++, internal++, external++)
252b5132 3554 {
9ea033b2
NC
3555 internal->p_type = BYTE_GET (external->p_type);
3556 internal->p_offset = BYTE_GET (external->p_offset);
3557 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3558 internal->p_paddr = BYTE_GET (external->p_paddr);
3559 internal->p_filesz = BYTE_GET (external->p_filesz);
3560 internal->p_memsz = BYTE_GET (external->p_memsz);
3561 internal->p_flags = BYTE_GET (external->p_flags);
3562 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3563 }
3564
9ea033b2
NC
3565 free (phdrs);
3566
252b5132
RH
3567 return 1;
3568}
3569
9ea033b2 3570static int
91d6fa6a 3571get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3572{
2cf0635d
NC
3573 Elf64_External_Phdr * phdrs;
3574 Elf64_External_Phdr * external;
3575 Elf_Internal_Phdr * internal;
b34976b6 3576 unsigned int i;
103f02d3 3577
3f5e193b
NC
3578 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3579 elf_header.e_phentsize,
3580 elf_header.e_phnum,
3581 _("program headers"));
a6e9f9df
AM
3582 if (!phdrs)
3583 return 0;
9ea033b2 3584
91d6fa6a 3585 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3586 i < elf_header.e_phnum;
b34976b6 3587 i++, internal++, external++)
9ea033b2
NC
3588 {
3589 internal->p_type = BYTE_GET (external->p_type);
3590 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3591 internal->p_offset = BYTE_GET (external->p_offset);
3592 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3593 internal->p_paddr = BYTE_GET (external->p_paddr);
3594 internal->p_filesz = BYTE_GET (external->p_filesz);
3595 internal->p_memsz = BYTE_GET (external->p_memsz);
3596 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3597 }
3598
3599 free (phdrs);
3600
3601 return 1;
3602}
252b5132 3603
d93f0186
NC
3604/* Returns 1 if the program headers were read into `program_headers'. */
3605
3606static int
2cf0635d 3607get_program_headers (FILE * file)
d93f0186 3608{
2cf0635d 3609 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3610
3611 /* Check cache of prior read. */
3612 if (program_headers != NULL)
3613 return 1;
3614
3f5e193b
NC
3615 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3616 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3617
3618 if (phdrs == NULL)
3619 {
3620 error (_("Out of memory\n"));
3621 return 0;
3622 }
3623
3624 if (is_32bit_elf
3625 ? get_32bit_program_headers (file, phdrs)
3626 : get_64bit_program_headers (file, phdrs))
3627 {
3628 program_headers = phdrs;
3629 return 1;
3630 }
3631
3632 free (phdrs);
3633 return 0;
3634}
3635
2f62977e
NC
3636/* Returns 1 if the program headers were loaded. */
3637
252b5132 3638static int
2cf0635d 3639process_program_headers (FILE * file)
252b5132 3640{
2cf0635d 3641 Elf_Internal_Phdr * segment;
b34976b6 3642 unsigned int i;
252b5132
RH
3643
3644 if (elf_header.e_phnum == 0)
3645 {
82f2dbf7
NC
3646 /* PR binutils/12467. */
3647 if (elf_header.e_phoff != 0)
3648 warn (_("possibly corrupt ELF header - it has a non-zero program"
3649 " header offset, but no program headers"));
3650 else if (do_segments)
252b5132 3651 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3652 return 0;
252b5132
RH
3653 }
3654
3655 if (do_segments && !do_header)
3656 {
f7a99963
NC
3657 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3658 printf (_("Entry point "));
3659 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3660 printf (_("\nThere are %d program headers, starting at offset "),
3661 elf_header.e_phnum);
3662 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3663 printf ("\n");
252b5132
RH
3664 }
3665
d93f0186 3666 if (! get_program_headers (file))
252b5132 3667 return 0;
103f02d3 3668
252b5132
RH
3669 if (do_segments)
3670 {
3a1a2036
NC
3671 if (elf_header.e_phnum > 1)
3672 printf (_("\nProgram Headers:\n"));
3673 else
3674 printf (_("\nProgram Headers:\n"));
76da6bbe 3675
f7a99963
NC
3676 if (is_32bit_elf)
3677 printf
3678 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3679 else if (do_wide)
3680 printf
3681 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3682 else
3683 {
3684 printf
3685 (_(" Type Offset VirtAddr PhysAddr\n"));
3686 printf
3687 (_(" FileSiz MemSiz Flags Align\n"));
3688 }
252b5132
RH
3689 }
3690
252b5132 3691 dynamic_addr = 0;
1b228002 3692 dynamic_size = 0;
252b5132
RH
3693
3694 for (i = 0, segment = program_headers;
3695 i < elf_header.e_phnum;
b34976b6 3696 i++, segment++)
252b5132
RH
3697 {
3698 if (do_segments)
3699 {
103f02d3 3700 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3701
3702 if (is_32bit_elf)
3703 {
3704 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3705 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3706 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3707 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3708 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3709 printf ("%c%c%c ",
3710 (segment->p_flags & PF_R ? 'R' : ' '),
3711 (segment->p_flags & PF_W ? 'W' : ' '),
3712 (segment->p_flags & PF_X ? 'E' : ' '));
3713 printf ("%#lx", (unsigned long) segment->p_align);
3714 }
d974e256
JJ
3715 else if (do_wide)
3716 {
3717 if ((unsigned long) segment->p_offset == segment->p_offset)
3718 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3719 else
3720 {
3721 print_vma (segment->p_offset, FULL_HEX);
3722 putchar (' ');
3723 }
3724
3725 print_vma (segment->p_vaddr, FULL_HEX);
3726 putchar (' ');
3727 print_vma (segment->p_paddr, FULL_HEX);
3728 putchar (' ');
3729
3730 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3731 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3732 else
3733 {
3734 print_vma (segment->p_filesz, FULL_HEX);
3735 putchar (' ');
3736 }
3737
3738 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3739 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3740 else
3741 {
3742 print_vma (segment->p_offset, FULL_HEX);
3743 }
3744
3745 printf (" %c%c%c ",
3746 (segment->p_flags & PF_R ? 'R' : ' '),
3747 (segment->p_flags & PF_W ? 'W' : ' '),
3748 (segment->p_flags & PF_X ? 'E' : ' '));
3749
3750 if ((unsigned long) segment->p_align == segment->p_align)
3751 printf ("%#lx", (unsigned long) segment->p_align);
3752 else
3753 {
3754 print_vma (segment->p_align, PREFIX_HEX);
3755 }
3756 }
f7a99963
NC
3757 else
3758 {
3759 print_vma (segment->p_offset, FULL_HEX);
3760 putchar (' ');
3761 print_vma (segment->p_vaddr, FULL_HEX);
3762 putchar (' ');
3763 print_vma (segment->p_paddr, FULL_HEX);
3764 printf ("\n ");
3765 print_vma (segment->p_filesz, FULL_HEX);
3766 putchar (' ');
3767 print_vma (segment->p_memsz, FULL_HEX);
3768 printf (" %c%c%c ",
3769 (segment->p_flags & PF_R ? 'R' : ' '),
3770 (segment->p_flags & PF_W ? 'W' : ' '),
3771 (segment->p_flags & PF_X ? 'E' : ' '));
3772 print_vma (segment->p_align, HEX);
3773 }
252b5132
RH
3774 }
3775
3776 switch (segment->p_type)
3777 {
252b5132
RH
3778 case PT_DYNAMIC:
3779 if (dynamic_addr)
3780 error (_("more than one dynamic segment\n"));
3781
20737c13
AM
3782 /* By default, assume that the .dynamic section is the first
3783 section in the DYNAMIC segment. */
3784 dynamic_addr = segment->p_offset;
3785 dynamic_size = segment->p_filesz;
3786
b2d38a17
NC
3787 /* Try to locate the .dynamic section. If there is
3788 a section header table, we can easily locate it. */
3789 if (section_headers != NULL)
3790 {
2cf0635d 3791 Elf_Internal_Shdr * sec;
b2d38a17 3792
89fac5e3
RS
3793 sec = find_section (".dynamic");
3794 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3795 {
28f997cf
TG
3796 /* A corresponding .dynamic section is expected, but on
3797 IA-64/OpenVMS it is OK for it to be missing. */
3798 if (!is_ia64_vms ())
3799 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3800 break;
3801 }
3802
42bb2e33 3803 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3804 {
3805 dynamic_size = 0;
3806 break;
3807 }
42bb2e33 3808
b2d38a17
NC
3809 dynamic_addr = sec->sh_offset;
3810 dynamic_size = sec->sh_size;
3811
3812 if (dynamic_addr < segment->p_offset
3813 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3814 warn (_("the .dynamic section is not contained"
3815 " within the dynamic segment\n"));
b2d38a17 3816 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3817 warn (_("the .dynamic section is not the first section"
3818 " in the dynamic segment.\n"));
b2d38a17 3819 }
252b5132
RH
3820 break;
3821
3822 case PT_INTERP:
fb52b2f4
NC
3823 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3824 SEEK_SET))
252b5132
RH
3825 error (_("Unable to find program interpreter name\n"));
3826 else
3827 {
f8eae8b2
L
3828 char fmt [32];
3829 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3830
3831 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3832 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3833
252b5132 3834 program_interpreter[0] = 0;
7bd7b3ef
AM
3835 if (fscanf (file, fmt, program_interpreter) <= 0)
3836 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3837
3838 if (do_segments)
3839 printf (_("\n [Requesting program interpreter: %s]"),
3840 program_interpreter);
3841 }
3842 break;
3843 }
3844
3845 if (do_segments)
3846 putc ('\n', stdout);
3847 }
3848
c256ffe7 3849 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3850 {
3851 printf (_("\n Section to Segment mapping:\n"));
3852 printf (_(" Segment Sections...\n"));
3853
252b5132
RH
3854 for (i = 0; i < elf_header.e_phnum; i++)
3855 {
9ad5cbcf 3856 unsigned int j;
2cf0635d 3857 Elf_Internal_Shdr * section;
252b5132
RH
3858
3859 segment = program_headers + i;
b391a3e3 3860 section = section_headers + 1;
252b5132
RH
3861
3862 printf (" %2.2d ", i);
3863
b34976b6 3864 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3865 {
f4638467
AM
3866 if (!ELF_TBSS_SPECIAL (section, segment)
3867 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
3868 printf ("%s ", SECTION_NAME (section));
3869 }
3870
3871 putc ('\n',stdout);
3872 }
3873 }
3874
252b5132
RH
3875 return 1;
3876}
3877
3878
d93f0186
NC
3879/* Find the file offset corresponding to VMA by using the program headers. */
3880
3881static long
2cf0635d 3882offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 3883{
2cf0635d 3884 Elf_Internal_Phdr * seg;
d93f0186
NC
3885
3886 if (! get_program_headers (file))
3887 {
3888 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3889 return (long) vma;
3890 }
3891
3892 for (seg = program_headers;
3893 seg < program_headers + elf_header.e_phnum;
3894 ++seg)
3895 {
3896 if (seg->p_type != PT_LOAD)
3897 continue;
3898
3899 if (vma >= (seg->p_vaddr & -seg->p_align)
3900 && vma + size <= seg->p_vaddr + seg->p_filesz)
3901 return vma - seg->p_vaddr + seg->p_offset;
3902 }
3903
3904 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 3905 (unsigned long) vma);
d93f0186
NC
3906 return (long) vma;
3907}
3908
3909
252b5132 3910static int
2cf0635d 3911get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 3912{
2cf0635d
NC
3913 Elf32_External_Shdr * shdrs;
3914 Elf_Internal_Shdr * internal;
b34976b6 3915 unsigned int i;
252b5132 3916
3f5e193b
NC
3917 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3918 elf_header.e_shentsize, num,
3919 _("section headers"));
a6e9f9df
AM
3920 if (!shdrs)
3921 return 0;
252b5132 3922
3f5e193b
NC
3923 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3924 sizeof (Elf_Internal_Shdr));
252b5132
RH
3925
3926 if (section_headers == NULL)
3927 {
3928 error (_("Out of memory\n"));
3929 return 0;
3930 }
3931
3932 for (i = 0, internal = section_headers;
560f3c1c 3933 i < num;
b34976b6 3934 i++, internal++)
252b5132
RH
3935 {
3936 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3937 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3938 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3939 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3940 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3941 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3942 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3943 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3944 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3945 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3946 }
3947
3948 free (shdrs);
3949
3950 return 1;
3951}
3952
9ea033b2 3953static int
2cf0635d 3954get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 3955{
2cf0635d
NC
3956 Elf64_External_Shdr * shdrs;
3957 Elf_Internal_Shdr * internal;
b34976b6 3958 unsigned int i;
9ea033b2 3959
3f5e193b
NC
3960 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3961 elf_header.e_shentsize, num,
3962 _("section headers"));
a6e9f9df
AM
3963 if (!shdrs)
3964 return 0;
9ea033b2 3965
3f5e193b
NC
3966 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3967 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
3968
3969 if (section_headers == NULL)
3970 {
3971 error (_("Out of memory\n"));
3972 return 0;
3973 }
3974
3975 for (i = 0, internal = section_headers;
560f3c1c 3976 i < num;
b34976b6 3977 i++, internal++)
9ea033b2
NC
3978 {
3979 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3980 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
3981 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3982 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3983 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3984 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
3985 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3986 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3987 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3988 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3989 }
3990
3991 free (shdrs);
3992
3993 return 1;
3994}
3995
252b5132 3996static Elf_Internal_Sym *
2cf0635d 3997get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
252b5132 3998{
9ad5cbcf 3999 unsigned long number;
dd24e3da 4000 Elf32_External_Sym * esyms = NULL;
2cf0635d 4001 Elf_External_Sym_Shndx * shndx;
dd24e3da 4002 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4003 Elf_Internal_Sym * psym;
b34976b6 4004 unsigned int j;
252b5132 4005
dd24e3da
NC
4006 /* Run some sanity checks first. */
4007 if (section->sh_entsize == 0)
4008 {
4009 error (_("sh_entsize is zero\n"));
4010 return NULL;
4011 }
4012
4013 number = section->sh_size / section->sh_entsize;
4014
4015 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4016 {
4017 error (_("Invalid sh_entsize\n"));
4018 return NULL;
4019 }
4020
3f5e193b
NC
4021 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4022 section->sh_size, _("symbols"));
dd24e3da 4023 if (esyms == NULL)
a6e9f9df 4024 return NULL;
252b5132 4025
9ad5cbcf
AM
4026 shndx = NULL;
4027 if (symtab_shndx_hdr != NULL
4028 && (symtab_shndx_hdr->sh_link
4fbb74a6 4029 == (unsigned long) (section - section_headers)))
9ad5cbcf 4030 {
3f5e193b
NC
4031 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4032 symtab_shndx_hdr->sh_offset,
4033 1, symtab_shndx_hdr->sh_size,
4034 _("symtab shndx"));
dd24e3da
NC
4035 if (shndx == NULL)
4036 goto exit_point;
9ad5cbcf
AM
4037 }
4038
3f5e193b 4039 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4040
4041 if (isyms == NULL)
4042 {
4043 error (_("Out of memory\n"));
dd24e3da 4044 goto exit_point;
252b5132
RH
4045 }
4046
dd24e3da 4047 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4048 {
4049 psym->st_name = BYTE_GET (esyms[j].st_name);
4050 psym->st_value = BYTE_GET (esyms[j].st_value);
4051 psym->st_size = BYTE_GET (esyms[j].st_size);
4052 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4053 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4054 psym->st_shndx
4055 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4056 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4057 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4058 psym->st_info = BYTE_GET (esyms[j].st_info);
4059 psym->st_other = BYTE_GET (esyms[j].st_other);
4060 }
4061
dd24e3da 4062 exit_point:
9ad5cbcf
AM
4063 if (shndx)
4064 free (shndx);
dd24e3da
NC
4065 if (esyms)
4066 free (esyms);
252b5132
RH
4067
4068 return isyms;
4069}
4070
9ea033b2 4071static Elf_Internal_Sym *
2cf0635d 4072get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
9ea033b2 4073{
9ad5cbcf 4074 unsigned long number;
2cf0635d
NC
4075 Elf64_External_Sym * esyms;
4076 Elf_External_Sym_Shndx * shndx;
4077 Elf_Internal_Sym * isyms;
4078 Elf_Internal_Sym * psym;
b34976b6 4079 unsigned int j;
9ea033b2 4080
dd24e3da
NC
4081 /* Run some sanity checks first. */
4082 if (section->sh_entsize == 0)
4083 {
4084 error (_("sh_entsize is zero\n"));
4085 return NULL;
4086 }
4087
4088 number = section->sh_size / section->sh_entsize;
4089
4090 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4091 {
4092 error (_("Invalid sh_entsize\n"));
4093 return NULL;
4094 }
4095
3f5e193b
NC
4096 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4097 section->sh_size, _("symbols"));
a6e9f9df
AM
4098 if (!esyms)
4099 return NULL;
9ea033b2 4100
9ad5cbcf
AM
4101 shndx = NULL;
4102 if (symtab_shndx_hdr != NULL
4103 && (symtab_shndx_hdr->sh_link
4fbb74a6 4104 == (unsigned long) (section - section_headers)))
9ad5cbcf 4105 {
3f5e193b
NC
4106 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4107 symtab_shndx_hdr->sh_offset,
4108 1, symtab_shndx_hdr->sh_size,
4109 _("symtab shndx"));
9ad5cbcf
AM
4110 if (!shndx)
4111 {
4112 free (esyms);
4113 return NULL;
4114 }
4115 }
4116
3f5e193b 4117 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4118
4119 if (isyms == NULL)
4120 {
4121 error (_("Out of memory\n"));
9ad5cbcf
AM
4122 if (shndx)
4123 free (shndx);
9ea033b2 4124 free (esyms);
9ea033b2
NC
4125 return NULL;
4126 }
4127
4128 for (j = 0, psym = isyms;
4129 j < number;
b34976b6 4130 j++, psym++)
9ea033b2
NC
4131 {
4132 psym->st_name = BYTE_GET (esyms[j].st_name);
4133 psym->st_info = BYTE_GET (esyms[j].st_info);
4134 psym->st_other = BYTE_GET (esyms[j].st_other);
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);
66543521
AM
4141 psym->st_value = BYTE_GET (esyms[j].st_value);
4142 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4143 }
4144
9ad5cbcf
AM
4145 if (shndx)
4146 free (shndx);
9ea033b2
NC
4147 free (esyms);
4148
4149 return isyms;
4150}
4151
d1133906 4152static const char *
d3ba0551 4153get_elf_section_flags (bfd_vma sh_flags)
d1133906 4154{
5477e8a0 4155 static char buff[1024];
2cf0635d 4156 char * p = buff;
8d5ff12c 4157 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4158 int sindex;
4159 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4160 bfd_vma os_flags = 0;
4161 bfd_vma proc_flags = 0;
4162 bfd_vma unknown_flags = 0;
148b93f2 4163 static const struct
5477e8a0 4164 {
2cf0635d 4165 const char * str;
5477e8a0
L
4166 int len;
4167 }
4168 flags [] =
4169 {
cfcac11d
NC
4170 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4171 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4172 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4173 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4174 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4175 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4176 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4177 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4178 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4179 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4180 /* IA-64 specific. */
4181 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4182 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4183 /* IA-64 OpenVMS specific. */
4184 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4185 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4186 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4187 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4188 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4189 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4190 /* Generic. */
cfcac11d 4191 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4192 /* SPARC specific. */
cfcac11d 4193 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4194 };
4195
4196 if (do_section_details)
4197 {
8d5ff12c
L
4198 sprintf (buff, "[%*.*lx]: ",
4199 field_size, field_size, (unsigned long) sh_flags);
4200 p += field_size + 4;
5477e8a0 4201 }
76da6bbe 4202
d1133906
NC
4203 while (sh_flags)
4204 {
4205 bfd_vma flag;
4206
4207 flag = sh_flags & - sh_flags;
4208 sh_flags &= ~ flag;
76da6bbe 4209
5477e8a0 4210 if (do_section_details)
d1133906 4211 {
5477e8a0
L
4212 switch (flag)
4213 {
91d6fa6a
NC
4214 case SHF_WRITE: sindex = 0; break;
4215 case SHF_ALLOC: sindex = 1; break;
4216 case SHF_EXECINSTR: sindex = 2; break;
4217 case SHF_MERGE: sindex = 3; break;
4218 case SHF_STRINGS: sindex = 4; break;
4219 case SHF_INFO_LINK: sindex = 5; break;
4220 case SHF_LINK_ORDER: sindex = 6; break;
4221 case SHF_OS_NONCONFORMING: sindex = 7; break;
4222 case SHF_GROUP: sindex = 8; break;
4223 case SHF_TLS: sindex = 9; break;
18ae9cc1 4224 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4225
5477e8a0 4226 default:
91d6fa6a 4227 sindex = -1;
cfcac11d 4228 switch (elf_header.e_machine)
148b93f2 4229 {
cfcac11d 4230 case EM_IA_64:
148b93f2 4231 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4232 sindex = 10;
148b93f2 4233 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4234 sindex = 11;
148b93f2
NC
4235#ifdef BFD64
4236 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4237 switch (flag)
4238 {
91d6fa6a
NC
4239 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4240 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4241 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4242 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4243 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4244 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4245 default: break;
4246 }
4247#endif
cfcac11d
NC
4248 break;
4249
caa83f8b
NC
4250 case EM_386:
4251 case EM_486:
4252 case EM_X86_64:
7f502d6c 4253 case EM_L1OM:
cfcac11d
NC
4254 case EM_OLD_SPARCV9:
4255 case EM_SPARC32PLUS:
4256 case EM_SPARCV9:
4257 case EM_SPARC:
18ae9cc1 4258 if (flag == SHF_ORDERED)
91d6fa6a 4259 sindex = 19;
cfcac11d
NC
4260 break;
4261 default:
4262 break;
148b93f2 4263 }
5477e8a0
L
4264 }
4265
91d6fa6a 4266 if (sindex != -1)
5477e8a0 4267 {
8d5ff12c
L
4268 if (p != buff + field_size + 4)
4269 {
4270 if (size < (10 + 2))
4271 abort ();
4272 size -= 2;
4273 *p++ = ',';
4274 *p++ = ' ';
4275 }
4276
91d6fa6a
NC
4277 size -= flags [sindex].len;
4278 p = stpcpy (p, flags [sindex].str);
5477e8a0 4279 }
3b22753a 4280 else if (flag & SHF_MASKOS)
8d5ff12c 4281 os_flags |= flag;
d1133906 4282 else if (flag & SHF_MASKPROC)
8d5ff12c 4283 proc_flags |= flag;
d1133906 4284 else
8d5ff12c 4285 unknown_flags |= flag;
5477e8a0
L
4286 }
4287 else
4288 {
4289 switch (flag)
4290 {
4291 case SHF_WRITE: *p = 'W'; break;
4292 case SHF_ALLOC: *p = 'A'; break;
4293 case SHF_EXECINSTR: *p = 'X'; break;
4294 case SHF_MERGE: *p = 'M'; break;
4295 case SHF_STRINGS: *p = 'S'; break;
4296 case SHF_INFO_LINK: *p = 'I'; break;
4297 case SHF_LINK_ORDER: *p = 'L'; break;
4298 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4299 case SHF_GROUP: *p = 'G'; break;
4300 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4301 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4302
4303 default:
8a9036a4
L
4304 if ((elf_header.e_machine == EM_X86_64
4305 || elf_header.e_machine == EM_L1OM)
5477e8a0
L
4306 && flag == SHF_X86_64_LARGE)
4307 *p = 'l';
4308 else if (flag & SHF_MASKOS)
4309 {
4310 *p = 'o';
4311 sh_flags &= ~ SHF_MASKOS;
4312 }
4313 else if (flag & SHF_MASKPROC)
4314 {
4315 *p = 'p';
4316 sh_flags &= ~ SHF_MASKPROC;
4317 }
4318 else
4319 *p = 'x';
4320 break;
4321 }
4322 p++;
d1133906
NC
4323 }
4324 }
76da6bbe 4325
8d5ff12c
L
4326 if (do_section_details)
4327 {
4328 if (os_flags)
4329 {
4330 size -= 5 + field_size;
4331 if (p != buff + field_size + 4)
4332 {
4333 if (size < (2 + 1))
4334 abort ();
4335 size -= 2;
4336 *p++ = ',';
4337 *p++ = ' ';
4338 }
4339 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4340 (unsigned long) os_flags);
4341 p += 5 + field_size;
4342 }
4343 if (proc_flags)
4344 {
4345 size -= 7 + field_size;
4346 if (p != buff + field_size + 4)
4347 {
4348 if (size < (2 + 1))
4349 abort ();
4350 size -= 2;
4351 *p++ = ',';
4352 *p++ = ' ';
4353 }
4354 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4355 (unsigned long) proc_flags);
4356 p += 7 + field_size;
4357 }
4358 if (unknown_flags)
4359 {
4360 size -= 10 + field_size;
4361 if (p != buff + field_size + 4)
4362 {
4363 if (size < (2 + 1))
4364 abort ();
4365 size -= 2;
4366 *p++ = ',';
4367 *p++ = ' ';
4368 }
2b692964 4369 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4370 (unsigned long) unknown_flags);
4371 p += 10 + field_size;
4372 }
4373 }
4374
e9e44622 4375 *p = '\0';
d1133906
NC
4376 return buff;
4377}
4378
252b5132 4379static int
2cf0635d 4380process_section_headers (FILE * file)
252b5132 4381{
2cf0635d 4382 Elf_Internal_Shdr * section;
b34976b6 4383 unsigned int i;
252b5132
RH
4384
4385 section_headers = NULL;
4386
4387 if (elf_header.e_shnum == 0)
4388 {
82f2dbf7
NC
4389 /* PR binutils/12467. */
4390 if (elf_header.e_shoff != 0)
4391 warn (_("possibly corrupt ELF file header - it has a non-zero"
4392 " section header offset, but no section headers\n"));
4393 else if (do_sections)
252b5132
RH
4394 printf (_("\nThere are no sections in this file.\n"));
4395
4396 return 1;
4397 }
4398
4399 if (do_sections && !do_header)
9ea033b2 4400 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4401 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4402
9ea033b2
NC
4403 if (is_32bit_elf)
4404 {
560f3c1c 4405 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4406 return 0;
4407 }
560f3c1c 4408 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4409 return 0;
4410
4411 /* Read in the string table, so that we have names to display. */
0b49d371 4412 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4413 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4414 {
4fbb74a6 4415 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4416
c256ffe7
JJ
4417 if (section->sh_size != 0)
4418 {
3f5e193b
NC
4419 string_table = (char *) get_data (NULL, file, section->sh_offset,
4420 1, section->sh_size,
4421 _("string table"));
0de14b54 4422
c256ffe7
JJ
4423 string_table_length = string_table != NULL ? section->sh_size : 0;
4424 }
252b5132
RH
4425 }
4426
4427 /* Scan the sections for the dynamic symbol table
e3c8793a 4428 and dynamic string table and debug sections. */
252b5132
RH
4429 dynamic_symbols = NULL;
4430 dynamic_strings = NULL;
4431 dynamic_syminfo = NULL;
f1ef08cb 4432 symtab_shndx_hdr = NULL;
103f02d3 4433
89fac5e3
RS
4434 eh_addr_size = is_32bit_elf ? 4 : 8;
4435 switch (elf_header.e_machine)
4436 {
4437 case EM_MIPS:
4438 case EM_MIPS_RS3_LE:
4439 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4440 FDE addresses. However, the ABI also has a semi-official ILP32
4441 variant for which the normal FDE address size rules apply.
4442
4443 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4444 section, where XX is the size of longs in bits. Unfortunately,
4445 earlier compilers provided no way of distinguishing ILP32 objects
4446 from LP64 objects, so if there's any doubt, we should assume that
4447 the official LP64 form is being used. */
4448 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4449 && find_section (".gcc_compiled_long32") == NULL)
4450 eh_addr_size = 8;
4451 break;
0f56a26a
DD
4452
4453 case EM_H8_300:
4454 case EM_H8_300H:
4455 switch (elf_header.e_flags & EF_H8_MACH)
4456 {
4457 case E_H8_MACH_H8300:
4458 case E_H8_MACH_H8300HN:
4459 case E_H8_MACH_H8300SN:
4460 case E_H8_MACH_H8300SXN:
4461 eh_addr_size = 2;
4462 break;
4463 case E_H8_MACH_H8300H:
4464 case E_H8_MACH_H8300S:
4465 case E_H8_MACH_H8300SX:
4466 eh_addr_size = 4;
4467 break;
4468 }
f4236fe4
DD
4469 break;
4470
ff7eeb89 4471 case EM_M32C_OLD:
f4236fe4
DD
4472 case EM_M32C:
4473 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4474 {
4475 case EF_M32C_CPU_M16C:
4476 eh_addr_size = 2;
4477 break;
4478 }
4479 break;
89fac5e3
RS
4480 }
4481
08d8fa11
JJ
4482#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4483 do \
4484 { \
4485 size_t expected_entsize \
4486 = is_32bit_elf ? size32 : size64; \
4487 if (section->sh_entsize != expected_entsize) \
4488 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4489 i, (unsigned long int) section->sh_entsize, \
4490 (unsigned long int) expected_entsize); \
4491 section->sh_entsize = expected_entsize; \
4492 } \
4493 while (0)
4494#define CHECK_ENTSIZE(section, i, type) \
4495 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4496 sizeof (Elf64_External_##type))
4497
252b5132
RH
4498 for (i = 0, section = section_headers;
4499 i < elf_header.e_shnum;
b34976b6 4500 i++, section++)
252b5132 4501 {
2cf0635d 4502 char * name = SECTION_NAME (section);
252b5132
RH
4503
4504 if (section->sh_type == SHT_DYNSYM)
4505 {
4506 if (dynamic_symbols != NULL)
4507 {
4508 error (_("File contains multiple dynamic symbol tables\n"));
4509 continue;
4510 }
4511
08d8fa11 4512 CHECK_ENTSIZE (section, i, Sym);
19936277 4513 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4514 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4515 }
4516 else if (section->sh_type == SHT_STRTAB
18bd398b 4517 && streq (name, ".dynstr"))
252b5132
RH
4518 {
4519 if (dynamic_strings != NULL)
4520 {
4521 error (_("File contains multiple dynamic string tables\n"));
4522 continue;
4523 }
4524
3f5e193b
NC
4525 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4526 1, section->sh_size,
4527 _("dynamic strings"));
d79b3d50 4528 dynamic_strings_length = section->sh_size;
252b5132 4529 }
9ad5cbcf
AM
4530 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4531 {
4532 if (symtab_shndx_hdr != NULL)
4533 {
4534 error (_("File contains multiple symtab shndx tables\n"));
4535 continue;
4536 }
4537 symtab_shndx_hdr = section;
4538 }
08d8fa11
JJ
4539 else if (section->sh_type == SHT_SYMTAB)
4540 CHECK_ENTSIZE (section, i, Sym);
4541 else if (section->sh_type == SHT_GROUP)
4542 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4543 else if (section->sh_type == SHT_REL)
4544 CHECK_ENTSIZE (section, i, Rel);
4545 else if (section->sh_type == SHT_RELA)
4546 CHECK_ENTSIZE (section, i, Rela);
252b5132 4547 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4548 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4549 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4550 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4551 && (const_strneq (name, ".debug_")
4552 || const_strneq (name, ".zdebug_")))
252b5132 4553 {
1b315056
CS
4554 if (name[1] == 'z')
4555 name += sizeof (".zdebug_") - 1;
4556 else
4557 name += sizeof (".debug_") - 1;
252b5132
RH
4558
4559 if (do_debugging
18bd398b 4560 || (do_debug_info && streq (name, "info"))
2b6f5997 4561 || (do_debug_info && streq (name, "types"))
18bd398b 4562 || (do_debug_abbrevs && streq (name, "abbrev"))
4cb93e3b 4563 || (do_debug_lines && streq (name, "line"))
18bd398b 4564 || (do_debug_pubnames && streq (name, "pubnames"))
f9f0e732 4565 || (do_debug_pubtypes && streq (name, "pubtypes"))
18bd398b
NC
4566 || (do_debug_aranges && streq (name, "aranges"))
4567 || (do_debug_ranges && streq (name, "ranges"))
4568 || (do_debug_frames && streq (name, "frame"))
4569 || (do_debug_macinfo && streq (name, "macinfo"))
4570 || (do_debug_str && streq (name, "str"))
4571 || (do_debug_loc && streq (name, "loc"))
252b5132 4572 )
09c11c86 4573 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4574 }
a262ae96 4575 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4576 else if ((do_debugging || do_debug_info)
0112cd26 4577 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4578 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4579 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4580 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4581 else if (do_gdb_index && streq (name, ".gdb_index"))
4582 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4583 /* Trace sections for Itanium VMS. */
4584 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4585 || do_trace_aranges)
4586 && const_strneq (name, ".trace_"))
4587 {
4588 name += sizeof (".trace_") - 1;
4589
4590 if (do_debugging
4591 || (do_trace_info && streq (name, "info"))
4592 || (do_trace_abbrevs && streq (name, "abbrev"))
4593 || (do_trace_aranges && streq (name, "aranges"))
4594 )
4595 request_dump_bynumber (i, DEBUG_DUMP);
4596 }
4597
252b5132
RH
4598 }
4599
4600 if (! do_sections)
4601 return 1;
4602
3a1a2036
NC
4603 if (elf_header.e_shnum > 1)
4604 printf (_("\nSection Headers:\n"));
4605 else
4606 printf (_("\nSection Header:\n"));
76da6bbe 4607
f7a99963 4608 if (is_32bit_elf)
595cf52e 4609 {
5477e8a0 4610 if (do_section_details)
595cf52e
L
4611 {
4612 printf (_(" [Nr] Name\n"));
5477e8a0 4613 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4614 }
4615 else
4616 printf
4617 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4618 }
d974e256 4619 else if (do_wide)
595cf52e 4620 {
5477e8a0 4621 if (do_section_details)
595cf52e
L
4622 {
4623 printf (_(" [Nr] Name\n"));
5477e8a0 4624 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4625 }
4626 else
4627 printf
4628 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4629 }
f7a99963
NC
4630 else
4631 {
5477e8a0 4632 if (do_section_details)
595cf52e
L
4633 {
4634 printf (_(" [Nr] Name\n"));
5477e8a0
L
4635 printf (_(" Type Address Offset Link\n"));
4636 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4637 }
4638 else
4639 {
4640 printf (_(" [Nr] Name Type Address Offset\n"));
4641 printf (_(" Size EntSize Flags Link Info Align\n"));
4642 }
f7a99963 4643 }
252b5132 4644
5477e8a0
L
4645 if (do_section_details)
4646 printf (_(" Flags\n"));
4647
252b5132
RH
4648 for (i = 0, section = section_headers;
4649 i < elf_header.e_shnum;
b34976b6 4650 i++, section++)
252b5132 4651 {
5477e8a0 4652 if (do_section_details)
595cf52e
L
4653 {
4654 printf (" [%2u] %s\n",
4fbb74a6 4655 i,
595cf52e
L
4656 SECTION_NAME (section));
4657 if (is_32bit_elf || do_wide)
4658 printf (" %-15.15s ",
4659 get_section_type_name (section->sh_type));
4660 }
4661 else
b9eb56c1
NC
4662 printf ((do_wide ? " [%2u] %-17s %-15s "
4663 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4664 i,
595cf52e
L
4665 SECTION_NAME (section),
4666 get_section_type_name (section->sh_type));
252b5132 4667
f7a99963
NC
4668 if (is_32bit_elf)
4669 {
cfcac11d
NC
4670 const char * link_too_big = NULL;
4671
f7a99963 4672 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4673
f7a99963
NC
4674 printf ( " %6.6lx %6.6lx %2.2lx",
4675 (unsigned long) section->sh_offset,
4676 (unsigned long) section->sh_size,
4677 (unsigned long) section->sh_entsize);
d1133906 4678
5477e8a0
L
4679 if (do_section_details)
4680 fputs (" ", stdout);
4681 else
4682 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4683
cfcac11d
NC
4684 if (section->sh_link >= elf_header.e_shnum)
4685 {
4686 link_too_big = "";
4687 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4688 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4689 switch (elf_header.e_machine)
4690 {
caa83f8b
NC
4691 case EM_386:
4692 case EM_486:
4693 case EM_X86_64:
7f502d6c 4694 case EM_L1OM:
cfcac11d
NC
4695 case EM_OLD_SPARCV9:
4696 case EM_SPARC32PLUS:
4697 case EM_SPARCV9:
4698 case EM_SPARC:
4699 if (section->sh_link == (SHN_BEFORE & 0xffff))
4700 link_too_big = "BEFORE";
4701 else if (section->sh_link == (SHN_AFTER & 0xffff))
4702 link_too_big = "AFTER";
4703 break;
4704 default:
4705 break;
4706 }
4707 }
4708
4709 if (do_section_details)
4710 {
4711 if (link_too_big != NULL && * link_too_big)
4712 printf ("<%s> ", link_too_big);
4713 else
4714 printf ("%2u ", section->sh_link);
4715 printf ("%3u %2lu\n", section->sh_info,
4716 (unsigned long) section->sh_addralign);
4717 }
4718 else
4719 printf ("%2u %3u %2lu\n",
4720 section->sh_link,
4721 section->sh_info,
4722 (unsigned long) section->sh_addralign);
4723
4724 if (link_too_big && ! * link_too_big)
4725 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4726 i, section->sh_link);
f7a99963 4727 }
d974e256
JJ
4728 else if (do_wide)
4729 {
4730 print_vma (section->sh_addr, LONG_HEX);
4731
4732 if ((long) section->sh_offset == section->sh_offset)
4733 printf (" %6.6lx", (unsigned long) section->sh_offset);
4734 else
4735 {
4736 putchar (' ');
4737 print_vma (section->sh_offset, LONG_HEX);
4738 }
4739
4740 if ((unsigned long) section->sh_size == section->sh_size)
4741 printf (" %6.6lx", (unsigned long) section->sh_size);
4742 else
4743 {
4744 putchar (' ');
4745 print_vma (section->sh_size, LONG_HEX);
4746 }
4747
4748 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4749 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4750 else
4751 {
4752 putchar (' ');
4753 print_vma (section->sh_entsize, LONG_HEX);
4754 }
4755
5477e8a0
L
4756 if (do_section_details)
4757 fputs (" ", stdout);
4758 else
4759 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4760
72de5009 4761 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4762
4763 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4764 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4765 else
4766 {
4767 print_vma (section->sh_addralign, DEC);
4768 putchar ('\n');
4769 }
4770 }
5477e8a0 4771 else if (do_section_details)
595cf52e 4772 {
5477e8a0 4773 printf (" %-15.15s ",
595cf52e 4774 get_section_type_name (section->sh_type));
595cf52e
L
4775 print_vma (section->sh_addr, LONG_HEX);
4776 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4777 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4778 else
4779 {
4780 printf (" ");
4781 print_vma (section->sh_offset, LONG_HEX);
4782 }
72de5009 4783 printf (" %u\n ", section->sh_link);
595cf52e 4784 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4785 putchar (' ');
595cf52e
L
4786 print_vma (section->sh_entsize, LONG_HEX);
4787
72de5009
AM
4788 printf (" %-16u %lu\n",
4789 section->sh_info,
595cf52e
L
4790 (unsigned long) section->sh_addralign);
4791 }
f7a99963
NC
4792 else
4793 {
4794 putchar (' ');
4795 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4796 if ((long) section->sh_offset == section->sh_offset)
4797 printf (" %8.8lx", (unsigned long) section->sh_offset);
4798 else
4799 {
4800 printf (" ");
4801 print_vma (section->sh_offset, LONG_HEX);
4802 }
f7a99963
NC
4803 printf ("\n ");
4804 print_vma (section->sh_size, LONG_HEX);
4805 printf (" ");
4806 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4807
d1133906 4808 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4809
72de5009
AM
4810 printf (" %2u %3u %lu\n",
4811 section->sh_link,
4812 section->sh_info,
f7a99963
NC
4813 (unsigned long) section->sh_addralign);
4814 }
5477e8a0
L
4815
4816 if (do_section_details)
4817 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4818 }
4819
5477e8a0 4820 if (!do_section_details)
3dbcc61d
NC
4821 {
4822 if (elf_header.e_machine == EM_X86_64
4823 || elf_header.e_machine == EM_L1OM)
4824 printf (_("Key to Flags:\n\
4825 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
4826 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
4827 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
4828 else
4829 printf (_("Key to Flags:\n\
e3c8793a 4830 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 4831 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 4832 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 4833 }
d1133906 4834
252b5132
RH
4835 return 1;
4836}
4837
f5842774
L
4838static const char *
4839get_group_flags (unsigned int flags)
4840{
4841 static char buff[32];
4842 switch (flags)
4843 {
220453ec
AM
4844 case 0:
4845 return "";
4846
f5842774 4847 case GRP_COMDAT:
220453ec 4848 return "COMDAT ";
f5842774
L
4849
4850 default:
220453ec 4851 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
4852 break;
4853 }
4854 return buff;
4855}
4856
4857static int
2cf0635d 4858process_section_groups (FILE * file)
f5842774 4859{
2cf0635d 4860 Elf_Internal_Shdr * section;
f5842774 4861 unsigned int i;
2cf0635d
NC
4862 struct group * group;
4863 Elf_Internal_Shdr * symtab_sec;
4864 Elf_Internal_Shdr * strtab_sec;
4865 Elf_Internal_Sym * symtab;
4866 char * strtab;
c256ffe7 4867 size_t strtab_size;
d1f5c6e3
L
4868
4869 /* Don't process section groups unless needed. */
4870 if (!do_unwind && !do_section_groups)
4871 return 1;
f5842774
L
4872
4873 if (elf_header.e_shnum == 0)
4874 {
4875 if (do_section_groups)
82f2dbf7 4876 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
4877
4878 return 1;
4879 }
4880
4881 if (section_headers == NULL)
4882 {
4883 error (_("Section headers are not available!\n"));
4884 abort ();
4885 }
4886
3f5e193b
NC
4887 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
4888 sizeof (struct group *));
e4b17d5c
L
4889
4890 if (section_headers_groups == NULL)
4891 {
4892 error (_("Out of memory\n"));
4893 return 0;
4894 }
4895
f5842774 4896 /* Scan the sections for the group section. */
d1f5c6e3 4897 group_count = 0;
f5842774
L
4898 for (i = 0, section = section_headers;
4899 i < elf_header.e_shnum;
4900 i++, section++)
e4b17d5c
L
4901 if (section->sh_type == SHT_GROUP)
4902 group_count++;
4903
d1f5c6e3
L
4904 if (group_count == 0)
4905 {
4906 if (do_section_groups)
4907 printf (_("\nThere are no section groups in this file.\n"));
4908
4909 return 1;
4910 }
4911
3f5e193b 4912 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
4913
4914 if (section_groups == NULL)
4915 {
4916 error (_("Out of memory\n"));
4917 return 0;
4918 }
4919
d1f5c6e3
L
4920 symtab_sec = NULL;
4921 strtab_sec = NULL;
4922 symtab = NULL;
4923 strtab = NULL;
c256ffe7 4924 strtab_size = 0;
e4b17d5c
L
4925 for (i = 0, section = section_headers, group = section_groups;
4926 i < elf_header.e_shnum;
4927 i++, section++)
f5842774
L
4928 {
4929 if (section->sh_type == SHT_GROUP)
4930 {
2cf0635d
NC
4931 char * name = SECTION_NAME (section);
4932 char * group_name;
4933 unsigned char * start;
4934 unsigned char * indices;
f5842774 4935 unsigned int entry, j, size;
2cf0635d
NC
4936 Elf_Internal_Shdr * sec;
4937 Elf_Internal_Sym * sym;
f5842774
L
4938
4939 /* Get the symbol table. */
4fbb74a6
AM
4940 if (section->sh_link >= elf_header.e_shnum
4941 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 4942 != SHT_SYMTAB))
f5842774
L
4943 {
4944 error (_("Bad sh_link in group section `%s'\n"), name);
4945 continue;
4946 }
d1f5c6e3
L
4947
4948 if (symtab_sec != sec)
4949 {
4950 symtab_sec = sec;
4951 if (symtab)
4952 free (symtab);
4953 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4954 }
f5842774 4955
dd24e3da
NC
4956 if (symtab == NULL)
4957 {
4958 error (_("Corrupt header in group section `%s'\n"), name);
4959 continue;
4960 }
4961
f5842774
L
4962 sym = symtab + section->sh_info;
4963
4964 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4965 {
4fbb74a6
AM
4966 if (sym->st_shndx == 0
4967 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
4968 {
4969 error (_("Bad sh_info in group section `%s'\n"), name);
4970 continue;
4971 }
ba2685cc 4972
4fbb74a6 4973 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
4974 strtab_sec = NULL;
4975 if (strtab)
4976 free (strtab);
f5842774 4977 strtab = NULL;
c256ffe7 4978 strtab_size = 0;
f5842774
L
4979 }
4980 else
4981 {
4982 /* Get the string table. */
4fbb74a6 4983 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
4984 {
4985 strtab_sec = NULL;
4986 if (strtab)
4987 free (strtab);
4988 strtab = NULL;
4989 strtab_size = 0;
4990 }
4991 else if (strtab_sec
4fbb74a6 4992 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
4993 {
4994 strtab_sec = sec;
4995 if (strtab)
4996 free (strtab);
3f5e193b
NC
4997 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
4998 1, strtab_sec->sh_size,
4999 _("string table"));
c256ffe7 5000 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5001 }
c256ffe7 5002 group_name = sym->st_name < strtab_size
2b692964 5003 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5004 }
5005
3f5e193b
NC
5006 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5007 1, section->sh_size,
5008 _("section data"));
f5842774
L
5009
5010 indices = start;
5011 size = (section->sh_size / section->sh_entsize) - 1;
5012 entry = byte_get (indices, 4);
5013 indices += 4;
e4b17d5c
L
5014
5015 if (do_section_groups)
5016 {
2b692964 5017 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5018 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5019
e4b17d5c
L
5020 printf (_(" [Index] Name\n"));
5021 }
5022
5023 group->group_index = i;
5024
f5842774
L
5025 for (j = 0; j < size; j++)
5026 {
2cf0635d 5027 struct group_list * g;
e4b17d5c 5028
f5842774
L
5029 entry = byte_get (indices, 4);
5030 indices += 4;
5031
4fbb74a6 5032 if (entry >= elf_header.e_shnum)
391cb864
L
5033 {
5034 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5035 entry, i, elf_header.e_shnum - 1);
5036 continue;
5037 }
391cb864 5038
4fbb74a6 5039 if (section_headers_groups [entry] != NULL)
e4b17d5c 5040 {
d1f5c6e3
L
5041 if (entry)
5042 {
391cb864
L
5043 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5044 entry, i,
4fbb74a6 5045 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5046 continue;
5047 }
5048 else
5049 {
5050 /* Intel C/C++ compiler may put section 0 in a
5051 section group. We just warn it the first time
5052 and ignore it afterwards. */
5053 static int warned = 0;
5054 if (!warned)
5055 {
5056 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5057 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5058 warned++;
5059 }
5060 }
e4b17d5c
L
5061 }
5062
4fbb74a6 5063 section_headers_groups [entry] = group;
e4b17d5c
L
5064
5065 if (do_section_groups)
5066 {
4fbb74a6 5067 sec = section_headers + entry;
c256ffe7 5068 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5069 }
5070
3f5e193b 5071 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5072 g->section_index = entry;
5073 g->next = group->root;
5074 group->root = g;
f5842774
L
5075 }
5076
f5842774
L
5077 if (start)
5078 free (start);
e4b17d5c
L
5079
5080 group++;
f5842774
L
5081 }
5082 }
5083
d1f5c6e3
L
5084 if (symtab)
5085 free (symtab);
5086 if (strtab)
5087 free (strtab);
f5842774
L
5088 return 1;
5089}
5090
28f997cf
TG
5091/* Data used to display dynamic fixups. */
5092
5093struct ia64_vms_dynfixup
5094{
5095 bfd_vma needed_ident; /* Library ident number. */
5096 bfd_vma needed; /* Index in the dstrtab of the library name. */
5097 bfd_vma fixup_needed; /* Index of the library. */
5098 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5099 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5100};
5101
5102/* Data used to display dynamic relocations. */
5103
5104struct ia64_vms_dynimgrela
5105{
5106 bfd_vma img_rela_cnt; /* Number of relocations. */
5107 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5108};
5109
5110/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5111 library). */
5112
5113static void
5114dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5115 const char *strtab, unsigned int strtab_sz)
5116{
5117 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5118 long i;
5119 const char *lib_name;
5120
5121 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5122 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5123 _("dynamic section image fixups"));
5124 if (!imfs)
5125 return;
5126
5127 if (fixup->needed < strtab_sz)
5128 lib_name = strtab + fixup->needed;
5129 else
5130 {
5131 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5132 (unsigned long) fixup->needed);
28f997cf
TG
5133 lib_name = "???";
5134 }
5135 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5136 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5137 printf
5138 (_("Seg Offset Type SymVec DataType\n"));
5139
5140 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5141 {
5142 unsigned int type;
5143 const char *rtype;
5144
5145 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5146 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5147 type = BYTE_GET (imfs [i].type);
5148 rtype = elf_ia64_reloc_type (type);
5149 if (rtype == NULL)
5150 printf (" 0x%08x ", type);
5151 else
5152 printf (" %-32s ", rtype);
5153 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5154 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5155 }
5156
5157 free (imfs);
5158}
5159
5160/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5161
5162static void
5163dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5164{
5165 Elf64_External_VMS_IMAGE_RELA *imrs;
5166 long i;
5167
5168 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5169 1, imgrela->img_rela_cnt * sizeof (*imrs),
5170 _("dynamic section image relas"));
5171 if (!imrs)
5172 return;
5173
5174 printf (_("\nImage relocs\n"));
5175 printf
5176 (_("Seg Offset Type Addend Seg Sym Off\n"));
5177
5178 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5179 {
5180 unsigned int type;
5181 const char *rtype;
5182
5183 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5184 printf ("%08" BFD_VMA_FMT "x ",
5185 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5186 type = BYTE_GET (imrs [i].type);
5187 rtype = elf_ia64_reloc_type (type);
5188 if (rtype == NULL)
5189 printf ("0x%08x ", type);
5190 else
5191 printf ("%-31s ", rtype);
5192 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5193 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5194 printf ("%08" BFD_VMA_FMT "x\n",
5195 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5196 }
5197
5198 free (imrs);
5199}
5200
5201/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5202
5203static int
5204process_ia64_vms_dynamic_relocs (FILE *file)
5205{
5206 struct ia64_vms_dynfixup fixup;
5207 struct ia64_vms_dynimgrela imgrela;
5208 Elf_Internal_Dyn *entry;
5209 int res = 0;
5210 bfd_vma strtab_off = 0;
5211 bfd_vma strtab_sz = 0;
5212 char *strtab = NULL;
5213
5214 memset (&fixup, 0, sizeof (fixup));
5215 memset (&imgrela, 0, sizeof (imgrela));
5216
5217 /* Note: the order of the entries is specified by the OpenVMS specs. */
5218 for (entry = dynamic_section;
5219 entry < dynamic_section + dynamic_nent;
5220 entry++)
5221 {
5222 switch (entry->d_tag)
5223 {
5224 case DT_IA_64_VMS_STRTAB_OFFSET:
5225 strtab_off = entry->d_un.d_val;
5226 break;
5227 case DT_STRSZ:
5228 strtab_sz = entry->d_un.d_val;
5229 if (strtab == NULL)
5230 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5231 1, strtab_sz, _("dynamic string section"));
5232 break;
5233
5234 case DT_IA_64_VMS_NEEDED_IDENT:
5235 fixup.needed_ident = entry->d_un.d_val;
5236 break;
5237 case DT_NEEDED:
5238 fixup.needed = entry->d_un.d_val;
5239 break;
5240 case DT_IA_64_VMS_FIXUP_NEEDED:
5241 fixup.fixup_needed = entry->d_un.d_val;
5242 break;
5243 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5244 fixup.fixup_rela_cnt = entry->d_un.d_val;
5245 break;
5246 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5247 fixup.fixup_rela_off = entry->d_un.d_val;
5248 res++;
5249 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5250 break;
5251
5252 case DT_IA_64_VMS_IMG_RELA_CNT:
5253 imgrela.img_rela_cnt = entry->d_un.d_val;
5254 break;
5255 case DT_IA_64_VMS_IMG_RELA_OFF:
5256 imgrela.img_rela_off = entry->d_un.d_val;
5257 res++;
5258 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5259 break;
5260
5261 default:
5262 break;
5263 }
5264 }
5265
5266 if (strtab != NULL)
5267 free (strtab);
5268
5269 return res;
5270}
5271
85b1c36d 5272static struct
566b0d53 5273{
2cf0635d 5274 const char * name;
566b0d53
L
5275 int reloc;
5276 int size;
5277 int rela;
5278} dynamic_relocations [] =
5279{
5280 { "REL", DT_REL, DT_RELSZ, FALSE },
5281 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5282 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5283};
5284
252b5132 5285/* Process the reloc section. */
18bd398b 5286
252b5132 5287static int
2cf0635d 5288process_relocs (FILE * file)
252b5132 5289{
b34976b6
AM
5290 unsigned long rel_size;
5291 unsigned long rel_offset;
252b5132
RH
5292
5293
5294 if (!do_reloc)
5295 return 1;
5296
5297 if (do_using_dynamic)
5298 {
566b0d53 5299 int is_rela;
2cf0635d 5300 const char * name;
566b0d53
L
5301 int has_dynamic_reloc;
5302 unsigned int i;
0de14b54 5303
566b0d53 5304 has_dynamic_reloc = 0;
252b5132 5305
566b0d53 5306 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5307 {
566b0d53
L
5308 is_rela = dynamic_relocations [i].rela;
5309 name = dynamic_relocations [i].name;
5310 rel_size = dynamic_info [dynamic_relocations [i].size];
5311 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5312
566b0d53
L
5313 has_dynamic_reloc |= rel_size;
5314
5315 if (is_rela == UNKNOWN)
aa903cfb 5316 {
566b0d53
L
5317 if (dynamic_relocations [i].reloc == DT_JMPREL)
5318 switch (dynamic_info[DT_PLTREL])
5319 {
5320 case DT_REL:
5321 is_rela = FALSE;
5322 break;
5323 case DT_RELA:
5324 is_rela = TRUE;
5325 break;
5326 }
aa903cfb 5327 }
252b5132 5328
566b0d53
L
5329 if (rel_size)
5330 {
5331 printf
5332 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5333 name, rel_offset, rel_size);
252b5132 5334
d93f0186
NC
5335 dump_relocations (file,
5336 offset_from_vma (file, rel_offset, rel_size),
5337 rel_size,
566b0d53 5338 dynamic_symbols, num_dynamic_syms,
d79b3d50 5339 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5340 }
252b5132 5341 }
566b0d53 5342
28f997cf
TG
5343 if (is_ia64_vms ())
5344 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5345
566b0d53 5346 if (! has_dynamic_reloc)
252b5132
RH
5347 printf (_("\nThere are no dynamic relocations in this file.\n"));
5348 }
5349 else
5350 {
2cf0635d 5351 Elf_Internal_Shdr * section;
b34976b6
AM
5352 unsigned long i;
5353 int found = 0;
252b5132
RH
5354
5355 for (i = 0, section = section_headers;
5356 i < elf_header.e_shnum;
b34976b6 5357 i++, section++)
252b5132
RH
5358 {
5359 if ( section->sh_type != SHT_RELA
5360 && section->sh_type != SHT_REL)
5361 continue;
5362
5363 rel_offset = section->sh_offset;
5364 rel_size = section->sh_size;
5365
5366 if (rel_size)
5367 {
2cf0635d 5368 Elf_Internal_Shdr * strsec;
b34976b6 5369 int is_rela;
103f02d3 5370
252b5132
RH
5371 printf (_("\nRelocation section "));
5372
5373 if (string_table == NULL)
19936277 5374 printf ("%d", section->sh_name);
252b5132 5375 else
3a1a2036 5376 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
5377
5378 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5379 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5380
d79b3d50
NC
5381 is_rela = section->sh_type == SHT_RELA;
5382
4fbb74a6
AM
5383 if (section->sh_link != 0
5384 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5385 {
2cf0635d
NC
5386 Elf_Internal_Shdr * symsec;
5387 Elf_Internal_Sym * symtab;
d79b3d50 5388 unsigned long nsyms;
c256ffe7 5389 unsigned long strtablen = 0;
2cf0635d 5390 char * strtab = NULL;
57346661 5391
4fbb74a6 5392 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5393 if (symsec->sh_type != SHT_SYMTAB
5394 && symsec->sh_type != SHT_DYNSYM)
5395 continue;
5396
af3fc3bc 5397 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 5398 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 5399
af3fc3bc
AM
5400 if (symtab == NULL)
5401 continue;
252b5132 5402
4fbb74a6
AM
5403 if (symsec->sh_link != 0
5404 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5405 {
4fbb74a6 5406 strsec = section_headers + symsec->sh_link;
103f02d3 5407
3f5e193b
NC
5408 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5409 1, strsec->sh_size,
5410 _("string table"));
c256ffe7
JJ
5411 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5412 }
252b5132 5413
d79b3d50
NC
5414 dump_relocations (file, rel_offset, rel_size,
5415 symtab, nsyms, strtab, strtablen, is_rela);
5416 if (strtab)
5417 free (strtab);
5418 free (symtab);
5419 }
5420 else
5421 dump_relocations (file, rel_offset, rel_size,
5422 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5423
5424 found = 1;
5425 }
5426 }
5427
5428 if (! found)
5429 printf (_("\nThere are no relocations in this file.\n"));
5430 }
5431
5432 return 1;
5433}
5434
57346661
AM
5435/* Process the unwind section. */
5436
4d6ed7c8
NC
5437#include "unwind-ia64.h"
5438
5439/* An absolute address consists of a section and an offset. If the
5440 section is NULL, the offset itself is the address, otherwise, the
5441 address equals to LOAD_ADDRESS(section) + offset. */
5442
5443struct absaddr
5444 {
5445 unsigned short section;
5446 bfd_vma offset;
5447 };
5448
1949de15
L
5449#define ABSADDR(a) \
5450 ((a).section \
5451 ? section_headers [(a).section].sh_addr + (a).offset \
5452 : (a).offset)
5453
3f5e193b
NC
5454struct ia64_unw_table_entry
5455 {
5456 struct absaddr start;
5457 struct absaddr end;
5458 struct absaddr info;
5459 };
5460
57346661 5461struct ia64_unw_aux_info
4d6ed7c8 5462 {
3f5e193b
NC
5463
5464 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5465 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5466 unsigned char * info; /* Unwind info. */
b34976b6
AM
5467 unsigned long info_size; /* Size of unwind info. */
5468 bfd_vma info_addr; /* starting address of unwind info. */
5469 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5470 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5471 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5472 char * strtab; /* The string table. */
b34976b6 5473 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5474 };
5475
4d6ed7c8 5476static void
2cf0635d 5477find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5478 unsigned long nsyms,
2cf0635d 5479 const char * strtab,
57346661 5480 unsigned long strtab_size,
d3ba0551 5481 struct absaddr addr,
2cf0635d
NC
5482 const char ** symname,
5483 bfd_vma * offset)
4d6ed7c8 5484{
d3ba0551 5485 bfd_vma dist = 0x100000;
2cf0635d
NC
5486 Elf_Internal_Sym * sym;
5487 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5488 unsigned long i;
5489
0b6ae522
DJ
5490 REMOVE_ARCH_BITS (addr.offset);
5491
57346661 5492 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5493 {
0b6ae522
DJ
5494 bfd_vma value = sym->st_value;
5495
5496 REMOVE_ARCH_BITS (value);
5497
4d6ed7c8
NC
5498 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5499 && sym->st_name != 0
5500 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5501 && addr.offset >= value
5502 && addr.offset - value < dist)
4d6ed7c8
NC
5503 {
5504 best = sym;
0b6ae522 5505 dist = addr.offset - value;
4d6ed7c8
NC
5506 if (!dist)
5507 break;
5508 }
5509 }
5510 if (best)
5511 {
57346661 5512 *symname = (best->st_name >= strtab_size
2b692964 5513 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5514 *offset = dist;
5515 return;
5516 }
5517 *symname = NULL;
5518 *offset = addr.offset;
5519}
5520
5521static void
2cf0635d 5522dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5523{
2cf0635d 5524 struct ia64_unw_table_entry * tp;
4d6ed7c8 5525 int in_body;
7036c0e1 5526
4d6ed7c8
NC
5527 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5528 {
5529 bfd_vma stamp;
5530 bfd_vma offset;
2cf0635d
NC
5531 const unsigned char * dp;
5532 const unsigned char * head;
5533 const char * procname;
4d6ed7c8 5534
57346661
AM
5535 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5536 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5537
5538 fputs ("\n<", stdout);
5539
5540 if (procname)
5541 {
5542 fputs (procname, stdout);
5543
5544 if (offset)
5545 printf ("+%lx", (unsigned long) offset);
5546 }
5547
5548 fputs (">: [", stdout);
5549 print_vma (tp->start.offset, PREFIX_HEX);
5550 fputc ('-', stdout);
5551 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5552 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5553 (unsigned long) (tp->info.offset - aux->seg_base));
5554
1949de15 5555 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5556 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5557
86f55779 5558 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5559 (unsigned) UNW_VER (stamp),
5560 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5561 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5562 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5563 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5564
5565 if (UNW_VER (stamp) != 1)
5566 {
2b692964 5567 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5568 continue;
5569 }
5570
5571 in_body = 0;
89fac5e3 5572 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5573 dp = unw_decode (dp, in_body, & in_body);
5574 }
5575}
5576
5577static int
2cf0635d
NC
5578slurp_ia64_unwind_table (FILE * file,
5579 struct ia64_unw_aux_info * aux,
5580 Elf_Internal_Shdr * sec)
4d6ed7c8 5581{
89fac5e3 5582 unsigned long size, nrelas, i;
2cf0635d
NC
5583 Elf_Internal_Phdr * seg;
5584 struct ia64_unw_table_entry * tep;
5585 Elf_Internal_Shdr * relsec;
5586 Elf_Internal_Rela * rela;
5587 Elf_Internal_Rela * rp;
5588 unsigned char * table;
5589 unsigned char * tp;
5590 Elf_Internal_Sym * sym;
5591 const char * relname;
4d6ed7c8 5592
4d6ed7c8
NC
5593 /* First, find the starting address of the segment that includes
5594 this section: */
5595
5596 if (elf_header.e_phnum)
5597 {
d93f0186 5598 if (! get_program_headers (file))
4d6ed7c8 5599 return 0;
4d6ed7c8 5600
d93f0186
NC
5601 for (seg = program_headers;
5602 seg < program_headers + elf_header.e_phnum;
5603 ++seg)
4d6ed7c8
NC
5604 {
5605 if (seg->p_type != PT_LOAD)
5606 continue;
5607
5608 if (sec->sh_addr >= seg->p_vaddr
5609 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5610 {
5611 aux->seg_base = seg->p_vaddr;
5612 break;
5613 }
5614 }
4d6ed7c8
NC
5615 }
5616
5617 /* Second, build the unwind table from the contents of the unwind section: */
5618 size = sec->sh_size;
3f5e193b
NC
5619 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5620 _("unwind table"));
a6e9f9df
AM
5621 if (!table)
5622 return 0;
4d6ed7c8 5623
3f5e193b
NC
5624 aux->table = (struct ia64_unw_table_entry *)
5625 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5626 tep = aux->table;
c6a0c689 5627 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5628 {
5629 tep->start.section = SHN_UNDEF;
5630 tep->end.section = SHN_UNDEF;
5631 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5632 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5633 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5634 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5635 tep->start.offset += aux->seg_base;
5636 tep->end.offset += aux->seg_base;
5637 tep->info.offset += aux->seg_base;
5638 }
5639 free (table);
5640
41e92641 5641 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5642 for (relsec = section_headers;
5643 relsec < section_headers + elf_header.e_shnum;
5644 ++relsec)
5645 {
5646 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5647 || relsec->sh_info >= elf_header.e_shnum
5648 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5649 continue;
5650
5651 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5652 & rela, & nrelas))
5653 return 0;
5654
5655 for (rp = rela; rp < rela + nrelas; ++rp)
5656 {
aca88567
NC
5657 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5658 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5659
0112cd26 5660 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5661 {
e5fb9629 5662 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5663 continue;
5664 }
5665
89fac5e3 5666 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5667
89fac5e3 5668 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5669 {
5670 case 0:
5671 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5672 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5673 break;
5674 case 1:
5675 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5676 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5677 break;
5678 case 2:
5679 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5680 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5681 break;
5682 default:
5683 break;
5684 }
5685 }
5686
5687 free (rela);
5688 }
5689
89fac5e3 5690 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5691 return 1;
5692}
5693
5694static int
2cf0635d 5695ia64_process_unwind (FILE * file)
4d6ed7c8 5696{
2cf0635d
NC
5697 Elf_Internal_Shdr * sec;
5698 Elf_Internal_Shdr * unwsec = NULL;
5699 Elf_Internal_Shdr * strsec;
89fac5e3 5700 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5701 struct ia64_unw_aux_info aux;
f1467e33 5702
4d6ed7c8
NC
5703 memset (& aux, 0, sizeof (aux));
5704
4d6ed7c8
NC
5705 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5706 {
c256ffe7 5707 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5708 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5709 {
5710 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5711 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5712
4fbb74a6 5713 strsec = section_headers + sec->sh_link;
3f5e193b
NC
5714 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5715 1, strsec->sh_size,
5716 _("string table"));
c256ffe7 5717 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5718 }
5719 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5720 unwcount++;
5721 }
5722
5723 if (!unwcount)
5724 printf (_("\nThere are no unwind sections in this file.\n"));
5725
5726 while (unwcount-- > 0)
5727 {
2cf0635d 5728 char * suffix;
579f31ac
JJ
5729 size_t len, len2;
5730
5731 for (i = unwstart, sec = section_headers + unwstart;
5732 i < elf_header.e_shnum; ++i, ++sec)
5733 if (sec->sh_type == SHT_IA_64_UNWIND)
5734 {
5735 unwsec = sec;
5736 break;
5737 }
5738
5739 unwstart = i + 1;
5740 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5741
e4b17d5c
L
5742 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5743 {
5744 /* We need to find which section group it is in. */
2cf0635d 5745 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5746
5747 for (; g != NULL; g = g->next)
5748 {
4fbb74a6 5749 sec = section_headers + g->section_index;
18bd398b
NC
5750
5751 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5752 break;
e4b17d5c
L
5753 }
5754
5755 if (g == NULL)
5756 i = elf_header.e_shnum;
5757 }
18bd398b 5758 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5759 {
18bd398b 5760 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5761 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5762 suffix = SECTION_NAME (unwsec) + len;
5763 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5764 ++i, ++sec)
18bd398b
NC
5765 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5766 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5767 break;
5768 }
5769 else
5770 {
5771 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5772 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5773 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5774 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5775 suffix = "";
18bd398b 5776 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5777 suffix = SECTION_NAME (unwsec) + len;
5778 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5779 ++i, ++sec)
18bd398b
NC
5780 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5781 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5782 break;
5783 }
5784
5785 if (i == elf_header.e_shnum)
5786 {
5787 printf (_("\nCould not find unwind info section for "));
5788
5789 if (string_table == NULL)
5790 printf ("%d", unwsec->sh_name);
5791 else
3a1a2036 5792 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5793 }
5794 else
4d6ed7c8
NC
5795 {
5796 aux.info_size = sec->sh_size;
5797 aux.info_addr = sec->sh_addr;
3f5e193b
NC
5798 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
5799 aux.info_size,
5800 _("unwind info"));
4d6ed7c8 5801
579f31ac 5802 printf (_("\nUnwind section "));
4d6ed7c8 5803
579f31ac
JJ
5804 if (string_table == NULL)
5805 printf ("%d", unwsec->sh_name);
5806 else
3a1a2036 5807 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5808
579f31ac 5809 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5810 (unsigned long) unwsec->sh_offset,
89fac5e3 5811 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5812
579f31ac 5813 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5814
579f31ac
JJ
5815 if (aux.table_len > 0)
5816 dump_ia64_unwind (& aux);
5817
5818 if (aux.table)
5819 free ((char *) aux.table);
5820 if (aux.info)
5821 free ((char *) aux.info);
5822 aux.table = NULL;
5823 aux.info = NULL;
5824 }
4d6ed7c8 5825 }
4d6ed7c8 5826
4d6ed7c8
NC
5827 if (aux.symtab)
5828 free (aux.symtab);
5829 if (aux.strtab)
5830 free ((char *) aux.strtab);
5831
5832 return 1;
5833}
5834
3f5e193b
NC
5835struct hppa_unw_table_entry
5836 {
5837 struct absaddr start;
5838 struct absaddr end;
5839 unsigned int Cannot_unwind:1; /* 0 */
5840 unsigned int Millicode:1; /* 1 */
5841 unsigned int Millicode_save_sr0:1; /* 2 */
5842 unsigned int Region_description:2; /* 3..4 */
5843 unsigned int reserved1:1; /* 5 */
5844 unsigned int Entry_SR:1; /* 6 */
5845 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5846 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5847 unsigned int Args_stored:1; /* 16 */
5848 unsigned int Variable_Frame:1; /* 17 */
5849 unsigned int Separate_Package_Body:1; /* 18 */
5850 unsigned int Frame_Extension_Millicode:1; /* 19 */
5851 unsigned int Stack_Overflow_Check:1; /* 20 */
5852 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5853 unsigned int Ada_Region:1; /* 22 */
5854 unsigned int cxx_info:1; /* 23 */
5855 unsigned int cxx_try_catch:1; /* 24 */
5856 unsigned int sched_entry_seq:1; /* 25 */
5857 unsigned int reserved2:1; /* 26 */
5858 unsigned int Save_SP:1; /* 27 */
5859 unsigned int Save_RP:1; /* 28 */
5860 unsigned int Save_MRP_in_frame:1; /* 29 */
5861 unsigned int extn_ptr_defined:1; /* 30 */
5862 unsigned int Cleanup_defined:1; /* 31 */
5863
5864 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5865 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5866 unsigned int Large_frame:1; /* 2 */
5867 unsigned int Pseudo_SP_Set:1; /* 3 */
5868 unsigned int reserved4:1; /* 4 */
5869 unsigned int Total_frame_size:27; /* 5..31 */
5870 };
5871
57346661
AM
5872struct hppa_unw_aux_info
5873 {
3f5e193b 5874 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
5875 unsigned long table_len; /* Length of unwind table. */
5876 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5877 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5878 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5879 char * strtab; /* The string table. */
57346661
AM
5880 unsigned long strtab_size; /* Size of string table. */
5881 };
5882
5883static void
2cf0635d 5884dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5885{
2cf0635d 5886 struct hppa_unw_table_entry * tp;
57346661 5887
57346661
AM
5888 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5889 {
5890 bfd_vma offset;
2cf0635d 5891 const char * procname;
57346661
AM
5892
5893 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5894 aux->strtab_size, tp->start, &procname,
5895 &offset);
5896
5897 fputs ("\n<", stdout);
5898
5899 if (procname)
5900 {
5901 fputs (procname, stdout);
5902
5903 if (offset)
5904 printf ("+%lx", (unsigned long) offset);
5905 }
5906
5907 fputs (">: [", stdout);
5908 print_vma (tp->start.offset, PREFIX_HEX);
5909 fputc ('-', stdout);
5910 print_vma (tp->end.offset, PREFIX_HEX);
5911 printf ("]\n\t");
5912
18bd398b
NC
5913#define PF(_m) if (tp->_m) printf (#_m " ");
5914#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5915 PF(Cannot_unwind);
5916 PF(Millicode);
5917 PF(Millicode_save_sr0);
18bd398b 5918 /* PV(Region_description); */
57346661
AM
5919 PF(Entry_SR);
5920 PV(Entry_FR);
5921 PV(Entry_GR);
5922 PF(Args_stored);
5923 PF(Variable_Frame);
5924 PF(Separate_Package_Body);
5925 PF(Frame_Extension_Millicode);
5926 PF(Stack_Overflow_Check);
5927 PF(Two_Instruction_SP_Increment);
5928 PF(Ada_Region);
5929 PF(cxx_info);
5930 PF(cxx_try_catch);
5931 PF(sched_entry_seq);
5932 PF(Save_SP);
5933 PF(Save_RP);
5934 PF(Save_MRP_in_frame);
5935 PF(extn_ptr_defined);
5936 PF(Cleanup_defined);
5937 PF(MPE_XL_interrupt_marker);
5938 PF(HP_UX_interrupt_marker);
5939 PF(Large_frame);
5940 PF(Pseudo_SP_Set);
5941 PV(Total_frame_size);
5942#undef PF
5943#undef PV
5944 }
5945
18bd398b 5946 printf ("\n");
57346661
AM
5947}
5948
5949static int
2cf0635d
NC
5950slurp_hppa_unwind_table (FILE * file,
5951 struct hppa_unw_aux_info * aux,
5952 Elf_Internal_Shdr * sec)
57346661 5953{
1c0751b2 5954 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
5955 Elf_Internal_Phdr * seg;
5956 struct hppa_unw_table_entry * tep;
5957 Elf_Internal_Shdr * relsec;
5958 Elf_Internal_Rela * rela;
5959 Elf_Internal_Rela * rp;
5960 unsigned char * table;
5961 unsigned char * tp;
5962 Elf_Internal_Sym * sym;
5963 const char * relname;
57346661 5964
57346661
AM
5965 /* First, find the starting address of the segment that includes
5966 this section. */
5967
5968 if (elf_header.e_phnum)
5969 {
5970 if (! get_program_headers (file))
5971 return 0;
5972
5973 for (seg = program_headers;
5974 seg < program_headers + elf_header.e_phnum;
5975 ++seg)
5976 {
5977 if (seg->p_type != PT_LOAD)
5978 continue;
5979
5980 if (sec->sh_addr >= seg->p_vaddr
5981 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5982 {
5983 aux->seg_base = seg->p_vaddr;
5984 break;
5985 }
5986 }
5987 }
5988
5989 /* Second, build the unwind table from the contents of the unwind
5990 section. */
5991 size = sec->sh_size;
3f5e193b
NC
5992 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5993 _("unwind table"));
57346661
AM
5994 if (!table)
5995 return 0;
5996
1c0751b2
DA
5997 unw_ent_size = 16;
5998 nentries = size / unw_ent_size;
5999 size = unw_ent_size * nentries;
57346661 6000
3f5e193b
NC
6001 tep = aux->table = (struct hppa_unw_table_entry *)
6002 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6003
1c0751b2 6004 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6005 {
6006 unsigned int tmp1, tmp2;
6007
6008 tep->start.section = SHN_UNDEF;
6009 tep->end.section = SHN_UNDEF;
6010
1c0751b2
DA
6011 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6012 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6013 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6014 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6015
6016 tep->start.offset += aux->seg_base;
6017 tep->end.offset += aux->seg_base;
57346661
AM
6018
6019 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6020 tep->Millicode = (tmp1 >> 30) & 0x1;
6021 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6022 tep->Region_description = (tmp1 >> 27) & 0x3;
6023 tep->reserved1 = (tmp1 >> 26) & 0x1;
6024 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6025 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6026 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6027 tep->Args_stored = (tmp1 >> 15) & 0x1;
6028 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6029 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6030 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6031 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6032 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6033 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6034 tep->cxx_info = (tmp1 >> 8) & 0x1;
6035 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6036 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6037 tep->reserved2 = (tmp1 >> 5) & 0x1;
6038 tep->Save_SP = (tmp1 >> 4) & 0x1;
6039 tep->Save_RP = (tmp1 >> 3) & 0x1;
6040 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6041 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6042 tep->Cleanup_defined = tmp1 & 0x1;
6043
6044 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6045 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6046 tep->Large_frame = (tmp2 >> 29) & 0x1;
6047 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6048 tep->reserved4 = (tmp2 >> 27) & 0x1;
6049 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6050 }
6051 free (table);
6052
6053 /* Third, apply any relocations to the unwind table. */
57346661
AM
6054 for (relsec = section_headers;
6055 relsec < section_headers + elf_header.e_shnum;
6056 ++relsec)
6057 {
6058 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6059 || relsec->sh_info >= elf_header.e_shnum
6060 || section_headers + relsec->sh_info != sec)
57346661
AM
6061 continue;
6062
6063 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6064 & rela, & nrelas))
6065 return 0;
6066
6067 for (rp = rela; rp < rela + nrelas; ++rp)
6068 {
aca88567
NC
6069 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6070 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6071
6072 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6073 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6074 {
6075 warn (_("Skipping unexpected relocation type %s\n"), relname);
6076 continue;
6077 }
6078
6079 i = rp->r_offset / unw_ent_size;
6080
89fac5e3 6081 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6082 {
6083 case 0:
6084 aux->table[i].start.section = sym->st_shndx;
1e456d54 6085 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6086 break;
6087 case 1:
6088 aux->table[i].end.section = sym->st_shndx;
1e456d54 6089 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6090 break;
6091 default:
6092 break;
6093 }
6094 }
6095
6096 free (rela);
6097 }
6098
1c0751b2 6099 aux->table_len = nentries;
57346661
AM
6100
6101 return 1;
6102}
6103
6104static int
2cf0635d 6105hppa_process_unwind (FILE * file)
57346661 6106{
57346661 6107 struct hppa_unw_aux_info aux;
2cf0635d
NC
6108 Elf_Internal_Shdr * unwsec = NULL;
6109 Elf_Internal_Shdr * strsec;
6110 Elf_Internal_Shdr * sec;
18bd398b 6111 unsigned long i;
57346661
AM
6112
6113 memset (& aux, 0, sizeof (aux));
6114
c256ffe7
JJ
6115 if (string_table == NULL)
6116 return 1;
57346661
AM
6117
6118 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6119 {
c256ffe7 6120 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6121 && sec->sh_link < elf_header.e_shnum)
57346661
AM
6122 {
6123 aux.nsyms = sec->sh_size / sec->sh_entsize;
6124 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6125
4fbb74a6 6126 strsec = section_headers + sec->sh_link;
3f5e193b
NC
6127 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6128 1, strsec->sh_size,
6129 _("string table"));
c256ffe7 6130 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6131 }
18bd398b 6132 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6133 unwsec = sec;
6134 }
6135
6136 if (!unwsec)
6137 printf (_("\nThere are no unwind sections in this file.\n"));
6138
6139 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6140 {
18bd398b 6141 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6142 {
57346661
AM
6143 printf (_("\nUnwind section "));
6144 printf (_("'%s'"), SECTION_NAME (sec));
6145
6146 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6147 (unsigned long) sec->sh_offset,
89fac5e3 6148 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6149
6150 slurp_hppa_unwind_table (file, &aux, sec);
6151 if (aux.table_len > 0)
6152 dump_hppa_unwind (&aux);
6153
6154 if (aux.table)
6155 free ((char *) aux.table);
6156 aux.table = NULL;
6157 }
6158 }
6159
6160 if (aux.symtab)
6161 free (aux.symtab);
6162 if (aux.strtab)
6163 free ((char *) aux.strtab);
6164
6165 return 1;
6166}
6167
0b6ae522
DJ
6168struct arm_section
6169{
6170 unsigned char *data;
6171
6172 Elf_Internal_Shdr *sec;
6173 Elf_Internal_Rela *rela;
6174 unsigned long nrelas;
6175 unsigned int rel_type;
6176
6177 Elf_Internal_Rela *next_rela;
6178};
6179
6180struct arm_unw_aux_info
6181{
6182 FILE *file;
6183
6184 Elf_Internal_Sym *symtab; /* The symbol table. */
6185 unsigned long nsyms; /* Number of symbols. */
6186 char *strtab; /* The string table. */
6187 unsigned long strtab_size; /* Size of string table. */
6188};
6189
6190static const char *
6191arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6192 bfd_vma fn, struct absaddr addr)
6193{
6194 const char *procname;
6195 bfd_vma sym_offset;
6196
6197 if (addr.section == SHN_UNDEF)
6198 addr.offset = fn;
6199
6200 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6201 aux->strtab_size, addr, &procname,
6202 &sym_offset);
6203
6204 print_vma (fn, PREFIX_HEX);
6205
6206 if (procname)
6207 {
6208 fputs (" <", stdout);
6209 fputs (procname, stdout);
6210
6211 if (sym_offset)
6212 printf ("+0x%lx", (unsigned long) sym_offset);
6213 fputc ('>', stdout);
6214 }
6215
6216 return procname;
6217}
6218
6219static void
6220arm_free_section (struct arm_section *arm_sec)
6221{
6222 if (arm_sec->data != NULL)
6223 free (arm_sec->data);
6224
6225 if (arm_sec->rela != NULL)
6226 free (arm_sec->rela);
6227}
6228
6229static int
6230arm_section_get_word (struct arm_unw_aux_info *aux,
6231 struct arm_section *arm_sec,
6232 Elf_Internal_Shdr *sec, bfd_vma word_offset,
6233 unsigned int *wordp, struct absaddr *addr)
6234{
6235 Elf_Internal_Rela *rp;
6236 Elf_Internal_Sym *sym;
6237 const char * relname;
6238 unsigned int word;
6239 bfd_boolean wrapped;
6240
6241 addr->section = SHN_UNDEF;
6242 addr->offset = 0;
6243
6244 if (sec != arm_sec->sec)
6245 {
6246 Elf_Internal_Shdr *relsec;
6247
6248 arm_free_section (arm_sec);
6249
6250 arm_sec->sec = sec;
6251 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6252 sec->sh_size, _("unwind data"));
6253
6254 arm_sec->rela = NULL;
6255 arm_sec->nrelas = 0;
6256
6257 for (relsec = section_headers;
6258 relsec < section_headers + elf_header.e_shnum;
6259 ++relsec)
6260 {
6261 if (relsec->sh_info >= elf_header.e_shnum
6262 || section_headers + relsec->sh_info != sec)
6263 continue;
6264
6265 if (relsec->sh_type == SHT_REL)
6266 {
6267 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6268 relsec->sh_size,
6269 & arm_sec->rela, & arm_sec->nrelas))
6270 return 0;
6271 break;
6272 }
6273 else if (relsec->sh_type == SHT_RELA)
6274 {
6275 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6276 relsec->sh_size,
6277 & arm_sec->rela, & arm_sec->nrelas))
6278 return 0;
6279 break;
6280 }
6281 }
6282
6283 arm_sec->next_rela = arm_sec->rela;
6284 }
6285
6286 if (arm_sec->data == NULL)
6287 return 0;
6288
6289 word = byte_get (arm_sec->data + word_offset, 4);
6290
6291 wrapped = FALSE;
6292 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6293 {
6294 bfd_vma prelval, offset;
6295
6296 if (rp->r_offset > word_offset && !wrapped)
6297 {
6298 rp = arm_sec->rela;
6299 wrapped = TRUE;
6300 }
6301 if (rp->r_offset > word_offset)
6302 break;
6303
6304 if (rp->r_offset & 3)
6305 {
6306 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6307 (unsigned long) rp->r_offset);
6308 continue;
6309 }
6310
6311 if (rp->r_offset < word_offset)
6312 continue;
6313
6314 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6315
6316 if (streq (relname, "R_ARM_NONE"))
6317 continue;
6318
6319 if (! streq (relname, "R_ARM_PREL31"))
6320 {
6321 warn (_("Skipping unexpected relocation type %s\n"), relname);
6322 continue;
6323 }
6324
6325 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6326
6327 if (arm_sec->rel_type == SHT_REL)
6328 {
6329 offset = word & 0x7fffffff;
6330 if (offset & 0x40000000)
6331 offset |= ~ (bfd_vma) 0x7fffffff;
6332 }
6333 else
6334 offset = rp->r_addend;
6335
6336 offset += sym->st_value;
6337 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6338
6339 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6340 addr->section = sym->st_shndx;
6341 addr->offset = offset;
6342 break;
6343 }
6344
6345 *wordp = word;
6346 arm_sec->next_rela = rp;
6347
6348 return 1;
6349}
6350
6351static void
6352decode_arm_unwind (struct arm_unw_aux_info *aux,
6353 unsigned int word, unsigned int remaining,
6354 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6355 struct arm_section *data_arm_sec)
6356{
6357 int per_index;
6358 unsigned int more_words;
6359 struct absaddr addr;
6360
6361#define ADVANCE \
6362 if (remaining == 0 && more_words) \
6363 { \
6364 data_offset += 4; \
6365 if (!arm_section_get_word (aux, data_arm_sec, data_sec, \
6366 data_offset, &word, &addr)) \
6367 return; \
6368 remaining = 4; \
6369 more_words--; \
6370 } \
6371
6372#define GET_OP(OP) \
6373 ADVANCE; \
6374 if (remaining) \
6375 { \
6376 remaining--; \
6377 (OP) = word >> 24; \
6378 word <<= 8; \
6379 } \
6380 else \
6381 { \
2b692964 6382 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6383 return; \
6384 } \
cc5914eb 6385 printf ("0x%02x ", OP)
0b6ae522
DJ
6386
6387 if (remaining == 0)
6388 {
6389 /* Fetch the first word. */
6390 if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
6391 &word, &addr))
6392 return;
6393 remaining = 4;
6394 }
6395
6396 if ((word & 0x80000000) == 0)
6397 {
6398 /* Expand prel31 for personality routine. */
6399 bfd_vma fn;
6400 const char *procname;
6401
6402 fn = word;
6403 if (fn & 0x40000000)
6404 fn |= ~ (bfd_vma) 0x7fffffff;
6405 fn = fn + data_sec->sh_addr + data_offset;
6406
6407 printf (_(" Personality routine: "));
6408 procname = arm_print_vma_and_name (aux, fn, addr);
6409 fputc ('\n', stdout);
6410
6411 /* The GCC personality routines use the standard compact
6412 encoding, starting with one byte giving the number of
6413 words. */
6414 if (procname != NULL
6415 && (const_strneq (procname, "__gcc_personality_v0")
6416 || const_strneq (procname, "__gxx_personality_v0")
6417 || const_strneq (procname, "__gcj_personality_v0")
6418 || const_strneq (procname, "__gnu_objc_personality_v0")))
6419 {
6420 remaining = 0;
6421 more_words = 1;
6422 ADVANCE;
6423 if (!remaining)
6424 {
6425 printf (_(" [Truncated data]\n"));
6426 return;
6427 }
6428 more_words = word >> 24;
6429 word <<= 8;
6430 remaining--;
6431 }
6432 else
6433 return;
6434 }
6435 else
6436 {
0b6ae522
DJ
6437 per_index = (word >> 24) & 0x7f;
6438 if (per_index != 0 && per_index != 1 && per_index != 2)
6439 {
6440 printf (_(" [reserved compact index %d]\n"), per_index);
6441 return;
6442 }
6443
6444 printf (_(" Compact model %d\n"), per_index);
6445 if (per_index == 0)
6446 {
6447 more_words = 0;
6448 word <<= 8;
6449 remaining--;
6450 }
6451 else
6452 {
6453 more_words = (word >> 16) & 0xff;
6454 word <<= 16;
6455 remaining -= 2;
6456 }
6457 }
6458
6459 /* Decode the unwinding instructions. */
6460 while (1)
6461 {
6462 unsigned int op, op2;
6463
6464 ADVANCE;
6465 if (remaining == 0)
6466 break;
6467 remaining--;
6468 op = word >> 24;
6469 word <<= 8;
6470
cc5914eb 6471 printf (" 0x%02x ", op);
0b6ae522
DJ
6472
6473 if ((op & 0xc0) == 0x00)
6474 {
6475 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6476
cc5914eb 6477 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6478 }
6479 else if ((op & 0xc0) == 0x40)
6480 {
6481 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6482
cc5914eb 6483 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6484 }
6485 else if ((op & 0xf0) == 0x80)
6486 {
6487 GET_OP (op2);
6488 if (op == 0x80 && op2 == 0)
6489 printf (_("Refuse to unwind"));
6490 else
6491 {
6492 unsigned int mask = ((op & 0x0f) << 8) | op2;
6493 int first = 1;
6494 int i;
2b692964 6495
0b6ae522
DJ
6496 printf ("pop {");
6497 for (i = 0; i < 12; i++)
6498 if (mask & (1 << i))
6499 {
6500 if (first)
6501 first = 0;
6502 else
6503 printf (", ");
6504 printf ("r%d", 4 + i);
6505 }
6506 printf ("}");
6507 }
6508 }
6509 else if ((op & 0xf0) == 0x90)
6510 {
6511 if (op == 0x9d || op == 0x9f)
6512 printf (_(" [Reserved]"));
6513 else
cc5914eb 6514 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6515 }
6516 else if ((op & 0xf0) == 0xa0)
6517 {
6518 int end = 4 + (op & 0x07);
6519 int first = 1;
6520 int i;
61865e30 6521
0b6ae522
DJ
6522 printf (" pop {");
6523 for (i = 4; i <= end; i++)
6524 {
6525 if (first)
6526 first = 0;
6527 else
6528 printf (", ");
6529 printf ("r%d", i);
6530 }
6531 if (op & 0x08)
6532 {
6533 if (first)
6534 printf (", ");
6535 printf ("r14");
6536 }
6537 printf ("}");
6538 }
6539 else if (op == 0xb0)
6540 printf (_(" finish"));
6541 else if (op == 0xb1)
6542 {
6543 GET_OP (op2);
6544 if (op2 == 0 || (op2 & 0xf0) != 0)
6545 printf (_("[Spare]"));
6546 else
6547 {
6548 unsigned int mask = op2 & 0x0f;
6549 int first = 1;
6550 int i;
61865e30 6551
0b6ae522
DJ
6552 printf ("pop {");
6553 for (i = 0; i < 12; i++)
6554 if (mask & (1 << i))
6555 {
6556 if (first)
6557 first = 0;
6558 else
6559 printf (", ");
6560 printf ("r%d", i);
6561 }
6562 printf ("}");
6563 }
6564 }
6565 else if (op == 0xb2)
6566 {
b115cf96 6567 unsigned char buf[9];
0b6ae522
DJ
6568 unsigned int i, len;
6569 unsigned long offset;
61865e30 6570
b115cf96 6571 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6572 {
6573 GET_OP (buf[i]);
6574 if ((buf[i] & 0x80) == 0)
6575 break;
6576 }
6577 assert (i < sizeof (buf));
6578 offset = read_uleb128 (buf, &len);
6579 assert (len == i + 1);
6580 offset = offset * 4 + 0x204;
cc5914eb 6581 printf ("vsp = vsp + %ld", offset);
0b6ae522 6582 }
61865e30 6583 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6584 {
61865e30
NC
6585 unsigned int first, last;
6586
6587 GET_OP (op2);
6588 first = op2 >> 4;
6589 last = op2 & 0x0f;
6590 if (op == 0xc8)
6591 first = first + 16;
6592 printf ("pop {D%d", first);
6593 if (last)
6594 printf ("-D%d", first + last);
6595 printf ("}");
6596 }
6597 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6598 {
6599 unsigned int count = op & 0x07;
6600
6601 printf ("pop {D8");
6602 if (count)
6603 printf ("-D%d", 8 + count);
6604 printf ("}");
6605 }
6606 else if (op >= 0xc0 && op <= 0xc5)
6607 {
6608 unsigned int count = op & 0x07;
6609
6610 printf (" pop {wR10");
6611 if (count)
6612 printf ("-wR%d", 10 + count);
6613 printf ("}");
6614 }
6615 else if (op == 0xc6)
6616 {
6617 unsigned int first, last;
6618
6619 GET_OP (op2);
6620 first = op2 >> 4;
6621 last = op2 & 0x0f;
6622 printf ("pop {wR%d", first);
6623 if (last)
6624 printf ("-wR%d", first + last);
6625 printf ("}");
6626 }
6627 else if (op == 0xc7)
6628 {
6629 GET_OP (op2);
6630 if (op2 == 0 || (op2 & 0xf0) != 0)
6631 printf (_("[Spare]"));
0b6ae522
DJ
6632 else
6633 {
61865e30
NC
6634 unsigned int mask = op2 & 0x0f;
6635 int first = 1;
6636 int i;
6637
6638 printf ("pop {");
6639 for (i = 0; i < 4; i++)
6640 if (mask & (1 << i))
6641 {
6642 if (first)
6643 first = 0;
6644 else
6645 printf (", ");
6646 printf ("wCGR%d", i);
6647 }
6648 printf ("}");
0b6ae522
DJ
6649 }
6650 }
61865e30
NC
6651 else
6652 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6653 printf ("\n");
6654 }
6655
6656 /* Decode the descriptors. Not implemented. */
6657}
6658
6659static void
6660dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
6661{
6662 struct arm_section exidx_arm_sec, extab_arm_sec;
6663 unsigned int i, exidx_len;
6664
6665 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
6666 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
6667 exidx_len = exidx_sec->sh_size / 8;
6668
6669 for (i = 0; i < exidx_len; i++)
6670 {
6671 unsigned int exidx_fn, exidx_entry;
6672 struct absaddr fn_addr, entry_addr;
6673 bfd_vma fn;
6674
6675 fputc ('\n', stdout);
6676
6677 if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6678 8 * i, &exidx_fn, &fn_addr)
6679 || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6680 8 * i + 4, &exidx_entry, &entry_addr))
6681 {
6682 arm_free_section (&exidx_arm_sec);
6683 arm_free_section (&extab_arm_sec);
6684 return;
6685 }
6686
6687 fn = exidx_fn & 0x7fffffff;
6688 if (fn & 0x40000000)
6689 fn |= ~ (bfd_vma) 0x7fffffff;
6690 fn = fn + exidx_sec->sh_addr + 8 * i;
6691
6692 arm_print_vma_and_name (aux, fn, entry_addr);
6693 fputs (": ", stdout);
6694
6695 if (exidx_entry == 1)
6696 {
6697 print_vma (exidx_entry, PREFIX_HEX);
6698 fputs (" [cantunwind]\n", stdout);
6699 }
6700 else if (exidx_entry & 0x80000000)
6701 {
6702 print_vma (exidx_entry, PREFIX_HEX);
6703 fputc ('\n', stdout);
6704 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
6705 }
6706 else
6707 {
8f73510c 6708 bfd_vma table, table_offset = 0;
0b6ae522
DJ
6709 Elf_Internal_Shdr *table_sec;
6710
6711 fputs ("@", stdout);
6712 table = exidx_entry;
6713 if (table & 0x40000000)
6714 table |= ~ (bfd_vma) 0x7fffffff;
6715 table = table + exidx_sec->sh_addr + 8 * i + 4;
6716 print_vma (table, PREFIX_HEX);
6717 printf ("\n");
6718
6719 /* Locate the matching .ARM.extab. */
6720 if (entry_addr.section != SHN_UNDEF
6721 && entry_addr.section < elf_header.e_shnum)
6722 {
6723 table_sec = section_headers + entry_addr.section;
6724 table_offset = entry_addr.offset;
6725 }
6726 else
6727 {
6728 table_sec = find_section_by_address (table);
6729 if (table_sec != NULL)
6730 table_offset = table - table_sec->sh_addr;
6731 }
6732 if (table_sec == NULL)
6733 {
6734 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
6735 (unsigned long) table);
6736 continue;
6737 }
6738 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
6739 &extab_arm_sec);
6740 }
6741 }
6742
6743 printf ("\n");
6744
6745 arm_free_section (&exidx_arm_sec);
6746 arm_free_section (&extab_arm_sec);
6747}
6748
6749static int
6750arm_process_unwind (FILE *file)
6751{
6752 struct arm_unw_aux_info aux;
6753 Elf_Internal_Shdr *unwsec = NULL;
6754 Elf_Internal_Shdr *strsec;
6755 Elf_Internal_Shdr *sec;
6756 unsigned long i;
6757
6758 memset (& aux, 0, sizeof (aux));
6759 aux.file = file;
6760
6761 if (string_table == NULL)
6762 return 1;
6763
6764 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6765 {
6766 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
6767 {
6768 aux.nsyms = sec->sh_size / sec->sh_entsize;
6769 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6770
6771 strsec = section_headers + sec->sh_link;
6772 aux.strtab = get_data (NULL, file, strsec->sh_offset,
6773 1, strsec->sh_size, _("string table"));
6774 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
6775 }
6776 else if (sec->sh_type == SHT_ARM_EXIDX)
6777 unwsec = sec;
6778 }
6779
6780 if (!unwsec)
6781 printf (_("\nThere are no unwind sections in this file.\n"));
6782
6783 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6784 {
6785 if (sec->sh_type == SHT_ARM_EXIDX)
6786 {
6787 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
6788 SECTION_NAME (sec),
6789 (unsigned long) sec->sh_offset,
6790 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
6791
6792 dump_arm_unwind (&aux, sec);
6793 }
6794 }
6795
6796 if (aux.symtab)
6797 free (aux.symtab);
6798 if (aux.strtab)
6799 free ((char *) aux.strtab);
6800
6801 return 1;
6802}
6803
57346661 6804static int
2cf0635d 6805process_unwind (FILE * file)
57346661 6806{
2cf0635d
NC
6807 struct unwind_handler
6808 {
57346661 6809 int machtype;
2cf0635d
NC
6810 int (* handler)(FILE *);
6811 } handlers[] =
6812 {
0b6ae522 6813 { EM_ARM, arm_process_unwind },
57346661
AM
6814 { EM_IA_64, ia64_process_unwind },
6815 { EM_PARISC, hppa_process_unwind },
6816 { 0, 0 }
6817 };
6818 int i;
6819
6820 if (!do_unwind)
6821 return 1;
6822
6823 for (i = 0; handlers[i].handler != NULL; i++)
6824 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 6825 return handlers[i].handler (file);
57346661
AM
6826
6827 printf (_("\nThere are no unwind sections in this file.\n"));
6828 return 1;
6829}
6830
252b5132 6831static void
2cf0635d 6832dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
6833{
6834 switch (entry->d_tag)
6835 {
6836 case DT_MIPS_FLAGS:
6837 if (entry->d_un.d_val == 0)
2b692964 6838 printf (_("NONE\n"));
252b5132
RH
6839 else
6840 {
6841 static const char * opts[] =
6842 {
6843 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
6844 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
6845 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
6846 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
6847 "RLD_ORDER_SAFE"
6848 };
6849 unsigned int cnt;
6850 int first = 1;
2b692964 6851
60bca95a 6852 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
6853 if (entry->d_un.d_val & (1 << cnt))
6854 {
6855 printf ("%s%s", first ? "" : " ", opts[cnt]);
6856 first = 0;
6857 }
6858 puts ("");
6859 }
6860 break;
103f02d3 6861
252b5132 6862 case DT_MIPS_IVERSION:
d79b3d50 6863 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
2b692964 6864 printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6865 else
2b692964 6866 printf (_("<corrupt: %ld>\n"), (long) entry->d_un.d_ptr);
252b5132 6867 break;
103f02d3 6868
252b5132
RH
6869 case DT_MIPS_TIME_STAMP:
6870 {
6871 char timebuf[20];
2cf0635d 6872 struct tm * tmp;
50da7a9c 6873
91d6fa6a
NC
6874 time_t atime = entry->d_un.d_val;
6875 tmp = gmtime (&atime);
e9e44622
JJ
6876 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
6877 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6878 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
2b692964 6879 printf (_("Time Stamp: %s\n"), timebuf);
252b5132
RH
6880 }
6881 break;
103f02d3 6882
252b5132
RH
6883 case DT_MIPS_RLD_VERSION:
6884 case DT_MIPS_LOCAL_GOTNO:
6885 case DT_MIPS_CONFLICTNO:
6886 case DT_MIPS_LIBLISTNO:
6887 case DT_MIPS_SYMTABNO:
6888 case DT_MIPS_UNREFEXTNO:
6889 case DT_MIPS_HIPAGENO:
6890 case DT_MIPS_DELTA_CLASS_NO:
6891 case DT_MIPS_DELTA_INSTANCE_NO:
6892 case DT_MIPS_DELTA_RELOC_NO:
6893 case DT_MIPS_DELTA_SYM_NO:
6894 case DT_MIPS_DELTA_CLASSSYM_NO:
6895 case DT_MIPS_COMPACT_SIZE:
6896 printf ("%ld\n", (long) entry->d_un.d_ptr);
6897 break;
103f02d3
UD
6898
6899 default:
0af1713e 6900 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
6901 }
6902}
6903
103f02d3 6904static void
2cf0635d 6905dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
6906{
6907 switch (entry->d_tag)
6908 {
6909 case DT_HP_DLD_FLAGS:
6910 {
6911 static struct
6912 {
6913 long int bit;
2cf0635d 6914 const char * str;
5e220199
NC
6915 }
6916 flags[] =
6917 {
6918 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
6919 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
6920 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
6921 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
6922 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
6923 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
6924 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
6925 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
6926 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
6927 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
6928 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
6929 { DT_HP_GST, "HP_GST" },
6930 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
6931 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
6932 { DT_HP_NODELETE, "HP_NODELETE" },
6933 { DT_HP_GROUP, "HP_GROUP" },
6934 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 6935 };
103f02d3 6936 int first = 1;
5e220199 6937 size_t cnt;
f7a99963 6938 bfd_vma val = entry->d_un.d_val;
103f02d3 6939
60bca95a 6940 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 6941 if (val & flags[cnt].bit)
30800947
NC
6942 {
6943 if (! first)
6944 putchar (' ');
6945 fputs (flags[cnt].str, stdout);
6946 first = 0;
6947 val ^= flags[cnt].bit;
6948 }
76da6bbe 6949
103f02d3 6950 if (val != 0 || first)
f7a99963
NC
6951 {
6952 if (! first)
6953 putchar (' ');
6954 print_vma (val, HEX);
6955 }
103f02d3
UD
6956 }
6957 break;
76da6bbe 6958
252b5132 6959 default:
f7a99963
NC
6960 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6961 break;
252b5132 6962 }
35b1837e 6963 putchar ('\n');
252b5132
RH
6964}
6965
28f997cf
TG
6966#ifdef BFD64
6967
6968/* VMS vs Unix time offset and factor. */
6969
6970#define VMS_EPOCH_OFFSET 35067168000000000LL
6971#define VMS_GRANULARITY_FACTOR 10000000
6972
6973/* Display a VMS time in a human readable format. */
6974
6975static void
6976print_vms_time (bfd_int64_t vmstime)
6977{
6978 struct tm *tm;
6979 time_t unxtime;
6980
6981 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
6982 tm = gmtime (&unxtime);
6983 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
6984 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
6985 tm->tm_hour, tm->tm_min, tm->tm_sec);
6986}
6987#endif /* BFD64 */
6988
ecc51f48 6989static void
2cf0635d 6990dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
6991{
6992 switch (entry->d_tag)
6993 {
0de14b54 6994 case DT_IA_64_PLT_RESERVE:
bdf4d63a 6995 /* First 3 slots reserved. */
ecc51f48
NC
6996 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6997 printf (" -- ");
6998 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
6999 break;
7000
28f997cf
TG
7001 case DT_IA_64_VMS_LINKTIME:
7002#ifdef BFD64
7003 print_vms_time (entry->d_un.d_val);
7004#endif
7005 break;
7006
7007 case DT_IA_64_VMS_LNKFLAGS:
7008 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7009 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7010 printf (" CALL_DEBUG");
7011 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7012 printf (" NOP0BUFS");
7013 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7014 printf (" P0IMAGE");
7015 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7016 printf (" MKTHREADS");
7017 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7018 printf (" UPCALLS");
7019 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7020 printf (" IMGSTA");
7021 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7022 printf (" INITIALIZE");
7023 if (entry->d_un.d_val & VMS_LF_MAIN)
7024 printf (" MAIN");
7025 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7026 printf (" EXE_INIT");
7027 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7028 printf (" TBK_IN_IMG");
7029 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7030 printf (" DBG_IN_IMG");
7031 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7032 printf (" TBK_IN_DSF");
7033 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7034 printf (" DBG_IN_DSF");
7035 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7036 printf (" SIGNATURES");
7037 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7038 printf (" REL_SEG_OFF");
7039 break;
7040
bdf4d63a
JJ
7041 default:
7042 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7043 break;
ecc51f48 7044 }
bdf4d63a 7045 putchar ('\n');
ecc51f48
NC
7046}
7047
252b5132 7048static int
2cf0635d 7049get_32bit_dynamic_section (FILE * file)
252b5132 7050{
2cf0635d
NC
7051 Elf32_External_Dyn * edyn;
7052 Elf32_External_Dyn * ext;
7053 Elf_Internal_Dyn * entry;
103f02d3 7054
3f5e193b
NC
7055 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7056 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7057 if (!edyn)
7058 return 0;
103f02d3 7059
ba2685cc
AM
7060/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7061 might not have the luxury of section headers. Look for the DT_NULL
7062 terminator to determine the number of entries. */
7063 for (ext = edyn, dynamic_nent = 0;
7064 (char *) ext < (char *) edyn + dynamic_size;
7065 ext++)
7066 {
7067 dynamic_nent++;
7068 if (BYTE_GET (ext->d_tag) == DT_NULL)
7069 break;
7070 }
252b5132 7071
3f5e193b
NC
7072 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7073 sizeof (* entry));
b2d38a17 7074 if (dynamic_section == NULL)
252b5132 7075 {
9ea033b2
NC
7076 error (_("Out of memory\n"));
7077 free (edyn);
7078 return 0;
7079 }
252b5132 7080
fb514b26 7081 for (ext = edyn, entry = dynamic_section;
ba2685cc 7082 entry < dynamic_section + dynamic_nent;
fb514b26 7083 ext++, entry++)
9ea033b2 7084 {
fb514b26
AM
7085 entry->d_tag = BYTE_GET (ext->d_tag);
7086 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7087 }
7088
9ea033b2
NC
7089 free (edyn);
7090
7091 return 1;
7092}
7093
7094static int
2cf0635d 7095get_64bit_dynamic_section (FILE * file)
9ea033b2 7096{
2cf0635d
NC
7097 Elf64_External_Dyn * edyn;
7098 Elf64_External_Dyn * ext;
7099 Elf_Internal_Dyn * entry;
103f02d3 7100
3f5e193b
NC
7101 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7102 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7103 if (!edyn)
7104 return 0;
103f02d3 7105
ba2685cc
AM
7106/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7107 might not have the luxury of section headers. Look for the DT_NULL
7108 terminator to determine the number of entries. */
7109 for (ext = edyn, dynamic_nent = 0;
7110 (char *) ext < (char *) edyn + dynamic_size;
7111 ext++)
7112 {
7113 dynamic_nent++;
66543521 7114 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7115 break;
7116 }
252b5132 7117
3f5e193b
NC
7118 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7119 sizeof (* entry));
b2d38a17 7120 if (dynamic_section == NULL)
252b5132
RH
7121 {
7122 error (_("Out of memory\n"));
7123 free (edyn);
7124 return 0;
7125 }
7126
fb514b26 7127 for (ext = edyn, entry = dynamic_section;
ba2685cc 7128 entry < dynamic_section + dynamic_nent;
fb514b26 7129 ext++, entry++)
252b5132 7130 {
66543521
AM
7131 entry->d_tag = BYTE_GET (ext->d_tag);
7132 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7133 }
7134
7135 free (edyn);
7136
9ea033b2
NC
7137 return 1;
7138}
7139
e9e44622
JJ
7140static void
7141print_dynamic_flags (bfd_vma flags)
d1133906 7142{
e9e44622 7143 int first = 1;
13ae64f3 7144
d1133906
NC
7145 while (flags)
7146 {
7147 bfd_vma flag;
7148
7149 flag = flags & - flags;
7150 flags &= ~ flag;
7151
e9e44622
JJ
7152 if (first)
7153 first = 0;
7154 else
7155 putc (' ', stdout);
13ae64f3 7156
d1133906
NC
7157 switch (flag)
7158 {
e9e44622
JJ
7159 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7160 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7161 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7162 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7163 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7164 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7165 }
7166 }
e9e44622 7167 puts ("");
d1133906
NC
7168}
7169
b2d38a17
NC
7170/* Parse and display the contents of the dynamic section. */
7171
9ea033b2 7172static int
2cf0635d 7173process_dynamic_section (FILE * file)
9ea033b2 7174{
2cf0635d 7175 Elf_Internal_Dyn * entry;
9ea033b2
NC
7176
7177 if (dynamic_size == 0)
7178 {
7179 if (do_dynamic)
b2d38a17 7180 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7181
7182 return 1;
7183 }
7184
7185 if (is_32bit_elf)
7186 {
b2d38a17 7187 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7188 return 0;
7189 }
b2d38a17 7190 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7191 return 0;
7192
252b5132
RH
7193 /* Find the appropriate symbol table. */
7194 if (dynamic_symbols == NULL)
7195 {
86dba8ee
AM
7196 for (entry = dynamic_section;
7197 entry < dynamic_section + dynamic_nent;
7198 ++entry)
252b5132 7199 {
c8286bd1 7200 Elf_Internal_Shdr section;
252b5132
RH
7201
7202 if (entry->d_tag != DT_SYMTAB)
7203 continue;
7204
7205 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7206
7207 /* Since we do not know how big the symbol table is,
7208 we default to reading in the entire file (!) and
7209 processing that. This is overkill, I know, but it
e3c8793a 7210 should work. */
d93f0186 7211 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7212
fb52b2f4
NC
7213 if (archive_file_offset != 0)
7214 section.sh_size = archive_file_size - section.sh_offset;
7215 else
7216 {
7217 if (fseek (file, 0, SEEK_END))
591a748a 7218 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7219
7220 section.sh_size = ftell (file) - section.sh_offset;
7221 }
252b5132 7222
9ea033b2 7223 if (is_32bit_elf)
9ad5cbcf 7224 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7225 else
9ad5cbcf 7226 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7227
9ad5cbcf 7228 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 7229 if (num_dynamic_syms < 1)
252b5132
RH
7230 {
7231 error (_("Unable to determine the number of symbols to load\n"));
7232 continue;
7233 }
7234
9ad5cbcf 7235 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
7236 }
7237 }
7238
7239 /* Similarly find a string table. */
7240 if (dynamic_strings == NULL)
7241 {
86dba8ee
AM
7242 for (entry = dynamic_section;
7243 entry < dynamic_section + dynamic_nent;
7244 ++entry)
252b5132
RH
7245 {
7246 unsigned long offset;
b34976b6 7247 long str_tab_len;
252b5132
RH
7248
7249 if (entry->d_tag != DT_STRTAB)
7250 continue;
7251
7252 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7253
7254 /* Since we do not know how big the string table is,
7255 we default to reading in the entire file (!) and
7256 processing that. This is overkill, I know, but it
e3c8793a 7257 should work. */
252b5132 7258
d93f0186 7259 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7260
7261 if (archive_file_offset != 0)
7262 str_tab_len = archive_file_size - offset;
7263 else
7264 {
7265 if (fseek (file, 0, SEEK_END))
7266 error (_("Unable to seek to end of file\n"));
7267 str_tab_len = ftell (file) - offset;
7268 }
252b5132
RH
7269
7270 if (str_tab_len < 1)
7271 {
7272 error
7273 (_("Unable to determine the length of the dynamic string table\n"));
7274 continue;
7275 }
7276
3f5e193b
NC
7277 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7278 str_tab_len,
7279 _("dynamic string table"));
d79b3d50 7280 dynamic_strings_length = str_tab_len;
252b5132
RH
7281 break;
7282 }
7283 }
7284
7285 /* And find the syminfo section if available. */
7286 if (dynamic_syminfo == NULL)
7287 {
3e8bba36 7288 unsigned long syminsz = 0;
252b5132 7289
86dba8ee
AM
7290 for (entry = dynamic_section;
7291 entry < dynamic_section + dynamic_nent;
7292 ++entry)
252b5132
RH
7293 {
7294 if (entry->d_tag == DT_SYMINENT)
7295 {
7296 /* Note: these braces are necessary to avoid a syntax
7297 error from the SunOS4 C compiler. */
7298 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7299 }
7300 else if (entry->d_tag == DT_SYMINSZ)
7301 syminsz = entry->d_un.d_val;
7302 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7303 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7304 syminsz);
252b5132
RH
7305 }
7306
7307 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7308 {
2cf0635d
NC
7309 Elf_External_Syminfo * extsyminfo;
7310 Elf_External_Syminfo * extsym;
7311 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7312
7313 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7314 extsyminfo = (Elf_External_Syminfo *)
7315 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7316 _("symbol information"));
a6e9f9df
AM
7317 if (!extsyminfo)
7318 return 0;
252b5132 7319
3f5e193b 7320 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7321 if (dynamic_syminfo == NULL)
7322 {
7323 error (_("Out of memory\n"));
7324 return 0;
7325 }
7326
7327 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7328 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7329 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7330 ++syminfo, ++extsym)
252b5132 7331 {
86dba8ee
AM
7332 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7333 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7334 }
7335
7336 free (extsyminfo);
7337 }
7338 }
7339
7340 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7341 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7342 dynamic_addr, dynamic_nent);
252b5132
RH
7343 if (do_dynamic)
7344 printf (_(" Tag Type Name/Value\n"));
7345
86dba8ee
AM
7346 for (entry = dynamic_section;
7347 entry < dynamic_section + dynamic_nent;
7348 entry++)
252b5132
RH
7349 {
7350 if (do_dynamic)
f7a99963 7351 {
2cf0635d 7352 const char * dtype;
e699b9ff 7353
f7a99963
NC
7354 putchar (' ');
7355 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7356 dtype = get_dynamic_type (entry->d_tag);
7357 printf (" (%s)%*s", dtype,
7358 ((is_32bit_elf ? 27 : 19)
7359 - (int) strlen (dtype)),
f7a99963
NC
7360 " ");
7361 }
252b5132
RH
7362
7363 switch (entry->d_tag)
7364 {
d1133906
NC
7365 case DT_FLAGS:
7366 if (do_dynamic)
e9e44622 7367 print_dynamic_flags (entry->d_un.d_val);
d1133906 7368 break;
76da6bbe 7369
252b5132
RH
7370 case DT_AUXILIARY:
7371 case DT_FILTER:
019148e4
L
7372 case DT_CONFIG:
7373 case DT_DEPAUDIT:
7374 case DT_AUDIT:
252b5132
RH
7375 if (do_dynamic)
7376 {
019148e4 7377 switch (entry->d_tag)
b34976b6 7378 {
019148e4
L
7379 case DT_AUXILIARY:
7380 printf (_("Auxiliary library"));
7381 break;
7382
7383 case DT_FILTER:
7384 printf (_("Filter library"));
7385 break;
7386
b34976b6 7387 case DT_CONFIG:
019148e4
L
7388 printf (_("Configuration file"));
7389 break;
7390
7391 case DT_DEPAUDIT:
7392 printf (_("Dependency audit library"));
7393 break;
7394
7395 case DT_AUDIT:
7396 printf (_("Audit library"));
7397 break;
7398 }
252b5132 7399
d79b3d50
NC
7400 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7401 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7402 else
f7a99963
NC
7403 {
7404 printf (": ");
7405 print_vma (entry->d_un.d_val, PREFIX_HEX);
7406 putchar ('\n');
7407 }
252b5132
RH
7408 }
7409 break;
7410
dcefbbbd 7411 case DT_FEATURE:
252b5132
RH
7412 if (do_dynamic)
7413 {
7414 printf (_("Flags:"));
86f55779 7415
252b5132
RH
7416 if (entry->d_un.d_val == 0)
7417 printf (_(" None\n"));
7418 else
7419 {
7420 unsigned long int val = entry->d_un.d_val;
86f55779 7421
252b5132
RH
7422 if (val & DTF_1_PARINIT)
7423 {
7424 printf (" PARINIT");
7425 val ^= DTF_1_PARINIT;
7426 }
dcefbbbd
L
7427 if (val & DTF_1_CONFEXP)
7428 {
7429 printf (" CONFEXP");
7430 val ^= DTF_1_CONFEXP;
7431 }
252b5132
RH
7432 if (val != 0)
7433 printf (" %lx", val);
7434 puts ("");
7435 }
7436 }
7437 break;
7438
7439 case DT_POSFLAG_1:
7440 if (do_dynamic)
7441 {
7442 printf (_("Flags:"));
86f55779 7443
252b5132
RH
7444 if (entry->d_un.d_val == 0)
7445 printf (_(" None\n"));
7446 else
7447 {
7448 unsigned long int val = entry->d_un.d_val;
86f55779 7449
252b5132
RH
7450 if (val & DF_P1_LAZYLOAD)
7451 {
7452 printf (" LAZYLOAD");
7453 val ^= DF_P1_LAZYLOAD;
7454 }
7455 if (val & DF_P1_GROUPPERM)
7456 {
7457 printf (" GROUPPERM");
7458 val ^= DF_P1_GROUPPERM;
7459 }
7460 if (val != 0)
7461 printf (" %lx", val);
7462 puts ("");
7463 }
7464 }
7465 break;
7466
7467 case DT_FLAGS_1:
7468 if (do_dynamic)
7469 {
7470 printf (_("Flags:"));
7471 if (entry->d_un.d_val == 0)
7472 printf (_(" None\n"));
7473 else
7474 {
7475 unsigned long int val = entry->d_un.d_val;
86f55779 7476
252b5132
RH
7477 if (val & DF_1_NOW)
7478 {
7479 printf (" NOW");
7480 val ^= DF_1_NOW;
7481 }
7482 if (val & DF_1_GLOBAL)
7483 {
7484 printf (" GLOBAL");
7485 val ^= DF_1_GLOBAL;
7486 }
7487 if (val & DF_1_GROUP)
7488 {
7489 printf (" GROUP");
7490 val ^= DF_1_GROUP;
7491 }
7492 if (val & DF_1_NODELETE)
7493 {
7494 printf (" NODELETE");
7495 val ^= DF_1_NODELETE;
7496 }
7497 if (val & DF_1_LOADFLTR)
7498 {
7499 printf (" LOADFLTR");
7500 val ^= DF_1_LOADFLTR;
7501 }
7502 if (val & DF_1_INITFIRST)
7503 {
7504 printf (" INITFIRST");
7505 val ^= DF_1_INITFIRST;
7506 }
7507 if (val & DF_1_NOOPEN)
7508 {
7509 printf (" NOOPEN");
7510 val ^= DF_1_NOOPEN;
7511 }
7512 if (val & DF_1_ORIGIN)
7513 {
7514 printf (" ORIGIN");
7515 val ^= DF_1_ORIGIN;
7516 }
7517 if (val & DF_1_DIRECT)
7518 {
7519 printf (" DIRECT");
7520 val ^= DF_1_DIRECT;
7521 }
7522 if (val & DF_1_TRANS)
7523 {
7524 printf (" TRANS");
7525 val ^= DF_1_TRANS;
7526 }
7527 if (val & DF_1_INTERPOSE)
7528 {
7529 printf (" INTERPOSE");
7530 val ^= DF_1_INTERPOSE;
7531 }
f7db6139 7532 if (val & DF_1_NODEFLIB)
dcefbbbd 7533 {
f7db6139
L
7534 printf (" NODEFLIB");
7535 val ^= DF_1_NODEFLIB;
dcefbbbd
L
7536 }
7537 if (val & DF_1_NODUMP)
7538 {
7539 printf (" NODUMP");
7540 val ^= DF_1_NODUMP;
7541 }
7542 if (val & DF_1_CONLFAT)
7543 {
7544 printf (" CONLFAT");
7545 val ^= DF_1_CONLFAT;
7546 }
252b5132
RH
7547 if (val != 0)
7548 printf (" %lx", val);
7549 puts ("");
7550 }
7551 }
7552 break;
7553
7554 case DT_PLTREL:
566b0d53 7555 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7556 if (do_dynamic)
7557 puts (get_dynamic_type (entry->d_un.d_val));
7558 break;
7559
7560 case DT_NULL :
7561 case DT_NEEDED :
7562 case DT_PLTGOT :
7563 case DT_HASH :
7564 case DT_STRTAB :
7565 case DT_SYMTAB :
7566 case DT_RELA :
7567 case DT_INIT :
7568 case DT_FINI :
7569 case DT_SONAME :
7570 case DT_RPATH :
7571 case DT_SYMBOLIC:
7572 case DT_REL :
7573 case DT_DEBUG :
7574 case DT_TEXTREL :
7575 case DT_JMPREL :
019148e4 7576 case DT_RUNPATH :
252b5132
RH
7577 dynamic_info[entry->d_tag] = entry->d_un.d_val;
7578
7579 if (do_dynamic)
7580 {
2cf0635d 7581 char * name;
252b5132 7582
d79b3d50
NC
7583 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7584 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7585 else
d79b3d50 7586 name = NULL;
252b5132
RH
7587
7588 if (name)
7589 {
7590 switch (entry->d_tag)
7591 {
7592 case DT_NEEDED:
7593 printf (_("Shared library: [%s]"), name);
7594
18bd398b 7595 if (streq (name, program_interpreter))
f7a99963 7596 printf (_(" program interpreter"));
252b5132
RH
7597 break;
7598
7599 case DT_SONAME:
f7a99963 7600 printf (_("Library soname: [%s]"), name);
252b5132
RH
7601 break;
7602
7603 case DT_RPATH:
f7a99963 7604 printf (_("Library rpath: [%s]"), name);
252b5132
RH
7605 break;
7606
019148e4
L
7607 case DT_RUNPATH:
7608 printf (_("Library runpath: [%s]"), name);
7609 break;
7610
252b5132 7611 default:
f7a99963
NC
7612 print_vma (entry->d_un.d_val, PREFIX_HEX);
7613 break;
252b5132
RH
7614 }
7615 }
7616 else
f7a99963
NC
7617 print_vma (entry->d_un.d_val, PREFIX_HEX);
7618
7619 putchar ('\n');
252b5132
RH
7620 }
7621 break;
7622
7623 case DT_PLTRELSZ:
7624 case DT_RELASZ :
7625 case DT_STRSZ :
7626 case DT_RELSZ :
7627 case DT_RELAENT :
7628 case DT_SYMENT :
7629 case DT_RELENT :
566b0d53 7630 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7631 case DT_PLTPADSZ:
7632 case DT_MOVEENT :
7633 case DT_MOVESZ :
7634 case DT_INIT_ARRAYSZ:
7635 case DT_FINI_ARRAYSZ:
047b2264
JJ
7636 case DT_GNU_CONFLICTSZ:
7637 case DT_GNU_LIBLISTSZ:
252b5132 7638 if (do_dynamic)
f7a99963
NC
7639 {
7640 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 7641 printf (_(" (bytes)\n"));
f7a99963 7642 }
252b5132
RH
7643 break;
7644
7645 case DT_VERDEFNUM:
7646 case DT_VERNEEDNUM:
7647 case DT_RELACOUNT:
7648 case DT_RELCOUNT:
7649 if (do_dynamic)
f7a99963
NC
7650 {
7651 print_vma (entry->d_un.d_val, UNSIGNED);
7652 putchar ('\n');
7653 }
252b5132
RH
7654 break;
7655
7656 case DT_SYMINSZ:
7657 case DT_SYMINENT:
7658 case DT_SYMINFO:
7659 case DT_USED:
7660 case DT_INIT_ARRAY:
7661 case DT_FINI_ARRAY:
7662 if (do_dynamic)
7663 {
d79b3d50
NC
7664 if (entry->d_tag == DT_USED
7665 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 7666 {
2cf0635d 7667 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7668
b34976b6 7669 if (*name)
252b5132
RH
7670 {
7671 printf (_("Not needed object: [%s]\n"), name);
7672 break;
7673 }
7674 }
103f02d3 7675
f7a99963
NC
7676 print_vma (entry->d_un.d_val, PREFIX_HEX);
7677 putchar ('\n');
252b5132
RH
7678 }
7679 break;
7680
7681 case DT_BIND_NOW:
7682 /* The value of this entry is ignored. */
35b1837e
AM
7683 if (do_dynamic)
7684 putchar ('\n');
252b5132 7685 break;
103f02d3 7686
047b2264
JJ
7687 case DT_GNU_PRELINKED:
7688 if (do_dynamic)
7689 {
2cf0635d 7690 struct tm * tmp;
91d6fa6a 7691 time_t atime = entry->d_un.d_val;
047b2264 7692
91d6fa6a 7693 tmp = gmtime (&atime);
047b2264
JJ
7694 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
7695 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7696 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7697
7698 }
7699 break;
7700
fdc90cb4
JJ
7701 case DT_GNU_HASH:
7702 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
7703 if (do_dynamic)
7704 {
7705 print_vma (entry->d_un.d_val, PREFIX_HEX);
7706 putchar ('\n');
7707 }
7708 break;
7709
252b5132
RH
7710 default:
7711 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 7712 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
7713 entry->d_un.d_val;
7714
7715 if (do_dynamic)
7716 {
7717 switch (elf_header.e_machine)
7718 {
7719 case EM_MIPS:
4fe85591 7720 case EM_MIPS_RS3_LE:
b2d38a17 7721 dynamic_section_mips_val (entry);
252b5132 7722 break;
103f02d3 7723 case EM_PARISC:
b2d38a17 7724 dynamic_section_parisc_val (entry);
103f02d3 7725 break;
ecc51f48 7726 case EM_IA_64:
b2d38a17 7727 dynamic_section_ia64_val (entry);
ecc51f48 7728 break;
252b5132 7729 default:
f7a99963
NC
7730 print_vma (entry->d_un.d_val, PREFIX_HEX);
7731 putchar ('\n');
252b5132
RH
7732 }
7733 }
7734 break;
7735 }
7736 }
7737
7738 return 1;
7739}
7740
7741static char *
d3ba0551 7742get_ver_flags (unsigned int flags)
252b5132 7743{
b34976b6 7744 static char buff[32];
252b5132
RH
7745
7746 buff[0] = 0;
7747
7748 if (flags == 0)
7749 return _("none");
7750
7751 if (flags & VER_FLG_BASE)
7752 strcat (buff, "BASE ");
7753
7754 if (flags & VER_FLG_WEAK)
7755 {
7756 if (flags & VER_FLG_BASE)
7757 strcat (buff, "| ");
7758
7759 strcat (buff, "WEAK ");
7760 }
7761
44ec90b9
RO
7762 if (flags & VER_FLG_INFO)
7763 {
7764 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7765 strcat (buff, "| ");
7766
7767 strcat (buff, "INFO ");
7768 }
7769
7770 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 7771 strcat (buff, _("| <unknown>"));
252b5132
RH
7772
7773 return buff;
7774}
7775
7776/* Display the contents of the version sections. */
98fb390a 7777
252b5132 7778static int
2cf0635d 7779process_version_sections (FILE * file)
252b5132 7780{
2cf0635d 7781 Elf_Internal_Shdr * section;
b34976b6
AM
7782 unsigned i;
7783 int found = 0;
252b5132
RH
7784
7785 if (! do_version)
7786 return 1;
7787
7788 for (i = 0, section = section_headers;
7789 i < elf_header.e_shnum;
b34976b6 7790 i++, section++)
252b5132
RH
7791 {
7792 switch (section->sh_type)
7793 {
7794 case SHT_GNU_verdef:
7795 {
2cf0635d 7796 Elf_External_Verdef * edefs;
b34976b6
AM
7797 unsigned int idx;
7798 unsigned int cnt;
2cf0635d 7799 char * endbuf;
252b5132
RH
7800
7801 found = 1;
7802
7803 printf
72de5009 7804 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
7805 SECTION_NAME (section), section->sh_info);
7806
7807 printf (_(" Addr: 0x"));
7808 printf_vma (section->sh_addr);
72de5009 7809 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7810 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
7811 section->sh_link < elf_header.e_shnum
7812 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 7813 : _("<corrupt>"));
252b5132 7814
3f5e193b
NC
7815 edefs = (Elf_External_Verdef *)
7816 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
7817 _("version definition section"));
54806181 7818 endbuf = (char *) edefs + section->sh_size;
a6e9f9df
AM
7819 if (!edefs)
7820 break;
252b5132 7821
b34976b6 7822 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 7823 {
2cf0635d
NC
7824 char * vstart;
7825 Elf_External_Verdef * edef;
b34976b6 7826 Elf_Internal_Verdef ent;
2cf0635d 7827 Elf_External_Verdaux * eaux;
b34976b6
AM
7828 Elf_Internal_Verdaux aux;
7829 int j;
7830 int isum;
103f02d3 7831
dd24e3da
NC
7832 /* Check for negative or very large indicies. */
7833 if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
7834 break;
7835
252b5132 7836 vstart = ((char *) edefs) + idx;
54806181
AM
7837 if (vstart + sizeof (*edef) > endbuf)
7838 break;
252b5132
RH
7839
7840 edef = (Elf_External_Verdef *) vstart;
7841
7842 ent.vd_version = BYTE_GET (edef->vd_version);
7843 ent.vd_flags = BYTE_GET (edef->vd_flags);
7844 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
7845 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
7846 ent.vd_hash = BYTE_GET (edef->vd_hash);
7847 ent.vd_aux = BYTE_GET (edef->vd_aux);
7848 ent.vd_next = BYTE_GET (edef->vd_next);
7849
7850 printf (_(" %#06x: Rev: %d Flags: %s"),
7851 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
7852
7853 printf (_(" Index: %d Cnt: %d "),
7854 ent.vd_ndx, ent.vd_cnt);
7855
dd24e3da
NC
7856 /* Check for overflow. */
7857 if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
7858 || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
7859 break;
7860
252b5132
RH
7861 vstart += ent.vd_aux;
7862
7863 eaux = (Elf_External_Verdaux *) vstart;
7864
7865 aux.vda_name = BYTE_GET (eaux->vda_name);
7866 aux.vda_next = BYTE_GET (eaux->vda_next);
7867
d79b3d50
NC
7868 if (VALID_DYNAMIC_NAME (aux.vda_name))
7869 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
7870 else
7871 printf (_("Name index: %ld\n"), aux.vda_name);
7872
7873 isum = idx + ent.vd_aux;
7874
b34976b6 7875 for (j = 1; j < ent.vd_cnt; j++)
252b5132 7876 {
dd24e3da
NC
7877 /* Check for overflow. */
7878 if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
7879 || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
7880 break;
7881
252b5132
RH
7882 isum += aux.vda_next;
7883 vstart += aux.vda_next;
7884
7885 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
7886 if (vstart + sizeof (*eaux) > endbuf)
7887 break;
252b5132
RH
7888
7889 aux.vda_name = BYTE_GET (eaux->vda_name);
7890 aux.vda_next = BYTE_GET (eaux->vda_next);
7891
d79b3d50 7892 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 7893 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 7894 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
7895 else
7896 printf (_(" %#06x: Parent %d, name index: %ld\n"),
7897 isum, j, aux.vda_name);
7898 }
dd24e3da 7899
54806181
AM
7900 if (j < ent.vd_cnt)
7901 printf (_(" Version def aux past end of section\n"));
252b5132
RH
7902
7903 idx += ent.vd_next;
7904 }
dd24e3da 7905
54806181
AM
7906 if (cnt < section->sh_info)
7907 printf (_(" Version definition past end of section\n"));
252b5132
RH
7908
7909 free (edefs);
7910 }
7911 break;
103f02d3 7912
252b5132
RH
7913 case SHT_GNU_verneed:
7914 {
2cf0635d 7915 Elf_External_Verneed * eneed;
b34976b6
AM
7916 unsigned int idx;
7917 unsigned int cnt;
2cf0635d 7918 char * endbuf;
252b5132
RH
7919
7920 found = 1;
7921
72de5009 7922 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
7923 SECTION_NAME (section), section->sh_info);
7924
7925 printf (_(" Addr: 0x"));
7926 printf_vma (section->sh_addr);
72de5009 7927 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7928 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
7929 section->sh_link < elf_header.e_shnum
7930 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 7931 : _("<corrupt>"));
252b5132 7932
3f5e193b
NC
7933 eneed = (Elf_External_Verneed *) get_data (NULL, file,
7934 section->sh_offset, 1,
7935 section->sh_size,
7936 _("version need section"));
54806181 7937 endbuf = (char *) eneed + section->sh_size;
a6e9f9df
AM
7938 if (!eneed)
7939 break;
252b5132
RH
7940
7941 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
7942 {
2cf0635d 7943 Elf_External_Verneed * entry;
b34976b6
AM
7944 Elf_Internal_Verneed ent;
7945 int j;
7946 int isum;
2cf0635d 7947 char * vstart;
252b5132 7948
dd24e3da
NC
7949 if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
7950 break;
7951
252b5132 7952 vstart = ((char *) eneed) + idx;
54806181
AM
7953 if (vstart + sizeof (*entry) > endbuf)
7954 break;
252b5132
RH
7955
7956 entry = (Elf_External_Verneed *) vstart;
7957
7958 ent.vn_version = BYTE_GET (entry->vn_version);
7959 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
7960 ent.vn_file = BYTE_GET (entry->vn_file);
7961 ent.vn_aux = BYTE_GET (entry->vn_aux);
7962 ent.vn_next = BYTE_GET (entry->vn_next);
7963
7964 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
7965
d79b3d50
NC
7966 if (VALID_DYNAMIC_NAME (ent.vn_file))
7967 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
7968 else
7969 printf (_(" File: %lx"), ent.vn_file);
7970
7971 printf (_(" Cnt: %d\n"), ent.vn_cnt);
7972
dd24e3da
NC
7973 /* Check for overflow. */
7974 if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
7975 || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
7976 break;
7977
252b5132
RH
7978 vstart += ent.vn_aux;
7979
7980 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
7981 {
2cf0635d 7982 Elf_External_Vernaux * eaux;
b34976b6 7983 Elf_Internal_Vernaux aux;
252b5132 7984
54806181
AM
7985 if (vstart + sizeof (*eaux) > endbuf)
7986 break;
252b5132
RH
7987 eaux = (Elf_External_Vernaux *) vstart;
7988
7989 aux.vna_hash = BYTE_GET (eaux->vna_hash);
7990 aux.vna_flags = BYTE_GET (eaux->vna_flags);
7991 aux.vna_other = BYTE_GET (eaux->vna_other);
7992 aux.vna_name = BYTE_GET (eaux->vna_name);
7993 aux.vna_next = BYTE_GET (eaux->vna_next);
7994
d79b3d50 7995 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 7996 printf (_(" %#06x: Name: %s"),
d79b3d50 7997 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 7998 else
ecc2063b 7999 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8000 isum, aux.vna_name);
8001
8002 printf (_(" Flags: %s Version: %d\n"),
8003 get_ver_flags (aux.vna_flags), aux.vna_other);
8004
dd24e3da
NC
8005 /* Check for overflow. */
8006 if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
8007 || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
8008 break;
8009
252b5132
RH
8010 isum += aux.vna_next;
8011 vstart += aux.vna_next;
8012 }
54806181
AM
8013 if (j < ent.vn_cnt)
8014 printf (_(" Version need aux past end of section\n"));
252b5132
RH
8015
8016 idx += ent.vn_next;
8017 }
54806181
AM
8018 if (cnt < section->sh_info)
8019 printf (_(" Version need past end of section\n"));
103f02d3 8020
252b5132
RH
8021 free (eneed);
8022 }
8023 break;
8024
8025 case SHT_GNU_versym:
8026 {
2cf0635d 8027 Elf_Internal_Shdr * link_section;
b34976b6
AM
8028 int total;
8029 int cnt;
2cf0635d
NC
8030 unsigned char * edata;
8031 unsigned short * data;
8032 char * strtab;
8033 Elf_Internal_Sym * symbols;
8034 Elf_Internal_Shdr * string_sec;
d3ba0551 8035 long off;
252b5132 8036
4fbb74a6 8037 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8038 break;
8039
4fbb74a6 8040 link_section = section_headers + section->sh_link;
08d8fa11 8041 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8042
4fbb74a6 8043 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8044 break;
8045
252b5132
RH
8046 found = 1;
8047
9ad5cbcf 8048 symbols = GET_ELF_SYMBOLS (file, link_section);
dd24e3da
NC
8049 if (symbols == NULL)
8050 break;
252b5132 8051
4fbb74a6 8052 string_sec = section_headers + link_section->sh_link;
252b5132 8053
3f5e193b
NC
8054 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8055 string_sec->sh_size,
8056 _("version string table"));
a6e9f9df 8057 if (!strtab)
0429c154
MS
8058 {
8059 free (symbols);
8060 break;
8061 }
252b5132
RH
8062
8063 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8064 SECTION_NAME (section), total);
8065
8066 printf (_(" Addr: "));
8067 printf_vma (section->sh_addr);
72de5009 8068 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8069 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8070 SECTION_NAME (link_section));
8071
d3ba0551
AM
8072 off = offset_from_vma (file,
8073 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8074 total * sizeof (short));
3f5e193b
NC
8075 edata = (unsigned char *) get_data (NULL, file, off, total,
8076 sizeof (short),
8077 _("version symbol data"));
a6e9f9df
AM
8078 if (!edata)
8079 {
8080 free (strtab);
0429c154 8081 free (symbols);
a6e9f9df
AM
8082 break;
8083 }
252b5132 8084
3f5e193b 8085 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8086
8087 for (cnt = total; cnt --;)
b34976b6
AM
8088 data[cnt] = byte_get (edata + cnt * sizeof (short),
8089 sizeof (short));
252b5132
RH
8090
8091 free (edata);
8092
8093 for (cnt = 0; cnt < total; cnt += 4)
8094 {
8095 int j, nn;
00d93f34 8096 int check_def, check_need;
2cf0635d 8097 char * name;
252b5132
RH
8098
8099 printf (" %03x:", cnt);
8100
8101 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8102 switch (data[cnt + j])
252b5132
RH
8103 {
8104 case 0:
8105 fputs (_(" 0 (*local*) "), stdout);
8106 break;
8107
8108 case 1:
8109 fputs (_(" 1 (*global*) "), stdout);
8110 break;
8111
8112 default:
c244d050
NC
8113 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8114 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8115
dd24e3da
NC
8116 /* If this index value is greater than the size of the symbols
8117 array, break to avoid an out-of-bounds read, */
8118 if ((unsigned long)(cnt + j) >=
8119 ((unsigned long)link_section->sh_size /
8120 (unsigned long)link_section->sh_entsize))
8121 {
8122 warn (_("invalid index into symbol array\n"));
8123 break;
8124 }
8125
00d93f34
JJ
8126 check_def = 1;
8127 check_need = 1;
4fbb74a6
AM
8128 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8129 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8130 != SHT_NOBITS)
252b5132 8131 {
b34976b6 8132 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8133 check_def = 0;
8134 else
8135 check_need = 0;
252b5132 8136 }
00d93f34
JJ
8137
8138 if (check_need
b34976b6 8139 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8140 {
b34976b6
AM
8141 Elf_Internal_Verneed ivn;
8142 unsigned long offset;
252b5132 8143
d93f0186
NC
8144 offset = offset_from_vma
8145 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8146 sizeof (Elf_External_Verneed));
252b5132 8147
b34976b6 8148 do
252b5132 8149 {
b34976b6
AM
8150 Elf_Internal_Vernaux ivna;
8151 Elf_External_Verneed evn;
8152 Elf_External_Vernaux evna;
8153 unsigned long a_off;
252b5132 8154
c256ffe7 8155 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 8156 _("version need"));
252b5132
RH
8157
8158 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8159 ivn.vn_next = BYTE_GET (evn.vn_next);
8160
8161 a_off = offset + ivn.vn_aux;
8162
8163 do
8164 {
a6e9f9df 8165 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 8166 1, _("version need aux (2)"));
252b5132
RH
8167
8168 ivna.vna_next = BYTE_GET (evna.vna_next);
8169 ivna.vna_other = BYTE_GET (evna.vna_other);
8170
8171 a_off += ivna.vna_next;
8172 }
b34976b6 8173 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8174 && ivna.vna_next != 0);
8175
b34976b6 8176 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8177 {
8178 ivna.vna_name = BYTE_GET (evna.vna_name);
8179
54806181
AM
8180 if (ivna.vna_name >= string_sec->sh_size)
8181 name = _("*invalid*");
8182 else
8183 name = strtab + ivna.vna_name;
252b5132 8184 nn += printf ("(%s%-*s",
16062207
ILT
8185 name,
8186 12 - (int) strlen (name),
252b5132 8187 ")");
00d93f34 8188 check_def = 0;
252b5132
RH
8189 break;
8190 }
8191
8192 offset += ivn.vn_next;
8193 }
8194 while (ivn.vn_next);
8195 }
00d93f34 8196
b34976b6
AM
8197 if (check_def && data[cnt + j] != 0x8001
8198 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8199 {
b34976b6
AM
8200 Elf_Internal_Verdef ivd;
8201 Elf_External_Verdef evd;
8202 unsigned long offset;
252b5132 8203
d93f0186
NC
8204 offset = offset_from_vma
8205 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8206 sizeof evd);
252b5132
RH
8207
8208 do
8209 {
c256ffe7 8210 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 8211 _("version def"));
252b5132
RH
8212
8213 ivd.vd_next = BYTE_GET (evd.vd_next);
8214 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8215
8216 offset += ivd.vd_next;
8217 }
c244d050 8218 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8219 && ivd.vd_next != 0);
8220
c244d050 8221 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8222 {
b34976b6
AM
8223 Elf_External_Verdaux evda;
8224 Elf_Internal_Verdaux ivda;
252b5132
RH
8225
8226 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8227
a6e9f9df
AM
8228 get_data (&evda, file,
8229 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
8230 sizeof (evda), 1,
8231 _("version def aux"));
252b5132
RH
8232
8233 ivda.vda_name = BYTE_GET (evda.vda_name);
8234
54806181
AM
8235 if (ivda.vda_name >= string_sec->sh_size)
8236 name = _("*invalid*");
8237 else
8238 name = strtab + ivda.vda_name;
252b5132 8239 nn += printf ("(%s%-*s",
16062207
ILT
8240 name,
8241 12 - (int) strlen (name),
252b5132
RH
8242 ")");
8243 }
8244 }
8245
8246 if (nn < 18)
8247 printf ("%*c", 18 - nn, ' ');
8248 }
8249
8250 putchar ('\n');
8251 }
8252
8253 free (data);
8254 free (strtab);
8255 free (symbols);
8256 }
8257 break;
103f02d3 8258
252b5132
RH
8259 default:
8260 break;
8261 }
8262 }
8263
8264 if (! found)
8265 printf (_("\nNo version information found in this file.\n"));
8266
8267 return 1;
8268}
8269
d1133906 8270static const char *
d3ba0551 8271get_symbol_binding (unsigned int binding)
252b5132 8272{
b34976b6 8273 static char buff[32];
252b5132
RH
8274
8275 switch (binding)
8276 {
b34976b6
AM
8277 case STB_LOCAL: return "LOCAL";
8278 case STB_GLOBAL: return "GLOBAL";
8279 case STB_WEAK: return "WEAK";
252b5132
RH
8280 default:
8281 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8282 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8283 binding);
252b5132 8284 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8285 {
8286 if (binding == STB_GNU_UNIQUE
8287 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
8288 /* GNU/Linux is still using the default value 0. */
8289 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8290 return "UNIQUE";
8291 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8292 }
252b5132 8293 else
e9e44622 8294 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8295 return buff;
8296 }
8297}
8298
d1133906 8299static const char *
d3ba0551 8300get_symbol_type (unsigned int type)
252b5132 8301{
b34976b6 8302 static char buff[32];
252b5132
RH
8303
8304 switch (type)
8305 {
b34976b6
AM
8306 case STT_NOTYPE: return "NOTYPE";
8307 case STT_OBJECT: return "OBJECT";
8308 case STT_FUNC: return "FUNC";
8309 case STT_SECTION: return "SECTION";
8310 case STT_FILE: return "FILE";
8311 case STT_COMMON: return "COMMON";
8312 case STT_TLS: return "TLS";
15ab5209
DB
8313 case STT_RELC: return "RELC";
8314 case STT_SRELC: return "SRELC";
252b5132
RH
8315 default:
8316 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8317 {
8318 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8319 return "THUMB_FUNC";
8320
351b4b40 8321 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8322 return "REGISTER";
8323
8324 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8325 return "PARISC_MILLI";
8326
e9e44622 8327 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8328 }
252b5132 8329 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8330 {
8331 if (elf_header.e_machine == EM_PARISC)
8332 {
8333 if (type == STT_HP_OPAQUE)
8334 return "HP_OPAQUE";
8335 if (type == STT_HP_STUB)
8336 return "HP_STUB";
8337 }
8338
d8045f23
NC
8339 if (type == STT_GNU_IFUNC
8340 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
8341 /* GNU/Linux is still using the default value 0. */
8342 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8343 return "IFUNC";
8344
e9e44622 8345 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8346 }
252b5132 8347 else
e9e44622 8348 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8349 return buff;
8350 }
8351}
8352
d1133906 8353static const char *
d3ba0551 8354get_symbol_visibility (unsigned int visibility)
d1133906
NC
8355{
8356 switch (visibility)
8357 {
b34976b6
AM
8358 case STV_DEFAULT: return "DEFAULT";
8359 case STV_INTERNAL: return "INTERNAL";
8360 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
8361 case STV_PROTECTED: return "PROTECTED";
8362 default: abort ();
8363 }
8364}
8365
5e2b0d47
NC
8366static const char *
8367get_mips_symbol_other (unsigned int other)
8368{
8369 switch (other)
8370 {
8371 case STO_OPTIONAL: return "OPTIONAL";
8372 case STO_MIPS16: return "MIPS16";
861fb55a
DJ
8373 case STO_MIPS_PLT: return "MIPS PLT";
8374 case STO_MIPS_PIC: return "MIPS PIC";
5e2b0d47
NC
8375 default: return NULL;
8376 }
8377}
8378
28f997cf
TG
8379static const char *
8380get_ia64_symbol_other (unsigned int other)
8381{
8382 if (is_ia64_vms ())
8383 {
8384 static char res[32];
8385
8386 res[0] = 0;
8387
8388 /* Function types is for images and .STB files only. */
8389 switch (elf_header.e_type)
8390 {
8391 case ET_DYN:
8392 case ET_EXEC:
8393 switch (VMS_ST_FUNC_TYPE (other))
8394 {
8395 case VMS_SFT_CODE_ADDR:
8396 strcat (res, " CA");
8397 break;
8398 case VMS_SFT_SYMV_IDX:
8399 strcat (res, " VEC");
8400 break;
8401 case VMS_SFT_FD:
8402 strcat (res, " FD");
8403 break;
8404 case VMS_SFT_RESERVE:
8405 strcat (res, " RSV");
8406 break;
8407 default:
8408 abort ();
8409 }
8410 break;
8411 default:
8412 break;
8413 }
8414 switch (VMS_ST_LINKAGE (other))
8415 {
8416 case VMS_STL_IGNORE:
8417 strcat (res, " IGN");
8418 break;
8419 case VMS_STL_RESERVE:
8420 strcat (res, " RSV");
8421 break;
8422 case VMS_STL_STD:
8423 strcat (res, " STD");
8424 break;
8425 case VMS_STL_LNK:
8426 strcat (res, " LNK");
8427 break;
8428 default:
8429 abort ();
8430 }
8431
8432 if (res[0] != 0)
8433 return res + 1;
8434 else
8435 return res;
8436 }
8437 return NULL;
8438}
8439
5e2b0d47
NC
8440static const char *
8441get_symbol_other (unsigned int other)
8442{
8443 const char * result = NULL;
8444 static char buff [32];
8445
8446 if (other == 0)
8447 return "";
8448
8449 switch (elf_header.e_machine)
8450 {
8451 case EM_MIPS:
8452 result = get_mips_symbol_other (other);
28f997cf
TG
8453 break;
8454 case EM_IA_64:
8455 result = get_ia64_symbol_other (other);
8456 break;
5e2b0d47
NC
8457 default:
8458 break;
8459 }
8460
8461 if (result)
8462 return result;
8463
8464 snprintf (buff, sizeof buff, _("<other>: %x"), other);
8465 return buff;
8466}
8467
d1133906 8468static const char *
d3ba0551 8469get_symbol_index_type (unsigned int type)
252b5132 8470{
b34976b6 8471 static char buff[32];
5cf1065c 8472
252b5132
RH
8473 switch (type)
8474 {
b34976b6
AM
8475 case SHN_UNDEF: return "UND";
8476 case SHN_ABS: return "ABS";
8477 case SHN_COMMON: return "COM";
252b5132 8478 default:
9ce701e2
L
8479 if (type == SHN_IA_64_ANSI_COMMON
8480 && elf_header.e_machine == EM_IA_64
8481 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
8482 return "ANSI_COM";
8a9036a4
L
8483 else if ((elf_header.e_machine == EM_X86_64
8484 || elf_header.e_machine == EM_L1OM)
3b22753a
L
8485 && type == SHN_X86_64_LCOMMON)
8486 return "LARGE_COM";
ac145307
BS
8487 else if ((type == SHN_MIPS_SCOMMON
8488 && elf_header.e_machine == EM_MIPS)
8489 || (type == SHN_TIC6X_SCOMMON
8490 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
8491 return "SCOM";
8492 else if (type == SHN_MIPS_SUNDEFINED
8493 && elf_header.e_machine == EM_MIPS)
8494 return "SUND";
9ce701e2 8495 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 8496 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 8497 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
8498 sprintf (buff, "OS [0x%04x]", type & 0xffff);
8499 else if (type >= SHN_LORESERVE)
8500 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 8501 else
232e7cb8 8502 sprintf (buff, "%3d", type);
5cf1065c 8503 break;
252b5132 8504 }
5cf1065c
NC
8505
8506 return buff;
252b5132
RH
8507}
8508
66543521 8509static bfd_vma *
2cf0635d 8510get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 8511{
2cf0635d
NC
8512 unsigned char * e_data;
8513 bfd_vma * i_data;
252b5132 8514
3f5e193b 8515 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
8516
8517 if (e_data == NULL)
8518 {
8519 error (_("Out of memory\n"));
8520 return NULL;
8521 }
8522
66543521 8523 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
8524 {
8525 error (_("Unable to read in dynamic data\n"));
8526 return NULL;
8527 }
8528
3f5e193b 8529 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
8530
8531 if (i_data == NULL)
8532 {
8533 error (_("Out of memory\n"));
8534 free (e_data);
8535 return NULL;
8536 }
8537
8538 while (number--)
66543521 8539 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
8540
8541 free (e_data);
8542
8543 return i_data;
8544}
8545
6bd1a22c
L
8546static void
8547print_dynamic_symbol (bfd_vma si, unsigned long hn)
8548{
2cf0635d 8549 Elf_Internal_Sym * psym;
6bd1a22c
L
8550 int n;
8551
8552 psym = dynamic_symbols + si;
8553
8554 n = print_vma (si, DEC_5);
8555 if (n < 5)
8556 fputs (" " + n, stdout);
8557 printf (" %3lu: ", hn);
8558 print_vma (psym->st_value, LONG_HEX);
8559 putchar (' ');
8560 print_vma (psym->st_size, DEC_5);
8561
f4be36b3
AM
8562 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8563 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
8564 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
8565 /* Check to see if any other bits in the st_other field are set.
8566 Note - displaying this information disrupts the layout of the
8567 table being generated, but for the moment this case is very
8568 rare. */
8569 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8570 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
8571 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
8572 if (VALID_DYNAMIC_NAME (psym->st_name))
8573 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
8574 else
2b692964 8575 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
8576 putchar ('\n');
8577}
8578
e3c8793a 8579/* Dump the symbol table. */
252b5132 8580static int
2cf0635d 8581process_symbol_table (FILE * file)
252b5132 8582{
2cf0635d 8583 Elf_Internal_Shdr * section;
66543521
AM
8584 bfd_vma nbuckets = 0;
8585 bfd_vma nchains = 0;
2cf0635d
NC
8586 bfd_vma * buckets = NULL;
8587 bfd_vma * chains = NULL;
fdc90cb4 8588 bfd_vma ngnubuckets = 0;
2cf0635d
NC
8589 bfd_vma * gnubuckets = NULL;
8590 bfd_vma * gnuchains = NULL;
6bd1a22c 8591 bfd_vma gnusymidx = 0;
252b5132 8592
2c610e4b 8593 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
8594 return 1;
8595
6bd1a22c
L
8596 if (dynamic_info[DT_HASH]
8597 && (do_histogram
2c610e4b
L
8598 || (do_using_dynamic
8599 && !do_dyn_syms
8600 && dynamic_strings != NULL)))
252b5132 8601 {
66543521
AM
8602 unsigned char nb[8];
8603 unsigned char nc[8];
8604 int hash_ent_size = 4;
8605
8606 if ((elf_header.e_machine == EM_ALPHA
8607 || elf_header.e_machine == EM_S390
8608 || elf_header.e_machine == EM_S390_OLD)
8609 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
8610 hash_ent_size = 8;
8611
fb52b2f4
NC
8612 if (fseek (file,
8613 (archive_file_offset
8614 + offset_from_vma (file, dynamic_info[DT_HASH],
8615 sizeof nb + sizeof nc)),
d93f0186 8616 SEEK_SET))
252b5132 8617 {
591a748a 8618 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8619 goto no_hash;
252b5132
RH
8620 }
8621
66543521 8622 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
8623 {
8624 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8625 goto no_hash;
252b5132
RH
8626 }
8627
66543521 8628 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
8629 {
8630 error (_("Failed to read in number of chains\n"));
d3a44ec6 8631 goto no_hash;
252b5132
RH
8632 }
8633
66543521
AM
8634 nbuckets = byte_get (nb, hash_ent_size);
8635 nchains = byte_get (nc, hash_ent_size);
252b5132 8636
66543521
AM
8637 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
8638 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 8639
d3a44ec6 8640 no_hash:
252b5132 8641 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
8642 {
8643 if (do_using_dynamic)
8644 return 0;
8645 free (buckets);
8646 free (chains);
8647 buckets = NULL;
8648 chains = NULL;
8649 nbuckets = 0;
8650 nchains = 0;
8651 }
252b5132
RH
8652 }
8653
6bd1a22c
L
8654 if (dynamic_info_DT_GNU_HASH
8655 && (do_histogram
2c610e4b
L
8656 || (do_using_dynamic
8657 && !do_dyn_syms
8658 && dynamic_strings != NULL)))
252b5132 8659 {
6bd1a22c
L
8660 unsigned char nb[16];
8661 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
8662 bfd_vma buckets_vma;
8663
8664 if (fseek (file,
8665 (archive_file_offset
8666 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
8667 sizeof nb)),
8668 SEEK_SET))
8669 {
8670 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8671 goto no_gnu_hash;
6bd1a22c 8672 }
252b5132 8673
6bd1a22c
L
8674 if (fread (nb, 16, 1, file) != 1)
8675 {
8676 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8677 goto no_gnu_hash;
6bd1a22c
L
8678 }
8679
8680 ngnubuckets = byte_get (nb, 4);
8681 gnusymidx = byte_get (nb + 4, 4);
8682 bitmaskwords = byte_get (nb + 8, 4);
8683 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 8684 if (is_32bit_elf)
6bd1a22c 8685 buckets_vma += bitmaskwords * 4;
f7a99963 8686 else
6bd1a22c 8687 buckets_vma += bitmaskwords * 8;
252b5132 8688
6bd1a22c
L
8689 if (fseek (file,
8690 (archive_file_offset
8691 + offset_from_vma (file, buckets_vma, 4)),
8692 SEEK_SET))
252b5132 8693 {
6bd1a22c 8694 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8695 goto no_gnu_hash;
6bd1a22c
L
8696 }
8697
8698 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 8699
6bd1a22c 8700 if (gnubuckets == NULL)
d3a44ec6 8701 goto no_gnu_hash;
6bd1a22c
L
8702
8703 for (i = 0; i < ngnubuckets; i++)
8704 if (gnubuckets[i] != 0)
8705 {
8706 if (gnubuckets[i] < gnusymidx)
8707 return 0;
8708
8709 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
8710 maxchain = gnubuckets[i];
8711 }
8712
8713 if (maxchain == 0xffffffff)
d3a44ec6 8714 goto no_gnu_hash;
6bd1a22c
L
8715
8716 maxchain -= gnusymidx;
8717
8718 if (fseek (file,
8719 (archive_file_offset
8720 + offset_from_vma (file, buckets_vma
8721 + 4 * (ngnubuckets + maxchain), 4)),
8722 SEEK_SET))
8723 {
8724 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8725 goto no_gnu_hash;
6bd1a22c
L
8726 }
8727
8728 do
8729 {
8730 if (fread (nb, 4, 1, file) != 1)
252b5132 8731 {
6bd1a22c 8732 error (_("Failed to determine last chain length\n"));
d3a44ec6 8733 goto no_gnu_hash;
6bd1a22c 8734 }
252b5132 8735
6bd1a22c 8736 if (maxchain + 1 == 0)
d3a44ec6 8737 goto no_gnu_hash;
252b5132 8738
6bd1a22c
L
8739 ++maxchain;
8740 }
8741 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 8742
6bd1a22c
L
8743 if (fseek (file,
8744 (archive_file_offset
8745 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
8746 SEEK_SET))
8747 {
8748 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8749 goto no_gnu_hash;
6bd1a22c
L
8750 }
8751
8752 gnuchains = get_dynamic_data (file, maxchain, 4);
8753
d3a44ec6 8754 no_gnu_hash:
6bd1a22c 8755 if (gnuchains == NULL)
d3a44ec6
JJ
8756 {
8757 free (gnubuckets);
d3a44ec6
JJ
8758 gnubuckets = NULL;
8759 ngnubuckets = 0;
f64fddf1
NC
8760 if (do_using_dynamic)
8761 return 0;
d3a44ec6 8762 }
6bd1a22c
L
8763 }
8764
8765 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
8766 && do_syms
8767 && do_using_dynamic
8768 && dynamic_strings != NULL)
8769 {
8770 unsigned long hn;
8771
8772 if (dynamic_info[DT_HASH])
8773 {
8774 bfd_vma si;
8775
8776 printf (_("\nSymbol table for image:\n"));
8777 if (is_32bit_elf)
8778 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8779 else
8780 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8781
8782 for (hn = 0; hn < nbuckets; hn++)
8783 {
8784 if (! buckets[hn])
8785 continue;
8786
8787 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
8788 print_dynamic_symbol (si, hn);
252b5132
RH
8789 }
8790 }
6bd1a22c
L
8791
8792 if (dynamic_info_DT_GNU_HASH)
8793 {
8794 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
8795 if (is_32bit_elf)
8796 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8797 else
8798 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8799
8800 for (hn = 0; hn < ngnubuckets; ++hn)
8801 if (gnubuckets[hn] != 0)
8802 {
8803 bfd_vma si = gnubuckets[hn];
8804 bfd_vma off = si - gnusymidx;
8805
8806 do
8807 {
8808 print_dynamic_symbol (si, hn);
8809 si++;
8810 }
8811 while ((gnuchains[off++] & 1) == 0);
8812 }
8813 }
252b5132 8814 }
2c610e4b 8815 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 8816 {
b34976b6 8817 unsigned int i;
252b5132
RH
8818
8819 for (i = 0, section = section_headers;
8820 i < elf_header.e_shnum;
8821 i++, section++)
8822 {
b34976b6 8823 unsigned int si;
2cf0635d 8824 char * strtab = NULL;
c256ffe7 8825 unsigned long int strtab_size = 0;
2cf0635d
NC
8826 Elf_Internal_Sym * symtab;
8827 Elf_Internal_Sym * psym;
252b5132 8828
2c610e4b
L
8829 if ((section->sh_type != SHT_SYMTAB
8830 && section->sh_type != SHT_DYNSYM)
8831 || (!do_syms
8832 && section->sh_type == SHT_SYMTAB))
252b5132
RH
8833 continue;
8834
dd24e3da
NC
8835 if (section->sh_entsize == 0)
8836 {
8837 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
8838 SECTION_NAME (section));
8839 continue;
8840 }
8841
252b5132
RH
8842 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
8843 SECTION_NAME (section),
8844 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 8845
f7a99963 8846 if (is_32bit_elf)
ca47b30c 8847 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 8848 else
ca47b30c 8849 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 8850
9ad5cbcf 8851 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
8852 if (symtab == NULL)
8853 continue;
8854
8855 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
8856 {
8857 strtab = string_table;
8858 strtab_size = string_table_length;
8859 }
4fbb74a6 8860 else if (section->sh_link < elf_header.e_shnum)
252b5132 8861 {
2cf0635d 8862 Elf_Internal_Shdr * string_sec;
252b5132 8863
4fbb74a6 8864 string_sec = section_headers + section->sh_link;
252b5132 8865
3f5e193b
NC
8866 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
8867 1, string_sec->sh_size,
8868 _("string table"));
c256ffe7 8869 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
8870 }
8871
8872 for (si = 0, psym = symtab;
8873 si < section->sh_size / section->sh_entsize;
b34976b6 8874 si++, psym++)
252b5132 8875 {
5e220199 8876 printf ("%6d: ", si);
f7a99963
NC
8877 print_vma (psym->st_value, LONG_HEX);
8878 putchar (' ');
8879 print_vma (psym->st_size, DEC_5);
d1133906
NC
8880 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8881 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 8882 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
8883 /* Check to see if any other bits in the st_other field are set.
8884 Note - displaying this information disrupts the layout of the
8885 table being generated, but for the moment this case is very rare. */
8886 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8887 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 8888 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 8889 print_symbol (25, psym->st_name < strtab_size
2b692964 8890 ? strtab + psym->st_name : _("<corrupt>"));
252b5132
RH
8891
8892 if (section->sh_type == SHT_DYNSYM &&
b34976b6 8893 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 8894 {
b34976b6
AM
8895 unsigned char data[2];
8896 unsigned short vers_data;
8897 unsigned long offset;
8898 int is_nobits;
8899 int check_def;
252b5132 8900
d93f0186
NC
8901 offset = offset_from_vma
8902 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8903 sizeof data + si * sizeof (vers_data));
252b5132 8904
a6e9f9df 8905 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 8906 sizeof (data), 1, _("version data"));
252b5132
RH
8907
8908 vers_data = byte_get (data, 2);
8909
4fbb74a6
AM
8910 is_nobits = (psym->st_shndx < elf_header.e_shnum
8911 && section_headers[psym->st_shndx].sh_type
c256ffe7 8912 == SHT_NOBITS);
252b5132
RH
8913
8914 check_def = (psym->st_shndx != SHN_UNDEF);
8915
c244d050 8916 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 8917 {
b34976b6 8918 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 8919 && (is_nobits || ! check_def))
252b5132 8920 {
b34976b6
AM
8921 Elf_External_Verneed evn;
8922 Elf_Internal_Verneed ivn;
8923 Elf_Internal_Vernaux ivna;
252b5132
RH
8924
8925 /* We must test both. */
d93f0186
NC
8926 offset = offset_from_vma
8927 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8928 sizeof evn);
252b5132 8929
252b5132
RH
8930 do
8931 {
b34976b6 8932 unsigned long vna_off;
252b5132 8933
c256ffe7 8934 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 8935 _("version need"));
dd27201e
L
8936
8937 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8938 ivn.vn_next = BYTE_GET (evn.vn_next);
8939
252b5132
RH
8940 vna_off = offset + ivn.vn_aux;
8941
8942 do
8943 {
b34976b6 8944 Elf_External_Vernaux evna;
252b5132 8945
a6e9f9df 8946 get_data (&evna, file, vna_off,
c256ffe7 8947 sizeof (evna), 1,
a6e9f9df 8948 _("version need aux (3)"));
252b5132
RH
8949
8950 ivna.vna_other = BYTE_GET (evna.vna_other);
8951 ivna.vna_next = BYTE_GET (evna.vna_next);
8952 ivna.vna_name = BYTE_GET (evna.vna_name);
8953
8954 vna_off += ivna.vna_next;
8955 }
8956 while (ivna.vna_other != vers_data
8957 && ivna.vna_next != 0);
8958
8959 if (ivna.vna_other == vers_data)
8960 break;
8961
8962 offset += ivn.vn_next;
8963 }
8964 while (ivn.vn_next != 0);
8965
8966 if (ivna.vna_other == vers_data)
8967 {
8968 printf ("@%s (%d)",
c256ffe7 8969 ivna.vna_name < strtab_size
2b692964 8970 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 8971 ivna.vna_other);
252b5132
RH
8972 check_def = 0;
8973 }
8974 else if (! is_nobits)
591a748a 8975 error (_("bad dynamic symbol\n"));
252b5132
RH
8976 else
8977 check_def = 1;
8978 }
8979
8980 if (check_def)
8981 {
00d93f34 8982 if (vers_data != 0x8001
b34976b6 8983 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8984 {
b34976b6
AM
8985 Elf_Internal_Verdef ivd;
8986 Elf_Internal_Verdaux ivda;
8987 Elf_External_Verdaux evda;
91d6fa6a 8988 unsigned long off;
252b5132 8989
91d6fa6a 8990 off = offset_from_vma
d93f0186
NC
8991 (file,
8992 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8993 sizeof (Elf_External_Verdef));
252b5132
RH
8994
8995 do
8996 {
b34976b6 8997 Elf_External_Verdef evd;
252b5132 8998
91d6fa6a 8999 get_data (&evd, file, off, sizeof (evd),
c256ffe7 9000 1, _("version def"));
252b5132 9001
b34976b6
AM
9002 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9003 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
9004 ivd.vd_next = BYTE_GET (evd.vd_next);
9005
91d6fa6a 9006 off += ivd.vd_next;
252b5132 9007 }
c244d050 9008 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9009 && ivd.vd_next != 0);
9010
91d6fa6a
NC
9011 off -= ivd.vd_next;
9012 off += ivd.vd_aux;
252b5132 9013
91d6fa6a 9014 get_data (&evda, file, off, sizeof (evda),
c256ffe7 9015 1, _("version def aux"));
252b5132
RH
9016
9017 ivda.vda_name = BYTE_GET (evda.vda_name);
9018
9019 if (psym->st_name != ivda.vda_name)
c244d050 9020 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9021 ? "@%s" : "@@%s",
c256ffe7 9022 ivda.vda_name < strtab_size
2b692964 9023 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9024 }
9025 }
9026 }
9027 }
9028
9029 putchar ('\n');
9030 }
9031
9032 free (symtab);
9033 if (strtab != string_table)
9034 free (strtab);
9035 }
9036 }
9037 else if (do_syms)
9038 printf
9039 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9040
9041 if (do_histogram && buckets != NULL)
9042 {
2cf0635d
NC
9043 unsigned long * lengths;
9044 unsigned long * counts;
66543521
AM
9045 unsigned long hn;
9046 bfd_vma si;
9047 unsigned long maxlength = 0;
9048 unsigned long nzero_counts = 0;
9049 unsigned long nsyms = 0;
252b5132 9050
66543521
AM
9051 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9052 (unsigned long) nbuckets);
252b5132
RH
9053 printf (_(" Length Number %% of total Coverage\n"));
9054
3f5e193b 9055 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9056 if (lengths == NULL)
9057 {
591a748a 9058 error (_("Out of memory\n"));
252b5132
RH
9059 return 0;
9060 }
9061 for (hn = 0; hn < nbuckets; ++hn)
9062 {
f7a99963 9063 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9064 {
b34976b6 9065 ++nsyms;
252b5132 9066 if (maxlength < ++lengths[hn])
b34976b6 9067 ++maxlength;
252b5132
RH
9068 }
9069 }
9070
3f5e193b 9071 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9072 if (counts == NULL)
9073 {
591a748a 9074 error (_("Out of memory\n"));
252b5132
RH
9075 return 0;
9076 }
9077
9078 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9079 ++counts[lengths[hn]];
252b5132 9080
103f02d3 9081 if (nbuckets > 0)
252b5132 9082 {
66543521
AM
9083 unsigned long i;
9084 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9085 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9086 for (i = 1; i <= maxlength; ++i)
103f02d3 9087 {
66543521
AM
9088 nzero_counts += counts[i] * i;
9089 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9090 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9091 (nzero_counts * 100.0) / nsyms);
9092 }
252b5132
RH
9093 }
9094
9095 free (counts);
9096 free (lengths);
9097 }
9098
9099 if (buckets != NULL)
9100 {
9101 free (buckets);
9102 free (chains);
9103 }
9104
d3a44ec6 9105 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9106 {
2cf0635d
NC
9107 unsigned long * lengths;
9108 unsigned long * counts;
fdc90cb4
JJ
9109 unsigned long hn;
9110 unsigned long maxlength = 0;
9111 unsigned long nzero_counts = 0;
9112 unsigned long nsyms = 0;
fdc90cb4 9113
3f5e193b 9114 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9115 if (lengths == NULL)
9116 {
591a748a 9117 error (_("Out of memory\n"));
fdc90cb4
JJ
9118 return 0;
9119 }
9120
9121 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9122 (unsigned long) ngnubuckets);
9123 printf (_(" Length Number %% of total Coverage\n"));
9124
9125 for (hn = 0; hn < ngnubuckets; ++hn)
9126 if (gnubuckets[hn] != 0)
9127 {
9128 bfd_vma off, length = 1;
9129
6bd1a22c 9130 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9131 (gnuchains[off] & 1) == 0; ++off)
9132 ++length;
9133 lengths[hn] = length;
9134 if (length > maxlength)
9135 maxlength = length;
9136 nsyms += length;
9137 }
9138
3f5e193b 9139 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9140 if (counts == NULL)
9141 {
591a748a 9142 error (_("Out of memory\n"));
fdc90cb4
JJ
9143 return 0;
9144 }
9145
9146 for (hn = 0; hn < ngnubuckets; ++hn)
9147 ++counts[lengths[hn]];
9148
9149 if (ngnubuckets > 0)
9150 {
9151 unsigned long j;
9152 printf (" 0 %-10lu (%5.1f%%)\n",
9153 counts[0], (counts[0] * 100.0) / ngnubuckets);
9154 for (j = 1; j <= maxlength; ++j)
9155 {
9156 nzero_counts += counts[j] * j;
9157 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9158 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9159 (nzero_counts * 100.0) / nsyms);
9160 }
9161 }
9162
9163 free (counts);
9164 free (lengths);
9165 free (gnubuckets);
9166 free (gnuchains);
9167 }
9168
252b5132
RH
9169 return 1;
9170}
9171
9172static int
2cf0635d 9173process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9174{
b4c96d0d 9175 unsigned int i;
252b5132
RH
9176
9177 if (dynamic_syminfo == NULL
9178 || !do_dynamic)
9179 /* No syminfo, this is ok. */
9180 return 1;
9181
9182 /* There better should be a dynamic symbol section. */
9183 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9184 return 0;
9185
9186 if (dynamic_addr)
9187 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9188 dynamic_syminfo_offset, dynamic_syminfo_nent);
9189
9190 printf (_(" Num: Name BoundTo Flags\n"));
9191 for (i = 0; i < dynamic_syminfo_nent; ++i)
9192 {
9193 unsigned short int flags = dynamic_syminfo[i].si_flags;
9194
31104126 9195 printf ("%4d: ", i);
d79b3d50
NC
9196 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9197 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9198 else
2b692964 9199 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9200 putchar (' ');
252b5132
RH
9201
9202 switch (dynamic_syminfo[i].si_boundto)
9203 {
9204 case SYMINFO_BT_SELF:
9205 fputs ("SELF ", stdout);
9206 break;
9207 case SYMINFO_BT_PARENT:
9208 fputs ("PARENT ", stdout);
9209 break;
9210 default:
9211 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9212 && dynamic_syminfo[i].si_boundto < dynamic_nent
9213 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9214 {
d79b3d50 9215 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9216 putchar (' ' );
9217 }
252b5132
RH
9218 else
9219 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9220 break;
9221 }
9222
9223 if (flags & SYMINFO_FLG_DIRECT)
9224 printf (" DIRECT");
9225 if (flags & SYMINFO_FLG_PASSTHRU)
9226 printf (" PASSTHRU");
9227 if (flags & SYMINFO_FLG_COPY)
9228 printf (" COPY");
9229 if (flags & SYMINFO_FLG_LAZYLOAD)
9230 printf (" LAZYLOAD");
9231
9232 puts ("");
9233 }
9234
9235 return 1;
9236}
9237
cf13d699
NC
9238/* Check to see if the given reloc needs to be handled in a target specific
9239 manner. If so then process the reloc and return TRUE otherwise return
9240 FALSE. */
09c11c86 9241
cf13d699
NC
9242static bfd_boolean
9243target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9244 unsigned char * start,
9245 Elf_Internal_Sym * symtab)
252b5132 9246{
cf13d699 9247 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9248
cf13d699 9249 switch (elf_header.e_machine)
252b5132 9250 {
cf13d699
NC
9251 case EM_MN10300:
9252 case EM_CYGNUS_MN10300:
9253 {
9254 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9255
cf13d699
NC
9256 switch (reloc_type)
9257 {
9258 case 34: /* R_MN10300_ALIGN */
9259 return TRUE;
9260 case 33: /* R_MN10300_SYM_DIFF */
9261 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9262 return TRUE;
9263 case 1: /* R_MN10300_32 */
9264 case 2: /* R_MN10300_16 */
9265 if (saved_sym != NULL)
9266 {
9267 bfd_vma value;
252b5132 9268
cf13d699
NC
9269 value = reloc->r_addend
9270 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9271 - saved_sym->st_value);
252b5132 9272
cf13d699 9273 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9274
cf13d699
NC
9275 saved_sym = NULL;
9276 return TRUE;
9277 }
9278 break;
9279 default:
9280 if (saved_sym != NULL)
9281 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9282 break;
9283 }
9284 break;
9285 }
252b5132
RH
9286 }
9287
cf13d699 9288 return FALSE;
252b5132
RH
9289}
9290
aca88567
NC
9291/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9292 DWARF debug sections. This is a target specific test. Note - we do not
9293 go through the whole including-target-headers-multiple-times route, (as
9294 we have already done with <elf/h8.h>) because this would become very
9295 messy and even then this function would have to contain target specific
9296 information (the names of the relocs instead of their numeric values).
9297 FIXME: This is not the correct way to solve this problem. The proper way
9298 is to have target specific reloc sizing and typing functions created by
9299 the reloc-macros.h header, in the same way that it already creates the
9300 reloc naming functions. */
9301
9302static bfd_boolean
9303is_32bit_abs_reloc (unsigned int reloc_type)
9304{
9305 switch (elf_header.e_machine)
9306 {
41e92641
NC
9307 case EM_386:
9308 case EM_486:
9309 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9310 case EM_68K:
9311 return reloc_type == 1; /* R_68K_32. */
9312 case EM_860:
9313 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9314 case EM_960:
9315 return reloc_type == 2; /* R_960_32. */
aca88567 9316 case EM_ALPHA:
137b6b5f 9317 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
9318 case EM_ARC:
9319 return reloc_type == 1; /* R_ARC_32. */
9320 case EM_ARM:
9321 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 9322 case EM_AVR_OLD:
aca88567
NC
9323 case EM_AVR:
9324 return reloc_type == 1;
9325 case EM_BLACKFIN:
9326 return reloc_type == 0x12; /* R_byte4_data. */
9327 case EM_CRIS:
9328 return reloc_type == 3; /* R_CRIS_32. */
9329 case EM_CR16:
6c03b1ed 9330 case EM_CR16_OLD:
aca88567
NC
9331 return reloc_type == 3; /* R_CR16_NUM32. */
9332 case EM_CRX:
9333 return reloc_type == 15; /* R_CRX_NUM32. */
9334 case EM_CYGNUS_FRV:
9335 return reloc_type == 1;
41e92641
NC
9336 case EM_CYGNUS_D10V:
9337 case EM_D10V:
9338 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
9339 case EM_CYGNUS_D30V:
9340 case EM_D30V:
9341 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
9342 case EM_DLX:
9343 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
9344 case EM_CYGNUS_FR30:
9345 case EM_FR30:
9346 return reloc_type == 3; /* R_FR30_32. */
9347 case EM_H8S:
9348 case EM_H8_300:
9349 case EM_H8_300H:
9350 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
9351 case EM_IA_64:
9352 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
9353 case EM_IP2K_OLD:
9354 case EM_IP2K:
9355 return reloc_type == 2; /* R_IP2K_32. */
9356 case EM_IQ2000:
9357 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
9358 case EM_LATTICEMICO32:
9359 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 9360 case EM_M32C_OLD:
aca88567
NC
9361 case EM_M32C:
9362 return reloc_type == 3; /* R_M32C_32. */
9363 case EM_M32R:
9364 return reloc_type == 34; /* R_M32R_32_RELA. */
9365 case EM_MCORE:
9366 return reloc_type == 1; /* R_MCORE_ADDR32. */
9367 case EM_CYGNUS_MEP:
9368 return reloc_type == 4; /* R_MEP_32. */
137b6b5f
AM
9369 case EM_MICROBLAZE:
9370 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
9371 case EM_MIPS:
9372 return reloc_type == 2; /* R_MIPS_32. */
9373 case EM_MMIX:
9374 return reloc_type == 4; /* R_MMIX_32. */
9375 case EM_CYGNUS_MN10200:
9376 case EM_MN10200:
9377 return reloc_type == 1; /* R_MN10200_32. */
9378 case EM_CYGNUS_MN10300:
9379 case EM_MN10300:
9380 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
9381 case EM_MOXIE:
9382 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
9383 case EM_MSP430_OLD:
9384 case EM_MSP430:
9385 return reloc_type == 1; /* R_MSP43_32. */
9386 case EM_MT:
9387 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
9388 case EM_ALTERA_NIOS2:
9389 case EM_NIOS32:
9390 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
9391 case EM_OPENRISC:
9392 case EM_OR32:
9393 return reloc_type == 1; /* R_OR32_32. */
aca88567 9394 case EM_PARISC:
5fda8eca
NC
9395 return (reloc_type == 1 /* R_PARISC_DIR32. */
9396 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
9397 case EM_PJ:
9398 case EM_PJ_OLD:
9399 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
9400 case EM_PPC64:
9401 return reloc_type == 1; /* R_PPC64_ADDR32. */
9402 case EM_PPC:
9403 return reloc_type == 1; /* R_PPC_ADDR32. */
c7927a3c
NC
9404 case EM_RX:
9405 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
9406 case EM_S370:
9407 return reloc_type == 1; /* R_I370_ADDR31. */
9408 case EM_S390_OLD:
9409 case EM_S390:
9410 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
9411 case EM_SCORE:
9412 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
9413 case EM_SH:
9414 return reloc_type == 1; /* R_SH_DIR32. */
9415 case EM_SPARC32PLUS:
9416 case EM_SPARCV9:
9417 case EM_SPARC:
9418 return reloc_type == 3 /* R_SPARC_32. */
9419 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
9420 case EM_SPU:
9421 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
9422 case EM_TI_C6000:
9423 return reloc_type == 1; /* R_C6000_ABS32. */
aca88567
NC
9424 case EM_CYGNUS_V850:
9425 case EM_V850:
9426 return reloc_type == 6; /* R_V850_ABS32. */
9427 case EM_VAX:
9428 return reloc_type == 1; /* R_VAX_32. */
9429 case EM_X86_64:
8a9036a4 9430 case EM_L1OM:
aca88567 9431 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
9432 case EM_XC16X:
9433 case EM_C166:
9434 return reloc_type == 3; /* R_XC16C_ABS_32. */
aca88567
NC
9435 case EM_XSTORMY16:
9436 return reloc_type == 1; /* R_XSTROMY16_32. */
9437 case EM_XTENSA_OLD:
9438 case EM_XTENSA:
9439 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
9440 default:
9441 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
9442 elf_header.e_machine);
9443 abort ();
9444 }
9445}
9446
9447/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9448 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
9449
9450static bfd_boolean
9451is_32bit_pcrel_reloc (unsigned int reloc_type)
9452{
9453 switch (elf_header.e_machine)
9454 {
41e92641
NC
9455 case EM_386:
9456 case EM_486:
3e0873ac 9457 return reloc_type == 2; /* R_386_PC32. */
aca88567 9458 case EM_68K:
3e0873ac 9459 return reloc_type == 4; /* R_68K_PC32. */
aca88567
NC
9460 case EM_ALPHA:
9461 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 9462 case EM_ARM:
3e0873ac 9463 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
9464 case EM_MICROBLAZE:
9465 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 9466 case EM_PARISC:
85acf597 9467 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
9468 case EM_PPC:
9469 return reloc_type == 26; /* R_PPC_REL32. */
9470 case EM_PPC64:
3e0873ac 9471 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
9472 case EM_S390_OLD:
9473 case EM_S390:
3e0873ac 9474 return reloc_type == 5; /* R_390_PC32. */
aca88567 9475 case EM_SH:
3e0873ac 9476 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
9477 case EM_SPARC32PLUS:
9478 case EM_SPARCV9:
9479 case EM_SPARC:
3e0873ac 9480 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
9481 case EM_SPU:
9482 return reloc_type == 13; /* R_SPU_REL32. */
aca88567 9483 case EM_X86_64:
8a9036a4 9484 case EM_L1OM:
3e0873ac 9485 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
9486 case EM_XTENSA_OLD:
9487 case EM_XTENSA:
9488 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
9489 default:
9490 /* Do not abort or issue an error message here. Not all targets use
9491 pc-relative 32-bit relocs in their DWARF debug information and we
9492 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
9493 more helpful warning message will be generated by apply_relocations
9494 anyway, so just return. */
aca88567
NC
9495 return FALSE;
9496 }
9497}
9498
9499/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9500 a 64-bit absolute RELA relocation used in DWARF debug sections. */
9501
9502static bfd_boolean
9503is_64bit_abs_reloc (unsigned int reloc_type)
9504{
9505 switch (elf_header.e_machine)
9506 {
9507 case EM_ALPHA:
9508 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
9509 case EM_IA_64:
9510 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
9511 case EM_PARISC:
9512 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
9513 case EM_PPC64:
9514 return reloc_type == 38; /* R_PPC64_ADDR64. */
9515 case EM_SPARC32PLUS:
9516 case EM_SPARCV9:
9517 case EM_SPARC:
9518 return reloc_type == 54; /* R_SPARC_UA64. */
9519 case EM_X86_64:
8a9036a4 9520 case EM_L1OM:
aca88567 9521 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
9522 case EM_S390_OLD:
9523 case EM_S390:
9524 return reloc_type == 22; /* R_S390_64 */
85a82265
AM
9525 case EM_MIPS:
9526 return reloc_type == 18; /* R_MIPS_64 */
aca88567
NC
9527 default:
9528 return FALSE;
9529 }
9530}
9531
85acf597
RH
9532/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
9533 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
9534
9535static bfd_boolean
9536is_64bit_pcrel_reloc (unsigned int reloc_type)
9537{
9538 switch (elf_header.e_machine)
9539 {
9540 case EM_ALPHA:
9541 return reloc_type == 11; /* R_ALPHA_SREL64 */
9542 case EM_IA_64:
9543 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB */
9544 case EM_PARISC:
9545 return reloc_type == 72; /* R_PARISC_PCREL64 */
9546 case EM_PPC64:
9547 return reloc_type == 44; /* R_PPC64_REL64 */
9548 case EM_SPARC32PLUS:
9549 case EM_SPARCV9:
9550 case EM_SPARC:
9551 return reloc_type == 46; /* R_SPARC_DISP64 */
9552 case EM_X86_64:
8a9036a4 9553 case EM_L1OM:
85acf597
RH
9554 return reloc_type == 24; /* R_X86_64_PC64 */
9555 case EM_S390_OLD:
9556 case EM_S390:
9557 return reloc_type == 23; /* R_S390_PC64 */
9558 default:
9559 return FALSE;
9560 }
9561}
9562
4dc3c23d
AM
9563/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9564 a 24-bit absolute RELA relocation used in DWARF debug sections. */
9565
9566static bfd_boolean
9567is_24bit_abs_reloc (unsigned int reloc_type)
9568{
9569 switch (elf_header.e_machine)
9570 {
9571 case EM_CYGNUS_MN10200:
9572 case EM_MN10200:
9573 return reloc_type == 4; /* R_MN10200_24. */
9574 default:
9575 return FALSE;
9576 }
9577}
9578
aca88567
NC
9579/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9580 a 16-bit absolute RELA relocation used in DWARF debug sections. */
9581
9582static bfd_boolean
9583is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
9584{
9585 switch (elf_header.e_machine)
9586 {
aca88567
NC
9587 case EM_AVR_OLD:
9588 case EM_AVR:
9589 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
9590 case EM_CYGNUS_D10V:
9591 case EM_D10V:
9592 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
9593 case EM_H8S:
9594 case EM_H8_300:
9595 case EM_H8_300H:
aca88567
NC
9596 return reloc_type == R_H8_DIR16;
9597 case EM_IP2K_OLD:
9598 case EM_IP2K:
9599 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 9600 case EM_M32C_OLD:
f4236fe4
DD
9601 case EM_M32C:
9602 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
9603 case EM_MSP430_OLD:
9604 case EM_MSP430:
9605 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
9606 case EM_ALTERA_NIOS2:
9607 case EM_NIOS32:
9608 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
9609 case EM_TI_C6000:
9610 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
9611 case EM_XC16X:
9612 case EM_C166:
9613 return reloc_type == 2; /* R_XC16C_ABS_16. */
4b78141a 9614 default:
aca88567 9615 return FALSE;
4b78141a
NC
9616 }
9617}
9618
2a7b2e88
JK
9619/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
9620 relocation entries (possibly formerly used for SHT_GROUP sections). */
9621
9622static bfd_boolean
9623is_none_reloc (unsigned int reloc_type)
9624{
9625 switch (elf_header.e_machine)
9626 {
cb8f3167
NC
9627 case EM_68K: /* R_68K_NONE. */
9628 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
9629 case EM_SPARC32PLUS:
9630 case EM_SPARCV9:
cb8f3167
NC
9631 case EM_SPARC: /* R_SPARC_NONE. */
9632 case EM_MIPS: /* R_MIPS_NONE. */
9633 case EM_PARISC: /* R_PARISC_NONE. */
9634 case EM_ALPHA: /* R_ALPHA_NONE. */
9635 case EM_PPC: /* R_PPC_NONE. */
9636 case EM_PPC64: /* R_PPC64_NONE. */
9637 case EM_ARM: /* R_ARM_NONE. */
9638 case EM_IA_64: /* R_IA64_NONE. */
9639 case EM_SH: /* R_SH_NONE. */
2a7b2e88 9640 case EM_S390_OLD:
cb8f3167
NC
9641 case EM_S390: /* R_390_NONE. */
9642 case EM_CRIS: /* R_CRIS_NONE. */
9643 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 9644 case EM_L1OM: /* R_X86_64_NONE. */
cb8f3167 9645 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 9646 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 9647 case EM_M32R: /* R_M32R_NONE. */
40b36596 9648 case EM_TI_C6000:/* R_C6000_NONE. */
c29aca4a
NC
9649 case EM_XC16X:
9650 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 9651 return reloc_type == 0;
58332dda
JK
9652 case EM_XTENSA_OLD:
9653 case EM_XTENSA:
4dc3c23d
AM
9654 return (reloc_type == 0 /* R_XTENSA_NONE. */
9655 || reloc_type == 17 /* R_XTENSA_DIFF8. */
9656 || reloc_type == 18 /* R_XTENSA_DIFF16. */
9657 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
9658 }
9659 return FALSE;
9660}
9661
cf13d699
NC
9662/* Apply relocations to a section.
9663 Note: So far support has been added only for those relocations
9664 which can be found in debug sections.
9665 FIXME: Add support for more relocations ? */
1b315056 9666
cf13d699
NC
9667static void
9668apply_relocations (void * file,
9669 Elf_Internal_Shdr * section,
9670 unsigned char * start)
1b315056 9671{
cf13d699
NC
9672 Elf_Internal_Shdr * relsec;
9673 unsigned char * end = start + section->sh_size;
cb8f3167 9674
cf13d699
NC
9675 if (elf_header.e_type != ET_REL)
9676 return;
1b315056 9677
cf13d699 9678 /* Find the reloc section associated with the section. */
5b18a4bc
NC
9679 for (relsec = section_headers;
9680 relsec < section_headers + elf_header.e_shnum;
9681 ++relsec)
252b5132 9682 {
41e92641
NC
9683 bfd_boolean is_rela;
9684 unsigned long num_relocs;
2cf0635d
NC
9685 Elf_Internal_Rela * relocs;
9686 Elf_Internal_Rela * rp;
9687 Elf_Internal_Shdr * symsec;
9688 Elf_Internal_Sym * symtab;
9689 Elf_Internal_Sym * sym;
252b5132 9690
41e92641 9691 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
9692 || relsec->sh_info >= elf_header.e_shnum
9693 || section_headers + relsec->sh_info != section
c256ffe7 9694 || relsec->sh_size == 0
4fbb74a6 9695 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 9696 continue;
428409d5 9697
41e92641
NC
9698 is_rela = relsec->sh_type == SHT_RELA;
9699
9700 if (is_rela)
9701 {
3f5e193b
NC
9702 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
9703 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
9704 return;
9705 }
9706 else
9707 {
3f5e193b
NC
9708 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
9709 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
9710 return;
9711 }
9712
9713 /* SH uses RELA but uses in place value instead of the addend field. */
9714 if (elf_header.e_machine == EM_SH)
9715 is_rela = FALSE;
428409d5 9716
4fbb74a6 9717 symsec = section_headers + relsec->sh_link;
3f5e193b 9718 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
103f02d3 9719
41e92641 9720 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 9721 {
41e92641
NC
9722 bfd_vma addend;
9723 unsigned int reloc_type;
9724 unsigned int reloc_size;
91d6fa6a 9725 unsigned char * rloc;
4b78141a 9726
aca88567 9727 reloc_type = get_reloc_type (rp->r_info);
41e92641 9728
98fb390a 9729 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 9730 continue;
98fb390a
NC
9731 else if (is_none_reloc (reloc_type))
9732 continue;
9733 else if (is_32bit_abs_reloc (reloc_type)
9734 || is_32bit_pcrel_reloc (reloc_type))
aca88567 9735 reloc_size = 4;
85acf597
RH
9736 else if (is_64bit_abs_reloc (reloc_type)
9737 || is_64bit_pcrel_reloc (reloc_type))
aca88567 9738 reloc_size = 8;
4dc3c23d
AM
9739 else if (is_24bit_abs_reloc (reloc_type))
9740 reloc_size = 3;
aca88567
NC
9741 else if (is_16bit_abs_reloc (reloc_type))
9742 reloc_size = 2;
9743 else
4b78141a 9744 {
41e92641 9745 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 9746 reloc_type, SECTION_NAME (section));
4b78141a
NC
9747 continue;
9748 }
103f02d3 9749
91d6fa6a
NC
9750 rloc = start + rp->r_offset;
9751 if ((rloc + reloc_size) > end)
700dd8b7
L
9752 {
9753 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
9754 (unsigned long) rp->r_offset,
9755 SECTION_NAME (section));
9756 continue;
9757 }
103f02d3 9758
41e92641
NC
9759 sym = symtab + get_reloc_symindex (rp->r_info);
9760
9761 /* If the reloc has a symbol associated with it,
55f25fc3
L
9762 make sure that it is of an appropriate type.
9763
9764 Relocations against symbols without type can happen.
9765 Gcc -feliminate-dwarf2-dups may generate symbols
9766 without type for debug info.
9767
9768 Icc generates relocations against function symbols
9769 instead of local labels.
9770
9771 Relocations against object symbols can happen, eg when
9772 referencing a global array. For an example of this see
9773 the _clz.o binary in libgcc.a. */
aca88567 9774 if (sym != symtab
55f25fc3 9775 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 9776 {
41e92641 9777 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 9778 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 9779 (long int)(rp - relocs),
41e92641 9780 SECTION_NAME (relsec));
aca88567 9781 continue;
5b18a4bc 9782 }
252b5132 9783
4dc3c23d
AM
9784 addend = 0;
9785 if (is_rela)
9786 addend += rp->r_addend;
c47320c3
AM
9787 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
9788 partial_inplace. */
4dc3c23d
AM
9789 if (!is_rela
9790 || (elf_header.e_machine == EM_XTENSA
9791 && reloc_type == 1)
9792 || ((elf_header.e_machine == EM_PJ
9793 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
9794 && reloc_type == 1)
9795 || ((elf_header.e_machine == EM_D30V
9796 || elf_header.e_machine == EM_CYGNUS_D30V)
9797 && reloc_type == 12))
91d6fa6a 9798 addend += byte_get (rloc, reloc_size);
cb8f3167 9799
85acf597
RH
9800 if (is_32bit_pcrel_reloc (reloc_type)
9801 || is_64bit_pcrel_reloc (reloc_type))
9802 {
9803 /* On HPPA, all pc-relative relocations are biased by 8. */
9804 if (elf_header.e_machine == EM_PARISC)
9805 addend -= 8;
91d6fa6a 9806 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
9807 reloc_size);
9808 }
41e92641 9809 else
91d6fa6a 9810 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 9811 }
252b5132 9812
5b18a4bc 9813 free (symtab);
41e92641 9814 free (relocs);
5b18a4bc
NC
9815 break;
9816 }
5b18a4bc 9817}
103f02d3 9818
cf13d699
NC
9819#ifdef SUPPORT_DISASSEMBLY
9820static int
9821disassemble_section (Elf_Internal_Shdr * section, FILE * file)
9822{
9823 printf (_("\nAssembly dump of section %s\n"),
9824 SECTION_NAME (section));
9825
9826 /* XXX -- to be done --- XXX */
9827
9828 return 1;
9829}
9830#endif
9831
9832/* Reads in the contents of SECTION from FILE, returning a pointer
9833 to a malloc'ed buffer or NULL if something went wrong. */
9834
9835static char *
9836get_section_contents (Elf_Internal_Shdr * section, FILE * file)
9837{
9838 bfd_size_type num_bytes;
9839
9840 num_bytes = section->sh_size;
9841
9842 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
9843 {
9844 printf (_("\nSection '%s' has no data to dump.\n"),
9845 SECTION_NAME (section));
9846 return NULL;
9847 }
9848
3f5e193b
NC
9849 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
9850 _("section contents"));
cf13d699
NC
9851}
9852
dd24e3da 9853
cf13d699
NC
9854static void
9855dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
9856{
9857 Elf_Internal_Shdr * relsec;
9858 bfd_size_type num_bytes;
cf13d699
NC
9859 char * data;
9860 char * end;
9861 char * start;
9862 char * name = SECTION_NAME (section);
9863 bfd_boolean some_strings_shown;
9864
9865 start = get_section_contents (section, file);
9866 if (start == NULL)
9867 return;
9868
9869 printf (_("\nString dump of section '%s':\n"), name);
9870
9871 /* If the section being dumped has relocations against it the user might
9872 be expecting these relocations to have been applied. Check for this
9873 case and issue a warning message in order to avoid confusion.
9874 FIXME: Maybe we ought to have an option that dumps a section with
9875 relocs applied ? */
9876 for (relsec = section_headers;
9877 relsec < section_headers + elf_header.e_shnum;
9878 ++relsec)
9879 {
9880 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
9881 || relsec->sh_info >= elf_header.e_shnum
9882 || section_headers + relsec->sh_info != section
9883 || relsec->sh_size == 0
9884 || relsec->sh_link >= elf_header.e_shnum)
9885 continue;
9886
9887 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
9888 break;
9889 }
9890
9891 num_bytes = section->sh_size;
cf13d699
NC
9892 data = start;
9893 end = start + num_bytes;
9894 some_strings_shown = FALSE;
9895
9896 while (data < end)
9897 {
9898 while (!ISPRINT (* data))
9899 if (++ data >= end)
9900 break;
9901
9902 if (data < end)
9903 {
9904#ifndef __MSVCRT__
c975cc98
NC
9905 /* PR 11128: Use two separate invocations in order to work
9906 around bugs in the Solaris 8 implementation of printf. */
9907 printf (" [%6tx] ", data - start);
9908 printf ("%s\n", data);
cf13d699
NC
9909#else
9910 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
9911#endif
9912 data += strlen (data);
9913 some_strings_shown = TRUE;
9914 }
9915 }
9916
9917 if (! some_strings_shown)
9918 printf (_(" No strings found in this section."));
9919
9920 free (start);
9921
9922 putchar ('\n');
9923}
9924
9925static void
9926dump_section_as_bytes (Elf_Internal_Shdr * section,
9927 FILE * file,
9928 bfd_boolean relocate)
9929{
9930 Elf_Internal_Shdr * relsec;
9931 bfd_size_type bytes;
9932 bfd_vma addr;
9933 unsigned char * data;
9934 unsigned char * start;
9935
9936 start = (unsigned char *) get_section_contents (section, file);
9937 if (start == NULL)
9938 return;
9939
9940 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
9941
9942 if (relocate)
9943 {
9944 apply_relocations (file, section, start);
9945 }
9946 else
9947 {
9948 /* If the section being dumped has relocations against it the user might
9949 be expecting these relocations to have been applied. Check for this
9950 case and issue a warning message in order to avoid confusion.
9951 FIXME: Maybe we ought to have an option that dumps a section with
9952 relocs applied ? */
9953 for (relsec = section_headers;
9954 relsec < section_headers + elf_header.e_shnum;
9955 ++relsec)
9956 {
9957 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
9958 || relsec->sh_info >= elf_header.e_shnum
9959 || section_headers + relsec->sh_info != section
9960 || relsec->sh_size == 0
9961 || relsec->sh_link >= elf_header.e_shnum)
9962 continue;
9963
9964 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
9965 break;
9966 }
9967 }
9968
9969 addr = section->sh_addr;
9970 bytes = section->sh_size;
9971 data = start;
9972
9973 while (bytes)
9974 {
9975 int j;
9976 int k;
9977 int lbytes;
9978
9979 lbytes = (bytes > 16 ? 16 : bytes);
9980
9981 printf (" 0x%8.8lx ", (unsigned long) addr);
9982
9983 for (j = 0; j < 16; j++)
9984 {
9985 if (j < lbytes)
9986 printf ("%2.2x", data[j]);
9987 else
9988 printf (" ");
9989
9990 if ((j & 3) == 3)
9991 printf (" ");
9992 }
9993
9994 for (j = 0; j < lbytes; j++)
9995 {
9996 k = data[j];
9997 if (k >= ' ' && k < 0x7f)
9998 printf ("%c", k);
9999 else
10000 printf (".");
10001 }
10002
10003 putchar ('\n');
10004
10005 data += lbytes;
10006 addr += lbytes;
10007 bytes -= lbytes;
10008 }
10009
10010 free (start);
10011
10012 putchar ('\n');
10013}
10014
4a114e3e 10015/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10016
10017static int
d3dbc530
AM
10018uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10019 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10020{
10021#ifndef HAVE_ZLIB_H
cf13d699
NC
10022 return FALSE;
10023#else
10024 dwarf_size_type compressed_size = *size;
10025 unsigned char * compressed_buffer = *buffer;
10026 dwarf_size_type uncompressed_size;
10027 unsigned char * uncompressed_buffer;
10028 z_stream strm;
10029 int rc;
10030 dwarf_size_type header_size = 12;
10031
10032 /* Read the zlib header. In this case, it should be "ZLIB" followed
10033 by the uncompressed section size, 8 bytes in big-endian order. */
10034 if (compressed_size < header_size
10035 || ! streq ((char *) compressed_buffer, "ZLIB"))
10036 return 0;
10037
10038 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10039 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10040 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10041 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10042 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10043 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10044 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10045 uncompressed_size += compressed_buffer[11];
10046
10047 /* It is possible the section consists of several compressed
10048 buffers concatenated together, so we uncompress in a loop. */
10049 strm.zalloc = NULL;
10050 strm.zfree = NULL;
10051 strm.opaque = NULL;
10052 strm.avail_in = compressed_size - header_size;
10053 strm.next_in = (Bytef *) compressed_buffer + header_size;
10054 strm.avail_out = uncompressed_size;
3f5e193b 10055 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10056
10057 rc = inflateInit (& strm);
10058 while (strm.avail_in > 0)
10059 {
10060 if (rc != Z_OK)
10061 goto fail;
10062 strm.next_out = ((Bytef *) uncompressed_buffer
10063 + (uncompressed_size - strm.avail_out));
10064 rc = inflate (&strm, Z_FINISH);
10065 if (rc != Z_STREAM_END)
10066 goto fail;
10067 rc = inflateReset (& strm);
10068 }
10069 rc = inflateEnd (& strm);
10070 if (rc != Z_OK
10071 || strm.avail_out != 0)
10072 goto fail;
10073
10074 free (compressed_buffer);
10075 *buffer = uncompressed_buffer;
10076 *size = uncompressed_size;
10077 return 1;
10078
10079 fail:
10080 free (uncompressed_buffer);
4a114e3e
L
10081 /* Indicate decompression failure. */
10082 *buffer = NULL;
cf13d699
NC
10083 return 0;
10084#endif /* HAVE_ZLIB_H */
10085}
10086
d966045b
DJ
10087static int
10088load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10089 Elf_Internal_Shdr * sec, void * file)
1007acb3 10090{
2cf0635d 10091 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10092 char buf [64];
1007acb3 10093
19e6b90e
L
10094 /* If it is already loaded, do nothing. */
10095 if (section->start != NULL)
10096 return 1;
1007acb3 10097
19e6b90e
L
10098 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10099 section->address = sec->sh_addr;
10100 section->size = sec->sh_size;
3f5e193b
NC
10101 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10102 sec->sh_offset, 1,
10103 sec->sh_size, buf);
4a114e3e
L
10104 if (uncompress_section_contents (&section->start, &section->size))
10105 sec->sh_size = section->size;
10106
1b315056
CS
10107 if (section->start == NULL)
10108 return 0;
10109
19e6b90e 10110 if (debug_displays [debug].relocate)
3f5e193b 10111 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10112
1b315056 10113 return 1;
1007acb3
L
10114}
10115
d966045b 10116int
2cf0635d 10117load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10118{
2cf0635d
NC
10119 struct dwarf_section * section = &debug_displays [debug].section;
10120 Elf_Internal_Shdr * sec;
d966045b
DJ
10121
10122 /* Locate the debug section. */
10123 sec = find_section (section->uncompressed_name);
10124 if (sec != NULL)
10125 section->name = section->uncompressed_name;
10126 else
10127 {
10128 sec = find_section (section->compressed_name);
10129 if (sec != NULL)
10130 section->name = section->compressed_name;
10131 }
10132 if (sec == NULL)
10133 return 0;
10134
3f5e193b 10135 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10136}
10137
19e6b90e
L
10138void
10139free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10140{
2cf0635d 10141 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10142
19e6b90e
L
10143 if (section->start == NULL)
10144 return;
1007acb3 10145
19e6b90e
L
10146 free ((char *) section->start);
10147 section->start = NULL;
10148 section->address = 0;
10149 section->size = 0;
1007acb3
L
10150}
10151
1007acb3 10152static int
2cf0635d 10153display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 10154{
2cf0635d 10155 char * name = SECTION_NAME (section);
19e6b90e
L
10156 bfd_size_type length;
10157 int result = 1;
3f5e193b 10158 int i;
1007acb3 10159
19e6b90e
L
10160 length = section->sh_size;
10161 if (length == 0)
1007acb3 10162 {
19e6b90e
L
10163 printf (_("\nSection '%s' has no debugging data.\n"), name);
10164 return 0;
1007acb3 10165 }
5dff79d8
NC
10166 if (section->sh_type == SHT_NOBITS)
10167 {
10168 /* There is no point in dumping the contents of a debugging section
10169 which has the NOBITS type - the bits in the file will be random.
10170 This can happen when a file containing a .eh_frame section is
10171 stripped with the --only-keep-debug command line option. */
10172 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10173 return 0;
10174 }
1007acb3 10175
0112cd26 10176 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10177 name = ".debug_info";
1007acb3 10178
19e6b90e
L
10179 /* See if we know how to display the contents of this section. */
10180 for (i = 0; i < max; i++)
1b315056
CS
10181 if (streq (debug_displays[i].section.uncompressed_name, name)
10182 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10183 {
2cf0635d 10184 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10185 int secondary = (section != find_section (name));
10186
10187 if (secondary)
3f5e193b 10188 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10189
2b6f5997 10190 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10191 sec->name = sec->uncompressed_name;
10192 else
10193 sec->name = sec->compressed_name;
3f5e193b
NC
10194 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10195 section, file))
19e6b90e
L
10196 {
10197 result &= debug_displays[i].display (sec, file);
1007acb3 10198
d966045b 10199 if (secondary || (i != info && i != abbrev))
3f5e193b 10200 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10201 }
1007acb3 10202
19e6b90e
L
10203 break;
10204 }
1007acb3 10205
19e6b90e 10206 if (i == max)
1007acb3 10207 {
19e6b90e
L
10208 printf (_("Unrecognized debug section: %s\n"), name);
10209 result = 0;
1007acb3
L
10210 }
10211
19e6b90e 10212 return result;
5b18a4bc 10213}
103f02d3 10214
aef1f6d0
DJ
10215/* Set DUMP_SECTS for all sections where dumps were requested
10216 based on section name. */
10217
10218static void
10219initialise_dumps_byname (void)
10220{
2cf0635d 10221 struct dump_list_entry * cur;
aef1f6d0
DJ
10222
10223 for (cur = dump_sects_byname; cur; cur = cur->next)
10224 {
10225 unsigned int i;
10226 int any;
10227
10228 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10229 if (streq (SECTION_NAME (section_headers + i), cur->name))
10230 {
09c11c86 10231 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10232 any = 1;
10233 }
10234
10235 if (!any)
10236 warn (_("Section '%s' was not dumped because it does not exist!\n"),
10237 cur->name);
10238 }
10239}
10240
5b18a4bc 10241static void
2cf0635d 10242process_section_contents (FILE * file)
5b18a4bc 10243{
2cf0635d 10244 Elf_Internal_Shdr * section;
19e6b90e 10245 unsigned int i;
103f02d3 10246
19e6b90e
L
10247 if (! do_dump)
10248 return;
103f02d3 10249
aef1f6d0
DJ
10250 initialise_dumps_byname ();
10251
19e6b90e
L
10252 for (i = 0, section = section_headers;
10253 i < elf_header.e_shnum && i < num_dump_sects;
10254 i++, section++)
10255 {
10256#ifdef SUPPORT_DISASSEMBLY
10257 if (dump_sects[i] & DISASS_DUMP)
10258 disassemble_section (section, file);
10259#endif
10260 if (dump_sects[i] & HEX_DUMP)
cf13d699 10261 dump_section_as_bytes (section, file, FALSE);
103f02d3 10262
cf13d699
NC
10263 if (dump_sects[i] & RELOC_DUMP)
10264 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
10265
10266 if (dump_sects[i] & STRING_DUMP)
10267 dump_section_as_strings (section, file);
cf13d699
NC
10268
10269 if (dump_sects[i] & DEBUG_DUMP)
10270 display_debug_section (section, file);
5b18a4bc 10271 }
103f02d3 10272
19e6b90e
L
10273 /* Check to see if the user requested a
10274 dump of a section that does not exist. */
10275 while (i++ < num_dump_sects)
10276 if (dump_sects[i])
10277 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 10278}
103f02d3 10279
5b18a4bc 10280static void
19e6b90e 10281process_mips_fpe_exception (int mask)
5b18a4bc 10282{
19e6b90e
L
10283 if (mask)
10284 {
10285 int first = 1;
10286 if (mask & OEX_FPU_INEX)
10287 fputs ("INEX", stdout), first = 0;
10288 if (mask & OEX_FPU_UFLO)
10289 printf ("%sUFLO", first ? "" : "|"), first = 0;
10290 if (mask & OEX_FPU_OFLO)
10291 printf ("%sOFLO", first ? "" : "|"), first = 0;
10292 if (mask & OEX_FPU_DIV0)
10293 printf ("%sDIV0", first ? "" : "|"), first = 0;
10294 if (mask & OEX_FPU_INVAL)
10295 printf ("%sINVAL", first ? "" : "|");
10296 }
5b18a4bc 10297 else
19e6b90e 10298 fputs ("0", stdout);
5b18a4bc 10299}
103f02d3 10300
11c1ff18
PB
10301/* ARM EABI attributes section. */
10302typedef struct
10303{
10304 int tag;
2cf0635d 10305 const char * name;
11c1ff18
PB
10306 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
10307 int type;
2cf0635d 10308 const char ** table;
11c1ff18
PB
10309} arm_attr_public_tag;
10310
2cf0635d 10311static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 10312 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
9e3c6df6 10313 "v6K", "v7", "v6-M", "v6S-M", "v7E-M"};
2cf0635d
NC
10314static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
10315static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 10316 {"No", "Thumb-1", "Thumb-2"};
75375b3e 10317static const char * arm_attr_tag_FP_arch[] =
62f3b8c8 10318 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
2cf0635d 10319static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 10320static const char * arm_attr_tag_Advanced_SIMD_arch[] =
cd21e546 10321 {"No", "NEONv1", "NEONv1 with Fused-MAC"};
2cf0635d 10322static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
10323 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
10324 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 10325static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 10326 {"V6", "SB", "TLS", "Unused"};
2cf0635d 10327static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 10328 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 10329static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 10330 {"Absolute", "PC-relative", "None"};
2cf0635d 10331static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 10332 {"None", "direct", "GOT-indirect"};
2cf0635d 10333static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 10334 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
10335static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
10336static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 10337 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
10338static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
10339static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
10340static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 10341 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 10342static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 10343 {"Unused", "small", "int", "forced to int"};
2cf0635d 10344static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 10345 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 10346static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 10347 {"AAPCS", "VFP registers", "custom"};
2cf0635d 10348static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 10349 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 10350static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
10351 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10352 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 10353static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
10354 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10355 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 10356static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 10357static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 10358 {"Not Allowed", "Allowed"};
2cf0635d 10359static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 10360 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 10361static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
10362 {"Not Allowed", "Allowed"};
10363static const char * arm_attr_tag_DIV_use[] =
dd24e3da 10364 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 10365 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
10366static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
10367static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 10368 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 10369 "TrustZone and Virtualization Extensions"};
dd24e3da 10370static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 10371 {"Not Allowed", "Allowed"};
11c1ff18
PB
10372
10373#define LOOKUP(id, name) \
10374 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 10375static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
10376{
10377 {4, "CPU_raw_name", 1, NULL},
10378 {5, "CPU_name", 1, NULL},
10379 LOOKUP(6, CPU_arch),
10380 {7, "CPU_arch_profile", 0, NULL},
10381 LOOKUP(8, ARM_ISA_use),
10382 LOOKUP(9, THUMB_ISA_use),
75375b3e 10383 LOOKUP(10, FP_arch),
11c1ff18 10384 LOOKUP(11, WMMX_arch),
f5f53991
AS
10385 LOOKUP(12, Advanced_SIMD_arch),
10386 LOOKUP(13, PCS_config),
11c1ff18
PB
10387 LOOKUP(14, ABI_PCS_R9_use),
10388 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 10389 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
10390 LOOKUP(17, ABI_PCS_GOT_use),
10391 LOOKUP(18, ABI_PCS_wchar_t),
10392 LOOKUP(19, ABI_FP_rounding),
10393 LOOKUP(20, ABI_FP_denormal),
10394 LOOKUP(21, ABI_FP_exceptions),
10395 LOOKUP(22, ABI_FP_user_exceptions),
10396 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
10397 {24, "ABI_align_needed", 0, NULL},
10398 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
10399 LOOKUP(26, ABI_enum_size),
10400 LOOKUP(27, ABI_HardFP_use),
10401 LOOKUP(28, ABI_VFP_args),
10402 LOOKUP(29, ABI_WMMX_args),
10403 LOOKUP(30, ABI_optimization_goals),
10404 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 10405 {32, "compatibility", 0, NULL},
f5f53991 10406 LOOKUP(34, CPU_unaligned_access),
75375b3e 10407 LOOKUP(36, FP_HP_extension),
8e79c3df 10408 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
10409 LOOKUP(42, MPextension_use),
10410 LOOKUP(44, DIV_use),
f5f53991
AS
10411 {64, "nodefaults", 0, NULL},
10412 {65, "also_compatible_with", 0, NULL},
10413 LOOKUP(66, T2EE_use),
10414 {67, "conformance", 1, NULL},
10415 LOOKUP(68, Virtualization_use),
cd21e546 10416 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
10417};
10418#undef LOOKUP
10419
11c1ff18 10420static unsigned char *
2cf0635d 10421display_arm_attribute (unsigned char * p)
11c1ff18
PB
10422{
10423 int tag;
10424 unsigned int len;
10425 int val;
2cf0635d 10426 arm_attr_public_tag * attr;
11c1ff18
PB
10427 unsigned i;
10428 int type;
10429
10430 tag = read_uleb128 (p, &len);
10431 p += len;
10432 attr = NULL;
2cf0635d 10433 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
10434 {
10435 if (arm_attr_public_tags[i].tag == tag)
10436 {
10437 attr = &arm_attr_public_tags[i];
10438 break;
10439 }
10440 }
10441
10442 if (attr)
10443 {
10444 printf (" Tag_%s: ", attr->name);
10445 switch (attr->type)
10446 {
10447 case 0:
10448 switch (tag)
10449 {
10450 case 7: /* Tag_CPU_arch_profile. */
10451 val = read_uleb128 (p, &len);
10452 p += len;
10453 switch (val)
10454 {
2b692964
NC
10455 case 0: printf (_("None\n")); break;
10456 case 'A': printf (_("Application\n")); break;
10457 case 'R': printf (_("Realtime\n")); break;
10458 case 'M': printf (_("Microcontroller\n")); break;
10459 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
10460 default: printf ("??? (%d)\n", val); break;
10461 }
10462 break;
10463
75375b3e
MGD
10464 case 24: /* Tag_align_needed. */
10465 val = read_uleb128 (p, &len);
10466 p += len;
10467 switch (val)
10468 {
2b692964
NC
10469 case 0: printf (_("None\n")); break;
10470 case 1: printf (_("8-byte\n")); break;
10471 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
10472 case 3: printf ("??? 3\n"); break;
10473 default:
10474 if (val <= 12)
dd24e3da 10475 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10476 1 << val);
10477 else
10478 printf ("??? (%d)\n", val);
10479 break;
10480 }
10481 break;
10482
10483 case 25: /* Tag_align_preserved. */
10484 val = read_uleb128 (p, &len);
10485 p += len;
10486 switch (val)
10487 {
2b692964
NC
10488 case 0: printf (_("None\n")); break;
10489 case 1: printf (_("8-byte, except leaf SP\n")); break;
10490 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
10491 case 3: printf ("??? 3\n"); break;
10492 default:
10493 if (val <= 12)
dd24e3da 10494 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10495 1 << val);
10496 else
10497 printf ("??? (%d)\n", val);
10498 break;
10499 }
10500 break;
10501
11c1ff18
PB
10502 case 32: /* Tag_compatibility. */
10503 val = read_uleb128 (p, &len);
10504 p += len;
2b692964 10505 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 10506 p += strlen ((char *) p) + 1;
11c1ff18
PB
10507 break;
10508
f5f53991
AS
10509 case 64: /* Tag_nodefaults. */
10510 p++;
2b692964 10511 printf (_("True\n"));
f5f53991
AS
10512 break;
10513
10514 case 65: /* Tag_also_compatible_with. */
10515 val = read_uleb128 (p, &len);
10516 p += len;
10517 if (val == 6 /* Tag_CPU_arch. */)
10518 {
10519 val = read_uleb128 (p, &len);
10520 p += len;
2cf0635d 10521 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
10522 printf ("??? (%d)\n", val);
10523 else
10524 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
10525 }
10526 else
10527 printf ("???\n");
10528 while (*(p++) != '\0' /* NUL terminator. */);
10529 break;
10530
11c1ff18 10531 default:
2cf0635d 10532 abort ();
11c1ff18
PB
10533 }
10534 return p;
10535
10536 case 1:
10537 case 2:
10538 type = attr->type;
10539 break;
10540
10541 default:
10542 assert (attr->type & 0x80);
10543 val = read_uleb128 (p, &len);
10544 p += len;
10545 type = attr->type & 0x7f;
10546 if (val >= type)
10547 printf ("??? (%d)\n", val);
10548 else
10549 printf ("%s\n", attr->table[val]);
10550 return p;
10551 }
10552 }
10553 else
10554 {
10555 if (tag & 1)
10556 type = 1; /* String. */
10557 else
10558 type = 2; /* uleb128. */
10559 printf (" Tag_unknown_%d: ", tag);
10560 }
10561
10562 if (type == 1)
10563 {
10564 printf ("\"%s\"\n", p);
2cf0635d 10565 p += strlen ((char *) p) + 1;
11c1ff18
PB
10566 }
10567 else
10568 {
10569 val = read_uleb128 (p, &len);
10570 p += len;
10571 printf ("%d (0x%x)\n", val, val);
10572 }
10573
10574 return p;
10575}
10576
104d59d1 10577static unsigned char *
60bca95a
NC
10578display_gnu_attribute (unsigned char * p,
10579 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
10580{
10581 int tag;
10582 unsigned int len;
10583 int val;
10584 int type;
10585
10586 tag = read_uleb128 (p, &len);
10587 p += len;
10588
10589 /* Tag_compatibility is the only generic GNU attribute defined at
10590 present. */
10591 if (tag == 32)
10592 {
10593 val = read_uleb128 (p, &len);
10594 p += len;
2b692964 10595 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 10596 p += strlen ((char *) p) + 1;
104d59d1
JM
10597 return p;
10598 }
10599
10600 if ((tag & 2) == 0 && display_proc_gnu_attribute)
10601 return display_proc_gnu_attribute (p, tag);
10602
10603 if (tag & 1)
10604 type = 1; /* String. */
10605 else
10606 type = 2; /* uleb128. */
10607 printf (" Tag_unknown_%d: ", tag);
10608
10609 if (type == 1)
10610 {
10611 printf ("\"%s\"\n", p);
60bca95a 10612 p += strlen ((char *) p) + 1;
104d59d1
JM
10613 }
10614 else
10615 {
10616 val = read_uleb128 (p, &len);
10617 p += len;
10618 printf ("%d (0x%x)\n", val, val);
10619 }
10620
10621 return p;
10622}
10623
34c8bcba 10624static unsigned char *
2cf0635d 10625display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
10626{
10627 int type;
10628 unsigned int len;
10629 int val;
10630
10631 if (tag == Tag_GNU_Power_ABI_FP)
10632 {
10633 val = read_uleb128 (p, &len);
10634 p += len;
10635 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 10636
34c8bcba
JM
10637 switch (val)
10638 {
10639 case 0:
2b692964 10640 printf (_("Hard or soft float\n"));
34c8bcba
JM
10641 break;
10642 case 1:
2b692964 10643 printf (_("Hard float\n"));
34c8bcba
JM
10644 break;
10645 case 2:
2b692964 10646 printf (_("Soft float\n"));
34c8bcba 10647 break;
3c7b9897 10648 case 3:
2b692964 10649 printf (_("Single-precision hard float\n"));
3c7b9897 10650 break;
34c8bcba
JM
10651 default:
10652 printf ("??? (%d)\n", val);
10653 break;
10654 }
10655 return p;
10656 }
10657
c6e65352
DJ
10658 if (tag == Tag_GNU_Power_ABI_Vector)
10659 {
10660 val = read_uleb128 (p, &len);
10661 p += len;
10662 printf (" Tag_GNU_Power_ABI_Vector: ");
10663 switch (val)
10664 {
10665 case 0:
2b692964 10666 printf (_("Any\n"));
c6e65352
DJ
10667 break;
10668 case 1:
2b692964 10669 printf (_("Generic\n"));
c6e65352
DJ
10670 break;
10671 case 2:
10672 printf ("AltiVec\n");
10673 break;
10674 case 3:
10675 printf ("SPE\n");
10676 break;
10677 default:
10678 printf ("??? (%d)\n", val);
10679 break;
10680 }
10681 return p;
10682 }
10683
f82e0623
NF
10684 if (tag == Tag_GNU_Power_ABI_Struct_Return)
10685 {
10686 val = read_uleb128 (p, &len);
10687 p += len;
10688 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
10689 switch (val)
10690 {
10691 case 0:
2b692964 10692 printf (_("Any\n"));
f82e0623
NF
10693 break;
10694 case 1:
10695 printf ("r3/r4\n");
10696 break;
10697 case 2:
2b692964 10698 printf (_("Memory\n"));
f82e0623
NF
10699 break;
10700 default:
10701 printf ("??? (%d)\n", val);
10702 break;
10703 }
10704 return p;
10705 }
10706
34c8bcba
JM
10707 if (tag & 1)
10708 type = 1; /* String. */
10709 else
10710 type = 2; /* uleb128. */
10711 printf (" Tag_unknown_%d: ", tag);
10712
10713 if (type == 1)
10714 {
10715 printf ("\"%s\"\n", p);
60bca95a 10716 p += strlen ((char *) p) + 1;
34c8bcba
JM
10717 }
10718 else
10719 {
10720 val = read_uleb128 (p, &len);
10721 p += len;
10722 printf ("%d (0x%x)\n", val, val);
10723 }
10724
10725 return p;
10726}
10727
2cf19d5c 10728static unsigned char *
2cf0635d 10729display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
10730{
10731 int type;
10732 unsigned int len;
10733 int val;
10734
10735 if (tag == Tag_GNU_MIPS_ABI_FP)
10736 {
10737 val = read_uleb128 (p, &len);
10738 p += len;
10739 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 10740
2cf19d5c
JM
10741 switch (val)
10742 {
10743 case 0:
2b692964 10744 printf (_("Hard or soft float\n"));
2cf19d5c
JM
10745 break;
10746 case 1:
2b692964 10747 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
10748 break;
10749 case 2:
2b692964 10750 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
10751 break;
10752 case 3:
2b692964 10753 printf (_("Soft float\n"));
2cf19d5c 10754 break;
42554f6a 10755 case 4:
9eeefea8 10756 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 10757 break;
2cf19d5c
JM
10758 default:
10759 printf ("??? (%d)\n", val);
10760 break;
10761 }
10762 return p;
10763 }
10764
10765 if (tag & 1)
10766 type = 1; /* String. */
10767 else
10768 type = 2; /* uleb128. */
10769 printf (" Tag_unknown_%d: ", tag);
10770
10771 if (type == 1)
10772 {
10773 printf ("\"%s\"\n", p);
60bca95a 10774 p += strlen ((char *) p) + 1;
2cf19d5c
JM
10775 }
10776 else
10777 {
10778 val = read_uleb128 (p, &len);
10779 p += len;
10780 printf ("%d (0x%x)\n", val, val);
10781 }
10782
10783 return p;
10784}
10785
59e6276b
JM
10786static unsigned char *
10787display_tic6x_attribute (unsigned char * p)
10788{
10789 int tag;
10790 unsigned int len;
10791 int val;
10792
10793 tag = read_uleb128 (p, &len);
10794 p += len;
10795
10796 switch (tag)
10797 {
75fa6dc1 10798 case Tag_ISA:
59e6276b
JM
10799 val = read_uleb128 (p, &len);
10800 p += len;
75fa6dc1 10801 printf (" Tag_ISA: ");
59e6276b
JM
10802
10803 switch (val)
10804 {
75fa6dc1 10805 case C6XABI_Tag_ISA_none:
59e6276b
JM
10806 printf (_("None\n"));
10807 break;
75fa6dc1 10808 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
10809 printf ("C62x\n");
10810 break;
75fa6dc1 10811 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
10812 printf ("C67x\n");
10813 break;
75fa6dc1 10814 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
10815 printf ("C67x+\n");
10816 break;
75fa6dc1 10817 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
10818 printf ("C64x\n");
10819 break;
75fa6dc1 10820 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
10821 printf ("C64x+\n");
10822 break;
75fa6dc1 10823 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
10824 printf ("C674x\n");
10825 break;
10826 default:
10827 printf ("??? (%d)\n", val);
10828 break;
10829 }
10830 return p;
10831
87779176
JM
10832 case Tag_ABI_wchar_t:
10833 val = read_uleb128 (p, &len);
10834 p += len;
10835 printf (" Tag_ABI_wchar_t: ");
10836 switch (val)
10837 {
10838 case 0:
10839 printf (_("Not used\n"));
10840 break;
10841 case 1:
10842 printf (_("2 bytes\n"));
10843 break;
10844 case 2:
10845 printf (_("4 bytes\n"));
10846 break;
10847 default:
10848 printf ("??? (%d)\n", val);
10849 break;
10850 }
10851 return p;
10852
10853 case Tag_ABI_stack_align_needed:
10854 val = read_uleb128 (p, &len);
10855 p += len;
10856 printf (" Tag_ABI_stack_align_needed: ");
10857 switch (val)
10858 {
10859 case 0:
10860 printf (_("8-byte\n"));
10861 break;
10862 case 1:
10863 printf (_("16-byte\n"));
10864 break;
10865 default:
10866 printf ("??? (%d)\n", val);
10867 break;
10868 }
10869 return p;
10870
10871 case Tag_ABI_stack_align_preserved:
10872 val = read_uleb128 (p, &len);
10873 p += len;
10874 printf (" Tag_ABI_stack_align_preserved: ");
10875 switch (val)
10876 {
10877 case 0:
10878 printf (_("8-byte\n"));
10879 break;
10880 case 1:
10881 printf (_("16-byte\n"));
10882 break;
10883 default:
10884 printf ("??? (%d)\n", val);
10885 break;
10886 }
10887 return p;
10888
b5593623
JM
10889 case Tag_ABI_DSBT:
10890 val = read_uleb128 (p, &len);
10891 p += len;
10892 printf (" Tag_ABI_DSBT: ");
10893 switch (val)
10894 {
10895 case 0:
10896 printf (_("DSBT addressing not used\n"));
10897 break;
10898 case 1:
10899 printf (_("DSBT addressing used\n"));
10900 break;
10901 default:
10902 printf ("??? (%d)\n", val);
10903 break;
10904 }
10905 return p;
10906
87779176
JM
10907 case Tag_ABI_PID:
10908 val = read_uleb128 (p, &len);
10909 p += len;
10910 printf (" Tag_ABI_PID: ");
10911 switch (val)
10912 {
10913 case 0:
10914 printf (_("Data addressing position-dependent\n"));
10915 break;
10916 case 1:
10917 printf (_("Data addressing position-independent, GOT near DP\n"));
10918 break;
10919 case 2:
10920 printf (_("Data addressing position-independent, GOT far from DP\n"));
10921 break;
10922 default:
10923 printf ("??? (%d)\n", val);
10924 break;
10925 }
10926 return p;
10927
10928 case Tag_ABI_PIC:
10929 val = read_uleb128 (p, &len);
10930 p += len;
10931 printf (" Tag_ABI_PIC: ");
10932 switch (val)
10933 {
10934 case 0:
10935 printf (_("Code addressing position-dependent\n"));
10936 break;
10937 case 1:
10938 printf (_("Code addressing position-independent\n"));
10939 break;
10940 default:
10941 printf ("??? (%d)\n", val);
10942 break;
10943 }
10944 return p;
10945
10946 case Tag_ABI_array_object_alignment:
10947 val = read_uleb128 (p, &len);
10948 p += len;
10949 printf (" Tag_ABI_array_object_alignment: ");
10950 switch (val)
10951 {
10952 case 0:
10953 printf (_("8-byte\n"));
10954 break;
10955 case 1:
10956 printf (_("4-byte\n"));
10957 break;
10958 case 2:
10959 printf (_("16-byte\n"));
10960 break;
10961 default:
10962 printf ("??? (%d)\n", val);
10963 break;
10964 }
10965 return p;
10966
10967 case Tag_ABI_array_object_align_expected:
10968 val = read_uleb128 (p, &len);
10969 p += len;
10970 printf (" Tag_ABI_array_object_align_expected: ");
10971 switch (val)
10972 {
10973 case 0:
10974 printf (_("8-byte\n"));
10975 break;
10976 case 1:
10977 printf (_("4-byte\n"));
10978 break;
10979 case 2:
10980 printf (_("16-byte\n"));
10981 break;
10982 default:
10983 printf ("??? (%d)\n", val);
10984 break;
10985 }
10986 return p;
10987
3cbd1c06 10988 case Tag_ABI_compatibility:
59e6276b
JM
10989 val = read_uleb128 (p, &len);
10990 p += len;
3cbd1c06 10991 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
10992 printf (_("flag = %d, vendor = %s\n"), val, p);
10993 p += strlen ((char *) p) + 1;
10994 return p;
87779176
JM
10995
10996 case Tag_ABI_conformance:
10997 printf (" Tag_ABI_conformance: ");
10998 printf ("\"%s\"\n", p);
10999 p += strlen ((char *) p) + 1;
11000 return p;
59e6276b
JM
11001 }
11002
11003 printf (" Tag_unknown_%d: ", tag);
11004
87779176
JM
11005 if (tag & 1)
11006 {
11007 printf ("\"%s\"\n", p);
11008 p += strlen ((char *) p) + 1;
11009 }
11010 else
11011 {
11012 val = read_uleb128 (p, &len);
11013 p += len;
11014 printf ("%d (0x%x)\n", val, val);
11015 }
59e6276b
JM
11016
11017 return p;
11018}
11019
11c1ff18 11020static int
60bca95a
NC
11021process_attributes (FILE * file,
11022 const char * public_name,
104d59d1 11023 unsigned int proc_type,
60bca95a
NC
11024 unsigned char * (* display_pub_attribute) (unsigned char *),
11025 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11026{
2cf0635d
NC
11027 Elf_Internal_Shdr * sect;
11028 unsigned char * contents;
11029 unsigned char * p;
11030 unsigned char * end;
11c1ff18
PB
11031 bfd_vma section_len;
11032 bfd_vma len;
11033 unsigned i;
11034
11035 /* Find the section header so that we get the size. */
11036 for (i = 0, sect = section_headers;
11037 i < elf_header.e_shnum;
11038 i++, sect++)
11039 {
104d59d1 11040 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11041 continue;
11042
3f5e193b
NC
11043 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11044 sect->sh_size, _("attributes"));
60bca95a 11045 if (contents == NULL)
11c1ff18 11046 continue;
60bca95a 11047
11c1ff18
PB
11048 p = contents;
11049 if (*p == 'A')
11050 {
11051 len = sect->sh_size - 1;
11052 p++;
60bca95a 11053
11c1ff18
PB
11054 while (len > 0)
11055 {
11056 int namelen;
11057 bfd_boolean public_section;
104d59d1 11058 bfd_boolean gnu_section;
11c1ff18
PB
11059
11060 section_len = byte_get (p, 4);
11061 p += 4;
60bca95a 11062
11c1ff18
PB
11063 if (section_len > len)
11064 {
11065 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11066 (int) section_len, (int) len);
11c1ff18
PB
11067 section_len = len;
11068 }
60bca95a 11069
11c1ff18 11070 len -= section_len;
2b692964 11071 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11072
11073 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11074 public_section = TRUE;
11075 else
11076 public_section = FALSE;
60bca95a
NC
11077
11078 if (streq ((char *) p, "gnu"))
104d59d1
JM
11079 gnu_section = TRUE;
11080 else
11081 gnu_section = FALSE;
60bca95a
NC
11082
11083 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11084 p += namelen;
11085 section_len -= namelen + 4;
60bca95a 11086
11c1ff18
PB
11087 while (section_len > 0)
11088 {
11089 int tag = *(p++);
11090 int val;
11091 bfd_vma size;
60bca95a 11092
11c1ff18
PB
11093 size = byte_get (p, 4);
11094 if (size > section_len)
11095 {
11096 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11097 (int) size, (int) section_len);
11c1ff18
PB
11098 size = section_len;
11099 }
60bca95a 11100
11c1ff18
PB
11101 section_len -= size;
11102 end = p + size - 1;
11103 p += 4;
60bca95a 11104
11c1ff18
PB
11105 switch (tag)
11106 {
11107 case 1:
2b692964 11108 printf (_("File Attributes\n"));
11c1ff18
PB
11109 break;
11110 case 2:
2b692964 11111 printf (_("Section Attributes:"));
11c1ff18
PB
11112 goto do_numlist;
11113 case 3:
2b692964 11114 printf (_("Symbol Attributes:"));
11c1ff18
PB
11115 do_numlist:
11116 for (;;)
11117 {
91d6fa6a 11118 unsigned int j;
60bca95a 11119
91d6fa6a
NC
11120 val = read_uleb128 (p, &j);
11121 p += j;
11c1ff18
PB
11122 if (val == 0)
11123 break;
11124 printf (" %d", val);
11125 }
11126 printf ("\n");
11127 break;
11128 default:
2b692964 11129 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
11130 public_section = FALSE;
11131 break;
11132 }
60bca95a 11133
11c1ff18
PB
11134 if (public_section)
11135 {
11136 while (p < end)
104d59d1
JM
11137 p = display_pub_attribute (p);
11138 }
11139 else if (gnu_section)
11140 {
11141 while (p < end)
11142 p = display_gnu_attribute (p,
11143 display_proc_gnu_attribute);
11c1ff18
PB
11144 }
11145 else
11146 {
11147 /* ??? Do something sensible, like dump hex. */
2b692964 11148 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
11149 p = end;
11150 }
11151 }
11152 }
11153 }
11154 else
60bca95a 11155 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 11156
60bca95a 11157 free (contents);
11c1ff18
PB
11158 }
11159 return 1;
11160}
11161
104d59d1 11162static int
2cf0635d 11163process_arm_specific (FILE * file)
104d59d1
JM
11164{
11165 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
11166 display_arm_attribute, NULL);
11167}
11168
34c8bcba 11169static int
2cf0635d 11170process_power_specific (FILE * file)
34c8bcba
JM
11171{
11172 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11173 display_power_gnu_attribute);
11174}
11175
59e6276b
JM
11176static int
11177process_tic6x_specific (FILE * file)
11178{
11179 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
11180 display_tic6x_attribute, NULL);
11181}
11182
ccb4c951
RS
11183/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
11184 Print the Address, Access and Initial fields of an entry at VMA ADDR
11185 and return the VMA of the next entry. */
11186
11187static bfd_vma
2cf0635d 11188print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
11189{
11190 printf (" ");
11191 print_vma (addr, LONG_HEX);
11192 printf (" ");
11193 if (addr < pltgot + 0xfff0)
11194 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
11195 else
11196 printf ("%10s", "");
11197 printf (" ");
11198 if (data == NULL)
2b692964 11199 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
11200 else
11201 {
11202 bfd_vma entry;
11203
11204 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11205 print_vma (entry, LONG_HEX);
11206 }
11207 return addr + (is_32bit_elf ? 4 : 8);
11208}
11209
861fb55a
DJ
11210/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
11211 PLTGOT. Print the Address and Initial fields of an entry at VMA
11212 ADDR and return the VMA of the next entry. */
11213
11214static bfd_vma
2cf0635d 11215print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
11216{
11217 printf (" ");
11218 print_vma (addr, LONG_HEX);
11219 printf (" ");
11220 if (data == NULL)
2b692964 11221 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
11222 else
11223 {
11224 bfd_vma entry;
11225
11226 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11227 print_vma (entry, LONG_HEX);
11228 }
11229 return addr + (is_32bit_elf ? 4 : 8);
11230}
11231
19e6b90e 11232static int
2cf0635d 11233process_mips_specific (FILE * file)
5b18a4bc 11234{
2cf0635d 11235 Elf_Internal_Dyn * entry;
19e6b90e
L
11236 size_t liblist_offset = 0;
11237 size_t liblistno = 0;
11238 size_t conflictsno = 0;
11239 size_t options_offset = 0;
11240 size_t conflicts_offset = 0;
861fb55a
DJ
11241 size_t pltrelsz = 0;
11242 size_t pltrel = 0;
ccb4c951 11243 bfd_vma pltgot = 0;
861fb55a
DJ
11244 bfd_vma mips_pltgot = 0;
11245 bfd_vma jmprel = 0;
ccb4c951
RS
11246 bfd_vma local_gotno = 0;
11247 bfd_vma gotsym = 0;
11248 bfd_vma symtabno = 0;
103f02d3 11249
2cf19d5c
JM
11250 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11251 display_mips_gnu_attribute);
11252
19e6b90e
L
11253 /* We have a lot of special sections. Thanks SGI! */
11254 if (dynamic_section == NULL)
11255 /* No information available. */
11256 return 0;
252b5132 11257
b2d38a17 11258 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
11259 switch (entry->d_tag)
11260 {
11261 case DT_MIPS_LIBLIST:
d93f0186
NC
11262 liblist_offset
11263 = offset_from_vma (file, entry->d_un.d_val,
11264 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
11265 break;
11266 case DT_MIPS_LIBLISTNO:
11267 liblistno = entry->d_un.d_val;
11268 break;
11269 case DT_MIPS_OPTIONS:
d93f0186 11270 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
11271 break;
11272 case DT_MIPS_CONFLICT:
d93f0186
NC
11273 conflicts_offset
11274 = offset_from_vma (file, entry->d_un.d_val,
11275 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
11276 break;
11277 case DT_MIPS_CONFLICTNO:
11278 conflictsno = entry->d_un.d_val;
11279 break;
ccb4c951 11280 case DT_PLTGOT:
861fb55a
DJ
11281 pltgot = entry->d_un.d_ptr;
11282 break;
ccb4c951
RS
11283 case DT_MIPS_LOCAL_GOTNO:
11284 local_gotno = entry->d_un.d_val;
11285 break;
11286 case DT_MIPS_GOTSYM:
11287 gotsym = entry->d_un.d_val;
11288 break;
11289 case DT_MIPS_SYMTABNO:
11290 symtabno = entry->d_un.d_val;
11291 break;
861fb55a
DJ
11292 case DT_MIPS_PLTGOT:
11293 mips_pltgot = entry->d_un.d_ptr;
11294 break;
11295 case DT_PLTREL:
11296 pltrel = entry->d_un.d_val;
11297 break;
11298 case DT_PLTRELSZ:
11299 pltrelsz = entry->d_un.d_val;
11300 break;
11301 case DT_JMPREL:
11302 jmprel = entry->d_un.d_ptr;
11303 break;
252b5132
RH
11304 default:
11305 break;
11306 }
11307
11308 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
11309 {
2cf0635d 11310 Elf32_External_Lib * elib;
252b5132
RH
11311 size_t cnt;
11312
3f5e193b
NC
11313 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
11314 liblistno,
11315 sizeof (Elf32_External_Lib),
11316 _("liblist"));
a6e9f9df 11317 if (elib)
252b5132 11318 {
2b692964 11319 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 11320 (unsigned long) liblistno);
2b692964 11321 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
11322 stdout);
11323
11324 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 11325 {
a6e9f9df 11326 Elf32_Lib liblist;
91d6fa6a 11327 time_t atime;
a6e9f9df 11328 char timebuf[20];
2cf0635d 11329 struct tm * tmp;
a6e9f9df
AM
11330
11331 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 11332 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
11333 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11334 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11335 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11336
91d6fa6a 11337 tmp = gmtime (&atime);
e9e44622
JJ
11338 snprintf (timebuf, sizeof (timebuf),
11339 "%04u-%02u-%02uT%02u:%02u:%02u",
11340 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11341 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 11342
31104126 11343 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
11344 if (VALID_DYNAMIC_NAME (liblist.l_name))
11345 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
11346 else
2b692964 11347 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
11348 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
11349 liblist.l_version);
a6e9f9df
AM
11350
11351 if (liblist.l_flags == 0)
2b692964 11352 puts (_(" NONE"));
a6e9f9df
AM
11353 else
11354 {
11355 static const struct
252b5132 11356 {
2cf0635d 11357 const char * name;
a6e9f9df 11358 int bit;
252b5132 11359 }
a6e9f9df
AM
11360 l_flags_vals[] =
11361 {
11362 { " EXACT_MATCH", LL_EXACT_MATCH },
11363 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
11364 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
11365 { " EXPORTS", LL_EXPORTS },
11366 { " DELAY_LOAD", LL_DELAY_LOAD },
11367 { " DELTA", LL_DELTA }
11368 };
11369 int flags = liblist.l_flags;
11370 size_t fcnt;
11371
60bca95a 11372 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
11373 if ((flags & l_flags_vals[fcnt].bit) != 0)
11374 {
11375 fputs (l_flags_vals[fcnt].name, stdout);
11376 flags ^= l_flags_vals[fcnt].bit;
11377 }
11378 if (flags != 0)
11379 printf (" %#x", (unsigned int) flags);
252b5132 11380
a6e9f9df
AM
11381 puts ("");
11382 }
252b5132 11383 }
252b5132 11384
a6e9f9df
AM
11385 free (elib);
11386 }
252b5132
RH
11387 }
11388
11389 if (options_offset != 0)
11390 {
2cf0635d
NC
11391 Elf_External_Options * eopt;
11392 Elf_Internal_Shdr * sect = section_headers;
11393 Elf_Internal_Options * iopt;
11394 Elf_Internal_Options * option;
252b5132
RH
11395 size_t offset;
11396 int cnt;
11397
11398 /* Find the section header so that we get the size. */
11399 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 11400 ++sect;
252b5132 11401
3f5e193b
NC
11402 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
11403 sect->sh_size, _("options"));
a6e9f9df 11404 if (eopt)
252b5132 11405 {
3f5e193b
NC
11406 iopt = (Elf_Internal_Options *)
11407 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
11408 if (iopt == NULL)
11409 {
591a748a 11410 error (_("Out of memory\n"));
a6e9f9df
AM
11411 return 0;
11412 }
76da6bbe 11413
a6e9f9df
AM
11414 offset = cnt = 0;
11415 option = iopt;
252b5132 11416
a6e9f9df
AM
11417 while (offset < sect->sh_size)
11418 {
2cf0635d 11419 Elf_External_Options * eoption;
252b5132 11420
a6e9f9df 11421 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 11422
a6e9f9df
AM
11423 option->kind = BYTE_GET (eoption->kind);
11424 option->size = BYTE_GET (eoption->size);
11425 option->section = BYTE_GET (eoption->section);
11426 option->info = BYTE_GET (eoption->info);
76da6bbe 11427
a6e9f9df 11428 offset += option->size;
252b5132 11429
a6e9f9df
AM
11430 ++option;
11431 ++cnt;
11432 }
252b5132 11433
a6e9f9df
AM
11434 printf (_("\nSection '%s' contains %d entries:\n"),
11435 SECTION_NAME (sect), cnt);
76da6bbe 11436
a6e9f9df 11437 option = iopt;
252b5132 11438
a6e9f9df 11439 while (cnt-- > 0)
252b5132 11440 {
a6e9f9df
AM
11441 size_t len;
11442
11443 switch (option->kind)
252b5132 11444 {
a6e9f9df
AM
11445 case ODK_NULL:
11446 /* This shouldn't happen. */
11447 printf (" NULL %d %lx", option->section, option->info);
11448 break;
11449 case ODK_REGINFO:
11450 printf (" REGINFO ");
11451 if (elf_header.e_machine == EM_MIPS)
11452 {
11453 /* 32bit form. */
2cf0635d 11454 Elf32_External_RegInfo * ereg;
b34976b6 11455 Elf32_RegInfo reginfo;
a6e9f9df
AM
11456
11457 ereg = (Elf32_External_RegInfo *) (option + 1);
11458 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11459 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11460 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11461 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11462 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
11463 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
11464
11465 printf ("GPR %08lx GP 0x%lx\n",
11466 reginfo.ri_gprmask,
11467 (unsigned long) reginfo.ri_gp_value);
11468 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11469 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11470 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11471 }
11472 else
11473 {
11474 /* 64 bit form. */
2cf0635d 11475 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
11476 Elf64_Internal_RegInfo reginfo;
11477
11478 ereg = (Elf64_External_RegInfo *) (option + 1);
11479 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11480 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11481 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11482 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11483 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 11484 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
11485
11486 printf ("GPR %08lx GP 0x",
11487 reginfo.ri_gprmask);
11488 printf_vma (reginfo.ri_gp_value);
11489 printf ("\n");
11490
11491 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11492 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11493 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11494 }
11495 ++option;
11496 continue;
11497 case ODK_EXCEPTIONS:
11498 fputs (" EXCEPTIONS fpe_min(", stdout);
11499 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
11500 fputs (") fpe_max(", stdout);
11501 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
11502 fputs (")", stdout);
11503
11504 if (option->info & OEX_PAGE0)
11505 fputs (" PAGE0", stdout);
11506 if (option->info & OEX_SMM)
11507 fputs (" SMM", stdout);
11508 if (option->info & OEX_FPDBUG)
11509 fputs (" FPDBUG", stdout);
11510 if (option->info & OEX_DISMISS)
11511 fputs (" DISMISS", stdout);
11512 break;
11513 case ODK_PAD:
11514 fputs (" PAD ", stdout);
11515 if (option->info & OPAD_PREFIX)
11516 fputs (" PREFIX", stdout);
11517 if (option->info & OPAD_POSTFIX)
11518 fputs (" POSTFIX", stdout);
11519 if (option->info & OPAD_SYMBOL)
11520 fputs (" SYMBOL", stdout);
11521 break;
11522 case ODK_HWPATCH:
11523 fputs (" HWPATCH ", stdout);
11524 if (option->info & OHW_R4KEOP)
11525 fputs (" R4KEOP", stdout);
11526 if (option->info & OHW_R8KPFETCH)
11527 fputs (" R8KPFETCH", stdout);
11528 if (option->info & OHW_R5KEOP)
11529 fputs (" R5KEOP", stdout);
11530 if (option->info & OHW_R5KCVTL)
11531 fputs (" R5KCVTL", stdout);
11532 break;
11533 case ODK_FILL:
11534 fputs (" FILL ", stdout);
11535 /* XXX Print content of info word? */
11536 break;
11537 case ODK_TAGS:
11538 fputs (" TAGS ", stdout);
11539 /* XXX Print content of info word? */
11540 break;
11541 case ODK_HWAND:
11542 fputs (" HWAND ", stdout);
11543 if (option->info & OHWA0_R4KEOP_CHECKED)
11544 fputs (" R4KEOP_CHECKED", stdout);
11545 if (option->info & OHWA0_R4KEOP_CLEAN)
11546 fputs (" R4KEOP_CLEAN", stdout);
11547 break;
11548 case ODK_HWOR:
11549 fputs (" HWOR ", stdout);
11550 if (option->info & OHWA0_R4KEOP_CHECKED)
11551 fputs (" R4KEOP_CHECKED", stdout);
11552 if (option->info & OHWA0_R4KEOP_CLEAN)
11553 fputs (" R4KEOP_CLEAN", stdout);
11554 break;
11555 case ODK_GP_GROUP:
11556 printf (" GP_GROUP %#06lx self-contained %#06lx",
11557 option->info & OGP_GROUP,
11558 (option->info & OGP_SELF) >> 16);
11559 break;
11560 case ODK_IDENT:
11561 printf (" IDENT %#06lx self-contained %#06lx",
11562 option->info & OGP_GROUP,
11563 (option->info & OGP_SELF) >> 16);
11564 break;
11565 default:
11566 /* This shouldn't happen. */
11567 printf (" %3d ??? %d %lx",
11568 option->kind, option->section, option->info);
11569 break;
252b5132 11570 }
a6e9f9df 11571
2cf0635d 11572 len = sizeof (* eopt);
a6e9f9df
AM
11573 while (len < option->size)
11574 if (((char *) option)[len] >= ' '
11575 && ((char *) option)[len] < 0x7f)
11576 printf ("%c", ((char *) option)[len++]);
11577 else
11578 printf ("\\%03o", ((char *) option)[len++]);
11579
11580 fputs ("\n", stdout);
252b5132 11581 ++option;
252b5132
RH
11582 }
11583
a6e9f9df 11584 free (eopt);
252b5132 11585 }
252b5132
RH
11586 }
11587
11588 if (conflicts_offset != 0 && conflictsno != 0)
11589 {
2cf0635d 11590 Elf32_Conflict * iconf;
252b5132
RH
11591 size_t cnt;
11592
11593 if (dynamic_symbols == NULL)
11594 {
591a748a 11595 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
11596 return 0;
11597 }
11598
3f5e193b 11599 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
11600 if (iconf == NULL)
11601 {
591a748a 11602 error (_("Out of memory\n"));
252b5132
RH
11603 return 0;
11604 }
11605
9ea033b2 11606 if (is_32bit_elf)
252b5132 11607 {
2cf0635d 11608 Elf32_External_Conflict * econf32;
a6e9f9df 11609
3f5e193b
NC
11610 econf32 = (Elf32_External_Conflict *)
11611 get_data (NULL, file, conflicts_offset, conflictsno,
11612 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
11613 if (!econf32)
11614 return 0;
252b5132
RH
11615
11616 for (cnt = 0; cnt < conflictsno; ++cnt)
11617 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
11618
11619 free (econf32);
252b5132
RH
11620 }
11621 else
11622 {
2cf0635d 11623 Elf64_External_Conflict * econf64;
a6e9f9df 11624
3f5e193b
NC
11625 econf64 = (Elf64_External_Conflict *)
11626 get_data (NULL, file, conflicts_offset, conflictsno,
11627 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
11628 if (!econf64)
11629 return 0;
252b5132
RH
11630
11631 for (cnt = 0; cnt < conflictsno; ++cnt)
11632 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
11633
11634 free (econf64);
252b5132
RH
11635 }
11636
c7e7ca54
NC
11637 printf (_("\nSection '.conflict' contains %lu entries:\n"),
11638 (unsigned long) conflictsno);
252b5132
RH
11639 puts (_(" Num: Index Value Name"));
11640
11641 for (cnt = 0; cnt < conflictsno; ++cnt)
11642 {
2cf0635d 11643 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 11644
b34976b6 11645 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 11646 print_vma (psym->st_value, FULL_HEX);
31104126 11647 putchar (' ');
d79b3d50
NC
11648 if (VALID_DYNAMIC_NAME (psym->st_name))
11649 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11650 else
2b692964 11651 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 11652 putchar ('\n');
252b5132
RH
11653 }
11654
252b5132
RH
11655 free (iconf);
11656 }
11657
ccb4c951
RS
11658 if (pltgot != 0 && local_gotno != 0)
11659 {
91d6fa6a 11660 bfd_vma ent, local_end, global_end;
bbeee7ea 11661 size_t i, offset;
2cf0635d 11662 unsigned char * data;
bbeee7ea 11663 int addr_size;
ccb4c951 11664
91d6fa6a 11665 ent = pltgot;
ccb4c951
RS
11666 addr_size = (is_32bit_elf ? 4 : 8);
11667 local_end = pltgot + local_gotno * addr_size;
11668 global_end = local_end + (symtabno - gotsym) * addr_size;
11669
11670 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b
NC
11671 data = (unsigned char *) get_data (NULL, file, offset,
11672 global_end - pltgot, 1, _("GOT"));
ccb4c951
RS
11673 printf (_("\nPrimary GOT:\n"));
11674 printf (_(" Canonical gp value: "));
11675 print_vma (pltgot + 0x7ff0, LONG_HEX);
11676 printf ("\n\n");
11677
11678 printf (_(" Reserved entries:\n"));
11679 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
11680 addr_size * 2, _("Address"), _("Access"),
11681 addr_size * 2, _("Initial"));
91d6fa6a 11682 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 11683 printf (_(" Lazy resolver\n"));
ccb4c951 11684 if (data
91d6fa6a 11685 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
11686 >> (addr_size * 8 - 1)) != 0)
11687 {
91d6fa6a 11688 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 11689 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
11690 }
11691 printf ("\n");
11692
91d6fa6a 11693 if (ent < local_end)
ccb4c951
RS
11694 {
11695 printf (_(" Local entries:\n"));
cc5914eb 11696 printf (" %*s %10s %*s\n",
2b692964
NC
11697 addr_size * 2, _("Address"), _("Access"),
11698 addr_size * 2, _("Initial"));
91d6fa6a 11699 while (ent < local_end)
ccb4c951 11700 {
91d6fa6a 11701 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
11702 printf ("\n");
11703 }
11704 printf ("\n");
11705 }
11706
11707 if (gotsym < symtabno)
11708 {
11709 int sym_width;
11710
11711 printf (_(" Global entries:\n"));
cc5914eb 11712 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
2b692964
NC
11713 addr_size * 2, _("Address"), _("Access"),
11714 addr_size * 2, _("Initial"),
11715 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
ccb4c951
RS
11716 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
11717 for (i = gotsym; i < symtabno; i++)
11718 {
2cf0635d 11719 Elf_Internal_Sym * psym;
ccb4c951
RS
11720
11721 psym = dynamic_symbols + i;
91d6fa6a 11722 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
11723 printf (" ");
11724 print_vma (psym->st_value, LONG_HEX);
11725 printf (" %-7s %3s ",
11726 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
11727 get_symbol_index_type (psym->st_shndx));
11728 if (VALID_DYNAMIC_NAME (psym->st_name))
11729 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
11730 else
2b692964 11731 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
11732 printf ("\n");
11733 }
11734 printf ("\n");
11735 }
11736
11737 if (data)
11738 free (data);
11739 }
11740
861fb55a
DJ
11741 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
11742 {
91d6fa6a 11743 bfd_vma ent, end;
861fb55a
DJ
11744 size_t offset, rel_offset;
11745 unsigned long count, i;
2cf0635d 11746 unsigned char * data;
861fb55a 11747 int addr_size, sym_width;
2cf0635d 11748 Elf_Internal_Rela * rels;
861fb55a
DJ
11749
11750 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
11751 if (pltrel == DT_RELA)
11752 {
11753 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
11754 return 0;
11755 }
11756 else
11757 {
11758 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
11759 return 0;
11760 }
11761
91d6fa6a 11762 ent = mips_pltgot;
861fb55a
DJ
11763 addr_size = (is_32bit_elf ? 4 : 8);
11764 end = mips_pltgot + (2 + count) * addr_size;
11765
11766 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b
NC
11767 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
11768 1, _("PLT GOT"));
861fb55a
DJ
11769 printf (_("\nPLT GOT:\n\n"));
11770 printf (_(" Reserved entries:\n"));
11771 printf (_(" %*s %*s Purpose\n"),
2b692964 11772 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 11773 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 11774 printf (_(" PLT lazy resolver\n"));
91d6fa6a 11775 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 11776 printf (_(" Module pointer\n"));
861fb55a
DJ
11777 printf ("\n");
11778
11779 printf (_(" Entries:\n"));
cc5914eb 11780 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
11781 addr_size * 2, _("Address"),
11782 addr_size * 2, _("Initial"),
11783 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
11784 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
11785 for (i = 0; i < count; i++)
11786 {
2cf0635d 11787 Elf_Internal_Sym * psym;
861fb55a
DJ
11788
11789 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 11790 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
11791 printf (" ");
11792 print_vma (psym->st_value, LONG_HEX);
11793 printf (" %-7s %3s ",
11794 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
11795 get_symbol_index_type (psym->st_shndx));
11796 if (VALID_DYNAMIC_NAME (psym->st_name))
11797 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
11798 else
2b692964 11799 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
11800 printf ("\n");
11801 }
11802 printf ("\n");
11803
11804 if (data)
11805 free (data);
11806 free (rels);
11807 }
11808
252b5132
RH
11809 return 1;
11810}
11811
047b2264 11812static int
2cf0635d 11813process_gnu_liblist (FILE * file)
047b2264 11814{
2cf0635d
NC
11815 Elf_Internal_Shdr * section;
11816 Elf_Internal_Shdr * string_sec;
11817 Elf32_External_Lib * elib;
11818 char * strtab;
c256ffe7 11819 size_t strtab_size;
047b2264
JJ
11820 size_t cnt;
11821 unsigned i;
11822
11823 if (! do_arch)
11824 return 0;
11825
11826 for (i = 0, section = section_headers;
11827 i < elf_header.e_shnum;
b34976b6 11828 i++, section++)
047b2264
JJ
11829 {
11830 switch (section->sh_type)
11831 {
11832 case SHT_GNU_LIBLIST:
4fbb74a6 11833 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
11834 break;
11835
3f5e193b
NC
11836 elib = (Elf32_External_Lib *)
11837 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
11838 _("liblist"));
047b2264
JJ
11839
11840 if (elib == NULL)
11841 break;
4fbb74a6 11842 string_sec = section_headers + section->sh_link;
047b2264 11843
3f5e193b
NC
11844 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
11845 string_sec->sh_size,
11846 _("liblist string table"));
c256ffe7 11847 strtab_size = string_sec->sh_size;
047b2264
JJ
11848
11849 if (strtab == NULL
11850 || section->sh_entsize != sizeof (Elf32_External_Lib))
11851 {
11852 free (elib);
2842702f 11853 free (strtab);
047b2264
JJ
11854 break;
11855 }
11856
11857 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
11858 SECTION_NAME (section),
0af1713e 11859 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 11860
2b692964 11861 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
11862
11863 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
11864 ++cnt)
11865 {
11866 Elf32_Lib liblist;
91d6fa6a 11867 time_t atime;
047b2264 11868 char timebuf[20];
2cf0635d 11869 struct tm * tmp;
047b2264
JJ
11870
11871 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 11872 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
11873 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11874 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11875 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11876
91d6fa6a 11877 tmp = gmtime (&atime);
e9e44622
JJ
11878 snprintf (timebuf, sizeof (timebuf),
11879 "%04u-%02u-%02uT%02u:%02u:%02u",
11880 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11881 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11882
11883 printf ("%3lu: ", (unsigned long) cnt);
11884 if (do_wide)
c256ffe7 11885 printf ("%-20s", liblist.l_name < strtab_size
2b692964 11886 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 11887 else
c256ffe7 11888 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 11889 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
11890 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
11891 liblist.l_version, liblist.l_flags);
11892 }
11893
11894 free (elib);
2842702f 11895 free (strtab);
047b2264
JJ
11896 }
11897 }
11898
11899 return 1;
11900}
11901
9437c45b 11902static const char *
d3ba0551 11903get_note_type (unsigned e_type)
779fe533
NC
11904{
11905 static char buff[64];
103f02d3 11906
1ec5cd37
NC
11907 if (elf_header.e_type == ET_CORE)
11908 switch (e_type)
11909 {
57346661 11910 case NT_AUXV:
1ec5cd37 11911 return _("NT_AUXV (auxiliary vector)");
57346661 11912 case NT_PRSTATUS:
1ec5cd37 11913 return _("NT_PRSTATUS (prstatus structure)");
57346661 11914 case NT_FPREGSET:
1ec5cd37 11915 return _("NT_FPREGSET (floating point registers)");
57346661 11916 case NT_PRPSINFO:
1ec5cd37 11917 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 11918 case NT_TASKSTRUCT:
1ec5cd37 11919 return _("NT_TASKSTRUCT (task structure)");
57346661 11920 case NT_PRXFPREG:
1ec5cd37 11921 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
11922 case NT_PPC_VMX:
11923 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
11924 case NT_PPC_VSX:
11925 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
11926 case NT_X86_XSTATE:
11927 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
11928 case NT_S390_HIGH_GPRS:
11929 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
11930 case NT_S390_TIMER:
11931 return _("NT_S390_TIMER (s390 timer register)");
11932 case NT_S390_TODCMP:
11933 return _("NT_S390_TODCMP (s390 TOD comparator register)");
11934 case NT_S390_TODPREG:
11935 return _("NT_S390_TODPREG (s390 TOD programmable register)");
11936 case NT_S390_CTRS:
11937 return _("NT_S390_CTRS (s390 control registers)");
11938 case NT_S390_PREFIX:
11939 return _("NT_S390_PREFIX (s390 prefix register)");
57346661 11940 case NT_PSTATUS:
1ec5cd37 11941 return _("NT_PSTATUS (pstatus structure)");
57346661 11942 case NT_FPREGS:
1ec5cd37 11943 return _("NT_FPREGS (floating point registers)");
57346661 11944 case NT_PSINFO:
1ec5cd37 11945 return _("NT_PSINFO (psinfo structure)");
57346661 11946 case NT_LWPSTATUS:
1ec5cd37 11947 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 11948 case NT_LWPSINFO:
1ec5cd37 11949 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 11950 case NT_WIN32PSTATUS:
1ec5cd37
NC
11951 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
11952 default:
11953 break;
11954 }
11955 else
11956 switch (e_type)
11957 {
11958 case NT_VERSION:
11959 return _("NT_VERSION (version)");
11960 case NT_ARCH:
11961 return _("NT_ARCH (architecture)");
11962 default:
11963 break;
11964 }
11965
e9e44622 11966 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 11967 return buff;
779fe533
NC
11968}
11969
1118d252
RM
11970static const char *
11971get_gnu_elf_note_type (unsigned e_type)
11972{
11973 static char buff[64];
11974
11975 switch (e_type)
11976 {
11977 case NT_GNU_ABI_TAG:
11978 return _("NT_GNU_ABI_TAG (ABI version tag)");
11979 case NT_GNU_HWCAP:
11980 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
11981 case NT_GNU_BUILD_ID:
11982 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
11983 case NT_GNU_GOLD_VERSION:
11984 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
11985 default:
11986 break;
11987 }
11988
11989 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
11990 return buff;
11991}
11992
9437c45b 11993static const char *
d3ba0551 11994get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
11995{
11996 static char buff[64];
11997
b4db1224 11998 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
11999 {
12000 /* NetBSD core "procinfo" structure. */
12001 return _("NetBSD procinfo structure");
12002 }
12003
12004 /* As of Jan 2002 there are no other machine-independent notes
12005 defined for NetBSD core files. If the note type is less
12006 than the start of the machine-dependent note types, we don't
12007 understand it. */
12008
b4db1224 12009 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 12010 {
e9e44622 12011 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
12012 return buff;
12013 }
12014
12015 switch (elf_header.e_machine)
12016 {
12017 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
12018 and PT_GETFPREGS == mach+2. */
12019
12020 case EM_OLD_ALPHA:
12021 case EM_ALPHA:
12022 case EM_SPARC:
12023 case EM_SPARC32PLUS:
12024 case EM_SPARCV9:
12025 switch (e_type)
12026 {
2b692964 12027 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 12028 return _("PT_GETREGS (reg structure)");
2b692964 12029 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 12030 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12031 default:
12032 break;
12033 }
12034 break;
12035
12036 /* On all other arch's, PT_GETREGS == mach+1 and
12037 PT_GETFPREGS == mach+3. */
12038 default:
12039 switch (e_type)
12040 {
2b692964 12041 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 12042 return _("PT_GETREGS (reg structure)");
2b692964 12043 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 12044 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12045 default:
12046 break;
12047 }
12048 }
12049
e9e44622
JJ
12050 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
12051 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
12052 return buff;
12053}
12054
00e98fc7
TG
12055static const char *
12056get_ia64_vms_note_type (unsigned e_type)
12057{
12058 static char buff[64];
12059
12060 switch (e_type)
12061 {
12062 case NT_VMS_MHD:
12063 return _("NT_VMS_MHD (module header)");
12064 case NT_VMS_LNM:
12065 return _("NT_VMS_LNM (language name)");
12066 case NT_VMS_SRC:
12067 return _("NT_VMS_SRC (source files)");
12068 case NT_VMS_TITLE:
12069 return _("NT_VMS_TITLE");
12070 case NT_VMS_EIDC:
12071 return _("NT_VMS_EIDC (consistency check)");
12072 case NT_VMS_FPMODE:
12073 return _("NT_VMS_FPMODE (FP mode)");
12074 case NT_VMS_LINKTIME:
12075 return _("NT_VMS_LINKTIME");
12076 case NT_VMS_IMGNAM:
12077 return _("NT_VMS_IMGNAM (image name)");
12078 case NT_VMS_IMGID:
12079 return _("NT_VMS_IMGID (image id)");
12080 case NT_VMS_LINKID:
12081 return _("NT_VMS_LINKID (link id)");
12082 case NT_VMS_IMGBID:
12083 return _("NT_VMS_IMGBID (build id)");
12084 case NT_VMS_GSTNAM:
12085 return _("NT_VMS_GSTNAM (sym table name)");
12086 case NT_VMS_ORIG_DYN:
12087 return _("NT_VMS_ORIG_DYN");
12088 case NT_VMS_PATCHTIME:
12089 return _("NT_VMS_PATCHTIME");
12090 default:
12091 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12092 return buff;
12093 }
12094}
12095
12096static int
12097print_ia64_vms_note (Elf_Internal_Note * pnote)
12098{
12099 switch (pnote->type)
12100 {
12101 case NT_VMS_MHD:
12102 if (pnote->descsz > 36)
12103 {
12104 size_t l = strlen (pnote->descdata + 34);
12105 printf (_(" Creation date : %.17s\n"), pnote->descdata);
12106 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
12107 printf (_(" Module name : %s\n"), pnote->descdata + 34);
12108 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
12109 }
12110 else
12111 printf (_(" Invalid size\n"));
12112 break;
12113 case NT_VMS_LNM:
12114 printf (_(" Language: %s\n"), pnote->descdata);
12115 break;
12116#ifdef BFD64
12117 case NT_VMS_FPMODE:
12118 printf (_(" FP mode: 0x%016" BFD_VMA_FMT "x\n"),
12119 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
12120 break;
12121 case NT_VMS_LINKTIME:
12122 printf (_(" Link time: "));
12123 print_vms_time
12124 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12125 printf ("\n");
12126 break;
12127 case NT_VMS_PATCHTIME:
12128 printf (_(" Patch time: "));
12129 print_vms_time
12130 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12131 printf ("\n");
12132 break;
12133 case NT_VMS_ORIG_DYN:
12134 printf (_(" Major id: %u, minor id: %u\n"),
12135 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
12136 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
12137 printf (_(" Manip date : "));
12138 print_vms_time
12139 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
12140 printf (_("\n"
12141 " Link flags : 0x%016" BFD_VMA_FMT "x\n"),
12142 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
12143 printf (_(" Header flags: 0x%08x\n"),
12144 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
12145 printf (_(" Image id : %s\n"), pnote->descdata + 32);
12146 break;
12147#endif
12148 case NT_VMS_IMGNAM:
12149 printf (_(" Image name: %s\n"), pnote->descdata);
12150 break;
12151 case NT_VMS_GSTNAM:
12152 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
12153 break;
12154 case NT_VMS_IMGID:
12155 printf (_(" Image id: %s\n"), pnote->descdata);
12156 break;
12157 case NT_VMS_LINKID:
12158 printf (_(" Linker id: %s\n"), pnote->descdata);
12159 break;
12160 default:
12161 break;
12162 }
12163 return 1;
12164}
12165
6d118b09
NC
12166/* Note that by the ELF standard, the name field is already null byte
12167 terminated, and namesz includes the terminating null byte.
12168 I.E. the value of namesz for the name "FSF" is 4.
12169
e3c8793a 12170 If the value of namesz is zero, there is no name present. */
779fe533 12171static int
2cf0635d 12172process_note (Elf_Internal_Note * pnote)
779fe533 12173{
2cf0635d
NC
12174 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
12175 const char * nt;
9437c45b
JT
12176
12177 if (pnote->namesz == 0)
1ec5cd37
NC
12178 /* If there is no note name, then use the default set of
12179 note type strings. */
12180 nt = get_note_type (pnote->type);
12181
1118d252
RM
12182 else if (const_strneq (pnote->namedata, "GNU"))
12183 /* GNU-specific object file notes. */
12184 nt = get_gnu_elf_note_type (pnote->type);
12185
0112cd26 12186 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
12187 /* NetBSD-specific core file notes. */
12188 nt = get_netbsd_elfcore_note_type (pnote->type);
12189
b15fa79e
AM
12190 else if (strneq (pnote->namedata, "SPU/", 4))
12191 {
12192 /* SPU-specific core file notes. */
12193 nt = pnote->namedata + 4;
12194 name = "SPU";
12195 }
12196
00e98fc7
TG
12197 else if (const_strneq (pnote->namedata, "IPF/VMS"))
12198 /* VMS/ia64-specific file notes. */
12199 nt = get_ia64_vms_note_type (pnote->type);
12200
9437c45b 12201 else
1ec5cd37
NC
12202 /* Don't recognize this note name; just use the default set of
12203 note type strings. */
00e98fc7 12204 nt = get_note_type (pnote->type);
9437c45b 12205
00e98fc7
TG
12206 printf (" %-10s\t0x%08lx\t%s\n", name, pnote->descsz, nt);
12207
12208 if (const_strneq (pnote->namedata, "IPF/VMS"))
12209 return print_ia64_vms_note (pnote);
12210 else
12211 return 1;
779fe533
NC
12212}
12213
6d118b09 12214
779fe533 12215static int
2cf0635d 12216process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 12217{
2cf0635d
NC
12218 Elf_External_Note * pnotes;
12219 Elf_External_Note * external;
b34976b6 12220 int res = 1;
103f02d3 12221
779fe533
NC
12222 if (length <= 0)
12223 return 0;
103f02d3 12224
3f5e193b
NC
12225 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
12226 _("notes"));
dd24e3da 12227 if (pnotes == NULL)
a6e9f9df 12228 return 0;
779fe533 12229
103f02d3 12230 external = pnotes;
103f02d3 12231
305c7206 12232 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 12233 (unsigned long) offset, (unsigned long) length);
779fe533 12234 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 12235
2cf0635d 12236 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 12237 {
2cf0635d 12238 Elf_External_Note * next;
b34976b6 12239 Elf_Internal_Note inote;
2cf0635d 12240 char * temp = NULL;
6d118b09 12241
00e98fc7
TG
12242 if (!is_ia64_vms ())
12243 {
12244 inote.type = BYTE_GET (external->type);
12245 inote.namesz = BYTE_GET (external->namesz);
12246 inote.namedata = external->name;
12247 inote.descsz = BYTE_GET (external->descsz);
12248 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
12249 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12250
12251 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
12252 }
12253 else
12254 {
12255 Elf64_External_VMS_Note *vms_external;
12256
12257 vms_external = (Elf64_External_VMS_Note *)external;
12258 inote.type = BYTE_GET (vms_external->type);
12259 inote.namesz = BYTE_GET (vms_external->namesz);
12260 inote.namedata = vms_external->name;
12261 inote.descsz = BYTE_GET (vms_external->descsz);
12262 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
12263 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12264
12265 next = (Elf_External_Note *)
12266 (inote.descdata + align_power (inote.descsz, 3));
12267 }
3e55a963 12268
dd24e3da
NC
12269 if ( ((char *) next > ((char *) pnotes) + length)
12270 || ((char *) next < (char *) pnotes))
3e55a963 12271 {
0fd3a477 12272 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 12273 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 12274 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
12275 inote.type, inote.namesz, inote.descsz);
12276 break;
12277 }
12278
12279 external = next;
6d118b09 12280
dd24e3da
NC
12281 /* Prevent out-of-bounds indexing. */
12282 if (inote.namedata + inote.namesz >= (char *) pnotes + length
12283 || inote.namedata + inote.namesz < inote.namedata)
12284 {
12285 warn (_("corrupt note found at offset %lx into core notes\n"),
12286 (unsigned long) ((char *) external - (char *) pnotes));
12287 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
12288 inote.type, inote.namesz, inote.descsz);
12289 break;
12290 }
12291
6d118b09
NC
12292 /* Verify that name is null terminated. It appears that at least
12293 one version of Linux (RedHat 6.0) generates corefiles that don't
12294 comply with the ELF spec by failing to include the null byte in
12295 namesz. */
12296 if (inote.namedata[inote.namesz] != '\0')
12297 {
3f5e193b 12298 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 12299
6d118b09
NC
12300 if (temp == NULL)
12301 {
12302 error (_("Out of memory\n"));
12303 res = 0;
12304 break;
12305 }
76da6bbe 12306
6d118b09
NC
12307 strncpy (temp, inote.namedata, inote.namesz);
12308 temp[inote.namesz] = 0;
76da6bbe 12309
6d118b09
NC
12310 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
12311 inote.namedata = temp;
12312 }
12313
12314 res &= process_note (& inote);
103f02d3 12315
6d118b09
NC
12316 if (temp != NULL)
12317 {
12318 free (temp);
12319 temp = NULL;
12320 }
779fe533
NC
12321 }
12322
12323 free (pnotes);
103f02d3 12324
779fe533
NC
12325 return res;
12326}
12327
12328static int
2cf0635d 12329process_corefile_note_segments (FILE * file)
779fe533 12330{
2cf0635d 12331 Elf_Internal_Phdr * segment;
b34976b6
AM
12332 unsigned int i;
12333 int res = 1;
103f02d3 12334
d93f0186 12335 if (! get_program_headers (file))
779fe533 12336 return 0;
103f02d3 12337
779fe533
NC
12338 for (i = 0, segment = program_headers;
12339 i < elf_header.e_phnum;
b34976b6 12340 i++, segment++)
779fe533
NC
12341 {
12342 if (segment->p_type == PT_NOTE)
103f02d3 12343 res &= process_corefile_note_segment (file,
30800947
NC
12344 (bfd_vma) segment->p_offset,
12345 (bfd_vma) segment->p_filesz);
779fe533 12346 }
103f02d3 12347
779fe533
NC
12348 return res;
12349}
12350
12351static int
2cf0635d 12352process_note_sections (FILE * file)
1ec5cd37 12353{
2cf0635d 12354 Elf_Internal_Shdr * section;
1ec5cd37
NC
12355 unsigned long i;
12356 int res = 1;
12357
12358 for (i = 0, section = section_headers;
12359 i < elf_header.e_shnum;
12360 i++, section++)
12361 if (section->sh_type == SHT_NOTE)
12362 res &= process_corefile_note_segment (file,
12363 (bfd_vma) section->sh_offset,
12364 (bfd_vma) section->sh_size);
12365
12366 return res;
12367}
12368
12369static int
2cf0635d 12370process_notes (FILE * file)
779fe533
NC
12371{
12372 /* If we have not been asked to display the notes then do nothing. */
12373 if (! do_notes)
12374 return 1;
103f02d3 12375
779fe533 12376 if (elf_header.e_type != ET_CORE)
1ec5cd37 12377 return process_note_sections (file);
103f02d3 12378
779fe533 12379 /* No program headers means no NOTE segment. */
1ec5cd37
NC
12380 if (elf_header.e_phnum > 0)
12381 return process_corefile_note_segments (file);
779fe533 12382
1ec5cd37
NC
12383 printf (_("No note segments present in the core file.\n"));
12384 return 1;
779fe533
NC
12385}
12386
252b5132 12387static int
2cf0635d 12388process_arch_specific (FILE * file)
252b5132 12389{
a952a375
NC
12390 if (! do_arch)
12391 return 1;
12392
252b5132
RH
12393 switch (elf_header.e_machine)
12394 {
11c1ff18
PB
12395 case EM_ARM:
12396 return process_arm_specific (file);
252b5132 12397 case EM_MIPS:
4fe85591 12398 case EM_MIPS_RS3_LE:
252b5132
RH
12399 return process_mips_specific (file);
12400 break;
34c8bcba
JM
12401 case EM_PPC:
12402 return process_power_specific (file);
12403 break;
59e6276b
JM
12404 case EM_TI_C6000:
12405 return process_tic6x_specific (file);
12406 break;
252b5132
RH
12407 default:
12408 break;
12409 }
12410 return 1;
12411}
12412
12413static int
2cf0635d 12414get_file_header (FILE * file)
252b5132 12415{
9ea033b2
NC
12416 /* Read in the identity array. */
12417 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
12418 return 0;
12419
9ea033b2 12420 /* Determine how to read the rest of the header. */
b34976b6 12421 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
12422 {
12423 default: /* fall through */
12424 case ELFDATANONE: /* fall through */
adab8cdc
AO
12425 case ELFDATA2LSB:
12426 byte_get = byte_get_little_endian;
12427 byte_put = byte_put_little_endian;
12428 break;
12429 case ELFDATA2MSB:
12430 byte_get = byte_get_big_endian;
12431 byte_put = byte_put_big_endian;
12432 break;
9ea033b2
NC
12433 }
12434
12435 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 12436 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
12437
12438 /* Read in the rest of the header. */
12439 if (is_32bit_elf)
12440 {
12441 Elf32_External_Ehdr ehdr32;
252b5132 12442
9ea033b2
NC
12443 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
12444 return 0;
103f02d3 12445
9ea033b2
NC
12446 elf_header.e_type = BYTE_GET (ehdr32.e_type);
12447 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
12448 elf_header.e_version = BYTE_GET (ehdr32.e_version);
12449 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
12450 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
12451 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
12452 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
12453 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
12454 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
12455 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
12456 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
12457 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
12458 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
12459 }
252b5132 12460 else
9ea033b2
NC
12461 {
12462 Elf64_External_Ehdr ehdr64;
a952a375
NC
12463
12464 /* If we have been compiled with sizeof (bfd_vma) == 4, then
12465 we will not be able to cope with the 64bit data found in
12466 64 ELF files. Detect this now and abort before we start
50c2245b 12467 overwriting things. */
a952a375
NC
12468 if (sizeof (bfd_vma) < 8)
12469 {
e3c8793a
NC
12470 error (_("This instance of readelf has been built without support for a\n\
1247164 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
12472 return 0;
12473 }
103f02d3 12474
9ea033b2
NC
12475 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
12476 return 0;
103f02d3 12477
9ea033b2
NC
12478 elf_header.e_type = BYTE_GET (ehdr64.e_type);
12479 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
12480 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
12481 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
12482 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
12483 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
12484 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
12485 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
12486 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
12487 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
12488 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
12489 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
12490 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
12491 }
252b5132 12492
7ece0d85
JJ
12493 if (elf_header.e_shoff)
12494 {
12495 /* There may be some extensions in the first section header. Don't
12496 bomb if we can't read it. */
12497 if (is_32bit_elf)
12498 get_32bit_section_headers (file, 1);
12499 else
12500 get_64bit_section_headers (file, 1);
12501 }
560f3c1c 12502
252b5132
RH
12503 return 1;
12504}
12505
fb52b2f4
NC
12506/* Process one ELF object file according to the command line options.
12507 This file may actually be stored in an archive. The file is
12508 positioned at the start of the ELF object. */
12509
ff78d6d6 12510static int
2cf0635d 12511process_object (char * file_name, FILE * file)
252b5132 12512{
252b5132
RH
12513 unsigned int i;
12514
252b5132
RH
12515 if (! get_file_header (file))
12516 {
12517 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 12518 return 1;
252b5132
RH
12519 }
12520
12521 /* Initialise per file variables. */
60bca95a 12522 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
12523 version_info[i] = 0;
12524
60bca95a 12525 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 12526 dynamic_info[i] = 0;
5115b233 12527 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
12528
12529 /* Process the file. */
12530 if (show_name)
12531 printf (_("\nFile: %s\n"), file_name);
12532
18bd398b
NC
12533 /* Initialise the dump_sects array from the cmdline_dump_sects array.
12534 Note we do this even if cmdline_dump_sects is empty because we
12535 must make sure that the dump_sets array is zeroed out before each
12536 object file is processed. */
12537 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 12538 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
12539
12540 if (num_cmdline_dump_sects > 0)
12541 {
12542 if (num_dump_sects == 0)
12543 /* A sneaky way of allocating the dump_sects array. */
09c11c86 12544 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
12545
12546 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
12547 memcpy (dump_sects, cmdline_dump_sects,
12548 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 12549 }
d70c5fc7 12550
252b5132 12551 if (! process_file_header ())
fb52b2f4 12552 return 1;
252b5132 12553
d1f5c6e3 12554 if (! process_section_headers (file))
2f62977e 12555 {
d1f5c6e3
L
12556 /* Without loaded section headers we cannot process lots of
12557 things. */
2f62977e 12558 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 12559
2f62977e 12560 if (! do_using_dynamic)
2c610e4b 12561 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 12562 }
252b5132 12563
d1f5c6e3
L
12564 if (! process_section_groups (file))
12565 {
12566 /* Without loaded section groups we cannot process unwind. */
12567 do_unwind = 0;
12568 }
12569
2f62977e 12570 if (process_program_headers (file))
b2d38a17 12571 process_dynamic_section (file);
252b5132
RH
12572
12573 process_relocs (file);
12574
4d6ed7c8
NC
12575 process_unwind (file);
12576
252b5132
RH
12577 process_symbol_table (file);
12578
12579 process_syminfo (file);
12580
12581 process_version_sections (file);
12582
12583 process_section_contents (file);
f5842774 12584
1ec5cd37 12585 process_notes (file);
103f02d3 12586
047b2264
JJ
12587 process_gnu_liblist (file);
12588
252b5132
RH
12589 process_arch_specific (file);
12590
d93f0186
NC
12591 if (program_headers)
12592 {
12593 free (program_headers);
12594 program_headers = NULL;
12595 }
12596
252b5132
RH
12597 if (section_headers)
12598 {
12599 free (section_headers);
12600 section_headers = NULL;
12601 }
12602
12603 if (string_table)
12604 {
12605 free (string_table);
12606 string_table = NULL;
d40ac9bd 12607 string_table_length = 0;
252b5132
RH
12608 }
12609
12610 if (dynamic_strings)
12611 {
12612 free (dynamic_strings);
12613 dynamic_strings = NULL;
d79b3d50 12614 dynamic_strings_length = 0;
252b5132
RH
12615 }
12616
12617 if (dynamic_symbols)
12618 {
12619 free (dynamic_symbols);
12620 dynamic_symbols = NULL;
19936277 12621 num_dynamic_syms = 0;
252b5132
RH
12622 }
12623
12624 if (dynamic_syminfo)
12625 {
12626 free (dynamic_syminfo);
12627 dynamic_syminfo = NULL;
12628 }
ff78d6d6 12629
293c573e
MR
12630 if (dynamic_section)
12631 {
12632 free (dynamic_section);
12633 dynamic_section = NULL;
12634 }
12635
e4b17d5c
L
12636 if (section_headers_groups)
12637 {
12638 free (section_headers_groups);
12639 section_headers_groups = NULL;
12640 }
12641
12642 if (section_groups)
12643 {
2cf0635d
NC
12644 struct group_list * g;
12645 struct group_list * next;
e4b17d5c
L
12646
12647 for (i = 0; i < group_count; i++)
12648 {
12649 for (g = section_groups [i].root; g != NULL; g = next)
12650 {
12651 next = g->next;
12652 free (g);
12653 }
12654 }
12655
12656 free (section_groups);
12657 section_groups = NULL;
12658 }
12659
19e6b90e 12660 free_debug_memory ();
18bd398b 12661
ff78d6d6 12662 return 0;
252b5132
RH
12663}
12664
2cf0635d
NC
12665/* Process an ELF archive.
12666 On entry the file is positioned just after the ARMAG string. */
12667
12668static int
12669process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
12670{
12671 struct archive_info arch;
12672 struct archive_info nested_arch;
12673 size_t got;
2cf0635d
NC
12674 int ret;
12675
12676 show_name = 1;
12677
12678 /* The ARCH structure is used to hold information about this archive. */
12679 arch.file_name = NULL;
12680 arch.file = NULL;
12681 arch.index_array = NULL;
12682 arch.sym_table = NULL;
12683 arch.longnames = NULL;
12684
12685 /* The NESTED_ARCH structure is used as a single-item cache of information
12686 about a nested archive (when members of a thin archive reside within
12687 another regular archive file). */
12688 nested_arch.file_name = NULL;
12689 nested_arch.file = NULL;
12690 nested_arch.index_array = NULL;
12691 nested_arch.sym_table = NULL;
12692 nested_arch.longnames = NULL;
12693
12694 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
12695 {
12696 ret = 1;
12697 goto out;
4145f1d5 12698 }
fb52b2f4 12699
4145f1d5
NC
12700 if (do_archive_index)
12701 {
2cf0635d 12702 if (arch.sym_table == NULL)
4145f1d5
NC
12703 error (_("%s: unable to dump the index as none was found\n"), file_name);
12704 else
12705 {
2cf0635d 12706 unsigned int i, l;
4145f1d5
NC
12707 unsigned long current_pos;
12708
12709 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 12710 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
12711 current_pos = ftell (file);
12712
2cf0635d 12713 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 12714 {
2cf0635d
NC
12715 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
12716 {
12717 char * member_name;
4145f1d5 12718
2cf0635d
NC
12719 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
12720
12721 if (member_name != NULL)
12722 {
12723 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
12724
12725 if (qualified_name != NULL)
12726 {
12727 printf (_("Binary %s contains:\n"), qualified_name);
12728 free (qualified_name);
12729 }
4145f1d5
NC
12730 }
12731 }
2cf0635d
NC
12732
12733 if (l >= arch.sym_size)
4145f1d5
NC
12734 {
12735 error (_("%s: end of the symbol table reached before the end of the index\n"),
12736 file_name);
cb8f3167 12737 break;
4145f1d5 12738 }
2cf0635d
NC
12739 printf ("\t%s\n", arch.sym_table + l);
12740 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
12741 }
12742
2cf0635d
NC
12743 if (l & 01)
12744 ++l;
12745 if (l < arch.sym_size)
4145f1d5
NC
12746 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
12747 file_name);
12748
4145f1d5
NC
12749 if (fseek (file, current_pos, SEEK_SET) != 0)
12750 {
12751 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
12752 ret = 1;
12753 goto out;
4145f1d5 12754 }
fb52b2f4 12755 }
4145f1d5
NC
12756
12757 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
12758 && !do_segments && !do_header && !do_dump && !do_version
12759 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 12760 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
12761 {
12762 ret = 0; /* Archive index only. */
12763 goto out;
12764 }
fb52b2f4
NC
12765 }
12766
d989285c 12767 ret = 0;
fb52b2f4
NC
12768
12769 while (1)
12770 {
2cf0635d
NC
12771 char * name;
12772 size_t namelen;
12773 char * qualified_name;
12774
12775 /* Read the next archive header. */
12776 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
12777 {
12778 error (_("%s: failed to seek to next archive header\n"), file_name);
12779 return 1;
12780 }
12781 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
12782 if (got != sizeof arch.arhdr)
12783 {
12784 if (got == 0)
12785 break;
12786 error (_("%s: failed to read archive header\n"), file_name);
12787 ret = 1;
12788 break;
12789 }
12790 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
12791 {
12792 error (_("%s: did not find a valid archive header\n"), arch.file_name);
12793 ret = 1;
12794 break;
12795 }
12796
12797 arch.next_arhdr_offset += sizeof arch.arhdr;
12798
12799 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
12800 if (archive_file_size & 01)
12801 ++archive_file_size;
12802
12803 name = get_archive_member_name (&arch, &nested_arch);
12804 if (name == NULL)
fb52b2f4 12805 {
0fd3a477 12806 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
12807 ret = 1;
12808 break;
fb52b2f4 12809 }
2cf0635d 12810 namelen = strlen (name);
fb52b2f4 12811
2cf0635d
NC
12812 qualified_name = make_qualified_name (&arch, &nested_arch, name);
12813 if (qualified_name == NULL)
fb52b2f4 12814 {
2cf0635d 12815 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
12816 ret = 1;
12817 break;
fb52b2f4
NC
12818 }
12819
2cf0635d
NC
12820 if (is_thin_archive && arch.nested_member_origin == 0)
12821 {
12822 /* This is a proxy for an external member of a thin archive. */
12823 FILE * member_file;
12824 char * member_file_name = adjust_relative_path (file_name, name, namelen);
12825 if (member_file_name == NULL)
12826 {
12827 ret = 1;
12828 break;
12829 }
12830
12831 member_file = fopen (member_file_name, "rb");
12832 if (member_file == NULL)
12833 {
12834 error (_("Input file '%s' is not readable.\n"), member_file_name);
12835 free (member_file_name);
12836 ret = 1;
12837 break;
12838 }
12839
12840 archive_file_offset = arch.nested_member_origin;
12841
12842 ret |= process_object (qualified_name, member_file);
12843
12844 fclose (member_file);
12845 free (member_file_name);
12846 }
12847 else if (is_thin_archive)
12848 {
12849 /* This is a proxy for a member of a nested archive. */
12850 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
12851
12852 /* The nested archive file will have been opened and setup by
12853 get_archive_member_name. */
12854 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
12855 {
12856 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
12857 ret = 1;
12858 break;
12859 }
12860
12861 ret |= process_object (qualified_name, nested_arch.file);
12862 }
12863 else
12864 {
12865 archive_file_offset = arch.next_arhdr_offset;
12866 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 12867
2cf0635d
NC
12868 ret |= process_object (qualified_name, file);
12869 }
fb52b2f4 12870
2b52916e
L
12871 if (dump_sects != NULL)
12872 {
12873 free (dump_sects);
12874 dump_sects = NULL;
12875 num_dump_sects = 0;
12876 }
12877
2cf0635d 12878 free (qualified_name);
fb52b2f4
NC
12879 }
12880
4145f1d5 12881 out:
2cf0635d
NC
12882 if (nested_arch.file != NULL)
12883 fclose (nested_arch.file);
12884 release_archive (&nested_arch);
12885 release_archive (&arch);
fb52b2f4 12886
d989285c 12887 return ret;
fb52b2f4
NC
12888}
12889
12890static int
2cf0635d 12891process_file (char * file_name)
fb52b2f4 12892{
2cf0635d 12893 FILE * file;
fb52b2f4
NC
12894 struct stat statbuf;
12895 char armag[SARMAG];
12896 int ret;
12897
12898 if (stat (file_name, &statbuf) < 0)
12899 {
f24ddbdd
NC
12900 if (errno == ENOENT)
12901 error (_("'%s': No such file\n"), file_name);
12902 else
12903 error (_("Could not locate '%s'. System error message: %s\n"),
12904 file_name, strerror (errno));
12905 return 1;
12906 }
12907
12908 if (! S_ISREG (statbuf.st_mode))
12909 {
12910 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
12911 return 1;
12912 }
12913
12914 file = fopen (file_name, "rb");
12915 if (file == NULL)
12916 {
f24ddbdd 12917 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
12918 return 1;
12919 }
12920
12921 if (fread (armag, SARMAG, 1, file) != 1)
12922 {
4145f1d5 12923 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
12924 fclose (file);
12925 return 1;
12926 }
12927
12928 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
12929 ret = process_archive (file_name, file, FALSE);
12930 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
12931 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
12932 else
12933 {
4145f1d5
NC
12934 if (do_archive_index)
12935 error (_("File %s is not an archive so its index cannot be displayed.\n"),
12936 file_name);
12937
fb52b2f4
NC
12938 rewind (file);
12939 archive_file_size = archive_file_offset = 0;
12940 ret = process_object (file_name, file);
12941 }
12942
12943 fclose (file);
12944
12945 return ret;
12946}
12947
252b5132
RH
12948#ifdef SUPPORT_DISASSEMBLY
12949/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 12950 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 12951 symbols. */
252b5132
RH
12952
12953void
2cf0635d 12954print_address (unsigned int addr, FILE * outfile)
252b5132
RH
12955{
12956 fprintf (outfile,"0x%8.8x", addr);
12957}
12958
e3c8793a 12959/* Needed by the i386 disassembler. */
252b5132
RH
12960void
12961db_task_printsym (unsigned int addr)
12962{
12963 print_address (addr, stderr);
12964}
12965#endif
12966
12967int
2cf0635d 12968main (int argc, char ** argv)
252b5132 12969{
ff78d6d6
L
12970 int err;
12971
252b5132
RH
12972#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
12973 setlocale (LC_MESSAGES, "");
3882b010
L
12974#endif
12975#if defined (HAVE_SETLOCALE)
12976 setlocale (LC_CTYPE, "");
252b5132
RH
12977#endif
12978 bindtextdomain (PACKAGE, LOCALEDIR);
12979 textdomain (PACKAGE);
12980
869b9d07
MM
12981 expandargv (&argc, &argv);
12982
252b5132
RH
12983 parse_args (argc, argv);
12984
18bd398b 12985 if (num_dump_sects > 0)
59f14fc0 12986 {
18bd398b 12987 /* Make a copy of the dump_sects array. */
3f5e193b
NC
12988 cmdline_dump_sects = (dump_type *)
12989 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 12990 if (cmdline_dump_sects == NULL)
591a748a 12991 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
12992 else
12993 {
09c11c86
NC
12994 memcpy (cmdline_dump_sects, dump_sects,
12995 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
12996 num_cmdline_dump_sects = num_dump_sects;
12997 }
12998 }
12999
18bd398b
NC
13000 if (optind < (argc - 1))
13001 show_name = 1;
13002
ff78d6d6 13003 err = 0;
252b5132 13004 while (optind < argc)
18bd398b 13005 err |= process_file (argv[optind++]);
252b5132
RH
13006
13007 if (dump_sects != NULL)
13008 free (dump_sects);
59f14fc0
AS
13009 if (cmdline_dump_sects != NULL)
13010 free (cmdline_dump_sects);
252b5132 13011
ff78d6d6 13012 return err;
252b5132 13013}