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