]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
gdb
[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,
a0f19280
L
3 2008, 2009, 2010
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"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
252b5132 94#include "elf/alpha.h"
3b16e843 95#include "elf/arc.h"
252b5132 96#include "elf/arm.h"
3b16e843 97#include "elf/avr.h"
1d65ded4 98#include "elf/bfin.h"
60bca95a 99#include "elf/cr16.h"
3b16e843 100#include "elf/cris.h"
1c0d3aa6 101#include "elf/crx.h"
252b5132
RH
102#include "elf/d10v.h"
103#include "elf/d30v.h"
d172d4ba 104#include "elf/dlx.h"
252b5132 105#include "elf/fr30.h"
5c70f934 106#include "elf/frv.h"
3b16e843
NC
107#include "elf/h8.h"
108#include "elf/hppa.h"
109#include "elf/i386.h"
35b1837e 110#include "elf/i370.h"
3b16e843
NC
111#include "elf/i860.h"
112#include "elf/i960.h"
113#include "elf/ia64.h"
1e4cf259 114#include "elf/ip2k.h"
84e94c90 115#include "elf/lm32.h"
1c0d3aa6 116#include "elf/iq2000.h"
49f58d10 117#include "elf/m32c.h"
3b16e843
NC
118#include "elf/m32r.h"
119#include "elf/m68k.h"
75751cd9 120#include "elf/m68hc11.h"
252b5132 121#include "elf/mcore.h"
15ab5209 122#include "elf/mep.h"
7ba29e2a 123#include "elf/microblaze.h"
3b16e843 124#include "elf/mips.h"
3c3bdf30 125#include "elf/mmix.h"
3b16e843
NC
126#include "elf/mn10200.h"
127#include "elf/mn10300.h"
4970f871 128#include "elf/mt.h"
2469cfa2 129#include "elf/msp430.h"
3b16e843 130#include "elf/or32.h"
7d466069 131#include "elf/pj.h"
3b16e843 132#include "elf/ppc.h"
c833c019 133#include "elf/ppc64.h"
c7927a3c 134#include "elf/rx.h"
a85d7ed0 135#include "elf/s390.h"
1c0d3aa6 136#include "elf/score.h"
3b16e843
NC
137#include "elf/sh.h"
138#include "elf/sparc.h"
e9f53129 139#include "elf/spu.h"
3b16e843 140#include "elf/v850.h"
179d3252 141#include "elf/vax.h"
3b16e843 142#include "elf/x86-64.h"
c29aca4a 143#include "elf/xc16x.h"
93fbbb04 144#include "elf/xstormy16.h"
88da6820 145#include "elf/xtensa.h"
252b5132 146
fb52b2f4
NC
147#include "aout/ar.h"
148
252b5132 149#include "getopt.h"
566b0d53 150#include "libiberty.h"
09c11c86 151#include "safe-ctype.h"
2cf0635d 152#include "filenames.h"
252b5132 153
2cf0635d 154char * program_name = "readelf";
85b1c36d
BE
155static long archive_file_offset;
156static unsigned long archive_file_size;
157static unsigned long dynamic_addr;
158static bfd_size_type dynamic_size;
159static unsigned int dynamic_nent;
2cf0635d 160static char * dynamic_strings;
85b1c36d 161static unsigned long dynamic_strings_length;
2cf0635d 162static char * string_table;
85b1c36d
BE
163static unsigned long string_table_length;
164static unsigned long num_dynamic_syms;
2cf0635d
NC
165static Elf_Internal_Sym * dynamic_symbols;
166static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
167static unsigned long dynamic_syminfo_offset;
168static unsigned int dynamic_syminfo_nent;
f8eae8b2 169static char program_interpreter[PATH_MAX];
bb8a0291 170static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 171static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
172static bfd_vma version_info[16];
173static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
174static Elf_Internal_Shdr * section_headers;
175static Elf_Internal_Phdr * program_headers;
176static Elf_Internal_Dyn * dynamic_section;
177static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
178static int show_name;
179static int do_dynamic;
180static int do_syms;
2c610e4b 181static int do_dyn_syms;
85b1c36d
BE
182static int do_reloc;
183static int do_sections;
184static int do_section_groups;
5477e8a0 185static int do_section_details;
85b1c36d
BE
186static int do_segments;
187static int do_unwind;
188static int do_using_dynamic;
189static int do_header;
190static int do_dump;
191static int do_version;
85b1c36d
BE
192static int do_histogram;
193static int do_debugging;
85b1c36d
BE
194static int do_arch;
195static int do_notes;
4145f1d5 196static int do_archive_index;
85b1c36d 197static int is_32bit_elf;
252b5132 198
e4b17d5c
L
199struct group_list
200{
2cf0635d 201 struct group_list * next;
e4b17d5c
L
202 unsigned int section_index;
203};
204
205struct group
206{
2cf0635d 207 struct group_list * root;
e4b17d5c
L
208 unsigned int group_index;
209};
210
85b1c36d 211static size_t group_count;
2cf0635d
NC
212static struct group * section_groups;
213static struct group ** section_headers_groups;
e4b17d5c 214
09c11c86
NC
215
216/* Flag bits indicating particular types of dump. */
217#define HEX_DUMP (1 << 0) /* The -x command line switch. */
218#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
219#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
220#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 221#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
222
223typedef unsigned char dump_type;
224
225/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
226struct dump_list_entry
227{
2cf0635d 228 char * name;
09c11c86 229 dump_type type;
2cf0635d 230 struct dump_list_entry * next;
aef1f6d0 231};
2cf0635d 232static struct dump_list_entry * dump_sects_byname;
aef1f6d0 233
09c11c86
NC
234/* A dynamic array of flags indicating for which sections a dump
235 has been requested via command line switches. */
236static dump_type * cmdline_dump_sects = NULL;
237static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
238
239/* A dynamic array of flags indicating for which sections a dump of
240 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
241 basis and then initialised from the cmdline_dump_sects array,
242 the results of interpreting the -w switch, and the
243 dump_sects_byname list. */
09c11c86
NC
244static dump_type * dump_sects = NULL;
245static unsigned int num_dump_sects = 0;
252b5132 246
252b5132 247
c256ffe7 248/* How to print a vma value. */
843dd992
NC
249typedef enum print_mode
250{
251 HEX,
252 DEC,
253 DEC_5,
254 UNSIGNED,
255 PREFIX_HEX,
256 FULL_HEX,
257 LONG_HEX
258}
259print_mode;
260
2cf0635d 261static void (* byte_put) (unsigned char *, bfd_vma, int);
252b5132 262
9c19a809
NC
263#define UNKNOWN -1
264
0b49d371
NC
265#define SECTION_NAME(X) \
266 ((X) == NULL ? "<none>" \
267 : string_table == NULL ? "<no-name>" \
268 : ((X)->sh_name >= string_table_length ? "<corrupt>" \
269 : string_table + (X)->sh_name))
252b5132 270
ee42cf8c 271#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 272
7036c0e1 273#define BYTE_GET(field) byte_get (field, sizeof (field))
a952a375 274
9ad5cbcf
AM
275#define GET_ELF_SYMBOLS(file, section) \
276 (is_32bit_elf ? get_32bit_elf_symbols (file, section) \
277 : get_64bit_elf_symbols (file, section))
9ea033b2 278
d79b3d50
NC
279#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
280/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
281 already been called and verified that the string exists. */
282#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b
NC
283
284/* This is just a bit of syntatic sugar. */
60bca95a
NC
285#define streq(a,b) (strcmp ((a), (b)) == 0)
286#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
0112cd26 287#define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
0b6ae522
DJ
288
289#define REMOVE_ARCH_BITS(ADDR) do { \
290 if (elf_header.e_machine == EM_ARM) \
291 (ADDR) &= ~1; \
292 } while (0)
d79b3d50 293\f
c256ffe7 294static void *
2cf0635d
NC
295get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
296 const char * reason)
a6e9f9df 297{
2cf0635d 298 void * mvar;
a6e9f9df 299
c256ffe7 300 if (size == 0 || nmemb == 0)
a6e9f9df
AM
301 return NULL;
302
fb52b2f4 303 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 304 {
0fd3a477 305 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 306 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
307 return NULL;
308 }
309
310 mvar = var;
311 if (mvar == NULL)
312 {
c256ffe7
JJ
313 /* Check for overflow. */
314 if (nmemb < (~(size_t) 0 - 1) / size)
315 /* + 1 so that we can '\0' terminate invalid string table sections. */
316 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
317
318 if (mvar == NULL)
319 {
0fd3a477
JW
320 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
321 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
322 return NULL;
323 }
c256ffe7
JJ
324
325 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
326 }
327
c256ffe7 328 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 329 {
0fd3a477
JW
330 error (_("Unable to read in 0x%lx bytes of %s\n"),
331 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
332 if (mvar != var)
333 free (mvar);
334 return NULL;
335 }
336
337 return mvar;
338}
339
adab8cdc 340static void
2cf0635d 341byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
adab8cdc
AO
342{
343 switch (size)
344 {
345 case 8:
346 field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
347 field[6] = ((value >> 24) >> 24) & 0xff;
348 field[5] = ((value >> 24) >> 16) & 0xff;
349 field[4] = ((value >> 24) >> 8) & 0xff;
350 /* Fall through. */
351 case 4:
352 field[3] = (value >> 24) & 0xff;
4dc3c23d
AM
353 /* Fall through. */
354 case 3:
adab8cdc
AO
355 field[2] = (value >> 16) & 0xff;
356 /* Fall through. */
357 case 2:
358 field[1] = (value >> 8) & 0xff;
359 /* Fall through. */
360 case 1:
361 field[0] = value & 0xff;
362 break;
363
364 default:
365 error (_("Unhandled data length: %d\n"), size);
366 abort ();
367 }
368}
369
14a91970 370/* Print a VMA value. */
cb8f3167 371
66543521 372static int
14a91970 373print_vma (bfd_vma vma, print_mode mode)
66543521 374{
66543521
AM
375 int nc = 0;
376
14a91970 377 switch (mode)
66543521 378 {
14a91970
AM
379 case FULL_HEX:
380 nc = printf ("0x");
381 /* Drop through. */
66543521 382
14a91970 383 case LONG_HEX:
f7a99963 384#ifdef BFD64
14a91970 385 if (is_32bit_elf)
437c2fb7 386 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 387#endif
14a91970
AM
388 printf_vma (vma);
389 return nc + 16;
b19aac67 390
14a91970
AM
391 case DEC_5:
392 if (vma <= 99999)
393 return printf ("%5" BFD_VMA_FMT "d", vma);
394 /* Drop through. */
66543521 395
14a91970
AM
396 case PREFIX_HEX:
397 nc = printf ("0x");
398 /* Drop through. */
66543521 399
14a91970
AM
400 case HEX:
401 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 402
14a91970
AM
403 case DEC:
404 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 405
14a91970
AM
406 case UNSIGNED:
407 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 408 }
66543521 409 return 0;
f7a99963
NC
410}
411
171191ba 412/* Display a symbol on stdout. Handles the display of non-printing characters.
31104126 413
171191ba
NC
414 If DO_WIDE is not true then format the symbol to be at most WIDTH characters,
415 truncating as necessary. If WIDTH is negative then format the string to be
416 exactly - WIDTH characters, truncating or padding as necessary.
417
418 Returns the number of emitted characters. */
419
420static unsigned int
2cf0635d 421print_symbol (int width, const char * symbol)
31104126 422{
961c521f 423 const char * c;
171191ba
NC
424 bfd_boolean extra_padding = FALSE;
425 unsigned int num_printed = 0;
961c521f 426
31104126 427 if (do_wide)
961c521f 428 {
961c521f
NC
429 /* Set the width to a very large value. This simplifies the code below. */
430 width = INT_MAX;
431 }
31104126 432 else if (width < 0)
961c521f 433 {
961c521f
NC
434 /* Keep the width positive. This also helps. */
435 width = - width;
171191ba 436 extra_padding = TRUE;
961c521f
NC
437 }
438
439 while (width)
440 {
441 int len;
442
443 c = symbol;
444
445 /* Look for non-printing symbols inside the symbol's name.
446 This test is triggered in particular by the names generated
447 by the assembler for local labels. */
448 while (ISPRINT (* c))
449 c++;
450
451 len = c - symbol;
452
453 if (len)
454 {
455 if (len > width)
456 len = width;
cb8f3167 457
171191ba 458 printf ("%.*s", len, symbol);
961c521f
NC
459
460 width -= len;
171191ba 461 num_printed += len;
961c521f
NC
462 }
463
464 if (* c == 0 || width == 0)
465 break;
466
467 /* Now display the non-printing character, if
468 there is room left in which to dipslay it. */
469 if (*c < 32)
470 {
471 if (width < 2)
472 break;
473
474 printf ("^%c", *c + 0x40);
475
476 width -= 2;
171191ba 477 num_printed += 2;
961c521f
NC
478 }
479 else
480 {
481 if (width < 6)
482 break;
cb8f3167 483
961c521f
NC
484 printf ("<0x%.2x>", *c);
485
486 width -= 6;
171191ba 487 num_printed += 6;
961c521f
NC
488 }
489
490 symbol = c + 1;
491 }
171191ba
NC
492
493 if (extra_padding && width > 0)
494 {
495 /* Fill in the remaining spaces. */
496 printf ("%-*s", width, " ");
497 num_printed += 2;
498 }
499
500 return num_printed;
31104126
NC
501}
502
adab8cdc 503static void
2cf0635d 504byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
adab8cdc
AO
505{
506 switch (size)
507 {
508 case 8:
509 field[7] = value & 0xff;
510 field[6] = (value >> 8) & 0xff;
511 field[5] = (value >> 16) & 0xff;
512 field[4] = (value >> 24) & 0xff;
513 value >>= 16;
514 value >>= 16;
515 /* Fall through. */
516 case 4:
517 field[3] = value & 0xff;
4dc3c23d
AM
518 value >>= 8;
519 /* Fall through. */
520 case 3:
521 field[2] = value & 0xff;
522 value >>= 8;
adab8cdc
AO
523 /* Fall through. */
524 case 2:
525 field[1] = value & 0xff;
526 value >>= 8;
527 /* Fall through. */
528 case 1:
529 field[0] = value & 0xff;
530 break;
531
532 default:
533 error (_("Unhandled data length: %d\n"), size);
534 abort ();
535 }
536}
537
89fac5e3
RS
538/* Return a pointer to section NAME, or NULL if no such section exists. */
539
540static Elf_Internal_Shdr *
2cf0635d 541find_section (const char * name)
89fac5e3
RS
542{
543 unsigned int i;
544
545 for (i = 0; i < elf_header.e_shnum; i++)
546 if (streq (SECTION_NAME (section_headers + i), name))
547 return section_headers + i;
548
549 return NULL;
550}
551
0b6ae522
DJ
552/* Return a pointer to a section containing ADDR, or NULL if no such
553 section exists. */
554
555static Elf_Internal_Shdr *
556find_section_by_address (bfd_vma addr)
557{
558 unsigned int i;
559
560 for (i = 0; i < elf_header.e_shnum; i++)
561 {
562 Elf_Internal_Shdr *sec = section_headers + i;
563 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
564 return sec;
565 }
566
567 return NULL;
568}
569
570/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
571 bytes read. */
572
573static unsigned long
574read_uleb128 (unsigned char *data, unsigned int *length_return)
575{
576 return read_leb128 (data, length_return, 0);
577}
578
bcedfee6 579/* Guess the relocation size commonly used by the specific machines. */
252b5132 580
252b5132 581static int
2dc4cec1 582guess_is_rela (unsigned int e_machine)
252b5132 583{
9c19a809 584 switch (e_machine)
252b5132
RH
585 {
586 /* Targets that use REL relocations. */
252b5132
RH
587 case EM_386:
588 case EM_486:
63fcb9e9 589 case EM_960:
e9f53129 590 case EM_ARM:
2b0337b0 591 case EM_D10V:
252b5132 592 case EM_CYGNUS_D10V:
e9f53129 593 case EM_DLX:
252b5132 594 case EM_MIPS:
4fe85591 595 case EM_MIPS_RS3_LE:
e9f53129
AM
596 case EM_CYGNUS_M32R:
597 case EM_OPENRISC:
598 case EM_OR32:
1c0d3aa6 599 case EM_SCORE:
9c19a809 600 return FALSE;
103f02d3 601
252b5132
RH
602 /* Targets that use RELA relocations. */
603 case EM_68K:
e9f53129
AM
604 case EM_860:
605 case EM_ALPHA:
606 case EM_ALTERA_NIOS2:
607 case EM_AVR:
608 case EM_AVR_OLD:
609 case EM_BLACKFIN:
60bca95a 610 case EM_CR16:
6c03b1ed 611 case EM_CR16_OLD:
e9f53129
AM
612 case EM_CRIS:
613 case EM_CRX:
2b0337b0 614 case EM_D30V:
252b5132 615 case EM_CYGNUS_D30V:
2b0337b0 616 case EM_FR30:
252b5132 617 case EM_CYGNUS_FR30:
5c70f934 618 case EM_CYGNUS_FRV:
e9f53129
AM
619 case EM_H8S:
620 case EM_H8_300:
621 case EM_H8_300H:
800eeca4 622 case EM_IA_64:
1e4cf259
NC
623 case EM_IP2K:
624 case EM_IP2K_OLD:
3b36097d 625 case EM_IQ2000:
84e94c90 626 case EM_LATTICEMICO32:
ff7eeb89 627 case EM_M32C_OLD:
49f58d10 628 case EM_M32C:
e9f53129
AM
629 case EM_M32R:
630 case EM_MCORE:
15ab5209 631 case EM_CYGNUS_MEP:
e9f53129
AM
632 case EM_MMIX:
633 case EM_MN10200:
634 case EM_CYGNUS_MN10200:
635 case EM_MN10300:
636 case EM_CYGNUS_MN10300:
637 case EM_MSP430:
638 case EM_MSP430_OLD:
d031aafb 639 case EM_MT:
64fd6348 640 case EM_NIOS32:
e9f53129
AM
641 case EM_PPC64:
642 case EM_PPC:
c7927a3c 643 case EM_RX:
e9f53129
AM
644 case EM_S390:
645 case EM_S390_OLD:
646 case EM_SH:
647 case EM_SPARC:
648 case EM_SPARC32PLUS:
649 case EM_SPARCV9:
650 case EM_SPU:
651 case EM_V850:
652 case EM_CYGNUS_V850:
653 case EM_VAX:
654 case EM_X86_64:
8a9036a4 655 case EM_L1OM:
e9f53129
AM
656 case EM_XSTORMY16:
657 case EM_XTENSA:
658 case EM_XTENSA_OLD:
7ba29e2a
NC
659 case EM_MICROBLAZE:
660 case EM_MICROBLAZE_OLD:
9c19a809 661 return TRUE;
103f02d3 662
e9f53129
AM
663 case EM_68HC05:
664 case EM_68HC08:
665 case EM_68HC11:
666 case EM_68HC16:
667 case EM_FX66:
668 case EM_ME16:
d1133906 669 case EM_MMA:
d1133906
NC
670 case EM_NCPU:
671 case EM_NDR1:
e9f53129 672 case EM_PCP:
d1133906 673 case EM_ST100:
e9f53129 674 case EM_ST19:
d1133906 675 case EM_ST7:
e9f53129
AM
676 case EM_ST9PLUS:
677 case EM_STARCORE:
d1133906 678 case EM_SVX:
e9f53129 679 case EM_TINYJ:
9c19a809
NC
680 default:
681 warn (_("Don't know about relocations on this machine architecture\n"));
682 return FALSE;
683 }
684}
252b5132 685
9c19a809 686static int
2cf0635d 687slurp_rela_relocs (FILE * file,
d3ba0551
AM
688 unsigned long rel_offset,
689 unsigned long rel_size,
2cf0635d
NC
690 Elf_Internal_Rela ** relasp,
691 unsigned long * nrelasp)
9c19a809 692{
2cf0635d 693 Elf_Internal_Rela * relas;
4d6ed7c8
NC
694 unsigned long nrelas;
695 unsigned int i;
252b5132 696
4d6ed7c8
NC
697 if (is_32bit_elf)
698 {
2cf0635d 699 Elf32_External_Rela * erelas;
103f02d3 700
3f5e193b
NC
701 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
702 rel_size, _("relocs"));
a6e9f9df
AM
703 if (!erelas)
704 return 0;
252b5132 705
4d6ed7c8 706 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 707
3f5e193b
NC
708 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
709 sizeof (Elf_Internal_Rela));
103f02d3 710
4d6ed7c8
NC
711 if (relas == NULL)
712 {
c256ffe7 713 free (erelas);
591a748a 714 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
715 return 0;
716 }
103f02d3 717
4d6ed7c8
NC
718 for (i = 0; i < nrelas; i++)
719 {
720 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
721 relas[i].r_info = BYTE_GET (erelas[i].r_info);
722 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
723 }
103f02d3 724
4d6ed7c8
NC
725 free (erelas);
726 }
727 else
728 {
2cf0635d 729 Elf64_External_Rela * erelas;
103f02d3 730
3f5e193b
NC
731 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
732 rel_size, _("relocs"));
a6e9f9df
AM
733 if (!erelas)
734 return 0;
4d6ed7c8
NC
735
736 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 737
3f5e193b
NC
738 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
739 sizeof (Elf_Internal_Rela));
103f02d3 740
4d6ed7c8
NC
741 if (relas == NULL)
742 {
c256ffe7 743 free (erelas);
591a748a 744 error (_("out of memory parsing relocs\n"));
4d6ed7c8 745 return 0;
9c19a809 746 }
4d6ed7c8
NC
747
748 for (i = 0; i < nrelas; i++)
9c19a809 749 {
66543521
AM
750 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
751 relas[i].r_info = BYTE_GET (erelas[i].r_info);
752 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
861fb55a
DJ
753
754 /* The #ifdef BFD64 below is to prevent a compile time
755 warning. We know that if we do not have a 64 bit data
756 type that we will never execute this code anyway. */
757#ifdef BFD64
758 if (elf_header.e_machine == EM_MIPS
759 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
760 {
761 /* In little-endian objects, r_info isn't really a
762 64-bit little-endian value: it has a 32-bit
763 little-endian symbol index followed by four
764 individual byte fields. Reorder INFO
765 accordingly. */
91d6fa6a
NC
766 bfd_vma inf = relas[i].r_info;
767 inf = (((inf & 0xffffffff) << 32)
768 | ((inf >> 56) & 0xff)
769 | ((inf >> 40) & 0xff00)
770 | ((inf >> 24) & 0xff0000)
771 | ((inf >> 8) & 0xff000000));
772 relas[i].r_info = inf;
861fb55a
DJ
773 }
774#endif /* BFD64 */
4d6ed7c8 775 }
103f02d3 776
4d6ed7c8
NC
777 free (erelas);
778 }
779 *relasp = relas;
780 *nrelasp = nrelas;
781 return 1;
782}
103f02d3 783
4d6ed7c8 784static int
2cf0635d 785slurp_rel_relocs (FILE * file,
d3ba0551
AM
786 unsigned long rel_offset,
787 unsigned long rel_size,
2cf0635d
NC
788 Elf_Internal_Rela ** relsp,
789 unsigned long * nrelsp)
4d6ed7c8 790{
2cf0635d 791 Elf_Internal_Rela * rels;
4d6ed7c8
NC
792 unsigned long nrels;
793 unsigned int i;
103f02d3 794
4d6ed7c8
NC
795 if (is_32bit_elf)
796 {
2cf0635d 797 Elf32_External_Rel * erels;
103f02d3 798
3f5e193b
NC
799 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
800 rel_size, _("relocs"));
a6e9f9df
AM
801 if (!erels)
802 return 0;
103f02d3 803
4d6ed7c8 804 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 805
3f5e193b 806 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 807
4d6ed7c8
NC
808 if (rels == NULL)
809 {
c256ffe7 810 free (erels);
591a748a 811 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
812 return 0;
813 }
814
815 for (i = 0; i < nrels; i++)
816 {
817 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
818 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 819 rels[i].r_addend = 0;
9ea033b2 820 }
4d6ed7c8
NC
821
822 free (erels);
9c19a809
NC
823 }
824 else
825 {
2cf0635d 826 Elf64_External_Rel * erels;
9ea033b2 827
3f5e193b
NC
828 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
829 rel_size, _("relocs"));
a6e9f9df
AM
830 if (!erels)
831 return 0;
103f02d3 832
4d6ed7c8 833 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 834
3f5e193b 835 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 836
4d6ed7c8 837 if (rels == NULL)
9c19a809 838 {
c256ffe7 839 free (erels);
591a748a 840 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
841 return 0;
842 }
103f02d3 843
4d6ed7c8
NC
844 for (i = 0; i < nrels; i++)
845 {
66543521
AM
846 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
847 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 848 rels[i].r_addend = 0;
861fb55a
DJ
849
850 /* The #ifdef BFD64 below is to prevent a compile time
851 warning. We know that if we do not have a 64 bit data
852 type that we will never execute this code anyway. */
853#ifdef BFD64
854 if (elf_header.e_machine == EM_MIPS
855 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
856 {
857 /* In little-endian objects, r_info isn't really a
858 64-bit little-endian value: it has a 32-bit
859 little-endian symbol index followed by four
860 individual byte fields. Reorder INFO
861 accordingly. */
91d6fa6a
NC
862 bfd_vma inf = rels[i].r_info;
863 inf = (((inf & 0xffffffff) << 32)
864 | ((inf >> 56) & 0xff)
865 | ((inf >> 40) & 0xff00)
866 | ((inf >> 24) & 0xff0000)
867 | ((inf >> 8) & 0xff000000));
868 rels[i].r_info = inf;
861fb55a
DJ
869 }
870#endif /* BFD64 */
4d6ed7c8 871 }
103f02d3 872
4d6ed7c8
NC
873 free (erels);
874 }
875 *relsp = rels;
876 *nrelsp = nrels;
877 return 1;
878}
103f02d3 879
aca88567
NC
880/* Returns the reloc type extracted from the reloc info field. */
881
882static unsigned int
883get_reloc_type (bfd_vma reloc_info)
884{
885 if (is_32bit_elf)
886 return ELF32_R_TYPE (reloc_info);
887
888 switch (elf_header.e_machine)
889 {
890 case EM_MIPS:
891 /* Note: We assume that reloc_info has already been adjusted for us. */
892 return ELF64_MIPS_R_TYPE (reloc_info);
893
894 case EM_SPARCV9:
895 return ELF64_R_TYPE_ID (reloc_info);
896
897 default:
898 return ELF64_R_TYPE (reloc_info);
899 }
900}
901
902/* Return the symbol index extracted from the reloc info field. */
903
904static bfd_vma
905get_reloc_symindex (bfd_vma reloc_info)
906{
907 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
908}
909
d3ba0551
AM
910/* Display the contents of the relocation data found at the specified
911 offset. */
ee42cf8c 912
41e92641 913static void
2cf0635d 914dump_relocations (FILE * file,
d3ba0551
AM
915 unsigned long rel_offset,
916 unsigned long rel_size,
2cf0635d 917 Elf_Internal_Sym * symtab,
d3ba0551 918 unsigned long nsyms,
2cf0635d 919 char * strtab,
d79b3d50 920 unsigned long strtablen,
d3ba0551 921 int is_rela)
4d6ed7c8 922{
b34976b6 923 unsigned int i;
2cf0635d 924 Elf_Internal_Rela * rels;
103f02d3 925
4d6ed7c8
NC
926 if (is_rela == UNKNOWN)
927 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 928
4d6ed7c8
NC
929 if (is_rela)
930 {
c8286bd1 931 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 932 return;
4d6ed7c8
NC
933 }
934 else
935 {
936 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 937 return;
252b5132
RH
938 }
939
410f7a12
L
940 if (is_32bit_elf)
941 {
942 if (is_rela)
2c71103e
NC
943 {
944 if (do_wide)
945 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
946 else
947 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
948 }
410f7a12 949 else
2c71103e
NC
950 {
951 if (do_wide)
952 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
953 else
954 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
955 }
410f7a12 956 }
252b5132 957 else
410f7a12
L
958 {
959 if (is_rela)
2c71103e
NC
960 {
961 if (do_wide)
8beeaeb7 962 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
963 else
964 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
965 }
410f7a12 966 else
2c71103e
NC
967 {
968 if (do_wide)
8beeaeb7 969 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
970 else
971 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
972 }
410f7a12 973 }
252b5132
RH
974
975 for (i = 0; i < rel_size; i++)
976 {
2cf0635d 977 const char * rtype;
b34976b6 978 bfd_vma offset;
91d6fa6a 979 bfd_vma inf;
b34976b6
AM
980 bfd_vma symtab_index;
981 bfd_vma type;
103f02d3 982
b34976b6 983 offset = rels[i].r_offset;
91d6fa6a 984 inf = rels[i].r_info;
103f02d3 985
91d6fa6a
NC
986 type = get_reloc_type (inf);
987 symtab_index = get_reloc_symindex (inf);
252b5132 988
410f7a12
L
989 if (is_32bit_elf)
990 {
39dbeff8
AM
991 printf ("%8.8lx %8.8lx ",
992 (unsigned long) offset & 0xffffffff,
91d6fa6a 993 (unsigned long) inf & 0xffffffff);
410f7a12
L
994 }
995 else
996 {
39dbeff8
AM
997#if BFD_HOST_64BIT_LONG
998 printf (do_wide
999 ? "%16.16lx %16.16lx "
1000 : "%12.12lx %12.12lx ",
91d6fa6a 1001 offset, inf);
39dbeff8 1002#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1003#ifndef __MSVCRT__
39dbeff8
AM
1004 printf (do_wide
1005 ? "%16.16llx %16.16llx "
1006 : "%12.12llx %12.12llx ",
91d6fa6a 1007 offset, inf);
6e3d6dc1
NC
1008#else
1009 printf (do_wide
1010 ? "%16.16I64x %16.16I64x "
1011 : "%12.12I64x %12.12I64x ",
91d6fa6a 1012 offset, inf);
6e3d6dc1 1013#endif
39dbeff8 1014#else
2c71103e
NC
1015 printf (do_wide
1016 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1017 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1018 _bfd_int64_high (offset),
1019 _bfd_int64_low (offset),
91d6fa6a
NC
1020 _bfd_int64_high (inf),
1021 _bfd_int64_low (inf));
9ea033b2 1022#endif
410f7a12 1023 }
103f02d3 1024
252b5132
RH
1025 switch (elf_header.e_machine)
1026 {
1027 default:
1028 rtype = NULL;
1029 break;
1030
2b0337b0 1031 case EM_M32R:
252b5132 1032 case EM_CYGNUS_M32R:
9ea033b2 1033 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1034 break;
1035
1036 case EM_386:
1037 case EM_486:
9ea033b2 1038 rtype = elf_i386_reloc_type (type);
252b5132
RH
1039 break;
1040
ba2685cc
AM
1041 case EM_68HC11:
1042 case EM_68HC12:
1043 rtype = elf_m68hc11_reloc_type (type);
1044 break;
75751cd9 1045
252b5132 1046 case EM_68K:
9ea033b2 1047 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1048 break;
1049
63fcb9e9 1050 case EM_960:
9ea033b2 1051 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1052 break;
1053
adde6300 1054 case EM_AVR:
2b0337b0 1055 case EM_AVR_OLD:
adde6300
AM
1056 rtype = elf_avr_reloc_type (type);
1057 break;
1058
9ea033b2
NC
1059 case EM_OLD_SPARCV9:
1060 case EM_SPARC32PLUS:
1061 case EM_SPARCV9:
252b5132 1062 case EM_SPARC:
9ea033b2 1063 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1064 break;
1065
e9f53129
AM
1066 case EM_SPU:
1067 rtype = elf_spu_reloc_type (type);
1068 break;
1069
2b0337b0 1070 case EM_V850:
252b5132 1071 case EM_CYGNUS_V850:
9ea033b2 1072 rtype = v850_reloc_type (type);
252b5132
RH
1073 break;
1074
2b0337b0 1075 case EM_D10V:
252b5132 1076 case EM_CYGNUS_D10V:
9ea033b2 1077 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1078 break;
1079
2b0337b0 1080 case EM_D30V:
252b5132 1081 case EM_CYGNUS_D30V:
9ea033b2 1082 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1083 break;
1084
d172d4ba
NC
1085 case EM_DLX:
1086 rtype = elf_dlx_reloc_type (type);
1087 break;
1088
252b5132 1089 case EM_SH:
9ea033b2 1090 rtype = elf_sh_reloc_type (type);
252b5132
RH
1091 break;
1092
2b0337b0 1093 case EM_MN10300:
252b5132 1094 case EM_CYGNUS_MN10300:
9ea033b2 1095 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1096 break;
1097
2b0337b0 1098 case EM_MN10200:
252b5132 1099 case EM_CYGNUS_MN10200:
9ea033b2 1100 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1101 break;
1102
2b0337b0 1103 case EM_FR30:
252b5132 1104 case EM_CYGNUS_FR30:
9ea033b2 1105 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1106 break;
1107
ba2685cc
AM
1108 case EM_CYGNUS_FRV:
1109 rtype = elf_frv_reloc_type (type);
1110 break;
5c70f934 1111
252b5132 1112 case EM_MCORE:
9ea033b2 1113 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1114 break;
1115
3c3bdf30
NC
1116 case EM_MMIX:
1117 rtype = elf_mmix_reloc_type (type);
1118 break;
1119
2469cfa2
NC
1120 case EM_MSP430:
1121 case EM_MSP430_OLD:
1122 rtype = elf_msp430_reloc_type (type);
1123 break;
1124
252b5132 1125 case EM_PPC:
9ea033b2 1126 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1127 break;
1128
c833c019
AM
1129 case EM_PPC64:
1130 rtype = elf_ppc64_reloc_type (type);
1131 break;
1132
252b5132 1133 case EM_MIPS:
4fe85591 1134 case EM_MIPS_RS3_LE:
9ea033b2 1135 rtype = elf_mips_reloc_type (type);
252b5132
RH
1136 break;
1137
1138 case EM_ALPHA:
9ea033b2 1139 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1140 break;
1141
1142 case EM_ARM:
9ea033b2 1143 rtype = elf_arm_reloc_type (type);
252b5132
RH
1144 break;
1145
584da044 1146 case EM_ARC:
9ea033b2 1147 rtype = elf_arc_reloc_type (type);
252b5132
RH
1148 break;
1149
1150 case EM_PARISC:
69e617ca 1151 rtype = elf_hppa_reloc_type (type);
252b5132 1152 break;
7d466069 1153
b8720f9d
JL
1154 case EM_H8_300:
1155 case EM_H8_300H:
1156 case EM_H8S:
1157 rtype = elf_h8_reloc_type (type);
1158 break;
1159
3b16e843
NC
1160 case EM_OPENRISC:
1161 case EM_OR32:
1162 rtype = elf_or32_reloc_type (type);
1163 break;
1164
7d466069 1165 case EM_PJ:
2b0337b0 1166 case EM_PJ_OLD:
7d466069
ILT
1167 rtype = elf_pj_reloc_type (type);
1168 break;
800eeca4
JW
1169 case EM_IA_64:
1170 rtype = elf_ia64_reloc_type (type);
1171 break;
1b61cf92
HPN
1172
1173 case EM_CRIS:
1174 rtype = elf_cris_reloc_type (type);
1175 break;
535c37ff
JE
1176
1177 case EM_860:
1178 rtype = elf_i860_reloc_type (type);
1179 break;
bcedfee6
NC
1180
1181 case EM_X86_64:
8a9036a4 1182 case EM_L1OM:
bcedfee6
NC
1183 rtype = elf_x86_64_reloc_type (type);
1184 break;
a85d7ed0 1185
35b1837e
AM
1186 case EM_S370:
1187 rtype = i370_reloc_type (type);
1188 break;
1189
53c7db4b
KH
1190 case EM_S390_OLD:
1191 case EM_S390:
1192 rtype = elf_s390_reloc_type (type);
1193 break;
93fbbb04 1194
1c0d3aa6
NC
1195 case EM_SCORE:
1196 rtype = elf_score_reloc_type (type);
1197 break;
1198
93fbbb04
GK
1199 case EM_XSTORMY16:
1200 rtype = elf_xstormy16_reloc_type (type);
1201 break;
179d3252 1202
1fe1f39c
NC
1203 case EM_CRX:
1204 rtype = elf_crx_reloc_type (type);
1205 break;
1206
179d3252
JT
1207 case EM_VAX:
1208 rtype = elf_vax_reloc_type (type);
1209 break;
1e4cf259
NC
1210
1211 case EM_IP2K:
1212 case EM_IP2K_OLD:
1213 rtype = elf_ip2k_reloc_type (type);
1214 break;
3b36097d
SC
1215
1216 case EM_IQ2000:
1217 rtype = elf_iq2000_reloc_type (type);
1218 break;
88da6820
NC
1219
1220 case EM_XTENSA_OLD:
1221 case EM_XTENSA:
1222 rtype = elf_xtensa_reloc_type (type);
1223 break;
a34e3ecb 1224
84e94c90
NC
1225 case EM_LATTICEMICO32:
1226 rtype = elf_lm32_reloc_type (type);
1227 break;
1228
ff7eeb89 1229 case EM_M32C_OLD:
49f58d10
JB
1230 case EM_M32C:
1231 rtype = elf_m32c_reloc_type (type);
1232 break;
1233
d031aafb
NS
1234 case EM_MT:
1235 rtype = elf_mt_reloc_type (type);
a34e3ecb 1236 break;
1d65ded4
CM
1237
1238 case EM_BLACKFIN:
1239 rtype = elf_bfin_reloc_type (type);
1240 break;
15ab5209
DB
1241
1242 case EM_CYGNUS_MEP:
1243 rtype = elf_mep_reloc_type (type);
1244 break;
60bca95a
NC
1245
1246 case EM_CR16:
6c03b1ed 1247 case EM_CR16_OLD:
60bca95a
NC
1248 rtype = elf_cr16_reloc_type (type);
1249 break;
7ba29e2a
NC
1250
1251 case EM_MICROBLAZE:
1252 case EM_MICROBLAZE_OLD:
1253 rtype = elf_microblaze_reloc_type (type);
1254 break;
c7927a3c
NC
1255
1256 case EM_RX:
1257 rtype = elf_rx_reloc_type (type);
1258 break;
c29aca4a
NC
1259
1260 case EM_XC16X:
1261 case EM_C166:
1262 rtype = elf_xc16x_reloc_type (type);
1263 break;
252b5132
RH
1264 }
1265
1266 if (rtype == NULL)
39dbeff8 1267 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1268 else
8beeaeb7 1269 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1270
7ace3541 1271 if (elf_header.e_machine == EM_ALPHA
157c2599 1272 && rtype != NULL
7ace3541
RH
1273 && streq (rtype, "R_ALPHA_LITUSE")
1274 && is_rela)
1275 {
1276 switch (rels[i].r_addend)
1277 {
1278 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1279 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1280 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1281 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1282 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1283 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1284 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1285 default: rtype = NULL;
1286 }
1287 if (rtype)
1288 printf (" (%s)", rtype);
1289 else
1290 {
1291 putchar (' ');
1292 printf (_("<unknown addend: %lx>"),
1293 (unsigned long) rels[i].r_addend);
1294 }
1295 }
1296 else if (symtab_index)
252b5132 1297 {
af3fc3bc
AM
1298 if (symtab == NULL || symtab_index >= nsyms)
1299 printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
1300 else
19936277 1301 {
2cf0635d 1302 Elf_Internal_Sym * psym;
19936277 1303
af3fc3bc 1304 psym = symtab + symtab_index;
103f02d3 1305
af3fc3bc 1306 printf (" ");
171191ba 1307
d8045f23
NC
1308 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1309 {
1310 const char * name;
1311 unsigned int len;
1312 unsigned int width = is_32bit_elf ? 8 : 14;
1313
1314 /* Relocations against GNU_IFUNC symbols do not use the value
1315 of the symbol as the address to relocate against. Instead
1316 they invoke the function named by the symbol and use its
1317 result as the address for relocation.
1318
1319 To indicate this to the user, do not display the value of
1320 the symbol in the "Symbols's Value" field. Instead show
1321 its name followed by () as a hint that the symbol is
1322 invoked. */
1323
1324 if (strtab == NULL
1325 || psym->st_name == 0
1326 || psym->st_name >= strtablen)
1327 name = "??";
1328 else
1329 name = strtab + psym->st_name;
1330
1331 len = print_symbol (width, name);
1332 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1333 }
1334 else
1335 {
1336 print_vma (psym->st_value, LONG_HEX);
171191ba 1337
d8045f23
NC
1338 printf (is_32bit_elf ? " " : " ");
1339 }
103f02d3 1340
af3fc3bc 1341 if (psym->st_name == 0)
f1ef08cb 1342 {
2cf0635d 1343 const char * sec_name = "<null>";
f1ef08cb
AM
1344 char name_buf[40];
1345
1346 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1347 {
4fbb74a6
AM
1348 if (psym->st_shndx < elf_header.e_shnum)
1349 sec_name
1350 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1351 else if (psym->st_shndx == SHN_ABS)
1352 sec_name = "ABS";
1353 else if (psym->st_shndx == SHN_COMMON)
1354 sec_name = "COMMON";
172553c7
TS
1355 else if (elf_header.e_machine == EM_MIPS
1356 && psym->st_shndx == SHN_MIPS_SCOMMON)
1357 sec_name = "SCOMMON";
1358 else if (elf_header.e_machine == EM_MIPS
1359 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1360 sec_name = "SUNDEF";
8a9036a4
L
1361 else if ((elf_header.e_machine == EM_X86_64
1362 || elf_header.e_machine == EM_L1OM)
3b22753a
L
1363 && psym->st_shndx == SHN_X86_64_LCOMMON)
1364 sec_name = "LARGE_COMMON";
9ce701e2
L
1365 else if (elf_header.e_machine == EM_IA_64
1366 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1367 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1368 sec_name = "ANSI_COM";
148b93f2 1369 else if (elf_header.e_machine == EM_IA_64
cb8f3167 1370 && (elf_header.e_ident[EI_OSABI]
148b93f2
NC
1371 == ELFOSABI_OPENVMS)
1372 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1373 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1374 else
1375 {
1376 sprintf (name_buf, "<section 0x%x>",
1377 (unsigned int) psym->st_shndx);
1378 sec_name = name_buf;
1379 }
1380 }
1381 print_symbol (22, sec_name);
1382 }
af3fc3bc 1383 else if (strtab == NULL)
d79b3d50 1384 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1385 else if (psym->st_name >= strtablen)
d79b3d50 1386 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1387 else
2c71103e 1388 print_symbol (22, strtab + psym->st_name);
103f02d3 1389
af3fc3bc 1390 if (is_rela)
171191ba 1391 {
91d6fa6a 1392 long off = (long) (bfd_signed_vma) rels[i].r_addend;
171191ba 1393
91d6fa6a
NC
1394 if (off < 0)
1395 printf (" - %lx", - off);
171191ba 1396 else
91d6fa6a 1397 printf (" + %lx", off);
171191ba 1398 }
19936277 1399 }
252b5132 1400 }
1b228002 1401 else if (is_rela)
f7a99963 1402 {
18bd398b
NC
1403 printf ("%*c", is_32bit_elf ?
1404 (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
c8286bd1 1405 print_vma (rels[i].r_addend, LONG_HEX);
f7a99963 1406 }
252b5132 1407
157c2599
NC
1408 if (elf_header.e_machine == EM_SPARCV9
1409 && rtype != NULL
1410 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1411 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1412
252b5132 1413 putchar ('\n');
2c71103e 1414
aca88567 1415#ifdef BFD64
53c7db4b 1416 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1417 {
91d6fa6a
NC
1418 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1419 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1420 const char * rtype2 = elf_mips_reloc_type (type2);
1421 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1422
2c71103e
NC
1423 printf (" Type2: ");
1424
1425 if (rtype2 == NULL)
39dbeff8
AM
1426 printf (_("unrecognized: %-7lx"),
1427 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1428 else
1429 printf ("%-17.17s", rtype2);
1430
18bd398b 1431 printf ("\n Type3: ");
2c71103e
NC
1432
1433 if (rtype3 == NULL)
39dbeff8
AM
1434 printf (_("unrecognized: %-7lx"),
1435 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1436 else
1437 printf ("%-17.17s", rtype3);
1438
53c7db4b 1439 putchar ('\n');
2c71103e 1440 }
aca88567 1441#endif /* BFD64 */
252b5132
RH
1442 }
1443
c8286bd1 1444 free (rels);
252b5132
RH
1445}
1446
1447static const char *
d3ba0551 1448get_mips_dynamic_type (unsigned long type)
252b5132
RH
1449{
1450 switch (type)
1451 {
1452 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1453 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1454 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1455 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1456 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1457 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1458 case DT_MIPS_MSYM: return "MIPS_MSYM";
1459 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1460 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1461 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1462 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1463 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1464 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1465 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1466 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1467 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1468 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1469 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1470 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1471 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1472 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1473 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1474 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1475 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1476 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1477 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1478 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1479 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1480 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1481 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1482 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1483 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1484 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1485 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1486 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1487 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1488 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1489 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1490 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1491 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1492 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1493 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1494 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1495 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1496 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1497 default:
1498 return NULL;
1499 }
1500}
1501
9a097730 1502static const char *
d3ba0551 1503get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1504{
1505 switch (type)
1506 {
1507 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1508 default:
1509 return NULL;
1510 }
103f02d3
UD
1511}
1512
7490d522
AM
1513static const char *
1514get_ppc_dynamic_type (unsigned long type)
1515{
1516 switch (type)
1517 {
a7f2871e
AM
1518 case DT_PPC_GOT: return "PPC_GOT";
1519 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1520 default:
1521 return NULL;
1522 }
1523}
1524
f1cb7e17 1525static const char *
d3ba0551 1526get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1527{
1528 switch (type)
1529 {
a7f2871e
AM
1530 case DT_PPC64_GLINK: return "PPC64_GLINK";
1531 case DT_PPC64_OPD: return "PPC64_OPD";
1532 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1533 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1534 default:
1535 return NULL;
1536 }
1537}
1538
103f02d3 1539static const char *
d3ba0551 1540get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1541{
1542 switch (type)
1543 {
1544 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1545 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1546 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1547 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1548 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1549 case DT_HP_PREINIT: return "HP_PREINIT";
1550 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1551 case DT_HP_NEEDED: return "HP_NEEDED";
1552 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1553 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1554 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1555 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1556 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1557 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1558 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1559 case DT_HP_FILTERED: return "HP_FILTERED";
1560 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1561 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1562 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1563 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1564 case DT_PLT: return "PLT";
1565 case DT_PLT_SIZE: return "PLT_SIZE";
1566 case DT_DLT: return "DLT";
1567 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1568 default:
1569 return NULL;
1570 }
1571}
9a097730 1572
ecc51f48 1573static const char *
d3ba0551 1574get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1575{
1576 switch (type)
1577 {
148b93f2
NC
1578 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1579 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1580 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1581 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1582 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1583 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1584 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1585 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1586 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1587 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1588 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1589 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1590 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1591 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1592 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1593 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1594 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1595 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1596 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1597 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1598 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1599 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1600 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1601 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1602 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1603 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1604 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1605 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1606 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1607 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1608 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1609 default:
1610 return NULL;
1611 }
1612}
1613
fabcb361
RH
1614static const char *
1615get_alpha_dynamic_type (unsigned long type)
1616{
1617 switch (type)
1618 {
1619 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1620 default:
1621 return NULL;
1622 }
1623}
1624
1c0d3aa6
NC
1625static const char *
1626get_score_dynamic_type (unsigned long type)
1627{
1628 switch (type)
1629 {
1630 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1631 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1632 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1633 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1634 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1635 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1636 default:
1637 return NULL;
1638 }
1639}
1640
1641
252b5132 1642static const char *
d3ba0551 1643get_dynamic_type (unsigned long type)
252b5132 1644{
e9e44622 1645 static char buff[64];
252b5132
RH
1646
1647 switch (type)
1648 {
1649 case DT_NULL: return "NULL";
1650 case DT_NEEDED: return "NEEDED";
1651 case DT_PLTRELSZ: return "PLTRELSZ";
1652 case DT_PLTGOT: return "PLTGOT";
1653 case DT_HASH: return "HASH";
1654 case DT_STRTAB: return "STRTAB";
1655 case DT_SYMTAB: return "SYMTAB";
1656 case DT_RELA: return "RELA";
1657 case DT_RELASZ: return "RELASZ";
1658 case DT_RELAENT: return "RELAENT";
1659 case DT_STRSZ: return "STRSZ";
1660 case DT_SYMENT: return "SYMENT";
1661 case DT_INIT: return "INIT";
1662 case DT_FINI: return "FINI";
1663 case DT_SONAME: return "SONAME";
1664 case DT_RPATH: return "RPATH";
1665 case DT_SYMBOLIC: return "SYMBOLIC";
1666 case DT_REL: return "REL";
1667 case DT_RELSZ: return "RELSZ";
1668 case DT_RELENT: return "RELENT";
1669 case DT_PLTREL: return "PLTREL";
1670 case DT_DEBUG: return "DEBUG";
1671 case DT_TEXTREL: return "TEXTREL";
1672 case DT_JMPREL: return "JMPREL";
1673 case DT_BIND_NOW: return "BIND_NOW";
1674 case DT_INIT_ARRAY: return "INIT_ARRAY";
1675 case DT_FINI_ARRAY: return "FINI_ARRAY";
1676 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1677 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1678 case DT_RUNPATH: return "RUNPATH";
1679 case DT_FLAGS: return "FLAGS";
2d0e6f43 1680
d1133906
NC
1681 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1682 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1683
05107a46 1684 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1685 case DT_PLTPADSZ: return "PLTPADSZ";
1686 case DT_MOVEENT: return "MOVEENT";
1687 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1688 case DT_FEATURE: return "FEATURE";
252b5132
RH
1689 case DT_POSFLAG_1: return "POSFLAG_1";
1690 case DT_SYMINSZ: return "SYMINSZ";
1691 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1692
252b5132 1693 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1694 case DT_CONFIG: return "CONFIG";
1695 case DT_DEPAUDIT: return "DEPAUDIT";
1696 case DT_AUDIT: return "AUDIT";
1697 case DT_PLTPAD: return "PLTPAD";
1698 case DT_MOVETAB: return "MOVETAB";
252b5132 1699 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1700
252b5132 1701 case DT_VERSYM: return "VERSYM";
103f02d3 1702
67a4f2b7
AO
1703 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1704 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1705 case DT_RELACOUNT: return "RELACOUNT";
1706 case DT_RELCOUNT: return "RELCOUNT";
1707 case DT_FLAGS_1: return "FLAGS_1";
1708 case DT_VERDEF: return "VERDEF";
1709 case DT_VERDEFNUM: return "VERDEFNUM";
1710 case DT_VERNEED: return "VERNEED";
1711 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1712
019148e4 1713 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1714 case DT_USED: return "USED";
1715 case DT_FILTER: return "FILTER";
103f02d3 1716
047b2264
JJ
1717 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1718 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1719 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1720 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1721 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1722 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1723
252b5132
RH
1724 default:
1725 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1726 {
2cf0635d 1727 const char * result;
103f02d3 1728
252b5132
RH
1729 switch (elf_header.e_machine)
1730 {
1731 case EM_MIPS:
4fe85591 1732 case EM_MIPS_RS3_LE:
252b5132
RH
1733 result = get_mips_dynamic_type (type);
1734 break;
9a097730
RH
1735 case EM_SPARCV9:
1736 result = get_sparc64_dynamic_type (type);
1737 break;
7490d522
AM
1738 case EM_PPC:
1739 result = get_ppc_dynamic_type (type);
1740 break;
f1cb7e17
AM
1741 case EM_PPC64:
1742 result = get_ppc64_dynamic_type (type);
1743 break;
ecc51f48
NC
1744 case EM_IA_64:
1745 result = get_ia64_dynamic_type (type);
1746 break;
fabcb361
RH
1747 case EM_ALPHA:
1748 result = get_alpha_dynamic_type (type);
1749 break;
1c0d3aa6
NC
1750 case EM_SCORE:
1751 result = get_score_dynamic_type (type);
1752 break;
252b5132
RH
1753 default:
1754 result = NULL;
1755 break;
1756 }
1757
1758 if (result != NULL)
1759 return result;
1760
e9e44622 1761 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1762 }
eec8f817
DA
1763 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1764 || (elf_header.e_machine == EM_PARISC
1765 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1766 {
2cf0635d 1767 const char * result;
103f02d3
UD
1768
1769 switch (elf_header.e_machine)
1770 {
1771 case EM_PARISC:
1772 result = get_parisc_dynamic_type (type);
1773 break;
148b93f2
NC
1774 case EM_IA_64:
1775 result = get_ia64_dynamic_type (type);
1776 break;
103f02d3
UD
1777 default:
1778 result = NULL;
1779 break;
1780 }
1781
1782 if (result != NULL)
1783 return result;
1784
e9e44622
JJ
1785 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1786 type);
103f02d3 1787 }
252b5132 1788 else
e9e44622 1789 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1790
252b5132
RH
1791 return buff;
1792 }
1793}
1794
1795static char *
d3ba0551 1796get_file_type (unsigned e_type)
252b5132 1797{
b34976b6 1798 static char buff[32];
252b5132
RH
1799
1800 switch (e_type)
1801 {
1802 case ET_NONE: return _("NONE (None)");
1803 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1804 case ET_EXEC: return _("EXEC (Executable file)");
1805 case ET_DYN: return _("DYN (Shared object file)");
1806 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1807
1808 default:
1809 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1810 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1811 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1812 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1813 else
e9e44622 1814 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1815 return buff;
1816 }
1817}
1818
1819static char *
d3ba0551 1820get_machine_name (unsigned e_machine)
252b5132 1821{
b34976b6 1822 static char buff[64]; /* XXX */
252b5132
RH
1823
1824 switch (e_machine)
1825 {
c45021f2
NC
1826 case EM_NONE: return _("None");
1827 case EM_M32: return "WE32100";
1828 case EM_SPARC: return "Sparc";
e9f53129 1829 case EM_SPU: return "SPU";
c45021f2
NC
1830 case EM_386: return "Intel 80386";
1831 case EM_68K: return "MC68000";
1832 case EM_88K: return "MC88000";
1833 case EM_486: return "Intel 80486";
1834 case EM_860: return "Intel 80860";
1835 case EM_MIPS: return "MIPS R3000";
1836 case EM_S370: return "IBM System/370";
7036c0e1 1837 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1838 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1839 case EM_PARISC: return "HPPA";
252b5132 1840 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1841 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1842 case EM_960: return "Intel 90860";
1843 case EM_PPC: return "PowerPC";
285d1771 1844 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1845 case EM_V800: return "NEC V800";
1846 case EM_FR20: return "Fujitsu FR20";
1847 case EM_RH32: return "TRW RH32";
b34976b6 1848 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1849 case EM_ARM: return "ARM";
1850 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1851 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1852 case EM_SPARCV9: return "Sparc v9";
1853 case EM_TRICORE: return "Siemens Tricore";
584da044 1854 case EM_ARC: return "ARC";
c2dcd04e
NC
1855 case EM_H8_300: return "Renesas H8/300";
1856 case EM_H8_300H: return "Renesas H8/300H";
1857 case EM_H8S: return "Renesas H8S";
1858 case EM_H8_500: return "Renesas H8/500";
30800947 1859 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1860 case EM_MIPS_X: return "Stanford MIPS-X";
1861 case EM_COLDFIRE: return "Motorola Coldfire";
1862 case EM_68HC12: return "Motorola M68HC12";
c45021f2 1863 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1864 case EM_CYGNUS_D10V:
1865 case EM_D10V: return "d10v";
1866 case EM_CYGNUS_D30V:
b34976b6 1867 case EM_D30V: return "d30v";
2b0337b0 1868 case EM_CYGNUS_M32R:
26597c86 1869 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0
AO
1870 case EM_CYGNUS_V850:
1871 case EM_V850: return "NEC v850";
1872 case EM_CYGNUS_MN10300:
1873 case EM_MN10300: return "mn10300";
1874 case EM_CYGNUS_MN10200:
1875 case EM_MN10200: return "mn10200";
1876 case EM_CYGNUS_FR30:
1877 case EM_FR30: return "Fujitsu FR30";
b34976b6 1878 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1879 case EM_PJ_OLD:
b34976b6 1880 case EM_PJ: return "picoJava";
7036c0e1
AJ
1881 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1882 case EM_PCP: return "Siemens PCP";
1883 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1884 case EM_NDR1: return "Denso NDR1 microprocesspr";
1885 case EM_STARCORE: return "Motorola Star*Core processor";
1886 case EM_ME16: return "Toyota ME16 processor";
1887 case EM_ST100: return "STMicroelectronics ST100 processor";
1888 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1889 case EM_PDSP: return "Sony DSP processor";
1890 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1891 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1892 case EM_FX66: return "Siemens FX66 microcontroller";
1893 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1894 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1895 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
1896 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1897 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1898 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1899 case EM_SVX: return "Silicon Graphics SVx";
1900 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1901 case EM_VAX: return "Digital VAX";
2b0337b0 1902 case EM_AVR_OLD:
b34976b6 1903 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1904 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1905 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1906 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1907 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1908 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1909 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1910 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1911 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1912 case EM_L1OM: return "Intel L1OM";
b7498e0e 1913 case EM_S390_OLD:
b34976b6 1914 case EM_S390: return "IBM S/390";
1c0d3aa6 1915 case EM_SCORE: return "SUNPLUS S+Core";
93fbbb04 1916 case EM_XSTORMY16: return "Sanyo Xstormy16 CPU core";
3b16e843
NC
1917 case EM_OPENRISC:
1918 case EM_OR32: return "OpenRISC";
11636f9e 1919 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1920 case EM_CRX: return "National Semiconductor CRX microprocessor";
d172d4ba 1921 case EM_DLX: return "OpenDLX";
1e4cf259 1922 case EM_IP2K_OLD:
b34976b6 1923 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1924 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1925 case EM_XTENSA_OLD:
1926 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1927 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1928 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1929 case EM_NS32K: return "National Semiconductor 32000 series";
1930 case EM_TPC: return "Tenor Network TPC processor";
1931 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1932 case EM_MAX: return "MAX Processor";
1933 case EM_CR: return "National Semiconductor CompactRISC";
1934 case EM_F2MC16: return "Fujitsu F2MC16";
1935 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1936 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1937 case EM_M32C_OLD:
49f58d10 1938 case EM_M32C: return "Renesas M32c";
d031aafb 1939 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1940 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1941 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1942 case EM_SEP: return "Sharp embedded microprocessor";
1943 case EM_ARCA: return "Arca RISC microprocessor";
1944 case EM_UNICORE: return "Unicore";
1945 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1946 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1947 case EM_NIOS32: return "Altera Nios";
1948 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1949 case EM_C166:
d70c5fc7 1950 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
1951 case EM_M16C: return "Renesas M16C series microprocessors";
1952 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
1953 case EM_CE: return "Freescale Communication Engine RISC core";
1954 case EM_TSK3000: return "Altium TSK3000 core";
1955 case EM_RS08: return "Freescale RS08 embedded processor";
1956 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
1957 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
1958 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
1959 case EM_SE_C17: return "Seiko Epson C17 family";
1960 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
1961 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
1962 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
1963 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
1964 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
1965 case EM_R32C: return "Renesas R32C series microprocessors";
1966 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
1967 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
1968 case EM_8051: return "Intel 8051 and variants";
1969 case EM_STXP7X: return "STMicroelectronics STxP7x family";
1970 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
1971 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
1972 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
1973 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
1974 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
1975 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 1976 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 1977 case EM_CR16:
6c03b1ed 1978 case EM_CR16_OLD: return "National Semiconductor's CR16";
7ba29e2a
NC
1979 case EM_MICROBLAZE: return "Xilinx MicroBlaze";
1980 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
c7927a3c 1981 case EM_RX: return "Renesas RX";
11636f9e
JM
1982 case EM_METAG: return "Imagination Technologies META processor architecture";
1983 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
1984 case EM_ECOG16: return "Cyan Technology eCOG16 family";
1985 case EM_ETPU: return "Freescale Extended Time Processing Unit";
1986 case EM_SLE9X: return "Infineon Technologies SLE9X core";
1987 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
1988 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
1989 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
1990 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
1991 case EM_CUDA: return "NVIDIA CUDA architecture";
252b5132 1992 default:
35d9dd2f 1993 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
1994 return buff;
1995 }
1996}
1997
f3485b74 1998static void
d3ba0551 1999decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2000{
2001 unsigned eabi;
2002 int unknown = 0;
2003
2004 eabi = EF_ARM_EABI_VERSION (e_flags);
2005 e_flags &= ~ EF_ARM_EABIMASK;
2006
2007 /* Handle "generic" ARM flags. */
2008 if (e_flags & EF_ARM_RELEXEC)
2009 {
2010 strcat (buf, ", relocatable executable");
2011 e_flags &= ~ EF_ARM_RELEXEC;
2012 }
76da6bbe 2013
f3485b74
NC
2014 if (e_flags & EF_ARM_HASENTRY)
2015 {
2016 strcat (buf, ", has entry point");
2017 e_flags &= ~ EF_ARM_HASENTRY;
2018 }
76da6bbe 2019
f3485b74
NC
2020 /* Now handle EABI specific flags. */
2021 switch (eabi)
2022 {
2023 default:
2c71103e 2024 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2025 if (e_flags)
2026 unknown = 1;
2027 break;
2028
2029 case EF_ARM_EABI_VER1:
a5bcd848 2030 strcat (buf, ", Version1 EABI");
f3485b74
NC
2031 while (e_flags)
2032 {
2033 unsigned flag;
76da6bbe 2034
f3485b74
NC
2035 /* Process flags one bit at a time. */
2036 flag = e_flags & - e_flags;
2037 e_flags &= ~ flag;
76da6bbe 2038
f3485b74
NC
2039 switch (flag)
2040 {
a5bcd848 2041 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2042 strcat (buf, ", sorted symbol tables");
2043 break;
76da6bbe 2044
f3485b74
NC
2045 default:
2046 unknown = 1;
2047 break;
2048 }
2049 }
2050 break;
76da6bbe 2051
a5bcd848
PB
2052 case EF_ARM_EABI_VER2:
2053 strcat (buf, ", Version2 EABI");
2054 while (e_flags)
2055 {
2056 unsigned flag;
2057
2058 /* Process flags one bit at a time. */
2059 flag = e_flags & - e_flags;
2060 e_flags &= ~ flag;
2061
2062 switch (flag)
2063 {
2064 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2065 strcat (buf, ", sorted symbol tables");
2066 break;
2067
2068 case EF_ARM_DYNSYMSUSESEGIDX:
2069 strcat (buf, ", dynamic symbols use segment index");
2070 break;
2071
2072 case EF_ARM_MAPSYMSFIRST:
2073 strcat (buf, ", mapping symbols precede others");
2074 break;
2075
2076 default:
2077 unknown = 1;
2078 break;
2079 }
2080 }
2081 break;
2082
d507cf36
PB
2083 case EF_ARM_EABI_VER3:
2084 strcat (buf, ", Version3 EABI");
8cb51566
PB
2085 break;
2086
2087 case EF_ARM_EABI_VER4:
2088 strcat (buf, ", Version4 EABI");
3a4a14e9
PB
2089 goto eabi;
2090
2091 case EF_ARM_EABI_VER5:
2092 strcat (buf, ", Version5 EABI");
2093 eabi:
d507cf36
PB
2094 while (e_flags)
2095 {
2096 unsigned flag;
2097
2098 /* Process flags one bit at a time. */
2099 flag = e_flags & - e_flags;
2100 e_flags &= ~ flag;
2101
2102 switch (flag)
2103 {
2104 case EF_ARM_BE8:
2105 strcat (buf, ", BE8");
2106 break;
2107
2108 case EF_ARM_LE8:
2109 strcat (buf, ", LE8");
2110 break;
2111
2112 default:
2113 unknown = 1;
2114 break;
2115 }
2116 }
2117 break;
2118
f3485b74 2119 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2120 strcat (buf, ", GNU EABI");
f3485b74
NC
2121 while (e_flags)
2122 {
2123 unsigned flag;
76da6bbe 2124
f3485b74
NC
2125 /* Process flags one bit at a time. */
2126 flag = e_flags & - e_flags;
2127 e_flags &= ~ flag;
76da6bbe 2128
f3485b74
NC
2129 switch (flag)
2130 {
a5bcd848 2131 case EF_ARM_INTERWORK:
f3485b74
NC
2132 strcat (buf, ", interworking enabled");
2133 break;
76da6bbe 2134
a5bcd848 2135 case EF_ARM_APCS_26:
f3485b74
NC
2136 strcat (buf, ", uses APCS/26");
2137 break;
76da6bbe 2138
a5bcd848 2139 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2140 strcat (buf, ", uses APCS/float");
2141 break;
76da6bbe 2142
a5bcd848 2143 case EF_ARM_PIC:
f3485b74
NC
2144 strcat (buf, ", position independent");
2145 break;
76da6bbe 2146
a5bcd848 2147 case EF_ARM_ALIGN8:
f3485b74
NC
2148 strcat (buf, ", 8 bit structure alignment");
2149 break;
76da6bbe 2150
a5bcd848 2151 case EF_ARM_NEW_ABI:
f3485b74
NC
2152 strcat (buf, ", uses new ABI");
2153 break;
76da6bbe 2154
a5bcd848 2155 case EF_ARM_OLD_ABI:
f3485b74
NC
2156 strcat (buf, ", uses old ABI");
2157 break;
76da6bbe 2158
a5bcd848 2159 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2160 strcat (buf, ", software FP");
2161 break;
76da6bbe 2162
90e01f86
ILT
2163 case EF_ARM_VFP_FLOAT:
2164 strcat (buf, ", VFP");
2165 break;
2166
fde78edd
NC
2167 case EF_ARM_MAVERICK_FLOAT:
2168 strcat (buf, ", Maverick FP");
2169 break;
2170
f3485b74
NC
2171 default:
2172 unknown = 1;
2173 break;
2174 }
2175 }
2176 }
f3485b74
NC
2177
2178 if (unknown)
2179 strcat (buf,", <unknown>");
2180}
2181
252b5132 2182static char *
d3ba0551 2183get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2184{
b34976b6 2185 static char buf[1024];
252b5132
RH
2186
2187 buf[0] = '\0';
76da6bbe 2188
252b5132
RH
2189 if (e_flags)
2190 {
2191 switch (e_machine)
2192 {
2193 default:
2194 break;
2195
f3485b74
NC
2196 case EM_ARM:
2197 decode_ARM_machine_flags (e_flags, buf);
2198 break;
76da6bbe 2199
ec2dfb42
AO
2200 case EM_CYGNUS_FRV:
2201 switch (e_flags & EF_FRV_CPU_MASK)
2202 {
2203 case EF_FRV_CPU_GENERIC:
2204 break;
2205
2206 default:
2207 strcat (buf, ", fr???");
2208 break;
57346661 2209
ec2dfb42
AO
2210 case EF_FRV_CPU_FR300:
2211 strcat (buf, ", fr300");
2212 break;
2213
2214 case EF_FRV_CPU_FR400:
2215 strcat (buf, ", fr400");
2216 break;
2217 case EF_FRV_CPU_FR405:
2218 strcat (buf, ", fr405");
2219 break;
2220
2221 case EF_FRV_CPU_FR450:
2222 strcat (buf, ", fr450");
2223 break;
2224
2225 case EF_FRV_CPU_FR500:
2226 strcat (buf, ", fr500");
2227 break;
2228 case EF_FRV_CPU_FR550:
2229 strcat (buf, ", fr550");
2230 break;
2231
2232 case EF_FRV_CPU_SIMPLE:
2233 strcat (buf, ", simple");
2234 break;
2235 case EF_FRV_CPU_TOMCAT:
2236 strcat (buf, ", tomcat");
2237 break;
2238 }
1c877e87 2239 break;
ec2dfb42 2240
53c7db4b 2241 case EM_68K:
425c6cb0 2242 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2243 strcat (buf, ", m68000");
425c6cb0 2244 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2245 strcat (buf, ", cpu32");
2246 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2247 strcat (buf, ", fido_a");
425c6cb0 2248 else
266abb8f 2249 {
2cf0635d
NC
2250 char const * isa = _("unknown");
2251 char const * mac = _("unknown mac");
2252 char const * additional = NULL;
0112cd26 2253
c694fd50 2254 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2255 {
c694fd50 2256 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2257 isa = "A";
2258 additional = ", nodiv";
2259 break;
c694fd50 2260 case EF_M68K_CF_ISA_A:
266abb8f
NS
2261 isa = "A";
2262 break;
c694fd50 2263 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2264 isa = "A+";
2265 break;
c694fd50 2266 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2267 isa = "B";
2268 additional = ", nousp";
2269 break;
c694fd50 2270 case EF_M68K_CF_ISA_B:
266abb8f
NS
2271 isa = "B";
2272 break;
2273 }
2274 strcat (buf, ", cf, isa ");
2275 strcat (buf, isa);
0b2e31dc
NS
2276 if (additional)
2277 strcat (buf, additional);
c694fd50 2278 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2279 strcat (buf, ", float");
c694fd50 2280 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2281 {
2282 case 0:
2283 mac = NULL;
2284 break;
c694fd50 2285 case EF_M68K_CF_MAC:
266abb8f
NS
2286 mac = "mac";
2287 break;
c694fd50 2288 case EF_M68K_CF_EMAC:
266abb8f
NS
2289 mac = "emac";
2290 break;
2291 }
2292 if (mac)
2293 {
2294 strcat (buf, ", ");
2295 strcat (buf, mac);
2296 }
266abb8f 2297 }
53c7db4b 2298 break;
33c63f9d 2299
252b5132
RH
2300 case EM_PPC:
2301 if (e_flags & EF_PPC_EMB)
2302 strcat (buf, ", emb");
2303
2304 if (e_flags & EF_PPC_RELOCATABLE)
2305 strcat (buf, ", relocatable");
2306
2307 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2308 strcat (buf, ", relocatable-lib");
2309 break;
2310
2b0337b0 2311 case EM_V850:
252b5132
RH
2312 case EM_CYGNUS_V850:
2313 switch (e_flags & EF_V850_ARCH)
2314 {
8ad30312
NC
2315 case E_V850E1_ARCH:
2316 strcat (buf, ", v850e1");
2317 break;
252b5132
RH
2318 case E_V850E_ARCH:
2319 strcat (buf, ", v850e");
2320 break;
252b5132
RH
2321 case E_V850_ARCH:
2322 strcat (buf, ", v850");
2323 break;
2324 default:
2325 strcat (buf, ", unknown v850 architecture variant");
2326 break;
2327 }
2328 break;
2329
2b0337b0 2330 case EM_M32R:
252b5132
RH
2331 case EM_CYGNUS_M32R:
2332 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2333 strcat (buf, ", m32r");
252b5132
RH
2334 break;
2335
2336 case EM_MIPS:
4fe85591 2337 case EM_MIPS_RS3_LE:
252b5132
RH
2338 if (e_flags & EF_MIPS_NOREORDER)
2339 strcat (buf, ", noreorder");
2340
2341 if (e_flags & EF_MIPS_PIC)
2342 strcat (buf, ", pic");
2343
2344 if (e_flags & EF_MIPS_CPIC)
2345 strcat (buf, ", cpic");
2346
d1bdd336
TS
2347 if (e_flags & EF_MIPS_UCODE)
2348 strcat (buf, ", ugen_reserved");
2349
252b5132
RH
2350 if (e_flags & EF_MIPS_ABI2)
2351 strcat (buf, ", abi2");
2352
43521d43
TS
2353 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2354 strcat (buf, ", odk first");
2355
a5d22d2a
TS
2356 if (e_flags & EF_MIPS_32BITMODE)
2357 strcat (buf, ", 32bitmode");
2358
156c2f8b
NC
2359 switch ((e_flags & EF_MIPS_MACH))
2360 {
2361 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2362 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2363 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2364 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2365 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2366 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2367 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2368 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2369 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2370 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2371 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2372 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
05c6f050 2373 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2374 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2375 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2376 case 0:
2377 /* We simply ignore the field in this case to avoid confusion:
2378 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2379 extension. */
2380 break;
2381 default: strcat (buf, ", unknown CPU"); break;
156c2f8b 2382 }
43521d43
TS
2383
2384 switch ((e_flags & EF_MIPS_ABI))
2385 {
2386 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2387 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2388 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2389 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2390 case 0:
2391 /* We simply ignore the field in this case to avoid confusion:
2392 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2393 This means it is likely to be an o32 file, but not for
2394 sure. */
2395 break;
2396 default: strcat (buf, ", unknown ABI"); break;
2397 }
2398
2399 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2400 strcat (buf, ", mdmx");
2401
2402 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2403 strcat (buf, ", mips16");
2404
2405 switch ((e_flags & EF_MIPS_ARCH))
2406 {
2407 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2408 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2409 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2410 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2411 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2412 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2413 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2414 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2415 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
43521d43
TS
2416 default: strcat (buf, ", unknown ISA"); break;
2417 }
2418
252b5132 2419 break;
351b4b40 2420
ccde1100
AO
2421 case EM_SH:
2422 switch ((e_flags & EF_SH_MACH_MASK))
2423 {
2424 case EF_SH1: strcat (buf, ", sh1"); break;
2425 case EF_SH2: strcat (buf, ", sh2"); break;
2426 case EF_SH3: strcat (buf, ", sh3"); break;
2427 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2428 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2429 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2430 case EF_SH3E: strcat (buf, ", sh3e"); break;
2431 case EF_SH4: strcat (buf, ", sh4"); break;
2432 case EF_SH5: strcat (buf, ", sh5"); break;
2433 case EF_SH2E: strcat (buf, ", sh2e"); break;
2434 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2435 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2436 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2437 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2438 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2439 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2440 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2441 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2442 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2443 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2444 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
dc85a459 2445 default: strcat (buf, ", unknown ISA"); break;
ccde1100
AO
2446 }
2447
2448 break;
57346661 2449
351b4b40
RH
2450 case EM_SPARCV9:
2451 if (e_flags & EF_SPARC_32PLUS)
2452 strcat (buf, ", v8+");
2453
2454 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2455 strcat (buf, ", ultrasparcI");
2456
2457 if (e_flags & EF_SPARC_SUN_US3)
2458 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2459
2460 if (e_flags & EF_SPARC_HAL_R1)
2461 strcat (buf, ", halr1");
2462
2463 if (e_flags & EF_SPARC_LEDATA)
2464 strcat (buf, ", ledata");
2465
2466 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2467 strcat (buf, ", tso");
2468
2469 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2470 strcat (buf, ", pso");
2471
2472 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2473 strcat (buf, ", rmo");
2474 break;
7d466069 2475
103f02d3
UD
2476 case EM_PARISC:
2477 switch (e_flags & EF_PARISC_ARCH)
2478 {
2479 case EFA_PARISC_1_0:
2480 strcpy (buf, ", PA-RISC 1.0");
2481 break;
2482 case EFA_PARISC_1_1:
2483 strcpy (buf, ", PA-RISC 1.1");
2484 break;
2485 case EFA_PARISC_2_0:
2486 strcpy (buf, ", PA-RISC 2.0");
2487 break;
2488 default:
2489 break;
2490 }
2491 if (e_flags & EF_PARISC_TRAPNIL)
2492 strcat (buf, ", trapnil");
2493 if (e_flags & EF_PARISC_EXT)
2494 strcat (buf, ", ext");
2495 if (e_flags & EF_PARISC_LSB)
2496 strcat (buf, ", lsb");
2497 if (e_flags & EF_PARISC_WIDE)
2498 strcat (buf, ", wide");
2499 if (e_flags & EF_PARISC_NO_KABP)
2500 strcat (buf, ", no kabp");
2501 if (e_flags & EF_PARISC_LAZYSWAP)
2502 strcat (buf, ", lazyswap");
30800947 2503 break;
76da6bbe 2504
7d466069 2505 case EM_PJ:
2b0337b0 2506 case EM_PJ_OLD:
7d466069
ILT
2507 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2508 strcat (buf, ", new calling convention");
2509
2510 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2511 strcat (buf, ", gnu calling convention");
2512 break;
4d6ed7c8
NC
2513
2514 case EM_IA_64:
2515 if ((e_flags & EF_IA_64_ABI64))
2516 strcat (buf, ", 64-bit");
2517 else
2518 strcat (buf, ", 32-bit");
2519 if ((e_flags & EF_IA_64_REDUCEDFP))
2520 strcat (buf, ", reduced fp model");
2521 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2522 strcat (buf, ", no function descriptors, constant gp");
2523 else if ((e_flags & EF_IA_64_CONS_GP))
2524 strcat (buf, ", constant gp");
2525 if ((e_flags & EF_IA_64_ABSOLUTE))
2526 strcat (buf, ", absolute");
2527 break;
179d3252
JT
2528
2529 case EM_VAX:
2530 if ((e_flags & EF_VAX_NONPIC))
2531 strcat (buf, ", non-PIC");
2532 if ((e_flags & EF_VAX_DFLOAT))
2533 strcat (buf, ", D-Float");
2534 if ((e_flags & EF_VAX_GFLOAT))
2535 strcat (buf, ", G-Float");
2536 break;
c7927a3c
NC
2537
2538 case EM_RX:
2539 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2540 strcat (buf, ", 64-bit doubles");
2541 if (e_flags & E_FLAG_RX_DSP)
2542 strcat (buf, ", dsp");
55786da2
AK
2543
2544 case EM_S390:
2545 if (e_flags & EF_S390_HIGH_GPRS)
2546 strcat (buf, ", highgprs");
252b5132
RH
2547 }
2548 }
2549
2550 return buf;
2551}
2552
252b5132 2553static const char *
d3ba0551
AM
2554get_osabi_name (unsigned int osabi)
2555{
2556 static char buff[32];
2557
2558 switch (osabi)
2559 {
2560 case ELFOSABI_NONE: return "UNIX - System V";
2561 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2562 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
2563 case ELFOSABI_LINUX: return "UNIX - Linux";
2564 case ELFOSABI_HURD: return "GNU/Hurd";
2565 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2566 case ELFOSABI_AIX: return "UNIX - AIX";
2567 case ELFOSABI_IRIX: return "UNIX - IRIX";
2568 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2569 case ELFOSABI_TRU64: return "UNIX - TRU64";
2570 case ELFOSABI_MODESTO: return "Novell - Modesto";
2571 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2572 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2573 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2574 case ELFOSABI_AROS: return "AROS";
11636f9e 2575 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551
AM
2576 case ELFOSABI_STANDALONE: return _("Standalone App");
2577 case ELFOSABI_ARM: return "ARM";
2578 default:
e9e44622 2579 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2580 return buff;
2581 }
2582}
2583
b294bdf8
MM
2584static const char *
2585get_arm_segment_type (unsigned long type)
2586{
2587 switch (type)
2588 {
2589 case PT_ARM_EXIDX:
2590 return "EXIDX";
2591 default:
2592 break;
2593 }
2594
2595 return NULL;
2596}
2597
d3ba0551
AM
2598static const char *
2599get_mips_segment_type (unsigned long type)
252b5132
RH
2600{
2601 switch (type)
2602 {
2603 case PT_MIPS_REGINFO:
2604 return "REGINFO";
2605 case PT_MIPS_RTPROC:
2606 return "RTPROC";
2607 case PT_MIPS_OPTIONS:
2608 return "OPTIONS";
2609 default:
2610 break;
2611 }
2612
2613 return NULL;
2614}
2615
103f02d3 2616static const char *
d3ba0551 2617get_parisc_segment_type (unsigned long type)
103f02d3
UD
2618{
2619 switch (type)
2620 {
2621 case PT_HP_TLS: return "HP_TLS";
2622 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2623 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2624 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2625 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2626 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2627 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2628 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2629 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2630 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2631 case PT_HP_PARALLEL: return "HP_PARALLEL";
2632 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2633 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2634 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2635 case PT_HP_STACK: return "HP_STACK";
2636 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2637 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2638 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2639 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2640 default:
2641 break;
2642 }
2643
2644 return NULL;
2645}
2646
4d6ed7c8 2647static const char *
d3ba0551 2648get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2649{
2650 switch (type)
2651 {
2652 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2653 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2654 case PT_HP_TLS: return "HP_TLS";
2655 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2656 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2657 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2658 default:
2659 break;
2660 }
2661
2662 return NULL;
2663}
2664
252b5132 2665static const char *
d3ba0551 2666get_segment_type (unsigned long p_type)
252b5132 2667{
b34976b6 2668 static char buff[32];
252b5132
RH
2669
2670 switch (p_type)
2671 {
b34976b6
AM
2672 case PT_NULL: return "NULL";
2673 case PT_LOAD: return "LOAD";
252b5132 2674 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2675 case PT_INTERP: return "INTERP";
2676 case PT_NOTE: return "NOTE";
2677 case PT_SHLIB: return "SHLIB";
2678 case PT_PHDR: return "PHDR";
13ae64f3 2679 case PT_TLS: return "TLS";
252b5132 2680
65765700
JJ
2681 case PT_GNU_EH_FRAME:
2682 return "GNU_EH_FRAME";
2b05f1b7 2683 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2684 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2685
252b5132
RH
2686 default:
2687 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2688 {
2cf0635d 2689 const char * result;
103f02d3 2690
252b5132
RH
2691 switch (elf_header.e_machine)
2692 {
b294bdf8
MM
2693 case EM_ARM:
2694 result = get_arm_segment_type (p_type);
2695 break;
252b5132 2696 case EM_MIPS:
4fe85591 2697 case EM_MIPS_RS3_LE:
252b5132
RH
2698 result = get_mips_segment_type (p_type);
2699 break;
103f02d3
UD
2700 case EM_PARISC:
2701 result = get_parisc_segment_type (p_type);
2702 break;
4d6ed7c8
NC
2703 case EM_IA_64:
2704 result = get_ia64_segment_type (p_type);
2705 break;
252b5132
RH
2706 default:
2707 result = NULL;
2708 break;
2709 }
103f02d3 2710
252b5132
RH
2711 if (result != NULL)
2712 return result;
103f02d3 2713
252b5132
RH
2714 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2715 }
2716 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2717 {
2cf0635d 2718 const char * result;
103f02d3
UD
2719
2720 switch (elf_header.e_machine)
2721 {
2722 case EM_PARISC:
2723 result = get_parisc_segment_type (p_type);
2724 break;
00428cca
AM
2725 case EM_IA_64:
2726 result = get_ia64_segment_type (p_type);
2727 break;
103f02d3
UD
2728 default:
2729 result = NULL;
2730 break;
2731 }
2732
2733 if (result != NULL)
2734 return result;
2735
2736 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2737 }
252b5132 2738 else
e9e44622 2739 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2740
2741 return buff;
2742 }
2743}
2744
2745static const char *
d3ba0551 2746get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2747{
2748 switch (sh_type)
2749 {
b34976b6
AM
2750 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2751 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2752 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2753 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2754 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2755 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2756 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2757 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2758 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2759 case SHT_MIPS_RELD: return "MIPS_RELD";
2760 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2761 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2762 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2763 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2764 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2765 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2766 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2767 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2768 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2769 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2770 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2771 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2772 case SHT_MIPS_LINE: return "MIPS_LINE";
2773 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2774 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2775 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2776 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2777 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2778 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2779 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2780 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2781 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2782 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2783 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2784 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2785 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2786 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2787 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2788 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2789 default:
2790 break;
2791 }
2792 return NULL;
2793}
2794
103f02d3 2795static const char *
d3ba0551 2796get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2797{
2798 switch (sh_type)
2799 {
2800 case SHT_PARISC_EXT: return "PARISC_EXT";
2801 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2802 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2803 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2804 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2805 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2806 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2807 default:
2808 break;
2809 }
2810 return NULL;
2811}
2812
4d6ed7c8 2813static const char *
d3ba0551 2814get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2815{
18bd398b 2816 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2817 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2818 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2819
4d6ed7c8
NC
2820 switch (sh_type)
2821 {
148b93f2
NC
2822 case SHT_IA_64_EXT: return "IA_64_EXT";
2823 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2824 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
2825 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
2826 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
2827 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
2828 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
2829 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
2830 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
2831 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
2832 default:
2833 break;
2834 }
2835 return NULL;
2836}
2837
d2b2c203
DJ
2838static const char *
2839get_x86_64_section_type_name (unsigned int sh_type)
2840{
2841 switch (sh_type)
2842 {
2843 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2844 default:
2845 break;
2846 }
2847 return NULL;
2848}
2849
40a18ebd
NC
2850static const char *
2851get_arm_section_type_name (unsigned int sh_type)
2852{
2853 switch (sh_type)
2854 {
7f6fed87
NC
2855 case SHT_ARM_EXIDX: return "ARM_EXIDX";
2856 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
2857 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
2858 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
2859 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
2860 default:
2861 break;
2862 }
2863 return NULL;
2864}
2865
252b5132 2866static const char *
d3ba0551 2867get_section_type_name (unsigned int sh_type)
252b5132 2868{
b34976b6 2869 static char buff[32];
252b5132
RH
2870
2871 switch (sh_type)
2872 {
2873 case SHT_NULL: return "NULL";
2874 case SHT_PROGBITS: return "PROGBITS";
2875 case SHT_SYMTAB: return "SYMTAB";
2876 case SHT_STRTAB: return "STRTAB";
2877 case SHT_RELA: return "RELA";
2878 case SHT_HASH: return "HASH";
2879 case SHT_DYNAMIC: return "DYNAMIC";
2880 case SHT_NOTE: return "NOTE";
2881 case SHT_NOBITS: return "NOBITS";
2882 case SHT_REL: return "REL";
2883 case SHT_SHLIB: return "SHLIB";
2884 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
2885 case SHT_INIT_ARRAY: return "INIT_ARRAY";
2886 case SHT_FINI_ARRAY: return "FINI_ARRAY";
2887 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 2888 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
2889 case SHT_GROUP: return "GROUP";
2890 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
2891 case SHT_GNU_verdef: return "VERDEF";
2892 case SHT_GNU_verneed: return "VERNEED";
2893 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
2894 case 0x6ffffff0: return "VERSYM";
2895 case 0x6ffffffc: return "VERDEF";
252b5132
RH
2896 case 0x7ffffffd: return "AUXILIARY";
2897 case 0x7fffffff: return "FILTER";
047b2264 2898 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
2899
2900 default:
2901 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
2902 {
2cf0635d 2903 const char * result;
252b5132
RH
2904
2905 switch (elf_header.e_machine)
2906 {
2907 case EM_MIPS:
4fe85591 2908 case EM_MIPS_RS3_LE:
252b5132
RH
2909 result = get_mips_section_type_name (sh_type);
2910 break;
103f02d3
UD
2911 case EM_PARISC:
2912 result = get_parisc_section_type_name (sh_type);
2913 break;
4d6ed7c8
NC
2914 case EM_IA_64:
2915 result = get_ia64_section_type_name (sh_type);
2916 break;
d2b2c203 2917 case EM_X86_64:
8a9036a4 2918 case EM_L1OM:
d2b2c203
DJ
2919 result = get_x86_64_section_type_name (sh_type);
2920 break;
40a18ebd
NC
2921 case EM_ARM:
2922 result = get_arm_section_type_name (sh_type);
2923 break;
252b5132
RH
2924 default:
2925 result = NULL;
2926 break;
2927 }
2928
2929 if (result != NULL)
2930 return result;
2931
c91d0dfb 2932 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
2933 }
2934 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 2935 {
2cf0635d 2936 const char * result;
148b93f2
NC
2937
2938 switch (elf_header.e_machine)
2939 {
2940 case EM_IA_64:
2941 result = get_ia64_section_type_name (sh_type);
2942 break;
2943 default:
2944 result = NULL;
2945 break;
2946 }
2947
2948 if (result != NULL)
2949 return result;
2950
2951 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
2952 }
252b5132 2953 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 2954 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 2955 else
e9e44622 2956 snprintf (buff, sizeof (buff), _("<unknown>: %x"), sh_type);
103f02d3 2957
252b5132
RH
2958 return buff;
2959 }
2960}
2961
2979dc34 2962#define OPTION_DEBUG_DUMP 512
2c610e4b 2963#define OPTION_DYN_SYMS 513
2979dc34 2964
85b1c36d 2965static struct option options[] =
252b5132 2966{
b34976b6 2967 {"all", no_argument, 0, 'a'},
252b5132
RH
2968 {"file-header", no_argument, 0, 'h'},
2969 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
2970 {"headers", no_argument, 0, 'e'},
2971 {"histogram", no_argument, 0, 'I'},
2972 {"segments", no_argument, 0, 'l'},
2973 {"sections", no_argument, 0, 'S'},
252b5132 2974 {"section-headers", no_argument, 0, 'S'},
f5842774 2975 {"section-groups", no_argument, 0, 'g'},
5477e8a0 2976 {"section-details", no_argument, 0, 't'},
595cf52e 2977 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
2978 {"symbols", no_argument, 0, 's'},
2979 {"syms", no_argument, 0, 's'},
2c610e4b 2980 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
2981 {"relocs", no_argument, 0, 'r'},
2982 {"notes", no_argument, 0, 'n'},
2983 {"dynamic", no_argument, 0, 'd'},
a952a375 2984 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
2985 {"version-info", no_argument, 0, 'V'},
2986 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 2987 {"unwind", no_argument, 0, 'u'},
4145f1d5 2988 {"archive-index", no_argument, 0, 'c'},
b34976b6 2989 {"hex-dump", required_argument, 0, 'x'},
cf13d699 2990 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 2991 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
2992#ifdef SUPPORT_DISASSEMBLY
2993 {"instruction-dump", required_argument, 0, 'i'},
2994#endif
cf13d699 2995 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 2996
b34976b6
AM
2997 {"version", no_argument, 0, 'v'},
2998 {"wide", no_argument, 0, 'W'},
2999 {"help", no_argument, 0, 'H'},
3000 {0, no_argument, 0, 0}
252b5132
RH
3001};
3002
3003static void
2cf0635d 3004usage (FILE * stream)
252b5132 3005{
92f01d61
JM
3006 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3007 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3008 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3009 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3010 -h --file-header Display the ELF file header\n\
3011 -l --program-headers Display the program headers\n\
3012 --segments An alias for --program-headers\n\
3013 -S --section-headers Display the sections' header\n\
3014 --sections An alias for --section-headers\n\
f5842774 3015 -g --section-groups Display the section groups\n\
5477e8a0 3016 -t --section-details Display the section details\n\
8b53311e
NC
3017 -e --headers Equivalent to: -h -l -S\n\
3018 -s --syms Display the symbol table\n\
3f08eb35 3019 --symbols An alias for --syms\n\
2c610e4b 3020 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3021 -n --notes Display the core notes (if present)\n\
3022 -r --relocs Display the relocations (if present)\n\
3023 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3024 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
3025 -V --version-info Display the version sections (if present)\n\
3026 -A --arch-specific Display architecture specific information (if any).\n\
4145f1d5 3027 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3028 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3029 -x --hex-dump=<number|name>\n\
3030 Dump the contents of section <number|name> as bytes\n\
3031 -p --string-dump=<number|name>\n\
3032 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3033 -R --relocated-dump=<number|name>\n\
3034 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3035 -w[lLiaprmfFsoRt] or\n\
1ed06042 3036 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
f9f0e732 3037 =frames-interp,=str,=loc,=Ranges,=pubtypes]\n\
8b53311e 3038 Display the contents of DWARF2 debug sections\n"));
252b5132 3039#ifdef SUPPORT_DISASSEMBLY
92f01d61 3040 fprintf (stream, _("\
09c11c86
NC
3041 -i --instruction-dump=<number|name>\n\
3042 Disassemble the contents of section <number|name>\n"));
252b5132 3043#endif
92f01d61 3044 fprintf (stream, _("\
8b53311e
NC
3045 -I --histogram Display histogram of bucket list lengths\n\
3046 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3047 @<file> Read options from <file>\n\
8b53311e
NC
3048 -H --help Display this information\n\
3049 -v --version Display the version number of readelf\n"));
1118d252 3050
92f01d61
JM
3051 if (REPORT_BUGS_TO[0] && stream == stdout)
3052 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3053
92f01d61 3054 exit (stream == stdout ? 0 : 1);
252b5132
RH
3055}
3056
18bd398b
NC
3057/* Record the fact that the user wants the contents of section number
3058 SECTION to be displayed using the method(s) encoded as flags bits
3059 in TYPE. Note, TYPE can be zero if we are creating the array for
3060 the first time. */
3061
252b5132 3062static void
09c11c86 3063request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3064{
3065 if (section >= num_dump_sects)
3066 {
2cf0635d 3067 dump_type * new_dump_sects;
252b5132 3068
3f5e193b
NC
3069 new_dump_sects = (dump_type *) calloc (section + 1,
3070 sizeof (* dump_sects));
252b5132
RH
3071
3072 if (new_dump_sects == NULL)
591a748a 3073 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3074 else
3075 {
3076 /* Copy current flag settings. */
09c11c86 3077 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3078
3079 free (dump_sects);
3080
3081 dump_sects = new_dump_sects;
3082 num_dump_sects = section + 1;
3083 }
3084 }
3085
3086 if (dump_sects)
b34976b6 3087 dump_sects[section] |= type;
252b5132
RH
3088
3089 return;
3090}
3091
aef1f6d0
DJ
3092/* Request a dump by section name. */
3093
3094static void
2cf0635d 3095request_dump_byname (const char * section, dump_type type)
aef1f6d0 3096{
2cf0635d 3097 struct dump_list_entry * new_request;
aef1f6d0 3098
3f5e193b
NC
3099 new_request = (struct dump_list_entry *)
3100 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3101 if (!new_request)
591a748a 3102 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3103
3104 new_request->name = strdup (section);
3105 if (!new_request->name)
591a748a 3106 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3107
3108 new_request->type = type;
3109
3110 new_request->next = dump_sects_byname;
3111 dump_sects_byname = new_request;
3112}
3113
cf13d699
NC
3114static inline void
3115request_dump (dump_type type)
3116{
3117 int section;
3118 char * cp;
3119
3120 do_dump++;
3121 section = strtoul (optarg, & cp, 0);
3122
3123 if (! *cp && section >= 0)
3124 request_dump_bynumber (section, type);
3125 else
3126 request_dump_byname (optarg, type);
3127}
3128
3129
252b5132 3130static void
2cf0635d 3131parse_args (int argc, char ** argv)
252b5132
RH
3132{
3133 int c;
3134
3135 if (argc < 2)
92f01d61 3136 usage (stderr);
252b5132
RH
3137
3138 while ((c = getopt_long
cf13d699 3139 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3140 {
252b5132
RH
3141 switch (c)
3142 {
3143 case 0:
3144 /* Long options. */
3145 break;
3146 case 'H':
92f01d61 3147 usage (stdout);
252b5132
RH
3148 break;
3149
3150 case 'a':
b34976b6
AM
3151 do_syms++;
3152 do_reloc++;
3153 do_unwind++;
3154 do_dynamic++;
3155 do_header++;
3156 do_sections++;
f5842774 3157 do_section_groups++;
b34976b6
AM
3158 do_segments++;
3159 do_version++;
3160 do_histogram++;
3161 do_arch++;
3162 do_notes++;
252b5132 3163 break;
f5842774
L
3164 case 'g':
3165 do_section_groups++;
3166 break;
5477e8a0 3167 case 't':
595cf52e 3168 case 'N':
5477e8a0
L
3169 do_sections++;
3170 do_section_details++;
595cf52e 3171 break;
252b5132 3172 case 'e':
b34976b6
AM
3173 do_header++;
3174 do_sections++;
3175 do_segments++;
252b5132 3176 break;
a952a375 3177 case 'A':
b34976b6 3178 do_arch++;
a952a375 3179 break;
252b5132 3180 case 'D':
b34976b6 3181 do_using_dynamic++;
252b5132
RH
3182 break;
3183 case 'r':
b34976b6 3184 do_reloc++;
252b5132 3185 break;
4d6ed7c8 3186 case 'u':
b34976b6 3187 do_unwind++;
4d6ed7c8 3188 break;
252b5132 3189 case 'h':
b34976b6 3190 do_header++;
252b5132
RH
3191 break;
3192 case 'l':
b34976b6 3193 do_segments++;
252b5132
RH
3194 break;
3195 case 's':
b34976b6 3196 do_syms++;
252b5132
RH
3197 break;
3198 case 'S':
b34976b6 3199 do_sections++;
252b5132
RH
3200 break;
3201 case 'd':
b34976b6 3202 do_dynamic++;
252b5132 3203 break;
a952a375 3204 case 'I':
b34976b6 3205 do_histogram++;
a952a375 3206 break;
779fe533 3207 case 'n':
b34976b6 3208 do_notes++;
779fe533 3209 break;
4145f1d5
NC
3210 case 'c':
3211 do_archive_index++;
3212 break;
252b5132 3213 case 'x':
cf13d699 3214 request_dump (HEX_DUMP);
aef1f6d0 3215 break;
09c11c86 3216 case 'p':
cf13d699
NC
3217 request_dump (STRING_DUMP);
3218 break;
3219 case 'R':
3220 request_dump (RELOC_DUMP);
09c11c86 3221 break;
252b5132 3222 case 'w':
b34976b6 3223 do_dump++;
252b5132 3224 if (optarg == 0)
613ff48b
CC
3225 {
3226 do_debugging = 1;
3227 dwarf_select_sections_all ();
3228 }
252b5132
RH
3229 else
3230 {
3231 do_debugging = 0;
4cb93e3b 3232 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3233 }
3234 break;
2979dc34 3235 case OPTION_DEBUG_DUMP:
b34976b6 3236 do_dump++;
2979dc34
JJ
3237 if (optarg == 0)
3238 do_debugging = 1;
3239 else
3240 {
2979dc34 3241 do_debugging = 0;
4cb93e3b 3242 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3243 }
3244 break;
2c610e4b
L
3245 case OPTION_DYN_SYMS:
3246 do_dyn_syms++;
3247 break;
252b5132
RH
3248#ifdef SUPPORT_DISASSEMBLY
3249 case 'i':
cf13d699
NC
3250 request_dump (DISASS_DUMP);
3251 break;
252b5132
RH
3252#endif
3253 case 'v':
3254 print_version (program_name);
3255 break;
3256 case 'V':
b34976b6 3257 do_version++;
252b5132 3258 break;
d974e256 3259 case 'W':
b34976b6 3260 do_wide++;
d974e256 3261 break;
252b5132 3262 default:
252b5132
RH
3263 /* xgettext:c-format */
3264 error (_("Invalid option '-%c'\n"), c);
3265 /* Drop through. */
3266 case '?':
92f01d61 3267 usage (stderr);
252b5132
RH
3268 }
3269 }
3270
4d6ed7c8 3271 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3272 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3273 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3274 && !do_section_groups && !do_archive_index
3275 && !do_dyn_syms)
92f01d61 3276 usage (stderr);
252b5132
RH
3277 else if (argc < 3)
3278 {
3279 warn (_("Nothing to do.\n"));
92f01d61 3280 usage (stderr);
252b5132
RH
3281 }
3282}
3283
3284static const char *
d3ba0551 3285get_elf_class (unsigned int elf_class)
252b5132 3286{
b34976b6 3287 static char buff[32];
103f02d3 3288
252b5132
RH
3289 switch (elf_class)
3290 {
3291 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3292 case ELFCLASS32: return "ELF32";
3293 case ELFCLASS64: return "ELF64";
ab5e7794 3294 default:
e9e44622 3295 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3296 return buff;
252b5132
RH
3297 }
3298}
3299
3300static const char *
d3ba0551 3301get_data_encoding (unsigned int encoding)
252b5132 3302{
b34976b6 3303 static char buff[32];
103f02d3 3304
252b5132
RH
3305 switch (encoding)
3306 {
3307 case ELFDATANONE: return _("none");
33c63f9d
CM
3308 case ELFDATA2LSB: return _("2's complement, little endian");
3309 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3310 default:
e9e44622 3311 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3312 return buff;
252b5132
RH
3313 }
3314}
3315
252b5132 3316/* Decode the data held in 'elf_header'. */
ee42cf8c 3317
252b5132 3318static int
d3ba0551 3319process_file_header (void)
252b5132 3320{
b34976b6
AM
3321 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3322 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3323 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3324 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3325 {
3326 error
3327 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3328 return 0;
3329 }
3330
2dc4cec1
L
3331 init_dwarf_regnames (elf_header.e_machine);
3332
252b5132
RH
3333 if (do_header)
3334 {
3335 int i;
3336
3337 printf (_("ELF Header:\n"));
3338 printf (_(" Magic: "));
b34976b6
AM
3339 for (i = 0; i < EI_NIDENT; i++)
3340 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3341 printf ("\n");
3342 printf (_(" Class: %s\n"),
b34976b6 3343 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3344 printf (_(" Data: %s\n"),
b34976b6 3345 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3346 printf (_(" Version: %d %s\n"),
b34976b6
AM
3347 elf_header.e_ident[EI_VERSION],
3348 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3349 ? "(current)"
b34976b6 3350 : (elf_header.e_ident[EI_VERSION] != EV_NONE
789be9f7
ILT
3351 ? "<unknown: %lx>"
3352 : "")));
252b5132 3353 printf (_(" OS/ABI: %s\n"),
b34976b6 3354 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3355 printf (_(" ABI Version: %d\n"),
b34976b6 3356 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3357 printf (_(" Type: %s\n"),
3358 get_file_type (elf_header.e_type));
3359 printf (_(" Machine: %s\n"),
3360 get_machine_name (elf_header.e_machine));
3361 printf (_(" Version: 0x%lx\n"),
3362 (unsigned long) elf_header.e_version);
76da6bbe 3363
f7a99963
NC
3364 printf (_(" Entry point address: "));
3365 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3366 printf (_("\n Start of program headers: "));
3367 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3368 printf (_(" (bytes into file)\n Start of section headers: "));
3369 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3370 printf (_(" (bytes into file)\n"));
76da6bbe 3371
252b5132
RH
3372 printf (_(" Flags: 0x%lx%s\n"),
3373 (unsigned long) elf_header.e_flags,
3374 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3375 printf (_(" Size of this header: %ld (bytes)\n"),
3376 (long) elf_header.e_ehsize);
3377 printf (_(" Size of program headers: %ld (bytes)\n"),
3378 (long) elf_header.e_phentsize);
2046a35d 3379 printf (_(" Number of program headers: %ld"),
252b5132 3380 (long) elf_header.e_phnum);
2046a35d
AM
3381 if (section_headers != NULL
3382 && elf_header.e_phnum == PN_XNUM
3383 && section_headers[0].sh_info != 0)
3384 printf (_(" (%ld)"), (long) section_headers[0].sh_info);
3385 putc ('\n', stdout);
252b5132
RH
3386 printf (_(" Size of section headers: %ld (bytes)\n"),
3387 (long) elf_header.e_shentsize);
560f3c1c 3388 printf (_(" Number of section headers: %ld"),
252b5132 3389 (long) elf_header.e_shnum);
4fbb74a6 3390 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3391 printf (" (%ld)", (long) section_headers[0].sh_size);
3392 putc ('\n', stdout);
3393 printf (_(" Section header string table index: %ld"),
252b5132 3394 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3395 if (section_headers != NULL
3396 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3397 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3398 else if (elf_header.e_shstrndx != SHN_UNDEF
3399 && elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3400 printf (" <corrupt: out of range>");
560f3c1c
AM
3401 putc ('\n', stdout);
3402 }
3403
3404 if (section_headers != NULL)
3405 {
2046a35d
AM
3406 if (elf_header.e_phnum == PN_XNUM
3407 && section_headers[0].sh_info != 0)
3408 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3409 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3410 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3411 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3412 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3413 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3414 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3415 free (section_headers);
3416 section_headers = NULL;
252b5132 3417 }
103f02d3 3418
9ea033b2
NC
3419 return 1;
3420}
3421
252b5132 3422
9ea033b2 3423static int
91d6fa6a 3424get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3425{
2cf0635d
NC
3426 Elf32_External_Phdr * phdrs;
3427 Elf32_External_Phdr * external;
3428 Elf_Internal_Phdr * internal;
b34976b6 3429 unsigned int i;
103f02d3 3430
3f5e193b
NC
3431 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3432 elf_header.e_phentsize,
3433 elf_header.e_phnum,
3434 _("program headers"));
a6e9f9df
AM
3435 if (!phdrs)
3436 return 0;
9ea033b2 3437
91d6fa6a 3438 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3439 i < elf_header.e_phnum;
b34976b6 3440 i++, internal++, external++)
252b5132 3441 {
9ea033b2
NC
3442 internal->p_type = BYTE_GET (external->p_type);
3443 internal->p_offset = BYTE_GET (external->p_offset);
3444 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3445 internal->p_paddr = BYTE_GET (external->p_paddr);
3446 internal->p_filesz = BYTE_GET (external->p_filesz);
3447 internal->p_memsz = BYTE_GET (external->p_memsz);
3448 internal->p_flags = BYTE_GET (external->p_flags);
3449 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3450 }
3451
9ea033b2
NC
3452 free (phdrs);
3453
252b5132
RH
3454 return 1;
3455}
3456
9ea033b2 3457static int
91d6fa6a 3458get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3459{
2cf0635d
NC
3460 Elf64_External_Phdr * phdrs;
3461 Elf64_External_Phdr * external;
3462 Elf_Internal_Phdr * internal;
b34976b6 3463 unsigned int i;
103f02d3 3464
3f5e193b
NC
3465 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3466 elf_header.e_phentsize,
3467 elf_header.e_phnum,
3468 _("program headers"));
a6e9f9df
AM
3469 if (!phdrs)
3470 return 0;
9ea033b2 3471
91d6fa6a 3472 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3473 i < elf_header.e_phnum;
b34976b6 3474 i++, internal++, external++)
9ea033b2
NC
3475 {
3476 internal->p_type = BYTE_GET (external->p_type);
3477 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3478 internal->p_offset = BYTE_GET (external->p_offset);
3479 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3480 internal->p_paddr = BYTE_GET (external->p_paddr);
3481 internal->p_filesz = BYTE_GET (external->p_filesz);
3482 internal->p_memsz = BYTE_GET (external->p_memsz);
3483 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3484 }
3485
3486 free (phdrs);
3487
3488 return 1;
3489}
252b5132 3490
d93f0186
NC
3491/* Returns 1 if the program headers were read into `program_headers'. */
3492
3493static int
2cf0635d 3494get_program_headers (FILE * file)
d93f0186 3495{
2cf0635d 3496 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3497
3498 /* Check cache of prior read. */
3499 if (program_headers != NULL)
3500 return 1;
3501
3f5e193b
NC
3502 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3503 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3504
3505 if (phdrs == NULL)
3506 {
3507 error (_("Out of memory\n"));
3508 return 0;
3509 }
3510
3511 if (is_32bit_elf
3512 ? get_32bit_program_headers (file, phdrs)
3513 : get_64bit_program_headers (file, phdrs))
3514 {
3515 program_headers = phdrs;
3516 return 1;
3517 }
3518
3519 free (phdrs);
3520 return 0;
3521}
3522
2f62977e
NC
3523/* Returns 1 if the program headers were loaded. */
3524
252b5132 3525static int
2cf0635d 3526process_program_headers (FILE * file)
252b5132 3527{
2cf0635d 3528 Elf_Internal_Phdr * segment;
b34976b6 3529 unsigned int i;
252b5132
RH
3530
3531 if (elf_header.e_phnum == 0)
3532 {
3533 if (do_segments)
3534 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3535 return 0;
252b5132
RH
3536 }
3537
3538 if (do_segments && !do_header)
3539 {
f7a99963
NC
3540 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3541 printf (_("Entry point "));
3542 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3543 printf (_("\nThere are %d program headers, starting at offset "),
3544 elf_header.e_phnum);
3545 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3546 printf ("\n");
252b5132
RH
3547 }
3548
d93f0186 3549 if (! get_program_headers (file))
252b5132 3550 return 0;
103f02d3 3551
252b5132
RH
3552 if (do_segments)
3553 {
3a1a2036
NC
3554 if (elf_header.e_phnum > 1)
3555 printf (_("\nProgram Headers:\n"));
3556 else
3557 printf (_("\nProgram Headers:\n"));
76da6bbe 3558
f7a99963
NC
3559 if (is_32bit_elf)
3560 printf
3561 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3562 else if (do_wide)
3563 printf
3564 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3565 else
3566 {
3567 printf
3568 (_(" Type Offset VirtAddr PhysAddr\n"));
3569 printf
3570 (_(" FileSiz MemSiz Flags Align\n"));
3571 }
252b5132
RH
3572 }
3573
252b5132 3574 dynamic_addr = 0;
1b228002 3575 dynamic_size = 0;
252b5132
RH
3576
3577 for (i = 0, segment = program_headers;
3578 i < elf_header.e_phnum;
b34976b6 3579 i++, segment++)
252b5132
RH
3580 {
3581 if (do_segments)
3582 {
103f02d3 3583 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3584
3585 if (is_32bit_elf)
3586 {
3587 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3588 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3589 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3590 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3591 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3592 printf ("%c%c%c ",
3593 (segment->p_flags & PF_R ? 'R' : ' '),
3594 (segment->p_flags & PF_W ? 'W' : ' '),
3595 (segment->p_flags & PF_X ? 'E' : ' '));
3596 printf ("%#lx", (unsigned long) segment->p_align);
3597 }
d974e256
JJ
3598 else if (do_wide)
3599 {
3600 if ((unsigned long) segment->p_offset == segment->p_offset)
3601 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3602 else
3603 {
3604 print_vma (segment->p_offset, FULL_HEX);
3605 putchar (' ');
3606 }
3607
3608 print_vma (segment->p_vaddr, FULL_HEX);
3609 putchar (' ');
3610 print_vma (segment->p_paddr, FULL_HEX);
3611 putchar (' ');
3612
3613 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3614 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3615 else
3616 {
3617 print_vma (segment->p_filesz, FULL_HEX);
3618 putchar (' ');
3619 }
3620
3621 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3622 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3623 else
3624 {
3625 print_vma (segment->p_offset, FULL_HEX);
3626 }
3627
3628 printf (" %c%c%c ",
3629 (segment->p_flags & PF_R ? 'R' : ' '),
3630 (segment->p_flags & PF_W ? 'W' : ' '),
3631 (segment->p_flags & PF_X ? 'E' : ' '));
3632
3633 if ((unsigned long) segment->p_align == segment->p_align)
3634 printf ("%#lx", (unsigned long) segment->p_align);
3635 else
3636 {
3637 print_vma (segment->p_align, PREFIX_HEX);
3638 }
3639 }
f7a99963
NC
3640 else
3641 {
3642 print_vma (segment->p_offset, FULL_HEX);
3643 putchar (' ');
3644 print_vma (segment->p_vaddr, FULL_HEX);
3645 putchar (' ');
3646 print_vma (segment->p_paddr, FULL_HEX);
3647 printf ("\n ");
3648 print_vma (segment->p_filesz, FULL_HEX);
3649 putchar (' ');
3650 print_vma (segment->p_memsz, FULL_HEX);
3651 printf (" %c%c%c ",
3652 (segment->p_flags & PF_R ? 'R' : ' '),
3653 (segment->p_flags & PF_W ? 'W' : ' '),
3654 (segment->p_flags & PF_X ? 'E' : ' '));
3655 print_vma (segment->p_align, HEX);
3656 }
252b5132
RH
3657 }
3658
3659 switch (segment->p_type)
3660 {
252b5132
RH
3661 case PT_DYNAMIC:
3662 if (dynamic_addr)
3663 error (_("more than one dynamic segment\n"));
3664
20737c13
AM
3665 /* By default, assume that the .dynamic section is the first
3666 section in the DYNAMIC segment. */
3667 dynamic_addr = segment->p_offset;
3668 dynamic_size = segment->p_filesz;
3669
b2d38a17
NC
3670 /* Try to locate the .dynamic section. If there is
3671 a section header table, we can easily locate it. */
3672 if (section_headers != NULL)
3673 {
2cf0635d 3674 Elf_Internal_Shdr * sec;
b2d38a17 3675
89fac5e3
RS
3676 sec = find_section (".dynamic");
3677 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3678 {
591a748a 3679 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3680 break;
3681 }
3682
42bb2e33 3683 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3684 {
3685 dynamic_size = 0;
3686 break;
3687 }
42bb2e33 3688
b2d38a17
NC
3689 dynamic_addr = sec->sh_offset;
3690 dynamic_size = sec->sh_size;
3691
3692 if (dynamic_addr < segment->p_offset
3693 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3694 warn (_("the .dynamic section is not contained"
3695 " within the dynamic segment\n"));
b2d38a17 3696 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3697 warn (_("the .dynamic section is not the first section"
3698 " in the dynamic segment.\n"));
b2d38a17 3699 }
252b5132
RH
3700 break;
3701
3702 case PT_INTERP:
fb52b2f4
NC
3703 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3704 SEEK_SET))
252b5132
RH
3705 error (_("Unable to find program interpreter name\n"));
3706 else
3707 {
f8eae8b2
L
3708 char fmt [32];
3709 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3710
3711 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3712 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3713
252b5132 3714 program_interpreter[0] = 0;
7bd7b3ef
AM
3715 if (fscanf (file, fmt, program_interpreter) <= 0)
3716 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3717
3718 if (do_segments)
3719 printf (_("\n [Requesting program interpreter: %s]"),
3720 program_interpreter);
3721 }
3722 break;
3723 }
3724
3725 if (do_segments)
3726 putc ('\n', stdout);
3727 }
3728
c256ffe7 3729 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3730 {
3731 printf (_("\n Section to Segment mapping:\n"));
3732 printf (_(" Segment Sections...\n"));
3733
252b5132
RH
3734 for (i = 0; i < elf_header.e_phnum; i++)
3735 {
9ad5cbcf 3736 unsigned int j;
2cf0635d 3737 Elf_Internal_Shdr * section;
252b5132
RH
3738
3739 segment = program_headers + i;
b391a3e3 3740 section = section_headers + 1;
252b5132
RH
3741
3742 printf (" %2.2d ", i);
3743
b34976b6 3744 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3745 {
2cf0635d 3746 if (ELF_IS_SECTION_IN_SEGMENT_MEMORY (section, segment))
252b5132
RH
3747 printf ("%s ", SECTION_NAME (section));
3748 }
3749
3750 putc ('\n',stdout);
3751 }
3752 }
3753
252b5132
RH
3754 return 1;
3755}
3756
3757
d93f0186
NC
3758/* Find the file offset corresponding to VMA by using the program headers. */
3759
3760static long
2cf0635d 3761offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 3762{
2cf0635d 3763 Elf_Internal_Phdr * seg;
d93f0186
NC
3764
3765 if (! get_program_headers (file))
3766 {
3767 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3768 return (long) vma;
3769 }
3770
3771 for (seg = program_headers;
3772 seg < program_headers + elf_header.e_phnum;
3773 ++seg)
3774 {
3775 if (seg->p_type != PT_LOAD)
3776 continue;
3777
3778 if (vma >= (seg->p_vaddr & -seg->p_align)
3779 && vma + size <= seg->p_vaddr + seg->p_filesz)
3780 return vma - seg->p_vaddr + seg->p_offset;
3781 }
3782
3783 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 3784 (unsigned long) vma);
d93f0186
NC
3785 return (long) vma;
3786}
3787
3788
252b5132 3789static int
2cf0635d 3790get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 3791{
2cf0635d
NC
3792 Elf32_External_Shdr * shdrs;
3793 Elf_Internal_Shdr * internal;
b34976b6 3794 unsigned int i;
252b5132 3795
3f5e193b
NC
3796 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3797 elf_header.e_shentsize, num,
3798 _("section headers"));
a6e9f9df
AM
3799 if (!shdrs)
3800 return 0;
252b5132 3801
3f5e193b
NC
3802 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3803 sizeof (Elf_Internal_Shdr));
252b5132
RH
3804
3805 if (section_headers == NULL)
3806 {
3807 error (_("Out of memory\n"));
3808 return 0;
3809 }
3810
3811 for (i = 0, internal = section_headers;
560f3c1c 3812 i < num;
b34976b6 3813 i++, internal++)
252b5132
RH
3814 {
3815 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3816 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3817 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3818 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3819 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3820 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3821 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3822 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3823 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3824 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3825 }
3826
3827 free (shdrs);
3828
3829 return 1;
3830}
3831
9ea033b2 3832static int
2cf0635d 3833get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 3834{
2cf0635d
NC
3835 Elf64_External_Shdr * shdrs;
3836 Elf_Internal_Shdr * internal;
b34976b6 3837 unsigned int i;
9ea033b2 3838
3f5e193b
NC
3839 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3840 elf_header.e_shentsize, num,
3841 _("section headers"));
a6e9f9df
AM
3842 if (!shdrs)
3843 return 0;
9ea033b2 3844
3f5e193b
NC
3845 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3846 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
3847
3848 if (section_headers == NULL)
3849 {
3850 error (_("Out of memory\n"));
3851 return 0;
3852 }
3853
3854 for (i = 0, internal = section_headers;
560f3c1c 3855 i < num;
b34976b6 3856 i++, internal++)
9ea033b2
NC
3857 {
3858 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3859 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
3860 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3861 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3862 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3863 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
3864 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3865 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3866 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3867 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3868 }
3869
3870 free (shdrs);
3871
3872 return 1;
3873}
3874
252b5132 3875static Elf_Internal_Sym *
2cf0635d 3876get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
252b5132 3877{
9ad5cbcf 3878 unsigned long number;
2cf0635d
NC
3879 Elf32_External_Sym * esyms;
3880 Elf_External_Sym_Shndx * shndx;
3881 Elf_Internal_Sym * isyms;
3882 Elf_Internal_Sym * psym;
b34976b6 3883 unsigned int j;
252b5132 3884
3f5e193b
NC
3885 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
3886 section->sh_size, _("symbols"));
a6e9f9df
AM
3887 if (!esyms)
3888 return NULL;
252b5132 3889
9ad5cbcf
AM
3890 shndx = NULL;
3891 if (symtab_shndx_hdr != NULL
3892 && (symtab_shndx_hdr->sh_link
4fbb74a6 3893 == (unsigned long) (section - section_headers)))
9ad5cbcf 3894 {
3f5e193b
NC
3895 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
3896 symtab_shndx_hdr->sh_offset,
3897 1, symtab_shndx_hdr->sh_size,
3898 _("symtab shndx"));
9ad5cbcf
AM
3899 if (!shndx)
3900 {
3901 free (esyms);
3902 return NULL;
3903 }
3904 }
3905
3906 number = section->sh_size / section->sh_entsize;
3f5e193b 3907 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
3908
3909 if (isyms == NULL)
3910 {
3911 error (_("Out of memory\n"));
9ad5cbcf
AM
3912 if (shndx)
3913 free (shndx);
252b5132 3914 free (esyms);
252b5132
RH
3915 return NULL;
3916 }
3917
3918 for (j = 0, psym = isyms;
3919 j < number;
b34976b6 3920 j++, psym++)
252b5132
RH
3921 {
3922 psym->st_name = BYTE_GET (esyms[j].st_name);
3923 psym->st_value = BYTE_GET (esyms[j].st_value);
3924 psym->st_size = BYTE_GET (esyms[j].st_size);
3925 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 3926 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
3927 psym->st_shndx
3928 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
3929 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
3930 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
3931 psym->st_info = BYTE_GET (esyms[j].st_info);
3932 psym->st_other = BYTE_GET (esyms[j].st_other);
3933 }
3934
9ad5cbcf
AM
3935 if (shndx)
3936 free (shndx);
252b5132
RH
3937 free (esyms);
3938
3939 return isyms;
3940}
3941
9ea033b2 3942static Elf_Internal_Sym *
2cf0635d 3943get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
9ea033b2 3944{
9ad5cbcf 3945 unsigned long number;
2cf0635d
NC
3946 Elf64_External_Sym * esyms;
3947 Elf_External_Sym_Shndx * shndx;
3948 Elf_Internal_Sym * isyms;
3949 Elf_Internal_Sym * psym;
b34976b6 3950 unsigned int j;
9ea033b2 3951
3f5e193b
NC
3952 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
3953 section->sh_size, _("symbols"));
a6e9f9df
AM
3954 if (!esyms)
3955 return NULL;
9ea033b2 3956
9ad5cbcf
AM
3957 shndx = NULL;
3958 if (symtab_shndx_hdr != NULL
3959 && (symtab_shndx_hdr->sh_link
4fbb74a6 3960 == (unsigned long) (section - section_headers)))
9ad5cbcf 3961 {
3f5e193b
NC
3962 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
3963 symtab_shndx_hdr->sh_offset,
3964 1, symtab_shndx_hdr->sh_size,
3965 _("symtab shndx"));
9ad5cbcf
AM
3966 if (!shndx)
3967 {
3968 free (esyms);
3969 return NULL;
3970 }
3971 }
3972
3973 number = section->sh_size / section->sh_entsize;
3f5e193b 3974 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
3975
3976 if (isyms == NULL)
3977 {
3978 error (_("Out of memory\n"));
9ad5cbcf
AM
3979 if (shndx)
3980 free (shndx);
9ea033b2 3981 free (esyms);
9ea033b2
NC
3982 return NULL;
3983 }
3984
3985 for (j = 0, psym = isyms;
3986 j < number;
b34976b6 3987 j++, psym++)
9ea033b2
NC
3988 {
3989 psym->st_name = BYTE_GET (esyms[j].st_name);
3990 psym->st_info = BYTE_GET (esyms[j].st_info);
3991 psym->st_other = BYTE_GET (esyms[j].st_other);
3992 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 3993 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
3994 psym->st_shndx
3995 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
3996 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
3997 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
66543521
AM
3998 psym->st_value = BYTE_GET (esyms[j].st_value);
3999 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4000 }
4001
9ad5cbcf
AM
4002 if (shndx)
4003 free (shndx);
9ea033b2
NC
4004 free (esyms);
4005
4006 return isyms;
4007}
4008
d1133906 4009static const char *
d3ba0551 4010get_elf_section_flags (bfd_vma sh_flags)
d1133906 4011{
5477e8a0 4012 static char buff[1024];
2cf0635d 4013 char * p = buff;
8d5ff12c 4014 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4015 int sindex;
4016 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4017 bfd_vma os_flags = 0;
4018 bfd_vma proc_flags = 0;
4019 bfd_vma unknown_flags = 0;
148b93f2 4020 static const struct
5477e8a0 4021 {
2cf0635d 4022 const char * str;
5477e8a0
L
4023 int len;
4024 }
4025 flags [] =
4026 {
cfcac11d
NC
4027 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4028 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4029 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4030 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4031 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4032 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4033 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4034 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4035 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4036 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4037 /* IA-64 specific. */
4038 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4039 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4040 /* IA-64 OpenVMS specific. */
4041 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4042 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4043 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4044 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4045 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4046 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
4047 /* SPARC specific. */
4048 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
4049 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4050 };
4051
4052 if (do_section_details)
4053 {
8d5ff12c
L
4054 sprintf (buff, "[%*.*lx]: ",
4055 field_size, field_size, (unsigned long) sh_flags);
4056 p += field_size + 4;
5477e8a0 4057 }
76da6bbe 4058
d1133906
NC
4059 while (sh_flags)
4060 {
4061 bfd_vma flag;
4062
4063 flag = sh_flags & - sh_flags;
4064 sh_flags &= ~ flag;
76da6bbe 4065
5477e8a0 4066 if (do_section_details)
d1133906 4067 {
5477e8a0
L
4068 switch (flag)
4069 {
91d6fa6a
NC
4070 case SHF_WRITE: sindex = 0; break;
4071 case SHF_ALLOC: sindex = 1; break;
4072 case SHF_EXECINSTR: sindex = 2; break;
4073 case SHF_MERGE: sindex = 3; break;
4074 case SHF_STRINGS: sindex = 4; break;
4075 case SHF_INFO_LINK: sindex = 5; break;
4076 case SHF_LINK_ORDER: sindex = 6; break;
4077 case SHF_OS_NONCONFORMING: sindex = 7; break;
4078 case SHF_GROUP: sindex = 8; break;
4079 case SHF_TLS: sindex = 9; break;
76da6bbe 4080
5477e8a0 4081 default:
91d6fa6a 4082 sindex = -1;
cfcac11d 4083 switch (elf_header.e_machine)
148b93f2 4084 {
cfcac11d 4085 case EM_IA_64:
148b93f2 4086 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4087 sindex = 10;
148b93f2 4088 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4089 sindex = 11;
148b93f2
NC
4090#ifdef BFD64
4091 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4092 switch (flag)
4093 {
91d6fa6a
NC
4094 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4095 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4096 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4097 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4098 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4099 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4100 default: break;
4101 }
4102#endif
cfcac11d
NC
4103 break;
4104
caa83f8b
NC
4105 case EM_386:
4106 case EM_486:
4107 case EM_X86_64:
cfcac11d
NC
4108 case EM_OLD_SPARCV9:
4109 case EM_SPARC32PLUS:
4110 case EM_SPARCV9:
4111 case EM_SPARC:
4112 if (flag == SHF_EXCLUDE)
91d6fa6a 4113 sindex = 18;
cfcac11d 4114 else if (flag == SHF_ORDERED)
91d6fa6a 4115 sindex = 19;
cfcac11d
NC
4116 break;
4117 default:
4118 break;
148b93f2 4119 }
5477e8a0
L
4120 }
4121
91d6fa6a 4122 if (sindex != -1)
5477e8a0 4123 {
8d5ff12c
L
4124 if (p != buff + field_size + 4)
4125 {
4126 if (size < (10 + 2))
4127 abort ();
4128 size -= 2;
4129 *p++ = ',';
4130 *p++ = ' ';
4131 }
4132
91d6fa6a
NC
4133 size -= flags [sindex].len;
4134 p = stpcpy (p, flags [sindex].str);
5477e8a0 4135 }
3b22753a 4136 else if (flag & SHF_MASKOS)
8d5ff12c 4137 os_flags |= flag;
d1133906 4138 else if (flag & SHF_MASKPROC)
8d5ff12c 4139 proc_flags |= flag;
d1133906 4140 else
8d5ff12c 4141 unknown_flags |= flag;
5477e8a0
L
4142 }
4143 else
4144 {
4145 switch (flag)
4146 {
4147 case SHF_WRITE: *p = 'W'; break;
4148 case SHF_ALLOC: *p = 'A'; break;
4149 case SHF_EXECINSTR: *p = 'X'; break;
4150 case SHF_MERGE: *p = 'M'; break;
4151 case SHF_STRINGS: *p = 'S'; break;
4152 case SHF_INFO_LINK: *p = 'I'; break;
4153 case SHF_LINK_ORDER: *p = 'L'; break;
4154 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4155 case SHF_GROUP: *p = 'G'; break;
4156 case SHF_TLS: *p = 'T'; break;
4157
4158 default:
8a9036a4
L
4159 if ((elf_header.e_machine == EM_X86_64
4160 || elf_header.e_machine == EM_L1OM)
5477e8a0
L
4161 && flag == SHF_X86_64_LARGE)
4162 *p = 'l';
4163 else if (flag & SHF_MASKOS)
4164 {
4165 *p = 'o';
4166 sh_flags &= ~ SHF_MASKOS;
4167 }
4168 else if (flag & SHF_MASKPROC)
4169 {
4170 *p = 'p';
4171 sh_flags &= ~ SHF_MASKPROC;
4172 }
4173 else
4174 *p = 'x';
4175 break;
4176 }
4177 p++;
d1133906
NC
4178 }
4179 }
76da6bbe 4180
8d5ff12c
L
4181 if (do_section_details)
4182 {
4183 if (os_flags)
4184 {
4185 size -= 5 + field_size;
4186 if (p != buff + field_size + 4)
4187 {
4188 if (size < (2 + 1))
4189 abort ();
4190 size -= 2;
4191 *p++ = ',';
4192 *p++ = ' ';
4193 }
4194 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4195 (unsigned long) os_flags);
4196 p += 5 + field_size;
4197 }
4198 if (proc_flags)
4199 {
4200 size -= 7 + field_size;
4201 if (p != buff + field_size + 4)
4202 {
4203 if (size < (2 + 1))
4204 abort ();
4205 size -= 2;
4206 *p++ = ',';
4207 *p++ = ' ';
4208 }
4209 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4210 (unsigned long) proc_flags);
4211 p += 7 + field_size;
4212 }
4213 if (unknown_flags)
4214 {
4215 size -= 10 + field_size;
4216 if (p != buff + field_size + 4)
4217 {
4218 if (size < (2 + 1))
4219 abort ();
4220 size -= 2;
4221 *p++ = ',';
4222 *p++ = ' ';
4223 }
4224 sprintf (p, "UNKNOWN (%*.*lx)", field_size, field_size,
4225 (unsigned long) unknown_flags);
4226 p += 10 + field_size;
4227 }
4228 }
4229
e9e44622 4230 *p = '\0';
d1133906
NC
4231 return buff;
4232}
4233
252b5132 4234static int
2cf0635d 4235process_section_headers (FILE * file)
252b5132 4236{
2cf0635d 4237 Elf_Internal_Shdr * section;
b34976b6 4238 unsigned int i;
252b5132
RH
4239
4240 section_headers = NULL;
4241
4242 if (elf_header.e_shnum == 0)
4243 {
4244 if (do_sections)
4245 printf (_("\nThere are no sections in this file.\n"));
4246
4247 return 1;
4248 }
4249
4250 if (do_sections && !do_header)
9ea033b2 4251 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4252 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4253
9ea033b2
NC
4254 if (is_32bit_elf)
4255 {
560f3c1c 4256 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4257 return 0;
4258 }
560f3c1c 4259 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4260 return 0;
4261
4262 /* Read in the string table, so that we have names to display. */
0b49d371 4263 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4264 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4265 {
4fbb74a6 4266 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4267
c256ffe7
JJ
4268 if (section->sh_size != 0)
4269 {
3f5e193b
NC
4270 string_table = (char *) get_data (NULL, file, section->sh_offset,
4271 1, section->sh_size,
4272 _("string table"));
0de14b54 4273
c256ffe7
JJ
4274 string_table_length = string_table != NULL ? section->sh_size : 0;
4275 }
252b5132
RH
4276 }
4277
4278 /* Scan the sections for the dynamic symbol table
e3c8793a 4279 and dynamic string table and debug sections. */
252b5132
RH
4280 dynamic_symbols = NULL;
4281 dynamic_strings = NULL;
4282 dynamic_syminfo = NULL;
f1ef08cb 4283 symtab_shndx_hdr = NULL;
103f02d3 4284
89fac5e3
RS
4285 eh_addr_size = is_32bit_elf ? 4 : 8;
4286 switch (elf_header.e_machine)
4287 {
4288 case EM_MIPS:
4289 case EM_MIPS_RS3_LE:
4290 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4291 FDE addresses. However, the ABI also has a semi-official ILP32
4292 variant for which the normal FDE address size rules apply.
4293
4294 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4295 section, where XX is the size of longs in bits. Unfortunately,
4296 earlier compilers provided no way of distinguishing ILP32 objects
4297 from LP64 objects, so if there's any doubt, we should assume that
4298 the official LP64 form is being used. */
4299 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4300 && find_section (".gcc_compiled_long32") == NULL)
4301 eh_addr_size = 8;
4302 break;
0f56a26a
DD
4303
4304 case EM_H8_300:
4305 case EM_H8_300H:
4306 switch (elf_header.e_flags & EF_H8_MACH)
4307 {
4308 case E_H8_MACH_H8300:
4309 case E_H8_MACH_H8300HN:
4310 case E_H8_MACH_H8300SN:
4311 case E_H8_MACH_H8300SXN:
4312 eh_addr_size = 2;
4313 break;
4314 case E_H8_MACH_H8300H:
4315 case E_H8_MACH_H8300S:
4316 case E_H8_MACH_H8300SX:
4317 eh_addr_size = 4;
4318 break;
4319 }
f4236fe4
DD
4320 break;
4321
ff7eeb89 4322 case EM_M32C_OLD:
f4236fe4
DD
4323 case EM_M32C:
4324 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4325 {
4326 case EF_M32C_CPU_M16C:
4327 eh_addr_size = 2;
4328 break;
4329 }
4330 break;
89fac5e3
RS
4331 }
4332
08d8fa11
JJ
4333#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4334 do \
4335 { \
4336 size_t expected_entsize \
4337 = is_32bit_elf ? size32 : size64; \
4338 if (section->sh_entsize != expected_entsize) \
4339 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4340 i, (unsigned long int) section->sh_entsize, \
4341 (unsigned long int) expected_entsize); \
4342 section->sh_entsize = expected_entsize; \
4343 } \
4344 while (0)
4345#define CHECK_ENTSIZE(section, i, type) \
4346 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4347 sizeof (Elf64_External_##type))
4348
252b5132
RH
4349 for (i = 0, section = section_headers;
4350 i < elf_header.e_shnum;
b34976b6 4351 i++, section++)
252b5132 4352 {
2cf0635d 4353 char * name = SECTION_NAME (section);
252b5132
RH
4354
4355 if (section->sh_type == SHT_DYNSYM)
4356 {
4357 if (dynamic_symbols != NULL)
4358 {
4359 error (_("File contains multiple dynamic symbol tables\n"));
4360 continue;
4361 }
4362
08d8fa11 4363 CHECK_ENTSIZE (section, i, Sym);
19936277 4364 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4365 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4366 }
4367 else if (section->sh_type == SHT_STRTAB
18bd398b 4368 && streq (name, ".dynstr"))
252b5132
RH
4369 {
4370 if (dynamic_strings != NULL)
4371 {
4372 error (_("File contains multiple dynamic string tables\n"));
4373 continue;
4374 }
4375
3f5e193b
NC
4376 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4377 1, section->sh_size,
4378 _("dynamic strings"));
d79b3d50 4379 dynamic_strings_length = section->sh_size;
252b5132 4380 }
9ad5cbcf
AM
4381 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4382 {
4383 if (symtab_shndx_hdr != NULL)
4384 {
4385 error (_("File contains multiple symtab shndx tables\n"));
4386 continue;
4387 }
4388 symtab_shndx_hdr = section;
4389 }
08d8fa11
JJ
4390 else if (section->sh_type == SHT_SYMTAB)
4391 CHECK_ENTSIZE (section, i, Sym);
4392 else if (section->sh_type == SHT_GROUP)
4393 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4394 else if (section->sh_type == SHT_REL)
4395 CHECK_ENTSIZE (section, i, Rel);
4396 else if (section->sh_type == SHT_RELA)
4397 CHECK_ENTSIZE (section, i, Rela);
252b5132 4398 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4399 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4400 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4401 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4402 && (const_strneq (name, ".debug_")
4403 || const_strneq (name, ".zdebug_")))
252b5132 4404 {
1b315056
CS
4405 if (name[1] == 'z')
4406 name += sizeof (".zdebug_") - 1;
4407 else
4408 name += sizeof (".debug_") - 1;
252b5132
RH
4409
4410 if (do_debugging
18bd398b 4411 || (do_debug_info && streq (name, "info"))
2b6f5997 4412 || (do_debug_info && streq (name, "types"))
18bd398b 4413 || (do_debug_abbrevs && streq (name, "abbrev"))
4cb93e3b 4414 || (do_debug_lines && streq (name, "line"))
18bd398b 4415 || (do_debug_pubnames && streq (name, "pubnames"))
f9f0e732 4416 || (do_debug_pubtypes && streq (name, "pubtypes"))
18bd398b
NC
4417 || (do_debug_aranges && streq (name, "aranges"))
4418 || (do_debug_ranges && streq (name, "ranges"))
4419 || (do_debug_frames && streq (name, "frame"))
4420 || (do_debug_macinfo && streq (name, "macinfo"))
4421 || (do_debug_str && streq (name, "str"))
4422 || (do_debug_loc && streq (name, "loc"))
252b5132 4423 )
09c11c86 4424 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4425 }
a262ae96 4426 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4427 else if ((do_debugging || do_debug_info)
0112cd26 4428 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4429 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4430 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4431 request_dump_bynumber (i, DEBUG_DUMP);
252b5132
RH
4432 }
4433
4434 if (! do_sections)
4435 return 1;
4436
3a1a2036
NC
4437 if (elf_header.e_shnum > 1)
4438 printf (_("\nSection Headers:\n"));
4439 else
4440 printf (_("\nSection Header:\n"));
76da6bbe 4441
f7a99963 4442 if (is_32bit_elf)
595cf52e 4443 {
5477e8a0 4444 if (do_section_details)
595cf52e
L
4445 {
4446 printf (_(" [Nr] Name\n"));
5477e8a0 4447 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4448 }
4449 else
4450 printf
4451 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4452 }
d974e256 4453 else if (do_wide)
595cf52e 4454 {
5477e8a0 4455 if (do_section_details)
595cf52e
L
4456 {
4457 printf (_(" [Nr] Name\n"));
5477e8a0 4458 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4459 }
4460 else
4461 printf
4462 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4463 }
f7a99963
NC
4464 else
4465 {
5477e8a0 4466 if (do_section_details)
595cf52e
L
4467 {
4468 printf (_(" [Nr] Name\n"));
5477e8a0
L
4469 printf (_(" Type Address Offset Link\n"));
4470 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4471 }
4472 else
4473 {
4474 printf (_(" [Nr] Name Type Address Offset\n"));
4475 printf (_(" Size EntSize Flags Link Info Align\n"));
4476 }
f7a99963 4477 }
252b5132 4478
5477e8a0
L
4479 if (do_section_details)
4480 printf (_(" Flags\n"));
4481
252b5132
RH
4482 for (i = 0, section = section_headers;
4483 i < elf_header.e_shnum;
b34976b6 4484 i++, section++)
252b5132 4485 {
5477e8a0 4486 if (do_section_details)
595cf52e
L
4487 {
4488 printf (" [%2u] %s\n",
4fbb74a6 4489 i,
595cf52e
L
4490 SECTION_NAME (section));
4491 if (is_32bit_elf || do_wide)
4492 printf (" %-15.15s ",
4493 get_section_type_name (section->sh_type));
4494 }
4495 else
b9eb56c1
NC
4496 printf ((do_wide ? " [%2u] %-17s %-15s "
4497 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4498 i,
595cf52e
L
4499 SECTION_NAME (section),
4500 get_section_type_name (section->sh_type));
252b5132 4501
f7a99963
NC
4502 if (is_32bit_elf)
4503 {
cfcac11d
NC
4504 const char * link_too_big = NULL;
4505
f7a99963 4506 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4507
f7a99963
NC
4508 printf ( " %6.6lx %6.6lx %2.2lx",
4509 (unsigned long) section->sh_offset,
4510 (unsigned long) section->sh_size,
4511 (unsigned long) section->sh_entsize);
d1133906 4512
5477e8a0
L
4513 if (do_section_details)
4514 fputs (" ", stdout);
4515 else
4516 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4517
cfcac11d
NC
4518 if (section->sh_link >= elf_header.e_shnum)
4519 {
4520 link_too_big = "";
4521 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4522 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4523 switch (elf_header.e_machine)
4524 {
caa83f8b
NC
4525 case EM_386:
4526 case EM_486:
4527 case EM_X86_64:
cfcac11d
NC
4528 case EM_OLD_SPARCV9:
4529 case EM_SPARC32PLUS:
4530 case EM_SPARCV9:
4531 case EM_SPARC:
4532 if (section->sh_link == (SHN_BEFORE & 0xffff))
4533 link_too_big = "BEFORE";
4534 else if (section->sh_link == (SHN_AFTER & 0xffff))
4535 link_too_big = "AFTER";
4536 break;
4537 default:
4538 break;
4539 }
4540 }
4541
4542 if (do_section_details)
4543 {
4544 if (link_too_big != NULL && * link_too_big)
4545 printf ("<%s> ", link_too_big);
4546 else
4547 printf ("%2u ", section->sh_link);
4548 printf ("%3u %2lu\n", section->sh_info,
4549 (unsigned long) section->sh_addralign);
4550 }
4551 else
4552 printf ("%2u %3u %2lu\n",
4553 section->sh_link,
4554 section->sh_info,
4555 (unsigned long) section->sh_addralign);
4556
4557 if (link_too_big && ! * link_too_big)
4558 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4559 i, section->sh_link);
f7a99963 4560 }
d974e256
JJ
4561 else if (do_wide)
4562 {
4563 print_vma (section->sh_addr, LONG_HEX);
4564
4565 if ((long) section->sh_offset == section->sh_offset)
4566 printf (" %6.6lx", (unsigned long) section->sh_offset);
4567 else
4568 {
4569 putchar (' ');
4570 print_vma (section->sh_offset, LONG_HEX);
4571 }
4572
4573 if ((unsigned long) section->sh_size == section->sh_size)
4574 printf (" %6.6lx", (unsigned long) section->sh_size);
4575 else
4576 {
4577 putchar (' ');
4578 print_vma (section->sh_size, LONG_HEX);
4579 }
4580
4581 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4582 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4583 else
4584 {
4585 putchar (' ');
4586 print_vma (section->sh_entsize, LONG_HEX);
4587 }
4588
5477e8a0
L
4589 if (do_section_details)
4590 fputs (" ", stdout);
4591 else
4592 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4593
72de5009 4594 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4595
4596 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4597 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4598 else
4599 {
4600 print_vma (section->sh_addralign, DEC);
4601 putchar ('\n');
4602 }
4603 }
5477e8a0 4604 else if (do_section_details)
595cf52e 4605 {
5477e8a0 4606 printf (" %-15.15s ",
595cf52e 4607 get_section_type_name (section->sh_type));
595cf52e
L
4608 print_vma (section->sh_addr, LONG_HEX);
4609 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4610 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4611 else
4612 {
4613 printf (" ");
4614 print_vma (section->sh_offset, LONG_HEX);
4615 }
72de5009 4616 printf (" %u\n ", section->sh_link);
595cf52e 4617 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4618 putchar (' ');
595cf52e
L
4619 print_vma (section->sh_entsize, LONG_HEX);
4620
72de5009
AM
4621 printf (" %-16u %lu\n",
4622 section->sh_info,
595cf52e
L
4623 (unsigned long) section->sh_addralign);
4624 }
f7a99963
NC
4625 else
4626 {
4627 putchar (' ');
4628 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4629 if ((long) section->sh_offset == section->sh_offset)
4630 printf (" %8.8lx", (unsigned long) section->sh_offset);
4631 else
4632 {
4633 printf (" ");
4634 print_vma (section->sh_offset, LONG_HEX);
4635 }
f7a99963
NC
4636 printf ("\n ");
4637 print_vma (section->sh_size, LONG_HEX);
4638 printf (" ");
4639 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4640
d1133906 4641 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4642
72de5009
AM
4643 printf (" %2u %3u %lu\n",
4644 section->sh_link,
4645 section->sh_info,
f7a99963
NC
4646 (unsigned long) section->sh_addralign);
4647 }
5477e8a0
L
4648
4649 if (do_section_details)
4650 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4651 }
4652
5477e8a0
L
4653 if (!do_section_details)
4654 printf (_("Key to Flags:\n\
e3c8793a
NC
4655 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
4656 I (info), L (link order), G (group), x (unknown)\n\
4657 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 4658
252b5132
RH
4659 return 1;
4660}
4661
f5842774
L
4662static const char *
4663get_group_flags (unsigned int flags)
4664{
4665 static char buff[32];
4666 switch (flags)
4667 {
220453ec
AM
4668 case 0:
4669 return "";
4670
f5842774 4671 case GRP_COMDAT:
220453ec 4672 return "COMDAT ";
f5842774
L
4673
4674 default:
220453ec 4675 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
4676 break;
4677 }
4678 return buff;
4679}
4680
4681static int
2cf0635d 4682process_section_groups (FILE * file)
f5842774 4683{
2cf0635d 4684 Elf_Internal_Shdr * section;
f5842774 4685 unsigned int i;
2cf0635d
NC
4686 struct group * group;
4687 Elf_Internal_Shdr * symtab_sec;
4688 Elf_Internal_Shdr * strtab_sec;
4689 Elf_Internal_Sym * symtab;
4690 char * strtab;
c256ffe7 4691 size_t strtab_size;
d1f5c6e3
L
4692
4693 /* Don't process section groups unless needed. */
4694 if (!do_unwind && !do_section_groups)
4695 return 1;
f5842774
L
4696
4697 if (elf_header.e_shnum == 0)
4698 {
4699 if (do_section_groups)
d1f5c6e3 4700 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
4701
4702 return 1;
4703 }
4704
4705 if (section_headers == NULL)
4706 {
4707 error (_("Section headers are not available!\n"));
4708 abort ();
4709 }
4710
3f5e193b
NC
4711 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
4712 sizeof (struct group *));
e4b17d5c
L
4713
4714 if (section_headers_groups == NULL)
4715 {
4716 error (_("Out of memory\n"));
4717 return 0;
4718 }
4719
f5842774 4720 /* Scan the sections for the group section. */
d1f5c6e3 4721 group_count = 0;
f5842774
L
4722 for (i = 0, section = section_headers;
4723 i < elf_header.e_shnum;
4724 i++, section++)
e4b17d5c
L
4725 if (section->sh_type == SHT_GROUP)
4726 group_count++;
4727
d1f5c6e3
L
4728 if (group_count == 0)
4729 {
4730 if (do_section_groups)
4731 printf (_("\nThere are no section groups in this file.\n"));
4732
4733 return 1;
4734 }
4735
3f5e193b 4736 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
4737
4738 if (section_groups == NULL)
4739 {
4740 error (_("Out of memory\n"));
4741 return 0;
4742 }
4743
d1f5c6e3
L
4744 symtab_sec = NULL;
4745 strtab_sec = NULL;
4746 symtab = NULL;
4747 strtab = NULL;
c256ffe7 4748 strtab_size = 0;
e4b17d5c
L
4749 for (i = 0, section = section_headers, group = section_groups;
4750 i < elf_header.e_shnum;
4751 i++, section++)
f5842774
L
4752 {
4753 if (section->sh_type == SHT_GROUP)
4754 {
2cf0635d
NC
4755 char * name = SECTION_NAME (section);
4756 char * group_name;
4757 unsigned char * start;
4758 unsigned char * indices;
f5842774 4759 unsigned int entry, j, size;
2cf0635d
NC
4760 Elf_Internal_Shdr * sec;
4761 Elf_Internal_Sym * sym;
f5842774
L
4762
4763 /* Get the symbol table. */
4fbb74a6
AM
4764 if (section->sh_link >= elf_header.e_shnum
4765 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 4766 != SHT_SYMTAB))
f5842774
L
4767 {
4768 error (_("Bad sh_link in group section `%s'\n"), name);
4769 continue;
4770 }
d1f5c6e3
L
4771
4772 if (symtab_sec != sec)
4773 {
4774 symtab_sec = sec;
4775 if (symtab)
4776 free (symtab);
4777 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4778 }
f5842774
L
4779
4780 sym = symtab + section->sh_info;
4781
4782 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4783 {
4fbb74a6
AM
4784 if (sym->st_shndx == 0
4785 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
4786 {
4787 error (_("Bad sh_info in group section `%s'\n"), name);
4788 continue;
4789 }
ba2685cc 4790
4fbb74a6 4791 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
4792 strtab_sec = NULL;
4793 if (strtab)
4794 free (strtab);
f5842774 4795 strtab = NULL;
c256ffe7 4796 strtab_size = 0;
f5842774
L
4797 }
4798 else
4799 {
4800 /* Get the string table. */
4fbb74a6 4801 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
4802 {
4803 strtab_sec = NULL;
4804 if (strtab)
4805 free (strtab);
4806 strtab = NULL;
4807 strtab_size = 0;
4808 }
4809 else if (strtab_sec
4fbb74a6 4810 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
4811 {
4812 strtab_sec = sec;
4813 if (strtab)
4814 free (strtab);
3f5e193b
NC
4815 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
4816 1, strtab_sec->sh_size,
4817 _("string table"));
c256ffe7 4818 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 4819 }
c256ffe7
JJ
4820 group_name = sym->st_name < strtab_size
4821 ? strtab + sym->st_name : "<corrupt>";
f5842774
L
4822 }
4823
3f5e193b
NC
4824 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
4825 1, section->sh_size,
4826 _("section data"));
f5842774
L
4827
4828 indices = start;
4829 size = (section->sh_size / section->sh_entsize) - 1;
4830 entry = byte_get (indices, 4);
4831 indices += 4;
e4b17d5c
L
4832
4833 if (do_section_groups)
4834 {
220453ec 4835 printf ("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n",
391cb864 4836 get_group_flags (entry), i, name, group_name, size);
ba2685cc 4837
e4b17d5c
L
4838 printf (_(" [Index] Name\n"));
4839 }
4840
4841 group->group_index = i;
4842
f5842774
L
4843 for (j = 0; j < size; j++)
4844 {
2cf0635d 4845 struct group_list * g;
e4b17d5c 4846
f5842774
L
4847 entry = byte_get (indices, 4);
4848 indices += 4;
4849
4fbb74a6 4850 if (entry >= elf_header.e_shnum)
391cb864
L
4851 {
4852 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
4853 entry, i, elf_header.e_shnum - 1);
4854 continue;
4855 }
391cb864 4856
4fbb74a6 4857 if (section_headers_groups [entry] != NULL)
e4b17d5c 4858 {
d1f5c6e3
L
4859 if (entry)
4860 {
391cb864
L
4861 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
4862 entry, i,
4fbb74a6 4863 section_headers_groups [entry]->group_index);
d1f5c6e3
L
4864 continue;
4865 }
4866 else
4867 {
4868 /* Intel C/C++ compiler may put section 0 in a
4869 section group. We just warn it the first time
4870 and ignore it afterwards. */
4871 static int warned = 0;
4872 if (!warned)
4873 {
4874 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 4875 section_headers_groups [entry]->group_index);
d1f5c6e3
L
4876 warned++;
4877 }
4878 }
e4b17d5c
L
4879 }
4880
4fbb74a6 4881 section_headers_groups [entry] = group;
e4b17d5c
L
4882
4883 if (do_section_groups)
4884 {
4fbb74a6 4885 sec = section_headers + entry;
c256ffe7 4886 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
4887 }
4888
3f5e193b 4889 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
4890 g->section_index = entry;
4891 g->next = group->root;
4892 group->root = g;
f5842774
L
4893 }
4894
f5842774
L
4895 if (start)
4896 free (start);
e4b17d5c
L
4897
4898 group++;
f5842774
L
4899 }
4900 }
4901
d1f5c6e3
L
4902 if (symtab)
4903 free (symtab);
4904 if (strtab)
4905 free (strtab);
f5842774
L
4906 return 1;
4907}
4908
85b1c36d 4909static struct
566b0d53 4910{
2cf0635d 4911 const char * name;
566b0d53
L
4912 int reloc;
4913 int size;
4914 int rela;
4915} dynamic_relocations [] =
4916{
4917 { "REL", DT_REL, DT_RELSZ, FALSE },
4918 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4919 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4920};
4921
252b5132 4922/* Process the reloc section. */
18bd398b 4923
252b5132 4924static int
2cf0635d 4925process_relocs (FILE * file)
252b5132 4926{
b34976b6
AM
4927 unsigned long rel_size;
4928 unsigned long rel_offset;
252b5132
RH
4929
4930
4931 if (!do_reloc)
4932 return 1;
4933
4934 if (do_using_dynamic)
4935 {
566b0d53 4936 int is_rela;
2cf0635d 4937 const char * name;
566b0d53
L
4938 int has_dynamic_reloc;
4939 unsigned int i;
0de14b54 4940
566b0d53 4941 has_dynamic_reloc = 0;
252b5132 4942
566b0d53 4943 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4944 {
566b0d53
L
4945 is_rela = dynamic_relocations [i].rela;
4946 name = dynamic_relocations [i].name;
4947 rel_size = dynamic_info [dynamic_relocations [i].size];
4948 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4949
566b0d53
L
4950 has_dynamic_reloc |= rel_size;
4951
4952 if (is_rela == UNKNOWN)
aa903cfb 4953 {
566b0d53
L
4954 if (dynamic_relocations [i].reloc == DT_JMPREL)
4955 switch (dynamic_info[DT_PLTREL])
4956 {
4957 case DT_REL:
4958 is_rela = FALSE;
4959 break;
4960 case DT_RELA:
4961 is_rela = TRUE;
4962 break;
4963 }
aa903cfb 4964 }
252b5132 4965
566b0d53
L
4966 if (rel_size)
4967 {
4968 printf
4969 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4970 name, rel_offset, rel_size);
252b5132 4971
d93f0186
NC
4972 dump_relocations (file,
4973 offset_from_vma (file, rel_offset, rel_size),
4974 rel_size,
566b0d53 4975 dynamic_symbols, num_dynamic_syms,
d79b3d50 4976 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 4977 }
252b5132 4978 }
566b0d53
L
4979
4980 if (! has_dynamic_reloc)
252b5132
RH
4981 printf (_("\nThere are no dynamic relocations in this file.\n"));
4982 }
4983 else
4984 {
2cf0635d 4985 Elf_Internal_Shdr * section;
b34976b6
AM
4986 unsigned long i;
4987 int found = 0;
252b5132
RH
4988
4989 for (i = 0, section = section_headers;
4990 i < elf_header.e_shnum;
b34976b6 4991 i++, section++)
252b5132
RH
4992 {
4993 if ( section->sh_type != SHT_RELA
4994 && section->sh_type != SHT_REL)
4995 continue;
4996
4997 rel_offset = section->sh_offset;
4998 rel_size = section->sh_size;
4999
5000 if (rel_size)
5001 {
2cf0635d 5002 Elf_Internal_Shdr * strsec;
b34976b6 5003 int is_rela;
103f02d3 5004
252b5132
RH
5005 printf (_("\nRelocation section "));
5006
5007 if (string_table == NULL)
19936277 5008 printf ("%d", section->sh_name);
252b5132 5009 else
3a1a2036 5010 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
5011
5012 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5013 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5014
d79b3d50
NC
5015 is_rela = section->sh_type == SHT_RELA;
5016
4fbb74a6
AM
5017 if (section->sh_link != 0
5018 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5019 {
2cf0635d
NC
5020 Elf_Internal_Shdr * symsec;
5021 Elf_Internal_Sym * symtab;
d79b3d50 5022 unsigned long nsyms;
c256ffe7 5023 unsigned long strtablen = 0;
2cf0635d 5024 char * strtab = NULL;
57346661 5025
4fbb74a6 5026 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5027 if (symsec->sh_type != SHT_SYMTAB
5028 && symsec->sh_type != SHT_DYNSYM)
5029 continue;
5030
af3fc3bc 5031 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 5032 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 5033
af3fc3bc
AM
5034 if (symtab == NULL)
5035 continue;
252b5132 5036
4fbb74a6
AM
5037 if (symsec->sh_link != 0
5038 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5039 {
4fbb74a6 5040 strsec = section_headers + symsec->sh_link;
103f02d3 5041
3f5e193b
NC
5042 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5043 1, strsec->sh_size,
5044 _("string table"));
c256ffe7
JJ
5045 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5046 }
252b5132 5047
d79b3d50
NC
5048 dump_relocations (file, rel_offset, rel_size,
5049 symtab, nsyms, strtab, strtablen, is_rela);
5050 if (strtab)
5051 free (strtab);
5052 free (symtab);
5053 }
5054 else
5055 dump_relocations (file, rel_offset, rel_size,
5056 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5057
5058 found = 1;
5059 }
5060 }
5061
5062 if (! found)
5063 printf (_("\nThere are no relocations in this file.\n"));
5064 }
5065
5066 return 1;
5067}
5068
57346661
AM
5069/* Process the unwind section. */
5070
4d6ed7c8
NC
5071#include "unwind-ia64.h"
5072
5073/* An absolute address consists of a section and an offset. If the
5074 section is NULL, the offset itself is the address, otherwise, the
5075 address equals to LOAD_ADDRESS(section) + offset. */
5076
5077struct absaddr
5078 {
5079 unsigned short section;
5080 bfd_vma offset;
5081 };
5082
1949de15
L
5083#define ABSADDR(a) \
5084 ((a).section \
5085 ? section_headers [(a).section].sh_addr + (a).offset \
5086 : (a).offset)
5087
3f5e193b
NC
5088struct ia64_unw_table_entry
5089 {
5090 struct absaddr start;
5091 struct absaddr end;
5092 struct absaddr info;
5093 };
5094
57346661 5095struct ia64_unw_aux_info
4d6ed7c8 5096 {
3f5e193b
NC
5097
5098 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5099 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5100 unsigned char * info; /* Unwind info. */
b34976b6
AM
5101 unsigned long info_size; /* Size of unwind info. */
5102 bfd_vma info_addr; /* starting address of unwind info. */
5103 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5104 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5105 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5106 char * strtab; /* The string table. */
b34976b6 5107 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5108 };
5109
4d6ed7c8 5110static void
2cf0635d 5111find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5112 unsigned long nsyms,
2cf0635d 5113 const char * strtab,
57346661 5114 unsigned long strtab_size,
d3ba0551 5115 struct absaddr addr,
2cf0635d
NC
5116 const char ** symname,
5117 bfd_vma * offset)
4d6ed7c8 5118{
d3ba0551 5119 bfd_vma dist = 0x100000;
2cf0635d
NC
5120 Elf_Internal_Sym * sym;
5121 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5122 unsigned long i;
5123
0b6ae522
DJ
5124 REMOVE_ARCH_BITS (addr.offset);
5125
57346661 5126 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5127 {
0b6ae522
DJ
5128 bfd_vma value = sym->st_value;
5129
5130 REMOVE_ARCH_BITS (value);
5131
4d6ed7c8
NC
5132 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5133 && sym->st_name != 0
5134 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5135 && addr.offset >= value
5136 && addr.offset - value < dist)
4d6ed7c8
NC
5137 {
5138 best = sym;
0b6ae522 5139 dist = addr.offset - value;
4d6ed7c8
NC
5140 if (!dist)
5141 break;
5142 }
5143 }
5144 if (best)
5145 {
57346661
AM
5146 *symname = (best->st_name >= strtab_size
5147 ? "<corrupt>" : strtab + best->st_name);
4d6ed7c8
NC
5148 *offset = dist;
5149 return;
5150 }
5151 *symname = NULL;
5152 *offset = addr.offset;
5153}
5154
5155static void
2cf0635d 5156dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5157{
2cf0635d 5158 struct ia64_unw_table_entry * tp;
4d6ed7c8 5159 int in_body;
7036c0e1 5160
4d6ed7c8
NC
5161 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5162 {
5163 bfd_vma stamp;
5164 bfd_vma offset;
2cf0635d
NC
5165 const unsigned char * dp;
5166 const unsigned char * head;
5167 const char * procname;
4d6ed7c8 5168
57346661
AM
5169 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5170 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5171
5172 fputs ("\n<", stdout);
5173
5174 if (procname)
5175 {
5176 fputs (procname, stdout);
5177
5178 if (offset)
5179 printf ("+%lx", (unsigned long) offset);
5180 }
5181
5182 fputs (">: [", stdout);
5183 print_vma (tp->start.offset, PREFIX_HEX);
5184 fputc ('-', stdout);
5185 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5186 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5187 (unsigned long) (tp->info.offset - aux->seg_base));
5188
1949de15 5189 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5190 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5191
86f55779 5192 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5193 (unsigned) UNW_VER (stamp),
5194 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5195 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5196 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5197 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5198
5199 if (UNW_VER (stamp) != 1)
5200 {
5201 printf ("\tUnknown version.\n");
5202 continue;
5203 }
5204
5205 in_body = 0;
89fac5e3 5206 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5207 dp = unw_decode (dp, in_body, & in_body);
5208 }
5209}
5210
5211static int
2cf0635d
NC
5212slurp_ia64_unwind_table (FILE * file,
5213 struct ia64_unw_aux_info * aux,
5214 Elf_Internal_Shdr * sec)
4d6ed7c8 5215{
89fac5e3 5216 unsigned long size, nrelas, i;
2cf0635d
NC
5217 Elf_Internal_Phdr * seg;
5218 struct ia64_unw_table_entry * tep;
5219 Elf_Internal_Shdr * relsec;
5220 Elf_Internal_Rela * rela;
5221 Elf_Internal_Rela * rp;
5222 unsigned char * table;
5223 unsigned char * tp;
5224 Elf_Internal_Sym * sym;
5225 const char * relname;
4d6ed7c8 5226
4d6ed7c8
NC
5227 /* First, find the starting address of the segment that includes
5228 this section: */
5229
5230 if (elf_header.e_phnum)
5231 {
d93f0186 5232 if (! get_program_headers (file))
4d6ed7c8 5233 return 0;
4d6ed7c8 5234
d93f0186
NC
5235 for (seg = program_headers;
5236 seg < program_headers + elf_header.e_phnum;
5237 ++seg)
4d6ed7c8
NC
5238 {
5239 if (seg->p_type != PT_LOAD)
5240 continue;
5241
5242 if (sec->sh_addr >= seg->p_vaddr
5243 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5244 {
5245 aux->seg_base = seg->p_vaddr;
5246 break;
5247 }
5248 }
4d6ed7c8
NC
5249 }
5250
5251 /* Second, build the unwind table from the contents of the unwind section: */
5252 size = sec->sh_size;
3f5e193b
NC
5253 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5254 _("unwind table"));
a6e9f9df
AM
5255 if (!table)
5256 return 0;
4d6ed7c8 5257
3f5e193b
NC
5258 aux->table = (struct ia64_unw_table_entry *)
5259 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5260 tep = aux->table;
c6a0c689 5261 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5262 {
5263 tep->start.section = SHN_UNDEF;
5264 tep->end.section = SHN_UNDEF;
5265 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5266 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5267 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5268 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5269 tep->start.offset += aux->seg_base;
5270 tep->end.offset += aux->seg_base;
5271 tep->info.offset += aux->seg_base;
5272 }
5273 free (table);
5274
41e92641 5275 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5276 for (relsec = section_headers;
5277 relsec < section_headers + elf_header.e_shnum;
5278 ++relsec)
5279 {
5280 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5281 || relsec->sh_info >= elf_header.e_shnum
5282 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5283 continue;
5284
5285 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5286 & rela, & nrelas))
5287 return 0;
5288
5289 for (rp = rela; rp < rela + nrelas; ++rp)
5290 {
aca88567
NC
5291 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5292 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5293
0112cd26 5294 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5295 {
e5fb9629 5296 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5297 continue;
5298 }
5299
89fac5e3 5300 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5301
89fac5e3 5302 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5303 {
5304 case 0:
5305 aux->table[i].start.section = sym->st_shndx;
1ffa9a18 5306 aux->table[i].start.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5307 break;
5308 case 1:
5309 aux->table[i].end.section = sym->st_shndx;
1ffa9a18 5310 aux->table[i].end.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5311 break;
5312 case 2:
5313 aux->table[i].info.section = sym->st_shndx;
1ffa9a18 5314 aux->table[i].info.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5315 break;
5316 default:
5317 break;
5318 }
5319 }
5320
5321 free (rela);
5322 }
5323
89fac5e3 5324 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5325 return 1;
5326}
5327
5328static int
2cf0635d 5329ia64_process_unwind (FILE * file)
4d6ed7c8 5330{
2cf0635d
NC
5331 Elf_Internal_Shdr * sec;
5332 Elf_Internal_Shdr * unwsec = NULL;
5333 Elf_Internal_Shdr * strsec;
89fac5e3 5334 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5335 struct ia64_unw_aux_info aux;
f1467e33 5336
4d6ed7c8
NC
5337 memset (& aux, 0, sizeof (aux));
5338
4d6ed7c8
NC
5339 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5340 {
c256ffe7 5341 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5342 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5343 {
5344 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5345 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5346
4fbb74a6 5347 strsec = section_headers + sec->sh_link;
3f5e193b
NC
5348 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5349 1, strsec->sh_size,
5350 _("string table"));
c256ffe7 5351 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5352 }
5353 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5354 unwcount++;
5355 }
5356
5357 if (!unwcount)
5358 printf (_("\nThere are no unwind sections in this file.\n"));
5359
5360 while (unwcount-- > 0)
5361 {
2cf0635d 5362 char * suffix;
579f31ac
JJ
5363 size_t len, len2;
5364
5365 for (i = unwstart, sec = section_headers + unwstart;
5366 i < elf_header.e_shnum; ++i, ++sec)
5367 if (sec->sh_type == SHT_IA_64_UNWIND)
5368 {
5369 unwsec = sec;
5370 break;
5371 }
5372
5373 unwstart = i + 1;
5374 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5375
e4b17d5c
L
5376 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5377 {
5378 /* We need to find which section group it is in. */
2cf0635d 5379 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5380
5381 for (; g != NULL; g = g->next)
5382 {
4fbb74a6 5383 sec = section_headers + g->section_index;
18bd398b
NC
5384
5385 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5386 break;
e4b17d5c
L
5387 }
5388
5389 if (g == NULL)
5390 i = elf_header.e_shnum;
5391 }
18bd398b 5392 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5393 {
18bd398b 5394 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5395 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5396 suffix = SECTION_NAME (unwsec) + len;
5397 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5398 ++i, ++sec)
18bd398b
NC
5399 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5400 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5401 break;
5402 }
5403 else
5404 {
5405 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5406 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5407 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5408 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5409 suffix = "";
18bd398b 5410 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5411 suffix = SECTION_NAME (unwsec) + len;
5412 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5413 ++i, ++sec)
18bd398b
NC
5414 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5415 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5416 break;
5417 }
5418
5419 if (i == elf_header.e_shnum)
5420 {
5421 printf (_("\nCould not find unwind info section for "));
5422
5423 if (string_table == NULL)
5424 printf ("%d", unwsec->sh_name);
5425 else
3a1a2036 5426 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5427 }
5428 else
4d6ed7c8
NC
5429 {
5430 aux.info_size = sec->sh_size;
5431 aux.info_addr = sec->sh_addr;
3f5e193b
NC
5432 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
5433 aux.info_size,
5434 _("unwind info"));
4d6ed7c8 5435
579f31ac 5436 printf (_("\nUnwind section "));
4d6ed7c8 5437
579f31ac
JJ
5438 if (string_table == NULL)
5439 printf ("%d", unwsec->sh_name);
5440 else
3a1a2036 5441 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5442
579f31ac 5443 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5444 (unsigned long) unwsec->sh_offset,
89fac5e3 5445 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5446
579f31ac 5447 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5448
579f31ac
JJ
5449 if (aux.table_len > 0)
5450 dump_ia64_unwind (& aux);
5451
5452 if (aux.table)
5453 free ((char *) aux.table);
5454 if (aux.info)
5455 free ((char *) aux.info);
5456 aux.table = NULL;
5457 aux.info = NULL;
5458 }
4d6ed7c8 5459 }
4d6ed7c8 5460
4d6ed7c8
NC
5461 if (aux.symtab)
5462 free (aux.symtab);
5463 if (aux.strtab)
5464 free ((char *) aux.strtab);
5465
5466 return 1;
5467}
5468
3f5e193b
NC
5469struct hppa_unw_table_entry
5470 {
5471 struct absaddr start;
5472 struct absaddr end;
5473 unsigned int Cannot_unwind:1; /* 0 */
5474 unsigned int Millicode:1; /* 1 */
5475 unsigned int Millicode_save_sr0:1; /* 2 */
5476 unsigned int Region_description:2; /* 3..4 */
5477 unsigned int reserved1:1; /* 5 */
5478 unsigned int Entry_SR:1; /* 6 */
5479 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5480 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5481 unsigned int Args_stored:1; /* 16 */
5482 unsigned int Variable_Frame:1; /* 17 */
5483 unsigned int Separate_Package_Body:1; /* 18 */
5484 unsigned int Frame_Extension_Millicode:1; /* 19 */
5485 unsigned int Stack_Overflow_Check:1; /* 20 */
5486 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5487 unsigned int Ada_Region:1; /* 22 */
5488 unsigned int cxx_info:1; /* 23 */
5489 unsigned int cxx_try_catch:1; /* 24 */
5490 unsigned int sched_entry_seq:1; /* 25 */
5491 unsigned int reserved2:1; /* 26 */
5492 unsigned int Save_SP:1; /* 27 */
5493 unsigned int Save_RP:1; /* 28 */
5494 unsigned int Save_MRP_in_frame:1; /* 29 */
5495 unsigned int extn_ptr_defined:1; /* 30 */
5496 unsigned int Cleanup_defined:1; /* 31 */
5497
5498 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5499 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5500 unsigned int Large_frame:1; /* 2 */
5501 unsigned int Pseudo_SP_Set:1; /* 3 */
5502 unsigned int reserved4:1; /* 4 */
5503 unsigned int Total_frame_size:27; /* 5..31 */
5504 };
5505
57346661
AM
5506struct hppa_unw_aux_info
5507 {
3f5e193b 5508 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
5509 unsigned long table_len; /* Length of unwind table. */
5510 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5511 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5512 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5513 char * strtab; /* The string table. */
57346661
AM
5514 unsigned long strtab_size; /* Size of string table. */
5515 };
5516
5517static void
2cf0635d 5518dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5519{
2cf0635d 5520 struct hppa_unw_table_entry * tp;
57346661 5521
57346661
AM
5522 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5523 {
5524 bfd_vma offset;
2cf0635d 5525 const char * procname;
57346661
AM
5526
5527 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5528 aux->strtab_size, tp->start, &procname,
5529 &offset);
5530
5531 fputs ("\n<", stdout);
5532
5533 if (procname)
5534 {
5535 fputs (procname, stdout);
5536
5537 if (offset)
5538 printf ("+%lx", (unsigned long) offset);
5539 }
5540
5541 fputs (">: [", stdout);
5542 print_vma (tp->start.offset, PREFIX_HEX);
5543 fputc ('-', stdout);
5544 print_vma (tp->end.offset, PREFIX_HEX);
5545 printf ("]\n\t");
5546
18bd398b
NC
5547#define PF(_m) if (tp->_m) printf (#_m " ");
5548#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5549 PF(Cannot_unwind);
5550 PF(Millicode);
5551 PF(Millicode_save_sr0);
18bd398b 5552 /* PV(Region_description); */
57346661
AM
5553 PF(Entry_SR);
5554 PV(Entry_FR);
5555 PV(Entry_GR);
5556 PF(Args_stored);
5557 PF(Variable_Frame);
5558 PF(Separate_Package_Body);
5559 PF(Frame_Extension_Millicode);
5560 PF(Stack_Overflow_Check);
5561 PF(Two_Instruction_SP_Increment);
5562 PF(Ada_Region);
5563 PF(cxx_info);
5564 PF(cxx_try_catch);
5565 PF(sched_entry_seq);
5566 PF(Save_SP);
5567 PF(Save_RP);
5568 PF(Save_MRP_in_frame);
5569 PF(extn_ptr_defined);
5570 PF(Cleanup_defined);
5571 PF(MPE_XL_interrupt_marker);
5572 PF(HP_UX_interrupt_marker);
5573 PF(Large_frame);
5574 PF(Pseudo_SP_Set);
5575 PV(Total_frame_size);
5576#undef PF
5577#undef PV
5578 }
5579
18bd398b 5580 printf ("\n");
57346661
AM
5581}
5582
5583static int
2cf0635d
NC
5584slurp_hppa_unwind_table (FILE * file,
5585 struct hppa_unw_aux_info * aux,
5586 Elf_Internal_Shdr * sec)
57346661 5587{
1c0751b2 5588 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
5589 Elf_Internal_Phdr * seg;
5590 struct hppa_unw_table_entry * tep;
5591 Elf_Internal_Shdr * relsec;
5592 Elf_Internal_Rela * rela;
5593 Elf_Internal_Rela * rp;
5594 unsigned char * table;
5595 unsigned char * tp;
5596 Elf_Internal_Sym * sym;
5597 const char * relname;
57346661 5598
57346661
AM
5599 /* First, find the starting address of the segment that includes
5600 this section. */
5601
5602 if (elf_header.e_phnum)
5603 {
5604 if (! get_program_headers (file))
5605 return 0;
5606
5607 for (seg = program_headers;
5608 seg < program_headers + elf_header.e_phnum;
5609 ++seg)
5610 {
5611 if (seg->p_type != PT_LOAD)
5612 continue;
5613
5614 if (sec->sh_addr >= seg->p_vaddr
5615 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5616 {
5617 aux->seg_base = seg->p_vaddr;
5618 break;
5619 }
5620 }
5621 }
5622
5623 /* Second, build the unwind table from the contents of the unwind
5624 section. */
5625 size = sec->sh_size;
3f5e193b
NC
5626 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5627 _("unwind table"));
57346661
AM
5628 if (!table)
5629 return 0;
5630
1c0751b2
DA
5631 unw_ent_size = 16;
5632 nentries = size / unw_ent_size;
5633 size = unw_ent_size * nentries;
57346661 5634
3f5e193b
NC
5635 tep = aux->table = (struct hppa_unw_table_entry *)
5636 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 5637
1c0751b2 5638 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
5639 {
5640 unsigned int tmp1, tmp2;
5641
5642 tep->start.section = SHN_UNDEF;
5643 tep->end.section = SHN_UNDEF;
5644
1c0751b2
DA
5645 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
5646 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
5647 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
5648 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
5649
5650 tep->start.offset += aux->seg_base;
5651 tep->end.offset += aux->seg_base;
57346661
AM
5652
5653 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
5654 tep->Millicode = (tmp1 >> 30) & 0x1;
5655 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
5656 tep->Region_description = (tmp1 >> 27) & 0x3;
5657 tep->reserved1 = (tmp1 >> 26) & 0x1;
5658 tep->Entry_SR = (tmp1 >> 25) & 0x1;
5659 tep->Entry_FR = (tmp1 >> 21) & 0xf;
5660 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
5661 tep->Args_stored = (tmp1 >> 15) & 0x1;
5662 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
5663 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
5664 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
5665 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
5666 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
5667 tep->Ada_Region = (tmp1 >> 9) & 0x1;
5668 tep->cxx_info = (tmp1 >> 8) & 0x1;
5669 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
5670 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
5671 tep->reserved2 = (tmp1 >> 5) & 0x1;
5672 tep->Save_SP = (tmp1 >> 4) & 0x1;
5673 tep->Save_RP = (tmp1 >> 3) & 0x1;
5674 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
5675 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
5676 tep->Cleanup_defined = tmp1 & 0x1;
5677
5678 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
5679 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
5680 tep->Large_frame = (tmp2 >> 29) & 0x1;
5681 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
5682 tep->reserved4 = (tmp2 >> 27) & 0x1;
5683 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
5684 }
5685 free (table);
5686
5687 /* Third, apply any relocations to the unwind table. */
57346661
AM
5688 for (relsec = section_headers;
5689 relsec < section_headers + elf_header.e_shnum;
5690 ++relsec)
5691 {
5692 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5693 || relsec->sh_info >= elf_header.e_shnum
5694 || section_headers + relsec->sh_info != sec)
57346661
AM
5695 continue;
5696
5697 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5698 & rela, & nrelas))
5699 return 0;
5700
5701 for (rp = rela; rp < rela + nrelas; ++rp)
5702 {
aca88567
NC
5703 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
5704 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
5705
5706 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 5707 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
5708 {
5709 warn (_("Skipping unexpected relocation type %s\n"), relname);
5710 continue;
5711 }
5712
5713 i = rp->r_offset / unw_ent_size;
5714
89fac5e3 5715 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
5716 {
5717 case 0:
5718 aux->table[i].start.section = sym->st_shndx;
1e456d54 5719 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
5720 break;
5721 case 1:
5722 aux->table[i].end.section = sym->st_shndx;
1e456d54 5723 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
5724 break;
5725 default:
5726 break;
5727 }
5728 }
5729
5730 free (rela);
5731 }
5732
1c0751b2 5733 aux->table_len = nentries;
57346661
AM
5734
5735 return 1;
5736}
5737
5738static int
2cf0635d 5739hppa_process_unwind (FILE * file)
57346661 5740{
57346661 5741 struct hppa_unw_aux_info aux;
2cf0635d
NC
5742 Elf_Internal_Shdr * unwsec = NULL;
5743 Elf_Internal_Shdr * strsec;
5744 Elf_Internal_Shdr * sec;
18bd398b 5745 unsigned long i;
57346661
AM
5746
5747 memset (& aux, 0, sizeof (aux));
5748
c256ffe7
JJ
5749 if (string_table == NULL)
5750 return 1;
57346661
AM
5751
5752 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5753 {
c256ffe7 5754 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5755 && sec->sh_link < elf_header.e_shnum)
57346661
AM
5756 {
5757 aux.nsyms = sec->sh_size / sec->sh_entsize;
5758 aux.symtab = GET_ELF_SYMBOLS (file, sec);
5759
4fbb74a6 5760 strsec = section_headers + sec->sh_link;
3f5e193b
NC
5761 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5762 1, strsec->sh_size,
5763 _("string table"));
c256ffe7 5764 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 5765 }
18bd398b 5766 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
5767 unwsec = sec;
5768 }
5769
5770 if (!unwsec)
5771 printf (_("\nThere are no unwind sections in this file.\n"));
5772
5773 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5774 {
18bd398b 5775 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 5776 {
57346661
AM
5777 printf (_("\nUnwind section "));
5778 printf (_("'%s'"), SECTION_NAME (sec));
5779
5780 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5781 (unsigned long) sec->sh_offset,
89fac5e3 5782 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
5783
5784 slurp_hppa_unwind_table (file, &aux, sec);
5785 if (aux.table_len > 0)
5786 dump_hppa_unwind (&aux);
5787
5788 if (aux.table)
5789 free ((char *) aux.table);
5790 aux.table = NULL;
5791 }
5792 }
5793
5794 if (aux.symtab)
5795 free (aux.symtab);
5796 if (aux.strtab)
5797 free ((char *) aux.strtab);
5798
5799 return 1;
5800}
5801
0b6ae522
DJ
5802struct arm_section
5803{
5804 unsigned char *data;
5805
5806 Elf_Internal_Shdr *sec;
5807 Elf_Internal_Rela *rela;
5808 unsigned long nrelas;
5809 unsigned int rel_type;
5810
5811 Elf_Internal_Rela *next_rela;
5812};
5813
5814struct arm_unw_aux_info
5815{
5816 FILE *file;
5817
5818 Elf_Internal_Sym *symtab; /* The symbol table. */
5819 unsigned long nsyms; /* Number of symbols. */
5820 char *strtab; /* The string table. */
5821 unsigned long strtab_size; /* Size of string table. */
5822};
5823
5824static const char *
5825arm_print_vma_and_name (struct arm_unw_aux_info *aux,
5826 bfd_vma fn, struct absaddr addr)
5827{
5828 const char *procname;
5829 bfd_vma sym_offset;
5830
5831 if (addr.section == SHN_UNDEF)
5832 addr.offset = fn;
5833
5834 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5835 aux->strtab_size, addr, &procname,
5836 &sym_offset);
5837
5838 print_vma (fn, PREFIX_HEX);
5839
5840 if (procname)
5841 {
5842 fputs (" <", stdout);
5843 fputs (procname, stdout);
5844
5845 if (sym_offset)
5846 printf ("+0x%lx", (unsigned long) sym_offset);
5847 fputc ('>', stdout);
5848 }
5849
5850 return procname;
5851}
5852
5853static void
5854arm_free_section (struct arm_section *arm_sec)
5855{
5856 if (arm_sec->data != NULL)
5857 free (arm_sec->data);
5858
5859 if (arm_sec->rela != NULL)
5860 free (arm_sec->rela);
5861}
5862
5863static int
5864arm_section_get_word (struct arm_unw_aux_info *aux,
5865 struct arm_section *arm_sec,
5866 Elf_Internal_Shdr *sec, bfd_vma word_offset,
5867 unsigned int *wordp, struct absaddr *addr)
5868{
5869 Elf_Internal_Rela *rp;
5870 Elf_Internal_Sym *sym;
5871 const char * relname;
5872 unsigned int word;
5873 bfd_boolean wrapped;
5874
5875 addr->section = SHN_UNDEF;
5876 addr->offset = 0;
5877
5878 if (sec != arm_sec->sec)
5879 {
5880 Elf_Internal_Shdr *relsec;
5881
5882 arm_free_section (arm_sec);
5883
5884 arm_sec->sec = sec;
5885 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
5886 sec->sh_size, _("unwind data"));
5887
5888 arm_sec->rela = NULL;
5889 arm_sec->nrelas = 0;
5890
5891 for (relsec = section_headers;
5892 relsec < section_headers + elf_header.e_shnum;
5893 ++relsec)
5894 {
5895 if (relsec->sh_info >= elf_header.e_shnum
5896 || section_headers + relsec->sh_info != sec)
5897 continue;
5898
5899 if (relsec->sh_type == SHT_REL)
5900 {
5901 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
5902 relsec->sh_size,
5903 & arm_sec->rela, & arm_sec->nrelas))
5904 return 0;
5905 break;
5906 }
5907 else if (relsec->sh_type == SHT_RELA)
5908 {
5909 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
5910 relsec->sh_size,
5911 & arm_sec->rela, & arm_sec->nrelas))
5912 return 0;
5913 break;
5914 }
5915 }
5916
5917 arm_sec->next_rela = arm_sec->rela;
5918 }
5919
5920 if (arm_sec->data == NULL)
5921 return 0;
5922
5923 word = byte_get (arm_sec->data + word_offset, 4);
5924
5925 wrapped = FALSE;
5926 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
5927 {
5928 bfd_vma prelval, offset;
5929
5930 if (rp->r_offset > word_offset && !wrapped)
5931 {
5932 rp = arm_sec->rela;
5933 wrapped = TRUE;
5934 }
5935 if (rp->r_offset > word_offset)
5936 break;
5937
5938 if (rp->r_offset & 3)
5939 {
5940 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
5941 (unsigned long) rp->r_offset);
5942 continue;
5943 }
5944
5945 if (rp->r_offset < word_offset)
5946 continue;
5947
5948 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
5949
5950 if (streq (relname, "R_ARM_NONE"))
5951 continue;
5952
5953 if (! streq (relname, "R_ARM_PREL31"))
5954 {
5955 warn (_("Skipping unexpected relocation type %s\n"), relname);
5956 continue;
5957 }
5958
5959 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
5960
5961 if (arm_sec->rel_type == SHT_REL)
5962 {
5963 offset = word & 0x7fffffff;
5964 if (offset & 0x40000000)
5965 offset |= ~ (bfd_vma) 0x7fffffff;
5966 }
5967 else
5968 offset = rp->r_addend;
5969
5970 offset += sym->st_value;
5971 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
5972
5973 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
5974 addr->section = sym->st_shndx;
5975 addr->offset = offset;
5976 break;
5977 }
5978
5979 *wordp = word;
5980 arm_sec->next_rela = rp;
5981
5982 return 1;
5983}
5984
5985static void
5986decode_arm_unwind (struct arm_unw_aux_info *aux,
5987 unsigned int word, unsigned int remaining,
5988 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
5989 struct arm_section *data_arm_sec)
5990{
5991 int per_index;
5992 unsigned int more_words;
5993 struct absaddr addr;
5994
5995#define ADVANCE \
5996 if (remaining == 0 && more_words) \
5997 { \
5998 data_offset += 4; \
5999 if (!arm_section_get_word (aux, data_arm_sec, data_sec, \
6000 data_offset, &word, &addr)) \
6001 return; \
6002 remaining = 4; \
6003 more_words--; \
6004 } \
6005
6006#define GET_OP(OP) \
6007 ADVANCE; \
6008 if (remaining) \
6009 { \
6010 remaining--; \
6011 (OP) = word >> 24; \
6012 word <<= 8; \
6013 } \
6014 else \
6015 { \
6016 printf ("[Truncated opcode]\n"); \
6017 return; \
6018 } \
6019 printf (_("0x%02x "), OP)
6020
6021 if (remaining == 0)
6022 {
6023 /* Fetch the first word. */
6024 if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
6025 &word, &addr))
6026 return;
6027 remaining = 4;
6028 }
6029
6030 if ((word & 0x80000000) == 0)
6031 {
6032 /* Expand prel31 for personality routine. */
6033 bfd_vma fn;
6034 const char *procname;
6035
6036 fn = word;
6037 if (fn & 0x40000000)
6038 fn |= ~ (bfd_vma) 0x7fffffff;
6039 fn = fn + data_sec->sh_addr + data_offset;
6040
6041 printf (_(" Personality routine: "));
6042 procname = arm_print_vma_and_name (aux, fn, addr);
6043 fputc ('\n', stdout);
6044
6045 /* The GCC personality routines use the standard compact
6046 encoding, starting with one byte giving the number of
6047 words. */
6048 if (procname != NULL
6049 && (const_strneq (procname, "__gcc_personality_v0")
6050 || const_strneq (procname, "__gxx_personality_v0")
6051 || const_strneq (procname, "__gcj_personality_v0")
6052 || const_strneq (procname, "__gnu_objc_personality_v0")))
6053 {
6054 remaining = 0;
6055 more_words = 1;
6056 ADVANCE;
6057 if (!remaining)
6058 {
6059 printf (_(" [Truncated data]\n"));
6060 return;
6061 }
6062 more_words = word >> 24;
6063 word <<= 8;
6064 remaining--;
6065 }
6066 else
6067 return;
6068 }
6069 else
6070 {
6071
6072 per_index = (word >> 24) & 0x7f;
6073 if (per_index != 0 && per_index != 1 && per_index != 2)
6074 {
6075 printf (_(" [reserved compact index %d]\n"), per_index);
6076 return;
6077 }
6078
6079 printf (_(" Compact model %d\n"), per_index);
6080 if (per_index == 0)
6081 {
6082 more_words = 0;
6083 word <<= 8;
6084 remaining--;
6085 }
6086 else
6087 {
6088 more_words = (word >> 16) & 0xff;
6089 word <<= 16;
6090 remaining -= 2;
6091 }
6092 }
6093
6094 /* Decode the unwinding instructions. */
6095 while (1)
6096 {
6097 unsigned int op, op2;
6098
6099 ADVANCE;
6100 if (remaining == 0)
6101 break;
6102 remaining--;
6103 op = word >> 24;
6104 word <<= 8;
6105
6106 printf (_(" 0x%02x "), op);
6107
6108 if ((op & 0xc0) == 0x00)
6109 {
6110 int offset = ((op & 0x3f) << 2) + 4;
6111 printf (_(" vsp = vsp + %d"), offset);
6112 }
6113 else if ((op & 0xc0) == 0x40)
6114 {
6115 int offset = ((op & 0x3f) << 2) + 4;
6116 printf (_(" vsp = vsp - %d"), offset);
6117 }
6118 else if ((op & 0xf0) == 0x80)
6119 {
6120 GET_OP (op2);
6121 if (op == 0x80 && op2 == 0)
6122 printf (_("Refuse to unwind"));
6123 else
6124 {
6125 unsigned int mask = ((op & 0x0f) << 8) | op2;
6126 int first = 1;
6127 int i;
6128 printf ("pop {");
6129 for (i = 0; i < 12; i++)
6130 if (mask & (1 << i))
6131 {
6132 if (first)
6133 first = 0;
6134 else
6135 printf (", ");
6136 printf ("r%d", 4 + i);
6137 }
6138 printf ("}");
6139 }
6140 }
6141 else if ((op & 0xf0) == 0x90)
6142 {
6143 if (op == 0x9d || op == 0x9f)
6144 printf (_(" [Reserved]"));
6145 else
6146 printf (_(" vsp = r%d"), op & 0x0f);
6147 }
6148 else if ((op & 0xf0) == 0xa0)
6149 {
6150 int end = 4 + (op & 0x07);
6151 int first = 1;
6152 int i;
6153 printf (" pop {");
6154 for (i = 4; i <= end; i++)
6155 {
6156 if (first)
6157 first = 0;
6158 else
6159 printf (", ");
6160 printf ("r%d", i);
6161 }
6162 if (op & 0x08)
6163 {
6164 if (first)
6165 printf (", ");
6166 printf ("r14");
6167 }
6168 printf ("}");
6169 }
6170 else if (op == 0xb0)
6171 printf (_(" finish"));
6172 else if (op == 0xb1)
6173 {
6174 GET_OP (op2);
6175 if (op2 == 0 || (op2 & 0xf0) != 0)
6176 printf (_("[Spare]"));
6177 else
6178 {
6179 unsigned int mask = op2 & 0x0f;
6180 int first = 1;
6181 int i;
6182 printf ("pop {");
6183 for (i = 0; i < 12; i++)
6184 if (mask & (1 << i))
6185 {
6186 if (first)
6187 first = 0;
6188 else
6189 printf (", ");
6190 printf ("r%d", i);
6191 }
6192 printf ("}");
6193 }
6194 }
6195 else if (op == 0xb2)
6196 {
6197 unsigned char buf[5];
6198 unsigned int i, len;
6199 unsigned long offset;
6200 for (i = 0; i < 9; i++)
6201 {
6202 GET_OP (buf[i]);
6203 if ((buf[i] & 0x80) == 0)
6204 break;
6205 }
6206 assert (i < sizeof (buf));
6207 offset = read_uleb128 (buf, &len);
6208 assert (len == i + 1);
6209 offset = offset * 4 + 0x204;
6210 printf (_("vsp = vsp + %ld"), offset);
6211 }
6212 else
6213 {
6214 if (op == 0xb3 || op == 0xc6 || op == 0xc7 || op == 0xc8 || op == 0xc9)
6215 {
6216 GET_OP (op2);
6217 printf (_("[unsupported two-byte opcode]"));
6218 }
6219 else
6220 {
6221 printf (_(" [unsupported opcode]"));
6222 }
6223 }
6224 printf ("\n");
6225 }
6226
6227 /* Decode the descriptors. Not implemented. */
6228}
6229
6230static void
6231dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
6232{
6233 struct arm_section exidx_arm_sec, extab_arm_sec;
6234 unsigned int i, exidx_len;
6235
6236 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
6237 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
6238 exidx_len = exidx_sec->sh_size / 8;
6239
6240 for (i = 0; i < exidx_len; i++)
6241 {
6242 unsigned int exidx_fn, exidx_entry;
6243 struct absaddr fn_addr, entry_addr;
6244 bfd_vma fn;
6245
6246 fputc ('\n', stdout);
6247
6248 if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6249 8 * i, &exidx_fn, &fn_addr)
6250 || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6251 8 * i + 4, &exidx_entry, &entry_addr))
6252 {
6253 arm_free_section (&exidx_arm_sec);
6254 arm_free_section (&extab_arm_sec);
6255 return;
6256 }
6257
6258 fn = exidx_fn & 0x7fffffff;
6259 if (fn & 0x40000000)
6260 fn |= ~ (bfd_vma) 0x7fffffff;
6261 fn = fn + exidx_sec->sh_addr + 8 * i;
6262
6263 arm_print_vma_and_name (aux, fn, entry_addr);
6264 fputs (": ", stdout);
6265
6266 if (exidx_entry == 1)
6267 {
6268 print_vma (exidx_entry, PREFIX_HEX);
6269 fputs (" [cantunwind]\n", stdout);
6270 }
6271 else if (exidx_entry & 0x80000000)
6272 {
6273 print_vma (exidx_entry, PREFIX_HEX);
6274 fputc ('\n', stdout);
6275 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
6276 }
6277 else
6278 {
6279 bfd_vma table, table_offset;
6280 Elf_Internal_Shdr *table_sec;
6281
6282 fputs ("@", stdout);
6283 table = exidx_entry;
6284 if (table & 0x40000000)
6285 table |= ~ (bfd_vma) 0x7fffffff;
6286 table = table + exidx_sec->sh_addr + 8 * i + 4;
6287 print_vma (table, PREFIX_HEX);
6288 printf ("\n");
6289
6290 /* Locate the matching .ARM.extab. */
6291 if (entry_addr.section != SHN_UNDEF
6292 && entry_addr.section < elf_header.e_shnum)
6293 {
6294 table_sec = section_headers + entry_addr.section;
6295 table_offset = entry_addr.offset;
6296 }
6297 else
6298 {
6299 table_sec = find_section_by_address (table);
6300 if (table_sec != NULL)
6301 table_offset = table - table_sec->sh_addr;
6302 }
6303 if (table_sec == NULL)
6304 {
6305 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
6306 (unsigned long) table);
6307 continue;
6308 }
6309 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
6310 &extab_arm_sec);
6311 }
6312 }
6313
6314 printf ("\n");
6315
6316 arm_free_section (&exidx_arm_sec);
6317 arm_free_section (&extab_arm_sec);
6318}
6319
6320static int
6321arm_process_unwind (FILE *file)
6322{
6323 struct arm_unw_aux_info aux;
6324 Elf_Internal_Shdr *unwsec = NULL;
6325 Elf_Internal_Shdr *strsec;
6326 Elf_Internal_Shdr *sec;
6327 unsigned long i;
6328
6329 memset (& aux, 0, sizeof (aux));
6330 aux.file = file;
6331
6332 if (string_table == NULL)
6333 return 1;
6334
6335 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6336 {
6337 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
6338 {
6339 aux.nsyms = sec->sh_size / sec->sh_entsize;
6340 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6341
6342 strsec = section_headers + sec->sh_link;
6343 aux.strtab = get_data (NULL, file, strsec->sh_offset,
6344 1, strsec->sh_size, _("string table"));
6345 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
6346 }
6347 else if (sec->sh_type == SHT_ARM_EXIDX)
6348 unwsec = sec;
6349 }
6350
6351 if (!unwsec)
6352 printf (_("\nThere are no unwind sections in this file.\n"));
6353
6354 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6355 {
6356 if (sec->sh_type == SHT_ARM_EXIDX)
6357 {
6358 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
6359 SECTION_NAME (sec),
6360 (unsigned long) sec->sh_offset,
6361 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
6362
6363 dump_arm_unwind (&aux, sec);
6364 }
6365 }
6366
6367 if (aux.symtab)
6368 free (aux.symtab);
6369 if (aux.strtab)
6370 free ((char *) aux.strtab);
6371
6372 return 1;
6373}
6374
57346661 6375static int
2cf0635d 6376process_unwind (FILE * file)
57346661 6377{
2cf0635d
NC
6378 struct unwind_handler
6379 {
57346661 6380 int machtype;
2cf0635d
NC
6381 int (* handler)(FILE *);
6382 } handlers[] =
6383 {
0b6ae522 6384 { EM_ARM, arm_process_unwind },
57346661
AM
6385 { EM_IA_64, ia64_process_unwind },
6386 { EM_PARISC, hppa_process_unwind },
6387 { 0, 0 }
6388 };
6389 int i;
6390
6391 if (!do_unwind)
6392 return 1;
6393
6394 for (i = 0; handlers[i].handler != NULL; i++)
6395 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 6396 return handlers[i].handler (file);
57346661
AM
6397
6398 printf (_("\nThere are no unwind sections in this file.\n"));
6399 return 1;
6400}
6401
252b5132 6402static void
2cf0635d 6403dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
6404{
6405 switch (entry->d_tag)
6406 {
6407 case DT_MIPS_FLAGS:
6408 if (entry->d_un.d_val == 0)
6409 printf ("NONE\n");
6410 else
6411 {
6412 static const char * opts[] =
6413 {
6414 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
6415 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
6416 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
6417 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
6418 "RLD_ORDER_SAFE"
6419 };
6420 unsigned int cnt;
6421 int first = 1;
60bca95a 6422 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
6423 if (entry->d_un.d_val & (1 << cnt))
6424 {
6425 printf ("%s%s", first ? "" : " ", opts[cnt]);
6426 first = 0;
6427 }
6428 puts ("");
6429 }
6430 break;
103f02d3 6431
252b5132 6432 case DT_MIPS_IVERSION:
d79b3d50
NC
6433 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6434 printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6435 else
d79b3d50 6436 printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
252b5132 6437 break;
103f02d3 6438
252b5132
RH
6439 case DT_MIPS_TIME_STAMP:
6440 {
6441 char timebuf[20];
2cf0635d 6442 struct tm * tmp;
50da7a9c 6443
91d6fa6a
NC
6444 time_t atime = entry->d_un.d_val;
6445 tmp = gmtime (&atime);
e9e44622
JJ
6446 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
6447 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6448 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
6449 printf ("Time Stamp: %s\n", timebuf);
6450 }
6451 break;
103f02d3 6452
252b5132
RH
6453 case DT_MIPS_RLD_VERSION:
6454 case DT_MIPS_LOCAL_GOTNO:
6455 case DT_MIPS_CONFLICTNO:
6456 case DT_MIPS_LIBLISTNO:
6457 case DT_MIPS_SYMTABNO:
6458 case DT_MIPS_UNREFEXTNO:
6459 case DT_MIPS_HIPAGENO:
6460 case DT_MIPS_DELTA_CLASS_NO:
6461 case DT_MIPS_DELTA_INSTANCE_NO:
6462 case DT_MIPS_DELTA_RELOC_NO:
6463 case DT_MIPS_DELTA_SYM_NO:
6464 case DT_MIPS_DELTA_CLASSSYM_NO:
6465 case DT_MIPS_COMPACT_SIZE:
6466 printf ("%ld\n", (long) entry->d_un.d_ptr);
6467 break;
103f02d3
UD
6468
6469 default:
0af1713e 6470 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
6471 }
6472}
6473
6474
6475static void
2cf0635d 6476dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
6477{
6478 switch (entry->d_tag)
6479 {
6480 case DT_HP_DLD_FLAGS:
6481 {
6482 static struct
6483 {
6484 long int bit;
2cf0635d 6485 const char * str;
5e220199
NC
6486 }
6487 flags[] =
6488 {
6489 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
6490 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
6491 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
6492 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
6493 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
6494 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
6495 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
6496 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
6497 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
6498 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
6499 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
6500 { DT_HP_GST, "HP_GST" },
6501 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
6502 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
6503 { DT_HP_NODELETE, "HP_NODELETE" },
6504 { DT_HP_GROUP, "HP_GROUP" },
6505 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 6506 };
103f02d3 6507 int first = 1;
5e220199 6508 size_t cnt;
f7a99963 6509 bfd_vma val = entry->d_un.d_val;
103f02d3 6510
60bca95a 6511 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 6512 if (val & flags[cnt].bit)
30800947
NC
6513 {
6514 if (! first)
6515 putchar (' ');
6516 fputs (flags[cnt].str, stdout);
6517 first = 0;
6518 val ^= flags[cnt].bit;
6519 }
76da6bbe 6520
103f02d3 6521 if (val != 0 || first)
f7a99963
NC
6522 {
6523 if (! first)
6524 putchar (' ');
6525 print_vma (val, HEX);
6526 }
103f02d3
UD
6527 }
6528 break;
76da6bbe 6529
252b5132 6530 default:
f7a99963
NC
6531 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6532 break;
252b5132 6533 }
35b1837e 6534 putchar ('\n');
252b5132
RH
6535}
6536
ecc51f48 6537static void
2cf0635d 6538dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
6539{
6540 switch (entry->d_tag)
6541 {
0de14b54 6542 case DT_IA_64_PLT_RESERVE:
bdf4d63a 6543 /* First 3 slots reserved. */
ecc51f48
NC
6544 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6545 printf (" -- ");
6546 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
6547 break;
6548
6549 default:
6550 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6551 break;
ecc51f48 6552 }
bdf4d63a 6553 putchar ('\n');
ecc51f48
NC
6554}
6555
252b5132 6556static int
2cf0635d 6557get_32bit_dynamic_section (FILE * file)
252b5132 6558{
2cf0635d
NC
6559 Elf32_External_Dyn * edyn;
6560 Elf32_External_Dyn * ext;
6561 Elf_Internal_Dyn * entry;
103f02d3 6562
3f5e193b
NC
6563 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
6564 dynamic_size, _("dynamic section"));
a6e9f9df
AM
6565 if (!edyn)
6566 return 0;
103f02d3 6567
ba2685cc
AM
6568/* SGI's ELF has more than one section in the DYNAMIC segment, and we
6569 might not have the luxury of section headers. Look for the DT_NULL
6570 terminator to determine the number of entries. */
6571 for (ext = edyn, dynamic_nent = 0;
6572 (char *) ext < (char *) edyn + dynamic_size;
6573 ext++)
6574 {
6575 dynamic_nent++;
6576 if (BYTE_GET (ext->d_tag) == DT_NULL)
6577 break;
6578 }
252b5132 6579
3f5e193b
NC
6580 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
6581 sizeof (* entry));
b2d38a17 6582 if (dynamic_section == NULL)
252b5132 6583 {
9ea033b2
NC
6584 error (_("Out of memory\n"));
6585 free (edyn);
6586 return 0;
6587 }
252b5132 6588
fb514b26 6589 for (ext = edyn, entry = dynamic_section;
ba2685cc 6590 entry < dynamic_section + dynamic_nent;
fb514b26 6591 ext++, entry++)
9ea033b2 6592 {
fb514b26
AM
6593 entry->d_tag = BYTE_GET (ext->d_tag);
6594 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
6595 }
6596
9ea033b2
NC
6597 free (edyn);
6598
6599 return 1;
6600}
6601
6602static int
2cf0635d 6603get_64bit_dynamic_section (FILE * file)
9ea033b2 6604{
2cf0635d
NC
6605 Elf64_External_Dyn * edyn;
6606 Elf64_External_Dyn * ext;
6607 Elf_Internal_Dyn * entry;
103f02d3 6608
3f5e193b
NC
6609 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
6610 dynamic_size, _("dynamic section"));
a6e9f9df
AM
6611 if (!edyn)
6612 return 0;
103f02d3 6613
ba2685cc
AM
6614/* SGI's ELF has more than one section in the DYNAMIC segment, and we
6615 might not have the luxury of section headers. Look for the DT_NULL
6616 terminator to determine the number of entries. */
6617 for (ext = edyn, dynamic_nent = 0;
6618 (char *) ext < (char *) edyn + dynamic_size;
6619 ext++)
6620 {
6621 dynamic_nent++;
66543521 6622 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
6623 break;
6624 }
252b5132 6625
3f5e193b
NC
6626 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
6627 sizeof (* entry));
b2d38a17 6628 if (dynamic_section == NULL)
252b5132
RH
6629 {
6630 error (_("Out of memory\n"));
6631 free (edyn);
6632 return 0;
6633 }
6634
fb514b26 6635 for (ext = edyn, entry = dynamic_section;
ba2685cc 6636 entry < dynamic_section + dynamic_nent;
fb514b26 6637 ext++, entry++)
252b5132 6638 {
66543521
AM
6639 entry->d_tag = BYTE_GET (ext->d_tag);
6640 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
6641 }
6642
6643 free (edyn);
6644
9ea033b2
NC
6645 return 1;
6646}
6647
e9e44622
JJ
6648static void
6649print_dynamic_flags (bfd_vma flags)
d1133906 6650{
e9e44622 6651 int first = 1;
13ae64f3 6652
d1133906
NC
6653 while (flags)
6654 {
6655 bfd_vma flag;
6656
6657 flag = flags & - flags;
6658 flags &= ~ flag;
6659
e9e44622
JJ
6660 if (first)
6661 first = 0;
6662 else
6663 putc (' ', stdout);
13ae64f3 6664
d1133906
NC
6665 switch (flag)
6666 {
e9e44622
JJ
6667 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
6668 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
6669 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
6670 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
6671 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
6672 default: fputs ("unknown", stdout); break;
d1133906
NC
6673 }
6674 }
e9e44622 6675 puts ("");
d1133906
NC
6676}
6677
b2d38a17
NC
6678/* Parse and display the contents of the dynamic section. */
6679
9ea033b2 6680static int
2cf0635d 6681process_dynamic_section (FILE * file)
9ea033b2 6682{
2cf0635d 6683 Elf_Internal_Dyn * entry;
9ea033b2
NC
6684
6685 if (dynamic_size == 0)
6686 {
6687 if (do_dynamic)
b2d38a17 6688 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
6689
6690 return 1;
6691 }
6692
6693 if (is_32bit_elf)
6694 {
b2d38a17 6695 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
6696 return 0;
6697 }
b2d38a17 6698 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
6699 return 0;
6700
252b5132
RH
6701 /* Find the appropriate symbol table. */
6702 if (dynamic_symbols == NULL)
6703 {
86dba8ee
AM
6704 for (entry = dynamic_section;
6705 entry < dynamic_section + dynamic_nent;
6706 ++entry)
252b5132 6707 {
c8286bd1 6708 Elf_Internal_Shdr section;
252b5132
RH
6709
6710 if (entry->d_tag != DT_SYMTAB)
6711 continue;
6712
6713 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
6714
6715 /* Since we do not know how big the symbol table is,
6716 we default to reading in the entire file (!) and
6717 processing that. This is overkill, I know, but it
e3c8793a 6718 should work. */
d93f0186 6719 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 6720
fb52b2f4
NC
6721 if (archive_file_offset != 0)
6722 section.sh_size = archive_file_size - section.sh_offset;
6723 else
6724 {
6725 if (fseek (file, 0, SEEK_END))
591a748a 6726 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
6727
6728 section.sh_size = ftell (file) - section.sh_offset;
6729 }
252b5132 6730
9ea033b2 6731 if (is_32bit_elf)
9ad5cbcf 6732 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 6733 else
9ad5cbcf 6734 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 6735
9ad5cbcf 6736 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 6737 if (num_dynamic_syms < 1)
252b5132
RH
6738 {
6739 error (_("Unable to determine the number of symbols to load\n"));
6740 continue;
6741 }
6742
9ad5cbcf 6743 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
6744 }
6745 }
6746
6747 /* Similarly find a string table. */
6748 if (dynamic_strings == NULL)
6749 {
86dba8ee
AM
6750 for (entry = dynamic_section;
6751 entry < dynamic_section + dynamic_nent;
6752 ++entry)
252b5132
RH
6753 {
6754 unsigned long offset;
b34976b6 6755 long str_tab_len;
252b5132
RH
6756
6757 if (entry->d_tag != DT_STRTAB)
6758 continue;
6759
6760 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
6761
6762 /* Since we do not know how big the string table is,
6763 we default to reading in the entire file (!) and
6764 processing that. This is overkill, I know, but it
e3c8793a 6765 should work. */
252b5132 6766
d93f0186 6767 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
6768
6769 if (archive_file_offset != 0)
6770 str_tab_len = archive_file_size - offset;
6771 else
6772 {
6773 if (fseek (file, 0, SEEK_END))
6774 error (_("Unable to seek to end of file\n"));
6775 str_tab_len = ftell (file) - offset;
6776 }
252b5132
RH
6777
6778 if (str_tab_len < 1)
6779 {
6780 error
6781 (_("Unable to determine the length of the dynamic string table\n"));
6782 continue;
6783 }
6784
3f5e193b
NC
6785 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
6786 str_tab_len,
6787 _("dynamic string table"));
d79b3d50 6788 dynamic_strings_length = str_tab_len;
252b5132
RH
6789 break;
6790 }
6791 }
6792
6793 /* And find the syminfo section if available. */
6794 if (dynamic_syminfo == NULL)
6795 {
3e8bba36 6796 unsigned long syminsz = 0;
252b5132 6797
86dba8ee
AM
6798 for (entry = dynamic_section;
6799 entry < dynamic_section + dynamic_nent;
6800 ++entry)
252b5132
RH
6801 {
6802 if (entry->d_tag == DT_SYMINENT)
6803 {
6804 /* Note: these braces are necessary to avoid a syntax
6805 error from the SunOS4 C compiler. */
6806 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
6807 }
6808 else if (entry->d_tag == DT_SYMINSZ)
6809 syminsz = entry->d_un.d_val;
6810 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
6811 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
6812 syminsz);
252b5132
RH
6813 }
6814
6815 if (dynamic_syminfo_offset != 0 && syminsz != 0)
6816 {
2cf0635d
NC
6817 Elf_External_Syminfo * extsyminfo;
6818 Elf_External_Syminfo * extsym;
6819 Elf_Internal_Syminfo * syminfo;
252b5132
RH
6820
6821 /* There is a syminfo section. Read the data. */
3f5e193b
NC
6822 extsyminfo = (Elf_External_Syminfo *)
6823 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
6824 _("symbol information"));
a6e9f9df
AM
6825 if (!extsyminfo)
6826 return 0;
252b5132 6827
3f5e193b 6828 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
6829 if (dynamic_syminfo == NULL)
6830 {
6831 error (_("Out of memory\n"));
6832 return 0;
6833 }
6834
6835 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
6836 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
6837 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
6838 ++syminfo, ++extsym)
252b5132 6839 {
86dba8ee
AM
6840 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
6841 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
6842 }
6843
6844 free (extsyminfo);
6845 }
6846 }
6847
6848 if (do_dynamic && dynamic_addr)
86dba8ee
AM
6849 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
6850 dynamic_addr, dynamic_nent);
252b5132
RH
6851 if (do_dynamic)
6852 printf (_(" Tag Type Name/Value\n"));
6853
86dba8ee
AM
6854 for (entry = dynamic_section;
6855 entry < dynamic_section + dynamic_nent;
6856 entry++)
252b5132
RH
6857 {
6858 if (do_dynamic)
f7a99963 6859 {
2cf0635d 6860 const char * dtype;
e699b9ff 6861
f7a99963
NC
6862 putchar (' ');
6863 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
6864 dtype = get_dynamic_type (entry->d_tag);
6865 printf (" (%s)%*s", dtype,
6866 ((is_32bit_elf ? 27 : 19)
6867 - (int) strlen (dtype)),
f7a99963
NC
6868 " ");
6869 }
252b5132
RH
6870
6871 switch (entry->d_tag)
6872 {
d1133906
NC
6873 case DT_FLAGS:
6874 if (do_dynamic)
e9e44622 6875 print_dynamic_flags (entry->d_un.d_val);
d1133906 6876 break;
76da6bbe 6877
252b5132
RH
6878 case DT_AUXILIARY:
6879 case DT_FILTER:
019148e4
L
6880 case DT_CONFIG:
6881 case DT_DEPAUDIT:
6882 case DT_AUDIT:
252b5132
RH
6883 if (do_dynamic)
6884 {
019148e4 6885 switch (entry->d_tag)
b34976b6 6886 {
019148e4
L
6887 case DT_AUXILIARY:
6888 printf (_("Auxiliary library"));
6889 break;
6890
6891 case DT_FILTER:
6892 printf (_("Filter library"));
6893 break;
6894
b34976b6 6895 case DT_CONFIG:
019148e4
L
6896 printf (_("Configuration file"));
6897 break;
6898
6899 case DT_DEPAUDIT:
6900 printf (_("Dependency audit library"));
6901 break;
6902
6903 case DT_AUDIT:
6904 printf (_("Audit library"));
6905 break;
6906 }
252b5132 6907
d79b3d50
NC
6908 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6909 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6910 else
f7a99963
NC
6911 {
6912 printf (": ");
6913 print_vma (entry->d_un.d_val, PREFIX_HEX);
6914 putchar ('\n');
6915 }
252b5132
RH
6916 }
6917 break;
6918
dcefbbbd 6919 case DT_FEATURE:
252b5132
RH
6920 if (do_dynamic)
6921 {
6922 printf (_("Flags:"));
86f55779 6923
252b5132
RH
6924 if (entry->d_un.d_val == 0)
6925 printf (_(" None\n"));
6926 else
6927 {
6928 unsigned long int val = entry->d_un.d_val;
86f55779 6929
252b5132
RH
6930 if (val & DTF_1_PARINIT)
6931 {
6932 printf (" PARINIT");
6933 val ^= DTF_1_PARINIT;
6934 }
dcefbbbd
L
6935 if (val & DTF_1_CONFEXP)
6936 {
6937 printf (" CONFEXP");
6938 val ^= DTF_1_CONFEXP;
6939 }
252b5132
RH
6940 if (val != 0)
6941 printf (" %lx", val);
6942 puts ("");
6943 }
6944 }
6945 break;
6946
6947 case DT_POSFLAG_1:
6948 if (do_dynamic)
6949 {
6950 printf (_("Flags:"));
86f55779 6951
252b5132
RH
6952 if (entry->d_un.d_val == 0)
6953 printf (_(" None\n"));
6954 else
6955 {
6956 unsigned long int val = entry->d_un.d_val;
86f55779 6957
252b5132
RH
6958 if (val & DF_P1_LAZYLOAD)
6959 {
6960 printf (" LAZYLOAD");
6961 val ^= DF_P1_LAZYLOAD;
6962 }
6963 if (val & DF_P1_GROUPPERM)
6964 {
6965 printf (" GROUPPERM");
6966 val ^= DF_P1_GROUPPERM;
6967 }
6968 if (val != 0)
6969 printf (" %lx", val);
6970 puts ("");
6971 }
6972 }
6973 break;
6974
6975 case DT_FLAGS_1:
6976 if (do_dynamic)
6977 {
6978 printf (_("Flags:"));
6979 if (entry->d_un.d_val == 0)
6980 printf (_(" None\n"));
6981 else
6982 {
6983 unsigned long int val = entry->d_un.d_val;
86f55779 6984
252b5132
RH
6985 if (val & DF_1_NOW)
6986 {
6987 printf (" NOW");
6988 val ^= DF_1_NOW;
6989 }
6990 if (val & DF_1_GLOBAL)
6991 {
6992 printf (" GLOBAL");
6993 val ^= DF_1_GLOBAL;
6994 }
6995 if (val & DF_1_GROUP)
6996 {
6997 printf (" GROUP");
6998 val ^= DF_1_GROUP;
6999 }
7000 if (val & DF_1_NODELETE)
7001 {
7002 printf (" NODELETE");
7003 val ^= DF_1_NODELETE;
7004 }
7005 if (val & DF_1_LOADFLTR)
7006 {
7007 printf (" LOADFLTR");
7008 val ^= DF_1_LOADFLTR;
7009 }
7010 if (val & DF_1_INITFIRST)
7011 {
7012 printf (" INITFIRST");
7013 val ^= DF_1_INITFIRST;
7014 }
7015 if (val & DF_1_NOOPEN)
7016 {
7017 printf (" NOOPEN");
7018 val ^= DF_1_NOOPEN;
7019 }
7020 if (val & DF_1_ORIGIN)
7021 {
7022 printf (" ORIGIN");
7023 val ^= DF_1_ORIGIN;
7024 }
7025 if (val & DF_1_DIRECT)
7026 {
7027 printf (" DIRECT");
7028 val ^= DF_1_DIRECT;
7029 }
7030 if (val & DF_1_TRANS)
7031 {
7032 printf (" TRANS");
7033 val ^= DF_1_TRANS;
7034 }
7035 if (val & DF_1_INTERPOSE)
7036 {
7037 printf (" INTERPOSE");
7038 val ^= DF_1_INTERPOSE;
7039 }
f7db6139 7040 if (val & DF_1_NODEFLIB)
dcefbbbd 7041 {
f7db6139
L
7042 printf (" NODEFLIB");
7043 val ^= DF_1_NODEFLIB;
dcefbbbd
L
7044 }
7045 if (val & DF_1_NODUMP)
7046 {
7047 printf (" NODUMP");
7048 val ^= DF_1_NODUMP;
7049 }
7050 if (val & DF_1_CONLFAT)
7051 {
7052 printf (" CONLFAT");
7053 val ^= DF_1_CONLFAT;
7054 }
252b5132
RH
7055 if (val != 0)
7056 printf (" %lx", val);
7057 puts ("");
7058 }
7059 }
7060 break;
7061
7062 case DT_PLTREL:
566b0d53 7063 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7064 if (do_dynamic)
7065 puts (get_dynamic_type (entry->d_un.d_val));
7066 break;
7067
7068 case DT_NULL :
7069 case DT_NEEDED :
7070 case DT_PLTGOT :
7071 case DT_HASH :
7072 case DT_STRTAB :
7073 case DT_SYMTAB :
7074 case DT_RELA :
7075 case DT_INIT :
7076 case DT_FINI :
7077 case DT_SONAME :
7078 case DT_RPATH :
7079 case DT_SYMBOLIC:
7080 case DT_REL :
7081 case DT_DEBUG :
7082 case DT_TEXTREL :
7083 case DT_JMPREL :
019148e4 7084 case DT_RUNPATH :
252b5132
RH
7085 dynamic_info[entry->d_tag] = entry->d_un.d_val;
7086
7087 if (do_dynamic)
7088 {
2cf0635d 7089 char * name;
252b5132 7090
d79b3d50
NC
7091 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7092 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7093 else
d79b3d50 7094 name = NULL;
252b5132
RH
7095
7096 if (name)
7097 {
7098 switch (entry->d_tag)
7099 {
7100 case DT_NEEDED:
7101 printf (_("Shared library: [%s]"), name);
7102
18bd398b 7103 if (streq (name, program_interpreter))
f7a99963 7104 printf (_(" program interpreter"));
252b5132
RH
7105 break;
7106
7107 case DT_SONAME:
f7a99963 7108 printf (_("Library soname: [%s]"), name);
252b5132
RH
7109 break;
7110
7111 case DT_RPATH:
f7a99963 7112 printf (_("Library rpath: [%s]"), name);
252b5132
RH
7113 break;
7114
019148e4
L
7115 case DT_RUNPATH:
7116 printf (_("Library runpath: [%s]"), name);
7117 break;
7118
252b5132 7119 default:
f7a99963
NC
7120 print_vma (entry->d_un.d_val, PREFIX_HEX);
7121 break;
252b5132
RH
7122 }
7123 }
7124 else
f7a99963
NC
7125 print_vma (entry->d_un.d_val, PREFIX_HEX);
7126
7127 putchar ('\n');
252b5132
RH
7128 }
7129 break;
7130
7131 case DT_PLTRELSZ:
7132 case DT_RELASZ :
7133 case DT_STRSZ :
7134 case DT_RELSZ :
7135 case DT_RELAENT :
7136 case DT_SYMENT :
7137 case DT_RELENT :
566b0d53 7138 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7139 case DT_PLTPADSZ:
7140 case DT_MOVEENT :
7141 case DT_MOVESZ :
7142 case DT_INIT_ARRAYSZ:
7143 case DT_FINI_ARRAYSZ:
047b2264
JJ
7144 case DT_GNU_CONFLICTSZ:
7145 case DT_GNU_LIBLISTSZ:
252b5132 7146 if (do_dynamic)
f7a99963
NC
7147 {
7148 print_vma (entry->d_un.d_val, UNSIGNED);
7149 printf (" (bytes)\n");
7150 }
252b5132
RH
7151 break;
7152
7153 case DT_VERDEFNUM:
7154 case DT_VERNEEDNUM:
7155 case DT_RELACOUNT:
7156 case DT_RELCOUNT:
7157 if (do_dynamic)
f7a99963
NC
7158 {
7159 print_vma (entry->d_un.d_val, UNSIGNED);
7160 putchar ('\n');
7161 }
252b5132
RH
7162 break;
7163
7164 case DT_SYMINSZ:
7165 case DT_SYMINENT:
7166 case DT_SYMINFO:
7167 case DT_USED:
7168 case DT_INIT_ARRAY:
7169 case DT_FINI_ARRAY:
7170 if (do_dynamic)
7171 {
d79b3d50
NC
7172 if (entry->d_tag == DT_USED
7173 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 7174 {
2cf0635d 7175 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7176
b34976b6 7177 if (*name)
252b5132
RH
7178 {
7179 printf (_("Not needed object: [%s]\n"), name);
7180 break;
7181 }
7182 }
103f02d3 7183
f7a99963
NC
7184 print_vma (entry->d_un.d_val, PREFIX_HEX);
7185 putchar ('\n');
252b5132
RH
7186 }
7187 break;
7188
7189 case DT_BIND_NOW:
7190 /* The value of this entry is ignored. */
35b1837e
AM
7191 if (do_dynamic)
7192 putchar ('\n');
252b5132 7193 break;
103f02d3 7194
047b2264
JJ
7195 case DT_GNU_PRELINKED:
7196 if (do_dynamic)
7197 {
2cf0635d 7198 struct tm * tmp;
91d6fa6a 7199 time_t atime = entry->d_un.d_val;
047b2264 7200
91d6fa6a 7201 tmp = gmtime (&atime);
047b2264
JJ
7202 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
7203 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7204 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7205
7206 }
7207 break;
7208
fdc90cb4
JJ
7209 case DT_GNU_HASH:
7210 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
7211 if (do_dynamic)
7212 {
7213 print_vma (entry->d_un.d_val, PREFIX_HEX);
7214 putchar ('\n');
7215 }
7216 break;
7217
252b5132
RH
7218 default:
7219 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 7220 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
7221 entry->d_un.d_val;
7222
7223 if (do_dynamic)
7224 {
7225 switch (elf_header.e_machine)
7226 {
7227 case EM_MIPS:
4fe85591 7228 case EM_MIPS_RS3_LE:
b2d38a17 7229 dynamic_section_mips_val (entry);
252b5132 7230 break;
103f02d3 7231 case EM_PARISC:
b2d38a17 7232 dynamic_section_parisc_val (entry);
103f02d3 7233 break;
ecc51f48 7234 case EM_IA_64:
b2d38a17 7235 dynamic_section_ia64_val (entry);
ecc51f48 7236 break;
252b5132 7237 default:
f7a99963
NC
7238 print_vma (entry->d_un.d_val, PREFIX_HEX);
7239 putchar ('\n');
252b5132
RH
7240 }
7241 }
7242 break;
7243 }
7244 }
7245
7246 return 1;
7247}
7248
7249static char *
d3ba0551 7250get_ver_flags (unsigned int flags)
252b5132 7251{
b34976b6 7252 static char buff[32];
252b5132
RH
7253
7254 buff[0] = 0;
7255
7256 if (flags == 0)
7257 return _("none");
7258
7259 if (flags & VER_FLG_BASE)
7260 strcat (buff, "BASE ");
7261
7262 if (flags & VER_FLG_WEAK)
7263 {
7264 if (flags & VER_FLG_BASE)
7265 strcat (buff, "| ");
7266
7267 strcat (buff, "WEAK ");
7268 }
7269
7270 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
7271 strcat (buff, "| <unknown>");
7272
7273 return buff;
7274}
7275
7276/* Display the contents of the version sections. */
98fb390a 7277
252b5132 7278static int
2cf0635d 7279process_version_sections (FILE * file)
252b5132 7280{
2cf0635d 7281 Elf_Internal_Shdr * section;
b34976b6
AM
7282 unsigned i;
7283 int found = 0;
252b5132
RH
7284
7285 if (! do_version)
7286 return 1;
7287
7288 for (i = 0, section = section_headers;
7289 i < elf_header.e_shnum;
b34976b6 7290 i++, section++)
252b5132
RH
7291 {
7292 switch (section->sh_type)
7293 {
7294 case SHT_GNU_verdef:
7295 {
2cf0635d 7296 Elf_External_Verdef * edefs;
b34976b6
AM
7297 unsigned int idx;
7298 unsigned int cnt;
2cf0635d 7299 char * endbuf;
252b5132
RH
7300
7301 found = 1;
7302
7303 printf
72de5009 7304 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
7305 SECTION_NAME (section), section->sh_info);
7306
7307 printf (_(" Addr: 0x"));
7308 printf_vma (section->sh_addr);
72de5009 7309 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7310 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
7311 section->sh_link < elf_header.e_shnum
7312 ? SECTION_NAME (section_headers + section->sh_link)
c256ffe7 7313 : "<corrupt>");
252b5132 7314
3f5e193b
NC
7315 edefs = (Elf_External_Verdef *)
7316 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
7317 _("version definition section"));
54806181 7318 endbuf = (char *) edefs + section->sh_size;
a6e9f9df
AM
7319 if (!edefs)
7320 break;
252b5132 7321
b34976b6 7322 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 7323 {
2cf0635d
NC
7324 char * vstart;
7325 Elf_External_Verdef * edef;
b34976b6 7326 Elf_Internal_Verdef ent;
2cf0635d 7327 Elf_External_Verdaux * eaux;
b34976b6
AM
7328 Elf_Internal_Verdaux aux;
7329 int j;
7330 int isum;
103f02d3 7331
252b5132 7332 vstart = ((char *) edefs) + idx;
54806181
AM
7333 if (vstart + sizeof (*edef) > endbuf)
7334 break;
252b5132
RH
7335
7336 edef = (Elf_External_Verdef *) vstart;
7337
7338 ent.vd_version = BYTE_GET (edef->vd_version);
7339 ent.vd_flags = BYTE_GET (edef->vd_flags);
7340 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
7341 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
7342 ent.vd_hash = BYTE_GET (edef->vd_hash);
7343 ent.vd_aux = BYTE_GET (edef->vd_aux);
7344 ent.vd_next = BYTE_GET (edef->vd_next);
7345
7346 printf (_(" %#06x: Rev: %d Flags: %s"),
7347 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
7348
7349 printf (_(" Index: %d Cnt: %d "),
7350 ent.vd_ndx, ent.vd_cnt);
7351
7352 vstart += ent.vd_aux;
7353
7354 eaux = (Elf_External_Verdaux *) vstart;
7355
7356 aux.vda_name = BYTE_GET (eaux->vda_name);
7357 aux.vda_next = BYTE_GET (eaux->vda_next);
7358
d79b3d50
NC
7359 if (VALID_DYNAMIC_NAME (aux.vda_name))
7360 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
7361 else
7362 printf (_("Name index: %ld\n"), aux.vda_name);
7363
7364 isum = idx + ent.vd_aux;
7365
b34976b6 7366 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
7367 {
7368 isum += aux.vda_next;
7369 vstart += aux.vda_next;
7370
7371 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
7372 if (vstart + sizeof (*eaux) > endbuf)
7373 break;
252b5132
RH
7374
7375 aux.vda_name = BYTE_GET (eaux->vda_name);
7376 aux.vda_next = BYTE_GET (eaux->vda_next);
7377
d79b3d50 7378 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 7379 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 7380 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
7381 else
7382 printf (_(" %#06x: Parent %d, name index: %ld\n"),
7383 isum, j, aux.vda_name);
7384 }
54806181
AM
7385 if (j < ent.vd_cnt)
7386 printf (_(" Version def aux past end of section\n"));
252b5132
RH
7387
7388 idx += ent.vd_next;
7389 }
54806181
AM
7390 if (cnt < section->sh_info)
7391 printf (_(" Version definition past end of section\n"));
252b5132
RH
7392
7393 free (edefs);
7394 }
7395 break;
103f02d3 7396
252b5132
RH
7397 case SHT_GNU_verneed:
7398 {
2cf0635d 7399 Elf_External_Verneed * eneed;
b34976b6
AM
7400 unsigned int idx;
7401 unsigned int cnt;
2cf0635d 7402 char * endbuf;
252b5132
RH
7403
7404 found = 1;
7405
72de5009 7406 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
7407 SECTION_NAME (section), section->sh_info);
7408
7409 printf (_(" Addr: 0x"));
7410 printf_vma (section->sh_addr);
72de5009 7411 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7412 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
7413 section->sh_link < elf_header.e_shnum
7414 ? SECTION_NAME (section_headers + section->sh_link)
c256ffe7 7415 : "<corrupt>");
252b5132 7416
3f5e193b
NC
7417 eneed = (Elf_External_Verneed *) get_data (NULL, file,
7418 section->sh_offset, 1,
7419 section->sh_size,
7420 _("version need section"));
54806181 7421 endbuf = (char *) eneed + section->sh_size;
a6e9f9df
AM
7422 if (!eneed)
7423 break;
252b5132
RH
7424
7425 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
7426 {
2cf0635d 7427 Elf_External_Verneed * entry;
b34976b6
AM
7428 Elf_Internal_Verneed ent;
7429 int j;
7430 int isum;
2cf0635d 7431 char * vstart;
252b5132
RH
7432
7433 vstart = ((char *) eneed) + idx;
54806181
AM
7434 if (vstart + sizeof (*entry) > endbuf)
7435 break;
252b5132
RH
7436
7437 entry = (Elf_External_Verneed *) vstart;
7438
7439 ent.vn_version = BYTE_GET (entry->vn_version);
7440 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
7441 ent.vn_file = BYTE_GET (entry->vn_file);
7442 ent.vn_aux = BYTE_GET (entry->vn_aux);
7443 ent.vn_next = BYTE_GET (entry->vn_next);
7444
7445 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
7446
d79b3d50
NC
7447 if (VALID_DYNAMIC_NAME (ent.vn_file))
7448 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
7449 else
7450 printf (_(" File: %lx"), ent.vn_file);
7451
7452 printf (_(" Cnt: %d\n"), ent.vn_cnt);
7453
7454 vstart += ent.vn_aux;
7455
7456 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
7457 {
2cf0635d 7458 Elf_External_Vernaux * eaux;
b34976b6 7459 Elf_Internal_Vernaux aux;
252b5132 7460
54806181
AM
7461 if (vstart + sizeof (*eaux) > endbuf)
7462 break;
252b5132
RH
7463 eaux = (Elf_External_Vernaux *) vstart;
7464
7465 aux.vna_hash = BYTE_GET (eaux->vna_hash);
7466 aux.vna_flags = BYTE_GET (eaux->vna_flags);
7467 aux.vna_other = BYTE_GET (eaux->vna_other);
7468 aux.vna_name = BYTE_GET (eaux->vna_name);
7469 aux.vna_next = BYTE_GET (eaux->vna_next);
7470
d79b3d50 7471 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 7472 printf (_(" %#06x: Name: %s"),
d79b3d50 7473 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 7474 else
ecc2063b 7475 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
7476 isum, aux.vna_name);
7477
7478 printf (_(" Flags: %s Version: %d\n"),
7479 get_ver_flags (aux.vna_flags), aux.vna_other);
7480
7481 isum += aux.vna_next;
7482 vstart += aux.vna_next;
7483 }
54806181
AM
7484 if (j < ent.vn_cnt)
7485 printf (_(" Version need aux past end of section\n"));
252b5132
RH
7486
7487 idx += ent.vn_next;
7488 }
54806181
AM
7489 if (cnt < section->sh_info)
7490 printf (_(" Version need past end of section\n"));
103f02d3 7491
252b5132
RH
7492 free (eneed);
7493 }
7494 break;
7495
7496 case SHT_GNU_versym:
7497 {
2cf0635d 7498 Elf_Internal_Shdr * link_section;
b34976b6
AM
7499 int total;
7500 int cnt;
2cf0635d
NC
7501 unsigned char * edata;
7502 unsigned short * data;
7503 char * strtab;
7504 Elf_Internal_Sym * symbols;
7505 Elf_Internal_Shdr * string_sec;
d3ba0551 7506 long off;
252b5132 7507
4fbb74a6 7508 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
7509 break;
7510
4fbb74a6 7511 link_section = section_headers + section->sh_link;
08d8fa11 7512 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 7513
4fbb74a6 7514 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
7515 break;
7516
252b5132
RH
7517 found = 1;
7518
9ad5cbcf 7519 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 7520
4fbb74a6 7521 string_sec = section_headers + link_section->sh_link;
252b5132 7522
3f5e193b
NC
7523 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
7524 string_sec->sh_size,
7525 _("version string table"));
a6e9f9df
AM
7526 if (!strtab)
7527 break;
252b5132
RH
7528
7529 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
7530 SECTION_NAME (section), total);
7531
7532 printf (_(" Addr: "));
7533 printf_vma (section->sh_addr);
72de5009 7534 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7535 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
7536 SECTION_NAME (link_section));
7537
d3ba0551
AM
7538 off = offset_from_vma (file,
7539 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
7540 total * sizeof (short));
3f5e193b
NC
7541 edata = (unsigned char *) get_data (NULL, file, off, total,
7542 sizeof (short),
7543 _("version symbol data"));
a6e9f9df
AM
7544 if (!edata)
7545 {
7546 free (strtab);
7547 break;
7548 }
252b5132 7549
3f5e193b 7550 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
7551
7552 for (cnt = total; cnt --;)
b34976b6
AM
7553 data[cnt] = byte_get (edata + cnt * sizeof (short),
7554 sizeof (short));
252b5132
RH
7555
7556 free (edata);
7557
7558 for (cnt = 0; cnt < total; cnt += 4)
7559 {
7560 int j, nn;
00d93f34 7561 int check_def, check_need;
2cf0635d 7562 char * name;
252b5132
RH
7563
7564 printf (" %03x:", cnt);
7565
7566 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 7567 switch (data[cnt + j])
252b5132
RH
7568 {
7569 case 0:
7570 fputs (_(" 0 (*local*) "), stdout);
7571 break;
7572
7573 case 1:
7574 fputs (_(" 1 (*global*) "), stdout);
7575 break;
7576
7577 default:
c244d050
NC
7578 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
7579 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 7580
00d93f34
JJ
7581 check_def = 1;
7582 check_need = 1;
4fbb74a6
AM
7583 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
7584 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 7585 != SHT_NOBITS)
252b5132 7586 {
b34976b6 7587 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
7588 check_def = 0;
7589 else
7590 check_need = 0;
252b5132 7591 }
00d93f34
JJ
7592
7593 if (check_need
b34976b6 7594 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 7595 {
b34976b6
AM
7596 Elf_Internal_Verneed ivn;
7597 unsigned long offset;
252b5132 7598
d93f0186
NC
7599 offset = offset_from_vma
7600 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
7601 sizeof (Elf_External_Verneed));
252b5132 7602
b34976b6 7603 do
252b5132 7604 {
b34976b6
AM
7605 Elf_Internal_Vernaux ivna;
7606 Elf_External_Verneed evn;
7607 Elf_External_Vernaux evna;
7608 unsigned long a_off;
252b5132 7609
c256ffe7 7610 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 7611 _("version need"));
252b5132
RH
7612
7613 ivn.vn_aux = BYTE_GET (evn.vn_aux);
7614 ivn.vn_next = BYTE_GET (evn.vn_next);
7615
7616 a_off = offset + ivn.vn_aux;
7617
7618 do
7619 {
a6e9f9df 7620 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 7621 1, _("version need aux (2)"));
252b5132
RH
7622
7623 ivna.vna_next = BYTE_GET (evna.vna_next);
7624 ivna.vna_other = BYTE_GET (evna.vna_other);
7625
7626 a_off += ivna.vna_next;
7627 }
b34976b6 7628 while (ivna.vna_other != data[cnt + j]
252b5132
RH
7629 && ivna.vna_next != 0);
7630
b34976b6 7631 if (ivna.vna_other == data[cnt + j])
252b5132
RH
7632 {
7633 ivna.vna_name = BYTE_GET (evna.vna_name);
7634
54806181
AM
7635 if (ivna.vna_name >= string_sec->sh_size)
7636 name = _("*invalid*");
7637 else
7638 name = strtab + ivna.vna_name;
252b5132 7639 nn += printf ("(%s%-*s",
16062207
ILT
7640 name,
7641 12 - (int) strlen (name),
252b5132 7642 ")");
00d93f34 7643 check_def = 0;
252b5132
RH
7644 break;
7645 }
7646
7647 offset += ivn.vn_next;
7648 }
7649 while (ivn.vn_next);
7650 }
00d93f34 7651
b34976b6
AM
7652 if (check_def && data[cnt + j] != 0x8001
7653 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 7654 {
b34976b6
AM
7655 Elf_Internal_Verdef ivd;
7656 Elf_External_Verdef evd;
7657 unsigned long offset;
252b5132 7658
d93f0186
NC
7659 offset = offset_from_vma
7660 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
7661 sizeof evd);
252b5132
RH
7662
7663 do
7664 {
c256ffe7 7665 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 7666 _("version def"));
252b5132
RH
7667
7668 ivd.vd_next = BYTE_GET (evd.vd_next);
7669 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
7670
7671 offset += ivd.vd_next;
7672 }
c244d050 7673 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
7674 && ivd.vd_next != 0);
7675
c244d050 7676 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 7677 {
b34976b6
AM
7678 Elf_External_Verdaux evda;
7679 Elf_Internal_Verdaux ivda;
252b5132
RH
7680
7681 ivd.vd_aux = BYTE_GET (evd.vd_aux);
7682
a6e9f9df
AM
7683 get_data (&evda, file,
7684 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
7685 sizeof (evda), 1,
7686 _("version def aux"));
252b5132
RH
7687
7688 ivda.vda_name = BYTE_GET (evda.vda_name);
7689
54806181
AM
7690 if (ivda.vda_name >= string_sec->sh_size)
7691 name = _("*invalid*");
7692 else
7693 name = strtab + ivda.vda_name;
252b5132 7694 nn += printf ("(%s%-*s",
16062207
ILT
7695 name,
7696 12 - (int) strlen (name),
252b5132
RH
7697 ")");
7698 }
7699 }
7700
7701 if (nn < 18)
7702 printf ("%*c", 18 - nn, ' ');
7703 }
7704
7705 putchar ('\n');
7706 }
7707
7708 free (data);
7709 free (strtab);
7710 free (symbols);
7711 }
7712 break;
103f02d3 7713
252b5132
RH
7714 default:
7715 break;
7716 }
7717 }
7718
7719 if (! found)
7720 printf (_("\nNo version information found in this file.\n"));
7721
7722 return 1;
7723}
7724
d1133906 7725static const char *
d3ba0551 7726get_symbol_binding (unsigned int binding)
252b5132 7727{
b34976b6 7728 static char buff[32];
252b5132
RH
7729
7730 switch (binding)
7731 {
b34976b6
AM
7732 case STB_LOCAL: return "LOCAL";
7733 case STB_GLOBAL: return "GLOBAL";
7734 case STB_WEAK: return "WEAK";
252b5132
RH
7735 default:
7736 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
7737 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
7738 binding);
252b5132 7739 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
7740 {
7741 if (binding == STB_GNU_UNIQUE
7742 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
7743 /* GNU/Linux is still using the default value 0. */
7744 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
7745 return "UNIQUE";
7746 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
7747 }
252b5132 7748 else
e9e44622 7749 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
7750 return buff;
7751 }
7752}
7753
d1133906 7754static const char *
d3ba0551 7755get_symbol_type (unsigned int type)
252b5132 7756{
b34976b6 7757 static char buff[32];
252b5132
RH
7758
7759 switch (type)
7760 {
b34976b6
AM
7761 case STT_NOTYPE: return "NOTYPE";
7762 case STT_OBJECT: return "OBJECT";
7763 case STT_FUNC: return "FUNC";
7764 case STT_SECTION: return "SECTION";
7765 case STT_FILE: return "FILE";
7766 case STT_COMMON: return "COMMON";
7767 case STT_TLS: return "TLS";
15ab5209
DB
7768 case STT_RELC: return "RELC";
7769 case STT_SRELC: return "SRELC";
252b5132
RH
7770 default:
7771 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
7772 {
7773 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
7774 return "THUMB_FUNC";
7775
351b4b40 7776 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
7777 return "REGISTER";
7778
7779 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
7780 return "PARISC_MILLI";
7781
e9e44622 7782 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 7783 }
252b5132 7784 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
7785 {
7786 if (elf_header.e_machine == EM_PARISC)
7787 {
7788 if (type == STT_HP_OPAQUE)
7789 return "HP_OPAQUE";
7790 if (type == STT_HP_STUB)
7791 return "HP_STUB";
7792 }
7793
d8045f23
NC
7794 if (type == STT_GNU_IFUNC
7795 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
7796 /* GNU/Linux is still using the default value 0. */
7797 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
7798 return "IFUNC";
7799
e9e44622 7800 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 7801 }
252b5132 7802 else
e9e44622 7803 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
7804 return buff;
7805 }
7806}
7807
d1133906 7808static const char *
d3ba0551 7809get_symbol_visibility (unsigned int visibility)
d1133906
NC
7810{
7811 switch (visibility)
7812 {
b34976b6
AM
7813 case STV_DEFAULT: return "DEFAULT";
7814 case STV_INTERNAL: return "INTERNAL";
7815 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
7816 case STV_PROTECTED: return "PROTECTED";
7817 default: abort ();
7818 }
7819}
7820
5e2b0d47
NC
7821static const char *
7822get_mips_symbol_other (unsigned int other)
7823{
7824 switch (other)
7825 {
7826 case STO_OPTIONAL: return "OPTIONAL";
7827 case STO_MIPS16: return "MIPS16";
861fb55a
DJ
7828 case STO_MIPS_PLT: return "MIPS PLT";
7829 case STO_MIPS_PIC: return "MIPS PIC";
5e2b0d47
NC
7830 default: return NULL;
7831 }
7832}
7833
7834static const char *
7835get_symbol_other (unsigned int other)
7836{
7837 const char * result = NULL;
7838 static char buff [32];
7839
7840 if (other == 0)
7841 return "";
7842
7843 switch (elf_header.e_machine)
7844 {
7845 case EM_MIPS:
7846 result = get_mips_symbol_other (other);
7847 default:
7848 break;
7849 }
7850
7851 if (result)
7852 return result;
7853
7854 snprintf (buff, sizeof buff, _("<other>: %x"), other);
7855 return buff;
7856}
7857
d1133906 7858static const char *
d3ba0551 7859get_symbol_index_type (unsigned int type)
252b5132 7860{
b34976b6 7861 static char buff[32];
5cf1065c 7862
252b5132
RH
7863 switch (type)
7864 {
b34976b6
AM
7865 case SHN_UNDEF: return "UND";
7866 case SHN_ABS: return "ABS";
7867 case SHN_COMMON: return "COM";
252b5132 7868 default:
9ce701e2
L
7869 if (type == SHN_IA_64_ANSI_COMMON
7870 && elf_header.e_machine == EM_IA_64
7871 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
7872 return "ANSI_COM";
8a9036a4
L
7873 else if ((elf_header.e_machine == EM_X86_64
7874 || elf_header.e_machine == EM_L1OM)
3b22753a
L
7875 && type == SHN_X86_64_LCOMMON)
7876 return "LARGE_COM";
172553c7
TS
7877 else if (type == SHN_MIPS_SCOMMON
7878 && elf_header.e_machine == EM_MIPS)
7879 return "SCOM";
7880 else if (type == SHN_MIPS_SUNDEFINED
7881 && elf_header.e_machine == EM_MIPS)
7882 return "SUND";
9ce701e2 7883 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 7884 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 7885 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
7886 sprintf (buff, "OS [0x%04x]", type & 0xffff);
7887 else if (type >= SHN_LORESERVE)
7888 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 7889 else
232e7cb8 7890 sprintf (buff, "%3d", type);
5cf1065c 7891 break;
252b5132 7892 }
5cf1065c
NC
7893
7894 return buff;
252b5132
RH
7895}
7896
66543521 7897static bfd_vma *
2cf0635d 7898get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 7899{
2cf0635d
NC
7900 unsigned char * e_data;
7901 bfd_vma * i_data;
252b5132 7902
3f5e193b 7903 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
7904
7905 if (e_data == NULL)
7906 {
7907 error (_("Out of memory\n"));
7908 return NULL;
7909 }
7910
66543521 7911 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
7912 {
7913 error (_("Unable to read in dynamic data\n"));
7914 return NULL;
7915 }
7916
3f5e193b 7917 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
7918
7919 if (i_data == NULL)
7920 {
7921 error (_("Out of memory\n"));
7922 free (e_data);
7923 return NULL;
7924 }
7925
7926 while (number--)
66543521 7927 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
7928
7929 free (e_data);
7930
7931 return i_data;
7932}
7933
6bd1a22c
L
7934static void
7935print_dynamic_symbol (bfd_vma si, unsigned long hn)
7936{
2cf0635d 7937 Elf_Internal_Sym * psym;
6bd1a22c
L
7938 int n;
7939
7940 psym = dynamic_symbols + si;
7941
7942 n = print_vma (si, DEC_5);
7943 if (n < 5)
7944 fputs (" " + n, stdout);
7945 printf (" %3lu: ", hn);
7946 print_vma (psym->st_value, LONG_HEX);
7947 putchar (' ');
7948 print_vma (psym->st_size, DEC_5);
7949
f4be36b3
AM
7950 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7951 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
7952 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
7953 /* Check to see if any other bits in the st_other field are set.
7954 Note - displaying this information disrupts the layout of the
7955 table being generated, but for the moment this case is very
7956 rare. */
7957 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7958 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
7959 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
7960 if (VALID_DYNAMIC_NAME (psym->st_name))
7961 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
7962 else
7963 printf (" <corrupt: %14ld>", psym->st_name);
7964 putchar ('\n');
7965}
7966
e3c8793a 7967/* Dump the symbol table. */
252b5132 7968static int
2cf0635d 7969process_symbol_table (FILE * file)
252b5132 7970{
2cf0635d 7971 Elf_Internal_Shdr * section;
66543521
AM
7972 bfd_vma nbuckets = 0;
7973 bfd_vma nchains = 0;
2cf0635d
NC
7974 bfd_vma * buckets = NULL;
7975 bfd_vma * chains = NULL;
fdc90cb4 7976 bfd_vma ngnubuckets = 0;
2cf0635d
NC
7977 bfd_vma * gnubuckets = NULL;
7978 bfd_vma * gnuchains = NULL;
6bd1a22c 7979 bfd_vma gnusymidx = 0;
252b5132 7980
2c610e4b 7981 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
7982 return 1;
7983
6bd1a22c
L
7984 if (dynamic_info[DT_HASH]
7985 && (do_histogram
2c610e4b
L
7986 || (do_using_dynamic
7987 && !do_dyn_syms
7988 && dynamic_strings != NULL)))
252b5132 7989 {
66543521
AM
7990 unsigned char nb[8];
7991 unsigned char nc[8];
7992 int hash_ent_size = 4;
7993
7994 if ((elf_header.e_machine == EM_ALPHA
7995 || elf_header.e_machine == EM_S390
7996 || elf_header.e_machine == EM_S390_OLD)
7997 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
7998 hash_ent_size = 8;
7999
fb52b2f4
NC
8000 if (fseek (file,
8001 (archive_file_offset
8002 + offset_from_vma (file, dynamic_info[DT_HASH],
8003 sizeof nb + sizeof nc)),
d93f0186 8004 SEEK_SET))
252b5132 8005 {
591a748a 8006 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8007 goto no_hash;
252b5132
RH
8008 }
8009
66543521 8010 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
8011 {
8012 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8013 goto no_hash;
252b5132
RH
8014 }
8015
66543521 8016 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
8017 {
8018 error (_("Failed to read in number of chains\n"));
d3a44ec6 8019 goto no_hash;
252b5132
RH
8020 }
8021
66543521
AM
8022 nbuckets = byte_get (nb, hash_ent_size);
8023 nchains = byte_get (nc, hash_ent_size);
252b5132 8024
66543521
AM
8025 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
8026 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 8027
d3a44ec6 8028 no_hash:
252b5132 8029 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
8030 {
8031 if (do_using_dynamic)
8032 return 0;
8033 free (buckets);
8034 free (chains);
8035 buckets = NULL;
8036 chains = NULL;
8037 nbuckets = 0;
8038 nchains = 0;
8039 }
252b5132
RH
8040 }
8041
6bd1a22c
L
8042 if (dynamic_info_DT_GNU_HASH
8043 && (do_histogram
2c610e4b
L
8044 || (do_using_dynamic
8045 && !do_dyn_syms
8046 && dynamic_strings != NULL)))
252b5132 8047 {
6bd1a22c
L
8048 unsigned char nb[16];
8049 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
8050 bfd_vma buckets_vma;
8051
8052 if (fseek (file,
8053 (archive_file_offset
8054 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
8055 sizeof nb)),
8056 SEEK_SET))
8057 {
8058 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8059 goto no_gnu_hash;
6bd1a22c 8060 }
252b5132 8061
6bd1a22c
L
8062 if (fread (nb, 16, 1, file) != 1)
8063 {
8064 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8065 goto no_gnu_hash;
6bd1a22c
L
8066 }
8067
8068 ngnubuckets = byte_get (nb, 4);
8069 gnusymidx = byte_get (nb + 4, 4);
8070 bitmaskwords = byte_get (nb + 8, 4);
8071 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 8072 if (is_32bit_elf)
6bd1a22c 8073 buckets_vma += bitmaskwords * 4;
f7a99963 8074 else
6bd1a22c 8075 buckets_vma += bitmaskwords * 8;
252b5132 8076
6bd1a22c
L
8077 if (fseek (file,
8078 (archive_file_offset
8079 + offset_from_vma (file, buckets_vma, 4)),
8080 SEEK_SET))
252b5132 8081 {
6bd1a22c 8082 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8083 goto no_gnu_hash;
6bd1a22c
L
8084 }
8085
8086 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 8087
6bd1a22c 8088 if (gnubuckets == NULL)
d3a44ec6 8089 goto no_gnu_hash;
6bd1a22c
L
8090
8091 for (i = 0; i < ngnubuckets; i++)
8092 if (gnubuckets[i] != 0)
8093 {
8094 if (gnubuckets[i] < gnusymidx)
8095 return 0;
8096
8097 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
8098 maxchain = gnubuckets[i];
8099 }
8100
8101 if (maxchain == 0xffffffff)
d3a44ec6 8102 goto no_gnu_hash;
6bd1a22c
L
8103
8104 maxchain -= gnusymidx;
8105
8106 if (fseek (file,
8107 (archive_file_offset
8108 + offset_from_vma (file, buckets_vma
8109 + 4 * (ngnubuckets + maxchain), 4)),
8110 SEEK_SET))
8111 {
8112 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8113 goto no_gnu_hash;
6bd1a22c
L
8114 }
8115
8116 do
8117 {
8118 if (fread (nb, 4, 1, file) != 1)
252b5132 8119 {
6bd1a22c 8120 error (_("Failed to determine last chain length\n"));
d3a44ec6 8121 goto no_gnu_hash;
6bd1a22c 8122 }
252b5132 8123
6bd1a22c 8124 if (maxchain + 1 == 0)
d3a44ec6 8125 goto no_gnu_hash;
252b5132 8126
6bd1a22c
L
8127 ++maxchain;
8128 }
8129 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 8130
6bd1a22c
L
8131 if (fseek (file,
8132 (archive_file_offset
8133 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
8134 SEEK_SET))
8135 {
8136 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8137 goto no_gnu_hash;
6bd1a22c
L
8138 }
8139
8140 gnuchains = get_dynamic_data (file, maxchain, 4);
8141
d3a44ec6 8142 no_gnu_hash:
6bd1a22c 8143 if (gnuchains == NULL)
d3a44ec6
JJ
8144 {
8145 free (gnubuckets);
d3a44ec6
JJ
8146 gnubuckets = NULL;
8147 ngnubuckets = 0;
f64fddf1
NC
8148 if (do_using_dynamic)
8149 return 0;
d3a44ec6 8150 }
6bd1a22c
L
8151 }
8152
8153 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
8154 && do_syms
8155 && do_using_dynamic
8156 && dynamic_strings != NULL)
8157 {
8158 unsigned long hn;
8159
8160 if (dynamic_info[DT_HASH])
8161 {
8162 bfd_vma si;
8163
8164 printf (_("\nSymbol table for image:\n"));
8165 if (is_32bit_elf)
8166 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8167 else
8168 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8169
8170 for (hn = 0; hn < nbuckets; hn++)
8171 {
8172 if (! buckets[hn])
8173 continue;
8174
8175 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
8176 print_dynamic_symbol (si, hn);
252b5132
RH
8177 }
8178 }
6bd1a22c
L
8179
8180 if (dynamic_info_DT_GNU_HASH)
8181 {
8182 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
8183 if (is_32bit_elf)
8184 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8185 else
8186 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8187
8188 for (hn = 0; hn < ngnubuckets; ++hn)
8189 if (gnubuckets[hn] != 0)
8190 {
8191 bfd_vma si = gnubuckets[hn];
8192 bfd_vma off = si - gnusymidx;
8193
8194 do
8195 {
8196 print_dynamic_symbol (si, hn);
8197 si++;
8198 }
8199 while ((gnuchains[off++] & 1) == 0);
8200 }
8201 }
252b5132 8202 }
2c610e4b 8203 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 8204 {
b34976b6 8205 unsigned int i;
252b5132
RH
8206
8207 for (i = 0, section = section_headers;
8208 i < elf_header.e_shnum;
8209 i++, section++)
8210 {
b34976b6 8211 unsigned int si;
2cf0635d 8212 char * strtab = NULL;
c256ffe7 8213 unsigned long int strtab_size = 0;
2cf0635d
NC
8214 Elf_Internal_Sym * symtab;
8215 Elf_Internal_Sym * psym;
252b5132 8216
2c610e4b
L
8217 if ((section->sh_type != SHT_SYMTAB
8218 && section->sh_type != SHT_DYNSYM)
8219 || (!do_syms
8220 && section->sh_type == SHT_SYMTAB))
252b5132
RH
8221 continue;
8222
8223 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
8224 SECTION_NAME (section),
8225 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 8226 if (is_32bit_elf)
ca47b30c 8227 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 8228 else
ca47b30c 8229 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 8230
9ad5cbcf 8231 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
8232 if (symtab == NULL)
8233 continue;
8234
8235 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
8236 {
8237 strtab = string_table;
8238 strtab_size = string_table_length;
8239 }
4fbb74a6 8240 else if (section->sh_link < elf_header.e_shnum)
252b5132 8241 {
2cf0635d 8242 Elf_Internal_Shdr * string_sec;
252b5132 8243
4fbb74a6 8244 string_sec = section_headers + section->sh_link;
252b5132 8245
3f5e193b
NC
8246 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
8247 1, string_sec->sh_size,
8248 _("string table"));
c256ffe7 8249 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
8250 }
8251
8252 for (si = 0, psym = symtab;
8253 si < section->sh_size / section->sh_entsize;
b34976b6 8254 si++, psym++)
252b5132 8255 {
5e220199 8256 printf ("%6d: ", si);
f7a99963
NC
8257 print_vma (psym->st_value, LONG_HEX);
8258 putchar (' ');
8259 print_vma (psym->st_size, DEC_5);
d1133906
NC
8260 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8261 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 8262 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
8263 /* Check to see if any other bits in the st_other field are set.
8264 Note - displaying this information disrupts the layout of the
8265 table being generated, but for the moment this case is very rare. */
8266 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8267 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 8268 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7
JJ
8269 print_symbol (25, psym->st_name < strtab_size
8270 ? strtab + psym->st_name : "<corrupt>");
252b5132
RH
8271
8272 if (section->sh_type == SHT_DYNSYM &&
b34976b6 8273 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 8274 {
b34976b6
AM
8275 unsigned char data[2];
8276 unsigned short vers_data;
8277 unsigned long offset;
8278 int is_nobits;
8279 int check_def;
252b5132 8280
d93f0186
NC
8281 offset = offset_from_vma
8282 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8283 sizeof data + si * sizeof (vers_data));
252b5132 8284
a6e9f9df 8285 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 8286 sizeof (data), 1, _("version data"));
252b5132
RH
8287
8288 vers_data = byte_get (data, 2);
8289
4fbb74a6
AM
8290 is_nobits = (psym->st_shndx < elf_header.e_shnum
8291 && section_headers[psym->st_shndx].sh_type
c256ffe7 8292 == SHT_NOBITS);
252b5132
RH
8293
8294 check_def = (psym->st_shndx != SHN_UNDEF);
8295
c244d050 8296 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 8297 {
b34976b6 8298 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 8299 && (is_nobits || ! check_def))
252b5132 8300 {
b34976b6
AM
8301 Elf_External_Verneed evn;
8302 Elf_Internal_Verneed ivn;
8303 Elf_Internal_Vernaux ivna;
252b5132
RH
8304
8305 /* We must test both. */
d93f0186
NC
8306 offset = offset_from_vma
8307 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8308 sizeof evn);
252b5132 8309
252b5132
RH
8310 do
8311 {
b34976b6 8312 unsigned long vna_off;
252b5132 8313
c256ffe7 8314 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 8315 _("version need"));
dd27201e
L
8316
8317 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8318 ivn.vn_next = BYTE_GET (evn.vn_next);
8319
252b5132
RH
8320 vna_off = offset + ivn.vn_aux;
8321
8322 do
8323 {
b34976b6 8324 Elf_External_Vernaux evna;
252b5132 8325
a6e9f9df 8326 get_data (&evna, file, vna_off,
c256ffe7 8327 sizeof (evna), 1,
a6e9f9df 8328 _("version need aux (3)"));
252b5132
RH
8329
8330 ivna.vna_other = BYTE_GET (evna.vna_other);
8331 ivna.vna_next = BYTE_GET (evna.vna_next);
8332 ivna.vna_name = BYTE_GET (evna.vna_name);
8333
8334 vna_off += ivna.vna_next;
8335 }
8336 while (ivna.vna_other != vers_data
8337 && ivna.vna_next != 0);
8338
8339 if (ivna.vna_other == vers_data)
8340 break;
8341
8342 offset += ivn.vn_next;
8343 }
8344 while (ivn.vn_next != 0);
8345
8346 if (ivna.vna_other == vers_data)
8347 {
8348 printf ("@%s (%d)",
c256ffe7
JJ
8349 ivna.vna_name < strtab_size
8350 ? strtab + ivna.vna_name : "<corrupt>",
8351 ivna.vna_other);
252b5132
RH
8352 check_def = 0;
8353 }
8354 else if (! is_nobits)
591a748a 8355 error (_("bad dynamic symbol\n"));
252b5132
RH
8356 else
8357 check_def = 1;
8358 }
8359
8360 if (check_def)
8361 {
00d93f34 8362 if (vers_data != 0x8001
b34976b6 8363 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8364 {
b34976b6
AM
8365 Elf_Internal_Verdef ivd;
8366 Elf_Internal_Verdaux ivda;
8367 Elf_External_Verdaux evda;
91d6fa6a 8368 unsigned long off;
252b5132 8369
91d6fa6a 8370 off = offset_from_vma
d93f0186
NC
8371 (file,
8372 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8373 sizeof (Elf_External_Verdef));
252b5132
RH
8374
8375 do
8376 {
b34976b6 8377 Elf_External_Verdef evd;
252b5132 8378
91d6fa6a 8379 get_data (&evd, file, off, sizeof (evd),
c256ffe7 8380 1, _("version def"));
252b5132 8381
b34976b6
AM
8382 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8383 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
8384 ivd.vd_next = BYTE_GET (evd.vd_next);
8385
91d6fa6a 8386 off += ivd.vd_next;
252b5132 8387 }
c244d050 8388 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
8389 && ivd.vd_next != 0);
8390
91d6fa6a
NC
8391 off -= ivd.vd_next;
8392 off += ivd.vd_aux;
252b5132 8393
91d6fa6a 8394 get_data (&evda, file, off, sizeof (evda),
c256ffe7 8395 1, _("version def aux"));
252b5132
RH
8396
8397 ivda.vda_name = BYTE_GET (evda.vda_name);
8398
8399 if (psym->st_name != ivda.vda_name)
c244d050 8400 printf ((vers_data & VERSYM_HIDDEN)
252b5132 8401 ? "@%s" : "@@%s",
c256ffe7
JJ
8402 ivda.vda_name < strtab_size
8403 ? strtab + ivda.vda_name : "<corrupt>");
252b5132
RH
8404 }
8405 }
8406 }
8407 }
8408
8409 putchar ('\n');
8410 }
8411
8412 free (symtab);
8413 if (strtab != string_table)
8414 free (strtab);
8415 }
8416 }
8417 else if (do_syms)
8418 printf
8419 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
8420
8421 if (do_histogram && buckets != NULL)
8422 {
2cf0635d
NC
8423 unsigned long * lengths;
8424 unsigned long * counts;
66543521
AM
8425 unsigned long hn;
8426 bfd_vma si;
8427 unsigned long maxlength = 0;
8428 unsigned long nzero_counts = 0;
8429 unsigned long nsyms = 0;
252b5132 8430
66543521
AM
8431 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
8432 (unsigned long) nbuckets);
252b5132
RH
8433 printf (_(" Length Number %% of total Coverage\n"));
8434
3f5e193b 8435 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
8436 if (lengths == NULL)
8437 {
591a748a 8438 error (_("Out of memory\n"));
252b5132
RH
8439 return 0;
8440 }
8441 for (hn = 0; hn < nbuckets; ++hn)
8442 {
f7a99963 8443 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 8444 {
b34976b6 8445 ++nsyms;
252b5132 8446 if (maxlength < ++lengths[hn])
b34976b6 8447 ++maxlength;
252b5132
RH
8448 }
8449 }
8450
3f5e193b 8451 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
8452 if (counts == NULL)
8453 {
591a748a 8454 error (_("Out of memory\n"));
252b5132
RH
8455 return 0;
8456 }
8457
8458 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 8459 ++counts[lengths[hn]];
252b5132 8460
103f02d3 8461 if (nbuckets > 0)
252b5132 8462 {
66543521
AM
8463 unsigned long i;
8464 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 8465 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 8466 for (i = 1; i <= maxlength; ++i)
103f02d3 8467 {
66543521
AM
8468 nzero_counts += counts[i] * i;
8469 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
8470 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
8471 (nzero_counts * 100.0) / nsyms);
8472 }
252b5132
RH
8473 }
8474
8475 free (counts);
8476 free (lengths);
8477 }
8478
8479 if (buckets != NULL)
8480 {
8481 free (buckets);
8482 free (chains);
8483 }
8484
d3a44ec6 8485 if (do_histogram && gnubuckets != NULL)
fdc90cb4 8486 {
2cf0635d
NC
8487 unsigned long * lengths;
8488 unsigned long * counts;
fdc90cb4
JJ
8489 unsigned long hn;
8490 unsigned long maxlength = 0;
8491 unsigned long nzero_counts = 0;
8492 unsigned long nsyms = 0;
fdc90cb4 8493
3f5e193b 8494 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
8495 if (lengths == NULL)
8496 {
591a748a 8497 error (_("Out of memory\n"));
fdc90cb4
JJ
8498 return 0;
8499 }
8500
8501 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
8502 (unsigned long) ngnubuckets);
8503 printf (_(" Length Number %% of total Coverage\n"));
8504
8505 for (hn = 0; hn < ngnubuckets; ++hn)
8506 if (gnubuckets[hn] != 0)
8507 {
8508 bfd_vma off, length = 1;
8509
6bd1a22c 8510 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
8511 (gnuchains[off] & 1) == 0; ++off)
8512 ++length;
8513 lengths[hn] = length;
8514 if (length > maxlength)
8515 maxlength = length;
8516 nsyms += length;
8517 }
8518
3f5e193b 8519 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
8520 if (counts == NULL)
8521 {
591a748a 8522 error (_("Out of memory\n"));
fdc90cb4
JJ
8523 return 0;
8524 }
8525
8526 for (hn = 0; hn < ngnubuckets; ++hn)
8527 ++counts[lengths[hn]];
8528
8529 if (ngnubuckets > 0)
8530 {
8531 unsigned long j;
8532 printf (" 0 %-10lu (%5.1f%%)\n",
8533 counts[0], (counts[0] * 100.0) / ngnubuckets);
8534 for (j = 1; j <= maxlength; ++j)
8535 {
8536 nzero_counts += counts[j] * j;
8537 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
8538 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
8539 (nzero_counts * 100.0) / nsyms);
8540 }
8541 }
8542
8543 free (counts);
8544 free (lengths);
8545 free (gnubuckets);
8546 free (gnuchains);
8547 }
8548
252b5132
RH
8549 return 1;
8550}
8551
8552static int
2cf0635d 8553process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 8554{
b4c96d0d 8555 unsigned int i;
252b5132
RH
8556
8557 if (dynamic_syminfo == NULL
8558 || !do_dynamic)
8559 /* No syminfo, this is ok. */
8560 return 1;
8561
8562 /* There better should be a dynamic symbol section. */
8563 if (dynamic_symbols == NULL || dynamic_strings == NULL)
8564 return 0;
8565
8566 if (dynamic_addr)
8567 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
8568 dynamic_syminfo_offset, dynamic_syminfo_nent);
8569
8570 printf (_(" Num: Name BoundTo Flags\n"));
8571 for (i = 0; i < dynamic_syminfo_nent; ++i)
8572 {
8573 unsigned short int flags = dynamic_syminfo[i].si_flags;
8574
31104126 8575 printf ("%4d: ", i);
d79b3d50
NC
8576 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
8577 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
8578 else
8579 printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
31104126 8580 putchar (' ');
252b5132
RH
8581
8582 switch (dynamic_syminfo[i].si_boundto)
8583 {
8584 case SYMINFO_BT_SELF:
8585 fputs ("SELF ", stdout);
8586 break;
8587 case SYMINFO_BT_PARENT:
8588 fputs ("PARENT ", stdout);
8589 break;
8590 default:
8591 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
8592 && dynamic_syminfo[i].si_boundto < dynamic_nent
8593 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 8594 {
d79b3d50 8595 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
8596 putchar (' ' );
8597 }
252b5132
RH
8598 else
8599 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
8600 break;
8601 }
8602
8603 if (flags & SYMINFO_FLG_DIRECT)
8604 printf (" DIRECT");
8605 if (flags & SYMINFO_FLG_PASSTHRU)
8606 printf (" PASSTHRU");
8607 if (flags & SYMINFO_FLG_COPY)
8608 printf (" COPY");
8609 if (flags & SYMINFO_FLG_LAZYLOAD)
8610 printf (" LAZYLOAD");
8611
8612 puts ("");
8613 }
8614
8615 return 1;
8616}
8617
cf13d699
NC
8618/* Check to see if the given reloc needs to be handled in a target specific
8619 manner. If so then process the reloc and return TRUE otherwise return
8620 FALSE. */
09c11c86 8621
cf13d699
NC
8622static bfd_boolean
8623target_specific_reloc_handling (Elf_Internal_Rela * reloc,
8624 unsigned char * start,
8625 Elf_Internal_Sym * symtab)
252b5132 8626{
cf13d699 8627 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 8628
cf13d699 8629 switch (elf_header.e_machine)
252b5132 8630 {
cf13d699
NC
8631 case EM_MN10300:
8632 case EM_CYGNUS_MN10300:
8633 {
8634 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 8635
cf13d699
NC
8636 switch (reloc_type)
8637 {
8638 case 34: /* R_MN10300_ALIGN */
8639 return TRUE;
8640 case 33: /* R_MN10300_SYM_DIFF */
8641 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
8642 return TRUE;
8643 case 1: /* R_MN10300_32 */
8644 case 2: /* R_MN10300_16 */
8645 if (saved_sym != NULL)
8646 {
8647 bfd_vma value;
252b5132 8648
cf13d699
NC
8649 value = reloc->r_addend
8650 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
8651 - saved_sym->st_value);
252b5132 8652
cf13d699 8653 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 8654
cf13d699
NC
8655 saved_sym = NULL;
8656 return TRUE;
8657 }
8658 break;
8659 default:
8660 if (saved_sym != NULL)
8661 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
8662 break;
8663 }
8664 break;
8665 }
252b5132
RH
8666 }
8667
cf13d699 8668 return FALSE;
252b5132
RH
8669}
8670
aca88567
NC
8671/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
8672 DWARF debug sections. This is a target specific test. Note - we do not
8673 go through the whole including-target-headers-multiple-times route, (as
8674 we have already done with <elf/h8.h>) because this would become very
8675 messy and even then this function would have to contain target specific
8676 information (the names of the relocs instead of their numeric values).
8677 FIXME: This is not the correct way to solve this problem. The proper way
8678 is to have target specific reloc sizing and typing functions created by
8679 the reloc-macros.h header, in the same way that it already creates the
8680 reloc naming functions. */
8681
8682static bfd_boolean
8683is_32bit_abs_reloc (unsigned int reloc_type)
8684{
8685 switch (elf_header.e_machine)
8686 {
41e92641
NC
8687 case EM_386:
8688 case EM_486:
8689 return reloc_type == 1; /* R_386_32. */
aca88567
NC
8690 case EM_68K:
8691 return reloc_type == 1; /* R_68K_32. */
8692 case EM_860:
8693 return reloc_type == 1; /* R_860_32. */
8694 case EM_ALPHA:
8695 return reloc_type == 1; /* XXX Is this right ? */
41e92641
NC
8696 case EM_ARC:
8697 return reloc_type == 1; /* R_ARC_32. */
8698 case EM_ARM:
8699 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 8700 case EM_AVR_OLD:
aca88567
NC
8701 case EM_AVR:
8702 return reloc_type == 1;
8703 case EM_BLACKFIN:
8704 return reloc_type == 0x12; /* R_byte4_data. */
8705 case EM_CRIS:
8706 return reloc_type == 3; /* R_CRIS_32. */
8707 case EM_CR16:
6c03b1ed 8708 case EM_CR16_OLD:
aca88567
NC
8709 return reloc_type == 3; /* R_CR16_NUM32. */
8710 case EM_CRX:
8711 return reloc_type == 15; /* R_CRX_NUM32. */
8712 case EM_CYGNUS_FRV:
8713 return reloc_type == 1;
41e92641
NC
8714 case EM_CYGNUS_D10V:
8715 case EM_D10V:
8716 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
8717 case EM_CYGNUS_D30V:
8718 case EM_D30V:
8719 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
8720 case EM_DLX:
8721 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
8722 case EM_CYGNUS_FR30:
8723 case EM_FR30:
8724 return reloc_type == 3; /* R_FR30_32. */
8725 case EM_H8S:
8726 case EM_H8_300:
8727 case EM_H8_300H:
8728 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
8729 case EM_IA_64:
8730 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
8731 case EM_IP2K_OLD:
8732 case EM_IP2K:
8733 return reloc_type == 2; /* R_IP2K_32. */
8734 case EM_IQ2000:
8735 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
8736 case EM_LATTICEMICO32:
8737 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 8738 case EM_M32C_OLD:
aca88567
NC
8739 case EM_M32C:
8740 return reloc_type == 3; /* R_M32C_32. */
8741 case EM_M32R:
8742 return reloc_type == 34; /* R_M32R_32_RELA. */
8743 case EM_MCORE:
8744 return reloc_type == 1; /* R_MCORE_ADDR32. */
8745 case EM_CYGNUS_MEP:
8746 return reloc_type == 4; /* R_MEP_32. */
8747 case EM_MIPS:
8748 return reloc_type == 2; /* R_MIPS_32. */
8749 case EM_MMIX:
8750 return reloc_type == 4; /* R_MMIX_32. */
8751 case EM_CYGNUS_MN10200:
8752 case EM_MN10200:
8753 return reloc_type == 1; /* R_MN10200_32. */
8754 case EM_CYGNUS_MN10300:
8755 case EM_MN10300:
8756 return reloc_type == 1; /* R_MN10300_32. */
8757 case EM_MSP430_OLD:
8758 case EM_MSP430:
8759 return reloc_type == 1; /* R_MSP43_32. */
8760 case EM_MT:
8761 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
8762 case EM_ALTERA_NIOS2:
8763 case EM_NIOS32:
8764 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
8765 case EM_OPENRISC:
8766 case EM_OR32:
8767 return reloc_type == 1; /* R_OR32_32. */
aca88567 8768 case EM_PARISC:
5fda8eca
NC
8769 return (reloc_type == 1 /* R_PARISC_DIR32. */
8770 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
8771 case EM_PJ:
8772 case EM_PJ_OLD:
8773 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
8774 case EM_PPC64:
8775 return reloc_type == 1; /* R_PPC64_ADDR32. */
8776 case EM_PPC:
8777 return reloc_type == 1; /* R_PPC_ADDR32. */
c7927a3c
NC
8778 case EM_RX:
8779 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
8780 case EM_S370:
8781 return reloc_type == 1; /* R_I370_ADDR31. */
8782 case EM_S390_OLD:
8783 case EM_S390:
8784 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
8785 case EM_SCORE:
8786 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
8787 case EM_SH:
8788 return reloc_type == 1; /* R_SH_DIR32. */
8789 case EM_SPARC32PLUS:
8790 case EM_SPARCV9:
8791 case EM_SPARC:
8792 return reloc_type == 3 /* R_SPARC_32. */
8793 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
8794 case EM_SPU:
8795 return reloc_type == 6; /* R_SPU_ADDR32 */
aca88567
NC
8796 case EM_CYGNUS_V850:
8797 case EM_V850:
8798 return reloc_type == 6; /* R_V850_ABS32. */
8799 case EM_VAX:
8800 return reloc_type == 1; /* R_VAX_32. */
8801 case EM_X86_64:
8a9036a4 8802 case EM_L1OM:
aca88567 8803 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
8804 case EM_XC16X:
8805 case EM_C166:
8806 return reloc_type == 3; /* R_XC16C_ABS_32. */
aca88567
NC
8807 case EM_XSTORMY16:
8808 return reloc_type == 1; /* R_XSTROMY16_32. */
8809 case EM_XTENSA_OLD:
8810 case EM_XTENSA:
8811 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
8812 default:
8813 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
8814 elf_header.e_machine);
8815 abort ();
8816 }
8817}
8818
8819/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8820 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
8821
8822static bfd_boolean
8823is_32bit_pcrel_reloc (unsigned int reloc_type)
8824{
8825 switch (elf_header.e_machine)
8826 {
41e92641
NC
8827 case EM_386:
8828 case EM_486:
3e0873ac 8829 return reloc_type == 2; /* R_386_PC32. */
aca88567 8830 case EM_68K:
3e0873ac 8831 return reloc_type == 4; /* R_68K_PC32. */
aca88567
NC
8832 case EM_ALPHA:
8833 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 8834 case EM_ARM:
3e0873ac 8835 return reloc_type == 3; /* R_ARM_REL32 */
aca88567 8836 case EM_PARISC:
85acf597 8837 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
8838 case EM_PPC:
8839 return reloc_type == 26; /* R_PPC_REL32. */
8840 case EM_PPC64:
3e0873ac 8841 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
8842 case EM_S390_OLD:
8843 case EM_S390:
3e0873ac 8844 return reloc_type == 5; /* R_390_PC32. */
aca88567 8845 case EM_SH:
3e0873ac 8846 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
8847 case EM_SPARC32PLUS:
8848 case EM_SPARCV9:
8849 case EM_SPARC:
3e0873ac 8850 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
8851 case EM_SPU:
8852 return reloc_type == 13; /* R_SPU_REL32. */
aca88567 8853 case EM_X86_64:
8a9036a4 8854 case EM_L1OM:
3e0873ac 8855 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
8856 case EM_XTENSA_OLD:
8857 case EM_XTENSA:
8858 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
8859 default:
8860 /* Do not abort or issue an error message here. Not all targets use
8861 pc-relative 32-bit relocs in their DWARF debug information and we
8862 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
8863 more helpful warning message will be generated by apply_relocations
8864 anyway, so just return. */
aca88567
NC
8865 return FALSE;
8866 }
8867}
8868
8869/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8870 a 64-bit absolute RELA relocation used in DWARF debug sections. */
8871
8872static bfd_boolean
8873is_64bit_abs_reloc (unsigned int reloc_type)
8874{
8875 switch (elf_header.e_machine)
8876 {
8877 case EM_ALPHA:
8878 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
8879 case EM_IA_64:
8880 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
8881 case EM_PARISC:
8882 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
8883 case EM_PPC64:
8884 return reloc_type == 38; /* R_PPC64_ADDR64. */
8885 case EM_SPARC32PLUS:
8886 case EM_SPARCV9:
8887 case EM_SPARC:
8888 return reloc_type == 54; /* R_SPARC_UA64. */
8889 case EM_X86_64:
8a9036a4 8890 case EM_L1OM:
aca88567 8891 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
8892 case EM_S390_OLD:
8893 case EM_S390:
8894 return reloc_type == 22; /* R_S390_64 */
85a82265
AM
8895 case EM_MIPS:
8896 return reloc_type == 18; /* R_MIPS_64 */
aca88567
NC
8897 default:
8898 return FALSE;
8899 }
8900}
8901
85acf597
RH
8902/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
8903 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
8904
8905static bfd_boolean
8906is_64bit_pcrel_reloc (unsigned int reloc_type)
8907{
8908 switch (elf_header.e_machine)
8909 {
8910 case EM_ALPHA:
8911 return reloc_type == 11; /* R_ALPHA_SREL64 */
8912 case EM_IA_64:
8913 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB */
8914 case EM_PARISC:
8915 return reloc_type == 72; /* R_PARISC_PCREL64 */
8916 case EM_PPC64:
8917 return reloc_type == 44; /* R_PPC64_REL64 */
8918 case EM_SPARC32PLUS:
8919 case EM_SPARCV9:
8920 case EM_SPARC:
8921 return reloc_type == 46; /* R_SPARC_DISP64 */
8922 case EM_X86_64:
8a9036a4 8923 case EM_L1OM:
85acf597
RH
8924 return reloc_type == 24; /* R_X86_64_PC64 */
8925 case EM_S390_OLD:
8926 case EM_S390:
8927 return reloc_type == 23; /* R_S390_PC64 */
8928 default:
8929 return FALSE;
8930 }
8931}
8932
4dc3c23d
AM
8933/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8934 a 24-bit absolute RELA relocation used in DWARF debug sections. */
8935
8936static bfd_boolean
8937is_24bit_abs_reloc (unsigned int reloc_type)
8938{
8939 switch (elf_header.e_machine)
8940 {
8941 case EM_CYGNUS_MN10200:
8942 case EM_MN10200:
8943 return reloc_type == 4; /* R_MN10200_24. */
8944 default:
8945 return FALSE;
8946 }
8947}
8948
aca88567
NC
8949/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8950 a 16-bit absolute RELA relocation used in DWARF debug sections. */
8951
8952static bfd_boolean
8953is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
8954{
8955 switch (elf_header.e_machine)
8956 {
aca88567
NC
8957 case EM_AVR_OLD:
8958 case EM_AVR:
8959 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
8960 case EM_CYGNUS_D10V:
8961 case EM_D10V:
8962 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
8963 case EM_H8S:
8964 case EM_H8_300:
8965 case EM_H8_300H:
aca88567
NC
8966 return reloc_type == R_H8_DIR16;
8967 case EM_IP2K_OLD:
8968 case EM_IP2K:
8969 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 8970 case EM_M32C_OLD:
f4236fe4
DD
8971 case EM_M32C:
8972 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
8973 case EM_MSP430_OLD:
8974 case EM_MSP430:
8975 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
8976 case EM_ALTERA_NIOS2:
8977 case EM_NIOS32:
8978 return reloc_type == 9; /* R_NIOS_16. */
c29aca4a
NC
8979 case EM_XC16X:
8980 case EM_C166:
8981 return reloc_type == 2; /* R_XC16C_ABS_16. */
4b78141a 8982 default:
aca88567 8983 return FALSE;
4b78141a
NC
8984 }
8985}
8986
2a7b2e88
JK
8987/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
8988 relocation entries (possibly formerly used for SHT_GROUP sections). */
8989
8990static bfd_boolean
8991is_none_reloc (unsigned int reloc_type)
8992{
8993 switch (elf_header.e_machine)
8994 {
cb8f3167
NC
8995 case EM_68K: /* R_68K_NONE. */
8996 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
8997 case EM_SPARC32PLUS:
8998 case EM_SPARCV9:
cb8f3167
NC
8999 case EM_SPARC: /* R_SPARC_NONE. */
9000 case EM_MIPS: /* R_MIPS_NONE. */
9001 case EM_PARISC: /* R_PARISC_NONE. */
9002 case EM_ALPHA: /* R_ALPHA_NONE. */
9003 case EM_PPC: /* R_PPC_NONE. */
9004 case EM_PPC64: /* R_PPC64_NONE. */
9005 case EM_ARM: /* R_ARM_NONE. */
9006 case EM_IA_64: /* R_IA64_NONE. */
9007 case EM_SH: /* R_SH_NONE. */
2a7b2e88 9008 case EM_S390_OLD:
cb8f3167
NC
9009 case EM_S390: /* R_390_NONE. */
9010 case EM_CRIS: /* R_CRIS_NONE. */
9011 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 9012 case EM_L1OM: /* R_X86_64_NONE. */
cb8f3167
NC
9013 case EM_MN10300: /* R_MN10300_NONE. */
9014 case EM_M32R: /* R_M32R_NONE. */
c29aca4a
NC
9015 case EM_XC16X:
9016 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 9017 return reloc_type == 0;
58332dda
JK
9018 case EM_XTENSA_OLD:
9019 case EM_XTENSA:
4dc3c23d
AM
9020 return (reloc_type == 0 /* R_XTENSA_NONE. */
9021 || reloc_type == 17 /* R_XTENSA_DIFF8. */
9022 || reloc_type == 18 /* R_XTENSA_DIFF16. */
9023 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
9024 }
9025 return FALSE;
9026}
9027
cf13d699
NC
9028/* Apply relocations to a section.
9029 Note: So far support has been added only for those relocations
9030 which can be found in debug sections.
9031 FIXME: Add support for more relocations ? */
1b315056 9032
cf13d699
NC
9033static void
9034apply_relocations (void * file,
9035 Elf_Internal_Shdr * section,
9036 unsigned char * start)
1b315056 9037{
cf13d699
NC
9038 Elf_Internal_Shdr * relsec;
9039 unsigned char * end = start + section->sh_size;
cb8f3167 9040
cf13d699
NC
9041 if (elf_header.e_type != ET_REL)
9042 return;
1b315056 9043
cf13d699 9044 /* Find the reloc section associated with the section. */
5b18a4bc
NC
9045 for (relsec = section_headers;
9046 relsec < section_headers + elf_header.e_shnum;
9047 ++relsec)
252b5132 9048 {
41e92641
NC
9049 bfd_boolean is_rela;
9050 unsigned long num_relocs;
2cf0635d
NC
9051 Elf_Internal_Rela * relocs;
9052 Elf_Internal_Rela * rp;
9053 Elf_Internal_Shdr * symsec;
9054 Elf_Internal_Sym * symtab;
9055 Elf_Internal_Sym * sym;
252b5132 9056
41e92641 9057 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
9058 || relsec->sh_info >= elf_header.e_shnum
9059 || section_headers + relsec->sh_info != section
c256ffe7 9060 || relsec->sh_size == 0
4fbb74a6 9061 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 9062 continue;
428409d5 9063
41e92641
NC
9064 is_rela = relsec->sh_type == SHT_RELA;
9065
9066 if (is_rela)
9067 {
3f5e193b
NC
9068 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
9069 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
9070 return;
9071 }
9072 else
9073 {
3f5e193b
NC
9074 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
9075 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
9076 return;
9077 }
9078
9079 /* SH uses RELA but uses in place value instead of the addend field. */
9080 if (elf_header.e_machine == EM_SH)
9081 is_rela = FALSE;
428409d5 9082
4fbb74a6 9083 symsec = section_headers + relsec->sh_link;
3f5e193b 9084 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
103f02d3 9085
41e92641 9086 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 9087 {
41e92641
NC
9088 bfd_vma addend;
9089 unsigned int reloc_type;
9090 unsigned int reloc_size;
91d6fa6a 9091 unsigned char * rloc;
4b78141a 9092
aca88567 9093 reloc_type = get_reloc_type (rp->r_info);
41e92641 9094
98fb390a 9095 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 9096 continue;
98fb390a
NC
9097 else if (is_none_reloc (reloc_type))
9098 continue;
9099 else if (is_32bit_abs_reloc (reloc_type)
9100 || is_32bit_pcrel_reloc (reloc_type))
aca88567 9101 reloc_size = 4;
85acf597
RH
9102 else if (is_64bit_abs_reloc (reloc_type)
9103 || is_64bit_pcrel_reloc (reloc_type))
aca88567 9104 reloc_size = 8;
4dc3c23d
AM
9105 else if (is_24bit_abs_reloc (reloc_type))
9106 reloc_size = 3;
aca88567
NC
9107 else if (is_16bit_abs_reloc (reloc_type))
9108 reloc_size = 2;
9109 else
4b78141a 9110 {
41e92641 9111 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 9112 reloc_type, SECTION_NAME (section));
4b78141a
NC
9113 continue;
9114 }
103f02d3 9115
91d6fa6a
NC
9116 rloc = start + rp->r_offset;
9117 if ((rloc + reloc_size) > end)
700dd8b7
L
9118 {
9119 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
9120 (unsigned long) rp->r_offset,
9121 SECTION_NAME (section));
9122 continue;
9123 }
103f02d3 9124
41e92641
NC
9125 sym = symtab + get_reloc_symindex (rp->r_info);
9126
9127 /* If the reloc has a symbol associated with it,
55f25fc3
L
9128 make sure that it is of an appropriate type.
9129
9130 Relocations against symbols without type can happen.
9131 Gcc -feliminate-dwarf2-dups may generate symbols
9132 without type for debug info.
9133
9134 Icc generates relocations against function symbols
9135 instead of local labels.
9136
9137 Relocations against object symbols can happen, eg when
9138 referencing a global array. For an example of this see
9139 the _clz.o binary in libgcc.a. */
aca88567 9140 if (sym != symtab
55f25fc3 9141 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 9142 {
41e92641 9143 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 9144 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 9145 (long int)(rp - relocs),
41e92641 9146 SECTION_NAME (relsec));
aca88567 9147 continue;
5b18a4bc 9148 }
252b5132 9149
4dc3c23d
AM
9150 addend = 0;
9151 if (is_rela)
9152 addend += rp->r_addend;
9153 /* R_XTENSA_32 and R_PJ_DATA_DIR32 are partial_inplace. */
9154 if (!is_rela
9155 || (elf_header.e_machine == EM_XTENSA
9156 && reloc_type == 1)
9157 || ((elf_header.e_machine == EM_PJ
9158 || elf_header.e_machine == EM_PJ_OLD)
9159 && reloc_type == 1))
91d6fa6a 9160 addend += byte_get (rloc, reloc_size);
cb8f3167 9161
85acf597
RH
9162 if (is_32bit_pcrel_reloc (reloc_type)
9163 || is_64bit_pcrel_reloc (reloc_type))
9164 {
9165 /* On HPPA, all pc-relative relocations are biased by 8. */
9166 if (elf_header.e_machine == EM_PARISC)
9167 addend -= 8;
91d6fa6a 9168 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
9169 reloc_size);
9170 }
41e92641 9171 else
91d6fa6a 9172 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 9173 }
252b5132 9174
5b18a4bc 9175 free (symtab);
41e92641 9176 free (relocs);
5b18a4bc
NC
9177 break;
9178 }
5b18a4bc 9179}
103f02d3 9180
cf13d699
NC
9181#ifdef SUPPORT_DISASSEMBLY
9182static int
9183disassemble_section (Elf_Internal_Shdr * section, FILE * file)
9184{
9185 printf (_("\nAssembly dump of section %s\n"),
9186 SECTION_NAME (section));
9187
9188 /* XXX -- to be done --- XXX */
9189
9190 return 1;
9191}
9192#endif
9193
9194/* Reads in the contents of SECTION from FILE, returning a pointer
9195 to a malloc'ed buffer or NULL if something went wrong. */
9196
9197static char *
9198get_section_contents (Elf_Internal_Shdr * section, FILE * file)
9199{
9200 bfd_size_type num_bytes;
9201
9202 num_bytes = section->sh_size;
9203
9204 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
9205 {
9206 printf (_("\nSection '%s' has no data to dump.\n"),
9207 SECTION_NAME (section));
9208 return NULL;
9209 }
9210
3f5e193b
NC
9211 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
9212 _("section contents"));
cf13d699
NC
9213}
9214
9215
9216static void
9217dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
9218{
9219 Elf_Internal_Shdr * relsec;
9220 bfd_size_type num_bytes;
9221 bfd_vma addr;
9222 char * data;
9223 char * end;
9224 char * start;
9225 char * name = SECTION_NAME (section);
9226 bfd_boolean some_strings_shown;
9227
9228 start = get_section_contents (section, file);
9229 if (start == NULL)
9230 return;
9231
9232 printf (_("\nString dump of section '%s':\n"), name);
9233
9234 /* If the section being dumped has relocations against it the user might
9235 be expecting these relocations to have been applied. Check for this
9236 case and issue a warning message in order to avoid confusion.
9237 FIXME: Maybe we ought to have an option that dumps a section with
9238 relocs applied ? */
9239 for (relsec = section_headers;
9240 relsec < section_headers + elf_header.e_shnum;
9241 ++relsec)
9242 {
9243 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
9244 || relsec->sh_info >= elf_header.e_shnum
9245 || section_headers + relsec->sh_info != section
9246 || relsec->sh_size == 0
9247 || relsec->sh_link >= elf_header.e_shnum)
9248 continue;
9249
9250 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
9251 break;
9252 }
9253
9254 num_bytes = section->sh_size;
9255 addr = section->sh_addr;
9256 data = start;
9257 end = start + num_bytes;
9258 some_strings_shown = FALSE;
9259
9260 while (data < end)
9261 {
9262 while (!ISPRINT (* data))
9263 if (++ data >= end)
9264 break;
9265
9266 if (data < end)
9267 {
9268#ifndef __MSVCRT__
c975cc98
NC
9269 /* PR 11128: Use two separate invocations in order to work
9270 around bugs in the Solaris 8 implementation of printf. */
9271 printf (" [%6tx] ", data - start);
9272 printf ("%s\n", data);
cf13d699
NC
9273#else
9274 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
9275#endif
9276 data += strlen (data);
9277 some_strings_shown = TRUE;
9278 }
9279 }
9280
9281 if (! some_strings_shown)
9282 printf (_(" No strings found in this section."));
9283
9284 free (start);
9285
9286 putchar ('\n');
9287}
9288
9289static void
9290dump_section_as_bytes (Elf_Internal_Shdr * section,
9291 FILE * file,
9292 bfd_boolean relocate)
9293{
9294 Elf_Internal_Shdr * relsec;
9295 bfd_size_type bytes;
9296 bfd_vma addr;
9297 unsigned char * data;
9298 unsigned char * start;
9299
9300 start = (unsigned char *) get_section_contents (section, file);
9301 if (start == NULL)
9302 return;
9303
9304 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
9305
9306 if (relocate)
9307 {
9308 apply_relocations (file, section, start);
9309 }
9310 else
9311 {
9312 /* If the section being dumped has relocations against it the user might
9313 be expecting these relocations to have been applied. Check for this
9314 case and issue a warning message in order to avoid confusion.
9315 FIXME: Maybe we ought to have an option that dumps a section with
9316 relocs applied ? */
9317 for (relsec = section_headers;
9318 relsec < section_headers + elf_header.e_shnum;
9319 ++relsec)
9320 {
9321 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
9322 || relsec->sh_info >= elf_header.e_shnum
9323 || section_headers + relsec->sh_info != section
9324 || relsec->sh_size == 0
9325 || relsec->sh_link >= elf_header.e_shnum)
9326 continue;
9327
9328 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
9329 break;
9330 }
9331 }
9332
9333 addr = section->sh_addr;
9334 bytes = section->sh_size;
9335 data = start;
9336
9337 while (bytes)
9338 {
9339 int j;
9340 int k;
9341 int lbytes;
9342
9343 lbytes = (bytes > 16 ? 16 : bytes);
9344
9345 printf (" 0x%8.8lx ", (unsigned long) addr);
9346
9347 for (j = 0; j < 16; j++)
9348 {
9349 if (j < lbytes)
9350 printf ("%2.2x", data[j]);
9351 else
9352 printf (" ");
9353
9354 if ((j & 3) == 3)
9355 printf (" ");
9356 }
9357
9358 for (j = 0; j < lbytes; j++)
9359 {
9360 k = data[j];
9361 if (k >= ' ' && k < 0x7f)
9362 printf ("%c", k);
9363 else
9364 printf (".");
9365 }
9366
9367 putchar ('\n');
9368
9369 data += lbytes;
9370 addr += lbytes;
9371 bytes -= lbytes;
9372 }
9373
9374 free (start);
9375
9376 putchar ('\n');
9377}
9378
9379/* Uncompresses a section that was compressed using zlib, in place.
9380 This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */
9381
9382static int
9383uncompress_section_contents (unsigned char ** buffer, dwarf_size_type * size)
9384{
9385#ifndef HAVE_ZLIB_H
9386 /* These are just to quiet gcc. */
9387 buffer = 0;
9388 size = 0;
9389 return FALSE;
9390#else
9391 dwarf_size_type compressed_size = *size;
9392 unsigned char * compressed_buffer = *buffer;
9393 dwarf_size_type uncompressed_size;
9394 unsigned char * uncompressed_buffer;
9395 z_stream strm;
9396 int rc;
9397 dwarf_size_type header_size = 12;
9398
9399 /* Read the zlib header. In this case, it should be "ZLIB" followed
9400 by the uncompressed section size, 8 bytes in big-endian order. */
9401 if (compressed_size < header_size
9402 || ! streq ((char *) compressed_buffer, "ZLIB"))
9403 return 0;
9404
9405 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
9406 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
9407 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
9408 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
9409 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
9410 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
9411 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
9412 uncompressed_size += compressed_buffer[11];
9413
9414 /* It is possible the section consists of several compressed
9415 buffers concatenated together, so we uncompress in a loop. */
9416 strm.zalloc = NULL;
9417 strm.zfree = NULL;
9418 strm.opaque = NULL;
9419 strm.avail_in = compressed_size - header_size;
9420 strm.next_in = (Bytef *) compressed_buffer + header_size;
9421 strm.avail_out = uncompressed_size;
3f5e193b 9422 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
9423
9424 rc = inflateInit (& strm);
9425 while (strm.avail_in > 0)
9426 {
9427 if (rc != Z_OK)
9428 goto fail;
9429 strm.next_out = ((Bytef *) uncompressed_buffer
9430 + (uncompressed_size - strm.avail_out));
9431 rc = inflate (&strm, Z_FINISH);
9432 if (rc != Z_STREAM_END)
9433 goto fail;
9434 rc = inflateReset (& strm);
9435 }
9436 rc = inflateEnd (& strm);
9437 if (rc != Z_OK
9438 || strm.avail_out != 0)
9439 goto fail;
9440
9441 free (compressed_buffer);
9442 *buffer = uncompressed_buffer;
9443 *size = uncompressed_size;
9444 return 1;
9445
9446 fail:
9447 free (uncompressed_buffer);
9448 return 0;
9449#endif /* HAVE_ZLIB_H */
9450}
9451
d966045b
DJ
9452static int
9453load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 9454 Elf_Internal_Shdr * sec, void * file)
1007acb3 9455{
2cf0635d 9456 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 9457 char buf [64];
1b315056 9458 int section_is_compressed;
1007acb3 9459
19e6b90e
L
9460 /* If it is already loaded, do nothing. */
9461 if (section->start != NULL)
9462 return 1;
1007acb3 9463
a71cc8e0 9464 section_is_compressed = section->name == section->compressed_name;
1007acb3 9465
19e6b90e
L
9466 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
9467 section->address = sec->sh_addr;
9468 section->size = sec->sh_size;
3f5e193b
NC
9469 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
9470 sec->sh_offset, 1,
9471 sec->sh_size, buf);
1b315056
CS
9472 if (section->start == NULL)
9473 return 0;
9474
9475 if (section_is_compressed)
9476 if (! uncompress_section_contents (&section->start, &section->size))
9477 return 0;
1007acb3 9478
19e6b90e 9479 if (debug_displays [debug].relocate)
3f5e193b 9480 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 9481
1b315056 9482 return 1;
1007acb3
L
9483}
9484
d966045b 9485int
2cf0635d 9486load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 9487{
2cf0635d
NC
9488 struct dwarf_section * section = &debug_displays [debug].section;
9489 Elf_Internal_Shdr * sec;
d966045b
DJ
9490
9491 /* Locate the debug section. */
9492 sec = find_section (section->uncompressed_name);
9493 if (sec != NULL)
9494 section->name = section->uncompressed_name;
9495 else
9496 {
9497 sec = find_section (section->compressed_name);
9498 if (sec != NULL)
9499 section->name = section->compressed_name;
9500 }
9501 if (sec == NULL)
9502 return 0;
9503
3f5e193b 9504 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
9505}
9506
19e6b90e
L
9507void
9508free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 9509{
2cf0635d 9510 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 9511
19e6b90e
L
9512 if (section->start == NULL)
9513 return;
1007acb3 9514
19e6b90e
L
9515 free ((char *) section->start);
9516 section->start = NULL;
9517 section->address = 0;
9518 section->size = 0;
1007acb3
L
9519}
9520
1007acb3 9521static int
2cf0635d 9522display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 9523{
2cf0635d 9524 char * name = SECTION_NAME (section);
19e6b90e
L
9525 bfd_size_type length;
9526 int result = 1;
3f5e193b 9527 int i;
1007acb3 9528
19e6b90e
L
9529 length = section->sh_size;
9530 if (length == 0)
1007acb3 9531 {
19e6b90e
L
9532 printf (_("\nSection '%s' has no debugging data.\n"), name);
9533 return 0;
1007acb3 9534 }
5dff79d8
NC
9535 if (section->sh_type == SHT_NOBITS)
9536 {
9537 /* There is no point in dumping the contents of a debugging section
9538 which has the NOBITS type - the bits in the file will be random.
9539 This can happen when a file containing a .eh_frame section is
9540 stripped with the --only-keep-debug command line option. */
9541 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
9542 return 0;
9543 }
1007acb3 9544
0112cd26 9545 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 9546 name = ".debug_info";
1007acb3 9547
19e6b90e
L
9548 /* See if we know how to display the contents of this section. */
9549 for (i = 0; i < max; i++)
1b315056
CS
9550 if (streq (debug_displays[i].section.uncompressed_name, name)
9551 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 9552 {
2cf0635d 9553 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
9554 int secondary = (section != find_section (name));
9555
9556 if (secondary)
3f5e193b 9557 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 9558
2b6f5997 9559 if (streq (sec->uncompressed_name, name))
d966045b
DJ
9560 sec->name = sec->uncompressed_name;
9561 else
9562 sec->name = sec->compressed_name;
3f5e193b
NC
9563 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
9564 section, file))
19e6b90e
L
9565 {
9566 result &= debug_displays[i].display (sec, file);
1007acb3 9567
d966045b 9568 if (secondary || (i != info && i != abbrev))
3f5e193b 9569 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 9570 }
1007acb3 9571
19e6b90e
L
9572 break;
9573 }
1007acb3 9574
19e6b90e 9575 if (i == max)
1007acb3 9576 {
19e6b90e
L
9577 printf (_("Unrecognized debug section: %s\n"), name);
9578 result = 0;
1007acb3
L
9579 }
9580
19e6b90e 9581 return result;
5b18a4bc 9582}
103f02d3 9583
aef1f6d0
DJ
9584/* Set DUMP_SECTS for all sections where dumps were requested
9585 based on section name. */
9586
9587static void
9588initialise_dumps_byname (void)
9589{
2cf0635d 9590 struct dump_list_entry * cur;
aef1f6d0
DJ
9591
9592 for (cur = dump_sects_byname; cur; cur = cur->next)
9593 {
9594 unsigned int i;
9595 int any;
9596
9597 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
9598 if (streq (SECTION_NAME (section_headers + i), cur->name))
9599 {
09c11c86 9600 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
9601 any = 1;
9602 }
9603
9604 if (!any)
9605 warn (_("Section '%s' was not dumped because it does not exist!\n"),
9606 cur->name);
9607 }
9608}
9609
5b18a4bc 9610static void
2cf0635d 9611process_section_contents (FILE * file)
5b18a4bc 9612{
2cf0635d 9613 Elf_Internal_Shdr * section;
19e6b90e 9614 unsigned int i;
103f02d3 9615
19e6b90e
L
9616 if (! do_dump)
9617 return;
103f02d3 9618
aef1f6d0
DJ
9619 initialise_dumps_byname ();
9620
19e6b90e
L
9621 for (i = 0, section = section_headers;
9622 i < elf_header.e_shnum && i < num_dump_sects;
9623 i++, section++)
9624 {
9625#ifdef SUPPORT_DISASSEMBLY
9626 if (dump_sects[i] & DISASS_DUMP)
9627 disassemble_section (section, file);
9628#endif
9629 if (dump_sects[i] & HEX_DUMP)
cf13d699 9630 dump_section_as_bytes (section, file, FALSE);
103f02d3 9631
cf13d699
NC
9632 if (dump_sects[i] & RELOC_DUMP)
9633 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
9634
9635 if (dump_sects[i] & STRING_DUMP)
9636 dump_section_as_strings (section, file);
cf13d699
NC
9637
9638 if (dump_sects[i] & DEBUG_DUMP)
9639 display_debug_section (section, file);
5b18a4bc 9640 }
103f02d3 9641
19e6b90e
L
9642 /* Check to see if the user requested a
9643 dump of a section that does not exist. */
9644 while (i++ < num_dump_sects)
9645 if (dump_sects[i])
9646 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 9647}
103f02d3 9648
5b18a4bc 9649static void
19e6b90e 9650process_mips_fpe_exception (int mask)
5b18a4bc 9651{
19e6b90e
L
9652 if (mask)
9653 {
9654 int first = 1;
9655 if (mask & OEX_FPU_INEX)
9656 fputs ("INEX", stdout), first = 0;
9657 if (mask & OEX_FPU_UFLO)
9658 printf ("%sUFLO", first ? "" : "|"), first = 0;
9659 if (mask & OEX_FPU_OFLO)
9660 printf ("%sOFLO", first ? "" : "|"), first = 0;
9661 if (mask & OEX_FPU_DIV0)
9662 printf ("%sDIV0", first ? "" : "|"), first = 0;
9663 if (mask & OEX_FPU_INVAL)
9664 printf ("%sINVAL", first ? "" : "|");
9665 }
5b18a4bc 9666 else
19e6b90e 9667 fputs ("0", stdout);
5b18a4bc 9668}
103f02d3 9669
11c1ff18
PB
9670/* ARM EABI attributes section. */
9671typedef struct
9672{
9673 int tag;
2cf0635d 9674 const char * name;
11c1ff18
PB
9675 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
9676 int type;
2cf0635d 9677 const char ** table;
11c1ff18
PB
9678} arm_attr_public_tag;
9679
2cf0635d 9680static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 9681 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
9e3c6df6 9682 "v6K", "v7", "v6-M", "v6S-M", "v7E-M"};
2cf0635d
NC
9683static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
9684static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 9685 {"No", "Thumb-1", "Thumb-2"};
2cf0635d 9686static const char * arm_attr_tag_VFP_arch[] =
62f3b8c8 9687 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
2cf0635d 9688static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
cd21e546
MGD
9689static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9690 {"No", "NEONv1", "NEONv1 with Fused-MAC"};
2cf0635d 9691static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
9692 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
9693 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 9694static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 9695 {"V6", "SB", "TLS", "Unused"};
2cf0635d 9696static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 9697 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 9698static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 9699 {"Absolute", "PC-relative", "None"};
2cf0635d 9700static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 9701 {"None", "direct", "GOT-indirect"};
2cf0635d 9702static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 9703 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
9704static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
9705static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 9706 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
9707static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
9708static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
9709static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 9710 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d
NC
9711static const char * arm_attr_tag_ABI_align8_needed[] = {"No", "Yes", "4-byte"};
9712static const char * arm_attr_tag_ABI_align8_preserved[] =
11c1ff18 9713 {"No", "Yes, except leaf SP", "Yes"};
2cf0635d 9714static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 9715 {"Unused", "small", "int", "forced to int"};
2cf0635d 9716static const char * arm_attr_tag_ABI_HardFP_use[] =
11c1ff18 9717 {"As Tag_VFP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 9718static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 9719 {"AAPCS", "VFP registers", "custom"};
2cf0635d 9720static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 9721 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 9722static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
9723 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
9724 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 9725static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
9726 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
9727 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d
NC
9728static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
9729static const char * arm_attr_tag_VFP_HP_extension[] =
8e79c3df 9730 {"Not Allowed", "Allowed"};
2cf0635d 9731static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 9732 {"None", "IEEE 754", "Alternative Format"};
cd21e546
MGD
9733static const char * arm_attr_tag_MPextension_use[] =
9734 {"Not Allowed", "Allowed"};
9735static const char * arm_attr_tag_DIV_use[] =
9736 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
9737 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
9738static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
9739static const char * arm_attr_tag_Virtualization_use[] =
cd21e546
MGD
9740 {"Not Allowed", "TrustZone", "Virtualization Extensions",
9741 "TrustZone and Virtualization Extensions"};
9742static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 9743 {"Not Allowed", "Allowed"};
11c1ff18
PB
9744
9745#define LOOKUP(id, name) \
9746 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 9747static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
9748{
9749 {4, "CPU_raw_name", 1, NULL},
9750 {5, "CPU_name", 1, NULL},
9751 LOOKUP(6, CPU_arch),
9752 {7, "CPU_arch_profile", 0, NULL},
9753 LOOKUP(8, ARM_ISA_use),
9754 LOOKUP(9, THUMB_ISA_use),
9755 LOOKUP(10, VFP_arch),
9756 LOOKUP(11, WMMX_arch),
f5f53991
AS
9757 LOOKUP(12, Advanced_SIMD_arch),
9758 LOOKUP(13, PCS_config),
11c1ff18
PB
9759 LOOKUP(14, ABI_PCS_R9_use),
9760 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 9761 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
9762 LOOKUP(17, ABI_PCS_GOT_use),
9763 LOOKUP(18, ABI_PCS_wchar_t),
9764 LOOKUP(19, ABI_FP_rounding),
9765 LOOKUP(20, ABI_FP_denormal),
9766 LOOKUP(21, ABI_FP_exceptions),
9767 LOOKUP(22, ABI_FP_user_exceptions),
9768 LOOKUP(23, ABI_FP_number_model),
9769 LOOKUP(24, ABI_align8_needed),
9770 LOOKUP(25, ABI_align8_preserved),
9771 LOOKUP(26, ABI_enum_size),
9772 LOOKUP(27, ABI_HardFP_use),
9773 LOOKUP(28, ABI_VFP_args),
9774 LOOKUP(29, ABI_WMMX_args),
9775 LOOKUP(30, ABI_optimization_goals),
9776 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 9777 {32, "compatibility", 0, NULL},
f5f53991 9778 LOOKUP(34, CPU_unaligned_access),
8e79c3df
CM
9779 LOOKUP(36, VFP_HP_extension),
9780 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
9781 LOOKUP(42, MPextension_use),
9782 LOOKUP(44, DIV_use),
f5f53991
AS
9783 {64, "nodefaults", 0, NULL},
9784 {65, "also_compatible_with", 0, NULL},
9785 LOOKUP(66, T2EE_use),
9786 {67, "conformance", 1, NULL},
9787 LOOKUP(68, Virtualization_use),
cd21e546 9788 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
9789};
9790#undef LOOKUP
9791
11c1ff18 9792static unsigned char *
2cf0635d 9793display_arm_attribute (unsigned char * p)
11c1ff18
PB
9794{
9795 int tag;
9796 unsigned int len;
9797 int val;
2cf0635d 9798 arm_attr_public_tag * attr;
11c1ff18
PB
9799 unsigned i;
9800 int type;
9801
9802 tag = read_uleb128 (p, &len);
9803 p += len;
9804 attr = NULL;
2cf0635d 9805 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
9806 {
9807 if (arm_attr_public_tags[i].tag == tag)
9808 {
9809 attr = &arm_attr_public_tags[i];
9810 break;
9811 }
9812 }
9813
9814 if (attr)
9815 {
9816 printf (" Tag_%s: ", attr->name);
9817 switch (attr->type)
9818 {
9819 case 0:
9820 switch (tag)
9821 {
9822 case 7: /* Tag_CPU_arch_profile. */
9823 val = read_uleb128 (p, &len);
9824 p += len;
9825 switch (val)
9826 {
9827 case 0: printf ("None\n"); break;
9828 case 'A': printf ("Application\n"); break;
9829 case 'R': printf ("Realtime\n"); break;
9830 case 'M': printf ("Microcontroller\n"); break;
9831 default: printf ("??? (%d)\n", val); break;
9832 }
9833 break;
9834
9835 case 32: /* Tag_compatibility. */
9836 val = read_uleb128 (p, &len);
9837 p += len;
9838 printf ("flag = %d, vendor = %s\n", val, p);
2cf0635d 9839 p += strlen ((char *) p) + 1;
11c1ff18
PB
9840 break;
9841
f5f53991
AS
9842 case 64: /* Tag_nodefaults. */
9843 p++;
9844 printf ("True\n");
9845 break;
9846
9847 case 65: /* Tag_also_compatible_with. */
9848 val = read_uleb128 (p, &len);
9849 p += len;
9850 if (val == 6 /* Tag_CPU_arch. */)
9851 {
9852 val = read_uleb128 (p, &len);
9853 p += len;
2cf0635d 9854 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
9855 printf ("??? (%d)\n", val);
9856 else
9857 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
9858 }
9859 else
9860 printf ("???\n");
9861 while (*(p++) != '\0' /* NUL terminator. */);
9862 break;
9863
11c1ff18 9864 default:
2cf0635d 9865 abort ();
11c1ff18
PB
9866 }
9867 return p;
9868
9869 case 1:
9870 case 2:
9871 type = attr->type;
9872 break;
9873
9874 default:
9875 assert (attr->type & 0x80);
9876 val = read_uleb128 (p, &len);
9877 p += len;
9878 type = attr->type & 0x7f;
9879 if (val >= type)
9880 printf ("??? (%d)\n", val);
9881 else
9882 printf ("%s\n", attr->table[val]);
9883 return p;
9884 }
9885 }
9886 else
9887 {
9888 if (tag & 1)
9889 type = 1; /* String. */
9890 else
9891 type = 2; /* uleb128. */
9892 printf (" Tag_unknown_%d: ", tag);
9893 }
9894
9895 if (type == 1)
9896 {
9897 printf ("\"%s\"\n", p);
2cf0635d 9898 p += strlen ((char *) p) + 1;
11c1ff18
PB
9899 }
9900 else
9901 {
9902 val = read_uleb128 (p, &len);
9903 p += len;
9904 printf ("%d (0x%x)\n", val, val);
9905 }
9906
9907 return p;
9908}
9909
104d59d1 9910static unsigned char *
60bca95a
NC
9911display_gnu_attribute (unsigned char * p,
9912 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
9913{
9914 int tag;
9915 unsigned int len;
9916 int val;
9917 int type;
9918
9919 tag = read_uleb128 (p, &len);
9920 p += len;
9921
9922 /* Tag_compatibility is the only generic GNU attribute defined at
9923 present. */
9924 if (tag == 32)
9925 {
9926 val = read_uleb128 (p, &len);
9927 p += len;
9928 printf ("flag = %d, vendor = %s\n", val, p);
60bca95a 9929 p += strlen ((char *) p) + 1;
104d59d1
JM
9930 return p;
9931 }
9932
9933 if ((tag & 2) == 0 && display_proc_gnu_attribute)
9934 return display_proc_gnu_attribute (p, tag);
9935
9936 if (tag & 1)
9937 type = 1; /* String. */
9938 else
9939 type = 2; /* uleb128. */
9940 printf (" Tag_unknown_%d: ", tag);
9941
9942 if (type == 1)
9943 {
9944 printf ("\"%s\"\n", p);
60bca95a 9945 p += strlen ((char *) p) + 1;
104d59d1
JM
9946 }
9947 else
9948 {
9949 val = read_uleb128 (p, &len);
9950 p += len;
9951 printf ("%d (0x%x)\n", val, val);
9952 }
9953
9954 return p;
9955}
9956
34c8bcba 9957static unsigned char *
2cf0635d 9958display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
9959{
9960 int type;
9961 unsigned int len;
9962 int val;
9963
9964 if (tag == Tag_GNU_Power_ABI_FP)
9965 {
9966 val = read_uleb128 (p, &len);
9967 p += len;
9968 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 9969
34c8bcba
JM
9970 switch (val)
9971 {
9972 case 0:
9973 printf ("Hard or soft float\n");
9974 break;
9975 case 1:
9976 printf ("Hard float\n");
9977 break;
9978 case 2:
9979 printf ("Soft float\n");
9980 break;
3c7b9897
AM
9981 case 3:
9982 printf ("Single-precision hard float\n");
9983 break;
34c8bcba
JM
9984 default:
9985 printf ("??? (%d)\n", val);
9986 break;
9987 }
9988 return p;
9989 }
9990
c6e65352
DJ
9991 if (tag == Tag_GNU_Power_ABI_Vector)
9992 {
9993 val = read_uleb128 (p, &len);
9994 p += len;
9995 printf (" Tag_GNU_Power_ABI_Vector: ");
9996 switch (val)
9997 {
9998 case 0:
9999 printf ("Any\n");
10000 break;
10001 case 1:
10002 printf ("Generic\n");
10003 break;
10004 case 2:
10005 printf ("AltiVec\n");
10006 break;
10007 case 3:
10008 printf ("SPE\n");
10009 break;
10010 default:
10011 printf ("??? (%d)\n", val);
10012 break;
10013 }
10014 return p;
10015 }
10016
f82e0623
NF
10017 if (tag == Tag_GNU_Power_ABI_Struct_Return)
10018 {
10019 val = read_uleb128 (p, &len);
10020 p += len;
10021 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
10022 switch (val)
10023 {
10024 case 0:
10025 printf ("Any\n");
10026 break;
10027 case 1:
10028 printf ("r3/r4\n");
10029 break;
10030 case 2:
10031 printf ("Memory\n");
10032 break;
10033 default:
10034 printf ("??? (%d)\n", val);
10035 break;
10036 }
10037 return p;
10038 }
10039
34c8bcba
JM
10040 if (tag & 1)
10041 type = 1; /* String. */
10042 else
10043 type = 2; /* uleb128. */
10044 printf (" Tag_unknown_%d: ", tag);
10045
10046 if (type == 1)
10047 {
10048 printf ("\"%s\"\n", p);
60bca95a 10049 p += strlen ((char *) p) + 1;
34c8bcba
JM
10050 }
10051 else
10052 {
10053 val = read_uleb128 (p, &len);
10054 p += len;
10055 printf ("%d (0x%x)\n", val, val);
10056 }
10057
10058 return p;
10059}
10060
2cf19d5c 10061static unsigned char *
2cf0635d 10062display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
10063{
10064 int type;
10065 unsigned int len;
10066 int val;
10067
10068 if (tag == Tag_GNU_MIPS_ABI_FP)
10069 {
10070 val = read_uleb128 (p, &len);
10071 p += len;
10072 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 10073
2cf19d5c
JM
10074 switch (val)
10075 {
10076 case 0:
10077 printf ("Hard or soft float\n");
10078 break;
10079 case 1:
10080 printf ("Hard float (-mdouble-float)\n");
10081 break;
10082 case 2:
10083 printf ("Hard float (-msingle-float)\n");
10084 break;
10085 case 3:
10086 printf ("Soft float\n");
10087 break;
42554f6a
TS
10088 case 4:
10089 printf ("64-bit float (-mips32r2 -mfp64)\n");
10090 break;
2cf19d5c
JM
10091 default:
10092 printf ("??? (%d)\n", val);
10093 break;
10094 }
10095 return p;
10096 }
10097
10098 if (tag & 1)
10099 type = 1; /* String. */
10100 else
10101 type = 2; /* uleb128. */
10102 printf (" Tag_unknown_%d: ", tag);
10103
10104 if (type == 1)
10105 {
10106 printf ("\"%s\"\n", p);
60bca95a 10107 p += strlen ((char *) p) + 1;
2cf19d5c
JM
10108 }
10109 else
10110 {
10111 val = read_uleb128 (p, &len);
10112 p += len;
10113 printf ("%d (0x%x)\n", val, val);
10114 }
10115
10116 return p;
10117}
10118
11c1ff18 10119static int
60bca95a
NC
10120process_attributes (FILE * file,
10121 const char * public_name,
104d59d1 10122 unsigned int proc_type,
60bca95a
NC
10123 unsigned char * (* display_pub_attribute) (unsigned char *),
10124 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 10125{
2cf0635d
NC
10126 Elf_Internal_Shdr * sect;
10127 unsigned char * contents;
10128 unsigned char * p;
10129 unsigned char * end;
11c1ff18
PB
10130 bfd_vma section_len;
10131 bfd_vma len;
10132 unsigned i;
10133
10134 /* Find the section header so that we get the size. */
10135 for (i = 0, sect = section_headers;
10136 i < elf_header.e_shnum;
10137 i++, sect++)
10138 {
104d59d1 10139 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
10140 continue;
10141
3f5e193b
NC
10142 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
10143 sect->sh_size, _("attributes"));
60bca95a 10144 if (contents == NULL)
11c1ff18 10145 continue;
60bca95a 10146
11c1ff18
PB
10147 p = contents;
10148 if (*p == 'A')
10149 {
10150 len = sect->sh_size - 1;
10151 p++;
60bca95a 10152
11c1ff18
PB
10153 while (len > 0)
10154 {
10155 int namelen;
10156 bfd_boolean public_section;
104d59d1 10157 bfd_boolean gnu_section;
11c1ff18
PB
10158
10159 section_len = byte_get (p, 4);
10160 p += 4;
60bca95a 10161
11c1ff18
PB
10162 if (section_len > len)
10163 {
10164 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 10165 (int) section_len, (int) len);
11c1ff18
PB
10166 section_len = len;
10167 }
60bca95a 10168
11c1ff18
PB
10169 len -= section_len;
10170 printf ("Attribute Section: %s\n", p);
60bca95a
NC
10171
10172 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
10173 public_section = TRUE;
10174 else
10175 public_section = FALSE;
60bca95a
NC
10176
10177 if (streq ((char *) p, "gnu"))
104d59d1
JM
10178 gnu_section = TRUE;
10179 else
10180 gnu_section = FALSE;
60bca95a
NC
10181
10182 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
10183 p += namelen;
10184 section_len -= namelen + 4;
60bca95a 10185
11c1ff18
PB
10186 while (section_len > 0)
10187 {
10188 int tag = *(p++);
10189 int val;
10190 bfd_vma size;
60bca95a 10191
11c1ff18
PB
10192 size = byte_get (p, 4);
10193 if (size > section_len)
10194 {
10195 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 10196 (int) size, (int) section_len);
11c1ff18
PB
10197 size = section_len;
10198 }
60bca95a 10199
11c1ff18
PB
10200 section_len -= size;
10201 end = p + size - 1;
10202 p += 4;
60bca95a 10203
11c1ff18
PB
10204 switch (tag)
10205 {
10206 case 1:
10207 printf ("File Attributes\n");
10208 break;
10209 case 2:
10210 printf ("Section Attributes:");
10211 goto do_numlist;
10212 case 3:
10213 printf ("Symbol Attributes:");
10214 do_numlist:
10215 for (;;)
10216 {
91d6fa6a 10217 unsigned int j;
60bca95a 10218
91d6fa6a
NC
10219 val = read_uleb128 (p, &j);
10220 p += j;
11c1ff18
PB
10221 if (val == 0)
10222 break;
10223 printf (" %d", val);
10224 }
10225 printf ("\n");
10226 break;
10227 default:
10228 printf ("Unknown tag: %d\n", tag);
10229 public_section = FALSE;
10230 break;
10231 }
60bca95a 10232
11c1ff18
PB
10233 if (public_section)
10234 {
10235 while (p < end)
104d59d1
JM
10236 p = display_pub_attribute (p);
10237 }
10238 else if (gnu_section)
10239 {
10240 while (p < end)
10241 p = display_gnu_attribute (p,
10242 display_proc_gnu_attribute);
11c1ff18
PB
10243 }
10244 else
10245 {
10246 /* ??? Do something sensible, like dump hex. */
10247 printf (" Unknown section contexts\n");
10248 p = end;
10249 }
10250 }
10251 }
10252 }
10253 else
60bca95a 10254 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 10255
60bca95a 10256 free (contents);
11c1ff18
PB
10257 }
10258 return 1;
10259}
10260
104d59d1 10261static int
2cf0635d 10262process_arm_specific (FILE * file)
104d59d1
JM
10263{
10264 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
10265 display_arm_attribute, NULL);
10266}
10267
34c8bcba 10268static int
2cf0635d 10269process_power_specific (FILE * file)
34c8bcba
JM
10270{
10271 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
10272 display_power_gnu_attribute);
10273}
10274
ccb4c951
RS
10275/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
10276 Print the Address, Access and Initial fields of an entry at VMA ADDR
10277 and return the VMA of the next entry. */
10278
10279static bfd_vma
2cf0635d 10280print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
10281{
10282 printf (" ");
10283 print_vma (addr, LONG_HEX);
10284 printf (" ");
10285 if (addr < pltgot + 0xfff0)
10286 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
10287 else
10288 printf ("%10s", "");
10289 printf (" ");
10290 if (data == NULL)
10291 printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
10292 else
10293 {
10294 bfd_vma entry;
10295
10296 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
10297 print_vma (entry, LONG_HEX);
10298 }
10299 return addr + (is_32bit_elf ? 4 : 8);
10300}
10301
861fb55a
DJ
10302/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
10303 PLTGOT. Print the Address and Initial fields of an entry at VMA
10304 ADDR and return the VMA of the next entry. */
10305
10306static bfd_vma
2cf0635d 10307print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
10308{
10309 printf (" ");
10310 print_vma (addr, LONG_HEX);
10311 printf (" ");
10312 if (data == NULL)
10313 printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
10314 else
10315 {
10316 bfd_vma entry;
10317
10318 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
10319 print_vma (entry, LONG_HEX);
10320 }
10321 return addr + (is_32bit_elf ? 4 : 8);
10322}
10323
19e6b90e 10324static int
2cf0635d 10325process_mips_specific (FILE * file)
5b18a4bc 10326{
2cf0635d 10327 Elf_Internal_Dyn * entry;
19e6b90e
L
10328 size_t liblist_offset = 0;
10329 size_t liblistno = 0;
10330 size_t conflictsno = 0;
10331 size_t options_offset = 0;
10332 size_t conflicts_offset = 0;
861fb55a
DJ
10333 size_t pltrelsz = 0;
10334 size_t pltrel = 0;
ccb4c951 10335 bfd_vma pltgot = 0;
861fb55a
DJ
10336 bfd_vma mips_pltgot = 0;
10337 bfd_vma jmprel = 0;
ccb4c951
RS
10338 bfd_vma local_gotno = 0;
10339 bfd_vma gotsym = 0;
10340 bfd_vma symtabno = 0;
103f02d3 10341
2cf19d5c
JM
10342 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
10343 display_mips_gnu_attribute);
10344
19e6b90e
L
10345 /* We have a lot of special sections. Thanks SGI! */
10346 if (dynamic_section == NULL)
10347 /* No information available. */
10348 return 0;
252b5132 10349
b2d38a17 10350 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
10351 switch (entry->d_tag)
10352 {
10353 case DT_MIPS_LIBLIST:
d93f0186
NC
10354 liblist_offset
10355 = offset_from_vma (file, entry->d_un.d_val,
10356 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
10357 break;
10358 case DT_MIPS_LIBLISTNO:
10359 liblistno = entry->d_un.d_val;
10360 break;
10361 case DT_MIPS_OPTIONS:
d93f0186 10362 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
10363 break;
10364 case DT_MIPS_CONFLICT:
d93f0186
NC
10365 conflicts_offset
10366 = offset_from_vma (file, entry->d_un.d_val,
10367 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
10368 break;
10369 case DT_MIPS_CONFLICTNO:
10370 conflictsno = entry->d_un.d_val;
10371 break;
ccb4c951 10372 case DT_PLTGOT:
861fb55a
DJ
10373 pltgot = entry->d_un.d_ptr;
10374 break;
ccb4c951
RS
10375 case DT_MIPS_LOCAL_GOTNO:
10376 local_gotno = entry->d_un.d_val;
10377 break;
10378 case DT_MIPS_GOTSYM:
10379 gotsym = entry->d_un.d_val;
10380 break;
10381 case DT_MIPS_SYMTABNO:
10382 symtabno = entry->d_un.d_val;
10383 break;
861fb55a
DJ
10384 case DT_MIPS_PLTGOT:
10385 mips_pltgot = entry->d_un.d_ptr;
10386 break;
10387 case DT_PLTREL:
10388 pltrel = entry->d_un.d_val;
10389 break;
10390 case DT_PLTRELSZ:
10391 pltrelsz = entry->d_un.d_val;
10392 break;
10393 case DT_JMPREL:
10394 jmprel = entry->d_un.d_ptr;
10395 break;
252b5132
RH
10396 default:
10397 break;
10398 }
10399
10400 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
10401 {
2cf0635d 10402 Elf32_External_Lib * elib;
252b5132
RH
10403 size_t cnt;
10404
3f5e193b
NC
10405 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
10406 liblistno,
10407 sizeof (Elf32_External_Lib),
10408 _("liblist"));
a6e9f9df 10409 if (elib)
252b5132 10410 {
a6e9f9df
AM
10411 printf ("\nSection '.liblist' contains %lu entries:\n",
10412 (unsigned long) liblistno);
10413 fputs (" Library Time Stamp Checksum Version Flags\n",
10414 stdout);
10415
10416 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 10417 {
a6e9f9df 10418 Elf32_Lib liblist;
91d6fa6a 10419 time_t atime;
a6e9f9df 10420 char timebuf[20];
2cf0635d 10421 struct tm * tmp;
a6e9f9df
AM
10422
10423 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 10424 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
10425 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10426 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10427 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10428
91d6fa6a 10429 tmp = gmtime (&atime);
e9e44622
JJ
10430 snprintf (timebuf, sizeof (timebuf),
10431 "%04u-%02u-%02uT%02u:%02u:%02u",
10432 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10433 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 10434
31104126 10435 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
10436 if (VALID_DYNAMIC_NAME (liblist.l_name))
10437 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
10438 else
10439 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
10440 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
10441 liblist.l_version);
a6e9f9df
AM
10442
10443 if (liblist.l_flags == 0)
10444 puts (" NONE");
10445 else
10446 {
10447 static const struct
252b5132 10448 {
2cf0635d 10449 const char * name;
a6e9f9df 10450 int bit;
252b5132 10451 }
a6e9f9df
AM
10452 l_flags_vals[] =
10453 {
10454 { " EXACT_MATCH", LL_EXACT_MATCH },
10455 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
10456 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
10457 { " EXPORTS", LL_EXPORTS },
10458 { " DELAY_LOAD", LL_DELAY_LOAD },
10459 { " DELTA", LL_DELTA }
10460 };
10461 int flags = liblist.l_flags;
10462 size_t fcnt;
10463
60bca95a 10464 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
10465 if ((flags & l_flags_vals[fcnt].bit) != 0)
10466 {
10467 fputs (l_flags_vals[fcnt].name, stdout);
10468 flags ^= l_flags_vals[fcnt].bit;
10469 }
10470 if (flags != 0)
10471 printf (" %#x", (unsigned int) flags);
252b5132 10472
a6e9f9df
AM
10473 puts ("");
10474 }
252b5132 10475 }
252b5132 10476
a6e9f9df
AM
10477 free (elib);
10478 }
252b5132
RH
10479 }
10480
10481 if (options_offset != 0)
10482 {
2cf0635d
NC
10483 Elf_External_Options * eopt;
10484 Elf_Internal_Shdr * sect = section_headers;
10485 Elf_Internal_Options * iopt;
10486 Elf_Internal_Options * option;
252b5132
RH
10487 size_t offset;
10488 int cnt;
10489
10490 /* Find the section header so that we get the size. */
10491 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 10492 ++sect;
252b5132 10493
3f5e193b
NC
10494 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
10495 sect->sh_size, _("options"));
a6e9f9df 10496 if (eopt)
252b5132 10497 {
3f5e193b
NC
10498 iopt = (Elf_Internal_Options *)
10499 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
10500 if (iopt == NULL)
10501 {
591a748a 10502 error (_("Out of memory\n"));
a6e9f9df
AM
10503 return 0;
10504 }
76da6bbe 10505
a6e9f9df
AM
10506 offset = cnt = 0;
10507 option = iopt;
252b5132 10508
a6e9f9df
AM
10509 while (offset < sect->sh_size)
10510 {
2cf0635d 10511 Elf_External_Options * eoption;
252b5132 10512
a6e9f9df 10513 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 10514
a6e9f9df
AM
10515 option->kind = BYTE_GET (eoption->kind);
10516 option->size = BYTE_GET (eoption->size);
10517 option->section = BYTE_GET (eoption->section);
10518 option->info = BYTE_GET (eoption->info);
76da6bbe 10519
a6e9f9df 10520 offset += option->size;
252b5132 10521
a6e9f9df
AM
10522 ++option;
10523 ++cnt;
10524 }
252b5132 10525
a6e9f9df
AM
10526 printf (_("\nSection '%s' contains %d entries:\n"),
10527 SECTION_NAME (sect), cnt);
76da6bbe 10528
a6e9f9df 10529 option = iopt;
252b5132 10530
a6e9f9df 10531 while (cnt-- > 0)
252b5132 10532 {
a6e9f9df
AM
10533 size_t len;
10534
10535 switch (option->kind)
252b5132 10536 {
a6e9f9df
AM
10537 case ODK_NULL:
10538 /* This shouldn't happen. */
10539 printf (" NULL %d %lx", option->section, option->info);
10540 break;
10541 case ODK_REGINFO:
10542 printf (" REGINFO ");
10543 if (elf_header.e_machine == EM_MIPS)
10544 {
10545 /* 32bit form. */
2cf0635d 10546 Elf32_External_RegInfo * ereg;
b34976b6 10547 Elf32_RegInfo reginfo;
a6e9f9df
AM
10548
10549 ereg = (Elf32_External_RegInfo *) (option + 1);
10550 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
10551 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
10552 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
10553 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
10554 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
10555 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
10556
10557 printf ("GPR %08lx GP 0x%lx\n",
10558 reginfo.ri_gprmask,
10559 (unsigned long) reginfo.ri_gp_value);
10560 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
10561 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
10562 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
10563 }
10564 else
10565 {
10566 /* 64 bit form. */
2cf0635d 10567 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
10568 Elf64_Internal_RegInfo reginfo;
10569
10570 ereg = (Elf64_External_RegInfo *) (option + 1);
10571 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
10572 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
10573 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
10574 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
10575 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 10576 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
10577
10578 printf ("GPR %08lx GP 0x",
10579 reginfo.ri_gprmask);
10580 printf_vma (reginfo.ri_gp_value);
10581 printf ("\n");
10582
10583 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
10584 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
10585 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
10586 }
10587 ++option;
10588 continue;
10589 case ODK_EXCEPTIONS:
10590 fputs (" EXCEPTIONS fpe_min(", stdout);
10591 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
10592 fputs (") fpe_max(", stdout);
10593 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
10594 fputs (")", stdout);
10595
10596 if (option->info & OEX_PAGE0)
10597 fputs (" PAGE0", stdout);
10598 if (option->info & OEX_SMM)
10599 fputs (" SMM", stdout);
10600 if (option->info & OEX_FPDBUG)
10601 fputs (" FPDBUG", stdout);
10602 if (option->info & OEX_DISMISS)
10603 fputs (" DISMISS", stdout);
10604 break;
10605 case ODK_PAD:
10606 fputs (" PAD ", stdout);
10607 if (option->info & OPAD_PREFIX)
10608 fputs (" PREFIX", stdout);
10609 if (option->info & OPAD_POSTFIX)
10610 fputs (" POSTFIX", stdout);
10611 if (option->info & OPAD_SYMBOL)
10612 fputs (" SYMBOL", stdout);
10613 break;
10614 case ODK_HWPATCH:
10615 fputs (" HWPATCH ", stdout);
10616 if (option->info & OHW_R4KEOP)
10617 fputs (" R4KEOP", stdout);
10618 if (option->info & OHW_R8KPFETCH)
10619 fputs (" R8KPFETCH", stdout);
10620 if (option->info & OHW_R5KEOP)
10621 fputs (" R5KEOP", stdout);
10622 if (option->info & OHW_R5KCVTL)
10623 fputs (" R5KCVTL", stdout);
10624 break;
10625 case ODK_FILL:
10626 fputs (" FILL ", stdout);
10627 /* XXX Print content of info word? */
10628 break;
10629 case ODK_TAGS:
10630 fputs (" TAGS ", stdout);
10631 /* XXX Print content of info word? */
10632 break;
10633 case ODK_HWAND:
10634 fputs (" HWAND ", stdout);
10635 if (option->info & OHWA0_R4KEOP_CHECKED)
10636 fputs (" R4KEOP_CHECKED", stdout);
10637 if (option->info & OHWA0_R4KEOP_CLEAN)
10638 fputs (" R4KEOP_CLEAN", stdout);
10639 break;
10640 case ODK_HWOR:
10641 fputs (" HWOR ", stdout);
10642 if (option->info & OHWA0_R4KEOP_CHECKED)
10643 fputs (" R4KEOP_CHECKED", stdout);
10644 if (option->info & OHWA0_R4KEOP_CLEAN)
10645 fputs (" R4KEOP_CLEAN", stdout);
10646 break;
10647 case ODK_GP_GROUP:
10648 printf (" GP_GROUP %#06lx self-contained %#06lx",
10649 option->info & OGP_GROUP,
10650 (option->info & OGP_SELF) >> 16);
10651 break;
10652 case ODK_IDENT:
10653 printf (" IDENT %#06lx self-contained %#06lx",
10654 option->info & OGP_GROUP,
10655 (option->info & OGP_SELF) >> 16);
10656 break;
10657 default:
10658 /* This shouldn't happen. */
10659 printf (" %3d ??? %d %lx",
10660 option->kind, option->section, option->info);
10661 break;
252b5132 10662 }
a6e9f9df 10663
2cf0635d 10664 len = sizeof (* eopt);
a6e9f9df
AM
10665 while (len < option->size)
10666 if (((char *) option)[len] >= ' '
10667 && ((char *) option)[len] < 0x7f)
10668 printf ("%c", ((char *) option)[len++]);
10669 else
10670 printf ("\\%03o", ((char *) option)[len++]);
10671
10672 fputs ("\n", stdout);
252b5132 10673 ++option;
252b5132
RH
10674 }
10675
a6e9f9df 10676 free (eopt);
252b5132 10677 }
252b5132
RH
10678 }
10679
10680 if (conflicts_offset != 0 && conflictsno != 0)
10681 {
2cf0635d 10682 Elf32_Conflict * iconf;
252b5132
RH
10683 size_t cnt;
10684
10685 if (dynamic_symbols == NULL)
10686 {
591a748a 10687 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
10688 return 0;
10689 }
10690
3f5e193b 10691 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
10692 if (iconf == NULL)
10693 {
591a748a 10694 error (_("Out of memory\n"));
252b5132
RH
10695 return 0;
10696 }
10697
9ea033b2 10698 if (is_32bit_elf)
252b5132 10699 {
2cf0635d 10700 Elf32_External_Conflict * econf32;
a6e9f9df 10701
3f5e193b
NC
10702 econf32 = (Elf32_External_Conflict *)
10703 get_data (NULL, file, conflicts_offset, conflictsno,
10704 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
10705 if (!econf32)
10706 return 0;
252b5132
RH
10707
10708 for (cnt = 0; cnt < conflictsno; ++cnt)
10709 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
10710
10711 free (econf32);
252b5132
RH
10712 }
10713 else
10714 {
2cf0635d 10715 Elf64_External_Conflict * econf64;
a6e9f9df 10716
3f5e193b
NC
10717 econf64 = (Elf64_External_Conflict *)
10718 get_data (NULL, file, conflicts_offset, conflictsno,
10719 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
10720 if (!econf64)
10721 return 0;
252b5132
RH
10722
10723 for (cnt = 0; cnt < conflictsno; ++cnt)
10724 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
10725
10726 free (econf64);
252b5132
RH
10727 }
10728
c7e7ca54
NC
10729 printf (_("\nSection '.conflict' contains %lu entries:\n"),
10730 (unsigned long) conflictsno);
252b5132
RH
10731 puts (_(" Num: Index Value Name"));
10732
10733 for (cnt = 0; cnt < conflictsno; ++cnt)
10734 {
2cf0635d 10735 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 10736
b34976b6 10737 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 10738 print_vma (psym->st_value, FULL_HEX);
31104126 10739 putchar (' ');
d79b3d50
NC
10740 if (VALID_DYNAMIC_NAME (psym->st_name))
10741 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10742 else
10743 printf ("<corrupt: %14ld>", psym->st_name);
31104126 10744 putchar ('\n');
252b5132
RH
10745 }
10746
252b5132
RH
10747 free (iconf);
10748 }
10749
ccb4c951
RS
10750 if (pltgot != 0 && local_gotno != 0)
10751 {
91d6fa6a 10752 bfd_vma ent, local_end, global_end;
bbeee7ea 10753 size_t i, offset;
2cf0635d 10754 unsigned char * data;
bbeee7ea 10755 int addr_size;
ccb4c951 10756
91d6fa6a 10757 ent = pltgot;
ccb4c951
RS
10758 addr_size = (is_32bit_elf ? 4 : 8);
10759 local_end = pltgot + local_gotno * addr_size;
10760 global_end = local_end + (symtabno - gotsym) * addr_size;
10761
10762 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b
NC
10763 data = (unsigned char *) get_data (NULL, file, offset,
10764 global_end - pltgot, 1, _("GOT"));
ccb4c951
RS
10765 printf (_("\nPrimary GOT:\n"));
10766 printf (_(" Canonical gp value: "));
10767 print_vma (pltgot + 0x7ff0, LONG_HEX);
10768 printf ("\n\n");
10769
10770 printf (_(" Reserved entries:\n"));
10771 printf (_(" %*s %10s %*s Purpose\n"),
10772 addr_size * 2, "Address", "Access",
10773 addr_size * 2, "Initial");
91d6fa6a 10774 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
10775 printf (" Lazy resolver\n");
10776 if (data
91d6fa6a 10777 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
10778 >> (addr_size * 8 - 1)) != 0)
10779 {
91d6fa6a 10780 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
10781 printf (" Module pointer (GNU extension)\n");
10782 }
10783 printf ("\n");
10784
91d6fa6a 10785 if (ent < local_end)
ccb4c951
RS
10786 {
10787 printf (_(" Local entries:\n"));
10788 printf (_(" %*s %10s %*s\n"),
10789 addr_size * 2, "Address", "Access",
10790 addr_size * 2, "Initial");
91d6fa6a 10791 while (ent < local_end)
ccb4c951 10792 {
91d6fa6a 10793 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
10794 printf ("\n");
10795 }
10796 printf ("\n");
10797 }
10798
10799 if (gotsym < symtabno)
10800 {
10801 int sym_width;
10802
10803 printf (_(" Global entries:\n"));
10804 printf (_(" %*s %10s %*s %*s %-7s %3s %s\n"),
10805 addr_size * 2, "Address", "Access",
10806 addr_size * 2, "Initial",
10807 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
10808 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
10809 for (i = gotsym; i < symtabno; i++)
10810 {
2cf0635d 10811 Elf_Internal_Sym * psym;
ccb4c951
RS
10812
10813 psym = dynamic_symbols + i;
91d6fa6a 10814 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
10815 printf (" ");
10816 print_vma (psym->st_value, LONG_HEX);
10817 printf (" %-7s %3s ",
10818 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
10819 get_symbol_index_type (psym->st_shndx));
10820 if (VALID_DYNAMIC_NAME (psym->st_name))
10821 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
10822 else
10823 printf ("<corrupt: %14ld>", psym->st_name);
10824 printf ("\n");
10825 }
10826 printf ("\n");
10827 }
10828
10829 if (data)
10830 free (data);
10831 }
10832
861fb55a
DJ
10833 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
10834 {
91d6fa6a 10835 bfd_vma ent, end;
861fb55a
DJ
10836 size_t offset, rel_offset;
10837 unsigned long count, i;
2cf0635d 10838 unsigned char * data;
861fb55a 10839 int addr_size, sym_width;
2cf0635d 10840 Elf_Internal_Rela * rels;
861fb55a
DJ
10841
10842 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
10843 if (pltrel == DT_RELA)
10844 {
10845 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
10846 return 0;
10847 }
10848 else
10849 {
10850 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
10851 return 0;
10852 }
10853
91d6fa6a 10854 ent = mips_pltgot;
861fb55a
DJ
10855 addr_size = (is_32bit_elf ? 4 : 8);
10856 end = mips_pltgot + (2 + count) * addr_size;
10857
10858 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b
NC
10859 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
10860 1, _("PLT GOT"));
861fb55a
DJ
10861 printf (_("\nPLT GOT:\n\n"));
10862 printf (_(" Reserved entries:\n"));
10863 printf (_(" %*s %*s Purpose\n"),
10864 addr_size * 2, "Address", addr_size * 2, "Initial");
91d6fa6a 10865 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 10866 printf (" PLT lazy resolver\n");
91d6fa6a 10867 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
10868 printf (" Module pointer\n");
10869 printf ("\n");
10870
10871 printf (_(" Entries:\n"));
10872 printf (_(" %*s %*s %*s %-7s %3s %s\n"),
10873 addr_size * 2, "Address",
10874 addr_size * 2, "Initial",
10875 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
10876 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
10877 for (i = 0; i < count; i++)
10878 {
2cf0635d 10879 Elf_Internal_Sym * psym;
861fb55a
DJ
10880
10881 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 10882 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
10883 printf (" ");
10884 print_vma (psym->st_value, LONG_HEX);
10885 printf (" %-7s %3s ",
10886 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
10887 get_symbol_index_type (psym->st_shndx));
10888 if (VALID_DYNAMIC_NAME (psym->st_name))
10889 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
10890 else
10891 printf ("<corrupt: %14ld>", psym->st_name);
10892 printf ("\n");
10893 }
10894 printf ("\n");
10895
10896 if (data)
10897 free (data);
10898 free (rels);
10899 }
10900
252b5132
RH
10901 return 1;
10902}
10903
047b2264 10904static int
2cf0635d 10905process_gnu_liblist (FILE * file)
047b2264 10906{
2cf0635d
NC
10907 Elf_Internal_Shdr * section;
10908 Elf_Internal_Shdr * string_sec;
10909 Elf32_External_Lib * elib;
10910 char * strtab;
c256ffe7 10911 size_t strtab_size;
047b2264
JJ
10912 size_t cnt;
10913 unsigned i;
10914
10915 if (! do_arch)
10916 return 0;
10917
10918 for (i = 0, section = section_headers;
10919 i < elf_header.e_shnum;
b34976b6 10920 i++, section++)
047b2264
JJ
10921 {
10922 switch (section->sh_type)
10923 {
10924 case SHT_GNU_LIBLIST:
4fbb74a6 10925 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
10926 break;
10927
3f5e193b
NC
10928 elib = (Elf32_External_Lib *)
10929 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
10930 _("liblist"));
047b2264
JJ
10931
10932 if (elib == NULL)
10933 break;
4fbb74a6 10934 string_sec = section_headers + section->sh_link;
047b2264 10935
3f5e193b
NC
10936 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
10937 string_sec->sh_size,
10938 _("liblist string table"));
c256ffe7 10939 strtab_size = string_sec->sh_size;
047b2264
JJ
10940
10941 if (strtab == NULL
10942 || section->sh_entsize != sizeof (Elf32_External_Lib))
10943 {
10944 free (elib);
10945 break;
10946 }
10947
10948 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
10949 SECTION_NAME (section),
0af1713e 10950 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264
JJ
10951
10952 puts (" Library Time Stamp Checksum Version Flags");
10953
10954 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
10955 ++cnt)
10956 {
10957 Elf32_Lib liblist;
91d6fa6a 10958 time_t atime;
047b2264 10959 char timebuf[20];
2cf0635d 10960 struct tm * tmp;
047b2264
JJ
10961
10962 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 10963 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
10964 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10965 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10966 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10967
91d6fa6a 10968 tmp = gmtime (&atime);
e9e44622
JJ
10969 snprintf (timebuf, sizeof (timebuf),
10970 "%04u-%02u-%02uT%02u:%02u:%02u",
10971 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10972 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10973
10974 printf ("%3lu: ", (unsigned long) cnt);
10975 if (do_wide)
c256ffe7
JJ
10976 printf ("%-20s", liblist.l_name < strtab_size
10977 ? strtab + liblist.l_name : "<corrupt>");
047b2264 10978 else
c256ffe7
JJ
10979 printf ("%-20.20s", liblist.l_name < strtab_size
10980 ? strtab + liblist.l_name : "<corrupt>");
047b2264
JJ
10981 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
10982 liblist.l_version, liblist.l_flags);
10983 }
10984
10985 free (elib);
10986 }
10987 }
10988
10989 return 1;
10990}
10991
9437c45b 10992static const char *
d3ba0551 10993get_note_type (unsigned e_type)
779fe533
NC
10994{
10995 static char buff[64];
103f02d3 10996
1ec5cd37
NC
10997 if (elf_header.e_type == ET_CORE)
10998 switch (e_type)
10999 {
57346661 11000 case NT_AUXV:
1ec5cd37 11001 return _("NT_AUXV (auxiliary vector)");
57346661 11002 case NT_PRSTATUS:
1ec5cd37 11003 return _("NT_PRSTATUS (prstatus structure)");
57346661 11004 case NT_FPREGSET:
1ec5cd37 11005 return _("NT_FPREGSET (floating point registers)");
57346661 11006 case NT_PRPSINFO:
1ec5cd37 11007 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 11008 case NT_TASKSTRUCT:
1ec5cd37 11009 return _("NT_TASKSTRUCT (task structure)");
57346661 11010 case NT_PRXFPREG:
1ec5cd37 11011 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
11012 case NT_PPC_VMX:
11013 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
11014 case NT_PPC_VSX:
11015 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
11016 case NT_X86_XSTATE:
11017 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
11018 case NT_S390_HIGH_GPRS:
11019 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
11020 case NT_S390_TIMER:
11021 return _("NT_S390_TIMER (s390 timer register)");
11022 case NT_S390_TODCMP:
11023 return _("NT_S390_TODCMP (s390 TOD comparator register)");
11024 case NT_S390_TODPREG:
11025 return _("NT_S390_TODPREG (s390 TOD programmable register)");
11026 case NT_S390_CTRS:
11027 return _("NT_S390_CTRS (s390 control registers)");
11028 case NT_S390_PREFIX:
11029 return _("NT_S390_PREFIX (s390 prefix register)");
57346661 11030 case NT_PSTATUS:
1ec5cd37 11031 return _("NT_PSTATUS (pstatus structure)");
57346661 11032 case NT_FPREGS:
1ec5cd37 11033 return _("NT_FPREGS (floating point registers)");
57346661 11034 case NT_PSINFO:
1ec5cd37 11035 return _("NT_PSINFO (psinfo structure)");
57346661 11036 case NT_LWPSTATUS:
1ec5cd37 11037 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 11038 case NT_LWPSINFO:
1ec5cd37 11039 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 11040 case NT_WIN32PSTATUS:
1ec5cd37
NC
11041 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
11042 default:
11043 break;
11044 }
11045 else
11046 switch (e_type)
11047 {
11048 case NT_VERSION:
11049 return _("NT_VERSION (version)");
11050 case NT_ARCH:
11051 return _("NT_ARCH (architecture)");
11052 default:
11053 break;
11054 }
11055
e9e44622 11056 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 11057 return buff;
779fe533
NC
11058}
11059
1118d252
RM
11060static const char *
11061get_gnu_elf_note_type (unsigned e_type)
11062{
11063 static char buff[64];
11064
11065 switch (e_type)
11066 {
11067 case NT_GNU_ABI_TAG:
11068 return _("NT_GNU_ABI_TAG (ABI version tag)");
11069 case NT_GNU_HWCAP:
11070 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
11071 case NT_GNU_BUILD_ID:
11072 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
11073 case NT_GNU_GOLD_VERSION:
11074 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
11075 default:
11076 break;
11077 }
11078
11079 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
11080 return buff;
11081}
11082
9437c45b 11083static const char *
d3ba0551 11084get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
11085{
11086 static char buff[64];
11087
b4db1224 11088 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
11089 {
11090 /* NetBSD core "procinfo" structure. */
11091 return _("NetBSD procinfo structure");
11092 }
11093
11094 /* As of Jan 2002 there are no other machine-independent notes
11095 defined for NetBSD core files. If the note type is less
11096 than the start of the machine-dependent note types, we don't
11097 understand it. */
11098
b4db1224 11099 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 11100 {
e9e44622 11101 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
11102 return buff;
11103 }
11104
11105 switch (elf_header.e_machine)
11106 {
11107 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
11108 and PT_GETFPREGS == mach+2. */
11109
11110 case EM_OLD_ALPHA:
11111 case EM_ALPHA:
11112 case EM_SPARC:
11113 case EM_SPARC32PLUS:
11114 case EM_SPARCV9:
11115 switch (e_type)
11116 {
b4db1224
JT
11117 case NT_NETBSDCORE_FIRSTMACH+0:
11118 return _("PT_GETREGS (reg structure)");
11119 case NT_NETBSDCORE_FIRSTMACH+2:
11120 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11121 default:
11122 break;
11123 }
11124 break;
11125
11126 /* On all other arch's, PT_GETREGS == mach+1 and
11127 PT_GETFPREGS == mach+3. */
11128 default:
11129 switch (e_type)
11130 {
b4db1224
JT
11131 case NT_NETBSDCORE_FIRSTMACH+1:
11132 return _("PT_GETREGS (reg structure)");
11133 case NT_NETBSDCORE_FIRSTMACH+3:
11134 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11135 default:
11136 break;
11137 }
11138 }
11139
e9e44622
JJ
11140 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
11141 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
11142 return buff;
11143}
11144
6d118b09
NC
11145/* Note that by the ELF standard, the name field is already null byte
11146 terminated, and namesz includes the terminating null byte.
11147 I.E. the value of namesz for the name "FSF" is 4.
11148
e3c8793a 11149 If the value of namesz is zero, there is no name present. */
779fe533 11150static int
2cf0635d 11151process_note (Elf_Internal_Note * pnote)
779fe533 11152{
2cf0635d
NC
11153 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
11154 const char * nt;
9437c45b
JT
11155
11156 if (pnote->namesz == 0)
1ec5cd37
NC
11157 /* If there is no note name, then use the default set of
11158 note type strings. */
11159 nt = get_note_type (pnote->type);
11160
1118d252
RM
11161 else if (const_strneq (pnote->namedata, "GNU"))
11162 /* GNU-specific object file notes. */
11163 nt = get_gnu_elf_note_type (pnote->type);
11164
0112cd26 11165 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
11166 /* NetBSD-specific core file notes. */
11167 nt = get_netbsd_elfcore_note_type (pnote->type);
11168
b15fa79e
AM
11169 else if (strneq (pnote->namedata, "SPU/", 4))
11170 {
11171 /* SPU-specific core file notes. */
11172 nt = pnote->namedata + 4;
11173 name = "SPU";
11174 }
11175
9437c45b 11176 else
1ec5cd37
NC
11177 /* Don't recognize this note name; just use the default set of
11178 note type strings. */
9437c45b 11179 nt = get_note_type (pnote->type);
9437c45b 11180
b15fa79e 11181 printf (" %s\t\t0x%08lx\t%s\n", name, pnote->descsz, nt);
779fe533
NC
11182 return 1;
11183}
11184
6d118b09 11185
779fe533 11186static int
2cf0635d 11187process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 11188{
2cf0635d
NC
11189 Elf_External_Note * pnotes;
11190 Elf_External_Note * external;
b34976b6 11191 int res = 1;
103f02d3 11192
779fe533
NC
11193 if (length <= 0)
11194 return 0;
103f02d3 11195
3f5e193b
NC
11196 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
11197 _("notes"));
a6e9f9df
AM
11198 if (!pnotes)
11199 return 0;
779fe533 11200
103f02d3 11201 external = pnotes;
103f02d3 11202
305c7206 11203 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 11204 (unsigned long) offset, (unsigned long) length);
779fe533 11205 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 11206
2cf0635d 11207 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 11208 {
2cf0635d 11209 Elf_External_Note * next;
b34976b6 11210 Elf_Internal_Note inote;
2cf0635d 11211 char * temp = NULL;
6d118b09
NC
11212
11213 inote.type = BYTE_GET (external->type);
11214 inote.namesz = BYTE_GET (external->namesz);
11215 inote.namedata = external->name;
11216 inote.descsz = BYTE_GET (external->descsz);
11217 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
11218 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 11219
2cf0635d 11220 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
3e55a963
NC
11221
11222 if (((char *) next) > (((char *) pnotes) + length))
11223 {
0fd3a477 11224 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 11225 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 11226 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
11227 inote.type, inote.namesz, inote.descsz);
11228 break;
11229 }
11230
11231 external = next;
6d118b09
NC
11232
11233 /* Verify that name is null terminated. It appears that at least
11234 one version of Linux (RedHat 6.0) generates corefiles that don't
11235 comply with the ELF spec by failing to include the null byte in
11236 namesz. */
11237 if (inote.namedata[inote.namesz] != '\0')
11238 {
3f5e193b 11239 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 11240
6d118b09
NC
11241 if (temp == NULL)
11242 {
11243 error (_("Out of memory\n"));
11244 res = 0;
11245 break;
11246 }
76da6bbe 11247
6d118b09
NC
11248 strncpy (temp, inote.namedata, inote.namesz);
11249 temp[inote.namesz] = 0;
76da6bbe 11250
6d118b09
NC
11251 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
11252 inote.namedata = temp;
11253 }
11254
11255 res &= process_note (& inote);
103f02d3 11256
6d118b09
NC
11257 if (temp != NULL)
11258 {
11259 free (temp);
11260 temp = NULL;
11261 }
779fe533
NC
11262 }
11263
11264 free (pnotes);
103f02d3 11265
779fe533
NC
11266 return res;
11267}
11268
11269static int
2cf0635d 11270process_corefile_note_segments (FILE * file)
779fe533 11271{
2cf0635d 11272 Elf_Internal_Phdr * segment;
b34976b6
AM
11273 unsigned int i;
11274 int res = 1;
103f02d3 11275
d93f0186 11276 if (! get_program_headers (file))
779fe533 11277 return 0;
103f02d3 11278
779fe533
NC
11279 for (i = 0, segment = program_headers;
11280 i < elf_header.e_phnum;
b34976b6 11281 i++, segment++)
779fe533
NC
11282 {
11283 if (segment->p_type == PT_NOTE)
103f02d3 11284 res &= process_corefile_note_segment (file,
30800947
NC
11285 (bfd_vma) segment->p_offset,
11286 (bfd_vma) segment->p_filesz);
779fe533 11287 }
103f02d3 11288
779fe533
NC
11289 return res;
11290}
11291
11292static int
2cf0635d 11293process_note_sections (FILE * file)
1ec5cd37 11294{
2cf0635d 11295 Elf_Internal_Shdr * section;
1ec5cd37
NC
11296 unsigned long i;
11297 int res = 1;
11298
11299 for (i = 0, section = section_headers;
11300 i < elf_header.e_shnum;
11301 i++, section++)
11302 if (section->sh_type == SHT_NOTE)
11303 res &= process_corefile_note_segment (file,
11304 (bfd_vma) section->sh_offset,
11305 (bfd_vma) section->sh_size);
11306
11307 return res;
11308}
11309
11310static int
2cf0635d 11311process_notes (FILE * file)
779fe533
NC
11312{
11313 /* If we have not been asked to display the notes then do nothing. */
11314 if (! do_notes)
11315 return 1;
103f02d3 11316
779fe533 11317 if (elf_header.e_type != ET_CORE)
1ec5cd37 11318 return process_note_sections (file);
103f02d3 11319
779fe533 11320 /* No program headers means no NOTE segment. */
1ec5cd37
NC
11321 if (elf_header.e_phnum > 0)
11322 return process_corefile_note_segments (file);
779fe533 11323
1ec5cd37
NC
11324 printf (_("No note segments present in the core file.\n"));
11325 return 1;
779fe533
NC
11326}
11327
252b5132 11328static int
2cf0635d 11329process_arch_specific (FILE * file)
252b5132 11330{
a952a375
NC
11331 if (! do_arch)
11332 return 1;
11333
252b5132
RH
11334 switch (elf_header.e_machine)
11335 {
11c1ff18
PB
11336 case EM_ARM:
11337 return process_arm_specific (file);
252b5132 11338 case EM_MIPS:
4fe85591 11339 case EM_MIPS_RS3_LE:
252b5132
RH
11340 return process_mips_specific (file);
11341 break;
34c8bcba
JM
11342 case EM_PPC:
11343 return process_power_specific (file);
11344 break;
252b5132
RH
11345 default:
11346 break;
11347 }
11348 return 1;
11349}
11350
11351static int
2cf0635d 11352get_file_header (FILE * file)
252b5132 11353{
9ea033b2
NC
11354 /* Read in the identity array. */
11355 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
11356 return 0;
11357
9ea033b2 11358 /* Determine how to read the rest of the header. */
b34976b6 11359 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
11360 {
11361 default: /* fall through */
11362 case ELFDATANONE: /* fall through */
adab8cdc
AO
11363 case ELFDATA2LSB:
11364 byte_get = byte_get_little_endian;
11365 byte_put = byte_put_little_endian;
11366 break;
11367 case ELFDATA2MSB:
11368 byte_get = byte_get_big_endian;
11369 byte_put = byte_put_big_endian;
11370 break;
9ea033b2
NC
11371 }
11372
11373 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 11374 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
11375
11376 /* Read in the rest of the header. */
11377 if (is_32bit_elf)
11378 {
11379 Elf32_External_Ehdr ehdr32;
252b5132 11380
9ea033b2
NC
11381 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
11382 return 0;
103f02d3 11383
9ea033b2
NC
11384 elf_header.e_type = BYTE_GET (ehdr32.e_type);
11385 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
11386 elf_header.e_version = BYTE_GET (ehdr32.e_version);
11387 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
11388 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
11389 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
11390 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
11391 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
11392 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
11393 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
11394 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
11395 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
11396 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
11397 }
252b5132 11398 else
9ea033b2
NC
11399 {
11400 Elf64_External_Ehdr ehdr64;
a952a375
NC
11401
11402 /* If we have been compiled with sizeof (bfd_vma) == 4, then
11403 we will not be able to cope with the 64bit data found in
11404 64 ELF files. Detect this now and abort before we start
50c2245b 11405 overwriting things. */
a952a375
NC
11406 if (sizeof (bfd_vma) < 8)
11407 {
e3c8793a
NC
11408 error (_("This instance of readelf has been built without support for a\n\
1140964 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
11410 return 0;
11411 }
103f02d3 11412
9ea033b2
NC
11413 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
11414 return 0;
103f02d3 11415
9ea033b2
NC
11416 elf_header.e_type = BYTE_GET (ehdr64.e_type);
11417 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
11418 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
11419 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
11420 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
11421 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
11422 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
11423 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
11424 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
11425 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
11426 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
11427 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
11428 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
11429 }
252b5132 11430
7ece0d85
JJ
11431 if (elf_header.e_shoff)
11432 {
11433 /* There may be some extensions in the first section header. Don't
11434 bomb if we can't read it. */
11435 if (is_32bit_elf)
11436 get_32bit_section_headers (file, 1);
11437 else
11438 get_64bit_section_headers (file, 1);
11439 }
560f3c1c 11440
252b5132
RH
11441 return 1;
11442}
11443
fb52b2f4
NC
11444/* Process one ELF object file according to the command line options.
11445 This file may actually be stored in an archive. The file is
11446 positioned at the start of the ELF object. */
11447
ff78d6d6 11448static int
2cf0635d 11449process_object (char * file_name, FILE * file)
252b5132 11450{
252b5132
RH
11451 unsigned int i;
11452
252b5132
RH
11453 if (! get_file_header (file))
11454 {
11455 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 11456 return 1;
252b5132
RH
11457 }
11458
11459 /* Initialise per file variables. */
60bca95a 11460 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
11461 version_info[i] = 0;
11462
60bca95a 11463 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132
RH
11464 dynamic_info[i] = 0;
11465
11466 /* Process the file. */
11467 if (show_name)
11468 printf (_("\nFile: %s\n"), file_name);
11469
18bd398b
NC
11470 /* Initialise the dump_sects array from the cmdline_dump_sects array.
11471 Note we do this even if cmdline_dump_sects is empty because we
11472 must make sure that the dump_sets array is zeroed out before each
11473 object file is processed. */
11474 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 11475 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
11476
11477 if (num_cmdline_dump_sects > 0)
11478 {
11479 if (num_dump_sects == 0)
11480 /* A sneaky way of allocating the dump_sects array. */
09c11c86 11481 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
11482
11483 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
11484 memcpy (dump_sects, cmdline_dump_sects,
11485 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 11486 }
d70c5fc7 11487
252b5132 11488 if (! process_file_header ())
fb52b2f4 11489 return 1;
252b5132 11490
d1f5c6e3 11491 if (! process_section_headers (file))
2f62977e 11492 {
d1f5c6e3
L
11493 /* Without loaded section headers we cannot process lots of
11494 things. */
2f62977e 11495 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 11496
2f62977e 11497 if (! do_using_dynamic)
2c610e4b 11498 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 11499 }
252b5132 11500
d1f5c6e3
L
11501 if (! process_section_groups (file))
11502 {
11503 /* Without loaded section groups we cannot process unwind. */
11504 do_unwind = 0;
11505 }
11506
2f62977e 11507 if (process_program_headers (file))
b2d38a17 11508 process_dynamic_section (file);
252b5132
RH
11509
11510 process_relocs (file);
11511
4d6ed7c8
NC
11512 process_unwind (file);
11513
252b5132
RH
11514 process_symbol_table (file);
11515
11516 process_syminfo (file);
11517
11518 process_version_sections (file);
11519
11520 process_section_contents (file);
f5842774 11521
1ec5cd37 11522 process_notes (file);
103f02d3 11523
047b2264
JJ
11524 process_gnu_liblist (file);
11525
252b5132
RH
11526 process_arch_specific (file);
11527
d93f0186
NC
11528 if (program_headers)
11529 {
11530 free (program_headers);
11531 program_headers = NULL;
11532 }
11533
252b5132
RH
11534 if (section_headers)
11535 {
11536 free (section_headers);
11537 section_headers = NULL;
11538 }
11539
11540 if (string_table)
11541 {
11542 free (string_table);
11543 string_table = NULL;
d40ac9bd 11544 string_table_length = 0;
252b5132
RH
11545 }
11546
11547 if (dynamic_strings)
11548 {
11549 free (dynamic_strings);
11550 dynamic_strings = NULL;
d79b3d50 11551 dynamic_strings_length = 0;
252b5132
RH
11552 }
11553
11554 if (dynamic_symbols)
11555 {
11556 free (dynamic_symbols);
11557 dynamic_symbols = NULL;
19936277 11558 num_dynamic_syms = 0;
252b5132
RH
11559 }
11560
11561 if (dynamic_syminfo)
11562 {
11563 free (dynamic_syminfo);
11564 dynamic_syminfo = NULL;
11565 }
ff78d6d6 11566
e4b17d5c
L
11567 if (section_headers_groups)
11568 {
11569 free (section_headers_groups);
11570 section_headers_groups = NULL;
11571 }
11572
11573 if (section_groups)
11574 {
2cf0635d
NC
11575 struct group_list * g;
11576 struct group_list * next;
e4b17d5c
L
11577
11578 for (i = 0; i < group_count; i++)
11579 {
11580 for (g = section_groups [i].root; g != NULL; g = next)
11581 {
11582 next = g->next;
11583 free (g);
11584 }
11585 }
11586
11587 free (section_groups);
11588 section_groups = NULL;
11589 }
11590
19e6b90e 11591 free_debug_memory ();
18bd398b 11592
ff78d6d6 11593 return 0;
252b5132
RH
11594}
11595
2cf0635d
NC
11596/* Return the path name for a proxy entry in a thin archive, adjusted relative
11597 to the path name of the thin archive itself if necessary. Always returns
11598 a pointer to malloc'ed memory. */
11599
11600static char *
11601adjust_relative_path (char * file_name, char * name, int name_len)
11602{
11603 char * member_file_name;
11604 const char * base_name = lbasename (file_name);
11605
11606 /* This is a proxy entry for a thin archive member.
11607 If the extended name table contains an absolute path
11608 name, or if the archive is in the current directory,
11609 use the path name as given. Otherwise, we need to
11610 find the member relative to the directory where the
11611 archive is located. */
11612 if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
11613 {
3f5e193b 11614 member_file_name = (char *) malloc (name_len + 1);
2cf0635d
NC
11615 if (member_file_name == NULL)
11616 {
11617 error (_("Out of memory\n"));
11618 return NULL;
11619 }
11620 memcpy (member_file_name, name, name_len);
11621 member_file_name[name_len] = '\0';
11622 }
11623 else
11624 {
11625 /* Concatenate the path components of the archive file name
11626 to the relative path name from the extended name table. */
11627 size_t prefix_len = base_name - file_name;
3f5e193b 11628 member_file_name = (char *) malloc (prefix_len + name_len + 1);
2cf0635d
NC
11629 if (member_file_name == NULL)
11630 {
11631 error (_("Out of memory\n"));
11632 return NULL;
11633 }
11634 memcpy (member_file_name, file_name, prefix_len);
11635 memcpy (member_file_name + prefix_len, name, name_len);
11636 member_file_name[prefix_len + name_len] = '\0';
11637 }
11638 return member_file_name;
11639}
11640
11641/* Structure to hold information about an archive file. */
11642
11643struct archive_info
11644{
11645 char * file_name; /* Archive file name. */
11646 FILE * file; /* Open file descriptor. */
11647 unsigned long index_num; /* Number of symbols in table. */
11648 unsigned long * index_array; /* The array of member offsets. */
11649 char * sym_table; /* The symbol table. */
11650 unsigned long sym_size; /* Size of the symbol table. */
11651 char * longnames; /* The long file names table. */
11652 unsigned long longnames_size; /* Size of the long file names table. */
11653 unsigned long nested_member_origin; /* Origin in the nested archive of the current member. */
11654 unsigned long next_arhdr_offset; /* Offset of the next archive header. */
11655 bfd_boolean is_thin_archive; /* TRUE if this is a thin archive. */
11656 struct ar_hdr arhdr; /* Current archive header. */
11657};
11658
11659/* Read the symbol table and long-name table from an archive. */
fb52b2f4
NC
11660
11661static int
2cf0635d
NC
11662setup_archive (struct archive_info * arch, char * file_name, FILE * file,
11663 bfd_boolean is_thin_archive, bfd_boolean read_symbols)
fb52b2f4 11664{
fb52b2f4
NC
11665 size_t got;
11666 unsigned long size;
fb52b2f4 11667
2cf0635d
NC
11668 arch->file_name = strdup (file_name);
11669 arch->file = file;
11670 arch->index_num = 0;
11671 arch->index_array = NULL;
11672 arch->sym_table = NULL;
11673 arch->sym_size = 0;
11674 arch->longnames = NULL;
11675 arch->longnames_size = 0;
11676 arch->nested_member_origin = 0;
11677 arch->is_thin_archive = is_thin_archive;
11678 arch->next_arhdr_offset = SARMAG;
11679
11680 /* Read the first archive member header. */
11681 if (fseek (file, SARMAG, SEEK_SET) != 0)
11682 {
11683 error (_("%s: failed to seek to first archive header\n"), file_name);
11684 return 1;
11685 }
11686 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
11687 if (got != sizeof arch->arhdr)
fb52b2f4
NC
11688 {
11689 if (got == 0)
11690 return 0;
11691
11692 error (_("%s: failed to read archive header\n"), file_name);
11693 return 1;
11694 }
11695
4145f1d5 11696 /* See if this is the archive symbol table. */
2cf0635d
NC
11697 if (const_strneq (arch->arhdr.ar_name, "/ ")
11698 || const_strneq (arch->arhdr.ar_name, "/SYM64/ "))
fb52b2f4 11699 {
2cf0635d 11700 size = strtoul (arch->arhdr.ar_size, NULL, 10);
4145f1d5
NC
11701 size = size + (size & 1);
11702
2cf0635d
NC
11703 arch->next_arhdr_offset += sizeof arch->arhdr + size;
11704
11705 if (read_symbols)
fb52b2f4 11706 {
4145f1d5
NC
11707 unsigned long i;
11708 /* A buffer used to hold numbers read in from an archive index.
11709 These are always 4 bytes long and stored in big-endian format. */
11710#define SIZEOF_AR_INDEX_NUMBERS 4
11711 unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
11712 unsigned char * index_buffer;
11713
11714 /* Check the size of the archive index. */
11715 if (size < SIZEOF_AR_INDEX_NUMBERS)
11716 {
11717 error (_("%s: the archive index is empty\n"), file_name);
11718 return 1;
11719 }
11720
11721 /* Read the numer of entries in the archive index. */
11722 got = fread (integer_buffer, 1, sizeof integer_buffer, file);
11723 if (got != sizeof (integer_buffer))
11724 {
11725 error (_("%s: failed to read archive index\n"), file_name);
11726 return 1;
11727 }
2cf0635d 11728 arch->index_num = byte_get_big_endian (integer_buffer, sizeof integer_buffer);
4145f1d5
NC
11729 size -= SIZEOF_AR_INDEX_NUMBERS;
11730
11731 /* Read in the archive index. */
2cf0635d 11732 if (size < arch->index_num * SIZEOF_AR_INDEX_NUMBERS)
4145f1d5
NC
11733 {
11734 error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
2cf0635d 11735 file_name, arch->index_num);
4145f1d5
NC
11736 return 1;
11737 }
3f5e193b
NC
11738 index_buffer = (unsigned char *)
11739 malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
11740 if (index_buffer == NULL)
11741 {
11742 error (_("Out of memory whilst trying to read archive symbol index\n"));
11743 return 1;
11744 }
2cf0635d
NC
11745 got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, arch->index_num, file);
11746 if (got != arch->index_num)
4145f1d5
NC
11747 {
11748 free (index_buffer);
11749 error (_("%s: failed to read archive index\n"), file_name);
2cf0635d 11750 return 1;
4145f1d5 11751 }
2cf0635d 11752 size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS;
4145f1d5
NC
11753
11754 /* Convert the index numbers into the host's numeric format. */
3f5e193b
NC
11755 arch->index_array = (long unsigned int *)
11756 malloc (arch->index_num * sizeof (* arch->index_array));
2cf0635d 11757 if (arch->index_array == NULL)
4145f1d5
NC
11758 {
11759 free (index_buffer);
11760 error (_("Out of memory whilst trying to convert the archive symbol index\n"));
11761 return 1;
11762 }
11763
2cf0635d
NC
11764 for (i = 0; i < arch->index_num; i++)
11765 arch->index_array[i] = byte_get_big_endian ((unsigned char *) (index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
11766 SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
11767 free (index_buffer);
11768
11769 /* The remaining space in the header is taken up by the symbol table. */
11770 if (size < 1)
11771 {
11772 error (_("%s: the archive has an index but no symbols\n"), file_name);
2cf0635d 11773 return 1;
4145f1d5 11774 }
3f5e193b 11775 arch->sym_table = (char *) malloc (size);
2cf0635d
NC
11776 arch->sym_size = size;
11777 if (arch->sym_table == NULL)
4145f1d5
NC
11778 {
11779 error (_("Out of memory whilst trying to read archive index symbol table\n"));
2cf0635d 11780 return 1;
4145f1d5 11781 }
2cf0635d 11782 got = fread (arch->sym_table, 1, size, file);
4145f1d5
NC
11783 if (got != size)
11784 {
11785 error (_("%s: failed to read archive index symbol table\n"), file_name);
2cf0635d 11786 return 1;
cb8f3167 11787 }
4145f1d5
NC
11788 }
11789 else
11790 {
11791 if (fseek (file, size, SEEK_CUR) != 0)
11792 {
11793 error (_("%s: failed to skip archive symbol table\n"), file_name);
11794 return 1;
11795 }
fb52b2f4
NC
11796 }
11797
2cf0635d
NC
11798 /* Read the next archive header. */
11799 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
11800 if (got != sizeof arch->arhdr)
fb52b2f4
NC
11801 {
11802 if (got == 0)
2cf0635d 11803 return 0;
4145f1d5 11804 error (_("%s: failed to read archive header following archive index\n"), file_name);
2cf0635d 11805 return 1;
fb52b2f4
NC
11806 }
11807 }
2cf0635d 11808 else if (read_symbols)
4145f1d5 11809 printf (_("%s has no archive index\n"), file_name);
fb52b2f4 11810
2cf0635d 11811 if (const_strneq (arch->arhdr.ar_name, "// "))
fb52b2f4 11812 {
2cf0635d
NC
11813 /* This is the archive string table holding long member names. */
11814 arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
11815 arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
fb52b2f4 11816
3f5e193b 11817 arch->longnames = (char *) malloc (arch->longnames_size);
2cf0635d 11818 if (arch->longnames == NULL)
fb52b2f4 11819 {
4145f1d5 11820 error (_("Out of memory reading long symbol names in archive\n"));
2cf0635d 11821 return 1;
fb52b2f4
NC
11822 }
11823
2cf0635d 11824 if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
fb52b2f4 11825 {
2cf0635d
NC
11826 free (arch->longnames);
11827 arch->longnames = NULL;
4145f1d5 11828 error (_("%s: failed to read long symbol name string table\n"), file_name);
2cf0635d 11829 return 1;
fb52b2f4
NC
11830 }
11831
2cf0635d 11832 if ((arch->longnames_size & 1) != 0)
fb52b2f4 11833 getc (file);
2cf0635d 11834 }
fb52b2f4 11835
2cf0635d
NC
11836 return 0;
11837}
11838
11839/* Release the memory used for the archive information. */
11840
11841static void
11842release_archive (struct archive_info * arch)
11843{
11844 if (arch->file_name != NULL)
11845 free (arch->file_name);
11846 if (arch->index_array != NULL)
11847 free (arch->index_array);
11848 if (arch->sym_table != NULL)
11849 free (arch->sym_table);
11850 if (arch->longnames != NULL)
11851 free (arch->longnames);
11852}
11853
11854/* Open and setup a nested archive, if not already open. */
11855
11856static int
11857setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
11858{
11859 FILE * member_file;
11860
11861 /* Have we already setup this archive? */
11862 if (nested_arch->file_name != NULL
11863 && streq (nested_arch->file_name, member_file_name))
11864 return 0;
11865
11866 /* Close previous file and discard cached information. */
11867 if (nested_arch->file != NULL)
11868 fclose (nested_arch->file);
11869 release_archive (nested_arch);
11870
11871 member_file = fopen (member_file_name, "rb");
11872 if (member_file == NULL)
11873 return 1;
11874 return setup_archive (nested_arch, member_file_name, member_file, FALSE, FALSE);
11875}
11876
11877static char *
11878get_archive_member_name_at (struct archive_info * arch,
11879 unsigned long offset,
11880 struct archive_info * nested_arch);
11881
11882/* Get the name of an archive member from the current archive header.
11883 For simple names, this will modify the ar_name field of the current
11884 archive header. For long names, it will return a pointer to the
11885 longnames table. For nested archives, it will open the nested archive
11886 and get the name recursively. NESTED_ARCH is a single-entry cache so
11887 we don't keep rereading the same information from a nested archive. */
11888
11889static char *
11890get_archive_member_name (struct archive_info * arch,
11891 struct archive_info * nested_arch)
11892{
11893 unsigned long j, k;
11894
11895 if (arch->arhdr.ar_name[0] == '/')
11896 {
11897 /* We have a long name. */
11898 char * endp;
11899 char * member_file_name;
11900 char * member_name;
11901
11902 arch->nested_member_origin = 0;
11903 k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
11904 if (arch->is_thin_archive && endp != NULL && * endp == ':')
11905 arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
11906
11907 while ((j < arch->longnames_size)
11908 && (arch->longnames[j] != '\n')
11909 && (arch->longnames[j] != '\0'))
11910 j++;
11911 if (arch->longnames[j-1] == '/')
11912 j--;
11913 arch->longnames[j] = '\0';
11914
11915 if (!arch->is_thin_archive || arch->nested_member_origin == 0)
11916 return arch->longnames + k;
11917
11918 /* This is a proxy for a member of a nested archive.
11919 Find the name of the member in that archive. */
11920 member_file_name = adjust_relative_path (arch->file_name, arch->longnames + k, j - k);
11921 if (member_file_name != NULL
11922 && setup_nested_archive (nested_arch, member_file_name) == 0
11923 && (member_name = get_archive_member_name_at (nested_arch, arch->nested_member_origin, NULL)) != NULL)
11924 {
11925 free (member_file_name);
11926 return member_name;
11927 }
11928 free (member_file_name);
11929
11930 /* Last resort: just return the name of the nested archive. */
11931 return arch->longnames + k;
11932 }
11933
11934 /* We have a normal (short) name. */
11935 j = 0;
11936 while ((arch->arhdr.ar_name[j] != '/') && (j < 16))
11937 j++;
11938 arch->arhdr.ar_name[j] = '\0';
11939 return arch->arhdr.ar_name;
11940}
11941
11942/* Get the name of an archive member at a given OFFSET within an archive ARCH. */
11943
11944static char *
11945get_archive_member_name_at (struct archive_info * arch,
11946 unsigned long offset,
11947 struct archive_info * nested_arch)
11948{
11949 size_t got;
11950
11951 if (fseek (arch->file, offset, SEEK_SET) != 0)
11952 {
11953 error (_("%s: failed to seek to next file name\n"), arch->file_name);
11954 return NULL;
11955 }
11956 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
11957 if (got != sizeof arch->arhdr)
11958 {
11959 error (_("%s: failed to read archive header\n"), arch->file_name);
11960 return NULL;
11961 }
11962 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
11963 {
11964 error (_("%s: did not find a valid archive header\n"), arch->file_name);
11965 return NULL;
11966 }
11967
11968 return get_archive_member_name (arch, nested_arch);
11969}
11970
11971/* Construct a string showing the name of the archive member, qualified
11972 with the name of the containing archive file. For thin archives, we
11973 use square brackets to denote the indirection. For nested archives,
11974 we show the qualified name of the external member inside the square
11975 brackets (e.g., "thin.a[normal.a(foo.o)]"). */
11976
11977static char *
11978make_qualified_name (struct archive_info * arch,
11979 struct archive_info * nested_arch,
11980 char * member_name)
11981{
11982 size_t len;
11983 char * name;
11984
11985 len = strlen (arch->file_name) + strlen (member_name) + 3;
11986 if (arch->is_thin_archive && arch->nested_member_origin != 0)
11987 len += strlen (nested_arch->file_name) + 2;
11988
3f5e193b 11989 name = (char *) malloc (len);
2cf0635d
NC
11990 if (name == NULL)
11991 {
11992 error (_("Out of memory\n"));
11993 return NULL;
11994 }
11995
11996 if (arch->is_thin_archive && arch->nested_member_origin != 0)
11997 snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name);
11998 else if (arch->is_thin_archive)
11999 snprintf (name, len, "%s[%s]", arch->file_name, member_name);
12000 else
12001 snprintf (name, len, "%s(%s)", arch->file_name, member_name);
12002
12003 return name;
12004}
12005
12006/* Process an ELF archive.
12007 On entry the file is positioned just after the ARMAG string. */
12008
12009static int
12010process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
12011{
12012 struct archive_info arch;
12013 struct archive_info nested_arch;
12014 size_t got;
12015 size_t file_name_size;
12016 int ret;
12017
12018 show_name = 1;
12019
12020 /* The ARCH structure is used to hold information about this archive. */
12021 arch.file_name = NULL;
12022 arch.file = NULL;
12023 arch.index_array = NULL;
12024 arch.sym_table = NULL;
12025 arch.longnames = NULL;
12026
12027 /* The NESTED_ARCH structure is used as a single-item cache of information
12028 about a nested archive (when members of a thin archive reside within
12029 another regular archive file). */
12030 nested_arch.file_name = NULL;
12031 nested_arch.file = NULL;
12032 nested_arch.index_array = NULL;
12033 nested_arch.sym_table = NULL;
12034 nested_arch.longnames = NULL;
12035
12036 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
12037 {
12038 ret = 1;
12039 goto out;
4145f1d5 12040 }
fb52b2f4 12041
4145f1d5
NC
12042 if (do_archive_index)
12043 {
2cf0635d 12044 if (arch.sym_table == NULL)
4145f1d5
NC
12045 error (_("%s: unable to dump the index as none was found\n"), file_name);
12046 else
12047 {
2cf0635d 12048 unsigned int i, l;
4145f1d5
NC
12049 unsigned long current_pos;
12050
12051 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 12052 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
12053 current_pos = ftell (file);
12054
2cf0635d 12055 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 12056 {
2cf0635d
NC
12057 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
12058 {
12059 char * member_name;
4145f1d5 12060
2cf0635d
NC
12061 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
12062
12063 if (member_name != NULL)
12064 {
12065 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
12066
12067 if (qualified_name != NULL)
12068 {
12069 printf (_("Binary %s contains:\n"), qualified_name);
12070 free (qualified_name);
12071 }
4145f1d5
NC
12072 }
12073 }
2cf0635d
NC
12074
12075 if (l >= arch.sym_size)
4145f1d5
NC
12076 {
12077 error (_("%s: end of the symbol table reached before the end of the index\n"),
12078 file_name);
cb8f3167 12079 break;
4145f1d5 12080 }
2cf0635d
NC
12081 printf ("\t%s\n", arch.sym_table + l);
12082 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
12083 }
12084
2cf0635d
NC
12085 if (l & 01)
12086 ++l;
12087 if (l < arch.sym_size)
4145f1d5
NC
12088 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
12089 file_name);
12090
4145f1d5
NC
12091 if (fseek (file, current_pos, SEEK_SET) != 0)
12092 {
12093 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
12094 ret = 1;
12095 goto out;
4145f1d5 12096 }
fb52b2f4 12097 }
4145f1d5
NC
12098
12099 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
12100 && !do_segments && !do_header && !do_dump && !do_version
12101 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 12102 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
12103 {
12104 ret = 0; /* Archive index only. */
12105 goto out;
12106 }
fb52b2f4
NC
12107 }
12108
12109 file_name_size = strlen (file_name);
d989285c 12110 ret = 0;
fb52b2f4
NC
12111
12112 while (1)
12113 {
2cf0635d
NC
12114 char * name;
12115 size_t namelen;
12116 char * qualified_name;
12117
12118 /* Read the next archive header. */
12119 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
12120 {
12121 error (_("%s: failed to seek to next archive header\n"), file_name);
12122 return 1;
12123 }
12124 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
12125 if (got != sizeof arch.arhdr)
12126 {
12127 if (got == 0)
12128 break;
12129 error (_("%s: failed to read archive header\n"), file_name);
12130 ret = 1;
12131 break;
12132 }
12133 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
12134 {
12135 error (_("%s: did not find a valid archive header\n"), arch.file_name);
12136 ret = 1;
12137 break;
12138 }
12139
12140 arch.next_arhdr_offset += sizeof arch.arhdr;
12141
12142 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
12143 if (archive_file_size & 01)
12144 ++archive_file_size;
12145
12146 name = get_archive_member_name (&arch, &nested_arch);
12147 if (name == NULL)
fb52b2f4 12148 {
0fd3a477 12149 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
12150 ret = 1;
12151 break;
fb52b2f4 12152 }
2cf0635d 12153 namelen = strlen (name);
fb52b2f4 12154
2cf0635d
NC
12155 qualified_name = make_qualified_name (&arch, &nested_arch, name);
12156 if (qualified_name == NULL)
fb52b2f4 12157 {
2cf0635d 12158 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
12159 ret = 1;
12160 break;
fb52b2f4
NC
12161 }
12162
2cf0635d
NC
12163 if (is_thin_archive && arch.nested_member_origin == 0)
12164 {
12165 /* This is a proxy for an external member of a thin archive. */
12166 FILE * member_file;
12167 char * member_file_name = adjust_relative_path (file_name, name, namelen);
12168 if (member_file_name == NULL)
12169 {
12170 ret = 1;
12171 break;
12172 }
12173
12174 member_file = fopen (member_file_name, "rb");
12175 if (member_file == NULL)
12176 {
12177 error (_("Input file '%s' is not readable.\n"), member_file_name);
12178 free (member_file_name);
12179 ret = 1;
12180 break;
12181 }
12182
12183 archive_file_offset = arch.nested_member_origin;
12184
12185 ret |= process_object (qualified_name, member_file);
12186
12187 fclose (member_file);
12188 free (member_file_name);
12189 }
12190 else if (is_thin_archive)
12191 {
12192 /* This is a proxy for a member of a nested archive. */
12193 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
12194
12195 /* The nested archive file will have been opened and setup by
12196 get_archive_member_name. */
12197 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
12198 {
12199 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
12200 ret = 1;
12201 break;
12202 }
12203
12204 ret |= process_object (qualified_name, nested_arch.file);
12205 }
12206 else
12207 {
12208 archive_file_offset = arch.next_arhdr_offset;
12209 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 12210
2cf0635d
NC
12211 ret |= process_object (qualified_name, file);
12212 }
fb52b2f4 12213
2cf0635d 12214 free (qualified_name);
fb52b2f4
NC
12215 }
12216
4145f1d5 12217 out:
2cf0635d
NC
12218 if (nested_arch.file != NULL)
12219 fclose (nested_arch.file);
12220 release_archive (&nested_arch);
12221 release_archive (&arch);
fb52b2f4 12222
d989285c 12223 return ret;
fb52b2f4
NC
12224}
12225
12226static int
2cf0635d 12227process_file (char * file_name)
fb52b2f4 12228{
2cf0635d 12229 FILE * file;
fb52b2f4
NC
12230 struct stat statbuf;
12231 char armag[SARMAG];
12232 int ret;
12233
12234 if (stat (file_name, &statbuf) < 0)
12235 {
f24ddbdd
NC
12236 if (errno == ENOENT)
12237 error (_("'%s': No such file\n"), file_name);
12238 else
12239 error (_("Could not locate '%s'. System error message: %s\n"),
12240 file_name, strerror (errno));
12241 return 1;
12242 }
12243
12244 if (! S_ISREG (statbuf.st_mode))
12245 {
12246 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
12247 return 1;
12248 }
12249
12250 file = fopen (file_name, "rb");
12251 if (file == NULL)
12252 {
f24ddbdd 12253 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
12254 return 1;
12255 }
12256
12257 if (fread (armag, SARMAG, 1, file) != 1)
12258 {
4145f1d5 12259 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
12260 fclose (file);
12261 return 1;
12262 }
12263
12264 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
12265 ret = process_archive (file_name, file, FALSE);
12266 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
12267 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
12268 else
12269 {
4145f1d5
NC
12270 if (do_archive_index)
12271 error (_("File %s is not an archive so its index cannot be displayed.\n"),
12272 file_name);
12273
fb52b2f4
NC
12274 rewind (file);
12275 archive_file_size = archive_file_offset = 0;
12276 ret = process_object (file_name, file);
12277 }
12278
12279 fclose (file);
12280
12281 return ret;
12282}
12283
252b5132
RH
12284#ifdef SUPPORT_DISASSEMBLY
12285/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 12286 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 12287 symbols. */
252b5132
RH
12288
12289void
2cf0635d 12290print_address (unsigned int addr, FILE * outfile)
252b5132
RH
12291{
12292 fprintf (outfile,"0x%8.8x", addr);
12293}
12294
e3c8793a 12295/* Needed by the i386 disassembler. */
252b5132
RH
12296void
12297db_task_printsym (unsigned int addr)
12298{
12299 print_address (addr, stderr);
12300}
12301#endif
12302
12303int
2cf0635d 12304main (int argc, char ** argv)
252b5132 12305{
ff78d6d6
L
12306 int err;
12307
252b5132
RH
12308#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
12309 setlocale (LC_MESSAGES, "");
3882b010
L
12310#endif
12311#if defined (HAVE_SETLOCALE)
12312 setlocale (LC_CTYPE, "");
252b5132
RH
12313#endif
12314 bindtextdomain (PACKAGE, LOCALEDIR);
12315 textdomain (PACKAGE);
12316
869b9d07
MM
12317 expandargv (&argc, &argv);
12318
252b5132
RH
12319 parse_args (argc, argv);
12320
18bd398b 12321 if (num_dump_sects > 0)
59f14fc0 12322 {
18bd398b 12323 /* Make a copy of the dump_sects array. */
3f5e193b
NC
12324 cmdline_dump_sects = (dump_type *)
12325 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 12326 if (cmdline_dump_sects == NULL)
591a748a 12327 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
12328 else
12329 {
09c11c86
NC
12330 memcpy (cmdline_dump_sects, dump_sects,
12331 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
12332 num_cmdline_dump_sects = num_dump_sects;
12333 }
12334 }
12335
18bd398b
NC
12336 if (optind < (argc - 1))
12337 show_name = 1;
12338
ff78d6d6 12339 err = 0;
252b5132 12340 while (optind < argc)
18bd398b 12341 err |= process_file (argv[optind++]);
252b5132
RH
12342
12343 if (dump_sects != NULL)
12344 free (dump_sects);
59f14fc0
AS
12345 if (cmdline_dump_sects != NULL)
12346 free (cmdline_dump_sects);
252b5132 12347
ff78d6d6 12348 return err;
252b5132 12349}