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