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