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