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