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