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