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