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