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