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