]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
*** empty log message ***
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
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
b2d38a17
NC
3533 /* Try to locate the .dynamic section. If there is
3534 a section header table, we can easily locate it. */
3535 if (section_headers != NULL)
3536 {
3537 Elf_Internal_Shdr *sec;
b2d38a17 3538
89fac5e3
RS
3539 sec = find_section (".dynamic");
3540 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3541 {
591a748a 3542 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3543 break;
3544 }
3545
42bb2e33
AM
3546 if (sec->sh_type == SHT_NOBITS)
3547 break;
3548
b2d38a17
NC
3549 dynamic_addr = sec->sh_offset;
3550 dynamic_size = sec->sh_size;
3551
3552 if (dynamic_addr < segment->p_offset
3553 || dynamic_addr > segment->p_offset + segment->p_filesz)
591a748a 3554 warn (_("the .dynamic section is not contained within the dynamic segment\n"));
b2d38a17 3555 else if (dynamic_addr > segment->p_offset)
591a748a 3556 warn (_("the .dynamic section is not the first section in the dynamic segment.\n"));
b2d38a17
NC
3557 }
3558 else
3559 {
3560 /* Otherwise, we can only assume that the .dynamic
3561 section is the first section in the DYNAMIC segment. */
3562 dynamic_addr = segment->p_offset;
3563 dynamic_size = segment->p_filesz;
3564 }
252b5132
RH
3565 break;
3566
3567 case PT_INTERP:
fb52b2f4
NC
3568 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3569 SEEK_SET))
252b5132
RH
3570 error (_("Unable to find program interpreter name\n"));
3571 else
3572 {
f8eae8b2
L
3573 char fmt [32];
3574 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3575
3576 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3577 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3578
252b5132 3579 program_interpreter[0] = 0;
7bd7b3ef
AM
3580 if (fscanf (file, fmt, program_interpreter) <= 0)
3581 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3582
3583 if (do_segments)
3584 printf (_("\n [Requesting program interpreter: %s]"),
3585 program_interpreter);
3586 }
3587 break;
3588 }
3589
3590 if (do_segments)
3591 putc ('\n', stdout);
3592 }
3593
c256ffe7 3594 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3595 {
3596 printf (_("\n Section to Segment mapping:\n"));
3597 printf (_(" Segment Sections...\n"));
3598
252b5132
RH
3599 for (i = 0; i < elf_header.e_phnum; i++)
3600 {
9ad5cbcf 3601 unsigned int j;
b34976b6 3602 Elf_Internal_Shdr *section;
252b5132
RH
3603
3604 segment = program_headers + i;
3605 section = section_headers;
3606
3607 printf (" %2.2d ", i);
3608
b34976b6 3609 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3610 {
84d1d650 3611 if (ELF_IS_SECTION_IN_SEGMENT_MEMORY(section, segment))
252b5132
RH
3612 printf ("%s ", SECTION_NAME (section));
3613 }
3614
3615 putc ('\n',stdout);
3616 }
3617 }
3618
252b5132
RH
3619 return 1;
3620}
3621
3622
d93f0186
NC
3623/* Find the file offset corresponding to VMA by using the program headers. */
3624
3625static long
d3ba0551 3626offset_from_vma (FILE *file, bfd_vma vma, bfd_size_type size)
d93f0186
NC
3627{
3628 Elf_Internal_Phdr *seg;
3629
3630 if (! get_program_headers (file))
3631 {
3632 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3633 return (long) vma;
3634 }
3635
3636 for (seg = program_headers;
3637 seg < program_headers + elf_header.e_phnum;
3638 ++seg)
3639 {
3640 if (seg->p_type != PT_LOAD)
3641 continue;
3642
3643 if (vma >= (seg->p_vaddr & -seg->p_align)
3644 && vma + size <= seg->p_vaddr + seg->p_filesz)
3645 return vma - seg->p_vaddr + seg->p_offset;
3646 }
3647
3648 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
3649 (long) vma);
3650 return (long) vma;
3651}
3652
3653
252b5132 3654static int
d3ba0551 3655get_32bit_section_headers (FILE *file, unsigned int num)
252b5132 3656{
b34976b6
AM
3657 Elf32_External_Shdr *shdrs;
3658 Elf_Internal_Shdr *internal;
3659 unsigned int i;
252b5132 3660
d3ba0551 3661 shdrs = get_data (NULL, file, elf_header.e_shoff,
c256ffe7 3662 elf_header.e_shentsize, num, _("section headers"));
a6e9f9df
AM
3663 if (!shdrs)
3664 return 0;
252b5132 3665
c256ffe7 3666 section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
252b5132
RH
3667
3668 if (section_headers == NULL)
3669 {
3670 error (_("Out of memory\n"));
3671 return 0;
3672 }
3673
3674 for (i = 0, internal = section_headers;
560f3c1c 3675 i < num;
b34976b6 3676 i++, internal++)
252b5132
RH
3677 {
3678 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3679 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3680 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3681 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3682 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3683 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3684 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3685 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3686 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3687 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3688 }
3689
3690 free (shdrs);
3691
3692 return 1;
3693}
3694
9ea033b2 3695static int
d3ba0551 3696get_64bit_section_headers (FILE *file, unsigned int num)
9ea033b2 3697{
b34976b6
AM
3698 Elf64_External_Shdr *shdrs;
3699 Elf_Internal_Shdr *internal;
3700 unsigned int i;
9ea033b2 3701
d3ba0551 3702 shdrs = get_data (NULL, file, elf_header.e_shoff,
c256ffe7 3703 elf_header.e_shentsize, num, _("section headers"));
a6e9f9df
AM
3704 if (!shdrs)
3705 return 0;
9ea033b2 3706
c256ffe7 3707 section_headers = cmalloc (num, sizeof (Elf_Internal_Shdr));
9ea033b2
NC
3708
3709 if (section_headers == NULL)
3710 {
3711 error (_("Out of memory\n"));
3712 return 0;
3713 }
3714
3715 for (i = 0, internal = section_headers;
560f3c1c 3716 i < num;
b34976b6 3717 i++, internal++)
9ea033b2
NC
3718 {
3719 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3720 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
3721 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3722 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3723 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3724 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
3725 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3726 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3727 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3728 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3729 }
3730
3731 free (shdrs);
3732
3733 return 1;
3734}
3735
252b5132 3736static Elf_Internal_Sym *
d3ba0551 3737get_32bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section)
252b5132 3738{
9ad5cbcf 3739 unsigned long number;
b34976b6 3740 Elf32_External_Sym *esyms;
9ad5cbcf 3741 Elf_External_Sym_Shndx *shndx;
b34976b6
AM
3742 Elf_Internal_Sym *isyms;
3743 Elf_Internal_Sym *psym;
3744 unsigned int j;
252b5132 3745
c256ffe7 3746 esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 3747 _("symbols"));
a6e9f9df
AM
3748 if (!esyms)
3749 return NULL;
252b5132 3750
9ad5cbcf
AM
3751 shndx = NULL;
3752 if (symtab_shndx_hdr != NULL
3753 && (symtab_shndx_hdr->sh_link
3754 == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
3755 {
d3ba0551 3756 shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
c256ffe7 3757 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
9ad5cbcf
AM
3758 if (!shndx)
3759 {
3760 free (esyms);
3761 return NULL;
3762 }
3763 }
3764
3765 number = section->sh_size / section->sh_entsize;
c256ffe7 3766 isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
3767
3768 if (isyms == NULL)
3769 {
3770 error (_("Out of memory\n"));
9ad5cbcf
AM
3771 if (shndx)
3772 free (shndx);
252b5132 3773 free (esyms);
252b5132
RH
3774 return NULL;
3775 }
3776
3777 for (j = 0, psym = isyms;
3778 j < number;
b34976b6 3779 j++, psym++)
252b5132
RH
3780 {
3781 psym->st_name = BYTE_GET (esyms[j].st_name);
3782 psym->st_value = BYTE_GET (esyms[j].st_value);
3783 psym->st_size = BYTE_GET (esyms[j].st_size);
3784 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
9ad5cbcf
AM
3785 if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
3786 psym->st_shndx
3787 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
252b5132
RH
3788 psym->st_info = BYTE_GET (esyms[j].st_info);
3789 psym->st_other = BYTE_GET (esyms[j].st_other);
3790 }
3791
9ad5cbcf
AM
3792 if (shndx)
3793 free (shndx);
252b5132
RH
3794 free (esyms);
3795
3796 return isyms;
3797}
3798
9ea033b2 3799static Elf_Internal_Sym *
d3ba0551 3800get_64bit_elf_symbols (FILE *file, Elf_Internal_Shdr *section)
9ea033b2 3801{
9ad5cbcf 3802 unsigned long number;
b34976b6 3803 Elf64_External_Sym *esyms;
9ad5cbcf 3804 Elf_External_Sym_Shndx *shndx;
b34976b6
AM
3805 Elf_Internal_Sym *isyms;
3806 Elf_Internal_Sym *psym;
3807 unsigned int j;
9ea033b2 3808
c256ffe7 3809 esyms = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 3810 _("symbols"));
a6e9f9df
AM
3811 if (!esyms)
3812 return NULL;
9ea033b2 3813
9ad5cbcf
AM
3814 shndx = NULL;
3815 if (symtab_shndx_hdr != NULL
3816 && (symtab_shndx_hdr->sh_link
3817 == (unsigned long) SECTION_HEADER_NUM (section - section_headers)))
3818 {
d3ba0551 3819 shndx = get_data (NULL, file, symtab_shndx_hdr->sh_offset,
c256ffe7 3820 1, symtab_shndx_hdr->sh_size, _("symtab shndx"));
9ad5cbcf
AM
3821 if (!shndx)
3822 {
3823 free (esyms);
3824 return NULL;
3825 }
3826 }
3827
3828 number = section->sh_size / section->sh_entsize;
c256ffe7 3829 isyms = cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
3830
3831 if (isyms == NULL)
3832 {
3833 error (_("Out of memory\n"));
9ad5cbcf
AM
3834 if (shndx)
3835 free (shndx);
9ea033b2 3836 free (esyms);
9ea033b2
NC
3837 return NULL;
3838 }
3839
3840 for (j = 0, psym = isyms;
3841 j < number;
b34976b6 3842 j++, psym++)
9ea033b2
NC
3843 {
3844 psym->st_name = BYTE_GET (esyms[j].st_name);
3845 psym->st_info = BYTE_GET (esyms[j].st_info);
3846 psym->st_other = BYTE_GET (esyms[j].st_other);
3847 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
9ad5cbcf
AM
3848 if (psym->st_shndx == SHN_XINDEX && shndx != NULL)
3849 psym->st_shndx
3850 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
66543521
AM
3851 psym->st_value = BYTE_GET (esyms[j].st_value);
3852 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
3853 }
3854
9ad5cbcf
AM
3855 if (shndx)
3856 free (shndx);
9ea033b2
NC
3857 free (esyms);
3858
3859 return isyms;
3860}
3861
d1133906 3862static const char *
d3ba0551 3863get_elf_section_flags (bfd_vma sh_flags)
d1133906 3864{
5477e8a0 3865 static char buff[1024];
e9e44622 3866 char *p = buff;
8d5ff12c
L
3867 int field_size = is_32bit_elf ? 8 : 16;
3868 int index, size = sizeof (buff) - (field_size + 4 + 1);
3869 bfd_vma os_flags = 0;
3870 bfd_vma proc_flags = 0;
3871 bfd_vma unknown_flags = 0;
5477e8a0
L
3872 const struct
3873 {
3874 const char *str;
3875 int len;
3876 }
3877 flags [] =
3878 {
3879 { "WRITE", 5 },
3880 { "ALLOC", 5 },
3881 { "EXEC", 4 },
3882 { "MERGE", 5 },
3883 { "STRINGS", 7 },
3884 { "INFO LINK", 9 },
3885 { "LINK ORDER", 10 },
3886 { "OS NONCONF", 10 },
3887 { "GROUP", 5 },
3888 { "TLS", 3 }
3889 };
3890
3891 if (do_section_details)
3892 {
8d5ff12c
L
3893 sprintf (buff, "[%*.*lx]: ",
3894 field_size, field_size, (unsigned long) sh_flags);
3895 p += field_size + 4;
5477e8a0 3896 }
76da6bbe 3897
d1133906
NC
3898 while (sh_flags)
3899 {
3900 bfd_vma flag;
3901
3902 flag = sh_flags & - sh_flags;
3903 sh_flags &= ~ flag;
76da6bbe 3904
5477e8a0 3905 if (do_section_details)
d1133906 3906 {
5477e8a0
L
3907 switch (flag)
3908 {
3909 case SHF_WRITE: index = 0; break;
3910 case SHF_ALLOC: index = 1; break;
3911 case SHF_EXECINSTR: index = 2; break;
3912 case SHF_MERGE: index = 3; break;
3913 case SHF_STRINGS: index = 4; break;
3914 case SHF_INFO_LINK: index = 5; break;
3915 case SHF_LINK_ORDER: index = 6; break;
3916 case SHF_OS_NONCONFORMING: index = 7; break;
3917 case SHF_GROUP: index = 8; break;
3918 case SHF_TLS: index = 9; break;
76da6bbe 3919
5477e8a0
L
3920 default:
3921 index = -1;
3922 break;
3923 }
3924
5477e8a0
L
3925 if (index != -1)
3926 {
8d5ff12c
L
3927 if (p != buff + field_size + 4)
3928 {
3929 if (size < (10 + 2))
3930 abort ();
3931 size -= 2;
3932 *p++ = ',';
3933 *p++ = ' ';
3934 }
3935
5477e8a0
L
3936 size -= flags [index].len;
3937 p = stpcpy (p, flags [index].str);
3938 }
3b22753a 3939 else if (flag & SHF_MASKOS)
8d5ff12c 3940 os_flags |= flag;
d1133906 3941 else if (flag & SHF_MASKPROC)
8d5ff12c 3942 proc_flags |= flag;
d1133906 3943 else
8d5ff12c 3944 unknown_flags |= flag;
5477e8a0
L
3945 }
3946 else
3947 {
3948 switch (flag)
3949 {
3950 case SHF_WRITE: *p = 'W'; break;
3951 case SHF_ALLOC: *p = 'A'; break;
3952 case SHF_EXECINSTR: *p = 'X'; break;
3953 case SHF_MERGE: *p = 'M'; break;
3954 case SHF_STRINGS: *p = 'S'; break;
3955 case SHF_INFO_LINK: *p = 'I'; break;
3956 case SHF_LINK_ORDER: *p = 'L'; break;
3957 case SHF_OS_NONCONFORMING: *p = 'O'; break;
3958 case SHF_GROUP: *p = 'G'; break;
3959 case SHF_TLS: *p = 'T'; break;
3960
3961 default:
3962 if (elf_header.e_machine == EM_X86_64
3963 && flag == SHF_X86_64_LARGE)
3964 *p = 'l';
3965 else if (flag & SHF_MASKOS)
3966 {
3967 *p = 'o';
3968 sh_flags &= ~ SHF_MASKOS;
3969 }
3970 else if (flag & SHF_MASKPROC)
3971 {
3972 *p = 'p';
3973 sh_flags &= ~ SHF_MASKPROC;
3974 }
3975 else
3976 *p = 'x';
3977 break;
3978 }
3979 p++;
d1133906
NC
3980 }
3981 }
76da6bbe 3982
8d5ff12c
L
3983 if (do_section_details)
3984 {
3985 if (os_flags)
3986 {
3987 size -= 5 + field_size;
3988 if (p != buff + field_size + 4)
3989 {
3990 if (size < (2 + 1))
3991 abort ();
3992 size -= 2;
3993 *p++ = ',';
3994 *p++ = ' ';
3995 }
3996 sprintf (p, "OS (%*.*lx)", field_size, field_size,
3997 (unsigned long) os_flags);
3998 p += 5 + field_size;
3999 }
4000 if (proc_flags)
4001 {
4002 size -= 7 + field_size;
4003 if (p != buff + field_size + 4)
4004 {
4005 if (size < (2 + 1))
4006 abort ();
4007 size -= 2;
4008 *p++ = ',';
4009 *p++ = ' ';
4010 }
4011 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4012 (unsigned long) proc_flags);
4013 p += 7 + field_size;
4014 }
4015 if (unknown_flags)
4016 {
4017 size -= 10 + field_size;
4018 if (p != buff + field_size + 4)
4019 {
4020 if (size < (2 + 1))
4021 abort ();
4022 size -= 2;
4023 *p++ = ',';
4024 *p++ = ' ';
4025 }
4026 sprintf (p, "UNKNOWN (%*.*lx)", field_size, field_size,
4027 (unsigned long) unknown_flags);
4028 p += 10 + field_size;
4029 }
4030 }
4031
e9e44622 4032 *p = '\0';
d1133906
NC
4033 return buff;
4034}
4035
252b5132 4036static int
d3ba0551 4037process_section_headers (FILE *file)
252b5132 4038{
b34976b6
AM
4039 Elf_Internal_Shdr *section;
4040 unsigned int i;
252b5132
RH
4041
4042 section_headers = NULL;
4043
4044 if (elf_header.e_shnum == 0)
4045 {
4046 if (do_sections)
4047 printf (_("\nThere are no sections in this file.\n"));
4048
4049 return 1;
4050 }
4051
4052 if (do_sections && !do_header)
9ea033b2 4053 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4054 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4055
9ea033b2
NC
4056 if (is_32bit_elf)
4057 {
560f3c1c 4058 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4059 return 0;
4060 }
560f3c1c 4061 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4062 return 0;
4063
4064 /* Read in the string table, so that we have names to display. */
0b49d371
NC
4065 if (elf_header.e_shstrndx != SHN_UNDEF
4066 && SECTION_HEADER_INDEX (elf_header.e_shstrndx) < elf_header.e_shnum)
252b5132 4067 {
c256ffe7 4068 section = SECTION_HEADER (elf_header.e_shstrndx);
d40ac9bd 4069
c256ffe7
JJ
4070 if (section->sh_size != 0)
4071 {
4072 string_table = get_data (NULL, file, section->sh_offset,
4073 1, section->sh_size, _("string table"));
0de14b54 4074
c256ffe7
JJ
4075 string_table_length = string_table != NULL ? section->sh_size : 0;
4076 }
252b5132
RH
4077 }
4078
4079 /* Scan the sections for the dynamic symbol table
e3c8793a 4080 and dynamic string table and debug sections. */
252b5132
RH
4081 dynamic_symbols = NULL;
4082 dynamic_strings = NULL;
4083 dynamic_syminfo = NULL;
f1ef08cb 4084 symtab_shndx_hdr = NULL;
103f02d3 4085
89fac5e3
RS
4086 eh_addr_size = is_32bit_elf ? 4 : 8;
4087 switch (elf_header.e_machine)
4088 {
4089 case EM_MIPS:
4090 case EM_MIPS_RS3_LE:
4091 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4092 FDE addresses. However, the ABI also has a semi-official ILP32
4093 variant for which the normal FDE address size rules apply.
4094
4095 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4096 section, where XX is the size of longs in bits. Unfortunately,
4097 earlier compilers provided no way of distinguishing ILP32 objects
4098 from LP64 objects, so if there's any doubt, we should assume that
4099 the official LP64 form is being used. */
4100 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4101 && find_section (".gcc_compiled_long32") == NULL)
4102 eh_addr_size = 8;
4103 break;
0f56a26a
DD
4104
4105 case EM_H8_300:
4106 case EM_H8_300H:
4107 switch (elf_header.e_flags & EF_H8_MACH)
4108 {
4109 case E_H8_MACH_H8300:
4110 case E_H8_MACH_H8300HN:
4111 case E_H8_MACH_H8300SN:
4112 case E_H8_MACH_H8300SXN:
4113 eh_addr_size = 2;
4114 break;
4115 case E_H8_MACH_H8300H:
4116 case E_H8_MACH_H8300S:
4117 case E_H8_MACH_H8300SX:
4118 eh_addr_size = 4;
4119 break;
4120 }
89fac5e3
RS
4121 }
4122
08d8fa11
JJ
4123#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4124 do \
4125 { \
4126 size_t expected_entsize \
4127 = is_32bit_elf ? size32 : size64; \
4128 if (section->sh_entsize != expected_entsize) \
4129 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4130 i, (unsigned long int) section->sh_entsize, \
4131 (unsigned long int) expected_entsize); \
4132 section->sh_entsize = expected_entsize; \
4133 } \
4134 while (0)
4135#define CHECK_ENTSIZE(section, i, type) \
4136 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4137 sizeof (Elf64_External_##type))
4138
252b5132
RH
4139 for (i = 0, section = section_headers;
4140 i < elf_header.e_shnum;
b34976b6 4141 i++, section++)
252b5132 4142 {
b34976b6 4143 char *name = SECTION_NAME (section);
252b5132
RH
4144
4145 if (section->sh_type == SHT_DYNSYM)
4146 {
4147 if (dynamic_symbols != NULL)
4148 {
4149 error (_("File contains multiple dynamic symbol tables\n"));
4150 continue;
4151 }
4152
08d8fa11 4153 CHECK_ENTSIZE (section, i, Sym);
19936277 4154 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4155 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4156 }
4157 else if (section->sh_type == SHT_STRTAB
18bd398b 4158 && streq (name, ".dynstr"))
252b5132
RH
4159 {
4160 if (dynamic_strings != NULL)
4161 {
4162 error (_("File contains multiple dynamic string tables\n"));
4163 continue;
4164 }
4165
d3ba0551 4166 dynamic_strings = get_data (NULL, file, section->sh_offset,
c256ffe7 4167 1, section->sh_size, _("dynamic strings"));
d79b3d50 4168 dynamic_strings_length = section->sh_size;
252b5132 4169 }
9ad5cbcf
AM
4170 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4171 {
4172 if (symtab_shndx_hdr != NULL)
4173 {
4174 error (_("File contains multiple symtab shndx tables\n"));
4175 continue;
4176 }
4177 symtab_shndx_hdr = section;
4178 }
08d8fa11
JJ
4179 else if (section->sh_type == SHT_SYMTAB)
4180 CHECK_ENTSIZE (section, i, Sym);
4181 else if (section->sh_type == SHT_GROUP)
4182 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4183 else if (section->sh_type == SHT_REL)
4184 CHECK_ENTSIZE (section, i, Rel);
4185 else if (section->sh_type == SHT_RELA)
4186 CHECK_ENTSIZE (section, i, Rela);
252b5132 4187 else if ((do_debugging || do_debug_info || do_debug_abbrevs
31b6fca6 4188 || do_debug_lines || do_debug_pubnames || do_debug_aranges
a2f14207 4189 || do_debug_frames || do_debug_macinfo || do_debug_str
18bd398b 4190 || do_debug_loc || do_debug_ranges)
0112cd26 4191 && const_strneq (name, ".debug_"))
252b5132
RH
4192 {
4193 name += 7;
4194
4195 if (do_debugging
18bd398b
NC
4196 || (do_debug_info && streq (name, "info"))
4197 || (do_debug_abbrevs && streq (name, "abbrev"))
4198 || (do_debug_lines && streq (name, "line"))
4199 || (do_debug_pubnames && streq (name, "pubnames"))
4200 || (do_debug_aranges && streq (name, "aranges"))
4201 || (do_debug_ranges && streq (name, "ranges"))
4202 || (do_debug_frames && streq (name, "frame"))
4203 || (do_debug_macinfo && streq (name, "macinfo"))
4204 || (do_debug_str && streq (name, "str"))
4205 || (do_debug_loc && streq (name, "loc"))
252b5132 4206 )
09c11c86 4207 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4208 }
09fd7e38
JM
4209 /* linkonce section to be combined with .debug_info at link time. */
4210 else if ((do_debugging || do_debug_info)
0112cd26 4211 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4212 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4213 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4214 request_dump_bynumber (i, DEBUG_DUMP);
252b5132
RH
4215 }
4216
4217 if (! do_sections)
4218 return 1;
4219
3a1a2036
NC
4220 if (elf_header.e_shnum > 1)
4221 printf (_("\nSection Headers:\n"));
4222 else
4223 printf (_("\nSection Header:\n"));
76da6bbe 4224
f7a99963 4225 if (is_32bit_elf)
595cf52e 4226 {
5477e8a0 4227 if (do_section_details)
595cf52e
L
4228 {
4229 printf (_(" [Nr] Name\n"));
5477e8a0 4230 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4231 }
4232 else
4233 printf
4234 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4235 }
d974e256 4236 else if (do_wide)
595cf52e 4237 {
5477e8a0 4238 if (do_section_details)
595cf52e
L
4239 {
4240 printf (_(" [Nr] Name\n"));
5477e8a0 4241 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4242 }
4243 else
4244 printf
4245 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4246 }
f7a99963
NC
4247 else
4248 {
5477e8a0 4249 if (do_section_details)
595cf52e
L
4250 {
4251 printf (_(" [Nr] Name\n"));
5477e8a0
L
4252 printf (_(" Type Address Offset Link\n"));
4253 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4254 }
4255 else
4256 {
4257 printf (_(" [Nr] Name Type Address Offset\n"));
4258 printf (_(" Size EntSize Flags Link Info Align\n"));
4259 }
f7a99963 4260 }
252b5132 4261
5477e8a0
L
4262 if (do_section_details)
4263 printf (_(" Flags\n"));
4264
252b5132
RH
4265 for (i = 0, section = section_headers;
4266 i < elf_header.e_shnum;
b34976b6 4267 i++, section++)
252b5132 4268 {
5477e8a0 4269 if (do_section_details)
595cf52e
L
4270 {
4271 printf (" [%2u] %s\n",
4272 SECTION_HEADER_NUM (i),
4273 SECTION_NAME (section));
4274 if (is_32bit_elf || do_wide)
4275 printf (" %-15.15s ",
4276 get_section_type_name (section->sh_type));
4277 }
4278 else
4279 printf (" [%2u] %-17.17s %-15.15s ",
4280 SECTION_HEADER_NUM (i),
4281 SECTION_NAME (section),
4282 get_section_type_name (section->sh_type));
252b5132 4283
f7a99963
NC
4284 if (is_32bit_elf)
4285 {
4286 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4287
f7a99963
NC
4288 printf ( " %6.6lx %6.6lx %2.2lx",
4289 (unsigned long) section->sh_offset,
4290 (unsigned long) section->sh_size,
4291 (unsigned long) section->sh_entsize);
d1133906 4292
5477e8a0
L
4293 if (do_section_details)
4294 fputs (" ", stdout);
4295 else
4296 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4297
f2da459f 4298 printf ("%2ld %3lu %2ld\n",
f7a99963
NC
4299 (unsigned long) section->sh_link,
4300 (unsigned long) section->sh_info,
4301 (unsigned long) section->sh_addralign);
4302 }
d974e256
JJ
4303 else if (do_wide)
4304 {
4305 print_vma (section->sh_addr, LONG_HEX);
4306
4307 if ((long) section->sh_offset == section->sh_offset)
4308 printf (" %6.6lx", (unsigned long) section->sh_offset);
4309 else
4310 {
4311 putchar (' ');
4312 print_vma (section->sh_offset, LONG_HEX);
4313 }
4314
4315 if ((unsigned long) section->sh_size == section->sh_size)
4316 printf (" %6.6lx", (unsigned long) section->sh_size);
4317 else
4318 {
4319 putchar (' ');
4320 print_vma (section->sh_size, LONG_HEX);
4321 }
4322
4323 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4324 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4325 else
4326 {
4327 putchar (' ');
4328 print_vma (section->sh_entsize, LONG_HEX);
4329 }
4330
5477e8a0
L
4331 if (do_section_details)
4332 fputs (" ", stdout);
4333 else
4334 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4335
f2da459f 4336 printf ("%2ld %3lu ",
d974e256
JJ
4337 (unsigned long) section->sh_link,
4338 (unsigned long) section->sh_info);
4339
4340 if ((unsigned long) section->sh_addralign == section->sh_addralign)
4341 printf ("%2ld\n", (unsigned long) section->sh_addralign);
4342 else
4343 {
4344 print_vma (section->sh_addralign, DEC);
4345 putchar ('\n');
4346 }
4347 }
5477e8a0 4348 else if (do_section_details)
595cf52e 4349 {
5477e8a0 4350 printf (" %-15.15s ",
595cf52e 4351 get_section_type_name (section->sh_type));
595cf52e
L
4352 print_vma (section->sh_addr, LONG_HEX);
4353 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4354 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4355 else
4356 {
4357 printf (" ");
4358 print_vma (section->sh_offset, LONG_HEX);
4359 }
5477e8a0 4360 printf (" %ld\n ", (unsigned long) section->sh_link);
595cf52e 4361 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4362 putchar (' ');
595cf52e
L
4363 print_vma (section->sh_entsize, LONG_HEX);
4364
5477e8a0 4365 printf (" %-16lu %ld\n",
595cf52e
L
4366 (unsigned long) section->sh_info,
4367 (unsigned long) section->sh_addralign);
4368 }
f7a99963
NC
4369 else
4370 {
4371 putchar (' ');
4372 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4373 if ((long) section->sh_offset == section->sh_offset)
4374 printf (" %8.8lx", (unsigned long) section->sh_offset);
4375 else
4376 {
4377 printf (" ");
4378 print_vma (section->sh_offset, LONG_HEX);
4379 }
f7a99963
NC
4380 printf ("\n ");
4381 print_vma (section->sh_size, LONG_HEX);
4382 printf (" ");
4383 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4384
d1133906 4385 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4386
f2da459f 4387 printf (" %2ld %3lu %ld\n",
f7a99963
NC
4388 (unsigned long) section->sh_link,
4389 (unsigned long) section->sh_info,
4390 (unsigned long) section->sh_addralign);
4391 }
5477e8a0
L
4392
4393 if (do_section_details)
4394 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4395 }
4396
5477e8a0
L
4397 if (!do_section_details)
4398 printf (_("Key to Flags:\n\
e3c8793a
NC
4399 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
4400 I (info), L (link order), G (group), x (unknown)\n\
4401 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 4402
252b5132
RH
4403 return 1;
4404}
4405
f5842774
L
4406static const char *
4407get_group_flags (unsigned int flags)
4408{
4409 static char buff[32];
4410 switch (flags)
4411 {
4412 case GRP_COMDAT:
4413 return "COMDAT";
4414
4415 default:
e9e44622 4416 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x]"), flags);
f5842774
L
4417 break;
4418 }
4419 return buff;
4420}
4421
4422static int
4423process_section_groups (FILE *file)
4424{
4425 Elf_Internal_Shdr *section;
4426 unsigned int i;
e4b17d5c 4427 struct group *group;
d1f5c6e3
L
4428 Elf_Internal_Shdr *symtab_sec, *strtab_sec;
4429 Elf_Internal_Sym *symtab;
4430 char *strtab;
c256ffe7 4431 size_t strtab_size;
d1f5c6e3
L
4432
4433 /* Don't process section groups unless needed. */
4434 if (!do_unwind && !do_section_groups)
4435 return 1;
f5842774
L
4436
4437 if (elf_header.e_shnum == 0)
4438 {
4439 if (do_section_groups)
d1f5c6e3 4440 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
4441
4442 return 1;
4443 }
4444
4445 if (section_headers == NULL)
4446 {
4447 error (_("Section headers are not available!\n"));
4448 abort ();
4449 }
4450
e4b17d5c
L
4451 section_headers_groups = calloc (elf_header.e_shnum,
4452 sizeof (struct group *));
4453
4454 if (section_headers_groups == NULL)
4455 {
4456 error (_("Out of memory\n"));
4457 return 0;
4458 }
4459
f5842774 4460 /* Scan the sections for the group section. */
d1f5c6e3 4461 group_count = 0;
f5842774
L
4462 for (i = 0, section = section_headers;
4463 i < elf_header.e_shnum;
4464 i++, section++)
e4b17d5c
L
4465 if (section->sh_type == SHT_GROUP)
4466 group_count++;
4467
d1f5c6e3
L
4468 if (group_count == 0)
4469 {
4470 if (do_section_groups)
4471 printf (_("\nThere are no section groups in this file.\n"));
4472
4473 return 1;
4474 }
4475
e4b17d5c
L
4476 section_groups = calloc (group_count, sizeof (struct group));
4477
4478 if (section_groups == NULL)
4479 {
4480 error (_("Out of memory\n"));
4481 return 0;
4482 }
4483
d1f5c6e3
L
4484 symtab_sec = NULL;
4485 strtab_sec = NULL;
4486 symtab = NULL;
4487 strtab = NULL;
c256ffe7 4488 strtab_size = 0;
e4b17d5c
L
4489 for (i = 0, section = section_headers, group = section_groups;
4490 i < elf_header.e_shnum;
4491 i++, section++)
f5842774
L
4492 {
4493 if (section->sh_type == SHT_GROUP)
4494 {
4495 char *name = SECTION_NAME (section);
dc3c06c2
AM
4496 char *group_name;
4497 unsigned char *start, *indices;
f5842774 4498 unsigned int entry, j, size;
d1f5c6e3 4499 Elf_Internal_Shdr *sec;
f5842774 4500 Elf_Internal_Sym *sym;
f5842774
L
4501
4502 /* Get the symbol table. */
c256ffe7
JJ
4503 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum
4504 || ((sec = SECTION_HEADER (section->sh_link))->sh_type
4505 != SHT_SYMTAB))
f5842774
L
4506 {
4507 error (_("Bad sh_link in group section `%s'\n"), name);
4508 continue;
4509 }
d1f5c6e3
L
4510
4511 if (symtab_sec != sec)
4512 {
4513 symtab_sec = sec;
4514 if (symtab)
4515 free (symtab);
4516 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4517 }
f5842774
L
4518
4519 sym = symtab + section->sh_info;
4520
4521 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4522 {
4523 bfd_vma sec_index = SECTION_HEADER_INDEX (sym->st_shndx);
4524 if (sec_index == 0)
4525 {
4526 error (_("Bad sh_info in group section `%s'\n"), name);
4527 continue;
4528 }
ba2685cc 4529
f5842774 4530 group_name = SECTION_NAME (section_headers + sec_index);
c256ffe7
JJ
4531 strtab_sec = NULL;
4532 if (strtab)
4533 free (strtab);
f5842774 4534 strtab = NULL;
c256ffe7 4535 strtab_size = 0;
f5842774
L
4536 }
4537 else
4538 {
4539 /* Get the string table. */
c256ffe7
JJ
4540 if (SECTION_HEADER_INDEX (symtab_sec->sh_link)
4541 >= elf_header.e_shnum)
4542 {
4543 strtab_sec = NULL;
4544 if (strtab)
4545 free (strtab);
4546 strtab = NULL;
4547 strtab_size = 0;
4548 }
4549 else if (strtab_sec
4550 != (sec = SECTION_HEADER (symtab_sec->sh_link)))
d1f5c6e3
L
4551 {
4552 strtab_sec = sec;
4553 if (strtab)
4554 free (strtab);
4555 strtab = get_data (NULL, file, strtab_sec->sh_offset,
c256ffe7 4556 1, strtab_sec->sh_size,
d1f5c6e3 4557 _("string table"));
c256ffe7 4558 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 4559 }
c256ffe7
JJ
4560 group_name = sym->st_name < strtab_size
4561 ? strtab + sym->st_name : "<corrupt>";
f5842774
L
4562 }
4563
4564 start = get_data (NULL, file, section->sh_offset,
c256ffe7 4565 1, section->sh_size, _("section data"));
f5842774
L
4566
4567 indices = start;
4568 size = (section->sh_size / section->sh_entsize) - 1;
4569 entry = byte_get (indices, 4);
4570 indices += 4;
e4b17d5c
L
4571
4572 if (do_section_groups)
4573 {
391cb864
L
4574 printf ("\n%s group section [%5u] `%s' [%s] contains %u sections:\n",
4575 get_group_flags (entry), i, name, group_name, size);
ba2685cc 4576
e4b17d5c
L
4577 printf (_(" [Index] Name\n"));
4578 }
4579
4580 group->group_index = i;
4581
f5842774
L
4582 for (j = 0; j < size; j++)
4583 {
e4b17d5c
L
4584 struct group_list *g;
4585
f5842774
L
4586 entry = byte_get (indices, 4);
4587 indices += 4;
4588
c256ffe7 4589 if (SECTION_HEADER_INDEX (entry) >= elf_header.e_shnum)
391cb864
L
4590 {
4591 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
4592 entry, i, elf_header.e_shnum - 1);
4593 continue;
4594 }
4595 else if (entry >= SHN_LORESERVE && entry <= SHN_HIRESERVE)
4596 {
4597 error (_("invalid section [%5u] in group section [%5u]\n"),
4598 entry, i);
4599 continue;
4600 }
4601
e4b17d5c
L
4602 if (section_headers_groups [SECTION_HEADER_INDEX (entry)]
4603 != NULL)
4604 {
d1f5c6e3
L
4605 if (entry)
4606 {
391cb864
L
4607 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
4608 entry, i,
d1f5c6e3
L
4609 section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
4610 continue;
4611 }
4612 else
4613 {
4614 /* Intel C/C++ compiler may put section 0 in a
4615 section group. We just warn it the first time
4616 and ignore it afterwards. */
4617 static int warned = 0;
4618 if (!warned)
4619 {
4620 error (_("section 0 in group section [%5u]\n"),
4621 section_headers_groups [SECTION_HEADER_INDEX (entry)]->group_index);
4622 warned++;
4623 }
4624 }
e4b17d5c
L
4625 }
4626
4627 section_headers_groups [SECTION_HEADER_INDEX (entry)]
4628 = group;
4629
4630 if (do_section_groups)
4631 {
4632 sec = SECTION_HEADER (entry);
c256ffe7 4633 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
4634 }
4635
e4b17d5c
L
4636 g = xmalloc (sizeof (struct group_list));
4637 g->section_index = entry;
4638 g->next = group->root;
4639 group->root = g;
f5842774
L
4640 }
4641
f5842774
L
4642 if (start)
4643 free (start);
e4b17d5c
L
4644
4645 group++;
f5842774
L
4646 }
4647 }
4648
d1f5c6e3
L
4649 if (symtab)
4650 free (symtab);
4651 if (strtab)
4652 free (strtab);
f5842774
L
4653 return 1;
4654}
4655
85b1c36d 4656static struct
566b0d53
L
4657{
4658 const char *name;
4659 int reloc;
4660 int size;
4661 int rela;
4662} dynamic_relocations [] =
4663{
4664 { "REL", DT_REL, DT_RELSZ, FALSE },
4665 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4666 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4667};
4668
252b5132 4669/* Process the reloc section. */
18bd398b 4670
252b5132 4671static int
d3ba0551 4672process_relocs (FILE *file)
252b5132 4673{
b34976b6
AM
4674 unsigned long rel_size;
4675 unsigned long rel_offset;
252b5132
RH
4676
4677
4678 if (!do_reloc)
4679 return 1;
4680
4681 if (do_using_dynamic)
4682 {
566b0d53
L
4683 int is_rela;
4684 const char *name;
4685 int has_dynamic_reloc;
4686 unsigned int i;
0de14b54 4687
566b0d53 4688 has_dynamic_reloc = 0;
252b5132 4689
566b0d53 4690 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4691 {
566b0d53
L
4692 is_rela = dynamic_relocations [i].rela;
4693 name = dynamic_relocations [i].name;
4694 rel_size = dynamic_info [dynamic_relocations [i].size];
4695 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4696
566b0d53
L
4697 has_dynamic_reloc |= rel_size;
4698
4699 if (is_rela == UNKNOWN)
aa903cfb 4700 {
566b0d53
L
4701 if (dynamic_relocations [i].reloc == DT_JMPREL)
4702 switch (dynamic_info[DT_PLTREL])
4703 {
4704 case DT_REL:
4705 is_rela = FALSE;
4706 break;
4707 case DT_RELA:
4708 is_rela = TRUE;
4709 break;
4710 }
aa903cfb 4711 }
252b5132 4712
566b0d53
L
4713 if (rel_size)
4714 {
4715 printf
4716 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4717 name, rel_offset, rel_size);
252b5132 4718
d93f0186
NC
4719 dump_relocations (file,
4720 offset_from_vma (file, rel_offset, rel_size),
4721 rel_size,
566b0d53 4722 dynamic_symbols, num_dynamic_syms,
d79b3d50 4723 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 4724 }
252b5132 4725 }
566b0d53
L
4726
4727 if (! has_dynamic_reloc)
252b5132
RH
4728 printf (_("\nThere are no dynamic relocations in this file.\n"));
4729 }
4730 else
4731 {
b34976b6
AM
4732 Elf_Internal_Shdr *section;
4733 unsigned long i;
4734 int found = 0;
252b5132
RH
4735
4736 for (i = 0, section = section_headers;
4737 i < elf_header.e_shnum;
b34976b6 4738 i++, section++)
252b5132
RH
4739 {
4740 if ( section->sh_type != SHT_RELA
4741 && section->sh_type != SHT_REL)
4742 continue;
4743
4744 rel_offset = section->sh_offset;
4745 rel_size = section->sh_size;
4746
4747 if (rel_size)
4748 {
b34976b6 4749 Elf_Internal_Shdr *strsec;
b34976b6 4750 int is_rela;
103f02d3 4751
252b5132
RH
4752 printf (_("\nRelocation section "));
4753
4754 if (string_table == NULL)
19936277 4755 printf ("%d", section->sh_name);
252b5132 4756 else
3a1a2036 4757 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
4758
4759 printf (_(" at offset 0x%lx contains %lu entries:\n"),
4760 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
4761
d79b3d50
NC
4762 is_rela = section->sh_type == SHT_RELA;
4763
c256ffe7
JJ
4764 if (section->sh_link
4765 && SECTION_HEADER_INDEX (section->sh_link)
4766 < elf_header.e_shnum)
af3fc3bc 4767 {
b34976b6 4768 Elf_Internal_Shdr *symsec;
d79b3d50
NC
4769 Elf_Internal_Sym *symtab;
4770 unsigned long nsyms;
c256ffe7 4771 unsigned long strtablen = 0;
d79b3d50 4772 char *strtab = NULL;
57346661 4773
9ad5cbcf 4774 symsec = SECTION_HEADER (section->sh_link);
08d8fa11
JJ
4775 if (symsec->sh_type != SHT_SYMTAB
4776 && symsec->sh_type != SHT_DYNSYM)
4777 continue;
4778
af3fc3bc 4779 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 4780 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 4781
af3fc3bc
AM
4782 if (symtab == NULL)
4783 continue;
252b5132 4784
c256ffe7
JJ
4785 if (SECTION_HEADER_INDEX (symsec->sh_link)
4786 < elf_header.e_shnum)
4787 {
4788 strsec = SECTION_HEADER (symsec->sh_link);
103f02d3 4789
c256ffe7
JJ
4790 strtab = get_data (NULL, file, strsec->sh_offset,
4791 1, strsec->sh_size,
4792 _("string table"));
4793 strtablen = strtab == NULL ? 0 : strsec->sh_size;
4794 }
252b5132 4795
d79b3d50
NC
4796 dump_relocations (file, rel_offset, rel_size,
4797 symtab, nsyms, strtab, strtablen, is_rela);
4798 if (strtab)
4799 free (strtab);
4800 free (symtab);
4801 }
4802 else
4803 dump_relocations (file, rel_offset, rel_size,
4804 NULL, 0, NULL, 0, is_rela);
252b5132
RH
4805
4806 found = 1;
4807 }
4808 }
4809
4810 if (! found)
4811 printf (_("\nThere are no relocations in this file.\n"));
4812 }
4813
4814 return 1;
4815}
4816
57346661
AM
4817/* Process the unwind section. */
4818
4d6ed7c8
NC
4819#include "unwind-ia64.h"
4820
4821/* An absolute address consists of a section and an offset. If the
4822 section is NULL, the offset itself is the address, otherwise, the
4823 address equals to LOAD_ADDRESS(section) + offset. */
4824
4825struct absaddr
4826 {
4827 unsigned short section;
4828 bfd_vma offset;
4829 };
4830
1949de15
L
4831#define ABSADDR(a) \
4832 ((a).section \
4833 ? section_headers [(a).section].sh_addr + (a).offset \
4834 : (a).offset)
4835
57346661 4836struct ia64_unw_aux_info
4d6ed7c8 4837 {
57346661 4838 struct ia64_unw_table_entry
4d6ed7c8 4839 {
b34976b6
AM
4840 struct absaddr start;
4841 struct absaddr end;
4842 struct absaddr info;
4d6ed7c8 4843 }
b34976b6
AM
4844 *table; /* Unwind table. */
4845 unsigned long table_len; /* Length of unwind table. */
4846 unsigned char *info; /* Unwind info. */
4847 unsigned long info_size; /* Size of unwind info. */
4848 bfd_vma info_addr; /* starting address of unwind info. */
4849 bfd_vma seg_base; /* Starting address of segment. */
4850 Elf_Internal_Sym *symtab; /* The symbol table. */
4851 unsigned long nsyms; /* Number of symbols. */
4852 char *strtab; /* The string table. */
4853 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
4854 };
4855
4d6ed7c8 4856static void
57346661
AM
4857find_symbol_for_address (Elf_Internal_Sym *symtab,
4858 unsigned long nsyms,
4859 const char *strtab,
4860 unsigned long strtab_size,
d3ba0551
AM
4861 struct absaddr addr,
4862 const char **symname,
4863 bfd_vma *offset)
4d6ed7c8 4864{
d3ba0551 4865 bfd_vma dist = 0x100000;
4d6ed7c8
NC
4866 Elf_Internal_Sym *sym, *best = NULL;
4867 unsigned long i;
4868
57346661 4869 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8
NC
4870 {
4871 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
4872 && sym->st_name != 0
4873 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
4874 && addr.offset >= sym->st_value
4875 && addr.offset - sym->st_value < dist)
4876 {
4877 best = sym;
4878 dist = addr.offset - sym->st_value;
4879 if (!dist)
4880 break;
4881 }
4882 }
4883 if (best)
4884 {
57346661
AM
4885 *symname = (best->st_name >= strtab_size
4886 ? "<corrupt>" : strtab + best->st_name);
4d6ed7c8
NC
4887 *offset = dist;
4888 return;
4889 }
4890 *symname = NULL;
4891 *offset = addr.offset;
4892}
4893
4894static void
57346661 4895dump_ia64_unwind (struct ia64_unw_aux_info *aux)
4d6ed7c8 4896{
57346661 4897 struct ia64_unw_table_entry *tp;
4d6ed7c8 4898 int in_body;
7036c0e1 4899
4d6ed7c8
NC
4900 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
4901 {
4902 bfd_vma stamp;
4903 bfd_vma offset;
b34976b6
AM
4904 const unsigned char *dp;
4905 const unsigned char *head;
4906 const char *procname;
4d6ed7c8 4907
57346661
AM
4908 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
4909 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
4910
4911 fputs ("\n<", stdout);
4912
4913 if (procname)
4914 {
4915 fputs (procname, stdout);
4916
4917 if (offset)
4918 printf ("+%lx", (unsigned long) offset);
4919 }
4920
4921 fputs (">: [", stdout);
4922 print_vma (tp->start.offset, PREFIX_HEX);
4923 fputc ('-', stdout);
4924 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 4925 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
4926 (unsigned long) (tp->info.offset - aux->seg_base));
4927
1949de15 4928 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 4929 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 4930
86f55779 4931 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
4932 (unsigned) UNW_VER (stamp),
4933 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
4934 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
4935 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 4936 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
4937
4938 if (UNW_VER (stamp) != 1)
4939 {
4940 printf ("\tUnknown version.\n");
4941 continue;
4942 }
4943
4944 in_body = 0;
89fac5e3 4945 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
4946 dp = unw_decode (dp, in_body, & in_body);
4947 }
4948}
4949
4950static int
d3ba0551 4951slurp_ia64_unwind_table (FILE *file,
57346661 4952 struct ia64_unw_aux_info *aux,
d3ba0551 4953 Elf_Internal_Shdr *sec)
4d6ed7c8 4954{
89fac5e3 4955 unsigned long size, nrelas, i;
d93f0186 4956 Elf_Internal_Phdr *seg;
57346661 4957 struct ia64_unw_table_entry *tep;
c8286bd1 4958 Elf_Internal_Shdr *relsec;
4d6ed7c8
NC
4959 Elf_Internal_Rela *rela, *rp;
4960 unsigned char *table, *tp;
4961 Elf_Internal_Sym *sym;
4962 const char *relname;
4d6ed7c8 4963
4d6ed7c8
NC
4964 /* First, find the starting address of the segment that includes
4965 this section: */
4966
4967 if (elf_header.e_phnum)
4968 {
d93f0186 4969 if (! get_program_headers (file))
4d6ed7c8 4970 return 0;
4d6ed7c8 4971
d93f0186
NC
4972 for (seg = program_headers;
4973 seg < program_headers + elf_header.e_phnum;
4974 ++seg)
4d6ed7c8
NC
4975 {
4976 if (seg->p_type != PT_LOAD)
4977 continue;
4978
4979 if (sec->sh_addr >= seg->p_vaddr
4980 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
4981 {
4982 aux->seg_base = seg->p_vaddr;
4983 break;
4984 }
4985 }
4d6ed7c8
NC
4986 }
4987
4988 /* Second, build the unwind table from the contents of the unwind section: */
4989 size = sec->sh_size;
c256ffe7 4990 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
a6e9f9df
AM
4991 if (!table)
4992 return 0;
4d6ed7c8 4993
c256ffe7 4994 aux->table = xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3
RS
4995 tep = aux->table;
4996 for (tp = table; tp < table + size; tp += 3 * eh_addr_size, ++tep)
4d6ed7c8
NC
4997 {
4998 tep->start.section = SHN_UNDEF;
4999 tep->end.section = SHN_UNDEF;
5000 tep->info.section = SHN_UNDEF;
5001 if (is_32bit_elf)
5002 {
5003 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
5004 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
5005 tep->info.offset = byte_get ((unsigned char *) tp + 8, 4);
5006 }
5007 else
5008 {
66543521
AM
5009 tep->start.offset = BYTE_GET ((unsigned char *) tp + 0);
5010 tep->end.offset = BYTE_GET ((unsigned char *) tp + 8);
5011 tep->info.offset = BYTE_GET ((unsigned char *) tp + 16);
4d6ed7c8
NC
5012 }
5013 tep->start.offset += aux->seg_base;
5014 tep->end.offset += aux->seg_base;
5015 tep->info.offset += aux->seg_base;
5016 }
5017 free (table);
5018
5019 /* Third, apply any relocations to the unwind table: */
5020
5021 for (relsec = section_headers;
5022 relsec < section_headers + elf_header.e_shnum;
5023 ++relsec)
5024 {
5025 if (relsec->sh_type != SHT_RELA
c256ffe7 5026 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
9ad5cbcf 5027 || SECTION_HEADER (relsec->sh_info) != sec)
4d6ed7c8
NC
5028 continue;
5029
5030 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5031 & rela, & nrelas))
5032 return 0;
5033
5034 for (rp = rela; rp < rela + nrelas; ++rp)
5035 {
5036 if (is_32bit_elf)
5037 {
5038 relname = elf_ia64_reloc_type (ELF32_R_TYPE (rp->r_info));
5039 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
4d6ed7c8
NC
5040 }
5041 else
5042 {
5043 relname = elf_ia64_reloc_type (ELF64_R_TYPE (rp->r_info));
5044 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
4d6ed7c8
NC
5045 }
5046
0112cd26 5047 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5048 {
e5fb9629 5049 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5050 continue;
5051 }
5052
89fac5e3 5053 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5054
89fac5e3 5055 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5056 {
5057 case 0:
5058 aux->table[i].start.section = sym->st_shndx;
1ffa9a18 5059 aux->table[i].start.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5060 break;
5061 case 1:
5062 aux->table[i].end.section = sym->st_shndx;
1ffa9a18 5063 aux->table[i].end.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5064 break;
5065 case 2:
5066 aux->table[i].info.section = sym->st_shndx;
1ffa9a18 5067 aux->table[i].info.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5068 break;
5069 default:
5070 break;
5071 }
5072 }
5073
5074 free (rela);
5075 }
5076
89fac5e3 5077 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5078 return 1;
5079}
5080
5081static int
57346661 5082ia64_process_unwind (FILE *file)
4d6ed7c8 5083{
c8286bd1 5084 Elf_Internal_Shdr *sec, *unwsec = NULL, *strsec;
89fac5e3 5085 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5086 struct ia64_unw_aux_info aux;
f1467e33 5087
4d6ed7c8
NC
5088 memset (& aux, 0, sizeof (aux));
5089
4d6ed7c8
NC
5090 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5091 {
c256ffe7
JJ
5092 if (sec->sh_type == SHT_SYMTAB
5093 && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
4d6ed7c8
NC
5094 {
5095 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5096 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5097
9ad5cbcf 5098 strsec = SECTION_HEADER (sec->sh_link);
d3ba0551 5099 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
5100 1, strsec->sh_size, _("string table"));
5101 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5102 }
5103 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5104 unwcount++;
5105 }
5106
5107 if (!unwcount)
5108 printf (_("\nThere are no unwind sections in this file.\n"));
5109
5110 while (unwcount-- > 0)
5111 {
5112 char *suffix;
5113 size_t len, len2;
5114
5115 for (i = unwstart, sec = section_headers + unwstart;
5116 i < elf_header.e_shnum; ++i, ++sec)
5117 if (sec->sh_type == SHT_IA_64_UNWIND)
5118 {
5119 unwsec = sec;
5120 break;
5121 }
5122
5123 unwstart = i + 1;
5124 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5125
e4b17d5c
L
5126 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5127 {
5128 /* We need to find which section group it is in. */
5129 struct group_list *g = section_headers_groups [i]->root;
5130
5131 for (; g != NULL; g = g->next)
5132 {
5133 sec = SECTION_HEADER (g->section_index);
18bd398b
NC
5134
5135 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5136 break;
e4b17d5c
L
5137 }
5138
5139 if (g == NULL)
5140 i = elf_header.e_shnum;
5141 }
18bd398b 5142 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5143 {
18bd398b 5144 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5145 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5146 suffix = SECTION_NAME (unwsec) + len;
5147 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5148 ++i, ++sec)
18bd398b
NC
5149 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5150 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5151 break;
5152 }
5153 else
5154 {
5155 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5156 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5157 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5158 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5159 suffix = "";
18bd398b 5160 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5161 suffix = SECTION_NAME (unwsec) + len;
5162 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5163 ++i, ++sec)
18bd398b
NC
5164 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5165 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5166 break;
5167 }
5168
5169 if (i == elf_header.e_shnum)
5170 {
5171 printf (_("\nCould not find unwind info section for "));
5172
5173 if (string_table == NULL)
5174 printf ("%d", unwsec->sh_name);
5175 else
3a1a2036 5176 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5177 }
5178 else
4d6ed7c8
NC
5179 {
5180 aux.info_size = sec->sh_size;
5181 aux.info_addr = sec->sh_addr;
c256ffe7 5182 aux.info = get_data (NULL, file, sec->sh_offset, 1, aux.info_size,
d3ba0551 5183 _("unwind info"));
4d6ed7c8 5184
579f31ac 5185 printf (_("\nUnwind section "));
4d6ed7c8 5186
579f31ac
JJ
5187 if (string_table == NULL)
5188 printf ("%d", unwsec->sh_name);
5189 else
3a1a2036 5190 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5191
579f31ac 5192 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5193 (unsigned long) unwsec->sh_offset,
89fac5e3 5194 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5195
579f31ac 5196 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5197
579f31ac
JJ
5198 if (aux.table_len > 0)
5199 dump_ia64_unwind (& aux);
5200
5201 if (aux.table)
5202 free ((char *) aux.table);
5203 if (aux.info)
5204 free ((char *) aux.info);
5205 aux.table = NULL;
5206 aux.info = NULL;
5207 }
4d6ed7c8 5208 }
4d6ed7c8 5209
4d6ed7c8
NC
5210 if (aux.symtab)
5211 free (aux.symtab);
5212 if (aux.strtab)
5213 free ((char *) aux.strtab);
5214
5215 return 1;
5216}
5217
57346661
AM
5218struct hppa_unw_aux_info
5219 {
5220 struct hppa_unw_table_entry
5221 {
5222 struct absaddr start;
5223 struct absaddr end;
5224 unsigned int Cannot_unwind:1; /* 0 */
5225 unsigned int Millicode:1; /* 1 */
5226 unsigned int Millicode_save_sr0:1; /* 2 */
5227 unsigned int Region_description:2; /* 3..4 */
5228 unsigned int reserved1:1; /* 5 */
5229 unsigned int Entry_SR:1; /* 6 */
5230 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5231 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5232 unsigned int Args_stored:1; /* 16 */
5233 unsigned int Variable_Frame:1; /* 17 */
5234 unsigned int Separate_Package_Body:1; /* 18 */
5235 unsigned int Frame_Extension_Millicode:1; /* 19 */
5236 unsigned int Stack_Overflow_Check:1; /* 20 */
5237 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5238 unsigned int Ada_Region:1; /* 22 */
5239 unsigned int cxx_info:1; /* 23 */
5240 unsigned int cxx_try_catch:1; /* 24 */
5241 unsigned int sched_entry_seq:1; /* 25 */
5242 unsigned int reserved2:1; /* 26 */
5243 unsigned int Save_SP:1; /* 27 */
5244 unsigned int Save_RP:1; /* 28 */
5245 unsigned int Save_MRP_in_frame:1; /* 29 */
5246 unsigned int extn_ptr_defined:1; /* 30 */
5247 unsigned int Cleanup_defined:1; /* 31 */
5248
5249 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5250 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5251 unsigned int Large_frame:1; /* 2 */
5252 unsigned int Pseudo_SP_Set:1; /* 3 */
5253 unsigned int reserved4:1; /* 4 */
5254 unsigned int Total_frame_size:27; /* 5..31 */
5255 }
5256 *table; /* Unwind table. */
5257 unsigned long table_len; /* Length of unwind table. */
5258 bfd_vma seg_base; /* Starting address of segment. */
5259 Elf_Internal_Sym *symtab; /* The symbol table. */
5260 unsigned long nsyms; /* Number of symbols. */
5261 char *strtab; /* The string table. */
5262 unsigned long strtab_size; /* Size of string table. */
5263 };
5264
5265static void
5266dump_hppa_unwind (struct hppa_unw_aux_info *aux)
5267{
57346661
AM
5268 struct hppa_unw_table_entry *tp;
5269
57346661
AM
5270 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5271 {
5272 bfd_vma offset;
5273 const char *procname;
5274
5275 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5276 aux->strtab_size, tp->start, &procname,
5277 &offset);
5278
5279 fputs ("\n<", stdout);
5280
5281 if (procname)
5282 {
5283 fputs (procname, stdout);
5284
5285 if (offset)
5286 printf ("+%lx", (unsigned long) offset);
5287 }
5288
5289 fputs (">: [", stdout);
5290 print_vma (tp->start.offset, PREFIX_HEX);
5291 fputc ('-', stdout);
5292 print_vma (tp->end.offset, PREFIX_HEX);
5293 printf ("]\n\t");
5294
18bd398b
NC
5295#define PF(_m) if (tp->_m) printf (#_m " ");
5296#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5297 PF(Cannot_unwind);
5298 PF(Millicode);
5299 PF(Millicode_save_sr0);
18bd398b 5300 /* PV(Region_description); */
57346661
AM
5301 PF(Entry_SR);
5302 PV(Entry_FR);
5303 PV(Entry_GR);
5304 PF(Args_stored);
5305 PF(Variable_Frame);
5306 PF(Separate_Package_Body);
5307 PF(Frame_Extension_Millicode);
5308 PF(Stack_Overflow_Check);
5309 PF(Two_Instruction_SP_Increment);
5310 PF(Ada_Region);
5311 PF(cxx_info);
5312 PF(cxx_try_catch);
5313 PF(sched_entry_seq);
5314 PF(Save_SP);
5315 PF(Save_RP);
5316 PF(Save_MRP_in_frame);
5317 PF(extn_ptr_defined);
5318 PF(Cleanup_defined);
5319 PF(MPE_XL_interrupt_marker);
5320 PF(HP_UX_interrupt_marker);
5321 PF(Large_frame);
5322 PF(Pseudo_SP_Set);
5323 PV(Total_frame_size);
5324#undef PF
5325#undef PV
5326 }
5327
18bd398b 5328 printf ("\n");
57346661
AM
5329}
5330
5331static int
5332slurp_hppa_unwind_table (FILE *file,
5333 struct hppa_unw_aux_info *aux,
5334 Elf_Internal_Shdr *sec)
5335{
1c0751b2 5336 unsigned long size, unw_ent_size, nentries, nrelas, i;
57346661
AM
5337 Elf_Internal_Phdr *seg;
5338 struct hppa_unw_table_entry *tep;
5339 Elf_Internal_Shdr *relsec;
5340 Elf_Internal_Rela *rela, *rp;
5341 unsigned char *table, *tp;
5342 Elf_Internal_Sym *sym;
5343 const char *relname;
5344
57346661
AM
5345 /* First, find the starting address of the segment that includes
5346 this section. */
5347
5348 if (elf_header.e_phnum)
5349 {
5350 if (! get_program_headers (file))
5351 return 0;
5352
5353 for (seg = program_headers;
5354 seg < program_headers + elf_header.e_phnum;
5355 ++seg)
5356 {
5357 if (seg->p_type != PT_LOAD)
5358 continue;
5359
5360 if (sec->sh_addr >= seg->p_vaddr
5361 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5362 {
5363 aux->seg_base = seg->p_vaddr;
5364 break;
5365 }
5366 }
5367 }
5368
5369 /* Second, build the unwind table from the contents of the unwind
5370 section. */
5371 size = sec->sh_size;
c256ffe7 5372 table = get_data (NULL, file, sec->sh_offset, 1, size, _("unwind table"));
57346661
AM
5373 if (!table)
5374 return 0;
5375
1c0751b2
DA
5376 unw_ent_size = 16;
5377 nentries = size / unw_ent_size;
5378 size = unw_ent_size * nentries;
57346661 5379
1c0751b2 5380 tep = aux->table = xcmalloc (nentries, sizeof (aux->table[0]));
57346661 5381
1c0751b2 5382 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
5383 {
5384 unsigned int tmp1, tmp2;
5385
5386 tep->start.section = SHN_UNDEF;
5387 tep->end.section = SHN_UNDEF;
5388
1c0751b2
DA
5389 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
5390 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
5391 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
5392 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
5393
5394 tep->start.offset += aux->seg_base;
5395 tep->end.offset += aux->seg_base;
57346661
AM
5396
5397 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
5398 tep->Millicode = (tmp1 >> 30) & 0x1;
5399 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
5400 tep->Region_description = (tmp1 >> 27) & 0x3;
5401 tep->reserved1 = (tmp1 >> 26) & 0x1;
5402 tep->Entry_SR = (tmp1 >> 25) & 0x1;
5403 tep->Entry_FR = (tmp1 >> 21) & 0xf;
5404 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
5405 tep->Args_stored = (tmp1 >> 15) & 0x1;
5406 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
5407 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
5408 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
5409 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
5410 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
5411 tep->Ada_Region = (tmp1 >> 9) & 0x1;
5412 tep->cxx_info = (tmp1 >> 8) & 0x1;
5413 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
5414 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
5415 tep->reserved2 = (tmp1 >> 5) & 0x1;
5416 tep->Save_SP = (tmp1 >> 4) & 0x1;
5417 tep->Save_RP = (tmp1 >> 3) & 0x1;
5418 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
5419 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
5420 tep->Cleanup_defined = tmp1 & 0x1;
5421
5422 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
5423 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
5424 tep->Large_frame = (tmp2 >> 29) & 0x1;
5425 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
5426 tep->reserved4 = (tmp2 >> 27) & 0x1;
5427 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
5428 }
5429 free (table);
5430
5431 /* Third, apply any relocations to the unwind table. */
5432
5433 for (relsec = section_headers;
5434 relsec < section_headers + elf_header.e_shnum;
5435 ++relsec)
5436 {
5437 if (relsec->sh_type != SHT_RELA
c256ffe7 5438 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
57346661
AM
5439 || SECTION_HEADER (relsec->sh_info) != sec)
5440 continue;
5441
5442 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5443 & rela, & nrelas))
5444 return 0;
5445
5446 for (rp = rela; rp < rela + nrelas; ++rp)
5447 {
5448 if (is_32bit_elf)
5449 {
5450 relname = elf_hppa_reloc_type (ELF32_R_TYPE (rp->r_info));
5451 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
5452 }
5453 else
5454 {
5455 relname = elf_hppa_reloc_type (ELF64_R_TYPE (rp->r_info));
5456 sym = aux->symtab + ELF64_R_SYM (rp->r_info);
5457 }
5458
5459 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 5460 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
5461 {
5462 warn (_("Skipping unexpected relocation type %s\n"), relname);
5463 continue;
5464 }
5465
5466 i = rp->r_offset / unw_ent_size;
5467
89fac5e3 5468 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
5469 {
5470 case 0:
5471 aux->table[i].start.section = sym->st_shndx;
5472 aux->table[i].start.offset += sym->st_value + rp->r_addend;
5473 break;
5474 case 1:
5475 aux->table[i].end.section = sym->st_shndx;
5476 aux->table[i].end.offset += sym->st_value + rp->r_addend;
5477 break;
5478 default:
5479 break;
5480 }
5481 }
5482
5483 free (rela);
5484 }
5485
1c0751b2 5486 aux->table_len = nentries;
57346661
AM
5487
5488 return 1;
5489}
5490
5491static int
5492hppa_process_unwind (FILE *file)
5493{
57346661 5494 struct hppa_unw_aux_info aux;
18bd398b
NC
5495 Elf_Internal_Shdr *unwsec = NULL;
5496 Elf_Internal_Shdr *strsec;
5497 Elf_Internal_Shdr *sec;
18bd398b 5498 unsigned long i;
57346661
AM
5499
5500 memset (& aux, 0, sizeof (aux));
5501
c256ffe7
JJ
5502 if (string_table == NULL)
5503 return 1;
57346661
AM
5504
5505 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5506 {
c256ffe7
JJ
5507 if (sec->sh_type == SHT_SYMTAB
5508 && SECTION_HEADER_INDEX (sec->sh_link) < elf_header.e_shnum)
57346661
AM
5509 {
5510 aux.nsyms = sec->sh_size / sec->sh_entsize;
5511 aux.symtab = GET_ELF_SYMBOLS (file, sec);
5512
5513 strsec = SECTION_HEADER (sec->sh_link);
57346661 5514 aux.strtab = get_data (NULL, file, strsec->sh_offset,
c256ffe7
JJ
5515 1, strsec->sh_size, _("string table"));
5516 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 5517 }
18bd398b 5518 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
5519 unwsec = sec;
5520 }
5521
5522 if (!unwsec)
5523 printf (_("\nThere are no unwind sections in this file.\n"));
5524
5525 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5526 {
18bd398b 5527 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 5528 {
57346661
AM
5529 printf (_("\nUnwind section "));
5530 printf (_("'%s'"), SECTION_NAME (sec));
5531
5532 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5533 (unsigned long) sec->sh_offset,
89fac5e3 5534 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
5535
5536 slurp_hppa_unwind_table (file, &aux, sec);
5537 if (aux.table_len > 0)
5538 dump_hppa_unwind (&aux);
5539
5540 if (aux.table)
5541 free ((char *) aux.table);
5542 aux.table = NULL;
5543 }
5544 }
5545
5546 if (aux.symtab)
5547 free (aux.symtab);
5548 if (aux.strtab)
5549 free ((char *) aux.strtab);
5550
5551 return 1;
5552}
5553
5554static int
5555process_unwind (FILE *file)
5556{
5557 struct unwind_handler {
5558 int machtype;
5559 int (*handler)(FILE *file);
5560 } handlers[] = {
5561 { EM_IA_64, ia64_process_unwind },
5562 { EM_PARISC, hppa_process_unwind },
5563 { 0, 0 }
5564 };
5565 int i;
5566
5567 if (!do_unwind)
5568 return 1;
5569
5570 for (i = 0; handlers[i].handler != NULL; i++)
5571 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 5572 return handlers[i].handler (file);
57346661
AM
5573
5574 printf (_("\nThere are no unwind sections in this file.\n"));
5575 return 1;
5576}
5577
252b5132 5578static void
b2d38a17 5579dynamic_section_mips_val (Elf_Internal_Dyn *entry)
252b5132
RH
5580{
5581 switch (entry->d_tag)
5582 {
5583 case DT_MIPS_FLAGS:
5584 if (entry->d_un.d_val == 0)
5585 printf ("NONE\n");
5586 else
5587 {
5588 static const char * opts[] =
5589 {
5590 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
5591 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
5592 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
5593 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
5594 "RLD_ORDER_SAFE"
5595 };
5596 unsigned int cnt;
5597 int first = 1;
60bca95a 5598 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
5599 if (entry->d_un.d_val & (1 << cnt))
5600 {
5601 printf ("%s%s", first ? "" : " ", opts[cnt]);
5602 first = 0;
5603 }
5604 puts ("");
5605 }
5606 break;
103f02d3 5607
252b5132 5608 case DT_MIPS_IVERSION:
d79b3d50
NC
5609 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5610 printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5611 else
d79b3d50 5612 printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
252b5132 5613 break;
103f02d3 5614
252b5132
RH
5615 case DT_MIPS_TIME_STAMP:
5616 {
5617 char timebuf[20];
b34976b6 5618 struct tm *tmp;
50da7a9c 5619
252b5132 5620 time_t time = entry->d_un.d_val;
50da7a9c 5621 tmp = gmtime (&time);
e9e44622
JJ
5622 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
5623 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5624 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
5625 printf ("Time Stamp: %s\n", timebuf);
5626 }
5627 break;
103f02d3 5628
252b5132
RH
5629 case DT_MIPS_RLD_VERSION:
5630 case DT_MIPS_LOCAL_GOTNO:
5631 case DT_MIPS_CONFLICTNO:
5632 case DT_MIPS_LIBLISTNO:
5633 case DT_MIPS_SYMTABNO:
5634 case DT_MIPS_UNREFEXTNO:
5635 case DT_MIPS_HIPAGENO:
5636 case DT_MIPS_DELTA_CLASS_NO:
5637 case DT_MIPS_DELTA_INSTANCE_NO:
5638 case DT_MIPS_DELTA_RELOC_NO:
5639 case DT_MIPS_DELTA_SYM_NO:
5640 case DT_MIPS_DELTA_CLASSSYM_NO:
5641 case DT_MIPS_COMPACT_SIZE:
5642 printf ("%ld\n", (long) entry->d_un.d_ptr);
5643 break;
103f02d3
UD
5644
5645 default:
5646 printf ("%#lx\n", (long) entry->d_un.d_ptr);
5647 }
5648}
5649
5650
5651static void
b2d38a17 5652dynamic_section_parisc_val (Elf_Internal_Dyn *entry)
103f02d3
UD
5653{
5654 switch (entry->d_tag)
5655 {
5656 case DT_HP_DLD_FLAGS:
5657 {
5658 static struct
5659 {
5660 long int bit;
b34976b6 5661 const char *str;
5e220199
NC
5662 }
5663 flags[] =
5664 {
5665 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
5666 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
5667 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
5668 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
5669 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
5670 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
5671 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
5672 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
5673 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
5674 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
5675 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
5676 { DT_HP_GST, "HP_GST" },
5677 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
5678 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
5679 { DT_HP_NODELETE, "HP_NODELETE" },
5680 { DT_HP_GROUP, "HP_GROUP" },
5681 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 5682 };
103f02d3 5683 int first = 1;
5e220199 5684 size_t cnt;
f7a99963 5685 bfd_vma val = entry->d_un.d_val;
103f02d3 5686
60bca95a 5687 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 5688 if (val & flags[cnt].bit)
30800947
NC
5689 {
5690 if (! first)
5691 putchar (' ');
5692 fputs (flags[cnt].str, stdout);
5693 first = 0;
5694 val ^= flags[cnt].bit;
5695 }
76da6bbe 5696
103f02d3 5697 if (val != 0 || first)
f7a99963
NC
5698 {
5699 if (! first)
5700 putchar (' ');
5701 print_vma (val, HEX);
5702 }
103f02d3
UD
5703 }
5704 break;
76da6bbe 5705
252b5132 5706 default:
f7a99963
NC
5707 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5708 break;
252b5132 5709 }
35b1837e 5710 putchar ('\n');
252b5132
RH
5711}
5712
ecc51f48 5713static void
b2d38a17 5714dynamic_section_ia64_val (Elf_Internal_Dyn *entry)
ecc51f48
NC
5715{
5716 switch (entry->d_tag)
5717 {
0de14b54 5718 case DT_IA_64_PLT_RESERVE:
bdf4d63a 5719 /* First 3 slots reserved. */
ecc51f48
NC
5720 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5721 printf (" -- ");
5722 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
5723 break;
5724
5725 default:
5726 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5727 break;
ecc51f48 5728 }
bdf4d63a 5729 putchar ('\n');
ecc51f48
NC
5730}
5731
252b5132 5732static int
b2d38a17 5733get_32bit_dynamic_section (FILE *file)
252b5132 5734{
fb514b26 5735 Elf32_External_Dyn *edyn, *ext;
b34976b6 5736 Elf_Internal_Dyn *entry;
103f02d3 5737
c256ffe7 5738 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5739 _("dynamic section"));
a6e9f9df
AM
5740 if (!edyn)
5741 return 0;
103f02d3 5742
ba2685cc
AM
5743/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5744 might not have the luxury of section headers. Look for the DT_NULL
5745 terminator to determine the number of entries. */
5746 for (ext = edyn, dynamic_nent = 0;
5747 (char *) ext < (char *) edyn + dynamic_size;
5748 ext++)
5749 {
5750 dynamic_nent++;
5751 if (BYTE_GET (ext->d_tag) == DT_NULL)
5752 break;
5753 }
252b5132 5754
c256ffe7 5755 dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
b2d38a17 5756 if (dynamic_section == NULL)
252b5132 5757 {
9ea033b2
NC
5758 error (_("Out of memory\n"));
5759 free (edyn);
5760 return 0;
5761 }
252b5132 5762
fb514b26 5763 for (ext = edyn, entry = dynamic_section;
ba2685cc 5764 entry < dynamic_section + dynamic_nent;
fb514b26 5765 ext++, entry++)
9ea033b2 5766 {
fb514b26
AM
5767 entry->d_tag = BYTE_GET (ext->d_tag);
5768 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5769 }
5770
9ea033b2
NC
5771 free (edyn);
5772
5773 return 1;
5774}
5775
5776static int
b2d38a17 5777get_64bit_dynamic_section (FILE *file)
9ea033b2 5778{
fb514b26 5779 Elf64_External_Dyn *edyn, *ext;
b34976b6 5780 Elf_Internal_Dyn *entry;
103f02d3 5781
c256ffe7 5782 edyn = get_data (NULL, file, dynamic_addr, 1, dynamic_size,
b2d38a17 5783 _("dynamic section"));
a6e9f9df
AM
5784 if (!edyn)
5785 return 0;
103f02d3 5786
ba2685cc
AM
5787/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5788 might not have the luxury of section headers. Look for the DT_NULL
5789 terminator to determine the number of entries. */
5790 for (ext = edyn, dynamic_nent = 0;
5791 (char *) ext < (char *) edyn + dynamic_size;
5792 ext++)
5793 {
5794 dynamic_nent++;
66543521 5795 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
5796 break;
5797 }
252b5132 5798
c256ffe7 5799 dynamic_section = cmalloc (dynamic_nent, sizeof (*entry));
b2d38a17 5800 if (dynamic_section == NULL)
252b5132
RH
5801 {
5802 error (_("Out of memory\n"));
5803 free (edyn);
5804 return 0;
5805 }
5806
fb514b26 5807 for (ext = edyn, entry = dynamic_section;
ba2685cc 5808 entry < dynamic_section + dynamic_nent;
fb514b26 5809 ext++, entry++)
252b5132 5810 {
66543521
AM
5811 entry->d_tag = BYTE_GET (ext->d_tag);
5812 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5813 }
5814
5815 free (edyn);
5816
9ea033b2
NC
5817 return 1;
5818}
5819
e9e44622
JJ
5820static void
5821print_dynamic_flags (bfd_vma flags)
d1133906 5822{
e9e44622 5823 int first = 1;
13ae64f3 5824
d1133906
NC
5825 while (flags)
5826 {
5827 bfd_vma flag;
5828
5829 flag = flags & - flags;
5830 flags &= ~ flag;
5831
e9e44622
JJ
5832 if (first)
5833 first = 0;
5834 else
5835 putc (' ', stdout);
13ae64f3 5836
d1133906
NC
5837 switch (flag)
5838 {
e9e44622
JJ
5839 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
5840 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
5841 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
5842 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
5843 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
5844 default: fputs ("unknown", stdout); break;
d1133906
NC
5845 }
5846 }
e9e44622 5847 puts ("");
d1133906
NC
5848}
5849
b2d38a17
NC
5850/* Parse and display the contents of the dynamic section. */
5851
9ea033b2 5852static int
b2d38a17 5853process_dynamic_section (FILE *file)
9ea033b2 5854{
b34976b6 5855 Elf_Internal_Dyn *entry;
9ea033b2
NC
5856
5857 if (dynamic_size == 0)
5858 {
5859 if (do_dynamic)
b2d38a17 5860 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
5861
5862 return 1;
5863 }
5864
5865 if (is_32bit_elf)
5866 {
b2d38a17 5867 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
5868 return 0;
5869 }
b2d38a17 5870 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
5871 return 0;
5872
252b5132
RH
5873 /* Find the appropriate symbol table. */
5874 if (dynamic_symbols == NULL)
5875 {
86dba8ee
AM
5876 for (entry = dynamic_section;
5877 entry < dynamic_section + dynamic_nent;
5878 ++entry)
252b5132 5879 {
c8286bd1 5880 Elf_Internal_Shdr section;
252b5132
RH
5881
5882 if (entry->d_tag != DT_SYMTAB)
5883 continue;
5884
5885 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
5886
5887 /* Since we do not know how big the symbol table is,
5888 we default to reading in the entire file (!) and
5889 processing that. This is overkill, I know, but it
e3c8793a 5890 should work. */
d93f0186 5891 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 5892
fb52b2f4
NC
5893 if (archive_file_offset != 0)
5894 section.sh_size = archive_file_size - section.sh_offset;
5895 else
5896 {
5897 if (fseek (file, 0, SEEK_END))
591a748a 5898 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
5899
5900 section.sh_size = ftell (file) - section.sh_offset;
5901 }
252b5132 5902
9ea033b2 5903 if (is_32bit_elf)
9ad5cbcf 5904 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 5905 else
9ad5cbcf 5906 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 5907
9ad5cbcf 5908 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 5909 if (num_dynamic_syms < 1)
252b5132
RH
5910 {
5911 error (_("Unable to determine the number of symbols to load\n"));
5912 continue;
5913 }
5914
9ad5cbcf 5915 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
5916 }
5917 }
5918
5919 /* Similarly find a string table. */
5920 if (dynamic_strings == NULL)
5921 {
86dba8ee
AM
5922 for (entry = dynamic_section;
5923 entry < dynamic_section + dynamic_nent;
5924 ++entry)
252b5132
RH
5925 {
5926 unsigned long offset;
b34976b6 5927 long str_tab_len;
252b5132
RH
5928
5929 if (entry->d_tag != DT_STRTAB)
5930 continue;
5931
5932 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
5933
5934 /* Since we do not know how big the string table is,
5935 we default to reading in the entire file (!) and
5936 processing that. This is overkill, I know, but it
e3c8793a 5937 should work. */
252b5132 5938
d93f0186 5939 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
5940
5941 if (archive_file_offset != 0)
5942 str_tab_len = archive_file_size - offset;
5943 else
5944 {
5945 if (fseek (file, 0, SEEK_END))
5946 error (_("Unable to seek to end of file\n"));
5947 str_tab_len = ftell (file) - offset;
5948 }
252b5132
RH
5949
5950 if (str_tab_len < 1)
5951 {
5952 error
5953 (_("Unable to determine the length of the dynamic string table\n"));
5954 continue;
5955 }
5956
c256ffe7 5957 dynamic_strings = get_data (NULL, file, offset, 1, str_tab_len,
d3ba0551 5958 _("dynamic string table"));
d79b3d50 5959 dynamic_strings_length = str_tab_len;
252b5132
RH
5960 break;
5961 }
5962 }
5963
5964 /* And find the syminfo section if available. */
5965 if (dynamic_syminfo == NULL)
5966 {
3e8bba36 5967 unsigned long syminsz = 0;
252b5132 5968
86dba8ee
AM
5969 for (entry = dynamic_section;
5970 entry < dynamic_section + dynamic_nent;
5971 ++entry)
252b5132
RH
5972 {
5973 if (entry->d_tag == DT_SYMINENT)
5974 {
5975 /* Note: these braces are necessary to avoid a syntax
5976 error from the SunOS4 C compiler. */
5977 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
5978 }
5979 else if (entry->d_tag == DT_SYMINSZ)
5980 syminsz = entry->d_un.d_val;
5981 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
5982 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
5983 syminsz);
252b5132
RH
5984 }
5985
5986 if (dynamic_syminfo_offset != 0 && syminsz != 0)
5987 {
86dba8ee 5988 Elf_External_Syminfo *extsyminfo, *extsym;
b34976b6 5989 Elf_Internal_Syminfo *syminfo;
252b5132
RH
5990
5991 /* There is a syminfo section. Read the data. */
c256ffe7
JJ
5992 extsyminfo = get_data (NULL, file, dynamic_syminfo_offset, 1,
5993 syminsz, _("symbol information"));
a6e9f9df
AM
5994 if (!extsyminfo)
5995 return 0;
252b5132 5996
d3ba0551 5997 dynamic_syminfo = malloc (syminsz);
252b5132
RH
5998 if (dynamic_syminfo == NULL)
5999 {
6000 error (_("Out of memory\n"));
6001 return 0;
6002 }
6003
6004 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
6005 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
6006 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
6007 ++syminfo, ++extsym)
252b5132 6008 {
86dba8ee
AM
6009 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
6010 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
6011 }
6012
6013 free (extsyminfo);
6014 }
6015 }
6016
6017 if (do_dynamic && dynamic_addr)
86dba8ee
AM
6018 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
6019 dynamic_addr, dynamic_nent);
252b5132
RH
6020 if (do_dynamic)
6021 printf (_(" Tag Type Name/Value\n"));
6022
86dba8ee
AM
6023 for (entry = dynamic_section;
6024 entry < dynamic_section + dynamic_nent;
6025 entry++)
252b5132
RH
6026 {
6027 if (do_dynamic)
f7a99963 6028 {
b34976b6 6029 const char *dtype;
e699b9ff 6030
f7a99963
NC
6031 putchar (' ');
6032 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
6033 dtype = get_dynamic_type (entry->d_tag);
6034 printf (" (%s)%*s", dtype,
6035 ((is_32bit_elf ? 27 : 19)
6036 - (int) strlen (dtype)),
f7a99963
NC
6037 " ");
6038 }
252b5132
RH
6039
6040 switch (entry->d_tag)
6041 {
d1133906
NC
6042 case DT_FLAGS:
6043 if (do_dynamic)
e9e44622 6044 print_dynamic_flags (entry->d_un.d_val);
d1133906 6045 break;
76da6bbe 6046
252b5132
RH
6047 case DT_AUXILIARY:
6048 case DT_FILTER:
019148e4
L
6049 case DT_CONFIG:
6050 case DT_DEPAUDIT:
6051 case DT_AUDIT:
252b5132
RH
6052 if (do_dynamic)
6053 {
019148e4 6054 switch (entry->d_tag)
b34976b6 6055 {
019148e4
L
6056 case DT_AUXILIARY:
6057 printf (_("Auxiliary library"));
6058 break;
6059
6060 case DT_FILTER:
6061 printf (_("Filter library"));
6062 break;
6063
b34976b6 6064 case DT_CONFIG:
019148e4
L
6065 printf (_("Configuration file"));
6066 break;
6067
6068 case DT_DEPAUDIT:
6069 printf (_("Dependency audit library"));
6070 break;
6071
6072 case DT_AUDIT:
6073 printf (_("Audit library"));
6074 break;
6075 }
252b5132 6076
d79b3d50
NC
6077 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6078 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6079 else
f7a99963
NC
6080 {
6081 printf (": ");
6082 print_vma (entry->d_un.d_val, PREFIX_HEX);
6083 putchar ('\n');
6084 }
252b5132
RH
6085 }
6086 break;
6087
dcefbbbd 6088 case DT_FEATURE:
252b5132
RH
6089 if (do_dynamic)
6090 {
6091 printf (_("Flags:"));
86f55779 6092
252b5132
RH
6093 if (entry->d_un.d_val == 0)
6094 printf (_(" None\n"));
6095 else
6096 {
6097 unsigned long int val = entry->d_un.d_val;
86f55779 6098
252b5132
RH
6099 if (val & DTF_1_PARINIT)
6100 {
6101 printf (" PARINIT");
6102 val ^= DTF_1_PARINIT;
6103 }
dcefbbbd
L
6104 if (val & DTF_1_CONFEXP)
6105 {
6106 printf (" CONFEXP");
6107 val ^= DTF_1_CONFEXP;
6108 }
252b5132
RH
6109 if (val != 0)
6110 printf (" %lx", val);
6111 puts ("");
6112 }
6113 }
6114 break;
6115
6116 case DT_POSFLAG_1:
6117 if (do_dynamic)
6118 {
6119 printf (_("Flags:"));
86f55779 6120
252b5132
RH
6121 if (entry->d_un.d_val == 0)
6122 printf (_(" None\n"));
6123 else
6124 {
6125 unsigned long int val = entry->d_un.d_val;
86f55779 6126
252b5132
RH
6127 if (val & DF_P1_LAZYLOAD)
6128 {
6129 printf (" LAZYLOAD");
6130 val ^= DF_P1_LAZYLOAD;
6131 }
6132 if (val & DF_P1_GROUPPERM)
6133 {
6134 printf (" GROUPPERM");
6135 val ^= DF_P1_GROUPPERM;
6136 }
6137 if (val != 0)
6138 printf (" %lx", val);
6139 puts ("");
6140 }
6141 }
6142 break;
6143
6144 case DT_FLAGS_1:
6145 if (do_dynamic)
6146 {
6147 printf (_("Flags:"));
6148 if (entry->d_un.d_val == 0)
6149 printf (_(" None\n"));
6150 else
6151 {
6152 unsigned long int val = entry->d_un.d_val;
86f55779 6153
252b5132
RH
6154 if (val & DF_1_NOW)
6155 {
6156 printf (" NOW");
6157 val ^= DF_1_NOW;
6158 }
6159 if (val & DF_1_GLOBAL)
6160 {
6161 printf (" GLOBAL");
6162 val ^= DF_1_GLOBAL;
6163 }
6164 if (val & DF_1_GROUP)
6165 {
6166 printf (" GROUP");
6167 val ^= DF_1_GROUP;
6168 }
6169 if (val & DF_1_NODELETE)
6170 {
6171 printf (" NODELETE");
6172 val ^= DF_1_NODELETE;
6173 }
6174 if (val & DF_1_LOADFLTR)
6175 {
6176 printf (" LOADFLTR");
6177 val ^= DF_1_LOADFLTR;
6178 }
6179 if (val & DF_1_INITFIRST)
6180 {
6181 printf (" INITFIRST");
6182 val ^= DF_1_INITFIRST;
6183 }
6184 if (val & DF_1_NOOPEN)
6185 {
6186 printf (" NOOPEN");
6187 val ^= DF_1_NOOPEN;
6188 }
6189 if (val & DF_1_ORIGIN)
6190 {
6191 printf (" ORIGIN");
6192 val ^= DF_1_ORIGIN;
6193 }
6194 if (val & DF_1_DIRECT)
6195 {
6196 printf (" DIRECT");
6197 val ^= DF_1_DIRECT;
6198 }
6199 if (val & DF_1_TRANS)
6200 {
6201 printf (" TRANS");
6202 val ^= DF_1_TRANS;
6203 }
6204 if (val & DF_1_INTERPOSE)
6205 {
6206 printf (" INTERPOSE");
6207 val ^= DF_1_INTERPOSE;
6208 }
f7db6139 6209 if (val & DF_1_NODEFLIB)
dcefbbbd 6210 {
f7db6139
L
6211 printf (" NODEFLIB");
6212 val ^= DF_1_NODEFLIB;
dcefbbbd
L
6213 }
6214 if (val & DF_1_NODUMP)
6215 {
6216 printf (" NODUMP");
6217 val ^= DF_1_NODUMP;
6218 }
6219 if (val & DF_1_CONLFAT)
6220 {
6221 printf (" CONLFAT");
6222 val ^= DF_1_CONLFAT;
6223 }
252b5132
RH
6224 if (val != 0)
6225 printf (" %lx", val);
6226 puts ("");
6227 }
6228 }
6229 break;
6230
6231 case DT_PLTREL:
566b0d53 6232 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6233 if (do_dynamic)
6234 puts (get_dynamic_type (entry->d_un.d_val));
6235 break;
6236
6237 case DT_NULL :
6238 case DT_NEEDED :
6239 case DT_PLTGOT :
6240 case DT_HASH :
6241 case DT_STRTAB :
6242 case DT_SYMTAB :
6243 case DT_RELA :
6244 case DT_INIT :
6245 case DT_FINI :
6246 case DT_SONAME :
6247 case DT_RPATH :
6248 case DT_SYMBOLIC:
6249 case DT_REL :
6250 case DT_DEBUG :
6251 case DT_TEXTREL :
6252 case DT_JMPREL :
019148e4 6253 case DT_RUNPATH :
252b5132
RH
6254 dynamic_info[entry->d_tag] = entry->d_un.d_val;
6255
6256 if (do_dynamic)
6257 {
b34976b6 6258 char *name;
252b5132 6259
d79b3d50
NC
6260 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6261 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6262 else
d79b3d50 6263 name = NULL;
252b5132
RH
6264
6265 if (name)
6266 {
6267 switch (entry->d_tag)
6268 {
6269 case DT_NEEDED:
6270 printf (_("Shared library: [%s]"), name);
6271
18bd398b 6272 if (streq (name, program_interpreter))
f7a99963 6273 printf (_(" program interpreter"));
252b5132
RH
6274 break;
6275
6276 case DT_SONAME:
f7a99963 6277 printf (_("Library soname: [%s]"), name);
252b5132
RH
6278 break;
6279
6280 case DT_RPATH:
f7a99963 6281 printf (_("Library rpath: [%s]"), name);
252b5132
RH
6282 break;
6283
019148e4
L
6284 case DT_RUNPATH:
6285 printf (_("Library runpath: [%s]"), name);
6286 break;
6287
252b5132 6288 default:
f7a99963
NC
6289 print_vma (entry->d_un.d_val, PREFIX_HEX);
6290 break;
252b5132
RH
6291 }
6292 }
6293 else
f7a99963
NC
6294 print_vma (entry->d_un.d_val, PREFIX_HEX);
6295
6296 putchar ('\n');
252b5132
RH
6297 }
6298 break;
6299
6300 case DT_PLTRELSZ:
6301 case DT_RELASZ :
6302 case DT_STRSZ :
6303 case DT_RELSZ :
6304 case DT_RELAENT :
6305 case DT_SYMENT :
6306 case DT_RELENT :
566b0d53 6307 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6308 case DT_PLTPADSZ:
6309 case DT_MOVEENT :
6310 case DT_MOVESZ :
6311 case DT_INIT_ARRAYSZ:
6312 case DT_FINI_ARRAYSZ:
047b2264
JJ
6313 case DT_GNU_CONFLICTSZ:
6314 case DT_GNU_LIBLISTSZ:
252b5132 6315 if (do_dynamic)
f7a99963
NC
6316 {
6317 print_vma (entry->d_un.d_val, UNSIGNED);
6318 printf (" (bytes)\n");
6319 }
252b5132
RH
6320 break;
6321
6322 case DT_VERDEFNUM:
6323 case DT_VERNEEDNUM:
6324 case DT_RELACOUNT:
6325 case DT_RELCOUNT:
6326 if (do_dynamic)
f7a99963
NC
6327 {
6328 print_vma (entry->d_un.d_val, UNSIGNED);
6329 putchar ('\n');
6330 }
252b5132
RH
6331 break;
6332
6333 case DT_SYMINSZ:
6334 case DT_SYMINENT:
6335 case DT_SYMINFO:
6336 case DT_USED:
6337 case DT_INIT_ARRAY:
6338 case DT_FINI_ARRAY:
6339 if (do_dynamic)
6340 {
d79b3d50
NC
6341 if (entry->d_tag == DT_USED
6342 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 6343 {
d79b3d50 6344 char *name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6345
b34976b6 6346 if (*name)
252b5132
RH
6347 {
6348 printf (_("Not needed object: [%s]\n"), name);
6349 break;
6350 }
6351 }
103f02d3 6352
f7a99963
NC
6353 print_vma (entry->d_un.d_val, PREFIX_HEX);
6354 putchar ('\n');
252b5132
RH
6355 }
6356 break;
6357
6358 case DT_BIND_NOW:
6359 /* The value of this entry is ignored. */
35b1837e
AM
6360 if (do_dynamic)
6361 putchar ('\n');
252b5132 6362 break;
103f02d3 6363
047b2264
JJ
6364 case DT_GNU_PRELINKED:
6365 if (do_dynamic)
6366 {
b34976b6 6367 struct tm *tmp;
047b2264
JJ
6368 time_t time = entry->d_un.d_val;
6369
6370 tmp = gmtime (&time);
6371 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
6372 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6373 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
6374
6375 }
6376 break;
6377
fdc90cb4
JJ
6378 case DT_GNU_HASH:
6379 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
6380 if (do_dynamic)
6381 {
6382 print_vma (entry->d_un.d_val, PREFIX_HEX);
6383 putchar ('\n');
6384 }
6385 break;
6386
252b5132
RH
6387 default:
6388 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 6389 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
6390 entry->d_un.d_val;
6391
6392 if (do_dynamic)
6393 {
6394 switch (elf_header.e_machine)
6395 {
6396 case EM_MIPS:
4fe85591 6397 case EM_MIPS_RS3_LE:
b2d38a17 6398 dynamic_section_mips_val (entry);
252b5132 6399 break;
103f02d3 6400 case EM_PARISC:
b2d38a17 6401 dynamic_section_parisc_val (entry);
103f02d3 6402 break;
ecc51f48 6403 case EM_IA_64:
b2d38a17 6404 dynamic_section_ia64_val (entry);
ecc51f48 6405 break;
252b5132 6406 default:
f7a99963
NC
6407 print_vma (entry->d_un.d_val, PREFIX_HEX);
6408 putchar ('\n');
252b5132
RH
6409 }
6410 }
6411 break;
6412 }
6413 }
6414
6415 return 1;
6416}
6417
6418static char *
d3ba0551 6419get_ver_flags (unsigned int flags)
252b5132 6420{
b34976b6 6421 static char buff[32];
252b5132
RH
6422
6423 buff[0] = 0;
6424
6425 if (flags == 0)
6426 return _("none");
6427
6428 if (flags & VER_FLG_BASE)
6429 strcat (buff, "BASE ");
6430
6431 if (flags & VER_FLG_WEAK)
6432 {
6433 if (flags & VER_FLG_BASE)
6434 strcat (buff, "| ");
6435
6436 strcat (buff, "WEAK ");
6437 }
6438
6439 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
6440 strcat (buff, "| <unknown>");
6441
6442 return buff;
6443}
6444
6445/* Display the contents of the version sections. */
6446static int
d3ba0551 6447process_version_sections (FILE *file)
252b5132 6448{
b34976b6
AM
6449 Elf_Internal_Shdr *section;
6450 unsigned i;
6451 int found = 0;
252b5132
RH
6452
6453 if (! do_version)
6454 return 1;
6455
6456 for (i = 0, section = section_headers;
6457 i < elf_header.e_shnum;
b34976b6 6458 i++, section++)
252b5132
RH
6459 {
6460 switch (section->sh_type)
6461 {
6462 case SHT_GNU_verdef:
6463 {
b34976b6
AM
6464 Elf_External_Verdef *edefs;
6465 unsigned int idx;
6466 unsigned int cnt;
54806181 6467 char *endbuf;
252b5132
RH
6468
6469 found = 1;
6470
6471 printf
6472 (_("\nVersion definition section '%s' contains %ld entries:\n"),
6473 SECTION_NAME (section), section->sh_info);
6474
6475 printf (_(" Addr: 0x"));
6476 printf_vma (section->sh_addr);
6477 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 6478 (unsigned long) section->sh_offset, section->sh_link,
c256ffe7
JJ
6479 SECTION_HEADER_INDEX (section->sh_link)
6480 < elf_header.e_shnum
6481 ? SECTION_NAME (SECTION_HEADER (section->sh_link))
6482 : "<corrupt>");
252b5132 6483
c256ffe7
JJ
6484 edefs = get_data (NULL, file, section->sh_offset, 1,
6485 section->sh_size,
d3ba0551 6486 _("version definition section"));
54806181 6487 endbuf = (char *) edefs + section->sh_size;
a6e9f9df
AM
6488 if (!edefs)
6489 break;
252b5132 6490
b34976b6 6491 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 6492 {
b34976b6
AM
6493 char *vstart;
6494 Elf_External_Verdef *edef;
6495 Elf_Internal_Verdef ent;
6496 Elf_External_Verdaux *eaux;
6497 Elf_Internal_Verdaux aux;
6498 int j;
6499 int isum;
103f02d3 6500
252b5132 6501 vstart = ((char *) edefs) + idx;
54806181
AM
6502 if (vstart + sizeof (*edef) > endbuf)
6503 break;
252b5132
RH
6504
6505 edef = (Elf_External_Verdef *) vstart;
6506
6507 ent.vd_version = BYTE_GET (edef->vd_version);
6508 ent.vd_flags = BYTE_GET (edef->vd_flags);
6509 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
6510 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
6511 ent.vd_hash = BYTE_GET (edef->vd_hash);
6512 ent.vd_aux = BYTE_GET (edef->vd_aux);
6513 ent.vd_next = BYTE_GET (edef->vd_next);
6514
6515 printf (_(" %#06x: Rev: %d Flags: %s"),
6516 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
6517
6518 printf (_(" Index: %d Cnt: %d "),
6519 ent.vd_ndx, ent.vd_cnt);
6520
6521 vstart += ent.vd_aux;
6522
6523 eaux = (Elf_External_Verdaux *) vstart;
6524
6525 aux.vda_name = BYTE_GET (eaux->vda_name);
6526 aux.vda_next = BYTE_GET (eaux->vda_next);
6527
d79b3d50
NC
6528 if (VALID_DYNAMIC_NAME (aux.vda_name))
6529 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6530 else
6531 printf (_("Name index: %ld\n"), aux.vda_name);
6532
6533 isum = idx + ent.vd_aux;
6534
b34976b6 6535 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
6536 {
6537 isum += aux.vda_next;
6538 vstart += aux.vda_next;
6539
6540 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
6541 if (vstart + sizeof (*eaux) > endbuf)
6542 break;
252b5132
RH
6543
6544 aux.vda_name = BYTE_GET (eaux->vda_name);
6545 aux.vda_next = BYTE_GET (eaux->vda_next);
6546
d79b3d50 6547 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 6548 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 6549 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6550 else
6551 printf (_(" %#06x: Parent %d, name index: %ld\n"),
6552 isum, j, aux.vda_name);
6553 }
54806181
AM
6554 if (j < ent.vd_cnt)
6555 printf (_(" Version def aux past end of section\n"));
252b5132
RH
6556
6557 idx += ent.vd_next;
6558 }
54806181
AM
6559 if (cnt < section->sh_info)
6560 printf (_(" Version definition past end of section\n"));
252b5132
RH
6561
6562 free (edefs);
6563 }
6564 break;
103f02d3 6565
252b5132
RH
6566 case SHT_GNU_verneed:
6567 {
b34976b6
AM
6568 Elf_External_Verneed *eneed;
6569 unsigned int idx;
6570 unsigned int cnt;
54806181 6571 char *endbuf;
252b5132
RH
6572
6573 found = 1;
6574
6575 printf (_("\nVersion needs section '%s' contains %ld entries:\n"),
6576 SECTION_NAME (section), section->sh_info);
6577
6578 printf (_(" Addr: 0x"));
6579 printf_vma (section->sh_addr);
6580 printf (_(" Offset: %#08lx Link to section: %ld (%s)\n"),
1b228002 6581 (unsigned long) section->sh_offset, section->sh_link,
c256ffe7
JJ
6582 SECTION_HEADER_INDEX (section->sh_link)
6583 < elf_header.e_shnum
6584 ? SECTION_NAME (SECTION_HEADER (section->sh_link))
6585 : "<corrupt>");
252b5132 6586
c256ffe7
JJ
6587 eneed = get_data (NULL, file, section->sh_offset, 1,
6588 section->sh_size,
d3ba0551 6589 _("version need section"));
54806181 6590 endbuf = (char *) eneed + section->sh_size;
a6e9f9df
AM
6591 if (!eneed)
6592 break;
252b5132
RH
6593
6594 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
6595 {
b34976b6
AM
6596 Elf_External_Verneed *entry;
6597 Elf_Internal_Verneed ent;
6598 int j;
6599 int isum;
6600 char *vstart;
252b5132
RH
6601
6602 vstart = ((char *) eneed) + idx;
54806181
AM
6603 if (vstart + sizeof (*entry) > endbuf)
6604 break;
252b5132
RH
6605
6606 entry = (Elf_External_Verneed *) vstart;
6607
6608 ent.vn_version = BYTE_GET (entry->vn_version);
6609 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
6610 ent.vn_file = BYTE_GET (entry->vn_file);
6611 ent.vn_aux = BYTE_GET (entry->vn_aux);
6612 ent.vn_next = BYTE_GET (entry->vn_next);
6613
6614 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
6615
d79b3d50
NC
6616 if (VALID_DYNAMIC_NAME (ent.vn_file))
6617 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
6618 else
6619 printf (_(" File: %lx"), ent.vn_file);
6620
6621 printf (_(" Cnt: %d\n"), ent.vn_cnt);
6622
6623 vstart += ent.vn_aux;
6624
6625 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
6626 {
b34976b6
AM
6627 Elf_External_Vernaux *eaux;
6628 Elf_Internal_Vernaux aux;
252b5132 6629
54806181
AM
6630 if (vstart + sizeof (*eaux) > endbuf)
6631 break;
252b5132
RH
6632 eaux = (Elf_External_Vernaux *) vstart;
6633
6634 aux.vna_hash = BYTE_GET (eaux->vna_hash);
6635 aux.vna_flags = BYTE_GET (eaux->vna_flags);
6636 aux.vna_other = BYTE_GET (eaux->vna_other);
6637 aux.vna_name = BYTE_GET (eaux->vna_name);
6638 aux.vna_next = BYTE_GET (eaux->vna_next);
6639
d79b3d50 6640 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 6641 printf (_(" %#06x: Name: %s"),
d79b3d50 6642 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 6643 else
ecc2063b 6644 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
6645 isum, aux.vna_name);
6646
6647 printf (_(" Flags: %s Version: %d\n"),
6648 get_ver_flags (aux.vna_flags), aux.vna_other);
6649
6650 isum += aux.vna_next;
6651 vstart += aux.vna_next;
6652 }
54806181
AM
6653 if (j < ent.vn_cnt)
6654 printf (_(" Version need aux past end of section\n"));
252b5132
RH
6655
6656 idx += ent.vn_next;
6657 }
54806181
AM
6658 if (cnt < section->sh_info)
6659 printf (_(" Version need past end of section\n"));
103f02d3 6660
252b5132
RH
6661 free (eneed);
6662 }
6663 break;
6664
6665 case SHT_GNU_versym:
6666 {
b34976b6
AM
6667 Elf_Internal_Shdr *link_section;
6668 int total;
6669 int cnt;
6670 unsigned char *edata;
6671 unsigned short *data;
6672 char *strtab;
6673 Elf_Internal_Sym *symbols;
6674 Elf_Internal_Shdr *string_sec;
d3ba0551 6675 long off;
252b5132 6676
c256ffe7
JJ
6677 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
6678 break;
6679
9ad5cbcf 6680 link_section = SECTION_HEADER (section->sh_link);
08d8fa11 6681 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 6682
c256ffe7
JJ
6683 if (SECTION_HEADER_INDEX (link_section->sh_link)
6684 >= elf_header.e_shnum)
6685 break;
6686
252b5132
RH
6687 found = 1;
6688
9ad5cbcf 6689 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 6690
9ad5cbcf 6691 string_sec = SECTION_HEADER (link_section->sh_link);
252b5132 6692
c256ffe7 6693 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 6694 string_sec->sh_size, _("version string table"));
a6e9f9df
AM
6695 if (!strtab)
6696 break;
252b5132
RH
6697
6698 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
6699 SECTION_NAME (section), total);
6700
6701 printf (_(" Addr: "));
6702 printf_vma (section->sh_addr);
6703 printf (_(" Offset: %#08lx Link: %lx (%s)\n"),
1b228002 6704 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
6705 SECTION_NAME (link_section));
6706
d3ba0551
AM
6707 off = offset_from_vma (file,
6708 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6709 total * sizeof (short));
c256ffe7 6710 edata = get_data (NULL, file, off, total, sizeof (short),
d3ba0551 6711 _("version symbol data"));
a6e9f9df
AM
6712 if (!edata)
6713 {
6714 free (strtab);
6715 break;
6716 }
252b5132 6717
c256ffe7 6718 data = cmalloc (total, sizeof (short));
252b5132
RH
6719
6720 for (cnt = total; cnt --;)
b34976b6
AM
6721 data[cnt] = byte_get (edata + cnt * sizeof (short),
6722 sizeof (short));
252b5132
RH
6723
6724 free (edata);
6725
6726 for (cnt = 0; cnt < total; cnt += 4)
6727 {
6728 int j, nn;
00d93f34 6729 int check_def, check_need;
b34976b6 6730 char *name;
252b5132
RH
6731
6732 printf (" %03x:", cnt);
6733
6734 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 6735 switch (data[cnt + j])
252b5132
RH
6736 {
6737 case 0:
6738 fputs (_(" 0 (*local*) "), stdout);
6739 break;
6740
6741 case 1:
6742 fputs (_(" 1 (*global*) "), stdout);
6743 break;
6744
6745 default:
b34976b6
AM
6746 nn = printf ("%4x%c", data[cnt + j] & 0x7fff,
6747 data[cnt + j] & 0x8000 ? 'h' : ' ');
252b5132 6748
00d93f34
JJ
6749 check_def = 1;
6750 check_need = 1;
c256ffe7
JJ
6751 if (SECTION_HEADER_INDEX (symbols[cnt + j].st_shndx)
6752 >= elf_header.e_shnum
6753 || SECTION_HEADER (symbols[cnt + j].st_shndx)->sh_type
6754 != SHT_NOBITS)
252b5132 6755 {
b34976b6 6756 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
6757 check_def = 0;
6758 else
6759 check_need = 0;
252b5132 6760 }
00d93f34
JJ
6761
6762 if (check_need
b34976b6 6763 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 6764 {
b34976b6
AM
6765 Elf_Internal_Verneed ivn;
6766 unsigned long offset;
252b5132 6767
d93f0186
NC
6768 offset = offset_from_vma
6769 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6770 sizeof (Elf_External_Verneed));
252b5132 6771
b34976b6 6772 do
252b5132 6773 {
b34976b6
AM
6774 Elf_Internal_Vernaux ivna;
6775 Elf_External_Verneed evn;
6776 Elf_External_Vernaux evna;
6777 unsigned long a_off;
252b5132 6778
c256ffe7 6779 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 6780 _("version need"));
252b5132
RH
6781
6782 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6783 ivn.vn_next = BYTE_GET (evn.vn_next);
6784
6785 a_off = offset + ivn.vn_aux;
6786
6787 do
6788 {
a6e9f9df 6789 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 6790 1, _("version need aux (2)"));
252b5132
RH
6791
6792 ivna.vna_next = BYTE_GET (evna.vna_next);
6793 ivna.vna_other = BYTE_GET (evna.vna_other);
6794
6795 a_off += ivna.vna_next;
6796 }
b34976b6 6797 while (ivna.vna_other != data[cnt + j]
252b5132
RH
6798 && ivna.vna_next != 0);
6799
b34976b6 6800 if (ivna.vna_other == data[cnt + j])
252b5132
RH
6801 {
6802 ivna.vna_name = BYTE_GET (evna.vna_name);
6803
54806181
AM
6804 if (ivna.vna_name >= string_sec->sh_size)
6805 name = _("*invalid*");
6806 else
6807 name = strtab + ivna.vna_name;
252b5132 6808 nn += printf ("(%s%-*s",
16062207
ILT
6809 name,
6810 12 - (int) strlen (name),
252b5132 6811 ")");
00d93f34 6812 check_def = 0;
252b5132
RH
6813 break;
6814 }
6815
6816 offset += ivn.vn_next;
6817 }
6818 while (ivn.vn_next);
6819 }
00d93f34 6820
b34976b6
AM
6821 if (check_def && data[cnt + j] != 0x8001
6822 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6823 {
b34976b6
AM
6824 Elf_Internal_Verdef ivd;
6825 Elf_External_Verdef evd;
6826 unsigned long offset;
252b5132 6827
d93f0186
NC
6828 offset = offset_from_vma
6829 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6830 sizeof evd);
252b5132
RH
6831
6832 do
6833 {
c256ffe7 6834 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 6835 _("version def"));
252b5132
RH
6836
6837 ivd.vd_next = BYTE_GET (evd.vd_next);
6838 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6839
6840 offset += ivd.vd_next;
6841 }
b34976b6 6842 while (ivd.vd_ndx != (data[cnt + j] & 0x7fff)
252b5132
RH
6843 && ivd.vd_next != 0);
6844
b34976b6 6845 if (ivd.vd_ndx == (data[cnt + j] & 0x7fff))
252b5132 6846 {
b34976b6
AM
6847 Elf_External_Verdaux evda;
6848 Elf_Internal_Verdaux ivda;
252b5132
RH
6849
6850 ivd.vd_aux = BYTE_GET (evd.vd_aux);
6851
a6e9f9df
AM
6852 get_data (&evda, file,
6853 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
6854 sizeof (evda), 1,
6855 _("version def aux"));
252b5132
RH
6856
6857 ivda.vda_name = BYTE_GET (evda.vda_name);
6858
54806181
AM
6859 if (ivda.vda_name >= string_sec->sh_size)
6860 name = _("*invalid*");
6861 else
6862 name = strtab + ivda.vda_name;
252b5132 6863 nn += printf ("(%s%-*s",
16062207
ILT
6864 name,
6865 12 - (int) strlen (name),
252b5132
RH
6866 ")");
6867 }
6868 }
6869
6870 if (nn < 18)
6871 printf ("%*c", 18 - nn, ' ');
6872 }
6873
6874 putchar ('\n');
6875 }
6876
6877 free (data);
6878 free (strtab);
6879 free (symbols);
6880 }
6881 break;
103f02d3 6882
252b5132
RH
6883 default:
6884 break;
6885 }
6886 }
6887
6888 if (! found)
6889 printf (_("\nNo version information found in this file.\n"));
6890
6891 return 1;
6892}
6893
d1133906 6894static const char *
d3ba0551 6895get_symbol_binding (unsigned int binding)
252b5132 6896{
b34976b6 6897 static char buff[32];
252b5132
RH
6898
6899 switch (binding)
6900 {
b34976b6
AM
6901 case STB_LOCAL: return "LOCAL";
6902 case STB_GLOBAL: return "GLOBAL";
6903 case STB_WEAK: return "WEAK";
252b5132
RH
6904 default:
6905 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
6906 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
6907 binding);
252b5132 6908 else if (binding >= STB_LOOS && binding <= STB_HIOS)
e9e44622 6909 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
252b5132 6910 else
e9e44622 6911 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
6912 return buff;
6913 }
6914}
6915
d1133906 6916static const char *
d3ba0551 6917get_symbol_type (unsigned int type)
252b5132 6918{
b34976b6 6919 static char buff[32];
252b5132
RH
6920
6921 switch (type)
6922 {
b34976b6
AM
6923 case STT_NOTYPE: return "NOTYPE";
6924 case STT_OBJECT: return "OBJECT";
6925 case STT_FUNC: return "FUNC";
6926 case STT_SECTION: return "SECTION";
6927 case STT_FILE: return "FILE";
6928 case STT_COMMON: return "COMMON";
6929 case STT_TLS: return "TLS";
15ab5209
DB
6930 case STT_RELC: return "RELC";
6931 case STT_SRELC: return "SRELC";
252b5132
RH
6932 default:
6933 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
6934 {
6935 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
6936 return "THUMB_FUNC";
6937
351b4b40 6938 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
6939 return "REGISTER";
6940
6941 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
6942 return "PARISC_MILLI";
6943
e9e44622 6944 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 6945 }
252b5132 6946 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
6947 {
6948 if (elf_header.e_machine == EM_PARISC)
6949 {
6950 if (type == STT_HP_OPAQUE)
6951 return "HP_OPAQUE";
6952 if (type == STT_HP_STUB)
6953 return "HP_STUB";
6954 }
6955
e9e44622 6956 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 6957 }
252b5132 6958 else
e9e44622 6959 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
6960 return buff;
6961 }
6962}
6963
d1133906 6964static const char *
d3ba0551 6965get_symbol_visibility (unsigned int visibility)
d1133906
NC
6966{
6967 switch (visibility)
6968 {
b34976b6
AM
6969 case STV_DEFAULT: return "DEFAULT";
6970 case STV_INTERNAL: return "INTERNAL";
6971 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
6972 case STV_PROTECTED: return "PROTECTED";
6973 default: abort ();
6974 }
6975}
6976
5e2b0d47
NC
6977static const char *
6978get_mips_symbol_other (unsigned int other)
6979{
6980 switch (other)
6981 {
6982 case STO_OPTIONAL: return "OPTIONAL";
6983 case STO_MIPS16: return "MIPS16";
6984 default: return NULL;
6985 }
6986}
6987
6988static const char *
6989get_symbol_other (unsigned int other)
6990{
6991 const char * result = NULL;
6992 static char buff [32];
6993
6994 if (other == 0)
6995 return "";
6996
6997 switch (elf_header.e_machine)
6998 {
6999 case EM_MIPS:
7000 result = get_mips_symbol_other (other);
7001 default:
7002 break;
7003 }
7004
7005 if (result)
7006 return result;
7007
7008 snprintf (buff, sizeof buff, _("<other>: %x"), other);
7009 return buff;
7010}
7011
d1133906 7012static const char *
d3ba0551 7013get_symbol_index_type (unsigned int type)
252b5132 7014{
b34976b6 7015 static char buff[32];
5cf1065c 7016
252b5132
RH
7017 switch (type)
7018 {
b34976b6
AM
7019 case SHN_UNDEF: return "UND";
7020 case SHN_ABS: return "ABS";
7021 case SHN_COMMON: return "COM";
252b5132 7022 default:
9ce701e2
L
7023 if (type == SHN_IA_64_ANSI_COMMON
7024 && elf_header.e_machine == EM_IA_64
7025 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
7026 return "ANSI_COM";
3b22753a
L
7027 else if (elf_header.e_machine == EM_X86_64
7028 && type == SHN_X86_64_LCOMMON)
7029 return "LARGE_COM";
172553c7
TS
7030 else if (type == SHN_MIPS_SCOMMON
7031 && elf_header.e_machine == EM_MIPS)
7032 return "SCOM";
7033 else if (type == SHN_MIPS_SUNDEFINED
7034 && elf_header.e_machine == EM_MIPS)
7035 return "SUND";
9ce701e2 7036 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
5cf1065c 7037 sprintf (buff, "PRC[0x%04x]", type);
252b5132 7038 else if (type >= SHN_LOOS && type <= SHN_HIOS)
5cf1065c 7039 sprintf (buff, "OS [0x%04x]", type);
9ad5cbcf 7040 else if (type >= SHN_LORESERVE && type <= SHN_HIRESERVE)
5cf1065c 7041 sprintf (buff, "RSV[0x%04x]", type);
252b5132 7042 else
232e7cb8 7043 sprintf (buff, "%3d", type);
5cf1065c 7044 break;
252b5132 7045 }
5cf1065c
NC
7046
7047 return buff;
252b5132
RH
7048}
7049
66543521
AM
7050static bfd_vma *
7051get_dynamic_data (FILE *file, unsigned int number, unsigned int ent_size)
252b5132 7052{
b34976b6 7053 unsigned char *e_data;
66543521 7054 bfd_vma *i_data;
252b5132 7055
c256ffe7 7056 e_data = cmalloc (number, ent_size);
252b5132
RH
7057
7058 if (e_data == NULL)
7059 {
7060 error (_("Out of memory\n"));
7061 return NULL;
7062 }
7063
66543521 7064 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
7065 {
7066 error (_("Unable to read in dynamic data\n"));
7067 return NULL;
7068 }
7069
c256ffe7 7070 i_data = cmalloc (number, sizeof (*i_data));
252b5132
RH
7071
7072 if (i_data == NULL)
7073 {
7074 error (_("Out of memory\n"));
7075 free (e_data);
7076 return NULL;
7077 }
7078
7079 while (number--)
66543521 7080 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
7081
7082 free (e_data);
7083
7084 return i_data;
7085}
7086
6bd1a22c
L
7087static void
7088print_dynamic_symbol (bfd_vma si, unsigned long hn)
7089{
7090 Elf_Internal_Sym *psym;
7091 int n;
7092
7093 psym = dynamic_symbols + si;
7094
7095 n = print_vma (si, DEC_5);
7096 if (n < 5)
7097 fputs (" " + n, stdout);
7098 printf (" %3lu: ", hn);
7099 print_vma (psym->st_value, LONG_HEX);
7100 putchar (' ');
7101 print_vma (psym->st_size, DEC_5);
7102
7103 printf (" %6s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7104 printf (" %6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
7105 printf (" %3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
7106 /* Check to see if any other bits in the st_other field are set.
7107 Note - displaying this information disrupts the layout of the
7108 table being generated, but for the moment this case is very
7109 rare. */
7110 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7111 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
7112 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
7113 if (VALID_DYNAMIC_NAME (psym->st_name))
7114 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
7115 else
7116 printf (" <corrupt: %14ld>", psym->st_name);
7117 putchar ('\n');
7118}
7119
e3c8793a 7120/* Dump the symbol table. */
252b5132 7121static int
d3ba0551 7122process_symbol_table (FILE *file)
252b5132 7123{
b34976b6 7124 Elf_Internal_Shdr *section;
66543521
AM
7125 bfd_vma nbuckets = 0;
7126 bfd_vma nchains = 0;
7127 bfd_vma *buckets = NULL;
7128 bfd_vma *chains = NULL;
fdc90cb4
JJ
7129 bfd_vma ngnubuckets = 0;
7130 bfd_vma *gnubuckets = NULL;
7131 bfd_vma *gnuchains = NULL;
6bd1a22c 7132 bfd_vma gnusymidx = 0;
252b5132
RH
7133
7134 if (! do_syms && !do_histogram)
7135 return 1;
7136
6bd1a22c
L
7137 if (dynamic_info[DT_HASH]
7138 && (do_histogram
7139 || (do_using_dynamic && dynamic_strings != NULL)))
252b5132 7140 {
66543521
AM
7141 unsigned char nb[8];
7142 unsigned char nc[8];
7143 int hash_ent_size = 4;
7144
7145 if ((elf_header.e_machine == EM_ALPHA
7146 || elf_header.e_machine == EM_S390
7147 || elf_header.e_machine == EM_S390_OLD)
7148 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
7149 hash_ent_size = 8;
7150
fb52b2f4
NC
7151 if (fseek (file,
7152 (archive_file_offset
7153 + offset_from_vma (file, dynamic_info[DT_HASH],
7154 sizeof nb + sizeof nc)),
d93f0186 7155 SEEK_SET))
252b5132 7156 {
591a748a 7157 error (_("Unable to seek to start of dynamic information\n"));
252b5132
RH
7158 return 0;
7159 }
7160
66543521 7161 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
7162 {
7163 error (_("Failed to read in number of buckets\n"));
7164 return 0;
7165 }
7166
66543521 7167 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
7168 {
7169 error (_("Failed to read in number of chains\n"));
7170 return 0;
7171 }
7172
66543521
AM
7173 nbuckets = byte_get (nb, hash_ent_size);
7174 nchains = byte_get (nc, hash_ent_size);
252b5132 7175
66543521
AM
7176 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
7177 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132
RH
7178
7179 if (buckets == NULL || chains == NULL)
7180 return 0;
7181 }
7182
6bd1a22c
L
7183 if (dynamic_info_DT_GNU_HASH
7184 && (do_histogram
7185 || (do_using_dynamic && dynamic_strings != NULL)))
252b5132 7186 {
6bd1a22c
L
7187 unsigned char nb[16];
7188 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
7189 bfd_vma buckets_vma;
7190
7191 if (fseek (file,
7192 (archive_file_offset
7193 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
7194 sizeof nb)),
7195 SEEK_SET))
7196 {
7197 error (_("Unable to seek to start of dynamic information\n"));
7198 return 0;
7199 }
252b5132 7200
6bd1a22c
L
7201 if (fread (nb, 16, 1, file) != 1)
7202 {
7203 error (_("Failed to read in number of buckets\n"));
7204 return 0;
7205 }
7206
7207 ngnubuckets = byte_get (nb, 4);
7208 gnusymidx = byte_get (nb + 4, 4);
7209 bitmaskwords = byte_get (nb + 8, 4);
7210 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 7211 if (is_32bit_elf)
6bd1a22c 7212 buckets_vma += bitmaskwords * 4;
f7a99963 7213 else
6bd1a22c 7214 buckets_vma += bitmaskwords * 8;
252b5132 7215
6bd1a22c
L
7216 if (fseek (file,
7217 (archive_file_offset
7218 + offset_from_vma (file, buckets_vma, 4)),
7219 SEEK_SET))
252b5132 7220 {
6bd1a22c
L
7221 error (_("Unable to seek to start of dynamic information\n"));
7222 return 0;
7223 }
7224
7225 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 7226
6bd1a22c
L
7227 if (gnubuckets == NULL)
7228 return 0;
7229
7230 for (i = 0; i < ngnubuckets; i++)
7231 if (gnubuckets[i] != 0)
7232 {
7233 if (gnubuckets[i] < gnusymidx)
7234 return 0;
7235
7236 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
7237 maxchain = gnubuckets[i];
7238 }
7239
7240 if (maxchain == 0xffffffff)
7241 return 0;
7242
7243 maxchain -= gnusymidx;
7244
7245 if (fseek (file,
7246 (archive_file_offset
7247 + offset_from_vma (file, buckets_vma
7248 + 4 * (ngnubuckets + maxchain), 4)),
7249 SEEK_SET))
7250 {
7251 error (_("Unable to seek to start of dynamic information\n"));
7252 return 0;
7253 }
7254
7255 do
7256 {
7257 if (fread (nb, 4, 1, file) != 1)
252b5132 7258 {
6bd1a22c
L
7259 error (_("Failed to determine last chain length\n"));
7260 return 0;
7261 }
252b5132 7262
6bd1a22c
L
7263 if (maxchain + 1 == 0)
7264 return 0;
252b5132 7265
6bd1a22c
L
7266 ++maxchain;
7267 }
7268 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 7269
6bd1a22c
L
7270 if (fseek (file,
7271 (archive_file_offset
7272 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
7273 SEEK_SET))
7274 {
7275 error (_("Unable to seek to start of dynamic information\n"));
7276 return 0;
7277 }
7278
7279 gnuchains = get_dynamic_data (file, maxchain, 4);
7280
7281 if (gnuchains == NULL)
7282 return 0;
7283 }
7284
7285 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
7286 && do_syms
7287 && do_using_dynamic
7288 && dynamic_strings != NULL)
7289 {
7290 unsigned long hn;
7291
7292 if (dynamic_info[DT_HASH])
7293 {
7294 bfd_vma si;
7295
7296 printf (_("\nSymbol table for image:\n"));
7297 if (is_32bit_elf)
7298 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7299 else
7300 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7301
7302 for (hn = 0; hn < nbuckets; hn++)
7303 {
7304 if (! buckets[hn])
7305 continue;
7306
7307 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
7308 print_dynamic_symbol (si, hn);
252b5132
RH
7309 }
7310 }
6bd1a22c
L
7311
7312 if (dynamic_info_DT_GNU_HASH)
7313 {
7314 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
7315 if (is_32bit_elf)
7316 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7317 else
7318 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7319
7320 for (hn = 0; hn < ngnubuckets; ++hn)
7321 if (gnubuckets[hn] != 0)
7322 {
7323 bfd_vma si = gnubuckets[hn];
7324 bfd_vma off = si - gnusymidx;
7325
7326 do
7327 {
7328 print_dynamic_symbol (si, hn);
7329 si++;
7330 }
7331 while ((gnuchains[off++] & 1) == 0);
7332 }
7333 }
252b5132
RH
7334 }
7335 else if (do_syms && !do_using_dynamic)
7336 {
b34976b6 7337 unsigned int i;
252b5132
RH
7338
7339 for (i = 0, section = section_headers;
7340 i < elf_header.e_shnum;
7341 i++, section++)
7342 {
b34976b6 7343 unsigned int si;
c256ffe7
JJ
7344 char *strtab = NULL;
7345 unsigned long int strtab_size = 0;
b34976b6
AM
7346 Elf_Internal_Sym *symtab;
7347 Elf_Internal_Sym *psym;
252b5132
RH
7348
7349
7350 if ( section->sh_type != SHT_SYMTAB
7351 && section->sh_type != SHT_DYNSYM)
7352 continue;
7353
7354 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
7355 SECTION_NAME (section),
7356 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 7357 if (is_32bit_elf)
ca47b30c 7358 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 7359 else
ca47b30c 7360 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 7361
9ad5cbcf 7362 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
7363 if (symtab == NULL)
7364 continue;
7365
7366 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
7367 {
7368 strtab = string_table;
7369 strtab_size = string_table_length;
7370 }
7371 else if (SECTION_HEADER_INDEX (section->sh_link) < elf_header.e_shnum)
252b5132 7372 {
b34976b6 7373 Elf_Internal_Shdr *string_sec;
252b5132 7374
9ad5cbcf 7375 string_sec = SECTION_HEADER (section->sh_link);
252b5132 7376
d3ba0551 7377 strtab = get_data (NULL, file, string_sec->sh_offset,
c256ffe7
JJ
7378 1, string_sec->sh_size, _("string table"));
7379 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
7380 }
7381
7382 for (si = 0, psym = symtab;
7383 si < section->sh_size / section->sh_entsize;
b34976b6 7384 si++, psym++)
252b5132 7385 {
5e220199 7386 printf ("%6d: ", si);
f7a99963
NC
7387 print_vma (psym->st_value, LONG_HEX);
7388 putchar (' ');
7389 print_vma (psym->st_size, DEC_5);
d1133906
NC
7390 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7391 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
7392 printf (" %-3s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
7393 /* Check to see if any other bits in the st_other field are set.
7394 Note - displaying this information disrupts the layout of the
7395 table being generated, but for the moment this case is very rare. */
7396 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7397 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 7398 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7
JJ
7399 print_symbol (25, psym->st_name < strtab_size
7400 ? strtab + psym->st_name : "<corrupt>");
252b5132
RH
7401
7402 if (section->sh_type == SHT_DYNSYM &&
b34976b6 7403 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 7404 {
b34976b6
AM
7405 unsigned char data[2];
7406 unsigned short vers_data;
7407 unsigned long offset;
7408 int is_nobits;
7409 int check_def;
252b5132 7410
d93f0186
NC
7411 offset = offset_from_vma
7412 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
7413 sizeof data + si * sizeof (vers_data));
252b5132 7414
a6e9f9df 7415 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 7416 sizeof (data), 1, _("version data"));
252b5132
RH
7417
7418 vers_data = byte_get (data, 2);
7419
c256ffe7
JJ
7420 is_nobits = (SECTION_HEADER_INDEX (psym->st_shndx)
7421 < elf_header.e_shnum
7422 && SECTION_HEADER (psym->st_shndx)->sh_type
7423 == SHT_NOBITS);
252b5132
RH
7424
7425 check_def = (psym->st_shndx != SHN_UNDEF);
7426
7427 if ((vers_data & 0x8000) || vers_data > 1)
7428 {
b34976b6 7429 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 7430 && (is_nobits || ! check_def))
252b5132 7431 {
b34976b6
AM
7432 Elf_External_Verneed evn;
7433 Elf_Internal_Verneed ivn;
7434 Elf_Internal_Vernaux ivna;
252b5132
RH
7435
7436 /* We must test both. */
d93f0186
NC
7437 offset = offset_from_vma
7438 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
7439 sizeof evn);
252b5132 7440
252b5132
RH
7441 do
7442 {
b34976b6 7443 unsigned long vna_off;
252b5132 7444
c256ffe7 7445 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 7446 _("version need"));
dd27201e
L
7447
7448 ivn.vn_aux = BYTE_GET (evn.vn_aux);
7449 ivn.vn_next = BYTE_GET (evn.vn_next);
7450
252b5132
RH
7451 vna_off = offset + ivn.vn_aux;
7452
7453 do
7454 {
b34976b6 7455 Elf_External_Vernaux evna;
252b5132 7456
a6e9f9df 7457 get_data (&evna, file, vna_off,
c256ffe7 7458 sizeof (evna), 1,
a6e9f9df 7459 _("version need aux (3)"));
252b5132
RH
7460
7461 ivna.vna_other = BYTE_GET (evna.vna_other);
7462 ivna.vna_next = BYTE_GET (evna.vna_next);
7463 ivna.vna_name = BYTE_GET (evna.vna_name);
7464
7465 vna_off += ivna.vna_next;
7466 }
7467 while (ivna.vna_other != vers_data
7468 && ivna.vna_next != 0);
7469
7470 if (ivna.vna_other == vers_data)
7471 break;
7472
7473 offset += ivn.vn_next;
7474 }
7475 while (ivn.vn_next != 0);
7476
7477 if (ivna.vna_other == vers_data)
7478 {
7479 printf ("@%s (%d)",
c256ffe7
JJ
7480 ivna.vna_name < strtab_size
7481 ? strtab + ivna.vna_name : "<corrupt>",
7482 ivna.vna_other);
252b5132
RH
7483 check_def = 0;
7484 }
7485 else if (! is_nobits)
591a748a 7486 error (_("bad dynamic symbol\n"));
252b5132
RH
7487 else
7488 check_def = 1;
7489 }
7490
7491 if (check_def)
7492 {
00d93f34 7493 if (vers_data != 0x8001
b34976b6 7494 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 7495 {
b34976b6
AM
7496 Elf_Internal_Verdef ivd;
7497 Elf_Internal_Verdaux ivda;
7498 Elf_External_Verdaux evda;
7499 unsigned long offset;
252b5132 7500
d93f0186
NC
7501 offset = offset_from_vma
7502 (file,
7503 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
7504 sizeof (Elf_External_Verdef));
252b5132
RH
7505
7506 do
7507 {
b34976b6 7508 Elf_External_Verdef evd;
252b5132 7509
a6e9f9df 7510 get_data (&evd, file, offset, sizeof (evd),
c256ffe7 7511 1, _("version def"));
252b5132 7512
b34976b6
AM
7513 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
7514 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
7515 ivd.vd_next = BYTE_GET (evd.vd_next);
7516
7517 offset += ivd.vd_next;
7518 }
7519 while (ivd.vd_ndx != (vers_data & 0x7fff)
7520 && ivd.vd_next != 0);
7521
7522 offset -= ivd.vd_next;
7523 offset += ivd.vd_aux;
7524
a6e9f9df 7525 get_data (&evda, file, offset, sizeof (evda),
c256ffe7 7526 1, _("version def aux"));
252b5132
RH
7527
7528 ivda.vda_name = BYTE_GET (evda.vda_name);
7529
7530 if (psym->st_name != ivda.vda_name)
7531 printf ((vers_data & 0x8000)
7532 ? "@%s" : "@@%s",
c256ffe7
JJ
7533 ivda.vda_name < strtab_size
7534 ? strtab + ivda.vda_name : "<corrupt>");
252b5132
RH
7535 }
7536 }
7537 }
7538 }
7539
7540 putchar ('\n');
7541 }
7542
7543 free (symtab);
7544 if (strtab != string_table)
7545 free (strtab);
7546 }
7547 }
7548 else if (do_syms)
7549 printf
7550 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
7551
7552 if (do_histogram && buckets != NULL)
7553 {
66543521
AM
7554 unsigned long *lengths;
7555 unsigned long *counts;
7556 unsigned long hn;
7557 bfd_vma si;
7558 unsigned long maxlength = 0;
7559 unsigned long nzero_counts = 0;
7560 unsigned long nsyms = 0;
252b5132 7561
66543521
AM
7562 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
7563 (unsigned long) nbuckets);
252b5132
RH
7564 printf (_(" Length Number %% of total Coverage\n"));
7565
66543521 7566 lengths = calloc (nbuckets, sizeof (*lengths));
252b5132
RH
7567 if (lengths == NULL)
7568 {
591a748a 7569 error (_("Out of memory\n"));
252b5132
RH
7570 return 0;
7571 }
7572 for (hn = 0; hn < nbuckets; ++hn)
7573 {
f7a99963 7574 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 7575 {
b34976b6 7576 ++nsyms;
252b5132 7577 if (maxlength < ++lengths[hn])
b34976b6 7578 ++maxlength;
252b5132
RH
7579 }
7580 }
7581
66543521 7582 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
7583 if (counts == NULL)
7584 {
591a748a 7585 error (_("Out of memory\n"));
252b5132
RH
7586 return 0;
7587 }
7588
7589 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 7590 ++counts[lengths[hn]];
252b5132 7591
103f02d3 7592 if (nbuckets > 0)
252b5132 7593 {
66543521
AM
7594 unsigned long i;
7595 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 7596 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 7597 for (i = 1; i <= maxlength; ++i)
103f02d3 7598 {
66543521
AM
7599 nzero_counts += counts[i] * i;
7600 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7601 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
7602 (nzero_counts * 100.0) / nsyms);
7603 }
252b5132
RH
7604 }
7605
7606 free (counts);
7607 free (lengths);
7608 }
7609
7610 if (buckets != NULL)
7611 {
7612 free (buckets);
7613 free (chains);
7614 }
7615
fdc90cb4
JJ
7616 if (do_histogram && dynamic_info_DT_GNU_HASH)
7617 {
fdc90cb4
JJ
7618 unsigned long *lengths;
7619 unsigned long *counts;
7620 unsigned long hn;
7621 unsigned long maxlength = 0;
7622 unsigned long nzero_counts = 0;
7623 unsigned long nsyms = 0;
fdc90cb4
JJ
7624
7625 lengths = calloc (ngnubuckets, sizeof (*lengths));
7626 if (lengths == NULL)
7627 {
591a748a 7628 error (_("Out of memory\n"));
fdc90cb4
JJ
7629 return 0;
7630 }
7631
7632 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
7633 (unsigned long) ngnubuckets);
7634 printf (_(" Length Number %% of total Coverage\n"));
7635
7636 for (hn = 0; hn < ngnubuckets; ++hn)
7637 if (gnubuckets[hn] != 0)
7638 {
7639 bfd_vma off, length = 1;
7640
6bd1a22c 7641 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
7642 (gnuchains[off] & 1) == 0; ++off)
7643 ++length;
7644 lengths[hn] = length;
7645 if (length > maxlength)
7646 maxlength = length;
7647 nsyms += length;
7648 }
7649
7650 counts = calloc (maxlength + 1, sizeof (*counts));
7651 if (counts == NULL)
7652 {
591a748a 7653 error (_("Out of memory\n"));
fdc90cb4
JJ
7654 return 0;
7655 }
7656
7657 for (hn = 0; hn < ngnubuckets; ++hn)
7658 ++counts[lengths[hn]];
7659
7660 if (ngnubuckets > 0)
7661 {
7662 unsigned long j;
7663 printf (" 0 %-10lu (%5.1f%%)\n",
7664 counts[0], (counts[0] * 100.0) / ngnubuckets);
7665 for (j = 1; j <= maxlength; ++j)
7666 {
7667 nzero_counts += counts[j] * j;
7668 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7669 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
7670 (nzero_counts * 100.0) / nsyms);
7671 }
7672 }
7673
7674 free (counts);
7675 free (lengths);
7676 free (gnubuckets);
7677 free (gnuchains);
7678 }
7679
252b5132
RH
7680 return 1;
7681}
7682
7683static int
d3ba0551 7684process_syminfo (FILE *file ATTRIBUTE_UNUSED)
252b5132 7685{
b4c96d0d 7686 unsigned int i;
252b5132
RH
7687
7688 if (dynamic_syminfo == NULL
7689 || !do_dynamic)
7690 /* No syminfo, this is ok. */
7691 return 1;
7692
7693 /* There better should be a dynamic symbol section. */
7694 if (dynamic_symbols == NULL || dynamic_strings == NULL)
7695 return 0;
7696
7697 if (dynamic_addr)
7698 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
7699 dynamic_syminfo_offset, dynamic_syminfo_nent);
7700
7701 printf (_(" Num: Name BoundTo Flags\n"));
7702 for (i = 0; i < dynamic_syminfo_nent; ++i)
7703 {
7704 unsigned short int flags = dynamic_syminfo[i].si_flags;
7705
31104126 7706 printf ("%4d: ", i);
d79b3d50
NC
7707 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
7708 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
7709 else
7710 printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
31104126 7711 putchar (' ');
252b5132
RH
7712
7713 switch (dynamic_syminfo[i].si_boundto)
7714 {
7715 case SYMINFO_BT_SELF:
7716 fputs ("SELF ", stdout);
7717 break;
7718 case SYMINFO_BT_PARENT:
7719 fputs ("PARENT ", stdout);
7720 break;
7721 default:
7722 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
7723 && dynamic_syminfo[i].si_boundto < dynamic_nent
7724 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 7725 {
d79b3d50 7726 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
7727 putchar (' ' );
7728 }
252b5132
RH
7729 else
7730 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
7731 break;
7732 }
7733
7734 if (flags & SYMINFO_FLG_DIRECT)
7735 printf (" DIRECT");
7736 if (flags & SYMINFO_FLG_PASSTHRU)
7737 printf (" PASSTHRU");
7738 if (flags & SYMINFO_FLG_COPY)
7739 printf (" COPY");
7740 if (flags & SYMINFO_FLG_LAZYLOAD)
7741 printf (" LAZYLOAD");
7742
7743 puts ("");
7744 }
7745
7746 return 1;
7747}
7748
7749#ifdef SUPPORT_DISASSEMBLY
18bd398b 7750static int
d3ba0551 7751disassemble_section (Elf_Internal_Shdr *section, FILE *file)
252b5132
RH
7752{
7753 printf (_("\nAssembly dump of section %s\n"),
7754 SECTION_NAME (section));
7755
7756 /* XXX -- to be done --- XXX */
7757
7758 return 1;
7759}
7760#endif
7761
7762static int
09c11c86
NC
7763dump_section_as_strings (Elf_Internal_Shdr *section, FILE *file)
7764{
7765 Elf_Internal_Shdr *relsec;
7766 bfd_size_type num_bytes;
7767 bfd_vma addr;
7768 char *data;
7769 char *end;
7770 char *start;
7771 char *name = SECTION_NAME (section);
7772 bfd_boolean some_strings_shown;
7773
7774 num_bytes = section->sh_size;
7775
7776 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
7777 {
7778 printf (_("\nSection '%s' has no data to dump.\n"), name);
7779 return 0;
7780 }
7781
7782 addr = section->sh_addr;
7783
7784 start = get_data (NULL, file, section->sh_offset, 1, num_bytes,
7785 _("section data"));
7786 if (!start)
7787 return 0;
7788
7789 printf (_("\nString dump of section '%s':\n"), name);
7790
7791 /* If the section being dumped has relocations against it the user might
7792 be expecting these relocations to have been applied. Check for this
7793 case and issue a warning message in order to avoid confusion.
7794 FIXME: Maybe we ought to have an option that dumps a section with
7795 relocs applied ? */
7796 for (relsec = section_headers;
7797 relsec < section_headers + elf_header.e_shnum;
7798 ++relsec)
7799 {
7800 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
7801 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
7802 || SECTION_HEADER (relsec->sh_info) != section
7803 || relsec->sh_size == 0
7804 || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
7805 continue;
7806
7807 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
7808 break;
7809 }
7810
7811 data = start;
7812 end = start + num_bytes;
7813 some_strings_shown = FALSE;
7814
7815 while (data < end)
7816 {
7817 while (!ISPRINT (* data))
7818 if (++ data >= end)
7819 break;
7820
7821 if (data < end)
7822 {
6f08d80e 7823 printf (" [%6tx] %s\n", data - start, data);
09c11c86
NC
7824 data += strlen (data);
7825 some_strings_shown = TRUE;
7826 }
7827 }
7828
7829 if (! some_strings_shown)
7830 printf (_(" No strings found in this section."));
7831
7832 free (start);
7833
7834 putchar ('\n');
7835 return 1;
7836}
7837
7838
7839static int
7840dump_section_as_bytes (Elf_Internal_Shdr *section, FILE *file)
252b5132 7841{
4b78141a 7842 Elf_Internal_Shdr *relsec;
b34976b6
AM
7843 bfd_size_type bytes;
7844 bfd_vma addr;
7845 unsigned char *data;
7846 unsigned char *start;
252b5132
RH
7847
7848 bytes = section->sh_size;
7849
e69f2d21 7850 if (bytes == 0 || section->sh_type == SHT_NOBITS)
252b5132
RH
7851 {
7852 printf (_("\nSection '%s' has no data to dump.\n"),
7853 SECTION_NAME (section));
7854 return 0;
7855 }
7856 else
7857 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
7858
7859 addr = section->sh_addr;
7860
c256ffe7
JJ
7861 start = get_data (NULL, file, section->sh_offset, 1, bytes,
7862 _("section data"));
a6e9f9df
AM
7863 if (!start)
7864 return 0;
252b5132 7865
4b78141a
NC
7866 /* If the section being dumped has relocations against it the user might
7867 be expecting these relocations to have been applied. Check for this
7868 case and issue a warning message in order to avoid confusion.
7869 FIXME: Maybe we ought to have an option that dumps a section with
7870 relocs applied ? */
7871 for (relsec = section_headers;
7872 relsec < section_headers + elf_header.e_shnum;
7873 ++relsec)
7874 {
35d9dd2f 7875 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4b78141a
NC
7876 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
7877 || SECTION_HEADER (relsec->sh_info) != section
7878 || relsec->sh_size == 0
7879 || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
7880 continue;
7881
7882 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
7883 break;
7884 }
1118d252 7885
252b5132
RH
7886 data = start;
7887
7888 while (bytes)
7889 {
7890 int j;
7891 int k;
7892 int lbytes;
7893
7894 lbytes = (bytes > 16 ? 16 : bytes);
7895
148d3c43 7896 printf (" 0x%8.8lx ", (unsigned long) addr);
252b5132 7897
20414cab 7898 for (j = 0; j < 16; j++)
252b5132 7899 {
20414cab
AM
7900 if (j < lbytes)
7901 printf ("%2.2x", data[j]);
7902 else
7903 printf (" ");
252b5132 7904
20414cab
AM
7905 if ((j & 3) == 3)
7906 printf (" ");
252b5132
RH
7907 }
7908
7909 for (j = 0; j < lbytes; j++)
7910 {
b34976b6 7911 k = data[j];
9376f0c7 7912 if (k >= ' ' && k < 0x7f)
252b5132
RH
7913 printf ("%c", k);
7914 else
7915 printf (".");
7916 }
7917
7918 putchar ('\n');
7919
7920 data += lbytes;
7921 addr += lbytes;
7922 bytes -= lbytes;
7923 }
7924
7925 free (start);
7926
4b78141a 7927 putchar ('\n');
252b5132
RH
7928 return 1;
7929}
7930
4b78141a
NC
7931/* Return the number of bytes affected by a given reloc.
7932 This information is architecture and reloc dependent.
7933 Returns 4 by default, although this is not always correct.
7934 It should return 0 if a decision cannot be made.
7935 FIXME: This is not the correct way to solve this problem.
7936 The proper way is to have target specific reloc sizing functions
7937 created by the reloc-macros.h header, in the same way that it
7938 already creates the reloc naming functions. */
7939
7940static unsigned int
7941get_reloc_size (Elf_Internal_Rela * reloc)
7942{
7943 switch (elf_header.e_machine)
7944 {
7945 case EM_H8S:
7946 case EM_H8_300:
7947 case EM_H8_300H:
7948 case EM_H8_500:
7949 switch (ELF32_R_TYPE (reloc->r_info))
7950 {
7951 /* PR gas/3800 - without this information we do not correctly
7952 decode the debug information generated by the h8300 assembler. */
7953 case R_H8_DIR16:
7954 return 2;
7955 default:
7956 return 4;
7957 }
7958 default:
7959 /* FIXME: We need to extend this switch statement to cope with other
7960 architecture's relocs. (When those relocs are used against debug
7961 sections, and when their size is not 4). But see the multiple
7962 inclusions of <elf/h8.h> for an example of the hoops that we need
7963 to jump through in order to obtain the reloc numbers. */
7964 return 4;
7965 }
7966}
7967
1007acb3 7968/* Apply addends of RELA relocations. */
d9296b18 7969
1007acb3
L
7970static int
7971debug_apply_rela_addends (void *file,
7972 Elf_Internal_Shdr *section,
7973 unsigned char *start)
d9296b18 7974{
1007acb3
L
7975 Elf_Internal_Shdr *relsec;
7976 unsigned char *end = start + section->sh_size;
18bd398b 7977
1007acb3
L
7978 if (!is_relocatable)
7979 return 1;
d9296b18 7980
6528d0cb
KK
7981 /* SH uses RELA but uses in place value instead of the addend field. */
7982 if (elf_header.e_machine == EM_SH)
7983 return 0;
7984
5b18a4bc
NC
7985 for (relsec = section_headers;
7986 relsec < section_headers + elf_header.e_shnum;
7987 ++relsec)
252b5132 7988 {
5b18a4bc
NC
7989 unsigned long nrelas;
7990 Elf_Internal_Rela *rela, *rp;
7991 Elf_Internal_Shdr *symsec;
7992 Elf_Internal_Sym *symtab;
7993 Elf_Internal_Sym *sym;
252b5132 7994
5b18a4bc 7995 if (relsec->sh_type != SHT_RELA
c256ffe7 7996 || SECTION_HEADER_INDEX (relsec->sh_info) >= elf_header.e_shnum
5b18a4bc 7997 || SECTION_HEADER (relsec->sh_info) != section
c256ffe7
JJ
7998 || relsec->sh_size == 0
7999 || SECTION_HEADER_INDEX (relsec->sh_link) >= elf_header.e_shnum)
5b18a4bc 8000 continue;
428409d5 8001
5b18a4bc
NC
8002 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
8003 &rela, &nrelas))
8004 return 0;
428409d5 8005
5b18a4bc
NC
8006 symsec = SECTION_HEADER (relsec->sh_link);
8007 symtab = GET_ELF_SYMBOLS (file, symsec);
103f02d3 8008
5b18a4bc 8009 for (rp = rela; rp < rela + nrelas; ++rp)
252b5132 8010 {
5b18a4bc 8011 unsigned char *loc;
4b78141a
NC
8012 unsigned int reloc_size;
8013
8014 reloc_size = get_reloc_size (rp);
8015 if (reloc_size == 0)
8016 {
8017 warn (_("skipping relocation of unknown size against offset 0x%lx in section %s\n"),
8018 (unsigned long) rp->r_offset,
8019 SECTION_NAME (section));
8020 continue;
8021 }
103f02d3 8022
700dd8b7
L
8023 loc = start + rp->r_offset;
8024 if ((loc + reloc_size) > end)
8025 {
8026 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
8027 (unsigned long) rp->r_offset,
8028 SECTION_NAME (section));
8029 continue;
8030 }
103f02d3 8031
5b18a4bc
NC
8032 if (is_32bit_elf)
8033 {
8034 sym = symtab + ELF32_R_SYM (rp->r_info);
103f02d3 8035
5b18a4bc
NC
8036 if (ELF32_R_SYM (rp->r_info) != 0
8037 && ELF32_ST_TYPE (sym->st_info) != STT_SECTION
3b578682
L
8038 /* Relocations against symbols without type can happen.
8039 Gcc -feliminate-dwarf2-dups may generate symbols
8040 without type for debug info. */
8041 && ELF32_ST_TYPE (sym->st_info) != STT_NOTYPE
5b18a4bc
NC
8042 /* Relocations against object symbols can happen,
8043 eg when referencing a global array. For an
8044 example of this see the _clz.o binary in libgcc.a. */
8045 && ELF32_ST_TYPE (sym->st_info) != STT_OBJECT)
8046 {
520494b6 8047 warn (_("skipping unexpected symbol type %s in relocation in section .rela%s\n"),
5b18a4bc
NC
8048 get_symbol_type (ELF32_ST_TYPE (sym->st_info)),
8049 SECTION_NAME (section));
8050 continue;
8051 }
8052 }
8053 else
8054 {
a8b683fc
MR
8055 /* In MIPS little-endian objects, r_info isn't really a
8056 64-bit little-endian value: it has a 32-bit little-endian
8057 symbol index followed by four individual byte fields.
8058 Reorder INFO accordingly. */
8059 if (elf_header.e_machine == EM_MIPS
8060 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
8061 rp->r_info = (((rp->r_info & 0xffffffff) << 32)
8062 | ((rp->r_info >> 56) & 0xff)
8063 | ((rp->r_info >> 40) & 0xff00)
8064 | ((rp->r_info >> 24) & 0xff0000)
8065 | ((rp->r_info >> 8) & 0xff000000));
8066
5b18a4bc 8067 sym = symtab + ELF64_R_SYM (rp->r_info);
0e0c4098 8068
5b18a4bc
NC
8069 if (ELF64_R_SYM (rp->r_info) != 0
8070 && ELF64_ST_TYPE (sym->st_info) != STT_SECTION
3b578682 8071 && ELF64_ST_TYPE (sym->st_info) != STT_NOTYPE
5b18a4bc
NC
8072 && ELF64_ST_TYPE (sym->st_info) != STT_OBJECT)
8073 {
8074 warn (_("skipping unexpected symbol type %s in relocation in section .rela.%s\n"),
8075 get_symbol_type (ELF64_ST_TYPE (sym->st_info)),
8076 SECTION_NAME (section));
8077 continue;
8078 }
8079 }
252b5132 8080
5b18a4bc
NC
8081 byte_put (loc, rp->r_addend, reloc_size);
8082 }
252b5132 8083
5b18a4bc
NC
8084 free (symtab);
8085 free (rela);
8086 break;
8087 }
8088 return 1;
8089}
103f02d3 8090
19e6b90e
L
8091int
8092load_debug_section (enum dwarf_section_display_enum debug, void *file)
1007acb3 8093{
19e6b90e
L
8094 struct dwarf_section *section = &debug_displays [debug].section;
8095 Elf_Internal_Shdr *sec;
8096 char buf [64];
1007acb3 8097
19e6b90e
L
8098 /* If it is already loaded, do nothing. */
8099 if (section->start != NULL)
8100 return 1;
1007acb3 8101
19e6b90e
L
8102 /* Locate the debug section. */
8103 sec = find_section (section->name);
8104 if (sec == NULL)
8105 return 0;
1007acb3 8106
19e6b90e
L
8107 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
8108 section->address = sec->sh_addr;
8109 section->size = sec->sh_size;
8110 section->start = get_data (NULL, file, sec->sh_offset, 1,
8111 sec->sh_size, buf);
1007acb3 8112
19e6b90e
L
8113 if (debug_displays [debug].relocate)
8114 debug_apply_rela_addends (file, sec, section->start);
1007acb3 8115
19e6b90e 8116 return section->start != NULL;
1007acb3
L
8117}
8118
19e6b90e
L
8119void
8120free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 8121{
19e6b90e 8122 struct dwarf_section *section = &debug_displays [debug].section;
1007acb3 8123
19e6b90e
L
8124 if (section->start == NULL)
8125 return;
1007acb3 8126
19e6b90e
L
8127 free ((char *) section->start);
8128 section->start = NULL;
8129 section->address = 0;
8130 section->size = 0;
1007acb3
L
8131}
8132
1007acb3 8133static int
19e6b90e 8134display_debug_section (Elf_Internal_Shdr *section, FILE *file)
1007acb3 8135{
19e6b90e
L
8136 char *name = SECTION_NAME (section);
8137 bfd_size_type length;
8138 int result = 1;
8139 enum dwarf_section_display_enum i;
1007acb3 8140
19e6b90e
L
8141 length = section->sh_size;
8142 if (length == 0)
1007acb3 8143 {
19e6b90e
L
8144 printf (_("\nSection '%s' has no debugging data.\n"), name);
8145 return 0;
1007acb3
L
8146 }
8147
0112cd26 8148 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 8149 name = ".debug_info";
1007acb3 8150
19e6b90e
L
8151 /* See if we know how to display the contents of this section. */
8152 for (i = 0; i < max; i++)
8153 if (streq (debug_displays[i].section.name, name))
8154 {
8155 struct dwarf_section *sec = &debug_displays [i].section;
1007acb3 8156
19e6b90e
L
8157 if (load_debug_section (i, file))
8158 {
8159 result &= debug_displays[i].display (sec, file);
1007acb3 8160
19e6b90e
L
8161 if (i != info && i != abbrev)
8162 free_debug_section (i);
8163 }
1007acb3 8164
19e6b90e
L
8165 break;
8166 }
1007acb3 8167
19e6b90e 8168 if (i == max)
1007acb3 8169 {
19e6b90e
L
8170 printf (_("Unrecognized debug section: %s\n"), name);
8171 result = 0;
1007acb3
L
8172 }
8173
19e6b90e 8174 return result;
5b18a4bc 8175}
103f02d3 8176
aef1f6d0
DJ
8177/* Set DUMP_SECTS for all sections where dumps were requested
8178 based on section name. */
8179
8180static void
8181initialise_dumps_byname (void)
8182{
8183 struct dump_list_entry *cur;
8184
8185 for (cur = dump_sects_byname; cur; cur = cur->next)
8186 {
8187 unsigned int i;
8188 int any;
8189
8190 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
8191 if (streq (SECTION_NAME (section_headers + i), cur->name))
8192 {
09c11c86 8193 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
8194 any = 1;
8195 }
8196
8197 if (!any)
8198 warn (_("Section '%s' was not dumped because it does not exist!\n"),
8199 cur->name);
8200 }
8201}
8202
5b18a4bc 8203static void
19e6b90e 8204process_section_contents (FILE *file)
5b18a4bc 8205{
19e6b90e
L
8206 Elf_Internal_Shdr *section;
8207 unsigned int i;
103f02d3 8208
19e6b90e
L
8209 if (! do_dump)
8210 return;
103f02d3 8211
aef1f6d0
DJ
8212 initialise_dumps_byname ();
8213
19e6b90e
L
8214 for (i = 0, section = section_headers;
8215 i < elf_header.e_shnum && i < num_dump_sects;
8216 i++, section++)
8217 {
8218#ifdef SUPPORT_DISASSEMBLY
8219 if (dump_sects[i] & DISASS_DUMP)
8220 disassemble_section (section, file);
8221#endif
8222 if (dump_sects[i] & HEX_DUMP)
09c11c86 8223 dump_section_as_bytes (section, file);
103f02d3 8224
19e6b90e
L
8225 if (dump_sects[i] & DEBUG_DUMP)
8226 display_debug_section (section, file);
09c11c86
NC
8227
8228 if (dump_sects[i] & STRING_DUMP)
8229 dump_section_as_strings (section, file);
5b18a4bc 8230 }
103f02d3 8231
19e6b90e
L
8232 /* Check to see if the user requested a
8233 dump of a section that does not exist. */
8234 while (i++ < num_dump_sects)
8235 if (dump_sects[i])
8236 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 8237}
103f02d3 8238
5b18a4bc 8239static void
19e6b90e 8240process_mips_fpe_exception (int mask)
5b18a4bc 8241{
19e6b90e
L
8242 if (mask)
8243 {
8244 int first = 1;
8245 if (mask & OEX_FPU_INEX)
8246 fputs ("INEX", stdout), first = 0;
8247 if (mask & OEX_FPU_UFLO)
8248 printf ("%sUFLO", first ? "" : "|"), first = 0;
8249 if (mask & OEX_FPU_OFLO)
8250 printf ("%sOFLO", first ? "" : "|"), first = 0;
8251 if (mask & OEX_FPU_DIV0)
8252 printf ("%sDIV0", first ? "" : "|"), first = 0;
8253 if (mask & OEX_FPU_INVAL)
8254 printf ("%sINVAL", first ? "" : "|");
8255 }
5b18a4bc 8256 else
19e6b90e 8257 fputs ("0", stdout);
5b18a4bc 8258}
103f02d3 8259
11c1ff18
PB
8260/* ARM EABI attributes section. */
8261typedef struct
8262{
8263 int tag;
8264 const char *name;
8265 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
8266 int type;
8267 const char **table;
8268} arm_attr_public_tag;
8269
8270static const char *arm_attr_tag_CPU_arch[] =
8271 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
8272 "v6K", "v7"};
8273static const char *arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
8274static const char *arm_attr_tag_THUMB_ISA_use[] =
8275 {"No", "Thumb-1", "Thumb-2"};
14c28b74
JB
8276/* FIXME: VFPv3 encoding was extrapolated! */
8277static const char *arm_attr_tag_VFP_arch[] = {"No", "VFPv1", "VFPv2", "VFPv3"};
11c1ff18
PB
8278static const char *arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1"};
8279static const char *arm_attr_tag_NEON_arch[] = {"No", "NEONv1"};
8280static const char *arm_attr_tag_ABI_PCS_config[] =
8281 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
8282 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
8283static const char *arm_attr_tag_ABI_PCS_R9_use[] =
8284 {"V6", "SB", "TLS", "Unused"};
8285static const char *arm_attr_tag_ABI_PCS_RW_data[] =
8286 {"Absolute", "PC-relative", "SB-relative", "None"};
8287static const char *arm_attr_tag_ABI_PCS_RO_DATA[] =
8288 {"Absolute", "PC-relative", "None"};
8289static const char *arm_attr_tag_ABI_PCS_GOT_use[] =
8290 {"None", "direct", "GOT-indirect"};
8291static const char *arm_attr_tag_ABI_PCS_wchar_t[] =
8292 {"None", "??? 1", "2", "??? 3", "4"};
8293static const char *arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
8294static const char *arm_attr_tag_ABI_FP_denormal[] = {"Unused", "Needed"};
8295static const char *arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
8296static const char *arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
8297static const char *arm_attr_tag_ABI_FP_number_model[] =
8298 {"Unused", "Finite", "RTABI", "IEEE 754"};
8299static const char *arm_attr_tag_ABI_align8_needed[] = {"No", "Yes", "4-byte"};
8300static const char *arm_attr_tag_ABI_align8_preserved[] =
8301 {"No", "Yes, except leaf SP", "Yes"};
8302static const char *arm_attr_tag_ABI_enum_size[] =
8303 {"Unused", "small", "int", "forced to int"};
8304static const char *arm_attr_tag_ABI_HardFP_use[] =
8305 {"As Tag_VFP_arch", "SP only", "DP only", "SP and DP"};
8306static const char *arm_attr_tag_ABI_VFP_args[] =
8307 {"AAPCS", "VFP registers", "custom"};
8308static const char *arm_attr_tag_ABI_WMMX_args[] =
8309 {"AAPCS", "WMMX registers", "custom"};
8310static const char *arm_attr_tag_ABI_optimization_goals[] =
8311 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8312 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
8313static const char *arm_attr_tag_ABI_FP_optimization_goals[] =
8314 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8315 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
8316
8317#define LOOKUP(id, name) \
8318 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 8319static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
8320{
8321 {4, "CPU_raw_name", 1, NULL},
8322 {5, "CPU_name", 1, NULL},
8323 LOOKUP(6, CPU_arch),
8324 {7, "CPU_arch_profile", 0, NULL},
8325 LOOKUP(8, ARM_ISA_use),
8326 LOOKUP(9, THUMB_ISA_use),
8327 LOOKUP(10, VFP_arch),
8328 LOOKUP(11, WMMX_arch),
8329 LOOKUP(12, NEON_arch),
8330 LOOKUP(13, ABI_PCS_config),
8331 LOOKUP(14, ABI_PCS_R9_use),
8332 LOOKUP(15, ABI_PCS_RW_data),
8333 LOOKUP(16, ABI_PCS_RO_DATA),
8334 LOOKUP(17, ABI_PCS_GOT_use),
8335 LOOKUP(18, ABI_PCS_wchar_t),
8336 LOOKUP(19, ABI_FP_rounding),
8337 LOOKUP(20, ABI_FP_denormal),
8338 LOOKUP(21, ABI_FP_exceptions),
8339 LOOKUP(22, ABI_FP_user_exceptions),
8340 LOOKUP(23, ABI_FP_number_model),
8341 LOOKUP(24, ABI_align8_needed),
8342 LOOKUP(25, ABI_align8_preserved),
8343 LOOKUP(26, ABI_enum_size),
8344 LOOKUP(27, ABI_HardFP_use),
8345 LOOKUP(28, ABI_VFP_args),
8346 LOOKUP(29, ABI_WMMX_args),
8347 LOOKUP(30, ABI_optimization_goals),
8348 LOOKUP(31, ABI_FP_optimization_goals),
8349 {32, "compatibility", 0, NULL}
8350};
8351#undef LOOKUP
8352
8353/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
8354 bytes read. */
8355static unsigned int
8356read_uleb128 (unsigned char *p, unsigned int *plen)
8357{
8358 unsigned char c;
8359 unsigned int val;
8360 int shift;
8361 int len;
8362
8363 val = 0;
8364 shift = 0;
8365 len = 0;
8366 do
8367 {
8368 c = *(p++);
8369 len++;
8370 val |= ((unsigned int)c & 0x7f) << shift;
8371 shift += 7;
8372 }
8373 while (c & 0x80);
8374
8375 *plen = len;
8376 return val;
8377}
8378
8379static unsigned char *
8380display_arm_attribute (unsigned char *p)
8381{
8382 int tag;
8383 unsigned int len;
8384 int val;
8385 arm_attr_public_tag *attr;
8386 unsigned i;
8387 int type;
8388
8389 tag = read_uleb128 (p, &len);
8390 p += len;
8391 attr = NULL;
8392 for (i = 0; i < ARRAY_SIZE(arm_attr_public_tags); i++)
8393 {
8394 if (arm_attr_public_tags[i].tag == tag)
8395 {
8396 attr = &arm_attr_public_tags[i];
8397 break;
8398 }
8399 }
8400
8401 if (attr)
8402 {
8403 printf (" Tag_%s: ", attr->name);
8404 switch (attr->type)
8405 {
8406 case 0:
8407 switch (tag)
8408 {
8409 case 7: /* Tag_CPU_arch_profile. */
8410 val = read_uleb128 (p, &len);
8411 p += len;
8412 switch (val)
8413 {
8414 case 0: printf ("None\n"); break;
8415 case 'A': printf ("Application\n"); break;
8416 case 'R': printf ("Realtime\n"); break;
8417 case 'M': printf ("Microcontroller\n"); break;
8418 default: printf ("??? (%d)\n", val); break;
8419 }
8420 break;
8421
8422 case 32: /* Tag_compatibility. */
8423 val = read_uleb128 (p, &len);
8424 p += len;
8425 printf ("flag = %d, vendor = %s\n", val, p);
8426 p += strlen((char *)p) + 1;
8427 break;
8428
8429 default:
8430 abort();
8431 }
8432 return p;
8433
8434 case 1:
8435 case 2:
8436 type = attr->type;
8437 break;
8438
8439 default:
8440 assert (attr->type & 0x80);
8441 val = read_uleb128 (p, &len);
8442 p += len;
8443 type = attr->type & 0x7f;
8444 if (val >= type)
8445 printf ("??? (%d)\n", val);
8446 else
8447 printf ("%s\n", attr->table[val]);
8448 return p;
8449 }
8450 }
8451 else
8452 {
8453 if (tag & 1)
8454 type = 1; /* String. */
8455 else
8456 type = 2; /* uleb128. */
8457 printf (" Tag_unknown_%d: ", tag);
8458 }
8459
8460 if (type == 1)
8461 {
8462 printf ("\"%s\"\n", p);
8463 p += strlen((char *)p) + 1;
8464 }
8465 else
8466 {
8467 val = read_uleb128 (p, &len);
8468 p += len;
8469 printf ("%d (0x%x)\n", val, val);
8470 }
8471
8472 return p;
8473}
8474
104d59d1 8475static unsigned char *
60bca95a
NC
8476display_gnu_attribute (unsigned char * p,
8477 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
8478{
8479 int tag;
8480 unsigned int len;
8481 int val;
8482 int type;
8483
8484 tag = read_uleb128 (p, &len);
8485 p += len;
8486
8487 /* Tag_compatibility is the only generic GNU attribute defined at
8488 present. */
8489 if (tag == 32)
8490 {
8491 val = read_uleb128 (p, &len);
8492 p += len;
8493 printf ("flag = %d, vendor = %s\n", val, p);
60bca95a 8494 p += strlen ((char *) p) + 1;
104d59d1
JM
8495 return p;
8496 }
8497
8498 if ((tag & 2) == 0 && display_proc_gnu_attribute)
8499 return display_proc_gnu_attribute (p, tag);
8500
8501 if (tag & 1)
8502 type = 1; /* String. */
8503 else
8504 type = 2; /* uleb128. */
8505 printf (" Tag_unknown_%d: ", tag);
8506
8507 if (type == 1)
8508 {
8509 printf ("\"%s\"\n", p);
60bca95a 8510 p += strlen ((char *) p) + 1;
104d59d1
JM
8511 }
8512 else
8513 {
8514 val = read_uleb128 (p, &len);
8515 p += len;
8516 printf ("%d (0x%x)\n", val, val);
8517 }
8518
8519 return p;
8520}
8521
34c8bcba
JM
8522static unsigned char *
8523display_power_gnu_attribute (unsigned char *p, int tag)
8524{
8525 int type;
8526 unsigned int len;
8527 int val;
8528
8529 if (tag == Tag_GNU_Power_ABI_FP)
8530 {
8531 val = read_uleb128 (p, &len);
8532 p += len;
8533 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 8534
34c8bcba
JM
8535 switch (val)
8536 {
8537 case 0:
8538 printf ("Hard or soft float\n");
8539 break;
8540 case 1:
8541 printf ("Hard float\n");
8542 break;
8543 case 2:
8544 printf ("Soft float\n");
8545 break;
8546 default:
8547 printf ("??? (%d)\n", val);
8548 break;
8549 }
8550 return p;
8551 }
8552
8553 if (tag & 1)
8554 type = 1; /* String. */
8555 else
8556 type = 2; /* uleb128. */
8557 printf (" Tag_unknown_%d: ", tag);
8558
8559 if (type == 1)
8560 {
8561 printf ("\"%s\"\n", p);
60bca95a 8562 p += strlen ((char *) p) + 1;
34c8bcba
JM
8563 }
8564 else
8565 {
8566 val = read_uleb128 (p, &len);
8567 p += len;
8568 printf ("%d (0x%x)\n", val, val);
8569 }
8570
8571 return p;
8572}
8573
2cf19d5c
JM
8574static unsigned char *
8575display_mips_gnu_attribute (unsigned char *p, int tag)
8576{
8577 int type;
8578 unsigned int len;
8579 int val;
8580
8581 if (tag == Tag_GNU_MIPS_ABI_FP)
8582 {
8583 val = read_uleb128 (p, &len);
8584 p += len;
8585 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 8586
2cf19d5c
JM
8587 switch (val)
8588 {
8589 case 0:
8590 printf ("Hard or soft float\n");
8591 break;
8592 case 1:
8593 printf ("Hard float (-mdouble-float)\n");
8594 break;
8595 case 2:
8596 printf ("Hard float (-msingle-float)\n");
8597 break;
8598 case 3:
8599 printf ("Soft float\n");
8600 break;
8601 default:
8602 printf ("??? (%d)\n", val);
8603 break;
8604 }
8605 return p;
8606 }
8607
8608 if (tag & 1)
8609 type = 1; /* String. */
8610 else
8611 type = 2; /* uleb128. */
8612 printf (" Tag_unknown_%d: ", tag);
8613
8614 if (type == 1)
8615 {
8616 printf ("\"%s\"\n", p);
60bca95a 8617 p += strlen ((char *) p) + 1;
2cf19d5c
JM
8618 }
8619 else
8620 {
8621 val = read_uleb128 (p, &len);
8622 p += len;
8623 printf ("%d (0x%x)\n", val, val);
8624 }
8625
8626 return p;
8627}
8628
11c1ff18 8629static int
60bca95a
NC
8630process_attributes (FILE * file,
8631 const char * public_name,
104d59d1 8632 unsigned int proc_type,
60bca95a
NC
8633 unsigned char * (* display_pub_attribute) (unsigned char *),
8634 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18
PB
8635{
8636 Elf_Internal_Shdr *sect;
8637 unsigned char *contents;
8638 unsigned char *p;
8639 unsigned char *end;
8640 bfd_vma section_len;
8641 bfd_vma len;
8642 unsigned i;
8643
8644 /* Find the section header so that we get the size. */
8645 for (i = 0, sect = section_headers;
8646 i < elf_header.e_shnum;
8647 i++, sect++)
8648 {
104d59d1 8649 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
8650 continue;
8651
8652 contents = get_data (NULL, file, sect->sh_offset, 1, sect->sh_size,
8653 _("attributes"));
60bca95a 8654 if (contents == NULL)
11c1ff18 8655 continue;
60bca95a 8656
11c1ff18
PB
8657 p = contents;
8658 if (*p == 'A')
8659 {
8660 len = sect->sh_size - 1;
8661 p++;
60bca95a 8662
11c1ff18
PB
8663 while (len > 0)
8664 {
8665 int namelen;
8666 bfd_boolean public_section;
104d59d1 8667 bfd_boolean gnu_section;
11c1ff18
PB
8668
8669 section_len = byte_get (p, 4);
8670 p += 4;
60bca95a 8671
11c1ff18
PB
8672 if (section_len > len)
8673 {
8674 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 8675 (int) section_len, (int) len);
11c1ff18
PB
8676 section_len = len;
8677 }
60bca95a 8678
11c1ff18
PB
8679 len -= section_len;
8680 printf ("Attribute Section: %s\n", p);
60bca95a
NC
8681
8682 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
8683 public_section = TRUE;
8684 else
8685 public_section = FALSE;
60bca95a
NC
8686
8687 if (streq ((char *) p, "gnu"))
104d59d1
JM
8688 gnu_section = TRUE;
8689 else
8690 gnu_section = FALSE;
60bca95a
NC
8691
8692 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
8693 p += namelen;
8694 section_len -= namelen + 4;
60bca95a 8695
11c1ff18
PB
8696 while (section_len > 0)
8697 {
8698 int tag = *(p++);
8699 int val;
8700 bfd_vma size;
60bca95a 8701
11c1ff18
PB
8702 size = byte_get (p, 4);
8703 if (size > section_len)
8704 {
8705 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 8706 (int) size, (int) section_len);
11c1ff18
PB
8707 size = section_len;
8708 }
60bca95a 8709
11c1ff18
PB
8710 section_len -= size;
8711 end = p + size - 1;
8712 p += 4;
60bca95a 8713
11c1ff18
PB
8714 switch (tag)
8715 {
8716 case 1:
8717 printf ("File Attributes\n");
8718 break;
8719 case 2:
8720 printf ("Section Attributes:");
8721 goto do_numlist;
8722 case 3:
8723 printf ("Symbol Attributes:");
8724 do_numlist:
8725 for (;;)
8726 {
8727 unsigned int i;
60bca95a 8728
11c1ff18
PB
8729 val = read_uleb128 (p, &i);
8730 p += i;
8731 if (val == 0)
8732 break;
8733 printf (" %d", val);
8734 }
8735 printf ("\n");
8736 break;
8737 default:
8738 printf ("Unknown tag: %d\n", tag);
8739 public_section = FALSE;
8740 break;
8741 }
60bca95a 8742
11c1ff18
PB
8743 if (public_section)
8744 {
8745 while (p < end)
104d59d1
JM
8746 p = display_pub_attribute (p);
8747 }
8748 else if (gnu_section)
8749 {
8750 while (p < end)
8751 p = display_gnu_attribute (p,
8752 display_proc_gnu_attribute);
11c1ff18
PB
8753 }
8754 else
8755 {
8756 /* ??? Do something sensible, like dump hex. */
8757 printf (" Unknown section contexts\n");
8758 p = end;
8759 }
8760 }
8761 }
8762 }
8763 else
60bca95a 8764 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 8765
60bca95a 8766 free (contents);
11c1ff18
PB
8767 }
8768 return 1;
8769}
8770
104d59d1
JM
8771static int
8772process_arm_specific (FILE *file)
8773{
8774 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
8775 display_arm_attribute, NULL);
8776}
8777
34c8bcba
JM
8778static int
8779process_power_specific (FILE *file)
8780{
8781 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
8782 display_power_gnu_attribute);
8783}
8784
19e6b90e
L
8785static int
8786process_mips_specific (FILE *file)
5b18a4bc 8787{
19e6b90e
L
8788 Elf_Internal_Dyn *entry;
8789 size_t liblist_offset = 0;
8790 size_t liblistno = 0;
8791 size_t conflictsno = 0;
8792 size_t options_offset = 0;
8793 size_t conflicts_offset = 0;
103f02d3 8794
2cf19d5c
JM
8795 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
8796 display_mips_gnu_attribute);
8797
19e6b90e
L
8798 /* We have a lot of special sections. Thanks SGI! */
8799 if (dynamic_section == NULL)
8800 /* No information available. */
8801 return 0;
252b5132 8802
b2d38a17 8803 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
8804 switch (entry->d_tag)
8805 {
8806 case DT_MIPS_LIBLIST:
d93f0186
NC
8807 liblist_offset
8808 = offset_from_vma (file, entry->d_un.d_val,
8809 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
8810 break;
8811 case DT_MIPS_LIBLISTNO:
8812 liblistno = entry->d_un.d_val;
8813 break;
8814 case DT_MIPS_OPTIONS:
d93f0186 8815 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
8816 break;
8817 case DT_MIPS_CONFLICT:
d93f0186
NC
8818 conflicts_offset
8819 = offset_from_vma (file, entry->d_un.d_val,
8820 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
8821 break;
8822 case DT_MIPS_CONFLICTNO:
8823 conflictsno = entry->d_un.d_val;
8824 break;
8825 default:
8826 break;
8827 }
8828
8829 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
8830 {
b34976b6 8831 Elf32_External_Lib *elib;
252b5132
RH
8832 size_t cnt;
8833
d3ba0551 8834 elib = get_data (NULL, file, liblist_offset,
c256ffe7 8835 liblistno, sizeof (Elf32_External_Lib),
d3ba0551 8836 _("liblist"));
a6e9f9df 8837 if (elib)
252b5132 8838 {
a6e9f9df
AM
8839 printf ("\nSection '.liblist' contains %lu entries:\n",
8840 (unsigned long) liblistno);
8841 fputs (" Library Time Stamp Checksum Version Flags\n",
8842 stdout);
8843
8844 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 8845 {
a6e9f9df
AM
8846 Elf32_Lib liblist;
8847 time_t time;
8848 char timebuf[20];
b34976b6 8849 struct tm *tmp;
a6e9f9df
AM
8850
8851 liblist.l_name = BYTE_GET (elib[cnt].l_name);
8852 time = BYTE_GET (elib[cnt].l_time_stamp);
8853 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
8854 liblist.l_version = BYTE_GET (elib[cnt].l_version);
8855 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
8856
8857 tmp = gmtime (&time);
e9e44622
JJ
8858 snprintf (timebuf, sizeof (timebuf),
8859 "%04u-%02u-%02uT%02u:%02u:%02u",
8860 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8861 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 8862
31104126 8863 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
8864 if (VALID_DYNAMIC_NAME (liblist.l_name))
8865 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
8866 else
8867 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
8868 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
8869 liblist.l_version);
a6e9f9df
AM
8870
8871 if (liblist.l_flags == 0)
8872 puts (" NONE");
8873 else
8874 {
8875 static const struct
252b5132 8876 {
b34976b6 8877 const char *name;
a6e9f9df 8878 int bit;
252b5132 8879 }
a6e9f9df
AM
8880 l_flags_vals[] =
8881 {
8882 { " EXACT_MATCH", LL_EXACT_MATCH },
8883 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
8884 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
8885 { " EXPORTS", LL_EXPORTS },
8886 { " DELAY_LOAD", LL_DELAY_LOAD },
8887 { " DELTA", LL_DELTA }
8888 };
8889 int flags = liblist.l_flags;
8890 size_t fcnt;
8891
60bca95a 8892 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
8893 if ((flags & l_flags_vals[fcnt].bit) != 0)
8894 {
8895 fputs (l_flags_vals[fcnt].name, stdout);
8896 flags ^= l_flags_vals[fcnt].bit;
8897 }
8898 if (flags != 0)
8899 printf (" %#x", (unsigned int) flags);
252b5132 8900
a6e9f9df
AM
8901 puts ("");
8902 }
252b5132 8903 }
252b5132 8904
a6e9f9df
AM
8905 free (elib);
8906 }
252b5132
RH
8907 }
8908
8909 if (options_offset != 0)
8910 {
b34976b6
AM
8911 Elf_External_Options *eopt;
8912 Elf_Internal_Shdr *sect = section_headers;
8913 Elf_Internal_Options *iopt;
8914 Elf_Internal_Options *option;
252b5132
RH
8915 size_t offset;
8916 int cnt;
8917
8918 /* Find the section header so that we get the size. */
8919 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 8920 ++sect;
252b5132 8921
c256ffe7 8922 eopt = get_data (NULL, file, options_offset, 1, sect->sh_size,
d3ba0551 8923 _("options"));
a6e9f9df 8924 if (eopt)
252b5132 8925 {
c256ffe7 8926 iopt = cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (*iopt));
a6e9f9df
AM
8927 if (iopt == NULL)
8928 {
591a748a 8929 error (_("Out of memory\n"));
a6e9f9df
AM
8930 return 0;
8931 }
76da6bbe 8932
a6e9f9df
AM
8933 offset = cnt = 0;
8934 option = iopt;
252b5132 8935
a6e9f9df
AM
8936 while (offset < sect->sh_size)
8937 {
b34976b6 8938 Elf_External_Options *eoption;
252b5132 8939
a6e9f9df 8940 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 8941
a6e9f9df
AM
8942 option->kind = BYTE_GET (eoption->kind);
8943 option->size = BYTE_GET (eoption->size);
8944 option->section = BYTE_GET (eoption->section);
8945 option->info = BYTE_GET (eoption->info);
76da6bbe 8946
a6e9f9df 8947 offset += option->size;
252b5132 8948
a6e9f9df
AM
8949 ++option;
8950 ++cnt;
8951 }
252b5132 8952
a6e9f9df
AM
8953 printf (_("\nSection '%s' contains %d entries:\n"),
8954 SECTION_NAME (sect), cnt);
76da6bbe 8955
a6e9f9df 8956 option = iopt;
252b5132 8957
a6e9f9df 8958 while (cnt-- > 0)
252b5132 8959 {
a6e9f9df
AM
8960 size_t len;
8961
8962 switch (option->kind)
252b5132 8963 {
a6e9f9df
AM
8964 case ODK_NULL:
8965 /* This shouldn't happen. */
8966 printf (" NULL %d %lx", option->section, option->info);
8967 break;
8968 case ODK_REGINFO:
8969 printf (" REGINFO ");
8970 if (elf_header.e_machine == EM_MIPS)
8971 {
8972 /* 32bit form. */
b34976b6
AM
8973 Elf32_External_RegInfo *ereg;
8974 Elf32_RegInfo reginfo;
a6e9f9df
AM
8975
8976 ereg = (Elf32_External_RegInfo *) (option + 1);
8977 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8978 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
8979 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
8980 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
8981 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
8982 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
8983
8984 printf ("GPR %08lx GP 0x%lx\n",
8985 reginfo.ri_gprmask,
8986 (unsigned long) reginfo.ri_gp_value);
8987 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
8988 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
8989 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
8990 }
8991 else
8992 {
8993 /* 64 bit form. */
b34976b6 8994 Elf64_External_RegInfo *ereg;
a6e9f9df
AM
8995 Elf64_Internal_RegInfo reginfo;
8996
8997 ereg = (Elf64_External_RegInfo *) (option + 1);
8998 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
8999 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
9000 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
9001 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
9002 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 9003 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
9004
9005 printf ("GPR %08lx GP 0x",
9006 reginfo.ri_gprmask);
9007 printf_vma (reginfo.ri_gp_value);
9008 printf ("\n");
9009
9010 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
9011 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
9012 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
9013 }
9014 ++option;
9015 continue;
9016 case ODK_EXCEPTIONS:
9017 fputs (" EXCEPTIONS fpe_min(", stdout);
9018 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
9019 fputs (") fpe_max(", stdout);
9020 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
9021 fputs (")", stdout);
9022
9023 if (option->info & OEX_PAGE0)
9024 fputs (" PAGE0", stdout);
9025 if (option->info & OEX_SMM)
9026 fputs (" SMM", stdout);
9027 if (option->info & OEX_FPDBUG)
9028 fputs (" FPDBUG", stdout);
9029 if (option->info & OEX_DISMISS)
9030 fputs (" DISMISS", stdout);
9031 break;
9032 case ODK_PAD:
9033 fputs (" PAD ", stdout);
9034 if (option->info & OPAD_PREFIX)
9035 fputs (" PREFIX", stdout);
9036 if (option->info & OPAD_POSTFIX)
9037 fputs (" POSTFIX", stdout);
9038 if (option->info & OPAD_SYMBOL)
9039 fputs (" SYMBOL", stdout);
9040 break;
9041 case ODK_HWPATCH:
9042 fputs (" HWPATCH ", stdout);
9043 if (option->info & OHW_R4KEOP)
9044 fputs (" R4KEOP", stdout);
9045 if (option->info & OHW_R8KPFETCH)
9046 fputs (" R8KPFETCH", stdout);
9047 if (option->info & OHW_R5KEOP)
9048 fputs (" R5KEOP", stdout);
9049 if (option->info & OHW_R5KCVTL)
9050 fputs (" R5KCVTL", stdout);
9051 break;
9052 case ODK_FILL:
9053 fputs (" FILL ", stdout);
9054 /* XXX Print content of info word? */
9055 break;
9056 case ODK_TAGS:
9057 fputs (" TAGS ", stdout);
9058 /* XXX Print content of info word? */
9059 break;
9060 case ODK_HWAND:
9061 fputs (" HWAND ", stdout);
9062 if (option->info & OHWA0_R4KEOP_CHECKED)
9063 fputs (" R4KEOP_CHECKED", stdout);
9064 if (option->info & OHWA0_R4KEOP_CLEAN)
9065 fputs (" R4KEOP_CLEAN", stdout);
9066 break;
9067 case ODK_HWOR:
9068 fputs (" HWOR ", stdout);
9069 if (option->info & OHWA0_R4KEOP_CHECKED)
9070 fputs (" R4KEOP_CHECKED", stdout);
9071 if (option->info & OHWA0_R4KEOP_CLEAN)
9072 fputs (" R4KEOP_CLEAN", stdout);
9073 break;
9074 case ODK_GP_GROUP:
9075 printf (" GP_GROUP %#06lx self-contained %#06lx",
9076 option->info & OGP_GROUP,
9077 (option->info & OGP_SELF) >> 16);
9078 break;
9079 case ODK_IDENT:
9080 printf (" IDENT %#06lx self-contained %#06lx",
9081 option->info & OGP_GROUP,
9082 (option->info & OGP_SELF) >> 16);
9083 break;
9084 default:
9085 /* This shouldn't happen. */
9086 printf (" %3d ??? %d %lx",
9087 option->kind, option->section, option->info);
9088 break;
252b5132 9089 }
a6e9f9df 9090
b34976b6 9091 len = sizeof (*eopt);
a6e9f9df
AM
9092 while (len < option->size)
9093 if (((char *) option)[len] >= ' '
9094 && ((char *) option)[len] < 0x7f)
9095 printf ("%c", ((char *) option)[len++]);
9096 else
9097 printf ("\\%03o", ((char *) option)[len++]);
9098
9099 fputs ("\n", stdout);
252b5132 9100 ++option;
252b5132
RH
9101 }
9102
a6e9f9df 9103 free (eopt);
252b5132 9104 }
252b5132
RH
9105 }
9106
9107 if (conflicts_offset != 0 && conflictsno != 0)
9108 {
b34976b6 9109 Elf32_Conflict *iconf;
252b5132
RH
9110 size_t cnt;
9111
9112 if (dynamic_symbols == NULL)
9113 {
591a748a 9114 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
9115 return 0;
9116 }
9117
c256ffe7 9118 iconf = cmalloc (conflictsno, sizeof (*iconf));
252b5132
RH
9119 if (iconf == NULL)
9120 {
591a748a 9121 error (_("Out of memory\n"));
252b5132
RH
9122 return 0;
9123 }
9124
9ea033b2 9125 if (is_32bit_elf)
252b5132 9126 {
b34976b6 9127 Elf32_External_Conflict *econf32;
a6e9f9df 9128
d3ba0551 9129 econf32 = get_data (NULL, file, conflicts_offset,
c256ffe7 9130 conflictsno, sizeof (*econf32), _("conflict"));
a6e9f9df
AM
9131 if (!econf32)
9132 return 0;
252b5132
RH
9133
9134 for (cnt = 0; cnt < conflictsno; ++cnt)
9135 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
9136
9137 free (econf32);
252b5132
RH
9138 }
9139 else
9140 {
b34976b6 9141 Elf64_External_Conflict *econf64;
a6e9f9df 9142
d3ba0551 9143 econf64 = get_data (NULL, file, conflicts_offset,
c256ffe7 9144 conflictsno, sizeof (*econf64), _("conflict"));
a6e9f9df
AM
9145 if (!econf64)
9146 return 0;
252b5132
RH
9147
9148 for (cnt = 0; cnt < conflictsno; ++cnt)
9149 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
9150
9151 free (econf64);
252b5132
RH
9152 }
9153
c7e7ca54
NC
9154 printf (_("\nSection '.conflict' contains %lu entries:\n"),
9155 (unsigned long) conflictsno);
252b5132
RH
9156 puts (_(" Num: Index Value Name"));
9157
9158 for (cnt = 0; cnt < conflictsno; ++cnt)
9159 {
b34976b6 9160 Elf_Internal_Sym *psym = & dynamic_symbols[iconf[cnt]];
252b5132 9161
b34976b6 9162 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 9163 print_vma (psym->st_value, FULL_HEX);
31104126 9164 putchar (' ');
d79b3d50
NC
9165 if (VALID_DYNAMIC_NAME (psym->st_name))
9166 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
9167 else
9168 printf ("<corrupt: %14ld>", psym->st_name);
31104126 9169 putchar ('\n');
252b5132
RH
9170 }
9171
252b5132
RH
9172 free (iconf);
9173 }
9174
9175 return 1;
9176}
9177
047b2264 9178static int
d3ba0551 9179process_gnu_liblist (FILE *file)
047b2264 9180{
b34976b6
AM
9181 Elf_Internal_Shdr *section, *string_sec;
9182 Elf32_External_Lib *elib;
9183 char *strtab;
c256ffe7 9184 size_t strtab_size;
047b2264
JJ
9185 size_t cnt;
9186 unsigned i;
9187
9188 if (! do_arch)
9189 return 0;
9190
9191 for (i = 0, section = section_headers;
9192 i < elf_header.e_shnum;
b34976b6 9193 i++, section++)
047b2264
JJ
9194 {
9195 switch (section->sh_type)
9196 {
9197 case SHT_GNU_LIBLIST:
c256ffe7
JJ
9198 if (SECTION_HEADER_INDEX (section->sh_link) >= elf_header.e_shnum)
9199 break;
9200
9201 elib = get_data (NULL, file, section->sh_offset, 1, section->sh_size,
d3ba0551 9202 _("liblist"));
047b2264
JJ
9203
9204 if (elib == NULL)
9205 break;
9206 string_sec = SECTION_HEADER (section->sh_link);
9207
c256ffe7 9208 strtab = get_data (NULL, file, string_sec->sh_offset, 1,
d3ba0551 9209 string_sec->sh_size, _("liblist string table"));
c256ffe7 9210 strtab_size = string_sec->sh_size;
047b2264
JJ
9211
9212 if (strtab == NULL
9213 || section->sh_entsize != sizeof (Elf32_External_Lib))
9214 {
9215 free (elib);
9216 break;
9217 }
9218
9219 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
9220 SECTION_NAME (section),
9221 (long) (section->sh_size / sizeof (Elf32_External_Lib)));
9222
9223 puts (" Library Time Stamp Checksum Version Flags");
9224
9225 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
9226 ++cnt)
9227 {
9228 Elf32_Lib liblist;
9229 time_t time;
9230 char timebuf[20];
b34976b6 9231 struct tm *tmp;
047b2264
JJ
9232
9233 liblist.l_name = BYTE_GET (elib[cnt].l_name);
9234 time = BYTE_GET (elib[cnt].l_time_stamp);
9235 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
9236 liblist.l_version = BYTE_GET (elib[cnt].l_version);
9237 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
9238
9239 tmp = gmtime (&time);
e9e44622
JJ
9240 snprintf (timebuf, sizeof (timebuf),
9241 "%04u-%02u-%02uT%02u:%02u:%02u",
9242 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9243 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9244
9245 printf ("%3lu: ", (unsigned long) cnt);
9246 if (do_wide)
c256ffe7
JJ
9247 printf ("%-20s", liblist.l_name < strtab_size
9248 ? strtab + liblist.l_name : "<corrupt>");
047b2264 9249 else
c256ffe7
JJ
9250 printf ("%-20.20s", liblist.l_name < strtab_size
9251 ? strtab + liblist.l_name : "<corrupt>");
047b2264
JJ
9252 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
9253 liblist.l_version, liblist.l_flags);
9254 }
9255
9256 free (elib);
9257 }
9258 }
9259
9260 return 1;
9261}
9262
9437c45b 9263static const char *
d3ba0551 9264get_note_type (unsigned e_type)
779fe533
NC
9265{
9266 static char buff[64];
103f02d3 9267
1ec5cd37
NC
9268 if (elf_header.e_type == ET_CORE)
9269 switch (e_type)
9270 {
57346661 9271 case NT_AUXV:
1ec5cd37 9272 return _("NT_AUXV (auxiliary vector)");
57346661 9273 case NT_PRSTATUS:
1ec5cd37 9274 return _("NT_PRSTATUS (prstatus structure)");
57346661 9275 case NT_FPREGSET:
1ec5cd37 9276 return _("NT_FPREGSET (floating point registers)");
57346661 9277 case NT_PRPSINFO:
1ec5cd37 9278 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 9279 case NT_TASKSTRUCT:
1ec5cd37 9280 return _("NT_TASKSTRUCT (task structure)");
57346661 9281 case NT_PRXFPREG:
1ec5cd37 9282 return _("NT_PRXFPREG (user_xfpregs structure)");
57346661 9283 case NT_PSTATUS:
1ec5cd37 9284 return _("NT_PSTATUS (pstatus structure)");
57346661 9285 case NT_FPREGS:
1ec5cd37 9286 return _("NT_FPREGS (floating point registers)");
57346661 9287 case NT_PSINFO:
1ec5cd37 9288 return _("NT_PSINFO (psinfo structure)");
57346661 9289 case NT_LWPSTATUS:
1ec5cd37 9290 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 9291 case NT_LWPSINFO:
1ec5cd37 9292 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 9293 case NT_WIN32PSTATUS:
1ec5cd37
NC
9294 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9295 default:
9296 break;
9297 }
9298 else
9299 switch (e_type)
9300 {
9301 case NT_VERSION:
9302 return _("NT_VERSION (version)");
9303 case NT_ARCH:
9304 return _("NT_ARCH (architecture)");
9305 default:
9306 break;
9307 }
9308
e9e44622 9309 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 9310 return buff;
779fe533
NC
9311}
9312
1118d252
RM
9313static const char *
9314get_gnu_elf_note_type (unsigned e_type)
9315{
9316 static char buff[64];
9317
9318 switch (e_type)
9319 {
9320 case NT_GNU_ABI_TAG:
9321 return _("NT_GNU_ABI_TAG (ABI version tag)");
9322 case NT_GNU_HWCAP:
9323 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
9324 case NT_GNU_BUILD_ID:
9325 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
9326 default:
9327 break;
9328 }
9329
9330 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9331 return buff;
9332}
9333
9437c45b 9334static const char *
d3ba0551 9335get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
9336{
9337 static char buff[64];
9338
b4db1224 9339 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
9340 {
9341 /* NetBSD core "procinfo" structure. */
9342 return _("NetBSD procinfo structure");
9343 }
9344
9345 /* As of Jan 2002 there are no other machine-independent notes
9346 defined for NetBSD core files. If the note type is less
9347 than the start of the machine-dependent note types, we don't
9348 understand it. */
9349
b4db1224 9350 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 9351 {
e9e44622 9352 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
9353 return buff;
9354 }
9355
9356 switch (elf_header.e_machine)
9357 {
9358 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
9359 and PT_GETFPREGS == mach+2. */
9360
9361 case EM_OLD_ALPHA:
9362 case EM_ALPHA:
9363 case EM_SPARC:
9364 case EM_SPARC32PLUS:
9365 case EM_SPARCV9:
9366 switch (e_type)
9367 {
b4db1224
JT
9368 case NT_NETBSDCORE_FIRSTMACH+0:
9369 return _("PT_GETREGS (reg structure)");
9370 case NT_NETBSDCORE_FIRSTMACH+2:
9371 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
9372 default:
9373 break;
9374 }
9375 break;
9376
9377 /* On all other arch's, PT_GETREGS == mach+1 and
9378 PT_GETFPREGS == mach+3. */
9379 default:
9380 switch (e_type)
9381 {
b4db1224
JT
9382 case NT_NETBSDCORE_FIRSTMACH+1:
9383 return _("PT_GETREGS (reg structure)");
9384 case NT_NETBSDCORE_FIRSTMACH+3:
9385 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
9386 default:
9387 break;
9388 }
9389 }
9390
e9e44622
JJ
9391 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
9392 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
9393 return buff;
9394}
9395
6d118b09
NC
9396/* Note that by the ELF standard, the name field is already null byte
9397 terminated, and namesz includes the terminating null byte.
9398 I.E. the value of namesz for the name "FSF" is 4.
9399
e3c8793a 9400 If the value of namesz is zero, there is no name present. */
779fe533 9401static int
d3ba0551 9402process_note (Elf_Internal_Note *pnote)
779fe533 9403{
b15fa79e 9404 const char *name = pnote->namesz ? pnote->namedata : "(NONE)";
9437c45b
JT
9405 const char *nt;
9406
9407 if (pnote->namesz == 0)
1ec5cd37
NC
9408 /* If there is no note name, then use the default set of
9409 note type strings. */
9410 nt = get_note_type (pnote->type);
9411
1118d252
RM
9412 else if (const_strneq (pnote->namedata, "GNU"))
9413 /* GNU-specific object file notes. */
9414 nt = get_gnu_elf_note_type (pnote->type);
9415
0112cd26 9416 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
9417 /* NetBSD-specific core file notes. */
9418 nt = get_netbsd_elfcore_note_type (pnote->type);
9419
b15fa79e
AM
9420 else if (strneq (pnote->namedata, "SPU/", 4))
9421 {
9422 /* SPU-specific core file notes. */
9423 nt = pnote->namedata + 4;
9424 name = "SPU";
9425 }
9426
9437c45b 9427 else
1ec5cd37
NC
9428 /* Don't recognize this note name; just use the default set of
9429 note type strings. */
9437c45b 9430 nt = get_note_type (pnote->type);
9437c45b 9431
b15fa79e 9432 printf (" %s\t\t0x%08lx\t%s\n", name, pnote->descsz, nt);
779fe533
NC
9433 return 1;
9434}
9435
6d118b09 9436
779fe533 9437static int
d3ba0551 9438process_corefile_note_segment (FILE *file, bfd_vma offset, bfd_vma length)
779fe533 9439{
b34976b6
AM
9440 Elf_External_Note *pnotes;
9441 Elf_External_Note *external;
9442 int res = 1;
103f02d3 9443
779fe533
NC
9444 if (length <= 0)
9445 return 0;
103f02d3 9446
c256ffe7 9447 pnotes = get_data (NULL, file, offset, 1, length, _("notes"));
a6e9f9df
AM
9448 if (!pnotes)
9449 return 0;
779fe533 9450
103f02d3 9451 external = pnotes;
103f02d3 9452
305c7206 9453 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 9454 (unsigned long) offset, (unsigned long) length);
779fe533 9455 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 9456
6d118b09 9457 while (external < (Elf_External_Note *)((char *) pnotes + length))
779fe533 9458 {
b34976b6
AM
9459 Elf_External_Note *next;
9460 Elf_Internal_Note inote;
9461 char *temp = NULL;
6d118b09
NC
9462
9463 inote.type = BYTE_GET (external->type);
9464 inote.namesz = BYTE_GET (external->namesz);
9465 inote.namedata = external->name;
9466 inote.descsz = BYTE_GET (external->descsz);
9467 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
9468 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 9469
3e55a963
NC
9470 next = (Elf_External_Note *)(inote.descdata + align_power (inote.descsz, 2));
9471
9472 if (((char *) next) > (((char *) pnotes) + length))
9473 {
0fd3a477
JW
9474 warn (_("corrupt note found at offset %lx into core notes\n"),
9475 (long)((char *)external - (char *)pnotes));
9476 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
9477 inote.type, inote.namesz, inote.descsz);
9478 break;
9479 }
9480
9481 external = next;
6d118b09
NC
9482
9483 /* Verify that name is null terminated. It appears that at least
9484 one version of Linux (RedHat 6.0) generates corefiles that don't
9485 comply with the ELF spec by failing to include the null byte in
9486 namesz. */
9487 if (inote.namedata[inote.namesz] != '\0')
9488 {
9489 temp = malloc (inote.namesz + 1);
76da6bbe 9490
6d118b09
NC
9491 if (temp == NULL)
9492 {
9493 error (_("Out of memory\n"));
9494 res = 0;
9495 break;
9496 }
76da6bbe 9497
6d118b09
NC
9498 strncpy (temp, inote.namedata, inote.namesz);
9499 temp[inote.namesz] = 0;
76da6bbe 9500
6d118b09
NC
9501 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
9502 inote.namedata = temp;
9503 }
9504
9505 res &= process_note (& inote);
103f02d3 9506
6d118b09
NC
9507 if (temp != NULL)
9508 {
9509 free (temp);
9510 temp = NULL;
9511 }
779fe533
NC
9512 }
9513
9514 free (pnotes);
103f02d3 9515
779fe533
NC
9516 return res;
9517}
9518
9519static int
d3ba0551 9520process_corefile_note_segments (FILE *file)
779fe533 9521{
b34976b6
AM
9522 Elf_Internal_Phdr *segment;
9523 unsigned int i;
9524 int res = 1;
103f02d3 9525
d93f0186 9526 if (! get_program_headers (file))
779fe533 9527 return 0;
103f02d3 9528
779fe533
NC
9529 for (i = 0, segment = program_headers;
9530 i < elf_header.e_phnum;
b34976b6 9531 i++, segment++)
779fe533
NC
9532 {
9533 if (segment->p_type == PT_NOTE)
103f02d3 9534 res &= process_corefile_note_segment (file,
30800947
NC
9535 (bfd_vma) segment->p_offset,
9536 (bfd_vma) segment->p_filesz);
779fe533 9537 }
103f02d3 9538
779fe533
NC
9539 return res;
9540}
9541
9542static int
1ec5cd37
NC
9543process_note_sections (FILE *file)
9544{
9545 Elf_Internal_Shdr *section;
9546 unsigned long i;
9547 int res = 1;
9548
9549 for (i = 0, section = section_headers;
9550 i < elf_header.e_shnum;
9551 i++, section++)
9552 if (section->sh_type == SHT_NOTE)
9553 res &= process_corefile_note_segment (file,
9554 (bfd_vma) section->sh_offset,
9555 (bfd_vma) section->sh_size);
9556
9557 return res;
9558}
9559
9560static int
9561process_notes (FILE *file)
779fe533
NC
9562{
9563 /* If we have not been asked to display the notes then do nothing. */
9564 if (! do_notes)
9565 return 1;
103f02d3 9566
779fe533 9567 if (elf_header.e_type != ET_CORE)
1ec5cd37 9568 return process_note_sections (file);
103f02d3 9569
779fe533 9570 /* No program headers means no NOTE segment. */
1ec5cd37
NC
9571 if (elf_header.e_phnum > 0)
9572 return process_corefile_note_segments (file);
779fe533 9573
1ec5cd37
NC
9574 printf (_("No note segments present in the core file.\n"));
9575 return 1;
779fe533
NC
9576}
9577
252b5132 9578static int
d3ba0551 9579process_arch_specific (FILE *file)
252b5132 9580{
a952a375
NC
9581 if (! do_arch)
9582 return 1;
9583
252b5132
RH
9584 switch (elf_header.e_machine)
9585 {
11c1ff18
PB
9586 case EM_ARM:
9587 return process_arm_specific (file);
252b5132 9588 case EM_MIPS:
4fe85591 9589 case EM_MIPS_RS3_LE:
252b5132
RH
9590 return process_mips_specific (file);
9591 break;
34c8bcba
JM
9592 case EM_PPC:
9593 return process_power_specific (file);
9594 break;
252b5132
RH
9595 default:
9596 break;
9597 }
9598 return 1;
9599}
9600
9601static int
d3ba0551 9602get_file_header (FILE *file)
252b5132 9603{
9ea033b2
NC
9604 /* Read in the identity array. */
9605 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
9606 return 0;
9607
9ea033b2 9608 /* Determine how to read the rest of the header. */
b34976b6 9609 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
9610 {
9611 default: /* fall through */
9612 case ELFDATANONE: /* fall through */
adab8cdc
AO
9613 case ELFDATA2LSB:
9614 byte_get = byte_get_little_endian;
9615 byte_put = byte_put_little_endian;
9616 break;
9617 case ELFDATA2MSB:
9618 byte_get = byte_get_big_endian;
9619 byte_put = byte_put_big_endian;
9620 break;
9ea033b2
NC
9621 }
9622
9623 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 9624 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
9625
9626 /* Read in the rest of the header. */
9627 if (is_32bit_elf)
9628 {
9629 Elf32_External_Ehdr ehdr32;
252b5132 9630
9ea033b2
NC
9631 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
9632 return 0;
103f02d3 9633
9ea033b2
NC
9634 elf_header.e_type = BYTE_GET (ehdr32.e_type);
9635 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
9636 elf_header.e_version = BYTE_GET (ehdr32.e_version);
9637 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
9638 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
9639 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
9640 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
9641 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
9642 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
9643 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
9644 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
9645 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
9646 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9647 }
252b5132 9648 else
9ea033b2
NC
9649 {
9650 Elf64_External_Ehdr ehdr64;
a952a375
NC
9651
9652 /* If we have been compiled with sizeof (bfd_vma) == 4, then
9653 we will not be able to cope with the 64bit data found in
9654 64 ELF files. Detect this now and abort before we start
50c2245b 9655 overwriting things. */
a952a375
NC
9656 if (sizeof (bfd_vma) < 8)
9657 {
e3c8793a
NC
9658 error (_("This instance of readelf has been built without support for a\n\
965964 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
9660 return 0;
9661 }
103f02d3 9662
9ea033b2
NC
9663 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
9664 return 0;
103f02d3 9665
9ea033b2
NC
9666 elf_header.e_type = BYTE_GET (ehdr64.e_type);
9667 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
9668 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
9669 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
9670 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
9671 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
9672 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
9673 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
9674 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
9675 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
9676 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
9677 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
9678 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9679 }
252b5132 9680
7ece0d85
JJ
9681 if (elf_header.e_shoff)
9682 {
9683 /* There may be some extensions in the first section header. Don't
9684 bomb if we can't read it. */
9685 if (is_32bit_elf)
9686 get_32bit_section_headers (file, 1);
9687 else
9688 get_64bit_section_headers (file, 1);
9689 }
560f3c1c 9690
1007acb3
L
9691 is_relocatable = elf_header.e_type == ET_REL;
9692
252b5132
RH
9693 return 1;
9694}
9695
fb52b2f4
NC
9696/* Process one ELF object file according to the command line options.
9697 This file may actually be stored in an archive. The file is
9698 positioned at the start of the ELF object. */
9699
ff78d6d6 9700static int
fb52b2f4 9701process_object (char *file_name, FILE *file)
252b5132 9702{
252b5132
RH
9703 unsigned int i;
9704
252b5132
RH
9705 if (! get_file_header (file))
9706 {
9707 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 9708 return 1;
252b5132
RH
9709 }
9710
9711 /* Initialise per file variables. */
60bca95a 9712 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
9713 version_info[i] = 0;
9714
60bca95a 9715 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132
RH
9716 dynamic_info[i] = 0;
9717
9718 /* Process the file. */
9719 if (show_name)
9720 printf (_("\nFile: %s\n"), file_name);
9721
18bd398b
NC
9722 /* Initialise the dump_sects array from the cmdline_dump_sects array.
9723 Note we do this even if cmdline_dump_sects is empty because we
9724 must make sure that the dump_sets array is zeroed out before each
9725 object file is processed. */
9726 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 9727 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
9728
9729 if (num_cmdline_dump_sects > 0)
9730 {
9731 if (num_dump_sects == 0)
9732 /* A sneaky way of allocating the dump_sects array. */
09c11c86 9733 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
9734
9735 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
9736 memcpy (dump_sects, cmdline_dump_sects,
9737 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 9738 }
d70c5fc7 9739
252b5132 9740 if (! process_file_header ())
fb52b2f4 9741 return 1;
252b5132 9742
d1f5c6e3 9743 if (! process_section_headers (file))
2f62977e 9744 {
d1f5c6e3
L
9745 /* Without loaded section headers we cannot process lots of
9746 things. */
2f62977e 9747 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 9748
2f62977e
NC
9749 if (! do_using_dynamic)
9750 do_syms = do_reloc = 0;
9751 }
252b5132 9752
d1f5c6e3
L
9753 if (! process_section_groups (file))
9754 {
9755 /* Without loaded section groups we cannot process unwind. */
9756 do_unwind = 0;
9757 }
9758
2f62977e 9759 if (process_program_headers (file))
b2d38a17 9760 process_dynamic_section (file);
252b5132
RH
9761
9762 process_relocs (file);
9763
4d6ed7c8
NC
9764 process_unwind (file);
9765
252b5132
RH
9766 process_symbol_table (file);
9767
9768 process_syminfo (file);
9769
9770 process_version_sections (file);
9771
9772 process_section_contents (file);
f5842774 9773
1ec5cd37 9774 process_notes (file);
103f02d3 9775
047b2264
JJ
9776 process_gnu_liblist (file);
9777
252b5132
RH
9778 process_arch_specific (file);
9779
d93f0186
NC
9780 if (program_headers)
9781 {
9782 free (program_headers);
9783 program_headers = NULL;
9784 }
9785
252b5132
RH
9786 if (section_headers)
9787 {
9788 free (section_headers);
9789 section_headers = NULL;
9790 }
9791
9792 if (string_table)
9793 {
9794 free (string_table);
9795 string_table = NULL;
d40ac9bd 9796 string_table_length = 0;
252b5132
RH
9797 }
9798
9799 if (dynamic_strings)
9800 {
9801 free (dynamic_strings);
9802 dynamic_strings = NULL;
d79b3d50 9803 dynamic_strings_length = 0;
252b5132
RH
9804 }
9805
9806 if (dynamic_symbols)
9807 {
9808 free (dynamic_symbols);
9809 dynamic_symbols = NULL;
19936277 9810 num_dynamic_syms = 0;
252b5132
RH
9811 }
9812
9813 if (dynamic_syminfo)
9814 {
9815 free (dynamic_syminfo);
9816 dynamic_syminfo = NULL;
9817 }
ff78d6d6 9818
e4b17d5c
L
9819 if (section_headers_groups)
9820 {
9821 free (section_headers_groups);
9822 section_headers_groups = NULL;
9823 }
9824
9825 if (section_groups)
9826 {
9827 struct group_list *g, *next;
9828
9829 for (i = 0; i < group_count; i++)
9830 {
9831 for (g = section_groups [i].root; g != NULL; g = next)
9832 {
9833 next = g->next;
9834 free (g);
9835 }
9836 }
9837
9838 free (section_groups);
9839 section_groups = NULL;
9840 }
9841
19e6b90e 9842 free_debug_memory ();
18bd398b 9843
ff78d6d6 9844 return 0;
252b5132
RH
9845}
9846
4145f1d5
NC
9847/* Process an ELF archive.
9848 On entry the file is positioned just after the ARMAG string. */
fb52b2f4
NC
9849
9850static int
9851process_archive (char *file_name, FILE *file)
9852{
9853 struct ar_hdr arhdr;
9854 size_t got;
9855 unsigned long size;
4145f1d5
NC
9856 unsigned long index_num = 0;
9857 unsigned long *index_array = NULL;
9858 char *sym_table = NULL;
9859 unsigned long sym_size = 0;
fb52b2f4
NC
9860 char *longnames = NULL;
9861 unsigned long longnames_size = 0;
9862 size_t file_name_size;
d989285c 9863 int ret;
fb52b2f4
NC
9864
9865 show_name = 1;
9866
9867 got = fread (&arhdr, 1, sizeof arhdr, file);
9868 if (got != sizeof arhdr)
9869 {
9870 if (got == 0)
9871 return 0;
9872
9873 error (_("%s: failed to read archive header\n"), file_name);
9874 return 1;
9875 }
9876
4145f1d5 9877 /* See if this is the archive symbol table. */
317e5c40
AN
9878 if (const_strneq (arhdr.ar_name, "/ ")
9879 || const_strneq (arhdr.ar_name, "/SYM64/ "))
fb52b2f4 9880 {
fb52b2f4 9881 size = strtoul (arhdr.ar_size, NULL, 10);
4145f1d5
NC
9882 size = size + (size & 1);
9883
9884 if (do_archive_index)
fb52b2f4 9885 {
4145f1d5
NC
9886 unsigned long i;
9887 /* A buffer used to hold numbers read in from an archive index.
9888 These are always 4 bytes long and stored in big-endian format. */
9889#define SIZEOF_AR_INDEX_NUMBERS 4
9890 unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
9891 unsigned char * index_buffer;
9892
9893 /* Check the size of the archive index. */
9894 if (size < SIZEOF_AR_INDEX_NUMBERS)
9895 {
9896 error (_("%s: the archive index is empty\n"), file_name);
9897 return 1;
9898 }
9899
9900 /* Read the numer of entries in the archive index. */
9901 got = fread (integer_buffer, 1, sizeof integer_buffer, file);
9902 if (got != sizeof (integer_buffer))
9903 {
9904 error (_("%s: failed to read archive index\n"), file_name);
9905 return 1;
9906 }
9907 index_num = byte_get_big_endian (integer_buffer, sizeof integer_buffer);
9908 size -= SIZEOF_AR_INDEX_NUMBERS;
9909
9910 /* Read in the archive index. */
9911 if (size < index_num * SIZEOF_AR_INDEX_NUMBERS)
9912 {
9913 error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
9914 file_name, index_num);
9915 return 1;
9916 }
9917 index_buffer = malloc (index_num * SIZEOF_AR_INDEX_NUMBERS);
9918 if (index_buffer == NULL)
9919 {
9920 error (_("Out of memory whilst trying to read archive symbol index\n"));
9921 return 1;
9922 }
9923 got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, index_num, file);
9924 if (got != index_num)
9925 {
9926 free (index_buffer);
9927 error (_("%s: failed to read archive index\n"), file_name);
9928 ret = 1;
9929 goto out;
9930 }
9931 size -= index_num * SIZEOF_AR_INDEX_NUMBERS;
9932
9933 /* Convert the index numbers into the host's numeric format. */
9934 index_array = malloc (index_num * sizeof (* index_array));
9935 if (index_array == NULL)
9936 {
9937 free (index_buffer);
9938 error (_("Out of memory whilst trying to convert the archive symbol index\n"));
9939 return 1;
9940 }
9941
9942 for (i = 0; i < index_num; i++)
9943 index_array[i] = byte_get_big_endian ((unsigned char *)(index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
9944 SIZEOF_AR_INDEX_NUMBERS);
9945 free (index_buffer);
9946
9947 /* The remaining space in the header is taken up by the symbol table. */
9948 if (size < 1)
9949 {
9950 error (_("%s: the archive has an index but no symbols\n"), file_name);
9951 ret = 1;
9952 goto out;
9953 }
9954 sym_table = malloc (size);
9955 sym_size = size;
9956 if (sym_table == NULL)
9957 {
9958 error (_("Out of memory whilst trying to read archive index symbol table\n"));
9959 ret = 1;
9960 goto out;
9961 }
9962 got = fread (sym_table, 1, size, file);
9963 if (got != size)
9964 {
9965 error (_("%s: failed to read archive index symbol table\n"), file_name);
9966 ret = 1;
9967 goto out;
9968 }
9969 }
9970 else
9971 {
9972 if (fseek (file, size, SEEK_CUR) != 0)
9973 {
9974 error (_("%s: failed to skip archive symbol table\n"), file_name);
9975 return 1;
9976 }
fb52b2f4
NC
9977 }
9978
4145f1d5 9979 got = fread (& arhdr, 1, sizeof arhdr, file);
fb52b2f4
NC
9980 if (got != sizeof arhdr)
9981 {
9982 if (got == 0)
4145f1d5
NC
9983 {
9984 ret = 0;
9985 goto out;
9986 }
fb52b2f4 9987
4145f1d5
NC
9988 error (_("%s: failed to read archive header following archive index\n"), file_name);
9989 ret = 1;
9990 goto out;
fb52b2f4
NC
9991 }
9992 }
4145f1d5
NC
9993 else if (do_archive_index)
9994 printf (_("%s has no archive index\n"), file_name);
fb52b2f4 9995
0112cd26 9996 if (const_strneq (arhdr.ar_name, "// "))
fb52b2f4
NC
9997 {
9998 /* This is the archive string table holding long member
9999 names. */
10000
10001 longnames_size = strtoul (arhdr.ar_size, NULL, 10);
fb52b2f4
NC
10002 longnames = malloc (longnames_size);
10003 if (longnames == NULL)
10004 {
4145f1d5
NC
10005 error (_("Out of memory reading long symbol names in archive\n"));
10006 ret = 1;
10007 goto out;
fb52b2f4
NC
10008 }
10009
10010 if (fread (longnames, longnames_size, 1, file) != 1)
10011 {
d989285c 10012 free (longnames);
4145f1d5
NC
10013 error (_("%s: failed to read long symbol name string table\n"), file_name);
10014 ret = 1;
10015 goto out;
fb52b2f4
NC
10016 }
10017
10018 if ((longnames_size & 1) != 0)
10019 getc (file);
10020
4145f1d5 10021 got = fread (& arhdr, 1, sizeof arhdr, file);
fb52b2f4
NC
10022 if (got != sizeof arhdr)
10023 {
10024 if (got == 0)
4145f1d5
NC
10025 ret = 0;
10026 else
10027 {
10028 error (_("%s: failed to read archive header following long symbol names\n"), file_name);
10029 ret = 1;
10030 }
10031 goto out;
10032 }
10033 }
fb52b2f4 10034
4145f1d5
NC
10035 if (do_archive_index)
10036 {
10037 if (sym_table == NULL)
10038 error (_("%s: unable to dump the index as none was found\n"), file_name);
10039 else
10040 {
10041 unsigned int i, j, k, l;
10042 char elf_name[16];
10043 unsigned long current_pos;
10044
10045 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
10046 file_name, index_num, sym_size);
10047 current_pos = ftell (file);
10048
10049 for (i = l = 0; i < index_num; i++)
10050 {
10051 if ((i == 0) || ((i > 0) && (index_array[i] != index_array[i - 1])))
10052 {
10053 if (fseek (file, index_array[i], SEEK_SET) != 0)
10054 {
10055 error (_("%s: failed to seek to next file name\n"), file_name);
10056 ret = 1;
10057 goto out;
10058 }
10059 got = fread (elf_name, 1, 16, file);
10060 if (got != 16)
10061 {
10062 error (_("%s: failed to read file name\n"), file_name);
10063 ret = 1;
10064 goto out;
10065 }
10066
10067 if (elf_name[0] == '/')
10068 {
10069 /* We have a long name. */
10070 k = j = strtoul (elf_name + 1, NULL, 10);
10071 while ((j < longnames_size) && (longnames[j] != '/'))
10072 j++;
10073 longnames[j] = '\0';
10074 printf (_("Binary %s contains:\n"), longnames + k);
10075 longnames[j] = '/';
10076 }
10077 else
10078 {
10079 j = 0;
10080 while ((elf_name[j] != '/') && (j < 16))
10081 j++;
10082 elf_name[j] = '\0';
10083 printf(_("Binary %s contains:\n"), elf_name);
10084 }
10085 }
10086 if (l >= sym_size)
10087 {
10088 error (_("%s: end of the symbol table reached before the end of the index\n"),
10089 file_name);
10090 break;
10091 }
10092 printf ("\t%s\n", sym_table + l);
10093 l += strlen (sym_table + l) + 1;
10094 }
10095
10096 if (l < sym_size)
10097 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
10098 file_name);
10099
10100 free (index_array);
10101 index_array = NULL;
10102 free (sym_table);
10103 sym_table = NULL;
10104 if (fseek (file, current_pos, SEEK_SET) != 0)
10105 {
10106 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
10107 return 1;
10108 }
fb52b2f4 10109 }
4145f1d5
NC
10110
10111 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
10112 && !do_segments && !do_header && !do_dump && !do_version
10113 && !do_histogram && !do_debugging && !do_arch && !do_notes
10114 && !do_section_groups)
10115 return 0; /* Archive index only. */
fb52b2f4
NC
10116 }
10117
10118 file_name_size = strlen (file_name);
d989285c 10119 ret = 0;
fb52b2f4
NC
10120
10121 while (1)
10122 {
10123 char *name;
10124 char *nameend;
10125 char *namealc;
10126
10127 if (arhdr.ar_name[0] == '/')
10128 {
10129 unsigned long off;
10130
10131 off = strtoul (arhdr.ar_name + 1, NULL, 10);
10132 if (off >= longnames_size)
10133 {
0fd3a477 10134 error (_("%s: invalid archive string table offset %lu\n"), file_name, off);
d989285c
ILT
10135 ret = 1;
10136 break;
fb52b2f4
NC
10137 }
10138
10139 name = longnames + off;
10140 nameend = memchr (name, '/', longnames_size - off);
10141 }
10142 else
10143 {
10144 name = arhdr.ar_name;
10145 nameend = memchr (name, '/', 16);
10146 }
10147
10148 if (nameend == NULL)
10149 {
0fd3a477 10150 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
10151 ret = 1;
10152 break;
fb52b2f4
NC
10153 }
10154
10155 namealc = malloc (file_name_size + (nameend - name) + 3);
10156 if (namealc == NULL)
10157 {
10158 error (_("Out of memory\n"));
d989285c
ILT
10159 ret = 1;
10160 break;
fb52b2f4
NC
10161 }
10162
10163 memcpy (namealc, file_name, file_name_size);
10164 namealc[file_name_size] = '(';
10165 memcpy (namealc + file_name_size + 1, name, nameend - name);
10166 namealc[file_name_size + 1 + (nameend - name)] = ')';
10167 namealc[file_name_size + 2 + (nameend - name)] = '\0';
10168
10169 archive_file_offset = ftell (file);
10170 archive_file_size = strtoul (arhdr.ar_size, NULL, 10);
d70c5fc7 10171
d989285c 10172 ret |= process_object (namealc, file);
fb52b2f4
NC
10173
10174 free (namealc);
10175
10176 if (fseek (file,
10177 (archive_file_offset
10178 + archive_file_size
10179 + (archive_file_size & 1)),
10180 SEEK_SET) != 0)
10181 {
10182 error (_("%s: failed to seek to next archive header\n"), file_name);
d989285c
ILT
10183 ret = 1;
10184 break;
fb52b2f4
NC
10185 }
10186
10187 got = fread (&arhdr, 1, sizeof arhdr, file);
10188 if (got != sizeof arhdr)
10189 {
10190 if (got == 0)
d989285c 10191 break;
fb52b2f4
NC
10192
10193 error (_("%s: failed to read archive header\n"), file_name);
d989285c
ILT
10194 ret = 1;
10195 break;
fb52b2f4
NC
10196 }
10197 }
10198
4145f1d5
NC
10199 out:
10200 if (index_array != NULL)
10201 free (index_array);
10202 if (sym_table != NULL)
10203 free (sym_table);
10204 if (longnames != NULL)
fb52b2f4
NC
10205 free (longnames);
10206
d989285c 10207 return ret;
fb52b2f4
NC
10208}
10209
10210static int
10211process_file (char *file_name)
10212{
10213 FILE *file;
10214 struct stat statbuf;
10215 char armag[SARMAG];
10216 int ret;
10217
10218 if (stat (file_name, &statbuf) < 0)
10219 {
f24ddbdd
NC
10220 if (errno == ENOENT)
10221 error (_("'%s': No such file\n"), file_name);
10222 else
10223 error (_("Could not locate '%s'. System error message: %s\n"),
10224 file_name, strerror (errno));
10225 return 1;
10226 }
10227
10228 if (! S_ISREG (statbuf.st_mode))
10229 {
10230 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
10231 return 1;
10232 }
10233
10234 file = fopen (file_name, "rb");
10235 if (file == NULL)
10236 {
f24ddbdd 10237 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
10238 return 1;
10239 }
10240
10241 if (fread (armag, SARMAG, 1, file) != 1)
10242 {
4145f1d5 10243 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
10244 fclose (file);
10245 return 1;
10246 }
10247
10248 if (memcmp (armag, ARMAG, SARMAG) == 0)
10249 ret = process_archive (file_name, file);
10250 else
10251 {
4145f1d5
NC
10252 if (do_archive_index)
10253 error (_("File %s is not an archive so its index cannot be displayed.\n"),
10254 file_name);
10255
fb52b2f4
NC
10256 rewind (file);
10257 archive_file_size = archive_file_offset = 0;
10258 ret = process_object (file_name, file);
10259 }
10260
10261 fclose (file);
10262
10263 return ret;
10264}
10265
252b5132
RH
10266#ifdef SUPPORT_DISASSEMBLY
10267/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 10268 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 10269 symbols. */
252b5132
RH
10270
10271void
b34976b6 10272print_address (unsigned int addr, FILE *outfile)
252b5132
RH
10273{
10274 fprintf (outfile,"0x%8.8x", addr);
10275}
10276
e3c8793a 10277/* Needed by the i386 disassembler. */
252b5132
RH
10278void
10279db_task_printsym (unsigned int addr)
10280{
10281 print_address (addr, stderr);
10282}
10283#endif
10284
10285int
d3ba0551 10286main (int argc, char **argv)
252b5132 10287{
ff78d6d6
L
10288 int err;
10289
252b5132
RH
10290#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
10291 setlocale (LC_MESSAGES, "");
3882b010
L
10292#endif
10293#if defined (HAVE_SETLOCALE)
10294 setlocale (LC_CTYPE, "");
252b5132
RH
10295#endif
10296 bindtextdomain (PACKAGE, LOCALEDIR);
10297 textdomain (PACKAGE);
10298
869b9d07
MM
10299 expandargv (&argc, &argv);
10300
252b5132
RH
10301 parse_args (argc, argv);
10302
18bd398b 10303 if (num_dump_sects > 0)
59f14fc0 10304 {
18bd398b 10305 /* Make a copy of the dump_sects array. */
09c11c86 10306 cmdline_dump_sects = malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 10307 if (cmdline_dump_sects == NULL)
591a748a 10308 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
10309 else
10310 {
09c11c86
NC
10311 memcpy (cmdline_dump_sects, dump_sects,
10312 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
10313 num_cmdline_dump_sects = num_dump_sects;
10314 }
10315 }
10316
18bd398b
NC
10317 if (optind < (argc - 1))
10318 show_name = 1;
10319
ff78d6d6 10320 err = 0;
252b5132 10321 while (optind < argc)
18bd398b 10322 err |= process_file (argv[optind++]);
252b5132
RH
10323
10324 if (dump_sects != NULL)
10325 free (dump_sects);
59f14fc0
AS
10326 if (cmdline_dump_sects != NULL)
10327 free (cmdline_dump_sects);
252b5132 10328
ff78d6d6 10329 return err;
252b5132 10330}