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