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