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