]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
PR gdb/11327, PR gdb/11328, PR breakpoints/11368:
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
6e3d6dc1 2 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
a0f19280
L
3 2008, 2009, 2010
4 Free Software Foundation, Inc.
252b5132
RH
5
6 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 7 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
8
9 This file is part of GNU Binutils.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
32866df7 13 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
b43b5d5f
NC
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
24 02110-1301, USA. */
252b5132 25\f
9eb20dd8 26/* The difference between readelf and objdump:
252b5132 27
74013231 28 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 29 so why does the binutils project have two file dumpers ?
0de14b54 30
9eb20dd8
NC
31 The reason is that objdump sees an ELF file through a BFD filter of the
32 world; if BFD has a bug where, say, it disagrees about a machine constant
33 in e_flags, then the odds are good that it will remain internally
34 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
35 GAS sees it the BFD way. There was need for a tool to go find out what
36 the file actually says.
37
38 This is why the readelf program does not link against the BFD library - it
39 exists as an independent program to help verify the correct working of BFD.
40
41 There is also the case that readelf can provide more information about an
42 ELF file than is provided by objdump. In particular it can display DWARF
43 debugging information which (at the moment) objdump cannot. */
44\f
1b315056 45#include "config.h"
3db64b00 46#include "sysdep.h"
252b5132
RH
47#include <assert.h>
48#include <sys/stat.h>
252b5132 49#include <time.h>
1b315056
CS
50#ifdef HAVE_ZLIB_H
51#include <zlib.h>
52#endif
252b5132 53
a952a375 54#if __GNUC__ >= 2
19936277 55/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 56 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 57 Only do this if we believe that the compiler can support a 64 bit
a952a375 58 data type. For now we only rely on GCC being able to do this. */
19936277 59#define BFD64
a952a375
NC
60#endif
61
3db64b00
AM
62#include "bfd.h"
63#include "bucomm.h"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
252b5132 94#include "elf/alpha.h"
3b16e843 95#include "elf/arc.h"
252b5132 96#include "elf/arm.h"
3b16e843 97#include "elf/avr.h"
1d65ded4 98#include "elf/bfin.h"
60bca95a 99#include "elf/cr16.h"
3b16e843 100#include "elf/cris.h"
1c0d3aa6 101#include "elf/crx.h"
252b5132
RH
102#include "elf/d10v.h"
103#include "elf/d30v.h"
d172d4ba 104#include "elf/dlx.h"
252b5132 105#include "elf/fr30.h"
5c70f934 106#include "elf/frv.h"
3b16e843
NC
107#include "elf/h8.h"
108#include "elf/hppa.h"
109#include "elf/i386.h"
35b1837e 110#include "elf/i370.h"
3b16e843
NC
111#include "elf/i860.h"
112#include "elf/i960.h"
113#include "elf/ia64.h"
1e4cf259 114#include "elf/ip2k.h"
84e94c90 115#include "elf/lm32.h"
1c0d3aa6 116#include "elf/iq2000.h"
49f58d10 117#include "elf/m32c.h"
3b16e843
NC
118#include "elf/m32r.h"
119#include "elf/m68k.h"
75751cd9 120#include "elf/m68hc11.h"
252b5132 121#include "elf/mcore.h"
15ab5209 122#include "elf/mep.h"
7ba29e2a 123#include "elf/microblaze.h"
3b16e843 124#include "elf/mips.h"
3c3bdf30 125#include "elf/mmix.h"
3b16e843
NC
126#include "elf/mn10200.h"
127#include "elf/mn10300.h"
4970f871 128#include "elf/mt.h"
2469cfa2 129#include "elf/msp430.h"
3b16e843 130#include "elf/or32.h"
7d466069 131#include "elf/pj.h"
3b16e843 132#include "elf/ppc.h"
c833c019 133#include "elf/ppc64.h"
c7927a3c 134#include "elf/rx.h"
a85d7ed0 135#include "elf/s390.h"
1c0d3aa6 136#include "elf/score.h"
3b16e843
NC
137#include "elf/sh.h"
138#include "elf/sparc.h"
e9f53129 139#include "elf/spu.h"
3b16e843 140#include "elf/v850.h"
179d3252 141#include "elf/vax.h"
3b16e843 142#include "elf/x86-64.h"
c29aca4a 143#include "elf/xc16x.h"
93fbbb04 144#include "elf/xstormy16.h"
88da6820 145#include "elf/xtensa.h"
252b5132 146
fb52b2f4
NC
147#include "aout/ar.h"
148
252b5132 149#include "getopt.h"
566b0d53 150#include "libiberty.h"
09c11c86 151#include "safe-ctype.h"
2cf0635d 152#include "filenames.h"
252b5132 153
2cf0635d 154char * program_name = "readelf";
85b1c36d
BE
155static long archive_file_offset;
156static unsigned long archive_file_size;
157static unsigned long dynamic_addr;
158static bfd_size_type dynamic_size;
159static unsigned int dynamic_nent;
2cf0635d 160static char * dynamic_strings;
85b1c36d 161static unsigned long dynamic_strings_length;
2cf0635d 162static char * string_table;
85b1c36d
BE
163static unsigned long string_table_length;
164static unsigned long num_dynamic_syms;
2cf0635d
NC
165static Elf_Internal_Sym * dynamic_symbols;
166static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
167static unsigned long dynamic_syminfo_offset;
168static unsigned int dynamic_syminfo_nent;
f8eae8b2 169static char program_interpreter[PATH_MAX];
bb8a0291 170static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 171static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
172static bfd_vma version_info[16];
173static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
174static Elf_Internal_Shdr * section_headers;
175static Elf_Internal_Phdr * program_headers;
176static Elf_Internal_Dyn * dynamic_section;
177static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
178static int show_name;
179static int do_dynamic;
180static int do_syms;
2c610e4b 181static int do_dyn_syms;
85b1c36d
BE
182static int do_reloc;
183static int do_sections;
184static int do_section_groups;
5477e8a0 185static int do_section_details;
85b1c36d
BE
186static int do_segments;
187static int do_unwind;
188static int do_using_dynamic;
189static int do_header;
190static int do_dump;
191static int do_version;
85b1c36d
BE
192static int do_histogram;
193static int do_debugging;
85b1c36d
BE
194static int do_arch;
195static int do_notes;
4145f1d5 196static int do_archive_index;
85b1c36d 197static int is_32bit_elf;
252b5132 198
e4b17d5c
L
199struct group_list
200{
2cf0635d 201 struct group_list * next;
e4b17d5c
L
202 unsigned int section_index;
203};
204
205struct group
206{
2cf0635d 207 struct group_list * root;
e4b17d5c
L
208 unsigned int group_index;
209};
210
85b1c36d 211static size_t group_count;
2cf0635d
NC
212static struct group * section_groups;
213static struct group ** section_headers_groups;
e4b17d5c 214
09c11c86
NC
215
216/* Flag bits indicating particular types of dump. */
217#define HEX_DUMP (1 << 0) /* The -x command line switch. */
218#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
219#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
220#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 221#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
222
223typedef unsigned char dump_type;
224
225/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
226struct dump_list_entry
227{
2cf0635d 228 char * name;
09c11c86 229 dump_type type;
2cf0635d 230 struct dump_list_entry * next;
aef1f6d0 231};
2cf0635d 232static struct dump_list_entry * dump_sects_byname;
aef1f6d0 233
09c11c86
NC
234/* A dynamic array of flags indicating for which sections a dump
235 has been requested via command line switches. */
236static dump_type * cmdline_dump_sects = NULL;
237static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
238
239/* A dynamic array of flags indicating for which sections a dump of
240 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
241 basis and then initialised from the cmdline_dump_sects array,
242 the results of interpreting the -w switch, and the
243 dump_sects_byname list. */
09c11c86
NC
244static dump_type * dump_sects = NULL;
245static unsigned int num_dump_sects = 0;
252b5132 246
252b5132 247
c256ffe7 248/* How to print a vma value. */
843dd992
NC
249typedef enum print_mode
250{
251 HEX,
252 DEC,
253 DEC_5,
254 UNSIGNED,
255 PREFIX_HEX,
256 FULL_HEX,
257 LONG_HEX
258}
259print_mode;
260
2cf0635d 261static void (* byte_put) (unsigned char *, bfd_vma, int);
252b5132 262
9c19a809
NC
263#define UNKNOWN -1
264
0b49d371
NC
265#define SECTION_NAME(X) \
266 ((X) == NULL ? "<none>" \
267 : string_table == NULL ? "<no-name>" \
268 : ((X)->sh_name >= string_table_length ? "<corrupt>" \
269 : string_table + (X)->sh_name))
252b5132 270
ee42cf8c 271#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 272
7036c0e1 273#define BYTE_GET(field) byte_get (field, sizeof (field))
a952a375 274
9ad5cbcf
AM
275#define GET_ELF_SYMBOLS(file, section) \
276 (is_32bit_elf ? get_32bit_elf_symbols (file, section) \
277 : get_64bit_elf_symbols (file, section))
9ea033b2 278
d79b3d50
NC
279#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
280/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
281 already been called and verified that the string exists. */
282#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b
NC
283
284/* This is just a bit of syntatic sugar. */
60bca95a
NC
285#define streq(a,b) (strcmp ((a), (b)) == 0)
286#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
0112cd26 287#define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
0b6ae522
DJ
288
289#define REMOVE_ARCH_BITS(ADDR) do { \
290 if (elf_header.e_machine == EM_ARM) \
291 (ADDR) &= ~1; \
292 } while (0)
d79b3d50 293\f
c256ffe7 294static void *
2cf0635d
NC
295get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
296 const char * reason)
a6e9f9df 297{
2cf0635d 298 void * mvar;
a6e9f9df 299
c256ffe7 300 if (size == 0 || nmemb == 0)
a6e9f9df
AM
301 return NULL;
302
fb52b2f4 303 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 304 {
0fd3a477 305 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 306 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
307 return NULL;
308 }
309
310 mvar = var;
311 if (mvar == NULL)
312 {
c256ffe7
JJ
313 /* Check for overflow. */
314 if (nmemb < (~(size_t) 0 - 1) / size)
315 /* + 1 so that we can '\0' terminate invalid string table sections. */
316 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
317
318 if (mvar == NULL)
319 {
0fd3a477
JW
320 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
321 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
322 return NULL;
323 }
c256ffe7
JJ
324
325 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
326 }
327
c256ffe7 328 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 329 {
0fd3a477
JW
330 error (_("Unable to read in 0x%lx bytes of %s\n"),
331 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
332 if (mvar != var)
333 free (mvar);
334 return NULL;
335 }
336
337 return mvar;
338}
339
adab8cdc 340static void
2cf0635d 341byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
adab8cdc
AO
342{
343 switch (size)
344 {
345 case 8:
346 field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
347 field[6] = ((value >> 24) >> 24) & 0xff;
348 field[5] = ((value >> 24) >> 16) & 0xff;
349 field[4] = ((value >> 24) >> 8) & 0xff;
350 /* Fall through. */
351 case 4:
352 field[3] = (value >> 24) & 0xff;
4dc3c23d
AM
353 /* Fall through. */
354 case 3:
adab8cdc
AO
355 field[2] = (value >> 16) & 0xff;
356 /* Fall through. */
357 case 2:
358 field[1] = (value >> 8) & 0xff;
359 /* Fall through. */
360 case 1:
361 field[0] = value & 0xff;
362 break;
363
364 default:
365 error (_("Unhandled data length: %d\n"), size);
366 abort ();
367 }
368}
369
14a91970 370/* Print a VMA value. */
cb8f3167 371
66543521 372static int
14a91970 373print_vma (bfd_vma vma, print_mode mode)
66543521 374{
66543521
AM
375 int nc = 0;
376
14a91970 377 switch (mode)
66543521 378 {
14a91970
AM
379 case FULL_HEX:
380 nc = printf ("0x");
381 /* Drop through. */
66543521 382
14a91970 383 case LONG_HEX:
f7a99963 384#ifdef BFD64
14a91970 385 if (is_32bit_elf)
437c2fb7 386 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 387#endif
14a91970
AM
388 printf_vma (vma);
389 return nc + 16;
b19aac67 390
14a91970
AM
391 case DEC_5:
392 if (vma <= 99999)
393 return printf ("%5" BFD_VMA_FMT "d", vma);
394 /* Drop through. */
66543521 395
14a91970
AM
396 case PREFIX_HEX:
397 nc = printf ("0x");
398 /* Drop through. */
66543521 399
14a91970
AM
400 case HEX:
401 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 402
14a91970
AM
403 case DEC:
404 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 405
14a91970
AM
406 case UNSIGNED:
407 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 408 }
66543521 409 return 0;
f7a99963
NC
410}
411
171191ba 412/* Display a symbol on stdout. Handles the display of non-printing characters.
31104126 413
171191ba
NC
414 If DO_WIDE is not true then format the symbol to be at most WIDTH characters,
415 truncating as necessary. If WIDTH is negative then format the string to be
416 exactly - WIDTH characters, truncating or padding as necessary.
417
418 Returns the number of emitted characters. */
419
420static unsigned int
2cf0635d 421print_symbol (int width, const char * symbol)
31104126 422{
961c521f 423 const char * c;
171191ba
NC
424 bfd_boolean extra_padding = FALSE;
425 unsigned int num_printed = 0;
961c521f 426
31104126 427 if (do_wide)
961c521f 428 {
961c521f
NC
429 /* Set the width to a very large value. This simplifies the code below. */
430 width = INT_MAX;
431 }
31104126 432 else if (width < 0)
961c521f 433 {
961c521f
NC
434 /* Keep the width positive. This also helps. */
435 width = - width;
171191ba 436 extra_padding = TRUE;
961c521f
NC
437 }
438
439 while (width)
440 {
441 int len;
442
443 c = symbol;
444
445 /* Look for non-printing symbols inside the symbol's name.
446 This test is triggered in particular by the names generated
447 by the assembler for local labels. */
448 while (ISPRINT (* c))
449 c++;
450
451 len = c - symbol;
452
453 if (len)
454 {
455 if (len > width)
456 len = width;
cb8f3167 457
171191ba 458 printf ("%.*s", len, symbol);
961c521f
NC
459
460 width -= len;
171191ba 461 num_printed += len;
961c521f
NC
462 }
463
464 if (* c == 0 || width == 0)
465 break;
466
467 /* Now display the non-printing character, if
468 there is room left in which to dipslay it. */
469 if (*c < 32)
470 {
471 if (width < 2)
472 break;
473
474 printf ("^%c", *c + 0x40);
475
476 width -= 2;
171191ba 477 num_printed += 2;
961c521f
NC
478 }
479 else
480 {
481 if (width < 6)
482 break;
cb8f3167 483
961c521f
NC
484 printf ("<0x%.2x>", *c);
485
486 width -= 6;
171191ba 487 num_printed += 6;
961c521f
NC
488 }
489
490 symbol = c + 1;
491 }
171191ba
NC
492
493 if (extra_padding && width > 0)
494 {
495 /* Fill in the remaining spaces. */
496 printf ("%-*s", width, " ");
497 num_printed += 2;
498 }
499
500 return num_printed;
31104126
NC
501}
502
adab8cdc 503static void
2cf0635d 504byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
adab8cdc
AO
505{
506 switch (size)
507 {
508 case 8:
509 field[7] = value & 0xff;
510 field[6] = (value >> 8) & 0xff;
511 field[5] = (value >> 16) & 0xff;
512 field[4] = (value >> 24) & 0xff;
513 value >>= 16;
514 value >>= 16;
515 /* Fall through. */
516 case 4:
517 field[3] = value & 0xff;
4dc3c23d
AM
518 value >>= 8;
519 /* Fall through. */
520 case 3:
521 field[2] = value & 0xff;
522 value >>= 8;
adab8cdc
AO
523 /* Fall through. */
524 case 2:
525 field[1] = value & 0xff;
526 value >>= 8;
527 /* Fall through. */
528 case 1:
529 field[0] = value & 0xff;
530 break;
531
532 default:
533 error (_("Unhandled data length: %d\n"), size);
534 abort ();
535 }
536}
537
89fac5e3
RS
538/* Return a pointer to section NAME, or NULL if no such section exists. */
539
540static Elf_Internal_Shdr *
2cf0635d 541find_section (const char * name)
89fac5e3
RS
542{
543 unsigned int i;
544
545 for (i = 0; i < elf_header.e_shnum; i++)
546 if (streq (SECTION_NAME (section_headers + i), name))
547 return section_headers + i;
548
549 return NULL;
550}
551
0b6ae522
DJ
552/* Return a pointer to a section containing ADDR, or NULL if no such
553 section exists. */
554
555static Elf_Internal_Shdr *
556find_section_by_address (bfd_vma addr)
557{
558 unsigned int i;
559
560 for (i = 0; i < elf_header.e_shnum; i++)
561 {
562 Elf_Internal_Shdr *sec = section_headers + i;
563 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
564 return sec;
565 }
566
567 return NULL;
568}
569
570/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
571 bytes read. */
572
573static unsigned long
574read_uleb128 (unsigned char *data, unsigned int *length_return)
575{
576 return read_leb128 (data, length_return, 0);
577}
578
bcedfee6 579/* Guess the relocation size commonly used by the specific machines. */
252b5132 580
252b5132 581static int
2dc4cec1 582guess_is_rela (unsigned int e_machine)
252b5132 583{
9c19a809 584 switch (e_machine)
252b5132
RH
585 {
586 /* Targets that use REL relocations. */
252b5132
RH
587 case EM_386:
588 case EM_486:
63fcb9e9 589 case EM_960:
e9f53129 590 case EM_ARM:
2b0337b0 591 case EM_D10V:
252b5132 592 case EM_CYGNUS_D10V:
e9f53129 593 case EM_DLX:
252b5132 594 case EM_MIPS:
4fe85591 595 case EM_MIPS_RS3_LE:
e9f53129
AM
596 case EM_CYGNUS_M32R:
597 case EM_OPENRISC:
598 case EM_OR32:
1c0d3aa6 599 case EM_SCORE:
9c19a809 600 return FALSE;
103f02d3 601
252b5132
RH
602 /* Targets that use RELA relocations. */
603 case EM_68K:
e9f53129
AM
604 case EM_860:
605 case EM_ALPHA:
606 case EM_ALTERA_NIOS2:
607 case EM_AVR:
608 case EM_AVR_OLD:
609 case EM_BLACKFIN:
60bca95a 610 case EM_CR16:
6c03b1ed 611 case EM_CR16_OLD:
e9f53129
AM
612 case EM_CRIS:
613 case EM_CRX:
2b0337b0 614 case EM_D30V:
252b5132 615 case EM_CYGNUS_D30V:
2b0337b0 616 case EM_FR30:
252b5132 617 case EM_CYGNUS_FR30:
5c70f934 618 case EM_CYGNUS_FRV:
e9f53129
AM
619 case EM_H8S:
620 case EM_H8_300:
621 case EM_H8_300H:
800eeca4 622 case EM_IA_64:
1e4cf259
NC
623 case EM_IP2K:
624 case EM_IP2K_OLD:
3b36097d 625 case EM_IQ2000:
84e94c90 626 case EM_LATTICEMICO32:
ff7eeb89 627 case EM_M32C_OLD:
49f58d10 628 case EM_M32C:
e9f53129
AM
629 case EM_M32R:
630 case EM_MCORE:
15ab5209 631 case EM_CYGNUS_MEP:
e9f53129
AM
632 case EM_MMIX:
633 case EM_MN10200:
634 case EM_CYGNUS_MN10200:
635 case EM_MN10300:
636 case EM_CYGNUS_MN10300:
637 case EM_MSP430:
638 case EM_MSP430_OLD:
d031aafb 639 case EM_MT:
64fd6348 640 case EM_NIOS32:
e9f53129
AM
641 case EM_PPC64:
642 case EM_PPC:
c7927a3c 643 case EM_RX:
e9f53129
AM
644 case EM_S390:
645 case EM_S390_OLD:
646 case EM_SH:
647 case EM_SPARC:
648 case EM_SPARC32PLUS:
649 case EM_SPARCV9:
650 case EM_SPU:
651 case EM_V850:
652 case EM_CYGNUS_V850:
653 case EM_VAX:
654 case EM_X86_64:
8a9036a4 655 case EM_L1OM:
e9f53129
AM
656 case EM_XSTORMY16:
657 case EM_XTENSA:
658 case EM_XTENSA_OLD:
7ba29e2a
NC
659 case EM_MICROBLAZE:
660 case EM_MICROBLAZE_OLD:
9c19a809 661 return TRUE;
103f02d3 662
e9f53129
AM
663 case EM_68HC05:
664 case EM_68HC08:
665 case EM_68HC11:
666 case EM_68HC16:
667 case EM_FX66:
668 case EM_ME16:
d1133906 669 case EM_MMA:
d1133906
NC
670 case EM_NCPU:
671 case EM_NDR1:
e9f53129 672 case EM_PCP:
d1133906 673 case EM_ST100:
e9f53129 674 case EM_ST19:
d1133906 675 case EM_ST7:
e9f53129
AM
676 case EM_ST9PLUS:
677 case EM_STARCORE:
d1133906 678 case EM_SVX:
e9f53129 679 case EM_TINYJ:
9c19a809
NC
680 default:
681 warn (_("Don't know about relocations on this machine architecture\n"));
682 return FALSE;
683 }
684}
252b5132 685
9c19a809 686static int
2cf0635d 687slurp_rela_relocs (FILE * file,
d3ba0551
AM
688 unsigned long rel_offset,
689 unsigned long rel_size,
2cf0635d
NC
690 Elf_Internal_Rela ** relasp,
691 unsigned long * nrelasp)
9c19a809 692{
2cf0635d 693 Elf_Internal_Rela * relas;
4d6ed7c8
NC
694 unsigned long nrelas;
695 unsigned int i;
252b5132 696
4d6ed7c8
NC
697 if (is_32bit_elf)
698 {
2cf0635d 699 Elf32_External_Rela * erelas;
103f02d3 700
3f5e193b
NC
701 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
702 rel_size, _("relocs"));
a6e9f9df
AM
703 if (!erelas)
704 return 0;
252b5132 705
4d6ed7c8 706 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 707
3f5e193b
NC
708 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
709 sizeof (Elf_Internal_Rela));
103f02d3 710
4d6ed7c8
NC
711 if (relas == NULL)
712 {
c256ffe7 713 free (erelas);
591a748a 714 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
715 return 0;
716 }
103f02d3 717
4d6ed7c8
NC
718 for (i = 0; i < nrelas; i++)
719 {
720 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
721 relas[i].r_info = BYTE_GET (erelas[i].r_info);
722 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
723 }
103f02d3 724
4d6ed7c8
NC
725 free (erelas);
726 }
727 else
728 {
2cf0635d 729 Elf64_External_Rela * erelas;
103f02d3 730
3f5e193b
NC
731 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
732 rel_size, _("relocs"));
a6e9f9df
AM
733 if (!erelas)
734 return 0;
4d6ed7c8
NC
735
736 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 737
3f5e193b
NC
738 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
739 sizeof (Elf_Internal_Rela));
103f02d3 740
4d6ed7c8
NC
741 if (relas == NULL)
742 {
c256ffe7 743 free (erelas);
591a748a 744 error (_("out of memory parsing relocs\n"));
4d6ed7c8 745 return 0;
9c19a809 746 }
4d6ed7c8
NC
747
748 for (i = 0; i < nrelas; i++)
9c19a809 749 {
66543521
AM
750 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
751 relas[i].r_info = BYTE_GET (erelas[i].r_info);
752 relas[i].r_addend = BYTE_GET (erelas[i].r_addend);
861fb55a
DJ
753
754 /* The #ifdef BFD64 below is to prevent a compile time
755 warning. We know that if we do not have a 64 bit data
756 type that we will never execute this code anyway. */
757#ifdef BFD64
758 if (elf_header.e_machine == EM_MIPS
759 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
760 {
761 /* In little-endian objects, r_info isn't really a
762 64-bit little-endian value: it has a 32-bit
763 little-endian symbol index followed by four
764 individual byte fields. Reorder INFO
765 accordingly. */
91d6fa6a
NC
766 bfd_vma inf = relas[i].r_info;
767 inf = (((inf & 0xffffffff) << 32)
768 | ((inf >> 56) & 0xff)
769 | ((inf >> 40) & 0xff00)
770 | ((inf >> 24) & 0xff0000)
771 | ((inf >> 8) & 0xff000000));
772 relas[i].r_info = inf;
861fb55a
DJ
773 }
774#endif /* BFD64 */
4d6ed7c8 775 }
103f02d3 776
4d6ed7c8
NC
777 free (erelas);
778 }
779 *relasp = relas;
780 *nrelasp = nrelas;
781 return 1;
782}
103f02d3 783
4d6ed7c8 784static int
2cf0635d 785slurp_rel_relocs (FILE * file,
d3ba0551
AM
786 unsigned long rel_offset,
787 unsigned long rel_size,
2cf0635d
NC
788 Elf_Internal_Rela ** relsp,
789 unsigned long * nrelsp)
4d6ed7c8 790{
2cf0635d 791 Elf_Internal_Rela * rels;
4d6ed7c8
NC
792 unsigned long nrels;
793 unsigned int i;
103f02d3 794
4d6ed7c8
NC
795 if (is_32bit_elf)
796 {
2cf0635d 797 Elf32_External_Rel * erels;
103f02d3 798
3f5e193b
NC
799 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
800 rel_size, _("relocs"));
a6e9f9df
AM
801 if (!erels)
802 return 0;
103f02d3 803
4d6ed7c8 804 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 805
3f5e193b 806 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 807
4d6ed7c8
NC
808 if (rels == NULL)
809 {
c256ffe7 810 free (erels);
591a748a 811 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
812 return 0;
813 }
814
815 for (i = 0; i < nrels; i++)
816 {
817 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
818 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 819 rels[i].r_addend = 0;
9ea033b2 820 }
4d6ed7c8
NC
821
822 free (erels);
9c19a809
NC
823 }
824 else
825 {
2cf0635d 826 Elf64_External_Rel * erels;
9ea033b2 827
3f5e193b
NC
828 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
829 rel_size, _("relocs"));
a6e9f9df
AM
830 if (!erels)
831 return 0;
103f02d3 832
4d6ed7c8 833 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 834
3f5e193b 835 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 836
4d6ed7c8 837 if (rels == NULL)
9c19a809 838 {
c256ffe7 839 free (erels);
591a748a 840 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
841 return 0;
842 }
103f02d3 843
4d6ed7c8
NC
844 for (i = 0; i < nrels; i++)
845 {
66543521
AM
846 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
847 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 848 rels[i].r_addend = 0;
861fb55a
DJ
849
850 /* The #ifdef BFD64 below is to prevent a compile time
851 warning. We know that if we do not have a 64 bit data
852 type that we will never execute this code anyway. */
853#ifdef BFD64
854 if (elf_header.e_machine == EM_MIPS
855 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
856 {
857 /* In little-endian objects, r_info isn't really a
858 64-bit little-endian value: it has a 32-bit
859 little-endian symbol index followed by four
860 individual byte fields. Reorder INFO
861 accordingly. */
91d6fa6a
NC
862 bfd_vma inf = rels[i].r_info;
863 inf = (((inf & 0xffffffff) << 32)
864 | ((inf >> 56) & 0xff)
865 | ((inf >> 40) & 0xff00)
866 | ((inf >> 24) & 0xff0000)
867 | ((inf >> 8) & 0xff000000));
868 rels[i].r_info = inf;
861fb55a
DJ
869 }
870#endif /* BFD64 */
4d6ed7c8 871 }
103f02d3 872
4d6ed7c8
NC
873 free (erels);
874 }
875 *relsp = rels;
876 *nrelsp = nrels;
877 return 1;
878}
103f02d3 879
aca88567
NC
880/* Returns the reloc type extracted from the reloc info field. */
881
882static unsigned int
883get_reloc_type (bfd_vma reloc_info)
884{
885 if (is_32bit_elf)
886 return ELF32_R_TYPE (reloc_info);
887
888 switch (elf_header.e_machine)
889 {
890 case EM_MIPS:
891 /* Note: We assume that reloc_info has already been adjusted for us. */
892 return ELF64_MIPS_R_TYPE (reloc_info);
893
894 case EM_SPARCV9:
895 return ELF64_R_TYPE_ID (reloc_info);
896
897 default:
898 return ELF64_R_TYPE (reloc_info);
899 }
900}
901
902/* Return the symbol index extracted from the reloc info field. */
903
904static bfd_vma
905get_reloc_symindex (bfd_vma reloc_info)
906{
907 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
908}
909
d3ba0551
AM
910/* Display the contents of the relocation data found at the specified
911 offset. */
ee42cf8c 912
41e92641 913static void
2cf0635d 914dump_relocations (FILE * file,
d3ba0551
AM
915 unsigned long rel_offset,
916 unsigned long rel_size,
2cf0635d 917 Elf_Internal_Sym * symtab,
d3ba0551 918 unsigned long nsyms,
2cf0635d 919 char * strtab,
d79b3d50 920 unsigned long strtablen,
d3ba0551 921 int is_rela)
4d6ed7c8 922{
b34976b6 923 unsigned int i;
2cf0635d 924 Elf_Internal_Rela * rels;
103f02d3 925
4d6ed7c8
NC
926 if (is_rela == UNKNOWN)
927 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 928
4d6ed7c8
NC
929 if (is_rela)
930 {
c8286bd1 931 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 932 return;
4d6ed7c8
NC
933 }
934 else
935 {
936 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 937 return;
252b5132
RH
938 }
939
410f7a12
L
940 if (is_32bit_elf)
941 {
942 if (is_rela)
2c71103e
NC
943 {
944 if (do_wide)
945 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
946 else
947 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
948 }
410f7a12 949 else
2c71103e
NC
950 {
951 if (do_wide)
952 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
953 else
954 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
955 }
410f7a12 956 }
252b5132 957 else
410f7a12
L
958 {
959 if (is_rela)
2c71103e
NC
960 {
961 if (do_wide)
8beeaeb7 962 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
963 else
964 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
965 }
410f7a12 966 else
2c71103e
NC
967 {
968 if (do_wide)
8beeaeb7 969 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
970 else
971 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
972 }
410f7a12 973 }
252b5132
RH
974
975 for (i = 0; i < rel_size; i++)
976 {
2cf0635d 977 const char * rtype;
b34976b6 978 bfd_vma offset;
91d6fa6a 979 bfd_vma inf;
b34976b6
AM
980 bfd_vma symtab_index;
981 bfd_vma type;
103f02d3 982
b34976b6 983 offset = rels[i].r_offset;
91d6fa6a 984 inf = rels[i].r_info;
103f02d3 985
91d6fa6a
NC
986 type = get_reloc_type (inf);
987 symtab_index = get_reloc_symindex (inf);
252b5132 988
410f7a12
L
989 if (is_32bit_elf)
990 {
39dbeff8
AM
991 printf ("%8.8lx %8.8lx ",
992 (unsigned long) offset & 0xffffffff,
91d6fa6a 993 (unsigned long) inf & 0xffffffff);
410f7a12
L
994 }
995 else
996 {
39dbeff8
AM
997#if BFD_HOST_64BIT_LONG
998 printf (do_wide
999 ? "%16.16lx %16.16lx "
1000 : "%12.12lx %12.12lx ",
91d6fa6a 1001 offset, inf);
39dbeff8 1002#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1003#ifndef __MSVCRT__
39dbeff8
AM
1004 printf (do_wide
1005 ? "%16.16llx %16.16llx "
1006 : "%12.12llx %12.12llx ",
91d6fa6a 1007 offset, inf);
6e3d6dc1
NC
1008#else
1009 printf (do_wide
1010 ? "%16.16I64x %16.16I64x "
1011 : "%12.12I64x %12.12I64x ",
91d6fa6a 1012 offset, inf);
6e3d6dc1 1013#endif
39dbeff8 1014#else
2c71103e
NC
1015 printf (do_wide
1016 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1017 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1018 _bfd_int64_high (offset),
1019 _bfd_int64_low (offset),
91d6fa6a
NC
1020 _bfd_int64_high (inf),
1021 _bfd_int64_low (inf));
9ea033b2 1022#endif
410f7a12 1023 }
103f02d3 1024
252b5132
RH
1025 switch (elf_header.e_machine)
1026 {
1027 default:
1028 rtype = NULL;
1029 break;
1030
2b0337b0 1031 case EM_M32R:
252b5132 1032 case EM_CYGNUS_M32R:
9ea033b2 1033 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1034 break;
1035
1036 case EM_386:
1037 case EM_486:
9ea033b2 1038 rtype = elf_i386_reloc_type (type);
252b5132
RH
1039 break;
1040
ba2685cc
AM
1041 case EM_68HC11:
1042 case EM_68HC12:
1043 rtype = elf_m68hc11_reloc_type (type);
1044 break;
75751cd9 1045
252b5132 1046 case EM_68K:
9ea033b2 1047 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1048 break;
1049
63fcb9e9 1050 case EM_960:
9ea033b2 1051 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1052 break;
1053
adde6300 1054 case EM_AVR:
2b0337b0 1055 case EM_AVR_OLD:
adde6300
AM
1056 rtype = elf_avr_reloc_type (type);
1057 break;
1058
9ea033b2
NC
1059 case EM_OLD_SPARCV9:
1060 case EM_SPARC32PLUS:
1061 case EM_SPARCV9:
252b5132 1062 case EM_SPARC:
9ea033b2 1063 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1064 break;
1065
e9f53129
AM
1066 case EM_SPU:
1067 rtype = elf_spu_reloc_type (type);
1068 break;
1069
2b0337b0 1070 case EM_V850:
252b5132 1071 case EM_CYGNUS_V850:
9ea033b2 1072 rtype = v850_reloc_type (type);
252b5132
RH
1073 break;
1074
2b0337b0 1075 case EM_D10V:
252b5132 1076 case EM_CYGNUS_D10V:
9ea033b2 1077 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1078 break;
1079
2b0337b0 1080 case EM_D30V:
252b5132 1081 case EM_CYGNUS_D30V:
9ea033b2 1082 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1083 break;
1084
d172d4ba
NC
1085 case EM_DLX:
1086 rtype = elf_dlx_reloc_type (type);
1087 break;
1088
252b5132 1089 case EM_SH:
9ea033b2 1090 rtype = elf_sh_reloc_type (type);
252b5132
RH
1091 break;
1092
2b0337b0 1093 case EM_MN10300:
252b5132 1094 case EM_CYGNUS_MN10300:
9ea033b2 1095 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1096 break;
1097
2b0337b0 1098 case EM_MN10200:
252b5132 1099 case EM_CYGNUS_MN10200:
9ea033b2 1100 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1101 break;
1102
2b0337b0 1103 case EM_FR30:
252b5132 1104 case EM_CYGNUS_FR30:
9ea033b2 1105 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1106 break;
1107
ba2685cc
AM
1108 case EM_CYGNUS_FRV:
1109 rtype = elf_frv_reloc_type (type);
1110 break;
5c70f934 1111
252b5132 1112 case EM_MCORE:
9ea033b2 1113 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1114 break;
1115
3c3bdf30
NC
1116 case EM_MMIX:
1117 rtype = elf_mmix_reloc_type (type);
1118 break;
1119
2469cfa2
NC
1120 case EM_MSP430:
1121 case EM_MSP430_OLD:
1122 rtype = elf_msp430_reloc_type (type);
1123 break;
1124
252b5132 1125 case EM_PPC:
9ea033b2 1126 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1127 break;
1128
c833c019
AM
1129 case EM_PPC64:
1130 rtype = elf_ppc64_reloc_type (type);
1131 break;
1132
252b5132 1133 case EM_MIPS:
4fe85591 1134 case EM_MIPS_RS3_LE:
9ea033b2 1135 rtype = elf_mips_reloc_type (type);
252b5132
RH
1136 break;
1137
1138 case EM_ALPHA:
9ea033b2 1139 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1140 break;
1141
1142 case EM_ARM:
9ea033b2 1143 rtype = elf_arm_reloc_type (type);
252b5132
RH
1144 break;
1145
584da044 1146 case EM_ARC:
9ea033b2 1147 rtype = elf_arc_reloc_type (type);
252b5132
RH
1148 break;
1149
1150 case EM_PARISC:
69e617ca 1151 rtype = elf_hppa_reloc_type (type);
252b5132 1152 break;
7d466069 1153
b8720f9d
JL
1154 case EM_H8_300:
1155 case EM_H8_300H:
1156 case EM_H8S:
1157 rtype = elf_h8_reloc_type (type);
1158 break;
1159
3b16e843
NC
1160 case EM_OPENRISC:
1161 case EM_OR32:
1162 rtype = elf_or32_reloc_type (type);
1163 break;
1164
7d466069 1165 case EM_PJ:
2b0337b0 1166 case EM_PJ_OLD:
7d466069
ILT
1167 rtype = elf_pj_reloc_type (type);
1168 break;
800eeca4
JW
1169 case EM_IA_64:
1170 rtype = elf_ia64_reloc_type (type);
1171 break;
1b61cf92
HPN
1172
1173 case EM_CRIS:
1174 rtype = elf_cris_reloc_type (type);
1175 break;
535c37ff
JE
1176
1177 case EM_860:
1178 rtype = elf_i860_reloc_type (type);
1179 break;
bcedfee6
NC
1180
1181 case EM_X86_64:
8a9036a4 1182 case EM_L1OM:
bcedfee6
NC
1183 rtype = elf_x86_64_reloc_type (type);
1184 break;
a85d7ed0 1185
35b1837e
AM
1186 case EM_S370:
1187 rtype = i370_reloc_type (type);
1188 break;
1189
53c7db4b
KH
1190 case EM_S390_OLD:
1191 case EM_S390:
1192 rtype = elf_s390_reloc_type (type);
1193 break;
93fbbb04 1194
1c0d3aa6
NC
1195 case EM_SCORE:
1196 rtype = elf_score_reloc_type (type);
1197 break;
1198
93fbbb04
GK
1199 case EM_XSTORMY16:
1200 rtype = elf_xstormy16_reloc_type (type);
1201 break;
179d3252 1202
1fe1f39c
NC
1203 case EM_CRX:
1204 rtype = elf_crx_reloc_type (type);
1205 break;
1206
179d3252
JT
1207 case EM_VAX:
1208 rtype = elf_vax_reloc_type (type);
1209 break;
1e4cf259
NC
1210
1211 case EM_IP2K:
1212 case EM_IP2K_OLD:
1213 rtype = elf_ip2k_reloc_type (type);
1214 break;
3b36097d
SC
1215
1216 case EM_IQ2000:
1217 rtype = elf_iq2000_reloc_type (type);
1218 break;
88da6820
NC
1219
1220 case EM_XTENSA_OLD:
1221 case EM_XTENSA:
1222 rtype = elf_xtensa_reloc_type (type);
1223 break;
a34e3ecb 1224
84e94c90
NC
1225 case EM_LATTICEMICO32:
1226 rtype = elf_lm32_reloc_type (type);
1227 break;
1228
ff7eeb89 1229 case EM_M32C_OLD:
49f58d10
JB
1230 case EM_M32C:
1231 rtype = elf_m32c_reloc_type (type);
1232 break;
1233
d031aafb
NS
1234 case EM_MT:
1235 rtype = elf_mt_reloc_type (type);
a34e3ecb 1236 break;
1d65ded4
CM
1237
1238 case EM_BLACKFIN:
1239 rtype = elf_bfin_reloc_type (type);
1240 break;
15ab5209
DB
1241
1242 case EM_CYGNUS_MEP:
1243 rtype = elf_mep_reloc_type (type);
1244 break;
60bca95a
NC
1245
1246 case EM_CR16:
6c03b1ed 1247 case EM_CR16_OLD:
60bca95a
NC
1248 rtype = elf_cr16_reloc_type (type);
1249 break;
7ba29e2a
NC
1250
1251 case EM_MICROBLAZE:
1252 case EM_MICROBLAZE_OLD:
1253 rtype = elf_microblaze_reloc_type (type);
1254 break;
c7927a3c
NC
1255
1256 case EM_RX:
1257 rtype = elf_rx_reloc_type (type);
1258 break;
c29aca4a
NC
1259
1260 case EM_XC16X:
1261 case EM_C166:
1262 rtype = elf_xc16x_reloc_type (type);
1263 break;
252b5132
RH
1264 }
1265
1266 if (rtype == NULL)
39dbeff8 1267 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1268 else
8beeaeb7 1269 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1270
7ace3541 1271 if (elf_header.e_machine == EM_ALPHA
157c2599 1272 && rtype != NULL
7ace3541
RH
1273 && streq (rtype, "R_ALPHA_LITUSE")
1274 && is_rela)
1275 {
1276 switch (rels[i].r_addend)
1277 {
1278 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1279 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1280 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1281 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1282 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1283 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1284 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1285 default: rtype = NULL;
1286 }
1287 if (rtype)
1288 printf (" (%s)", rtype);
1289 else
1290 {
1291 putchar (' ');
1292 printf (_("<unknown addend: %lx>"),
1293 (unsigned long) rels[i].r_addend);
1294 }
1295 }
1296 else if (symtab_index)
252b5132 1297 {
af3fc3bc
AM
1298 if (symtab == NULL || symtab_index >= nsyms)
1299 printf (" bad symbol index: %08lx", (unsigned long) symtab_index);
1300 else
19936277 1301 {
2cf0635d 1302 Elf_Internal_Sym * psym;
19936277 1303
af3fc3bc 1304 psym = symtab + symtab_index;
103f02d3 1305
af3fc3bc 1306 printf (" ");
171191ba 1307
d8045f23
NC
1308 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1309 {
1310 const char * name;
1311 unsigned int len;
1312 unsigned int width = is_32bit_elf ? 8 : 14;
1313
1314 /* Relocations against GNU_IFUNC symbols do not use the value
1315 of the symbol as the address to relocate against. Instead
1316 they invoke the function named by the symbol and use its
1317 result as the address for relocation.
1318
1319 To indicate this to the user, do not display the value of
1320 the symbol in the "Symbols's Value" field. Instead show
1321 its name followed by () as a hint that the symbol is
1322 invoked. */
1323
1324 if (strtab == NULL
1325 || psym->st_name == 0
1326 || psym->st_name >= strtablen)
1327 name = "??";
1328 else
1329 name = strtab + psym->st_name;
1330
1331 len = print_symbol (width, name);
1332 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1333 }
1334 else
1335 {
1336 print_vma (psym->st_value, LONG_HEX);
171191ba 1337
d8045f23
NC
1338 printf (is_32bit_elf ? " " : " ");
1339 }
103f02d3 1340
af3fc3bc 1341 if (psym->st_name == 0)
f1ef08cb 1342 {
2cf0635d 1343 const char * sec_name = "<null>";
f1ef08cb
AM
1344 char name_buf[40];
1345
1346 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1347 {
4fbb74a6
AM
1348 if (psym->st_shndx < elf_header.e_shnum)
1349 sec_name
1350 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1351 else if (psym->st_shndx == SHN_ABS)
1352 sec_name = "ABS";
1353 else if (psym->st_shndx == SHN_COMMON)
1354 sec_name = "COMMON";
172553c7
TS
1355 else if (elf_header.e_machine == EM_MIPS
1356 && psym->st_shndx == SHN_MIPS_SCOMMON)
1357 sec_name = "SCOMMON";
1358 else if (elf_header.e_machine == EM_MIPS
1359 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1360 sec_name = "SUNDEF";
8a9036a4
L
1361 else if ((elf_header.e_machine == EM_X86_64
1362 || elf_header.e_machine == EM_L1OM)
3b22753a
L
1363 && psym->st_shndx == SHN_X86_64_LCOMMON)
1364 sec_name = "LARGE_COMMON";
9ce701e2
L
1365 else if (elf_header.e_machine == EM_IA_64
1366 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1367 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1368 sec_name = "ANSI_COM";
148b93f2 1369 else if (elf_header.e_machine == EM_IA_64
cb8f3167 1370 && (elf_header.e_ident[EI_OSABI]
148b93f2
NC
1371 == ELFOSABI_OPENVMS)
1372 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1373 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1374 else
1375 {
1376 sprintf (name_buf, "<section 0x%x>",
1377 (unsigned int) psym->st_shndx);
1378 sec_name = name_buf;
1379 }
1380 }
1381 print_symbol (22, sec_name);
1382 }
af3fc3bc 1383 else if (strtab == NULL)
d79b3d50 1384 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1385 else if (psym->st_name >= strtablen)
d79b3d50 1386 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1387 else
2c71103e 1388 print_symbol (22, strtab + psym->st_name);
103f02d3 1389
af3fc3bc 1390 if (is_rela)
171191ba 1391 {
91d6fa6a 1392 long off = (long) (bfd_signed_vma) rels[i].r_addend;
171191ba 1393
91d6fa6a
NC
1394 if (off < 0)
1395 printf (" - %lx", - off);
171191ba 1396 else
91d6fa6a 1397 printf (" + %lx", off);
171191ba 1398 }
19936277 1399 }
252b5132 1400 }
1b228002 1401 else if (is_rela)
f7a99963 1402 {
18bd398b
NC
1403 printf ("%*c", is_32bit_elf ?
1404 (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
c8286bd1 1405 print_vma (rels[i].r_addend, LONG_HEX);
f7a99963 1406 }
252b5132 1407
157c2599
NC
1408 if (elf_header.e_machine == EM_SPARCV9
1409 && rtype != NULL
1410 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1411 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1412
252b5132 1413 putchar ('\n');
2c71103e 1414
aca88567 1415#ifdef BFD64
53c7db4b 1416 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1417 {
91d6fa6a
NC
1418 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1419 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1420 const char * rtype2 = elf_mips_reloc_type (type2);
1421 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1422
2c71103e
NC
1423 printf (" Type2: ");
1424
1425 if (rtype2 == NULL)
39dbeff8
AM
1426 printf (_("unrecognized: %-7lx"),
1427 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1428 else
1429 printf ("%-17.17s", rtype2);
1430
18bd398b 1431 printf ("\n Type3: ");
2c71103e
NC
1432
1433 if (rtype3 == NULL)
39dbeff8
AM
1434 printf (_("unrecognized: %-7lx"),
1435 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1436 else
1437 printf ("%-17.17s", rtype3);
1438
53c7db4b 1439 putchar ('\n');
2c71103e 1440 }
aca88567 1441#endif /* BFD64 */
252b5132
RH
1442 }
1443
c8286bd1 1444 free (rels);
252b5132
RH
1445}
1446
1447static const char *
d3ba0551 1448get_mips_dynamic_type (unsigned long type)
252b5132
RH
1449{
1450 switch (type)
1451 {
1452 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1453 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1454 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1455 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1456 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1457 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1458 case DT_MIPS_MSYM: return "MIPS_MSYM";
1459 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1460 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1461 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1462 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1463 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1464 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1465 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1466 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1467 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1468 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1469 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1470 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1471 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1472 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1473 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1474 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1475 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1476 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1477 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1478 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1479 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1480 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1481 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1482 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1483 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1484 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1485 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1486 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1487 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1488 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1489 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1490 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1491 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1492 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1493 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1494 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1495 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1496 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1497 default:
1498 return NULL;
1499 }
1500}
1501
9a097730 1502static const char *
d3ba0551 1503get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1504{
1505 switch (type)
1506 {
1507 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1508 default:
1509 return NULL;
1510 }
103f02d3
UD
1511}
1512
7490d522
AM
1513static const char *
1514get_ppc_dynamic_type (unsigned long type)
1515{
1516 switch (type)
1517 {
a7f2871e
AM
1518 case DT_PPC_GOT: return "PPC_GOT";
1519 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1520 default:
1521 return NULL;
1522 }
1523}
1524
f1cb7e17 1525static const char *
d3ba0551 1526get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1527{
1528 switch (type)
1529 {
a7f2871e
AM
1530 case DT_PPC64_GLINK: return "PPC64_GLINK";
1531 case DT_PPC64_OPD: return "PPC64_OPD";
1532 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1533 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1534 default:
1535 return NULL;
1536 }
1537}
1538
103f02d3 1539static const char *
d3ba0551 1540get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1541{
1542 switch (type)
1543 {
1544 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1545 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1546 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1547 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1548 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1549 case DT_HP_PREINIT: return "HP_PREINIT";
1550 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1551 case DT_HP_NEEDED: return "HP_NEEDED";
1552 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1553 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1554 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1555 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1556 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1557 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1558 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1559 case DT_HP_FILTERED: return "HP_FILTERED";
1560 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1561 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1562 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1563 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1564 case DT_PLT: return "PLT";
1565 case DT_PLT_SIZE: return "PLT_SIZE";
1566 case DT_DLT: return "DLT";
1567 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1568 default:
1569 return NULL;
1570 }
1571}
9a097730 1572
ecc51f48 1573static const char *
d3ba0551 1574get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1575{
1576 switch (type)
1577 {
148b93f2
NC
1578 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1579 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1580 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1581 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1582 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1583 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1584 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1585 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1586 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1587 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1588 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1589 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1590 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1591 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1592 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1593 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1594 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1595 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1596 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1597 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1598 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1599 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1600 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1601 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1602 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1603 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1604 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1605 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1606 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1607 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1608 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1609 default:
1610 return NULL;
1611 }
1612}
1613
fabcb361
RH
1614static const char *
1615get_alpha_dynamic_type (unsigned long type)
1616{
1617 switch (type)
1618 {
1619 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1620 default:
1621 return NULL;
1622 }
1623}
1624
1c0d3aa6
NC
1625static const char *
1626get_score_dynamic_type (unsigned long type)
1627{
1628 switch (type)
1629 {
1630 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1631 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1632 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1633 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1634 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1635 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1636 default:
1637 return NULL;
1638 }
1639}
1640
1641
252b5132 1642static const char *
d3ba0551 1643get_dynamic_type (unsigned long type)
252b5132 1644{
e9e44622 1645 static char buff[64];
252b5132
RH
1646
1647 switch (type)
1648 {
1649 case DT_NULL: return "NULL";
1650 case DT_NEEDED: return "NEEDED";
1651 case DT_PLTRELSZ: return "PLTRELSZ";
1652 case DT_PLTGOT: return "PLTGOT";
1653 case DT_HASH: return "HASH";
1654 case DT_STRTAB: return "STRTAB";
1655 case DT_SYMTAB: return "SYMTAB";
1656 case DT_RELA: return "RELA";
1657 case DT_RELASZ: return "RELASZ";
1658 case DT_RELAENT: return "RELAENT";
1659 case DT_STRSZ: return "STRSZ";
1660 case DT_SYMENT: return "SYMENT";
1661 case DT_INIT: return "INIT";
1662 case DT_FINI: return "FINI";
1663 case DT_SONAME: return "SONAME";
1664 case DT_RPATH: return "RPATH";
1665 case DT_SYMBOLIC: return "SYMBOLIC";
1666 case DT_REL: return "REL";
1667 case DT_RELSZ: return "RELSZ";
1668 case DT_RELENT: return "RELENT";
1669 case DT_PLTREL: return "PLTREL";
1670 case DT_DEBUG: return "DEBUG";
1671 case DT_TEXTREL: return "TEXTREL";
1672 case DT_JMPREL: return "JMPREL";
1673 case DT_BIND_NOW: return "BIND_NOW";
1674 case DT_INIT_ARRAY: return "INIT_ARRAY";
1675 case DT_FINI_ARRAY: return "FINI_ARRAY";
1676 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1677 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1678 case DT_RUNPATH: return "RUNPATH";
1679 case DT_FLAGS: return "FLAGS";
2d0e6f43 1680
d1133906
NC
1681 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1682 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1683
05107a46 1684 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1685 case DT_PLTPADSZ: return "PLTPADSZ";
1686 case DT_MOVEENT: return "MOVEENT";
1687 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1688 case DT_FEATURE: return "FEATURE";
252b5132
RH
1689 case DT_POSFLAG_1: return "POSFLAG_1";
1690 case DT_SYMINSZ: return "SYMINSZ";
1691 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1692
252b5132 1693 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1694 case DT_CONFIG: return "CONFIG";
1695 case DT_DEPAUDIT: return "DEPAUDIT";
1696 case DT_AUDIT: return "AUDIT";
1697 case DT_PLTPAD: return "PLTPAD";
1698 case DT_MOVETAB: return "MOVETAB";
252b5132 1699 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1700
252b5132 1701 case DT_VERSYM: return "VERSYM";
103f02d3 1702
67a4f2b7
AO
1703 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1704 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1705 case DT_RELACOUNT: return "RELACOUNT";
1706 case DT_RELCOUNT: return "RELCOUNT";
1707 case DT_FLAGS_1: return "FLAGS_1";
1708 case DT_VERDEF: return "VERDEF";
1709 case DT_VERDEFNUM: return "VERDEFNUM";
1710 case DT_VERNEED: return "VERNEED";
1711 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1712
019148e4 1713 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1714 case DT_USED: return "USED";
1715 case DT_FILTER: return "FILTER";
103f02d3 1716
047b2264
JJ
1717 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1718 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1719 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1720 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1721 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1722 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1723
252b5132
RH
1724 default:
1725 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1726 {
2cf0635d 1727 const char * result;
103f02d3 1728
252b5132
RH
1729 switch (elf_header.e_machine)
1730 {
1731 case EM_MIPS:
4fe85591 1732 case EM_MIPS_RS3_LE:
252b5132
RH
1733 result = get_mips_dynamic_type (type);
1734 break;
9a097730
RH
1735 case EM_SPARCV9:
1736 result = get_sparc64_dynamic_type (type);
1737 break;
7490d522
AM
1738 case EM_PPC:
1739 result = get_ppc_dynamic_type (type);
1740 break;
f1cb7e17
AM
1741 case EM_PPC64:
1742 result = get_ppc64_dynamic_type (type);
1743 break;
ecc51f48
NC
1744 case EM_IA_64:
1745 result = get_ia64_dynamic_type (type);
1746 break;
fabcb361
RH
1747 case EM_ALPHA:
1748 result = get_alpha_dynamic_type (type);
1749 break;
1c0d3aa6
NC
1750 case EM_SCORE:
1751 result = get_score_dynamic_type (type);
1752 break;
252b5132
RH
1753 default:
1754 result = NULL;
1755 break;
1756 }
1757
1758 if (result != NULL)
1759 return result;
1760
e9e44622 1761 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1762 }
eec8f817
DA
1763 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1764 || (elf_header.e_machine == EM_PARISC
1765 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1766 {
2cf0635d 1767 const char * result;
103f02d3
UD
1768
1769 switch (elf_header.e_machine)
1770 {
1771 case EM_PARISC:
1772 result = get_parisc_dynamic_type (type);
1773 break;
148b93f2
NC
1774 case EM_IA_64:
1775 result = get_ia64_dynamic_type (type);
1776 break;
103f02d3
UD
1777 default:
1778 result = NULL;
1779 break;
1780 }
1781
1782 if (result != NULL)
1783 return result;
1784
e9e44622
JJ
1785 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1786 type);
103f02d3 1787 }
252b5132 1788 else
e9e44622 1789 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1790
252b5132
RH
1791 return buff;
1792 }
1793}
1794
1795static char *
d3ba0551 1796get_file_type (unsigned e_type)
252b5132 1797{
b34976b6 1798 static char buff[32];
252b5132
RH
1799
1800 switch (e_type)
1801 {
1802 case ET_NONE: return _("NONE (None)");
1803 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1804 case ET_EXEC: return _("EXEC (Executable file)");
1805 case ET_DYN: return _("DYN (Shared object file)");
1806 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1807
1808 default:
1809 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1810 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1811 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1812 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1813 else
e9e44622 1814 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1815 return buff;
1816 }
1817}
1818
1819static char *
d3ba0551 1820get_machine_name (unsigned e_machine)
252b5132 1821{
b34976b6 1822 static char buff[64]; /* XXX */
252b5132
RH
1823
1824 switch (e_machine)
1825 {
c45021f2
NC
1826 case EM_NONE: return _("None");
1827 case EM_M32: return "WE32100";
1828 case EM_SPARC: return "Sparc";
e9f53129 1829 case EM_SPU: return "SPU";
c45021f2
NC
1830 case EM_386: return "Intel 80386";
1831 case EM_68K: return "MC68000";
1832 case EM_88K: return "MC88000";
1833 case EM_486: return "Intel 80486";
1834 case EM_860: return "Intel 80860";
1835 case EM_MIPS: return "MIPS R3000";
1836 case EM_S370: return "IBM System/370";
7036c0e1 1837 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1838 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1839 case EM_PARISC: return "HPPA";
252b5132 1840 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1841 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1842 case EM_960: return "Intel 90860";
1843 case EM_PPC: return "PowerPC";
285d1771 1844 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1845 case EM_V800: return "NEC V800";
1846 case EM_FR20: return "Fujitsu FR20";
1847 case EM_RH32: return "TRW RH32";
b34976b6 1848 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1849 case EM_ARM: return "ARM";
1850 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1851 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1852 case EM_SPARCV9: return "Sparc v9";
1853 case EM_TRICORE: return "Siemens Tricore";
584da044 1854 case EM_ARC: return "ARC";
c2dcd04e
NC
1855 case EM_H8_300: return "Renesas H8/300";
1856 case EM_H8_300H: return "Renesas H8/300H";
1857 case EM_H8S: return "Renesas H8S";
1858 case EM_H8_500: return "Renesas H8/500";
30800947 1859 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1860 case EM_MIPS_X: return "Stanford MIPS-X";
1861 case EM_COLDFIRE: return "Motorola Coldfire";
1862 case EM_68HC12: return "Motorola M68HC12";
c45021f2 1863 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1864 case EM_CYGNUS_D10V:
1865 case EM_D10V: return "d10v";
1866 case EM_CYGNUS_D30V:
b34976b6 1867 case EM_D30V: return "d30v";
2b0337b0 1868 case EM_CYGNUS_M32R:
26597c86 1869 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0
AO
1870 case EM_CYGNUS_V850:
1871 case EM_V850: return "NEC v850";
1872 case EM_CYGNUS_MN10300:
1873 case EM_MN10300: return "mn10300";
1874 case EM_CYGNUS_MN10200:
1875 case EM_MN10200: return "mn10200";
1876 case EM_CYGNUS_FR30:
1877 case EM_FR30: return "Fujitsu FR30";
b34976b6 1878 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1879 case EM_PJ_OLD:
b34976b6 1880 case EM_PJ: return "picoJava";
7036c0e1
AJ
1881 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1882 case EM_PCP: return "Siemens PCP";
1883 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1884 case EM_NDR1: return "Denso NDR1 microprocesspr";
1885 case EM_STARCORE: return "Motorola Star*Core processor";
1886 case EM_ME16: return "Toyota ME16 processor";
1887 case EM_ST100: return "STMicroelectronics ST100 processor";
1888 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1889 case EM_PDSP: return "Sony DSP processor";
1890 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1891 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1892 case EM_FX66: return "Siemens FX66 microcontroller";
1893 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1894 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1895 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
1896 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1897 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1898 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1899 case EM_SVX: return "Silicon Graphics SVx";
1900 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1901 case EM_VAX: return "Digital VAX";
2b0337b0 1902 case EM_AVR_OLD:
b34976b6 1903 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1904 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1905 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1906 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1907 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1908 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1909 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1910 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1911 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1912 case EM_L1OM: return "Intel L1OM";
b7498e0e 1913 case EM_S390_OLD:
b34976b6 1914 case EM_S390: return "IBM S/390";
1c0d3aa6 1915 case EM_SCORE: return "SUNPLUS S+Core";
93fbbb04 1916 case EM_XSTORMY16: return "Sanyo Xstormy16 CPU core";
3b16e843
NC
1917 case EM_OPENRISC:
1918 case EM_OR32: return "OpenRISC";
11636f9e 1919 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1920 case EM_CRX: return "National Semiconductor CRX microprocessor";
d172d4ba 1921 case EM_DLX: return "OpenDLX";
1e4cf259 1922 case EM_IP2K_OLD:
b34976b6 1923 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1924 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1925 case EM_XTENSA_OLD:
1926 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1927 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1928 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1929 case EM_NS32K: return "National Semiconductor 32000 series";
1930 case EM_TPC: return "Tenor Network TPC processor";
1931 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1932 case EM_MAX: return "MAX Processor";
1933 case EM_CR: return "National Semiconductor CompactRISC";
1934 case EM_F2MC16: return "Fujitsu F2MC16";
1935 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1936 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1937 case EM_M32C_OLD:
49f58d10 1938 case EM_M32C: return "Renesas M32c";
d031aafb 1939 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1940 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1941 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1942 case EM_SEP: return "Sharp embedded microprocessor";
1943 case EM_ARCA: return "Arca RISC microprocessor";
1944 case EM_UNICORE: return "Unicore";
1945 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1946 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1947 case EM_NIOS32: return "Altera Nios";
1948 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1949 case EM_C166:
d70c5fc7 1950 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
1951 case EM_M16C: return "Renesas M16C series microprocessors";
1952 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
1953 case EM_CE: return "Freescale Communication Engine RISC core";
1954 case EM_TSK3000: return "Altium TSK3000 core";
1955 case EM_RS08: return "Freescale RS08 embedded processor";
1956 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
1957 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
1958 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
1959 case EM_SE_C17: return "Seiko Epson C17 family";
1960 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
1961 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
1962 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
1963 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
1964 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
1965 case EM_R32C: return "Renesas R32C series microprocessors";
1966 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
1967 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
1968 case EM_8051: return "Intel 8051 and variants";
1969 case EM_STXP7X: return "STMicroelectronics STxP7x family";
1970 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
1971 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
1972 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
1973 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
1974 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
1975 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 1976 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 1977 case EM_CR16:
6c03b1ed 1978 case EM_CR16_OLD: return "National Semiconductor's CR16";
7ba29e2a
NC
1979 case EM_MICROBLAZE: return "Xilinx MicroBlaze";
1980 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
c7927a3c 1981 case EM_RX: return "Renesas RX";
11636f9e
JM
1982 case EM_METAG: return "Imagination Technologies META processor architecture";
1983 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
1984 case EM_ECOG16: return "Cyan Technology eCOG16 family";
1985 case EM_ETPU: return "Freescale Extended Time Processing Unit";
1986 case EM_SLE9X: return "Infineon Technologies SLE9X core";
1987 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
1988 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
1989 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
1990 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
1991 case EM_CUDA: return "NVIDIA CUDA architecture";
252b5132 1992 default:
35d9dd2f 1993 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
1994 return buff;
1995 }
1996}
1997
f3485b74 1998static void
d3ba0551 1999decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2000{
2001 unsigned eabi;
2002 int unknown = 0;
2003
2004 eabi = EF_ARM_EABI_VERSION (e_flags);
2005 e_flags &= ~ EF_ARM_EABIMASK;
2006
2007 /* Handle "generic" ARM flags. */
2008 if (e_flags & EF_ARM_RELEXEC)
2009 {
2010 strcat (buf, ", relocatable executable");
2011 e_flags &= ~ EF_ARM_RELEXEC;
2012 }
76da6bbe 2013
f3485b74
NC
2014 if (e_flags & EF_ARM_HASENTRY)
2015 {
2016 strcat (buf, ", has entry point");
2017 e_flags &= ~ EF_ARM_HASENTRY;
2018 }
76da6bbe 2019
f3485b74
NC
2020 /* Now handle EABI specific flags. */
2021 switch (eabi)
2022 {
2023 default:
2c71103e 2024 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2025 if (e_flags)
2026 unknown = 1;
2027 break;
2028
2029 case EF_ARM_EABI_VER1:
a5bcd848 2030 strcat (buf, ", Version1 EABI");
f3485b74
NC
2031 while (e_flags)
2032 {
2033 unsigned flag;
76da6bbe 2034
f3485b74
NC
2035 /* Process flags one bit at a time. */
2036 flag = e_flags & - e_flags;
2037 e_flags &= ~ flag;
76da6bbe 2038
f3485b74
NC
2039 switch (flag)
2040 {
a5bcd848 2041 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2042 strcat (buf, ", sorted symbol tables");
2043 break;
76da6bbe 2044
f3485b74
NC
2045 default:
2046 unknown = 1;
2047 break;
2048 }
2049 }
2050 break;
76da6bbe 2051
a5bcd848
PB
2052 case EF_ARM_EABI_VER2:
2053 strcat (buf, ", Version2 EABI");
2054 while (e_flags)
2055 {
2056 unsigned flag;
2057
2058 /* Process flags one bit at a time. */
2059 flag = e_flags & - e_flags;
2060 e_flags &= ~ flag;
2061
2062 switch (flag)
2063 {
2064 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2065 strcat (buf, ", sorted symbol tables");
2066 break;
2067
2068 case EF_ARM_DYNSYMSUSESEGIDX:
2069 strcat (buf, ", dynamic symbols use segment index");
2070 break;
2071
2072 case EF_ARM_MAPSYMSFIRST:
2073 strcat (buf, ", mapping symbols precede others");
2074 break;
2075
2076 default:
2077 unknown = 1;
2078 break;
2079 }
2080 }
2081 break;
2082
d507cf36
PB
2083 case EF_ARM_EABI_VER3:
2084 strcat (buf, ", Version3 EABI");
8cb51566
PB
2085 break;
2086
2087 case EF_ARM_EABI_VER4:
2088 strcat (buf, ", Version4 EABI");
3a4a14e9
PB
2089 goto eabi;
2090
2091 case EF_ARM_EABI_VER5:
2092 strcat (buf, ", Version5 EABI");
2093 eabi:
d507cf36
PB
2094 while (e_flags)
2095 {
2096 unsigned flag;
2097
2098 /* Process flags one bit at a time. */
2099 flag = e_flags & - e_flags;
2100 e_flags &= ~ flag;
2101
2102 switch (flag)
2103 {
2104 case EF_ARM_BE8:
2105 strcat (buf, ", BE8");
2106 break;
2107
2108 case EF_ARM_LE8:
2109 strcat (buf, ", LE8");
2110 break;
2111
2112 default:
2113 unknown = 1;
2114 break;
2115 }
2116 }
2117 break;
2118
f3485b74 2119 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2120 strcat (buf, ", GNU EABI");
f3485b74
NC
2121 while (e_flags)
2122 {
2123 unsigned flag;
76da6bbe 2124
f3485b74
NC
2125 /* Process flags one bit at a time. */
2126 flag = e_flags & - e_flags;
2127 e_flags &= ~ flag;
76da6bbe 2128
f3485b74
NC
2129 switch (flag)
2130 {
a5bcd848 2131 case EF_ARM_INTERWORK:
f3485b74
NC
2132 strcat (buf, ", interworking enabled");
2133 break;
76da6bbe 2134
a5bcd848 2135 case EF_ARM_APCS_26:
f3485b74
NC
2136 strcat (buf, ", uses APCS/26");
2137 break;
76da6bbe 2138
a5bcd848 2139 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2140 strcat (buf, ", uses APCS/float");
2141 break;
76da6bbe 2142
a5bcd848 2143 case EF_ARM_PIC:
f3485b74
NC
2144 strcat (buf, ", position independent");
2145 break;
76da6bbe 2146
a5bcd848 2147 case EF_ARM_ALIGN8:
f3485b74
NC
2148 strcat (buf, ", 8 bit structure alignment");
2149 break;
76da6bbe 2150
a5bcd848 2151 case EF_ARM_NEW_ABI:
f3485b74
NC
2152 strcat (buf, ", uses new ABI");
2153 break;
76da6bbe 2154
a5bcd848 2155 case EF_ARM_OLD_ABI:
f3485b74
NC
2156 strcat (buf, ", uses old ABI");
2157 break;
76da6bbe 2158
a5bcd848 2159 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2160 strcat (buf, ", software FP");
2161 break;
76da6bbe 2162
90e01f86
ILT
2163 case EF_ARM_VFP_FLOAT:
2164 strcat (buf, ", VFP");
2165 break;
2166
fde78edd
NC
2167 case EF_ARM_MAVERICK_FLOAT:
2168 strcat (buf, ", Maverick FP");
2169 break;
2170
f3485b74
NC
2171 default:
2172 unknown = 1;
2173 break;
2174 }
2175 }
2176 }
f3485b74
NC
2177
2178 if (unknown)
2179 strcat (buf,", <unknown>");
2180}
2181
252b5132 2182static char *
d3ba0551 2183get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2184{
b34976b6 2185 static char buf[1024];
252b5132
RH
2186
2187 buf[0] = '\0';
76da6bbe 2188
252b5132
RH
2189 if (e_flags)
2190 {
2191 switch (e_machine)
2192 {
2193 default:
2194 break;
2195
f3485b74
NC
2196 case EM_ARM:
2197 decode_ARM_machine_flags (e_flags, buf);
2198 break;
76da6bbe 2199
ec2dfb42
AO
2200 case EM_CYGNUS_FRV:
2201 switch (e_flags & EF_FRV_CPU_MASK)
2202 {
2203 case EF_FRV_CPU_GENERIC:
2204 break;
2205
2206 default:
2207 strcat (buf, ", fr???");
2208 break;
57346661 2209
ec2dfb42
AO
2210 case EF_FRV_CPU_FR300:
2211 strcat (buf, ", fr300");
2212 break;
2213
2214 case EF_FRV_CPU_FR400:
2215 strcat (buf, ", fr400");
2216 break;
2217 case EF_FRV_CPU_FR405:
2218 strcat (buf, ", fr405");
2219 break;
2220
2221 case EF_FRV_CPU_FR450:
2222 strcat (buf, ", fr450");
2223 break;
2224
2225 case EF_FRV_CPU_FR500:
2226 strcat (buf, ", fr500");
2227 break;
2228 case EF_FRV_CPU_FR550:
2229 strcat (buf, ", fr550");
2230 break;
2231
2232 case EF_FRV_CPU_SIMPLE:
2233 strcat (buf, ", simple");
2234 break;
2235 case EF_FRV_CPU_TOMCAT:
2236 strcat (buf, ", tomcat");
2237 break;
2238 }
1c877e87 2239 break;
ec2dfb42 2240
53c7db4b 2241 case EM_68K:
425c6cb0 2242 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2243 strcat (buf, ", m68000");
425c6cb0 2244 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2245 strcat (buf, ", cpu32");
2246 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2247 strcat (buf, ", fido_a");
425c6cb0 2248 else
266abb8f 2249 {
2cf0635d
NC
2250 char const * isa = _("unknown");
2251 char const * mac = _("unknown mac");
2252 char const * additional = NULL;
0112cd26 2253
c694fd50 2254 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2255 {
c694fd50 2256 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2257 isa = "A";
2258 additional = ", nodiv";
2259 break;
c694fd50 2260 case EF_M68K_CF_ISA_A:
266abb8f
NS
2261 isa = "A";
2262 break;
c694fd50 2263 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2264 isa = "A+";
2265 break;
c694fd50 2266 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2267 isa = "B";
2268 additional = ", nousp";
2269 break;
c694fd50 2270 case EF_M68K_CF_ISA_B:
266abb8f
NS
2271 isa = "B";
2272 break;
2273 }
2274 strcat (buf, ", cf, isa ");
2275 strcat (buf, isa);
0b2e31dc
NS
2276 if (additional)
2277 strcat (buf, additional);
c694fd50 2278 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2279 strcat (buf, ", float");
c694fd50 2280 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2281 {
2282 case 0:
2283 mac = NULL;
2284 break;
c694fd50 2285 case EF_M68K_CF_MAC:
266abb8f
NS
2286 mac = "mac";
2287 break;
c694fd50 2288 case EF_M68K_CF_EMAC:
266abb8f
NS
2289 mac = "emac";
2290 break;
2291 }
2292 if (mac)
2293 {
2294 strcat (buf, ", ");
2295 strcat (buf, mac);
2296 }
266abb8f 2297 }
53c7db4b 2298 break;
33c63f9d 2299
252b5132
RH
2300 case EM_PPC:
2301 if (e_flags & EF_PPC_EMB)
2302 strcat (buf, ", emb");
2303
2304 if (e_flags & EF_PPC_RELOCATABLE)
2305 strcat (buf, ", relocatable");
2306
2307 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2308 strcat (buf, ", relocatable-lib");
2309 break;
2310
2b0337b0 2311 case EM_V850:
252b5132
RH
2312 case EM_CYGNUS_V850:
2313 switch (e_flags & EF_V850_ARCH)
2314 {
8ad30312
NC
2315 case E_V850E1_ARCH:
2316 strcat (buf, ", v850e1");
2317 break;
252b5132
RH
2318 case E_V850E_ARCH:
2319 strcat (buf, ", v850e");
2320 break;
252b5132
RH
2321 case E_V850_ARCH:
2322 strcat (buf, ", v850");
2323 break;
2324 default:
2325 strcat (buf, ", unknown v850 architecture variant");
2326 break;
2327 }
2328 break;
2329
2b0337b0 2330 case EM_M32R:
252b5132
RH
2331 case EM_CYGNUS_M32R:
2332 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2333 strcat (buf, ", m32r");
252b5132
RH
2334 break;
2335
2336 case EM_MIPS:
4fe85591 2337 case EM_MIPS_RS3_LE:
252b5132
RH
2338 if (e_flags & EF_MIPS_NOREORDER)
2339 strcat (buf, ", noreorder");
2340
2341 if (e_flags & EF_MIPS_PIC)
2342 strcat (buf, ", pic");
2343
2344 if (e_flags & EF_MIPS_CPIC)
2345 strcat (buf, ", cpic");
2346
d1bdd336
TS
2347 if (e_flags & EF_MIPS_UCODE)
2348 strcat (buf, ", ugen_reserved");
2349
252b5132
RH
2350 if (e_flags & EF_MIPS_ABI2)
2351 strcat (buf, ", abi2");
2352
43521d43
TS
2353 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2354 strcat (buf, ", odk first");
2355
a5d22d2a
TS
2356 if (e_flags & EF_MIPS_32BITMODE)
2357 strcat (buf, ", 32bitmode");
2358
156c2f8b
NC
2359 switch ((e_flags & EF_MIPS_MACH))
2360 {
2361 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2362 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2363 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2364 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2365 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2366 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2367 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2368 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2369 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2370 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2371 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2372 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
05c6f050 2373 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2374 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2375 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2376 case 0:
2377 /* We simply ignore the field in this case to avoid confusion:
2378 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2379 extension. */
2380 break;
2381 default: strcat (buf, ", unknown CPU"); break;
156c2f8b 2382 }
43521d43
TS
2383
2384 switch ((e_flags & EF_MIPS_ABI))
2385 {
2386 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2387 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2388 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2389 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2390 case 0:
2391 /* We simply ignore the field in this case to avoid confusion:
2392 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2393 This means it is likely to be an o32 file, but not for
2394 sure. */
2395 break;
2396 default: strcat (buf, ", unknown ABI"); break;
2397 }
2398
2399 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2400 strcat (buf, ", mdmx");
2401
2402 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2403 strcat (buf, ", mips16");
2404
2405 switch ((e_flags & EF_MIPS_ARCH))
2406 {
2407 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2408 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2409 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2410 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2411 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2412 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2413 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2414 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2415 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
43521d43
TS
2416 default: strcat (buf, ", unknown ISA"); break;
2417 }
2418
252b5132 2419 break;
351b4b40 2420
ccde1100
AO
2421 case EM_SH:
2422 switch ((e_flags & EF_SH_MACH_MASK))
2423 {
2424 case EF_SH1: strcat (buf, ", sh1"); break;
2425 case EF_SH2: strcat (buf, ", sh2"); break;
2426 case EF_SH3: strcat (buf, ", sh3"); break;
2427 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2428 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2429 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2430 case EF_SH3E: strcat (buf, ", sh3e"); break;
2431 case EF_SH4: strcat (buf, ", sh4"); break;
2432 case EF_SH5: strcat (buf, ", sh5"); break;
2433 case EF_SH2E: strcat (buf, ", sh2e"); break;
2434 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2435 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2436 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2437 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2438 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2439 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2440 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2441 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2442 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2443 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2444 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
dc85a459 2445 default: strcat (buf, ", unknown ISA"); break;
ccde1100
AO
2446 }
2447
2448 break;
57346661 2449
351b4b40
RH
2450 case EM_SPARCV9:
2451 if (e_flags & EF_SPARC_32PLUS)
2452 strcat (buf, ", v8+");
2453
2454 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2455 strcat (buf, ", ultrasparcI");
2456
2457 if (e_flags & EF_SPARC_SUN_US3)
2458 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2459
2460 if (e_flags & EF_SPARC_HAL_R1)
2461 strcat (buf, ", halr1");
2462
2463 if (e_flags & EF_SPARC_LEDATA)
2464 strcat (buf, ", ledata");
2465
2466 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2467 strcat (buf, ", tso");
2468
2469 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2470 strcat (buf, ", pso");
2471
2472 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2473 strcat (buf, ", rmo");
2474 break;
7d466069 2475
103f02d3
UD
2476 case EM_PARISC:
2477 switch (e_flags & EF_PARISC_ARCH)
2478 {
2479 case EFA_PARISC_1_0:
2480 strcpy (buf, ", PA-RISC 1.0");
2481 break;
2482 case EFA_PARISC_1_1:
2483 strcpy (buf, ", PA-RISC 1.1");
2484 break;
2485 case EFA_PARISC_2_0:
2486 strcpy (buf, ", PA-RISC 2.0");
2487 break;
2488 default:
2489 break;
2490 }
2491 if (e_flags & EF_PARISC_TRAPNIL)
2492 strcat (buf, ", trapnil");
2493 if (e_flags & EF_PARISC_EXT)
2494 strcat (buf, ", ext");
2495 if (e_flags & EF_PARISC_LSB)
2496 strcat (buf, ", lsb");
2497 if (e_flags & EF_PARISC_WIDE)
2498 strcat (buf, ", wide");
2499 if (e_flags & EF_PARISC_NO_KABP)
2500 strcat (buf, ", no kabp");
2501 if (e_flags & EF_PARISC_LAZYSWAP)
2502 strcat (buf, ", lazyswap");
30800947 2503 break;
76da6bbe 2504
7d466069 2505 case EM_PJ:
2b0337b0 2506 case EM_PJ_OLD:
7d466069
ILT
2507 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2508 strcat (buf, ", new calling convention");
2509
2510 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2511 strcat (buf, ", gnu calling convention");
2512 break;
4d6ed7c8
NC
2513
2514 case EM_IA_64:
2515 if ((e_flags & EF_IA_64_ABI64))
2516 strcat (buf, ", 64-bit");
2517 else
2518 strcat (buf, ", 32-bit");
2519 if ((e_flags & EF_IA_64_REDUCEDFP))
2520 strcat (buf, ", reduced fp model");
2521 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2522 strcat (buf, ", no function descriptors, constant gp");
2523 else if ((e_flags & EF_IA_64_CONS_GP))
2524 strcat (buf, ", constant gp");
2525 if ((e_flags & EF_IA_64_ABSOLUTE))
2526 strcat (buf, ", absolute");
2527 break;
179d3252
JT
2528
2529 case EM_VAX:
2530 if ((e_flags & EF_VAX_NONPIC))
2531 strcat (buf, ", non-PIC");
2532 if ((e_flags & EF_VAX_DFLOAT))
2533 strcat (buf, ", D-Float");
2534 if ((e_flags & EF_VAX_GFLOAT))
2535 strcat (buf, ", G-Float");
2536 break;
c7927a3c
NC
2537
2538 case EM_RX:
2539 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2540 strcat (buf, ", 64-bit doubles");
2541 if (e_flags & E_FLAG_RX_DSP)
2542 strcat (buf, ", dsp");
55786da2
AK
2543
2544 case EM_S390:
2545 if (e_flags & EF_S390_HIGH_GPRS)
2546 strcat (buf, ", highgprs");
252b5132
RH
2547 }
2548 }
2549
2550 return buf;
2551}
2552
252b5132 2553static const char *
d3ba0551
AM
2554get_osabi_name (unsigned int osabi)
2555{
2556 static char buff[32];
2557
2558 switch (osabi)
2559 {
2560 case ELFOSABI_NONE: return "UNIX - System V";
2561 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2562 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
2563 case ELFOSABI_LINUX: return "UNIX - Linux";
2564 case ELFOSABI_HURD: return "GNU/Hurd";
2565 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2566 case ELFOSABI_AIX: return "UNIX - AIX";
2567 case ELFOSABI_IRIX: return "UNIX - IRIX";
2568 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2569 case ELFOSABI_TRU64: return "UNIX - TRU64";
2570 case ELFOSABI_MODESTO: return "Novell - Modesto";
2571 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2572 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2573 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2574 case ELFOSABI_AROS: return "AROS";
11636f9e 2575 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551
AM
2576 case ELFOSABI_STANDALONE: return _("Standalone App");
2577 case ELFOSABI_ARM: return "ARM";
2578 default:
e9e44622 2579 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2580 return buff;
2581 }
2582}
2583
b294bdf8
MM
2584static const char *
2585get_arm_segment_type (unsigned long type)
2586{
2587 switch (type)
2588 {
2589 case PT_ARM_EXIDX:
2590 return "EXIDX";
2591 default:
2592 break;
2593 }
2594
2595 return NULL;
2596}
2597
d3ba0551
AM
2598static const char *
2599get_mips_segment_type (unsigned long type)
252b5132
RH
2600{
2601 switch (type)
2602 {
2603 case PT_MIPS_REGINFO:
2604 return "REGINFO";
2605 case PT_MIPS_RTPROC:
2606 return "RTPROC";
2607 case PT_MIPS_OPTIONS:
2608 return "OPTIONS";
2609 default:
2610 break;
2611 }
2612
2613 return NULL;
2614}
2615
103f02d3 2616static const char *
d3ba0551 2617get_parisc_segment_type (unsigned long type)
103f02d3
UD
2618{
2619 switch (type)
2620 {
2621 case PT_HP_TLS: return "HP_TLS";
2622 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2623 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2624 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2625 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2626 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2627 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2628 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2629 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2630 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2631 case PT_HP_PARALLEL: return "HP_PARALLEL";
2632 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2633 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2634 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2635 case PT_HP_STACK: return "HP_STACK";
2636 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2637 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2638 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2639 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2640 default:
2641 break;
2642 }
2643
2644 return NULL;
2645}
2646
4d6ed7c8 2647static const char *
d3ba0551 2648get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2649{
2650 switch (type)
2651 {
2652 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2653 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2654 case PT_HP_TLS: return "HP_TLS";
2655 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2656 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2657 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2658 default:
2659 break;
2660 }
2661
2662 return NULL;
2663}
2664
252b5132 2665static const char *
d3ba0551 2666get_segment_type (unsigned long p_type)
252b5132 2667{
b34976b6 2668 static char buff[32];
252b5132
RH
2669
2670 switch (p_type)
2671 {
b34976b6
AM
2672 case PT_NULL: return "NULL";
2673 case PT_LOAD: return "LOAD";
252b5132 2674 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2675 case PT_INTERP: return "INTERP";
2676 case PT_NOTE: return "NOTE";
2677 case PT_SHLIB: return "SHLIB";
2678 case PT_PHDR: return "PHDR";
13ae64f3 2679 case PT_TLS: return "TLS";
252b5132 2680
65765700
JJ
2681 case PT_GNU_EH_FRAME:
2682 return "GNU_EH_FRAME";
2b05f1b7 2683 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2684 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2685
252b5132
RH
2686 default:
2687 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2688 {
2cf0635d 2689 const char * result;
103f02d3 2690
252b5132
RH
2691 switch (elf_header.e_machine)
2692 {
b294bdf8
MM
2693 case EM_ARM:
2694 result = get_arm_segment_type (p_type);
2695 break;
252b5132 2696 case EM_MIPS:
4fe85591 2697 case EM_MIPS_RS3_LE:
252b5132
RH
2698 result = get_mips_segment_type (p_type);
2699 break;
103f02d3
UD
2700 case EM_PARISC:
2701 result = get_parisc_segment_type (p_type);
2702 break;
4d6ed7c8
NC
2703 case EM_IA_64:
2704 result = get_ia64_segment_type (p_type);
2705 break;
252b5132
RH
2706 default:
2707 result = NULL;
2708 break;
2709 }
103f02d3 2710
252b5132
RH
2711 if (result != NULL)
2712 return result;
103f02d3 2713
252b5132
RH
2714 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2715 }
2716 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2717 {
2cf0635d 2718 const char * result;
103f02d3
UD
2719
2720 switch (elf_header.e_machine)
2721 {
2722 case EM_PARISC:
2723 result = get_parisc_segment_type (p_type);
2724 break;
00428cca
AM
2725 case EM_IA_64:
2726 result = get_ia64_segment_type (p_type);
2727 break;
103f02d3
UD
2728 default:
2729 result = NULL;
2730 break;
2731 }
2732
2733 if (result != NULL)
2734 return result;
2735
2736 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2737 }
252b5132 2738 else
e9e44622 2739 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2740
2741 return buff;
2742 }
2743}
2744
2745static const char *
d3ba0551 2746get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2747{
2748 switch (sh_type)
2749 {
b34976b6
AM
2750 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2751 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2752 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2753 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2754 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2755 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2756 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2757 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2758 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2759 case SHT_MIPS_RELD: return "MIPS_RELD";
2760 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2761 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2762 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2763 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2764 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2765 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2766 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2767 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2768 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2769 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2770 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2771 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2772 case SHT_MIPS_LINE: return "MIPS_LINE";
2773 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2774 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2775 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2776 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2777 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2778 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2779 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2780 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2781 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2782 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2783 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2784 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2785 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2786 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2787 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2788 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2789 default:
2790 break;
2791 }
2792 return NULL;
2793}
2794
103f02d3 2795static const char *
d3ba0551 2796get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2797{
2798 switch (sh_type)
2799 {
2800 case SHT_PARISC_EXT: return "PARISC_EXT";
2801 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2802 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2803 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2804 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2805 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2806 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2807 default:
2808 break;
2809 }
2810 return NULL;
2811}
2812
4d6ed7c8 2813static const char *
d3ba0551 2814get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2815{
18bd398b 2816 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2817 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2818 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2819
4d6ed7c8
NC
2820 switch (sh_type)
2821 {
148b93f2
NC
2822 case SHT_IA_64_EXT: return "IA_64_EXT";
2823 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2824 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
2825 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
2826 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
2827 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
2828 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
2829 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
2830 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
2831 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
2832 default:
2833 break;
2834 }
2835 return NULL;
2836}
2837
d2b2c203
DJ
2838static const char *
2839get_x86_64_section_type_name (unsigned int sh_type)
2840{
2841 switch (sh_type)
2842 {
2843 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2844 default:
2845 break;
2846 }
2847 return NULL;
2848}
2849
40a18ebd
NC
2850static const char *
2851get_arm_section_type_name (unsigned int sh_type)
2852{
2853 switch (sh_type)
2854 {
7f6fed87
NC
2855 case SHT_ARM_EXIDX: return "ARM_EXIDX";
2856 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
2857 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
2858 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
2859 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
2860 default:
2861 break;
2862 }
2863 return NULL;
2864}
2865
252b5132 2866static const char *
d3ba0551 2867get_section_type_name (unsigned int sh_type)
252b5132 2868{
b34976b6 2869 static char buff[32];
252b5132
RH
2870
2871 switch (sh_type)
2872 {
2873 case SHT_NULL: return "NULL";
2874 case SHT_PROGBITS: return "PROGBITS";
2875 case SHT_SYMTAB: return "SYMTAB";
2876 case SHT_STRTAB: return "STRTAB";
2877 case SHT_RELA: return "RELA";
2878 case SHT_HASH: return "HASH";
2879 case SHT_DYNAMIC: return "DYNAMIC";
2880 case SHT_NOTE: return "NOTE";
2881 case SHT_NOBITS: return "NOBITS";
2882 case SHT_REL: return "REL";
2883 case SHT_SHLIB: return "SHLIB";
2884 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
2885 case SHT_INIT_ARRAY: return "INIT_ARRAY";
2886 case SHT_FINI_ARRAY: return "FINI_ARRAY";
2887 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 2888 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
2889 case SHT_GROUP: return "GROUP";
2890 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
2891 case SHT_GNU_verdef: return "VERDEF";
2892 case SHT_GNU_verneed: return "VERNEED";
2893 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
2894 case 0x6ffffff0: return "VERSYM";
2895 case 0x6ffffffc: return "VERDEF";
252b5132
RH
2896 case 0x7ffffffd: return "AUXILIARY";
2897 case 0x7fffffff: return "FILTER";
047b2264 2898 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
2899
2900 default:
2901 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
2902 {
2cf0635d 2903 const char * result;
252b5132
RH
2904
2905 switch (elf_header.e_machine)
2906 {
2907 case EM_MIPS:
4fe85591 2908 case EM_MIPS_RS3_LE:
252b5132
RH
2909 result = get_mips_section_type_name (sh_type);
2910 break;
103f02d3
UD
2911 case EM_PARISC:
2912 result = get_parisc_section_type_name (sh_type);
2913 break;
4d6ed7c8
NC
2914 case EM_IA_64:
2915 result = get_ia64_section_type_name (sh_type);
2916 break;
d2b2c203 2917 case EM_X86_64:
8a9036a4 2918 case EM_L1OM:
d2b2c203
DJ
2919 result = get_x86_64_section_type_name (sh_type);
2920 break;
40a18ebd
NC
2921 case EM_ARM:
2922 result = get_arm_section_type_name (sh_type);
2923 break;
252b5132
RH
2924 default:
2925 result = NULL;
2926 break;
2927 }
2928
2929 if (result != NULL)
2930 return result;
2931
c91d0dfb 2932 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
2933 }
2934 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 2935 {
2cf0635d 2936 const char * result;
148b93f2
NC
2937
2938 switch (elf_header.e_machine)
2939 {
2940 case EM_IA_64:
2941 result = get_ia64_section_type_name (sh_type);
2942 break;
2943 default:
2944 result = NULL;
2945 break;
2946 }
2947
2948 if (result != NULL)
2949 return result;
2950
2951 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
2952 }
252b5132 2953 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 2954 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 2955 else
e9e44622 2956 snprintf (buff, sizeof (buff), _("<unknown>: %x"), sh_type);
103f02d3 2957
252b5132
RH
2958 return buff;
2959 }
2960}
2961
2979dc34 2962#define OPTION_DEBUG_DUMP 512
2c610e4b 2963#define OPTION_DYN_SYMS 513
2979dc34 2964
85b1c36d 2965static struct option options[] =
252b5132 2966{
b34976b6 2967 {"all", no_argument, 0, 'a'},
252b5132
RH
2968 {"file-header", no_argument, 0, 'h'},
2969 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
2970 {"headers", no_argument, 0, 'e'},
2971 {"histogram", no_argument, 0, 'I'},
2972 {"segments", no_argument, 0, 'l'},
2973 {"sections", no_argument, 0, 'S'},
252b5132 2974 {"section-headers", no_argument, 0, 'S'},
f5842774 2975 {"section-groups", no_argument, 0, 'g'},
5477e8a0 2976 {"section-details", no_argument, 0, 't'},
595cf52e 2977 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
2978 {"symbols", no_argument, 0, 's'},
2979 {"syms", no_argument, 0, 's'},
2c610e4b 2980 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
2981 {"relocs", no_argument, 0, 'r'},
2982 {"notes", no_argument, 0, 'n'},
2983 {"dynamic", no_argument, 0, 'd'},
a952a375 2984 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
2985 {"version-info", no_argument, 0, 'V'},
2986 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 2987 {"unwind", no_argument, 0, 'u'},
4145f1d5 2988 {"archive-index", no_argument, 0, 'c'},
b34976b6 2989 {"hex-dump", required_argument, 0, 'x'},
cf13d699 2990 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 2991 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
2992#ifdef SUPPORT_DISASSEMBLY
2993 {"instruction-dump", required_argument, 0, 'i'},
2994#endif
cf13d699 2995 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 2996
b34976b6
AM
2997 {"version", no_argument, 0, 'v'},
2998 {"wide", no_argument, 0, 'W'},
2999 {"help", no_argument, 0, 'H'},
3000 {0, no_argument, 0, 0}
252b5132
RH
3001};
3002
3003static void
2cf0635d 3004usage (FILE * stream)
252b5132 3005{
92f01d61
JM
3006 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3007 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3008 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3009 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3010 -h --file-header Display the ELF file header\n\
3011 -l --program-headers Display the program headers\n\
3012 --segments An alias for --program-headers\n\
3013 -S --section-headers Display the sections' header\n\
3014 --sections An alias for --section-headers\n\
f5842774 3015 -g --section-groups Display the section groups\n\
5477e8a0 3016 -t --section-details Display the section details\n\
8b53311e
NC
3017 -e --headers Equivalent to: -h -l -S\n\
3018 -s --syms Display the symbol table\n\
3f08eb35 3019 --symbols An alias for --syms\n\
2c610e4b 3020 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3021 -n --notes Display the core notes (if present)\n\
3022 -r --relocs Display the relocations (if present)\n\
3023 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3024 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
3025 -V --version-info Display the version sections (if present)\n\
3026 -A --arch-specific Display architecture specific information (if any).\n\
4145f1d5 3027 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3028 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3029 -x --hex-dump=<number|name>\n\
3030 Dump the contents of section <number|name> as bytes\n\
3031 -p --string-dump=<number|name>\n\
3032 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3033 -R --relocated-dump=<number|name>\n\
3034 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3035 -w[lLiaprmfFsoRt] or\n\
1ed06042 3036 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
f9f0e732 3037 =frames-interp,=str,=loc,=Ranges,=pubtypes]\n\
8b53311e 3038 Display the contents of DWARF2 debug sections\n"));
252b5132 3039#ifdef SUPPORT_DISASSEMBLY
92f01d61 3040 fprintf (stream, _("\
09c11c86
NC
3041 -i --instruction-dump=<number|name>\n\
3042 Disassemble the contents of section <number|name>\n"));
252b5132 3043#endif
92f01d61 3044 fprintf (stream, _("\
8b53311e
NC
3045 -I --histogram Display histogram of bucket list lengths\n\
3046 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3047 @<file> Read options from <file>\n\
8b53311e
NC
3048 -H --help Display this information\n\
3049 -v --version Display the version number of readelf\n"));
1118d252 3050
92f01d61
JM
3051 if (REPORT_BUGS_TO[0] && stream == stdout)
3052 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3053
92f01d61 3054 exit (stream == stdout ? 0 : 1);
252b5132
RH
3055}
3056
18bd398b
NC
3057/* Record the fact that the user wants the contents of section number
3058 SECTION to be displayed using the method(s) encoded as flags bits
3059 in TYPE. Note, TYPE can be zero if we are creating the array for
3060 the first time. */
3061
252b5132 3062static void
09c11c86 3063request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3064{
3065 if (section >= num_dump_sects)
3066 {
2cf0635d 3067 dump_type * new_dump_sects;
252b5132 3068
3f5e193b
NC
3069 new_dump_sects = (dump_type *) calloc (section + 1,
3070 sizeof (* dump_sects));
252b5132
RH
3071
3072 if (new_dump_sects == NULL)
591a748a 3073 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3074 else
3075 {
3076 /* Copy current flag settings. */
09c11c86 3077 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3078
3079 free (dump_sects);
3080
3081 dump_sects = new_dump_sects;
3082 num_dump_sects = section + 1;
3083 }
3084 }
3085
3086 if (dump_sects)
b34976b6 3087 dump_sects[section] |= type;
252b5132
RH
3088
3089 return;
3090}
3091
aef1f6d0
DJ
3092/* Request a dump by section name. */
3093
3094static void
2cf0635d 3095request_dump_byname (const char * section, dump_type type)
aef1f6d0 3096{
2cf0635d 3097 struct dump_list_entry * new_request;
aef1f6d0 3098
3f5e193b
NC
3099 new_request = (struct dump_list_entry *)
3100 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3101 if (!new_request)
591a748a 3102 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3103
3104 new_request->name = strdup (section);
3105 if (!new_request->name)
591a748a 3106 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3107
3108 new_request->type = type;
3109
3110 new_request->next = dump_sects_byname;
3111 dump_sects_byname = new_request;
3112}
3113
cf13d699
NC
3114static inline void
3115request_dump (dump_type type)
3116{
3117 int section;
3118 char * cp;
3119
3120 do_dump++;
3121 section = strtoul (optarg, & cp, 0);
3122
3123 if (! *cp && section >= 0)
3124 request_dump_bynumber (section, type);
3125 else
3126 request_dump_byname (optarg, type);
3127}
3128
3129
252b5132 3130static void
2cf0635d 3131parse_args (int argc, char ** argv)
252b5132
RH
3132{
3133 int c;
3134
3135 if (argc < 2)
92f01d61 3136 usage (stderr);
252b5132
RH
3137
3138 while ((c = getopt_long
cf13d699 3139 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3140 {
252b5132
RH
3141 switch (c)
3142 {
3143 case 0:
3144 /* Long options. */
3145 break;
3146 case 'H':
92f01d61 3147 usage (stdout);
252b5132
RH
3148 break;
3149
3150 case 'a':
b34976b6
AM
3151 do_syms++;
3152 do_reloc++;
3153 do_unwind++;
3154 do_dynamic++;
3155 do_header++;
3156 do_sections++;
f5842774 3157 do_section_groups++;
b34976b6
AM
3158 do_segments++;
3159 do_version++;
3160 do_histogram++;
3161 do_arch++;
3162 do_notes++;
252b5132 3163 break;
f5842774
L
3164 case 'g':
3165 do_section_groups++;
3166 break;
5477e8a0 3167 case 't':
595cf52e 3168 case 'N':
5477e8a0
L
3169 do_sections++;
3170 do_section_details++;
595cf52e 3171 break;
252b5132 3172 case 'e':
b34976b6
AM
3173 do_header++;
3174 do_sections++;
3175 do_segments++;
252b5132 3176 break;
a952a375 3177 case 'A':
b34976b6 3178 do_arch++;
a952a375 3179 break;
252b5132 3180 case 'D':
b34976b6 3181 do_using_dynamic++;
252b5132
RH
3182 break;
3183 case 'r':
b34976b6 3184 do_reloc++;
252b5132 3185 break;
4d6ed7c8 3186 case 'u':
b34976b6 3187 do_unwind++;
4d6ed7c8 3188 break;
252b5132 3189 case 'h':
b34976b6 3190 do_header++;
252b5132
RH
3191 break;
3192 case 'l':
b34976b6 3193 do_segments++;
252b5132
RH
3194 break;
3195 case 's':
b34976b6 3196 do_syms++;
252b5132
RH
3197 break;
3198 case 'S':
b34976b6 3199 do_sections++;
252b5132
RH
3200 break;
3201 case 'd':
b34976b6 3202 do_dynamic++;
252b5132 3203 break;
a952a375 3204 case 'I':
b34976b6 3205 do_histogram++;
a952a375 3206 break;
779fe533 3207 case 'n':
b34976b6 3208 do_notes++;
779fe533 3209 break;
4145f1d5
NC
3210 case 'c':
3211 do_archive_index++;
3212 break;
252b5132 3213 case 'x':
cf13d699 3214 request_dump (HEX_DUMP);
aef1f6d0 3215 break;
09c11c86 3216 case 'p':
cf13d699
NC
3217 request_dump (STRING_DUMP);
3218 break;
3219 case 'R':
3220 request_dump (RELOC_DUMP);
09c11c86 3221 break;
252b5132 3222 case 'w':
b34976b6 3223 do_dump++;
252b5132 3224 if (optarg == 0)
613ff48b
CC
3225 {
3226 do_debugging = 1;
3227 dwarf_select_sections_all ();
3228 }
252b5132
RH
3229 else
3230 {
3231 do_debugging = 0;
4cb93e3b 3232 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3233 }
3234 break;
2979dc34 3235 case OPTION_DEBUG_DUMP:
b34976b6 3236 do_dump++;
2979dc34
JJ
3237 if (optarg == 0)
3238 do_debugging = 1;
3239 else
3240 {
2979dc34 3241 do_debugging = 0;
4cb93e3b 3242 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3243 }
3244 break;
2c610e4b
L
3245 case OPTION_DYN_SYMS:
3246 do_dyn_syms++;
3247 break;
252b5132
RH
3248#ifdef SUPPORT_DISASSEMBLY
3249 case 'i':
cf13d699
NC
3250 request_dump (DISASS_DUMP);
3251 break;
252b5132
RH
3252#endif
3253 case 'v':
3254 print_version (program_name);
3255 break;
3256 case 'V':
b34976b6 3257 do_version++;
252b5132 3258 break;
d974e256 3259 case 'W':
b34976b6 3260 do_wide++;
d974e256 3261 break;
252b5132 3262 default:
252b5132
RH
3263 /* xgettext:c-format */
3264 error (_("Invalid option '-%c'\n"), c);
3265 /* Drop through. */
3266 case '?':
92f01d61 3267 usage (stderr);
252b5132
RH
3268 }
3269 }
3270
4d6ed7c8 3271 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3272 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3273 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3274 && !do_section_groups && !do_archive_index
3275 && !do_dyn_syms)
92f01d61 3276 usage (stderr);
252b5132
RH
3277 else if (argc < 3)
3278 {
3279 warn (_("Nothing to do.\n"));
92f01d61 3280 usage (stderr);
252b5132
RH
3281 }
3282}
3283
3284static const char *
d3ba0551 3285get_elf_class (unsigned int elf_class)
252b5132 3286{
b34976b6 3287 static char buff[32];
103f02d3 3288
252b5132
RH
3289 switch (elf_class)
3290 {
3291 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3292 case ELFCLASS32: return "ELF32";
3293 case ELFCLASS64: return "ELF64";
ab5e7794 3294 default:
e9e44622 3295 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3296 return buff;
252b5132
RH
3297 }
3298}
3299
3300static const char *
d3ba0551 3301get_data_encoding (unsigned int encoding)
252b5132 3302{
b34976b6 3303 static char buff[32];
103f02d3 3304
252b5132
RH
3305 switch (encoding)
3306 {
3307 case ELFDATANONE: return _("none");
33c63f9d
CM
3308 case ELFDATA2LSB: return _("2's complement, little endian");
3309 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3310 default:
e9e44622 3311 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3312 return buff;
252b5132
RH
3313 }
3314}
3315
252b5132 3316/* Decode the data held in 'elf_header'. */
ee42cf8c 3317
252b5132 3318static int
d3ba0551 3319process_file_header (void)
252b5132 3320{
b34976b6
AM
3321 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3322 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3323 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3324 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3325 {
3326 error
3327 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3328 return 0;
3329 }
3330
2dc4cec1
L
3331 init_dwarf_regnames (elf_header.e_machine);
3332
252b5132
RH
3333 if (do_header)
3334 {
3335 int i;
3336
3337 printf (_("ELF Header:\n"));
3338 printf (_(" Magic: "));
b34976b6
AM
3339 for (i = 0; i < EI_NIDENT; i++)
3340 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3341 printf ("\n");
3342 printf (_(" Class: %s\n"),
b34976b6 3343 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3344 printf (_(" Data: %s\n"),
b34976b6 3345 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3346 printf (_(" Version: %d %s\n"),
b34976b6
AM
3347 elf_header.e_ident[EI_VERSION],
3348 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3349 ? "(current)"
b34976b6 3350 : (elf_header.e_ident[EI_VERSION] != EV_NONE
789be9f7
ILT
3351 ? "<unknown: %lx>"
3352 : "")));
252b5132 3353 printf (_(" OS/ABI: %s\n"),
b34976b6 3354 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3355 printf (_(" ABI Version: %d\n"),
b34976b6 3356 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3357 printf (_(" Type: %s\n"),
3358 get_file_type (elf_header.e_type));
3359 printf (_(" Machine: %s\n"),
3360 get_machine_name (elf_header.e_machine));
3361 printf (_(" Version: 0x%lx\n"),
3362 (unsigned long) elf_header.e_version);
76da6bbe 3363
f7a99963
NC
3364 printf (_(" Entry point address: "));
3365 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3366 printf (_("\n Start of program headers: "));
3367 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3368 printf (_(" (bytes into file)\n Start of section headers: "));
3369 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3370 printf (_(" (bytes into file)\n"));
76da6bbe 3371
252b5132
RH
3372 printf (_(" Flags: 0x%lx%s\n"),
3373 (unsigned long) elf_header.e_flags,
3374 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3375 printf (_(" Size of this header: %ld (bytes)\n"),
3376 (long) elf_header.e_ehsize);
3377 printf (_(" Size of program headers: %ld (bytes)\n"),
3378 (long) elf_header.e_phentsize);
2046a35d 3379 printf (_(" Number of program headers: %ld"),
252b5132 3380 (long) elf_header.e_phnum);
2046a35d
AM
3381 if (section_headers != NULL
3382 && elf_header.e_phnum == PN_XNUM
3383 && section_headers[0].sh_info != 0)
3384 printf (_(" (%ld)"), (long) section_headers[0].sh_info);
3385 putc ('\n', stdout);
252b5132
RH
3386 printf (_(" Size of section headers: %ld (bytes)\n"),
3387 (long) elf_header.e_shentsize);
560f3c1c 3388 printf (_(" Number of section headers: %ld"),
252b5132 3389 (long) elf_header.e_shnum);
4fbb74a6 3390 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3391 printf (" (%ld)", (long) section_headers[0].sh_size);
3392 putc ('\n', stdout);
3393 printf (_(" Section header string table index: %ld"),
252b5132 3394 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3395 if (section_headers != NULL
3396 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3397 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3398 else if (elf_header.e_shstrndx != SHN_UNDEF
3399 && elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3400 printf (" <corrupt: out of range>");
560f3c1c
AM
3401 putc ('\n', stdout);
3402 }
3403
3404 if (section_headers != NULL)
3405 {
2046a35d
AM
3406 if (elf_header.e_phnum == PN_XNUM
3407 && section_headers[0].sh_info != 0)
3408 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3409 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3410 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3411 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3412 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3413 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3414 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3415 free (section_headers);
3416 section_headers = NULL;
252b5132 3417 }
103f02d3 3418
9ea033b2
NC
3419 return 1;
3420}
3421
252b5132 3422
9ea033b2 3423static int
91d6fa6a 3424get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3425{
2cf0635d
NC
3426 Elf32_External_Phdr * phdrs;
3427 Elf32_External_Phdr * external;
3428 Elf_Internal_Phdr * internal;
b34976b6 3429 unsigned int i;
103f02d3 3430
3f5e193b
NC
3431 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3432 elf_header.e_phentsize,
3433 elf_header.e_phnum,
3434 _("program headers"));
a6e9f9df
AM
3435 if (!phdrs)
3436 return 0;
9ea033b2 3437
91d6fa6a 3438 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3439 i < elf_header.e_phnum;
b34976b6 3440 i++, internal++, external++)
252b5132 3441 {
9ea033b2
NC
3442 internal->p_type = BYTE_GET (external->p_type);
3443 internal->p_offset = BYTE_GET (external->p_offset);
3444 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3445 internal->p_paddr = BYTE_GET (external->p_paddr);
3446 internal->p_filesz = BYTE_GET (external->p_filesz);
3447 internal->p_memsz = BYTE_GET (external->p_memsz);
3448 internal->p_flags = BYTE_GET (external->p_flags);
3449 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3450 }
3451
9ea033b2
NC
3452 free (phdrs);
3453
252b5132
RH
3454 return 1;
3455}
3456
9ea033b2 3457static int
91d6fa6a 3458get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3459{
2cf0635d
NC
3460 Elf64_External_Phdr * phdrs;
3461 Elf64_External_Phdr * external;
3462 Elf_Internal_Phdr * internal;
b34976b6 3463 unsigned int i;
103f02d3 3464
3f5e193b
NC
3465 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3466 elf_header.e_phentsize,
3467 elf_header.e_phnum,
3468 _("program headers"));
a6e9f9df
AM
3469 if (!phdrs)
3470 return 0;
9ea033b2 3471
91d6fa6a 3472 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3473 i < elf_header.e_phnum;
b34976b6 3474 i++, internal++, external++)
9ea033b2
NC
3475 {
3476 internal->p_type = BYTE_GET (external->p_type);
3477 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3478 internal->p_offset = BYTE_GET (external->p_offset);
3479 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3480 internal->p_paddr = BYTE_GET (external->p_paddr);
3481 internal->p_filesz = BYTE_GET (external->p_filesz);
3482 internal->p_memsz = BYTE_GET (external->p_memsz);
3483 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3484 }
3485
3486 free (phdrs);
3487
3488 return 1;
3489}
252b5132 3490
d93f0186
NC
3491/* Returns 1 if the program headers were read into `program_headers'. */
3492
3493static int
2cf0635d 3494get_program_headers (FILE * file)
d93f0186 3495{
2cf0635d 3496 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3497
3498 /* Check cache of prior read. */
3499 if (program_headers != NULL)
3500 return 1;
3501
3f5e193b
NC
3502 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3503 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3504
3505 if (phdrs == NULL)
3506 {
3507 error (_("Out of memory\n"));
3508 return 0;
3509 }
3510
3511 if (is_32bit_elf
3512 ? get_32bit_program_headers (file, phdrs)
3513 : get_64bit_program_headers (file, phdrs))
3514 {
3515 program_headers = phdrs;
3516 return 1;
3517 }
3518
3519 free (phdrs);
3520 return 0;
3521}
3522
2f62977e
NC
3523/* Returns 1 if the program headers were loaded. */
3524
252b5132 3525static int
2cf0635d 3526process_program_headers (FILE * file)
252b5132 3527{
2cf0635d 3528 Elf_Internal_Phdr * segment;
b34976b6 3529 unsigned int i;
252b5132
RH
3530
3531 if (elf_header.e_phnum == 0)
3532 {
3533 if (do_segments)
3534 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3535 return 0;
252b5132
RH
3536 }
3537
3538 if (do_segments && !do_header)
3539 {
f7a99963
NC
3540 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3541 printf (_("Entry point "));
3542 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3543 printf (_("\nThere are %d program headers, starting at offset "),
3544 elf_header.e_phnum);
3545 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3546 printf ("\n");
252b5132
RH
3547 }
3548
d93f0186 3549 if (! get_program_headers (file))
252b5132 3550 return 0;
103f02d3 3551
252b5132
RH
3552 if (do_segments)
3553 {
3a1a2036
NC
3554 if (elf_header.e_phnum > 1)
3555 printf (_("\nProgram Headers:\n"));
3556 else
3557 printf (_("\nProgram Headers:\n"));
76da6bbe 3558
f7a99963
NC
3559 if (is_32bit_elf)
3560 printf
3561 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3562 else if (do_wide)
3563 printf
3564 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3565 else
3566 {
3567 printf
3568 (_(" Type Offset VirtAddr PhysAddr\n"));
3569 printf
3570 (_(" FileSiz MemSiz Flags Align\n"));
3571 }
252b5132
RH
3572 }
3573
252b5132 3574 dynamic_addr = 0;
1b228002 3575 dynamic_size = 0;
252b5132
RH
3576
3577 for (i = 0, segment = program_headers;
3578 i < elf_header.e_phnum;
b34976b6 3579 i++, segment++)
252b5132
RH
3580 {
3581 if (do_segments)
3582 {
103f02d3 3583 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3584
3585 if (is_32bit_elf)
3586 {
3587 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3588 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3589 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3590 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3591 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3592 printf ("%c%c%c ",
3593 (segment->p_flags & PF_R ? 'R' : ' '),
3594 (segment->p_flags & PF_W ? 'W' : ' '),
3595 (segment->p_flags & PF_X ? 'E' : ' '));
3596 printf ("%#lx", (unsigned long) segment->p_align);
3597 }
d974e256
JJ
3598 else if (do_wide)
3599 {
3600 if ((unsigned long) segment->p_offset == segment->p_offset)
3601 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3602 else
3603 {
3604 print_vma (segment->p_offset, FULL_HEX);
3605 putchar (' ');
3606 }
3607
3608 print_vma (segment->p_vaddr, FULL_HEX);
3609 putchar (' ');
3610 print_vma (segment->p_paddr, FULL_HEX);
3611 putchar (' ');
3612
3613 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3614 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3615 else
3616 {
3617 print_vma (segment->p_filesz, FULL_HEX);
3618 putchar (' ');
3619 }
3620
3621 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3622 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3623 else
3624 {
3625 print_vma (segment->p_offset, FULL_HEX);
3626 }
3627
3628 printf (" %c%c%c ",
3629 (segment->p_flags & PF_R ? 'R' : ' '),
3630 (segment->p_flags & PF_W ? 'W' : ' '),
3631 (segment->p_flags & PF_X ? 'E' : ' '));
3632
3633 if ((unsigned long) segment->p_align == segment->p_align)
3634 printf ("%#lx", (unsigned long) segment->p_align);
3635 else
3636 {
3637 print_vma (segment->p_align, PREFIX_HEX);
3638 }
3639 }
f7a99963
NC
3640 else
3641 {
3642 print_vma (segment->p_offset, FULL_HEX);
3643 putchar (' ');
3644 print_vma (segment->p_vaddr, FULL_HEX);
3645 putchar (' ');
3646 print_vma (segment->p_paddr, FULL_HEX);
3647 printf ("\n ");
3648 print_vma (segment->p_filesz, FULL_HEX);
3649 putchar (' ');
3650 print_vma (segment->p_memsz, FULL_HEX);
3651 printf (" %c%c%c ",
3652 (segment->p_flags & PF_R ? 'R' : ' '),
3653 (segment->p_flags & PF_W ? 'W' : ' '),
3654 (segment->p_flags & PF_X ? 'E' : ' '));
3655 print_vma (segment->p_align, HEX);
3656 }
252b5132
RH
3657 }
3658
3659 switch (segment->p_type)
3660 {
252b5132
RH
3661 case PT_DYNAMIC:
3662 if (dynamic_addr)
3663 error (_("more than one dynamic segment\n"));
3664
20737c13
AM
3665 /* By default, assume that the .dynamic section is the first
3666 section in the DYNAMIC segment. */
3667 dynamic_addr = segment->p_offset;
3668 dynamic_size = segment->p_filesz;
3669
b2d38a17
NC
3670 /* Try to locate the .dynamic section. If there is
3671 a section header table, we can easily locate it. */
3672 if (section_headers != NULL)
3673 {
2cf0635d 3674 Elf_Internal_Shdr * sec;
b2d38a17 3675
89fac5e3
RS
3676 sec = find_section (".dynamic");
3677 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3678 {
591a748a 3679 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3680 break;
3681 }
3682
42bb2e33 3683 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3684 {
3685 dynamic_size = 0;
3686 break;
3687 }
42bb2e33 3688
b2d38a17
NC
3689 dynamic_addr = sec->sh_offset;
3690 dynamic_size = sec->sh_size;
3691
3692 if (dynamic_addr < segment->p_offset
3693 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3694 warn (_("the .dynamic section is not contained"
3695 " within the dynamic segment\n"));
b2d38a17 3696 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3697 warn (_("the .dynamic section is not the first section"
3698 " in the dynamic segment.\n"));
b2d38a17 3699 }
252b5132
RH
3700 break;
3701
3702 case PT_INTERP:
fb52b2f4
NC
3703 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3704 SEEK_SET))
252b5132
RH
3705 error (_("Unable to find program interpreter name\n"));
3706 else
3707 {
f8eae8b2
L
3708 char fmt [32];
3709 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3710
3711 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3712 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3713
252b5132 3714 program_interpreter[0] = 0;
7bd7b3ef
AM
3715 if (fscanf (file, fmt, program_interpreter) <= 0)
3716 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3717
3718 if (do_segments)
3719 printf (_("\n [Requesting program interpreter: %s]"),
3720 program_interpreter);
3721 }
3722 break;
3723 }
3724
3725 if (do_segments)
3726 putc ('\n', stdout);
3727 }
3728
c256ffe7 3729 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3730 {
3731 printf (_("\n Section to Segment mapping:\n"));
3732 printf (_(" Segment Sections...\n"));
3733
252b5132
RH
3734 for (i = 0; i < elf_header.e_phnum; i++)
3735 {
9ad5cbcf 3736 unsigned int j;
2cf0635d 3737 Elf_Internal_Shdr * section;
252b5132
RH
3738
3739 segment = program_headers + i;
b391a3e3 3740 section = section_headers + 1;
252b5132
RH
3741
3742 printf (" %2.2d ", i);
3743
b34976b6 3744 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3745 {
2cf0635d 3746 if (ELF_IS_SECTION_IN_SEGMENT_MEMORY (section, segment))
252b5132
RH
3747 printf ("%s ", SECTION_NAME (section));
3748 }
3749
3750 putc ('\n',stdout);
3751 }
3752 }
3753
252b5132
RH
3754 return 1;
3755}
3756
3757
d93f0186
NC
3758/* Find the file offset corresponding to VMA by using the program headers. */
3759
3760static long
2cf0635d 3761offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 3762{
2cf0635d 3763 Elf_Internal_Phdr * seg;
d93f0186
NC
3764
3765 if (! get_program_headers (file))
3766 {
3767 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3768 return (long) vma;
3769 }
3770
3771 for (seg = program_headers;
3772 seg < program_headers + elf_header.e_phnum;
3773 ++seg)
3774 {
3775 if (seg->p_type != PT_LOAD)
3776 continue;
3777
3778 if (vma >= (seg->p_vaddr & -seg->p_align)
3779 && vma + size <= seg->p_vaddr + seg->p_filesz)
3780 return vma - seg->p_vaddr + seg->p_offset;
3781 }
3782
3783 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 3784 (unsigned long) vma);
d93f0186
NC
3785 return (long) vma;
3786}
3787
3788
252b5132 3789static int
2cf0635d 3790get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 3791{
2cf0635d
NC
3792 Elf32_External_Shdr * shdrs;
3793 Elf_Internal_Shdr * internal;
b34976b6 3794 unsigned int i;
252b5132 3795
3f5e193b
NC
3796 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3797 elf_header.e_shentsize, num,
3798 _("section headers"));
a6e9f9df
AM
3799 if (!shdrs)
3800 return 0;
252b5132 3801
3f5e193b
NC
3802 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3803 sizeof (Elf_Internal_Shdr));
252b5132
RH
3804
3805 if (section_headers == NULL)
3806 {
3807 error (_("Out of memory\n"));
3808 return 0;
3809 }
3810
3811 for (i = 0, internal = section_headers;
560f3c1c 3812 i < num;
b34976b6 3813 i++, internal++)
252b5132
RH
3814 {
3815 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3816 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3817 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3818 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3819 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3820 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3821 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3822 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3823 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3824 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3825 }
3826
3827 free (shdrs);
3828
3829 return 1;
3830}
3831
9ea033b2 3832static int
2cf0635d 3833get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 3834{
2cf0635d
NC
3835 Elf64_External_Shdr * shdrs;
3836 Elf_Internal_Shdr * internal;
b34976b6 3837 unsigned int i;
9ea033b2 3838
3f5e193b
NC
3839 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3840 elf_header.e_shentsize, num,
3841 _("section headers"));
a6e9f9df
AM
3842 if (!shdrs)
3843 return 0;
9ea033b2 3844
3f5e193b
NC
3845 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3846 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
3847
3848 if (section_headers == NULL)
3849 {
3850 error (_("Out of memory\n"));
3851 return 0;
3852 }
3853
3854 for (i = 0, internal = section_headers;
560f3c1c 3855 i < num;
b34976b6 3856 i++, internal++)
9ea033b2
NC
3857 {
3858 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3859 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
3860 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3861 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3862 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3863 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
3864 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3865 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3866 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3867 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3868 }
3869
3870 free (shdrs);
3871
3872 return 1;
3873}
3874
252b5132 3875static Elf_Internal_Sym *
2cf0635d 3876get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
252b5132 3877{
9ad5cbcf 3878 unsigned long number;
2cf0635d
NC
3879 Elf32_External_Sym * esyms;
3880 Elf_External_Sym_Shndx * shndx;
3881 Elf_Internal_Sym * isyms;
3882 Elf_Internal_Sym * psym;
b34976b6 3883 unsigned int j;
252b5132 3884
3f5e193b
NC
3885 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
3886 section->sh_size, _("symbols"));
a6e9f9df
AM
3887 if (!esyms)
3888 return NULL;
252b5132 3889
9ad5cbcf
AM
3890 shndx = NULL;
3891 if (symtab_shndx_hdr != NULL
3892 && (symtab_shndx_hdr->sh_link
4fbb74a6 3893 == (unsigned long) (section - section_headers)))
9ad5cbcf 3894 {
3f5e193b
NC
3895 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
3896 symtab_shndx_hdr->sh_offset,
3897 1, symtab_shndx_hdr->sh_size,
3898 _("symtab shndx"));
9ad5cbcf
AM
3899 if (!shndx)
3900 {
3901 free (esyms);
3902 return NULL;
3903 }
3904 }
3905
3906 number = section->sh_size / section->sh_entsize;
3f5e193b 3907 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
3908
3909 if (isyms == NULL)
3910 {
3911 error (_("Out of memory\n"));
9ad5cbcf
AM
3912 if (shndx)
3913 free (shndx);
252b5132 3914 free (esyms);
252b5132
RH
3915 return NULL;
3916 }
3917
3918 for (j = 0, psym = isyms;
3919 j < number;
b34976b6 3920 j++, psym++)
252b5132
RH
3921 {
3922 psym->st_name = BYTE_GET (esyms[j].st_name);
3923 psym->st_value = BYTE_GET (esyms[j].st_value);
3924 psym->st_size = BYTE_GET (esyms[j].st_size);
3925 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 3926 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
3927 psym->st_shndx
3928 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
3929 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
3930 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
3931 psym->st_info = BYTE_GET (esyms[j].st_info);
3932 psym->st_other = BYTE_GET (esyms[j].st_other);
3933 }
3934
9ad5cbcf
AM
3935 if (shndx)
3936 free (shndx);
252b5132
RH
3937 free (esyms);
3938
3939 return isyms;
3940}
3941
9ea033b2 3942static Elf_Internal_Sym *
2cf0635d 3943get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
9ea033b2 3944{
9ad5cbcf 3945 unsigned long number;
2cf0635d
NC
3946 Elf64_External_Sym * esyms;
3947 Elf_External_Sym_Shndx * shndx;
3948 Elf_Internal_Sym * isyms;
3949 Elf_Internal_Sym * psym;
b34976b6 3950 unsigned int j;
9ea033b2 3951
3f5e193b
NC
3952 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
3953 section->sh_size, _("symbols"));
a6e9f9df
AM
3954 if (!esyms)
3955 return NULL;
9ea033b2 3956
9ad5cbcf
AM
3957 shndx = NULL;
3958 if (symtab_shndx_hdr != NULL
3959 && (symtab_shndx_hdr->sh_link
4fbb74a6 3960 == (unsigned long) (section - section_headers)))
9ad5cbcf 3961 {
3f5e193b
NC
3962 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
3963 symtab_shndx_hdr->sh_offset,
3964 1, symtab_shndx_hdr->sh_size,
3965 _("symtab shndx"));
9ad5cbcf
AM
3966 if (!shndx)
3967 {
3968 free (esyms);
3969 return NULL;
3970 }
3971 }
3972
3973 number = section->sh_size / section->sh_entsize;
3f5e193b 3974 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
3975
3976 if (isyms == NULL)
3977 {
3978 error (_("Out of memory\n"));
9ad5cbcf
AM
3979 if (shndx)
3980 free (shndx);
9ea033b2 3981 free (esyms);
9ea033b2
NC
3982 return NULL;
3983 }
3984
3985 for (j = 0, psym = isyms;
3986 j < number;
b34976b6 3987 j++, psym++)
9ea033b2
NC
3988 {
3989 psym->st_name = BYTE_GET (esyms[j].st_name);
3990 psym->st_info = BYTE_GET (esyms[j].st_info);
3991 psym->st_other = BYTE_GET (esyms[j].st_other);
3992 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 3993 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
3994 psym->st_shndx
3995 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
3996 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
3997 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
66543521
AM
3998 psym->st_value = BYTE_GET (esyms[j].st_value);
3999 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4000 }
4001
9ad5cbcf
AM
4002 if (shndx)
4003 free (shndx);
9ea033b2
NC
4004 free (esyms);
4005
4006 return isyms;
4007}
4008
d1133906 4009static const char *
d3ba0551 4010get_elf_section_flags (bfd_vma sh_flags)
d1133906 4011{
5477e8a0 4012 static char buff[1024];
2cf0635d 4013 char * p = buff;
8d5ff12c 4014 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4015 int sindex;
4016 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4017 bfd_vma os_flags = 0;
4018 bfd_vma proc_flags = 0;
4019 bfd_vma unknown_flags = 0;
148b93f2 4020 static const struct
5477e8a0 4021 {
2cf0635d 4022 const char * str;
5477e8a0
L
4023 int len;
4024 }
4025 flags [] =
4026 {
cfcac11d
NC
4027 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4028 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4029 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4030 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4031 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4032 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4033 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4034 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4035 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4036 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4037 /* IA-64 specific. */
4038 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4039 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4040 /* IA-64 OpenVMS specific. */
4041 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4042 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4043 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4044 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4045 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4046 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
4047 /* SPARC specific. */
4048 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
4049 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4050 };
4051
4052 if (do_section_details)
4053 {
8d5ff12c
L
4054 sprintf (buff, "[%*.*lx]: ",
4055 field_size, field_size, (unsigned long) sh_flags);
4056 p += field_size + 4;
5477e8a0 4057 }
76da6bbe 4058
d1133906
NC
4059 while (sh_flags)
4060 {
4061 bfd_vma flag;
4062
4063 flag = sh_flags & - sh_flags;
4064 sh_flags &= ~ flag;
76da6bbe 4065
5477e8a0 4066 if (do_section_details)
d1133906 4067 {
5477e8a0
L
4068 switch (flag)
4069 {
91d6fa6a
NC
4070 case SHF_WRITE: sindex = 0; break;
4071 case SHF_ALLOC: sindex = 1; break;
4072 case SHF_EXECINSTR: sindex = 2; break;
4073 case SHF_MERGE: sindex = 3; break;
4074 case SHF_STRINGS: sindex = 4; break;
4075 case SHF_INFO_LINK: sindex = 5; break;
4076 case SHF_LINK_ORDER: sindex = 6; break;
4077 case SHF_OS_NONCONFORMING: sindex = 7; break;
4078 case SHF_GROUP: sindex = 8; break;
4079 case SHF_TLS: sindex = 9; break;
76da6bbe 4080
5477e8a0 4081 default:
91d6fa6a 4082 sindex = -1;
cfcac11d 4083 switch (elf_header.e_machine)
148b93f2 4084 {
cfcac11d 4085 case EM_IA_64:
148b93f2 4086 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4087 sindex = 10;
148b93f2 4088 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4089 sindex = 11;
148b93f2
NC
4090#ifdef BFD64
4091 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4092 switch (flag)
4093 {
91d6fa6a
NC
4094 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4095 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4096 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4097 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4098 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4099 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4100 default: break;
4101 }
4102#endif
cfcac11d
NC
4103 break;
4104
caa83f8b
NC
4105 case EM_386:
4106 case EM_486:
4107 case EM_X86_64:
cfcac11d
NC
4108 case EM_OLD_SPARCV9:
4109 case EM_SPARC32PLUS:
4110 case EM_SPARCV9:
4111 case EM_SPARC:
4112 if (flag == SHF_EXCLUDE)
91d6fa6a 4113 sindex = 18;
cfcac11d 4114 else if (flag == SHF_ORDERED)
91d6fa6a 4115 sindex = 19;
cfcac11d
NC
4116 break;
4117 default:
4118 break;
148b93f2 4119 }
5477e8a0
L
4120 }
4121
91d6fa6a 4122 if (sindex != -1)
5477e8a0 4123 {
8d5ff12c
L
4124 if (p != buff + field_size + 4)
4125 {
4126 if (size < (10 + 2))
4127 abort ();
4128 size -= 2;
4129 *p++ = ',';
4130 *p++ = ' ';
4131 }
4132
91d6fa6a
NC
4133 size -= flags [sindex].len;
4134 p = stpcpy (p, flags [sindex].str);
5477e8a0 4135 }
3b22753a 4136 else if (flag & SHF_MASKOS)
8d5ff12c 4137 os_flags |= flag;
d1133906 4138 else if (flag & SHF_MASKPROC)
8d5ff12c 4139 proc_flags |= flag;
d1133906 4140 else
8d5ff12c 4141 unknown_flags |= flag;
5477e8a0
L
4142 }
4143 else
4144 {
4145 switch (flag)
4146 {
4147 case SHF_WRITE: *p = 'W'; break;
4148 case SHF_ALLOC: *p = 'A'; break;
4149 case SHF_EXECINSTR: *p = 'X'; break;
4150 case SHF_MERGE: *p = 'M'; break;
4151 case SHF_STRINGS: *p = 'S'; break;
4152 case SHF_INFO_LINK: *p = 'I'; break;
4153 case SHF_LINK_ORDER: *p = 'L'; break;
4154 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4155 case SHF_GROUP: *p = 'G'; break;
4156 case SHF_TLS: *p = 'T'; break;
4157
4158 default:
8a9036a4
L
4159 if ((elf_header.e_machine == EM_X86_64
4160 || elf_header.e_machine == EM_L1OM)
5477e8a0
L
4161 && flag == SHF_X86_64_LARGE)
4162 *p = 'l';
4163 else if (flag & SHF_MASKOS)
4164 {
4165 *p = 'o';
4166 sh_flags &= ~ SHF_MASKOS;
4167 }
4168 else if (flag & SHF_MASKPROC)
4169 {
4170 *p = 'p';
4171 sh_flags &= ~ SHF_MASKPROC;
4172 }
4173 else
4174 *p = 'x';
4175 break;
4176 }
4177 p++;
d1133906
NC
4178 }
4179 }
76da6bbe 4180
8d5ff12c
L
4181 if (do_section_details)
4182 {
4183 if (os_flags)
4184 {
4185 size -= 5 + field_size;
4186 if (p != buff + field_size + 4)
4187 {
4188 if (size < (2 + 1))
4189 abort ();
4190 size -= 2;
4191 *p++ = ',';
4192 *p++ = ' ';
4193 }
4194 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4195 (unsigned long) os_flags);
4196 p += 5 + field_size;
4197 }
4198 if (proc_flags)
4199 {
4200 size -= 7 + field_size;
4201 if (p != buff + field_size + 4)
4202 {
4203 if (size < (2 + 1))
4204 abort ();
4205 size -= 2;
4206 *p++ = ',';
4207 *p++ = ' ';
4208 }
4209 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4210 (unsigned long) proc_flags);
4211 p += 7 + field_size;
4212 }
4213 if (unknown_flags)
4214 {
4215 size -= 10 + field_size;
4216 if (p != buff + field_size + 4)
4217 {
4218 if (size < (2 + 1))
4219 abort ();
4220 size -= 2;
4221 *p++ = ',';
4222 *p++ = ' ';
4223 }
4224 sprintf (p, "UNKNOWN (%*.*lx)", field_size, field_size,
4225 (unsigned long) unknown_flags);
4226 p += 10 + field_size;
4227 }
4228 }
4229
e9e44622 4230 *p = '\0';
d1133906
NC
4231 return buff;
4232}
4233
252b5132 4234static int
2cf0635d 4235process_section_headers (FILE * file)
252b5132 4236{
2cf0635d 4237 Elf_Internal_Shdr * section;
b34976b6 4238 unsigned int i;
252b5132
RH
4239
4240 section_headers = NULL;
4241
4242 if (elf_header.e_shnum == 0)
4243 {
4244 if (do_sections)
4245 printf (_("\nThere are no sections in this file.\n"));
4246
4247 return 1;
4248 }
4249
4250 if (do_sections && !do_header)
9ea033b2 4251 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4252 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4253
9ea033b2
NC
4254 if (is_32bit_elf)
4255 {
560f3c1c 4256 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4257 return 0;
4258 }
560f3c1c 4259 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4260 return 0;
4261
4262 /* Read in the string table, so that we have names to display. */
0b49d371 4263 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4264 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4265 {
4fbb74a6 4266 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4267
c256ffe7
JJ
4268 if (section->sh_size != 0)
4269 {
3f5e193b
NC
4270 string_table = (char *) get_data (NULL, file, section->sh_offset,
4271 1, section->sh_size,
4272 _("string table"));
0de14b54 4273
c256ffe7
JJ
4274 string_table_length = string_table != NULL ? section->sh_size : 0;
4275 }
252b5132
RH
4276 }
4277
4278 /* Scan the sections for the dynamic symbol table
e3c8793a 4279 and dynamic string table and debug sections. */
252b5132
RH
4280 dynamic_symbols = NULL;
4281 dynamic_strings = NULL;
4282 dynamic_syminfo = NULL;
f1ef08cb 4283 symtab_shndx_hdr = NULL;
103f02d3 4284
89fac5e3
RS
4285 eh_addr_size = is_32bit_elf ? 4 : 8;
4286 switch (elf_header.e_machine)
4287 {
4288 case EM_MIPS:
4289 case EM_MIPS_RS3_LE:
4290 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4291 FDE addresses. However, the ABI also has a semi-official ILP32
4292 variant for which the normal FDE address size rules apply.
4293
4294 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4295 section, where XX is the size of longs in bits. Unfortunately,
4296 earlier compilers provided no way of distinguishing ILP32 objects
4297 from LP64 objects, so if there's any doubt, we should assume that
4298 the official LP64 form is being used. */
4299 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4300 && find_section (".gcc_compiled_long32") == NULL)
4301 eh_addr_size = 8;
4302 break;
0f56a26a
DD
4303
4304 case EM_H8_300:
4305 case EM_H8_300H:
4306 switch (elf_header.e_flags & EF_H8_MACH)
4307 {
4308 case E_H8_MACH_H8300:
4309 case E_H8_MACH_H8300HN:
4310 case E_H8_MACH_H8300SN:
4311 case E_H8_MACH_H8300SXN:
4312 eh_addr_size = 2;
4313 break;
4314 case E_H8_MACH_H8300H:
4315 case E_H8_MACH_H8300S:
4316 case E_H8_MACH_H8300SX:
4317 eh_addr_size = 4;
4318 break;
4319 }
f4236fe4
DD
4320 break;
4321
ff7eeb89 4322 case EM_M32C_OLD:
f4236fe4
DD
4323 case EM_M32C:
4324 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4325 {
4326 case EF_M32C_CPU_M16C:
4327 eh_addr_size = 2;
4328 break;
4329 }
4330 break;
89fac5e3
RS
4331 }
4332
08d8fa11
JJ
4333#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4334 do \
4335 { \
4336 size_t expected_entsize \
4337 = is_32bit_elf ? size32 : size64; \
4338 if (section->sh_entsize != expected_entsize) \
4339 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4340 i, (unsigned long int) section->sh_entsize, \
4341 (unsigned long int) expected_entsize); \
4342 section->sh_entsize = expected_entsize; \
4343 } \
4344 while (0)
4345#define CHECK_ENTSIZE(section, i, type) \
4346 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4347 sizeof (Elf64_External_##type))
4348
252b5132
RH
4349 for (i = 0, section = section_headers;
4350 i < elf_header.e_shnum;
b34976b6 4351 i++, section++)
252b5132 4352 {
2cf0635d 4353 char * name = SECTION_NAME (section);
252b5132
RH
4354
4355 if (section->sh_type == SHT_DYNSYM)
4356 {
4357 if (dynamic_symbols != NULL)
4358 {
4359 error (_("File contains multiple dynamic symbol tables\n"));
4360 continue;
4361 }
4362
08d8fa11 4363 CHECK_ENTSIZE (section, i, Sym);
19936277 4364 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4365 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4366 }
4367 else if (section->sh_type == SHT_STRTAB
18bd398b 4368 && streq (name, ".dynstr"))
252b5132
RH
4369 {
4370 if (dynamic_strings != NULL)
4371 {
4372 error (_("File contains multiple dynamic string tables\n"));
4373 continue;
4374 }
4375
3f5e193b
NC
4376 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4377 1, section->sh_size,
4378 _("dynamic strings"));
d79b3d50 4379 dynamic_strings_length = section->sh_size;
252b5132 4380 }
9ad5cbcf
AM
4381 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4382 {
4383 if (symtab_shndx_hdr != NULL)
4384 {
4385 error (_("File contains multiple symtab shndx tables\n"));
4386 continue;
4387 }
4388 symtab_shndx_hdr = section;
4389 }
08d8fa11
JJ
4390 else if (section->sh_type == SHT_SYMTAB)
4391 CHECK_ENTSIZE (section, i, Sym);
4392 else if (section->sh_type == SHT_GROUP)
4393 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4394 else if (section->sh_type == SHT_REL)
4395 CHECK_ENTSIZE (section, i, Rel);
4396 else if (section->sh_type == SHT_RELA)
4397 CHECK_ENTSIZE (section, i, Rela);
252b5132 4398 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4399 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4400 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4401 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4402 && (const_strneq (name, ".debug_")
4403 || const_strneq (name, ".zdebug_")))
252b5132 4404 {
1b315056
CS
4405 if (name[1] == 'z')
4406 name += sizeof (".zdebug_") - 1;
4407 else
4408 name += sizeof (".debug_") - 1;
252b5132
RH
4409
4410 if (do_debugging
18bd398b 4411 || (do_debug_info && streq (name, "info"))
2b6f5997 4412 || (do_debug_info && streq (name, "types"))
18bd398b 4413 || (do_debug_abbrevs && streq (name, "abbrev"))
4cb93e3b 4414 || (do_debug_lines && streq (name, "line"))
18bd398b 4415 || (do_debug_pubnames && streq (name, "pubnames"))
f9f0e732 4416 || (do_debug_pubtypes && streq (name, "pubtypes"))
18bd398b
NC
4417 || (do_debug_aranges && streq (name, "aranges"))
4418 || (do_debug_ranges && streq (name, "ranges"))
4419 || (do_debug_frames && streq (name, "frame"))
4420 || (do_debug_macinfo && streq (name, "macinfo"))
4421 || (do_debug_str && streq (name, "str"))
4422 || (do_debug_loc && streq (name, "loc"))
252b5132 4423 )
09c11c86 4424 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4425 }
a262ae96 4426 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4427 else if ((do_debugging || do_debug_info)
0112cd26 4428 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4429 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4430 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4431 request_dump_bynumber (i, DEBUG_DUMP);
252b5132
RH
4432 }
4433
4434 if (! do_sections)
4435 return 1;
4436
3a1a2036
NC
4437 if (elf_header.e_shnum > 1)
4438 printf (_("\nSection Headers:\n"));
4439 else
4440 printf (_("\nSection Header:\n"));
76da6bbe 4441
f7a99963 4442 if (is_32bit_elf)
595cf52e 4443 {
5477e8a0 4444 if (do_section_details)
595cf52e
L
4445 {
4446 printf (_(" [Nr] Name\n"));
5477e8a0 4447 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4448 }
4449 else
4450 printf
4451 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4452 }
d974e256 4453 else if (do_wide)
595cf52e 4454 {
5477e8a0 4455 if (do_section_details)
595cf52e
L
4456 {
4457 printf (_(" [Nr] Name\n"));
5477e8a0 4458 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4459 }
4460 else
4461 printf
4462 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4463 }
f7a99963
NC
4464 else
4465 {
5477e8a0 4466 if (do_section_details)
595cf52e
L
4467 {
4468 printf (_(" [Nr] Name\n"));
5477e8a0
L
4469 printf (_(" Type Address Offset Link\n"));
4470 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4471 }
4472 else
4473 {
4474 printf (_(" [Nr] Name Type Address Offset\n"));
4475 printf (_(" Size EntSize Flags Link Info Align\n"));
4476 }
f7a99963 4477 }
252b5132 4478
5477e8a0
L
4479 if (do_section_details)
4480 printf (_(" Flags\n"));
4481
252b5132
RH
4482 for (i = 0, section = section_headers;
4483 i < elf_header.e_shnum;
b34976b6 4484 i++, section++)
252b5132 4485 {
5477e8a0 4486 if (do_section_details)
595cf52e
L
4487 {
4488 printf (" [%2u] %s\n",
4fbb74a6 4489 i,
595cf52e
L
4490 SECTION_NAME (section));
4491 if (is_32bit_elf || do_wide)
4492 printf (" %-15.15s ",
4493 get_section_type_name (section->sh_type));
4494 }
4495 else
b9eb56c1
NC
4496 printf ((do_wide ? " [%2u] %-17s %-15s "
4497 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4498 i,
595cf52e
L
4499 SECTION_NAME (section),
4500 get_section_type_name (section->sh_type));
252b5132 4501
f7a99963
NC
4502 if (is_32bit_elf)
4503 {
cfcac11d
NC
4504 const char * link_too_big = NULL;
4505
f7a99963 4506 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4507
f7a99963
NC
4508 printf ( " %6.6lx %6.6lx %2.2lx",
4509 (unsigned long) section->sh_offset,
4510 (unsigned long) section->sh_size,
4511 (unsigned long) section->sh_entsize);
d1133906 4512
5477e8a0
L
4513 if (do_section_details)
4514 fputs (" ", stdout);
4515 else
4516 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4517
cfcac11d
NC
4518 if (section->sh_link >= elf_header.e_shnum)
4519 {
4520 link_too_big = "";
4521 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4522 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4523 switch (elf_header.e_machine)
4524 {
caa83f8b
NC
4525 case EM_386:
4526 case EM_486:
4527 case EM_X86_64:
cfcac11d
NC
4528 case EM_OLD_SPARCV9:
4529 case EM_SPARC32PLUS:
4530 case EM_SPARCV9:
4531 case EM_SPARC:
4532 if (section->sh_link == (SHN_BEFORE & 0xffff))
4533 link_too_big = "BEFORE";
4534 else if (section->sh_link == (SHN_AFTER & 0xffff))
4535 link_too_big = "AFTER";
4536 break;
4537 default:
4538 break;
4539 }
4540 }
4541
4542 if (do_section_details)
4543 {
4544 if (link_too_big != NULL && * link_too_big)
4545 printf ("<%s> ", link_too_big);
4546 else
4547 printf ("%2u ", section->sh_link);
4548 printf ("%3u %2lu\n", section->sh_info,
4549 (unsigned long) section->sh_addralign);
4550 }
4551 else
4552 printf ("%2u %3u %2lu\n",
4553 section->sh_link,
4554 section->sh_info,
4555 (unsigned long) section->sh_addralign);
4556
4557 if (link_too_big && ! * link_too_big)
4558 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4559 i, section->sh_link);
f7a99963 4560 }
d974e256
JJ
4561 else if (do_wide)
4562 {
4563 print_vma (section->sh_addr, LONG_HEX);
4564
4565 if ((long) section->sh_offset == section->sh_offset)
4566 printf (" %6.6lx", (unsigned long) section->sh_offset);
4567 else
4568 {
4569 putchar (' ');
4570 print_vma (section->sh_offset, LONG_HEX);
4571 }
4572
4573 if ((unsigned long) section->sh_size == section->sh_size)
4574 printf (" %6.6lx", (unsigned long) section->sh_size);
4575 else
4576 {
4577 putchar (' ');
4578 print_vma (section->sh_size, LONG_HEX);
4579 }
4580
4581 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4582 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4583 else
4584 {
4585 putchar (' ');
4586 print_vma (section->sh_entsize, LONG_HEX);
4587 }
4588
5477e8a0
L
4589 if (do_section_details)
4590 fputs (" ", stdout);
4591 else
4592 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4593
72de5009 4594 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4595
4596 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4597 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4598 else
4599 {
4600 print_vma (section->sh_addralign, DEC);
4601 putchar ('\n');
4602 }
4603 }
5477e8a0 4604 else if (do_section_details)
595cf52e 4605 {
5477e8a0 4606 printf (" %-15.15s ",
595cf52e 4607 get_section_type_name (section->sh_type));
595cf52e
L
4608 print_vma (section->sh_addr, LONG_HEX);
4609 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4610 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4611 else
4612 {
4613 printf (" ");
4614 print_vma (section->sh_offset, LONG_HEX);
4615 }
72de5009 4616 printf (" %u\n ", section->sh_link);
595cf52e 4617 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4618 putchar (' ');
595cf52e
L
4619 print_vma (section->sh_entsize, LONG_HEX);
4620
72de5009
AM
4621 printf (" %-16u %lu\n",
4622 section->sh_info,
595cf52e
L
4623 (unsigned long) section->sh_addralign);
4624 }
f7a99963
NC
4625 else
4626 {
4627 putchar (' ');
4628 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4629 if ((long) section->sh_offset == section->sh_offset)
4630 printf (" %8.8lx", (unsigned long) section->sh_offset);
4631 else
4632 {
4633 printf (" ");
4634 print_vma (section->sh_offset, LONG_HEX);
4635 }
f7a99963
NC
4636 printf ("\n ");
4637 print_vma (section->sh_size, LONG_HEX);
4638 printf (" ");
4639 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4640
d1133906 4641 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4642
72de5009
AM
4643 printf (" %2u %3u %lu\n",
4644 section->sh_link,
4645 section->sh_info,
f7a99963
NC
4646 (unsigned long) section->sh_addralign);
4647 }
5477e8a0
L
4648
4649 if (do_section_details)
4650 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4651 }
4652
5477e8a0
L
4653 if (!do_section_details)
4654 printf (_("Key to Flags:\n\
e3c8793a
NC
4655 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
4656 I (info), L (link order), G (group), x (unknown)\n\
4657 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 4658
252b5132
RH
4659 return 1;
4660}
4661
f5842774
L
4662static const char *
4663get_group_flags (unsigned int flags)
4664{
4665 static char buff[32];
4666 switch (flags)
4667 {
220453ec
AM
4668 case 0:
4669 return "";
4670
f5842774 4671 case GRP_COMDAT:
220453ec 4672 return "COMDAT ";
f5842774
L
4673
4674 default:
220453ec 4675 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
4676 break;
4677 }
4678 return buff;
4679}
4680
4681static int
2cf0635d 4682process_section_groups (FILE * file)
f5842774 4683{
2cf0635d 4684 Elf_Internal_Shdr * section;
f5842774 4685 unsigned int i;
2cf0635d
NC
4686 struct group * group;
4687 Elf_Internal_Shdr * symtab_sec;
4688 Elf_Internal_Shdr * strtab_sec;
4689 Elf_Internal_Sym * symtab;
4690 char * strtab;
c256ffe7 4691 size_t strtab_size;
d1f5c6e3
L
4692
4693 /* Don't process section groups unless needed. */
4694 if (!do_unwind && !do_section_groups)
4695 return 1;
f5842774
L
4696
4697 if (elf_header.e_shnum == 0)
4698 {
4699 if (do_section_groups)
d1f5c6e3 4700 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
4701
4702 return 1;
4703 }
4704
4705 if (section_headers == NULL)
4706 {
4707 error (_("Section headers are not available!\n"));
4708 abort ();
4709 }
4710
3f5e193b
NC
4711 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
4712 sizeof (struct group *));
e4b17d5c
L
4713
4714 if (section_headers_groups == NULL)
4715 {
4716 error (_("Out of memory\n"));
4717 return 0;
4718 }
4719
f5842774 4720 /* Scan the sections for the group section. */
d1f5c6e3 4721 group_count = 0;
f5842774
L
4722 for (i = 0, section = section_headers;
4723 i < elf_header.e_shnum;
4724 i++, section++)
e4b17d5c
L
4725 if (section->sh_type == SHT_GROUP)
4726 group_count++;
4727
d1f5c6e3
L
4728 if (group_count == 0)
4729 {
4730 if (do_section_groups)
4731 printf (_("\nThere are no section groups in this file.\n"));
4732
4733 return 1;
4734 }
4735
3f5e193b 4736 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
4737
4738 if (section_groups == NULL)
4739 {
4740 error (_("Out of memory\n"));
4741 return 0;
4742 }
4743
d1f5c6e3
L
4744 symtab_sec = NULL;
4745 strtab_sec = NULL;
4746 symtab = NULL;
4747 strtab = NULL;
c256ffe7 4748 strtab_size = 0;
e4b17d5c
L
4749 for (i = 0, section = section_headers, group = section_groups;
4750 i < elf_header.e_shnum;
4751 i++, section++)
f5842774
L
4752 {
4753 if (section->sh_type == SHT_GROUP)
4754 {
2cf0635d
NC
4755 char * name = SECTION_NAME (section);
4756 char * group_name;
4757 unsigned char * start;
4758 unsigned char * indices;
f5842774 4759 unsigned int entry, j, size;
2cf0635d
NC
4760 Elf_Internal_Shdr * sec;
4761 Elf_Internal_Sym * sym;
f5842774
L
4762
4763 /* Get the symbol table. */
4fbb74a6
AM
4764 if (section->sh_link >= elf_header.e_shnum
4765 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 4766 != SHT_SYMTAB))
f5842774
L
4767 {
4768 error (_("Bad sh_link in group section `%s'\n"), name);
4769 continue;
4770 }
d1f5c6e3
L
4771
4772 if (symtab_sec != sec)
4773 {
4774 symtab_sec = sec;
4775 if (symtab)
4776 free (symtab);
4777 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4778 }
f5842774
L
4779
4780 sym = symtab + section->sh_info;
4781
4782 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4783 {
4fbb74a6
AM
4784 if (sym->st_shndx == 0
4785 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
4786 {
4787 error (_("Bad sh_info in group section `%s'\n"), name);
4788 continue;
4789 }
ba2685cc 4790
4fbb74a6 4791 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
4792 strtab_sec = NULL;
4793 if (strtab)
4794 free (strtab);
f5842774 4795 strtab = NULL;
c256ffe7 4796 strtab_size = 0;
f5842774
L
4797 }
4798 else
4799 {
4800 /* Get the string table. */
4fbb74a6 4801 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
4802 {
4803 strtab_sec = NULL;
4804 if (strtab)
4805 free (strtab);
4806 strtab = NULL;
4807 strtab_size = 0;
4808 }
4809 else if (strtab_sec
4fbb74a6 4810 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
4811 {
4812 strtab_sec = sec;
4813 if (strtab)
4814 free (strtab);
3f5e193b
NC
4815 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
4816 1, strtab_sec->sh_size,
4817 _("string table"));
c256ffe7 4818 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 4819 }
c256ffe7
JJ
4820 group_name = sym->st_name < strtab_size
4821 ? strtab + sym->st_name : "<corrupt>";
f5842774
L
4822 }
4823
3f5e193b
NC
4824 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
4825 1, section->sh_size,
4826 _("section data"));
f5842774
L
4827
4828 indices = start;
4829 size = (section->sh_size / section->sh_entsize) - 1;
4830 entry = byte_get (indices, 4);
4831 indices += 4;
e4b17d5c
L
4832
4833 if (do_section_groups)
4834 {
220453ec 4835 printf ("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n",
391cb864 4836 get_group_flags (entry), i, name, group_name, size);
ba2685cc 4837
e4b17d5c
L
4838 printf (_(" [Index] Name\n"));
4839 }
4840
4841 group->group_index = i;
4842
f5842774
L
4843 for (j = 0; j < size; j++)
4844 {
2cf0635d 4845 struct group_list * g;
e4b17d5c 4846
f5842774
L
4847 entry = byte_get (indices, 4);
4848 indices += 4;
4849
4fbb74a6 4850 if (entry >= elf_header.e_shnum)
391cb864
L
4851 {
4852 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
4853 entry, i, elf_header.e_shnum - 1);
4854 continue;
4855 }
391cb864 4856
4fbb74a6 4857 if (section_headers_groups [entry] != NULL)
e4b17d5c 4858 {
d1f5c6e3
L
4859 if (entry)
4860 {
391cb864
L
4861 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
4862 entry, i,
4fbb74a6 4863 section_headers_groups [entry]->group_index);
d1f5c6e3
L
4864 continue;
4865 }
4866 else
4867 {
4868 /* Intel C/C++ compiler may put section 0 in a
4869 section group. We just warn it the first time
4870 and ignore it afterwards. */
4871 static int warned = 0;
4872 if (!warned)
4873 {
4874 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 4875 section_headers_groups [entry]->group_index);
d1f5c6e3
L
4876 warned++;
4877 }
4878 }
e4b17d5c
L
4879 }
4880
4fbb74a6 4881 section_headers_groups [entry] = group;
e4b17d5c
L
4882
4883 if (do_section_groups)
4884 {
4fbb74a6 4885 sec = section_headers + entry;
c256ffe7 4886 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
4887 }
4888
3f5e193b 4889 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
4890 g->section_index = entry;
4891 g->next = group->root;
4892 group->root = g;
f5842774
L
4893 }
4894
f5842774
L
4895 if (start)
4896 free (start);
e4b17d5c
L
4897
4898 group++;
f5842774
L
4899 }
4900 }
4901
d1f5c6e3
L
4902 if (symtab)
4903 free (symtab);
4904 if (strtab)
4905 free (strtab);
f5842774
L
4906 return 1;
4907}
4908
85b1c36d 4909static struct
566b0d53 4910{
2cf0635d 4911 const char * name;
566b0d53
L
4912 int reloc;
4913 int size;
4914 int rela;
4915} dynamic_relocations [] =
4916{
4917 { "REL", DT_REL, DT_RELSZ, FALSE },
4918 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4919 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4920};
4921
252b5132 4922/* Process the reloc section. */
18bd398b 4923
252b5132 4924static int
2cf0635d 4925process_relocs (FILE * file)
252b5132 4926{
b34976b6
AM
4927 unsigned long rel_size;
4928 unsigned long rel_offset;
252b5132
RH
4929
4930
4931 if (!do_reloc)
4932 return 1;
4933
4934 if (do_using_dynamic)
4935 {
566b0d53 4936 int is_rela;
2cf0635d 4937 const char * name;
566b0d53
L
4938 int has_dynamic_reloc;
4939 unsigned int i;
0de14b54 4940
566b0d53 4941 has_dynamic_reloc = 0;
252b5132 4942
566b0d53 4943 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4944 {
566b0d53
L
4945 is_rela = dynamic_relocations [i].rela;
4946 name = dynamic_relocations [i].name;
4947 rel_size = dynamic_info [dynamic_relocations [i].size];
4948 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4949
566b0d53
L
4950 has_dynamic_reloc |= rel_size;
4951
4952 if (is_rela == UNKNOWN)
aa903cfb 4953 {
566b0d53
L
4954 if (dynamic_relocations [i].reloc == DT_JMPREL)
4955 switch (dynamic_info[DT_PLTREL])
4956 {
4957 case DT_REL:
4958 is_rela = FALSE;
4959 break;
4960 case DT_RELA:
4961 is_rela = TRUE;
4962 break;
4963 }
aa903cfb 4964 }
252b5132 4965
566b0d53
L
4966 if (rel_size)
4967 {
4968 printf
4969 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4970 name, rel_offset, rel_size);
252b5132 4971
d93f0186
NC
4972 dump_relocations (file,
4973 offset_from_vma (file, rel_offset, rel_size),
4974 rel_size,
566b0d53 4975 dynamic_symbols, num_dynamic_syms,
d79b3d50 4976 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 4977 }
252b5132 4978 }
566b0d53
L
4979
4980 if (! has_dynamic_reloc)
252b5132
RH
4981 printf (_("\nThere are no dynamic relocations in this file.\n"));
4982 }
4983 else
4984 {
2cf0635d 4985 Elf_Internal_Shdr * section;
b34976b6
AM
4986 unsigned long i;
4987 int found = 0;
252b5132
RH
4988
4989 for (i = 0, section = section_headers;
4990 i < elf_header.e_shnum;
b34976b6 4991 i++, section++)
252b5132
RH
4992 {
4993 if ( section->sh_type != SHT_RELA
4994 && section->sh_type != SHT_REL)
4995 continue;
4996
4997 rel_offset = section->sh_offset;
4998 rel_size = section->sh_size;
4999
5000 if (rel_size)
5001 {
2cf0635d 5002 Elf_Internal_Shdr * strsec;
b34976b6 5003 int is_rela;
103f02d3 5004
252b5132
RH
5005 printf (_("\nRelocation section "));
5006
5007 if (string_table == NULL)
19936277 5008 printf ("%d", section->sh_name);
252b5132 5009 else
3a1a2036 5010 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
5011
5012 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5013 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5014
d79b3d50
NC
5015 is_rela = section->sh_type == SHT_RELA;
5016
4fbb74a6
AM
5017 if (section->sh_link != 0
5018 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5019 {
2cf0635d
NC
5020 Elf_Internal_Shdr * symsec;
5021 Elf_Internal_Sym * symtab;
d79b3d50 5022 unsigned long nsyms;
c256ffe7 5023 unsigned long strtablen = 0;
2cf0635d 5024 char * strtab = NULL;
57346661 5025
4fbb74a6 5026 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5027 if (symsec->sh_type != SHT_SYMTAB
5028 && symsec->sh_type != SHT_DYNSYM)
5029 continue;
5030
af3fc3bc 5031 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 5032 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 5033
af3fc3bc
AM
5034 if (symtab == NULL)
5035 continue;
252b5132 5036
4fbb74a6
AM
5037 if (symsec->sh_link != 0
5038 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5039 {
4fbb74a6 5040 strsec = section_headers + symsec->sh_link;
103f02d3 5041
3f5e193b
NC
5042 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5043 1, strsec->sh_size,
5044 _("string table"));
c256ffe7
JJ
5045 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5046 }
252b5132 5047
d79b3d50
NC
5048 dump_relocations (file, rel_offset, rel_size,
5049 symtab, nsyms, strtab, strtablen, is_rela);
5050 if (strtab)
5051 free (strtab);
5052 free (symtab);
5053 }
5054 else
5055 dump_relocations (file, rel_offset, rel_size,
5056 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5057
5058 found = 1;
5059 }
5060 }
5061
5062 if (! found)
5063 printf (_("\nThere are no relocations in this file.\n"));
5064 }
5065
5066 return 1;
5067}
5068
57346661
AM
5069/* Process the unwind section. */
5070
4d6ed7c8
NC
5071#include "unwind-ia64.h"
5072
5073/* An absolute address consists of a section and an offset. If the
5074 section is NULL, the offset itself is the address, otherwise, the
5075 address equals to LOAD_ADDRESS(section) + offset. */
5076
5077struct absaddr
5078 {
5079 unsigned short section;
5080 bfd_vma offset;
5081 };
5082
1949de15
L
5083#define ABSADDR(a) \
5084 ((a).section \
5085 ? section_headers [(a).section].sh_addr + (a).offset \
5086 : (a).offset)
5087
3f5e193b
NC
5088struct ia64_unw_table_entry
5089 {
5090 struct absaddr start;
5091 struct absaddr end;
5092 struct absaddr info;
5093 };
5094
57346661 5095struct ia64_unw_aux_info
4d6ed7c8 5096 {
3f5e193b
NC
5097
5098 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5099 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5100 unsigned char * info; /* Unwind info. */
b34976b6
AM
5101 unsigned long info_size; /* Size of unwind info. */
5102 bfd_vma info_addr; /* starting address of unwind info. */
5103 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5104 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5105 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5106 char * strtab; /* The string table. */
b34976b6 5107 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5108 };
5109
4d6ed7c8 5110static void
2cf0635d 5111find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5112 unsigned long nsyms,
2cf0635d 5113 const char * strtab,
57346661 5114 unsigned long strtab_size,
d3ba0551 5115 struct absaddr addr,
2cf0635d
NC
5116 const char ** symname,
5117 bfd_vma * offset)
4d6ed7c8 5118{
d3ba0551 5119 bfd_vma dist = 0x100000;
2cf0635d
NC
5120 Elf_Internal_Sym * sym;
5121 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5122 unsigned long i;
5123
0b6ae522
DJ
5124 REMOVE_ARCH_BITS (addr.offset);
5125
57346661 5126 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5127 {
0b6ae522
DJ
5128 bfd_vma value = sym->st_value;
5129
5130 REMOVE_ARCH_BITS (value);
5131
4d6ed7c8
NC
5132 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5133 && sym->st_name != 0
5134 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5135 && addr.offset >= value
5136 && addr.offset - value < dist)
4d6ed7c8
NC
5137 {
5138 best = sym;
0b6ae522 5139 dist = addr.offset - value;
4d6ed7c8
NC
5140 if (!dist)
5141 break;
5142 }
5143 }
5144 if (best)
5145 {
57346661
AM
5146 *symname = (best->st_name >= strtab_size
5147 ? "<corrupt>" : strtab + best->st_name);
4d6ed7c8
NC
5148 *offset = dist;
5149 return;
5150 }
5151 *symname = NULL;
5152 *offset = addr.offset;
5153}
5154
5155static void
2cf0635d 5156dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5157{
2cf0635d 5158 struct ia64_unw_table_entry * tp;
4d6ed7c8 5159 int in_body;
7036c0e1 5160
4d6ed7c8
NC
5161 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5162 {
5163 bfd_vma stamp;
5164 bfd_vma offset;
2cf0635d
NC
5165 const unsigned char * dp;
5166 const unsigned char * head;
5167 const char * procname;
4d6ed7c8 5168
57346661
AM
5169 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5170 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5171
5172 fputs ("\n<", stdout);
5173
5174 if (procname)
5175 {
5176 fputs (procname, stdout);
5177
5178 if (offset)
5179 printf ("+%lx", (unsigned long) offset);
5180 }
5181
5182 fputs (">: [", stdout);
5183 print_vma (tp->start.offset, PREFIX_HEX);
5184 fputc ('-', stdout);
5185 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5186 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5187 (unsigned long) (tp->info.offset - aux->seg_base));
5188
1949de15 5189 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5190 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5191
86f55779 5192 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5193 (unsigned) UNW_VER (stamp),
5194 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5195 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5196 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5197 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5198
5199 if (UNW_VER (stamp) != 1)
5200 {
5201 printf ("\tUnknown version.\n");
5202 continue;
5203 }
5204
5205 in_body = 0;
89fac5e3 5206 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5207 dp = unw_decode (dp, in_body, & in_body);
5208 }
5209}
5210
5211static int
2cf0635d
NC
5212slurp_ia64_unwind_table (FILE * file,
5213 struct ia64_unw_aux_info * aux,
5214 Elf_Internal_Shdr * sec)
4d6ed7c8 5215{
89fac5e3 5216 unsigned long size, nrelas, i;
2cf0635d
NC
5217 Elf_Internal_Phdr * seg;
5218 struct ia64_unw_table_entry * tep;
5219 Elf_Internal_Shdr * relsec;
5220 Elf_Internal_Rela * rela;
5221 Elf_Internal_Rela * rp;
5222 unsigned char * table;
5223 unsigned char * tp;
5224 Elf_Internal_Sym * sym;
5225 const char * relname;
4d6ed7c8 5226
4d6ed7c8
NC
5227 /* First, find the starting address of the segment that includes
5228 this section: */
5229
5230 if (elf_header.e_phnum)
5231 {
d93f0186 5232 if (! get_program_headers (file))
4d6ed7c8 5233 return 0;
4d6ed7c8 5234
d93f0186
NC
5235 for (seg = program_headers;
5236 seg < program_headers + elf_header.e_phnum;
5237 ++seg)
4d6ed7c8
NC
5238 {
5239 if (seg->p_type != PT_LOAD)
5240 continue;
5241
5242 if (sec->sh_addr >= seg->p_vaddr
5243 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5244 {
5245 aux->seg_base = seg->p_vaddr;
5246 break;
5247 }
5248 }
4d6ed7c8
NC
5249 }
5250
5251 /* Second, build the unwind table from the contents of the unwind section: */
5252 size = sec->sh_size;
3f5e193b
NC
5253 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5254 _("unwind table"));
a6e9f9df
AM
5255 if (!table)
5256 return 0;
4d6ed7c8 5257
3f5e193b
NC
5258 aux->table = (struct ia64_unw_table_entry *)
5259 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5260 tep = aux->table;
c6a0c689 5261 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5262 {
5263 tep->start.section = SHN_UNDEF;
5264 tep->end.section = SHN_UNDEF;
5265 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5266 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5267 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5268 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5269 tep->start.offset += aux->seg_base;
5270 tep->end.offset += aux->seg_base;
5271 tep->info.offset += aux->seg_base;
5272 }
5273 free (table);
5274
41e92641 5275 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5276 for (relsec = section_headers;
5277 relsec < section_headers + elf_header.e_shnum;
5278 ++relsec)
5279 {
5280 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5281 || relsec->sh_info >= elf_header.e_shnum
5282 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5283 continue;
5284
5285 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5286 & rela, & nrelas))
5287 return 0;
5288
5289 for (rp = rela; rp < rela + nrelas; ++rp)
5290 {
aca88567
NC
5291 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5292 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5293
0112cd26 5294 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5295 {
e5fb9629 5296 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5297 continue;
5298 }
5299
89fac5e3 5300 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5301
89fac5e3 5302 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5303 {
5304 case 0:
5305 aux->table[i].start.section = sym->st_shndx;
1ffa9a18 5306 aux->table[i].start.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5307 break;
5308 case 1:
5309 aux->table[i].end.section = sym->st_shndx;
1ffa9a18 5310 aux->table[i].end.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5311 break;
5312 case 2:
5313 aux->table[i].info.section = sym->st_shndx;
1ffa9a18 5314 aux->table[i].info.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5315 break;
5316 default:
5317 break;
5318 }
5319 }
5320
5321 free (rela);
5322 }
5323
89fac5e3 5324 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5325 return 1;
5326}
5327
5328static int
2cf0635d 5329ia64_process_unwind (FILE * file)
4d6ed7c8 5330{
2cf0635d
NC
5331 Elf_Internal_Shdr * sec;
5332 Elf_Internal_Shdr * unwsec = NULL;
5333 Elf_Internal_Shdr * strsec;
89fac5e3 5334 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5335 struct ia64_unw_aux_info aux;
f1467e33 5336
4d6ed7c8
NC
5337 memset (& aux, 0, sizeof (aux));
5338
4d6ed7c8
NC
5339 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5340 {
c256ffe7 5341 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5342 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5343 {
5344 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5345 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5346
4fbb74a6 5347 strsec = section_headers + sec->sh_link;
3f5e193b
NC
5348 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5349 1, strsec->sh_size,
5350 _("string table"));
c256ffe7 5351 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5352 }
5353 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5354 unwcount++;
5355 }
5356
5357 if (!unwcount)
5358 printf (_("\nThere are no unwind sections in this file.\n"));
5359
5360 while (unwcount-- > 0)
5361 {
2cf0635d 5362 char * suffix;
579f31ac
JJ
5363 size_t len, len2;
5364
5365 for (i = unwstart, sec = section_headers + unwstart;
5366 i < elf_header.e_shnum; ++i, ++sec)
5367 if (sec->sh_type == SHT_IA_64_UNWIND)
5368 {
5369 unwsec = sec;
5370 break;
5371 }
5372
5373 unwstart = i + 1;
5374 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5375
e4b17d5c
L
5376 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5377 {
5378 /* We need to find which section group it is in. */
2cf0635d 5379 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5380
5381 for (; g != NULL; g = g->next)
5382 {
4fbb74a6 5383 sec = section_headers + g->section_index;
18bd398b
NC
5384
5385 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5386 break;
e4b17d5c
L
5387 }
5388
5389 if (g == NULL)
5390 i = elf_header.e_shnum;
5391 }
18bd398b 5392 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5393 {
18bd398b 5394 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5395 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5396 suffix = SECTION_NAME (unwsec) + len;
5397 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5398 ++i, ++sec)
18bd398b
NC
5399 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5400 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5401 break;
5402 }
5403 else
5404 {
5405 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5406 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5407 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5408 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5409 suffix = "";
18bd398b 5410 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5411 suffix = SECTION_NAME (unwsec) + len;
5412 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5413 ++i, ++sec)
18bd398b
NC
5414 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5415 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5416 break;
5417 }
5418
5419 if (i == elf_header.e_shnum)
5420 {
5421 printf (_("\nCould not find unwind info section for "));
5422
5423 if (string_table == NULL)
5424 printf ("%d", unwsec->sh_name);
5425 else
3a1a2036 5426 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5427 }
5428 else
4d6ed7c8
NC
5429 {
5430 aux.info_size = sec->sh_size;
5431 aux.info_addr = sec->sh_addr;
3f5e193b
NC
5432 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
5433 aux.info_size,
5434 _("unwind info"));
4d6ed7c8 5435
579f31ac 5436 printf (_("\nUnwind section "));
4d6ed7c8 5437
579f31ac
JJ
5438 if (string_table == NULL)
5439 printf ("%d", unwsec->sh_name);
5440 else
3a1a2036 5441 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5442
579f31ac 5443 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5444 (unsigned long) unwsec->sh_offset,
89fac5e3 5445 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5446
579f31ac 5447 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5448
579f31ac
JJ
5449 if (aux.table_len > 0)
5450 dump_ia64_unwind (& aux);
5451
5452 if (aux.table)
5453 free ((char *) aux.table);
5454 if (aux.info)
5455 free ((char *) aux.info);
5456 aux.table = NULL;
5457 aux.info = NULL;
5458 }
4d6ed7c8 5459 }
4d6ed7c8 5460
4d6ed7c8
NC
5461 if (aux.symtab)
5462 free (aux.symtab);
5463 if (aux.strtab)
5464 free ((char *) aux.strtab);
5465
5466 return 1;
5467}
5468
3f5e193b
NC
5469struct hppa_unw_table_entry
5470 {
5471 struct absaddr start;
5472 struct absaddr end;
5473 unsigned int Cannot_unwind:1; /* 0 */
5474 unsigned int Millicode:1; /* 1 */
5475 unsigned int Millicode_save_sr0:1; /* 2 */
5476 unsigned int Region_description:2; /* 3..4 */
5477 unsigned int reserved1:1; /* 5 */
5478 unsigned int Entry_SR:1; /* 6 */
5479 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5480 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5481 unsigned int Args_stored:1; /* 16 */
5482 unsigned int Variable_Frame:1; /* 17 */
5483 unsigned int Separate_Package_Body:1; /* 18 */
5484 unsigned int Frame_Extension_Millicode:1; /* 19 */
5485 unsigned int Stack_Overflow_Check:1; /* 20 */
5486 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5487 unsigned int Ada_Region:1; /* 22 */
5488 unsigned int cxx_info:1; /* 23 */
5489 unsigned int cxx_try_catch:1; /* 24 */
5490 unsigned int sched_entry_seq:1; /* 25 */
5491 unsigned int reserved2:1; /* 26 */
5492 unsigned int Save_SP:1; /* 27 */
5493 unsigned int Save_RP:1; /* 28 */
5494 unsigned int Save_MRP_in_frame:1; /* 29 */
5495 unsigned int extn_ptr_defined:1; /* 30 */
5496 unsigned int Cleanup_defined:1; /* 31 */
5497
5498 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5499 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5500 unsigned int Large_frame:1; /* 2 */
5501 unsigned int Pseudo_SP_Set:1; /* 3 */
5502 unsigned int reserved4:1; /* 4 */
5503 unsigned int Total_frame_size:27; /* 5..31 */
5504 };
5505
57346661
AM
5506struct hppa_unw_aux_info
5507 {
3f5e193b 5508 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
5509 unsigned long table_len; /* Length of unwind table. */
5510 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5511 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5512 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5513 char * strtab; /* The string table. */
57346661
AM
5514 unsigned long strtab_size; /* Size of string table. */
5515 };
5516
5517static void
2cf0635d 5518dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5519{
2cf0635d 5520 struct hppa_unw_table_entry * tp;
57346661 5521
57346661
AM
5522 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5523 {
5524 bfd_vma offset;
2cf0635d 5525 const char * procname;
57346661
AM
5526
5527 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5528 aux->strtab_size, tp->start, &procname,
5529 &offset);
5530
5531 fputs ("\n<", stdout);
5532
5533 if (procname)
5534 {
5535 fputs (procname, stdout);
5536
5537 if (offset)
5538 printf ("+%lx", (unsigned long) offset);
5539 }
5540
5541 fputs (">: [", stdout);
5542 print_vma (tp->start.offset, PREFIX_HEX);
5543 fputc ('-', stdout);
5544 print_vma (tp->end.offset, PREFIX_HEX);
5545 printf ("]\n\t");
5546
18bd398b
NC
5547#define PF(_m) if (tp->_m) printf (#_m " ");
5548#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5549 PF(Cannot_unwind);
5550 PF(Millicode);
5551 PF(Millicode_save_sr0);
18bd398b 5552 /* PV(Region_description); */
57346661
AM
5553 PF(Entry_SR);
5554 PV(Entry_FR);
5555 PV(Entry_GR);
5556 PF(Args_stored);
5557 PF(Variable_Frame);
5558 PF(Separate_Package_Body);
5559 PF(Frame_Extension_Millicode);
5560 PF(Stack_Overflow_Check);
5561 PF(Two_Instruction_SP_Increment);
5562 PF(Ada_Region);
5563 PF(cxx_info);
5564 PF(cxx_try_catch);
5565 PF(sched_entry_seq);
5566 PF(Save_SP);
5567 PF(Save_RP);
5568 PF(Save_MRP_in_frame);
5569 PF(extn_ptr_defined);
5570 PF(Cleanup_defined);
5571 PF(MPE_XL_interrupt_marker);
5572 PF(HP_UX_interrupt_marker);
5573 PF(Large_frame);
5574 PF(Pseudo_SP_Set);
5575 PV(Total_frame_size);
5576#undef PF
5577#undef PV
5578 }
5579
18bd398b 5580 printf ("\n");
57346661
AM
5581}
5582
5583static int
2cf0635d
NC
5584slurp_hppa_unwind_table (FILE * file,
5585 struct hppa_unw_aux_info * aux,
5586 Elf_Internal_Shdr * sec)
57346661 5587{
1c0751b2 5588 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
5589 Elf_Internal_Phdr * seg;
5590 struct hppa_unw_table_entry * tep;
5591 Elf_Internal_Shdr * relsec;
5592 Elf_Internal_Rela * rela;
5593 Elf_Internal_Rela * rp;
5594 unsigned char * table;
5595 unsigned char * tp;
5596 Elf_Internal_Sym * sym;
5597 const char * relname;
57346661 5598
57346661
AM
5599 /* First, find the starting address of the segment that includes
5600 this section. */
5601
5602 if (elf_header.e_phnum)
5603 {
5604 if (! get_program_headers (file))
5605 return 0;
5606
5607 for (seg = program_headers;
5608 seg < program_headers + elf_header.e_phnum;
5609 ++seg)
5610 {
5611 if (seg->p_type != PT_LOAD)
5612 continue;
5613
5614 if (sec->sh_addr >= seg->p_vaddr
5615 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5616 {
5617 aux->seg_base = seg->p_vaddr;
5618 break;
5619 }
5620 }
5621 }
5622
5623 /* Second, build the unwind table from the contents of the unwind
5624 section. */
5625 size = sec->sh_size;
3f5e193b
NC
5626 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5627 _("unwind table"));
57346661
AM
5628 if (!table)
5629 return 0;
5630
1c0751b2
DA
5631 unw_ent_size = 16;
5632 nentries = size / unw_ent_size;
5633 size = unw_ent_size * nentries;
57346661 5634
3f5e193b
NC
5635 tep = aux->table = (struct hppa_unw_table_entry *)
5636 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 5637
1c0751b2 5638 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
5639 {
5640 unsigned int tmp1, tmp2;
5641
5642 tep->start.section = SHN_UNDEF;
5643 tep->end.section = SHN_UNDEF;
5644
1c0751b2
DA
5645 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
5646 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
5647 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
5648 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
5649
5650 tep->start.offset += aux->seg_base;
5651 tep->end.offset += aux->seg_base;
57346661
AM
5652
5653 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
5654 tep->Millicode = (tmp1 >> 30) & 0x1;
5655 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
5656 tep->Region_description = (tmp1 >> 27) & 0x3;
5657 tep->reserved1 = (tmp1 >> 26) & 0x1;
5658 tep->Entry_SR = (tmp1 >> 25) & 0x1;
5659 tep->Entry_FR = (tmp1 >> 21) & 0xf;
5660 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
5661 tep->Args_stored = (tmp1 >> 15) & 0x1;
5662 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
5663 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
5664 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
5665 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
5666 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
5667 tep->Ada_Region = (tmp1 >> 9) & 0x1;
5668 tep->cxx_info = (tmp1 >> 8) & 0x1;
5669 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
5670 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
5671 tep->reserved2 = (tmp1 >> 5) & 0x1;
5672 tep->Save_SP = (tmp1 >> 4) & 0x1;
5673 tep->Save_RP = (tmp1 >> 3) & 0x1;
5674 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
5675 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
5676 tep->Cleanup_defined = tmp1 & 0x1;
5677
5678 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
5679 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
5680 tep->Large_frame = (tmp2 >> 29) & 0x1;
5681 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
5682 tep->reserved4 = (tmp2 >> 27) & 0x1;
5683 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
5684 }
5685 free (table);
5686
5687 /* Third, apply any relocations to the unwind table. */
57346661
AM
5688 for (relsec = section_headers;
5689 relsec < section_headers + elf_header.e_shnum;
5690 ++relsec)
5691 {
5692 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5693 || relsec->sh_info >= elf_header.e_shnum
5694 || section_headers + relsec->sh_info != sec)
57346661
AM
5695 continue;
5696
5697 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5698 & rela, & nrelas))
5699 return 0;
5700
5701 for (rp = rela; rp < rela + nrelas; ++rp)
5702 {
aca88567
NC
5703 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
5704 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
5705
5706 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 5707 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
5708 {
5709 warn (_("Skipping unexpected relocation type %s\n"), relname);
5710 continue;
5711 }
5712
5713 i = rp->r_offset / unw_ent_size;
5714
89fac5e3 5715 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
5716 {
5717 case 0:
5718 aux->table[i].start.section = sym->st_shndx;
1e456d54 5719 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
5720 break;
5721 case 1:
5722 aux->table[i].end.section = sym->st_shndx;
1e456d54 5723 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
5724 break;
5725 default:
5726 break;
5727 }
5728 }
5729
5730 free (rela);
5731 }
5732
1c0751b2 5733 aux->table_len = nentries;
57346661
AM
5734
5735 return 1;
5736}
5737
5738static int
2cf0635d 5739hppa_process_unwind (FILE * file)
57346661 5740{
57346661 5741 struct hppa_unw_aux_info aux;
2cf0635d
NC
5742 Elf_Internal_Shdr * unwsec = NULL;
5743 Elf_Internal_Shdr * strsec;
5744 Elf_Internal_Shdr * sec;
18bd398b 5745 unsigned long i;
57346661
AM
5746
5747 memset (& aux, 0, sizeof (aux));
5748
c256ffe7
JJ
5749 if (string_table == NULL)
5750 return 1;
57346661
AM
5751
5752 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5753 {
c256ffe7 5754 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5755 && sec->sh_link < elf_header.e_shnum)
57346661
AM
5756 {
5757 aux.nsyms = sec->sh_size / sec->sh_entsize;
5758 aux.symtab = GET_ELF_SYMBOLS (file, sec);
5759
4fbb74a6 5760 strsec = section_headers + sec->sh_link;
3f5e193b
NC
5761 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5762 1, strsec->sh_size,
5763 _("string table"));
c256ffe7 5764 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 5765 }
18bd398b 5766 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
5767 unwsec = sec;
5768 }
5769
5770 if (!unwsec)
5771 printf (_("\nThere are no unwind sections in this file.\n"));
5772
5773 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5774 {
18bd398b 5775 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 5776 {
57346661
AM
5777 printf (_("\nUnwind section "));
5778 printf (_("'%s'"), SECTION_NAME (sec));
5779
5780 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5781 (unsigned long) sec->sh_offset,
89fac5e3 5782 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
5783
5784 slurp_hppa_unwind_table (file, &aux, sec);
5785 if (aux.table_len > 0)
5786 dump_hppa_unwind (&aux);
5787
5788 if (aux.table)
5789 free ((char *) aux.table);
5790 aux.table = NULL;
5791 }
5792 }
5793
5794 if (aux.symtab)
5795 free (aux.symtab);
5796 if (aux.strtab)
5797 free ((char *) aux.strtab);
5798
5799 return 1;
5800}
5801
0b6ae522
DJ
5802struct arm_section
5803{
5804 unsigned char *data;
5805
5806 Elf_Internal_Shdr *sec;
5807 Elf_Internal_Rela *rela;
5808 unsigned long nrelas;
5809 unsigned int rel_type;
5810
5811 Elf_Internal_Rela *next_rela;
5812};
5813
5814struct arm_unw_aux_info
5815{
5816 FILE *file;
5817
5818 Elf_Internal_Sym *symtab; /* The symbol table. */
5819 unsigned long nsyms; /* Number of symbols. */
5820 char *strtab; /* The string table. */
5821 unsigned long strtab_size; /* Size of string table. */
5822};
5823
5824static const char *
5825arm_print_vma_and_name (struct arm_unw_aux_info *aux,
5826 bfd_vma fn, struct absaddr addr)
5827{
5828 const char *procname;
5829 bfd_vma sym_offset;
5830
5831 if (addr.section == SHN_UNDEF)
5832 addr.offset = fn;
5833
5834 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5835 aux->strtab_size, addr, &procname,
5836 &sym_offset);
5837
5838 print_vma (fn, PREFIX_HEX);
5839
5840 if (procname)
5841 {
5842 fputs (" <", stdout);
5843 fputs (procname, stdout);
5844
5845 if (sym_offset)
5846 printf ("+0x%lx", (unsigned long) sym_offset);
5847 fputc ('>', stdout);
5848 }
5849
5850 return procname;
5851}
5852
5853static void
5854arm_free_section (struct arm_section *arm_sec)
5855{
5856 if (arm_sec->data != NULL)
5857 free (arm_sec->data);
5858
5859 if (arm_sec->rela != NULL)
5860 free (arm_sec->rela);
5861}
5862
5863static int
5864arm_section_get_word (struct arm_unw_aux_info *aux,
5865 struct arm_section *arm_sec,
5866 Elf_Internal_Shdr *sec, bfd_vma word_offset,
5867 unsigned int *wordp, struct absaddr *addr)
5868{
5869 Elf_Internal_Rela *rp;
5870 Elf_Internal_Sym *sym;
5871 const char * relname;
5872 unsigned int word;
5873 bfd_boolean wrapped;
5874
5875 addr->section = SHN_UNDEF;
5876 addr->offset = 0;
5877
5878 if (sec != arm_sec->sec)
5879 {
5880 Elf_Internal_Shdr *relsec;
5881
5882 arm_free_section (arm_sec);
5883
5884 arm_sec->sec = sec;
5885 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
5886 sec->sh_size, _("unwind data"));
5887
5888 arm_sec->rela = NULL;
5889 arm_sec->nrelas = 0;
5890
5891 for (relsec = section_headers;
5892 relsec < section_headers + elf_header.e_shnum;
5893 ++relsec)
5894 {
5895 if (relsec->sh_info >= elf_header.e_shnum
5896 || section_headers + relsec->sh_info != sec)
5897 continue;
5898
5899 if (relsec->sh_type == SHT_REL)
5900 {
5901 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
5902 relsec->sh_size,
5903 & arm_sec->rela, & arm_sec->nrelas))
5904 return 0;
5905 break;
5906 }
5907 else if (relsec->sh_type == SHT_RELA)
5908 {
5909 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
5910 relsec->sh_size,
5911 & arm_sec->rela, & arm_sec->nrelas))
5912 return 0;
5913 break;
5914 }
5915 }
5916
5917 arm_sec->next_rela = arm_sec->rela;
5918 }
5919
5920 if (arm_sec->data == NULL)
5921 return 0;
5922
5923 word = byte_get (arm_sec->data + word_offset, 4);
5924
5925 wrapped = FALSE;
5926 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
5927 {
5928 bfd_vma prelval, offset;
5929
5930 if (rp->r_offset > word_offset && !wrapped)
5931 {
5932 rp = arm_sec->rela;
5933 wrapped = TRUE;
5934 }
5935 if (rp->r_offset > word_offset)
5936 break;
5937
5938 if (rp->r_offset & 3)
5939 {
5940 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
5941 (unsigned long) rp->r_offset);
5942 continue;
5943 }
5944
5945 if (rp->r_offset < word_offset)
5946 continue;
5947
5948 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
5949
5950 if (streq (relname, "R_ARM_NONE"))
5951 continue;
5952
5953 if (! streq (relname, "R_ARM_PREL31"))
5954 {
5955 warn (_("Skipping unexpected relocation type %s\n"), relname);
5956 continue;
5957 }
5958
5959 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
5960
5961 if (arm_sec->rel_type == SHT_REL)
5962 {
5963 offset = word & 0x7fffffff;
5964 if (offset & 0x40000000)
5965 offset |= ~ (bfd_vma) 0x7fffffff;
5966 }
5967 else
5968 offset = rp->r_addend;
5969
5970 offset += sym->st_value;
5971 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
5972
5973 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
5974 addr->section = sym->st_shndx;
5975 addr->offset = offset;
5976 break;
5977 }
5978
5979 *wordp = word;
5980 arm_sec->next_rela = rp;
5981
5982 return 1;
5983}
5984
5985static void
5986decode_arm_unwind (struct arm_unw_aux_info *aux,
5987 unsigned int word, unsigned int remaining,
5988 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
5989 struct arm_section *data_arm_sec)
5990{
5991 int per_index;
5992 unsigned int more_words;
5993 struct absaddr addr;
5994
5995#define ADVANCE \
5996 if (remaining == 0 && more_words) \
5997 { \
5998 data_offset += 4; \
5999 if (!arm_section_get_word (aux, data_arm_sec, data_sec, \
6000 data_offset, &word, &addr)) \
6001 return; \
6002 remaining = 4; \
6003 more_words--; \
6004 } \
6005
6006#define GET_OP(OP) \
6007 ADVANCE; \
6008 if (remaining) \
6009 { \
6010 remaining--; \
6011 (OP) = word >> 24; \
6012 word <<= 8; \
6013 } \
6014 else \
6015 { \
6016 printf ("[Truncated opcode]\n"); \
6017 return; \
6018 } \
6019 printf (_("0x%02x "), OP)
6020
6021 if (remaining == 0)
6022 {
6023 /* Fetch the first word. */
6024 if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
6025 &word, &addr))
6026 return;
6027 remaining = 4;
6028 }
6029
6030 if ((word & 0x80000000) == 0)
6031 {
6032 /* Expand prel31 for personality routine. */
6033 bfd_vma fn;
6034 const char *procname;
6035
6036 fn = word;
6037 if (fn & 0x40000000)
6038 fn |= ~ (bfd_vma) 0x7fffffff;
6039 fn = fn + data_sec->sh_addr + data_offset;
6040
6041 printf (_(" Personality routine: "));
6042 procname = arm_print_vma_and_name (aux, fn, addr);
6043 fputc ('\n', stdout);
6044
6045 /* The GCC personality routines use the standard compact
6046 encoding, starting with one byte giving the number of
6047 words. */
6048 if (procname != NULL
6049 && (const_strneq (procname, "__gcc_personality_v0")
6050 || const_strneq (procname, "__gxx_personality_v0")
6051 || const_strneq (procname, "__gcj_personality_v0")
6052 || const_strneq (procname, "__gnu_objc_personality_v0")))
6053 {
6054 remaining = 0;
6055 more_words = 1;
6056 ADVANCE;
6057 if (!remaining)
6058 {
6059 printf (_(" [Truncated data]\n"));
6060 return;
6061 }
6062 more_words = word >> 24;
6063 word <<= 8;
6064 remaining--;
6065 }
6066 else
6067 return;
6068 }
6069 else
6070 {
6071
6072 per_index = (word >> 24) & 0x7f;
6073 if (per_index != 0 && per_index != 1 && per_index != 2)
6074 {
6075 printf (_(" [reserved compact index %d]\n"), per_index);
6076 return;
6077 }
6078
6079 printf (_(" Compact model %d\n"), per_index);
6080 if (per_index == 0)
6081 {
6082 more_words = 0;
6083 word <<= 8;
6084 remaining--;
6085 }
6086 else
6087 {
6088 more_words = (word >> 16) & 0xff;
6089 word <<= 16;
6090 remaining -= 2;
6091 }
6092 }
6093
6094 /* Decode the unwinding instructions. */
6095 while (1)
6096 {
6097 unsigned int op, op2;
6098
6099 ADVANCE;
6100 if (remaining == 0)
6101 break;
6102 remaining--;
6103 op = word >> 24;
6104 word <<= 8;
6105
6106 printf (_(" 0x%02x "), op);
6107
6108 if ((op & 0xc0) == 0x00)
6109 {
6110 int offset = ((op & 0x3f) << 2) + 4;
6111 printf (_(" vsp = vsp + %d"), offset);
6112 }
6113 else if ((op & 0xc0) == 0x40)
6114 {
6115 int offset = ((op & 0x3f) << 2) + 4;
6116 printf (_(" vsp = vsp - %d"), offset);
6117 }
6118 else if ((op & 0xf0) == 0x80)
6119 {
6120 GET_OP (op2);
6121 if (op == 0x80 && op2 == 0)
6122 printf (_("Refuse to unwind"));
6123 else
6124 {
6125 unsigned int mask = ((op & 0x0f) << 8) | op2;
6126 int first = 1;
6127 int i;
6128 printf ("pop {");
6129 for (i = 0; i < 12; i++)
6130 if (mask & (1 << i))
6131 {
6132 if (first)
6133 first = 0;
6134 else
6135 printf (", ");
6136 printf ("r%d", 4 + i);
6137 }
6138 printf ("}");
6139 }
6140 }
6141 else if ((op & 0xf0) == 0x90)
6142 {
6143 if (op == 0x9d || op == 0x9f)
6144 printf (_(" [Reserved]"));
6145 else
6146 printf (_(" vsp = r%d"), op & 0x0f);
6147 }
6148 else if ((op & 0xf0) == 0xa0)
6149 {
6150 int end = 4 + (op & 0x07);
6151 int first = 1;
6152 int i;
6153 printf (" pop {");
6154 for (i = 4; i <= end; i++)
6155 {
6156 if (first)
6157 first = 0;
6158 else
6159 printf (", ");
6160 printf ("r%d", i);
6161 }
6162 if (op & 0x08)
6163 {
6164 if (first)
6165 printf (", ");
6166 printf ("r14");
6167 }
6168 printf ("}");
6169 }
6170 else if (op == 0xb0)
6171 printf (_(" finish"));
6172 else if (op == 0xb1)
6173 {
6174 GET_OP (op2);
6175 if (op2 == 0 || (op2 & 0xf0) != 0)
6176 printf (_("[Spare]"));
6177 else
6178 {
6179 unsigned int mask = op2 & 0x0f;
6180 int first = 1;
6181 int i;
6182 printf ("pop {");
6183 for (i = 0; i < 12; i++)
6184 if (mask & (1 << i))
6185 {
6186 if (first)
6187 first = 0;
6188 else
6189 printf (", ");
6190 printf ("r%d", i);
6191 }
6192 printf ("}");
6193 }
6194 }
6195 else if (op == 0xb2)
6196 {
b115cf96 6197 unsigned char buf[9];
0b6ae522
DJ
6198 unsigned int i, len;
6199 unsigned long offset;
b115cf96 6200 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6201 {
6202 GET_OP (buf[i]);
6203 if ((buf[i] & 0x80) == 0)
6204 break;
6205 }
6206 assert (i < sizeof (buf));
6207 offset = read_uleb128 (buf, &len);
6208 assert (len == i + 1);
6209 offset = offset * 4 + 0x204;
6210 printf (_("vsp = vsp + %ld"), offset);
6211 }
6212 else
6213 {
6214 if (op == 0xb3 || op == 0xc6 || op == 0xc7 || op == 0xc8 || op == 0xc9)
6215 {
6216 GET_OP (op2);
6217 printf (_("[unsupported two-byte opcode]"));
6218 }
6219 else
6220 {
6221 printf (_(" [unsupported opcode]"));
6222 }
6223 }
6224 printf ("\n");
6225 }
6226
6227 /* Decode the descriptors. Not implemented. */
6228}
6229
6230static void
6231dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
6232{
6233 struct arm_section exidx_arm_sec, extab_arm_sec;
6234 unsigned int i, exidx_len;
6235
6236 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
6237 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
6238 exidx_len = exidx_sec->sh_size / 8;
6239
6240 for (i = 0; i < exidx_len; i++)
6241 {
6242 unsigned int exidx_fn, exidx_entry;
6243 struct absaddr fn_addr, entry_addr;
6244 bfd_vma fn;
6245
6246 fputc ('\n', stdout);
6247
6248 if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6249 8 * i, &exidx_fn, &fn_addr)
6250 || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6251 8 * i + 4, &exidx_entry, &entry_addr))
6252 {
6253 arm_free_section (&exidx_arm_sec);
6254 arm_free_section (&extab_arm_sec);
6255 return;
6256 }
6257
6258 fn = exidx_fn & 0x7fffffff;
6259 if (fn & 0x40000000)
6260 fn |= ~ (bfd_vma) 0x7fffffff;
6261 fn = fn + exidx_sec->sh_addr + 8 * i;
6262
6263 arm_print_vma_and_name (aux, fn, entry_addr);
6264 fputs (": ", stdout);
6265
6266 if (exidx_entry == 1)
6267 {
6268 print_vma (exidx_entry, PREFIX_HEX);
6269 fputs (" [cantunwind]\n", stdout);
6270 }
6271 else if (exidx_entry & 0x80000000)
6272 {
6273 print_vma (exidx_entry, PREFIX_HEX);
6274 fputc ('\n', stdout);
6275 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
6276 }
6277 else
6278 {
8f73510c 6279 bfd_vma table, table_offset = 0;
0b6ae522
DJ
6280 Elf_Internal_Shdr *table_sec;
6281
6282 fputs ("@", stdout);
6283 table = exidx_entry;
6284 if (table & 0x40000000)
6285 table |= ~ (bfd_vma) 0x7fffffff;
6286 table = table + exidx_sec->sh_addr + 8 * i + 4;
6287 print_vma (table, PREFIX_HEX);
6288 printf ("\n");
6289
6290 /* Locate the matching .ARM.extab. */
6291 if (entry_addr.section != SHN_UNDEF
6292 && entry_addr.section < elf_header.e_shnum)
6293 {
6294 table_sec = section_headers + entry_addr.section;
6295 table_offset = entry_addr.offset;
6296 }
6297 else
6298 {
6299 table_sec = find_section_by_address (table);
6300 if (table_sec != NULL)
6301 table_offset = table - table_sec->sh_addr;
6302 }
6303 if (table_sec == NULL)
6304 {
6305 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
6306 (unsigned long) table);
6307 continue;
6308 }
6309 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
6310 &extab_arm_sec);
6311 }
6312 }
6313
6314 printf ("\n");
6315
6316 arm_free_section (&exidx_arm_sec);
6317 arm_free_section (&extab_arm_sec);
6318}
6319
6320static int
6321arm_process_unwind (FILE *file)
6322{
6323 struct arm_unw_aux_info aux;
6324 Elf_Internal_Shdr *unwsec = NULL;
6325 Elf_Internal_Shdr *strsec;
6326 Elf_Internal_Shdr *sec;
6327 unsigned long i;
6328
6329 memset (& aux, 0, sizeof (aux));
6330 aux.file = file;
6331
6332 if (string_table == NULL)
6333 return 1;
6334
6335 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6336 {
6337 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
6338 {
6339 aux.nsyms = sec->sh_size / sec->sh_entsize;
6340 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6341
6342 strsec = section_headers + sec->sh_link;
6343 aux.strtab = get_data (NULL, file, strsec->sh_offset,
6344 1, strsec->sh_size, _("string table"));
6345 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
6346 }
6347 else if (sec->sh_type == SHT_ARM_EXIDX)
6348 unwsec = sec;
6349 }
6350
6351 if (!unwsec)
6352 printf (_("\nThere are no unwind sections in this file.\n"));
6353
6354 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6355 {
6356 if (sec->sh_type == SHT_ARM_EXIDX)
6357 {
6358 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
6359 SECTION_NAME (sec),
6360 (unsigned long) sec->sh_offset,
6361 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
6362
6363 dump_arm_unwind (&aux, sec);
6364 }
6365 }
6366
6367 if (aux.symtab)
6368 free (aux.symtab);
6369 if (aux.strtab)
6370 free ((char *) aux.strtab);
6371
6372 return 1;
6373}
6374
57346661 6375static int
2cf0635d 6376process_unwind (FILE * file)
57346661 6377{
2cf0635d
NC
6378 struct unwind_handler
6379 {
57346661 6380 int machtype;
2cf0635d
NC
6381 int (* handler)(FILE *);
6382 } handlers[] =
6383 {
0b6ae522 6384 { EM_ARM, arm_process_unwind },
57346661
AM
6385 { EM_IA_64, ia64_process_unwind },
6386 { EM_PARISC, hppa_process_unwind },
6387 { 0, 0 }
6388 };
6389 int i;
6390
6391 if (!do_unwind)
6392 return 1;
6393
6394 for (i = 0; handlers[i].handler != NULL; i++)
6395 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 6396 return handlers[i].handler (file);
57346661
AM
6397
6398 printf (_("\nThere are no unwind sections in this file.\n"));
6399 return 1;
6400}
6401
252b5132 6402static void
2cf0635d 6403dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
6404{
6405 switch (entry->d_tag)
6406 {
6407 case DT_MIPS_FLAGS:
6408 if (entry->d_un.d_val == 0)
6409 printf ("NONE\n");
6410 else
6411 {
6412 static const char * opts[] =
6413 {
6414 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
6415 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
6416 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
6417 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
6418 "RLD_ORDER_SAFE"
6419 };
6420 unsigned int cnt;
6421 int first = 1;
60bca95a 6422 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
6423 if (entry->d_un.d_val & (1 << cnt))
6424 {
6425 printf ("%s%s", first ? "" : " ", opts[cnt]);
6426 first = 0;
6427 }
6428 puts ("");
6429 }
6430 break;
103f02d3 6431
252b5132 6432 case DT_MIPS_IVERSION:
d79b3d50
NC
6433 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6434 printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6435 else
d79b3d50 6436 printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
252b5132 6437 break;
103f02d3 6438
252b5132
RH
6439 case DT_MIPS_TIME_STAMP:
6440 {
6441 char timebuf[20];
2cf0635d 6442 struct tm * tmp;
50da7a9c 6443
91d6fa6a
NC
6444 time_t atime = entry->d_un.d_val;
6445 tmp = gmtime (&atime);
e9e44622
JJ
6446 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
6447 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6448 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
6449 printf ("Time Stamp: %s\n", timebuf);
6450 }
6451 break;
103f02d3 6452
252b5132
RH
6453 case DT_MIPS_RLD_VERSION:
6454 case DT_MIPS_LOCAL_GOTNO:
6455 case DT_MIPS_CONFLICTNO:
6456 case DT_MIPS_LIBLISTNO:
6457 case DT_MIPS_SYMTABNO:
6458 case DT_MIPS_UNREFEXTNO:
6459 case DT_MIPS_HIPAGENO:
6460 case DT_MIPS_DELTA_CLASS_NO:
6461 case DT_MIPS_DELTA_INSTANCE_NO:
6462 case DT_MIPS_DELTA_RELOC_NO:
6463 case DT_MIPS_DELTA_SYM_NO:
6464 case DT_MIPS_DELTA_CLASSSYM_NO:
6465 case DT_MIPS_COMPACT_SIZE:
6466 printf ("%ld\n", (long) entry->d_un.d_ptr);
6467 break;
103f02d3
UD
6468
6469 default:
0af1713e 6470 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
6471 }
6472}
6473
6474
6475static void
2cf0635d 6476dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
6477{
6478 switch (entry->d_tag)
6479 {
6480 case DT_HP_DLD_FLAGS:
6481 {
6482 static struct
6483 {
6484 long int bit;
2cf0635d 6485 const char * str;
5e220199
NC
6486 }
6487 flags[] =
6488 {
6489 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
6490 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
6491 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
6492 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
6493 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
6494 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
6495 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
6496 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
6497 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
6498 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
6499 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
6500 { DT_HP_GST, "HP_GST" },
6501 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
6502 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
6503 { DT_HP_NODELETE, "HP_NODELETE" },
6504 { DT_HP_GROUP, "HP_GROUP" },
6505 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 6506 };
103f02d3 6507 int first = 1;
5e220199 6508 size_t cnt;
f7a99963 6509 bfd_vma val = entry->d_un.d_val;
103f02d3 6510
60bca95a 6511 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 6512 if (val & flags[cnt].bit)
30800947
NC
6513 {
6514 if (! first)
6515 putchar (' ');
6516 fputs (flags[cnt].str, stdout);
6517 first = 0;
6518 val ^= flags[cnt].bit;
6519 }
76da6bbe 6520
103f02d3 6521 if (val != 0 || first)
f7a99963
NC
6522 {
6523 if (! first)
6524 putchar (' ');
6525 print_vma (val, HEX);
6526 }
103f02d3
UD
6527 }
6528 break;
76da6bbe 6529
252b5132 6530 default:
f7a99963
NC
6531 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6532 break;
252b5132 6533 }
35b1837e 6534 putchar ('\n');
252b5132
RH
6535}
6536
ecc51f48 6537static void
2cf0635d 6538dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
6539{
6540 switch (entry->d_tag)
6541 {
0de14b54 6542 case DT_IA_64_PLT_RESERVE:
bdf4d63a 6543 /* First 3 slots reserved. */
ecc51f48
NC
6544 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6545 printf (" -- ");
6546 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
6547 break;
6548
6549 default:
6550 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6551 break;
ecc51f48 6552 }
bdf4d63a 6553 putchar ('\n');
ecc51f48
NC
6554}
6555
252b5132 6556static int
2cf0635d 6557get_32bit_dynamic_section (FILE * file)
252b5132 6558{
2cf0635d
NC
6559 Elf32_External_Dyn * edyn;
6560 Elf32_External_Dyn * ext;
6561 Elf_Internal_Dyn * entry;
103f02d3 6562
3f5e193b
NC
6563 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
6564 dynamic_size, _("dynamic section"));
a6e9f9df
AM
6565 if (!edyn)
6566 return 0;
103f02d3 6567
ba2685cc
AM
6568/* SGI's ELF has more than one section in the DYNAMIC segment, and we
6569 might not have the luxury of section headers. Look for the DT_NULL
6570 terminator to determine the number of entries. */
6571 for (ext = edyn, dynamic_nent = 0;
6572 (char *) ext < (char *) edyn + dynamic_size;
6573 ext++)
6574 {
6575 dynamic_nent++;
6576 if (BYTE_GET (ext->d_tag) == DT_NULL)
6577 break;
6578 }
252b5132 6579
3f5e193b
NC
6580 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
6581 sizeof (* entry));
b2d38a17 6582 if (dynamic_section == NULL)
252b5132 6583 {
9ea033b2
NC
6584 error (_("Out of memory\n"));
6585 free (edyn);
6586 return 0;
6587 }
252b5132 6588
fb514b26 6589 for (ext = edyn, entry = dynamic_section;
ba2685cc 6590 entry < dynamic_section + dynamic_nent;
fb514b26 6591 ext++, entry++)
9ea033b2 6592 {
fb514b26
AM
6593 entry->d_tag = BYTE_GET (ext->d_tag);
6594 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
6595 }
6596
9ea033b2
NC
6597 free (edyn);
6598
6599 return 1;
6600}
6601
6602static int
2cf0635d 6603get_64bit_dynamic_section (FILE * file)
9ea033b2 6604{
2cf0635d
NC
6605 Elf64_External_Dyn * edyn;
6606 Elf64_External_Dyn * ext;
6607 Elf_Internal_Dyn * entry;
103f02d3 6608
3f5e193b
NC
6609 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
6610 dynamic_size, _("dynamic section"));
a6e9f9df
AM
6611 if (!edyn)
6612 return 0;
103f02d3 6613
ba2685cc
AM
6614/* SGI's ELF has more than one section in the DYNAMIC segment, and we
6615 might not have the luxury of section headers. Look for the DT_NULL
6616 terminator to determine the number of entries. */
6617 for (ext = edyn, dynamic_nent = 0;
6618 (char *) ext < (char *) edyn + dynamic_size;
6619 ext++)
6620 {
6621 dynamic_nent++;
66543521 6622 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
6623 break;
6624 }
252b5132 6625
3f5e193b
NC
6626 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
6627 sizeof (* entry));
b2d38a17 6628 if (dynamic_section == NULL)
252b5132
RH
6629 {
6630 error (_("Out of memory\n"));
6631 free (edyn);
6632 return 0;
6633 }
6634
fb514b26 6635 for (ext = edyn, entry = dynamic_section;
ba2685cc 6636 entry < dynamic_section + dynamic_nent;
fb514b26 6637 ext++, entry++)
252b5132 6638 {
66543521
AM
6639 entry->d_tag = BYTE_GET (ext->d_tag);
6640 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
6641 }
6642
6643 free (edyn);
6644
9ea033b2
NC
6645 return 1;
6646}
6647
e9e44622
JJ
6648static void
6649print_dynamic_flags (bfd_vma flags)
d1133906 6650{
e9e44622 6651 int first = 1;
13ae64f3 6652
d1133906
NC
6653 while (flags)
6654 {
6655 bfd_vma flag;
6656
6657 flag = flags & - flags;
6658 flags &= ~ flag;
6659
e9e44622
JJ
6660 if (first)
6661 first = 0;
6662 else
6663 putc (' ', stdout);
13ae64f3 6664
d1133906
NC
6665 switch (flag)
6666 {
e9e44622
JJ
6667 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
6668 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
6669 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
6670 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
6671 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
6672 default: fputs ("unknown", stdout); break;
d1133906
NC
6673 }
6674 }
e9e44622 6675 puts ("");
d1133906
NC
6676}
6677
b2d38a17
NC
6678/* Parse and display the contents of the dynamic section. */
6679
9ea033b2 6680static int
2cf0635d 6681process_dynamic_section (FILE * file)
9ea033b2 6682{
2cf0635d 6683 Elf_Internal_Dyn * entry;
9ea033b2
NC
6684
6685 if (dynamic_size == 0)
6686 {
6687 if (do_dynamic)
b2d38a17 6688 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
6689
6690 return 1;
6691 }
6692
6693 if (is_32bit_elf)
6694 {
b2d38a17 6695 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
6696 return 0;
6697 }
b2d38a17 6698 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
6699 return 0;
6700
252b5132
RH
6701 /* Find the appropriate symbol table. */
6702 if (dynamic_symbols == NULL)
6703 {
86dba8ee
AM
6704 for (entry = dynamic_section;
6705 entry < dynamic_section + dynamic_nent;
6706 ++entry)
252b5132 6707 {
c8286bd1 6708 Elf_Internal_Shdr section;
252b5132
RH
6709
6710 if (entry->d_tag != DT_SYMTAB)
6711 continue;
6712
6713 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
6714
6715 /* Since we do not know how big the symbol table is,
6716 we default to reading in the entire file (!) and
6717 processing that. This is overkill, I know, but it
e3c8793a 6718 should work. */
d93f0186 6719 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 6720
fb52b2f4
NC
6721 if (archive_file_offset != 0)
6722 section.sh_size = archive_file_size - section.sh_offset;
6723 else
6724 {
6725 if (fseek (file, 0, SEEK_END))
591a748a 6726 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
6727
6728 section.sh_size = ftell (file) - section.sh_offset;
6729 }
252b5132 6730
9ea033b2 6731 if (is_32bit_elf)
9ad5cbcf 6732 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 6733 else
9ad5cbcf 6734 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 6735
9ad5cbcf 6736 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 6737 if (num_dynamic_syms < 1)
252b5132
RH
6738 {
6739 error (_("Unable to determine the number of symbols to load\n"));
6740 continue;
6741 }
6742
9ad5cbcf 6743 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
6744 }
6745 }
6746
6747 /* Similarly find a string table. */
6748 if (dynamic_strings == NULL)
6749 {
86dba8ee
AM
6750 for (entry = dynamic_section;
6751 entry < dynamic_section + dynamic_nent;
6752 ++entry)
252b5132
RH
6753 {
6754 unsigned long offset;
b34976b6 6755 long str_tab_len;
252b5132
RH
6756
6757 if (entry->d_tag != DT_STRTAB)
6758 continue;
6759
6760 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
6761
6762 /* Since we do not know how big the string table is,
6763 we default to reading in the entire file (!) and
6764 processing that. This is overkill, I know, but it
e3c8793a 6765 should work. */
252b5132 6766
d93f0186 6767 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
6768
6769 if (archive_file_offset != 0)
6770 str_tab_len = archive_file_size - offset;
6771 else
6772 {
6773 if (fseek (file, 0, SEEK_END))
6774 error (_("Unable to seek to end of file\n"));
6775 str_tab_len = ftell (file) - offset;
6776 }
252b5132
RH
6777
6778 if (str_tab_len < 1)
6779 {
6780 error
6781 (_("Unable to determine the length of the dynamic string table\n"));
6782 continue;
6783 }
6784
3f5e193b
NC
6785 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
6786 str_tab_len,
6787 _("dynamic string table"));
d79b3d50 6788 dynamic_strings_length = str_tab_len;
252b5132
RH
6789 break;
6790 }
6791 }
6792
6793 /* And find the syminfo section if available. */
6794 if (dynamic_syminfo == NULL)
6795 {
3e8bba36 6796 unsigned long syminsz = 0;
252b5132 6797
86dba8ee
AM
6798 for (entry = dynamic_section;
6799 entry < dynamic_section + dynamic_nent;
6800 ++entry)
252b5132
RH
6801 {
6802 if (entry->d_tag == DT_SYMINENT)
6803 {
6804 /* Note: these braces are necessary to avoid a syntax
6805 error from the SunOS4 C compiler. */
6806 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
6807 }
6808 else if (entry->d_tag == DT_SYMINSZ)
6809 syminsz = entry->d_un.d_val;
6810 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
6811 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
6812 syminsz);
252b5132
RH
6813 }
6814
6815 if (dynamic_syminfo_offset != 0 && syminsz != 0)
6816 {
2cf0635d
NC
6817 Elf_External_Syminfo * extsyminfo;
6818 Elf_External_Syminfo * extsym;
6819 Elf_Internal_Syminfo * syminfo;
252b5132
RH
6820
6821 /* There is a syminfo section. Read the data. */
3f5e193b
NC
6822 extsyminfo = (Elf_External_Syminfo *)
6823 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
6824 _("symbol information"));
a6e9f9df
AM
6825 if (!extsyminfo)
6826 return 0;
252b5132 6827
3f5e193b 6828 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
6829 if (dynamic_syminfo == NULL)
6830 {
6831 error (_("Out of memory\n"));
6832 return 0;
6833 }
6834
6835 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
6836 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
6837 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
6838 ++syminfo, ++extsym)
252b5132 6839 {
86dba8ee
AM
6840 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
6841 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
6842 }
6843
6844 free (extsyminfo);
6845 }
6846 }
6847
6848 if (do_dynamic && dynamic_addr)
86dba8ee
AM
6849 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
6850 dynamic_addr, dynamic_nent);
252b5132
RH
6851 if (do_dynamic)
6852 printf (_(" Tag Type Name/Value\n"));
6853
86dba8ee
AM
6854 for (entry = dynamic_section;
6855 entry < dynamic_section + dynamic_nent;
6856 entry++)
252b5132
RH
6857 {
6858 if (do_dynamic)
f7a99963 6859 {
2cf0635d 6860 const char * dtype;
e699b9ff 6861
f7a99963
NC
6862 putchar (' ');
6863 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
6864 dtype = get_dynamic_type (entry->d_tag);
6865 printf (" (%s)%*s", dtype,
6866 ((is_32bit_elf ? 27 : 19)
6867 - (int) strlen (dtype)),
f7a99963
NC
6868 " ");
6869 }
252b5132
RH
6870
6871 switch (entry->d_tag)
6872 {
d1133906
NC
6873 case DT_FLAGS:
6874 if (do_dynamic)
e9e44622 6875 print_dynamic_flags (entry->d_un.d_val);
d1133906 6876 break;
76da6bbe 6877
252b5132
RH
6878 case DT_AUXILIARY:
6879 case DT_FILTER:
019148e4
L
6880 case DT_CONFIG:
6881 case DT_DEPAUDIT:
6882 case DT_AUDIT:
252b5132
RH
6883 if (do_dynamic)
6884 {
019148e4 6885 switch (entry->d_tag)
b34976b6 6886 {
019148e4
L
6887 case DT_AUXILIARY:
6888 printf (_("Auxiliary library"));
6889 break;
6890
6891 case DT_FILTER:
6892 printf (_("Filter library"));
6893 break;
6894
b34976b6 6895 case DT_CONFIG:
019148e4
L
6896 printf (_("Configuration file"));
6897 break;
6898
6899 case DT_DEPAUDIT:
6900 printf (_("Dependency audit library"));
6901 break;
6902
6903 case DT_AUDIT:
6904 printf (_("Audit library"));
6905 break;
6906 }
252b5132 6907
d79b3d50
NC
6908 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6909 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6910 else
f7a99963
NC
6911 {
6912 printf (": ");
6913 print_vma (entry->d_un.d_val, PREFIX_HEX);
6914 putchar ('\n');
6915 }
252b5132
RH
6916 }
6917 break;
6918
dcefbbbd 6919 case DT_FEATURE:
252b5132
RH
6920 if (do_dynamic)
6921 {
6922 printf (_("Flags:"));
86f55779 6923
252b5132
RH
6924 if (entry->d_un.d_val == 0)
6925 printf (_(" None\n"));
6926 else
6927 {
6928 unsigned long int val = entry->d_un.d_val;
86f55779 6929
252b5132
RH
6930 if (val & DTF_1_PARINIT)
6931 {
6932 printf (" PARINIT");
6933 val ^= DTF_1_PARINIT;
6934 }
dcefbbbd
L
6935 if (val & DTF_1_CONFEXP)
6936 {
6937 printf (" CONFEXP");
6938 val ^= DTF_1_CONFEXP;
6939 }
252b5132
RH
6940 if (val != 0)
6941 printf (" %lx", val);
6942 puts ("");
6943 }
6944 }
6945 break;
6946
6947 case DT_POSFLAG_1:
6948 if (do_dynamic)
6949 {
6950 printf (_("Flags:"));
86f55779 6951
252b5132
RH
6952 if (entry->d_un.d_val == 0)
6953 printf (_(" None\n"));
6954 else
6955 {
6956 unsigned long int val = entry->d_un.d_val;
86f55779 6957
252b5132
RH
6958 if (val & DF_P1_LAZYLOAD)
6959 {
6960 printf (" LAZYLOAD");
6961 val ^= DF_P1_LAZYLOAD;
6962 }
6963 if (val & DF_P1_GROUPPERM)
6964 {
6965 printf (" GROUPPERM");
6966 val ^= DF_P1_GROUPPERM;
6967 }
6968 if (val != 0)
6969 printf (" %lx", val);
6970 puts ("");
6971 }
6972 }
6973 break;
6974
6975 case DT_FLAGS_1:
6976 if (do_dynamic)
6977 {
6978 printf (_("Flags:"));
6979 if (entry->d_un.d_val == 0)
6980 printf (_(" None\n"));
6981 else
6982 {
6983 unsigned long int val = entry->d_un.d_val;
86f55779 6984
252b5132
RH
6985 if (val & DF_1_NOW)
6986 {
6987 printf (" NOW");
6988 val ^= DF_1_NOW;
6989 }
6990 if (val & DF_1_GLOBAL)
6991 {
6992 printf (" GLOBAL");
6993 val ^= DF_1_GLOBAL;
6994 }
6995 if (val & DF_1_GROUP)
6996 {
6997 printf (" GROUP");
6998 val ^= DF_1_GROUP;
6999 }
7000 if (val & DF_1_NODELETE)
7001 {
7002 printf (" NODELETE");
7003 val ^= DF_1_NODELETE;
7004 }
7005 if (val & DF_1_LOADFLTR)
7006 {
7007 printf (" LOADFLTR");
7008 val ^= DF_1_LOADFLTR;
7009 }
7010 if (val & DF_1_INITFIRST)
7011 {
7012 printf (" INITFIRST");
7013 val ^= DF_1_INITFIRST;
7014 }
7015 if (val & DF_1_NOOPEN)
7016 {
7017 printf (" NOOPEN");
7018 val ^= DF_1_NOOPEN;
7019 }
7020 if (val & DF_1_ORIGIN)
7021 {
7022 printf (" ORIGIN");
7023 val ^= DF_1_ORIGIN;
7024 }
7025 if (val & DF_1_DIRECT)
7026 {
7027 printf (" DIRECT");
7028 val ^= DF_1_DIRECT;
7029 }
7030 if (val & DF_1_TRANS)
7031 {
7032 printf (" TRANS");
7033 val ^= DF_1_TRANS;
7034 }
7035 if (val & DF_1_INTERPOSE)
7036 {
7037 printf (" INTERPOSE");
7038 val ^= DF_1_INTERPOSE;
7039 }
f7db6139 7040 if (val & DF_1_NODEFLIB)
dcefbbbd 7041 {
f7db6139
L
7042 printf (" NODEFLIB");
7043 val ^= DF_1_NODEFLIB;
dcefbbbd
L
7044 }
7045 if (val & DF_1_NODUMP)
7046 {
7047 printf (" NODUMP");
7048 val ^= DF_1_NODUMP;
7049 }
7050 if (val & DF_1_CONLFAT)
7051 {
7052 printf (" CONLFAT");
7053 val ^= DF_1_CONLFAT;
7054 }
252b5132
RH
7055 if (val != 0)
7056 printf (" %lx", val);
7057 puts ("");
7058 }
7059 }
7060 break;
7061
7062 case DT_PLTREL:
566b0d53 7063 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7064 if (do_dynamic)
7065 puts (get_dynamic_type (entry->d_un.d_val));
7066 break;
7067
7068 case DT_NULL :
7069 case DT_NEEDED :
7070 case DT_PLTGOT :
7071 case DT_HASH :
7072 case DT_STRTAB :
7073 case DT_SYMTAB :
7074 case DT_RELA :
7075 case DT_INIT :
7076 case DT_FINI :
7077 case DT_SONAME :
7078 case DT_RPATH :
7079 case DT_SYMBOLIC:
7080 case DT_REL :
7081 case DT_DEBUG :
7082 case DT_TEXTREL :
7083 case DT_JMPREL :
019148e4 7084 case DT_RUNPATH :
252b5132
RH
7085 dynamic_info[entry->d_tag] = entry->d_un.d_val;
7086
7087 if (do_dynamic)
7088 {
2cf0635d 7089 char * name;
252b5132 7090
d79b3d50
NC
7091 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7092 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7093 else
d79b3d50 7094 name = NULL;
252b5132
RH
7095
7096 if (name)
7097 {
7098 switch (entry->d_tag)
7099 {
7100 case DT_NEEDED:
7101 printf (_("Shared library: [%s]"), name);
7102
18bd398b 7103 if (streq (name, program_interpreter))
f7a99963 7104 printf (_(" program interpreter"));
252b5132
RH
7105 break;
7106
7107 case DT_SONAME:
f7a99963 7108 printf (_("Library soname: [%s]"), name);
252b5132
RH
7109 break;
7110
7111 case DT_RPATH:
f7a99963 7112 printf (_("Library rpath: [%s]"), name);
252b5132
RH
7113 break;
7114
019148e4
L
7115 case DT_RUNPATH:
7116 printf (_("Library runpath: [%s]"), name);
7117 break;
7118
252b5132 7119 default:
f7a99963
NC
7120 print_vma (entry->d_un.d_val, PREFIX_HEX);
7121 break;
252b5132
RH
7122 }
7123 }
7124 else
f7a99963
NC
7125 print_vma (entry->d_un.d_val, PREFIX_HEX);
7126
7127 putchar ('\n');
252b5132
RH
7128 }
7129 break;
7130
7131 case DT_PLTRELSZ:
7132 case DT_RELASZ :
7133 case DT_STRSZ :
7134 case DT_RELSZ :
7135 case DT_RELAENT :
7136 case DT_SYMENT :
7137 case DT_RELENT :
566b0d53 7138 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7139 case DT_PLTPADSZ:
7140 case DT_MOVEENT :
7141 case DT_MOVESZ :
7142 case DT_INIT_ARRAYSZ:
7143 case DT_FINI_ARRAYSZ:
047b2264
JJ
7144 case DT_GNU_CONFLICTSZ:
7145 case DT_GNU_LIBLISTSZ:
252b5132 7146 if (do_dynamic)
f7a99963
NC
7147 {
7148 print_vma (entry->d_un.d_val, UNSIGNED);
7149 printf (" (bytes)\n");
7150 }
252b5132
RH
7151 break;
7152
7153 case DT_VERDEFNUM:
7154 case DT_VERNEEDNUM:
7155 case DT_RELACOUNT:
7156 case DT_RELCOUNT:
7157 if (do_dynamic)
f7a99963
NC
7158 {
7159 print_vma (entry->d_un.d_val, UNSIGNED);
7160 putchar ('\n');
7161 }
252b5132
RH
7162 break;
7163
7164 case DT_SYMINSZ:
7165 case DT_SYMINENT:
7166 case DT_SYMINFO:
7167 case DT_USED:
7168 case DT_INIT_ARRAY:
7169 case DT_FINI_ARRAY:
7170 if (do_dynamic)
7171 {
d79b3d50
NC
7172 if (entry->d_tag == DT_USED
7173 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 7174 {
2cf0635d 7175 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7176
b34976b6 7177 if (*name)
252b5132
RH
7178 {
7179 printf (_("Not needed object: [%s]\n"), name);
7180 break;
7181 }
7182 }
103f02d3 7183
f7a99963
NC
7184 print_vma (entry->d_un.d_val, PREFIX_HEX);
7185 putchar ('\n');
252b5132
RH
7186 }
7187 break;
7188
7189 case DT_BIND_NOW:
7190 /* The value of this entry is ignored. */
35b1837e
AM
7191 if (do_dynamic)
7192 putchar ('\n');
252b5132 7193 break;
103f02d3 7194
047b2264
JJ
7195 case DT_GNU_PRELINKED:
7196 if (do_dynamic)
7197 {
2cf0635d 7198 struct tm * tmp;
91d6fa6a 7199 time_t atime = entry->d_un.d_val;
047b2264 7200
91d6fa6a 7201 tmp = gmtime (&atime);
047b2264
JJ
7202 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
7203 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7204 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7205
7206 }
7207 break;
7208
fdc90cb4
JJ
7209 case DT_GNU_HASH:
7210 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
7211 if (do_dynamic)
7212 {
7213 print_vma (entry->d_un.d_val, PREFIX_HEX);
7214 putchar ('\n');
7215 }
7216 break;
7217
252b5132
RH
7218 default:
7219 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 7220 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
7221 entry->d_un.d_val;
7222
7223 if (do_dynamic)
7224 {
7225 switch (elf_header.e_machine)
7226 {
7227 case EM_MIPS:
4fe85591 7228 case EM_MIPS_RS3_LE:
b2d38a17 7229 dynamic_section_mips_val (entry);
252b5132 7230 break;
103f02d3 7231 case EM_PARISC:
b2d38a17 7232 dynamic_section_parisc_val (entry);
103f02d3 7233 break;
ecc51f48 7234 case EM_IA_64:
b2d38a17 7235 dynamic_section_ia64_val (entry);
ecc51f48 7236 break;
252b5132 7237 default:
f7a99963
NC
7238 print_vma (entry->d_un.d_val, PREFIX_HEX);
7239 putchar ('\n');
252b5132
RH
7240 }
7241 }
7242 break;
7243 }
7244 }
7245
7246 return 1;
7247}
7248
7249static char *
d3ba0551 7250get_ver_flags (unsigned int flags)
252b5132 7251{
b34976b6 7252 static char buff[32];
252b5132
RH
7253
7254 buff[0] = 0;
7255
7256 if (flags == 0)
7257 return _("none");
7258
7259 if (flags & VER_FLG_BASE)
7260 strcat (buff, "BASE ");
7261
7262 if (flags & VER_FLG_WEAK)
7263 {
7264 if (flags & VER_FLG_BASE)
7265 strcat (buff, "| ");
7266
7267 strcat (buff, "WEAK ");
7268 }
7269
44ec90b9
RO
7270 if (flags & VER_FLG_INFO)
7271 {
7272 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7273 strcat (buff, "| ");
7274
7275 strcat (buff, "INFO ");
7276 }
7277
7278 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
252b5132
RH
7279 strcat (buff, "| <unknown>");
7280
7281 return buff;
7282}
7283
7284/* Display the contents of the version sections. */
98fb390a 7285
252b5132 7286static int
2cf0635d 7287process_version_sections (FILE * file)
252b5132 7288{
2cf0635d 7289 Elf_Internal_Shdr * section;
b34976b6
AM
7290 unsigned i;
7291 int found = 0;
252b5132
RH
7292
7293 if (! do_version)
7294 return 1;
7295
7296 for (i = 0, section = section_headers;
7297 i < elf_header.e_shnum;
b34976b6 7298 i++, section++)
252b5132
RH
7299 {
7300 switch (section->sh_type)
7301 {
7302 case SHT_GNU_verdef:
7303 {
2cf0635d 7304 Elf_External_Verdef * edefs;
b34976b6
AM
7305 unsigned int idx;
7306 unsigned int cnt;
2cf0635d 7307 char * endbuf;
252b5132
RH
7308
7309 found = 1;
7310
7311 printf
72de5009 7312 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
7313 SECTION_NAME (section), section->sh_info);
7314
7315 printf (_(" Addr: 0x"));
7316 printf_vma (section->sh_addr);
72de5009 7317 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7318 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
7319 section->sh_link < elf_header.e_shnum
7320 ? SECTION_NAME (section_headers + section->sh_link)
c256ffe7 7321 : "<corrupt>");
252b5132 7322
3f5e193b
NC
7323 edefs = (Elf_External_Verdef *)
7324 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
7325 _("version definition section"));
54806181 7326 endbuf = (char *) edefs + section->sh_size;
a6e9f9df
AM
7327 if (!edefs)
7328 break;
252b5132 7329
b34976b6 7330 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 7331 {
2cf0635d
NC
7332 char * vstart;
7333 Elf_External_Verdef * edef;
b34976b6 7334 Elf_Internal_Verdef ent;
2cf0635d 7335 Elf_External_Verdaux * eaux;
b34976b6
AM
7336 Elf_Internal_Verdaux aux;
7337 int j;
7338 int isum;
103f02d3 7339
252b5132 7340 vstart = ((char *) edefs) + idx;
54806181
AM
7341 if (vstart + sizeof (*edef) > endbuf)
7342 break;
252b5132
RH
7343
7344 edef = (Elf_External_Verdef *) vstart;
7345
7346 ent.vd_version = BYTE_GET (edef->vd_version);
7347 ent.vd_flags = BYTE_GET (edef->vd_flags);
7348 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
7349 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
7350 ent.vd_hash = BYTE_GET (edef->vd_hash);
7351 ent.vd_aux = BYTE_GET (edef->vd_aux);
7352 ent.vd_next = BYTE_GET (edef->vd_next);
7353
7354 printf (_(" %#06x: Rev: %d Flags: %s"),
7355 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
7356
7357 printf (_(" Index: %d Cnt: %d "),
7358 ent.vd_ndx, ent.vd_cnt);
7359
7360 vstart += ent.vd_aux;
7361
7362 eaux = (Elf_External_Verdaux *) vstart;
7363
7364 aux.vda_name = BYTE_GET (eaux->vda_name);
7365 aux.vda_next = BYTE_GET (eaux->vda_next);
7366
d79b3d50
NC
7367 if (VALID_DYNAMIC_NAME (aux.vda_name))
7368 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
7369 else
7370 printf (_("Name index: %ld\n"), aux.vda_name);
7371
7372 isum = idx + ent.vd_aux;
7373
b34976b6 7374 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
7375 {
7376 isum += aux.vda_next;
7377 vstart += aux.vda_next;
7378
7379 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
7380 if (vstart + sizeof (*eaux) > endbuf)
7381 break;
252b5132
RH
7382
7383 aux.vda_name = BYTE_GET (eaux->vda_name);
7384 aux.vda_next = BYTE_GET (eaux->vda_next);
7385
d79b3d50 7386 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 7387 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 7388 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
7389 else
7390 printf (_(" %#06x: Parent %d, name index: %ld\n"),
7391 isum, j, aux.vda_name);
7392 }
54806181
AM
7393 if (j < ent.vd_cnt)
7394 printf (_(" Version def aux past end of section\n"));
252b5132
RH
7395
7396 idx += ent.vd_next;
7397 }
54806181
AM
7398 if (cnt < section->sh_info)
7399 printf (_(" Version definition past end of section\n"));
252b5132
RH
7400
7401 free (edefs);
7402 }
7403 break;
103f02d3 7404
252b5132
RH
7405 case SHT_GNU_verneed:
7406 {
2cf0635d 7407 Elf_External_Verneed * eneed;
b34976b6
AM
7408 unsigned int idx;
7409 unsigned int cnt;
2cf0635d 7410 char * endbuf;
252b5132
RH
7411
7412 found = 1;
7413
72de5009 7414 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
7415 SECTION_NAME (section), section->sh_info);
7416
7417 printf (_(" Addr: 0x"));
7418 printf_vma (section->sh_addr);
72de5009 7419 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7420 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
7421 section->sh_link < elf_header.e_shnum
7422 ? SECTION_NAME (section_headers + section->sh_link)
c256ffe7 7423 : "<corrupt>");
252b5132 7424
3f5e193b
NC
7425 eneed = (Elf_External_Verneed *) get_data (NULL, file,
7426 section->sh_offset, 1,
7427 section->sh_size,
7428 _("version need section"));
54806181 7429 endbuf = (char *) eneed + section->sh_size;
a6e9f9df
AM
7430 if (!eneed)
7431 break;
252b5132
RH
7432
7433 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
7434 {
2cf0635d 7435 Elf_External_Verneed * entry;
b34976b6
AM
7436 Elf_Internal_Verneed ent;
7437 int j;
7438 int isum;
2cf0635d 7439 char * vstart;
252b5132
RH
7440
7441 vstart = ((char *) eneed) + idx;
54806181
AM
7442 if (vstart + sizeof (*entry) > endbuf)
7443 break;
252b5132
RH
7444
7445 entry = (Elf_External_Verneed *) vstart;
7446
7447 ent.vn_version = BYTE_GET (entry->vn_version);
7448 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
7449 ent.vn_file = BYTE_GET (entry->vn_file);
7450 ent.vn_aux = BYTE_GET (entry->vn_aux);
7451 ent.vn_next = BYTE_GET (entry->vn_next);
7452
7453 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
7454
d79b3d50
NC
7455 if (VALID_DYNAMIC_NAME (ent.vn_file))
7456 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
7457 else
7458 printf (_(" File: %lx"), ent.vn_file);
7459
7460 printf (_(" Cnt: %d\n"), ent.vn_cnt);
7461
7462 vstart += ent.vn_aux;
7463
7464 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
7465 {
2cf0635d 7466 Elf_External_Vernaux * eaux;
b34976b6 7467 Elf_Internal_Vernaux aux;
252b5132 7468
54806181
AM
7469 if (vstart + sizeof (*eaux) > endbuf)
7470 break;
252b5132
RH
7471 eaux = (Elf_External_Vernaux *) vstart;
7472
7473 aux.vna_hash = BYTE_GET (eaux->vna_hash);
7474 aux.vna_flags = BYTE_GET (eaux->vna_flags);
7475 aux.vna_other = BYTE_GET (eaux->vna_other);
7476 aux.vna_name = BYTE_GET (eaux->vna_name);
7477 aux.vna_next = BYTE_GET (eaux->vna_next);
7478
d79b3d50 7479 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 7480 printf (_(" %#06x: Name: %s"),
d79b3d50 7481 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 7482 else
ecc2063b 7483 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
7484 isum, aux.vna_name);
7485
7486 printf (_(" Flags: %s Version: %d\n"),
7487 get_ver_flags (aux.vna_flags), aux.vna_other);
7488
7489 isum += aux.vna_next;
7490 vstart += aux.vna_next;
7491 }
54806181
AM
7492 if (j < ent.vn_cnt)
7493 printf (_(" Version need aux past end of section\n"));
252b5132
RH
7494
7495 idx += ent.vn_next;
7496 }
54806181
AM
7497 if (cnt < section->sh_info)
7498 printf (_(" Version need past end of section\n"));
103f02d3 7499
252b5132
RH
7500 free (eneed);
7501 }
7502 break;
7503
7504 case SHT_GNU_versym:
7505 {
2cf0635d 7506 Elf_Internal_Shdr * link_section;
b34976b6
AM
7507 int total;
7508 int cnt;
2cf0635d
NC
7509 unsigned char * edata;
7510 unsigned short * data;
7511 char * strtab;
7512 Elf_Internal_Sym * symbols;
7513 Elf_Internal_Shdr * string_sec;
d3ba0551 7514 long off;
252b5132 7515
4fbb74a6 7516 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
7517 break;
7518
4fbb74a6 7519 link_section = section_headers + section->sh_link;
08d8fa11 7520 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 7521
4fbb74a6 7522 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
7523 break;
7524
252b5132
RH
7525 found = 1;
7526
9ad5cbcf 7527 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 7528
4fbb74a6 7529 string_sec = section_headers + link_section->sh_link;
252b5132 7530
3f5e193b
NC
7531 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
7532 string_sec->sh_size,
7533 _("version string table"));
a6e9f9df
AM
7534 if (!strtab)
7535 break;
252b5132
RH
7536
7537 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
7538 SECTION_NAME (section), total);
7539
7540 printf (_(" Addr: "));
7541 printf_vma (section->sh_addr);
72de5009 7542 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7543 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
7544 SECTION_NAME (link_section));
7545
d3ba0551
AM
7546 off = offset_from_vma (file,
7547 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
7548 total * sizeof (short));
3f5e193b
NC
7549 edata = (unsigned char *) get_data (NULL, file, off, total,
7550 sizeof (short),
7551 _("version symbol data"));
a6e9f9df
AM
7552 if (!edata)
7553 {
7554 free (strtab);
7555 break;
7556 }
252b5132 7557
3f5e193b 7558 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
7559
7560 for (cnt = total; cnt --;)
b34976b6
AM
7561 data[cnt] = byte_get (edata + cnt * sizeof (short),
7562 sizeof (short));
252b5132
RH
7563
7564 free (edata);
7565
7566 for (cnt = 0; cnt < total; cnt += 4)
7567 {
7568 int j, nn;
00d93f34 7569 int check_def, check_need;
2cf0635d 7570 char * name;
252b5132
RH
7571
7572 printf (" %03x:", cnt);
7573
7574 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 7575 switch (data[cnt + j])
252b5132
RH
7576 {
7577 case 0:
7578 fputs (_(" 0 (*local*) "), stdout);
7579 break;
7580
7581 case 1:
7582 fputs (_(" 1 (*global*) "), stdout);
7583 break;
7584
7585 default:
c244d050
NC
7586 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
7587 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 7588
00d93f34
JJ
7589 check_def = 1;
7590 check_need = 1;
4fbb74a6
AM
7591 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
7592 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 7593 != SHT_NOBITS)
252b5132 7594 {
b34976b6 7595 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
7596 check_def = 0;
7597 else
7598 check_need = 0;
252b5132 7599 }
00d93f34
JJ
7600
7601 if (check_need
b34976b6 7602 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 7603 {
b34976b6
AM
7604 Elf_Internal_Verneed ivn;
7605 unsigned long offset;
252b5132 7606
d93f0186
NC
7607 offset = offset_from_vma
7608 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
7609 sizeof (Elf_External_Verneed));
252b5132 7610
b34976b6 7611 do
252b5132 7612 {
b34976b6
AM
7613 Elf_Internal_Vernaux ivna;
7614 Elf_External_Verneed evn;
7615 Elf_External_Vernaux evna;
7616 unsigned long a_off;
252b5132 7617
c256ffe7 7618 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 7619 _("version need"));
252b5132
RH
7620
7621 ivn.vn_aux = BYTE_GET (evn.vn_aux);
7622 ivn.vn_next = BYTE_GET (evn.vn_next);
7623
7624 a_off = offset + ivn.vn_aux;
7625
7626 do
7627 {
a6e9f9df 7628 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 7629 1, _("version need aux (2)"));
252b5132
RH
7630
7631 ivna.vna_next = BYTE_GET (evna.vna_next);
7632 ivna.vna_other = BYTE_GET (evna.vna_other);
7633
7634 a_off += ivna.vna_next;
7635 }
b34976b6 7636 while (ivna.vna_other != data[cnt + j]
252b5132
RH
7637 && ivna.vna_next != 0);
7638
b34976b6 7639 if (ivna.vna_other == data[cnt + j])
252b5132
RH
7640 {
7641 ivna.vna_name = BYTE_GET (evna.vna_name);
7642
54806181
AM
7643 if (ivna.vna_name >= string_sec->sh_size)
7644 name = _("*invalid*");
7645 else
7646 name = strtab + ivna.vna_name;
252b5132 7647 nn += printf ("(%s%-*s",
16062207
ILT
7648 name,
7649 12 - (int) strlen (name),
252b5132 7650 ")");
00d93f34 7651 check_def = 0;
252b5132
RH
7652 break;
7653 }
7654
7655 offset += ivn.vn_next;
7656 }
7657 while (ivn.vn_next);
7658 }
00d93f34 7659
b34976b6
AM
7660 if (check_def && data[cnt + j] != 0x8001
7661 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 7662 {
b34976b6
AM
7663 Elf_Internal_Verdef ivd;
7664 Elf_External_Verdef evd;
7665 unsigned long offset;
252b5132 7666
d93f0186
NC
7667 offset = offset_from_vma
7668 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
7669 sizeof evd);
252b5132
RH
7670
7671 do
7672 {
c256ffe7 7673 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 7674 _("version def"));
252b5132
RH
7675
7676 ivd.vd_next = BYTE_GET (evd.vd_next);
7677 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
7678
7679 offset += ivd.vd_next;
7680 }
c244d050 7681 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
7682 && ivd.vd_next != 0);
7683
c244d050 7684 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 7685 {
b34976b6
AM
7686 Elf_External_Verdaux evda;
7687 Elf_Internal_Verdaux ivda;
252b5132
RH
7688
7689 ivd.vd_aux = BYTE_GET (evd.vd_aux);
7690
a6e9f9df
AM
7691 get_data (&evda, file,
7692 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
7693 sizeof (evda), 1,
7694 _("version def aux"));
252b5132
RH
7695
7696 ivda.vda_name = BYTE_GET (evda.vda_name);
7697
54806181
AM
7698 if (ivda.vda_name >= string_sec->sh_size)
7699 name = _("*invalid*");
7700 else
7701 name = strtab + ivda.vda_name;
252b5132 7702 nn += printf ("(%s%-*s",
16062207
ILT
7703 name,
7704 12 - (int) strlen (name),
252b5132
RH
7705 ")");
7706 }
7707 }
7708
7709 if (nn < 18)
7710 printf ("%*c", 18 - nn, ' ');
7711 }
7712
7713 putchar ('\n');
7714 }
7715
7716 free (data);
7717 free (strtab);
7718 free (symbols);
7719 }
7720 break;
103f02d3 7721
252b5132
RH
7722 default:
7723 break;
7724 }
7725 }
7726
7727 if (! found)
7728 printf (_("\nNo version information found in this file.\n"));
7729
7730 return 1;
7731}
7732
d1133906 7733static const char *
d3ba0551 7734get_symbol_binding (unsigned int binding)
252b5132 7735{
b34976b6 7736 static char buff[32];
252b5132
RH
7737
7738 switch (binding)
7739 {
b34976b6
AM
7740 case STB_LOCAL: return "LOCAL";
7741 case STB_GLOBAL: return "GLOBAL";
7742 case STB_WEAK: return "WEAK";
252b5132
RH
7743 default:
7744 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
7745 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
7746 binding);
252b5132 7747 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
7748 {
7749 if (binding == STB_GNU_UNIQUE
7750 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
7751 /* GNU/Linux is still using the default value 0. */
7752 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
7753 return "UNIQUE";
7754 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
7755 }
252b5132 7756 else
e9e44622 7757 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
7758 return buff;
7759 }
7760}
7761
d1133906 7762static const char *
d3ba0551 7763get_symbol_type (unsigned int type)
252b5132 7764{
b34976b6 7765 static char buff[32];
252b5132
RH
7766
7767 switch (type)
7768 {
b34976b6
AM
7769 case STT_NOTYPE: return "NOTYPE";
7770 case STT_OBJECT: return "OBJECT";
7771 case STT_FUNC: return "FUNC";
7772 case STT_SECTION: return "SECTION";
7773 case STT_FILE: return "FILE";
7774 case STT_COMMON: return "COMMON";
7775 case STT_TLS: return "TLS";
15ab5209
DB
7776 case STT_RELC: return "RELC";
7777 case STT_SRELC: return "SRELC";
252b5132
RH
7778 default:
7779 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
7780 {
7781 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
7782 return "THUMB_FUNC";
7783
351b4b40 7784 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
7785 return "REGISTER";
7786
7787 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
7788 return "PARISC_MILLI";
7789
e9e44622 7790 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 7791 }
252b5132 7792 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
7793 {
7794 if (elf_header.e_machine == EM_PARISC)
7795 {
7796 if (type == STT_HP_OPAQUE)
7797 return "HP_OPAQUE";
7798 if (type == STT_HP_STUB)
7799 return "HP_STUB";
7800 }
7801
d8045f23
NC
7802 if (type == STT_GNU_IFUNC
7803 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
7804 /* GNU/Linux is still using the default value 0. */
7805 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
7806 return "IFUNC";
7807
e9e44622 7808 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 7809 }
252b5132 7810 else
e9e44622 7811 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
7812 return buff;
7813 }
7814}
7815
d1133906 7816static const char *
d3ba0551 7817get_symbol_visibility (unsigned int visibility)
d1133906
NC
7818{
7819 switch (visibility)
7820 {
b34976b6
AM
7821 case STV_DEFAULT: return "DEFAULT";
7822 case STV_INTERNAL: return "INTERNAL";
7823 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
7824 case STV_PROTECTED: return "PROTECTED";
7825 default: abort ();
7826 }
7827}
7828
5e2b0d47
NC
7829static const char *
7830get_mips_symbol_other (unsigned int other)
7831{
7832 switch (other)
7833 {
7834 case STO_OPTIONAL: return "OPTIONAL";
7835 case STO_MIPS16: return "MIPS16";
861fb55a
DJ
7836 case STO_MIPS_PLT: return "MIPS PLT";
7837 case STO_MIPS_PIC: return "MIPS PIC";
5e2b0d47
NC
7838 default: return NULL;
7839 }
7840}
7841
7842static const char *
7843get_symbol_other (unsigned int other)
7844{
7845 const char * result = NULL;
7846 static char buff [32];
7847
7848 if (other == 0)
7849 return "";
7850
7851 switch (elf_header.e_machine)
7852 {
7853 case EM_MIPS:
7854 result = get_mips_symbol_other (other);
7855 default:
7856 break;
7857 }
7858
7859 if (result)
7860 return result;
7861
7862 snprintf (buff, sizeof buff, _("<other>: %x"), other);
7863 return buff;
7864}
7865
d1133906 7866static const char *
d3ba0551 7867get_symbol_index_type (unsigned int type)
252b5132 7868{
b34976b6 7869 static char buff[32];
5cf1065c 7870
252b5132
RH
7871 switch (type)
7872 {
b34976b6
AM
7873 case SHN_UNDEF: return "UND";
7874 case SHN_ABS: return "ABS";
7875 case SHN_COMMON: return "COM";
252b5132 7876 default:
9ce701e2
L
7877 if (type == SHN_IA_64_ANSI_COMMON
7878 && elf_header.e_machine == EM_IA_64
7879 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
7880 return "ANSI_COM";
8a9036a4
L
7881 else if ((elf_header.e_machine == EM_X86_64
7882 || elf_header.e_machine == EM_L1OM)
3b22753a
L
7883 && type == SHN_X86_64_LCOMMON)
7884 return "LARGE_COM";
172553c7
TS
7885 else if (type == SHN_MIPS_SCOMMON
7886 && elf_header.e_machine == EM_MIPS)
7887 return "SCOM";
7888 else if (type == SHN_MIPS_SUNDEFINED
7889 && elf_header.e_machine == EM_MIPS)
7890 return "SUND";
9ce701e2 7891 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 7892 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 7893 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
7894 sprintf (buff, "OS [0x%04x]", type & 0xffff);
7895 else if (type >= SHN_LORESERVE)
7896 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 7897 else
232e7cb8 7898 sprintf (buff, "%3d", type);
5cf1065c 7899 break;
252b5132 7900 }
5cf1065c
NC
7901
7902 return buff;
252b5132
RH
7903}
7904
66543521 7905static bfd_vma *
2cf0635d 7906get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 7907{
2cf0635d
NC
7908 unsigned char * e_data;
7909 bfd_vma * i_data;
252b5132 7910
3f5e193b 7911 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
7912
7913 if (e_data == NULL)
7914 {
7915 error (_("Out of memory\n"));
7916 return NULL;
7917 }
7918
66543521 7919 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
7920 {
7921 error (_("Unable to read in dynamic data\n"));
7922 return NULL;
7923 }
7924
3f5e193b 7925 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
7926
7927 if (i_data == NULL)
7928 {
7929 error (_("Out of memory\n"));
7930 free (e_data);
7931 return NULL;
7932 }
7933
7934 while (number--)
66543521 7935 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
7936
7937 free (e_data);
7938
7939 return i_data;
7940}
7941
6bd1a22c
L
7942static void
7943print_dynamic_symbol (bfd_vma si, unsigned long hn)
7944{
2cf0635d 7945 Elf_Internal_Sym * psym;
6bd1a22c
L
7946 int n;
7947
7948 psym = dynamic_symbols + si;
7949
7950 n = print_vma (si, DEC_5);
7951 if (n < 5)
7952 fputs (" " + n, stdout);
7953 printf (" %3lu: ", hn);
7954 print_vma (psym->st_value, LONG_HEX);
7955 putchar (' ');
7956 print_vma (psym->st_size, DEC_5);
7957
f4be36b3
AM
7958 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7959 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
7960 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
7961 /* Check to see if any other bits in the st_other field are set.
7962 Note - displaying this information disrupts the layout of the
7963 table being generated, but for the moment this case is very
7964 rare. */
7965 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7966 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
7967 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
7968 if (VALID_DYNAMIC_NAME (psym->st_name))
7969 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
7970 else
7971 printf (" <corrupt: %14ld>", psym->st_name);
7972 putchar ('\n');
7973}
7974
e3c8793a 7975/* Dump the symbol table. */
252b5132 7976static int
2cf0635d 7977process_symbol_table (FILE * file)
252b5132 7978{
2cf0635d 7979 Elf_Internal_Shdr * section;
66543521
AM
7980 bfd_vma nbuckets = 0;
7981 bfd_vma nchains = 0;
2cf0635d
NC
7982 bfd_vma * buckets = NULL;
7983 bfd_vma * chains = NULL;
fdc90cb4 7984 bfd_vma ngnubuckets = 0;
2cf0635d
NC
7985 bfd_vma * gnubuckets = NULL;
7986 bfd_vma * gnuchains = NULL;
6bd1a22c 7987 bfd_vma gnusymidx = 0;
252b5132 7988
2c610e4b 7989 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
7990 return 1;
7991
6bd1a22c
L
7992 if (dynamic_info[DT_HASH]
7993 && (do_histogram
2c610e4b
L
7994 || (do_using_dynamic
7995 && !do_dyn_syms
7996 && dynamic_strings != NULL)))
252b5132 7997 {
66543521
AM
7998 unsigned char nb[8];
7999 unsigned char nc[8];
8000 int hash_ent_size = 4;
8001
8002 if ((elf_header.e_machine == EM_ALPHA
8003 || elf_header.e_machine == EM_S390
8004 || elf_header.e_machine == EM_S390_OLD)
8005 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
8006 hash_ent_size = 8;
8007
fb52b2f4
NC
8008 if (fseek (file,
8009 (archive_file_offset
8010 + offset_from_vma (file, dynamic_info[DT_HASH],
8011 sizeof nb + sizeof nc)),
d93f0186 8012 SEEK_SET))
252b5132 8013 {
591a748a 8014 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8015 goto no_hash;
252b5132
RH
8016 }
8017
66543521 8018 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
8019 {
8020 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8021 goto no_hash;
252b5132
RH
8022 }
8023
66543521 8024 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
8025 {
8026 error (_("Failed to read in number of chains\n"));
d3a44ec6 8027 goto no_hash;
252b5132
RH
8028 }
8029
66543521
AM
8030 nbuckets = byte_get (nb, hash_ent_size);
8031 nchains = byte_get (nc, hash_ent_size);
252b5132 8032
66543521
AM
8033 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
8034 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 8035
d3a44ec6 8036 no_hash:
252b5132 8037 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
8038 {
8039 if (do_using_dynamic)
8040 return 0;
8041 free (buckets);
8042 free (chains);
8043 buckets = NULL;
8044 chains = NULL;
8045 nbuckets = 0;
8046 nchains = 0;
8047 }
252b5132
RH
8048 }
8049
6bd1a22c
L
8050 if (dynamic_info_DT_GNU_HASH
8051 && (do_histogram
2c610e4b
L
8052 || (do_using_dynamic
8053 && !do_dyn_syms
8054 && dynamic_strings != NULL)))
252b5132 8055 {
6bd1a22c
L
8056 unsigned char nb[16];
8057 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
8058 bfd_vma buckets_vma;
8059
8060 if (fseek (file,
8061 (archive_file_offset
8062 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
8063 sizeof nb)),
8064 SEEK_SET))
8065 {
8066 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8067 goto no_gnu_hash;
6bd1a22c 8068 }
252b5132 8069
6bd1a22c
L
8070 if (fread (nb, 16, 1, file) != 1)
8071 {
8072 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8073 goto no_gnu_hash;
6bd1a22c
L
8074 }
8075
8076 ngnubuckets = byte_get (nb, 4);
8077 gnusymidx = byte_get (nb + 4, 4);
8078 bitmaskwords = byte_get (nb + 8, 4);
8079 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 8080 if (is_32bit_elf)
6bd1a22c 8081 buckets_vma += bitmaskwords * 4;
f7a99963 8082 else
6bd1a22c 8083 buckets_vma += bitmaskwords * 8;
252b5132 8084
6bd1a22c
L
8085 if (fseek (file,
8086 (archive_file_offset
8087 + offset_from_vma (file, buckets_vma, 4)),
8088 SEEK_SET))
252b5132 8089 {
6bd1a22c 8090 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8091 goto no_gnu_hash;
6bd1a22c
L
8092 }
8093
8094 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 8095
6bd1a22c 8096 if (gnubuckets == NULL)
d3a44ec6 8097 goto no_gnu_hash;
6bd1a22c
L
8098
8099 for (i = 0; i < ngnubuckets; i++)
8100 if (gnubuckets[i] != 0)
8101 {
8102 if (gnubuckets[i] < gnusymidx)
8103 return 0;
8104
8105 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
8106 maxchain = gnubuckets[i];
8107 }
8108
8109 if (maxchain == 0xffffffff)
d3a44ec6 8110 goto no_gnu_hash;
6bd1a22c
L
8111
8112 maxchain -= gnusymidx;
8113
8114 if (fseek (file,
8115 (archive_file_offset
8116 + offset_from_vma (file, buckets_vma
8117 + 4 * (ngnubuckets + maxchain), 4)),
8118 SEEK_SET))
8119 {
8120 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8121 goto no_gnu_hash;
6bd1a22c
L
8122 }
8123
8124 do
8125 {
8126 if (fread (nb, 4, 1, file) != 1)
252b5132 8127 {
6bd1a22c 8128 error (_("Failed to determine last chain length\n"));
d3a44ec6 8129 goto no_gnu_hash;
6bd1a22c 8130 }
252b5132 8131
6bd1a22c 8132 if (maxchain + 1 == 0)
d3a44ec6 8133 goto no_gnu_hash;
252b5132 8134
6bd1a22c
L
8135 ++maxchain;
8136 }
8137 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 8138
6bd1a22c
L
8139 if (fseek (file,
8140 (archive_file_offset
8141 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
8142 SEEK_SET))
8143 {
8144 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8145 goto no_gnu_hash;
6bd1a22c
L
8146 }
8147
8148 gnuchains = get_dynamic_data (file, maxchain, 4);
8149
d3a44ec6 8150 no_gnu_hash:
6bd1a22c 8151 if (gnuchains == NULL)
d3a44ec6
JJ
8152 {
8153 free (gnubuckets);
d3a44ec6
JJ
8154 gnubuckets = NULL;
8155 ngnubuckets = 0;
f64fddf1
NC
8156 if (do_using_dynamic)
8157 return 0;
d3a44ec6 8158 }
6bd1a22c
L
8159 }
8160
8161 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
8162 && do_syms
8163 && do_using_dynamic
8164 && dynamic_strings != NULL)
8165 {
8166 unsigned long hn;
8167
8168 if (dynamic_info[DT_HASH])
8169 {
8170 bfd_vma si;
8171
8172 printf (_("\nSymbol table for image:\n"));
8173 if (is_32bit_elf)
8174 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8175 else
8176 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8177
8178 for (hn = 0; hn < nbuckets; hn++)
8179 {
8180 if (! buckets[hn])
8181 continue;
8182
8183 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
8184 print_dynamic_symbol (si, hn);
252b5132
RH
8185 }
8186 }
6bd1a22c
L
8187
8188 if (dynamic_info_DT_GNU_HASH)
8189 {
8190 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
8191 if (is_32bit_elf)
8192 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8193 else
8194 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8195
8196 for (hn = 0; hn < ngnubuckets; ++hn)
8197 if (gnubuckets[hn] != 0)
8198 {
8199 bfd_vma si = gnubuckets[hn];
8200 bfd_vma off = si - gnusymidx;
8201
8202 do
8203 {
8204 print_dynamic_symbol (si, hn);
8205 si++;
8206 }
8207 while ((gnuchains[off++] & 1) == 0);
8208 }
8209 }
252b5132 8210 }
2c610e4b 8211 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 8212 {
b34976b6 8213 unsigned int i;
252b5132
RH
8214
8215 for (i = 0, section = section_headers;
8216 i < elf_header.e_shnum;
8217 i++, section++)
8218 {
b34976b6 8219 unsigned int si;
2cf0635d 8220 char * strtab = NULL;
c256ffe7 8221 unsigned long int strtab_size = 0;
2cf0635d
NC
8222 Elf_Internal_Sym * symtab;
8223 Elf_Internal_Sym * psym;
252b5132 8224
2c610e4b
L
8225 if ((section->sh_type != SHT_SYMTAB
8226 && section->sh_type != SHT_DYNSYM)
8227 || (!do_syms
8228 && section->sh_type == SHT_SYMTAB))
252b5132
RH
8229 continue;
8230
8231 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
8232 SECTION_NAME (section),
8233 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 8234 if (is_32bit_elf)
ca47b30c 8235 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 8236 else
ca47b30c 8237 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 8238
9ad5cbcf 8239 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
8240 if (symtab == NULL)
8241 continue;
8242
8243 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
8244 {
8245 strtab = string_table;
8246 strtab_size = string_table_length;
8247 }
4fbb74a6 8248 else if (section->sh_link < elf_header.e_shnum)
252b5132 8249 {
2cf0635d 8250 Elf_Internal_Shdr * string_sec;
252b5132 8251
4fbb74a6 8252 string_sec = section_headers + section->sh_link;
252b5132 8253
3f5e193b
NC
8254 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
8255 1, string_sec->sh_size,
8256 _("string table"));
c256ffe7 8257 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
8258 }
8259
8260 for (si = 0, psym = symtab;
8261 si < section->sh_size / section->sh_entsize;
b34976b6 8262 si++, psym++)
252b5132 8263 {
5e220199 8264 printf ("%6d: ", si);
f7a99963
NC
8265 print_vma (psym->st_value, LONG_HEX);
8266 putchar (' ');
8267 print_vma (psym->st_size, DEC_5);
d1133906
NC
8268 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8269 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 8270 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
8271 /* Check to see if any other bits in the st_other field are set.
8272 Note - displaying this information disrupts the layout of the
8273 table being generated, but for the moment this case is very rare. */
8274 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8275 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 8276 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7
JJ
8277 print_symbol (25, psym->st_name < strtab_size
8278 ? strtab + psym->st_name : "<corrupt>");
252b5132
RH
8279
8280 if (section->sh_type == SHT_DYNSYM &&
b34976b6 8281 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 8282 {
b34976b6
AM
8283 unsigned char data[2];
8284 unsigned short vers_data;
8285 unsigned long offset;
8286 int is_nobits;
8287 int check_def;
252b5132 8288
d93f0186
NC
8289 offset = offset_from_vma
8290 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8291 sizeof data + si * sizeof (vers_data));
252b5132 8292
a6e9f9df 8293 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 8294 sizeof (data), 1, _("version data"));
252b5132
RH
8295
8296 vers_data = byte_get (data, 2);
8297
4fbb74a6
AM
8298 is_nobits = (psym->st_shndx < elf_header.e_shnum
8299 && section_headers[psym->st_shndx].sh_type
c256ffe7 8300 == SHT_NOBITS);
252b5132
RH
8301
8302 check_def = (psym->st_shndx != SHN_UNDEF);
8303
c244d050 8304 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 8305 {
b34976b6 8306 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 8307 && (is_nobits || ! check_def))
252b5132 8308 {
b34976b6
AM
8309 Elf_External_Verneed evn;
8310 Elf_Internal_Verneed ivn;
8311 Elf_Internal_Vernaux ivna;
252b5132
RH
8312
8313 /* We must test both. */
d93f0186
NC
8314 offset = offset_from_vma
8315 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8316 sizeof evn);
252b5132 8317
252b5132
RH
8318 do
8319 {
b34976b6 8320 unsigned long vna_off;
252b5132 8321
c256ffe7 8322 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 8323 _("version need"));
dd27201e
L
8324
8325 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8326 ivn.vn_next = BYTE_GET (evn.vn_next);
8327
252b5132
RH
8328 vna_off = offset + ivn.vn_aux;
8329
8330 do
8331 {
b34976b6 8332 Elf_External_Vernaux evna;
252b5132 8333
a6e9f9df 8334 get_data (&evna, file, vna_off,
c256ffe7 8335 sizeof (evna), 1,
a6e9f9df 8336 _("version need aux (3)"));
252b5132
RH
8337
8338 ivna.vna_other = BYTE_GET (evna.vna_other);
8339 ivna.vna_next = BYTE_GET (evna.vna_next);
8340 ivna.vna_name = BYTE_GET (evna.vna_name);
8341
8342 vna_off += ivna.vna_next;
8343 }
8344 while (ivna.vna_other != vers_data
8345 && ivna.vna_next != 0);
8346
8347 if (ivna.vna_other == vers_data)
8348 break;
8349
8350 offset += ivn.vn_next;
8351 }
8352 while (ivn.vn_next != 0);
8353
8354 if (ivna.vna_other == vers_data)
8355 {
8356 printf ("@%s (%d)",
c256ffe7
JJ
8357 ivna.vna_name < strtab_size
8358 ? strtab + ivna.vna_name : "<corrupt>",
8359 ivna.vna_other);
252b5132
RH
8360 check_def = 0;
8361 }
8362 else if (! is_nobits)
591a748a 8363 error (_("bad dynamic symbol\n"));
252b5132
RH
8364 else
8365 check_def = 1;
8366 }
8367
8368 if (check_def)
8369 {
00d93f34 8370 if (vers_data != 0x8001
b34976b6 8371 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8372 {
b34976b6
AM
8373 Elf_Internal_Verdef ivd;
8374 Elf_Internal_Verdaux ivda;
8375 Elf_External_Verdaux evda;
91d6fa6a 8376 unsigned long off;
252b5132 8377
91d6fa6a 8378 off = offset_from_vma
d93f0186
NC
8379 (file,
8380 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8381 sizeof (Elf_External_Verdef));
252b5132
RH
8382
8383 do
8384 {
b34976b6 8385 Elf_External_Verdef evd;
252b5132 8386
91d6fa6a 8387 get_data (&evd, file, off, sizeof (evd),
c256ffe7 8388 1, _("version def"));
252b5132 8389
b34976b6
AM
8390 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8391 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
8392 ivd.vd_next = BYTE_GET (evd.vd_next);
8393
91d6fa6a 8394 off += ivd.vd_next;
252b5132 8395 }
c244d050 8396 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
8397 && ivd.vd_next != 0);
8398
91d6fa6a
NC
8399 off -= ivd.vd_next;
8400 off += ivd.vd_aux;
252b5132 8401
91d6fa6a 8402 get_data (&evda, file, off, sizeof (evda),
c256ffe7 8403 1, _("version def aux"));
252b5132
RH
8404
8405 ivda.vda_name = BYTE_GET (evda.vda_name);
8406
8407 if (psym->st_name != ivda.vda_name)
c244d050 8408 printf ((vers_data & VERSYM_HIDDEN)
252b5132 8409 ? "@%s" : "@@%s",
c256ffe7
JJ
8410 ivda.vda_name < strtab_size
8411 ? strtab + ivda.vda_name : "<corrupt>");
252b5132
RH
8412 }
8413 }
8414 }
8415 }
8416
8417 putchar ('\n');
8418 }
8419
8420 free (symtab);
8421 if (strtab != string_table)
8422 free (strtab);
8423 }
8424 }
8425 else if (do_syms)
8426 printf
8427 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
8428
8429 if (do_histogram && buckets != NULL)
8430 {
2cf0635d
NC
8431 unsigned long * lengths;
8432 unsigned long * counts;
66543521
AM
8433 unsigned long hn;
8434 bfd_vma si;
8435 unsigned long maxlength = 0;
8436 unsigned long nzero_counts = 0;
8437 unsigned long nsyms = 0;
252b5132 8438
66543521
AM
8439 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
8440 (unsigned long) nbuckets);
252b5132
RH
8441 printf (_(" Length Number %% of total Coverage\n"));
8442
3f5e193b 8443 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
8444 if (lengths == NULL)
8445 {
591a748a 8446 error (_("Out of memory\n"));
252b5132
RH
8447 return 0;
8448 }
8449 for (hn = 0; hn < nbuckets; ++hn)
8450 {
f7a99963 8451 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 8452 {
b34976b6 8453 ++nsyms;
252b5132 8454 if (maxlength < ++lengths[hn])
b34976b6 8455 ++maxlength;
252b5132
RH
8456 }
8457 }
8458
3f5e193b 8459 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
8460 if (counts == NULL)
8461 {
591a748a 8462 error (_("Out of memory\n"));
252b5132
RH
8463 return 0;
8464 }
8465
8466 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 8467 ++counts[lengths[hn]];
252b5132 8468
103f02d3 8469 if (nbuckets > 0)
252b5132 8470 {
66543521
AM
8471 unsigned long i;
8472 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 8473 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 8474 for (i = 1; i <= maxlength; ++i)
103f02d3 8475 {
66543521
AM
8476 nzero_counts += counts[i] * i;
8477 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
8478 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
8479 (nzero_counts * 100.0) / nsyms);
8480 }
252b5132
RH
8481 }
8482
8483 free (counts);
8484 free (lengths);
8485 }
8486
8487 if (buckets != NULL)
8488 {
8489 free (buckets);
8490 free (chains);
8491 }
8492
d3a44ec6 8493 if (do_histogram && gnubuckets != NULL)
fdc90cb4 8494 {
2cf0635d
NC
8495 unsigned long * lengths;
8496 unsigned long * counts;
fdc90cb4
JJ
8497 unsigned long hn;
8498 unsigned long maxlength = 0;
8499 unsigned long nzero_counts = 0;
8500 unsigned long nsyms = 0;
fdc90cb4 8501
3f5e193b 8502 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
8503 if (lengths == NULL)
8504 {
591a748a 8505 error (_("Out of memory\n"));
fdc90cb4
JJ
8506 return 0;
8507 }
8508
8509 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
8510 (unsigned long) ngnubuckets);
8511 printf (_(" Length Number %% of total Coverage\n"));
8512
8513 for (hn = 0; hn < ngnubuckets; ++hn)
8514 if (gnubuckets[hn] != 0)
8515 {
8516 bfd_vma off, length = 1;
8517
6bd1a22c 8518 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
8519 (gnuchains[off] & 1) == 0; ++off)
8520 ++length;
8521 lengths[hn] = length;
8522 if (length > maxlength)
8523 maxlength = length;
8524 nsyms += length;
8525 }
8526
3f5e193b 8527 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
8528 if (counts == NULL)
8529 {
591a748a 8530 error (_("Out of memory\n"));
fdc90cb4
JJ
8531 return 0;
8532 }
8533
8534 for (hn = 0; hn < ngnubuckets; ++hn)
8535 ++counts[lengths[hn]];
8536
8537 if (ngnubuckets > 0)
8538 {
8539 unsigned long j;
8540 printf (" 0 %-10lu (%5.1f%%)\n",
8541 counts[0], (counts[0] * 100.0) / ngnubuckets);
8542 for (j = 1; j <= maxlength; ++j)
8543 {
8544 nzero_counts += counts[j] * j;
8545 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
8546 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
8547 (nzero_counts * 100.0) / nsyms);
8548 }
8549 }
8550
8551 free (counts);
8552 free (lengths);
8553 free (gnubuckets);
8554 free (gnuchains);
8555 }
8556
252b5132
RH
8557 return 1;
8558}
8559
8560static int
2cf0635d 8561process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 8562{
b4c96d0d 8563 unsigned int i;
252b5132
RH
8564
8565 if (dynamic_syminfo == NULL
8566 || !do_dynamic)
8567 /* No syminfo, this is ok. */
8568 return 1;
8569
8570 /* There better should be a dynamic symbol section. */
8571 if (dynamic_symbols == NULL || dynamic_strings == NULL)
8572 return 0;
8573
8574 if (dynamic_addr)
8575 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
8576 dynamic_syminfo_offset, dynamic_syminfo_nent);
8577
8578 printf (_(" Num: Name BoundTo Flags\n"));
8579 for (i = 0; i < dynamic_syminfo_nent; ++i)
8580 {
8581 unsigned short int flags = dynamic_syminfo[i].si_flags;
8582
31104126 8583 printf ("%4d: ", i);
d79b3d50
NC
8584 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
8585 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
8586 else
8587 printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
31104126 8588 putchar (' ');
252b5132
RH
8589
8590 switch (dynamic_syminfo[i].si_boundto)
8591 {
8592 case SYMINFO_BT_SELF:
8593 fputs ("SELF ", stdout);
8594 break;
8595 case SYMINFO_BT_PARENT:
8596 fputs ("PARENT ", stdout);
8597 break;
8598 default:
8599 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
8600 && dynamic_syminfo[i].si_boundto < dynamic_nent
8601 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 8602 {
d79b3d50 8603 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
8604 putchar (' ' );
8605 }
252b5132
RH
8606 else
8607 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
8608 break;
8609 }
8610
8611 if (flags & SYMINFO_FLG_DIRECT)
8612 printf (" DIRECT");
8613 if (flags & SYMINFO_FLG_PASSTHRU)
8614 printf (" PASSTHRU");
8615 if (flags & SYMINFO_FLG_COPY)
8616 printf (" COPY");
8617 if (flags & SYMINFO_FLG_LAZYLOAD)
8618 printf (" LAZYLOAD");
8619
8620 puts ("");
8621 }
8622
8623 return 1;
8624}
8625
cf13d699
NC
8626/* Check to see if the given reloc needs to be handled in a target specific
8627 manner. If so then process the reloc and return TRUE otherwise return
8628 FALSE. */
09c11c86 8629
cf13d699
NC
8630static bfd_boolean
8631target_specific_reloc_handling (Elf_Internal_Rela * reloc,
8632 unsigned char * start,
8633 Elf_Internal_Sym * symtab)
252b5132 8634{
cf13d699 8635 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 8636
cf13d699 8637 switch (elf_header.e_machine)
252b5132 8638 {
cf13d699
NC
8639 case EM_MN10300:
8640 case EM_CYGNUS_MN10300:
8641 {
8642 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 8643
cf13d699
NC
8644 switch (reloc_type)
8645 {
8646 case 34: /* R_MN10300_ALIGN */
8647 return TRUE;
8648 case 33: /* R_MN10300_SYM_DIFF */
8649 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
8650 return TRUE;
8651 case 1: /* R_MN10300_32 */
8652 case 2: /* R_MN10300_16 */
8653 if (saved_sym != NULL)
8654 {
8655 bfd_vma value;
252b5132 8656
cf13d699
NC
8657 value = reloc->r_addend
8658 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
8659 - saved_sym->st_value);
252b5132 8660
cf13d699 8661 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 8662
cf13d699
NC
8663 saved_sym = NULL;
8664 return TRUE;
8665 }
8666 break;
8667 default:
8668 if (saved_sym != NULL)
8669 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
8670 break;
8671 }
8672 break;
8673 }
252b5132
RH
8674 }
8675
cf13d699 8676 return FALSE;
252b5132
RH
8677}
8678
aca88567
NC
8679/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
8680 DWARF debug sections. This is a target specific test. Note - we do not
8681 go through the whole including-target-headers-multiple-times route, (as
8682 we have already done with <elf/h8.h>) because this would become very
8683 messy and even then this function would have to contain target specific
8684 information (the names of the relocs instead of their numeric values).
8685 FIXME: This is not the correct way to solve this problem. The proper way
8686 is to have target specific reloc sizing and typing functions created by
8687 the reloc-macros.h header, in the same way that it already creates the
8688 reloc naming functions. */
8689
8690static bfd_boolean
8691is_32bit_abs_reloc (unsigned int reloc_type)
8692{
8693 switch (elf_header.e_machine)
8694 {
41e92641
NC
8695 case EM_386:
8696 case EM_486:
8697 return reloc_type == 1; /* R_386_32. */
aca88567
NC
8698 case EM_68K:
8699 return reloc_type == 1; /* R_68K_32. */
8700 case EM_860:
8701 return reloc_type == 1; /* R_860_32. */
8702 case EM_ALPHA:
8703 return reloc_type == 1; /* XXX Is this right ? */
41e92641
NC
8704 case EM_ARC:
8705 return reloc_type == 1; /* R_ARC_32. */
8706 case EM_ARM:
8707 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 8708 case EM_AVR_OLD:
aca88567
NC
8709 case EM_AVR:
8710 return reloc_type == 1;
8711 case EM_BLACKFIN:
8712 return reloc_type == 0x12; /* R_byte4_data. */
8713 case EM_CRIS:
8714 return reloc_type == 3; /* R_CRIS_32. */
8715 case EM_CR16:
6c03b1ed 8716 case EM_CR16_OLD:
aca88567
NC
8717 return reloc_type == 3; /* R_CR16_NUM32. */
8718 case EM_CRX:
8719 return reloc_type == 15; /* R_CRX_NUM32. */
8720 case EM_CYGNUS_FRV:
8721 return reloc_type == 1;
41e92641
NC
8722 case EM_CYGNUS_D10V:
8723 case EM_D10V:
8724 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
8725 case EM_CYGNUS_D30V:
8726 case EM_D30V:
8727 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
8728 case EM_DLX:
8729 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
8730 case EM_CYGNUS_FR30:
8731 case EM_FR30:
8732 return reloc_type == 3; /* R_FR30_32. */
8733 case EM_H8S:
8734 case EM_H8_300:
8735 case EM_H8_300H:
8736 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
8737 case EM_IA_64:
8738 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
8739 case EM_IP2K_OLD:
8740 case EM_IP2K:
8741 return reloc_type == 2; /* R_IP2K_32. */
8742 case EM_IQ2000:
8743 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
8744 case EM_LATTICEMICO32:
8745 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 8746 case EM_M32C_OLD:
aca88567
NC
8747 case EM_M32C:
8748 return reloc_type == 3; /* R_M32C_32. */
8749 case EM_M32R:
8750 return reloc_type == 34; /* R_M32R_32_RELA. */
8751 case EM_MCORE:
8752 return reloc_type == 1; /* R_MCORE_ADDR32. */
8753 case EM_CYGNUS_MEP:
8754 return reloc_type == 4; /* R_MEP_32. */
8755 case EM_MIPS:
8756 return reloc_type == 2; /* R_MIPS_32. */
8757 case EM_MMIX:
8758 return reloc_type == 4; /* R_MMIX_32. */
8759 case EM_CYGNUS_MN10200:
8760 case EM_MN10200:
8761 return reloc_type == 1; /* R_MN10200_32. */
8762 case EM_CYGNUS_MN10300:
8763 case EM_MN10300:
8764 return reloc_type == 1; /* R_MN10300_32. */
8765 case EM_MSP430_OLD:
8766 case EM_MSP430:
8767 return reloc_type == 1; /* R_MSP43_32. */
8768 case EM_MT:
8769 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
8770 case EM_ALTERA_NIOS2:
8771 case EM_NIOS32:
8772 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
8773 case EM_OPENRISC:
8774 case EM_OR32:
8775 return reloc_type == 1; /* R_OR32_32. */
aca88567 8776 case EM_PARISC:
5fda8eca
NC
8777 return (reloc_type == 1 /* R_PARISC_DIR32. */
8778 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
8779 case EM_PJ:
8780 case EM_PJ_OLD:
8781 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
8782 case EM_PPC64:
8783 return reloc_type == 1; /* R_PPC64_ADDR32. */
8784 case EM_PPC:
8785 return reloc_type == 1; /* R_PPC_ADDR32. */
c7927a3c
NC
8786 case EM_RX:
8787 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
8788 case EM_S370:
8789 return reloc_type == 1; /* R_I370_ADDR31. */
8790 case EM_S390_OLD:
8791 case EM_S390:
8792 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
8793 case EM_SCORE:
8794 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
8795 case EM_SH:
8796 return reloc_type == 1; /* R_SH_DIR32. */
8797 case EM_SPARC32PLUS:
8798 case EM_SPARCV9:
8799 case EM_SPARC:
8800 return reloc_type == 3 /* R_SPARC_32. */
8801 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
8802 case EM_SPU:
8803 return reloc_type == 6; /* R_SPU_ADDR32 */
aca88567
NC
8804 case EM_CYGNUS_V850:
8805 case EM_V850:
8806 return reloc_type == 6; /* R_V850_ABS32. */
8807 case EM_VAX:
8808 return reloc_type == 1; /* R_VAX_32. */
8809 case EM_X86_64:
8a9036a4 8810 case EM_L1OM:
aca88567 8811 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
8812 case EM_XC16X:
8813 case EM_C166:
8814 return reloc_type == 3; /* R_XC16C_ABS_32. */
aca88567
NC
8815 case EM_XSTORMY16:
8816 return reloc_type == 1; /* R_XSTROMY16_32. */
8817 case EM_XTENSA_OLD:
8818 case EM_XTENSA:
8819 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
8820 default:
8821 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
8822 elf_header.e_machine);
8823 abort ();
8824 }
8825}
8826
8827/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8828 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
8829
8830static bfd_boolean
8831is_32bit_pcrel_reloc (unsigned int reloc_type)
8832{
8833 switch (elf_header.e_machine)
8834 {
41e92641
NC
8835 case EM_386:
8836 case EM_486:
3e0873ac 8837 return reloc_type == 2; /* R_386_PC32. */
aca88567 8838 case EM_68K:
3e0873ac 8839 return reloc_type == 4; /* R_68K_PC32. */
aca88567
NC
8840 case EM_ALPHA:
8841 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 8842 case EM_ARM:
3e0873ac 8843 return reloc_type == 3; /* R_ARM_REL32 */
aca88567 8844 case EM_PARISC:
85acf597 8845 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
8846 case EM_PPC:
8847 return reloc_type == 26; /* R_PPC_REL32. */
8848 case EM_PPC64:
3e0873ac 8849 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
8850 case EM_S390_OLD:
8851 case EM_S390:
3e0873ac 8852 return reloc_type == 5; /* R_390_PC32. */
aca88567 8853 case EM_SH:
3e0873ac 8854 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
8855 case EM_SPARC32PLUS:
8856 case EM_SPARCV9:
8857 case EM_SPARC:
3e0873ac 8858 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
8859 case EM_SPU:
8860 return reloc_type == 13; /* R_SPU_REL32. */
aca88567 8861 case EM_X86_64:
8a9036a4 8862 case EM_L1OM:
3e0873ac 8863 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
8864 case EM_XTENSA_OLD:
8865 case EM_XTENSA:
8866 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
8867 default:
8868 /* Do not abort or issue an error message here. Not all targets use
8869 pc-relative 32-bit relocs in their DWARF debug information and we
8870 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
8871 more helpful warning message will be generated by apply_relocations
8872 anyway, so just return. */
aca88567
NC
8873 return FALSE;
8874 }
8875}
8876
8877/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8878 a 64-bit absolute RELA relocation used in DWARF debug sections. */
8879
8880static bfd_boolean
8881is_64bit_abs_reloc (unsigned int reloc_type)
8882{
8883 switch (elf_header.e_machine)
8884 {
8885 case EM_ALPHA:
8886 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
8887 case EM_IA_64:
8888 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
8889 case EM_PARISC:
8890 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
8891 case EM_PPC64:
8892 return reloc_type == 38; /* R_PPC64_ADDR64. */
8893 case EM_SPARC32PLUS:
8894 case EM_SPARCV9:
8895 case EM_SPARC:
8896 return reloc_type == 54; /* R_SPARC_UA64. */
8897 case EM_X86_64:
8a9036a4 8898 case EM_L1OM:
aca88567 8899 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
8900 case EM_S390_OLD:
8901 case EM_S390:
8902 return reloc_type == 22; /* R_S390_64 */
85a82265
AM
8903 case EM_MIPS:
8904 return reloc_type == 18; /* R_MIPS_64 */
aca88567
NC
8905 default:
8906 return FALSE;
8907 }
8908}
8909
85acf597
RH
8910/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
8911 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
8912
8913static bfd_boolean
8914is_64bit_pcrel_reloc (unsigned int reloc_type)
8915{
8916 switch (elf_header.e_machine)
8917 {
8918 case EM_ALPHA:
8919 return reloc_type == 11; /* R_ALPHA_SREL64 */
8920 case EM_IA_64:
8921 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB */
8922 case EM_PARISC:
8923 return reloc_type == 72; /* R_PARISC_PCREL64 */
8924 case EM_PPC64:
8925 return reloc_type == 44; /* R_PPC64_REL64 */
8926 case EM_SPARC32PLUS:
8927 case EM_SPARCV9:
8928 case EM_SPARC:
8929 return reloc_type == 46; /* R_SPARC_DISP64 */
8930 case EM_X86_64:
8a9036a4 8931 case EM_L1OM:
85acf597
RH
8932 return reloc_type == 24; /* R_X86_64_PC64 */
8933 case EM_S390_OLD:
8934 case EM_S390:
8935 return reloc_type == 23; /* R_S390_PC64 */
8936 default:
8937 return FALSE;
8938 }
8939}
8940
4dc3c23d
AM
8941/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8942 a 24-bit absolute RELA relocation used in DWARF debug sections. */
8943
8944static bfd_boolean
8945is_24bit_abs_reloc (unsigned int reloc_type)
8946{
8947 switch (elf_header.e_machine)
8948 {
8949 case EM_CYGNUS_MN10200:
8950 case EM_MN10200:
8951 return reloc_type == 4; /* R_MN10200_24. */
8952 default:
8953 return FALSE;
8954 }
8955}
8956
aca88567
NC
8957/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8958 a 16-bit absolute RELA relocation used in DWARF debug sections. */
8959
8960static bfd_boolean
8961is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
8962{
8963 switch (elf_header.e_machine)
8964 {
aca88567
NC
8965 case EM_AVR_OLD:
8966 case EM_AVR:
8967 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
8968 case EM_CYGNUS_D10V:
8969 case EM_D10V:
8970 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
8971 case EM_H8S:
8972 case EM_H8_300:
8973 case EM_H8_300H:
aca88567
NC
8974 return reloc_type == R_H8_DIR16;
8975 case EM_IP2K_OLD:
8976 case EM_IP2K:
8977 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 8978 case EM_M32C_OLD:
f4236fe4
DD
8979 case EM_M32C:
8980 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
8981 case EM_MSP430_OLD:
8982 case EM_MSP430:
8983 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
8984 case EM_ALTERA_NIOS2:
8985 case EM_NIOS32:
8986 return reloc_type == 9; /* R_NIOS_16. */
c29aca4a
NC
8987 case EM_XC16X:
8988 case EM_C166:
8989 return reloc_type == 2; /* R_XC16C_ABS_16. */
4b78141a 8990 default:
aca88567 8991 return FALSE;
4b78141a
NC
8992 }
8993}
8994
2a7b2e88
JK
8995/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
8996 relocation entries (possibly formerly used for SHT_GROUP sections). */
8997
8998static bfd_boolean
8999is_none_reloc (unsigned int reloc_type)
9000{
9001 switch (elf_header.e_machine)
9002 {
cb8f3167
NC
9003 case EM_68K: /* R_68K_NONE. */
9004 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
9005 case EM_SPARC32PLUS:
9006 case EM_SPARCV9:
cb8f3167
NC
9007 case EM_SPARC: /* R_SPARC_NONE. */
9008 case EM_MIPS: /* R_MIPS_NONE. */
9009 case EM_PARISC: /* R_PARISC_NONE. */
9010 case EM_ALPHA: /* R_ALPHA_NONE. */
9011 case EM_PPC: /* R_PPC_NONE. */
9012 case EM_PPC64: /* R_PPC64_NONE. */
9013 case EM_ARM: /* R_ARM_NONE. */
9014 case EM_IA_64: /* R_IA64_NONE. */
9015 case EM_SH: /* R_SH_NONE. */
2a7b2e88 9016 case EM_S390_OLD:
cb8f3167
NC
9017 case EM_S390: /* R_390_NONE. */
9018 case EM_CRIS: /* R_CRIS_NONE. */
9019 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 9020 case EM_L1OM: /* R_X86_64_NONE. */
cb8f3167
NC
9021 case EM_MN10300: /* R_MN10300_NONE. */
9022 case EM_M32R: /* R_M32R_NONE. */
c29aca4a
NC
9023 case EM_XC16X:
9024 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 9025 return reloc_type == 0;
58332dda
JK
9026 case EM_XTENSA_OLD:
9027 case EM_XTENSA:
4dc3c23d
AM
9028 return (reloc_type == 0 /* R_XTENSA_NONE. */
9029 || reloc_type == 17 /* R_XTENSA_DIFF8. */
9030 || reloc_type == 18 /* R_XTENSA_DIFF16. */
9031 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
9032 }
9033 return FALSE;
9034}
9035
cf13d699
NC
9036/* Apply relocations to a section.
9037 Note: So far support has been added only for those relocations
9038 which can be found in debug sections.
9039 FIXME: Add support for more relocations ? */
1b315056 9040
cf13d699
NC
9041static void
9042apply_relocations (void * file,
9043 Elf_Internal_Shdr * section,
9044 unsigned char * start)
1b315056 9045{
cf13d699
NC
9046 Elf_Internal_Shdr * relsec;
9047 unsigned char * end = start + section->sh_size;
cb8f3167 9048
cf13d699
NC
9049 if (elf_header.e_type != ET_REL)
9050 return;
1b315056 9051
cf13d699 9052 /* Find the reloc section associated with the section. */
5b18a4bc
NC
9053 for (relsec = section_headers;
9054 relsec < section_headers + elf_header.e_shnum;
9055 ++relsec)
252b5132 9056 {
41e92641
NC
9057 bfd_boolean is_rela;
9058 unsigned long num_relocs;
2cf0635d
NC
9059 Elf_Internal_Rela * relocs;
9060 Elf_Internal_Rela * rp;
9061 Elf_Internal_Shdr * symsec;
9062 Elf_Internal_Sym * symtab;
9063 Elf_Internal_Sym * sym;
252b5132 9064
41e92641 9065 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
9066 || relsec->sh_info >= elf_header.e_shnum
9067 || section_headers + relsec->sh_info != section
c256ffe7 9068 || relsec->sh_size == 0
4fbb74a6 9069 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 9070 continue;
428409d5 9071
41e92641
NC
9072 is_rela = relsec->sh_type == SHT_RELA;
9073
9074 if (is_rela)
9075 {
3f5e193b
NC
9076 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
9077 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
9078 return;
9079 }
9080 else
9081 {
3f5e193b
NC
9082 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
9083 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
9084 return;
9085 }
9086
9087 /* SH uses RELA but uses in place value instead of the addend field. */
9088 if (elf_header.e_machine == EM_SH)
9089 is_rela = FALSE;
428409d5 9090
4fbb74a6 9091 symsec = section_headers + relsec->sh_link;
3f5e193b 9092 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
103f02d3 9093
41e92641 9094 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 9095 {
41e92641
NC
9096 bfd_vma addend;
9097 unsigned int reloc_type;
9098 unsigned int reloc_size;
91d6fa6a 9099 unsigned char * rloc;
4b78141a 9100
aca88567 9101 reloc_type = get_reloc_type (rp->r_info);
41e92641 9102
98fb390a 9103 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 9104 continue;
98fb390a
NC
9105 else if (is_none_reloc (reloc_type))
9106 continue;
9107 else if (is_32bit_abs_reloc (reloc_type)
9108 || is_32bit_pcrel_reloc (reloc_type))
aca88567 9109 reloc_size = 4;
85acf597
RH
9110 else if (is_64bit_abs_reloc (reloc_type)
9111 || is_64bit_pcrel_reloc (reloc_type))
aca88567 9112 reloc_size = 8;
4dc3c23d
AM
9113 else if (is_24bit_abs_reloc (reloc_type))
9114 reloc_size = 3;
aca88567
NC
9115 else if (is_16bit_abs_reloc (reloc_type))
9116 reloc_size = 2;
9117 else
4b78141a 9118 {
41e92641 9119 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 9120 reloc_type, SECTION_NAME (section));
4b78141a
NC
9121 continue;
9122 }
103f02d3 9123
91d6fa6a
NC
9124 rloc = start + rp->r_offset;
9125 if ((rloc + reloc_size) > end)
700dd8b7
L
9126 {
9127 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
9128 (unsigned long) rp->r_offset,
9129 SECTION_NAME (section));
9130 continue;
9131 }
103f02d3 9132
41e92641
NC
9133 sym = symtab + get_reloc_symindex (rp->r_info);
9134
9135 /* If the reloc has a symbol associated with it,
55f25fc3
L
9136 make sure that it is of an appropriate type.
9137
9138 Relocations against symbols without type can happen.
9139 Gcc -feliminate-dwarf2-dups may generate symbols
9140 without type for debug info.
9141
9142 Icc generates relocations against function symbols
9143 instead of local labels.
9144
9145 Relocations against object symbols can happen, eg when
9146 referencing a global array. For an example of this see
9147 the _clz.o binary in libgcc.a. */
aca88567 9148 if (sym != symtab
55f25fc3 9149 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 9150 {
41e92641 9151 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 9152 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 9153 (long int)(rp - relocs),
41e92641 9154 SECTION_NAME (relsec));
aca88567 9155 continue;
5b18a4bc 9156 }
252b5132 9157
4dc3c23d
AM
9158 addend = 0;
9159 if (is_rela)
9160 addend += rp->r_addend;
9161 /* R_XTENSA_32 and R_PJ_DATA_DIR32 are partial_inplace. */
9162 if (!is_rela
9163 || (elf_header.e_machine == EM_XTENSA
9164 && reloc_type == 1)
9165 || ((elf_header.e_machine == EM_PJ
9166 || elf_header.e_machine == EM_PJ_OLD)
9167 && reloc_type == 1))
91d6fa6a 9168 addend += byte_get (rloc, reloc_size);
cb8f3167 9169
85acf597
RH
9170 if (is_32bit_pcrel_reloc (reloc_type)
9171 || is_64bit_pcrel_reloc (reloc_type))
9172 {
9173 /* On HPPA, all pc-relative relocations are biased by 8. */
9174 if (elf_header.e_machine == EM_PARISC)
9175 addend -= 8;
91d6fa6a 9176 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
9177 reloc_size);
9178 }
41e92641 9179 else
91d6fa6a 9180 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 9181 }
252b5132 9182
5b18a4bc 9183 free (symtab);
41e92641 9184 free (relocs);
5b18a4bc
NC
9185 break;
9186 }
5b18a4bc 9187}
103f02d3 9188
cf13d699
NC
9189#ifdef SUPPORT_DISASSEMBLY
9190static int
9191disassemble_section (Elf_Internal_Shdr * section, FILE * file)
9192{
9193 printf (_("\nAssembly dump of section %s\n"),
9194 SECTION_NAME (section));
9195
9196 /* XXX -- to be done --- XXX */
9197
9198 return 1;
9199}
9200#endif
9201
9202/* Reads in the contents of SECTION from FILE, returning a pointer
9203 to a malloc'ed buffer or NULL if something went wrong. */
9204
9205static char *
9206get_section_contents (Elf_Internal_Shdr * section, FILE * file)
9207{
9208 bfd_size_type num_bytes;
9209
9210 num_bytes = section->sh_size;
9211
9212 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
9213 {
9214 printf (_("\nSection '%s' has no data to dump.\n"),
9215 SECTION_NAME (section));
9216 return NULL;
9217 }
9218
3f5e193b
NC
9219 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
9220 _("section contents"));
cf13d699
NC
9221}
9222
9223
9224static void
9225dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
9226{
9227 Elf_Internal_Shdr * relsec;
9228 bfd_size_type num_bytes;
9229 bfd_vma addr;
9230 char * data;
9231 char * end;
9232 char * start;
9233 char * name = SECTION_NAME (section);
9234 bfd_boolean some_strings_shown;
9235
9236 start = get_section_contents (section, file);
9237 if (start == NULL)
9238 return;
9239
9240 printf (_("\nString dump of section '%s':\n"), name);
9241
9242 /* If the section being dumped has relocations against it the user might
9243 be expecting these relocations to have been applied. Check for this
9244 case and issue a warning message in order to avoid confusion.
9245 FIXME: Maybe we ought to have an option that dumps a section with
9246 relocs applied ? */
9247 for (relsec = section_headers;
9248 relsec < section_headers + elf_header.e_shnum;
9249 ++relsec)
9250 {
9251 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
9252 || relsec->sh_info >= elf_header.e_shnum
9253 || section_headers + relsec->sh_info != section
9254 || relsec->sh_size == 0
9255 || relsec->sh_link >= elf_header.e_shnum)
9256 continue;
9257
9258 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
9259 break;
9260 }
9261
9262 num_bytes = section->sh_size;
9263 addr = section->sh_addr;
9264 data = start;
9265 end = start + num_bytes;
9266 some_strings_shown = FALSE;
9267
9268 while (data < end)
9269 {
9270 while (!ISPRINT (* data))
9271 if (++ data >= end)
9272 break;
9273
9274 if (data < end)
9275 {
9276#ifndef __MSVCRT__
c975cc98
NC
9277 /* PR 11128: Use two separate invocations in order to work
9278 around bugs in the Solaris 8 implementation of printf. */
9279 printf (" [%6tx] ", data - start);
9280 printf ("%s\n", data);
cf13d699
NC
9281#else
9282 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
9283#endif
9284 data += strlen (data);
9285 some_strings_shown = TRUE;
9286 }
9287 }
9288
9289 if (! some_strings_shown)
9290 printf (_(" No strings found in this section."));
9291
9292 free (start);
9293
9294 putchar ('\n');
9295}
9296
9297static void
9298dump_section_as_bytes (Elf_Internal_Shdr * section,
9299 FILE * file,
9300 bfd_boolean relocate)
9301{
9302 Elf_Internal_Shdr * relsec;
9303 bfd_size_type bytes;
9304 bfd_vma addr;
9305 unsigned char * data;
9306 unsigned char * start;
9307
9308 start = (unsigned char *) get_section_contents (section, file);
9309 if (start == NULL)
9310 return;
9311
9312 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
9313
9314 if (relocate)
9315 {
9316 apply_relocations (file, section, start);
9317 }
9318 else
9319 {
9320 /* If the section being dumped has relocations against it the user might
9321 be expecting these relocations to have been applied. Check for this
9322 case and issue a warning message in order to avoid confusion.
9323 FIXME: Maybe we ought to have an option that dumps a section with
9324 relocs applied ? */
9325 for (relsec = section_headers;
9326 relsec < section_headers + elf_header.e_shnum;
9327 ++relsec)
9328 {
9329 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
9330 || relsec->sh_info >= elf_header.e_shnum
9331 || section_headers + relsec->sh_info != section
9332 || relsec->sh_size == 0
9333 || relsec->sh_link >= elf_header.e_shnum)
9334 continue;
9335
9336 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
9337 break;
9338 }
9339 }
9340
9341 addr = section->sh_addr;
9342 bytes = section->sh_size;
9343 data = start;
9344
9345 while (bytes)
9346 {
9347 int j;
9348 int k;
9349 int lbytes;
9350
9351 lbytes = (bytes > 16 ? 16 : bytes);
9352
9353 printf (" 0x%8.8lx ", (unsigned long) addr);
9354
9355 for (j = 0; j < 16; j++)
9356 {
9357 if (j < lbytes)
9358 printf ("%2.2x", data[j]);
9359 else
9360 printf (" ");
9361
9362 if ((j & 3) == 3)
9363 printf (" ");
9364 }
9365
9366 for (j = 0; j < lbytes; j++)
9367 {
9368 k = data[j];
9369 if (k >= ' ' && k < 0x7f)
9370 printf ("%c", k);
9371 else
9372 printf (".");
9373 }
9374
9375 putchar ('\n');
9376
9377 data += lbytes;
9378 addr += lbytes;
9379 bytes -= lbytes;
9380 }
9381
9382 free (start);
9383
9384 putchar ('\n');
9385}
9386
9387/* Uncompresses a section that was compressed using zlib, in place.
9388 This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */
9389
9390static int
9391uncompress_section_contents (unsigned char ** buffer, dwarf_size_type * size)
9392{
9393#ifndef HAVE_ZLIB_H
9394 /* These are just to quiet gcc. */
9395 buffer = 0;
9396 size = 0;
9397 return FALSE;
9398#else
9399 dwarf_size_type compressed_size = *size;
9400 unsigned char * compressed_buffer = *buffer;
9401 dwarf_size_type uncompressed_size;
9402 unsigned char * uncompressed_buffer;
9403 z_stream strm;
9404 int rc;
9405 dwarf_size_type header_size = 12;
9406
9407 /* Read the zlib header. In this case, it should be "ZLIB" followed
9408 by the uncompressed section size, 8 bytes in big-endian order. */
9409 if (compressed_size < header_size
9410 || ! streq ((char *) compressed_buffer, "ZLIB"))
9411 return 0;
9412
9413 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
9414 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
9415 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
9416 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
9417 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
9418 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
9419 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
9420 uncompressed_size += compressed_buffer[11];
9421
9422 /* It is possible the section consists of several compressed
9423 buffers concatenated together, so we uncompress in a loop. */
9424 strm.zalloc = NULL;
9425 strm.zfree = NULL;
9426 strm.opaque = NULL;
9427 strm.avail_in = compressed_size - header_size;
9428 strm.next_in = (Bytef *) compressed_buffer + header_size;
9429 strm.avail_out = uncompressed_size;
3f5e193b 9430 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
9431
9432 rc = inflateInit (& strm);
9433 while (strm.avail_in > 0)
9434 {
9435 if (rc != Z_OK)
9436 goto fail;
9437 strm.next_out = ((Bytef *) uncompressed_buffer
9438 + (uncompressed_size - strm.avail_out));
9439 rc = inflate (&strm, Z_FINISH);
9440 if (rc != Z_STREAM_END)
9441 goto fail;
9442 rc = inflateReset (& strm);
9443 }
9444 rc = inflateEnd (& strm);
9445 if (rc != Z_OK
9446 || strm.avail_out != 0)
9447 goto fail;
9448
9449 free (compressed_buffer);
9450 *buffer = uncompressed_buffer;
9451 *size = uncompressed_size;
9452 return 1;
9453
9454 fail:
9455 free (uncompressed_buffer);
9456 return 0;
9457#endif /* HAVE_ZLIB_H */
9458}
9459
d966045b
DJ
9460static int
9461load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 9462 Elf_Internal_Shdr * sec, void * file)
1007acb3 9463{
2cf0635d 9464 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 9465 char buf [64];
1b315056 9466 int section_is_compressed;
1007acb3 9467
19e6b90e
L
9468 /* If it is already loaded, do nothing. */
9469 if (section->start != NULL)
9470 return 1;
1007acb3 9471
a71cc8e0 9472 section_is_compressed = section->name == section->compressed_name;
1007acb3 9473
19e6b90e
L
9474 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
9475 section->address = sec->sh_addr;
9476 section->size = sec->sh_size;
3f5e193b
NC
9477 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
9478 sec->sh_offset, 1,
9479 sec->sh_size, buf);
1b315056
CS
9480 if (section->start == NULL)
9481 return 0;
9482
9483 if (section_is_compressed)
9484 if (! uncompress_section_contents (&section->start, &section->size))
9485 return 0;
1007acb3 9486
19e6b90e 9487 if (debug_displays [debug].relocate)
3f5e193b 9488 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 9489
1b315056 9490 return 1;
1007acb3
L
9491}
9492
d966045b 9493int
2cf0635d 9494load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 9495{
2cf0635d
NC
9496 struct dwarf_section * section = &debug_displays [debug].section;
9497 Elf_Internal_Shdr * sec;
d966045b
DJ
9498
9499 /* Locate the debug section. */
9500 sec = find_section (section->uncompressed_name);
9501 if (sec != NULL)
9502 section->name = section->uncompressed_name;
9503 else
9504 {
9505 sec = find_section (section->compressed_name);
9506 if (sec != NULL)
9507 section->name = section->compressed_name;
9508 }
9509 if (sec == NULL)
9510 return 0;
9511
3f5e193b 9512 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
9513}
9514
19e6b90e
L
9515void
9516free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 9517{
2cf0635d 9518 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 9519
19e6b90e
L
9520 if (section->start == NULL)
9521 return;
1007acb3 9522
19e6b90e
L
9523 free ((char *) section->start);
9524 section->start = NULL;
9525 section->address = 0;
9526 section->size = 0;
1007acb3
L
9527}
9528
1007acb3 9529static int
2cf0635d 9530display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 9531{
2cf0635d 9532 char * name = SECTION_NAME (section);
19e6b90e
L
9533 bfd_size_type length;
9534 int result = 1;
3f5e193b 9535 int i;
1007acb3 9536
19e6b90e
L
9537 length = section->sh_size;
9538 if (length == 0)
1007acb3 9539 {
19e6b90e
L
9540 printf (_("\nSection '%s' has no debugging data.\n"), name);
9541 return 0;
1007acb3 9542 }
5dff79d8
NC
9543 if (section->sh_type == SHT_NOBITS)
9544 {
9545 /* There is no point in dumping the contents of a debugging section
9546 which has the NOBITS type - the bits in the file will be random.
9547 This can happen when a file containing a .eh_frame section is
9548 stripped with the --only-keep-debug command line option. */
9549 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
9550 return 0;
9551 }
1007acb3 9552
0112cd26 9553 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 9554 name = ".debug_info";
1007acb3 9555
19e6b90e
L
9556 /* See if we know how to display the contents of this section. */
9557 for (i = 0; i < max; i++)
1b315056
CS
9558 if (streq (debug_displays[i].section.uncompressed_name, name)
9559 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 9560 {
2cf0635d 9561 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
9562 int secondary = (section != find_section (name));
9563
9564 if (secondary)
3f5e193b 9565 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 9566
2b6f5997 9567 if (streq (sec->uncompressed_name, name))
d966045b
DJ
9568 sec->name = sec->uncompressed_name;
9569 else
9570 sec->name = sec->compressed_name;
3f5e193b
NC
9571 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
9572 section, file))
19e6b90e
L
9573 {
9574 result &= debug_displays[i].display (sec, file);
1007acb3 9575
d966045b 9576 if (secondary || (i != info && i != abbrev))
3f5e193b 9577 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 9578 }
1007acb3 9579
19e6b90e
L
9580 break;
9581 }
1007acb3 9582
19e6b90e 9583 if (i == max)
1007acb3 9584 {
19e6b90e
L
9585 printf (_("Unrecognized debug section: %s\n"), name);
9586 result = 0;
1007acb3
L
9587 }
9588
19e6b90e 9589 return result;
5b18a4bc 9590}
103f02d3 9591
aef1f6d0
DJ
9592/* Set DUMP_SECTS for all sections where dumps were requested
9593 based on section name. */
9594
9595static void
9596initialise_dumps_byname (void)
9597{
2cf0635d 9598 struct dump_list_entry * cur;
aef1f6d0
DJ
9599
9600 for (cur = dump_sects_byname; cur; cur = cur->next)
9601 {
9602 unsigned int i;
9603 int any;
9604
9605 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
9606 if (streq (SECTION_NAME (section_headers + i), cur->name))
9607 {
09c11c86 9608 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
9609 any = 1;
9610 }
9611
9612 if (!any)
9613 warn (_("Section '%s' was not dumped because it does not exist!\n"),
9614 cur->name);
9615 }
9616}
9617
5b18a4bc 9618static void
2cf0635d 9619process_section_contents (FILE * file)
5b18a4bc 9620{
2cf0635d 9621 Elf_Internal_Shdr * section;
19e6b90e 9622 unsigned int i;
103f02d3 9623
19e6b90e
L
9624 if (! do_dump)
9625 return;
103f02d3 9626
aef1f6d0
DJ
9627 initialise_dumps_byname ();
9628
19e6b90e
L
9629 for (i = 0, section = section_headers;
9630 i < elf_header.e_shnum && i < num_dump_sects;
9631 i++, section++)
9632 {
9633#ifdef SUPPORT_DISASSEMBLY
9634 if (dump_sects[i] & DISASS_DUMP)
9635 disassemble_section (section, file);
9636#endif
9637 if (dump_sects[i] & HEX_DUMP)
cf13d699 9638 dump_section_as_bytes (section, file, FALSE);
103f02d3 9639
cf13d699
NC
9640 if (dump_sects[i] & RELOC_DUMP)
9641 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
9642
9643 if (dump_sects[i] & STRING_DUMP)
9644 dump_section_as_strings (section, file);
cf13d699
NC
9645
9646 if (dump_sects[i] & DEBUG_DUMP)
9647 display_debug_section (section, file);
5b18a4bc 9648 }
103f02d3 9649
19e6b90e
L
9650 /* Check to see if the user requested a
9651 dump of a section that does not exist. */
9652 while (i++ < num_dump_sects)
9653 if (dump_sects[i])
9654 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 9655}
103f02d3 9656
5b18a4bc 9657static void
19e6b90e 9658process_mips_fpe_exception (int mask)
5b18a4bc 9659{
19e6b90e
L
9660 if (mask)
9661 {
9662 int first = 1;
9663 if (mask & OEX_FPU_INEX)
9664 fputs ("INEX", stdout), first = 0;
9665 if (mask & OEX_FPU_UFLO)
9666 printf ("%sUFLO", first ? "" : "|"), first = 0;
9667 if (mask & OEX_FPU_OFLO)
9668 printf ("%sOFLO", first ? "" : "|"), first = 0;
9669 if (mask & OEX_FPU_DIV0)
9670 printf ("%sDIV0", first ? "" : "|"), first = 0;
9671 if (mask & OEX_FPU_INVAL)
9672 printf ("%sINVAL", first ? "" : "|");
9673 }
5b18a4bc 9674 else
19e6b90e 9675 fputs ("0", stdout);
5b18a4bc 9676}
103f02d3 9677
11c1ff18
PB
9678/* ARM EABI attributes section. */
9679typedef struct
9680{
9681 int tag;
2cf0635d 9682 const char * name;
11c1ff18
PB
9683 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
9684 int type;
2cf0635d 9685 const char ** table;
11c1ff18
PB
9686} arm_attr_public_tag;
9687
2cf0635d 9688static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 9689 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
9e3c6df6 9690 "v6K", "v7", "v6-M", "v6S-M", "v7E-M"};
2cf0635d
NC
9691static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
9692static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 9693 {"No", "Thumb-1", "Thumb-2"};
2cf0635d 9694static const char * arm_attr_tag_VFP_arch[] =
62f3b8c8 9695 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
2cf0635d 9696static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
cd21e546
MGD
9697static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9698 {"No", "NEONv1", "NEONv1 with Fused-MAC"};
2cf0635d 9699static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
9700 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
9701 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 9702static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 9703 {"V6", "SB", "TLS", "Unused"};
2cf0635d 9704static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 9705 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 9706static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 9707 {"Absolute", "PC-relative", "None"};
2cf0635d 9708static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 9709 {"None", "direct", "GOT-indirect"};
2cf0635d 9710static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 9711 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
9712static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
9713static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 9714 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
9715static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
9716static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
9717static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 9718 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d
NC
9719static const char * arm_attr_tag_ABI_align8_needed[] = {"No", "Yes", "4-byte"};
9720static const char * arm_attr_tag_ABI_align8_preserved[] =
11c1ff18 9721 {"No", "Yes, except leaf SP", "Yes"};
2cf0635d 9722static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 9723 {"Unused", "small", "int", "forced to int"};
2cf0635d 9724static const char * arm_attr_tag_ABI_HardFP_use[] =
11c1ff18 9725 {"As Tag_VFP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 9726static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 9727 {"AAPCS", "VFP registers", "custom"};
2cf0635d 9728static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 9729 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 9730static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
9731 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
9732 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 9733static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
9734 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
9735 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d
NC
9736static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
9737static const char * arm_attr_tag_VFP_HP_extension[] =
8e79c3df 9738 {"Not Allowed", "Allowed"};
2cf0635d 9739static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 9740 {"None", "IEEE 754", "Alternative Format"};
cd21e546
MGD
9741static const char * arm_attr_tag_MPextension_use[] =
9742 {"Not Allowed", "Allowed"};
9743static const char * arm_attr_tag_DIV_use[] =
9744 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
9745 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
9746static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
9747static const char * arm_attr_tag_Virtualization_use[] =
cd21e546
MGD
9748 {"Not Allowed", "TrustZone", "Virtualization Extensions",
9749 "TrustZone and Virtualization Extensions"};
9750static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 9751 {"Not Allowed", "Allowed"};
11c1ff18
PB
9752
9753#define LOOKUP(id, name) \
9754 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 9755static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
9756{
9757 {4, "CPU_raw_name", 1, NULL},
9758 {5, "CPU_name", 1, NULL},
9759 LOOKUP(6, CPU_arch),
9760 {7, "CPU_arch_profile", 0, NULL},
9761 LOOKUP(8, ARM_ISA_use),
9762 LOOKUP(9, THUMB_ISA_use),
9763 LOOKUP(10, VFP_arch),
9764 LOOKUP(11, WMMX_arch),
f5f53991
AS
9765 LOOKUP(12, Advanced_SIMD_arch),
9766 LOOKUP(13, PCS_config),
11c1ff18
PB
9767 LOOKUP(14, ABI_PCS_R9_use),
9768 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 9769 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
9770 LOOKUP(17, ABI_PCS_GOT_use),
9771 LOOKUP(18, ABI_PCS_wchar_t),
9772 LOOKUP(19, ABI_FP_rounding),
9773 LOOKUP(20, ABI_FP_denormal),
9774 LOOKUP(21, ABI_FP_exceptions),
9775 LOOKUP(22, ABI_FP_user_exceptions),
9776 LOOKUP(23, ABI_FP_number_model),
9777 LOOKUP(24, ABI_align8_needed),
9778 LOOKUP(25, ABI_align8_preserved),
9779 LOOKUP(26, ABI_enum_size),
9780 LOOKUP(27, ABI_HardFP_use),
9781 LOOKUP(28, ABI_VFP_args),
9782 LOOKUP(29, ABI_WMMX_args),
9783 LOOKUP(30, ABI_optimization_goals),
9784 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 9785 {32, "compatibility", 0, NULL},
f5f53991 9786 LOOKUP(34, CPU_unaligned_access),
8e79c3df
CM
9787 LOOKUP(36, VFP_HP_extension),
9788 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
9789 LOOKUP(42, MPextension_use),
9790 LOOKUP(44, DIV_use),
f5f53991
AS
9791 {64, "nodefaults", 0, NULL},
9792 {65, "also_compatible_with", 0, NULL},
9793 LOOKUP(66, T2EE_use),
9794 {67, "conformance", 1, NULL},
9795 LOOKUP(68, Virtualization_use),
cd21e546 9796 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
9797};
9798#undef LOOKUP
9799
11c1ff18 9800static unsigned char *
2cf0635d 9801display_arm_attribute (unsigned char * p)
11c1ff18
PB
9802{
9803 int tag;
9804 unsigned int len;
9805 int val;
2cf0635d 9806 arm_attr_public_tag * attr;
11c1ff18
PB
9807 unsigned i;
9808 int type;
9809
9810 tag = read_uleb128 (p, &len);
9811 p += len;
9812 attr = NULL;
2cf0635d 9813 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
9814 {
9815 if (arm_attr_public_tags[i].tag == tag)
9816 {
9817 attr = &arm_attr_public_tags[i];
9818 break;
9819 }
9820 }
9821
9822 if (attr)
9823 {
9824 printf (" Tag_%s: ", attr->name);
9825 switch (attr->type)
9826 {
9827 case 0:
9828 switch (tag)
9829 {
9830 case 7: /* Tag_CPU_arch_profile. */
9831 val = read_uleb128 (p, &len);
9832 p += len;
9833 switch (val)
9834 {
9835 case 0: printf ("None\n"); break;
9836 case 'A': printf ("Application\n"); break;
9837 case 'R': printf ("Realtime\n"); break;
9838 case 'M': printf ("Microcontroller\n"); break;
9839 default: printf ("??? (%d)\n", val); break;
9840 }
9841 break;
9842
9843 case 32: /* Tag_compatibility. */
9844 val = read_uleb128 (p, &len);
9845 p += len;
9846 printf ("flag = %d, vendor = %s\n", val, p);
2cf0635d 9847 p += strlen ((char *) p) + 1;
11c1ff18
PB
9848 break;
9849
f5f53991
AS
9850 case 64: /* Tag_nodefaults. */
9851 p++;
9852 printf ("True\n");
9853 break;
9854
9855 case 65: /* Tag_also_compatible_with. */
9856 val = read_uleb128 (p, &len);
9857 p += len;
9858 if (val == 6 /* Tag_CPU_arch. */)
9859 {
9860 val = read_uleb128 (p, &len);
9861 p += len;
2cf0635d 9862 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
9863 printf ("??? (%d)\n", val);
9864 else
9865 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
9866 }
9867 else
9868 printf ("???\n");
9869 while (*(p++) != '\0' /* NUL terminator. */);
9870 break;
9871
11c1ff18 9872 default:
2cf0635d 9873 abort ();
11c1ff18
PB
9874 }
9875 return p;
9876
9877 case 1:
9878 case 2:
9879 type = attr->type;
9880 break;
9881
9882 default:
9883 assert (attr->type & 0x80);
9884 val = read_uleb128 (p, &len);
9885 p += len;
9886 type = attr->type & 0x7f;
9887 if (val >= type)
9888 printf ("??? (%d)\n", val);
9889 else
9890 printf ("%s\n", attr->table[val]);
9891 return p;
9892 }
9893 }
9894 else
9895 {
9896 if (tag & 1)
9897 type = 1; /* String. */
9898 else
9899 type = 2; /* uleb128. */
9900 printf (" Tag_unknown_%d: ", tag);
9901 }
9902
9903 if (type == 1)
9904 {
9905 printf ("\"%s\"\n", p);
2cf0635d 9906 p += strlen ((char *) p) + 1;
11c1ff18
PB
9907 }
9908 else
9909 {
9910 val = read_uleb128 (p, &len);
9911 p += len;
9912 printf ("%d (0x%x)\n", val, val);
9913 }
9914
9915 return p;
9916}
9917
104d59d1 9918static unsigned char *
60bca95a
NC
9919display_gnu_attribute (unsigned char * p,
9920 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
9921{
9922 int tag;
9923 unsigned int len;
9924 int val;
9925 int type;
9926
9927 tag = read_uleb128 (p, &len);
9928 p += len;
9929
9930 /* Tag_compatibility is the only generic GNU attribute defined at
9931 present. */
9932 if (tag == 32)
9933 {
9934 val = read_uleb128 (p, &len);
9935 p += len;
9936 printf ("flag = %d, vendor = %s\n", val, p);
60bca95a 9937 p += strlen ((char *) p) + 1;
104d59d1
JM
9938 return p;
9939 }
9940
9941 if ((tag & 2) == 0 && display_proc_gnu_attribute)
9942 return display_proc_gnu_attribute (p, tag);
9943
9944 if (tag & 1)
9945 type = 1; /* String. */
9946 else
9947 type = 2; /* uleb128. */
9948 printf (" Tag_unknown_%d: ", tag);
9949
9950 if (type == 1)
9951 {
9952 printf ("\"%s\"\n", p);
60bca95a 9953 p += strlen ((char *) p) + 1;
104d59d1
JM
9954 }
9955 else
9956 {
9957 val = read_uleb128 (p, &len);
9958 p += len;
9959 printf ("%d (0x%x)\n", val, val);
9960 }
9961
9962 return p;
9963}
9964
34c8bcba 9965static unsigned char *
2cf0635d 9966display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
9967{
9968 int type;
9969 unsigned int len;
9970 int val;
9971
9972 if (tag == Tag_GNU_Power_ABI_FP)
9973 {
9974 val = read_uleb128 (p, &len);
9975 p += len;
9976 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 9977
34c8bcba
JM
9978 switch (val)
9979 {
9980 case 0:
9981 printf ("Hard or soft float\n");
9982 break;
9983 case 1:
9984 printf ("Hard float\n");
9985 break;
9986 case 2:
9987 printf ("Soft float\n");
9988 break;
3c7b9897
AM
9989 case 3:
9990 printf ("Single-precision hard float\n");
9991 break;
34c8bcba
JM
9992 default:
9993 printf ("??? (%d)\n", val);
9994 break;
9995 }
9996 return p;
9997 }
9998
c6e65352
DJ
9999 if (tag == Tag_GNU_Power_ABI_Vector)
10000 {
10001 val = read_uleb128 (p, &len);
10002 p += len;
10003 printf (" Tag_GNU_Power_ABI_Vector: ");
10004 switch (val)
10005 {
10006 case 0:
10007 printf ("Any\n");
10008 break;
10009 case 1:
10010 printf ("Generic\n");
10011 break;
10012 case 2:
10013 printf ("AltiVec\n");
10014 break;
10015 case 3:
10016 printf ("SPE\n");
10017 break;
10018 default:
10019 printf ("??? (%d)\n", val);
10020 break;
10021 }
10022 return p;
10023 }
10024
f82e0623
NF
10025 if (tag == Tag_GNU_Power_ABI_Struct_Return)
10026 {
10027 val = read_uleb128 (p, &len);
10028 p += len;
10029 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
10030 switch (val)
10031 {
10032 case 0:
10033 printf ("Any\n");
10034 break;
10035 case 1:
10036 printf ("r3/r4\n");
10037 break;
10038 case 2:
10039 printf ("Memory\n");
10040 break;
10041 default:
10042 printf ("??? (%d)\n", val);
10043 break;
10044 }
10045 return p;
10046 }
10047
34c8bcba
JM
10048 if (tag & 1)
10049 type = 1; /* String. */
10050 else
10051 type = 2; /* uleb128. */
10052 printf (" Tag_unknown_%d: ", tag);
10053
10054 if (type == 1)
10055 {
10056 printf ("\"%s\"\n", p);
60bca95a 10057 p += strlen ((char *) p) + 1;
34c8bcba
JM
10058 }
10059 else
10060 {
10061 val = read_uleb128 (p, &len);
10062 p += len;
10063 printf ("%d (0x%x)\n", val, val);
10064 }
10065
10066 return p;
10067}
10068
2cf19d5c 10069static unsigned char *
2cf0635d 10070display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
10071{
10072 int type;
10073 unsigned int len;
10074 int val;
10075
10076 if (tag == Tag_GNU_MIPS_ABI_FP)
10077 {
10078 val = read_uleb128 (p, &len);
10079 p += len;
10080 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 10081
2cf19d5c
JM
10082 switch (val)
10083 {
10084 case 0:
10085 printf ("Hard or soft float\n");
10086 break;
10087 case 1:
10088 printf ("Hard float (-mdouble-float)\n");
10089 break;
10090 case 2:
10091 printf ("Hard float (-msingle-float)\n");
10092 break;
10093 case 3:
10094 printf ("Soft float\n");
10095 break;
42554f6a
TS
10096 case 4:
10097 printf ("64-bit float (-mips32r2 -mfp64)\n");
10098 break;
2cf19d5c
JM
10099 default:
10100 printf ("??? (%d)\n", val);
10101 break;
10102 }
10103 return p;
10104 }
10105
10106 if (tag & 1)
10107 type = 1; /* String. */
10108 else
10109 type = 2; /* uleb128. */
10110 printf (" Tag_unknown_%d: ", tag);
10111
10112 if (type == 1)
10113 {
10114 printf ("\"%s\"\n", p);
60bca95a 10115 p += strlen ((char *) p) + 1;
2cf19d5c
JM
10116 }
10117 else
10118 {
10119 val = read_uleb128 (p, &len);
10120 p += len;
10121 printf ("%d (0x%x)\n", val, val);
10122 }
10123
10124 return p;
10125}
10126
11c1ff18 10127static int
60bca95a
NC
10128process_attributes (FILE * file,
10129 const char * public_name,
104d59d1 10130 unsigned int proc_type,
60bca95a
NC
10131 unsigned char * (* display_pub_attribute) (unsigned char *),
10132 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 10133{
2cf0635d
NC
10134 Elf_Internal_Shdr * sect;
10135 unsigned char * contents;
10136 unsigned char * p;
10137 unsigned char * end;
11c1ff18
PB
10138 bfd_vma section_len;
10139 bfd_vma len;
10140 unsigned i;
10141
10142 /* Find the section header so that we get the size. */
10143 for (i = 0, sect = section_headers;
10144 i < elf_header.e_shnum;
10145 i++, sect++)
10146 {
104d59d1 10147 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
10148 continue;
10149
3f5e193b
NC
10150 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
10151 sect->sh_size, _("attributes"));
60bca95a 10152 if (contents == NULL)
11c1ff18 10153 continue;
60bca95a 10154
11c1ff18
PB
10155 p = contents;
10156 if (*p == 'A')
10157 {
10158 len = sect->sh_size - 1;
10159 p++;
60bca95a 10160
11c1ff18
PB
10161 while (len > 0)
10162 {
10163 int namelen;
10164 bfd_boolean public_section;
104d59d1 10165 bfd_boolean gnu_section;
11c1ff18
PB
10166
10167 section_len = byte_get (p, 4);
10168 p += 4;
60bca95a 10169
11c1ff18
PB
10170 if (section_len > len)
10171 {
10172 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 10173 (int) section_len, (int) len);
11c1ff18
PB
10174 section_len = len;
10175 }
60bca95a 10176
11c1ff18
PB
10177 len -= section_len;
10178 printf ("Attribute Section: %s\n", p);
60bca95a
NC
10179
10180 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
10181 public_section = TRUE;
10182 else
10183 public_section = FALSE;
60bca95a
NC
10184
10185 if (streq ((char *) p, "gnu"))
104d59d1
JM
10186 gnu_section = TRUE;
10187 else
10188 gnu_section = FALSE;
60bca95a
NC
10189
10190 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
10191 p += namelen;
10192 section_len -= namelen + 4;
60bca95a 10193
11c1ff18
PB
10194 while (section_len > 0)
10195 {
10196 int tag = *(p++);
10197 int val;
10198 bfd_vma size;
60bca95a 10199
11c1ff18
PB
10200 size = byte_get (p, 4);
10201 if (size > section_len)
10202 {
10203 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 10204 (int) size, (int) section_len);
11c1ff18
PB
10205 size = section_len;
10206 }
60bca95a 10207
11c1ff18
PB
10208 section_len -= size;
10209 end = p + size - 1;
10210 p += 4;
60bca95a 10211
11c1ff18
PB
10212 switch (tag)
10213 {
10214 case 1:
10215 printf ("File Attributes\n");
10216 break;
10217 case 2:
10218 printf ("Section Attributes:");
10219 goto do_numlist;
10220 case 3:
10221 printf ("Symbol Attributes:");
10222 do_numlist:
10223 for (;;)
10224 {
91d6fa6a 10225 unsigned int j;
60bca95a 10226
91d6fa6a
NC
10227 val = read_uleb128 (p, &j);
10228 p += j;
11c1ff18
PB
10229 if (val == 0)
10230 break;
10231 printf (" %d", val);
10232 }
10233 printf ("\n");
10234 break;
10235 default:
10236 printf ("Unknown tag: %d\n", tag);
10237 public_section = FALSE;
10238 break;
10239 }
60bca95a 10240
11c1ff18
PB
10241 if (public_section)
10242 {
10243 while (p < end)
104d59d1
JM
10244 p = display_pub_attribute (p);
10245 }
10246 else if (gnu_section)
10247 {
10248 while (p < end)
10249 p = display_gnu_attribute (p,
10250 display_proc_gnu_attribute);
11c1ff18
PB
10251 }
10252 else
10253 {
10254 /* ??? Do something sensible, like dump hex. */
10255 printf (" Unknown section contexts\n");
10256 p = end;
10257 }
10258 }
10259 }
10260 }
10261 else
60bca95a 10262 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 10263
60bca95a 10264 free (contents);
11c1ff18
PB
10265 }
10266 return 1;
10267}
10268
104d59d1 10269static int
2cf0635d 10270process_arm_specific (FILE * file)
104d59d1
JM
10271{
10272 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
10273 display_arm_attribute, NULL);
10274}
10275
34c8bcba 10276static int
2cf0635d 10277process_power_specific (FILE * file)
34c8bcba
JM
10278{
10279 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
10280 display_power_gnu_attribute);
10281}
10282
ccb4c951
RS
10283/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
10284 Print the Address, Access and Initial fields of an entry at VMA ADDR
10285 and return the VMA of the next entry. */
10286
10287static bfd_vma
2cf0635d 10288print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
10289{
10290 printf (" ");
10291 print_vma (addr, LONG_HEX);
10292 printf (" ");
10293 if (addr < pltgot + 0xfff0)
10294 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
10295 else
10296 printf ("%10s", "");
10297 printf (" ");
10298 if (data == NULL)
10299 printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
10300 else
10301 {
10302 bfd_vma entry;
10303
10304 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
10305 print_vma (entry, LONG_HEX);
10306 }
10307 return addr + (is_32bit_elf ? 4 : 8);
10308}
10309
861fb55a
DJ
10310/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
10311 PLTGOT. Print the Address and Initial fields of an entry at VMA
10312 ADDR and return the VMA of the next entry. */
10313
10314static bfd_vma
2cf0635d 10315print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
10316{
10317 printf (" ");
10318 print_vma (addr, LONG_HEX);
10319 printf (" ");
10320 if (data == NULL)
10321 printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
10322 else
10323 {
10324 bfd_vma entry;
10325
10326 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
10327 print_vma (entry, LONG_HEX);
10328 }
10329 return addr + (is_32bit_elf ? 4 : 8);
10330}
10331
19e6b90e 10332static int
2cf0635d 10333process_mips_specific (FILE * file)
5b18a4bc 10334{
2cf0635d 10335 Elf_Internal_Dyn * entry;
19e6b90e
L
10336 size_t liblist_offset = 0;
10337 size_t liblistno = 0;
10338 size_t conflictsno = 0;
10339 size_t options_offset = 0;
10340 size_t conflicts_offset = 0;
861fb55a
DJ
10341 size_t pltrelsz = 0;
10342 size_t pltrel = 0;
ccb4c951 10343 bfd_vma pltgot = 0;
861fb55a
DJ
10344 bfd_vma mips_pltgot = 0;
10345 bfd_vma jmprel = 0;
ccb4c951
RS
10346 bfd_vma local_gotno = 0;
10347 bfd_vma gotsym = 0;
10348 bfd_vma symtabno = 0;
103f02d3 10349
2cf19d5c
JM
10350 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
10351 display_mips_gnu_attribute);
10352
19e6b90e
L
10353 /* We have a lot of special sections. Thanks SGI! */
10354 if (dynamic_section == NULL)
10355 /* No information available. */
10356 return 0;
252b5132 10357
b2d38a17 10358 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
10359 switch (entry->d_tag)
10360 {
10361 case DT_MIPS_LIBLIST:
d93f0186
NC
10362 liblist_offset
10363 = offset_from_vma (file, entry->d_un.d_val,
10364 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
10365 break;
10366 case DT_MIPS_LIBLISTNO:
10367 liblistno = entry->d_un.d_val;
10368 break;
10369 case DT_MIPS_OPTIONS:
d93f0186 10370 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
10371 break;
10372 case DT_MIPS_CONFLICT:
d93f0186
NC
10373 conflicts_offset
10374 = offset_from_vma (file, entry->d_un.d_val,
10375 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
10376 break;
10377 case DT_MIPS_CONFLICTNO:
10378 conflictsno = entry->d_un.d_val;
10379 break;
ccb4c951 10380 case DT_PLTGOT:
861fb55a
DJ
10381 pltgot = entry->d_un.d_ptr;
10382 break;
ccb4c951
RS
10383 case DT_MIPS_LOCAL_GOTNO:
10384 local_gotno = entry->d_un.d_val;
10385 break;
10386 case DT_MIPS_GOTSYM:
10387 gotsym = entry->d_un.d_val;
10388 break;
10389 case DT_MIPS_SYMTABNO:
10390 symtabno = entry->d_un.d_val;
10391 break;
861fb55a
DJ
10392 case DT_MIPS_PLTGOT:
10393 mips_pltgot = entry->d_un.d_ptr;
10394 break;
10395 case DT_PLTREL:
10396 pltrel = entry->d_un.d_val;
10397 break;
10398 case DT_PLTRELSZ:
10399 pltrelsz = entry->d_un.d_val;
10400 break;
10401 case DT_JMPREL:
10402 jmprel = entry->d_un.d_ptr;
10403 break;
252b5132
RH
10404 default:
10405 break;
10406 }
10407
10408 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
10409 {
2cf0635d 10410 Elf32_External_Lib * elib;
252b5132
RH
10411 size_t cnt;
10412
3f5e193b
NC
10413 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
10414 liblistno,
10415 sizeof (Elf32_External_Lib),
10416 _("liblist"));
a6e9f9df 10417 if (elib)
252b5132 10418 {
a6e9f9df
AM
10419 printf ("\nSection '.liblist' contains %lu entries:\n",
10420 (unsigned long) liblistno);
10421 fputs (" Library Time Stamp Checksum Version Flags\n",
10422 stdout);
10423
10424 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 10425 {
a6e9f9df 10426 Elf32_Lib liblist;
91d6fa6a 10427 time_t atime;
a6e9f9df 10428 char timebuf[20];
2cf0635d 10429 struct tm * tmp;
a6e9f9df
AM
10430
10431 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 10432 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
10433 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10434 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10435 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10436
91d6fa6a 10437 tmp = gmtime (&atime);
e9e44622
JJ
10438 snprintf (timebuf, sizeof (timebuf),
10439 "%04u-%02u-%02uT%02u:%02u:%02u",
10440 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10441 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 10442
31104126 10443 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
10444 if (VALID_DYNAMIC_NAME (liblist.l_name))
10445 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
10446 else
10447 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
10448 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
10449 liblist.l_version);
a6e9f9df
AM
10450
10451 if (liblist.l_flags == 0)
10452 puts (" NONE");
10453 else
10454 {
10455 static const struct
252b5132 10456 {
2cf0635d 10457 const char * name;
a6e9f9df 10458 int bit;
252b5132 10459 }
a6e9f9df
AM
10460 l_flags_vals[] =
10461 {
10462 { " EXACT_MATCH", LL_EXACT_MATCH },
10463 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
10464 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
10465 { " EXPORTS", LL_EXPORTS },
10466 { " DELAY_LOAD", LL_DELAY_LOAD },
10467 { " DELTA", LL_DELTA }
10468 };
10469 int flags = liblist.l_flags;
10470 size_t fcnt;
10471
60bca95a 10472 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
10473 if ((flags & l_flags_vals[fcnt].bit) != 0)
10474 {
10475 fputs (l_flags_vals[fcnt].name, stdout);
10476 flags ^= l_flags_vals[fcnt].bit;
10477 }
10478 if (flags != 0)
10479 printf (" %#x", (unsigned int) flags);
252b5132 10480
a6e9f9df
AM
10481 puts ("");
10482 }
252b5132 10483 }
252b5132 10484
a6e9f9df
AM
10485 free (elib);
10486 }
252b5132
RH
10487 }
10488
10489 if (options_offset != 0)
10490 {
2cf0635d
NC
10491 Elf_External_Options * eopt;
10492 Elf_Internal_Shdr * sect = section_headers;
10493 Elf_Internal_Options * iopt;
10494 Elf_Internal_Options * option;
252b5132
RH
10495 size_t offset;
10496 int cnt;
10497
10498 /* Find the section header so that we get the size. */
10499 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 10500 ++sect;
252b5132 10501
3f5e193b
NC
10502 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
10503 sect->sh_size, _("options"));
a6e9f9df 10504 if (eopt)
252b5132 10505 {
3f5e193b
NC
10506 iopt = (Elf_Internal_Options *)
10507 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
10508 if (iopt == NULL)
10509 {
591a748a 10510 error (_("Out of memory\n"));
a6e9f9df
AM
10511 return 0;
10512 }
76da6bbe 10513
a6e9f9df
AM
10514 offset = cnt = 0;
10515 option = iopt;
252b5132 10516
a6e9f9df
AM
10517 while (offset < sect->sh_size)
10518 {
2cf0635d 10519 Elf_External_Options * eoption;
252b5132 10520
a6e9f9df 10521 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 10522
a6e9f9df
AM
10523 option->kind = BYTE_GET (eoption->kind);
10524 option->size = BYTE_GET (eoption->size);
10525 option->section = BYTE_GET (eoption->section);
10526 option->info = BYTE_GET (eoption->info);
76da6bbe 10527
a6e9f9df 10528 offset += option->size;
252b5132 10529
a6e9f9df
AM
10530 ++option;
10531 ++cnt;
10532 }
252b5132 10533
a6e9f9df
AM
10534 printf (_("\nSection '%s' contains %d entries:\n"),
10535 SECTION_NAME (sect), cnt);
76da6bbe 10536
a6e9f9df 10537 option = iopt;
252b5132 10538
a6e9f9df 10539 while (cnt-- > 0)
252b5132 10540 {
a6e9f9df
AM
10541 size_t len;
10542
10543 switch (option->kind)
252b5132 10544 {
a6e9f9df
AM
10545 case ODK_NULL:
10546 /* This shouldn't happen. */
10547 printf (" NULL %d %lx", option->section, option->info);
10548 break;
10549 case ODK_REGINFO:
10550 printf (" REGINFO ");
10551 if (elf_header.e_machine == EM_MIPS)
10552 {
10553 /* 32bit form. */
2cf0635d 10554 Elf32_External_RegInfo * ereg;
b34976b6 10555 Elf32_RegInfo reginfo;
a6e9f9df
AM
10556
10557 ereg = (Elf32_External_RegInfo *) (option + 1);
10558 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
10559 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
10560 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
10561 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
10562 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
10563 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
10564
10565 printf ("GPR %08lx GP 0x%lx\n",
10566 reginfo.ri_gprmask,
10567 (unsigned long) reginfo.ri_gp_value);
10568 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
10569 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
10570 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
10571 }
10572 else
10573 {
10574 /* 64 bit form. */
2cf0635d 10575 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
10576 Elf64_Internal_RegInfo reginfo;
10577
10578 ereg = (Elf64_External_RegInfo *) (option + 1);
10579 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
10580 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
10581 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
10582 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
10583 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 10584 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
10585
10586 printf ("GPR %08lx GP 0x",
10587 reginfo.ri_gprmask);
10588 printf_vma (reginfo.ri_gp_value);
10589 printf ("\n");
10590
10591 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
10592 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
10593 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
10594 }
10595 ++option;
10596 continue;
10597 case ODK_EXCEPTIONS:
10598 fputs (" EXCEPTIONS fpe_min(", stdout);
10599 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
10600 fputs (") fpe_max(", stdout);
10601 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
10602 fputs (")", stdout);
10603
10604 if (option->info & OEX_PAGE0)
10605 fputs (" PAGE0", stdout);
10606 if (option->info & OEX_SMM)
10607 fputs (" SMM", stdout);
10608 if (option->info & OEX_FPDBUG)
10609 fputs (" FPDBUG", stdout);
10610 if (option->info & OEX_DISMISS)
10611 fputs (" DISMISS", stdout);
10612 break;
10613 case ODK_PAD:
10614 fputs (" PAD ", stdout);
10615 if (option->info & OPAD_PREFIX)
10616 fputs (" PREFIX", stdout);
10617 if (option->info & OPAD_POSTFIX)
10618 fputs (" POSTFIX", stdout);
10619 if (option->info & OPAD_SYMBOL)
10620 fputs (" SYMBOL", stdout);
10621 break;
10622 case ODK_HWPATCH:
10623 fputs (" HWPATCH ", stdout);
10624 if (option->info & OHW_R4KEOP)
10625 fputs (" R4KEOP", stdout);
10626 if (option->info & OHW_R8KPFETCH)
10627 fputs (" R8KPFETCH", stdout);
10628 if (option->info & OHW_R5KEOP)
10629 fputs (" R5KEOP", stdout);
10630 if (option->info & OHW_R5KCVTL)
10631 fputs (" R5KCVTL", stdout);
10632 break;
10633 case ODK_FILL:
10634 fputs (" FILL ", stdout);
10635 /* XXX Print content of info word? */
10636 break;
10637 case ODK_TAGS:
10638 fputs (" TAGS ", stdout);
10639 /* XXX Print content of info word? */
10640 break;
10641 case ODK_HWAND:
10642 fputs (" HWAND ", stdout);
10643 if (option->info & OHWA0_R4KEOP_CHECKED)
10644 fputs (" R4KEOP_CHECKED", stdout);
10645 if (option->info & OHWA0_R4KEOP_CLEAN)
10646 fputs (" R4KEOP_CLEAN", stdout);
10647 break;
10648 case ODK_HWOR:
10649 fputs (" HWOR ", stdout);
10650 if (option->info & OHWA0_R4KEOP_CHECKED)
10651 fputs (" R4KEOP_CHECKED", stdout);
10652 if (option->info & OHWA0_R4KEOP_CLEAN)
10653 fputs (" R4KEOP_CLEAN", stdout);
10654 break;
10655 case ODK_GP_GROUP:
10656 printf (" GP_GROUP %#06lx self-contained %#06lx",
10657 option->info & OGP_GROUP,
10658 (option->info & OGP_SELF) >> 16);
10659 break;
10660 case ODK_IDENT:
10661 printf (" IDENT %#06lx self-contained %#06lx",
10662 option->info & OGP_GROUP,
10663 (option->info & OGP_SELF) >> 16);
10664 break;
10665 default:
10666 /* This shouldn't happen. */
10667 printf (" %3d ??? %d %lx",
10668 option->kind, option->section, option->info);
10669 break;
252b5132 10670 }
a6e9f9df 10671
2cf0635d 10672 len = sizeof (* eopt);
a6e9f9df
AM
10673 while (len < option->size)
10674 if (((char *) option)[len] >= ' '
10675 && ((char *) option)[len] < 0x7f)
10676 printf ("%c", ((char *) option)[len++]);
10677 else
10678 printf ("\\%03o", ((char *) option)[len++]);
10679
10680 fputs ("\n", stdout);
252b5132 10681 ++option;
252b5132
RH
10682 }
10683
a6e9f9df 10684 free (eopt);
252b5132 10685 }
252b5132
RH
10686 }
10687
10688 if (conflicts_offset != 0 && conflictsno != 0)
10689 {
2cf0635d 10690 Elf32_Conflict * iconf;
252b5132
RH
10691 size_t cnt;
10692
10693 if (dynamic_symbols == NULL)
10694 {
591a748a 10695 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
10696 return 0;
10697 }
10698
3f5e193b 10699 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
10700 if (iconf == NULL)
10701 {
591a748a 10702 error (_("Out of memory\n"));
252b5132
RH
10703 return 0;
10704 }
10705
9ea033b2 10706 if (is_32bit_elf)
252b5132 10707 {
2cf0635d 10708 Elf32_External_Conflict * econf32;
a6e9f9df 10709
3f5e193b
NC
10710 econf32 = (Elf32_External_Conflict *)
10711 get_data (NULL, file, conflicts_offset, conflictsno,
10712 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
10713 if (!econf32)
10714 return 0;
252b5132
RH
10715
10716 for (cnt = 0; cnt < conflictsno; ++cnt)
10717 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
10718
10719 free (econf32);
252b5132
RH
10720 }
10721 else
10722 {
2cf0635d 10723 Elf64_External_Conflict * econf64;
a6e9f9df 10724
3f5e193b
NC
10725 econf64 = (Elf64_External_Conflict *)
10726 get_data (NULL, file, conflicts_offset, conflictsno,
10727 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
10728 if (!econf64)
10729 return 0;
252b5132
RH
10730
10731 for (cnt = 0; cnt < conflictsno; ++cnt)
10732 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
10733
10734 free (econf64);
252b5132
RH
10735 }
10736
c7e7ca54
NC
10737 printf (_("\nSection '.conflict' contains %lu entries:\n"),
10738 (unsigned long) conflictsno);
252b5132
RH
10739 puts (_(" Num: Index Value Name"));
10740
10741 for (cnt = 0; cnt < conflictsno; ++cnt)
10742 {
2cf0635d 10743 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 10744
b34976b6 10745 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 10746 print_vma (psym->st_value, FULL_HEX);
31104126 10747 putchar (' ');
d79b3d50
NC
10748 if (VALID_DYNAMIC_NAME (psym->st_name))
10749 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10750 else
10751 printf ("<corrupt: %14ld>", psym->st_name);
31104126 10752 putchar ('\n');
252b5132
RH
10753 }
10754
252b5132
RH
10755 free (iconf);
10756 }
10757
ccb4c951
RS
10758 if (pltgot != 0 && local_gotno != 0)
10759 {
91d6fa6a 10760 bfd_vma ent, local_end, global_end;
bbeee7ea 10761 size_t i, offset;
2cf0635d 10762 unsigned char * data;
bbeee7ea 10763 int addr_size;
ccb4c951 10764
91d6fa6a 10765 ent = pltgot;
ccb4c951
RS
10766 addr_size = (is_32bit_elf ? 4 : 8);
10767 local_end = pltgot + local_gotno * addr_size;
10768 global_end = local_end + (symtabno - gotsym) * addr_size;
10769
10770 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b
NC
10771 data = (unsigned char *) get_data (NULL, file, offset,
10772 global_end - pltgot, 1, _("GOT"));
ccb4c951
RS
10773 printf (_("\nPrimary GOT:\n"));
10774 printf (_(" Canonical gp value: "));
10775 print_vma (pltgot + 0x7ff0, LONG_HEX);
10776 printf ("\n\n");
10777
10778 printf (_(" Reserved entries:\n"));
10779 printf (_(" %*s %10s %*s Purpose\n"),
10780 addr_size * 2, "Address", "Access",
10781 addr_size * 2, "Initial");
91d6fa6a 10782 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
10783 printf (" Lazy resolver\n");
10784 if (data
91d6fa6a 10785 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
10786 >> (addr_size * 8 - 1)) != 0)
10787 {
91d6fa6a 10788 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
10789 printf (" Module pointer (GNU extension)\n");
10790 }
10791 printf ("\n");
10792
91d6fa6a 10793 if (ent < local_end)
ccb4c951
RS
10794 {
10795 printf (_(" Local entries:\n"));
10796 printf (_(" %*s %10s %*s\n"),
10797 addr_size * 2, "Address", "Access",
10798 addr_size * 2, "Initial");
91d6fa6a 10799 while (ent < local_end)
ccb4c951 10800 {
91d6fa6a 10801 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
10802 printf ("\n");
10803 }
10804 printf ("\n");
10805 }
10806
10807 if (gotsym < symtabno)
10808 {
10809 int sym_width;
10810
10811 printf (_(" Global entries:\n"));
10812 printf (_(" %*s %10s %*s %*s %-7s %3s %s\n"),
10813 addr_size * 2, "Address", "Access",
10814 addr_size * 2, "Initial",
10815 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
10816 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
10817 for (i = gotsym; i < symtabno; i++)
10818 {
2cf0635d 10819 Elf_Internal_Sym * psym;
ccb4c951
RS
10820
10821 psym = dynamic_symbols + i;
91d6fa6a 10822 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
10823 printf (" ");
10824 print_vma (psym->st_value, LONG_HEX);
10825 printf (" %-7s %3s ",
10826 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
10827 get_symbol_index_type (psym->st_shndx));
10828 if (VALID_DYNAMIC_NAME (psym->st_name))
10829 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
10830 else
10831 printf ("<corrupt: %14ld>", psym->st_name);
10832 printf ("\n");
10833 }
10834 printf ("\n");
10835 }
10836
10837 if (data)
10838 free (data);
10839 }
10840
861fb55a
DJ
10841 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
10842 {
91d6fa6a 10843 bfd_vma ent, end;
861fb55a
DJ
10844 size_t offset, rel_offset;
10845 unsigned long count, i;
2cf0635d 10846 unsigned char * data;
861fb55a 10847 int addr_size, sym_width;
2cf0635d 10848 Elf_Internal_Rela * rels;
861fb55a
DJ
10849
10850 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
10851 if (pltrel == DT_RELA)
10852 {
10853 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
10854 return 0;
10855 }
10856 else
10857 {
10858 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
10859 return 0;
10860 }
10861
91d6fa6a 10862 ent = mips_pltgot;
861fb55a
DJ
10863 addr_size = (is_32bit_elf ? 4 : 8);
10864 end = mips_pltgot + (2 + count) * addr_size;
10865
10866 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b
NC
10867 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
10868 1, _("PLT GOT"));
861fb55a
DJ
10869 printf (_("\nPLT GOT:\n\n"));
10870 printf (_(" Reserved entries:\n"));
10871 printf (_(" %*s %*s Purpose\n"),
10872 addr_size * 2, "Address", addr_size * 2, "Initial");
91d6fa6a 10873 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 10874 printf (" PLT lazy resolver\n");
91d6fa6a 10875 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
10876 printf (" Module pointer\n");
10877 printf ("\n");
10878
10879 printf (_(" Entries:\n"));
10880 printf (_(" %*s %*s %*s %-7s %3s %s\n"),
10881 addr_size * 2, "Address",
10882 addr_size * 2, "Initial",
10883 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
10884 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
10885 for (i = 0; i < count; i++)
10886 {
2cf0635d 10887 Elf_Internal_Sym * psym;
861fb55a
DJ
10888
10889 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 10890 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
10891 printf (" ");
10892 print_vma (psym->st_value, LONG_HEX);
10893 printf (" %-7s %3s ",
10894 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
10895 get_symbol_index_type (psym->st_shndx));
10896 if (VALID_DYNAMIC_NAME (psym->st_name))
10897 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
10898 else
10899 printf ("<corrupt: %14ld>", psym->st_name);
10900 printf ("\n");
10901 }
10902 printf ("\n");
10903
10904 if (data)
10905 free (data);
10906 free (rels);
10907 }
10908
252b5132
RH
10909 return 1;
10910}
10911
047b2264 10912static int
2cf0635d 10913process_gnu_liblist (FILE * file)
047b2264 10914{
2cf0635d
NC
10915 Elf_Internal_Shdr * section;
10916 Elf_Internal_Shdr * string_sec;
10917 Elf32_External_Lib * elib;
10918 char * strtab;
c256ffe7 10919 size_t strtab_size;
047b2264
JJ
10920 size_t cnt;
10921 unsigned i;
10922
10923 if (! do_arch)
10924 return 0;
10925
10926 for (i = 0, section = section_headers;
10927 i < elf_header.e_shnum;
b34976b6 10928 i++, section++)
047b2264
JJ
10929 {
10930 switch (section->sh_type)
10931 {
10932 case SHT_GNU_LIBLIST:
4fbb74a6 10933 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
10934 break;
10935
3f5e193b
NC
10936 elib = (Elf32_External_Lib *)
10937 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
10938 _("liblist"));
047b2264
JJ
10939
10940 if (elib == NULL)
10941 break;
4fbb74a6 10942 string_sec = section_headers + section->sh_link;
047b2264 10943
3f5e193b
NC
10944 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
10945 string_sec->sh_size,
10946 _("liblist string table"));
c256ffe7 10947 strtab_size = string_sec->sh_size;
047b2264
JJ
10948
10949 if (strtab == NULL
10950 || section->sh_entsize != sizeof (Elf32_External_Lib))
10951 {
10952 free (elib);
10953 break;
10954 }
10955
10956 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
10957 SECTION_NAME (section),
0af1713e 10958 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264
JJ
10959
10960 puts (" Library Time Stamp Checksum Version Flags");
10961
10962 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
10963 ++cnt)
10964 {
10965 Elf32_Lib liblist;
91d6fa6a 10966 time_t atime;
047b2264 10967 char timebuf[20];
2cf0635d 10968 struct tm * tmp;
047b2264
JJ
10969
10970 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 10971 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
10972 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10973 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10974 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10975
91d6fa6a 10976 tmp = gmtime (&atime);
e9e44622
JJ
10977 snprintf (timebuf, sizeof (timebuf),
10978 "%04u-%02u-%02uT%02u:%02u:%02u",
10979 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10980 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10981
10982 printf ("%3lu: ", (unsigned long) cnt);
10983 if (do_wide)
c256ffe7
JJ
10984 printf ("%-20s", liblist.l_name < strtab_size
10985 ? strtab + liblist.l_name : "<corrupt>");
047b2264 10986 else
c256ffe7
JJ
10987 printf ("%-20.20s", liblist.l_name < strtab_size
10988 ? strtab + liblist.l_name : "<corrupt>");
047b2264
JJ
10989 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
10990 liblist.l_version, liblist.l_flags);
10991 }
10992
10993 free (elib);
10994 }
10995 }
10996
10997 return 1;
10998}
10999
9437c45b 11000static const char *
d3ba0551 11001get_note_type (unsigned e_type)
779fe533
NC
11002{
11003 static char buff[64];
103f02d3 11004
1ec5cd37
NC
11005 if (elf_header.e_type == ET_CORE)
11006 switch (e_type)
11007 {
57346661 11008 case NT_AUXV:
1ec5cd37 11009 return _("NT_AUXV (auxiliary vector)");
57346661 11010 case NT_PRSTATUS:
1ec5cd37 11011 return _("NT_PRSTATUS (prstatus structure)");
57346661 11012 case NT_FPREGSET:
1ec5cd37 11013 return _("NT_FPREGSET (floating point registers)");
57346661 11014 case NT_PRPSINFO:
1ec5cd37 11015 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 11016 case NT_TASKSTRUCT:
1ec5cd37 11017 return _("NT_TASKSTRUCT (task structure)");
57346661 11018 case NT_PRXFPREG:
1ec5cd37 11019 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
11020 case NT_PPC_VMX:
11021 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
11022 case NT_PPC_VSX:
11023 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
11024 case NT_X86_XSTATE:
11025 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
11026 case NT_S390_HIGH_GPRS:
11027 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
11028 case NT_S390_TIMER:
11029 return _("NT_S390_TIMER (s390 timer register)");
11030 case NT_S390_TODCMP:
11031 return _("NT_S390_TODCMP (s390 TOD comparator register)");
11032 case NT_S390_TODPREG:
11033 return _("NT_S390_TODPREG (s390 TOD programmable register)");
11034 case NT_S390_CTRS:
11035 return _("NT_S390_CTRS (s390 control registers)");
11036 case NT_S390_PREFIX:
11037 return _("NT_S390_PREFIX (s390 prefix register)");
57346661 11038 case NT_PSTATUS:
1ec5cd37 11039 return _("NT_PSTATUS (pstatus structure)");
57346661 11040 case NT_FPREGS:
1ec5cd37 11041 return _("NT_FPREGS (floating point registers)");
57346661 11042 case NT_PSINFO:
1ec5cd37 11043 return _("NT_PSINFO (psinfo structure)");
57346661 11044 case NT_LWPSTATUS:
1ec5cd37 11045 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 11046 case NT_LWPSINFO:
1ec5cd37 11047 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 11048 case NT_WIN32PSTATUS:
1ec5cd37
NC
11049 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
11050 default:
11051 break;
11052 }
11053 else
11054 switch (e_type)
11055 {
11056 case NT_VERSION:
11057 return _("NT_VERSION (version)");
11058 case NT_ARCH:
11059 return _("NT_ARCH (architecture)");
11060 default:
11061 break;
11062 }
11063
e9e44622 11064 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 11065 return buff;
779fe533
NC
11066}
11067
1118d252
RM
11068static const char *
11069get_gnu_elf_note_type (unsigned e_type)
11070{
11071 static char buff[64];
11072
11073 switch (e_type)
11074 {
11075 case NT_GNU_ABI_TAG:
11076 return _("NT_GNU_ABI_TAG (ABI version tag)");
11077 case NT_GNU_HWCAP:
11078 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
11079 case NT_GNU_BUILD_ID:
11080 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
11081 case NT_GNU_GOLD_VERSION:
11082 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
11083 default:
11084 break;
11085 }
11086
11087 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
11088 return buff;
11089}
11090
9437c45b 11091static const char *
d3ba0551 11092get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
11093{
11094 static char buff[64];
11095
b4db1224 11096 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
11097 {
11098 /* NetBSD core "procinfo" structure. */
11099 return _("NetBSD procinfo structure");
11100 }
11101
11102 /* As of Jan 2002 there are no other machine-independent notes
11103 defined for NetBSD core files. If the note type is less
11104 than the start of the machine-dependent note types, we don't
11105 understand it. */
11106
b4db1224 11107 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 11108 {
e9e44622 11109 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
11110 return buff;
11111 }
11112
11113 switch (elf_header.e_machine)
11114 {
11115 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
11116 and PT_GETFPREGS == mach+2. */
11117
11118 case EM_OLD_ALPHA:
11119 case EM_ALPHA:
11120 case EM_SPARC:
11121 case EM_SPARC32PLUS:
11122 case EM_SPARCV9:
11123 switch (e_type)
11124 {
b4db1224
JT
11125 case NT_NETBSDCORE_FIRSTMACH+0:
11126 return _("PT_GETREGS (reg structure)");
11127 case NT_NETBSDCORE_FIRSTMACH+2:
11128 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11129 default:
11130 break;
11131 }
11132 break;
11133
11134 /* On all other arch's, PT_GETREGS == mach+1 and
11135 PT_GETFPREGS == mach+3. */
11136 default:
11137 switch (e_type)
11138 {
b4db1224
JT
11139 case NT_NETBSDCORE_FIRSTMACH+1:
11140 return _("PT_GETREGS (reg structure)");
11141 case NT_NETBSDCORE_FIRSTMACH+3:
11142 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11143 default:
11144 break;
11145 }
11146 }
11147
e9e44622
JJ
11148 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
11149 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
11150 return buff;
11151}
11152
6d118b09
NC
11153/* Note that by the ELF standard, the name field is already null byte
11154 terminated, and namesz includes the terminating null byte.
11155 I.E. the value of namesz for the name "FSF" is 4.
11156
e3c8793a 11157 If the value of namesz is zero, there is no name present. */
779fe533 11158static int
2cf0635d 11159process_note (Elf_Internal_Note * pnote)
779fe533 11160{
2cf0635d
NC
11161 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
11162 const char * nt;
9437c45b
JT
11163
11164 if (pnote->namesz == 0)
1ec5cd37
NC
11165 /* If there is no note name, then use the default set of
11166 note type strings. */
11167 nt = get_note_type (pnote->type);
11168
1118d252
RM
11169 else if (const_strneq (pnote->namedata, "GNU"))
11170 /* GNU-specific object file notes. */
11171 nt = get_gnu_elf_note_type (pnote->type);
11172
0112cd26 11173 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
11174 /* NetBSD-specific core file notes. */
11175 nt = get_netbsd_elfcore_note_type (pnote->type);
11176
b15fa79e
AM
11177 else if (strneq (pnote->namedata, "SPU/", 4))
11178 {
11179 /* SPU-specific core file notes. */
11180 nt = pnote->namedata + 4;
11181 name = "SPU";
11182 }
11183
9437c45b 11184 else
1ec5cd37
NC
11185 /* Don't recognize this note name; just use the default set of
11186 note type strings. */
9437c45b 11187 nt = get_note_type (pnote->type);
9437c45b 11188
b15fa79e 11189 printf (" %s\t\t0x%08lx\t%s\n", name, pnote->descsz, nt);
779fe533
NC
11190 return 1;
11191}
11192
6d118b09 11193
779fe533 11194static int
2cf0635d 11195process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 11196{
2cf0635d
NC
11197 Elf_External_Note * pnotes;
11198 Elf_External_Note * external;
b34976b6 11199 int res = 1;
103f02d3 11200
779fe533
NC
11201 if (length <= 0)
11202 return 0;
103f02d3 11203
3f5e193b
NC
11204 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
11205 _("notes"));
a6e9f9df
AM
11206 if (!pnotes)
11207 return 0;
779fe533 11208
103f02d3 11209 external = pnotes;
103f02d3 11210
305c7206 11211 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 11212 (unsigned long) offset, (unsigned long) length);
779fe533 11213 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 11214
2cf0635d 11215 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 11216 {
2cf0635d 11217 Elf_External_Note * next;
b34976b6 11218 Elf_Internal_Note inote;
2cf0635d 11219 char * temp = NULL;
6d118b09
NC
11220
11221 inote.type = BYTE_GET (external->type);
11222 inote.namesz = BYTE_GET (external->namesz);
11223 inote.namedata = external->name;
11224 inote.descsz = BYTE_GET (external->descsz);
11225 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
11226 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 11227
2cf0635d 11228 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
3e55a963
NC
11229
11230 if (((char *) next) > (((char *) pnotes) + length))
11231 {
0fd3a477 11232 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 11233 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 11234 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
11235 inote.type, inote.namesz, inote.descsz);
11236 break;
11237 }
11238
11239 external = next;
6d118b09
NC
11240
11241 /* Verify that name is null terminated. It appears that at least
11242 one version of Linux (RedHat 6.0) generates corefiles that don't
11243 comply with the ELF spec by failing to include the null byte in
11244 namesz. */
11245 if (inote.namedata[inote.namesz] != '\0')
11246 {
3f5e193b 11247 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 11248
6d118b09
NC
11249 if (temp == NULL)
11250 {
11251 error (_("Out of memory\n"));
11252 res = 0;
11253 break;
11254 }
76da6bbe 11255
6d118b09
NC
11256 strncpy (temp, inote.namedata, inote.namesz);
11257 temp[inote.namesz] = 0;
76da6bbe 11258
6d118b09
NC
11259 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
11260 inote.namedata = temp;
11261 }
11262
11263 res &= process_note (& inote);
103f02d3 11264
6d118b09
NC
11265 if (temp != NULL)
11266 {
11267 free (temp);
11268 temp = NULL;
11269 }
779fe533
NC
11270 }
11271
11272 free (pnotes);
103f02d3 11273
779fe533
NC
11274 return res;
11275}
11276
11277static int
2cf0635d 11278process_corefile_note_segments (FILE * file)
779fe533 11279{
2cf0635d 11280 Elf_Internal_Phdr * segment;
b34976b6
AM
11281 unsigned int i;
11282 int res = 1;
103f02d3 11283
d93f0186 11284 if (! get_program_headers (file))
779fe533 11285 return 0;
103f02d3 11286
779fe533
NC
11287 for (i = 0, segment = program_headers;
11288 i < elf_header.e_phnum;
b34976b6 11289 i++, segment++)
779fe533
NC
11290 {
11291 if (segment->p_type == PT_NOTE)
103f02d3 11292 res &= process_corefile_note_segment (file,
30800947
NC
11293 (bfd_vma) segment->p_offset,
11294 (bfd_vma) segment->p_filesz);
779fe533 11295 }
103f02d3 11296
779fe533
NC
11297 return res;
11298}
11299
11300static int
2cf0635d 11301process_note_sections (FILE * file)
1ec5cd37 11302{
2cf0635d 11303 Elf_Internal_Shdr * section;
1ec5cd37
NC
11304 unsigned long i;
11305 int res = 1;
11306
11307 for (i = 0, section = section_headers;
11308 i < elf_header.e_shnum;
11309 i++, section++)
11310 if (section->sh_type == SHT_NOTE)
11311 res &= process_corefile_note_segment (file,
11312 (bfd_vma) section->sh_offset,
11313 (bfd_vma) section->sh_size);
11314
11315 return res;
11316}
11317
11318static int
2cf0635d 11319process_notes (FILE * file)
779fe533
NC
11320{
11321 /* If we have not been asked to display the notes then do nothing. */
11322 if (! do_notes)
11323 return 1;
103f02d3 11324
779fe533 11325 if (elf_header.e_type != ET_CORE)
1ec5cd37 11326 return process_note_sections (file);
103f02d3 11327
779fe533 11328 /* No program headers means no NOTE segment. */
1ec5cd37
NC
11329 if (elf_header.e_phnum > 0)
11330 return process_corefile_note_segments (file);
779fe533 11331
1ec5cd37
NC
11332 printf (_("No note segments present in the core file.\n"));
11333 return 1;
779fe533
NC
11334}
11335
252b5132 11336static int
2cf0635d 11337process_arch_specific (FILE * file)
252b5132 11338{
a952a375
NC
11339 if (! do_arch)
11340 return 1;
11341
252b5132
RH
11342 switch (elf_header.e_machine)
11343 {
11c1ff18
PB
11344 case EM_ARM:
11345 return process_arm_specific (file);
252b5132 11346 case EM_MIPS:
4fe85591 11347 case EM_MIPS_RS3_LE:
252b5132
RH
11348 return process_mips_specific (file);
11349 break;
34c8bcba
JM
11350 case EM_PPC:
11351 return process_power_specific (file);
11352 break;
252b5132
RH
11353 default:
11354 break;
11355 }
11356 return 1;
11357}
11358
11359static int
2cf0635d 11360get_file_header (FILE * file)
252b5132 11361{
9ea033b2
NC
11362 /* Read in the identity array. */
11363 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
11364 return 0;
11365
9ea033b2 11366 /* Determine how to read the rest of the header. */
b34976b6 11367 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
11368 {
11369 default: /* fall through */
11370 case ELFDATANONE: /* fall through */
adab8cdc
AO
11371 case ELFDATA2LSB:
11372 byte_get = byte_get_little_endian;
11373 byte_put = byte_put_little_endian;
11374 break;
11375 case ELFDATA2MSB:
11376 byte_get = byte_get_big_endian;
11377 byte_put = byte_put_big_endian;
11378 break;
9ea033b2
NC
11379 }
11380
11381 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 11382 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
11383
11384 /* Read in the rest of the header. */
11385 if (is_32bit_elf)
11386 {
11387 Elf32_External_Ehdr ehdr32;
252b5132 11388
9ea033b2
NC
11389 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
11390 return 0;
103f02d3 11391
9ea033b2
NC
11392 elf_header.e_type = BYTE_GET (ehdr32.e_type);
11393 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
11394 elf_header.e_version = BYTE_GET (ehdr32.e_version);
11395 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
11396 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
11397 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
11398 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
11399 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
11400 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
11401 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
11402 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
11403 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
11404 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
11405 }
252b5132 11406 else
9ea033b2
NC
11407 {
11408 Elf64_External_Ehdr ehdr64;
a952a375
NC
11409
11410 /* If we have been compiled with sizeof (bfd_vma) == 4, then
11411 we will not be able to cope with the 64bit data found in
11412 64 ELF files. Detect this now and abort before we start
50c2245b 11413 overwriting things. */
a952a375
NC
11414 if (sizeof (bfd_vma) < 8)
11415 {
e3c8793a
NC
11416 error (_("This instance of readelf has been built without support for a\n\
1141764 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
11418 return 0;
11419 }
103f02d3 11420
9ea033b2
NC
11421 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
11422 return 0;
103f02d3 11423
9ea033b2
NC
11424 elf_header.e_type = BYTE_GET (ehdr64.e_type);
11425 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
11426 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
11427 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
11428 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
11429 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
11430 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
11431 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
11432 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
11433 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
11434 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
11435 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
11436 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
11437 }
252b5132 11438
7ece0d85
JJ
11439 if (elf_header.e_shoff)
11440 {
11441 /* There may be some extensions in the first section header. Don't
11442 bomb if we can't read it. */
11443 if (is_32bit_elf)
11444 get_32bit_section_headers (file, 1);
11445 else
11446 get_64bit_section_headers (file, 1);
11447 }
560f3c1c 11448
252b5132
RH
11449 return 1;
11450}
11451
fb52b2f4
NC
11452/* Process one ELF object file according to the command line options.
11453 This file may actually be stored in an archive. The file is
11454 positioned at the start of the ELF object. */
11455
ff78d6d6 11456static int
2cf0635d 11457process_object (char * file_name, FILE * file)
252b5132 11458{
252b5132
RH
11459 unsigned int i;
11460
252b5132
RH
11461 if (! get_file_header (file))
11462 {
11463 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 11464 return 1;
252b5132
RH
11465 }
11466
11467 /* Initialise per file variables. */
60bca95a 11468 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
11469 version_info[i] = 0;
11470
60bca95a 11471 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132
RH
11472 dynamic_info[i] = 0;
11473
11474 /* Process the file. */
11475 if (show_name)
11476 printf (_("\nFile: %s\n"), file_name);
11477
18bd398b
NC
11478 /* Initialise the dump_sects array from the cmdline_dump_sects array.
11479 Note we do this even if cmdline_dump_sects is empty because we
11480 must make sure that the dump_sets array is zeroed out before each
11481 object file is processed. */
11482 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 11483 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
11484
11485 if (num_cmdline_dump_sects > 0)
11486 {
11487 if (num_dump_sects == 0)
11488 /* A sneaky way of allocating the dump_sects array. */
09c11c86 11489 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
11490
11491 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
11492 memcpy (dump_sects, cmdline_dump_sects,
11493 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 11494 }
d70c5fc7 11495
252b5132 11496 if (! process_file_header ())
fb52b2f4 11497 return 1;
252b5132 11498
d1f5c6e3 11499 if (! process_section_headers (file))
2f62977e 11500 {
d1f5c6e3
L
11501 /* Without loaded section headers we cannot process lots of
11502 things. */
2f62977e 11503 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 11504
2f62977e 11505 if (! do_using_dynamic)
2c610e4b 11506 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 11507 }
252b5132 11508
d1f5c6e3
L
11509 if (! process_section_groups (file))
11510 {
11511 /* Without loaded section groups we cannot process unwind. */
11512 do_unwind = 0;
11513 }
11514
2f62977e 11515 if (process_program_headers (file))
b2d38a17 11516 process_dynamic_section (file);
252b5132
RH
11517
11518 process_relocs (file);
11519
4d6ed7c8
NC
11520 process_unwind (file);
11521
252b5132
RH
11522 process_symbol_table (file);
11523
11524 process_syminfo (file);
11525
11526 process_version_sections (file);
11527
11528 process_section_contents (file);
f5842774 11529
1ec5cd37 11530 process_notes (file);
103f02d3 11531
047b2264
JJ
11532 process_gnu_liblist (file);
11533
252b5132
RH
11534 process_arch_specific (file);
11535
d93f0186
NC
11536 if (program_headers)
11537 {
11538 free (program_headers);
11539 program_headers = NULL;
11540 }
11541
252b5132
RH
11542 if (section_headers)
11543 {
11544 free (section_headers);
11545 section_headers = NULL;
11546 }
11547
11548 if (string_table)
11549 {
11550 free (string_table);
11551 string_table = NULL;
d40ac9bd 11552 string_table_length = 0;
252b5132
RH
11553 }
11554
11555 if (dynamic_strings)
11556 {
11557 free (dynamic_strings);
11558 dynamic_strings = NULL;
d79b3d50 11559 dynamic_strings_length = 0;
252b5132
RH
11560 }
11561
11562 if (dynamic_symbols)
11563 {
11564 free (dynamic_symbols);
11565 dynamic_symbols = NULL;
19936277 11566 num_dynamic_syms = 0;
252b5132
RH
11567 }
11568
11569 if (dynamic_syminfo)
11570 {
11571 free (dynamic_syminfo);
11572 dynamic_syminfo = NULL;
11573 }
ff78d6d6 11574
e4b17d5c
L
11575 if (section_headers_groups)
11576 {
11577 free (section_headers_groups);
11578 section_headers_groups = NULL;
11579 }
11580
11581 if (section_groups)
11582 {
2cf0635d
NC
11583 struct group_list * g;
11584 struct group_list * next;
e4b17d5c
L
11585
11586 for (i = 0; i < group_count; i++)
11587 {
11588 for (g = section_groups [i].root; g != NULL; g = next)
11589 {
11590 next = g->next;
11591 free (g);
11592 }
11593 }
11594
11595 free (section_groups);
11596 section_groups = NULL;
11597 }
11598
19e6b90e 11599 free_debug_memory ();
18bd398b 11600
ff78d6d6 11601 return 0;
252b5132
RH
11602}
11603
2cf0635d
NC
11604/* Return the path name for a proxy entry in a thin archive, adjusted relative
11605 to the path name of the thin archive itself if necessary. Always returns
11606 a pointer to malloc'ed memory. */
11607
11608static char *
11609adjust_relative_path (char * file_name, char * name, int name_len)
11610{
11611 char * member_file_name;
11612 const char * base_name = lbasename (file_name);
11613
11614 /* This is a proxy entry for a thin archive member.
11615 If the extended name table contains an absolute path
11616 name, or if the archive is in the current directory,
11617 use the path name as given. Otherwise, we need to
11618 find the member relative to the directory where the
11619 archive is located. */
11620 if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
11621 {
3f5e193b 11622 member_file_name = (char *) malloc (name_len + 1);
2cf0635d
NC
11623 if (member_file_name == NULL)
11624 {
11625 error (_("Out of memory\n"));
11626 return NULL;
11627 }
11628 memcpy (member_file_name, name, name_len);
11629 member_file_name[name_len] = '\0';
11630 }
11631 else
11632 {
11633 /* Concatenate the path components of the archive file name
11634 to the relative path name from the extended name table. */
11635 size_t prefix_len = base_name - file_name;
3f5e193b 11636 member_file_name = (char *) malloc (prefix_len + name_len + 1);
2cf0635d
NC
11637 if (member_file_name == NULL)
11638 {
11639 error (_("Out of memory\n"));
11640 return NULL;
11641 }
11642 memcpy (member_file_name, file_name, prefix_len);
11643 memcpy (member_file_name + prefix_len, name, name_len);
11644 member_file_name[prefix_len + name_len] = '\0';
11645 }
11646 return member_file_name;
11647}
11648
11649/* Structure to hold information about an archive file. */
11650
11651struct archive_info
11652{
11653 char * file_name; /* Archive file name. */
11654 FILE * file; /* Open file descriptor. */
11655 unsigned long index_num; /* Number of symbols in table. */
11656 unsigned long * index_array; /* The array of member offsets. */
11657 char * sym_table; /* The symbol table. */
11658 unsigned long sym_size; /* Size of the symbol table. */
11659 char * longnames; /* The long file names table. */
11660 unsigned long longnames_size; /* Size of the long file names table. */
11661 unsigned long nested_member_origin; /* Origin in the nested archive of the current member. */
11662 unsigned long next_arhdr_offset; /* Offset of the next archive header. */
11663 bfd_boolean is_thin_archive; /* TRUE if this is a thin archive. */
11664 struct ar_hdr arhdr; /* Current archive header. */
11665};
11666
11667/* Read the symbol table and long-name table from an archive. */
fb52b2f4
NC
11668
11669static int
2cf0635d
NC
11670setup_archive (struct archive_info * arch, char * file_name, FILE * file,
11671 bfd_boolean is_thin_archive, bfd_boolean read_symbols)
fb52b2f4 11672{
fb52b2f4
NC
11673 size_t got;
11674 unsigned long size;
fb52b2f4 11675
2cf0635d
NC
11676 arch->file_name = strdup (file_name);
11677 arch->file = file;
11678 arch->index_num = 0;
11679 arch->index_array = NULL;
11680 arch->sym_table = NULL;
11681 arch->sym_size = 0;
11682 arch->longnames = NULL;
11683 arch->longnames_size = 0;
11684 arch->nested_member_origin = 0;
11685 arch->is_thin_archive = is_thin_archive;
11686 arch->next_arhdr_offset = SARMAG;
11687
11688 /* Read the first archive member header. */
11689 if (fseek (file, SARMAG, SEEK_SET) != 0)
11690 {
11691 error (_("%s: failed to seek to first archive header\n"), file_name);
11692 return 1;
11693 }
11694 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
11695 if (got != sizeof arch->arhdr)
fb52b2f4
NC
11696 {
11697 if (got == 0)
11698 return 0;
11699
11700 error (_("%s: failed to read archive header\n"), file_name);
11701 return 1;
11702 }
11703
4145f1d5 11704 /* See if this is the archive symbol table. */
2cf0635d
NC
11705 if (const_strneq (arch->arhdr.ar_name, "/ ")
11706 || const_strneq (arch->arhdr.ar_name, "/SYM64/ "))
fb52b2f4 11707 {
2cf0635d 11708 size = strtoul (arch->arhdr.ar_size, NULL, 10);
4145f1d5
NC
11709 size = size + (size & 1);
11710
2cf0635d
NC
11711 arch->next_arhdr_offset += sizeof arch->arhdr + size;
11712
11713 if (read_symbols)
fb52b2f4 11714 {
4145f1d5
NC
11715 unsigned long i;
11716 /* A buffer used to hold numbers read in from an archive index.
11717 These are always 4 bytes long and stored in big-endian format. */
11718#define SIZEOF_AR_INDEX_NUMBERS 4
11719 unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
11720 unsigned char * index_buffer;
11721
11722 /* Check the size of the archive index. */
11723 if (size < SIZEOF_AR_INDEX_NUMBERS)
11724 {
11725 error (_("%s: the archive index is empty\n"), file_name);
11726 return 1;
11727 }
11728
11729 /* Read the numer of entries in the archive index. */
11730 got = fread (integer_buffer, 1, sizeof integer_buffer, file);
11731 if (got != sizeof (integer_buffer))
11732 {
11733 error (_("%s: failed to read archive index\n"), file_name);
11734 return 1;
11735 }
2cf0635d 11736 arch->index_num = byte_get_big_endian (integer_buffer, sizeof integer_buffer);
4145f1d5
NC
11737 size -= SIZEOF_AR_INDEX_NUMBERS;
11738
11739 /* Read in the archive index. */
2cf0635d 11740 if (size < arch->index_num * SIZEOF_AR_INDEX_NUMBERS)
4145f1d5
NC
11741 {
11742 error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
2cf0635d 11743 file_name, arch->index_num);
4145f1d5
NC
11744 return 1;
11745 }
3f5e193b
NC
11746 index_buffer = (unsigned char *)
11747 malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
11748 if (index_buffer == NULL)
11749 {
11750 error (_("Out of memory whilst trying to read archive symbol index\n"));
11751 return 1;
11752 }
2cf0635d
NC
11753 got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, arch->index_num, file);
11754 if (got != arch->index_num)
4145f1d5
NC
11755 {
11756 free (index_buffer);
11757 error (_("%s: failed to read archive index\n"), file_name);
2cf0635d 11758 return 1;
4145f1d5 11759 }
2cf0635d 11760 size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS;
4145f1d5
NC
11761
11762 /* Convert the index numbers into the host's numeric format. */
3f5e193b
NC
11763 arch->index_array = (long unsigned int *)
11764 malloc (arch->index_num * sizeof (* arch->index_array));
2cf0635d 11765 if (arch->index_array == NULL)
4145f1d5
NC
11766 {
11767 free (index_buffer);
11768 error (_("Out of memory whilst trying to convert the archive symbol index\n"));
11769 return 1;
11770 }
11771
2cf0635d
NC
11772 for (i = 0; i < arch->index_num; i++)
11773 arch->index_array[i] = byte_get_big_endian ((unsigned char *) (index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
11774 SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
11775 free (index_buffer);
11776
11777 /* The remaining space in the header is taken up by the symbol table. */
11778 if (size < 1)
11779 {
11780 error (_("%s: the archive has an index but no symbols\n"), file_name);
2cf0635d 11781 return 1;
4145f1d5 11782 }
3f5e193b 11783 arch->sym_table = (char *) malloc (size);
2cf0635d
NC
11784 arch->sym_size = size;
11785 if (arch->sym_table == NULL)
4145f1d5
NC
11786 {
11787 error (_("Out of memory whilst trying to read archive index symbol table\n"));
2cf0635d 11788 return 1;
4145f1d5 11789 }
2cf0635d 11790 got = fread (arch->sym_table, 1, size, file);
4145f1d5
NC
11791 if (got != size)
11792 {
11793 error (_("%s: failed to read archive index symbol table\n"), file_name);
2cf0635d 11794 return 1;
cb8f3167 11795 }
4145f1d5
NC
11796 }
11797 else
11798 {
11799 if (fseek (file, size, SEEK_CUR) != 0)
11800 {
11801 error (_("%s: failed to skip archive symbol table\n"), file_name);
11802 return 1;
11803 }
fb52b2f4
NC
11804 }
11805
2cf0635d
NC
11806 /* Read the next archive header. */
11807 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
11808 if (got != sizeof arch->arhdr)
fb52b2f4
NC
11809 {
11810 if (got == 0)
2cf0635d 11811 return 0;
4145f1d5 11812 error (_("%s: failed to read archive header following archive index\n"), file_name);
2cf0635d 11813 return 1;
fb52b2f4
NC
11814 }
11815 }
2cf0635d 11816 else if (read_symbols)
4145f1d5 11817 printf (_("%s has no archive index\n"), file_name);
fb52b2f4 11818
2cf0635d 11819 if (const_strneq (arch->arhdr.ar_name, "// "))
fb52b2f4 11820 {
2cf0635d
NC
11821 /* This is the archive string table holding long member names. */
11822 arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
11823 arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
fb52b2f4 11824
3f5e193b 11825 arch->longnames = (char *) malloc (arch->longnames_size);
2cf0635d 11826 if (arch->longnames == NULL)
fb52b2f4 11827 {
4145f1d5 11828 error (_("Out of memory reading long symbol names in archive\n"));
2cf0635d 11829 return 1;
fb52b2f4
NC
11830 }
11831
2cf0635d 11832 if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
fb52b2f4 11833 {
2cf0635d
NC
11834 free (arch->longnames);
11835 arch->longnames = NULL;
4145f1d5 11836 error (_("%s: failed to read long symbol name string table\n"), file_name);
2cf0635d 11837 return 1;
fb52b2f4
NC
11838 }
11839
2cf0635d 11840 if ((arch->longnames_size & 1) != 0)
fb52b2f4 11841 getc (file);
2cf0635d 11842 }
fb52b2f4 11843
2cf0635d
NC
11844 return 0;
11845}
11846
11847/* Release the memory used for the archive information. */
11848
11849static void
11850release_archive (struct archive_info * arch)
11851{
11852 if (arch->file_name != NULL)
11853 free (arch->file_name);
11854 if (arch->index_array != NULL)
11855 free (arch->index_array);
11856 if (arch->sym_table != NULL)
11857 free (arch->sym_table);
11858 if (arch->longnames != NULL)
11859 free (arch->longnames);
11860}
11861
11862/* Open and setup a nested archive, if not already open. */
11863
11864static int
11865setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
11866{
11867 FILE * member_file;
11868
11869 /* Have we already setup this archive? */
11870 if (nested_arch->file_name != NULL
11871 && streq (nested_arch->file_name, member_file_name))
11872 return 0;
11873
11874 /* Close previous file and discard cached information. */
11875 if (nested_arch->file != NULL)
11876 fclose (nested_arch->file);
11877 release_archive (nested_arch);
11878
11879 member_file = fopen (member_file_name, "rb");
11880 if (member_file == NULL)
11881 return 1;
11882 return setup_archive (nested_arch, member_file_name, member_file, FALSE, FALSE);
11883}
11884
11885static char *
11886get_archive_member_name_at (struct archive_info * arch,
11887 unsigned long offset,
11888 struct archive_info * nested_arch);
11889
11890/* Get the name of an archive member from the current archive header.
11891 For simple names, this will modify the ar_name field of the current
11892 archive header. For long names, it will return a pointer to the
11893 longnames table. For nested archives, it will open the nested archive
11894 and get the name recursively. NESTED_ARCH is a single-entry cache so
11895 we don't keep rereading the same information from a nested archive. */
11896
11897static char *
11898get_archive_member_name (struct archive_info * arch,
11899 struct archive_info * nested_arch)
11900{
11901 unsigned long j, k;
11902
11903 if (arch->arhdr.ar_name[0] == '/')
11904 {
11905 /* We have a long name. */
11906 char * endp;
11907 char * member_file_name;
11908 char * member_name;
11909
11910 arch->nested_member_origin = 0;
11911 k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
11912 if (arch->is_thin_archive && endp != NULL && * endp == ':')
11913 arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
11914
11915 while ((j < arch->longnames_size)
11916 && (arch->longnames[j] != '\n')
11917 && (arch->longnames[j] != '\0'))
11918 j++;
11919 if (arch->longnames[j-1] == '/')
11920 j--;
11921 arch->longnames[j] = '\0';
11922
11923 if (!arch->is_thin_archive || arch->nested_member_origin == 0)
11924 return arch->longnames + k;
11925
11926 /* This is a proxy for a member of a nested archive.
11927 Find the name of the member in that archive. */
11928 member_file_name = adjust_relative_path (arch->file_name, arch->longnames + k, j - k);
11929 if (member_file_name != NULL
11930 && setup_nested_archive (nested_arch, member_file_name) == 0
11931 && (member_name = get_archive_member_name_at (nested_arch, arch->nested_member_origin, NULL)) != NULL)
11932 {
11933 free (member_file_name);
11934 return member_name;
11935 }
11936 free (member_file_name);
11937
11938 /* Last resort: just return the name of the nested archive. */
11939 return arch->longnames + k;
11940 }
11941
11942 /* We have a normal (short) name. */
11943 j = 0;
11944 while ((arch->arhdr.ar_name[j] != '/') && (j < 16))
11945 j++;
11946 arch->arhdr.ar_name[j] = '\0';
11947 return arch->arhdr.ar_name;
11948}
11949
11950/* Get the name of an archive member at a given OFFSET within an archive ARCH. */
11951
11952static char *
11953get_archive_member_name_at (struct archive_info * arch,
11954 unsigned long offset,
11955 struct archive_info * nested_arch)
11956{
11957 size_t got;
11958
11959 if (fseek (arch->file, offset, SEEK_SET) != 0)
11960 {
11961 error (_("%s: failed to seek to next file name\n"), arch->file_name);
11962 return NULL;
11963 }
11964 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
11965 if (got != sizeof arch->arhdr)
11966 {
11967 error (_("%s: failed to read archive header\n"), arch->file_name);
11968 return NULL;
11969 }
11970 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
11971 {
11972 error (_("%s: did not find a valid archive header\n"), arch->file_name);
11973 return NULL;
11974 }
11975
11976 return get_archive_member_name (arch, nested_arch);
11977}
11978
11979/* Construct a string showing the name of the archive member, qualified
11980 with the name of the containing archive file. For thin archives, we
11981 use square brackets to denote the indirection. For nested archives,
11982 we show the qualified name of the external member inside the square
11983 brackets (e.g., "thin.a[normal.a(foo.o)]"). */
11984
11985static char *
11986make_qualified_name (struct archive_info * arch,
11987 struct archive_info * nested_arch,
11988 char * member_name)
11989{
11990 size_t len;
11991 char * name;
11992
11993 len = strlen (arch->file_name) + strlen (member_name) + 3;
11994 if (arch->is_thin_archive && arch->nested_member_origin != 0)
11995 len += strlen (nested_arch->file_name) + 2;
11996
3f5e193b 11997 name = (char *) malloc (len);
2cf0635d
NC
11998 if (name == NULL)
11999 {
12000 error (_("Out of memory\n"));
12001 return NULL;
12002 }
12003
12004 if (arch->is_thin_archive && arch->nested_member_origin != 0)
12005 snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name);
12006 else if (arch->is_thin_archive)
12007 snprintf (name, len, "%s[%s]", arch->file_name, member_name);
12008 else
12009 snprintf (name, len, "%s(%s)", arch->file_name, member_name);
12010
12011 return name;
12012}
12013
12014/* Process an ELF archive.
12015 On entry the file is positioned just after the ARMAG string. */
12016
12017static int
12018process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
12019{
12020 struct archive_info arch;
12021 struct archive_info nested_arch;
12022 size_t got;
12023 size_t file_name_size;
12024 int ret;
12025
12026 show_name = 1;
12027
12028 /* The ARCH structure is used to hold information about this archive. */
12029 arch.file_name = NULL;
12030 arch.file = NULL;
12031 arch.index_array = NULL;
12032 arch.sym_table = NULL;
12033 arch.longnames = NULL;
12034
12035 /* The NESTED_ARCH structure is used as a single-item cache of information
12036 about a nested archive (when members of a thin archive reside within
12037 another regular archive file). */
12038 nested_arch.file_name = NULL;
12039 nested_arch.file = NULL;
12040 nested_arch.index_array = NULL;
12041 nested_arch.sym_table = NULL;
12042 nested_arch.longnames = NULL;
12043
12044 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
12045 {
12046 ret = 1;
12047 goto out;
4145f1d5 12048 }
fb52b2f4 12049
4145f1d5
NC
12050 if (do_archive_index)
12051 {
2cf0635d 12052 if (arch.sym_table == NULL)
4145f1d5
NC
12053 error (_("%s: unable to dump the index as none was found\n"), file_name);
12054 else
12055 {
2cf0635d 12056 unsigned int i, l;
4145f1d5
NC
12057 unsigned long current_pos;
12058
12059 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 12060 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
12061 current_pos = ftell (file);
12062
2cf0635d 12063 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 12064 {
2cf0635d
NC
12065 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
12066 {
12067 char * member_name;
4145f1d5 12068
2cf0635d
NC
12069 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
12070
12071 if (member_name != NULL)
12072 {
12073 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
12074
12075 if (qualified_name != NULL)
12076 {
12077 printf (_("Binary %s contains:\n"), qualified_name);
12078 free (qualified_name);
12079 }
4145f1d5
NC
12080 }
12081 }
2cf0635d
NC
12082
12083 if (l >= arch.sym_size)
4145f1d5
NC
12084 {
12085 error (_("%s: end of the symbol table reached before the end of the index\n"),
12086 file_name);
cb8f3167 12087 break;
4145f1d5 12088 }
2cf0635d
NC
12089 printf ("\t%s\n", arch.sym_table + l);
12090 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
12091 }
12092
2cf0635d
NC
12093 if (l & 01)
12094 ++l;
12095 if (l < arch.sym_size)
4145f1d5
NC
12096 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
12097 file_name);
12098
4145f1d5
NC
12099 if (fseek (file, current_pos, SEEK_SET) != 0)
12100 {
12101 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
12102 ret = 1;
12103 goto out;
4145f1d5 12104 }
fb52b2f4 12105 }
4145f1d5
NC
12106
12107 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
12108 && !do_segments && !do_header && !do_dump && !do_version
12109 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 12110 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
12111 {
12112 ret = 0; /* Archive index only. */
12113 goto out;
12114 }
fb52b2f4
NC
12115 }
12116
12117 file_name_size = strlen (file_name);
d989285c 12118 ret = 0;
fb52b2f4
NC
12119
12120 while (1)
12121 {
2cf0635d
NC
12122 char * name;
12123 size_t namelen;
12124 char * qualified_name;
12125
12126 /* Read the next archive header. */
12127 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
12128 {
12129 error (_("%s: failed to seek to next archive header\n"), file_name);
12130 return 1;
12131 }
12132 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
12133 if (got != sizeof arch.arhdr)
12134 {
12135 if (got == 0)
12136 break;
12137 error (_("%s: failed to read archive header\n"), file_name);
12138 ret = 1;
12139 break;
12140 }
12141 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
12142 {
12143 error (_("%s: did not find a valid archive header\n"), arch.file_name);
12144 ret = 1;
12145 break;
12146 }
12147
12148 arch.next_arhdr_offset += sizeof arch.arhdr;
12149
12150 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
12151 if (archive_file_size & 01)
12152 ++archive_file_size;
12153
12154 name = get_archive_member_name (&arch, &nested_arch);
12155 if (name == NULL)
fb52b2f4 12156 {
0fd3a477 12157 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
12158 ret = 1;
12159 break;
fb52b2f4 12160 }
2cf0635d 12161 namelen = strlen (name);
fb52b2f4 12162
2cf0635d
NC
12163 qualified_name = make_qualified_name (&arch, &nested_arch, name);
12164 if (qualified_name == NULL)
fb52b2f4 12165 {
2cf0635d 12166 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
12167 ret = 1;
12168 break;
fb52b2f4
NC
12169 }
12170
2cf0635d
NC
12171 if (is_thin_archive && arch.nested_member_origin == 0)
12172 {
12173 /* This is a proxy for an external member of a thin archive. */
12174 FILE * member_file;
12175 char * member_file_name = adjust_relative_path (file_name, name, namelen);
12176 if (member_file_name == NULL)
12177 {
12178 ret = 1;
12179 break;
12180 }
12181
12182 member_file = fopen (member_file_name, "rb");
12183 if (member_file == NULL)
12184 {
12185 error (_("Input file '%s' is not readable.\n"), member_file_name);
12186 free (member_file_name);
12187 ret = 1;
12188 break;
12189 }
12190
12191 archive_file_offset = arch.nested_member_origin;
12192
12193 ret |= process_object (qualified_name, member_file);
12194
12195 fclose (member_file);
12196 free (member_file_name);
12197 }
12198 else if (is_thin_archive)
12199 {
12200 /* This is a proxy for a member of a nested archive. */
12201 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
12202
12203 /* The nested archive file will have been opened and setup by
12204 get_archive_member_name. */
12205 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
12206 {
12207 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
12208 ret = 1;
12209 break;
12210 }
12211
12212 ret |= process_object (qualified_name, nested_arch.file);
12213 }
12214 else
12215 {
12216 archive_file_offset = arch.next_arhdr_offset;
12217 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 12218
2cf0635d
NC
12219 ret |= process_object (qualified_name, file);
12220 }
fb52b2f4 12221
2cf0635d 12222 free (qualified_name);
fb52b2f4
NC
12223 }
12224
4145f1d5 12225 out:
2cf0635d
NC
12226 if (nested_arch.file != NULL)
12227 fclose (nested_arch.file);
12228 release_archive (&nested_arch);
12229 release_archive (&arch);
fb52b2f4 12230
d989285c 12231 return ret;
fb52b2f4
NC
12232}
12233
12234static int
2cf0635d 12235process_file (char * file_name)
fb52b2f4 12236{
2cf0635d 12237 FILE * file;
fb52b2f4
NC
12238 struct stat statbuf;
12239 char armag[SARMAG];
12240 int ret;
12241
12242 if (stat (file_name, &statbuf) < 0)
12243 {
f24ddbdd
NC
12244 if (errno == ENOENT)
12245 error (_("'%s': No such file\n"), file_name);
12246 else
12247 error (_("Could not locate '%s'. System error message: %s\n"),
12248 file_name, strerror (errno));
12249 return 1;
12250 }
12251
12252 if (! S_ISREG (statbuf.st_mode))
12253 {
12254 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
12255 return 1;
12256 }
12257
12258 file = fopen (file_name, "rb");
12259 if (file == NULL)
12260 {
f24ddbdd 12261 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
12262 return 1;
12263 }
12264
12265 if (fread (armag, SARMAG, 1, file) != 1)
12266 {
4145f1d5 12267 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
12268 fclose (file);
12269 return 1;
12270 }
12271
12272 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
12273 ret = process_archive (file_name, file, FALSE);
12274 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
12275 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
12276 else
12277 {
4145f1d5
NC
12278 if (do_archive_index)
12279 error (_("File %s is not an archive so its index cannot be displayed.\n"),
12280 file_name);
12281
fb52b2f4
NC
12282 rewind (file);
12283 archive_file_size = archive_file_offset = 0;
12284 ret = process_object (file_name, file);
12285 }
12286
12287 fclose (file);
12288
12289 return ret;
12290}
12291
252b5132
RH
12292#ifdef SUPPORT_DISASSEMBLY
12293/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 12294 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 12295 symbols. */
252b5132
RH
12296
12297void
2cf0635d 12298print_address (unsigned int addr, FILE * outfile)
252b5132
RH
12299{
12300 fprintf (outfile,"0x%8.8x", addr);
12301}
12302
e3c8793a 12303/* Needed by the i386 disassembler. */
252b5132
RH
12304void
12305db_task_printsym (unsigned int addr)
12306{
12307 print_address (addr, stderr);
12308}
12309#endif
12310
12311int
2cf0635d 12312main (int argc, char ** argv)
252b5132 12313{
ff78d6d6
L
12314 int err;
12315
252b5132
RH
12316#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
12317 setlocale (LC_MESSAGES, "");
3882b010
L
12318#endif
12319#if defined (HAVE_SETLOCALE)
12320 setlocale (LC_CTYPE, "");
252b5132
RH
12321#endif
12322 bindtextdomain (PACKAGE, LOCALEDIR);
12323 textdomain (PACKAGE);
12324
869b9d07
MM
12325 expandargv (&argc, &argv);
12326
252b5132
RH
12327 parse_args (argc, argv);
12328
18bd398b 12329 if (num_dump_sects > 0)
59f14fc0 12330 {
18bd398b 12331 /* Make a copy of the dump_sects array. */
3f5e193b
NC
12332 cmdline_dump_sects = (dump_type *)
12333 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 12334 if (cmdline_dump_sects == NULL)
591a748a 12335 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
12336 else
12337 {
09c11c86
NC
12338 memcpy (cmdline_dump_sects, dump_sects,
12339 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
12340 num_cmdline_dump_sects = num_dump_sects;
12341 }
12342 }
12343
18bd398b
NC
12344 if (optind < (argc - 1))
12345 show_name = 1;
12346
ff78d6d6 12347 err = 0;
252b5132 12348 while (optind < argc)
18bd398b 12349 err |= process_file (argv[optind++]);
252b5132
RH
12350
12351 if (dump_sects != NULL)
12352 free (dump_sects);
59f14fc0
AS
12353 if (cmdline_dump_sects != NULL)
12354 free (cmdline_dump_sects);
252b5132 12355
ff78d6d6 12356 return err;
252b5132 12357}