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