]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Add compressed debug section support to binutils and ld.
[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"
5506d11a 128#include "elf/moxie.h"
4970f871 129#include "elf/mt.h"
2469cfa2 130#include "elf/msp430.h"
3b16e843 131#include "elf/or32.h"
7d466069 132#include "elf/pj.h"
3b16e843 133#include "elf/ppc.h"
c833c019 134#include "elf/ppc64.h"
c7927a3c 135#include "elf/rx.h"
a85d7ed0 136#include "elf/s390.h"
1c0d3aa6 137#include "elf/score.h"
3b16e843
NC
138#include "elf/sh.h"
139#include "elf/sparc.h"
e9f53129 140#include "elf/spu.h"
40b36596 141#include "elf/tic6x.h"
3b16e843 142#include "elf/v850.h"
179d3252 143#include "elf/vax.h"
3b16e843 144#include "elf/x86-64.h"
c29aca4a 145#include "elf/xc16x.h"
93fbbb04 146#include "elf/xstormy16.h"
88da6820 147#include "elf/xtensa.h"
252b5132 148
fb52b2f4
NC
149#include "aout/ar.h"
150
252b5132 151#include "getopt.h"
566b0d53 152#include "libiberty.h"
09c11c86 153#include "safe-ctype.h"
2cf0635d 154#include "filenames.h"
252b5132 155
2cf0635d 156char * program_name = "readelf";
85b1c36d
BE
157static long archive_file_offset;
158static unsigned long archive_file_size;
159static unsigned long dynamic_addr;
160static bfd_size_type dynamic_size;
161static unsigned int dynamic_nent;
2cf0635d 162static char * dynamic_strings;
85b1c36d 163static unsigned long dynamic_strings_length;
2cf0635d 164static char * string_table;
85b1c36d
BE
165static unsigned long string_table_length;
166static unsigned long num_dynamic_syms;
2cf0635d
NC
167static Elf_Internal_Sym * dynamic_symbols;
168static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
169static unsigned long dynamic_syminfo_offset;
170static unsigned int dynamic_syminfo_nent;
f8eae8b2 171static char program_interpreter[PATH_MAX];
bb8a0291 172static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 173static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
174static bfd_vma version_info[16];
175static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
176static Elf_Internal_Shdr * section_headers;
177static Elf_Internal_Phdr * program_headers;
178static Elf_Internal_Dyn * dynamic_section;
179static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
180static int show_name;
181static int do_dynamic;
182static int do_syms;
2c610e4b 183static int do_dyn_syms;
85b1c36d
BE
184static int do_reloc;
185static int do_sections;
186static int do_section_groups;
5477e8a0 187static int do_section_details;
85b1c36d
BE
188static int do_segments;
189static int do_unwind;
190static int do_using_dynamic;
191static int do_header;
192static int do_dump;
193static int do_version;
85b1c36d
BE
194static int do_histogram;
195static int do_debugging;
85b1c36d
BE
196static int do_arch;
197static int do_notes;
4145f1d5 198static int do_archive_index;
85b1c36d 199static int is_32bit_elf;
252b5132 200
e4b17d5c
L
201struct group_list
202{
2cf0635d 203 struct group_list * next;
e4b17d5c
L
204 unsigned int section_index;
205};
206
207struct group
208{
2cf0635d 209 struct group_list * root;
e4b17d5c
L
210 unsigned int group_index;
211};
212
85b1c36d 213static size_t group_count;
2cf0635d
NC
214static struct group * section_groups;
215static struct group ** section_headers_groups;
e4b17d5c 216
09c11c86
NC
217
218/* Flag bits indicating particular types of dump. */
219#define HEX_DUMP (1 << 0) /* The -x command line switch. */
220#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
221#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
222#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 223#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
224
225typedef unsigned char dump_type;
226
227/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
228struct dump_list_entry
229{
2cf0635d 230 char * name;
09c11c86 231 dump_type type;
2cf0635d 232 struct dump_list_entry * next;
aef1f6d0 233};
2cf0635d 234static struct dump_list_entry * dump_sects_byname;
aef1f6d0 235
09c11c86
NC
236/* A dynamic array of flags indicating for which sections a dump
237 has been requested via command line switches. */
238static dump_type * cmdline_dump_sects = NULL;
239static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
240
241/* A dynamic array of flags indicating for which sections a dump of
242 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
243 basis and then initialised from the cmdline_dump_sects array,
244 the results of interpreting the -w switch, and the
245 dump_sects_byname list. */
09c11c86
NC
246static dump_type * dump_sects = NULL;
247static unsigned int num_dump_sects = 0;
252b5132 248
252b5132 249
c256ffe7 250/* How to print a vma value. */
843dd992
NC
251typedef enum print_mode
252{
253 HEX,
254 DEC,
255 DEC_5,
256 UNSIGNED,
257 PREFIX_HEX,
258 FULL_HEX,
259 LONG_HEX
260}
261print_mode;
262
2cf0635d 263static void (* byte_put) (unsigned char *, bfd_vma, int);
252b5132 264
9c19a809
NC
265#define UNKNOWN -1
266
2b692964
NC
267#define SECTION_NAME(X) \
268 ((X) == NULL ? _("<none>") \
269 : string_table == NULL ? _("<no-name>") \
270 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 271 : string_table + (X)->sh_name))
252b5132 272
ee42cf8c 273#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 274
598aaa76
L
275#define BYTE_GET(field) byte_get (field, sizeof (field))
276#define BYTE_GET_SIGNED(field) byte_get_signed (field, sizeof (field))
a952a375 277
9ad5cbcf
AM
278#define GET_ELF_SYMBOLS(file, section) \
279 (is_32bit_elf ? get_32bit_elf_symbols (file, section) \
280 : get_64bit_elf_symbols (file, section))
9ea033b2 281
d79b3d50
NC
282#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
283/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
284 already been called and verified that the string exists. */
285#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b
NC
286
287/* This is just a bit of syntatic sugar. */
60bca95a
NC
288#define streq(a,b) (strcmp ((a), (b)) == 0)
289#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
0112cd26 290#define const_strneq(a,b) (strncmp ((a), (b), sizeof (b) - 1) == 0)
0b6ae522
DJ
291
292#define REMOVE_ARCH_BITS(ADDR) do { \
293 if (elf_header.e_machine == EM_ARM) \
294 (ADDR) &= ~1; \
295 } while (0)
d79b3d50 296\f
c256ffe7 297static void *
2cf0635d
NC
298get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
299 const char * reason)
a6e9f9df 300{
2cf0635d 301 void * mvar;
a6e9f9df 302
c256ffe7 303 if (size == 0 || nmemb == 0)
a6e9f9df
AM
304 return NULL;
305
fb52b2f4 306 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 307 {
0fd3a477 308 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 309 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
310 return NULL;
311 }
312
313 mvar = var;
314 if (mvar == NULL)
315 {
c256ffe7
JJ
316 /* Check for overflow. */
317 if (nmemb < (~(size_t) 0 - 1) / size)
318 /* + 1 so that we can '\0' terminate invalid string table sections. */
319 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
320
321 if (mvar == NULL)
322 {
0fd3a477
JW
323 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
324 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
325 return NULL;
326 }
c256ffe7
JJ
327
328 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
329 }
330
c256ffe7 331 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 332 {
0fd3a477
JW
333 error (_("Unable to read in 0x%lx bytes of %s\n"),
334 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
335 if (mvar != var)
336 free (mvar);
337 return NULL;
338 }
339
340 return mvar;
341}
342
adab8cdc 343static void
2cf0635d 344byte_put_little_endian (unsigned char * field, bfd_vma value, int size)
adab8cdc
AO
345{
346 switch (size)
347 {
348 case 8:
349 field[7] = (((value >> 24) >> 24) >> 8) & 0xff;
350 field[6] = ((value >> 24) >> 24) & 0xff;
351 field[5] = ((value >> 24) >> 16) & 0xff;
352 field[4] = ((value >> 24) >> 8) & 0xff;
353 /* Fall through. */
354 case 4:
355 field[3] = (value >> 24) & 0xff;
4dc3c23d
AM
356 /* Fall through. */
357 case 3:
adab8cdc
AO
358 field[2] = (value >> 16) & 0xff;
359 /* Fall through. */
360 case 2:
361 field[1] = (value >> 8) & 0xff;
362 /* Fall through. */
363 case 1:
364 field[0] = value & 0xff;
365 break;
366
367 default:
368 error (_("Unhandled data length: %d\n"), size);
369 abort ();
370 }
371}
372
14a91970 373/* Print a VMA value. */
cb8f3167 374
66543521 375static int
14a91970 376print_vma (bfd_vma vma, print_mode mode)
66543521 377{
66543521
AM
378 int nc = 0;
379
14a91970 380 switch (mode)
66543521 381 {
14a91970
AM
382 case FULL_HEX:
383 nc = printf ("0x");
384 /* Drop through. */
66543521 385
14a91970 386 case LONG_HEX:
f7a99963 387#ifdef BFD64
14a91970 388 if (is_32bit_elf)
437c2fb7 389 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 390#endif
14a91970
AM
391 printf_vma (vma);
392 return nc + 16;
b19aac67 393
14a91970
AM
394 case DEC_5:
395 if (vma <= 99999)
396 return printf ("%5" BFD_VMA_FMT "d", vma);
397 /* Drop through. */
66543521 398
14a91970
AM
399 case PREFIX_HEX:
400 nc = printf ("0x");
401 /* Drop through. */
66543521 402
14a91970
AM
403 case HEX:
404 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 405
14a91970
AM
406 case DEC:
407 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 408
14a91970
AM
409 case UNSIGNED:
410 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 411 }
66543521 412 return 0;
f7a99963
NC
413}
414
171191ba 415/* Display a symbol on stdout. Handles the display of non-printing characters.
31104126 416
171191ba
NC
417 If DO_WIDE is not true then format the symbol to be at most WIDTH characters,
418 truncating as necessary. If WIDTH is negative then format the string to be
419 exactly - WIDTH characters, truncating or padding as necessary.
420
421 Returns the number of emitted characters. */
422
423static unsigned int
2cf0635d 424print_symbol (int width, const char * symbol)
31104126 425{
961c521f 426 const char * c;
171191ba
NC
427 bfd_boolean extra_padding = FALSE;
428 unsigned int num_printed = 0;
961c521f 429
31104126 430 if (do_wide)
961c521f 431 {
961c521f
NC
432 /* Set the width to a very large value. This simplifies the code below. */
433 width = INT_MAX;
434 }
31104126 435 else if (width < 0)
961c521f 436 {
961c521f
NC
437 /* Keep the width positive. This also helps. */
438 width = - width;
171191ba 439 extra_padding = TRUE;
961c521f
NC
440 }
441
442 while (width)
443 {
444 int len;
445
446 c = symbol;
447
448 /* Look for non-printing symbols inside the symbol's name.
449 This test is triggered in particular by the names generated
450 by the assembler for local labels. */
451 while (ISPRINT (* c))
452 c++;
453
454 len = c - symbol;
455
456 if (len)
457 {
458 if (len > width)
459 len = width;
cb8f3167 460
171191ba 461 printf ("%.*s", len, symbol);
961c521f
NC
462
463 width -= len;
171191ba 464 num_printed += len;
961c521f
NC
465 }
466
467 if (* c == 0 || width == 0)
468 break;
469
470 /* Now display the non-printing character, if
471 there is room left in which to dipslay it. */
472 if (*c < 32)
473 {
474 if (width < 2)
475 break;
476
477 printf ("^%c", *c + 0x40);
478
479 width -= 2;
171191ba 480 num_printed += 2;
961c521f
NC
481 }
482 else
483 {
484 if (width < 6)
485 break;
cb8f3167 486
961c521f
NC
487 printf ("<0x%.2x>", *c);
488
489 width -= 6;
171191ba 490 num_printed += 6;
961c521f
NC
491 }
492
493 symbol = c + 1;
494 }
171191ba
NC
495
496 if (extra_padding && width > 0)
497 {
498 /* Fill in the remaining spaces. */
499 printf ("%-*s", width, " ");
500 num_printed += 2;
501 }
502
503 return num_printed;
31104126
NC
504}
505
adab8cdc 506static void
2cf0635d 507byte_put_big_endian (unsigned char * field, bfd_vma value, int size)
adab8cdc
AO
508{
509 switch (size)
510 {
511 case 8:
512 field[7] = value & 0xff;
513 field[6] = (value >> 8) & 0xff;
514 field[5] = (value >> 16) & 0xff;
515 field[4] = (value >> 24) & 0xff;
516 value >>= 16;
517 value >>= 16;
518 /* Fall through. */
519 case 4:
520 field[3] = value & 0xff;
4dc3c23d
AM
521 value >>= 8;
522 /* Fall through. */
523 case 3:
524 field[2] = value & 0xff;
525 value >>= 8;
adab8cdc
AO
526 /* Fall through. */
527 case 2:
528 field[1] = value & 0xff;
529 value >>= 8;
530 /* Fall through. */
531 case 1:
532 field[0] = value & 0xff;
533 break;
534
535 default:
536 error (_("Unhandled data length: %d\n"), size);
537 abort ();
538 }
539}
540
89fac5e3
RS
541/* Return a pointer to section NAME, or NULL if no such section exists. */
542
543static Elf_Internal_Shdr *
2cf0635d 544find_section (const char * name)
89fac5e3
RS
545{
546 unsigned int i;
547
548 for (i = 0; i < elf_header.e_shnum; i++)
549 if (streq (SECTION_NAME (section_headers + i), name))
550 return section_headers + i;
551
552 return NULL;
553}
554
0b6ae522
DJ
555/* Return a pointer to a section containing ADDR, or NULL if no such
556 section exists. */
557
558static Elf_Internal_Shdr *
559find_section_by_address (bfd_vma addr)
560{
561 unsigned int i;
562
563 for (i = 0; i < elf_header.e_shnum; i++)
564 {
565 Elf_Internal_Shdr *sec = section_headers + i;
566 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
567 return sec;
568 }
569
570 return NULL;
571}
572
573/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
574 bytes read. */
575
576static unsigned long
577read_uleb128 (unsigned char *data, unsigned int *length_return)
578{
579 return read_leb128 (data, length_return, 0);
580}
581
28f997cf
TG
582/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
583 This OS has so many departures from the ELF standard that we test it at
584 many places. */
585
586static inline int
587is_ia64_vms (void)
588{
589 return elf_header.e_machine == EM_IA_64
590 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
591}
592
bcedfee6 593/* Guess the relocation size commonly used by the specific machines. */
252b5132 594
252b5132 595static int
2dc4cec1 596guess_is_rela (unsigned int e_machine)
252b5132 597{
9c19a809 598 switch (e_machine)
252b5132
RH
599 {
600 /* Targets that use REL relocations. */
252b5132
RH
601 case EM_386:
602 case EM_486:
63fcb9e9 603 case EM_960:
e9f53129 604 case EM_ARM:
2b0337b0 605 case EM_D10V:
252b5132 606 case EM_CYGNUS_D10V:
e9f53129 607 case EM_DLX:
252b5132 608 case EM_MIPS:
4fe85591 609 case EM_MIPS_RS3_LE:
e9f53129
AM
610 case EM_CYGNUS_M32R:
611 case EM_OPENRISC:
612 case EM_OR32:
1c0d3aa6 613 case EM_SCORE:
9c19a809 614 return FALSE;
103f02d3 615
252b5132
RH
616 /* Targets that use RELA relocations. */
617 case EM_68K:
e9f53129
AM
618 case EM_860:
619 case EM_ALPHA:
620 case EM_ALTERA_NIOS2:
621 case EM_AVR:
622 case EM_AVR_OLD:
623 case EM_BLACKFIN:
60bca95a 624 case EM_CR16:
6c03b1ed 625 case EM_CR16_OLD:
e9f53129
AM
626 case EM_CRIS:
627 case EM_CRX:
2b0337b0 628 case EM_D30V:
252b5132 629 case EM_CYGNUS_D30V:
2b0337b0 630 case EM_FR30:
252b5132 631 case EM_CYGNUS_FR30:
5c70f934 632 case EM_CYGNUS_FRV:
e9f53129
AM
633 case EM_H8S:
634 case EM_H8_300:
635 case EM_H8_300H:
800eeca4 636 case EM_IA_64:
1e4cf259
NC
637 case EM_IP2K:
638 case EM_IP2K_OLD:
3b36097d 639 case EM_IQ2000:
84e94c90 640 case EM_LATTICEMICO32:
ff7eeb89 641 case EM_M32C_OLD:
49f58d10 642 case EM_M32C:
e9f53129
AM
643 case EM_M32R:
644 case EM_MCORE:
15ab5209 645 case EM_CYGNUS_MEP:
e9f53129
AM
646 case EM_MMIX:
647 case EM_MN10200:
648 case EM_CYGNUS_MN10200:
649 case EM_MN10300:
650 case EM_CYGNUS_MN10300:
5506d11a 651 case EM_MOXIE:
e9f53129
AM
652 case EM_MSP430:
653 case EM_MSP430_OLD:
d031aafb 654 case EM_MT:
64fd6348 655 case EM_NIOS32:
e9f53129
AM
656 case EM_PPC64:
657 case EM_PPC:
c7927a3c 658 case EM_RX:
e9f53129
AM
659 case EM_S390:
660 case EM_S390_OLD:
661 case EM_SH:
662 case EM_SPARC:
663 case EM_SPARC32PLUS:
664 case EM_SPARCV9:
665 case EM_SPU:
40b36596 666 case EM_TI_C6000:
e9f53129
AM
667 case EM_V850:
668 case EM_CYGNUS_V850:
669 case EM_VAX:
670 case EM_X86_64:
8a9036a4 671 case EM_L1OM:
e9f53129
AM
672 case EM_XSTORMY16:
673 case EM_XTENSA:
674 case EM_XTENSA_OLD:
7ba29e2a
NC
675 case EM_MICROBLAZE:
676 case EM_MICROBLAZE_OLD:
9c19a809 677 return TRUE;
103f02d3 678
e9f53129
AM
679 case EM_68HC05:
680 case EM_68HC08:
681 case EM_68HC11:
682 case EM_68HC16:
683 case EM_FX66:
684 case EM_ME16:
d1133906 685 case EM_MMA:
d1133906
NC
686 case EM_NCPU:
687 case EM_NDR1:
e9f53129 688 case EM_PCP:
d1133906 689 case EM_ST100:
e9f53129 690 case EM_ST19:
d1133906 691 case EM_ST7:
e9f53129
AM
692 case EM_ST9PLUS:
693 case EM_STARCORE:
d1133906 694 case EM_SVX:
e9f53129 695 case EM_TINYJ:
9c19a809
NC
696 default:
697 warn (_("Don't know about relocations on this machine architecture\n"));
698 return FALSE;
699 }
700}
252b5132 701
9c19a809 702static int
2cf0635d 703slurp_rela_relocs (FILE * file,
d3ba0551
AM
704 unsigned long rel_offset,
705 unsigned long rel_size,
2cf0635d
NC
706 Elf_Internal_Rela ** relasp,
707 unsigned long * nrelasp)
9c19a809 708{
2cf0635d 709 Elf_Internal_Rela * relas;
4d6ed7c8
NC
710 unsigned long nrelas;
711 unsigned int i;
252b5132 712
4d6ed7c8
NC
713 if (is_32bit_elf)
714 {
2cf0635d 715 Elf32_External_Rela * erelas;
103f02d3 716
3f5e193b
NC
717 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
718 rel_size, _("relocs"));
a6e9f9df
AM
719 if (!erelas)
720 return 0;
252b5132 721
4d6ed7c8 722 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 723
3f5e193b
NC
724 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
725 sizeof (Elf_Internal_Rela));
103f02d3 726
4d6ed7c8
NC
727 if (relas == NULL)
728 {
c256ffe7 729 free (erelas);
591a748a 730 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
731 return 0;
732 }
103f02d3 733
4d6ed7c8
NC
734 for (i = 0; i < nrelas; i++)
735 {
736 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
737 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 738 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 739 }
103f02d3 740
4d6ed7c8
NC
741 free (erelas);
742 }
743 else
744 {
2cf0635d 745 Elf64_External_Rela * erelas;
103f02d3 746
3f5e193b
NC
747 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
748 rel_size, _("relocs"));
a6e9f9df
AM
749 if (!erelas)
750 return 0;
4d6ed7c8
NC
751
752 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 753
3f5e193b
NC
754 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
755 sizeof (Elf_Internal_Rela));
103f02d3 756
4d6ed7c8
NC
757 if (relas == NULL)
758 {
c256ffe7 759 free (erelas);
591a748a 760 error (_("out of memory parsing relocs\n"));
4d6ed7c8 761 return 0;
9c19a809 762 }
4d6ed7c8
NC
763
764 for (i = 0; i < nrelas; i++)
9c19a809 765 {
66543521
AM
766 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
767 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 768 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
769
770 /* The #ifdef BFD64 below is to prevent a compile time
771 warning. We know that if we do not have a 64 bit data
772 type that we will never execute this code anyway. */
773#ifdef BFD64
774 if (elf_header.e_machine == EM_MIPS
775 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
776 {
777 /* In little-endian objects, r_info isn't really a
778 64-bit little-endian value: it has a 32-bit
779 little-endian symbol index followed by four
780 individual byte fields. Reorder INFO
781 accordingly. */
91d6fa6a
NC
782 bfd_vma inf = relas[i].r_info;
783 inf = (((inf & 0xffffffff) << 32)
784 | ((inf >> 56) & 0xff)
785 | ((inf >> 40) & 0xff00)
786 | ((inf >> 24) & 0xff0000)
787 | ((inf >> 8) & 0xff000000));
788 relas[i].r_info = inf;
861fb55a
DJ
789 }
790#endif /* BFD64 */
4d6ed7c8 791 }
103f02d3 792
4d6ed7c8
NC
793 free (erelas);
794 }
795 *relasp = relas;
796 *nrelasp = nrelas;
797 return 1;
798}
103f02d3 799
4d6ed7c8 800static int
2cf0635d 801slurp_rel_relocs (FILE * file,
d3ba0551
AM
802 unsigned long rel_offset,
803 unsigned long rel_size,
2cf0635d
NC
804 Elf_Internal_Rela ** relsp,
805 unsigned long * nrelsp)
4d6ed7c8 806{
2cf0635d 807 Elf_Internal_Rela * rels;
4d6ed7c8
NC
808 unsigned long nrels;
809 unsigned int i;
103f02d3 810
4d6ed7c8
NC
811 if (is_32bit_elf)
812 {
2cf0635d 813 Elf32_External_Rel * erels;
103f02d3 814
3f5e193b
NC
815 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
816 rel_size, _("relocs"));
a6e9f9df
AM
817 if (!erels)
818 return 0;
103f02d3 819
4d6ed7c8 820 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 821
3f5e193b 822 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 823
4d6ed7c8
NC
824 if (rels == NULL)
825 {
c256ffe7 826 free (erels);
591a748a 827 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
828 return 0;
829 }
830
831 for (i = 0; i < nrels; i++)
832 {
833 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
834 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 835 rels[i].r_addend = 0;
9ea033b2 836 }
4d6ed7c8
NC
837
838 free (erels);
9c19a809
NC
839 }
840 else
841 {
2cf0635d 842 Elf64_External_Rel * erels;
9ea033b2 843
3f5e193b
NC
844 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
845 rel_size, _("relocs"));
a6e9f9df
AM
846 if (!erels)
847 return 0;
103f02d3 848
4d6ed7c8 849 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 850
3f5e193b 851 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 852
4d6ed7c8 853 if (rels == NULL)
9c19a809 854 {
c256ffe7 855 free (erels);
591a748a 856 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
857 return 0;
858 }
103f02d3 859
4d6ed7c8
NC
860 for (i = 0; i < nrels; i++)
861 {
66543521
AM
862 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
863 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 864 rels[i].r_addend = 0;
861fb55a
DJ
865
866 /* The #ifdef BFD64 below is to prevent a compile time
867 warning. We know that if we do not have a 64 bit data
868 type that we will never execute this code anyway. */
869#ifdef BFD64
870 if (elf_header.e_machine == EM_MIPS
871 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
872 {
873 /* In little-endian objects, r_info isn't really a
874 64-bit little-endian value: it has a 32-bit
875 little-endian symbol index followed by four
876 individual byte fields. Reorder INFO
877 accordingly. */
91d6fa6a
NC
878 bfd_vma inf = rels[i].r_info;
879 inf = (((inf & 0xffffffff) << 32)
880 | ((inf >> 56) & 0xff)
881 | ((inf >> 40) & 0xff00)
882 | ((inf >> 24) & 0xff0000)
883 | ((inf >> 8) & 0xff000000));
884 rels[i].r_info = inf;
861fb55a
DJ
885 }
886#endif /* BFD64 */
4d6ed7c8 887 }
103f02d3 888
4d6ed7c8
NC
889 free (erels);
890 }
891 *relsp = rels;
892 *nrelsp = nrels;
893 return 1;
894}
103f02d3 895
aca88567
NC
896/* Returns the reloc type extracted from the reloc info field. */
897
898static unsigned int
899get_reloc_type (bfd_vma reloc_info)
900{
901 if (is_32bit_elf)
902 return ELF32_R_TYPE (reloc_info);
903
904 switch (elf_header.e_machine)
905 {
906 case EM_MIPS:
907 /* Note: We assume that reloc_info has already been adjusted for us. */
908 return ELF64_MIPS_R_TYPE (reloc_info);
909
910 case EM_SPARCV9:
911 return ELF64_R_TYPE_ID (reloc_info);
912
913 default:
914 return ELF64_R_TYPE (reloc_info);
915 }
916}
917
918/* Return the symbol index extracted from the reloc info field. */
919
920static bfd_vma
921get_reloc_symindex (bfd_vma reloc_info)
922{
923 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
924}
925
d3ba0551
AM
926/* Display the contents of the relocation data found at the specified
927 offset. */
ee42cf8c 928
41e92641 929static void
2cf0635d 930dump_relocations (FILE * file,
d3ba0551
AM
931 unsigned long rel_offset,
932 unsigned long rel_size,
2cf0635d 933 Elf_Internal_Sym * symtab,
d3ba0551 934 unsigned long nsyms,
2cf0635d 935 char * strtab,
d79b3d50 936 unsigned long strtablen,
d3ba0551 937 int is_rela)
4d6ed7c8 938{
b34976b6 939 unsigned int i;
2cf0635d 940 Elf_Internal_Rela * rels;
103f02d3 941
4d6ed7c8
NC
942 if (is_rela == UNKNOWN)
943 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 944
4d6ed7c8
NC
945 if (is_rela)
946 {
c8286bd1 947 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 948 return;
4d6ed7c8
NC
949 }
950 else
951 {
952 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 953 return;
252b5132
RH
954 }
955
410f7a12
L
956 if (is_32bit_elf)
957 {
958 if (is_rela)
2c71103e
NC
959 {
960 if (do_wide)
961 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
962 else
963 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
964 }
410f7a12 965 else
2c71103e
NC
966 {
967 if (do_wide)
968 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
969 else
970 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
971 }
410f7a12 972 }
252b5132 973 else
410f7a12
L
974 {
975 if (is_rela)
2c71103e
NC
976 {
977 if (do_wide)
8beeaeb7 978 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
979 else
980 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
981 }
410f7a12 982 else
2c71103e
NC
983 {
984 if (do_wide)
8beeaeb7 985 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
986 else
987 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
988 }
410f7a12 989 }
252b5132
RH
990
991 for (i = 0; i < rel_size; i++)
992 {
2cf0635d 993 const char * rtype;
b34976b6 994 bfd_vma offset;
91d6fa6a 995 bfd_vma inf;
b34976b6
AM
996 bfd_vma symtab_index;
997 bfd_vma type;
103f02d3 998
b34976b6 999 offset = rels[i].r_offset;
91d6fa6a 1000 inf = rels[i].r_info;
103f02d3 1001
91d6fa6a
NC
1002 type = get_reloc_type (inf);
1003 symtab_index = get_reloc_symindex (inf);
252b5132 1004
410f7a12
L
1005 if (is_32bit_elf)
1006 {
39dbeff8
AM
1007 printf ("%8.8lx %8.8lx ",
1008 (unsigned long) offset & 0xffffffff,
91d6fa6a 1009 (unsigned long) inf & 0xffffffff);
410f7a12
L
1010 }
1011 else
1012 {
39dbeff8
AM
1013#if BFD_HOST_64BIT_LONG
1014 printf (do_wide
1015 ? "%16.16lx %16.16lx "
1016 : "%12.12lx %12.12lx ",
91d6fa6a 1017 offset, inf);
39dbeff8 1018#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1019#ifndef __MSVCRT__
39dbeff8
AM
1020 printf (do_wide
1021 ? "%16.16llx %16.16llx "
1022 : "%12.12llx %12.12llx ",
91d6fa6a 1023 offset, inf);
6e3d6dc1
NC
1024#else
1025 printf (do_wide
1026 ? "%16.16I64x %16.16I64x "
1027 : "%12.12I64x %12.12I64x ",
91d6fa6a 1028 offset, inf);
6e3d6dc1 1029#endif
39dbeff8 1030#else
2c71103e
NC
1031 printf (do_wide
1032 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1033 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1034 _bfd_int64_high (offset),
1035 _bfd_int64_low (offset),
91d6fa6a
NC
1036 _bfd_int64_high (inf),
1037 _bfd_int64_low (inf));
9ea033b2 1038#endif
410f7a12 1039 }
103f02d3 1040
252b5132
RH
1041 switch (elf_header.e_machine)
1042 {
1043 default:
1044 rtype = NULL;
1045 break;
1046
2b0337b0 1047 case EM_M32R:
252b5132 1048 case EM_CYGNUS_M32R:
9ea033b2 1049 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1050 break;
1051
1052 case EM_386:
1053 case EM_486:
9ea033b2 1054 rtype = elf_i386_reloc_type (type);
252b5132
RH
1055 break;
1056
ba2685cc
AM
1057 case EM_68HC11:
1058 case EM_68HC12:
1059 rtype = elf_m68hc11_reloc_type (type);
1060 break;
75751cd9 1061
252b5132 1062 case EM_68K:
9ea033b2 1063 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1064 break;
1065
63fcb9e9 1066 case EM_960:
9ea033b2 1067 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1068 break;
1069
adde6300 1070 case EM_AVR:
2b0337b0 1071 case EM_AVR_OLD:
adde6300
AM
1072 rtype = elf_avr_reloc_type (type);
1073 break;
1074
9ea033b2
NC
1075 case EM_OLD_SPARCV9:
1076 case EM_SPARC32PLUS:
1077 case EM_SPARCV9:
252b5132 1078 case EM_SPARC:
9ea033b2 1079 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1080 break;
1081
e9f53129
AM
1082 case EM_SPU:
1083 rtype = elf_spu_reloc_type (type);
1084 break;
1085
2b0337b0 1086 case EM_V850:
252b5132 1087 case EM_CYGNUS_V850:
9ea033b2 1088 rtype = v850_reloc_type (type);
252b5132
RH
1089 break;
1090
2b0337b0 1091 case EM_D10V:
252b5132 1092 case EM_CYGNUS_D10V:
9ea033b2 1093 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1094 break;
1095
2b0337b0 1096 case EM_D30V:
252b5132 1097 case EM_CYGNUS_D30V:
9ea033b2 1098 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1099 break;
1100
d172d4ba
NC
1101 case EM_DLX:
1102 rtype = elf_dlx_reloc_type (type);
1103 break;
1104
252b5132 1105 case EM_SH:
9ea033b2 1106 rtype = elf_sh_reloc_type (type);
252b5132
RH
1107 break;
1108
2b0337b0 1109 case EM_MN10300:
252b5132 1110 case EM_CYGNUS_MN10300:
9ea033b2 1111 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1112 break;
1113
2b0337b0 1114 case EM_MN10200:
252b5132 1115 case EM_CYGNUS_MN10200:
9ea033b2 1116 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1117 break;
1118
2b0337b0 1119 case EM_FR30:
252b5132 1120 case EM_CYGNUS_FR30:
9ea033b2 1121 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1122 break;
1123
ba2685cc
AM
1124 case EM_CYGNUS_FRV:
1125 rtype = elf_frv_reloc_type (type);
1126 break;
5c70f934 1127
252b5132 1128 case EM_MCORE:
9ea033b2 1129 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1130 break;
1131
3c3bdf30
NC
1132 case EM_MMIX:
1133 rtype = elf_mmix_reloc_type (type);
1134 break;
1135
5506d11a
AM
1136 case EM_MOXIE:
1137 rtype = elf_moxie_reloc_type (type);
1138 break;
1139
2469cfa2
NC
1140 case EM_MSP430:
1141 case EM_MSP430_OLD:
1142 rtype = elf_msp430_reloc_type (type);
1143 break;
1144
252b5132 1145 case EM_PPC:
9ea033b2 1146 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1147 break;
1148
c833c019
AM
1149 case EM_PPC64:
1150 rtype = elf_ppc64_reloc_type (type);
1151 break;
1152
252b5132 1153 case EM_MIPS:
4fe85591 1154 case EM_MIPS_RS3_LE:
9ea033b2 1155 rtype = elf_mips_reloc_type (type);
252b5132
RH
1156 break;
1157
1158 case EM_ALPHA:
9ea033b2 1159 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1160 break;
1161
1162 case EM_ARM:
9ea033b2 1163 rtype = elf_arm_reloc_type (type);
252b5132
RH
1164 break;
1165
584da044 1166 case EM_ARC:
9ea033b2 1167 rtype = elf_arc_reloc_type (type);
252b5132
RH
1168 break;
1169
1170 case EM_PARISC:
69e617ca 1171 rtype = elf_hppa_reloc_type (type);
252b5132 1172 break;
7d466069 1173
b8720f9d
JL
1174 case EM_H8_300:
1175 case EM_H8_300H:
1176 case EM_H8S:
1177 rtype = elf_h8_reloc_type (type);
1178 break;
1179
3b16e843
NC
1180 case EM_OPENRISC:
1181 case EM_OR32:
1182 rtype = elf_or32_reloc_type (type);
1183 break;
1184
7d466069 1185 case EM_PJ:
2b0337b0 1186 case EM_PJ_OLD:
7d466069
ILT
1187 rtype = elf_pj_reloc_type (type);
1188 break;
800eeca4
JW
1189 case EM_IA_64:
1190 rtype = elf_ia64_reloc_type (type);
1191 break;
1b61cf92
HPN
1192
1193 case EM_CRIS:
1194 rtype = elf_cris_reloc_type (type);
1195 break;
535c37ff
JE
1196
1197 case EM_860:
1198 rtype = elf_i860_reloc_type (type);
1199 break;
bcedfee6
NC
1200
1201 case EM_X86_64:
8a9036a4 1202 case EM_L1OM:
bcedfee6
NC
1203 rtype = elf_x86_64_reloc_type (type);
1204 break;
a85d7ed0 1205
35b1837e
AM
1206 case EM_S370:
1207 rtype = i370_reloc_type (type);
1208 break;
1209
53c7db4b
KH
1210 case EM_S390_OLD:
1211 case EM_S390:
1212 rtype = elf_s390_reloc_type (type);
1213 break;
93fbbb04 1214
1c0d3aa6
NC
1215 case EM_SCORE:
1216 rtype = elf_score_reloc_type (type);
1217 break;
1218
93fbbb04
GK
1219 case EM_XSTORMY16:
1220 rtype = elf_xstormy16_reloc_type (type);
1221 break;
179d3252 1222
1fe1f39c
NC
1223 case EM_CRX:
1224 rtype = elf_crx_reloc_type (type);
1225 break;
1226
179d3252
JT
1227 case EM_VAX:
1228 rtype = elf_vax_reloc_type (type);
1229 break;
1e4cf259
NC
1230
1231 case EM_IP2K:
1232 case EM_IP2K_OLD:
1233 rtype = elf_ip2k_reloc_type (type);
1234 break;
3b36097d
SC
1235
1236 case EM_IQ2000:
1237 rtype = elf_iq2000_reloc_type (type);
1238 break;
88da6820
NC
1239
1240 case EM_XTENSA_OLD:
1241 case EM_XTENSA:
1242 rtype = elf_xtensa_reloc_type (type);
1243 break;
a34e3ecb 1244
84e94c90
NC
1245 case EM_LATTICEMICO32:
1246 rtype = elf_lm32_reloc_type (type);
1247 break;
1248
ff7eeb89 1249 case EM_M32C_OLD:
49f58d10
JB
1250 case EM_M32C:
1251 rtype = elf_m32c_reloc_type (type);
1252 break;
1253
d031aafb
NS
1254 case EM_MT:
1255 rtype = elf_mt_reloc_type (type);
a34e3ecb 1256 break;
1d65ded4
CM
1257
1258 case EM_BLACKFIN:
1259 rtype = elf_bfin_reloc_type (type);
1260 break;
15ab5209
DB
1261
1262 case EM_CYGNUS_MEP:
1263 rtype = elf_mep_reloc_type (type);
1264 break;
60bca95a
NC
1265
1266 case EM_CR16:
6c03b1ed 1267 case EM_CR16_OLD:
60bca95a
NC
1268 rtype = elf_cr16_reloc_type (type);
1269 break;
dd24e3da 1270
7ba29e2a
NC
1271 case EM_MICROBLAZE:
1272 case EM_MICROBLAZE_OLD:
1273 rtype = elf_microblaze_reloc_type (type);
1274 break;
c7927a3c
NC
1275
1276 case EM_RX:
1277 rtype = elf_rx_reloc_type (type);
1278 break;
c29aca4a
NC
1279
1280 case EM_XC16X:
1281 case EM_C166:
1282 rtype = elf_xc16x_reloc_type (type);
1283 break;
40b36596
JM
1284
1285 case EM_TI_C6000:
1286 rtype = elf_tic6x_reloc_type (type);
1287 break;
252b5132
RH
1288 }
1289
1290 if (rtype == NULL)
39dbeff8 1291 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1292 else
8beeaeb7 1293 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1294
7ace3541 1295 if (elf_header.e_machine == EM_ALPHA
157c2599 1296 && rtype != NULL
7ace3541
RH
1297 && streq (rtype, "R_ALPHA_LITUSE")
1298 && is_rela)
1299 {
1300 switch (rels[i].r_addend)
1301 {
1302 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1303 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1304 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1305 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1306 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1307 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1308 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1309 default: rtype = NULL;
1310 }
1311 if (rtype)
1312 printf (" (%s)", rtype);
1313 else
1314 {
1315 putchar (' ');
1316 printf (_("<unknown addend: %lx>"),
1317 (unsigned long) rels[i].r_addend);
1318 }
1319 }
1320 else if (symtab_index)
252b5132 1321 {
af3fc3bc 1322 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1323 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1324 else
19936277 1325 {
2cf0635d 1326 Elf_Internal_Sym * psym;
19936277 1327
af3fc3bc 1328 psym = symtab + symtab_index;
103f02d3 1329
af3fc3bc 1330 printf (" ");
171191ba 1331
d8045f23
NC
1332 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1333 {
1334 const char * name;
1335 unsigned int len;
1336 unsigned int width = is_32bit_elf ? 8 : 14;
1337
1338 /* Relocations against GNU_IFUNC symbols do not use the value
1339 of the symbol as the address to relocate against. Instead
1340 they invoke the function named by the symbol and use its
1341 result as the address for relocation.
1342
1343 To indicate this to the user, do not display the value of
1344 the symbol in the "Symbols's Value" field. Instead show
1345 its name followed by () as a hint that the symbol is
1346 invoked. */
1347
1348 if (strtab == NULL
1349 || psym->st_name == 0
1350 || psym->st_name >= strtablen)
1351 name = "??";
1352 else
1353 name = strtab + psym->st_name;
1354
1355 len = print_symbol (width, name);
1356 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1357 }
1358 else
1359 {
1360 print_vma (psym->st_value, LONG_HEX);
171191ba 1361
d8045f23
NC
1362 printf (is_32bit_elf ? " " : " ");
1363 }
103f02d3 1364
af3fc3bc 1365 if (psym->st_name == 0)
f1ef08cb 1366 {
2cf0635d 1367 const char * sec_name = "<null>";
f1ef08cb
AM
1368 char name_buf[40];
1369
1370 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1371 {
4fbb74a6
AM
1372 if (psym->st_shndx < elf_header.e_shnum)
1373 sec_name
1374 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1375 else if (psym->st_shndx == SHN_ABS)
1376 sec_name = "ABS";
1377 else if (psym->st_shndx == SHN_COMMON)
1378 sec_name = "COMMON";
172553c7
TS
1379 else if (elf_header.e_machine == EM_MIPS
1380 && psym->st_shndx == SHN_MIPS_SCOMMON)
1381 sec_name = "SCOMMON";
1382 else if (elf_header.e_machine == EM_MIPS
1383 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1384 sec_name = "SUNDEF";
8a9036a4
L
1385 else if ((elf_header.e_machine == EM_X86_64
1386 || elf_header.e_machine == EM_L1OM)
3b22753a
L
1387 && psym->st_shndx == SHN_X86_64_LCOMMON)
1388 sec_name = "LARGE_COMMON";
9ce701e2
L
1389 else if (elf_header.e_machine == EM_IA_64
1390 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1391 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1392 sec_name = "ANSI_COM";
28f997cf 1393 else if (is_ia64_vms ()
148b93f2
NC
1394 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1395 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1396 else
1397 {
1398 sprintf (name_buf, "<section 0x%x>",
1399 (unsigned int) psym->st_shndx);
1400 sec_name = name_buf;
1401 }
1402 }
1403 print_symbol (22, sec_name);
1404 }
af3fc3bc 1405 else if (strtab == NULL)
d79b3d50 1406 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1407 else if (psym->st_name >= strtablen)
d79b3d50 1408 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1409 else
2c71103e 1410 print_symbol (22, strtab + psym->st_name);
103f02d3 1411
af3fc3bc 1412 if (is_rela)
171191ba 1413 {
598aaa76 1414 bfd_signed_vma off = rels[i].r_addend;
171191ba 1415
91d6fa6a 1416 if (off < 0)
598aaa76 1417 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1418 else
598aaa76 1419 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1420 }
19936277 1421 }
252b5132 1422 }
1b228002 1423 else if (is_rela)
f7a99963 1424 {
18bd398b
NC
1425 printf ("%*c", is_32bit_elf ?
1426 (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
c8286bd1 1427 print_vma (rels[i].r_addend, LONG_HEX);
f7a99963 1428 }
252b5132 1429
157c2599
NC
1430 if (elf_header.e_machine == EM_SPARCV9
1431 && rtype != NULL
1432 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1433 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1434
252b5132 1435 putchar ('\n');
2c71103e 1436
aca88567 1437#ifdef BFD64
53c7db4b 1438 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1439 {
91d6fa6a
NC
1440 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1441 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1442 const char * rtype2 = elf_mips_reloc_type (type2);
1443 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1444
2c71103e
NC
1445 printf (" Type2: ");
1446
1447 if (rtype2 == NULL)
39dbeff8
AM
1448 printf (_("unrecognized: %-7lx"),
1449 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1450 else
1451 printf ("%-17.17s", rtype2);
1452
18bd398b 1453 printf ("\n Type3: ");
2c71103e
NC
1454
1455 if (rtype3 == NULL)
39dbeff8
AM
1456 printf (_("unrecognized: %-7lx"),
1457 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1458 else
1459 printf ("%-17.17s", rtype3);
1460
53c7db4b 1461 putchar ('\n');
2c71103e 1462 }
aca88567 1463#endif /* BFD64 */
252b5132
RH
1464 }
1465
c8286bd1 1466 free (rels);
252b5132
RH
1467}
1468
1469static const char *
d3ba0551 1470get_mips_dynamic_type (unsigned long type)
252b5132
RH
1471{
1472 switch (type)
1473 {
1474 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1475 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1476 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1477 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1478 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1479 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1480 case DT_MIPS_MSYM: return "MIPS_MSYM";
1481 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1482 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1483 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1484 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1485 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1486 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1487 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1488 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1489 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1490 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1491 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1492 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1493 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1494 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1495 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1496 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1497 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1498 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1499 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1500 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1501 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1502 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1503 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1504 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1505 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1506 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1507 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1508 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1509 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1510 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1511 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1512 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1513 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1514 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1515 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1516 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1517 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1518 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1519 default:
1520 return NULL;
1521 }
1522}
1523
9a097730 1524static const char *
d3ba0551 1525get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1526{
1527 switch (type)
1528 {
1529 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1530 default:
1531 return NULL;
1532 }
103f02d3
UD
1533}
1534
7490d522
AM
1535static const char *
1536get_ppc_dynamic_type (unsigned long type)
1537{
1538 switch (type)
1539 {
a7f2871e
AM
1540 case DT_PPC_GOT: return "PPC_GOT";
1541 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1542 default:
1543 return NULL;
1544 }
1545}
1546
f1cb7e17 1547static const char *
d3ba0551 1548get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1549{
1550 switch (type)
1551 {
a7f2871e
AM
1552 case DT_PPC64_GLINK: return "PPC64_GLINK";
1553 case DT_PPC64_OPD: return "PPC64_OPD";
1554 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1555 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1556 default:
1557 return NULL;
1558 }
1559}
1560
103f02d3 1561static const char *
d3ba0551 1562get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1563{
1564 switch (type)
1565 {
1566 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1567 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1568 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1569 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1570 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1571 case DT_HP_PREINIT: return "HP_PREINIT";
1572 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1573 case DT_HP_NEEDED: return "HP_NEEDED";
1574 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1575 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1576 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1577 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1578 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1579 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1580 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1581 case DT_HP_FILTERED: return "HP_FILTERED";
1582 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1583 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1584 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1585 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1586 case DT_PLT: return "PLT";
1587 case DT_PLT_SIZE: return "PLT_SIZE";
1588 case DT_DLT: return "DLT";
1589 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1590 default:
1591 return NULL;
1592 }
1593}
9a097730 1594
ecc51f48 1595static const char *
d3ba0551 1596get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1597{
1598 switch (type)
1599 {
148b93f2
NC
1600 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1601 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1602 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1603 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1604 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1605 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1606 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1607 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1608 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1609 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1610 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1611 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1612 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1613 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1614 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1615 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1616 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1617 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1618 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1619 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1620 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1621 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1622 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1623 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1624 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1625 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1626 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1627 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1628 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1629 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1630 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1631 default:
1632 return NULL;
1633 }
1634}
1635
fabcb361
RH
1636static const char *
1637get_alpha_dynamic_type (unsigned long type)
1638{
1639 switch (type)
1640 {
1641 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1642 default:
1643 return NULL;
1644 }
1645}
1646
1c0d3aa6
NC
1647static const char *
1648get_score_dynamic_type (unsigned long type)
1649{
1650 switch (type)
1651 {
1652 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1653 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1654 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1655 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1656 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1657 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1658 default:
1659 return NULL;
1660 }
1661}
1662
40b36596
JM
1663static const char *
1664get_tic6x_dynamic_type (unsigned long type)
1665{
1666 switch (type)
1667 {
1668 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1669 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1670 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1671 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1672 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1673 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1674 default:
1675 return NULL;
1676 }
1677}
1c0d3aa6 1678
252b5132 1679static const char *
d3ba0551 1680get_dynamic_type (unsigned long type)
252b5132 1681{
e9e44622 1682 static char buff[64];
252b5132
RH
1683
1684 switch (type)
1685 {
1686 case DT_NULL: return "NULL";
1687 case DT_NEEDED: return "NEEDED";
1688 case DT_PLTRELSZ: return "PLTRELSZ";
1689 case DT_PLTGOT: return "PLTGOT";
1690 case DT_HASH: return "HASH";
1691 case DT_STRTAB: return "STRTAB";
1692 case DT_SYMTAB: return "SYMTAB";
1693 case DT_RELA: return "RELA";
1694 case DT_RELASZ: return "RELASZ";
1695 case DT_RELAENT: return "RELAENT";
1696 case DT_STRSZ: return "STRSZ";
1697 case DT_SYMENT: return "SYMENT";
1698 case DT_INIT: return "INIT";
1699 case DT_FINI: return "FINI";
1700 case DT_SONAME: return "SONAME";
1701 case DT_RPATH: return "RPATH";
1702 case DT_SYMBOLIC: return "SYMBOLIC";
1703 case DT_REL: return "REL";
1704 case DT_RELSZ: return "RELSZ";
1705 case DT_RELENT: return "RELENT";
1706 case DT_PLTREL: return "PLTREL";
1707 case DT_DEBUG: return "DEBUG";
1708 case DT_TEXTREL: return "TEXTREL";
1709 case DT_JMPREL: return "JMPREL";
1710 case DT_BIND_NOW: return "BIND_NOW";
1711 case DT_INIT_ARRAY: return "INIT_ARRAY";
1712 case DT_FINI_ARRAY: return "FINI_ARRAY";
1713 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1714 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1715 case DT_RUNPATH: return "RUNPATH";
1716 case DT_FLAGS: return "FLAGS";
2d0e6f43 1717
d1133906
NC
1718 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1719 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1720
05107a46 1721 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1722 case DT_PLTPADSZ: return "PLTPADSZ";
1723 case DT_MOVEENT: return "MOVEENT";
1724 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1725 case DT_FEATURE: return "FEATURE";
252b5132
RH
1726 case DT_POSFLAG_1: return "POSFLAG_1";
1727 case DT_SYMINSZ: return "SYMINSZ";
1728 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1729
252b5132 1730 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1731 case DT_CONFIG: return "CONFIG";
1732 case DT_DEPAUDIT: return "DEPAUDIT";
1733 case DT_AUDIT: return "AUDIT";
1734 case DT_PLTPAD: return "PLTPAD";
1735 case DT_MOVETAB: return "MOVETAB";
252b5132 1736 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1737
252b5132 1738 case DT_VERSYM: return "VERSYM";
103f02d3 1739
67a4f2b7
AO
1740 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1741 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1742 case DT_RELACOUNT: return "RELACOUNT";
1743 case DT_RELCOUNT: return "RELCOUNT";
1744 case DT_FLAGS_1: return "FLAGS_1";
1745 case DT_VERDEF: return "VERDEF";
1746 case DT_VERDEFNUM: return "VERDEFNUM";
1747 case DT_VERNEED: return "VERNEED";
1748 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1749
019148e4 1750 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1751 case DT_USED: return "USED";
1752 case DT_FILTER: return "FILTER";
103f02d3 1753
047b2264
JJ
1754 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1755 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1756 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1757 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1758 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1759 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1760
252b5132
RH
1761 default:
1762 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1763 {
2cf0635d 1764 const char * result;
103f02d3 1765
252b5132
RH
1766 switch (elf_header.e_machine)
1767 {
1768 case EM_MIPS:
4fe85591 1769 case EM_MIPS_RS3_LE:
252b5132
RH
1770 result = get_mips_dynamic_type (type);
1771 break;
9a097730
RH
1772 case EM_SPARCV9:
1773 result = get_sparc64_dynamic_type (type);
1774 break;
7490d522
AM
1775 case EM_PPC:
1776 result = get_ppc_dynamic_type (type);
1777 break;
f1cb7e17
AM
1778 case EM_PPC64:
1779 result = get_ppc64_dynamic_type (type);
1780 break;
ecc51f48
NC
1781 case EM_IA_64:
1782 result = get_ia64_dynamic_type (type);
1783 break;
fabcb361
RH
1784 case EM_ALPHA:
1785 result = get_alpha_dynamic_type (type);
1786 break;
1c0d3aa6
NC
1787 case EM_SCORE:
1788 result = get_score_dynamic_type (type);
1789 break;
40b36596
JM
1790 case EM_TI_C6000:
1791 result = get_tic6x_dynamic_type (type);
1792 break;
252b5132
RH
1793 default:
1794 result = NULL;
1795 break;
1796 }
1797
1798 if (result != NULL)
1799 return result;
1800
e9e44622 1801 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1802 }
eec8f817
DA
1803 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1804 || (elf_header.e_machine == EM_PARISC
1805 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1806 {
2cf0635d 1807 const char * result;
103f02d3
UD
1808
1809 switch (elf_header.e_machine)
1810 {
1811 case EM_PARISC:
1812 result = get_parisc_dynamic_type (type);
1813 break;
148b93f2
NC
1814 case EM_IA_64:
1815 result = get_ia64_dynamic_type (type);
1816 break;
103f02d3
UD
1817 default:
1818 result = NULL;
1819 break;
1820 }
1821
1822 if (result != NULL)
1823 return result;
1824
e9e44622
JJ
1825 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1826 type);
103f02d3 1827 }
252b5132 1828 else
e9e44622 1829 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1830
252b5132
RH
1831 return buff;
1832 }
1833}
1834
1835static char *
d3ba0551 1836get_file_type (unsigned e_type)
252b5132 1837{
b34976b6 1838 static char buff[32];
252b5132
RH
1839
1840 switch (e_type)
1841 {
1842 case ET_NONE: return _("NONE (None)");
1843 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1844 case ET_EXEC: return _("EXEC (Executable file)");
1845 case ET_DYN: return _("DYN (Shared object file)");
1846 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1847
1848 default:
1849 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1850 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1851 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1852 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1853 else
e9e44622 1854 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1855 return buff;
1856 }
1857}
1858
1859static char *
d3ba0551 1860get_machine_name (unsigned e_machine)
252b5132 1861{
b34976b6 1862 static char buff[64]; /* XXX */
252b5132
RH
1863
1864 switch (e_machine)
1865 {
c45021f2
NC
1866 case EM_NONE: return _("None");
1867 case EM_M32: return "WE32100";
1868 case EM_SPARC: return "Sparc";
e9f53129 1869 case EM_SPU: return "SPU";
c45021f2
NC
1870 case EM_386: return "Intel 80386";
1871 case EM_68K: return "MC68000";
1872 case EM_88K: return "MC88000";
1873 case EM_486: return "Intel 80486";
1874 case EM_860: return "Intel 80860";
1875 case EM_MIPS: return "MIPS R3000";
1876 case EM_S370: return "IBM System/370";
7036c0e1 1877 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1878 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1879 case EM_PARISC: return "HPPA";
252b5132 1880 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1881 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1882 case EM_960: return "Intel 90860";
1883 case EM_PPC: return "PowerPC";
285d1771 1884 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1885 case EM_V800: return "NEC V800";
1886 case EM_FR20: return "Fujitsu FR20";
1887 case EM_RH32: return "TRW RH32";
b34976b6 1888 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1889 case EM_ARM: return "ARM";
1890 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1891 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1892 case EM_SPARCV9: return "Sparc v9";
1893 case EM_TRICORE: return "Siemens Tricore";
584da044 1894 case EM_ARC: return "ARC";
c2dcd04e
NC
1895 case EM_H8_300: return "Renesas H8/300";
1896 case EM_H8_300H: return "Renesas H8/300H";
1897 case EM_H8S: return "Renesas H8S";
1898 case EM_H8_500: return "Renesas H8/500";
30800947 1899 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1900 case EM_MIPS_X: return "Stanford MIPS-X";
1901 case EM_COLDFIRE: return "Motorola Coldfire";
1902 case EM_68HC12: return "Motorola M68HC12";
c45021f2 1903 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1904 case EM_CYGNUS_D10V:
1905 case EM_D10V: return "d10v";
1906 case EM_CYGNUS_D30V:
b34976b6 1907 case EM_D30V: return "d30v";
2b0337b0 1908 case EM_CYGNUS_M32R:
26597c86 1909 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0
AO
1910 case EM_CYGNUS_V850:
1911 case EM_V850: return "NEC v850";
1912 case EM_CYGNUS_MN10300:
1913 case EM_MN10300: return "mn10300";
1914 case EM_CYGNUS_MN10200:
1915 case EM_MN10200: return "mn10200";
5506d11a 1916 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1917 case EM_CYGNUS_FR30:
1918 case EM_FR30: return "Fujitsu FR30";
b34976b6 1919 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1920 case EM_PJ_OLD:
b34976b6 1921 case EM_PJ: return "picoJava";
7036c0e1
AJ
1922 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1923 case EM_PCP: return "Siemens PCP";
1924 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1925 case EM_NDR1: return "Denso NDR1 microprocesspr";
1926 case EM_STARCORE: return "Motorola Star*Core processor";
1927 case EM_ME16: return "Toyota ME16 processor";
1928 case EM_ST100: return "STMicroelectronics ST100 processor";
1929 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1930 case EM_PDSP: return "Sony DSP processor";
1931 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1932 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1933 case EM_FX66: return "Siemens FX66 microcontroller";
1934 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1935 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1936 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
1937 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1938 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1939 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1940 case EM_SVX: return "Silicon Graphics SVx";
1941 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1942 case EM_VAX: return "Digital VAX";
2b0337b0 1943 case EM_AVR_OLD:
b34976b6 1944 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1945 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1946 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1947 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1948 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1949 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1950 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1951 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1952 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1953 case EM_L1OM: return "Intel L1OM";
b7498e0e 1954 case EM_S390_OLD:
b34976b6 1955 case EM_S390: return "IBM S/390";
1c0d3aa6 1956 case EM_SCORE: return "SUNPLUS S+Core";
93fbbb04 1957 case EM_XSTORMY16: return "Sanyo Xstormy16 CPU core";
3b16e843
NC
1958 case EM_OPENRISC:
1959 case EM_OR32: return "OpenRISC";
11636f9e 1960 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1961 case EM_CRX: return "National Semiconductor CRX microprocessor";
d172d4ba 1962 case EM_DLX: return "OpenDLX";
1e4cf259 1963 case EM_IP2K_OLD:
b34976b6 1964 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1965 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1966 case EM_XTENSA_OLD:
1967 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1968 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1969 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1970 case EM_NS32K: return "National Semiconductor 32000 series";
1971 case EM_TPC: return "Tenor Network TPC processor";
1972 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1973 case EM_MAX: return "MAX Processor";
1974 case EM_CR: return "National Semiconductor CompactRISC";
1975 case EM_F2MC16: return "Fujitsu F2MC16";
1976 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1977 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1978 case EM_M32C_OLD:
49f58d10 1979 case EM_M32C: return "Renesas M32c";
d031aafb 1980 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1981 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1982 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1983 case EM_SEP: return "Sharp embedded microprocessor";
1984 case EM_ARCA: return "Arca RISC microprocessor";
1985 case EM_UNICORE: return "Unicore";
1986 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1987 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1988 case EM_NIOS32: return "Altera Nios";
1989 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1990 case EM_C166:
d70c5fc7 1991 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
1992 case EM_M16C: return "Renesas M16C series microprocessors";
1993 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
1994 case EM_CE: return "Freescale Communication Engine RISC core";
1995 case EM_TSK3000: return "Altium TSK3000 core";
1996 case EM_RS08: return "Freescale RS08 embedded processor";
1997 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
1998 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
1999 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2000 case EM_SE_C17: return "Seiko Epson C17 family";
2001 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2002 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2003 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2004 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2005 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2006 case EM_R32C: return "Renesas R32C series microprocessors";
2007 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2008 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2009 case EM_8051: return "Intel 8051 and variants";
2010 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2011 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2012 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2013 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2014 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2015 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2016 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2017 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2018 case EM_CR16:
6c03b1ed 2019 case EM_CR16_OLD: return "National Semiconductor's CR16";
7ba29e2a
NC
2020 case EM_MICROBLAZE: return "Xilinx MicroBlaze";
2021 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
c7927a3c 2022 case EM_RX: return "Renesas RX";
11636f9e
JM
2023 case EM_METAG: return "Imagination Technologies META processor architecture";
2024 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2025 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2026 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2027 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2028 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2029 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2030 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2031 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
2032 case EM_CUDA: return "NVIDIA CUDA architecture";
252b5132 2033 default:
35d9dd2f 2034 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2035 return buff;
2036 }
2037}
2038
f3485b74 2039static void
d3ba0551 2040decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2041{
2042 unsigned eabi;
2043 int unknown = 0;
2044
2045 eabi = EF_ARM_EABI_VERSION (e_flags);
2046 e_flags &= ~ EF_ARM_EABIMASK;
2047
2048 /* Handle "generic" ARM flags. */
2049 if (e_flags & EF_ARM_RELEXEC)
2050 {
2051 strcat (buf, ", relocatable executable");
2052 e_flags &= ~ EF_ARM_RELEXEC;
2053 }
76da6bbe 2054
f3485b74
NC
2055 if (e_flags & EF_ARM_HASENTRY)
2056 {
2057 strcat (buf, ", has entry point");
2058 e_flags &= ~ EF_ARM_HASENTRY;
2059 }
76da6bbe 2060
f3485b74
NC
2061 /* Now handle EABI specific flags. */
2062 switch (eabi)
2063 {
2064 default:
2c71103e 2065 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2066 if (e_flags)
2067 unknown = 1;
2068 break;
2069
2070 case EF_ARM_EABI_VER1:
a5bcd848 2071 strcat (buf, ", Version1 EABI");
f3485b74
NC
2072 while (e_flags)
2073 {
2074 unsigned flag;
76da6bbe 2075
f3485b74
NC
2076 /* Process flags one bit at a time. */
2077 flag = e_flags & - e_flags;
2078 e_flags &= ~ flag;
76da6bbe 2079
f3485b74
NC
2080 switch (flag)
2081 {
a5bcd848 2082 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2083 strcat (buf, ", sorted symbol tables");
2084 break;
76da6bbe 2085
f3485b74
NC
2086 default:
2087 unknown = 1;
2088 break;
2089 }
2090 }
2091 break;
76da6bbe 2092
a5bcd848
PB
2093 case EF_ARM_EABI_VER2:
2094 strcat (buf, ", Version2 EABI");
2095 while (e_flags)
2096 {
2097 unsigned flag;
2098
2099 /* Process flags one bit at a time. */
2100 flag = e_flags & - e_flags;
2101 e_flags &= ~ flag;
2102
2103 switch (flag)
2104 {
2105 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2106 strcat (buf, ", sorted symbol tables");
2107 break;
2108
2109 case EF_ARM_DYNSYMSUSESEGIDX:
2110 strcat (buf, ", dynamic symbols use segment index");
2111 break;
2112
2113 case EF_ARM_MAPSYMSFIRST:
2114 strcat (buf, ", mapping symbols precede others");
2115 break;
2116
2117 default:
2118 unknown = 1;
2119 break;
2120 }
2121 }
2122 break;
2123
d507cf36
PB
2124 case EF_ARM_EABI_VER3:
2125 strcat (buf, ", Version3 EABI");
8cb51566
PB
2126 break;
2127
2128 case EF_ARM_EABI_VER4:
2129 strcat (buf, ", Version4 EABI");
3a4a14e9
PB
2130 goto eabi;
2131
2132 case EF_ARM_EABI_VER5:
2133 strcat (buf, ", Version5 EABI");
2134 eabi:
d507cf36
PB
2135 while (e_flags)
2136 {
2137 unsigned flag;
2138
2139 /* Process flags one bit at a time. */
2140 flag = e_flags & - e_flags;
2141 e_flags &= ~ flag;
2142
2143 switch (flag)
2144 {
2145 case EF_ARM_BE8:
2146 strcat (buf, ", BE8");
2147 break;
2148
2149 case EF_ARM_LE8:
2150 strcat (buf, ", LE8");
2151 break;
2152
2153 default:
2154 unknown = 1;
2155 break;
2156 }
2157 }
2158 break;
2159
f3485b74 2160 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2161 strcat (buf, ", GNU EABI");
f3485b74
NC
2162 while (e_flags)
2163 {
2164 unsigned flag;
76da6bbe 2165
f3485b74
NC
2166 /* Process flags one bit at a time. */
2167 flag = e_flags & - e_flags;
2168 e_flags &= ~ flag;
76da6bbe 2169
f3485b74
NC
2170 switch (flag)
2171 {
a5bcd848 2172 case EF_ARM_INTERWORK:
f3485b74
NC
2173 strcat (buf, ", interworking enabled");
2174 break;
76da6bbe 2175
a5bcd848 2176 case EF_ARM_APCS_26:
f3485b74
NC
2177 strcat (buf, ", uses APCS/26");
2178 break;
76da6bbe 2179
a5bcd848 2180 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2181 strcat (buf, ", uses APCS/float");
2182 break;
76da6bbe 2183
a5bcd848 2184 case EF_ARM_PIC:
f3485b74
NC
2185 strcat (buf, ", position independent");
2186 break;
76da6bbe 2187
a5bcd848 2188 case EF_ARM_ALIGN8:
f3485b74
NC
2189 strcat (buf, ", 8 bit structure alignment");
2190 break;
76da6bbe 2191
a5bcd848 2192 case EF_ARM_NEW_ABI:
f3485b74
NC
2193 strcat (buf, ", uses new ABI");
2194 break;
76da6bbe 2195
a5bcd848 2196 case EF_ARM_OLD_ABI:
f3485b74
NC
2197 strcat (buf, ", uses old ABI");
2198 break;
76da6bbe 2199
a5bcd848 2200 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2201 strcat (buf, ", software FP");
2202 break;
76da6bbe 2203
90e01f86
ILT
2204 case EF_ARM_VFP_FLOAT:
2205 strcat (buf, ", VFP");
2206 break;
2207
fde78edd
NC
2208 case EF_ARM_MAVERICK_FLOAT:
2209 strcat (buf, ", Maverick FP");
2210 break;
2211
f3485b74
NC
2212 default:
2213 unknown = 1;
2214 break;
2215 }
2216 }
2217 }
f3485b74
NC
2218
2219 if (unknown)
2b692964 2220 strcat (buf,_(", <unknown>"));
f3485b74
NC
2221}
2222
252b5132 2223static char *
d3ba0551 2224get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2225{
b34976b6 2226 static char buf[1024];
252b5132
RH
2227
2228 buf[0] = '\0';
76da6bbe 2229
252b5132
RH
2230 if (e_flags)
2231 {
2232 switch (e_machine)
2233 {
2234 default:
2235 break;
2236
f3485b74
NC
2237 case EM_ARM:
2238 decode_ARM_machine_flags (e_flags, buf);
2239 break;
76da6bbe 2240
ec2dfb42
AO
2241 case EM_CYGNUS_FRV:
2242 switch (e_flags & EF_FRV_CPU_MASK)
2243 {
2244 case EF_FRV_CPU_GENERIC:
2245 break;
2246
2247 default:
2248 strcat (buf, ", fr???");
2249 break;
57346661 2250
ec2dfb42
AO
2251 case EF_FRV_CPU_FR300:
2252 strcat (buf, ", fr300");
2253 break;
2254
2255 case EF_FRV_CPU_FR400:
2256 strcat (buf, ", fr400");
2257 break;
2258 case EF_FRV_CPU_FR405:
2259 strcat (buf, ", fr405");
2260 break;
2261
2262 case EF_FRV_CPU_FR450:
2263 strcat (buf, ", fr450");
2264 break;
2265
2266 case EF_FRV_CPU_FR500:
2267 strcat (buf, ", fr500");
2268 break;
2269 case EF_FRV_CPU_FR550:
2270 strcat (buf, ", fr550");
2271 break;
2272
2273 case EF_FRV_CPU_SIMPLE:
2274 strcat (buf, ", simple");
2275 break;
2276 case EF_FRV_CPU_TOMCAT:
2277 strcat (buf, ", tomcat");
2278 break;
2279 }
1c877e87 2280 break;
ec2dfb42 2281
53c7db4b 2282 case EM_68K:
425c6cb0 2283 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2284 strcat (buf, ", m68000");
425c6cb0 2285 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2286 strcat (buf, ", cpu32");
2287 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2288 strcat (buf, ", fido_a");
425c6cb0 2289 else
266abb8f 2290 {
2cf0635d
NC
2291 char const * isa = _("unknown");
2292 char const * mac = _("unknown mac");
2293 char const * additional = NULL;
0112cd26 2294
c694fd50 2295 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2296 {
c694fd50 2297 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2298 isa = "A";
2299 additional = ", nodiv";
2300 break;
c694fd50 2301 case EF_M68K_CF_ISA_A:
266abb8f
NS
2302 isa = "A";
2303 break;
c694fd50 2304 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2305 isa = "A+";
2306 break;
c694fd50 2307 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2308 isa = "B";
2309 additional = ", nousp";
2310 break;
c694fd50 2311 case EF_M68K_CF_ISA_B:
266abb8f
NS
2312 isa = "B";
2313 break;
f608cd77
NS
2314 case EF_M68K_CF_ISA_C:
2315 isa = "C";
2316 break;
2317 case EF_M68K_CF_ISA_C_NODIV:
2318 isa = "C";
2319 additional = ", nodiv";
2320 break;
266abb8f
NS
2321 }
2322 strcat (buf, ", cf, isa ");
2323 strcat (buf, isa);
0b2e31dc
NS
2324 if (additional)
2325 strcat (buf, additional);
c694fd50 2326 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2327 strcat (buf, ", float");
c694fd50 2328 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2329 {
2330 case 0:
2331 mac = NULL;
2332 break;
c694fd50 2333 case EF_M68K_CF_MAC:
266abb8f
NS
2334 mac = "mac";
2335 break;
c694fd50 2336 case EF_M68K_CF_EMAC:
266abb8f
NS
2337 mac = "emac";
2338 break;
f608cd77
NS
2339 case EF_M68K_CF_EMAC_B:
2340 mac = "emac_b";
2341 break;
266abb8f
NS
2342 }
2343 if (mac)
2344 {
2345 strcat (buf, ", ");
2346 strcat (buf, mac);
2347 }
266abb8f 2348 }
53c7db4b 2349 break;
33c63f9d 2350
252b5132
RH
2351 case EM_PPC:
2352 if (e_flags & EF_PPC_EMB)
2353 strcat (buf, ", emb");
2354
2355 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2356 strcat (buf, _(", relocatable"));
252b5132
RH
2357
2358 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2359 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2360 break;
2361
2b0337b0 2362 case EM_V850:
252b5132
RH
2363 case EM_CYGNUS_V850:
2364 switch (e_flags & EF_V850_ARCH)
2365 {
1cd986c5
NC
2366 case E_V850E2V3_ARCH:
2367 strcat (buf, ", v850e2v3");
2368 break;
2369 case E_V850E2_ARCH:
2370 strcat (buf, ", v850e2");
2371 break;
2372 case E_V850E1_ARCH:
2373 strcat (buf, ", v850e1");
8ad30312 2374 break;
252b5132
RH
2375 case E_V850E_ARCH:
2376 strcat (buf, ", v850e");
2377 break;
252b5132
RH
2378 case E_V850_ARCH:
2379 strcat (buf, ", v850");
2380 break;
2381 default:
2b692964 2382 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2383 break;
2384 }
2385 break;
2386
2b0337b0 2387 case EM_M32R:
252b5132
RH
2388 case EM_CYGNUS_M32R:
2389 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2390 strcat (buf, ", m32r");
252b5132
RH
2391 break;
2392
2393 case EM_MIPS:
4fe85591 2394 case EM_MIPS_RS3_LE:
252b5132
RH
2395 if (e_flags & EF_MIPS_NOREORDER)
2396 strcat (buf, ", noreorder");
2397
2398 if (e_flags & EF_MIPS_PIC)
2399 strcat (buf, ", pic");
2400
2401 if (e_flags & EF_MIPS_CPIC)
2402 strcat (buf, ", cpic");
2403
d1bdd336
TS
2404 if (e_flags & EF_MIPS_UCODE)
2405 strcat (buf, ", ugen_reserved");
2406
252b5132
RH
2407 if (e_flags & EF_MIPS_ABI2)
2408 strcat (buf, ", abi2");
2409
43521d43
TS
2410 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2411 strcat (buf, ", odk first");
2412
a5d22d2a
TS
2413 if (e_flags & EF_MIPS_32BITMODE)
2414 strcat (buf, ", 32bitmode");
2415
156c2f8b
NC
2416 switch ((e_flags & EF_MIPS_MACH))
2417 {
2418 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2419 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2420 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2421 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2422 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2423 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2424 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2425 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2426 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2427 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2428 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2429 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
05c6f050 2430 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2431 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2432 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2433 case 0:
2434 /* We simply ignore the field in this case to avoid confusion:
2435 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2436 extension. */
2437 break;
2b692964 2438 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2439 }
43521d43
TS
2440
2441 switch ((e_flags & EF_MIPS_ABI))
2442 {
2443 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2444 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2445 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2446 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2447 case 0:
2448 /* We simply ignore the field in this case to avoid confusion:
2449 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2450 This means it is likely to be an o32 file, but not for
2451 sure. */
2452 break;
2b692964 2453 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2454 }
2455
2456 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2457 strcat (buf, ", mdmx");
2458
2459 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2460 strcat (buf, ", mips16");
2461
2462 switch ((e_flags & EF_MIPS_ARCH))
2463 {
2464 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2465 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2466 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2467 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2468 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2469 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2470 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2471 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2472 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2473 default: strcat (buf, _(", unknown ISA")); break;
43521d43
TS
2474 }
2475
8e45593f
NC
2476 if (e_flags & EF_SH_PIC)
2477 strcat (buf, ", pic");
2478
2479 if (e_flags & EF_SH_FDPIC)
2480 strcat (buf, ", fdpic");
252b5132 2481 break;
351b4b40 2482
ccde1100
AO
2483 case EM_SH:
2484 switch ((e_flags & EF_SH_MACH_MASK))
2485 {
2486 case EF_SH1: strcat (buf, ", sh1"); break;
2487 case EF_SH2: strcat (buf, ", sh2"); break;
2488 case EF_SH3: strcat (buf, ", sh3"); break;
2489 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2490 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2491 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2492 case EF_SH3E: strcat (buf, ", sh3e"); break;
2493 case EF_SH4: strcat (buf, ", sh4"); break;
2494 case EF_SH5: strcat (buf, ", sh5"); break;
2495 case EF_SH2E: strcat (buf, ", sh2e"); break;
2496 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2497 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2498 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2499 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2500 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2501 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2502 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2503 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2504 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2505 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2506 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2507 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2508 }
2509
2510 break;
57346661 2511
351b4b40
RH
2512 case EM_SPARCV9:
2513 if (e_flags & EF_SPARC_32PLUS)
2514 strcat (buf, ", v8+");
2515
2516 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2517 strcat (buf, ", ultrasparcI");
2518
2519 if (e_flags & EF_SPARC_SUN_US3)
2520 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2521
2522 if (e_flags & EF_SPARC_HAL_R1)
2523 strcat (buf, ", halr1");
2524
2525 if (e_flags & EF_SPARC_LEDATA)
2526 strcat (buf, ", ledata");
2527
2528 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2529 strcat (buf, ", tso");
2530
2531 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2532 strcat (buf, ", pso");
2533
2534 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2535 strcat (buf, ", rmo");
2536 break;
7d466069 2537
103f02d3
UD
2538 case EM_PARISC:
2539 switch (e_flags & EF_PARISC_ARCH)
2540 {
2541 case EFA_PARISC_1_0:
2542 strcpy (buf, ", PA-RISC 1.0");
2543 break;
2544 case EFA_PARISC_1_1:
2545 strcpy (buf, ", PA-RISC 1.1");
2546 break;
2547 case EFA_PARISC_2_0:
2548 strcpy (buf, ", PA-RISC 2.0");
2549 break;
2550 default:
2551 break;
2552 }
2553 if (e_flags & EF_PARISC_TRAPNIL)
2554 strcat (buf, ", trapnil");
2555 if (e_flags & EF_PARISC_EXT)
2556 strcat (buf, ", ext");
2557 if (e_flags & EF_PARISC_LSB)
2558 strcat (buf, ", lsb");
2559 if (e_flags & EF_PARISC_WIDE)
2560 strcat (buf, ", wide");
2561 if (e_flags & EF_PARISC_NO_KABP)
2562 strcat (buf, ", no kabp");
2563 if (e_flags & EF_PARISC_LAZYSWAP)
2564 strcat (buf, ", lazyswap");
30800947 2565 break;
76da6bbe 2566
7d466069 2567 case EM_PJ:
2b0337b0 2568 case EM_PJ_OLD:
7d466069
ILT
2569 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2570 strcat (buf, ", new calling convention");
2571
2572 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2573 strcat (buf, ", gnu calling convention");
2574 break;
4d6ed7c8
NC
2575
2576 case EM_IA_64:
2577 if ((e_flags & EF_IA_64_ABI64))
2578 strcat (buf, ", 64-bit");
2579 else
2580 strcat (buf, ", 32-bit");
2581 if ((e_flags & EF_IA_64_REDUCEDFP))
2582 strcat (buf, ", reduced fp model");
2583 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2584 strcat (buf, ", no function descriptors, constant gp");
2585 else if ((e_flags & EF_IA_64_CONS_GP))
2586 strcat (buf, ", constant gp");
2587 if ((e_flags & EF_IA_64_ABSOLUTE))
2588 strcat (buf, ", absolute");
28f997cf
TG
2589 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2590 {
2591 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2592 strcat (buf, ", vms_linkages");
2593 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2594 {
2595 case EF_IA_64_VMS_COMCOD_SUCCESS:
2596 break;
2597 case EF_IA_64_VMS_COMCOD_WARNING:
2598 strcat (buf, ", warning");
2599 break;
2600 case EF_IA_64_VMS_COMCOD_ERROR:
2601 strcat (buf, ", error");
2602 break;
2603 case EF_IA_64_VMS_COMCOD_ABORT:
2604 strcat (buf, ", abort");
2605 break;
2606 default:
2607 abort ();
2608 }
2609 }
4d6ed7c8 2610 break;
179d3252
JT
2611
2612 case EM_VAX:
2613 if ((e_flags & EF_VAX_NONPIC))
2614 strcat (buf, ", non-PIC");
2615 if ((e_flags & EF_VAX_DFLOAT))
2616 strcat (buf, ", D-Float");
2617 if ((e_flags & EF_VAX_GFLOAT))
2618 strcat (buf, ", G-Float");
2619 break;
c7927a3c
NC
2620
2621 case EM_RX:
2622 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2623 strcat (buf, ", 64-bit doubles");
2624 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2625 strcat (buf, ", dsp");
55786da2
AK
2626
2627 case EM_S390:
2628 if (e_flags & EF_S390_HIGH_GPRS)
2629 strcat (buf, ", highgprs");
40b36596
JM
2630
2631 case EM_TI_C6000:
2632 if ((e_flags & EF_C6000_REL))
2633 strcat (buf, ", relocatable module");
252b5132
RH
2634 }
2635 }
2636
2637 return buf;
2638}
2639
252b5132 2640static const char *
d3ba0551
AM
2641get_osabi_name (unsigned int osabi)
2642{
2643 static char buff[32];
2644
2645 switch (osabi)
2646 {
2647 case ELFOSABI_NONE: return "UNIX - System V";
2648 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2649 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
2650 case ELFOSABI_LINUX: return "UNIX - Linux";
2651 case ELFOSABI_HURD: return "GNU/Hurd";
2652 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2653 case ELFOSABI_AIX: return "UNIX - AIX";
2654 case ELFOSABI_IRIX: return "UNIX - IRIX";
2655 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2656 case ELFOSABI_TRU64: return "UNIX - TRU64";
2657 case ELFOSABI_MODESTO: return "Novell - Modesto";
2658 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2659 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2660 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2661 case ELFOSABI_AROS: return "AROS";
11636f9e 2662 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2663 default:
40b36596
JM
2664 if (osabi >= 64)
2665 switch (elf_header.e_machine)
2666 {
2667 case EM_ARM:
2668 switch (osabi)
2669 {
2670 case ELFOSABI_ARM: return "ARM";
2671 default:
2672 break;
2673 }
2674 break;
2675
2676 case EM_MSP430:
2677 case EM_MSP430_OLD:
2678 switch (osabi)
2679 {
2680 case ELFOSABI_STANDALONE: return _("Standalone App");
2681 default:
2682 break;
2683 }
2684 break;
2685
2686 case EM_TI_C6000:
2687 switch (osabi)
2688 {
2689 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2690 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2691 default:
2692 break;
2693 }
2694 break;
2695
2696 default:
2697 break;
2698 }
e9e44622 2699 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2700 return buff;
2701 }
2702}
2703
b294bdf8
MM
2704static const char *
2705get_arm_segment_type (unsigned long type)
2706{
2707 switch (type)
2708 {
2709 case PT_ARM_EXIDX:
2710 return "EXIDX";
2711 default:
2712 break;
2713 }
2714
2715 return NULL;
2716}
2717
d3ba0551
AM
2718static const char *
2719get_mips_segment_type (unsigned long type)
252b5132
RH
2720{
2721 switch (type)
2722 {
2723 case PT_MIPS_REGINFO:
2724 return "REGINFO";
2725 case PT_MIPS_RTPROC:
2726 return "RTPROC";
2727 case PT_MIPS_OPTIONS:
2728 return "OPTIONS";
2729 default:
2730 break;
2731 }
2732
2733 return NULL;
2734}
2735
103f02d3 2736static const char *
d3ba0551 2737get_parisc_segment_type (unsigned long type)
103f02d3
UD
2738{
2739 switch (type)
2740 {
2741 case PT_HP_TLS: return "HP_TLS";
2742 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2743 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2744 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2745 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2746 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2747 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2748 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2749 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2750 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2751 case PT_HP_PARALLEL: return "HP_PARALLEL";
2752 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2753 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2754 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2755 case PT_HP_STACK: return "HP_STACK";
2756 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2757 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2758 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2759 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2760 default:
2761 break;
2762 }
2763
2764 return NULL;
2765}
2766
4d6ed7c8 2767static const char *
d3ba0551 2768get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2769{
2770 switch (type)
2771 {
2772 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2773 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2774 case PT_HP_TLS: return "HP_TLS";
2775 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2776 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2777 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2778 default:
2779 break;
2780 }
2781
2782 return NULL;
2783}
2784
40b36596
JM
2785static const char *
2786get_tic6x_segment_type (unsigned long type)
2787{
2788 switch (type)
2789 {
2790 case PT_C6000_PHATTR: return "C6000_PHATTR";
2791 default:
2792 break;
2793 }
2794
2795 return NULL;
2796}
2797
252b5132 2798static const char *
d3ba0551 2799get_segment_type (unsigned long p_type)
252b5132 2800{
b34976b6 2801 static char buff[32];
252b5132
RH
2802
2803 switch (p_type)
2804 {
b34976b6
AM
2805 case PT_NULL: return "NULL";
2806 case PT_LOAD: return "LOAD";
252b5132 2807 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2808 case PT_INTERP: return "INTERP";
2809 case PT_NOTE: return "NOTE";
2810 case PT_SHLIB: return "SHLIB";
2811 case PT_PHDR: return "PHDR";
13ae64f3 2812 case PT_TLS: return "TLS";
252b5132 2813
65765700
JJ
2814 case PT_GNU_EH_FRAME:
2815 return "GNU_EH_FRAME";
2b05f1b7 2816 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2817 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2818
252b5132
RH
2819 default:
2820 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2821 {
2cf0635d 2822 const char * result;
103f02d3 2823
252b5132
RH
2824 switch (elf_header.e_machine)
2825 {
b294bdf8
MM
2826 case EM_ARM:
2827 result = get_arm_segment_type (p_type);
2828 break;
252b5132 2829 case EM_MIPS:
4fe85591 2830 case EM_MIPS_RS3_LE:
252b5132
RH
2831 result = get_mips_segment_type (p_type);
2832 break;
103f02d3
UD
2833 case EM_PARISC:
2834 result = get_parisc_segment_type (p_type);
2835 break;
4d6ed7c8
NC
2836 case EM_IA_64:
2837 result = get_ia64_segment_type (p_type);
2838 break;
40b36596
JM
2839 case EM_TI_C6000:
2840 result = get_tic6x_segment_type (p_type);
2841 break;
252b5132
RH
2842 default:
2843 result = NULL;
2844 break;
2845 }
103f02d3 2846
252b5132
RH
2847 if (result != NULL)
2848 return result;
103f02d3 2849
252b5132
RH
2850 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2851 }
2852 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2853 {
2cf0635d 2854 const char * result;
103f02d3
UD
2855
2856 switch (elf_header.e_machine)
2857 {
2858 case EM_PARISC:
2859 result = get_parisc_segment_type (p_type);
2860 break;
00428cca
AM
2861 case EM_IA_64:
2862 result = get_ia64_segment_type (p_type);
2863 break;
103f02d3
UD
2864 default:
2865 result = NULL;
2866 break;
2867 }
2868
2869 if (result != NULL)
2870 return result;
2871
2872 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2873 }
252b5132 2874 else
e9e44622 2875 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2876
2877 return buff;
2878 }
2879}
2880
2881static const char *
d3ba0551 2882get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2883{
2884 switch (sh_type)
2885 {
b34976b6
AM
2886 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2887 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2888 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2889 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2890 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2891 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2892 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2893 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2894 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2895 case SHT_MIPS_RELD: return "MIPS_RELD";
2896 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2897 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2898 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2899 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2900 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2901 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2902 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2903 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2904 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2905 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2906 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2907 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2908 case SHT_MIPS_LINE: return "MIPS_LINE";
2909 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2910 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2911 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2912 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2913 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2914 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2915 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2916 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2917 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2918 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2919 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2920 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2921 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2922 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2923 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2924 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2925 default:
2926 break;
2927 }
2928 return NULL;
2929}
2930
103f02d3 2931static const char *
d3ba0551 2932get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2933{
2934 switch (sh_type)
2935 {
2936 case SHT_PARISC_EXT: return "PARISC_EXT";
2937 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2938 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2939 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2940 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2941 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2942 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2943 default:
2944 break;
2945 }
2946 return NULL;
2947}
2948
4d6ed7c8 2949static const char *
d3ba0551 2950get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2951{
18bd398b 2952 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2953 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2954 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2955
4d6ed7c8
NC
2956 switch (sh_type)
2957 {
148b93f2
NC
2958 case SHT_IA_64_EXT: return "IA_64_EXT";
2959 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2960 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
2961 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
2962 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
2963 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
2964 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
2965 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
2966 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
2967 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
2968 default:
2969 break;
2970 }
2971 return NULL;
2972}
2973
d2b2c203
DJ
2974static const char *
2975get_x86_64_section_type_name (unsigned int sh_type)
2976{
2977 switch (sh_type)
2978 {
2979 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2980 default:
2981 break;
2982 }
2983 return NULL;
2984}
2985
40a18ebd
NC
2986static const char *
2987get_arm_section_type_name (unsigned int sh_type)
2988{
2989 switch (sh_type)
2990 {
7f6fed87
NC
2991 case SHT_ARM_EXIDX: return "ARM_EXIDX";
2992 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
2993 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
2994 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
2995 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
2996 default:
2997 break;
2998 }
2999 return NULL;
3000}
3001
40b36596
JM
3002static const char *
3003get_tic6x_section_type_name (unsigned int sh_type)
3004{
3005 switch (sh_type)
3006 {
3007 case SHT_C6000_UNWIND:
3008 return "C6000_UNWIND";
3009 case SHT_C6000_PREEMPTMAP:
3010 return "C6000_PREEMPTMAP";
3011 case SHT_C6000_ATTRIBUTES:
3012 return "C6000_ATTRIBUTES";
3013 case SHT_TI_ICODE:
3014 return "TI_ICODE";
3015 case SHT_TI_XREF:
3016 return "TI_XREF";
3017 case SHT_TI_HANDLER:
3018 return "TI_HANDLER";
3019 case SHT_TI_INITINFO:
3020 return "TI_INITINFO";
3021 case SHT_TI_PHATTRS:
3022 return "TI_PHATTRS";
3023 default:
3024 break;
3025 }
3026 return NULL;
3027}
3028
252b5132 3029static const char *
d3ba0551 3030get_section_type_name (unsigned int sh_type)
252b5132 3031{
b34976b6 3032 static char buff[32];
252b5132
RH
3033
3034 switch (sh_type)
3035 {
3036 case SHT_NULL: return "NULL";
3037 case SHT_PROGBITS: return "PROGBITS";
3038 case SHT_SYMTAB: return "SYMTAB";
3039 case SHT_STRTAB: return "STRTAB";
3040 case SHT_RELA: return "RELA";
3041 case SHT_HASH: return "HASH";
3042 case SHT_DYNAMIC: return "DYNAMIC";
3043 case SHT_NOTE: return "NOTE";
3044 case SHT_NOBITS: return "NOBITS";
3045 case SHT_REL: return "REL";
3046 case SHT_SHLIB: return "SHLIB";
3047 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3048 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3049 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3050 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3051 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3052 case SHT_GROUP: return "GROUP";
3053 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3054 case SHT_GNU_verdef: return "VERDEF";
3055 case SHT_GNU_verneed: return "VERNEED";
3056 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3057 case 0x6ffffff0: return "VERSYM";
3058 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3059 case 0x7ffffffd: return "AUXILIARY";
3060 case 0x7fffffff: return "FILTER";
047b2264 3061 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3062
3063 default:
3064 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3065 {
2cf0635d 3066 const char * result;
252b5132
RH
3067
3068 switch (elf_header.e_machine)
3069 {
3070 case EM_MIPS:
4fe85591 3071 case EM_MIPS_RS3_LE:
252b5132
RH
3072 result = get_mips_section_type_name (sh_type);
3073 break;
103f02d3
UD
3074 case EM_PARISC:
3075 result = get_parisc_section_type_name (sh_type);
3076 break;
4d6ed7c8
NC
3077 case EM_IA_64:
3078 result = get_ia64_section_type_name (sh_type);
3079 break;
d2b2c203 3080 case EM_X86_64:
8a9036a4 3081 case EM_L1OM:
d2b2c203
DJ
3082 result = get_x86_64_section_type_name (sh_type);
3083 break;
40a18ebd
NC
3084 case EM_ARM:
3085 result = get_arm_section_type_name (sh_type);
3086 break;
40b36596
JM
3087 case EM_TI_C6000:
3088 result = get_tic6x_section_type_name (sh_type);
3089 break;
252b5132
RH
3090 default:
3091 result = NULL;
3092 break;
3093 }
3094
3095 if (result != NULL)
3096 return result;
3097
c91d0dfb 3098 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3099 }
3100 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3101 {
2cf0635d 3102 const char * result;
148b93f2
NC
3103
3104 switch (elf_header.e_machine)
3105 {
3106 case EM_IA_64:
3107 result = get_ia64_section_type_name (sh_type);
3108 break;
3109 default:
3110 result = NULL;
3111 break;
3112 }
3113
3114 if (result != NULL)
3115 return result;
3116
3117 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3118 }
252b5132 3119 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3120 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3121 else
e9e44622 3122 snprintf (buff, sizeof (buff), _("<unknown>: %x"), sh_type);
103f02d3 3123
252b5132
RH
3124 return buff;
3125 }
3126}
3127
2979dc34 3128#define OPTION_DEBUG_DUMP 512
2c610e4b 3129#define OPTION_DYN_SYMS 513
2979dc34 3130
85b1c36d 3131static struct option options[] =
252b5132 3132{
b34976b6 3133 {"all", no_argument, 0, 'a'},
252b5132
RH
3134 {"file-header", no_argument, 0, 'h'},
3135 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3136 {"headers", no_argument, 0, 'e'},
3137 {"histogram", no_argument, 0, 'I'},
3138 {"segments", no_argument, 0, 'l'},
3139 {"sections", no_argument, 0, 'S'},
252b5132 3140 {"section-headers", no_argument, 0, 'S'},
f5842774 3141 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3142 {"section-details", no_argument, 0, 't'},
595cf52e 3143 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3144 {"symbols", no_argument, 0, 's'},
3145 {"syms", no_argument, 0, 's'},
2c610e4b 3146 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3147 {"relocs", no_argument, 0, 'r'},
3148 {"notes", no_argument, 0, 'n'},
3149 {"dynamic", no_argument, 0, 'd'},
a952a375 3150 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3151 {"version-info", no_argument, 0, 'V'},
3152 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3153 {"unwind", no_argument, 0, 'u'},
4145f1d5 3154 {"archive-index", no_argument, 0, 'c'},
b34976b6 3155 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3156 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3157 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3158#ifdef SUPPORT_DISASSEMBLY
3159 {"instruction-dump", required_argument, 0, 'i'},
3160#endif
cf13d699 3161 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3162
b34976b6
AM
3163 {"version", no_argument, 0, 'v'},
3164 {"wide", no_argument, 0, 'W'},
3165 {"help", no_argument, 0, 'H'},
3166 {0, no_argument, 0, 0}
252b5132
RH
3167};
3168
3169static void
2cf0635d 3170usage (FILE * stream)
252b5132 3171{
92f01d61
JM
3172 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3173 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3174 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3175 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3176 -h --file-header Display the ELF file header\n\
3177 -l --program-headers Display the program headers\n\
3178 --segments An alias for --program-headers\n\
3179 -S --section-headers Display the sections' header\n\
3180 --sections An alias for --section-headers\n\
f5842774 3181 -g --section-groups Display the section groups\n\
5477e8a0 3182 -t --section-details Display the section details\n\
8b53311e
NC
3183 -e --headers Equivalent to: -h -l -S\n\
3184 -s --syms Display the symbol table\n\
3f08eb35 3185 --symbols An alias for --syms\n\
2c610e4b 3186 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3187 -n --notes Display the core notes (if present)\n\
3188 -r --relocs Display the relocations (if present)\n\
3189 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3190 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
3191 -V --version-info Display the version sections (if present)\n\
3192 -A --arch-specific Display architecture specific information (if any).\n\
4145f1d5 3193 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3194 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3195 -x --hex-dump=<number|name>\n\
3196 Dump the contents of section <number|name> as bytes\n\
3197 -p --string-dump=<number|name>\n\
3198 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3199 -R --relocated-dump=<number|name>\n\
3200 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3201 -w[lLiaprmfFsoRt] or\n\
1ed06042 3202 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884
TG
3203 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
3204 =trace_info,=trace_abbrev,=trace_aranges]\n\
8b53311e 3205 Display the contents of DWARF2 debug sections\n"));
252b5132 3206#ifdef SUPPORT_DISASSEMBLY
92f01d61 3207 fprintf (stream, _("\
09c11c86
NC
3208 -i --instruction-dump=<number|name>\n\
3209 Disassemble the contents of section <number|name>\n"));
252b5132 3210#endif
92f01d61 3211 fprintf (stream, _("\
8b53311e
NC
3212 -I --histogram Display histogram of bucket list lengths\n\
3213 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3214 @<file> Read options from <file>\n\
8b53311e
NC
3215 -H --help Display this information\n\
3216 -v --version Display the version number of readelf\n"));
1118d252 3217
92f01d61
JM
3218 if (REPORT_BUGS_TO[0] && stream == stdout)
3219 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3220
92f01d61 3221 exit (stream == stdout ? 0 : 1);
252b5132
RH
3222}
3223
18bd398b
NC
3224/* Record the fact that the user wants the contents of section number
3225 SECTION to be displayed using the method(s) encoded as flags bits
3226 in TYPE. Note, TYPE can be zero if we are creating the array for
3227 the first time. */
3228
252b5132 3229static void
09c11c86 3230request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3231{
3232 if (section >= num_dump_sects)
3233 {
2cf0635d 3234 dump_type * new_dump_sects;
252b5132 3235
3f5e193b
NC
3236 new_dump_sects = (dump_type *) calloc (section + 1,
3237 sizeof (* dump_sects));
252b5132
RH
3238
3239 if (new_dump_sects == NULL)
591a748a 3240 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3241 else
3242 {
3243 /* Copy current flag settings. */
09c11c86 3244 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3245
3246 free (dump_sects);
3247
3248 dump_sects = new_dump_sects;
3249 num_dump_sects = section + 1;
3250 }
3251 }
3252
3253 if (dump_sects)
b34976b6 3254 dump_sects[section] |= type;
252b5132
RH
3255
3256 return;
3257}
3258
aef1f6d0
DJ
3259/* Request a dump by section name. */
3260
3261static void
2cf0635d 3262request_dump_byname (const char * section, dump_type type)
aef1f6d0 3263{
2cf0635d 3264 struct dump_list_entry * new_request;
aef1f6d0 3265
3f5e193b
NC
3266 new_request = (struct dump_list_entry *)
3267 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3268 if (!new_request)
591a748a 3269 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3270
3271 new_request->name = strdup (section);
3272 if (!new_request->name)
591a748a 3273 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3274
3275 new_request->type = type;
3276
3277 new_request->next = dump_sects_byname;
3278 dump_sects_byname = new_request;
3279}
3280
cf13d699
NC
3281static inline void
3282request_dump (dump_type type)
3283{
3284 int section;
3285 char * cp;
3286
3287 do_dump++;
3288 section = strtoul (optarg, & cp, 0);
3289
3290 if (! *cp && section >= 0)
3291 request_dump_bynumber (section, type);
3292 else
3293 request_dump_byname (optarg, type);
3294}
3295
3296
252b5132 3297static void
2cf0635d 3298parse_args (int argc, char ** argv)
252b5132
RH
3299{
3300 int c;
3301
3302 if (argc < 2)
92f01d61 3303 usage (stderr);
252b5132
RH
3304
3305 while ((c = getopt_long
cf13d699 3306 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3307 {
252b5132
RH
3308 switch (c)
3309 {
3310 case 0:
3311 /* Long options. */
3312 break;
3313 case 'H':
92f01d61 3314 usage (stdout);
252b5132
RH
3315 break;
3316
3317 case 'a':
b34976b6
AM
3318 do_syms++;
3319 do_reloc++;
3320 do_unwind++;
3321 do_dynamic++;
3322 do_header++;
3323 do_sections++;
f5842774 3324 do_section_groups++;
b34976b6
AM
3325 do_segments++;
3326 do_version++;
3327 do_histogram++;
3328 do_arch++;
3329 do_notes++;
252b5132 3330 break;
f5842774
L
3331 case 'g':
3332 do_section_groups++;
3333 break;
5477e8a0 3334 case 't':
595cf52e 3335 case 'N':
5477e8a0
L
3336 do_sections++;
3337 do_section_details++;
595cf52e 3338 break;
252b5132 3339 case 'e':
b34976b6
AM
3340 do_header++;
3341 do_sections++;
3342 do_segments++;
252b5132 3343 break;
a952a375 3344 case 'A':
b34976b6 3345 do_arch++;
a952a375 3346 break;
252b5132 3347 case 'D':
b34976b6 3348 do_using_dynamic++;
252b5132
RH
3349 break;
3350 case 'r':
b34976b6 3351 do_reloc++;
252b5132 3352 break;
4d6ed7c8 3353 case 'u':
b34976b6 3354 do_unwind++;
4d6ed7c8 3355 break;
252b5132 3356 case 'h':
b34976b6 3357 do_header++;
252b5132
RH
3358 break;
3359 case 'l':
b34976b6 3360 do_segments++;
252b5132
RH
3361 break;
3362 case 's':
b34976b6 3363 do_syms++;
252b5132
RH
3364 break;
3365 case 'S':
b34976b6 3366 do_sections++;
252b5132
RH
3367 break;
3368 case 'd':
b34976b6 3369 do_dynamic++;
252b5132 3370 break;
a952a375 3371 case 'I':
b34976b6 3372 do_histogram++;
a952a375 3373 break;
779fe533 3374 case 'n':
b34976b6 3375 do_notes++;
779fe533 3376 break;
4145f1d5
NC
3377 case 'c':
3378 do_archive_index++;
3379 break;
252b5132 3380 case 'x':
cf13d699 3381 request_dump (HEX_DUMP);
aef1f6d0 3382 break;
09c11c86 3383 case 'p':
cf13d699
NC
3384 request_dump (STRING_DUMP);
3385 break;
3386 case 'R':
3387 request_dump (RELOC_DUMP);
09c11c86 3388 break;
252b5132 3389 case 'w':
b34976b6 3390 do_dump++;
252b5132 3391 if (optarg == 0)
613ff48b
CC
3392 {
3393 do_debugging = 1;
3394 dwarf_select_sections_all ();
3395 }
252b5132
RH
3396 else
3397 {
3398 do_debugging = 0;
4cb93e3b 3399 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3400 }
3401 break;
2979dc34 3402 case OPTION_DEBUG_DUMP:
b34976b6 3403 do_dump++;
2979dc34
JJ
3404 if (optarg == 0)
3405 do_debugging = 1;
3406 else
3407 {
2979dc34 3408 do_debugging = 0;
4cb93e3b 3409 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3410 }
3411 break;
2c610e4b
L
3412 case OPTION_DYN_SYMS:
3413 do_dyn_syms++;
3414 break;
252b5132
RH
3415#ifdef SUPPORT_DISASSEMBLY
3416 case 'i':
cf13d699
NC
3417 request_dump (DISASS_DUMP);
3418 break;
252b5132
RH
3419#endif
3420 case 'v':
3421 print_version (program_name);
3422 break;
3423 case 'V':
b34976b6 3424 do_version++;
252b5132 3425 break;
d974e256 3426 case 'W':
b34976b6 3427 do_wide++;
d974e256 3428 break;
252b5132 3429 default:
252b5132
RH
3430 /* xgettext:c-format */
3431 error (_("Invalid option '-%c'\n"), c);
3432 /* Drop through. */
3433 case '?':
92f01d61 3434 usage (stderr);
252b5132
RH
3435 }
3436 }
3437
4d6ed7c8 3438 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3439 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3440 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3441 && !do_section_groups && !do_archive_index
3442 && !do_dyn_syms)
92f01d61 3443 usage (stderr);
252b5132
RH
3444 else if (argc < 3)
3445 {
3446 warn (_("Nothing to do.\n"));
92f01d61 3447 usage (stderr);
252b5132
RH
3448 }
3449}
3450
3451static const char *
d3ba0551 3452get_elf_class (unsigned int elf_class)
252b5132 3453{
b34976b6 3454 static char buff[32];
103f02d3 3455
252b5132
RH
3456 switch (elf_class)
3457 {
3458 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3459 case ELFCLASS32: return "ELF32";
3460 case ELFCLASS64: return "ELF64";
ab5e7794 3461 default:
e9e44622 3462 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3463 return buff;
252b5132
RH
3464 }
3465}
3466
3467static const char *
d3ba0551 3468get_data_encoding (unsigned int encoding)
252b5132 3469{
b34976b6 3470 static char buff[32];
103f02d3 3471
252b5132
RH
3472 switch (encoding)
3473 {
3474 case ELFDATANONE: return _("none");
33c63f9d
CM
3475 case ELFDATA2LSB: return _("2's complement, little endian");
3476 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3477 default:
e9e44622 3478 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3479 return buff;
252b5132
RH
3480 }
3481}
3482
252b5132 3483/* Decode the data held in 'elf_header'. */
ee42cf8c 3484
252b5132 3485static int
d3ba0551 3486process_file_header (void)
252b5132 3487{
b34976b6
AM
3488 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3489 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3490 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3491 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3492 {
3493 error
3494 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3495 return 0;
3496 }
3497
2dc4cec1
L
3498 init_dwarf_regnames (elf_header.e_machine);
3499
252b5132
RH
3500 if (do_header)
3501 {
3502 int i;
3503
3504 printf (_("ELF Header:\n"));
3505 printf (_(" Magic: "));
b34976b6
AM
3506 for (i = 0; i < EI_NIDENT; i++)
3507 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3508 printf ("\n");
3509 printf (_(" Class: %s\n"),
b34976b6 3510 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3511 printf (_(" Data: %s\n"),
b34976b6 3512 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3513 printf (_(" Version: %d %s\n"),
b34976b6
AM
3514 elf_header.e_ident[EI_VERSION],
3515 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3516 ? "(current)"
b34976b6 3517 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3518 ? _("<unknown: %lx>")
789be9f7 3519 : "")));
252b5132 3520 printf (_(" OS/ABI: %s\n"),
b34976b6 3521 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3522 printf (_(" ABI Version: %d\n"),
b34976b6 3523 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3524 printf (_(" Type: %s\n"),
3525 get_file_type (elf_header.e_type));
3526 printf (_(" Machine: %s\n"),
3527 get_machine_name (elf_header.e_machine));
3528 printf (_(" Version: 0x%lx\n"),
3529 (unsigned long) elf_header.e_version);
76da6bbe 3530
f7a99963
NC
3531 printf (_(" Entry point address: "));
3532 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3533 printf (_("\n Start of program headers: "));
3534 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3535 printf (_(" (bytes into file)\n Start of section headers: "));
3536 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3537 printf (_(" (bytes into file)\n"));
76da6bbe 3538
252b5132
RH
3539 printf (_(" Flags: 0x%lx%s\n"),
3540 (unsigned long) elf_header.e_flags,
3541 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3542 printf (_(" Size of this header: %ld (bytes)\n"),
3543 (long) elf_header.e_ehsize);
3544 printf (_(" Size of program headers: %ld (bytes)\n"),
3545 (long) elf_header.e_phentsize);
2046a35d 3546 printf (_(" Number of program headers: %ld"),
252b5132 3547 (long) elf_header.e_phnum);
2046a35d
AM
3548 if (section_headers != NULL
3549 && elf_header.e_phnum == PN_XNUM
3550 && section_headers[0].sh_info != 0)
3551 printf (_(" (%ld)"), (long) section_headers[0].sh_info);
3552 putc ('\n', stdout);
252b5132
RH
3553 printf (_(" Size of section headers: %ld (bytes)\n"),
3554 (long) elf_header.e_shentsize);
560f3c1c 3555 printf (_(" Number of section headers: %ld"),
252b5132 3556 (long) elf_header.e_shnum);
4fbb74a6 3557 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3558 printf (" (%ld)", (long) section_headers[0].sh_size);
3559 putc ('\n', stdout);
3560 printf (_(" Section header string table index: %ld"),
252b5132 3561 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3562 if (section_headers != NULL
3563 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3564 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3565 else if (elf_header.e_shstrndx != SHN_UNDEF
3566 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3567 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3568 putc ('\n', stdout);
3569 }
3570
3571 if (section_headers != NULL)
3572 {
2046a35d
AM
3573 if (elf_header.e_phnum == PN_XNUM
3574 && section_headers[0].sh_info != 0)
3575 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3576 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3577 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3578 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3579 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3580 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3581 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3582 free (section_headers);
3583 section_headers = NULL;
252b5132 3584 }
103f02d3 3585
9ea033b2
NC
3586 return 1;
3587}
3588
252b5132 3589
9ea033b2 3590static int
91d6fa6a 3591get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3592{
2cf0635d
NC
3593 Elf32_External_Phdr * phdrs;
3594 Elf32_External_Phdr * external;
3595 Elf_Internal_Phdr * internal;
b34976b6 3596 unsigned int i;
103f02d3 3597
3f5e193b
NC
3598 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3599 elf_header.e_phentsize,
3600 elf_header.e_phnum,
3601 _("program headers"));
a6e9f9df
AM
3602 if (!phdrs)
3603 return 0;
9ea033b2 3604
91d6fa6a 3605 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3606 i < elf_header.e_phnum;
b34976b6 3607 i++, internal++, external++)
252b5132 3608 {
9ea033b2
NC
3609 internal->p_type = BYTE_GET (external->p_type);
3610 internal->p_offset = BYTE_GET (external->p_offset);
3611 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3612 internal->p_paddr = BYTE_GET (external->p_paddr);
3613 internal->p_filesz = BYTE_GET (external->p_filesz);
3614 internal->p_memsz = BYTE_GET (external->p_memsz);
3615 internal->p_flags = BYTE_GET (external->p_flags);
3616 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3617 }
3618
9ea033b2
NC
3619 free (phdrs);
3620
252b5132
RH
3621 return 1;
3622}
3623
9ea033b2 3624static int
91d6fa6a 3625get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3626{
2cf0635d
NC
3627 Elf64_External_Phdr * phdrs;
3628 Elf64_External_Phdr * external;
3629 Elf_Internal_Phdr * internal;
b34976b6 3630 unsigned int i;
103f02d3 3631
3f5e193b
NC
3632 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3633 elf_header.e_phentsize,
3634 elf_header.e_phnum,
3635 _("program headers"));
a6e9f9df
AM
3636 if (!phdrs)
3637 return 0;
9ea033b2 3638
91d6fa6a 3639 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3640 i < elf_header.e_phnum;
b34976b6 3641 i++, internal++, external++)
9ea033b2
NC
3642 {
3643 internal->p_type = BYTE_GET (external->p_type);
3644 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3645 internal->p_offset = BYTE_GET (external->p_offset);
3646 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3647 internal->p_paddr = BYTE_GET (external->p_paddr);
3648 internal->p_filesz = BYTE_GET (external->p_filesz);
3649 internal->p_memsz = BYTE_GET (external->p_memsz);
3650 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3651 }
3652
3653 free (phdrs);
3654
3655 return 1;
3656}
252b5132 3657
d93f0186
NC
3658/* Returns 1 if the program headers were read into `program_headers'. */
3659
3660static int
2cf0635d 3661get_program_headers (FILE * file)
d93f0186 3662{
2cf0635d 3663 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3664
3665 /* Check cache of prior read. */
3666 if (program_headers != NULL)
3667 return 1;
3668
3f5e193b
NC
3669 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3670 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3671
3672 if (phdrs == NULL)
3673 {
3674 error (_("Out of memory\n"));
3675 return 0;
3676 }
3677
3678 if (is_32bit_elf
3679 ? get_32bit_program_headers (file, phdrs)
3680 : get_64bit_program_headers (file, phdrs))
3681 {
3682 program_headers = phdrs;
3683 return 1;
3684 }
3685
3686 free (phdrs);
3687 return 0;
3688}
3689
2f62977e
NC
3690/* Returns 1 if the program headers were loaded. */
3691
252b5132 3692static int
2cf0635d 3693process_program_headers (FILE * file)
252b5132 3694{
2cf0635d 3695 Elf_Internal_Phdr * segment;
b34976b6 3696 unsigned int i;
252b5132
RH
3697
3698 if (elf_header.e_phnum == 0)
3699 {
3700 if (do_segments)
3701 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3702 return 0;
252b5132
RH
3703 }
3704
3705 if (do_segments && !do_header)
3706 {
f7a99963
NC
3707 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3708 printf (_("Entry point "));
3709 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3710 printf (_("\nThere are %d program headers, starting at offset "),
3711 elf_header.e_phnum);
3712 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3713 printf ("\n");
252b5132
RH
3714 }
3715
d93f0186 3716 if (! get_program_headers (file))
252b5132 3717 return 0;
103f02d3 3718
252b5132
RH
3719 if (do_segments)
3720 {
3a1a2036
NC
3721 if (elf_header.e_phnum > 1)
3722 printf (_("\nProgram Headers:\n"));
3723 else
3724 printf (_("\nProgram Headers:\n"));
76da6bbe 3725
f7a99963
NC
3726 if (is_32bit_elf)
3727 printf
3728 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3729 else if (do_wide)
3730 printf
3731 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3732 else
3733 {
3734 printf
3735 (_(" Type Offset VirtAddr PhysAddr\n"));
3736 printf
3737 (_(" FileSiz MemSiz Flags Align\n"));
3738 }
252b5132
RH
3739 }
3740
252b5132 3741 dynamic_addr = 0;
1b228002 3742 dynamic_size = 0;
252b5132
RH
3743
3744 for (i = 0, segment = program_headers;
3745 i < elf_header.e_phnum;
b34976b6 3746 i++, segment++)
252b5132
RH
3747 {
3748 if (do_segments)
3749 {
103f02d3 3750 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3751
3752 if (is_32bit_elf)
3753 {
3754 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3755 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3756 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3757 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3758 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3759 printf ("%c%c%c ",
3760 (segment->p_flags & PF_R ? 'R' : ' '),
3761 (segment->p_flags & PF_W ? 'W' : ' '),
3762 (segment->p_flags & PF_X ? 'E' : ' '));
3763 printf ("%#lx", (unsigned long) segment->p_align);
3764 }
d974e256
JJ
3765 else if (do_wide)
3766 {
3767 if ((unsigned long) segment->p_offset == segment->p_offset)
3768 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3769 else
3770 {
3771 print_vma (segment->p_offset, FULL_HEX);
3772 putchar (' ');
3773 }
3774
3775 print_vma (segment->p_vaddr, FULL_HEX);
3776 putchar (' ');
3777 print_vma (segment->p_paddr, FULL_HEX);
3778 putchar (' ');
3779
3780 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3781 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3782 else
3783 {
3784 print_vma (segment->p_filesz, FULL_HEX);
3785 putchar (' ');
3786 }
3787
3788 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3789 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3790 else
3791 {
3792 print_vma (segment->p_offset, FULL_HEX);
3793 }
3794
3795 printf (" %c%c%c ",
3796 (segment->p_flags & PF_R ? 'R' : ' '),
3797 (segment->p_flags & PF_W ? 'W' : ' '),
3798 (segment->p_flags & PF_X ? 'E' : ' '));
3799
3800 if ((unsigned long) segment->p_align == segment->p_align)
3801 printf ("%#lx", (unsigned long) segment->p_align);
3802 else
3803 {
3804 print_vma (segment->p_align, PREFIX_HEX);
3805 }
3806 }
f7a99963
NC
3807 else
3808 {
3809 print_vma (segment->p_offset, FULL_HEX);
3810 putchar (' ');
3811 print_vma (segment->p_vaddr, FULL_HEX);
3812 putchar (' ');
3813 print_vma (segment->p_paddr, FULL_HEX);
3814 printf ("\n ");
3815 print_vma (segment->p_filesz, FULL_HEX);
3816 putchar (' ');
3817 print_vma (segment->p_memsz, FULL_HEX);
3818 printf (" %c%c%c ",
3819 (segment->p_flags & PF_R ? 'R' : ' '),
3820 (segment->p_flags & PF_W ? 'W' : ' '),
3821 (segment->p_flags & PF_X ? 'E' : ' '));
3822 print_vma (segment->p_align, HEX);
3823 }
252b5132
RH
3824 }
3825
3826 switch (segment->p_type)
3827 {
252b5132
RH
3828 case PT_DYNAMIC:
3829 if (dynamic_addr)
3830 error (_("more than one dynamic segment\n"));
3831
20737c13
AM
3832 /* By default, assume that the .dynamic section is the first
3833 section in the DYNAMIC segment. */
3834 dynamic_addr = segment->p_offset;
3835 dynamic_size = segment->p_filesz;
3836
b2d38a17
NC
3837 /* Try to locate the .dynamic section. If there is
3838 a section header table, we can easily locate it. */
3839 if (section_headers != NULL)
3840 {
2cf0635d 3841 Elf_Internal_Shdr * sec;
b2d38a17 3842
89fac5e3
RS
3843 sec = find_section (".dynamic");
3844 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3845 {
28f997cf
TG
3846 /* A corresponding .dynamic section is expected, but on
3847 IA-64/OpenVMS it is OK for it to be missing. */
3848 if (!is_ia64_vms ())
3849 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3850 break;
3851 }
3852
42bb2e33 3853 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3854 {
3855 dynamic_size = 0;
3856 break;
3857 }
42bb2e33 3858
b2d38a17
NC
3859 dynamic_addr = sec->sh_offset;
3860 dynamic_size = sec->sh_size;
3861
3862 if (dynamic_addr < segment->p_offset
3863 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3864 warn (_("the .dynamic section is not contained"
3865 " within the dynamic segment\n"));
b2d38a17 3866 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3867 warn (_("the .dynamic section is not the first section"
3868 " in the dynamic segment.\n"));
b2d38a17 3869 }
252b5132
RH
3870 break;
3871
3872 case PT_INTERP:
fb52b2f4
NC
3873 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3874 SEEK_SET))
252b5132
RH
3875 error (_("Unable to find program interpreter name\n"));
3876 else
3877 {
f8eae8b2
L
3878 char fmt [32];
3879 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3880
3881 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3882 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3883
252b5132 3884 program_interpreter[0] = 0;
7bd7b3ef
AM
3885 if (fscanf (file, fmt, program_interpreter) <= 0)
3886 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3887
3888 if (do_segments)
3889 printf (_("\n [Requesting program interpreter: %s]"),
3890 program_interpreter);
3891 }
3892 break;
3893 }
3894
3895 if (do_segments)
3896 putc ('\n', stdout);
3897 }
3898
c256ffe7 3899 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3900 {
3901 printf (_("\n Section to Segment mapping:\n"));
3902 printf (_(" Segment Sections...\n"));
3903
252b5132
RH
3904 for (i = 0; i < elf_header.e_phnum; i++)
3905 {
9ad5cbcf 3906 unsigned int j;
2cf0635d 3907 Elf_Internal_Shdr * section;
252b5132
RH
3908
3909 segment = program_headers + i;
b391a3e3 3910 section = section_headers + 1;
252b5132
RH
3911
3912 printf (" %2.2d ", i);
3913
b34976b6 3914 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3915 {
f4638467
AM
3916 if (!ELF_TBSS_SPECIAL (section, segment)
3917 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
3918 printf ("%s ", SECTION_NAME (section));
3919 }
3920
3921 putc ('\n',stdout);
3922 }
3923 }
3924
252b5132
RH
3925 return 1;
3926}
3927
3928
d93f0186
NC
3929/* Find the file offset corresponding to VMA by using the program headers. */
3930
3931static long
2cf0635d 3932offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 3933{
2cf0635d 3934 Elf_Internal_Phdr * seg;
d93f0186
NC
3935
3936 if (! get_program_headers (file))
3937 {
3938 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3939 return (long) vma;
3940 }
3941
3942 for (seg = program_headers;
3943 seg < program_headers + elf_header.e_phnum;
3944 ++seg)
3945 {
3946 if (seg->p_type != PT_LOAD)
3947 continue;
3948
3949 if (vma >= (seg->p_vaddr & -seg->p_align)
3950 && vma + size <= seg->p_vaddr + seg->p_filesz)
3951 return vma - seg->p_vaddr + seg->p_offset;
3952 }
3953
3954 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 3955 (unsigned long) vma);
d93f0186
NC
3956 return (long) vma;
3957}
3958
3959
252b5132 3960static int
2cf0635d 3961get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 3962{
2cf0635d
NC
3963 Elf32_External_Shdr * shdrs;
3964 Elf_Internal_Shdr * internal;
b34976b6 3965 unsigned int i;
252b5132 3966
3f5e193b
NC
3967 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3968 elf_header.e_shentsize, num,
3969 _("section headers"));
a6e9f9df
AM
3970 if (!shdrs)
3971 return 0;
252b5132 3972
3f5e193b
NC
3973 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3974 sizeof (Elf_Internal_Shdr));
252b5132
RH
3975
3976 if (section_headers == NULL)
3977 {
3978 error (_("Out of memory\n"));
3979 return 0;
3980 }
3981
3982 for (i = 0, internal = section_headers;
560f3c1c 3983 i < num;
b34976b6 3984 i++, internal++)
252b5132
RH
3985 {
3986 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3987 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3988 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3989 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3990 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3991 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3992 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3993 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
3994 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
3995 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
3996 }
3997
3998 free (shdrs);
3999
4000 return 1;
4001}
4002
9ea033b2 4003static int
2cf0635d 4004get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4005{
2cf0635d
NC
4006 Elf64_External_Shdr * shdrs;
4007 Elf_Internal_Shdr * internal;
b34976b6 4008 unsigned int i;
9ea033b2 4009
3f5e193b
NC
4010 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4011 elf_header.e_shentsize, num,
4012 _("section headers"));
a6e9f9df
AM
4013 if (!shdrs)
4014 return 0;
9ea033b2 4015
3f5e193b
NC
4016 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4017 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4018
4019 if (section_headers == NULL)
4020 {
4021 error (_("Out of memory\n"));
4022 return 0;
4023 }
4024
4025 for (i = 0, internal = section_headers;
560f3c1c 4026 i < num;
b34976b6 4027 i++, internal++)
9ea033b2
NC
4028 {
4029 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4030 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4031 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4032 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4033 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4034 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4035 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4036 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4037 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4038 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4039 }
4040
4041 free (shdrs);
4042
4043 return 1;
4044}
4045
252b5132 4046static Elf_Internal_Sym *
2cf0635d 4047get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
252b5132 4048{
9ad5cbcf 4049 unsigned long number;
dd24e3da 4050 Elf32_External_Sym * esyms = NULL;
2cf0635d 4051 Elf_External_Sym_Shndx * shndx;
dd24e3da 4052 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4053 Elf_Internal_Sym * psym;
b34976b6 4054 unsigned int j;
252b5132 4055
dd24e3da
NC
4056 /* Run some sanity checks first. */
4057 if (section->sh_entsize == 0)
4058 {
4059 error (_("sh_entsize is zero\n"));
4060 return NULL;
4061 }
4062
4063 number = section->sh_size / section->sh_entsize;
4064
4065 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4066 {
4067 error (_("Invalid sh_entsize\n"));
4068 return NULL;
4069 }
4070
3f5e193b
NC
4071 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4072 section->sh_size, _("symbols"));
dd24e3da 4073 if (esyms == NULL)
a6e9f9df 4074 return NULL;
252b5132 4075
9ad5cbcf
AM
4076 shndx = NULL;
4077 if (symtab_shndx_hdr != NULL
4078 && (symtab_shndx_hdr->sh_link
4fbb74a6 4079 == (unsigned long) (section - section_headers)))
9ad5cbcf 4080 {
3f5e193b
NC
4081 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4082 symtab_shndx_hdr->sh_offset,
4083 1, symtab_shndx_hdr->sh_size,
4084 _("symtab shndx"));
dd24e3da
NC
4085 if (shndx == NULL)
4086 goto exit_point;
9ad5cbcf
AM
4087 }
4088
3f5e193b 4089 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4090
4091 if (isyms == NULL)
4092 {
4093 error (_("Out of memory\n"));
dd24e3da 4094 goto exit_point;
252b5132
RH
4095 }
4096
dd24e3da 4097 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4098 {
4099 psym->st_name = BYTE_GET (esyms[j].st_name);
4100 psym->st_value = BYTE_GET (esyms[j].st_value);
4101 psym->st_size = BYTE_GET (esyms[j].st_size);
4102 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4103 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4104 psym->st_shndx
4105 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4106 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4107 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4108 psym->st_info = BYTE_GET (esyms[j].st_info);
4109 psym->st_other = BYTE_GET (esyms[j].st_other);
4110 }
4111
dd24e3da 4112 exit_point:
9ad5cbcf
AM
4113 if (shndx)
4114 free (shndx);
dd24e3da
NC
4115 if (esyms)
4116 free (esyms);
252b5132
RH
4117
4118 return isyms;
4119}
4120
9ea033b2 4121static Elf_Internal_Sym *
2cf0635d 4122get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
9ea033b2 4123{
9ad5cbcf 4124 unsigned long number;
2cf0635d
NC
4125 Elf64_External_Sym * esyms;
4126 Elf_External_Sym_Shndx * shndx;
4127 Elf_Internal_Sym * isyms;
4128 Elf_Internal_Sym * psym;
b34976b6 4129 unsigned int j;
9ea033b2 4130
dd24e3da
NC
4131 /* Run some sanity checks first. */
4132 if (section->sh_entsize == 0)
4133 {
4134 error (_("sh_entsize is zero\n"));
4135 return NULL;
4136 }
4137
4138 number = section->sh_size / section->sh_entsize;
4139
4140 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4141 {
4142 error (_("Invalid sh_entsize\n"));
4143 return NULL;
4144 }
4145
3f5e193b
NC
4146 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4147 section->sh_size, _("symbols"));
a6e9f9df
AM
4148 if (!esyms)
4149 return NULL;
9ea033b2 4150
9ad5cbcf
AM
4151 shndx = NULL;
4152 if (symtab_shndx_hdr != NULL
4153 && (symtab_shndx_hdr->sh_link
4fbb74a6 4154 == (unsigned long) (section - section_headers)))
9ad5cbcf 4155 {
3f5e193b
NC
4156 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4157 symtab_shndx_hdr->sh_offset,
4158 1, symtab_shndx_hdr->sh_size,
4159 _("symtab shndx"));
9ad5cbcf
AM
4160 if (!shndx)
4161 {
4162 free (esyms);
4163 return NULL;
4164 }
4165 }
4166
3f5e193b 4167 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4168
4169 if (isyms == NULL)
4170 {
4171 error (_("Out of memory\n"));
9ad5cbcf
AM
4172 if (shndx)
4173 free (shndx);
9ea033b2 4174 free (esyms);
9ea033b2
NC
4175 return NULL;
4176 }
4177
4178 for (j = 0, psym = isyms;
4179 j < number;
b34976b6 4180 j++, psym++)
9ea033b2
NC
4181 {
4182 psym->st_name = BYTE_GET (esyms[j].st_name);
4183 psym->st_info = BYTE_GET (esyms[j].st_info);
4184 psym->st_other = BYTE_GET (esyms[j].st_other);
4185 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4186 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4187 psym->st_shndx
4188 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4189 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4190 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
66543521
AM
4191 psym->st_value = BYTE_GET (esyms[j].st_value);
4192 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4193 }
4194
9ad5cbcf
AM
4195 if (shndx)
4196 free (shndx);
9ea033b2
NC
4197 free (esyms);
4198
4199 return isyms;
4200}
4201
d1133906 4202static const char *
d3ba0551 4203get_elf_section_flags (bfd_vma sh_flags)
d1133906 4204{
5477e8a0 4205 static char buff[1024];
2cf0635d 4206 char * p = buff;
8d5ff12c 4207 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4208 int sindex;
4209 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4210 bfd_vma os_flags = 0;
4211 bfd_vma proc_flags = 0;
4212 bfd_vma unknown_flags = 0;
148b93f2 4213 static const struct
5477e8a0 4214 {
2cf0635d 4215 const char * str;
5477e8a0
L
4216 int len;
4217 }
4218 flags [] =
4219 {
cfcac11d
NC
4220 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4221 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4222 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4223 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4224 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4225 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4226 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4227 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4228 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4229 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4230 /* IA-64 specific. */
4231 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4232 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4233 /* IA-64 OpenVMS specific. */
4234 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4235 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4236 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4237 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4238 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4239 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4240 /* Generic. */
cfcac11d 4241 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4242 /* SPARC specific. */
cfcac11d 4243 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4244 };
4245
4246 if (do_section_details)
4247 {
8d5ff12c
L
4248 sprintf (buff, "[%*.*lx]: ",
4249 field_size, field_size, (unsigned long) sh_flags);
4250 p += field_size + 4;
5477e8a0 4251 }
76da6bbe 4252
d1133906
NC
4253 while (sh_flags)
4254 {
4255 bfd_vma flag;
4256
4257 flag = sh_flags & - sh_flags;
4258 sh_flags &= ~ flag;
76da6bbe 4259
5477e8a0 4260 if (do_section_details)
d1133906 4261 {
5477e8a0
L
4262 switch (flag)
4263 {
91d6fa6a
NC
4264 case SHF_WRITE: sindex = 0; break;
4265 case SHF_ALLOC: sindex = 1; break;
4266 case SHF_EXECINSTR: sindex = 2; break;
4267 case SHF_MERGE: sindex = 3; break;
4268 case SHF_STRINGS: sindex = 4; break;
4269 case SHF_INFO_LINK: sindex = 5; break;
4270 case SHF_LINK_ORDER: sindex = 6; break;
4271 case SHF_OS_NONCONFORMING: sindex = 7; break;
4272 case SHF_GROUP: sindex = 8; break;
4273 case SHF_TLS: sindex = 9; break;
18ae9cc1 4274 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4275
5477e8a0 4276 default:
91d6fa6a 4277 sindex = -1;
cfcac11d 4278 switch (elf_header.e_machine)
148b93f2 4279 {
cfcac11d 4280 case EM_IA_64:
148b93f2 4281 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4282 sindex = 10;
148b93f2 4283 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4284 sindex = 11;
148b93f2
NC
4285#ifdef BFD64
4286 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4287 switch (flag)
4288 {
91d6fa6a
NC
4289 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4290 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4291 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4292 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4293 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4294 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4295 default: break;
4296 }
4297#endif
cfcac11d
NC
4298 break;
4299
caa83f8b
NC
4300 case EM_386:
4301 case EM_486:
4302 case EM_X86_64:
7f502d6c 4303 case EM_L1OM:
cfcac11d
NC
4304 case EM_OLD_SPARCV9:
4305 case EM_SPARC32PLUS:
4306 case EM_SPARCV9:
4307 case EM_SPARC:
18ae9cc1 4308 if (flag == SHF_ORDERED)
91d6fa6a 4309 sindex = 19;
cfcac11d
NC
4310 break;
4311 default:
4312 break;
148b93f2 4313 }
5477e8a0
L
4314 }
4315
91d6fa6a 4316 if (sindex != -1)
5477e8a0 4317 {
8d5ff12c
L
4318 if (p != buff + field_size + 4)
4319 {
4320 if (size < (10 + 2))
4321 abort ();
4322 size -= 2;
4323 *p++ = ',';
4324 *p++ = ' ';
4325 }
4326
91d6fa6a
NC
4327 size -= flags [sindex].len;
4328 p = stpcpy (p, flags [sindex].str);
5477e8a0 4329 }
3b22753a 4330 else if (flag & SHF_MASKOS)
8d5ff12c 4331 os_flags |= flag;
d1133906 4332 else if (flag & SHF_MASKPROC)
8d5ff12c 4333 proc_flags |= flag;
d1133906 4334 else
8d5ff12c 4335 unknown_flags |= flag;
5477e8a0
L
4336 }
4337 else
4338 {
4339 switch (flag)
4340 {
4341 case SHF_WRITE: *p = 'W'; break;
4342 case SHF_ALLOC: *p = 'A'; break;
4343 case SHF_EXECINSTR: *p = 'X'; break;
4344 case SHF_MERGE: *p = 'M'; break;
4345 case SHF_STRINGS: *p = 'S'; break;
4346 case SHF_INFO_LINK: *p = 'I'; break;
4347 case SHF_LINK_ORDER: *p = 'L'; break;
4348 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4349 case SHF_GROUP: *p = 'G'; break;
4350 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4351 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4352
4353 default:
8a9036a4
L
4354 if ((elf_header.e_machine == EM_X86_64
4355 || elf_header.e_machine == EM_L1OM)
5477e8a0
L
4356 && flag == SHF_X86_64_LARGE)
4357 *p = 'l';
4358 else if (flag & SHF_MASKOS)
4359 {
4360 *p = 'o';
4361 sh_flags &= ~ SHF_MASKOS;
4362 }
4363 else if (flag & SHF_MASKPROC)
4364 {
4365 *p = 'p';
4366 sh_flags &= ~ SHF_MASKPROC;
4367 }
4368 else
4369 *p = 'x';
4370 break;
4371 }
4372 p++;
d1133906
NC
4373 }
4374 }
76da6bbe 4375
8d5ff12c
L
4376 if (do_section_details)
4377 {
4378 if (os_flags)
4379 {
4380 size -= 5 + field_size;
4381 if (p != buff + field_size + 4)
4382 {
4383 if (size < (2 + 1))
4384 abort ();
4385 size -= 2;
4386 *p++ = ',';
4387 *p++ = ' ';
4388 }
4389 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4390 (unsigned long) os_flags);
4391 p += 5 + field_size;
4392 }
4393 if (proc_flags)
4394 {
4395 size -= 7 + field_size;
4396 if (p != buff + field_size + 4)
4397 {
4398 if (size < (2 + 1))
4399 abort ();
4400 size -= 2;
4401 *p++ = ',';
4402 *p++ = ' ';
4403 }
4404 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4405 (unsigned long) proc_flags);
4406 p += 7 + field_size;
4407 }
4408 if (unknown_flags)
4409 {
4410 size -= 10 + field_size;
4411 if (p != buff + field_size + 4)
4412 {
4413 if (size < (2 + 1))
4414 abort ();
4415 size -= 2;
4416 *p++ = ',';
4417 *p++ = ' ';
4418 }
2b692964 4419 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4420 (unsigned long) unknown_flags);
4421 p += 10 + field_size;
4422 }
4423 }
4424
e9e44622 4425 *p = '\0';
d1133906
NC
4426 return buff;
4427}
4428
252b5132 4429static int
2cf0635d 4430process_section_headers (FILE * file)
252b5132 4431{
2cf0635d 4432 Elf_Internal_Shdr * section;
b34976b6 4433 unsigned int i;
252b5132
RH
4434
4435 section_headers = NULL;
4436
4437 if (elf_header.e_shnum == 0)
4438 {
4439 if (do_sections)
4440 printf (_("\nThere are no sections in this file.\n"));
4441
4442 return 1;
4443 }
4444
4445 if (do_sections && !do_header)
9ea033b2 4446 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4447 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4448
9ea033b2
NC
4449 if (is_32bit_elf)
4450 {
560f3c1c 4451 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4452 return 0;
4453 }
560f3c1c 4454 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4455 return 0;
4456
4457 /* Read in the string table, so that we have names to display. */
0b49d371 4458 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4459 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4460 {
4fbb74a6 4461 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4462
c256ffe7
JJ
4463 if (section->sh_size != 0)
4464 {
3f5e193b
NC
4465 string_table = (char *) get_data (NULL, file, section->sh_offset,
4466 1, section->sh_size,
4467 _("string table"));
0de14b54 4468
c256ffe7
JJ
4469 string_table_length = string_table != NULL ? section->sh_size : 0;
4470 }
252b5132
RH
4471 }
4472
4473 /* Scan the sections for the dynamic symbol table
e3c8793a 4474 and dynamic string table and debug sections. */
252b5132
RH
4475 dynamic_symbols = NULL;
4476 dynamic_strings = NULL;
4477 dynamic_syminfo = NULL;
f1ef08cb 4478 symtab_shndx_hdr = NULL;
103f02d3 4479
89fac5e3
RS
4480 eh_addr_size = is_32bit_elf ? 4 : 8;
4481 switch (elf_header.e_machine)
4482 {
4483 case EM_MIPS:
4484 case EM_MIPS_RS3_LE:
4485 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4486 FDE addresses. However, the ABI also has a semi-official ILP32
4487 variant for which the normal FDE address size rules apply.
4488
4489 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4490 section, where XX is the size of longs in bits. Unfortunately,
4491 earlier compilers provided no way of distinguishing ILP32 objects
4492 from LP64 objects, so if there's any doubt, we should assume that
4493 the official LP64 form is being used. */
4494 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4495 && find_section (".gcc_compiled_long32") == NULL)
4496 eh_addr_size = 8;
4497 break;
0f56a26a
DD
4498
4499 case EM_H8_300:
4500 case EM_H8_300H:
4501 switch (elf_header.e_flags & EF_H8_MACH)
4502 {
4503 case E_H8_MACH_H8300:
4504 case E_H8_MACH_H8300HN:
4505 case E_H8_MACH_H8300SN:
4506 case E_H8_MACH_H8300SXN:
4507 eh_addr_size = 2;
4508 break;
4509 case E_H8_MACH_H8300H:
4510 case E_H8_MACH_H8300S:
4511 case E_H8_MACH_H8300SX:
4512 eh_addr_size = 4;
4513 break;
4514 }
f4236fe4
DD
4515 break;
4516
ff7eeb89 4517 case EM_M32C_OLD:
f4236fe4
DD
4518 case EM_M32C:
4519 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4520 {
4521 case EF_M32C_CPU_M16C:
4522 eh_addr_size = 2;
4523 break;
4524 }
4525 break;
89fac5e3
RS
4526 }
4527
08d8fa11
JJ
4528#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4529 do \
4530 { \
4531 size_t expected_entsize \
4532 = is_32bit_elf ? size32 : size64; \
4533 if (section->sh_entsize != expected_entsize) \
4534 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4535 i, (unsigned long int) section->sh_entsize, \
4536 (unsigned long int) expected_entsize); \
4537 section->sh_entsize = expected_entsize; \
4538 } \
4539 while (0)
4540#define CHECK_ENTSIZE(section, i, type) \
4541 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4542 sizeof (Elf64_External_##type))
4543
252b5132
RH
4544 for (i = 0, section = section_headers;
4545 i < elf_header.e_shnum;
b34976b6 4546 i++, section++)
252b5132 4547 {
2cf0635d 4548 char * name = SECTION_NAME (section);
252b5132
RH
4549
4550 if (section->sh_type == SHT_DYNSYM)
4551 {
4552 if (dynamic_symbols != NULL)
4553 {
4554 error (_("File contains multiple dynamic symbol tables\n"));
4555 continue;
4556 }
4557
08d8fa11 4558 CHECK_ENTSIZE (section, i, Sym);
19936277 4559 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4560 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4561 }
4562 else if (section->sh_type == SHT_STRTAB
18bd398b 4563 && streq (name, ".dynstr"))
252b5132
RH
4564 {
4565 if (dynamic_strings != NULL)
4566 {
4567 error (_("File contains multiple dynamic string tables\n"));
4568 continue;
4569 }
4570
3f5e193b
NC
4571 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4572 1, section->sh_size,
4573 _("dynamic strings"));
d79b3d50 4574 dynamic_strings_length = section->sh_size;
252b5132 4575 }
9ad5cbcf
AM
4576 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4577 {
4578 if (symtab_shndx_hdr != NULL)
4579 {
4580 error (_("File contains multiple symtab shndx tables\n"));
4581 continue;
4582 }
4583 symtab_shndx_hdr = section;
4584 }
08d8fa11
JJ
4585 else if (section->sh_type == SHT_SYMTAB)
4586 CHECK_ENTSIZE (section, i, Sym);
4587 else if (section->sh_type == SHT_GROUP)
4588 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4589 else if (section->sh_type == SHT_REL)
4590 CHECK_ENTSIZE (section, i, Rel);
4591 else if (section->sh_type == SHT_RELA)
4592 CHECK_ENTSIZE (section, i, Rela);
252b5132 4593 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4594 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4595 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4596 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4597 && (const_strneq (name, ".debug_")
4598 || const_strneq (name, ".zdebug_")))
252b5132 4599 {
1b315056
CS
4600 if (name[1] == 'z')
4601 name += sizeof (".zdebug_") - 1;
4602 else
4603 name += sizeof (".debug_") - 1;
252b5132
RH
4604
4605 if (do_debugging
18bd398b 4606 || (do_debug_info && streq (name, "info"))
2b6f5997 4607 || (do_debug_info && streq (name, "types"))
18bd398b 4608 || (do_debug_abbrevs && streq (name, "abbrev"))
4cb93e3b 4609 || (do_debug_lines && streq (name, "line"))
18bd398b 4610 || (do_debug_pubnames && streq (name, "pubnames"))
f9f0e732 4611 || (do_debug_pubtypes && streq (name, "pubtypes"))
18bd398b
NC
4612 || (do_debug_aranges && streq (name, "aranges"))
4613 || (do_debug_ranges && streq (name, "ranges"))
4614 || (do_debug_frames && streq (name, "frame"))
4615 || (do_debug_macinfo && streq (name, "macinfo"))
4616 || (do_debug_str && streq (name, "str"))
4617 || (do_debug_loc && streq (name, "loc"))
252b5132 4618 )
09c11c86 4619 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4620 }
a262ae96 4621 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4622 else if ((do_debugging || do_debug_info)
0112cd26 4623 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4624 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4625 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4626 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4627 /* Trace sections for Itanium VMS. */
4628 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4629 || do_trace_aranges)
4630 && const_strneq (name, ".trace_"))
4631 {
4632 name += sizeof (".trace_") - 1;
4633
4634 if (do_debugging
4635 || (do_trace_info && streq (name, "info"))
4636 || (do_trace_abbrevs && streq (name, "abbrev"))
4637 || (do_trace_aranges && streq (name, "aranges"))
4638 )
4639 request_dump_bynumber (i, DEBUG_DUMP);
4640 }
4641
252b5132
RH
4642 }
4643
4644 if (! do_sections)
4645 return 1;
4646
3a1a2036
NC
4647 if (elf_header.e_shnum > 1)
4648 printf (_("\nSection Headers:\n"));
4649 else
4650 printf (_("\nSection Header:\n"));
76da6bbe 4651
f7a99963 4652 if (is_32bit_elf)
595cf52e 4653 {
5477e8a0 4654 if (do_section_details)
595cf52e
L
4655 {
4656 printf (_(" [Nr] Name\n"));
5477e8a0 4657 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4658 }
4659 else
4660 printf
4661 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4662 }
d974e256 4663 else if (do_wide)
595cf52e 4664 {
5477e8a0 4665 if (do_section_details)
595cf52e
L
4666 {
4667 printf (_(" [Nr] Name\n"));
5477e8a0 4668 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4669 }
4670 else
4671 printf
4672 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4673 }
f7a99963
NC
4674 else
4675 {
5477e8a0 4676 if (do_section_details)
595cf52e
L
4677 {
4678 printf (_(" [Nr] Name\n"));
5477e8a0
L
4679 printf (_(" Type Address Offset Link\n"));
4680 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4681 }
4682 else
4683 {
4684 printf (_(" [Nr] Name Type Address Offset\n"));
4685 printf (_(" Size EntSize Flags Link Info Align\n"));
4686 }
f7a99963 4687 }
252b5132 4688
5477e8a0
L
4689 if (do_section_details)
4690 printf (_(" Flags\n"));
4691
252b5132
RH
4692 for (i = 0, section = section_headers;
4693 i < elf_header.e_shnum;
b34976b6 4694 i++, section++)
252b5132 4695 {
5477e8a0 4696 if (do_section_details)
595cf52e
L
4697 {
4698 printf (" [%2u] %s\n",
4fbb74a6 4699 i,
595cf52e
L
4700 SECTION_NAME (section));
4701 if (is_32bit_elf || do_wide)
4702 printf (" %-15.15s ",
4703 get_section_type_name (section->sh_type));
4704 }
4705 else
b9eb56c1
NC
4706 printf ((do_wide ? " [%2u] %-17s %-15s "
4707 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4708 i,
595cf52e
L
4709 SECTION_NAME (section),
4710 get_section_type_name (section->sh_type));
252b5132 4711
f7a99963
NC
4712 if (is_32bit_elf)
4713 {
cfcac11d
NC
4714 const char * link_too_big = NULL;
4715
f7a99963 4716 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4717
f7a99963
NC
4718 printf ( " %6.6lx %6.6lx %2.2lx",
4719 (unsigned long) section->sh_offset,
4720 (unsigned long) section->sh_size,
4721 (unsigned long) section->sh_entsize);
d1133906 4722
5477e8a0
L
4723 if (do_section_details)
4724 fputs (" ", stdout);
4725 else
4726 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4727
cfcac11d
NC
4728 if (section->sh_link >= elf_header.e_shnum)
4729 {
4730 link_too_big = "";
4731 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4732 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4733 switch (elf_header.e_machine)
4734 {
caa83f8b
NC
4735 case EM_386:
4736 case EM_486:
4737 case EM_X86_64:
7f502d6c 4738 case EM_L1OM:
cfcac11d
NC
4739 case EM_OLD_SPARCV9:
4740 case EM_SPARC32PLUS:
4741 case EM_SPARCV9:
4742 case EM_SPARC:
4743 if (section->sh_link == (SHN_BEFORE & 0xffff))
4744 link_too_big = "BEFORE";
4745 else if (section->sh_link == (SHN_AFTER & 0xffff))
4746 link_too_big = "AFTER";
4747 break;
4748 default:
4749 break;
4750 }
4751 }
4752
4753 if (do_section_details)
4754 {
4755 if (link_too_big != NULL && * link_too_big)
4756 printf ("<%s> ", link_too_big);
4757 else
4758 printf ("%2u ", section->sh_link);
4759 printf ("%3u %2lu\n", section->sh_info,
4760 (unsigned long) section->sh_addralign);
4761 }
4762 else
4763 printf ("%2u %3u %2lu\n",
4764 section->sh_link,
4765 section->sh_info,
4766 (unsigned long) section->sh_addralign);
4767
4768 if (link_too_big && ! * link_too_big)
4769 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4770 i, section->sh_link);
f7a99963 4771 }
d974e256
JJ
4772 else if (do_wide)
4773 {
4774 print_vma (section->sh_addr, LONG_HEX);
4775
4776 if ((long) section->sh_offset == section->sh_offset)
4777 printf (" %6.6lx", (unsigned long) section->sh_offset);
4778 else
4779 {
4780 putchar (' ');
4781 print_vma (section->sh_offset, LONG_HEX);
4782 }
4783
4784 if ((unsigned long) section->sh_size == section->sh_size)
4785 printf (" %6.6lx", (unsigned long) section->sh_size);
4786 else
4787 {
4788 putchar (' ');
4789 print_vma (section->sh_size, LONG_HEX);
4790 }
4791
4792 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4793 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4794 else
4795 {
4796 putchar (' ');
4797 print_vma (section->sh_entsize, LONG_HEX);
4798 }
4799
5477e8a0
L
4800 if (do_section_details)
4801 fputs (" ", stdout);
4802 else
4803 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4804
72de5009 4805 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4806
4807 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4808 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4809 else
4810 {
4811 print_vma (section->sh_addralign, DEC);
4812 putchar ('\n');
4813 }
4814 }
5477e8a0 4815 else if (do_section_details)
595cf52e 4816 {
5477e8a0 4817 printf (" %-15.15s ",
595cf52e 4818 get_section_type_name (section->sh_type));
595cf52e
L
4819 print_vma (section->sh_addr, LONG_HEX);
4820 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4821 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4822 else
4823 {
4824 printf (" ");
4825 print_vma (section->sh_offset, LONG_HEX);
4826 }
72de5009 4827 printf (" %u\n ", section->sh_link);
595cf52e 4828 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4829 putchar (' ');
595cf52e
L
4830 print_vma (section->sh_entsize, LONG_HEX);
4831
72de5009
AM
4832 printf (" %-16u %lu\n",
4833 section->sh_info,
595cf52e
L
4834 (unsigned long) section->sh_addralign);
4835 }
f7a99963
NC
4836 else
4837 {
4838 putchar (' ');
4839 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4840 if ((long) section->sh_offset == section->sh_offset)
4841 printf (" %8.8lx", (unsigned long) section->sh_offset);
4842 else
4843 {
4844 printf (" ");
4845 print_vma (section->sh_offset, LONG_HEX);
4846 }
f7a99963
NC
4847 printf ("\n ");
4848 print_vma (section->sh_size, LONG_HEX);
4849 printf (" ");
4850 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4851
d1133906 4852 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4853
72de5009
AM
4854 printf (" %2u %3u %lu\n",
4855 section->sh_link,
4856 section->sh_info,
f7a99963
NC
4857 (unsigned long) section->sh_addralign);
4858 }
5477e8a0
L
4859
4860 if (do_section_details)
4861 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4862 }
4863
5477e8a0 4864 if (!do_section_details)
3dbcc61d
NC
4865 {
4866 if (elf_header.e_machine == EM_X86_64
4867 || elf_header.e_machine == EM_L1OM)
4868 printf (_("Key to Flags:\n\
4869 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
4870 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
4871 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
4872 else
4873 printf (_("Key to Flags:\n\
e3c8793a 4874 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 4875 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 4876 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 4877 }
d1133906 4878
252b5132
RH
4879 return 1;
4880}
4881
f5842774
L
4882static const char *
4883get_group_flags (unsigned int flags)
4884{
4885 static char buff[32];
4886 switch (flags)
4887 {
220453ec
AM
4888 case 0:
4889 return "";
4890
f5842774 4891 case GRP_COMDAT:
220453ec 4892 return "COMDAT ";
f5842774
L
4893
4894 default:
220453ec 4895 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
4896 break;
4897 }
4898 return buff;
4899}
4900
4901static int
2cf0635d 4902process_section_groups (FILE * file)
f5842774 4903{
2cf0635d 4904 Elf_Internal_Shdr * section;
f5842774 4905 unsigned int i;
2cf0635d
NC
4906 struct group * group;
4907 Elf_Internal_Shdr * symtab_sec;
4908 Elf_Internal_Shdr * strtab_sec;
4909 Elf_Internal_Sym * symtab;
4910 char * strtab;
c256ffe7 4911 size_t strtab_size;
d1f5c6e3
L
4912
4913 /* Don't process section groups unless needed. */
4914 if (!do_unwind && !do_section_groups)
4915 return 1;
f5842774
L
4916
4917 if (elf_header.e_shnum == 0)
4918 {
4919 if (do_section_groups)
d1f5c6e3 4920 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
4921
4922 return 1;
4923 }
4924
4925 if (section_headers == NULL)
4926 {
4927 error (_("Section headers are not available!\n"));
4928 abort ();
4929 }
4930
3f5e193b
NC
4931 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
4932 sizeof (struct group *));
e4b17d5c
L
4933
4934 if (section_headers_groups == NULL)
4935 {
4936 error (_("Out of memory\n"));
4937 return 0;
4938 }
4939
f5842774 4940 /* Scan the sections for the group section. */
d1f5c6e3 4941 group_count = 0;
f5842774
L
4942 for (i = 0, section = section_headers;
4943 i < elf_header.e_shnum;
4944 i++, section++)
e4b17d5c
L
4945 if (section->sh_type == SHT_GROUP)
4946 group_count++;
4947
d1f5c6e3
L
4948 if (group_count == 0)
4949 {
4950 if (do_section_groups)
4951 printf (_("\nThere are no section groups in this file.\n"));
4952
4953 return 1;
4954 }
4955
3f5e193b 4956 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
4957
4958 if (section_groups == NULL)
4959 {
4960 error (_("Out of memory\n"));
4961 return 0;
4962 }
4963
d1f5c6e3
L
4964 symtab_sec = NULL;
4965 strtab_sec = NULL;
4966 symtab = NULL;
4967 strtab = NULL;
c256ffe7 4968 strtab_size = 0;
e4b17d5c
L
4969 for (i = 0, section = section_headers, group = section_groups;
4970 i < elf_header.e_shnum;
4971 i++, section++)
f5842774
L
4972 {
4973 if (section->sh_type == SHT_GROUP)
4974 {
2cf0635d
NC
4975 char * name = SECTION_NAME (section);
4976 char * group_name;
4977 unsigned char * start;
4978 unsigned char * indices;
f5842774 4979 unsigned int entry, j, size;
2cf0635d
NC
4980 Elf_Internal_Shdr * sec;
4981 Elf_Internal_Sym * sym;
f5842774
L
4982
4983 /* Get the symbol table. */
4fbb74a6
AM
4984 if (section->sh_link >= elf_header.e_shnum
4985 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 4986 != SHT_SYMTAB))
f5842774
L
4987 {
4988 error (_("Bad sh_link in group section `%s'\n"), name);
4989 continue;
4990 }
d1f5c6e3
L
4991
4992 if (symtab_sec != sec)
4993 {
4994 symtab_sec = sec;
4995 if (symtab)
4996 free (symtab);
4997 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4998 }
f5842774 4999
dd24e3da
NC
5000 if (symtab == NULL)
5001 {
5002 error (_("Corrupt header in group section `%s'\n"), name);
5003 continue;
5004 }
5005
f5842774
L
5006 sym = symtab + section->sh_info;
5007
5008 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5009 {
4fbb74a6
AM
5010 if (sym->st_shndx == 0
5011 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5012 {
5013 error (_("Bad sh_info in group section `%s'\n"), name);
5014 continue;
5015 }
ba2685cc 5016
4fbb74a6 5017 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5018 strtab_sec = NULL;
5019 if (strtab)
5020 free (strtab);
f5842774 5021 strtab = NULL;
c256ffe7 5022 strtab_size = 0;
f5842774
L
5023 }
5024 else
5025 {
5026 /* Get the string table. */
4fbb74a6 5027 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5028 {
5029 strtab_sec = NULL;
5030 if (strtab)
5031 free (strtab);
5032 strtab = NULL;
5033 strtab_size = 0;
5034 }
5035 else if (strtab_sec
4fbb74a6 5036 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5037 {
5038 strtab_sec = sec;
5039 if (strtab)
5040 free (strtab);
3f5e193b
NC
5041 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5042 1, strtab_sec->sh_size,
5043 _("string table"));
c256ffe7 5044 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5045 }
c256ffe7 5046 group_name = sym->st_name < strtab_size
2b692964 5047 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5048 }
5049
3f5e193b
NC
5050 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5051 1, section->sh_size,
5052 _("section data"));
f5842774
L
5053
5054 indices = start;
5055 size = (section->sh_size / section->sh_entsize) - 1;
5056 entry = byte_get (indices, 4);
5057 indices += 4;
e4b17d5c
L
5058
5059 if (do_section_groups)
5060 {
2b692964 5061 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5062 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5063
e4b17d5c
L
5064 printf (_(" [Index] Name\n"));
5065 }
5066
5067 group->group_index = i;
5068
f5842774
L
5069 for (j = 0; j < size; j++)
5070 {
2cf0635d 5071 struct group_list * g;
e4b17d5c 5072
f5842774
L
5073 entry = byte_get (indices, 4);
5074 indices += 4;
5075
4fbb74a6 5076 if (entry >= elf_header.e_shnum)
391cb864
L
5077 {
5078 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5079 entry, i, elf_header.e_shnum - 1);
5080 continue;
5081 }
391cb864 5082
4fbb74a6 5083 if (section_headers_groups [entry] != NULL)
e4b17d5c 5084 {
d1f5c6e3
L
5085 if (entry)
5086 {
391cb864
L
5087 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5088 entry, i,
4fbb74a6 5089 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5090 continue;
5091 }
5092 else
5093 {
5094 /* Intel C/C++ compiler may put section 0 in a
5095 section group. We just warn it the first time
5096 and ignore it afterwards. */
5097 static int warned = 0;
5098 if (!warned)
5099 {
5100 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5101 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5102 warned++;
5103 }
5104 }
e4b17d5c
L
5105 }
5106
4fbb74a6 5107 section_headers_groups [entry] = group;
e4b17d5c
L
5108
5109 if (do_section_groups)
5110 {
4fbb74a6 5111 sec = section_headers + entry;
c256ffe7 5112 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5113 }
5114
3f5e193b 5115 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5116 g->section_index = entry;
5117 g->next = group->root;
5118 group->root = g;
f5842774
L
5119 }
5120
f5842774
L
5121 if (start)
5122 free (start);
e4b17d5c
L
5123
5124 group++;
f5842774
L
5125 }
5126 }
5127
d1f5c6e3
L
5128 if (symtab)
5129 free (symtab);
5130 if (strtab)
5131 free (strtab);
f5842774
L
5132 return 1;
5133}
5134
28f997cf
TG
5135/* Data used to display dynamic fixups. */
5136
5137struct ia64_vms_dynfixup
5138{
5139 bfd_vma needed_ident; /* Library ident number. */
5140 bfd_vma needed; /* Index in the dstrtab of the library name. */
5141 bfd_vma fixup_needed; /* Index of the library. */
5142 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5143 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5144};
5145
5146/* Data used to display dynamic relocations. */
5147
5148struct ia64_vms_dynimgrela
5149{
5150 bfd_vma img_rela_cnt; /* Number of relocations. */
5151 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5152};
5153
5154/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5155 library). */
5156
5157static void
5158dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5159 const char *strtab, unsigned int strtab_sz)
5160{
5161 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5162 long i;
5163 const char *lib_name;
5164
5165 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5166 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5167 _("dynamic section image fixups"));
5168 if (!imfs)
5169 return;
5170
5171 if (fixup->needed < strtab_sz)
5172 lib_name = strtab + fixup->needed;
5173 else
5174 {
5175 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5176 (unsigned long) fixup->needed);
28f997cf
TG
5177 lib_name = "???";
5178 }
5179 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5180 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5181 printf
5182 (_("Seg Offset Type SymVec DataType\n"));
5183
5184 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5185 {
5186 unsigned int type;
5187 const char *rtype;
5188
5189 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5190 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5191 type = BYTE_GET (imfs [i].type);
5192 rtype = elf_ia64_reloc_type (type);
5193 if (rtype == NULL)
5194 printf (" 0x%08x ", type);
5195 else
5196 printf (" %-32s ", rtype);
5197 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5198 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5199 }
5200
5201 free (imfs);
5202}
5203
5204/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5205
5206static void
5207dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5208{
5209 Elf64_External_VMS_IMAGE_RELA *imrs;
5210 long i;
5211
5212 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5213 1, imgrela->img_rela_cnt * sizeof (*imrs),
5214 _("dynamic section image relas"));
5215 if (!imrs)
5216 return;
5217
5218 printf (_("\nImage relocs\n"));
5219 printf
5220 (_("Seg Offset Type Addend Seg Sym Off\n"));
5221
5222 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5223 {
5224 unsigned int type;
5225 const char *rtype;
5226
5227 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5228 printf ("%08" BFD_VMA_FMT "x ",
5229 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5230 type = BYTE_GET (imrs [i].type);
5231 rtype = elf_ia64_reloc_type (type);
5232 if (rtype == NULL)
5233 printf ("0x%08x ", type);
5234 else
5235 printf ("%-31s ", rtype);
5236 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5237 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5238 printf ("%08" BFD_VMA_FMT "x\n",
5239 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5240 }
5241
5242 free (imrs);
5243}
5244
5245/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5246
5247static int
5248process_ia64_vms_dynamic_relocs (FILE *file)
5249{
5250 struct ia64_vms_dynfixup fixup;
5251 struct ia64_vms_dynimgrela imgrela;
5252 Elf_Internal_Dyn *entry;
5253 int res = 0;
5254 bfd_vma strtab_off = 0;
5255 bfd_vma strtab_sz = 0;
5256 char *strtab = NULL;
5257
5258 memset (&fixup, 0, sizeof (fixup));
5259 memset (&imgrela, 0, sizeof (imgrela));
5260
5261 /* Note: the order of the entries is specified by the OpenVMS specs. */
5262 for (entry = dynamic_section;
5263 entry < dynamic_section + dynamic_nent;
5264 entry++)
5265 {
5266 switch (entry->d_tag)
5267 {
5268 case DT_IA_64_VMS_STRTAB_OFFSET:
5269 strtab_off = entry->d_un.d_val;
5270 break;
5271 case DT_STRSZ:
5272 strtab_sz = entry->d_un.d_val;
5273 if (strtab == NULL)
5274 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5275 1, strtab_sz, _("dynamic string section"));
5276 break;
5277
5278 case DT_IA_64_VMS_NEEDED_IDENT:
5279 fixup.needed_ident = entry->d_un.d_val;
5280 break;
5281 case DT_NEEDED:
5282 fixup.needed = entry->d_un.d_val;
5283 break;
5284 case DT_IA_64_VMS_FIXUP_NEEDED:
5285 fixup.fixup_needed = entry->d_un.d_val;
5286 break;
5287 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5288 fixup.fixup_rela_cnt = entry->d_un.d_val;
5289 break;
5290 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5291 fixup.fixup_rela_off = entry->d_un.d_val;
5292 res++;
5293 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5294 break;
5295
5296 case DT_IA_64_VMS_IMG_RELA_CNT:
5297 imgrela.img_rela_cnt = entry->d_un.d_val;
5298 break;
5299 case DT_IA_64_VMS_IMG_RELA_OFF:
5300 imgrela.img_rela_off = entry->d_un.d_val;
5301 res++;
5302 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5303 break;
5304
5305 default:
5306 break;
5307 }
5308 }
5309
5310 if (strtab != NULL)
5311 free (strtab);
5312
5313 return res;
5314}
5315
85b1c36d 5316static struct
566b0d53 5317{
2cf0635d 5318 const char * name;
566b0d53
L
5319 int reloc;
5320 int size;
5321 int rela;
5322} dynamic_relocations [] =
5323{
5324 { "REL", DT_REL, DT_RELSZ, FALSE },
5325 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5326 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5327};
5328
252b5132 5329/* Process the reloc section. */
18bd398b 5330
252b5132 5331static int
2cf0635d 5332process_relocs (FILE * file)
252b5132 5333{
b34976b6
AM
5334 unsigned long rel_size;
5335 unsigned long rel_offset;
252b5132
RH
5336
5337
5338 if (!do_reloc)
5339 return 1;
5340
5341 if (do_using_dynamic)
5342 {
566b0d53 5343 int is_rela;
2cf0635d 5344 const char * name;
566b0d53
L
5345 int has_dynamic_reloc;
5346 unsigned int i;
0de14b54 5347
566b0d53 5348 has_dynamic_reloc = 0;
252b5132 5349
566b0d53 5350 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5351 {
566b0d53
L
5352 is_rela = dynamic_relocations [i].rela;
5353 name = dynamic_relocations [i].name;
5354 rel_size = dynamic_info [dynamic_relocations [i].size];
5355 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5356
566b0d53
L
5357 has_dynamic_reloc |= rel_size;
5358
5359 if (is_rela == UNKNOWN)
aa903cfb 5360 {
566b0d53
L
5361 if (dynamic_relocations [i].reloc == DT_JMPREL)
5362 switch (dynamic_info[DT_PLTREL])
5363 {
5364 case DT_REL:
5365 is_rela = FALSE;
5366 break;
5367 case DT_RELA:
5368 is_rela = TRUE;
5369 break;
5370 }
aa903cfb 5371 }
252b5132 5372
566b0d53
L
5373 if (rel_size)
5374 {
5375 printf
5376 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5377 name, rel_offset, rel_size);
252b5132 5378
d93f0186
NC
5379 dump_relocations (file,
5380 offset_from_vma (file, rel_offset, rel_size),
5381 rel_size,
566b0d53 5382 dynamic_symbols, num_dynamic_syms,
d79b3d50 5383 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5384 }
252b5132 5385 }
566b0d53 5386
28f997cf
TG
5387 if (is_ia64_vms ())
5388 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5389
566b0d53 5390 if (! has_dynamic_reloc)
252b5132
RH
5391 printf (_("\nThere are no dynamic relocations in this file.\n"));
5392 }
5393 else
5394 {
2cf0635d 5395 Elf_Internal_Shdr * section;
b34976b6
AM
5396 unsigned long i;
5397 int found = 0;
252b5132
RH
5398
5399 for (i = 0, section = section_headers;
5400 i < elf_header.e_shnum;
b34976b6 5401 i++, section++)
252b5132
RH
5402 {
5403 if ( section->sh_type != SHT_RELA
5404 && section->sh_type != SHT_REL)
5405 continue;
5406
5407 rel_offset = section->sh_offset;
5408 rel_size = section->sh_size;
5409
5410 if (rel_size)
5411 {
2cf0635d 5412 Elf_Internal_Shdr * strsec;
b34976b6 5413 int is_rela;
103f02d3 5414
252b5132
RH
5415 printf (_("\nRelocation section "));
5416
5417 if (string_table == NULL)
19936277 5418 printf ("%d", section->sh_name);
252b5132 5419 else
3a1a2036 5420 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
5421
5422 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5423 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5424
d79b3d50
NC
5425 is_rela = section->sh_type == SHT_RELA;
5426
4fbb74a6
AM
5427 if (section->sh_link != 0
5428 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5429 {
2cf0635d
NC
5430 Elf_Internal_Shdr * symsec;
5431 Elf_Internal_Sym * symtab;
d79b3d50 5432 unsigned long nsyms;
c256ffe7 5433 unsigned long strtablen = 0;
2cf0635d 5434 char * strtab = NULL;
57346661 5435
4fbb74a6 5436 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5437 if (symsec->sh_type != SHT_SYMTAB
5438 && symsec->sh_type != SHT_DYNSYM)
5439 continue;
5440
af3fc3bc 5441 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 5442 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 5443
af3fc3bc
AM
5444 if (symtab == NULL)
5445 continue;
252b5132 5446
4fbb74a6
AM
5447 if (symsec->sh_link != 0
5448 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5449 {
4fbb74a6 5450 strsec = section_headers + symsec->sh_link;
103f02d3 5451
3f5e193b
NC
5452 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5453 1, strsec->sh_size,
5454 _("string table"));
c256ffe7
JJ
5455 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5456 }
252b5132 5457
d79b3d50
NC
5458 dump_relocations (file, rel_offset, rel_size,
5459 symtab, nsyms, strtab, strtablen, is_rela);
5460 if (strtab)
5461 free (strtab);
5462 free (symtab);
5463 }
5464 else
5465 dump_relocations (file, rel_offset, rel_size,
5466 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5467
5468 found = 1;
5469 }
5470 }
5471
5472 if (! found)
5473 printf (_("\nThere are no relocations in this file.\n"));
5474 }
5475
5476 return 1;
5477}
5478
57346661
AM
5479/* Process the unwind section. */
5480
4d6ed7c8
NC
5481#include "unwind-ia64.h"
5482
5483/* An absolute address consists of a section and an offset. If the
5484 section is NULL, the offset itself is the address, otherwise, the
5485 address equals to LOAD_ADDRESS(section) + offset. */
5486
5487struct absaddr
5488 {
5489 unsigned short section;
5490 bfd_vma offset;
5491 };
5492
1949de15
L
5493#define ABSADDR(a) \
5494 ((a).section \
5495 ? section_headers [(a).section].sh_addr + (a).offset \
5496 : (a).offset)
5497
3f5e193b
NC
5498struct ia64_unw_table_entry
5499 {
5500 struct absaddr start;
5501 struct absaddr end;
5502 struct absaddr info;
5503 };
5504
57346661 5505struct ia64_unw_aux_info
4d6ed7c8 5506 {
3f5e193b
NC
5507
5508 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5509 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5510 unsigned char * info; /* Unwind info. */
b34976b6
AM
5511 unsigned long info_size; /* Size of unwind info. */
5512 bfd_vma info_addr; /* starting address of unwind info. */
5513 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5514 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5515 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5516 char * strtab; /* The string table. */
b34976b6 5517 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5518 };
5519
4d6ed7c8 5520static void
2cf0635d 5521find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5522 unsigned long nsyms,
2cf0635d 5523 const char * strtab,
57346661 5524 unsigned long strtab_size,
d3ba0551 5525 struct absaddr addr,
2cf0635d
NC
5526 const char ** symname,
5527 bfd_vma * offset)
4d6ed7c8 5528{
d3ba0551 5529 bfd_vma dist = 0x100000;
2cf0635d
NC
5530 Elf_Internal_Sym * sym;
5531 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5532 unsigned long i;
5533
0b6ae522
DJ
5534 REMOVE_ARCH_BITS (addr.offset);
5535
57346661 5536 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5537 {
0b6ae522
DJ
5538 bfd_vma value = sym->st_value;
5539
5540 REMOVE_ARCH_BITS (value);
5541
4d6ed7c8
NC
5542 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5543 && sym->st_name != 0
5544 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5545 && addr.offset >= value
5546 && addr.offset - value < dist)
4d6ed7c8
NC
5547 {
5548 best = sym;
0b6ae522 5549 dist = addr.offset - value;
4d6ed7c8
NC
5550 if (!dist)
5551 break;
5552 }
5553 }
5554 if (best)
5555 {
57346661 5556 *symname = (best->st_name >= strtab_size
2b692964 5557 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5558 *offset = dist;
5559 return;
5560 }
5561 *symname = NULL;
5562 *offset = addr.offset;
5563}
5564
5565static void
2cf0635d 5566dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5567{
2cf0635d 5568 struct ia64_unw_table_entry * tp;
4d6ed7c8 5569 int in_body;
7036c0e1 5570
4d6ed7c8
NC
5571 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5572 {
5573 bfd_vma stamp;
5574 bfd_vma offset;
2cf0635d
NC
5575 const unsigned char * dp;
5576 const unsigned char * head;
5577 const char * procname;
4d6ed7c8 5578
57346661
AM
5579 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5580 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5581
5582 fputs ("\n<", stdout);
5583
5584 if (procname)
5585 {
5586 fputs (procname, stdout);
5587
5588 if (offset)
5589 printf ("+%lx", (unsigned long) offset);
5590 }
5591
5592 fputs (">: [", stdout);
5593 print_vma (tp->start.offset, PREFIX_HEX);
5594 fputc ('-', stdout);
5595 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5596 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5597 (unsigned long) (tp->info.offset - aux->seg_base));
5598
1949de15 5599 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5600 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5601
86f55779 5602 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5603 (unsigned) UNW_VER (stamp),
5604 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5605 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5606 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5607 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5608
5609 if (UNW_VER (stamp) != 1)
5610 {
2b692964 5611 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5612 continue;
5613 }
5614
5615 in_body = 0;
89fac5e3 5616 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5617 dp = unw_decode (dp, in_body, & in_body);
5618 }
5619}
5620
5621static int
2cf0635d
NC
5622slurp_ia64_unwind_table (FILE * file,
5623 struct ia64_unw_aux_info * aux,
5624 Elf_Internal_Shdr * sec)
4d6ed7c8 5625{
89fac5e3 5626 unsigned long size, nrelas, i;
2cf0635d
NC
5627 Elf_Internal_Phdr * seg;
5628 struct ia64_unw_table_entry * tep;
5629 Elf_Internal_Shdr * relsec;
5630 Elf_Internal_Rela * rela;
5631 Elf_Internal_Rela * rp;
5632 unsigned char * table;
5633 unsigned char * tp;
5634 Elf_Internal_Sym * sym;
5635 const char * relname;
4d6ed7c8 5636
4d6ed7c8
NC
5637 /* First, find the starting address of the segment that includes
5638 this section: */
5639
5640 if (elf_header.e_phnum)
5641 {
d93f0186 5642 if (! get_program_headers (file))
4d6ed7c8 5643 return 0;
4d6ed7c8 5644
d93f0186
NC
5645 for (seg = program_headers;
5646 seg < program_headers + elf_header.e_phnum;
5647 ++seg)
4d6ed7c8
NC
5648 {
5649 if (seg->p_type != PT_LOAD)
5650 continue;
5651
5652 if (sec->sh_addr >= seg->p_vaddr
5653 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5654 {
5655 aux->seg_base = seg->p_vaddr;
5656 break;
5657 }
5658 }
4d6ed7c8
NC
5659 }
5660
5661 /* Second, build the unwind table from the contents of the unwind section: */
5662 size = sec->sh_size;
3f5e193b
NC
5663 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5664 _("unwind table"));
a6e9f9df
AM
5665 if (!table)
5666 return 0;
4d6ed7c8 5667
3f5e193b
NC
5668 aux->table = (struct ia64_unw_table_entry *)
5669 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5670 tep = aux->table;
c6a0c689 5671 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5672 {
5673 tep->start.section = SHN_UNDEF;
5674 tep->end.section = SHN_UNDEF;
5675 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5676 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5677 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5678 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5679 tep->start.offset += aux->seg_base;
5680 tep->end.offset += aux->seg_base;
5681 tep->info.offset += aux->seg_base;
5682 }
5683 free (table);
5684
41e92641 5685 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5686 for (relsec = section_headers;
5687 relsec < section_headers + elf_header.e_shnum;
5688 ++relsec)
5689 {
5690 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5691 || relsec->sh_info >= elf_header.e_shnum
5692 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5693 continue;
5694
5695 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5696 & rela, & nrelas))
5697 return 0;
5698
5699 for (rp = rela; rp < rela + nrelas; ++rp)
5700 {
aca88567
NC
5701 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5702 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5703
0112cd26 5704 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5705 {
e5fb9629 5706 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5707 continue;
5708 }
5709
89fac5e3 5710 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5711
89fac5e3 5712 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5713 {
5714 case 0:
5715 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5716 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5717 break;
5718 case 1:
5719 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5720 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5721 break;
5722 case 2:
5723 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5724 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5725 break;
5726 default:
5727 break;
5728 }
5729 }
5730
5731 free (rela);
5732 }
5733
89fac5e3 5734 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5735 return 1;
5736}
5737
5738static int
2cf0635d 5739ia64_process_unwind (FILE * file)
4d6ed7c8 5740{
2cf0635d
NC
5741 Elf_Internal_Shdr * sec;
5742 Elf_Internal_Shdr * unwsec = NULL;
5743 Elf_Internal_Shdr * strsec;
89fac5e3 5744 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5745 struct ia64_unw_aux_info aux;
f1467e33 5746
4d6ed7c8
NC
5747 memset (& aux, 0, sizeof (aux));
5748
4d6ed7c8
NC
5749 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5750 {
c256ffe7 5751 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5752 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5753 {
5754 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5755 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5756
4fbb74a6 5757 strsec = section_headers + sec->sh_link;
3f5e193b
NC
5758 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5759 1, strsec->sh_size,
5760 _("string table"));
c256ffe7 5761 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5762 }
5763 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5764 unwcount++;
5765 }
5766
5767 if (!unwcount)
5768 printf (_("\nThere are no unwind sections in this file.\n"));
5769
5770 while (unwcount-- > 0)
5771 {
2cf0635d 5772 char * suffix;
579f31ac
JJ
5773 size_t len, len2;
5774
5775 for (i = unwstart, sec = section_headers + unwstart;
5776 i < elf_header.e_shnum; ++i, ++sec)
5777 if (sec->sh_type == SHT_IA_64_UNWIND)
5778 {
5779 unwsec = sec;
5780 break;
5781 }
5782
5783 unwstart = i + 1;
5784 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5785
e4b17d5c
L
5786 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5787 {
5788 /* We need to find which section group it is in. */
2cf0635d 5789 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5790
5791 for (; g != NULL; g = g->next)
5792 {
4fbb74a6 5793 sec = section_headers + g->section_index;
18bd398b
NC
5794
5795 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5796 break;
e4b17d5c
L
5797 }
5798
5799 if (g == NULL)
5800 i = elf_header.e_shnum;
5801 }
18bd398b 5802 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5803 {
18bd398b 5804 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5805 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5806 suffix = SECTION_NAME (unwsec) + len;
5807 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5808 ++i, ++sec)
18bd398b
NC
5809 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5810 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5811 break;
5812 }
5813 else
5814 {
5815 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5816 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5817 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5818 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5819 suffix = "";
18bd398b 5820 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5821 suffix = SECTION_NAME (unwsec) + len;
5822 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5823 ++i, ++sec)
18bd398b
NC
5824 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5825 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5826 break;
5827 }
5828
5829 if (i == elf_header.e_shnum)
5830 {
5831 printf (_("\nCould not find unwind info section for "));
5832
5833 if (string_table == NULL)
5834 printf ("%d", unwsec->sh_name);
5835 else
3a1a2036 5836 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5837 }
5838 else
4d6ed7c8
NC
5839 {
5840 aux.info_size = sec->sh_size;
5841 aux.info_addr = sec->sh_addr;
3f5e193b
NC
5842 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
5843 aux.info_size,
5844 _("unwind info"));
4d6ed7c8 5845
579f31ac 5846 printf (_("\nUnwind section "));
4d6ed7c8 5847
579f31ac
JJ
5848 if (string_table == NULL)
5849 printf ("%d", unwsec->sh_name);
5850 else
3a1a2036 5851 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5852
579f31ac 5853 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5854 (unsigned long) unwsec->sh_offset,
89fac5e3 5855 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5856
579f31ac 5857 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5858
579f31ac
JJ
5859 if (aux.table_len > 0)
5860 dump_ia64_unwind (& aux);
5861
5862 if (aux.table)
5863 free ((char *) aux.table);
5864 if (aux.info)
5865 free ((char *) aux.info);
5866 aux.table = NULL;
5867 aux.info = NULL;
5868 }
4d6ed7c8 5869 }
4d6ed7c8 5870
4d6ed7c8
NC
5871 if (aux.symtab)
5872 free (aux.symtab);
5873 if (aux.strtab)
5874 free ((char *) aux.strtab);
5875
5876 return 1;
5877}
5878
3f5e193b
NC
5879struct hppa_unw_table_entry
5880 {
5881 struct absaddr start;
5882 struct absaddr end;
5883 unsigned int Cannot_unwind:1; /* 0 */
5884 unsigned int Millicode:1; /* 1 */
5885 unsigned int Millicode_save_sr0:1; /* 2 */
5886 unsigned int Region_description:2; /* 3..4 */
5887 unsigned int reserved1:1; /* 5 */
5888 unsigned int Entry_SR:1; /* 6 */
5889 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5890 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5891 unsigned int Args_stored:1; /* 16 */
5892 unsigned int Variable_Frame:1; /* 17 */
5893 unsigned int Separate_Package_Body:1; /* 18 */
5894 unsigned int Frame_Extension_Millicode:1; /* 19 */
5895 unsigned int Stack_Overflow_Check:1; /* 20 */
5896 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5897 unsigned int Ada_Region:1; /* 22 */
5898 unsigned int cxx_info:1; /* 23 */
5899 unsigned int cxx_try_catch:1; /* 24 */
5900 unsigned int sched_entry_seq:1; /* 25 */
5901 unsigned int reserved2:1; /* 26 */
5902 unsigned int Save_SP:1; /* 27 */
5903 unsigned int Save_RP:1; /* 28 */
5904 unsigned int Save_MRP_in_frame:1; /* 29 */
5905 unsigned int extn_ptr_defined:1; /* 30 */
5906 unsigned int Cleanup_defined:1; /* 31 */
5907
5908 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5909 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5910 unsigned int Large_frame:1; /* 2 */
5911 unsigned int Pseudo_SP_Set:1; /* 3 */
5912 unsigned int reserved4:1; /* 4 */
5913 unsigned int Total_frame_size:27; /* 5..31 */
5914 };
5915
57346661
AM
5916struct hppa_unw_aux_info
5917 {
3f5e193b 5918 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
5919 unsigned long table_len; /* Length of unwind table. */
5920 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5921 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5922 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5923 char * strtab; /* The string table. */
57346661
AM
5924 unsigned long strtab_size; /* Size of string table. */
5925 };
5926
5927static void
2cf0635d 5928dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5929{
2cf0635d 5930 struct hppa_unw_table_entry * tp;
57346661 5931
57346661
AM
5932 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5933 {
5934 bfd_vma offset;
2cf0635d 5935 const char * procname;
57346661
AM
5936
5937 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5938 aux->strtab_size, tp->start, &procname,
5939 &offset);
5940
5941 fputs ("\n<", stdout);
5942
5943 if (procname)
5944 {
5945 fputs (procname, stdout);
5946
5947 if (offset)
5948 printf ("+%lx", (unsigned long) offset);
5949 }
5950
5951 fputs (">: [", stdout);
5952 print_vma (tp->start.offset, PREFIX_HEX);
5953 fputc ('-', stdout);
5954 print_vma (tp->end.offset, PREFIX_HEX);
5955 printf ("]\n\t");
5956
18bd398b
NC
5957#define PF(_m) if (tp->_m) printf (#_m " ");
5958#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5959 PF(Cannot_unwind);
5960 PF(Millicode);
5961 PF(Millicode_save_sr0);
18bd398b 5962 /* PV(Region_description); */
57346661
AM
5963 PF(Entry_SR);
5964 PV(Entry_FR);
5965 PV(Entry_GR);
5966 PF(Args_stored);
5967 PF(Variable_Frame);
5968 PF(Separate_Package_Body);
5969 PF(Frame_Extension_Millicode);
5970 PF(Stack_Overflow_Check);
5971 PF(Two_Instruction_SP_Increment);
5972 PF(Ada_Region);
5973 PF(cxx_info);
5974 PF(cxx_try_catch);
5975 PF(sched_entry_seq);
5976 PF(Save_SP);
5977 PF(Save_RP);
5978 PF(Save_MRP_in_frame);
5979 PF(extn_ptr_defined);
5980 PF(Cleanup_defined);
5981 PF(MPE_XL_interrupt_marker);
5982 PF(HP_UX_interrupt_marker);
5983 PF(Large_frame);
5984 PF(Pseudo_SP_Set);
5985 PV(Total_frame_size);
5986#undef PF
5987#undef PV
5988 }
5989
18bd398b 5990 printf ("\n");
57346661
AM
5991}
5992
5993static int
2cf0635d
NC
5994slurp_hppa_unwind_table (FILE * file,
5995 struct hppa_unw_aux_info * aux,
5996 Elf_Internal_Shdr * sec)
57346661 5997{
1c0751b2 5998 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
5999 Elf_Internal_Phdr * seg;
6000 struct hppa_unw_table_entry * tep;
6001 Elf_Internal_Shdr * relsec;
6002 Elf_Internal_Rela * rela;
6003 Elf_Internal_Rela * rp;
6004 unsigned char * table;
6005 unsigned char * tp;
6006 Elf_Internal_Sym * sym;
6007 const char * relname;
57346661 6008
57346661
AM
6009 /* First, find the starting address of the segment that includes
6010 this section. */
6011
6012 if (elf_header.e_phnum)
6013 {
6014 if (! get_program_headers (file))
6015 return 0;
6016
6017 for (seg = program_headers;
6018 seg < program_headers + elf_header.e_phnum;
6019 ++seg)
6020 {
6021 if (seg->p_type != PT_LOAD)
6022 continue;
6023
6024 if (sec->sh_addr >= seg->p_vaddr
6025 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6026 {
6027 aux->seg_base = seg->p_vaddr;
6028 break;
6029 }
6030 }
6031 }
6032
6033 /* Second, build the unwind table from the contents of the unwind
6034 section. */
6035 size = sec->sh_size;
3f5e193b
NC
6036 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6037 _("unwind table"));
57346661
AM
6038 if (!table)
6039 return 0;
6040
1c0751b2
DA
6041 unw_ent_size = 16;
6042 nentries = size / unw_ent_size;
6043 size = unw_ent_size * nentries;
57346661 6044
3f5e193b
NC
6045 tep = aux->table = (struct hppa_unw_table_entry *)
6046 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6047
1c0751b2 6048 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6049 {
6050 unsigned int tmp1, tmp2;
6051
6052 tep->start.section = SHN_UNDEF;
6053 tep->end.section = SHN_UNDEF;
6054
1c0751b2
DA
6055 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6056 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6057 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6058 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6059
6060 tep->start.offset += aux->seg_base;
6061 tep->end.offset += aux->seg_base;
57346661
AM
6062
6063 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6064 tep->Millicode = (tmp1 >> 30) & 0x1;
6065 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6066 tep->Region_description = (tmp1 >> 27) & 0x3;
6067 tep->reserved1 = (tmp1 >> 26) & 0x1;
6068 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6069 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6070 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6071 tep->Args_stored = (tmp1 >> 15) & 0x1;
6072 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6073 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6074 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6075 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6076 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6077 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6078 tep->cxx_info = (tmp1 >> 8) & 0x1;
6079 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6080 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6081 tep->reserved2 = (tmp1 >> 5) & 0x1;
6082 tep->Save_SP = (tmp1 >> 4) & 0x1;
6083 tep->Save_RP = (tmp1 >> 3) & 0x1;
6084 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6085 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6086 tep->Cleanup_defined = tmp1 & 0x1;
6087
6088 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6089 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6090 tep->Large_frame = (tmp2 >> 29) & 0x1;
6091 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6092 tep->reserved4 = (tmp2 >> 27) & 0x1;
6093 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6094 }
6095 free (table);
6096
6097 /* Third, apply any relocations to the unwind table. */
57346661
AM
6098 for (relsec = section_headers;
6099 relsec < section_headers + elf_header.e_shnum;
6100 ++relsec)
6101 {
6102 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6103 || relsec->sh_info >= elf_header.e_shnum
6104 || section_headers + relsec->sh_info != sec)
57346661
AM
6105 continue;
6106
6107 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6108 & rela, & nrelas))
6109 return 0;
6110
6111 for (rp = rela; rp < rela + nrelas; ++rp)
6112 {
aca88567
NC
6113 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6114 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6115
6116 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6117 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6118 {
6119 warn (_("Skipping unexpected relocation type %s\n"), relname);
6120 continue;
6121 }
6122
6123 i = rp->r_offset / unw_ent_size;
6124
89fac5e3 6125 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6126 {
6127 case 0:
6128 aux->table[i].start.section = sym->st_shndx;
1e456d54 6129 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6130 break;
6131 case 1:
6132 aux->table[i].end.section = sym->st_shndx;
1e456d54 6133 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6134 break;
6135 default:
6136 break;
6137 }
6138 }
6139
6140 free (rela);
6141 }
6142
1c0751b2 6143 aux->table_len = nentries;
57346661
AM
6144
6145 return 1;
6146}
6147
6148static int
2cf0635d 6149hppa_process_unwind (FILE * file)
57346661 6150{
57346661 6151 struct hppa_unw_aux_info aux;
2cf0635d
NC
6152 Elf_Internal_Shdr * unwsec = NULL;
6153 Elf_Internal_Shdr * strsec;
6154 Elf_Internal_Shdr * sec;
18bd398b 6155 unsigned long i;
57346661
AM
6156
6157 memset (& aux, 0, sizeof (aux));
6158
c256ffe7
JJ
6159 if (string_table == NULL)
6160 return 1;
57346661
AM
6161
6162 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6163 {
c256ffe7 6164 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6165 && sec->sh_link < elf_header.e_shnum)
57346661
AM
6166 {
6167 aux.nsyms = sec->sh_size / sec->sh_entsize;
6168 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6169
4fbb74a6 6170 strsec = section_headers + sec->sh_link;
3f5e193b
NC
6171 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6172 1, strsec->sh_size,
6173 _("string table"));
c256ffe7 6174 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6175 }
18bd398b 6176 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6177 unwsec = sec;
6178 }
6179
6180 if (!unwsec)
6181 printf (_("\nThere are no unwind sections in this file.\n"));
6182
6183 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6184 {
18bd398b 6185 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6186 {
57346661
AM
6187 printf (_("\nUnwind section "));
6188 printf (_("'%s'"), SECTION_NAME (sec));
6189
6190 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6191 (unsigned long) sec->sh_offset,
89fac5e3 6192 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6193
6194 slurp_hppa_unwind_table (file, &aux, sec);
6195 if (aux.table_len > 0)
6196 dump_hppa_unwind (&aux);
6197
6198 if (aux.table)
6199 free ((char *) aux.table);
6200 aux.table = NULL;
6201 }
6202 }
6203
6204 if (aux.symtab)
6205 free (aux.symtab);
6206 if (aux.strtab)
6207 free ((char *) aux.strtab);
6208
6209 return 1;
6210}
6211
0b6ae522
DJ
6212struct arm_section
6213{
6214 unsigned char *data;
6215
6216 Elf_Internal_Shdr *sec;
6217 Elf_Internal_Rela *rela;
6218 unsigned long nrelas;
6219 unsigned int rel_type;
6220
6221 Elf_Internal_Rela *next_rela;
6222};
6223
6224struct arm_unw_aux_info
6225{
6226 FILE *file;
6227
6228 Elf_Internal_Sym *symtab; /* The symbol table. */
6229 unsigned long nsyms; /* Number of symbols. */
6230 char *strtab; /* The string table. */
6231 unsigned long strtab_size; /* Size of string table. */
6232};
6233
6234static const char *
6235arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6236 bfd_vma fn, struct absaddr addr)
6237{
6238 const char *procname;
6239 bfd_vma sym_offset;
6240
6241 if (addr.section == SHN_UNDEF)
6242 addr.offset = fn;
6243
6244 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6245 aux->strtab_size, addr, &procname,
6246 &sym_offset);
6247
6248 print_vma (fn, PREFIX_HEX);
6249
6250 if (procname)
6251 {
6252 fputs (" <", stdout);
6253 fputs (procname, stdout);
6254
6255 if (sym_offset)
6256 printf ("+0x%lx", (unsigned long) sym_offset);
6257 fputc ('>', stdout);
6258 }
6259
6260 return procname;
6261}
6262
6263static void
6264arm_free_section (struct arm_section *arm_sec)
6265{
6266 if (arm_sec->data != NULL)
6267 free (arm_sec->data);
6268
6269 if (arm_sec->rela != NULL)
6270 free (arm_sec->rela);
6271}
6272
6273static int
6274arm_section_get_word (struct arm_unw_aux_info *aux,
6275 struct arm_section *arm_sec,
6276 Elf_Internal_Shdr *sec, bfd_vma word_offset,
6277 unsigned int *wordp, struct absaddr *addr)
6278{
6279 Elf_Internal_Rela *rp;
6280 Elf_Internal_Sym *sym;
6281 const char * relname;
6282 unsigned int word;
6283 bfd_boolean wrapped;
6284
6285 addr->section = SHN_UNDEF;
6286 addr->offset = 0;
6287
6288 if (sec != arm_sec->sec)
6289 {
6290 Elf_Internal_Shdr *relsec;
6291
6292 arm_free_section (arm_sec);
6293
6294 arm_sec->sec = sec;
6295 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6296 sec->sh_size, _("unwind data"));
6297
6298 arm_sec->rela = NULL;
6299 arm_sec->nrelas = 0;
6300
6301 for (relsec = section_headers;
6302 relsec < section_headers + elf_header.e_shnum;
6303 ++relsec)
6304 {
6305 if (relsec->sh_info >= elf_header.e_shnum
6306 || section_headers + relsec->sh_info != sec)
6307 continue;
6308
6309 if (relsec->sh_type == SHT_REL)
6310 {
6311 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6312 relsec->sh_size,
6313 & arm_sec->rela, & arm_sec->nrelas))
6314 return 0;
6315 break;
6316 }
6317 else if (relsec->sh_type == SHT_RELA)
6318 {
6319 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6320 relsec->sh_size,
6321 & arm_sec->rela, & arm_sec->nrelas))
6322 return 0;
6323 break;
6324 }
6325 }
6326
6327 arm_sec->next_rela = arm_sec->rela;
6328 }
6329
6330 if (arm_sec->data == NULL)
6331 return 0;
6332
6333 word = byte_get (arm_sec->data + word_offset, 4);
6334
6335 wrapped = FALSE;
6336 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6337 {
6338 bfd_vma prelval, offset;
6339
6340 if (rp->r_offset > word_offset && !wrapped)
6341 {
6342 rp = arm_sec->rela;
6343 wrapped = TRUE;
6344 }
6345 if (rp->r_offset > word_offset)
6346 break;
6347
6348 if (rp->r_offset & 3)
6349 {
6350 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6351 (unsigned long) rp->r_offset);
6352 continue;
6353 }
6354
6355 if (rp->r_offset < word_offset)
6356 continue;
6357
6358 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6359
6360 if (streq (relname, "R_ARM_NONE"))
6361 continue;
6362
6363 if (! streq (relname, "R_ARM_PREL31"))
6364 {
6365 warn (_("Skipping unexpected relocation type %s\n"), relname);
6366 continue;
6367 }
6368
6369 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6370
6371 if (arm_sec->rel_type == SHT_REL)
6372 {
6373 offset = word & 0x7fffffff;
6374 if (offset & 0x40000000)
6375 offset |= ~ (bfd_vma) 0x7fffffff;
6376 }
6377 else
6378 offset = rp->r_addend;
6379
6380 offset += sym->st_value;
6381 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6382
6383 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6384 addr->section = sym->st_shndx;
6385 addr->offset = offset;
6386 break;
6387 }
6388
6389 *wordp = word;
6390 arm_sec->next_rela = rp;
6391
6392 return 1;
6393}
6394
6395static void
6396decode_arm_unwind (struct arm_unw_aux_info *aux,
6397 unsigned int word, unsigned int remaining,
6398 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6399 struct arm_section *data_arm_sec)
6400{
6401 int per_index;
6402 unsigned int more_words;
6403 struct absaddr addr;
6404
6405#define ADVANCE \
6406 if (remaining == 0 && more_words) \
6407 { \
6408 data_offset += 4; \
6409 if (!arm_section_get_word (aux, data_arm_sec, data_sec, \
6410 data_offset, &word, &addr)) \
6411 return; \
6412 remaining = 4; \
6413 more_words--; \
6414 } \
6415
6416#define GET_OP(OP) \
6417 ADVANCE; \
6418 if (remaining) \
6419 { \
6420 remaining--; \
6421 (OP) = word >> 24; \
6422 word <<= 8; \
6423 } \
6424 else \
6425 { \
2b692964 6426 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6427 return; \
6428 } \
6429 printf (_("0x%02x "), OP)
6430
6431 if (remaining == 0)
6432 {
6433 /* Fetch the first word. */
6434 if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
6435 &word, &addr))
6436 return;
6437 remaining = 4;
6438 }
6439
6440 if ((word & 0x80000000) == 0)
6441 {
6442 /* Expand prel31 for personality routine. */
6443 bfd_vma fn;
6444 const char *procname;
6445
6446 fn = word;
6447 if (fn & 0x40000000)
6448 fn |= ~ (bfd_vma) 0x7fffffff;
6449 fn = fn + data_sec->sh_addr + data_offset;
6450
6451 printf (_(" Personality routine: "));
6452 procname = arm_print_vma_and_name (aux, fn, addr);
6453 fputc ('\n', stdout);
6454
6455 /* The GCC personality routines use the standard compact
6456 encoding, starting with one byte giving the number of
6457 words. */
6458 if (procname != NULL
6459 && (const_strneq (procname, "__gcc_personality_v0")
6460 || const_strneq (procname, "__gxx_personality_v0")
6461 || const_strneq (procname, "__gcj_personality_v0")
6462 || const_strneq (procname, "__gnu_objc_personality_v0")))
6463 {
6464 remaining = 0;
6465 more_words = 1;
6466 ADVANCE;
6467 if (!remaining)
6468 {
6469 printf (_(" [Truncated data]\n"));
6470 return;
6471 }
6472 more_words = word >> 24;
6473 word <<= 8;
6474 remaining--;
6475 }
6476 else
6477 return;
6478 }
6479 else
6480 {
0b6ae522
DJ
6481 per_index = (word >> 24) & 0x7f;
6482 if (per_index != 0 && per_index != 1 && per_index != 2)
6483 {
6484 printf (_(" [reserved compact index %d]\n"), per_index);
6485 return;
6486 }
6487
6488 printf (_(" Compact model %d\n"), per_index);
6489 if (per_index == 0)
6490 {
6491 more_words = 0;
6492 word <<= 8;
6493 remaining--;
6494 }
6495 else
6496 {
6497 more_words = (word >> 16) & 0xff;
6498 word <<= 16;
6499 remaining -= 2;
6500 }
6501 }
6502
6503 /* Decode the unwinding instructions. */
6504 while (1)
6505 {
6506 unsigned int op, op2;
6507
6508 ADVANCE;
6509 if (remaining == 0)
6510 break;
6511 remaining--;
6512 op = word >> 24;
6513 word <<= 8;
6514
6515 printf (_(" 0x%02x "), op);
6516
6517 if ((op & 0xc0) == 0x00)
6518 {
6519 int offset = ((op & 0x3f) << 2) + 4;
6520 printf (_(" vsp = vsp + %d"), offset);
6521 }
6522 else if ((op & 0xc0) == 0x40)
6523 {
6524 int offset = ((op & 0x3f) << 2) + 4;
6525 printf (_(" vsp = vsp - %d"), offset);
6526 }
6527 else if ((op & 0xf0) == 0x80)
6528 {
6529 GET_OP (op2);
6530 if (op == 0x80 && op2 == 0)
6531 printf (_("Refuse to unwind"));
6532 else
6533 {
6534 unsigned int mask = ((op & 0x0f) << 8) | op2;
6535 int first = 1;
6536 int i;
2b692964 6537
0b6ae522
DJ
6538 printf ("pop {");
6539 for (i = 0; i < 12; i++)
6540 if (mask & (1 << i))
6541 {
6542 if (first)
6543 first = 0;
6544 else
6545 printf (", ");
6546 printf ("r%d", 4 + i);
6547 }
6548 printf ("}");
6549 }
6550 }
6551 else if ((op & 0xf0) == 0x90)
6552 {
6553 if (op == 0x9d || op == 0x9f)
6554 printf (_(" [Reserved]"));
6555 else
6556 printf (_(" vsp = r%d"), op & 0x0f);
6557 }
6558 else if ((op & 0xf0) == 0xa0)
6559 {
6560 int end = 4 + (op & 0x07);
6561 int first = 1;
6562 int i;
6563 printf (" pop {");
6564 for (i = 4; i <= end; i++)
6565 {
6566 if (first)
6567 first = 0;
6568 else
6569 printf (", ");
6570 printf ("r%d", i);
6571 }
6572 if (op & 0x08)
6573 {
6574 if (first)
6575 printf (", ");
6576 printf ("r14");
6577 }
6578 printf ("}");
6579 }
6580 else if (op == 0xb0)
6581 printf (_(" finish"));
6582 else if (op == 0xb1)
6583 {
6584 GET_OP (op2);
6585 if (op2 == 0 || (op2 & 0xf0) != 0)
6586 printf (_("[Spare]"));
6587 else
6588 {
6589 unsigned int mask = op2 & 0x0f;
6590 int first = 1;
6591 int i;
6592 printf ("pop {");
6593 for (i = 0; i < 12; i++)
6594 if (mask & (1 << i))
6595 {
6596 if (first)
6597 first = 0;
6598 else
6599 printf (", ");
6600 printf ("r%d", i);
6601 }
6602 printf ("}");
6603 }
6604 }
6605 else if (op == 0xb2)
6606 {
b115cf96 6607 unsigned char buf[9];
0b6ae522
DJ
6608 unsigned int i, len;
6609 unsigned long offset;
b115cf96 6610 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6611 {
6612 GET_OP (buf[i]);
6613 if ((buf[i] & 0x80) == 0)
6614 break;
6615 }
6616 assert (i < sizeof (buf));
6617 offset = read_uleb128 (buf, &len);
6618 assert (len == i + 1);
6619 offset = offset * 4 + 0x204;
6620 printf (_("vsp = vsp + %ld"), offset);
6621 }
6622 else
6623 {
6624 if (op == 0xb3 || op == 0xc6 || op == 0xc7 || op == 0xc8 || op == 0xc9)
6625 {
6626 GET_OP (op2);
6627 printf (_("[unsupported two-byte opcode]"));
6628 }
6629 else
6630 {
6631 printf (_(" [unsupported opcode]"));
6632 }
6633 }
6634 printf ("\n");
6635 }
6636
6637 /* Decode the descriptors. Not implemented. */
6638}
6639
6640static void
6641dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
6642{
6643 struct arm_section exidx_arm_sec, extab_arm_sec;
6644 unsigned int i, exidx_len;
6645
6646 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
6647 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
6648 exidx_len = exidx_sec->sh_size / 8;
6649
6650 for (i = 0; i < exidx_len; i++)
6651 {
6652 unsigned int exidx_fn, exidx_entry;
6653 struct absaddr fn_addr, entry_addr;
6654 bfd_vma fn;
6655
6656 fputc ('\n', stdout);
6657
6658 if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6659 8 * i, &exidx_fn, &fn_addr)
6660 || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6661 8 * i + 4, &exidx_entry, &entry_addr))
6662 {
6663 arm_free_section (&exidx_arm_sec);
6664 arm_free_section (&extab_arm_sec);
6665 return;
6666 }
6667
6668 fn = exidx_fn & 0x7fffffff;
6669 if (fn & 0x40000000)
6670 fn |= ~ (bfd_vma) 0x7fffffff;
6671 fn = fn + exidx_sec->sh_addr + 8 * i;
6672
6673 arm_print_vma_and_name (aux, fn, entry_addr);
6674 fputs (": ", stdout);
6675
6676 if (exidx_entry == 1)
6677 {
6678 print_vma (exidx_entry, PREFIX_HEX);
6679 fputs (" [cantunwind]\n", stdout);
6680 }
6681 else if (exidx_entry & 0x80000000)
6682 {
6683 print_vma (exidx_entry, PREFIX_HEX);
6684 fputc ('\n', stdout);
6685 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
6686 }
6687 else
6688 {
8f73510c 6689 bfd_vma table, table_offset = 0;
0b6ae522
DJ
6690 Elf_Internal_Shdr *table_sec;
6691
6692 fputs ("@", stdout);
6693 table = exidx_entry;
6694 if (table & 0x40000000)
6695 table |= ~ (bfd_vma) 0x7fffffff;
6696 table = table + exidx_sec->sh_addr + 8 * i + 4;
6697 print_vma (table, PREFIX_HEX);
6698 printf ("\n");
6699
6700 /* Locate the matching .ARM.extab. */
6701 if (entry_addr.section != SHN_UNDEF
6702 && entry_addr.section < elf_header.e_shnum)
6703 {
6704 table_sec = section_headers + entry_addr.section;
6705 table_offset = entry_addr.offset;
6706 }
6707 else
6708 {
6709 table_sec = find_section_by_address (table);
6710 if (table_sec != NULL)
6711 table_offset = table - table_sec->sh_addr;
6712 }
6713 if (table_sec == NULL)
6714 {
6715 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
6716 (unsigned long) table);
6717 continue;
6718 }
6719 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
6720 &extab_arm_sec);
6721 }
6722 }
6723
6724 printf ("\n");
6725
6726 arm_free_section (&exidx_arm_sec);
6727 arm_free_section (&extab_arm_sec);
6728}
6729
6730static int
6731arm_process_unwind (FILE *file)
6732{
6733 struct arm_unw_aux_info aux;
6734 Elf_Internal_Shdr *unwsec = NULL;
6735 Elf_Internal_Shdr *strsec;
6736 Elf_Internal_Shdr *sec;
6737 unsigned long i;
6738
6739 memset (& aux, 0, sizeof (aux));
6740 aux.file = file;
6741
6742 if (string_table == NULL)
6743 return 1;
6744
6745 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6746 {
6747 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
6748 {
6749 aux.nsyms = sec->sh_size / sec->sh_entsize;
6750 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6751
6752 strsec = section_headers + sec->sh_link;
6753 aux.strtab = get_data (NULL, file, strsec->sh_offset,
6754 1, strsec->sh_size, _("string table"));
6755 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
6756 }
6757 else if (sec->sh_type == SHT_ARM_EXIDX)
6758 unwsec = sec;
6759 }
6760
6761 if (!unwsec)
6762 printf (_("\nThere are no unwind sections in this file.\n"));
6763
6764 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6765 {
6766 if (sec->sh_type == SHT_ARM_EXIDX)
6767 {
6768 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
6769 SECTION_NAME (sec),
6770 (unsigned long) sec->sh_offset,
6771 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
6772
6773 dump_arm_unwind (&aux, sec);
6774 }
6775 }
6776
6777 if (aux.symtab)
6778 free (aux.symtab);
6779 if (aux.strtab)
6780 free ((char *) aux.strtab);
6781
6782 return 1;
6783}
6784
57346661 6785static int
2cf0635d 6786process_unwind (FILE * file)
57346661 6787{
2cf0635d
NC
6788 struct unwind_handler
6789 {
57346661 6790 int machtype;
2cf0635d
NC
6791 int (* handler)(FILE *);
6792 } handlers[] =
6793 {
0b6ae522 6794 { EM_ARM, arm_process_unwind },
57346661
AM
6795 { EM_IA_64, ia64_process_unwind },
6796 { EM_PARISC, hppa_process_unwind },
6797 { 0, 0 }
6798 };
6799 int i;
6800
6801 if (!do_unwind)
6802 return 1;
6803
6804 for (i = 0; handlers[i].handler != NULL; i++)
6805 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 6806 return handlers[i].handler (file);
57346661
AM
6807
6808 printf (_("\nThere are no unwind sections in this file.\n"));
6809 return 1;
6810}
6811
252b5132 6812static void
2cf0635d 6813dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
6814{
6815 switch (entry->d_tag)
6816 {
6817 case DT_MIPS_FLAGS:
6818 if (entry->d_un.d_val == 0)
2b692964 6819 printf (_("NONE\n"));
252b5132
RH
6820 else
6821 {
6822 static const char * opts[] =
6823 {
6824 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
6825 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
6826 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
6827 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
6828 "RLD_ORDER_SAFE"
6829 };
6830 unsigned int cnt;
6831 int first = 1;
2b692964 6832
60bca95a 6833 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
6834 if (entry->d_un.d_val & (1 << cnt))
6835 {
6836 printf ("%s%s", first ? "" : " ", opts[cnt]);
6837 first = 0;
6838 }
6839 puts ("");
6840 }
6841 break;
103f02d3 6842
252b5132 6843 case DT_MIPS_IVERSION:
d79b3d50 6844 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
2b692964 6845 printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6846 else
2b692964 6847 printf (_("<corrupt: %ld>\n"), (long) entry->d_un.d_ptr);
252b5132 6848 break;
103f02d3 6849
252b5132
RH
6850 case DT_MIPS_TIME_STAMP:
6851 {
6852 char timebuf[20];
2cf0635d 6853 struct tm * tmp;
50da7a9c 6854
91d6fa6a
NC
6855 time_t atime = entry->d_un.d_val;
6856 tmp = gmtime (&atime);
e9e44622
JJ
6857 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
6858 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6859 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
2b692964 6860 printf (_("Time Stamp: %s\n"), timebuf);
252b5132
RH
6861 }
6862 break;
103f02d3 6863
252b5132
RH
6864 case DT_MIPS_RLD_VERSION:
6865 case DT_MIPS_LOCAL_GOTNO:
6866 case DT_MIPS_CONFLICTNO:
6867 case DT_MIPS_LIBLISTNO:
6868 case DT_MIPS_SYMTABNO:
6869 case DT_MIPS_UNREFEXTNO:
6870 case DT_MIPS_HIPAGENO:
6871 case DT_MIPS_DELTA_CLASS_NO:
6872 case DT_MIPS_DELTA_INSTANCE_NO:
6873 case DT_MIPS_DELTA_RELOC_NO:
6874 case DT_MIPS_DELTA_SYM_NO:
6875 case DT_MIPS_DELTA_CLASSSYM_NO:
6876 case DT_MIPS_COMPACT_SIZE:
6877 printf ("%ld\n", (long) entry->d_un.d_ptr);
6878 break;
103f02d3
UD
6879
6880 default:
0af1713e 6881 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
6882 }
6883}
6884
103f02d3 6885static void
2cf0635d 6886dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
6887{
6888 switch (entry->d_tag)
6889 {
6890 case DT_HP_DLD_FLAGS:
6891 {
6892 static struct
6893 {
6894 long int bit;
2cf0635d 6895 const char * str;
5e220199
NC
6896 }
6897 flags[] =
6898 {
6899 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
6900 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
6901 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
6902 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
6903 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
6904 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
6905 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
6906 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
6907 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
6908 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
6909 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
6910 { DT_HP_GST, "HP_GST" },
6911 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
6912 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
6913 { DT_HP_NODELETE, "HP_NODELETE" },
6914 { DT_HP_GROUP, "HP_GROUP" },
6915 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 6916 };
103f02d3 6917 int first = 1;
5e220199 6918 size_t cnt;
f7a99963 6919 bfd_vma val = entry->d_un.d_val;
103f02d3 6920
60bca95a 6921 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 6922 if (val & flags[cnt].bit)
30800947
NC
6923 {
6924 if (! first)
6925 putchar (' ');
6926 fputs (flags[cnt].str, stdout);
6927 first = 0;
6928 val ^= flags[cnt].bit;
6929 }
76da6bbe 6930
103f02d3 6931 if (val != 0 || first)
f7a99963
NC
6932 {
6933 if (! first)
6934 putchar (' ');
6935 print_vma (val, HEX);
6936 }
103f02d3
UD
6937 }
6938 break;
76da6bbe 6939
252b5132 6940 default:
f7a99963
NC
6941 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6942 break;
252b5132 6943 }
35b1837e 6944 putchar ('\n');
252b5132
RH
6945}
6946
28f997cf
TG
6947#ifdef BFD64
6948
6949/* VMS vs Unix time offset and factor. */
6950
6951#define VMS_EPOCH_OFFSET 35067168000000000LL
6952#define VMS_GRANULARITY_FACTOR 10000000
6953
6954/* Display a VMS time in a human readable format. */
6955
6956static void
6957print_vms_time (bfd_int64_t vmstime)
6958{
6959 struct tm *tm;
6960 time_t unxtime;
6961
6962 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
6963 tm = gmtime (&unxtime);
6964 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
6965 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
6966 tm->tm_hour, tm->tm_min, tm->tm_sec);
6967}
6968#endif /* BFD64 */
6969
ecc51f48 6970static void
2cf0635d 6971dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
6972{
6973 switch (entry->d_tag)
6974 {
0de14b54 6975 case DT_IA_64_PLT_RESERVE:
bdf4d63a 6976 /* First 3 slots reserved. */
ecc51f48
NC
6977 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6978 printf (" -- ");
6979 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
6980 break;
6981
28f997cf
TG
6982 case DT_IA_64_VMS_LINKTIME:
6983#ifdef BFD64
6984 print_vms_time (entry->d_un.d_val);
6985#endif
6986 break;
6987
6988 case DT_IA_64_VMS_LNKFLAGS:
6989 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6990 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
6991 printf (" CALL_DEBUG");
6992 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
6993 printf (" NOP0BUFS");
6994 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
6995 printf (" P0IMAGE");
6996 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
6997 printf (" MKTHREADS");
6998 if (entry->d_un.d_val & VMS_LF_UPCALLS)
6999 printf (" UPCALLS");
7000 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7001 printf (" IMGSTA");
7002 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7003 printf (" INITIALIZE");
7004 if (entry->d_un.d_val & VMS_LF_MAIN)
7005 printf (" MAIN");
7006 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7007 printf (" EXE_INIT");
7008 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7009 printf (" TBK_IN_IMG");
7010 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7011 printf (" DBG_IN_IMG");
7012 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7013 printf (" TBK_IN_DSF");
7014 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7015 printf (" DBG_IN_DSF");
7016 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7017 printf (" SIGNATURES");
7018 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7019 printf (" REL_SEG_OFF");
7020 break;
7021
bdf4d63a
JJ
7022 default:
7023 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7024 break;
ecc51f48 7025 }
bdf4d63a 7026 putchar ('\n');
ecc51f48
NC
7027}
7028
252b5132 7029static int
2cf0635d 7030get_32bit_dynamic_section (FILE * file)
252b5132 7031{
2cf0635d
NC
7032 Elf32_External_Dyn * edyn;
7033 Elf32_External_Dyn * ext;
7034 Elf_Internal_Dyn * entry;
103f02d3 7035
3f5e193b
NC
7036 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7037 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7038 if (!edyn)
7039 return 0;
103f02d3 7040
ba2685cc
AM
7041/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7042 might not have the luxury of section headers. Look for the DT_NULL
7043 terminator to determine the number of entries. */
7044 for (ext = edyn, dynamic_nent = 0;
7045 (char *) ext < (char *) edyn + dynamic_size;
7046 ext++)
7047 {
7048 dynamic_nent++;
7049 if (BYTE_GET (ext->d_tag) == DT_NULL)
7050 break;
7051 }
252b5132 7052
3f5e193b
NC
7053 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7054 sizeof (* entry));
b2d38a17 7055 if (dynamic_section == NULL)
252b5132 7056 {
9ea033b2
NC
7057 error (_("Out of memory\n"));
7058 free (edyn);
7059 return 0;
7060 }
252b5132 7061
fb514b26 7062 for (ext = edyn, entry = dynamic_section;
ba2685cc 7063 entry < dynamic_section + dynamic_nent;
fb514b26 7064 ext++, entry++)
9ea033b2 7065 {
fb514b26
AM
7066 entry->d_tag = BYTE_GET (ext->d_tag);
7067 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7068 }
7069
9ea033b2
NC
7070 free (edyn);
7071
7072 return 1;
7073}
7074
7075static int
2cf0635d 7076get_64bit_dynamic_section (FILE * file)
9ea033b2 7077{
2cf0635d
NC
7078 Elf64_External_Dyn * edyn;
7079 Elf64_External_Dyn * ext;
7080 Elf_Internal_Dyn * entry;
103f02d3 7081
3f5e193b
NC
7082 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7083 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7084 if (!edyn)
7085 return 0;
103f02d3 7086
ba2685cc
AM
7087/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7088 might not have the luxury of section headers. Look for the DT_NULL
7089 terminator to determine the number of entries. */
7090 for (ext = edyn, dynamic_nent = 0;
7091 (char *) ext < (char *) edyn + dynamic_size;
7092 ext++)
7093 {
7094 dynamic_nent++;
66543521 7095 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7096 break;
7097 }
252b5132 7098
3f5e193b
NC
7099 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7100 sizeof (* entry));
b2d38a17 7101 if (dynamic_section == NULL)
252b5132
RH
7102 {
7103 error (_("Out of memory\n"));
7104 free (edyn);
7105 return 0;
7106 }
7107
fb514b26 7108 for (ext = edyn, entry = dynamic_section;
ba2685cc 7109 entry < dynamic_section + dynamic_nent;
fb514b26 7110 ext++, entry++)
252b5132 7111 {
66543521
AM
7112 entry->d_tag = BYTE_GET (ext->d_tag);
7113 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7114 }
7115
7116 free (edyn);
7117
9ea033b2
NC
7118 return 1;
7119}
7120
e9e44622
JJ
7121static void
7122print_dynamic_flags (bfd_vma flags)
d1133906 7123{
e9e44622 7124 int first = 1;
13ae64f3 7125
d1133906
NC
7126 while (flags)
7127 {
7128 bfd_vma flag;
7129
7130 flag = flags & - flags;
7131 flags &= ~ flag;
7132
e9e44622
JJ
7133 if (first)
7134 first = 0;
7135 else
7136 putc (' ', stdout);
13ae64f3 7137
d1133906
NC
7138 switch (flag)
7139 {
e9e44622
JJ
7140 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7141 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7142 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7143 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7144 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7145 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7146 }
7147 }
e9e44622 7148 puts ("");
d1133906
NC
7149}
7150
b2d38a17
NC
7151/* Parse and display the contents of the dynamic section. */
7152
9ea033b2 7153static int
2cf0635d 7154process_dynamic_section (FILE * file)
9ea033b2 7155{
2cf0635d 7156 Elf_Internal_Dyn * entry;
9ea033b2
NC
7157
7158 if (dynamic_size == 0)
7159 {
7160 if (do_dynamic)
b2d38a17 7161 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7162
7163 return 1;
7164 }
7165
7166 if (is_32bit_elf)
7167 {
b2d38a17 7168 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7169 return 0;
7170 }
b2d38a17 7171 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7172 return 0;
7173
252b5132
RH
7174 /* Find the appropriate symbol table. */
7175 if (dynamic_symbols == NULL)
7176 {
86dba8ee
AM
7177 for (entry = dynamic_section;
7178 entry < dynamic_section + dynamic_nent;
7179 ++entry)
252b5132 7180 {
c8286bd1 7181 Elf_Internal_Shdr section;
252b5132
RH
7182
7183 if (entry->d_tag != DT_SYMTAB)
7184 continue;
7185
7186 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7187
7188 /* Since we do not know how big the symbol table is,
7189 we default to reading in the entire file (!) and
7190 processing that. This is overkill, I know, but it
e3c8793a 7191 should work. */
d93f0186 7192 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7193
fb52b2f4
NC
7194 if (archive_file_offset != 0)
7195 section.sh_size = archive_file_size - section.sh_offset;
7196 else
7197 {
7198 if (fseek (file, 0, SEEK_END))
591a748a 7199 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7200
7201 section.sh_size = ftell (file) - section.sh_offset;
7202 }
252b5132 7203
9ea033b2 7204 if (is_32bit_elf)
9ad5cbcf 7205 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7206 else
9ad5cbcf 7207 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7208
9ad5cbcf 7209 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 7210 if (num_dynamic_syms < 1)
252b5132
RH
7211 {
7212 error (_("Unable to determine the number of symbols to load\n"));
7213 continue;
7214 }
7215
9ad5cbcf 7216 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
7217 }
7218 }
7219
7220 /* Similarly find a string table. */
7221 if (dynamic_strings == NULL)
7222 {
86dba8ee
AM
7223 for (entry = dynamic_section;
7224 entry < dynamic_section + dynamic_nent;
7225 ++entry)
252b5132
RH
7226 {
7227 unsigned long offset;
b34976b6 7228 long str_tab_len;
252b5132
RH
7229
7230 if (entry->d_tag != DT_STRTAB)
7231 continue;
7232
7233 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7234
7235 /* Since we do not know how big the string table is,
7236 we default to reading in the entire file (!) and
7237 processing that. This is overkill, I know, but it
e3c8793a 7238 should work. */
252b5132 7239
d93f0186 7240 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7241
7242 if (archive_file_offset != 0)
7243 str_tab_len = archive_file_size - offset;
7244 else
7245 {
7246 if (fseek (file, 0, SEEK_END))
7247 error (_("Unable to seek to end of file\n"));
7248 str_tab_len = ftell (file) - offset;
7249 }
252b5132
RH
7250
7251 if (str_tab_len < 1)
7252 {
7253 error
7254 (_("Unable to determine the length of the dynamic string table\n"));
7255 continue;
7256 }
7257
3f5e193b
NC
7258 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7259 str_tab_len,
7260 _("dynamic string table"));
d79b3d50 7261 dynamic_strings_length = str_tab_len;
252b5132
RH
7262 break;
7263 }
7264 }
7265
7266 /* And find the syminfo section if available. */
7267 if (dynamic_syminfo == NULL)
7268 {
3e8bba36 7269 unsigned long syminsz = 0;
252b5132 7270
86dba8ee
AM
7271 for (entry = dynamic_section;
7272 entry < dynamic_section + dynamic_nent;
7273 ++entry)
252b5132
RH
7274 {
7275 if (entry->d_tag == DT_SYMINENT)
7276 {
7277 /* Note: these braces are necessary to avoid a syntax
7278 error from the SunOS4 C compiler. */
7279 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7280 }
7281 else if (entry->d_tag == DT_SYMINSZ)
7282 syminsz = entry->d_un.d_val;
7283 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7284 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7285 syminsz);
252b5132
RH
7286 }
7287
7288 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7289 {
2cf0635d
NC
7290 Elf_External_Syminfo * extsyminfo;
7291 Elf_External_Syminfo * extsym;
7292 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7293
7294 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7295 extsyminfo = (Elf_External_Syminfo *)
7296 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7297 _("symbol information"));
a6e9f9df
AM
7298 if (!extsyminfo)
7299 return 0;
252b5132 7300
3f5e193b 7301 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7302 if (dynamic_syminfo == NULL)
7303 {
7304 error (_("Out of memory\n"));
7305 return 0;
7306 }
7307
7308 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7309 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7310 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7311 ++syminfo, ++extsym)
252b5132 7312 {
86dba8ee
AM
7313 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7314 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7315 }
7316
7317 free (extsyminfo);
7318 }
7319 }
7320
7321 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7322 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7323 dynamic_addr, dynamic_nent);
252b5132
RH
7324 if (do_dynamic)
7325 printf (_(" Tag Type Name/Value\n"));
7326
86dba8ee
AM
7327 for (entry = dynamic_section;
7328 entry < dynamic_section + dynamic_nent;
7329 entry++)
252b5132
RH
7330 {
7331 if (do_dynamic)
f7a99963 7332 {
2cf0635d 7333 const char * dtype;
e699b9ff 7334
f7a99963
NC
7335 putchar (' ');
7336 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7337 dtype = get_dynamic_type (entry->d_tag);
7338 printf (" (%s)%*s", dtype,
7339 ((is_32bit_elf ? 27 : 19)
7340 - (int) strlen (dtype)),
f7a99963
NC
7341 " ");
7342 }
252b5132
RH
7343
7344 switch (entry->d_tag)
7345 {
d1133906
NC
7346 case DT_FLAGS:
7347 if (do_dynamic)
e9e44622 7348 print_dynamic_flags (entry->d_un.d_val);
d1133906 7349 break;
76da6bbe 7350
252b5132
RH
7351 case DT_AUXILIARY:
7352 case DT_FILTER:
019148e4
L
7353 case DT_CONFIG:
7354 case DT_DEPAUDIT:
7355 case DT_AUDIT:
252b5132
RH
7356 if (do_dynamic)
7357 {
019148e4 7358 switch (entry->d_tag)
b34976b6 7359 {
019148e4
L
7360 case DT_AUXILIARY:
7361 printf (_("Auxiliary library"));
7362 break;
7363
7364 case DT_FILTER:
7365 printf (_("Filter library"));
7366 break;
7367
b34976b6 7368 case DT_CONFIG:
019148e4
L
7369 printf (_("Configuration file"));
7370 break;
7371
7372 case DT_DEPAUDIT:
7373 printf (_("Dependency audit library"));
7374 break;
7375
7376 case DT_AUDIT:
7377 printf (_("Audit library"));
7378 break;
7379 }
252b5132 7380
d79b3d50
NC
7381 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7382 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7383 else
f7a99963
NC
7384 {
7385 printf (": ");
7386 print_vma (entry->d_un.d_val, PREFIX_HEX);
7387 putchar ('\n');
7388 }
252b5132
RH
7389 }
7390 break;
7391
dcefbbbd 7392 case DT_FEATURE:
252b5132
RH
7393 if (do_dynamic)
7394 {
7395 printf (_("Flags:"));
86f55779 7396
252b5132
RH
7397 if (entry->d_un.d_val == 0)
7398 printf (_(" None\n"));
7399 else
7400 {
7401 unsigned long int val = entry->d_un.d_val;
86f55779 7402
252b5132
RH
7403 if (val & DTF_1_PARINIT)
7404 {
7405 printf (" PARINIT");
7406 val ^= DTF_1_PARINIT;
7407 }
dcefbbbd
L
7408 if (val & DTF_1_CONFEXP)
7409 {
7410 printf (" CONFEXP");
7411 val ^= DTF_1_CONFEXP;
7412 }
252b5132
RH
7413 if (val != 0)
7414 printf (" %lx", val);
7415 puts ("");
7416 }
7417 }
7418 break;
7419
7420 case DT_POSFLAG_1:
7421 if (do_dynamic)
7422 {
7423 printf (_("Flags:"));
86f55779 7424
252b5132
RH
7425 if (entry->d_un.d_val == 0)
7426 printf (_(" None\n"));
7427 else
7428 {
7429 unsigned long int val = entry->d_un.d_val;
86f55779 7430
252b5132
RH
7431 if (val & DF_P1_LAZYLOAD)
7432 {
7433 printf (" LAZYLOAD");
7434 val ^= DF_P1_LAZYLOAD;
7435 }
7436 if (val & DF_P1_GROUPPERM)
7437 {
7438 printf (" GROUPPERM");
7439 val ^= DF_P1_GROUPPERM;
7440 }
7441 if (val != 0)
7442 printf (" %lx", val);
7443 puts ("");
7444 }
7445 }
7446 break;
7447
7448 case DT_FLAGS_1:
7449 if (do_dynamic)
7450 {
7451 printf (_("Flags:"));
7452 if (entry->d_un.d_val == 0)
7453 printf (_(" None\n"));
7454 else
7455 {
7456 unsigned long int val = entry->d_un.d_val;
86f55779 7457
252b5132
RH
7458 if (val & DF_1_NOW)
7459 {
7460 printf (" NOW");
7461 val ^= DF_1_NOW;
7462 }
7463 if (val & DF_1_GLOBAL)
7464 {
7465 printf (" GLOBAL");
7466 val ^= DF_1_GLOBAL;
7467 }
7468 if (val & DF_1_GROUP)
7469 {
7470 printf (" GROUP");
7471 val ^= DF_1_GROUP;
7472 }
7473 if (val & DF_1_NODELETE)
7474 {
7475 printf (" NODELETE");
7476 val ^= DF_1_NODELETE;
7477 }
7478 if (val & DF_1_LOADFLTR)
7479 {
7480 printf (" LOADFLTR");
7481 val ^= DF_1_LOADFLTR;
7482 }
7483 if (val & DF_1_INITFIRST)
7484 {
7485 printf (" INITFIRST");
7486 val ^= DF_1_INITFIRST;
7487 }
7488 if (val & DF_1_NOOPEN)
7489 {
7490 printf (" NOOPEN");
7491 val ^= DF_1_NOOPEN;
7492 }
7493 if (val & DF_1_ORIGIN)
7494 {
7495 printf (" ORIGIN");
7496 val ^= DF_1_ORIGIN;
7497 }
7498 if (val & DF_1_DIRECT)
7499 {
7500 printf (" DIRECT");
7501 val ^= DF_1_DIRECT;
7502 }
7503 if (val & DF_1_TRANS)
7504 {
7505 printf (" TRANS");
7506 val ^= DF_1_TRANS;
7507 }
7508 if (val & DF_1_INTERPOSE)
7509 {
7510 printf (" INTERPOSE");
7511 val ^= DF_1_INTERPOSE;
7512 }
f7db6139 7513 if (val & DF_1_NODEFLIB)
dcefbbbd 7514 {
f7db6139
L
7515 printf (" NODEFLIB");
7516 val ^= DF_1_NODEFLIB;
dcefbbbd
L
7517 }
7518 if (val & DF_1_NODUMP)
7519 {
7520 printf (" NODUMP");
7521 val ^= DF_1_NODUMP;
7522 }
7523 if (val & DF_1_CONLFAT)
7524 {
7525 printf (" CONLFAT");
7526 val ^= DF_1_CONLFAT;
7527 }
252b5132
RH
7528 if (val != 0)
7529 printf (" %lx", val);
7530 puts ("");
7531 }
7532 }
7533 break;
7534
7535 case DT_PLTREL:
566b0d53 7536 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7537 if (do_dynamic)
7538 puts (get_dynamic_type (entry->d_un.d_val));
7539 break;
7540
7541 case DT_NULL :
7542 case DT_NEEDED :
7543 case DT_PLTGOT :
7544 case DT_HASH :
7545 case DT_STRTAB :
7546 case DT_SYMTAB :
7547 case DT_RELA :
7548 case DT_INIT :
7549 case DT_FINI :
7550 case DT_SONAME :
7551 case DT_RPATH :
7552 case DT_SYMBOLIC:
7553 case DT_REL :
7554 case DT_DEBUG :
7555 case DT_TEXTREL :
7556 case DT_JMPREL :
019148e4 7557 case DT_RUNPATH :
252b5132
RH
7558 dynamic_info[entry->d_tag] = entry->d_un.d_val;
7559
7560 if (do_dynamic)
7561 {
2cf0635d 7562 char * name;
252b5132 7563
d79b3d50
NC
7564 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7565 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7566 else
d79b3d50 7567 name = NULL;
252b5132
RH
7568
7569 if (name)
7570 {
7571 switch (entry->d_tag)
7572 {
7573 case DT_NEEDED:
7574 printf (_("Shared library: [%s]"), name);
7575
18bd398b 7576 if (streq (name, program_interpreter))
f7a99963 7577 printf (_(" program interpreter"));
252b5132
RH
7578 break;
7579
7580 case DT_SONAME:
f7a99963 7581 printf (_("Library soname: [%s]"), name);
252b5132
RH
7582 break;
7583
7584 case DT_RPATH:
f7a99963 7585 printf (_("Library rpath: [%s]"), name);
252b5132
RH
7586 break;
7587
019148e4
L
7588 case DT_RUNPATH:
7589 printf (_("Library runpath: [%s]"), name);
7590 break;
7591
252b5132 7592 default:
f7a99963
NC
7593 print_vma (entry->d_un.d_val, PREFIX_HEX);
7594 break;
252b5132
RH
7595 }
7596 }
7597 else
f7a99963
NC
7598 print_vma (entry->d_un.d_val, PREFIX_HEX);
7599
7600 putchar ('\n');
252b5132
RH
7601 }
7602 break;
7603
7604 case DT_PLTRELSZ:
7605 case DT_RELASZ :
7606 case DT_STRSZ :
7607 case DT_RELSZ :
7608 case DT_RELAENT :
7609 case DT_SYMENT :
7610 case DT_RELENT :
566b0d53 7611 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7612 case DT_PLTPADSZ:
7613 case DT_MOVEENT :
7614 case DT_MOVESZ :
7615 case DT_INIT_ARRAYSZ:
7616 case DT_FINI_ARRAYSZ:
047b2264
JJ
7617 case DT_GNU_CONFLICTSZ:
7618 case DT_GNU_LIBLISTSZ:
252b5132 7619 if (do_dynamic)
f7a99963
NC
7620 {
7621 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 7622 printf (_(" (bytes)\n"));
f7a99963 7623 }
252b5132
RH
7624 break;
7625
7626 case DT_VERDEFNUM:
7627 case DT_VERNEEDNUM:
7628 case DT_RELACOUNT:
7629 case DT_RELCOUNT:
7630 if (do_dynamic)
f7a99963
NC
7631 {
7632 print_vma (entry->d_un.d_val, UNSIGNED);
7633 putchar ('\n');
7634 }
252b5132
RH
7635 break;
7636
7637 case DT_SYMINSZ:
7638 case DT_SYMINENT:
7639 case DT_SYMINFO:
7640 case DT_USED:
7641 case DT_INIT_ARRAY:
7642 case DT_FINI_ARRAY:
7643 if (do_dynamic)
7644 {
d79b3d50
NC
7645 if (entry->d_tag == DT_USED
7646 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 7647 {
2cf0635d 7648 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7649
b34976b6 7650 if (*name)
252b5132
RH
7651 {
7652 printf (_("Not needed object: [%s]\n"), name);
7653 break;
7654 }
7655 }
103f02d3 7656
f7a99963
NC
7657 print_vma (entry->d_un.d_val, PREFIX_HEX);
7658 putchar ('\n');
252b5132
RH
7659 }
7660 break;
7661
7662 case DT_BIND_NOW:
7663 /* The value of this entry is ignored. */
35b1837e
AM
7664 if (do_dynamic)
7665 putchar ('\n');
252b5132 7666 break;
103f02d3 7667
047b2264
JJ
7668 case DT_GNU_PRELINKED:
7669 if (do_dynamic)
7670 {
2cf0635d 7671 struct tm * tmp;
91d6fa6a 7672 time_t atime = entry->d_un.d_val;
047b2264 7673
91d6fa6a 7674 tmp = gmtime (&atime);
047b2264
JJ
7675 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
7676 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7677 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7678
7679 }
7680 break;
7681
fdc90cb4
JJ
7682 case DT_GNU_HASH:
7683 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
7684 if (do_dynamic)
7685 {
7686 print_vma (entry->d_un.d_val, PREFIX_HEX);
7687 putchar ('\n');
7688 }
7689 break;
7690
252b5132
RH
7691 default:
7692 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 7693 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
7694 entry->d_un.d_val;
7695
7696 if (do_dynamic)
7697 {
7698 switch (elf_header.e_machine)
7699 {
7700 case EM_MIPS:
4fe85591 7701 case EM_MIPS_RS3_LE:
b2d38a17 7702 dynamic_section_mips_val (entry);
252b5132 7703 break;
103f02d3 7704 case EM_PARISC:
b2d38a17 7705 dynamic_section_parisc_val (entry);
103f02d3 7706 break;
ecc51f48 7707 case EM_IA_64:
b2d38a17 7708 dynamic_section_ia64_val (entry);
ecc51f48 7709 break;
252b5132 7710 default:
f7a99963
NC
7711 print_vma (entry->d_un.d_val, PREFIX_HEX);
7712 putchar ('\n');
252b5132
RH
7713 }
7714 }
7715 break;
7716 }
7717 }
7718
7719 return 1;
7720}
7721
7722static char *
d3ba0551 7723get_ver_flags (unsigned int flags)
252b5132 7724{
b34976b6 7725 static char buff[32];
252b5132
RH
7726
7727 buff[0] = 0;
7728
7729 if (flags == 0)
7730 return _("none");
7731
7732 if (flags & VER_FLG_BASE)
7733 strcat (buff, "BASE ");
7734
7735 if (flags & VER_FLG_WEAK)
7736 {
7737 if (flags & VER_FLG_BASE)
7738 strcat (buff, "| ");
7739
7740 strcat (buff, "WEAK ");
7741 }
7742
44ec90b9
RO
7743 if (flags & VER_FLG_INFO)
7744 {
7745 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7746 strcat (buff, "| ");
7747
7748 strcat (buff, "INFO ");
7749 }
7750
7751 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 7752 strcat (buff, _("| <unknown>"));
252b5132
RH
7753
7754 return buff;
7755}
7756
7757/* Display the contents of the version sections. */
98fb390a 7758
252b5132 7759static int
2cf0635d 7760process_version_sections (FILE * file)
252b5132 7761{
2cf0635d 7762 Elf_Internal_Shdr * section;
b34976b6
AM
7763 unsigned i;
7764 int found = 0;
252b5132
RH
7765
7766 if (! do_version)
7767 return 1;
7768
7769 for (i = 0, section = section_headers;
7770 i < elf_header.e_shnum;
b34976b6 7771 i++, section++)
252b5132
RH
7772 {
7773 switch (section->sh_type)
7774 {
7775 case SHT_GNU_verdef:
7776 {
2cf0635d 7777 Elf_External_Verdef * edefs;
b34976b6
AM
7778 unsigned int idx;
7779 unsigned int cnt;
2cf0635d 7780 char * endbuf;
252b5132
RH
7781
7782 found = 1;
7783
7784 printf
72de5009 7785 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
7786 SECTION_NAME (section), section->sh_info);
7787
7788 printf (_(" Addr: 0x"));
7789 printf_vma (section->sh_addr);
72de5009 7790 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7791 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
7792 section->sh_link < elf_header.e_shnum
7793 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 7794 : _("<corrupt>"));
252b5132 7795
3f5e193b
NC
7796 edefs = (Elf_External_Verdef *)
7797 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
7798 _("version definition section"));
54806181 7799 endbuf = (char *) edefs + section->sh_size;
a6e9f9df
AM
7800 if (!edefs)
7801 break;
252b5132 7802
b34976b6 7803 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 7804 {
2cf0635d
NC
7805 char * vstart;
7806 Elf_External_Verdef * edef;
b34976b6 7807 Elf_Internal_Verdef ent;
2cf0635d 7808 Elf_External_Verdaux * eaux;
b34976b6
AM
7809 Elf_Internal_Verdaux aux;
7810 int j;
7811 int isum;
103f02d3 7812
dd24e3da
NC
7813 /* Check for negative or very large indicies. */
7814 if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
7815 break;
7816
252b5132 7817 vstart = ((char *) edefs) + idx;
54806181
AM
7818 if (vstart + sizeof (*edef) > endbuf)
7819 break;
252b5132
RH
7820
7821 edef = (Elf_External_Verdef *) vstart;
7822
7823 ent.vd_version = BYTE_GET (edef->vd_version);
7824 ent.vd_flags = BYTE_GET (edef->vd_flags);
7825 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
7826 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
7827 ent.vd_hash = BYTE_GET (edef->vd_hash);
7828 ent.vd_aux = BYTE_GET (edef->vd_aux);
7829 ent.vd_next = BYTE_GET (edef->vd_next);
7830
7831 printf (_(" %#06x: Rev: %d Flags: %s"),
7832 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
7833
7834 printf (_(" Index: %d Cnt: %d "),
7835 ent.vd_ndx, ent.vd_cnt);
7836
dd24e3da
NC
7837 /* Check for overflow. */
7838 if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
7839 || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
7840 break;
7841
252b5132
RH
7842 vstart += ent.vd_aux;
7843
7844 eaux = (Elf_External_Verdaux *) vstart;
7845
7846 aux.vda_name = BYTE_GET (eaux->vda_name);
7847 aux.vda_next = BYTE_GET (eaux->vda_next);
7848
d79b3d50
NC
7849 if (VALID_DYNAMIC_NAME (aux.vda_name))
7850 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
7851 else
7852 printf (_("Name index: %ld\n"), aux.vda_name);
7853
7854 isum = idx + ent.vd_aux;
7855
b34976b6 7856 for (j = 1; j < ent.vd_cnt; j++)
252b5132 7857 {
dd24e3da
NC
7858 /* Check for overflow. */
7859 if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
7860 || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
7861 break;
7862
252b5132
RH
7863 isum += aux.vda_next;
7864 vstart += aux.vda_next;
7865
7866 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
7867 if (vstart + sizeof (*eaux) > endbuf)
7868 break;
252b5132
RH
7869
7870 aux.vda_name = BYTE_GET (eaux->vda_name);
7871 aux.vda_next = BYTE_GET (eaux->vda_next);
7872
d79b3d50 7873 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 7874 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 7875 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
7876 else
7877 printf (_(" %#06x: Parent %d, name index: %ld\n"),
7878 isum, j, aux.vda_name);
7879 }
dd24e3da 7880
54806181
AM
7881 if (j < ent.vd_cnt)
7882 printf (_(" Version def aux past end of section\n"));
252b5132
RH
7883
7884 idx += ent.vd_next;
7885 }
dd24e3da 7886
54806181
AM
7887 if (cnt < section->sh_info)
7888 printf (_(" Version definition past end of section\n"));
252b5132
RH
7889
7890 free (edefs);
7891 }
7892 break;
103f02d3 7893
252b5132
RH
7894 case SHT_GNU_verneed:
7895 {
2cf0635d 7896 Elf_External_Verneed * eneed;
b34976b6
AM
7897 unsigned int idx;
7898 unsigned int cnt;
2cf0635d 7899 char * endbuf;
252b5132
RH
7900
7901 found = 1;
7902
72de5009 7903 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
7904 SECTION_NAME (section), section->sh_info);
7905
7906 printf (_(" Addr: 0x"));
7907 printf_vma (section->sh_addr);
72de5009 7908 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7909 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
7910 section->sh_link < elf_header.e_shnum
7911 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 7912 : _("<corrupt>"));
252b5132 7913
3f5e193b
NC
7914 eneed = (Elf_External_Verneed *) get_data (NULL, file,
7915 section->sh_offset, 1,
7916 section->sh_size,
7917 _("version need section"));
54806181 7918 endbuf = (char *) eneed + section->sh_size;
a6e9f9df
AM
7919 if (!eneed)
7920 break;
252b5132
RH
7921
7922 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
7923 {
2cf0635d 7924 Elf_External_Verneed * entry;
b34976b6
AM
7925 Elf_Internal_Verneed ent;
7926 int j;
7927 int isum;
2cf0635d 7928 char * vstart;
252b5132 7929
dd24e3da
NC
7930 if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
7931 break;
7932
252b5132 7933 vstart = ((char *) eneed) + idx;
54806181
AM
7934 if (vstart + sizeof (*entry) > endbuf)
7935 break;
252b5132
RH
7936
7937 entry = (Elf_External_Verneed *) vstart;
7938
7939 ent.vn_version = BYTE_GET (entry->vn_version);
7940 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
7941 ent.vn_file = BYTE_GET (entry->vn_file);
7942 ent.vn_aux = BYTE_GET (entry->vn_aux);
7943 ent.vn_next = BYTE_GET (entry->vn_next);
7944
7945 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
7946
d79b3d50
NC
7947 if (VALID_DYNAMIC_NAME (ent.vn_file))
7948 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
7949 else
7950 printf (_(" File: %lx"), ent.vn_file);
7951
7952 printf (_(" Cnt: %d\n"), ent.vn_cnt);
7953
dd24e3da
NC
7954 /* Check for overflow. */
7955 if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
7956 || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
7957 break;
7958
252b5132
RH
7959 vstart += ent.vn_aux;
7960
7961 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
7962 {
2cf0635d 7963 Elf_External_Vernaux * eaux;
b34976b6 7964 Elf_Internal_Vernaux aux;
252b5132 7965
54806181
AM
7966 if (vstart + sizeof (*eaux) > endbuf)
7967 break;
252b5132
RH
7968 eaux = (Elf_External_Vernaux *) vstart;
7969
7970 aux.vna_hash = BYTE_GET (eaux->vna_hash);
7971 aux.vna_flags = BYTE_GET (eaux->vna_flags);
7972 aux.vna_other = BYTE_GET (eaux->vna_other);
7973 aux.vna_name = BYTE_GET (eaux->vna_name);
7974 aux.vna_next = BYTE_GET (eaux->vna_next);
7975
d79b3d50 7976 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 7977 printf (_(" %#06x: Name: %s"),
d79b3d50 7978 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 7979 else
ecc2063b 7980 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
7981 isum, aux.vna_name);
7982
7983 printf (_(" Flags: %s Version: %d\n"),
7984 get_ver_flags (aux.vna_flags), aux.vna_other);
7985
dd24e3da
NC
7986 /* Check for overflow. */
7987 if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
7988 || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
7989 break;
7990
252b5132
RH
7991 isum += aux.vna_next;
7992 vstart += aux.vna_next;
7993 }
54806181
AM
7994 if (j < ent.vn_cnt)
7995 printf (_(" Version need aux past end of section\n"));
252b5132
RH
7996
7997 idx += ent.vn_next;
7998 }
54806181
AM
7999 if (cnt < section->sh_info)
8000 printf (_(" Version need past end of section\n"));
103f02d3 8001
252b5132
RH
8002 free (eneed);
8003 }
8004 break;
8005
8006 case SHT_GNU_versym:
8007 {
2cf0635d 8008 Elf_Internal_Shdr * link_section;
b34976b6
AM
8009 int total;
8010 int cnt;
2cf0635d
NC
8011 unsigned char * edata;
8012 unsigned short * data;
8013 char * strtab;
8014 Elf_Internal_Sym * symbols;
8015 Elf_Internal_Shdr * string_sec;
d3ba0551 8016 long off;
252b5132 8017
4fbb74a6 8018 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8019 break;
8020
4fbb74a6 8021 link_section = section_headers + section->sh_link;
08d8fa11 8022 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8023
4fbb74a6 8024 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8025 break;
8026
252b5132
RH
8027 found = 1;
8028
9ad5cbcf 8029 symbols = GET_ELF_SYMBOLS (file, link_section);
dd24e3da
NC
8030 if (symbols == NULL)
8031 break;
252b5132 8032
4fbb74a6 8033 string_sec = section_headers + link_section->sh_link;
252b5132 8034
3f5e193b
NC
8035 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8036 string_sec->sh_size,
8037 _("version string table"));
a6e9f9df
AM
8038 if (!strtab)
8039 break;
252b5132
RH
8040
8041 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8042 SECTION_NAME (section), total);
8043
8044 printf (_(" Addr: "));
8045 printf_vma (section->sh_addr);
72de5009 8046 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8047 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8048 SECTION_NAME (link_section));
8049
d3ba0551
AM
8050 off = offset_from_vma (file,
8051 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8052 total * sizeof (short));
3f5e193b
NC
8053 edata = (unsigned char *) get_data (NULL, file, off, total,
8054 sizeof (short),
8055 _("version symbol data"));
a6e9f9df
AM
8056 if (!edata)
8057 {
8058 free (strtab);
8059 break;
8060 }
252b5132 8061
3f5e193b 8062 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8063
8064 for (cnt = total; cnt --;)
b34976b6
AM
8065 data[cnt] = byte_get (edata + cnt * sizeof (short),
8066 sizeof (short));
252b5132
RH
8067
8068 free (edata);
8069
8070 for (cnt = 0; cnt < total; cnt += 4)
8071 {
8072 int j, nn;
00d93f34 8073 int check_def, check_need;
2cf0635d 8074 char * name;
252b5132
RH
8075
8076 printf (" %03x:", cnt);
8077
8078 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8079 switch (data[cnt + j])
252b5132
RH
8080 {
8081 case 0:
8082 fputs (_(" 0 (*local*) "), stdout);
8083 break;
8084
8085 case 1:
8086 fputs (_(" 1 (*global*) "), stdout);
8087 break;
8088
8089 default:
c244d050
NC
8090 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8091 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8092
dd24e3da
NC
8093 /* If this index value is greater than the size of the symbols
8094 array, break to avoid an out-of-bounds read, */
8095 if ((unsigned long)(cnt + j) >=
8096 ((unsigned long)link_section->sh_size /
8097 (unsigned long)link_section->sh_entsize))
8098 {
8099 warn (_("invalid index into symbol array\n"));
8100 break;
8101 }
8102
00d93f34
JJ
8103 check_def = 1;
8104 check_need = 1;
4fbb74a6
AM
8105 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8106 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8107 != SHT_NOBITS)
252b5132 8108 {
b34976b6 8109 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8110 check_def = 0;
8111 else
8112 check_need = 0;
252b5132 8113 }
00d93f34
JJ
8114
8115 if (check_need
b34976b6 8116 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8117 {
b34976b6
AM
8118 Elf_Internal_Verneed ivn;
8119 unsigned long offset;
252b5132 8120
d93f0186
NC
8121 offset = offset_from_vma
8122 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8123 sizeof (Elf_External_Verneed));
252b5132 8124
b34976b6 8125 do
252b5132 8126 {
b34976b6
AM
8127 Elf_Internal_Vernaux ivna;
8128 Elf_External_Verneed evn;
8129 Elf_External_Vernaux evna;
8130 unsigned long a_off;
252b5132 8131
c256ffe7 8132 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 8133 _("version need"));
252b5132
RH
8134
8135 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8136 ivn.vn_next = BYTE_GET (evn.vn_next);
8137
8138 a_off = offset + ivn.vn_aux;
8139
8140 do
8141 {
a6e9f9df 8142 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 8143 1, _("version need aux (2)"));
252b5132
RH
8144
8145 ivna.vna_next = BYTE_GET (evna.vna_next);
8146 ivna.vna_other = BYTE_GET (evna.vna_other);
8147
8148 a_off += ivna.vna_next;
8149 }
b34976b6 8150 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8151 && ivna.vna_next != 0);
8152
b34976b6 8153 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8154 {
8155 ivna.vna_name = BYTE_GET (evna.vna_name);
8156
54806181
AM
8157 if (ivna.vna_name >= string_sec->sh_size)
8158 name = _("*invalid*");
8159 else
8160 name = strtab + ivna.vna_name;
252b5132 8161 nn += printf ("(%s%-*s",
16062207
ILT
8162 name,
8163 12 - (int) strlen (name),
252b5132 8164 ")");
00d93f34 8165 check_def = 0;
252b5132
RH
8166 break;
8167 }
8168
8169 offset += ivn.vn_next;
8170 }
8171 while (ivn.vn_next);
8172 }
00d93f34 8173
b34976b6
AM
8174 if (check_def && data[cnt + j] != 0x8001
8175 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8176 {
b34976b6
AM
8177 Elf_Internal_Verdef ivd;
8178 Elf_External_Verdef evd;
8179 unsigned long offset;
252b5132 8180
d93f0186
NC
8181 offset = offset_from_vma
8182 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8183 sizeof evd);
252b5132
RH
8184
8185 do
8186 {
c256ffe7 8187 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 8188 _("version def"));
252b5132
RH
8189
8190 ivd.vd_next = BYTE_GET (evd.vd_next);
8191 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8192
8193 offset += ivd.vd_next;
8194 }
c244d050 8195 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8196 && ivd.vd_next != 0);
8197
c244d050 8198 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8199 {
b34976b6
AM
8200 Elf_External_Verdaux evda;
8201 Elf_Internal_Verdaux ivda;
252b5132
RH
8202
8203 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8204
a6e9f9df
AM
8205 get_data (&evda, file,
8206 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
8207 sizeof (evda), 1,
8208 _("version def aux"));
252b5132
RH
8209
8210 ivda.vda_name = BYTE_GET (evda.vda_name);
8211
54806181
AM
8212 if (ivda.vda_name >= string_sec->sh_size)
8213 name = _("*invalid*");
8214 else
8215 name = strtab + ivda.vda_name;
252b5132 8216 nn += printf ("(%s%-*s",
16062207
ILT
8217 name,
8218 12 - (int) strlen (name),
252b5132
RH
8219 ")");
8220 }
8221 }
8222
8223 if (nn < 18)
8224 printf ("%*c", 18 - nn, ' ');
8225 }
8226
8227 putchar ('\n');
8228 }
8229
8230 free (data);
8231 free (strtab);
8232 free (symbols);
8233 }
8234 break;
103f02d3 8235
252b5132
RH
8236 default:
8237 break;
8238 }
8239 }
8240
8241 if (! found)
8242 printf (_("\nNo version information found in this file.\n"));
8243
8244 return 1;
8245}
8246
d1133906 8247static const char *
d3ba0551 8248get_symbol_binding (unsigned int binding)
252b5132 8249{
b34976b6 8250 static char buff[32];
252b5132
RH
8251
8252 switch (binding)
8253 {
b34976b6
AM
8254 case STB_LOCAL: return "LOCAL";
8255 case STB_GLOBAL: return "GLOBAL";
8256 case STB_WEAK: return "WEAK";
252b5132
RH
8257 default:
8258 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8259 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8260 binding);
252b5132 8261 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8262 {
8263 if (binding == STB_GNU_UNIQUE
8264 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
8265 /* GNU/Linux is still using the default value 0. */
8266 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8267 return "UNIQUE";
8268 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8269 }
252b5132 8270 else
e9e44622 8271 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8272 return buff;
8273 }
8274}
8275
d1133906 8276static const char *
d3ba0551 8277get_symbol_type (unsigned int type)
252b5132 8278{
b34976b6 8279 static char buff[32];
252b5132
RH
8280
8281 switch (type)
8282 {
b34976b6
AM
8283 case STT_NOTYPE: return "NOTYPE";
8284 case STT_OBJECT: return "OBJECT";
8285 case STT_FUNC: return "FUNC";
8286 case STT_SECTION: return "SECTION";
8287 case STT_FILE: return "FILE";
8288 case STT_COMMON: return "COMMON";
8289 case STT_TLS: return "TLS";
15ab5209
DB
8290 case STT_RELC: return "RELC";
8291 case STT_SRELC: return "SRELC";
252b5132
RH
8292 default:
8293 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8294 {
8295 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8296 return "THUMB_FUNC";
8297
351b4b40 8298 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8299 return "REGISTER";
8300
8301 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8302 return "PARISC_MILLI";
8303
e9e44622 8304 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8305 }
252b5132 8306 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8307 {
8308 if (elf_header.e_machine == EM_PARISC)
8309 {
8310 if (type == STT_HP_OPAQUE)
8311 return "HP_OPAQUE";
8312 if (type == STT_HP_STUB)
8313 return "HP_STUB";
8314 }
8315
d8045f23
NC
8316 if (type == STT_GNU_IFUNC
8317 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
8318 /* GNU/Linux is still using the default value 0. */
8319 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8320 return "IFUNC";
8321
e9e44622 8322 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8323 }
252b5132 8324 else
e9e44622 8325 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8326 return buff;
8327 }
8328}
8329
d1133906 8330static const char *
d3ba0551 8331get_symbol_visibility (unsigned int visibility)
d1133906
NC
8332{
8333 switch (visibility)
8334 {
b34976b6
AM
8335 case STV_DEFAULT: return "DEFAULT";
8336 case STV_INTERNAL: return "INTERNAL";
8337 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
8338 case STV_PROTECTED: return "PROTECTED";
8339 default: abort ();
8340 }
8341}
8342
5e2b0d47
NC
8343static const char *
8344get_mips_symbol_other (unsigned int other)
8345{
8346 switch (other)
8347 {
8348 case STO_OPTIONAL: return "OPTIONAL";
8349 case STO_MIPS16: return "MIPS16";
861fb55a
DJ
8350 case STO_MIPS_PLT: return "MIPS PLT";
8351 case STO_MIPS_PIC: return "MIPS PIC";
5e2b0d47
NC
8352 default: return NULL;
8353 }
8354}
8355
28f997cf
TG
8356static const char *
8357get_ia64_symbol_other (unsigned int other)
8358{
8359 if (is_ia64_vms ())
8360 {
8361 static char res[32];
8362
8363 res[0] = 0;
8364
8365 /* Function types is for images and .STB files only. */
8366 switch (elf_header.e_type)
8367 {
8368 case ET_DYN:
8369 case ET_EXEC:
8370 switch (VMS_ST_FUNC_TYPE (other))
8371 {
8372 case VMS_SFT_CODE_ADDR:
8373 strcat (res, " CA");
8374 break;
8375 case VMS_SFT_SYMV_IDX:
8376 strcat (res, " VEC");
8377 break;
8378 case VMS_SFT_FD:
8379 strcat (res, " FD");
8380 break;
8381 case VMS_SFT_RESERVE:
8382 strcat (res, " RSV");
8383 break;
8384 default:
8385 abort ();
8386 }
8387 break;
8388 default:
8389 break;
8390 }
8391 switch (VMS_ST_LINKAGE (other))
8392 {
8393 case VMS_STL_IGNORE:
8394 strcat (res, " IGN");
8395 break;
8396 case VMS_STL_RESERVE:
8397 strcat (res, " RSV");
8398 break;
8399 case VMS_STL_STD:
8400 strcat (res, " STD");
8401 break;
8402 case VMS_STL_LNK:
8403 strcat (res, " LNK");
8404 break;
8405 default:
8406 abort ();
8407 }
8408
8409 if (res[0] != 0)
8410 return res + 1;
8411 else
8412 return res;
8413 }
8414 return NULL;
8415}
8416
5e2b0d47
NC
8417static const char *
8418get_symbol_other (unsigned int other)
8419{
8420 const char * result = NULL;
8421 static char buff [32];
8422
8423 if (other == 0)
8424 return "";
8425
8426 switch (elf_header.e_machine)
8427 {
8428 case EM_MIPS:
8429 result = get_mips_symbol_other (other);
28f997cf
TG
8430 break;
8431 case EM_IA_64:
8432 result = get_ia64_symbol_other (other);
8433 break;
5e2b0d47
NC
8434 default:
8435 break;
8436 }
8437
8438 if (result)
8439 return result;
8440
8441 snprintf (buff, sizeof buff, _("<other>: %x"), other);
8442 return buff;
8443}
8444
d1133906 8445static const char *
d3ba0551 8446get_symbol_index_type (unsigned int type)
252b5132 8447{
b34976b6 8448 static char buff[32];
5cf1065c 8449
252b5132
RH
8450 switch (type)
8451 {
b34976b6
AM
8452 case SHN_UNDEF: return "UND";
8453 case SHN_ABS: return "ABS";
8454 case SHN_COMMON: return "COM";
252b5132 8455 default:
9ce701e2
L
8456 if (type == SHN_IA_64_ANSI_COMMON
8457 && elf_header.e_machine == EM_IA_64
8458 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
8459 return "ANSI_COM";
8a9036a4
L
8460 else if ((elf_header.e_machine == EM_X86_64
8461 || elf_header.e_machine == EM_L1OM)
3b22753a
L
8462 && type == SHN_X86_64_LCOMMON)
8463 return "LARGE_COM";
172553c7
TS
8464 else if (type == SHN_MIPS_SCOMMON
8465 && elf_header.e_machine == EM_MIPS)
8466 return "SCOM";
8467 else if (type == SHN_MIPS_SUNDEFINED
8468 && elf_header.e_machine == EM_MIPS)
8469 return "SUND";
9ce701e2 8470 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 8471 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 8472 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
8473 sprintf (buff, "OS [0x%04x]", type & 0xffff);
8474 else if (type >= SHN_LORESERVE)
8475 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 8476 else
232e7cb8 8477 sprintf (buff, "%3d", type);
5cf1065c 8478 break;
252b5132 8479 }
5cf1065c
NC
8480
8481 return buff;
252b5132
RH
8482}
8483
66543521 8484static bfd_vma *
2cf0635d 8485get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 8486{
2cf0635d
NC
8487 unsigned char * e_data;
8488 bfd_vma * i_data;
252b5132 8489
3f5e193b 8490 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
8491
8492 if (e_data == NULL)
8493 {
8494 error (_("Out of memory\n"));
8495 return NULL;
8496 }
8497
66543521 8498 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
8499 {
8500 error (_("Unable to read in dynamic data\n"));
8501 return NULL;
8502 }
8503
3f5e193b 8504 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
8505
8506 if (i_data == NULL)
8507 {
8508 error (_("Out of memory\n"));
8509 free (e_data);
8510 return NULL;
8511 }
8512
8513 while (number--)
66543521 8514 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
8515
8516 free (e_data);
8517
8518 return i_data;
8519}
8520
6bd1a22c
L
8521static void
8522print_dynamic_symbol (bfd_vma si, unsigned long hn)
8523{
2cf0635d 8524 Elf_Internal_Sym * psym;
6bd1a22c
L
8525 int n;
8526
8527 psym = dynamic_symbols + si;
8528
8529 n = print_vma (si, DEC_5);
8530 if (n < 5)
8531 fputs (" " + n, stdout);
8532 printf (" %3lu: ", hn);
8533 print_vma (psym->st_value, LONG_HEX);
8534 putchar (' ');
8535 print_vma (psym->st_size, DEC_5);
8536
f4be36b3
AM
8537 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8538 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
8539 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
8540 /* Check to see if any other bits in the st_other field are set.
8541 Note - displaying this information disrupts the layout of the
8542 table being generated, but for the moment this case is very
8543 rare. */
8544 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8545 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
8546 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
8547 if (VALID_DYNAMIC_NAME (psym->st_name))
8548 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
8549 else
2b692964 8550 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
8551 putchar ('\n');
8552}
8553
e3c8793a 8554/* Dump the symbol table. */
252b5132 8555static int
2cf0635d 8556process_symbol_table (FILE * file)
252b5132 8557{
2cf0635d 8558 Elf_Internal_Shdr * section;
66543521
AM
8559 bfd_vma nbuckets = 0;
8560 bfd_vma nchains = 0;
2cf0635d
NC
8561 bfd_vma * buckets = NULL;
8562 bfd_vma * chains = NULL;
fdc90cb4 8563 bfd_vma ngnubuckets = 0;
2cf0635d
NC
8564 bfd_vma * gnubuckets = NULL;
8565 bfd_vma * gnuchains = NULL;
6bd1a22c 8566 bfd_vma gnusymidx = 0;
252b5132 8567
2c610e4b 8568 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
8569 return 1;
8570
6bd1a22c
L
8571 if (dynamic_info[DT_HASH]
8572 && (do_histogram
2c610e4b
L
8573 || (do_using_dynamic
8574 && !do_dyn_syms
8575 && dynamic_strings != NULL)))
252b5132 8576 {
66543521
AM
8577 unsigned char nb[8];
8578 unsigned char nc[8];
8579 int hash_ent_size = 4;
8580
8581 if ((elf_header.e_machine == EM_ALPHA
8582 || elf_header.e_machine == EM_S390
8583 || elf_header.e_machine == EM_S390_OLD)
8584 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
8585 hash_ent_size = 8;
8586
fb52b2f4
NC
8587 if (fseek (file,
8588 (archive_file_offset
8589 + offset_from_vma (file, dynamic_info[DT_HASH],
8590 sizeof nb + sizeof nc)),
d93f0186 8591 SEEK_SET))
252b5132 8592 {
591a748a 8593 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8594 goto no_hash;
252b5132
RH
8595 }
8596
66543521 8597 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
8598 {
8599 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8600 goto no_hash;
252b5132
RH
8601 }
8602
66543521 8603 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
8604 {
8605 error (_("Failed to read in number of chains\n"));
d3a44ec6 8606 goto no_hash;
252b5132
RH
8607 }
8608
66543521
AM
8609 nbuckets = byte_get (nb, hash_ent_size);
8610 nchains = byte_get (nc, hash_ent_size);
252b5132 8611
66543521
AM
8612 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
8613 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 8614
d3a44ec6 8615 no_hash:
252b5132 8616 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
8617 {
8618 if (do_using_dynamic)
8619 return 0;
8620 free (buckets);
8621 free (chains);
8622 buckets = NULL;
8623 chains = NULL;
8624 nbuckets = 0;
8625 nchains = 0;
8626 }
252b5132
RH
8627 }
8628
6bd1a22c
L
8629 if (dynamic_info_DT_GNU_HASH
8630 && (do_histogram
2c610e4b
L
8631 || (do_using_dynamic
8632 && !do_dyn_syms
8633 && dynamic_strings != NULL)))
252b5132 8634 {
6bd1a22c
L
8635 unsigned char nb[16];
8636 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
8637 bfd_vma buckets_vma;
8638
8639 if (fseek (file,
8640 (archive_file_offset
8641 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
8642 sizeof nb)),
8643 SEEK_SET))
8644 {
8645 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8646 goto no_gnu_hash;
6bd1a22c 8647 }
252b5132 8648
6bd1a22c
L
8649 if (fread (nb, 16, 1, file) != 1)
8650 {
8651 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8652 goto no_gnu_hash;
6bd1a22c
L
8653 }
8654
8655 ngnubuckets = byte_get (nb, 4);
8656 gnusymidx = byte_get (nb + 4, 4);
8657 bitmaskwords = byte_get (nb + 8, 4);
8658 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 8659 if (is_32bit_elf)
6bd1a22c 8660 buckets_vma += bitmaskwords * 4;
f7a99963 8661 else
6bd1a22c 8662 buckets_vma += bitmaskwords * 8;
252b5132 8663
6bd1a22c
L
8664 if (fseek (file,
8665 (archive_file_offset
8666 + offset_from_vma (file, buckets_vma, 4)),
8667 SEEK_SET))
252b5132 8668 {
6bd1a22c 8669 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8670 goto no_gnu_hash;
6bd1a22c
L
8671 }
8672
8673 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 8674
6bd1a22c 8675 if (gnubuckets == NULL)
d3a44ec6 8676 goto no_gnu_hash;
6bd1a22c
L
8677
8678 for (i = 0; i < ngnubuckets; i++)
8679 if (gnubuckets[i] != 0)
8680 {
8681 if (gnubuckets[i] < gnusymidx)
8682 return 0;
8683
8684 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
8685 maxchain = gnubuckets[i];
8686 }
8687
8688 if (maxchain == 0xffffffff)
d3a44ec6 8689 goto no_gnu_hash;
6bd1a22c
L
8690
8691 maxchain -= gnusymidx;
8692
8693 if (fseek (file,
8694 (archive_file_offset
8695 + offset_from_vma (file, buckets_vma
8696 + 4 * (ngnubuckets + maxchain), 4)),
8697 SEEK_SET))
8698 {
8699 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8700 goto no_gnu_hash;
6bd1a22c
L
8701 }
8702
8703 do
8704 {
8705 if (fread (nb, 4, 1, file) != 1)
252b5132 8706 {
6bd1a22c 8707 error (_("Failed to determine last chain length\n"));
d3a44ec6 8708 goto no_gnu_hash;
6bd1a22c 8709 }
252b5132 8710
6bd1a22c 8711 if (maxchain + 1 == 0)
d3a44ec6 8712 goto no_gnu_hash;
252b5132 8713
6bd1a22c
L
8714 ++maxchain;
8715 }
8716 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 8717
6bd1a22c
L
8718 if (fseek (file,
8719 (archive_file_offset
8720 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
8721 SEEK_SET))
8722 {
8723 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8724 goto no_gnu_hash;
6bd1a22c
L
8725 }
8726
8727 gnuchains = get_dynamic_data (file, maxchain, 4);
8728
d3a44ec6 8729 no_gnu_hash:
6bd1a22c 8730 if (gnuchains == NULL)
d3a44ec6
JJ
8731 {
8732 free (gnubuckets);
d3a44ec6
JJ
8733 gnubuckets = NULL;
8734 ngnubuckets = 0;
f64fddf1
NC
8735 if (do_using_dynamic)
8736 return 0;
d3a44ec6 8737 }
6bd1a22c
L
8738 }
8739
8740 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
8741 && do_syms
8742 && do_using_dynamic
8743 && dynamic_strings != NULL)
8744 {
8745 unsigned long hn;
8746
8747 if (dynamic_info[DT_HASH])
8748 {
8749 bfd_vma si;
8750
8751 printf (_("\nSymbol table for image:\n"));
8752 if (is_32bit_elf)
8753 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8754 else
8755 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8756
8757 for (hn = 0; hn < nbuckets; hn++)
8758 {
8759 if (! buckets[hn])
8760 continue;
8761
8762 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
8763 print_dynamic_symbol (si, hn);
252b5132
RH
8764 }
8765 }
6bd1a22c
L
8766
8767 if (dynamic_info_DT_GNU_HASH)
8768 {
8769 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
8770 if (is_32bit_elf)
8771 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8772 else
8773 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8774
8775 for (hn = 0; hn < ngnubuckets; ++hn)
8776 if (gnubuckets[hn] != 0)
8777 {
8778 bfd_vma si = gnubuckets[hn];
8779 bfd_vma off = si - gnusymidx;
8780
8781 do
8782 {
8783 print_dynamic_symbol (si, hn);
8784 si++;
8785 }
8786 while ((gnuchains[off++] & 1) == 0);
8787 }
8788 }
252b5132 8789 }
2c610e4b 8790 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 8791 {
b34976b6 8792 unsigned int i;
252b5132
RH
8793
8794 for (i = 0, section = section_headers;
8795 i < elf_header.e_shnum;
8796 i++, section++)
8797 {
b34976b6 8798 unsigned int si;
2cf0635d 8799 char * strtab = NULL;
c256ffe7 8800 unsigned long int strtab_size = 0;
2cf0635d
NC
8801 Elf_Internal_Sym * symtab;
8802 Elf_Internal_Sym * psym;
252b5132 8803
2c610e4b
L
8804 if ((section->sh_type != SHT_SYMTAB
8805 && section->sh_type != SHT_DYNSYM)
8806 || (!do_syms
8807 && section->sh_type == SHT_SYMTAB))
252b5132
RH
8808 continue;
8809
dd24e3da
NC
8810 if (section->sh_entsize == 0)
8811 {
8812 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
8813 SECTION_NAME (section));
8814 continue;
8815 }
8816
252b5132
RH
8817 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
8818 SECTION_NAME (section),
8819 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 8820
f7a99963 8821 if (is_32bit_elf)
ca47b30c 8822 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 8823 else
ca47b30c 8824 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 8825
9ad5cbcf 8826 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
8827 if (symtab == NULL)
8828 continue;
8829
8830 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
8831 {
8832 strtab = string_table;
8833 strtab_size = string_table_length;
8834 }
4fbb74a6 8835 else if (section->sh_link < elf_header.e_shnum)
252b5132 8836 {
2cf0635d 8837 Elf_Internal_Shdr * string_sec;
252b5132 8838
4fbb74a6 8839 string_sec = section_headers + section->sh_link;
252b5132 8840
3f5e193b
NC
8841 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
8842 1, string_sec->sh_size,
8843 _("string table"));
c256ffe7 8844 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
8845 }
8846
8847 for (si = 0, psym = symtab;
8848 si < section->sh_size / section->sh_entsize;
b34976b6 8849 si++, psym++)
252b5132 8850 {
5e220199 8851 printf ("%6d: ", si);
f7a99963
NC
8852 print_vma (psym->st_value, LONG_HEX);
8853 putchar (' ');
8854 print_vma (psym->st_size, DEC_5);
d1133906
NC
8855 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8856 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 8857 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
8858 /* Check to see if any other bits in the st_other field are set.
8859 Note - displaying this information disrupts the layout of the
8860 table being generated, but for the moment this case is very rare. */
8861 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8862 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 8863 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 8864 print_symbol (25, psym->st_name < strtab_size
2b692964 8865 ? strtab + psym->st_name : _("<corrupt>"));
252b5132
RH
8866
8867 if (section->sh_type == SHT_DYNSYM &&
b34976b6 8868 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 8869 {
b34976b6
AM
8870 unsigned char data[2];
8871 unsigned short vers_data;
8872 unsigned long offset;
8873 int is_nobits;
8874 int check_def;
252b5132 8875
d93f0186
NC
8876 offset = offset_from_vma
8877 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8878 sizeof data + si * sizeof (vers_data));
252b5132 8879
a6e9f9df 8880 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 8881 sizeof (data), 1, _("version data"));
252b5132
RH
8882
8883 vers_data = byte_get (data, 2);
8884
4fbb74a6
AM
8885 is_nobits = (psym->st_shndx < elf_header.e_shnum
8886 && section_headers[psym->st_shndx].sh_type
c256ffe7 8887 == SHT_NOBITS);
252b5132
RH
8888
8889 check_def = (psym->st_shndx != SHN_UNDEF);
8890
c244d050 8891 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 8892 {
b34976b6 8893 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 8894 && (is_nobits || ! check_def))
252b5132 8895 {
b34976b6
AM
8896 Elf_External_Verneed evn;
8897 Elf_Internal_Verneed ivn;
8898 Elf_Internal_Vernaux ivna;
252b5132
RH
8899
8900 /* We must test both. */
d93f0186
NC
8901 offset = offset_from_vma
8902 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8903 sizeof evn);
252b5132 8904
252b5132
RH
8905 do
8906 {
b34976b6 8907 unsigned long vna_off;
252b5132 8908
c256ffe7 8909 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 8910 _("version need"));
dd27201e
L
8911
8912 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8913 ivn.vn_next = BYTE_GET (evn.vn_next);
8914
252b5132
RH
8915 vna_off = offset + ivn.vn_aux;
8916
8917 do
8918 {
b34976b6 8919 Elf_External_Vernaux evna;
252b5132 8920
a6e9f9df 8921 get_data (&evna, file, vna_off,
c256ffe7 8922 sizeof (evna), 1,
a6e9f9df 8923 _("version need aux (3)"));
252b5132
RH
8924
8925 ivna.vna_other = BYTE_GET (evna.vna_other);
8926 ivna.vna_next = BYTE_GET (evna.vna_next);
8927 ivna.vna_name = BYTE_GET (evna.vna_name);
8928
8929 vna_off += ivna.vna_next;
8930 }
8931 while (ivna.vna_other != vers_data
8932 && ivna.vna_next != 0);
8933
8934 if (ivna.vna_other == vers_data)
8935 break;
8936
8937 offset += ivn.vn_next;
8938 }
8939 while (ivn.vn_next != 0);
8940
8941 if (ivna.vna_other == vers_data)
8942 {
8943 printf ("@%s (%d)",
c256ffe7 8944 ivna.vna_name < strtab_size
2b692964 8945 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 8946 ivna.vna_other);
252b5132
RH
8947 check_def = 0;
8948 }
8949 else if (! is_nobits)
591a748a 8950 error (_("bad dynamic symbol\n"));
252b5132
RH
8951 else
8952 check_def = 1;
8953 }
8954
8955 if (check_def)
8956 {
00d93f34 8957 if (vers_data != 0x8001
b34976b6 8958 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8959 {
b34976b6
AM
8960 Elf_Internal_Verdef ivd;
8961 Elf_Internal_Verdaux ivda;
8962 Elf_External_Verdaux evda;
91d6fa6a 8963 unsigned long off;
252b5132 8964
91d6fa6a 8965 off = offset_from_vma
d93f0186
NC
8966 (file,
8967 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8968 sizeof (Elf_External_Verdef));
252b5132
RH
8969
8970 do
8971 {
b34976b6 8972 Elf_External_Verdef evd;
252b5132 8973
91d6fa6a 8974 get_data (&evd, file, off, sizeof (evd),
c256ffe7 8975 1, _("version def"));
252b5132 8976
b34976b6
AM
8977 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8978 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
8979 ivd.vd_next = BYTE_GET (evd.vd_next);
8980
91d6fa6a 8981 off += ivd.vd_next;
252b5132 8982 }
c244d050 8983 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
8984 && ivd.vd_next != 0);
8985
91d6fa6a
NC
8986 off -= ivd.vd_next;
8987 off += ivd.vd_aux;
252b5132 8988
91d6fa6a 8989 get_data (&evda, file, off, sizeof (evda),
c256ffe7 8990 1, _("version def aux"));
252b5132
RH
8991
8992 ivda.vda_name = BYTE_GET (evda.vda_name);
8993
8994 if (psym->st_name != ivda.vda_name)
c244d050 8995 printf ((vers_data & VERSYM_HIDDEN)
252b5132 8996 ? "@%s" : "@@%s",
c256ffe7 8997 ivda.vda_name < strtab_size
2b692964 8998 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
8999 }
9000 }
9001 }
9002 }
9003
9004 putchar ('\n');
9005 }
9006
9007 free (symtab);
9008 if (strtab != string_table)
9009 free (strtab);
9010 }
9011 }
9012 else if (do_syms)
9013 printf
9014 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9015
9016 if (do_histogram && buckets != NULL)
9017 {
2cf0635d
NC
9018 unsigned long * lengths;
9019 unsigned long * counts;
66543521
AM
9020 unsigned long hn;
9021 bfd_vma si;
9022 unsigned long maxlength = 0;
9023 unsigned long nzero_counts = 0;
9024 unsigned long nsyms = 0;
252b5132 9025
66543521
AM
9026 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9027 (unsigned long) nbuckets);
252b5132
RH
9028 printf (_(" Length Number %% of total Coverage\n"));
9029
3f5e193b 9030 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9031 if (lengths == NULL)
9032 {
591a748a 9033 error (_("Out of memory\n"));
252b5132
RH
9034 return 0;
9035 }
9036 for (hn = 0; hn < nbuckets; ++hn)
9037 {
f7a99963 9038 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9039 {
b34976b6 9040 ++nsyms;
252b5132 9041 if (maxlength < ++lengths[hn])
b34976b6 9042 ++maxlength;
252b5132
RH
9043 }
9044 }
9045
3f5e193b 9046 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9047 if (counts == NULL)
9048 {
591a748a 9049 error (_("Out of memory\n"));
252b5132
RH
9050 return 0;
9051 }
9052
9053 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9054 ++counts[lengths[hn]];
252b5132 9055
103f02d3 9056 if (nbuckets > 0)
252b5132 9057 {
66543521
AM
9058 unsigned long i;
9059 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9060 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9061 for (i = 1; i <= maxlength; ++i)
103f02d3 9062 {
66543521
AM
9063 nzero_counts += counts[i] * i;
9064 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9065 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9066 (nzero_counts * 100.0) / nsyms);
9067 }
252b5132
RH
9068 }
9069
9070 free (counts);
9071 free (lengths);
9072 }
9073
9074 if (buckets != NULL)
9075 {
9076 free (buckets);
9077 free (chains);
9078 }
9079
d3a44ec6 9080 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9081 {
2cf0635d
NC
9082 unsigned long * lengths;
9083 unsigned long * counts;
fdc90cb4
JJ
9084 unsigned long hn;
9085 unsigned long maxlength = 0;
9086 unsigned long nzero_counts = 0;
9087 unsigned long nsyms = 0;
fdc90cb4 9088
3f5e193b 9089 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9090 if (lengths == NULL)
9091 {
591a748a 9092 error (_("Out of memory\n"));
fdc90cb4
JJ
9093 return 0;
9094 }
9095
9096 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9097 (unsigned long) ngnubuckets);
9098 printf (_(" Length Number %% of total Coverage\n"));
9099
9100 for (hn = 0; hn < ngnubuckets; ++hn)
9101 if (gnubuckets[hn] != 0)
9102 {
9103 bfd_vma off, length = 1;
9104
6bd1a22c 9105 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9106 (gnuchains[off] & 1) == 0; ++off)
9107 ++length;
9108 lengths[hn] = length;
9109 if (length > maxlength)
9110 maxlength = length;
9111 nsyms += length;
9112 }
9113
3f5e193b 9114 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9115 if (counts == NULL)
9116 {
591a748a 9117 error (_("Out of memory\n"));
fdc90cb4
JJ
9118 return 0;
9119 }
9120
9121 for (hn = 0; hn < ngnubuckets; ++hn)
9122 ++counts[lengths[hn]];
9123
9124 if (ngnubuckets > 0)
9125 {
9126 unsigned long j;
9127 printf (" 0 %-10lu (%5.1f%%)\n",
9128 counts[0], (counts[0] * 100.0) / ngnubuckets);
9129 for (j = 1; j <= maxlength; ++j)
9130 {
9131 nzero_counts += counts[j] * j;
9132 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9133 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9134 (nzero_counts * 100.0) / nsyms);
9135 }
9136 }
9137
9138 free (counts);
9139 free (lengths);
9140 free (gnubuckets);
9141 free (gnuchains);
9142 }
9143
252b5132
RH
9144 return 1;
9145}
9146
9147static int
2cf0635d 9148process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9149{
b4c96d0d 9150 unsigned int i;
252b5132
RH
9151
9152 if (dynamic_syminfo == NULL
9153 || !do_dynamic)
9154 /* No syminfo, this is ok. */
9155 return 1;
9156
9157 /* There better should be a dynamic symbol section. */
9158 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9159 return 0;
9160
9161 if (dynamic_addr)
9162 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9163 dynamic_syminfo_offset, dynamic_syminfo_nent);
9164
9165 printf (_(" Num: Name BoundTo Flags\n"));
9166 for (i = 0; i < dynamic_syminfo_nent; ++i)
9167 {
9168 unsigned short int flags = dynamic_syminfo[i].si_flags;
9169
31104126 9170 printf ("%4d: ", i);
d79b3d50
NC
9171 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9172 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9173 else
2b692964 9174 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9175 putchar (' ');
252b5132
RH
9176
9177 switch (dynamic_syminfo[i].si_boundto)
9178 {
9179 case SYMINFO_BT_SELF:
9180 fputs ("SELF ", stdout);
9181 break;
9182 case SYMINFO_BT_PARENT:
9183 fputs ("PARENT ", stdout);
9184 break;
9185 default:
9186 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9187 && dynamic_syminfo[i].si_boundto < dynamic_nent
9188 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9189 {
d79b3d50 9190 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9191 putchar (' ' );
9192 }
252b5132
RH
9193 else
9194 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9195 break;
9196 }
9197
9198 if (flags & SYMINFO_FLG_DIRECT)
9199 printf (" DIRECT");
9200 if (flags & SYMINFO_FLG_PASSTHRU)
9201 printf (" PASSTHRU");
9202 if (flags & SYMINFO_FLG_COPY)
9203 printf (" COPY");
9204 if (flags & SYMINFO_FLG_LAZYLOAD)
9205 printf (" LAZYLOAD");
9206
9207 puts ("");
9208 }
9209
9210 return 1;
9211}
9212
cf13d699
NC
9213/* Check to see if the given reloc needs to be handled in a target specific
9214 manner. If so then process the reloc and return TRUE otherwise return
9215 FALSE. */
09c11c86 9216
cf13d699
NC
9217static bfd_boolean
9218target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9219 unsigned char * start,
9220 Elf_Internal_Sym * symtab)
252b5132 9221{
cf13d699 9222 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9223
cf13d699 9224 switch (elf_header.e_machine)
252b5132 9225 {
cf13d699
NC
9226 case EM_MN10300:
9227 case EM_CYGNUS_MN10300:
9228 {
9229 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9230
cf13d699
NC
9231 switch (reloc_type)
9232 {
9233 case 34: /* R_MN10300_ALIGN */
9234 return TRUE;
9235 case 33: /* R_MN10300_SYM_DIFF */
9236 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9237 return TRUE;
9238 case 1: /* R_MN10300_32 */
9239 case 2: /* R_MN10300_16 */
9240 if (saved_sym != NULL)
9241 {
9242 bfd_vma value;
252b5132 9243
cf13d699
NC
9244 value = reloc->r_addend
9245 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9246 - saved_sym->st_value);
252b5132 9247
cf13d699 9248 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9249
cf13d699
NC
9250 saved_sym = NULL;
9251 return TRUE;
9252 }
9253 break;
9254 default:
9255 if (saved_sym != NULL)
9256 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9257 break;
9258 }
9259 break;
9260 }
252b5132
RH
9261 }
9262
cf13d699 9263 return FALSE;
252b5132
RH
9264}
9265
aca88567
NC
9266/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9267 DWARF debug sections. This is a target specific test. Note - we do not
9268 go through the whole including-target-headers-multiple-times route, (as
9269 we have already done with <elf/h8.h>) because this would become very
9270 messy and even then this function would have to contain target specific
9271 information (the names of the relocs instead of their numeric values).
9272 FIXME: This is not the correct way to solve this problem. The proper way
9273 is to have target specific reloc sizing and typing functions created by
9274 the reloc-macros.h header, in the same way that it already creates the
9275 reloc naming functions. */
9276
9277static bfd_boolean
9278is_32bit_abs_reloc (unsigned int reloc_type)
9279{
9280 switch (elf_header.e_machine)
9281 {
41e92641
NC
9282 case EM_386:
9283 case EM_486:
9284 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9285 case EM_68K:
9286 return reloc_type == 1; /* R_68K_32. */
9287 case EM_860:
9288 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9289 case EM_960:
9290 return reloc_type == 2; /* R_960_32. */
aca88567 9291 case EM_ALPHA:
137b6b5f 9292 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
9293 case EM_ARC:
9294 return reloc_type == 1; /* R_ARC_32. */
9295 case EM_ARM:
9296 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 9297 case EM_AVR_OLD:
aca88567
NC
9298 case EM_AVR:
9299 return reloc_type == 1;
9300 case EM_BLACKFIN:
9301 return reloc_type == 0x12; /* R_byte4_data. */
9302 case EM_CRIS:
9303 return reloc_type == 3; /* R_CRIS_32. */
9304 case EM_CR16:
6c03b1ed 9305 case EM_CR16_OLD:
aca88567
NC
9306 return reloc_type == 3; /* R_CR16_NUM32. */
9307 case EM_CRX:
9308 return reloc_type == 15; /* R_CRX_NUM32. */
9309 case EM_CYGNUS_FRV:
9310 return reloc_type == 1;
41e92641
NC
9311 case EM_CYGNUS_D10V:
9312 case EM_D10V:
9313 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
9314 case EM_CYGNUS_D30V:
9315 case EM_D30V:
9316 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
9317 case EM_DLX:
9318 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
9319 case EM_CYGNUS_FR30:
9320 case EM_FR30:
9321 return reloc_type == 3; /* R_FR30_32. */
9322 case EM_H8S:
9323 case EM_H8_300:
9324 case EM_H8_300H:
9325 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
9326 case EM_IA_64:
9327 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
9328 case EM_IP2K_OLD:
9329 case EM_IP2K:
9330 return reloc_type == 2; /* R_IP2K_32. */
9331 case EM_IQ2000:
9332 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
9333 case EM_LATTICEMICO32:
9334 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 9335 case EM_M32C_OLD:
aca88567
NC
9336 case EM_M32C:
9337 return reloc_type == 3; /* R_M32C_32. */
9338 case EM_M32R:
9339 return reloc_type == 34; /* R_M32R_32_RELA. */
9340 case EM_MCORE:
9341 return reloc_type == 1; /* R_MCORE_ADDR32. */
9342 case EM_CYGNUS_MEP:
9343 return reloc_type == 4; /* R_MEP_32. */
137b6b5f
AM
9344 case EM_MICROBLAZE:
9345 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
9346 case EM_MIPS:
9347 return reloc_type == 2; /* R_MIPS_32. */
9348 case EM_MMIX:
9349 return reloc_type == 4; /* R_MMIX_32. */
9350 case EM_CYGNUS_MN10200:
9351 case EM_MN10200:
9352 return reloc_type == 1; /* R_MN10200_32. */
9353 case EM_CYGNUS_MN10300:
9354 case EM_MN10300:
9355 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
9356 case EM_MOXIE:
9357 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
9358 case EM_MSP430_OLD:
9359 case EM_MSP430:
9360 return reloc_type == 1; /* R_MSP43_32. */
9361 case EM_MT:
9362 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
9363 case EM_ALTERA_NIOS2:
9364 case EM_NIOS32:
9365 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
9366 case EM_OPENRISC:
9367 case EM_OR32:
9368 return reloc_type == 1; /* R_OR32_32. */
aca88567 9369 case EM_PARISC:
5fda8eca
NC
9370 return (reloc_type == 1 /* R_PARISC_DIR32. */
9371 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
9372 case EM_PJ:
9373 case EM_PJ_OLD:
9374 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
9375 case EM_PPC64:
9376 return reloc_type == 1; /* R_PPC64_ADDR32. */
9377 case EM_PPC:
9378 return reloc_type == 1; /* R_PPC_ADDR32. */
c7927a3c
NC
9379 case EM_RX:
9380 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
9381 case EM_S370:
9382 return reloc_type == 1; /* R_I370_ADDR31. */
9383 case EM_S390_OLD:
9384 case EM_S390:
9385 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
9386 case EM_SCORE:
9387 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
9388 case EM_SH:
9389 return reloc_type == 1; /* R_SH_DIR32. */
9390 case EM_SPARC32PLUS:
9391 case EM_SPARCV9:
9392 case EM_SPARC:
9393 return reloc_type == 3 /* R_SPARC_32. */
9394 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
9395 case EM_SPU:
9396 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
9397 case EM_TI_C6000:
9398 return reloc_type == 1; /* R_C6000_ABS32. */
aca88567
NC
9399 case EM_CYGNUS_V850:
9400 case EM_V850:
9401 return reloc_type == 6; /* R_V850_ABS32. */
9402 case EM_VAX:
9403 return reloc_type == 1; /* R_VAX_32. */
9404 case EM_X86_64:
8a9036a4 9405 case EM_L1OM:
aca88567 9406 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
9407 case EM_XC16X:
9408 case EM_C166:
9409 return reloc_type == 3; /* R_XC16C_ABS_32. */
aca88567
NC
9410 case EM_XSTORMY16:
9411 return reloc_type == 1; /* R_XSTROMY16_32. */
9412 case EM_XTENSA_OLD:
9413 case EM_XTENSA:
9414 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
9415 default:
9416 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
9417 elf_header.e_machine);
9418 abort ();
9419 }
9420}
9421
9422/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9423 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
9424
9425static bfd_boolean
9426is_32bit_pcrel_reloc (unsigned int reloc_type)
9427{
9428 switch (elf_header.e_machine)
9429 {
41e92641
NC
9430 case EM_386:
9431 case EM_486:
3e0873ac 9432 return reloc_type == 2; /* R_386_PC32. */
aca88567 9433 case EM_68K:
3e0873ac 9434 return reloc_type == 4; /* R_68K_PC32. */
aca88567
NC
9435 case EM_ALPHA:
9436 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 9437 case EM_ARM:
3e0873ac 9438 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
9439 case EM_MICROBLAZE:
9440 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 9441 case EM_PARISC:
85acf597 9442 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
9443 case EM_PPC:
9444 return reloc_type == 26; /* R_PPC_REL32. */
9445 case EM_PPC64:
3e0873ac 9446 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
9447 case EM_S390_OLD:
9448 case EM_S390:
3e0873ac 9449 return reloc_type == 5; /* R_390_PC32. */
aca88567 9450 case EM_SH:
3e0873ac 9451 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
9452 case EM_SPARC32PLUS:
9453 case EM_SPARCV9:
9454 case EM_SPARC:
3e0873ac 9455 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
9456 case EM_SPU:
9457 return reloc_type == 13; /* R_SPU_REL32. */
aca88567 9458 case EM_X86_64:
8a9036a4 9459 case EM_L1OM:
3e0873ac 9460 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
9461 case EM_XTENSA_OLD:
9462 case EM_XTENSA:
9463 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
9464 default:
9465 /* Do not abort or issue an error message here. Not all targets use
9466 pc-relative 32-bit relocs in their DWARF debug information and we
9467 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
9468 more helpful warning message will be generated by apply_relocations
9469 anyway, so just return. */
aca88567
NC
9470 return FALSE;
9471 }
9472}
9473
9474/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9475 a 64-bit absolute RELA relocation used in DWARF debug sections. */
9476
9477static bfd_boolean
9478is_64bit_abs_reloc (unsigned int reloc_type)
9479{
9480 switch (elf_header.e_machine)
9481 {
9482 case EM_ALPHA:
9483 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
9484 case EM_IA_64:
9485 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
9486 case EM_PARISC:
9487 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
9488 case EM_PPC64:
9489 return reloc_type == 38; /* R_PPC64_ADDR64. */
9490 case EM_SPARC32PLUS:
9491 case EM_SPARCV9:
9492 case EM_SPARC:
9493 return reloc_type == 54; /* R_SPARC_UA64. */
9494 case EM_X86_64:
8a9036a4 9495 case EM_L1OM:
aca88567 9496 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
9497 case EM_S390_OLD:
9498 case EM_S390:
9499 return reloc_type == 22; /* R_S390_64 */
85a82265
AM
9500 case EM_MIPS:
9501 return reloc_type == 18; /* R_MIPS_64 */
aca88567
NC
9502 default:
9503 return FALSE;
9504 }
9505}
9506
85acf597
RH
9507/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
9508 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
9509
9510static bfd_boolean
9511is_64bit_pcrel_reloc (unsigned int reloc_type)
9512{
9513 switch (elf_header.e_machine)
9514 {
9515 case EM_ALPHA:
9516 return reloc_type == 11; /* R_ALPHA_SREL64 */
9517 case EM_IA_64:
9518 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB */
9519 case EM_PARISC:
9520 return reloc_type == 72; /* R_PARISC_PCREL64 */
9521 case EM_PPC64:
9522 return reloc_type == 44; /* R_PPC64_REL64 */
9523 case EM_SPARC32PLUS:
9524 case EM_SPARCV9:
9525 case EM_SPARC:
9526 return reloc_type == 46; /* R_SPARC_DISP64 */
9527 case EM_X86_64:
8a9036a4 9528 case EM_L1OM:
85acf597
RH
9529 return reloc_type == 24; /* R_X86_64_PC64 */
9530 case EM_S390_OLD:
9531 case EM_S390:
9532 return reloc_type == 23; /* R_S390_PC64 */
9533 default:
9534 return FALSE;
9535 }
9536}
9537
4dc3c23d
AM
9538/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9539 a 24-bit absolute RELA relocation used in DWARF debug sections. */
9540
9541static bfd_boolean
9542is_24bit_abs_reloc (unsigned int reloc_type)
9543{
9544 switch (elf_header.e_machine)
9545 {
9546 case EM_CYGNUS_MN10200:
9547 case EM_MN10200:
9548 return reloc_type == 4; /* R_MN10200_24. */
9549 default:
9550 return FALSE;
9551 }
9552}
9553
aca88567
NC
9554/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9555 a 16-bit absolute RELA relocation used in DWARF debug sections. */
9556
9557static bfd_boolean
9558is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
9559{
9560 switch (elf_header.e_machine)
9561 {
aca88567
NC
9562 case EM_AVR_OLD:
9563 case EM_AVR:
9564 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
9565 case EM_CYGNUS_D10V:
9566 case EM_D10V:
9567 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
9568 case EM_H8S:
9569 case EM_H8_300:
9570 case EM_H8_300H:
aca88567
NC
9571 return reloc_type == R_H8_DIR16;
9572 case EM_IP2K_OLD:
9573 case EM_IP2K:
9574 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 9575 case EM_M32C_OLD:
f4236fe4
DD
9576 case EM_M32C:
9577 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
9578 case EM_MSP430_OLD:
9579 case EM_MSP430:
9580 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
9581 case EM_ALTERA_NIOS2:
9582 case EM_NIOS32:
9583 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
9584 case EM_TI_C6000:
9585 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
9586 case EM_XC16X:
9587 case EM_C166:
9588 return reloc_type == 2; /* R_XC16C_ABS_16. */
4b78141a 9589 default:
aca88567 9590 return FALSE;
4b78141a
NC
9591 }
9592}
9593
2a7b2e88
JK
9594/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
9595 relocation entries (possibly formerly used for SHT_GROUP sections). */
9596
9597static bfd_boolean
9598is_none_reloc (unsigned int reloc_type)
9599{
9600 switch (elf_header.e_machine)
9601 {
cb8f3167
NC
9602 case EM_68K: /* R_68K_NONE. */
9603 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
9604 case EM_SPARC32PLUS:
9605 case EM_SPARCV9:
cb8f3167
NC
9606 case EM_SPARC: /* R_SPARC_NONE. */
9607 case EM_MIPS: /* R_MIPS_NONE. */
9608 case EM_PARISC: /* R_PARISC_NONE. */
9609 case EM_ALPHA: /* R_ALPHA_NONE. */
9610 case EM_PPC: /* R_PPC_NONE. */
9611 case EM_PPC64: /* R_PPC64_NONE. */
9612 case EM_ARM: /* R_ARM_NONE. */
9613 case EM_IA_64: /* R_IA64_NONE. */
9614 case EM_SH: /* R_SH_NONE. */
2a7b2e88 9615 case EM_S390_OLD:
cb8f3167
NC
9616 case EM_S390: /* R_390_NONE. */
9617 case EM_CRIS: /* R_CRIS_NONE. */
9618 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 9619 case EM_L1OM: /* R_X86_64_NONE. */
cb8f3167 9620 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 9621 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 9622 case EM_M32R: /* R_M32R_NONE. */
40b36596 9623 case EM_TI_C6000:/* R_C6000_NONE. */
c29aca4a
NC
9624 case EM_XC16X:
9625 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 9626 return reloc_type == 0;
58332dda
JK
9627 case EM_XTENSA_OLD:
9628 case EM_XTENSA:
4dc3c23d
AM
9629 return (reloc_type == 0 /* R_XTENSA_NONE. */
9630 || reloc_type == 17 /* R_XTENSA_DIFF8. */
9631 || reloc_type == 18 /* R_XTENSA_DIFF16. */
9632 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
9633 }
9634 return FALSE;
9635}
9636
cf13d699
NC
9637/* Apply relocations to a section.
9638 Note: So far support has been added only for those relocations
9639 which can be found in debug sections.
9640 FIXME: Add support for more relocations ? */
1b315056 9641
cf13d699
NC
9642static void
9643apply_relocations (void * file,
9644 Elf_Internal_Shdr * section,
9645 unsigned char * start)
1b315056 9646{
cf13d699
NC
9647 Elf_Internal_Shdr * relsec;
9648 unsigned char * end = start + section->sh_size;
cb8f3167 9649
cf13d699
NC
9650 if (elf_header.e_type != ET_REL)
9651 return;
1b315056 9652
cf13d699 9653 /* Find the reloc section associated with the section. */
5b18a4bc
NC
9654 for (relsec = section_headers;
9655 relsec < section_headers + elf_header.e_shnum;
9656 ++relsec)
252b5132 9657 {
41e92641
NC
9658 bfd_boolean is_rela;
9659 unsigned long num_relocs;
2cf0635d
NC
9660 Elf_Internal_Rela * relocs;
9661 Elf_Internal_Rela * rp;
9662 Elf_Internal_Shdr * symsec;
9663 Elf_Internal_Sym * symtab;
9664 Elf_Internal_Sym * sym;
252b5132 9665
41e92641 9666 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
9667 || relsec->sh_info >= elf_header.e_shnum
9668 || section_headers + relsec->sh_info != section
c256ffe7 9669 || relsec->sh_size == 0
4fbb74a6 9670 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 9671 continue;
428409d5 9672
41e92641
NC
9673 is_rela = relsec->sh_type == SHT_RELA;
9674
9675 if (is_rela)
9676 {
3f5e193b
NC
9677 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
9678 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
9679 return;
9680 }
9681 else
9682 {
3f5e193b
NC
9683 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
9684 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
9685 return;
9686 }
9687
9688 /* SH uses RELA but uses in place value instead of the addend field. */
9689 if (elf_header.e_machine == EM_SH)
9690 is_rela = FALSE;
428409d5 9691
4fbb74a6 9692 symsec = section_headers + relsec->sh_link;
3f5e193b 9693 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
103f02d3 9694
41e92641 9695 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 9696 {
41e92641
NC
9697 bfd_vma addend;
9698 unsigned int reloc_type;
9699 unsigned int reloc_size;
91d6fa6a 9700 unsigned char * rloc;
4b78141a 9701
aca88567 9702 reloc_type = get_reloc_type (rp->r_info);
41e92641 9703
98fb390a 9704 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 9705 continue;
98fb390a
NC
9706 else if (is_none_reloc (reloc_type))
9707 continue;
9708 else if (is_32bit_abs_reloc (reloc_type)
9709 || is_32bit_pcrel_reloc (reloc_type))
aca88567 9710 reloc_size = 4;
85acf597
RH
9711 else if (is_64bit_abs_reloc (reloc_type)
9712 || is_64bit_pcrel_reloc (reloc_type))
aca88567 9713 reloc_size = 8;
4dc3c23d
AM
9714 else if (is_24bit_abs_reloc (reloc_type))
9715 reloc_size = 3;
aca88567
NC
9716 else if (is_16bit_abs_reloc (reloc_type))
9717 reloc_size = 2;
9718 else
4b78141a 9719 {
41e92641 9720 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 9721 reloc_type, SECTION_NAME (section));
4b78141a
NC
9722 continue;
9723 }
103f02d3 9724
91d6fa6a
NC
9725 rloc = start + rp->r_offset;
9726 if ((rloc + reloc_size) > end)
700dd8b7
L
9727 {
9728 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
9729 (unsigned long) rp->r_offset,
9730 SECTION_NAME (section));
9731 continue;
9732 }
103f02d3 9733
41e92641
NC
9734 sym = symtab + get_reloc_symindex (rp->r_info);
9735
9736 /* If the reloc has a symbol associated with it,
55f25fc3
L
9737 make sure that it is of an appropriate type.
9738
9739 Relocations against symbols without type can happen.
9740 Gcc -feliminate-dwarf2-dups may generate symbols
9741 without type for debug info.
9742
9743 Icc generates relocations against function symbols
9744 instead of local labels.
9745
9746 Relocations against object symbols can happen, eg when
9747 referencing a global array. For an example of this see
9748 the _clz.o binary in libgcc.a. */
aca88567 9749 if (sym != symtab
55f25fc3 9750 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 9751 {
41e92641 9752 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 9753 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 9754 (long int)(rp - relocs),
41e92641 9755 SECTION_NAME (relsec));
aca88567 9756 continue;
5b18a4bc 9757 }
252b5132 9758
4dc3c23d
AM
9759 addend = 0;
9760 if (is_rela)
9761 addend += rp->r_addend;
c47320c3
AM
9762 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
9763 partial_inplace. */
4dc3c23d
AM
9764 if (!is_rela
9765 || (elf_header.e_machine == EM_XTENSA
9766 && reloc_type == 1)
9767 || ((elf_header.e_machine == EM_PJ
9768 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
9769 && reloc_type == 1)
9770 || ((elf_header.e_machine == EM_D30V
9771 || elf_header.e_machine == EM_CYGNUS_D30V)
9772 && reloc_type == 12))
91d6fa6a 9773 addend += byte_get (rloc, reloc_size);
cb8f3167 9774
85acf597
RH
9775 if (is_32bit_pcrel_reloc (reloc_type)
9776 || is_64bit_pcrel_reloc (reloc_type))
9777 {
9778 /* On HPPA, all pc-relative relocations are biased by 8. */
9779 if (elf_header.e_machine == EM_PARISC)
9780 addend -= 8;
91d6fa6a 9781 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
9782 reloc_size);
9783 }
41e92641 9784 else
91d6fa6a 9785 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 9786 }
252b5132 9787
5b18a4bc 9788 free (symtab);
41e92641 9789 free (relocs);
5b18a4bc
NC
9790 break;
9791 }
5b18a4bc 9792}
103f02d3 9793
cf13d699
NC
9794#ifdef SUPPORT_DISASSEMBLY
9795static int
9796disassemble_section (Elf_Internal_Shdr * section, FILE * file)
9797{
9798 printf (_("\nAssembly dump of section %s\n"),
9799 SECTION_NAME (section));
9800
9801 /* XXX -- to be done --- XXX */
9802
9803 return 1;
9804}
9805#endif
9806
9807/* Reads in the contents of SECTION from FILE, returning a pointer
9808 to a malloc'ed buffer or NULL if something went wrong. */
9809
9810static char *
9811get_section_contents (Elf_Internal_Shdr * section, FILE * file)
9812{
9813 bfd_size_type num_bytes;
9814
9815 num_bytes = section->sh_size;
9816
9817 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
9818 {
9819 printf (_("\nSection '%s' has no data to dump.\n"),
9820 SECTION_NAME (section));
9821 return NULL;
9822 }
9823
3f5e193b
NC
9824 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
9825 _("section contents"));
cf13d699
NC
9826}
9827
dd24e3da 9828
cf13d699
NC
9829static void
9830dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
9831{
9832 Elf_Internal_Shdr * relsec;
9833 bfd_size_type num_bytes;
cf13d699
NC
9834 char * data;
9835 char * end;
9836 char * start;
9837 char * name = SECTION_NAME (section);
9838 bfd_boolean some_strings_shown;
9839
9840 start = get_section_contents (section, file);
9841 if (start == NULL)
9842 return;
9843
9844 printf (_("\nString dump of section '%s':\n"), name);
9845
9846 /* If the section being dumped has relocations against it the user might
9847 be expecting these relocations to have been applied. Check for this
9848 case and issue a warning message in order to avoid confusion.
9849 FIXME: Maybe we ought to have an option that dumps a section with
9850 relocs applied ? */
9851 for (relsec = section_headers;
9852 relsec < section_headers + elf_header.e_shnum;
9853 ++relsec)
9854 {
9855 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
9856 || relsec->sh_info >= elf_header.e_shnum
9857 || section_headers + relsec->sh_info != section
9858 || relsec->sh_size == 0
9859 || relsec->sh_link >= elf_header.e_shnum)
9860 continue;
9861
9862 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
9863 break;
9864 }
9865
9866 num_bytes = section->sh_size;
cf13d699
NC
9867 data = start;
9868 end = start + num_bytes;
9869 some_strings_shown = FALSE;
9870
9871 while (data < end)
9872 {
9873 while (!ISPRINT (* data))
9874 if (++ data >= end)
9875 break;
9876
9877 if (data < end)
9878 {
9879#ifndef __MSVCRT__
c975cc98
NC
9880 /* PR 11128: Use two separate invocations in order to work
9881 around bugs in the Solaris 8 implementation of printf. */
9882 printf (" [%6tx] ", data - start);
9883 printf ("%s\n", data);
cf13d699
NC
9884#else
9885 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
9886#endif
9887 data += strlen (data);
9888 some_strings_shown = TRUE;
9889 }
9890 }
9891
9892 if (! some_strings_shown)
9893 printf (_(" No strings found in this section."));
9894
9895 free (start);
9896
9897 putchar ('\n');
9898}
9899
9900static void
9901dump_section_as_bytes (Elf_Internal_Shdr * section,
9902 FILE * file,
9903 bfd_boolean relocate)
9904{
9905 Elf_Internal_Shdr * relsec;
9906 bfd_size_type bytes;
9907 bfd_vma addr;
9908 unsigned char * data;
9909 unsigned char * start;
9910
9911 start = (unsigned char *) get_section_contents (section, file);
9912 if (start == NULL)
9913 return;
9914
9915 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
9916
9917 if (relocate)
9918 {
9919 apply_relocations (file, section, start);
9920 }
9921 else
9922 {
9923 /* If the section being dumped has relocations against it the user might
9924 be expecting these relocations to have been applied. Check for this
9925 case and issue a warning message in order to avoid confusion.
9926 FIXME: Maybe we ought to have an option that dumps a section with
9927 relocs applied ? */
9928 for (relsec = section_headers;
9929 relsec < section_headers + elf_header.e_shnum;
9930 ++relsec)
9931 {
9932 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
9933 || relsec->sh_info >= elf_header.e_shnum
9934 || section_headers + relsec->sh_info != section
9935 || relsec->sh_size == 0
9936 || relsec->sh_link >= elf_header.e_shnum)
9937 continue;
9938
9939 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
9940 break;
9941 }
9942 }
9943
9944 addr = section->sh_addr;
9945 bytes = section->sh_size;
9946 data = start;
9947
9948 while (bytes)
9949 {
9950 int j;
9951 int k;
9952 int lbytes;
9953
9954 lbytes = (bytes > 16 ? 16 : bytes);
9955
9956 printf (" 0x%8.8lx ", (unsigned long) addr);
9957
9958 for (j = 0; j < 16; j++)
9959 {
9960 if (j < lbytes)
9961 printf ("%2.2x", data[j]);
9962 else
9963 printf (" ");
9964
9965 if ((j & 3) == 3)
9966 printf (" ");
9967 }
9968
9969 for (j = 0; j < lbytes; j++)
9970 {
9971 k = data[j];
9972 if (k >= ' ' && k < 0x7f)
9973 printf ("%c", k);
9974 else
9975 printf (".");
9976 }
9977
9978 putchar ('\n');
9979
9980 data += lbytes;
9981 addr += lbytes;
9982 bytes -= lbytes;
9983 }
9984
9985 free (start);
9986
9987 putchar ('\n');
9988}
9989
4a114e3e 9990/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
9991
9992static int
d3dbc530
AM
9993uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
9994 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
9995{
9996#ifndef HAVE_ZLIB_H
cf13d699
NC
9997 return FALSE;
9998#else
9999 dwarf_size_type compressed_size = *size;
10000 unsigned char * compressed_buffer = *buffer;
10001 dwarf_size_type uncompressed_size;
10002 unsigned char * uncompressed_buffer;
10003 z_stream strm;
10004 int rc;
10005 dwarf_size_type header_size = 12;
10006
10007 /* Read the zlib header. In this case, it should be "ZLIB" followed
10008 by the uncompressed section size, 8 bytes in big-endian order. */
10009 if (compressed_size < header_size
10010 || ! streq ((char *) compressed_buffer, "ZLIB"))
10011 return 0;
10012
10013 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10014 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10015 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10016 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10017 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10018 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10019 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10020 uncompressed_size += compressed_buffer[11];
10021
10022 /* It is possible the section consists of several compressed
10023 buffers concatenated together, so we uncompress in a loop. */
10024 strm.zalloc = NULL;
10025 strm.zfree = NULL;
10026 strm.opaque = NULL;
10027 strm.avail_in = compressed_size - header_size;
10028 strm.next_in = (Bytef *) compressed_buffer + header_size;
10029 strm.avail_out = uncompressed_size;
3f5e193b 10030 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10031
10032 rc = inflateInit (& strm);
10033 while (strm.avail_in > 0)
10034 {
10035 if (rc != Z_OK)
10036 goto fail;
10037 strm.next_out = ((Bytef *) uncompressed_buffer
10038 + (uncompressed_size - strm.avail_out));
10039 rc = inflate (&strm, Z_FINISH);
10040 if (rc != Z_STREAM_END)
10041 goto fail;
10042 rc = inflateReset (& strm);
10043 }
10044 rc = inflateEnd (& strm);
10045 if (rc != Z_OK
10046 || strm.avail_out != 0)
10047 goto fail;
10048
10049 free (compressed_buffer);
10050 *buffer = uncompressed_buffer;
10051 *size = uncompressed_size;
10052 return 1;
10053
10054 fail:
10055 free (uncompressed_buffer);
4a114e3e
L
10056 /* Indicate decompression failure. */
10057 *buffer = NULL;
cf13d699
NC
10058 return 0;
10059#endif /* HAVE_ZLIB_H */
10060}
10061
d966045b
DJ
10062static int
10063load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10064 Elf_Internal_Shdr * sec, void * file)
1007acb3 10065{
2cf0635d 10066 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10067 char buf [64];
1007acb3 10068
19e6b90e
L
10069 /* If it is already loaded, do nothing. */
10070 if (section->start != NULL)
10071 return 1;
1007acb3 10072
19e6b90e
L
10073 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10074 section->address = sec->sh_addr;
10075 section->size = sec->sh_size;
3f5e193b
NC
10076 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10077 sec->sh_offset, 1,
10078 sec->sh_size, buf);
4a114e3e
L
10079 if (uncompress_section_contents (&section->start, &section->size))
10080 sec->sh_size = section->size;
10081
1b315056
CS
10082 if (section->start == NULL)
10083 return 0;
10084
19e6b90e 10085 if (debug_displays [debug].relocate)
3f5e193b 10086 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10087
1b315056 10088 return 1;
1007acb3
L
10089}
10090
d966045b 10091int
2cf0635d 10092load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10093{
2cf0635d
NC
10094 struct dwarf_section * section = &debug_displays [debug].section;
10095 Elf_Internal_Shdr * sec;
d966045b
DJ
10096
10097 /* Locate the debug section. */
10098 sec = find_section (section->uncompressed_name);
10099 if (sec != NULL)
10100 section->name = section->uncompressed_name;
10101 else
10102 {
10103 sec = find_section (section->compressed_name);
10104 if (sec != NULL)
10105 section->name = section->compressed_name;
10106 }
10107 if (sec == NULL)
10108 return 0;
10109
3f5e193b 10110 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10111}
10112
19e6b90e
L
10113void
10114free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10115{
2cf0635d 10116 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10117
19e6b90e
L
10118 if (section->start == NULL)
10119 return;
1007acb3 10120
19e6b90e
L
10121 free ((char *) section->start);
10122 section->start = NULL;
10123 section->address = 0;
10124 section->size = 0;
1007acb3
L
10125}
10126
1007acb3 10127static int
2cf0635d 10128display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 10129{
2cf0635d 10130 char * name = SECTION_NAME (section);
19e6b90e
L
10131 bfd_size_type length;
10132 int result = 1;
3f5e193b 10133 int i;
1007acb3 10134
19e6b90e
L
10135 length = section->sh_size;
10136 if (length == 0)
1007acb3 10137 {
19e6b90e
L
10138 printf (_("\nSection '%s' has no debugging data.\n"), name);
10139 return 0;
1007acb3 10140 }
5dff79d8
NC
10141 if (section->sh_type == SHT_NOBITS)
10142 {
10143 /* There is no point in dumping the contents of a debugging section
10144 which has the NOBITS type - the bits in the file will be random.
10145 This can happen when a file containing a .eh_frame section is
10146 stripped with the --only-keep-debug command line option. */
10147 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10148 return 0;
10149 }
1007acb3 10150
0112cd26 10151 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10152 name = ".debug_info";
1007acb3 10153
19e6b90e
L
10154 /* See if we know how to display the contents of this section. */
10155 for (i = 0; i < max; i++)
1b315056
CS
10156 if (streq (debug_displays[i].section.uncompressed_name, name)
10157 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10158 {
2cf0635d 10159 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10160 int secondary = (section != find_section (name));
10161
10162 if (secondary)
3f5e193b 10163 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10164
2b6f5997 10165 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10166 sec->name = sec->uncompressed_name;
10167 else
10168 sec->name = sec->compressed_name;
3f5e193b
NC
10169 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10170 section, file))
19e6b90e
L
10171 {
10172 result &= debug_displays[i].display (sec, file);
1007acb3 10173
d966045b 10174 if (secondary || (i != info && i != abbrev))
3f5e193b 10175 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10176 }
1007acb3 10177
19e6b90e
L
10178 break;
10179 }
1007acb3 10180
19e6b90e 10181 if (i == max)
1007acb3 10182 {
19e6b90e
L
10183 printf (_("Unrecognized debug section: %s\n"), name);
10184 result = 0;
1007acb3
L
10185 }
10186
19e6b90e 10187 return result;
5b18a4bc 10188}
103f02d3 10189
aef1f6d0
DJ
10190/* Set DUMP_SECTS for all sections where dumps were requested
10191 based on section name. */
10192
10193static void
10194initialise_dumps_byname (void)
10195{
2cf0635d 10196 struct dump_list_entry * cur;
aef1f6d0
DJ
10197
10198 for (cur = dump_sects_byname; cur; cur = cur->next)
10199 {
10200 unsigned int i;
10201 int any;
10202
10203 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10204 if (streq (SECTION_NAME (section_headers + i), cur->name))
10205 {
09c11c86 10206 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10207 any = 1;
10208 }
10209
10210 if (!any)
10211 warn (_("Section '%s' was not dumped because it does not exist!\n"),
10212 cur->name);
10213 }
10214}
10215
5b18a4bc 10216static void
2cf0635d 10217process_section_contents (FILE * file)
5b18a4bc 10218{
2cf0635d 10219 Elf_Internal_Shdr * section;
19e6b90e 10220 unsigned int i;
103f02d3 10221
19e6b90e
L
10222 if (! do_dump)
10223 return;
103f02d3 10224
aef1f6d0
DJ
10225 initialise_dumps_byname ();
10226
19e6b90e
L
10227 for (i = 0, section = section_headers;
10228 i < elf_header.e_shnum && i < num_dump_sects;
10229 i++, section++)
10230 {
10231#ifdef SUPPORT_DISASSEMBLY
10232 if (dump_sects[i] & DISASS_DUMP)
10233 disassemble_section (section, file);
10234#endif
10235 if (dump_sects[i] & HEX_DUMP)
cf13d699 10236 dump_section_as_bytes (section, file, FALSE);
103f02d3 10237
cf13d699
NC
10238 if (dump_sects[i] & RELOC_DUMP)
10239 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
10240
10241 if (dump_sects[i] & STRING_DUMP)
10242 dump_section_as_strings (section, file);
cf13d699
NC
10243
10244 if (dump_sects[i] & DEBUG_DUMP)
10245 display_debug_section (section, file);
5b18a4bc 10246 }
103f02d3 10247
19e6b90e
L
10248 /* Check to see if the user requested a
10249 dump of a section that does not exist. */
10250 while (i++ < num_dump_sects)
10251 if (dump_sects[i])
10252 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 10253}
103f02d3 10254
5b18a4bc 10255static void
19e6b90e 10256process_mips_fpe_exception (int mask)
5b18a4bc 10257{
19e6b90e
L
10258 if (mask)
10259 {
10260 int first = 1;
10261 if (mask & OEX_FPU_INEX)
10262 fputs ("INEX", stdout), first = 0;
10263 if (mask & OEX_FPU_UFLO)
10264 printf ("%sUFLO", first ? "" : "|"), first = 0;
10265 if (mask & OEX_FPU_OFLO)
10266 printf ("%sOFLO", first ? "" : "|"), first = 0;
10267 if (mask & OEX_FPU_DIV0)
10268 printf ("%sDIV0", first ? "" : "|"), first = 0;
10269 if (mask & OEX_FPU_INVAL)
10270 printf ("%sINVAL", first ? "" : "|");
10271 }
5b18a4bc 10272 else
19e6b90e 10273 fputs ("0", stdout);
5b18a4bc 10274}
103f02d3 10275
11c1ff18
PB
10276/* ARM EABI attributes section. */
10277typedef struct
10278{
10279 int tag;
2cf0635d 10280 const char * name;
11c1ff18
PB
10281 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
10282 int type;
2cf0635d 10283 const char ** table;
11c1ff18
PB
10284} arm_attr_public_tag;
10285
2cf0635d 10286static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 10287 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
9e3c6df6 10288 "v6K", "v7", "v6-M", "v6S-M", "v7E-M"};
2cf0635d
NC
10289static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
10290static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 10291 {"No", "Thumb-1", "Thumb-2"};
75375b3e 10292static const char * arm_attr_tag_FP_arch[] =
62f3b8c8 10293 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
2cf0635d 10294static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 10295static const char * arm_attr_tag_Advanced_SIMD_arch[] =
cd21e546 10296 {"No", "NEONv1", "NEONv1 with Fused-MAC"};
2cf0635d 10297static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
10298 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
10299 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 10300static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 10301 {"V6", "SB", "TLS", "Unused"};
2cf0635d 10302static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 10303 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 10304static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 10305 {"Absolute", "PC-relative", "None"};
2cf0635d 10306static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 10307 {"None", "direct", "GOT-indirect"};
2cf0635d 10308static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 10309 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
10310static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
10311static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 10312 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
10313static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
10314static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
10315static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 10316 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 10317static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 10318 {"Unused", "small", "int", "forced to int"};
2cf0635d 10319static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 10320 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 10321static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 10322 {"AAPCS", "VFP registers", "custom"};
2cf0635d 10323static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 10324 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 10325static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
10326 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10327 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 10328static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
10329 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10330 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 10331static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 10332static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 10333 {"Not Allowed", "Allowed"};
2cf0635d 10334static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 10335 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 10336static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
10337 {"Not Allowed", "Allowed"};
10338static const char * arm_attr_tag_DIV_use[] =
dd24e3da 10339 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 10340 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
10341static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
10342static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 10343 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 10344 "TrustZone and Virtualization Extensions"};
dd24e3da 10345static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 10346 {"Not Allowed", "Allowed"};
11c1ff18
PB
10347
10348#define LOOKUP(id, name) \
10349 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 10350static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
10351{
10352 {4, "CPU_raw_name", 1, NULL},
10353 {5, "CPU_name", 1, NULL},
10354 LOOKUP(6, CPU_arch),
10355 {7, "CPU_arch_profile", 0, NULL},
10356 LOOKUP(8, ARM_ISA_use),
10357 LOOKUP(9, THUMB_ISA_use),
75375b3e 10358 LOOKUP(10, FP_arch),
11c1ff18 10359 LOOKUP(11, WMMX_arch),
f5f53991
AS
10360 LOOKUP(12, Advanced_SIMD_arch),
10361 LOOKUP(13, PCS_config),
11c1ff18
PB
10362 LOOKUP(14, ABI_PCS_R9_use),
10363 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 10364 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
10365 LOOKUP(17, ABI_PCS_GOT_use),
10366 LOOKUP(18, ABI_PCS_wchar_t),
10367 LOOKUP(19, ABI_FP_rounding),
10368 LOOKUP(20, ABI_FP_denormal),
10369 LOOKUP(21, ABI_FP_exceptions),
10370 LOOKUP(22, ABI_FP_user_exceptions),
10371 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
10372 {24, "ABI_align_needed", 0, NULL},
10373 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
10374 LOOKUP(26, ABI_enum_size),
10375 LOOKUP(27, ABI_HardFP_use),
10376 LOOKUP(28, ABI_VFP_args),
10377 LOOKUP(29, ABI_WMMX_args),
10378 LOOKUP(30, ABI_optimization_goals),
10379 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 10380 {32, "compatibility", 0, NULL},
f5f53991 10381 LOOKUP(34, CPU_unaligned_access),
75375b3e 10382 LOOKUP(36, FP_HP_extension),
8e79c3df 10383 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
10384 LOOKUP(42, MPextension_use),
10385 LOOKUP(44, DIV_use),
f5f53991
AS
10386 {64, "nodefaults", 0, NULL},
10387 {65, "also_compatible_with", 0, NULL},
10388 LOOKUP(66, T2EE_use),
10389 {67, "conformance", 1, NULL},
10390 LOOKUP(68, Virtualization_use),
cd21e546 10391 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
10392};
10393#undef LOOKUP
10394
11c1ff18 10395static unsigned char *
2cf0635d 10396display_arm_attribute (unsigned char * p)
11c1ff18
PB
10397{
10398 int tag;
10399 unsigned int len;
10400 int val;
2cf0635d 10401 arm_attr_public_tag * attr;
11c1ff18
PB
10402 unsigned i;
10403 int type;
10404
10405 tag = read_uleb128 (p, &len);
10406 p += len;
10407 attr = NULL;
2cf0635d 10408 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
10409 {
10410 if (arm_attr_public_tags[i].tag == tag)
10411 {
10412 attr = &arm_attr_public_tags[i];
10413 break;
10414 }
10415 }
10416
10417 if (attr)
10418 {
10419 printf (" Tag_%s: ", attr->name);
10420 switch (attr->type)
10421 {
10422 case 0:
10423 switch (tag)
10424 {
10425 case 7: /* Tag_CPU_arch_profile. */
10426 val = read_uleb128 (p, &len);
10427 p += len;
10428 switch (val)
10429 {
2b692964
NC
10430 case 0: printf (_("None\n")); break;
10431 case 'A': printf (_("Application\n")); break;
10432 case 'R': printf (_("Realtime\n")); break;
10433 case 'M': printf (_("Microcontroller\n")); break;
10434 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
10435 default: printf ("??? (%d)\n", val); break;
10436 }
10437 break;
10438
75375b3e
MGD
10439 case 24: /* Tag_align_needed. */
10440 val = read_uleb128 (p, &len);
10441 p += len;
10442 switch (val)
10443 {
2b692964
NC
10444 case 0: printf (_("None\n")); break;
10445 case 1: printf (_("8-byte\n")); break;
10446 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
10447 case 3: printf ("??? 3\n"); break;
10448 default:
10449 if (val <= 12)
dd24e3da 10450 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10451 1 << val);
10452 else
10453 printf ("??? (%d)\n", val);
10454 break;
10455 }
10456 break;
10457
10458 case 25: /* Tag_align_preserved. */
10459 val = read_uleb128 (p, &len);
10460 p += len;
10461 switch (val)
10462 {
2b692964
NC
10463 case 0: printf (_("None\n")); break;
10464 case 1: printf (_("8-byte, except leaf SP\n")); break;
10465 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
10466 case 3: printf ("??? 3\n"); break;
10467 default:
10468 if (val <= 12)
dd24e3da 10469 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10470 1 << val);
10471 else
10472 printf ("??? (%d)\n", val);
10473 break;
10474 }
10475 break;
10476
11c1ff18
PB
10477 case 32: /* Tag_compatibility. */
10478 val = read_uleb128 (p, &len);
10479 p += len;
2b692964 10480 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 10481 p += strlen ((char *) p) + 1;
11c1ff18
PB
10482 break;
10483
f5f53991
AS
10484 case 64: /* Tag_nodefaults. */
10485 p++;
2b692964 10486 printf (_("True\n"));
f5f53991
AS
10487 break;
10488
10489 case 65: /* Tag_also_compatible_with. */
10490 val = read_uleb128 (p, &len);
10491 p += len;
10492 if (val == 6 /* Tag_CPU_arch. */)
10493 {
10494 val = read_uleb128 (p, &len);
10495 p += len;
2cf0635d 10496 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
10497 printf ("??? (%d)\n", val);
10498 else
10499 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
10500 }
10501 else
10502 printf ("???\n");
10503 while (*(p++) != '\0' /* NUL terminator. */);
10504 break;
10505
11c1ff18 10506 default:
2cf0635d 10507 abort ();
11c1ff18
PB
10508 }
10509 return p;
10510
10511 case 1:
10512 case 2:
10513 type = attr->type;
10514 break;
10515
10516 default:
10517 assert (attr->type & 0x80);
10518 val = read_uleb128 (p, &len);
10519 p += len;
10520 type = attr->type & 0x7f;
10521 if (val >= type)
10522 printf ("??? (%d)\n", val);
10523 else
10524 printf ("%s\n", attr->table[val]);
10525 return p;
10526 }
10527 }
10528 else
10529 {
10530 if (tag & 1)
10531 type = 1; /* String. */
10532 else
10533 type = 2; /* uleb128. */
10534 printf (" Tag_unknown_%d: ", tag);
10535 }
10536
10537 if (type == 1)
10538 {
10539 printf ("\"%s\"\n", p);
2cf0635d 10540 p += strlen ((char *) p) + 1;
11c1ff18
PB
10541 }
10542 else
10543 {
10544 val = read_uleb128 (p, &len);
10545 p += len;
10546 printf ("%d (0x%x)\n", val, val);
10547 }
10548
10549 return p;
10550}
10551
104d59d1 10552static unsigned char *
60bca95a
NC
10553display_gnu_attribute (unsigned char * p,
10554 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
10555{
10556 int tag;
10557 unsigned int len;
10558 int val;
10559 int type;
10560
10561 tag = read_uleb128 (p, &len);
10562 p += len;
10563
10564 /* Tag_compatibility is the only generic GNU attribute defined at
10565 present. */
10566 if (tag == 32)
10567 {
10568 val = read_uleb128 (p, &len);
10569 p += len;
2b692964 10570 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 10571 p += strlen ((char *) p) + 1;
104d59d1
JM
10572 return p;
10573 }
10574
10575 if ((tag & 2) == 0 && display_proc_gnu_attribute)
10576 return display_proc_gnu_attribute (p, tag);
10577
10578 if (tag & 1)
10579 type = 1; /* String. */
10580 else
10581 type = 2; /* uleb128. */
10582 printf (" Tag_unknown_%d: ", tag);
10583
10584 if (type == 1)
10585 {
10586 printf ("\"%s\"\n", p);
60bca95a 10587 p += strlen ((char *) p) + 1;
104d59d1
JM
10588 }
10589 else
10590 {
10591 val = read_uleb128 (p, &len);
10592 p += len;
10593 printf ("%d (0x%x)\n", val, val);
10594 }
10595
10596 return p;
10597}
10598
34c8bcba 10599static unsigned char *
2cf0635d 10600display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
10601{
10602 int type;
10603 unsigned int len;
10604 int val;
10605
10606 if (tag == Tag_GNU_Power_ABI_FP)
10607 {
10608 val = read_uleb128 (p, &len);
10609 p += len;
10610 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 10611
34c8bcba
JM
10612 switch (val)
10613 {
10614 case 0:
2b692964 10615 printf (_("Hard or soft float\n"));
34c8bcba
JM
10616 break;
10617 case 1:
2b692964 10618 printf (_("Hard float\n"));
34c8bcba
JM
10619 break;
10620 case 2:
2b692964 10621 printf (_("Soft float\n"));
34c8bcba 10622 break;
3c7b9897 10623 case 3:
2b692964 10624 printf (_("Single-precision hard float\n"));
3c7b9897 10625 break;
34c8bcba
JM
10626 default:
10627 printf ("??? (%d)\n", val);
10628 break;
10629 }
10630 return p;
10631 }
10632
c6e65352
DJ
10633 if (tag == Tag_GNU_Power_ABI_Vector)
10634 {
10635 val = read_uleb128 (p, &len);
10636 p += len;
10637 printf (" Tag_GNU_Power_ABI_Vector: ");
10638 switch (val)
10639 {
10640 case 0:
2b692964 10641 printf (_("Any\n"));
c6e65352
DJ
10642 break;
10643 case 1:
2b692964 10644 printf (_("Generic\n"));
c6e65352
DJ
10645 break;
10646 case 2:
10647 printf ("AltiVec\n");
10648 break;
10649 case 3:
10650 printf ("SPE\n");
10651 break;
10652 default:
10653 printf ("??? (%d)\n", val);
10654 break;
10655 }
10656 return p;
10657 }
10658
f82e0623
NF
10659 if (tag == Tag_GNU_Power_ABI_Struct_Return)
10660 {
10661 val = read_uleb128 (p, &len);
10662 p += len;
10663 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
10664 switch (val)
10665 {
10666 case 0:
2b692964 10667 printf (_("Any\n"));
f82e0623
NF
10668 break;
10669 case 1:
10670 printf ("r3/r4\n");
10671 break;
10672 case 2:
2b692964 10673 printf (_("Memory\n"));
f82e0623
NF
10674 break;
10675 default:
10676 printf ("??? (%d)\n", val);
10677 break;
10678 }
10679 return p;
10680 }
10681
34c8bcba
JM
10682 if (tag & 1)
10683 type = 1; /* String. */
10684 else
10685 type = 2; /* uleb128. */
10686 printf (" Tag_unknown_%d: ", tag);
10687
10688 if (type == 1)
10689 {
10690 printf ("\"%s\"\n", p);
60bca95a 10691 p += strlen ((char *) p) + 1;
34c8bcba
JM
10692 }
10693 else
10694 {
10695 val = read_uleb128 (p, &len);
10696 p += len;
10697 printf ("%d (0x%x)\n", val, val);
10698 }
10699
10700 return p;
10701}
10702
2cf19d5c 10703static unsigned char *
2cf0635d 10704display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
10705{
10706 int type;
10707 unsigned int len;
10708 int val;
10709
10710 if (tag == Tag_GNU_MIPS_ABI_FP)
10711 {
10712 val = read_uleb128 (p, &len);
10713 p += len;
10714 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 10715
2cf19d5c
JM
10716 switch (val)
10717 {
10718 case 0:
2b692964 10719 printf (_("Hard or soft float\n"));
2cf19d5c
JM
10720 break;
10721 case 1:
2b692964 10722 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
10723 break;
10724 case 2:
2b692964 10725 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
10726 break;
10727 case 3:
2b692964 10728 printf (_("Soft float\n"));
2cf19d5c 10729 break;
42554f6a 10730 case 4:
9eeefea8 10731 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 10732 break;
2cf19d5c
JM
10733 default:
10734 printf ("??? (%d)\n", val);
10735 break;
10736 }
10737 return p;
10738 }
10739
10740 if (tag & 1)
10741 type = 1; /* String. */
10742 else
10743 type = 2; /* uleb128. */
10744 printf (" Tag_unknown_%d: ", tag);
10745
10746 if (type == 1)
10747 {
10748 printf ("\"%s\"\n", p);
60bca95a 10749 p += strlen ((char *) p) + 1;
2cf19d5c
JM
10750 }
10751 else
10752 {
10753 val = read_uleb128 (p, &len);
10754 p += len;
10755 printf ("%d (0x%x)\n", val, val);
10756 }
10757
10758 return p;
10759}
10760
59e6276b
JM
10761static unsigned char *
10762display_tic6x_attribute (unsigned char * p)
10763{
10764 int tag;
10765 unsigned int len;
10766 int val;
10767
10768 tag = read_uleb128 (p, &len);
10769 p += len;
10770
10771 switch (tag)
10772 {
75fa6dc1 10773 case Tag_ISA:
59e6276b
JM
10774 val = read_uleb128 (p, &len);
10775 p += len;
75fa6dc1 10776 printf (" Tag_ISA: ");
59e6276b
JM
10777
10778 switch (val)
10779 {
75fa6dc1 10780 case C6XABI_Tag_ISA_none:
59e6276b
JM
10781 printf (_("None\n"));
10782 break;
75fa6dc1 10783 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
10784 printf ("C62x\n");
10785 break;
75fa6dc1 10786 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
10787 printf ("C67x\n");
10788 break;
75fa6dc1 10789 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
10790 printf ("C67x+\n");
10791 break;
75fa6dc1 10792 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
10793 printf ("C64x\n");
10794 break;
75fa6dc1 10795 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
10796 printf ("C64x+\n");
10797 break;
75fa6dc1 10798 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
10799 printf ("C674x\n");
10800 break;
10801 default:
10802 printf ("??? (%d)\n", val);
10803 break;
10804 }
10805 return p;
10806
b5593623
JM
10807 case Tag_ABI_DSBT:
10808 val = read_uleb128 (p, &len);
10809 p += len;
10810 printf (" Tag_ABI_DSBT: ");
10811 switch (val)
10812 {
10813 case 0:
10814 printf (_("DSBT addressing not used\n"));
10815 break;
10816 case 1:
10817 printf (_("DSBT addressing used\n"));
10818 break;
10819 default:
10820 printf ("??? (%d)\n", val);
10821 break;
10822 }
10823 return p;
10824
59e6276b
JM
10825 case 32:
10826 /* Tag_compatibility - treated as generic by binutils for now
10827 although not currently specified for C6X. */
10828 val = read_uleb128 (p, &len);
10829 p += len;
10830 printf (_("flag = %d, vendor = %s\n"), val, p);
10831 p += strlen ((char *) p) + 1;
10832 return p;
10833 }
10834
10835 printf (" Tag_unknown_%d: ", tag);
10836
10837 /* No general documentation of handling unknown attributes, treat as
10838 ULEB128 for now. */
10839 val = read_uleb128 (p, &len);
10840 p += len;
10841 printf ("%d (0x%x)\n", val, val);
10842
10843 return p;
10844}
10845
11c1ff18 10846static int
60bca95a
NC
10847process_attributes (FILE * file,
10848 const char * public_name,
104d59d1 10849 unsigned int proc_type,
60bca95a
NC
10850 unsigned char * (* display_pub_attribute) (unsigned char *),
10851 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 10852{
2cf0635d
NC
10853 Elf_Internal_Shdr * sect;
10854 unsigned char * contents;
10855 unsigned char * p;
10856 unsigned char * end;
11c1ff18
PB
10857 bfd_vma section_len;
10858 bfd_vma len;
10859 unsigned i;
10860
10861 /* Find the section header so that we get the size. */
10862 for (i = 0, sect = section_headers;
10863 i < elf_header.e_shnum;
10864 i++, sect++)
10865 {
104d59d1 10866 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
10867 continue;
10868
3f5e193b
NC
10869 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
10870 sect->sh_size, _("attributes"));
60bca95a 10871 if (contents == NULL)
11c1ff18 10872 continue;
60bca95a 10873
11c1ff18
PB
10874 p = contents;
10875 if (*p == 'A')
10876 {
10877 len = sect->sh_size - 1;
10878 p++;
60bca95a 10879
11c1ff18
PB
10880 while (len > 0)
10881 {
10882 int namelen;
10883 bfd_boolean public_section;
104d59d1 10884 bfd_boolean gnu_section;
11c1ff18
PB
10885
10886 section_len = byte_get (p, 4);
10887 p += 4;
60bca95a 10888
11c1ff18
PB
10889 if (section_len > len)
10890 {
10891 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 10892 (int) section_len, (int) len);
11c1ff18
PB
10893 section_len = len;
10894 }
60bca95a 10895
11c1ff18 10896 len -= section_len;
2b692964 10897 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
10898
10899 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
10900 public_section = TRUE;
10901 else
10902 public_section = FALSE;
60bca95a
NC
10903
10904 if (streq ((char *) p, "gnu"))
104d59d1
JM
10905 gnu_section = TRUE;
10906 else
10907 gnu_section = FALSE;
60bca95a
NC
10908
10909 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
10910 p += namelen;
10911 section_len -= namelen + 4;
60bca95a 10912
11c1ff18
PB
10913 while (section_len > 0)
10914 {
10915 int tag = *(p++);
10916 int val;
10917 bfd_vma size;
60bca95a 10918
11c1ff18
PB
10919 size = byte_get (p, 4);
10920 if (size > section_len)
10921 {
10922 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 10923 (int) size, (int) section_len);
11c1ff18
PB
10924 size = section_len;
10925 }
60bca95a 10926
11c1ff18
PB
10927 section_len -= size;
10928 end = p + size - 1;
10929 p += 4;
60bca95a 10930
11c1ff18
PB
10931 switch (tag)
10932 {
10933 case 1:
2b692964 10934 printf (_("File Attributes\n"));
11c1ff18
PB
10935 break;
10936 case 2:
2b692964 10937 printf (_("Section Attributes:"));
11c1ff18
PB
10938 goto do_numlist;
10939 case 3:
2b692964 10940 printf (_("Symbol Attributes:"));
11c1ff18
PB
10941 do_numlist:
10942 for (;;)
10943 {
91d6fa6a 10944 unsigned int j;
60bca95a 10945
91d6fa6a
NC
10946 val = read_uleb128 (p, &j);
10947 p += j;
11c1ff18
PB
10948 if (val == 0)
10949 break;
10950 printf (" %d", val);
10951 }
10952 printf ("\n");
10953 break;
10954 default:
2b692964 10955 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
10956 public_section = FALSE;
10957 break;
10958 }
60bca95a 10959
11c1ff18
PB
10960 if (public_section)
10961 {
10962 while (p < end)
104d59d1
JM
10963 p = display_pub_attribute (p);
10964 }
10965 else if (gnu_section)
10966 {
10967 while (p < end)
10968 p = display_gnu_attribute (p,
10969 display_proc_gnu_attribute);
11c1ff18
PB
10970 }
10971 else
10972 {
10973 /* ??? Do something sensible, like dump hex. */
2b692964 10974 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
10975 p = end;
10976 }
10977 }
10978 }
10979 }
10980 else
60bca95a 10981 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 10982
60bca95a 10983 free (contents);
11c1ff18
PB
10984 }
10985 return 1;
10986}
10987
104d59d1 10988static int
2cf0635d 10989process_arm_specific (FILE * file)
104d59d1
JM
10990{
10991 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
10992 display_arm_attribute, NULL);
10993}
10994
34c8bcba 10995static int
2cf0635d 10996process_power_specific (FILE * file)
34c8bcba
JM
10997{
10998 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
10999 display_power_gnu_attribute);
11000}
11001
59e6276b
JM
11002static int
11003process_tic6x_specific (FILE * file)
11004{
11005 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
11006 display_tic6x_attribute, NULL);
11007}
11008
ccb4c951
RS
11009/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
11010 Print the Address, Access and Initial fields of an entry at VMA ADDR
11011 and return the VMA of the next entry. */
11012
11013static bfd_vma
2cf0635d 11014print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
11015{
11016 printf (" ");
11017 print_vma (addr, LONG_HEX);
11018 printf (" ");
11019 if (addr < pltgot + 0xfff0)
11020 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
11021 else
11022 printf ("%10s", "");
11023 printf (" ");
11024 if (data == NULL)
2b692964 11025 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
11026 else
11027 {
11028 bfd_vma entry;
11029
11030 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11031 print_vma (entry, LONG_HEX);
11032 }
11033 return addr + (is_32bit_elf ? 4 : 8);
11034}
11035
861fb55a
DJ
11036/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
11037 PLTGOT. Print the Address and Initial fields of an entry at VMA
11038 ADDR and return the VMA of the next entry. */
11039
11040static bfd_vma
2cf0635d 11041print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
11042{
11043 printf (" ");
11044 print_vma (addr, LONG_HEX);
11045 printf (" ");
11046 if (data == NULL)
2b692964 11047 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
11048 else
11049 {
11050 bfd_vma entry;
11051
11052 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11053 print_vma (entry, LONG_HEX);
11054 }
11055 return addr + (is_32bit_elf ? 4 : 8);
11056}
11057
19e6b90e 11058static int
2cf0635d 11059process_mips_specific (FILE * file)
5b18a4bc 11060{
2cf0635d 11061 Elf_Internal_Dyn * entry;
19e6b90e
L
11062 size_t liblist_offset = 0;
11063 size_t liblistno = 0;
11064 size_t conflictsno = 0;
11065 size_t options_offset = 0;
11066 size_t conflicts_offset = 0;
861fb55a
DJ
11067 size_t pltrelsz = 0;
11068 size_t pltrel = 0;
ccb4c951 11069 bfd_vma pltgot = 0;
861fb55a
DJ
11070 bfd_vma mips_pltgot = 0;
11071 bfd_vma jmprel = 0;
ccb4c951
RS
11072 bfd_vma local_gotno = 0;
11073 bfd_vma gotsym = 0;
11074 bfd_vma symtabno = 0;
103f02d3 11075
2cf19d5c
JM
11076 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11077 display_mips_gnu_attribute);
11078
19e6b90e
L
11079 /* We have a lot of special sections. Thanks SGI! */
11080 if (dynamic_section == NULL)
11081 /* No information available. */
11082 return 0;
252b5132 11083
b2d38a17 11084 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
11085 switch (entry->d_tag)
11086 {
11087 case DT_MIPS_LIBLIST:
d93f0186
NC
11088 liblist_offset
11089 = offset_from_vma (file, entry->d_un.d_val,
11090 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
11091 break;
11092 case DT_MIPS_LIBLISTNO:
11093 liblistno = entry->d_un.d_val;
11094 break;
11095 case DT_MIPS_OPTIONS:
d93f0186 11096 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
11097 break;
11098 case DT_MIPS_CONFLICT:
d93f0186
NC
11099 conflicts_offset
11100 = offset_from_vma (file, entry->d_un.d_val,
11101 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
11102 break;
11103 case DT_MIPS_CONFLICTNO:
11104 conflictsno = entry->d_un.d_val;
11105 break;
ccb4c951 11106 case DT_PLTGOT:
861fb55a
DJ
11107 pltgot = entry->d_un.d_ptr;
11108 break;
ccb4c951
RS
11109 case DT_MIPS_LOCAL_GOTNO:
11110 local_gotno = entry->d_un.d_val;
11111 break;
11112 case DT_MIPS_GOTSYM:
11113 gotsym = entry->d_un.d_val;
11114 break;
11115 case DT_MIPS_SYMTABNO:
11116 symtabno = entry->d_un.d_val;
11117 break;
861fb55a
DJ
11118 case DT_MIPS_PLTGOT:
11119 mips_pltgot = entry->d_un.d_ptr;
11120 break;
11121 case DT_PLTREL:
11122 pltrel = entry->d_un.d_val;
11123 break;
11124 case DT_PLTRELSZ:
11125 pltrelsz = entry->d_un.d_val;
11126 break;
11127 case DT_JMPREL:
11128 jmprel = entry->d_un.d_ptr;
11129 break;
252b5132
RH
11130 default:
11131 break;
11132 }
11133
11134 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
11135 {
2cf0635d 11136 Elf32_External_Lib * elib;
252b5132
RH
11137 size_t cnt;
11138
3f5e193b
NC
11139 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
11140 liblistno,
11141 sizeof (Elf32_External_Lib),
11142 _("liblist"));
a6e9f9df 11143 if (elib)
252b5132 11144 {
2b692964 11145 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 11146 (unsigned long) liblistno);
2b692964 11147 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
11148 stdout);
11149
11150 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 11151 {
a6e9f9df 11152 Elf32_Lib liblist;
91d6fa6a 11153 time_t atime;
a6e9f9df 11154 char timebuf[20];
2cf0635d 11155 struct tm * tmp;
a6e9f9df
AM
11156
11157 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 11158 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
11159 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11160 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11161 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11162
91d6fa6a 11163 tmp = gmtime (&atime);
e9e44622
JJ
11164 snprintf (timebuf, sizeof (timebuf),
11165 "%04u-%02u-%02uT%02u:%02u:%02u",
11166 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11167 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 11168
31104126 11169 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
11170 if (VALID_DYNAMIC_NAME (liblist.l_name))
11171 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
11172 else
2b692964 11173 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
11174 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
11175 liblist.l_version);
a6e9f9df
AM
11176
11177 if (liblist.l_flags == 0)
2b692964 11178 puts (_(" NONE"));
a6e9f9df
AM
11179 else
11180 {
11181 static const struct
252b5132 11182 {
2cf0635d 11183 const char * name;
a6e9f9df 11184 int bit;
252b5132 11185 }
a6e9f9df
AM
11186 l_flags_vals[] =
11187 {
11188 { " EXACT_MATCH", LL_EXACT_MATCH },
11189 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
11190 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
11191 { " EXPORTS", LL_EXPORTS },
11192 { " DELAY_LOAD", LL_DELAY_LOAD },
11193 { " DELTA", LL_DELTA }
11194 };
11195 int flags = liblist.l_flags;
11196 size_t fcnt;
11197
60bca95a 11198 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
11199 if ((flags & l_flags_vals[fcnt].bit) != 0)
11200 {
11201 fputs (l_flags_vals[fcnt].name, stdout);
11202 flags ^= l_flags_vals[fcnt].bit;
11203 }
11204 if (flags != 0)
11205 printf (" %#x", (unsigned int) flags);
252b5132 11206
a6e9f9df
AM
11207 puts ("");
11208 }
252b5132 11209 }
252b5132 11210
a6e9f9df
AM
11211 free (elib);
11212 }
252b5132
RH
11213 }
11214
11215 if (options_offset != 0)
11216 {
2cf0635d
NC
11217 Elf_External_Options * eopt;
11218 Elf_Internal_Shdr * sect = section_headers;
11219 Elf_Internal_Options * iopt;
11220 Elf_Internal_Options * option;
252b5132
RH
11221 size_t offset;
11222 int cnt;
11223
11224 /* Find the section header so that we get the size. */
11225 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 11226 ++sect;
252b5132 11227
3f5e193b
NC
11228 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
11229 sect->sh_size, _("options"));
a6e9f9df 11230 if (eopt)
252b5132 11231 {
3f5e193b
NC
11232 iopt = (Elf_Internal_Options *)
11233 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
11234 if (iopt == NULL)
11235 {
591a748a 11236 error (_("Out of memory\n"));
a6e9f9df
AM
11237 return 0;
11238 }
76da6bbe 11239
a6e9f9df
AM
11240 offset = cnt = 0;
11241 option = iopt;
252b5132 11242
a6e9f9df
AM
11243 while (offset < sect->sh_size)
11244 {
2cf0635d 11245 Elf_External_Options * eoption;
252b5132 11246
a6e9f9df 11247 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 11248
a6e9f9df
AM
11249 option->kind = BYTE_GET (eoption->kind);
11250 option->size = BYTE_GET (eoption->size);
11251 option->section = BYTE_GET (eoption->section);
11252 option->info = BYTE_GET (eoption->info);
76da6bbe 11253
a6e9f9df 11254 offset += option->size;
252b5132 11255
a6e9f9df
AM
11256 ++option;
11257 ++cnt;
11258 }
252b5132 11259
a6e9f9df
AM
11260 printf (_("\nSection '%s' contains %d entries:\n"),
11261 SECTION_NAME (sect), cnt);
76da6bbe 11262
a6e9f9df 11263 option = iopt;
252b5132 11264
a6e9f9df 11265 while (cnt-- > 0)
252b5132 11266 {
a6e9f9df
AM
11267 size_t len;
11268
11269 switch (option->kind)
252b5132 11270 {
a6e9f9df
AM
11271 case ODK_NULL:
11272 /* This shouldn't happen. */
11273 printf (" NULL %d %lx", option->section, option->info);
11274 break;
11275 case ODK_REGINFO:
11276 printf (" REGINFO ");
11277 if (elf_header.e_machine == EM_MIPS)
11278 {
11279 /* 32bit form. */
2cf0635d 11280 Elf32_External_RegInfo * ereg;
b34976b6 11281 Elf32_RegInfo reginfo;
a6e9f9df
AM
11282
11283 ereg = (Elf32_External_RegInfo *) (option + 1);
11284 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11285 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11286 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11287 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11288 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
11289 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
11290
11291 printf ("GPR %08lx GP 0x%lx\n",
11292 reginfo.ri_gprmask,
11293 (unsigned long) reginfo.ri_gp_value);
11294 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11295 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11296 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11297 }
11298 else
11299 {
11300 /* 64 bit form. */
2cf0635d 11301 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
11302 Elf64_Internal_RegInfo reginfo;
11303
11304 ereg = (Elf64_External_RegInfo *) (option + 1);
11305 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11306 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11307 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11308 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11309 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 11310 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
11311
11312 printf ("GPR %08lx GP 0x",
11313 reginfo.ri_gprmask);
11314 printf_vma (reginfo.ri_gp_value);
11315 printf ("\n");
11316
11317 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11318 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11319 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11320 }
11321 ++option;
11322 continue;
11323 case ODK_EXCEPTIONS:
11324 fputs (" EXCEPTIONS fpe_min(", stdout);
11325 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
11326 fputs (") fpe_max(", stdout);
11327 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
11328 fputs (")", stdout);
11329
11330 if (option->info & OEX_PAGE0)
11331 fputs (" PAGE0", stdout);
11332 if (option->info & OEX_SMM)
11333 fputs (" SMM", stdout);
11334 if (option->info & OEX_FPDBUG)
11335 fputs (" FPDBUG", stdout);
11336 if (option->info & OEX_DISMISS)
11337 fputs (" DISMISS", stdout);
11338 break;
11339 case ODK_PAD:
11340 fputs (" PAD ", stdout);
11341 if (option->info & OPAD_PREFIX)
11342 fputs (" PREFIX", stdout);
11343 if (option->info & OPAD_POSTFIX)
11344 fputs (" POSTFIX", stdout);
11345 if (option->info & OPAD_SYMBOL)
11346 fputs (" SYMBOL", stdout);
11347 break;
11348 case ODK_HWPATCH:
11349 fputs (" HWPATCH ", stdout);
11350 if (option->info & OHW_R4KEOP)
11351 fputs (" R4KEOP", stdout);
11352 if (option->info & OHW_R8KPFETCH)
11353 fputs (" R8KPFETCH", stdout);
11354 if (option->info & OHW_R5KEOP)
11355 fputs (" R5KEOP", stdout);
11356 if (option->info & OHW_R5KCVTL)
11357 fputs (" R5KCVTL", stdout);
11358 break;
11359 case ODK_FILL:
11360 fputs (" FILL ", stdout);
11361 /* XXX Print content of info word? */
11362 break;
11363 case ODK_TAGS:
11364 fputs (" TAGS ", stdout);
11365 /* XXX Print content of info word? */
11366 break;
11367 case ODK_HWAND:
11368 fputs (" HWAND ", stdout);
11369 if (option->info & OHWA0_R4KEOP_CHECKED)
11370 fputs (" R4KEOP_CHECKED", stdout);
11371 if (option->info & OHWA0_R4KEOP_CLEAN)
11372 fputs (" R4KEOP_CLEAN", stdout);
11373 break;
11374 case ODK_HWOR:
11375 fputs (" HWOR ", stdout);
11376 if (option->info & OHWA0_R4KEOP_CHECKED)
11377 fputs (" R4KEOP_CHECKED", stdout);
11378 if (option->info & OHWA0_R4KEOP_CLEAN)
11379 fputs (" R4KEOP_CLEAN", stdout);
11380 break;
11381 case ODK_GP_GROUP:
11382 printf (" GP_GROUP %#06lx self-contained %#06lx",
11383 option->info & OGP_GROUP,
11384 (option->info & OGP_SELF) >> 16);
11385 break;
11386 case ODK_IDENT:
11387 printf (" IDENT %#06lx self-contained %#06lx",
11388 option->info & OGP_GROUP,
11389 (option->info & OGP_SELF) >> 16);
11390 break;
11391 default:
11392 /* This shouldn't happen. */
11393 printf (" %3d ??? %d %lx",
11394 option->kind, option->section, option->info);
11395 break;
252b5132 11396 }
a6e9f9df 11397
2cf0635d 11398 len = sizeof (* eopt);
a6e9f9df
AM
11399 while (len < option->size)
11400 if (((char *) option)[len] >= ' '
11401 && ((char *) option)[len] < 0x7f)
11402 printf ("%c", ((char *) option)[len++]);
11403 else
11404 printf ("\\%03o", ((char *) option)[len++]);
11405
11406 fputs ("\n", stdout);
252b5132 11407 ++option;
252b5132
RH
11408 }
11409
a6e9f9df 11410 free (eopt);
252b5132 11411 }
252b5132
RH
11412 }
11413
11414 if (conflicts_offset != 0 && conflictsno != 0)
11415 {
2cf0635d 11416 Elf32_Conflict * iconf;
252b5132
RH
11417 size_t cnt;
11418
11419 if (dynamic_symbols == NULL)
11420 {
591a748a 11421 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
11422 return 0;
11423 }
11424
3f5e193b 11425 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
11426 if (iconf == NULL)
11427 {
591a748a 11428 error (_("Out of memory\n"));
252b5132
RH
11429 return 0;
11430 }
11431
9ea033b2 11432 if (is_32bit_elf)
252b5132 11433 {
2cf0635d 11434 Elf32_External_Conflict * econf32;
a6e9f9df 11435
3f5e193b
NC
11436 econf32 = (Elf32_External_Conflict *)
11437 get_data (NULL, file, conflicts_offset, conflictsno,
11438 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
11439 if (!econf32)
11440 return 0;
252b5132
RH
11441
11442 for (cnt = 0; cnt < conflictsno; ++cnt)
11443 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
11444
11445 free (econf32);
252b5132
RH
11446 }
11447 else
11448 {
2cf0635d 11449 Elf64_External_Conflict * econf64;
a6e9f9df 11450
3f5e193b
NC
11451 econf64 = (Elf64_External_Conflict *)
11452 get_data (NULL, file, conflicts_offset, conflictsno,
11453 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
11454 if (!econf64)
11455 return 0;
252b5132
RH
11456
11457 for (cnt = 0; cnt < conflictsno; ++cnt)
11458 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
11459
11460 free (econf64);
252b5132
RH
11461 }
11462
c7e7ca54
NC
11463 printf (_("\nSection '.conflict' contains %lu entries:\n"),
11464 (unsigned long) conflictsno);
252b5132
RH
11465 puts (_(" Num: Index Value Name"));
11466
11467 for (cnt = 0; cnt < conflictsno; ++cnt)
11468 {
2cf0635d 11469 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 11470
b34976b6 11471 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 11472 print_vma (psym->st_value, FULL_HEX);
31104126 11473 putchar (' ');
d79b3d50
NC
11474 if (VALID_DYNAMIC_NAME (psym->st_name))
11475 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11476 else
2b692964 11477 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 11478 putchar ('\n');
252b5132
RH
11479 }
11480
252b5132
RH
11481 free (iconf);
11482 }
11483
ccb4c951
RS
11484 if (pltgot != 0 && local_gotno != 0)
11485 {
91d6fa6a 11486 bfd_vma ent, local_end, global_end;
bbeee7ea 11487 size_t i, offset;
2cf0635d 11488 unsigned char * data;
bbeee7ea 11489 int addr_size;
ccb4c951 11490
91d6fa6a 11491 ent = pltgot;
ccb4c951
RS
11492 addr_size = (is_32bit_elf ? 4 : 8);
11493 local_end = pltgot + local_gotno * addr_size;
11494 global_end = local_end + (symtabno - gotsym) * addr_size;
11495
11496 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b
NC
11497 data = (unsigned char *) get_data (NULL, file, offset,
11498 global_end - pltgot, 1, _("GOT"));
ccb4c951
RS
11499 printf (_("\nPrimary GOT:\n"));
11500 printf (_(" Canonical gp value: "));
11501 print_vma (pltgot + 0x7ff0, LONG_HEX);
11502 printf ("\n\n");
11503
11504 printf (_(" Reserved entries:\n"));
11505 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
11506 addr_size * 2, _("Address"), _("Access"),
11507 addr_size * 2, _("Initial"));
91d6fa6a 11508 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 11509 printf (_(" Lazy resolver\n"));
ccb4c951 11510 if (data
91d6fa6a 11511 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
11512 >> (addr_size * 8 - 1)) != 0)
11513 {
91d6fa6a 11514 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 11515 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
11516 }
11517 printf ("\n");
11518
91d6fa6a 11519 if (ent < local_end)
ccb4c951
RS
11520 {
11521 printf (_(" Local entries:\n"));
11522 printf (_(" %*s %10s %*s\n"),
2b692964
NC
11523 addr_size * 2, _("Address"), _("Access"),
11524 addr_size * 2, _("Initial"));
91d6fa6a 11525 while (ent < local_end)
ccb4c951 11526 {
91d6fa6a 11527 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
11528 printf ("\n");
11529 }
11530 printf ("\n");
11531 }
11532
11533 if (gotsym < symtabno)
11534 {
11535 int sym_width;
11536
11537 printf (_(" Global entries:\n"));
11538 printf (_(" %*s %10s %*s %*s %-7s %3s %s\n"),
2b692964
NC
11539 addr_size * 2, _("Address"), _("Access"),
11540 addr_size * 2, _("Initial"),
11541 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
ccb4c951
RS
11542 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
11543 for (i = gotsym; i < symtabno; i++)
11544 {
2cf0635d 11545 Elf_Internal_Sym * psym;
ccb4c951
RS
11546
11547 psym = dynamic_symbols + i;
91d6fa6a 11548 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
11549 printf (" ");
11550 print_vma (psym->st_value, LONG_HEX);
11551 printf (" %-7s %3s ",
11552 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
11553 get_symbol_index_type (psym->st_shndx));
11554 if (VALID_DYNAMIC_NAME (psym->st_name))
11555 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
11556 else
2b692964 11557 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
11558 printf ("\n");
11559 }
11560 printf ("\n");
11561 }
11562
11563 if (data)
11564 free (data);
11565 }
11566
861fb55a
DJ
11567 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
11568 {
91d6fa6a 11569 bfd_vma ent, end;
861fb55a
DJ
11570 size_t offset, rel_offset;
11571 unsigned long count, i;
2cf0635d 11572 unsigned char * data;
861fb55a 11573 int addr_size, sym_width;
2cf0635d 11574 Elf_Internal_Rela * rels;
861fb55a
DJ
11575
11576 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
11577 if (pltrel == DT_RELA)
11578 {
11579 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
11580 return 0;
11581 }
11582 else
11583 {
11584 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
11585 return 0;
11586 }
11587
91d6fa6a 11588 ent = mips_pltgot;
861fb55a
DJ
11589 addr_size = (is_32bit_elf ? 4 : 8);
11590 end = mips_pltgot + (2 + count) * addr_size;
11591
11592 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b
NC
11593 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
11594 1, _("PLT GOT"));
861fb55a
DJ
11595 printf (_("\nPLT GOT:\n\n"));
11596 printf (_(" Reserved entries:\n"));
11597 printf (_(" %*s %*s Purpose\n"),
2b692964 11598 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 11599 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 11600 printf (_(" PLT lazy resolver\n"));
91d6fa6a 11601 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 11602 printf (_(" Module pointer\n"));
861fb55a
DJ
11603 printf ("\n");
11604
11605 printf (_(" Entries:\n"));
11606 printf (_(" %*s %*s %*s %-7s %3s %s\n"),
2b692964
NC
11607 addr_size * 2, _("Address"),
11608 addr_size * 2, _("Initial"),
11609 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
11610 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
11611 for (i = 0; i < count; i++)
11612 {
2cf0635d 11613 Elf_Internal_Sym * psym;
861fb55a
DJ
11614
11615 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 11616 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
11617 printf (" ");
11618 print_vma (psym->st_value, LONG_HEX);
11619 printf (" %-7s %3s ",
11620 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
11621 get_symbol_index_type (psym->st_shndx));
11622 if (VALID_DYNAMIC_NAME (psym->st_name))
11623 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
11624 else
2b692964 11625 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
11626 printf ("\n");
11627 }
11628 printf ("\n");
11629
11630 if (data)
11631 free (data);
11632 free (rels);
11633 }
11634
252b5132
RH
11635 return 1;
11636}
11637
047b2264 11638static int
2cf0635d 11639process_gnu_liblist (FILE * file)
047b2264 11640{
2cf0635d
NC
11641 Elf_Internal_Shdr * section;
11642 Elf_Internal_Shdr * string_sec;
11643 Elf32_External_Lib * elib;
11644 char * strtab;
c256ffe7 11645 size_t strtab_size;
047b2264
JJ
11646 size_t cnt;
11647 unsigned i;
11648
11649 if (! do_arch)
11650 return 0;
11651
11652 for (i = 0, section = section_headers;
11653 i < elf_header.e_shnum;
b34976b6 11654 i++, section++)
047b2264
JJ
11655 {
11656 switch (section->sh_type)
11657 {
11658 case SHT_GNU_LIBLIST:
4fbb74a6 11659 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
11660 break;
11661
3f5e193b
NC
11662 elib = (Elf32_External_Lib *)
11663 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
11664 _("liblist"));
047b2264
JJ
11665
11666 if (elib == NULL)
11667 break;
4fbb74a6 11668 string_sec = section_headers + section->sh_link;
047b2264 11669
3f5e193b
NC
11670 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
11671 string_sec->sh_size,
11672 _("liblist string table"));
c256ffe7 11673 strtab_size = string_sec->sh_size;
047b2264
JJ
11674
11675 if (strtab == NULL
11676 || section->sh_entsize != sizeof (Elf32_External_Lib))
11677 {
11678 free (elib);
11679 break;
11680 }
11681
11682 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
11683 SECTION_NAME (section),
0af1713e 11684 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 11685
2b692964 11686 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
11687
11688 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
11689 ++cnt)
11690 {
11691 Elf32_Lib liblist;
91d6fa6a 11692 time_t atime;
047b2264 11693 char timebuf[20];
2cf0635d 11694 struct tm * tmp;
047b2264
JJ
11695
11696 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 11697 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
11698 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11699 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11700 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11701
91d6fa6a 11702 tmp = gmtime (&atime);
e9e44622
JJ
11703 snprintf (timebuf, sizeof (timebuf),
11704 "%04u-%02u-%02uT%02u:%02u:%02u",
11705 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11706 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11707
11708 printf ("%3lu: ", (unsigned long) cnt);
11709 if (do_wide)
c256ffe7 11710 printf ("%-20s", liblist.l_name < strtab_size
2b692964 11711 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 11712 else
c256ffe7 11713 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 11714 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
11715 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
11716 liblist.l_version, liblist.l_flags);
11717 }
11718
11719 free (elib);
11720 }
11721 }
11722
11723 return 1;
11724}
11725
9437c45b 11726static const char *
d3ba0551 11727get_note_type (unsigned e_type)
779fe533
NC
11728{
11729 static char buff[64];
103f02d3 11730
1ec5cd37
NC
11731 if (elf_header.e_type == ET_CORE)
11732 switch (e_type)
11733 {
57346661 11734 case NT_AUXV:
1ec5cd37 11735 return _("NT_AUXV (auxiliary vector)");
57346661 11736 case NT_PRSTATUS:
1ec5cd37 11737 return _("NT_PRSTATUS (prstatus structure)");
57346661 11738 case NT_FPREGSET:
1ec5cd37 11739 return _("NT_FPREGSET (floating point registers)");
57346661 11740 case NT_PRPSINFO:
1ec5cd37 11741 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 11742 case NT_TASKSTRUCT:
1ec5cd37 11743 return _("NT_TASKSTRUCT (task structure)");
57346661 11744 case NT_PRXFPREG:
1ec5cd37 11745 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
11746 case NT_PPC_VMX:
11747 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
11748 case NT_PPC_VSX:
11749 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
11750 case NT_X86_XSTATE:
11751 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
11752 case NT_S390_HIGH_GPRS:
11753 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
11754 case NT_S390_TIMER:
11755 return _("NT_S390_TIMER (s390 timer register)");
11756 case NT_S390_TODCMP:
11757 return _("NT_S390_TODCMP (s390 TOD comparator register)");
11758 case NT_S390_TODPREG:
11759 return _("NT_S390_TODPREG (s390 TOD programmable register)");
11760 case NT_S390_CTRS:
11761 return _("NT_S390_CTRS (s390 control registers)");
11762 case NT_S390_PREFIX:
11763 return _("NT_S390_PREFIX (s390 prefix register)");
57346661 11764 case NT_PSTATUS:
1ec5cd37 11765 return _("NT_PSTATUS (pstatus structure)");
57346661 11766 case NT_FPREGS:
1ec5cd37 11767 return _("NT_FPREGS (floating point registers)");
57346661 11768 case NT_PSINFO:
1ec5cd37 11769 return _("NT_PSINFO (psinfo structure)");
57346661 11770 case NT_LWPSTATUS:
1ec5cd37 11771 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 11772 case NT_LWPSINFO:
1ec5cd37 11773 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 11774 case NT_WIN32PSTATUS:
1ec5cd37
NC
11775 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
11776 default:
11777 break;
11778 }
11779 else
11780 switch (e_type)
11781 {
11782 case NT_VERSION:
11783 return _("NT_VERSION (version)");
11784 case NT_ARCH:
11785 return _("NT_ARCH (architecture)");
11786 default:
11787 break;
11788 }
11789
e9e44622 11790 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 11791 return buff;
779fe533
NC
11792}
11793
1118d252
RM
11794static const char *
11795get_gnu_elf_note_type (unsigned e_type)
11796{
11797 static char buff[64];
11798
11799 switch (e_type)
11800 {
11801 case NT_GNU_ABI_TAG:
11802 return _("NT_GNU_ABI_TAG (ABI version tag)");
11803 case NT_GNU_HWCAP:
11804 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
11805 case NT_GNU_BUILD_ID:
11806 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
11807 case NT_GNU_GOLD_VERSION:
11808 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
11809 default:
11810 break;
11811 }
11812
11813 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
11814 return buff;
11815}
11816
9437c45b 11817static const char *
d3ba0551 11818get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
11819{
11820 static char buff[64];
11821
b4db1224 11822 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
11823 {
11824 /* NetBSD core "procinfo" structure. */
11825 return _("NetBSD procinfo structure");
11826 }
11827
11828 /* As of Jan 2002 there are no other machine-independent notes
11829 defined for NetBSD core files. If the note type is less
11830 than the start of the machine-dependent note types, we don't
11831 understand it. */
11832
b4db1224 11833 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 11834 {
e9e44622 11835 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
11836 return buff;
11837 }
11838
11839 switch (elf_header.e_machine)
11840 {
11841 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
11842 and PT_GETFPREGS == mach+2. */
11843
11844 case EM_OLD_ALPHA:
11845 case EM_ALPHA:
11846 case EM_SPARC:
11847 case EM_SPARC32PLUS:
11848 case EM_SPARCV9:
11849 switch (e_type)
11850 {
2b692964 11851 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 11852 return _("PT_GETREGS (reg structure)");
2b692964 11853 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 11854 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11855 default:
11856 break;
11857 }
11858 break;
11859
11860 /* On all other arch's, PT_GETREGS == mach+1 and
11861 PT_GETFPREGS == mach+3. */
11862 default:
11863 switch (e_type)
11864 {
2b692964 11865 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 11866 return _("PT_GETREGS (reg structure)");
2b692964 11867 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 11868 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
11869 default:
11870 break;
11871 }
11872 }
11873
e9e44622
JJ
11874 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
11875 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
11876 return buff;
11877}
11878
6d118b09
NC
11879/* Note that by the ELF standard, the name field is already null byte
11880 terminated, and namesz includes the terminating null byte.
11881 I.E. the value of namesz for the name "FSF" is 4.
11882
e3c8793a 11883 If the value of namesz is zero, there is no name present. */
779fe533 11884static int
2cf0635d 11885process_note (Elf_Internal_Note * pnote)
779fe533 11886{
2cf0635d
NC
11887 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
11888 const char * nt;
9437c45b
JT
11889
11890 if (pnote->namesz == 0)
1ec5cd37
NC
11891 /* If there is no note name, then use the default set of
11892 note type strings. */
11893 nt = get_note_type (pnote->type);
11894
1118d252
RM
11895 else if (const_strneq (pnote->namedata, "GNU"))
11896 /* GNU-specific object file notes. */
11897 nt = get_gnu_elf_note_type (pnote->type);
11898
0112cd26 11899 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
11900 /* NetBSD-specific core file notes. */
11901 nt = get_netbsd_elfcore_note_type (pnote->type);
11902
b15fa79e
AM
11903 else if (strneq (pnote->namedata, "SPU/", 4))
11904 {
11905 /* SPU-specific core file notes. */
11906 nt = pnote->namedata + 4;
11907 name = "SPU";
11908 }
11909
9437c45b 11910 else
1ec5cd37
NC
11911 /* Don't recognize this note name; just use the default set of
11912 note type strings. */
9437c45b 11913 nt = get_note_type (pnote->type);
9437c45b 11914
b15fa79e 11915 printf (" %s\t\t0x%08lx\t%s\n", name, pnote->descsz, nt);
779fe533
NC
11916 return 1;
11917}
11918
6d118b09 11919
779fe533 11920static int
2cf0635d 11921process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 11922{
2cf0635d
NC
11923 Elf_External_Note * pnotes;
11924 Elf_External_Note * external;
b34976b6 11925 int res = 1;
103f02d3 11926
779fe533
NC
11927 if (length <= 0)
11928 return 0;
103f02d3 11929
3f5e193b
NC
11930 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
11931 _("notes"));
dd24e3da 11932 if (pnotes == NULL)
a6e9f9df 11933 return 0;
779fe533 11934
103f02d3 11935 external = pnotes;
103f02d3 11936
305c7206 11937 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 11938 (unsigned long) offset, (unsigned long) length);
779fe533 11939 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 11940
2cf0635d 11941 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 11942 {
2cf0635d 11943 Elf_External_Note * next;
b34976b6 11944 Elf_Internal_Note inote;
2cf0635d 11945 char * temp = NULL;
6d118b09
NC
11946
11947 inote.type = BYTE_GET (external->type);
11948 inote.namesz = BYTE_GET (external->namesz);
11949 inote.namedata = external->name;
11950 inote.descsz = BYTE_GET (external->descsz);
11951 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
11952 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 11953
2cf0635d 11954 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
3e55a963 11955
dd24e3da
NC
11956 if ( ((char *) next > ((char *) pnotes) + length)
11957 || ((char *) next < (char *) pnotes))
3e55a963 11958 {
0fd3a477 11959 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 11960 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 11961 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
11962 inote.type, inote.namesz, inote.descsz);
11963 break;
11964 }
11965
11966 external = next;
6d118b09 11967
dd24e3da
NC
11968 /* Prevent out-of-bounds indexing. */
11969 if (inote.namedata + inote.namesz >= (char *) pnotes + length
11970 || inote.namedata + inote.namesz < inote.namedata)
11971 {
11972 warn (_("corrupt note found at offset %lx into core notes\n"),
11973 (unsigned long) ((char *) external - (char *) pnotes));
11974 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
11975 inote.type, inote.namesz, inote.descsz);
11976 break;
11977 }
11978
6d118b09
NC
11979 /* Verify that name is null terminated. It appears that at least
11980 one version of Linux (RedHat 6.0) generates corefiles that don't
11981 comply with the ELF spec by failing to include the null byte in
11982 namesz. */
11983 if (inote.namedata[inote.namesz] != '\0')
11984 {
3f5e193b 11985 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 11986
6d118b09
NC
11987 if (temp == NULL)
11988 {
11989 error (_("Out of memory\n"));
11990 res = 0;
11991 break;
11992 }
76da6bbe 11993
6d118b09
NC
11994 strncpy (temp, inote.namedata, inote.namesz);
11995 temp[inote.namesz] = 0;
76da6bbe 11996
6d118b09
NC
11997 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
11998 inote.namedata = temp;
11999 }
12000
12001 res &= process_note (& inote);
103f02d3 12002
6d118b09
NC
12003 if (temp != NULL)
12004 {
12005 free (temp);
12006 temp = NULL;
12007 }
779fe533
NC
12008 }
12009
12010 free (pnotes);
103f02d3 12011
779fe533
NC
12012 return res;
12013}
12014
12015static int
2cf0635d 12016process_corefile_note_segments (FILE * file)
779fe533 12017{
2cf0635d 12018 Elf_Internal_Phdr * segment;
b34976b6
AM
12019 unsigned int i;
12020 int res = 1;
103f02d3 12021
d93f0186 12022 if (! get_program_headers (file))
779fe533 12023 return 0;
103f02d3 12024
779fe533
NC
12025 for (i = 0, segment = program_headers;
12026 i < elf_header.e_phnum;
b34976b6 12027 i++, segment++)
779fe533
NC
12028 {
12029 if (segment->p_type == PT_NOTE)
103f02d3 12030 res &= process_corefile_note_segment (file,
30800947
NC
12031 (bfd_vma) segment->p_offset,
12032 (bfd_vma) segment->p_filesz);
779fe533 12033 }
103f02d3 12034
779fe533
NC
12035 return res;
12036}
12037
12038static int
2cf0635d 12039process_note_sections (FILE * file)
1ec5cd37 12040{
2cf0635d 12041 Elf_Internal_Shdr * section;
1ec5cd37
NC
12042 unsigned long i;
12043 int res = 1;
12044
12045 for (i = 0, section = section_headers;
12046 i < elf_header.e_shnum;
12047 i++, section++)
12048 if (section->sh_type == SHT_NOTE)
12049 res &= process_corefile_note_segment (file,
12050 (bfd_vma) section->sh_offset,
12051 (bfd_vma) section->sh_size);
12052
12053 return res;
12054}
12055
12056static int
2cf0635d 12057process_notes (FILE * file)
779fe533
NC
12058{
12059 /* If we have not been asked to display the notes then do nothing. */
12060 if (! do_notes)
12061 return 1;
103f02d3 12062
779fe533 12063 if (elf_header.e_type != ET_CORE)
1ec5cd37 12064 return process_note_sections (file);
103f02d3 12065
779fe533 12066 /* No program headers means no NOTE segment. */
1ec5cd37
NC
12067 if (elf_header.e_phnum > 0)
12068 return process_corefile_note_segments (file);
779fe533 12069
1ec5cd37
NC
12070 printf (_("No note segments present in the core file.\n"));
12071 return 1;
779fe533
NC
12072}
12073
252b5132 12074static int
2cf0635d 12075process_arch_specific (FILE * file)
252b5132 12076{
a952a375
NC
12077 if (! do_arch)
12078 return 1;
12079
252b5132
RH
12080 switch (elf_header.e_machine)
12081 {
11c1ff18
PB
12082 case EM_ARM:
12083 return process_arm_specific (file);
252b5132 12084 case EM_MIPS:
4fe85591 12085 case EM_MIPS_RS3_LE:
252b5132
RH
12086 return process_mips_specific (file);
12087 break;
34c8bcba
JM
12088 case EM_PPC:
12089 return process_power_specific (file);
12090 break;
59e6276b
JM
12091 case EM_TI_C6000:
12092 return process_tic6x_specific (file);
12093 break;
252b5132
RH
12094 default:
12095 break;
12096 }
12097 return 1;
12098}
12099
12100static int
2cf0635d 12101get_file_header (FILE * file)
252b5132 12102{
9ea033b2
NC
12103 /* Read in the identity array. */
12104 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
12105 return 0;
12106
9ea033b2 12107 /* Determine how to read the rest of the header. */
b34976b6 12108 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
12109 {
12110 default: /* fall through */
12111 case ELFDATANONE: /* fall through */
adab8cdc
AO
12112 case ELFDATA2LSB:
12113 byte_get = byte_get_little_endian;
12114 byte_put = byte_put_little_endian;
12115 break;
12116 case ELFDATA2MSB:
12117 byte_get = byte_get_big_endian;
12118 byte_put = byte_put_big_endian;
12119 break;
9ea033b2
NC
12120 }
12121
12122 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 12123 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
12124
12125 /* Read in the rest of the header. */
12126 if (is_32bit_elf)
12127 {
12128 Elf32_External_Ehdr ehdr32;
252b5132 12129
9ea033b2
NC
12130 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
12131 return 0;
103f02d3 12132
9ea033b2
NC
12133 elf_header.e_type = BYTE_GET (ehdr32.e_type);
12134 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
12135 elf_header.e_version = BYTE_GET (ehdr32.e_version);
12136 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
12137 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
12138 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
12139 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
12140 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
12141 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
12142 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
12143 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
12144 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
12145 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
12146 }
252b5132 12147 else
9ea033b2
NC
12148 {
12149 Elf64_External_Ehdr ehdr64;
a952a375
NC
12150
12151 /* If we have been compiled with sizeof (bfd_vma) == 4, then
12152 we will not be able to cope with the 64bit data found in
12153 64 ELF files. Detect this now and abort before we start
50c2245b 12154 overwriting things. */
a952a375
NC
12155 if (sizeof (bfd_vma) < 8)
12156 {
e3c8793a
NC
12157 error (_("This instance of readelf has been built without support for a\n\
1215864 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
12159 return 0;
12160 }
103f02d3 12161
9ea033b2
NC
12162 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
12163 return 0;
103f02d3 12164
9ea033b2
NC
12165 elf_header.e_type = BYTE_GET (ehdr64.e_type);
12166 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
12167 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
12168 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
12169 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
12170 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
12171 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
12172 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
12173 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
12174 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
12175 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
12176 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
12177 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
12178 }
252b5132 12179
7ece0d85
JJ
12180 if (elf_header.e_shoff)
12181 {
12182 /* There may be some extensions in the first section header. Don't
12183 bomb if we can't read it. */
12184 if (is_32bit_elf)
12185 get_32bit_section_headers (file, 1);
12186 else
12187 get_64bit_section_headers (file, 1);
12188 }
560f3c1c 12189
252b5132
RH
12190 return 1;
12191}
12192
fb52b2f4
NC
12193/* Process one ELF object file according to the command line options.
12194 This file may actually be stored in an archive. The file is
12195 positioned at the start of the ELF object. */
12196
ff78d6d6 12197static int
2cf0635d 12198process_object (char * file_name, FILE * file)
252b5132 12199{
252b5132
RH
12200 unsigned int i;
12201
252b5132
RH
12202 if (! get_file_header (file))
12203 {
12204 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 12205 return 1;
252b5132
RH
12206 }
12207
12208 /* Initialise per file variables. */
60bca95a 12209 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
12210 version_info[i] = 0;
12211
60bca95a 12212 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132
RH
12213 dynamic_info[i] = 0;
12214
12215 /* Process the file. */
12216 if (show_name)
12217 printf (_("\nFile: %s\n"), file_name);
12218
18bd398b
NC
12219 /* Initialise the dump_sects array from the cmdline_dump_sects array.
12220 Note we do this even if cmdline_dump_sects is empty because we
12221 must make sure that the dump_sets array is zeroed out before each
12222 object file is processed. */
12223 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 12224 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
12225
12226 if (num_cmdline_dump_sects > 0)
12227 {
12228 if (num_dump_sects == 0)
12229 /* A sneaky way of allocating the dump_sects array. */
09c11c86 12230 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
12231
12232 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
12233 memcpy (dump_sects, cmdline_dump_sects,
12234 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 12235 }
d70c5fc7 12236
252b5132 12237 if (! process_file_header ())
fb52b2f4 12238 return 1;
252b5132 12239
d1f5c6e3 12240 if (! process_section_headers (file))
2f62977e 12241 {
d1f5c6e3
L
12242 /* Without loaded section headers we cannot process lots of
12243 things. */
2f62977e 12244 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 12245
2f62977e 12246 if (! do_using_dynamic)
2c610e4b 12247 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 12248 }
252b5132 12249
d1f5c6e3
L
12250 if (! process_section_groups (file))
12251 {
12252 /* Without loaded section groups we cannot process unwind. */
12253 do_unwind = 0;
12254 }
12255
2f62977e 12256 if (process_program_headers (file))
b2d38a17 12257 process_dynamic_section (file);
252b5132
RH
12258
12259 process_relocs (file);
12260
4d6ed7c8
NC
12261 process_unwind (file);
12262
252b5132
RH
12263 process_symbol_table (file);
12264
12265 process_syminfo (file);
12266
12267 process_version_sections (file);
12268
12269 process_section_contents (file);
f5842774 12270
1ec5cd37 12271 process_notes (file);
103f02d3 12272
047b2264
JJ
12273 process_gnu_liblist (file);
12274
252b5132
RH
12275 process_arch_specific (file);
12276
d93f0186
NC
12277 if (program_headers)
12278 {
12279 free (program_headers);
12280 program_headers = NULL;
12281 }
12282
252b5132
RH
12283 if (section_headers)
12284 {
12285 free (section_headers);
12286 section_headers = NULL;
12287 }
12288
12289 if (string_table)
12290 {
12291 free (string_table);
12292 string_table = NULL;
d40ac9bd 12293 string_table_length = 0;
252b5132
RH
12294 }
12295
12296 if (dynamic_strings)
12297 {
12298 free (dynamic_strings);
12299 dynamic_strings = NULL;
d79b3d50 12300 dynamic_strings_length = 0;
252b5132
RH
12301 }
12302
12303 if (dynamic_symbols)
12304 {
12305 free (dynamic_symbols);
12306 dynamic_symbols = NULL;
19936277 12307 num_dynamic_syms = 0;
252b5132
RH
12308 }
12309
12310 if (dynamic_syminfo)
12311 {
12312 free (dynamic_syminfo);
12313 dynamic_syminfo = NULL;
12314 }
ff78d6d6 12315
e4b17d5c
L
12316 if (section_headers_groups)
12317 {
12318 free (section_headers_groups);
12319 section_headers_groups = NULL;
12320 }
12321
12322 if (section_groups)
12323 {
2cf0635d
NC
12324 struct group_list * g;
12325 struct group_list * next;
e4b17d5c
L
12326
12327 for (i = 0; i < group_count; i++)
12328 {
12329 for (g = section_groups [i].root; g != NULL; g = next)
12330 {
12331 next = g->next;
12332 free (g);
12333 }
12334 }
12335
12336 free (section_groups);
12337 section_groups = NULL;
12338 }
12339
19e6b90e 12340 free_debug_memory ();
18bd398b 12341
ff78d6d6 12342 return 0;
252b5132
RH
12343}
12344
2cf0635d
NC
12345/* Return the path name for a proxy entry in a thin archive, adjusted relative
12346 to the path name of the thin archive itself if necessary. Always returns
12347 a pointer to malloc'ed memory. */
12348
12349static char *
12350adjust_relative_path (char * file_name, char * name, int name_len)
12351{
12352 char * member_file_name;
12353 const char * base_name = lbasename (file_name);
12354
12355 /* This is a proxy entry for a thin archive member.
12356 If the extended name table contains an absolute path
12357 name, or if the archive is in the current directory,
12358 use the path name as given. Otherwise, we need to
12359 find the member relative to the directory where the
12360 archive is located. */
12361 if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
12362 {
3f5e193b 12363 member_file_name = (char *) malloc (name_len + 1);
2cf0635d
NC
12364 if (member_file_name == NULL)
12365 {
12366 error (_("Out of memory\n"));
12367 return NULL;
12368 }
12369 memcpy (member_file_name, name, name_len);
12370 member_file_name[name_len] = '\0';
12371 }
12372 else
12373 {
12374 /* Concatenate the path components of the archive file name
12375 to the relative path name from the extended name table. */
12376 size_t prefix_len = base_name - file_name;
3f5e193b 12377 member_file_name = (char *) malloc (prefix_len + name_len + 1);
2cf0635d
NC
12378 if (member_file_name == NULL)
12379 {
12380 error (_("Out of memory\n"));
12381 return NULL;
12382 }
12383 memcpy (member_file_name, file_name, prefix_len);
12384 memcpy (member_file_name + prefix_len, name, name_len);
12385 member_file_name[prefix_len + name_len] = '\0';
12386 }
12387 return member_file_name;
12388}
12389
12390/* Structure to hold information about an archive file. */
12391
12392struct archive_info
12393{
12394 char * file_name; /* Archive file name. */
12395 FILE * file; /* Open file descriptor. */
12396 unsigned long index_num; /* Number of symbols in table. */
12397 unsigned long * index_array; /* The array of member offsets. */
12398 char * sym_table; /* The symbol table. */
12399 unsigned long sym_size; /* Size of the symbol table. */
12400 char * longnames; /* The long file names table. */
12401 unsigned long longnames_size; /* Size of the long file names table. */
12402 unsigned long nested_member_origin; /* Origin in the nested archive of the current member. */
12403 unsigned long next_arhdr_offset; /* Offset of the next archive header. */
12404 bfd_boolean is_thin_archive; /* TRUE if this is a thin archive. */
12405 struct ar_hdr arhdr; /* Current archive header. */
12406};
12407
12408/* Read the symbol table and long-name table from an archive. */
fb52b2f4
NC
12409
12410static int
2cf0635d
NC
12411setup_archive (struct archive_info * arch, char * file_name, FILE * file,
12412 bfd_boolean is_thin_archive, bfd_boolean read_symbols)
fb52b2f4 12413{
fb52b2f4
NC
12414 size_t got;
12415 unsigned long size;
fb52b2f4 12416
2cf0635d
NC
12417 arch->file_name = strdup (file_name);
12418 arch->file = file;
12419 arch->index_num = 0;
12420 arch->index_array = NULL;
12421 arch->sym_table = NULL;
12422 arch->sym_size = 0;
12423 arch->longnames = NULL;
12424 arch->longnames_size = 0;
12425 arch->nested_member_origin = 0;
12426 arch->is_thin_archive = is_thin_archive;
12427 arch->next_arhdr_offset = SARMAG;
12428
12429 /* Read the first archive member header. */
12430 if (fseek (file, SARMAG, SEEK_SET) != 0)
12431 {
12432 error (_("%s: failed to seek to first archive header\n"), file_name);
12433 return 1;
12434 }
12435 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
12436 if (got != sizeof arch->arhdr)
fb52b2f4
NC
12437 {
12438 if (got == 0)
12439 return 0;
12440
12441 error (_("%s: failed to read archive header\n"), file_name);
12442 return 1;
12443 }
12444
4145f1d5 12445 /* See if this is the archive symbol table. */
2cf0635d
NC
12446 if (const_strneq (arch->arhdr.ar_name, "/ ")
12447 || const_strneq (arch->arhdr.ar_name, "/SYM64/ "))
fb52b2f4 12448 {
2cf0635d 12449 size = strtoul (arch->arhdr.ar_size, NULL, 10);
4145f1d5
NC
12450 size = size + (size & 1);
12451
2cf0635d
NC
12452 arch->next_arhdr_offset += sizeof arch->arhdr + size;
12453
12454 if (read_symbols)
fb52b2f4 12455 {
4145f1d5
NC
12456 unsigned long i;
12457 /* A buffer used to hold numbers read in from an archive index.
12458 These are always 4 bytes long and stored in big-endian format. */
12459#define SIZEOF_AR_INDEX_NUMBERS 4
12460 unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
12461 unsigned char * index_buffer;
12462
12463 /* Check the size of the archive index. */
12464 if (size < SIZEOF_AR_INDEX_NUMBERS)
12465 {
12466 error (_("%s: the archive index is empty\n"), file_name);
12467 return 1;
12468 }
12469
12470 /* Read the numer of entries in the archive index. */
12471 got = fread (integer_buffer, 1, sizeof integer_buffer, file);
12472 if (got != sizeof (integer_buffer))
12473 {
12474 error (_("%s: failed to read archive index\n"), file_name);
12475 return 1;
12476 }
2cf0635d 12477 arch->index_num = byte_get_big_endian (integer_buffer, sizeof integer_buffer);
4145f1d5
NC
12478 size -= SIZEOF_AR_INDEX_NUMBERS;
12479
12480 /* Read in the archive index. */
2cf0635d 12481 if (size < arch->index_num * SIZEOF_AR_INDEX_NUMBERS)
4145f1d5
NC
12482 {
12483 error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
2cf0635d 12484 file_name, arch->index_num);
4145f1d5
NC
12485 return 1;
12486 }
3f5e193b
NC
12487 index_buffer = (unsigned char *)
12488 malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
12489 if (index_buffer == NULL)
12490 {
12491 error (_("Out of memory whilst trying to read archive symbol index\n"));
12492 return 1;
12493 }
2cf0635d
NC
12494 got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, arch->index_num, file);
12495 if (got != arch->index_num)
4145f1d5
NC
12496 {
12497 free (index_buffer);
12498 error (_("%s: failed to read archive index\n"), file_name);
2cf0635d 12499 return 1;
4145f1d5 12500 }
2cf0635d 12501 size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS;
4145f1d5
NC
12502
12503 /* Convert the index numbers into the host's numeric format. */
3f5e193b
NC
12504 arch->index_array = (long unsigned int *)
12505 malloc (arch->index_num * sizeof (* arch->index_array));
2cf0635d 12506 if (arch->index_array == NULL)
4145f1d5
NC
12507 {
12508 free (index_buffer);
12509 error (_("Out of memory whilst trying to convert the archive symbol index\n"));
12510 return 1;
12511 }
12512
2cf0635d
NC
12513 for (i = 0; i < arch->index_num; i++)
12514 arch->index_array[i] = byte_get_big_endian ((unsigned char *) (index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
12515 SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
12516 free (index_buffer);
12517
12518 /* The remaining space in the header is taken up by the symbol table. */
12519 if (size < 1)
12520 {
12521 error (_("%s: the archive has an index but no symbols\n"), file_name);
2cf0635d 12522 return 1;
4145f1d5 12523 }
3f5e193b 12524 arch->sym_table = (char *) malloc (size);
2cf0635d
NC
12525 arch->sym_size = size;
12526 if (arch->sym_table == NULL)
4145f1d5
NC
12527 {
12528 error (_("Out of memory whilst trying to read archive index symbol table\n"));
2cf0635d 12529 return 1;
4145f1d5 12530 }
2cf0635d 12531 got = fread (arch->sym_table, 1, size, file);
4145f1d5
NC
12532 if (got != size)
12533 {
12534 error (_("%s: failed to read archive index symbol table\n"), file_name);
2cf0635d 12535 return 1;
cb8f3167 12536 }
4145f1d5
NC
12537 }
12538 else
12539 {
12540 if (fseek (file, size, SEEK_CUR) != 0)
12541 {
12542 error (_("%s: failed to skip archive symbol table\n"), file_name);
12543 return 1;
12544 }
fb52b2f4
NC
12545 }
12546
2cf0635d
NC
12547 /* Read the next archive header. */
12548 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
12549 if (got != sizeof arch->arhdr)
fb52b2f4
NC
12550 {
12551 if (got == 0)
2cf0635d 12552 return 0;
4145f1d5 12553 error (_("%s: failed to read archive header following archive index\n"), file_name);
2cf0635d 12554 return 1;
fb52b2f4
NC
12555 }
12556 }
2cf0635d 12557 else if (read_symbols)
4145f1d5 12558 printf (_("%s has no archive index\n"), file_name);
fb52b2f4 12559
2cf0635d 12560 if (const_strneq (arch->arhdr.ar_name, "// "))
fb52b2f4 12561 {
2cf0635d
NC
12562 /* This is the archive string table holding long member names. */
12563 arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
12564 arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
fb52b2f4 12565
3f5e193b 12566 arch->longnames = (char *) malloc (arch->longnames_size);
2cf0635d 12567 if (arch->longnames == NULL)
fb52b2f4 12568 {
4145f1d5 12569 error (_("Out of memory reading long symbol names in archive\n"));
2cf0635d 12570 return 1;
fb52b2f4
NC
12571 }
12572
2cf0635d 12573 if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
fb52b2f4 12574 {
2cf0635d
NC
12575 free (arch->longnames);
12576 arch->longnames = NULL;
4145f1d5 12577 error (_("%s: failed to read long symbol name string table\n"), file_name);
2cf0635d 12578 return 1;
fb52b2f4
NC
12579 }
12580
2cf0635d 12581 if ((arch->longnames_size & 1) != 0)
fb52b2f4 12582 getc (file);
2cf0635d 12583 }
fb52b2f4 12584
2cf0635d
NC
12585 return 0;
12586}
12587
12588/* Release the memory used for the archive information. */
12589
12590static void
12591release_archive (struct archive_info * arch)
12592{
12593 if (arch->file_name != NULL)
12594 free (arch->file_name);
12595 if (arch->index_array != NULL)
12596 free (arch->index_array);
12597 if (arch->sym_table != NULL)
12598 free (arch->sym_table);
12599 if (arch->longnames != NULL)
12600 free (arch->longnames);
12601}
12602
12603/* Open and setup a nested archive, if not already open. */
12604
12605static int
12606setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
12607{
12608 FILE * member_file;
12609
12610 /* Have we already setup this archive? */
12611 if (nested_arch->file_name != NULL
12612 && streq (nested_arch->file_name, member_file_name))
12613 return 0;
12614
12615 /* Close previous file and discard cached information. */
12616 if (nested_arch->file != NULL)
12617 fclose (nested_arch->file);
12618 release_archive (nested_arch);
12619
12620 member_file = fopen (member_file_name, "rb");
12621 if (member_file == NULL)
12622 return 1;
12623 return setup_archive (nested_arch, member_file_name, member_file, FALSE, FALSE);
12624}
12625
12626static char *
12627get_archive_member_name_at (struct archive_info * arch,
12628 unsigned long offset,
12629 struct archive_info * nested_arch);
12630
12631/* Get the name of an archive member from the current archive header.
12632 For simple names, this will modify the ar_name field of the current
12633 archive header. For long names, it will return a pointer to the
12634 longnames table. For nested archives, it will open the nested archive
12635 and get the name recursively. NESTED_ARCH is a single-entry cache so
12636 we don't keep rereading the same information from a nested archive. */
12637
12638static char *
12639get_archive_member_name (struct archive_info * arch,
12640 struct archive_info * nested_arch)
12641{
12642 unsigned long j, k;
12643
12644 if (arch->arhdr.ar_name[0] == '/')
12645 {
12646 /* We have a long name. */
12647 char * endp;
12648 char * member_file_name;
12649 char * member_name;
12650
12651 arch->nested_member_origin = 0;
12652 k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
12653 if (arch->is_thin_archive && endp != NULL && * endp == ':')
12654 arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
12655
12656 while ((j < arch->longnames_size)
12657 && (arch->longnames[j] != '\n')
12658 && (arch->longnames[j] != '\0'))
12659 j++;
12660 if (arch->longnames[j-1] == '/')
12661 j--;
12662 arch->longnames[j] = '\0';
12663
12664 if (!arch->is_thin_archive || arch->nested_member_origin == 0)
12665 return arch->longnames + k;
12666
12667 /* This is a proxy for a member of a nested archive.
12668 Find the name of the member in that archive. */
12669 member_file_name = adjust_relative_path (arch->file_name, arch->longnames + k, j - k);
12670 if (member_file_name != NULL
12671 && setup_nested_archive (nested_arch, member_file_name) == 0
12672 && (member_name = get_archive_member_name_at (nested_arch, arch->nested_member_origin, NULL)) != NULL)
12673 {
12674 free (member_file_name);
12675 return member_name;
12676 }
12677 free (member_file_name);
12678
12679 /* Last resort: just return the name of the nested archive. */
12680 return arch->longnames + k;
12681 }
12682
12683 /* We have a normal (short) name. */
12684 j = 0;
2e49a6d0
NC
12685 while ((arch->arhdr.ar_name[j] != '/')
12686 && (j < sizeof (arch->arhdr.ar_name) - 1))
2cf0635d
NC
12687 j++;
12688 arch->arhdr.ar_name[j] = '\0';
12689 return arch->arhdr.ar_name;
12690}
12691
12692/* Get the name of an archive member at a given OFFSET within an archive ARCH. */
12693
12694static char *
12695get_archive_member_name_at (struct archive_info * arch,
12696 unsigned long offset,
12697 struct archive_info * nested_arch)
12698{
12699 size_t got;
12700
12701 if (fseek (arch->file, offset, SEEK_SET) != 0)
12702 {
12703 error (_("%s: failed to seek to next file name\n"), arch->file_name);
12704 return NULL;
12705 }
12706 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
12707 if (got != sizeof arch->arhdr)
12708 {
12709 error (_("%s: failed to read archive header\n"), arch->file_name);
12710 return NULL;
12711 }
12712 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
12713 {
12714 error (_("%s: did not find a valid archive header\n"), arch->file_name);
12715 return NULL;
12716 }
12717
12718 return get_archive_member_name (arch, nested_arch);
12719}
12720
12721/* Construct a string showing the name of the archive member, qualified
12722 with the name of the containing archive file. For thin archives, we
12723 use square brackets to denote the indirection. For nested archives,
12724 we show the qualified name of the external member inside the square
12725 brackets (e.g., "thin.a[normal.a(foo.o)]"). */
12726
12727static char *
12728make_qualified_name (struct archive_info * arch,
12729 struct archive_info * nested_arch,
12730 char * member_name)
12731{
12732 size_t len;
12733 char * name;
12734
12735 len = strlen (arch->file_name) + strlen (member_name) + 3;
12736 if (arch->is_thin_archive && arch->nested_member_origin != 0)
12737 len += strlen (nested_arch->file_name) + 2;
12738
3f5e193b 12739 name = (char *) malloc (len);
2cf0635d
NC
12740 if (name == NULL)
12741 {
12742 error (_("Out of memory\n"));
12743 return NULL;
12744 }
12745
12746 if (arch->is_thin_archive && arch->nested_member_origin != 0)
12747 snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name);
12748 else if (arch->is_thin_archive)
12749 snprintf (name, len, "%s[%s]", arch->file_name, member_name);
12750 else
12751 snprintf (name, len, "%s(%s)", arch->file_name, member_name);
12752
12753 return name;
12754}
12755
12756/* Process an ELF archive.
12757 On entry the file is positioned just after the ARMAG string. */
12758
12759static int
12760process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
12761{
12762 struct archive_info arch;
12763 struct archive_info nested_arch;
12764 size_t got;
2cf0635d
NC
12765 int ret;
12766
12767 show_name = 1;
12768
12769 /* The ARCH structure is used to hold information about this archive. */
12770 arch.file_name = NULL;
12771 arch.file = NULL;
12772 arch.index_array = NULL;
12773 arch.sym_table = NULL;
12774 arch.longnames = NULL;
12775
12776 /* The NESTED_ARCH structure is used as a single-item cache of information
12777 about a nested archive (when members of a thin archive reside within
12778 another regular archive file). */
12779 nested_arch.file_name = NULL;
12780 nested_arch.file = NULL;
12781 nested_arch.index_array = NULL;
12782 nested_arch.sym_table = NULL;
12783 nested_arch.longnames = NULL;
12784
12785 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
12786 {
12787 ret = 1;
12788 goto out;
4145f1d5 12789 }
fb52b2f4 12790
4145f1d5
NC
12791 if (do_archive_index)
12792 {
2cf0635d 12793 if (arch.sym_table == NULL)
4145f1d5
NC
12794 error (_("%s: unable to dump the index as none was found\n"), file_name);
12795 else
12796 {
2cf0635d 12797 unsigned int i, l;
4145f1d5
NC
12798 unsigned long current_pos;
12799
12800 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 12801 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
12802 current_pos = ftell (file);
12803
2cf0635d 12804 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 12805 {
2cf0635d
NC
12806 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
12807 {
12808 char * member_name;
4145f1d5 12809
2cf0635d
NC
12810 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
12811
12812 if (member_name != NULL)
12813 {
12814 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
12815
12816 if (qualified_name != NULL)
12817 {
12818 printf (_("Binary %s contains:\n"), qualified_name);
12819 free (qualified_name);
12820 }
4145f1d5
NC
12821 }
12822 }
2cf0635d
NC
12823
12824 if (l >= arch.sym_size)
4145f1d5
NC
12825 {
12826 error (_("%s: end of the symbol table reached before the end of the index\n"),
12827 file_name);
cb8f3167 12828 break;
4145f1d5 12829 }
2cf0635d
NC
12830 printf ("\t%s\n", arch.sym_table + l);
12831 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
12832 }
12833
2cf0635d
NC
12834 if (l & 01)
12835 ++l;
12836 if (l < arch.sym_size)
4145f1d5
NC
12837 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
12838 file_name);
12839
4145f1d5
NC
12840 if (fseek (file, current_pos, SEEK_SET) != 0)
12841 {
12842 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
12843 ret = 1;
12844 goto out;
4145f1d5 12845 }
fb52b2f4 12846 }
4145f1d5
NC
12847
12848 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
12849 && !do_segments && !do_header && !do_dump && !do_version
12850 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 12851 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
12852 {
12853 ret = 0; /* Archive index only. */
12854 goto out;
12855 }
fb52b2f4
NC
12856 }
12857
d989285c 12858 ret = 0;
fb52b2f4
NC
12859
12860 while (1)
12861 {
2cf0635d
NC
12862 char * name;
12863 size_t namelen;
12864 char * qualified_name;
12865
12866 /* Read the next archive header. */
12867 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
12868 {
12869 error (_("%s: failed to seek to next archive header\n"), file_name);
12870 return 1;
12871 }
12872 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
12873 if (got != sizeof arch.arhdr)
12874 {
12875 if (got == 0)
12876 break;
12877 error (_("%s: failed to read archive header\n"), file_name);
12878 ret = 1;
12879 break;
12880 }
12881 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
12882 {
12883 error (_("%s: did not find a valid archive header\n"), arch.file_name);
12884 ret = 1;
12885 break;
12886 }
12887
12888 arch.next_arhdr_offset += sizeof arch.arhdr;
12889
12890 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
12891 if (archive_file_size & 01)
12892 ++archive_file_size;
12893
12894 name = get_archive_member_name (&arch, &nested_arch);
12895 if (name == NULL)
fb52b2f4 12896 {
0fd3a477 12897 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
12898 ret = 1;
12899 break;
fb52b2f4 12900 }
2cf0635d 12901 namelen = strlen (name);
fb52b2f4 12902
2cf0635d
NC
12903 qualified_name = make_qualified_name (&arch, &nested_arch, name);
12904 if (qualified_name == NULL)
fb52b2f4 12905 {
2cf0635d 12906 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
12907 ret = 1;
12908 break;
fb52b2f4
NC
12909 }
12910
2cf0635d
NC
12911 if (is_thin_archive && arch.nested_member_origin == 0)
12912 {
12913 /* This is a proxy for an external member of a thin archive. */
12914 FILE * member_file;
12915 char * member_file_name = adjust_relative_path (file_name, name, namelen);
12916 if (member_file_name == NULL)
12917 {
12918 ret = 1;
12919 break;
12920 }
12921
12922 member_file = fopen (member_file_name, "rb");
12923 if (member_file == NULL)
12924 {
12925 error (_("Input file '%s' is not readable.\n"), member_file_name);
12926 free (member_file_name);
12927 ret = 1;
12928 break;
12929 }
12930
12931 archive_file_offset = arch.nested_member_origin;
12932
12933 ret |= process_object (qualified_name, member_file);
12934
12935 fclose (member_file);
12936 free (member_file_name);
12937 }
12938 else if (is_thin_archive)
12939 {
12940 /* This is a proxy for a member of a nested archive. */
12941 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
12942
12943 /* The nested archive file will have been opened and setup by
12944 get_archive_member_name. */
12945 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
12946 {
12947 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
12948 ret = 1;
12949 break;
12950 }
12951
12952 ret |= process_object (qualified_name, nested_arch.file);
12953 }
12954 else
12955 {
12956 archive_file_offset = arch.next_arhdr_offset;
12957 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 12958
2cf0635d
NC
12959 ret |= process_object (qualified_name, file);
12960 }
fb52b2f4 12961
2cf0635d 12962 free (qualified_name);
fb52b2f4
NC
12963 }
12964
4145f1d5 12965 out:
2cf0635d
NC
12966 if (nested_arch.file != NULL)
12967 fclose (nested_arch.file);
12968 release_archive (&nested_arch);
12969 release_archive (&arch);
fb52b2f4 12970
d989285c 12971 return ret;
fb52b2f4
NC
12972}
12973
12974static int
2cf0635d 12975process_file (char * file_name)
fb52b2f4 12976{
2cf0635d 12977 FILE * file;
fb52b2f4
NC
12978 struct stat statbuf;
12979 char armag[SARMAG];
12980 int ret;
12981
12982 if (stat (file_name, &statbuf) < 0)
12983 {
f24ddbdd
NC
12984 if (errno == ENOENT)
12985 error (_("'%s': No such file\n"), file_name);
12986 else
12987 error (_("Could not locate '%s'. System error message: %s\n"),
12988 file_name, strerror (errno));
12989 return 1;
12990 }
12991
12992 if (! S_ISREG (statbuf.st_mode))
12993 {
12994 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
12995 return 1;
12996 }
12997
12998 file = fopen (file_name, "rb");
12999 if (file == NULL)
13000 {
f24ddbdd 13001 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
13002 return 1;
13003 }
13004
13005 if (fread (armag, SARMAG, 1, file) != 1)
13006 {
4145f1d5 13007 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
13008 fclose (file);
13009 return 1;
13010 }
13011
13012 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
13013 ret = process_archive (file_name, file, FALSE);
13014 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
13015 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
13016 else
13017 {
4145f1d5
NC
13018 if (do_archive_index)
13019 error (_("File %s is not an archive so its index cannot be displayed.\n"),
13020 file_name);
13021
fb52b2f4
NC
13022 rewind (file);
13023 archive_file_size = archive_file_offset = 0;
13024 ret = process_object (file_name, file);
13025 }
13026
13027 fclose (file);
13028
13029 return ret;
13030}
13031
252b5132
RH
13032#ifdef SUPPORT_DISASSEMBLY
13033/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 13034 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 13035 symbols. */
252b5132
RH
13036
13037void
2cf0635d 13038print_address (unsigned int addr, FILE * outfile)
252b5132
RH
13039{
13040 fprintf (outfile,"0x%8.8x", addr);
13041}
13042
e3c8793a 13043/* Needed by the i386 disassembler. */
252b5132
RH
13044void
13045db_task_printsym (unsigned int addr)
13046{
13047 print_address (addr, stderr);
13048}
13049#endif
13050
13051int
2cf0635d 13052main (int argc, char ** argv)
252b5132 13053{
ff78d6d6
L
13054 int err;
13055
252b5132
RH
13056#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
13057 setlocale (LC_MESSAGES, "");
3882b010
L
13058#endif
13059#if defined (HAVE_SETLOCALE)
13060 setlocale (LC_CTYPE, "");
252b5132
RH
13061#endif
13062 bindtextdomain (PACKAGE, LOCALEDIR);
13063 textdomain (PACKAGE);
13064
869b9d07
MM
13065 expandargv (&argc, &argv);
13066
252b5132
RH
13067 parse_args (argc, argv);
13068
18bd398b 13069 if (num_dump_sects > 0)
59f14fc0 13070 {
18bd398b 13071 /* Make a copy of the dump_sects array. */
3f5e193b
NC
13072 cmdline_dump_sects = (dump_type *)
13073 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 13074 if (cmdline_dump_sects == NULL)
591a748a 13075 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
13076 else
13077 {
09c11c86
NC
13078 memcpy (cmdline_dump_sects, dump_sects,
13079 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
13080 num_cmdline_dump_sects = num_dump_sects;
13081 }
13082 }
13083
18bd398b
NC
13084 if (optind < (argc - 1))
13085 show_name = 1;
13086
ff78d6d6 13087 err = 0;
252b5132 13088 while (optind < argc)
18bd398b 13089 err |= process_file (argv[optind++]);
252b5132
RH
13090
13091 if (dump_sects != NULL)
13092 free (dump_sects);
59f14fc0
AS
13093 if (cmdline_dump_sects != NULL)
13094 free (cmdline_dump_sects);
252b5132 13095
ff78d6d6 13096 return err;
252b5132 13097}