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