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