]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Re-indent plugin code.
[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
781303ce
MF
2241 case EM_BLACKFIN:
2242 if (e_flags & EF_BFIN_PIC)
2243 strcat (buf, ", PIC");
2244
2245 if (e_flags & EF_BFIN_FDPIC)
2246 strcat (buf, ", FDPIC");
2247
2248 if (e_flags & EF_BFIN_CODE_IN_L1)
2249 strcat (buf, ", code in L1");
2250
2251 if (e_flags & EF_BFIN_DATA_IN_L1)
2252 strcat (buf, ", data in L1");
2253
2254 break;
2255
ec2dfb42
AO
2256 case EM_CYGNUS_FRV:
2257 switch (e_flags & EF_FRV_CPU_MASK)
2258 {
2259 case EF_FRV_CPU_GENERIC:
2260 break;
2261
2262 default:
2263 strcat (buf, ", fr???");
2264 break;
57346661 2265
ec2dfb42
AO
2266 case EF_FRV_CPU_FR300:
2267 strcat (buf, ", fr300");
2268 break;
2269
2270 case EF_FRV_CPU_FR400:
2271 strcat (buf, ", fr400");
2272 break;
2273 case EF_FRV_CPU_FR405:
2274 strcat (buf, ", fr405");
2275 break;
2276
2277 case EF_FRV_CPU_FR450:
2278 strcat (buf, ", fr450");
2279 break;
2280
2281 case EF_FRV_CPU_FR500:
2282 strcat (buf, ", fr500");
2283 break;
2284 case EF_FRV_CPU_FR550:
2285 strcat (buf, ", fr550");
2286 break;
2287
2288 case EF_FRV_CPU_SIMPLE:
2289 strcat (buf, ", simple");
2290 break;
2291 case EF_FRV_CPU_TOMCAT:
2292 strcat (buf, ", tomcat");
2293 break;
2294 }
1c877e87 2295 break;
ec2dfb42 2296
53c7db4b 2297 case EM_68K:
425c6cb0 2298 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2299 strcat (buf, ", m68000");
425c6cb0 2300 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2301 strcat (buf, ", cpu32");
2302 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2303 strcat (buf, ", fido_a");
425c6cb0 2304 else
266abb8f 2305 {
2cf0635d
NC
2306 char const * isa = _("unknown");
2307 char const * mac = _("unknown mac");
2308 char const * additional = NULL;
0112cd26 2309
c694fd50 2310 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2311 {
c694fd50 2312 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2313 isa = "A";
2314 additional = ", nodiv";
2315 break;
c694fd50 2316 case EF_M68K_CF_ISA_A:
266abb8f
NS
2317 isa = "A";
2318 break;
c694fd50 2319 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2320 isa = "A+";
2321 break;
c694fd50 2322 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2323 isa = "B";
2324 additional = ", nousp";
2325 break;
c694fd50 2326 case EF_M68K_CF_ISA_B:
266abb8f
NS
2327 isa = "B";
2328 break;
f608cd77
NS
2329 case EF_M68K_CF_ISA_C:
2330 isa = "C";
2331 break;
2332 case EF_M68K_CF_ISA_C_NODIV:
2333 isa = "C";
2334 additional = ", nodiv";
2335 break;
266abb8f
NS
2336 }
2337 strcat (buf, ", cf, isa ");
2338 strcat (buf, isa);
0b2e31dc
NS
2339 if (additional)
2340 strcat (buf, additional);
c694fd50 2341 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2342 strcat (buf, ", float");
c694fd50 2343 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2344 {
2345 case 0:
2346 mac = NULL;
2347 break;
c694fd50 2348 case EF_M68K_CF_MAC:
266abb8f
NS
2349 mac = "mac";
2350 break;
c694fd50 2351 case EF_M68K_CF_EMAC:
266abb8f
NS
2352 mac = "emac";
2353 break;
f608cd77
NS
2354 case EF_M68K_CF_EMAC_B:
2355 mac = "emac_b";
2356 break;
266abb8f
NS
2357 }
2358 if (mac)
2359 {
2360 strcat (buf, ", ");
2361 strcat (buf, mac);
2362 }
266abb8f 2363 }
53c7db4b 2364 break;
33c63f9d 2365
252b5132
RH
2366 case EM_PPC:
2367 if (e_flags & EF_PPC_EMB)
2368 strcat (buf, ", emb");
2369
2370 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2371 strcat (buf, _(", relocatable"));
252b5132
RH
2372
2373 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2374 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2375 break;
2376
2b0337b0 2377 case EM_V850:
252b5132
RH
2378 case EM_CYGNUS_V850:
2379 switch (e_flags & EF_V850_ARCH)
2380 {
1cd986c5
NC
2381 case E_V850E2V3_ARCH:
2382 strcat (buf, ", v850e2v3");
2383 break;
2384 case E_V850E2_ARCH:
2385 strcat (buf, ", v850e2");
2386 break;
2387 case E_V850E1_ARCH:
2388 strcat (buf, ", v850e1");
8ad30312 2389 break;
252b5132
RH
2390 case E_V850E_ARCH:
2391 strcat (buf, ", v850e");
2392 break;
252b5132
RH
2393 case E_V850_ARCH:
2394 strcat (buf, ", v850");
2395 break;
2396 default:
2b692964 2397 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2398 break;
2399 }
2400 break;
2401
2b0337b0 2402 case EM_M32R:
252b5132
RH
2403 case EM_CYGNUS_M32R:
2404 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2405 strcat (buf, ", m32r");
252b5132
RH
2406 break;
2407
2408 case EM_MIPS:
4fe85591 2409 case EM_MIPS_RS3_LE:
252b5132
RH
2410 if (e_flags & EF_MIPS_NOREORDER)
2411 strcat (buf, ", noreorder");
2412
2413 if (e_flags & EF_MIPS_PIC)
2414 strcat (buf, ", pic");
2415
2416 if (e_flags & EF_MIPS_CPIC)
2417 strcat (buf, ", cpic");
2418
d1bdd336
TS
2419 if (e_flags & EF_MIPS_UCODE)
2420 strcat (buf, ", ugen_reserved");
2421
252b5132
RH
2422 if (e_flags & EF_MIPS_ABI2)
2423 strcat (buf, ", abi2");
2424
43521d43
TS
2425 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2426 strcat (buf, ", odk first");
2427
a5d22d2a
TS
2428 if (e_flags & EF_MIPS_32BITMODE)
2429 strcat (buf, ", 32bitmode");
2430
156c2f8b
NC
2431 switch ((e_flags & EF_MIPS_MACH))
2432 {
2433 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2434 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2435 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2436 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2437 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2438 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2439 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2440 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2441 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2442 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2443 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2444 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2445 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2446 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2447 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2448 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2449 case 0:
2450 /* We simply ignore the field in this case to avoid confusion:
2451 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2452 extension. */
2453 break;
2b692964 2454 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2455 }
43521d43
TS
2456
2457 switch ((e_flags & EF_MIPS_ABI))
2458 {
2459 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2460 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2461 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2462 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2463 case 0:
2464 /* We simply ignore the field in this case to avoid confusion:
2465 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2466 This means it is likely to be an o32 file, but not for
2467 sure. */
2468 break;
2b692964 2469 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2470 }
2471
2472 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2473 strcat (buf, ", mdmx");
2474
2475 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2476 strcat (buf, ", mips16");
2477
2478 switch ((e_flags & EF_MIPS_ARCH))
2479 {
2480 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2481 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2482 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2483 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2484 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2485 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2486 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2487 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2488 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2489 default: strcat (buf, _(", unknown ISA")); break;
43521d43
TS
2490 }
2491
8e45593f
NC
2492 if (e_flags & EF_SH_PIC)
2493 strcat (buf, ", pic");
2494
2495 if (e_flags & EF_SH_FDPIC)
2496 strcat (buf, ", fdpic");
252b5132 2497 break;
351b4b40 2498
ccde1100
AO
2499 case EM_SH:
2500 switch ((e_flags & EF_SH_MACH_MASK))
2501 {
2502 case EF_SH1: strcat (buf, ", sh1"); break;
2503 case EF_SH2: strcat (buf, ", sh2"); break;
2504 case EF_SH3: strcat (buf, ", sh3"); break;
2505 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2506 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2507 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2508 case EF_SH3E: strcat (buf, ", sh3e"); break;
2509 case EF_SH4: strcat (buf, ", sh4"); break;
2510 case EF_SH5: strcat (buf, ", sh5"); break;
2511 case EF_SH2E: strcat (buf, ", sh2e"); break;
2512 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2513 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2514 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2515 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2516 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2517 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2518 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2519 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2520 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2521 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2522 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2523 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2524 }
2525
2526 break;
57346661 2527
351b4b40
RH
2528 case EM_SPARCV9:
2529 if (e_flags & EF_SPARC_32PLUS)
2530 strcat (buf, ", v8+");
2531
2532 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2533 strcat (buf, ", ultrasparcI");
2534
2535 if (e_flags & EF_SPARC_SUN_US3)
2536 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2537
2538 if (e_flags & EF_SPARC_HAL_R1)
2539 strcat (buf, ", halr1");
2540
2541 if (e_flags & EF_SPARC_LEDATA)
2542 strcat (buf, ", ledata");
2543
2544 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2545 strcat (buf, ", tso");
2546
2547 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2548 strcat (buf, ", pso");
2549
2550 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2551 strcat (buf, ", rmo");
2552 break;
7d466069 2553
103f02d3
UD
2554 case EM_PARISC:
2555 switch (e_flags & EF_PARISC_ARCH)
2556 {
2557 case EFA_PARISC_1_0:
2558 strcpy (buf, ", PA-RISC 1.0");
2559 break;
2560 case EFA_PARISC_1_1:
2561 strcpy (buf, ", PA-RISC 1.1");
2562 break;
2563 case EFA_PARISC_2_0:
2564 strcpy (buf, ", PA-RISC 2.0");
2565 break;
2566 default:
2567 break;
2568 }
2569 if (e_flags & EF_PARISC_TRAPNIL)
2570 strcat (buf, ", trapnil");
2571 if (e_flags & EF_PARISC_EXT)
2572 strcat (buf, ", ext");
2573 if (e_flags & EF_PARISC_LSB)
2574 strcat (buf, ", lsb");
2575 if (e_flags & EF_PARISC_WIDE)
2576 strcat (buf, ", wide");
2577 if (e_flags & EF_PARISC_NO_KABP)
2578 strcat (buf, ", no kabp");
2579 if (e_flags & EF_PARISC_LAZYSWAP)
2580 strcat (buf, ", lazyswap");
30800947 2581 break;
76da6bbe 2582
7d466069 2583 case EM_PJ:
2b0337b0 2584 case EM_PJ_OLD:
7d466069
ILT
2585 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2586 strcat (buf, ", new calling convention");
2587
2588 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2589 strcat (buf, ", gnu calling convention");
2590 break;
4d6ed7c8
NC
2591
2592 case EM_IA_64:
2593 if ((e_flags & EF_IA_64_ABI64))
2594 strcat (buf, ", 64-bit");
2595 else
2596 strcat (buf, ", 32-bit");
2597 if ((e_flags & EF_IA_64_REDUCEDFP))
2598 strcat (buf, ", reduced fp model");
2599 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2600 strcat (buf, ", no function descriptors, constant gp");
2601 else if ((e_flags & EF_IA_64_CONS_GP))
2602 strcat (buf, ", constant gp");
2603 if ((e_flags & EF_IA_64_ABSOLUTE))
2604 strcat (buf, ", absolute");
28f997cf
TG
2605 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2606 {
2607 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2608 strcat (buf, ", vms_linkages");
2609 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2610 {
2611 case EF_IA_64_VMS_COMCOD_SUCCESS:
2612 break;
2613 case EF_IA_64_VMS_COMCOD_WARNING:
2614 strcat (buf, ", warning");
2615 break;
2616 case EF_IA_64_VMS_COMCOD_ERROR:
2617 strcat (buf, ", error");
2618 break;
2619 case EF_IA_64_VMS_COMCOD_ABORT:
2620 strcat (buf, ", abort");
2621 break;
2622 default:
2623 abort ();
2624 }
2625 }
4d6ed7c8 2626 break;
179d3252
JT
2627
2628 case EM_VAX:
2629 if ((e_flags & EF_VAX_NONPIC))
2630 strcat (buf, ", non-PIC");
2631 if ((e_flags & EF_VAX_DFLOAT))
2632 strcat (buf, ", D-Float");
2633 if ((e_flags & EF_VAX_GFLOAT))
2634 strcat (buf, ", G-Float");
2635 break;
c7927a3c
NC
2636
2637 case EM_RX:
2638 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2639 strcat (buf, ", 64-bit doubles");
2640 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2641 strcat (buf, ", dsp");
55786da2
AK
2642
2643 case EM_S390:
2644 if (e_flags & EF_S390_HIGH_GPRS)
2645 strcat (buf, ", highgprs");
40b36596
JM
2646
2647 case EM_TI_C6000:
2648 if ((e_flags & EF_C6000_REL))
2649 strcat (buf, ", relocatable module");
252b5132
RH
2650 }
2651 }
2652
2653 return buf;
2654}
2655
252b5132 2656static const char *
d3ba0551
AM
2657get_osabi_name (unsigned int osabi)
2658{
2659 static char buff[32];
2660
2661 switch (osabi)
2662 {
2663 case ELFOSABI_NONE: return "UNIX - System V";
2664 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2665 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
2666 case ELFOSABI_LINUX: return "UNIX - Linux";
2667 case ELFOSABI_HURD: return "GNU/Hurd";
2668 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2669 case ELFOSABI_AIX: return "UNIX - AIX";
2670 case ELFOSABI_IRIX: return "UNIX - IRIX";
2671 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2672 case ELFOSABI_TRU64: return "UNIX - TRU64";
2673 case ELFOSABI_MODESTO: return "Novell - Modesto";
2674 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2675 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2676 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2677 case ELFOSABI_AROS: return "AROS";
11636f9e 2678 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2679 default:
40b36596
JM
2680 if (osabi >= 64)
2681 switch (elf_header.e_machine)
2682 {
2683 case EM_ARM:
2684 switch (osabi)
2685 {
2686 case ELFOSABI_ARM: return "ARM";
2687 default:
2688 break;
2689 }
2690 break;
2691
2692 case EM_MSP430:
2693 case EM_MSP430_OLD:
2694 switch (osabi)
2695 {
2696 case ELFOSABI_STANDALONE: return _("Standalone App");
2697 default:
2698 break;
2699 }
2700 break;
2701
2702 case EM_TI_C6000:
2703 switch (osabi)
2704 {
2705 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2706 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2707 default:
2708 break;
2709 }
2710 break;
2711
2712 default:
2713 break;
2714 }
e9e44622 2715 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2716 return buff;
2717 }
2718}
2719
b294bdf8
MM
2720static const char *
2721get_arm_segment_type (unsigned long type)
2722{
2723 switch (type)
2724 {
2725 case PT_ARM_EXIDX:
2726 return "EXIDX";
2727 default:
2728 break;
2729 }
2730
2731 return NULL;
2732}
2733
d3ba0551
AM
2734static const char *
2735get_mips_segment_type (unsigned long type)
252b5132
RH
2736{
2737 switch (type)
2738 {
2739 case PT_MIPS_REGINFO:
2740 return "REGINFO";
2741 case PT_MIPS_RTPROC:
2742 return "RTPROC";
2743 case PT_MIPS_OPTIONS:
2744 return "OPTIONS";
2745 default:
2746 break;
2747 }
2748
2749 return NULL;
2750}
2751
103f02d3 2752static const char *
d3ba0551 2753get_parisc_segment_type (unsigned long type)
103f02d3
UD
2754{
2755 switch (type)
2756 {
2757 case PT_HP_TLS: return "HP_TLS";
2758 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2759 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2760 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2761 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2762 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2763 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2764 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2765 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2766 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2767 case PT_HP_PARALLEL: return "HP_PARALLEL";
2768 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2769 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2770 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2771 case PT_HP_STACK: return "HP_STACK";
2772 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2773 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2774 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2775 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2776 default:
2777 break;
2778 }
2779
2780 return NULL;
2781}
2782
4d6ed7c8 2783static const char *
d3ba0551 2784get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2785{
2786 switch (type)
2787 {
2788 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2789 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2790 case PT_HP_TLS: return "HP_TLS";
2791 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2792 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2793 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2794 default:
2795 break;
2796 }
2797
2798 return NULL;
2799}
2800
40b36596
JM
2801static const char *
2802get_tic6x_segment_type (unsigned long type)
2803{
2804 switch (type)
2805 {
2806 case PT_C6000_PHATTR: return "C6000_PHATTR";
2807 default:
2808 break;
2809 }
2810
2811 return NULL;
2812}
2813
252b5132 2814static const char *
d3ba0551 2815get_segment_type (unsigned long p_type)
252b5132 2816{
b34976b6 2817 static char buff[32];
252b5132
RH
2818
2819 switch (p_type)
2820 {
b34976b6
AM
2821 case PT_NULL: return "NULL";
2822 case PT_LOAD: return "LOAD";
252b5132 2823 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2824 case PT_INTERP: return "INTERP";
2825 case PT_NOTE: return "NOTE";
2826 case PT_SHLIB: return "SHLIB";
2827 case PT_PHDR: return "PHDR";
13ae64f3 2828 case PT_TLS: return "TLS";
252b5132 2829
65765700
JJ
2830 case PT_GNU_EH_FRAME:
2831 return "GNU_EH_FRAME";
2b05f1b7 2832 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2833 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2834
252b5132
RH
2835 default:
2836 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2837 {
2cf0635d 2838 const char * result;
103f02d3 2839
252b5132
RH
2840 switch (elf_header.e_machine)
2841 {
b294bdf8
MM
2842 case EM_ARM:
2843 result = get_arm_segment_type (p_type);
2844 break;
252b5132 2845 case EM_MIPS:
4fe85591 2846 case EM_MIPS_RS3_LE:
252b5132
RH
2847 result = get_mips_segment_type (p_type);
2848 break;
103f02d3
UD
2849 case EM_PARISC:
2850 result = get_parisc_segment_type (p_type);
2851 break;
4d6ed7c8
NC
2852 case EM_IA_64:
2853 result = get_ia64_segment_type (p_type);
2854 break;
40b36596
JM
2855 case EM_TI_C6000:
2856 result = get_tic6x_segment_type (p_type);
2857 break;
252b5132
RH
2858 default:
2859 result = NULL;
2860 break;
2861 }
103f02d3 2862
252b5132
RH
2863 if (result != NULL)
2864 return result;
103f02d3 2865
252b5132
RH
2866 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2867 }
2868 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2869 {
2cf0635d 2870 const char * result;
103f02d3
UD
2871
2872 switch (elf_header.e_machine)
2873 {
2874 case EM_PARISC:
2875 result = get_parisc_segment_type (p_type);
2876 break;
00428cca
AM
2877 case EM_IA_64:
2878 result = get_ia64_segment_type (p_type);
2879 break;
103f02d3
UD
2880 default:
2881 result = NULL;
2882 break;
2883 }
2884
2885 if (result != NULL)
2886 return result;
2887
2888 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2889 }
252b5132 2890 else
e9e44622 2891 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2892
2893 return buff;
2894 }
2895}
2896
2897static const char *
d3ba0551 2898get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2899{
2900 switch (sh_type)
2901 {
b34976b6
AM
2902 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2903 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2904 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2905 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2906 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2907 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2908 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2909 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2910 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2911 case SHT_MIPS_RELD: return "MIPS_RELD";
2912 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2913 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2914 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2915 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2916 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2917 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2918 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2919 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2920 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2921 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2922 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2923 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2924 case SHT_MIPS_LINE: return "MIPS_LINE";
2925 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2926 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2927 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2928 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2929 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2930 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2931 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2932 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2933 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2934 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2935 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2936 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2937 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2938 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2939 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2940 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2941 default:
2942 break;
2943 }
2944 return NULL;
2945}
2946
103f02d3 2947static const char *
d3ba0551 2948get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2949{
2950 switch (sh_type)
2951 {
2952 case SHT_PARISC_EXT: return "PARISC_EXT";
2953 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2954 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2955 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2956 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2957 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2958 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2959 default:
2960 break;
2961 }
2962 return NULL;
2963}
2964
4d6ed7c8 2965static const char *
d3ba0551 2966get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2967{
18bd398b 2968 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2969 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2970 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2971
4d6ed7c8
NC
2972 switch (sh_type)
2973 {
148b93f2
NC
2974 case SHT_IA_64_EXT: return "IA_64_EXT";
2975 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2976 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
2977 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
2978 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
2979 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
2980 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
2981 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
2982 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
2983 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
2984 default:
2985 break;
2986 }
2987 return NULL;
2988}
2989
d2b2c203
DJ
2990static const char *
2991get_x86_64_section_type_name (unsigned int sh_type)
2992{
2993 switch (sh_type)
2994 {
2995 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2996 default:
2997 break;
2998 }
2999 return NULL;
3000}
3001
40a18ebd
NC
3002static const char *
3003get_arm_section_type_name (unsigned int sh_type)
3004{
3005 switch (sh_type)
3006 {
7f6fed87
NC
3007 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3008 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3009 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3010 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3011 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3012 default:
3013 break;
3014 }
3015 return NULL;
3016}
3017
40b36596
JM
3018static const char *
3019get_tic6x_section_type_name (unsigned int sh_type)
3020{
3021 switch (sh_type)
3022 {
3023 case SHT_C6000_UNWIND:
3024 return "C6000_UNWIND";
3025 case SHT_C6000_PREEMPTMAP:
3026 return "C6000_PREEMPTMAP";
3027 case SHT_C6000_ATTRIBUTES:
3028 return "C6000_ATTRIBUTES";
3029 case SHT_TI_ICODE:
3030 return "TI_ICODE";
3031 case SHT_TI_XREF:
3032 return "TI_XREF";
3033 case SHT_TI_HANDLER:
3034 return "TI_HANDLER";
3035 case SHT_TI_INITINFO:
3036 return "TI_INITINFO";
3037 case SHT_TI_PHATTRS:
3038 return "TI_PHATTRS";
3039 default:
3040 break;
3041 }
3042 return NULL;
3043}
3044
252b5132 3045static const char *
d3ba0551 3046get_section_type_name (unsigned int sh_type)
252b5132 3047{
b34976b6 3048 static char buff[32];
252b5132
RH
3049
3050 switch (sh_type)
3051 {
3052 case SHT_NULL: return "NULL";
3053 case SHT_PROGBITS: return "PROGBITS";
3054 case SHT_SYMTAB: return "SYMTAB";
3055 case SHT_STRTAB: return "STRTAB";
3056 case SHT_RELA: return "RELA";
3057 case SHT_HASH: return "HASH";
3058 case SHT_DYNAMIC: return "DYNAMIC";
3059 case SHT_NOTE: return "NOTE";
3060 case SHT_NOBITS: return "NOBITS";
3061 case SHT_REL: return "REL";
3062 case SHT_SHLIB: return "SHLIB";
3063 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3064 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3065 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3066 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3067 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3068 case SHT_GROUP: return "GROUP";
3069 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3070 case SHT_GNU_verdef: return "VERDEF";
3071 case SHT_GNU_verneed: return "VERNEED";
3072 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3073 case 0x6ffffff0: return "VERSYM";
3074 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3075 case 0x7ffffffd: return "AUXILIARY";
3076 case 0x7fffffff: return "FILTER";
047b2264 3077 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3078
3079 default:
3080 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3081 {
2cf0635d 3082 const char * result;
252b5132
RH
3083
3084 switch (elf_header.e_machine)
3085 {
3086 case EM_MIPS:
4fe85591 3087 case EM_MIPS_RS3_LE:
252b5132
RH
3088 result = get_mips_section_type_name (sh_type);
3089 break;
103f02d3
UD
3090 case EM_PARISC:
3091 result = get_parisc_section_type_name (sh_type);
3092 break;
4d6ed7c8
NC
3093 case EM_IA_64:
3094 result = get_ia64_section_type_name (sh_type);
3095 break;
d2b2c203 3096 case EM_X86_64:
8a9036a4 3097 case EM_L1OM:
d2b2c203
DJ
3098 result = get_x86_64_section_type_name (sh_type);
3099 break;
40a18ebd
NC
3100 case EM_ARM:
3101 result = get_arm_section_type_name (sh_type);
3102 break;
40b36596
JM
3103 case EM_TI_C6000:
3104 result = get_tic6x_section_type_name (sh_type);
3105 break;
252b5132
RH
3106 default:
3107 result = NULL;
3108 break;
3109 }
3110
3111 if (result != NULL)
3112 return result;
3113
c91d0dfb 3114 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3115 }
3116 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3117 {
2cf0635d 3118 const char * result;
148b93f2
NC
3119
3120 switch (elf_header.e_machine)
3121 {
3122 case EM_IA_64:
3123 result = get_ia64_section_type_name (sh_type);
3124 break;
3125 default:
3126 result = NULL;
3127 break;
3128 }
3129
3130 if (result != NULL)
3131 return result;
3132
3133 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3134 }
252b5132 3135 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3136 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3137 else
e9e44622 3138 snprintf (buff, sizeof (buff), _("<unknown>: %x"), sh_type);
103f02d3 3139
252b5132
RH
3140 return buff;
3141 }
3142}
3143
2979dc34 3144#define OPTION_DEBUG_DUMP 512
2c610e4b 3145#define OPTION_DYN_SYMS 513
2979dc34 3146
85b1c36d 3147static struct option options[] =
252b5132 3148{
b34976b6 3149 {"all", no_argument, 0, 'a'},
252b5132
RH
3150 {"file-header", no_argument, 0, 'h'},
3151 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3152 {"headers", no_argument, 0, 'e'},
3153 {"histogram", no_argument, 0, 'I'},
3154 {"segments", no_argument, 0, 'l'},
3155 {"sections", no_argument, 0, 'S'},
252b5132 3156 {"section-headers", no_argument, 0, 'S'},
f5842774 3157 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3158 {"section-details", no_argument, 0, 't'},
595cf52e 3159 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3160 {"symbols", no_argument, 0, 's'},
3161 {"syms", no_argument, 0, 's'},
2c610e4b 3162 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3163 {"relocs", no_argument, 0, 'r'},
3164 {"notes", no_argument, 0, 'n'},
3165 {"dynamic", no_argument, 0, 'd'},
a952a375 3166 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3167 {"version-info", no_argument, 0, 'V'},
3168 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3169 {"unwind", no_argument, 0, 'u'},
4145f1d5 3170 {"archive-index", no_argument, 0, 'c'},
b34976b6 3171 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3172 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3173 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3174#ifdef SUPPORT_DISASSEMBLY
3175 {"instruction-dump", required_argument, 0, 'i'},
3176#endif
cf13d699 3177 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3178
b34976b6
AM
3179 {"version", no_argument, 0, 'v'},
3180 {"wide", no_argument, 0, 'W'},
3181 {"help", no_argument, 0, 'H'},
3182 {0, no_argument, 0, 0}
252b5132
RH
3183};
3184
3185static void
2cf0635d 3186usage (FILE * stream)
252b5132 3187{
92f01d61
JM
3188 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3189 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3190 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3191 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3192 -h --file-header Display the ELF file header\n\
3193 -l --program-headers Display the program headers\n\
3194 --segments An alias for --program-headers\n\
3195 -S --section-headers Display the sections' header\n\
3196 --sections An alias for --section-headers\n\
f5842774 3197 -g --section-groups Display the section groups\n\
5477e8a0 3198 -t --section-details Display the section details\n\
8b53311e
NC
3199 -e --headers Equivalent to: -h -l -S\n\
3200 -s --syms Display the symbol table\n\
3f08eb35 3201 --symbols An alias for --syms\n\
2c610e4b 3202 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3203 -n --notes Display the core notes (if present)\n\
3204 -r --relocs Display the relocations (if present)\n\
3205 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3206 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
3207 -V --version-info Display the version sections (if present)\n\
3208 -A --arch-specific Display architecture specific information (if any).\n\
4145f1d5 3209 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3210 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3211 -x --hex-dump=<number|name>\n\
3212 Dump the contents of section <number|name> as bytes\n\
3213 -p --string-dump=<number|name>\n\
3214 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3215 -R --relocated-dump=<number|name>\n\
3216 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3217 -w[lLiaprmfFsoRt] or\n\
1ed06042 3218 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884
TG
3219 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
3220 =trace_info,=trace_abbrev,=trace_aranges]\n\
8b53311e 3221 Display the contents of DWARF2 debug sections\n"));
252b5132 3222#ifdef SUPPORT_DISASSEMBLY
92f01d61 3223 fprintf (stream, _("\
09c11c86
NC
3224 -i --instruction-dump=<number|name>\n\
3225 Disassemble the contents of section <number|name>\n"));
252b5132 3226#endif
92f01d61 3227 fprintf (stream, _("\
8b53311e
NC
3228 -I --histogram Display histogram of bucket list lengths\n\
3229 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3230 @<file> Read options from <file>\n\
8b53311e
NC
3231 -H --help Display this information\n\
3232 -v --version Display the version number of readelf\n"));
1118d252 3233
92f01d61
JM
3234 if (REPORT_BUGS_TO[0] && stream == stdout)
3235 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3236
92f01d61 3237 exit (stream == stdout ? 0 : 1);
252b5132
RH
3238}
3239
18bd398b
NC
3240/* Record the fact that the user wants the contents of section number
3241 SECTION to be displayed using the method(s) encoded as flags bits
3242 in TYPE. Note, TYPE can be zero if we are creating the array for
3243 the first time. */
3244
252b5132 3245static void
09c11c86 3246request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3247{
3248 if (section >= num_dump_sects)
3249 {
2cf0635d 3250 dump_type * new_dump_sects;
252b5132 3251
3f5e193b
NC
3252 new_dump_sects = (dump_type *) calloc (section + 1,
3253 sizeof (* dump_sects));
252b5132
RH
3254
3255 if (new_dump_sects == NULL)
591a748a 3256 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3257 else
3258 {
3259 /* Copy current flag settings. */
09c11c86 3260 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3261
3262 free (dump_sects);
3263
3264 dump_sects = new_dump_sects;
3265 num_dump_sects = section + 1;
3266 }
3267 }
3268
3269 if (dump_sects)
b34976b6 3270 dump_sects[section] |= type;
252b5132
RH
3271
3272 return;
3273}
3274
aef1f6d0
DJ
3275/* Request a dump by section name. */
3276
3277static void
2cf0635d 3278request_dump_byname (const char * section, dump_type type)
aef1f6d0 3279{
2cf0635d 3280 struct dump_list_entry * new_request;
aef1f6d0 3281
3f5e193b
NC
3282 new_request = (struct dump_list_entry *)
3283 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3284 if (!new_request)
591a748a 3285 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3286
3287 new_request->name = strdup (section);
3288 if (!new_request->name)
591a748a 3289 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3290
3291 new_request->type = type;
3292
3293 new_request->next = dump_sects_byname;
3294 dump_sects_byname = new_request;
3295}
3296
cf13d699
NC
3297static inline void
3298request_dump (dump_type type)
3299{
3300 int section;
3301 char * cp;
3302
3303 do_dump++;
3304 section = strtoul (optarg, & cp, 0);
3305
3306 if (! *cp && section >= 0)
3307 request_dump_bynumber (section, type);
3308 else
3309 request_dump_byname (optarg, type);
3310}
3311
3312
252b5132 3313static void
2cf0635d 3314parse_args (int argc, char ** argv)
252b5132
RH
3315{
3316 int c;
3317
3318 if (argc < 2)
92f01d61 3319 usage (stderr);
252b5132
RH
3320
3321 while ((c = getopt_long
cf13d699 3322 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3323 {
252b5132
RH
3324 switch (c)
3325 {
3326 case 0:
3327 /* Long options. */
3328 break;
3329 case 'H':
92f01d61 3330 usage (stdout);
252b5132
RH
3331 break;
3332
3333 case 'a':
b34976b6
AM
3334 do_syms++;
3335 do_reloc++;
3336 do_unwind++;
3337 do_dynamic++;
3338 do_header++;
3339 do_sections++;
f5842774 3340 do_section_groups++;
b34976b6
AM
3341 do_segments++;
3342 do_version++;
3343 do_histogram++;
3344 do_arch++;
3345 do_notes++;
252b5132 3346 break;
f5842774
L
3347 case 'g':
3348 do_section_groups++;
3349 break;
5477e8a0 3350 case 't':
595cf52e 3351 case 'N':
5477e8a0
L
3352 do_sections++;
3353 do_section_details++;
595cf52e 3354 break;
252b5132 3355 case 'e':
b34976b6
AM
3356 do_header++;
3357 do_sections++;
3358 do_segments++;
252b5132 3359 break;
a952a375 3360 case 'A':
b34976b6 3361 do_arch++;
a952a375 3362 break;
252b5132 3363 case 'D':
b34976b6 3364 do_using_dynamic++;
252b5132
RH
3365 break;
3366 case 'r':
b34976b6 3367 do_reloc++;
252b5132 3368 break;
4d6ed7c8 3369 case 'u':
b34976b6 3370 do_unwind++;
4d6ed7c8 3371 break;
252b5132 3372 case 'h':
b34976b6 3373 do_header++;
252b5132
RH
3374 break;
3375 case 'l':
b34976b6 3376 do_segments++;
252b5132
RH
3377 break;
3378 case 's':
b34976b6 3379 do_syms++;
252b5132
RH
3380 break;
3381 case 'S':
b34976b6 3382 do_sections++;
252b5132
RH
3383 break;
3384 case 'd':
b34976b6 3385 do_dynamic++;
252b5132 3386 break;
a952a375 3387 case 'I':
b34976b6 3388 do_histogram++;
a952a375 3389 break;
779fe533 3390 case 'n':
b34976b6 3391 do_notes++;
779fe533 3392 break;
4145f1d5
NC
3393 case 'c':
3394 do_archive_index++;
3395 break;
252b5132 3396 case 'x':
cf13d699 3397 request_dump (HEX_DUMP);
aef1f6d0 3398 break;
09c11c86 3399 case 'p':
cf13d699
NC
3400 request_dump (STRING_DUMP);
3401 break;
3402 case 'R':
3403 request_dump (RELOC_DUMP);
09c11c86 3404 break;
252b5132 3405 case 'w':
b34976b6 3406 do_dump++;
252b5132 3407 if (optarg == 0)
613ff48b
CC
3408 {
3409 do_debugging = 1;
3410 dwarf_select_sections_all ();
3411 }
252b5132
RH
3412 else
3413 {
3414 do_debugging = 0;
4cb93e3b 3415 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3416 }
3417 break;
2979dc34 3418 case OPTION_DEBUG_DUMP:
b34976b6 3419 do_dump++;
2979dc34
JJ
3420 if (optarg == 0)
3421 do_debugging = 1;
3422 else
3423 {
2979dc34 3424 do_debugging = 0;
4cb93e3b 3425 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3426 }
3427 break;
2c610e4b
L
3428 case OPTION_DYN_SYMS:
3429 do_dyn_syms++;
3430 break;
252b5132
RH
3431#ifdef SUPPORT_DISASSEMBLY
3432 case 'i':
cf13d699
NC
3433 request_dump (DISASS_DUMP);
3434 break;
252b5132
RH
3435#endif
3436 case 'v':
3437 print_version (program_name);
3438 break;
3439 case 'V':
b34976b6 3440 do_version++;
252b5132 3441 break;
d974e256 3442 case 'W':
b34976b6 3443 do_wide++;
d974e256 3444 break;
252b5132 3445 default:
252b5132
RH
3446 /* xgettext:c-format */
3447 error (_("Invalid option '-%c'\n"), c);
3448 /* Drop through. */
3449 case '?':
92f01d61 3450 usage (stderr);
252b5132
RH
3451 }
3452 }
3453
4d6ed7c8 3454 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3455 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3456 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3457 && !do_section_groups && !do_archive_index
3458 && !do_dyn_syms)
92f01d61 3459 usage (stderr);
252b5132
RH
3460 else if (argc < 3)
3461 {
3462 warn (_("Nothing to do.\n"));
92f01d61 3463 usage (stderr);
252b5132
RH
3464 }
3465}
3466
3467static const char *
d3ba0551 3468get_elf_class (unsigned int elf_class)
252b5132 3469{
b34976b6 3470 static char buff[32];
103f02d3 3471
252b5132
RH
3472 switch (elf_class)
3473 {
3474 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3475 case ELFCLASS32: return "ELF32";
3476 case ELFCLASS64: return "ELF64";
ab5e7794 3477 default:
e9e44622 3478 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3479 return buff;
252b5132
RH
3480 }
3481}
3482
3483static const char *
d3ba0551 3484get_data_encoding (unsigned int encoding)
252b5132 3485{
b34976b6 3486 static char buff[32];
103f02d3 3487
252b5132
RH
3488 switch (encoding)
3489 {
3490 case ELFDATANONE: return _("none");
33c63f9d
CM
3491 case ELFDATA2LSB: return _("2's complement, little endian");
3492 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3493 default:
e9e44622 3494 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3495 return buff;
252b5132
RH
3496 }
3497}
3498
252b5132 3499/* Decode the data held in 'elf_header'. */
ee42cf8c 3500
252b5132 3501static int
d3ba0551 3502process_file_header (void)
252b5132 3503{
b34976b6
AM
3504 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3505 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3506 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3507 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3508 {
3509 error
3510 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3511 return 0;
3512 }
3513
2dc4cec1
L
3514 init_dwarf_regnames (elf_header.e_machine);
3515
252b5132
RH
3516 if (do_header)
3517 {
3518 int i;
3519
3520 printf (_("ELF Header:\n"));
3521 printf (_(" Magic: "));
b34976b6
AM
3522 for (i = 0; i < EI_NIDENT; i++)
3523 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3524 printf ("\n");
3525 printf (_(" Class: %s\n"),
b34976b6 3526 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3527 printf (_(" Data: %s\n"),
b34976b6 3528 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3529 printf (_(" Version: %d %s\n"),
b34976b6
AM
3530 elf_header.e_ident[EI_VERSION],
3531 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3532 ? "(current)"
b34976b6 3533 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3534 ? _("<unknown: %lx>")
789be9f7 3535 : "")));
252b5132 3536 printf (_(" OS/ABI: %s\n"),
b34976b6 3537 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3538 printf (_(" ABI Version: %d\n"),
b34976b6 3539 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3540 printf (_(" Type: %s\n"),
3541 get_file_type (elf_header.e_type));
3542 printf (_(" Machine: %s\n"),
3543 get_machine_name (elf_header.e_machine));
3544 printf (_(" Version: 0x%lx\n"),
3545 (unsigned long) elf_header.e_version);
76da6bbe 3546
f7a99963
NC
3547 printf (_(" Entry point address: "));
3548 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3549 printf (_("\n Start of program headers: "));
3550 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3551 printf (_(" (bytes into file)\n Start of section headers: "));
3552 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3553 printf (_(" (bytes into file)\n"));
76da6bbe 3554
252b5132
RH
3555 printf (_(" Flags: 0x%lx%s\n"),
3556 (unsigned long) elf_header.e_flags,
3557 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3558 printf (_(" Size of this header: %ld (bytes)\n"),
3559 (long) elf_header.e_ehsize);
3560 printf (_(" Size of program headers: %ld (bytes)\n"),
3561 (long) elf_header.e_phentsize);
2046a35d 3562 printf (_(" Number of program headers: %ld"),
252b5132 3563 (long) elf_header.e_phnum);
2046a35d
AM
3564 if (section_headers != NULL
3565 && elf_header.e_phnum == PN_XNUM
3566 && section_headers[0].sh_info != 0)
cc5914eb 3567 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3568 putc ('\n', stdout);
252b5132
RH
3569 printf (_(" Size of section headers: %ld (bytes)\n"),
3570 (long) elf_header.e_shentsize);
560f3c1c 3571 printf (_(" Number of section headers: %ld"),
252b5132 3572 (long) elf_header.e_shnum);
4fbb74a6 3573 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3574 printf (" (%ld)", (long) section_headers[0].sh_size);
3575 putc ('\n', stdout);
3576 printf (_(" Section header string table index: %ld"),
252b5132 3577 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3578 if (section_headers != NULL
3579 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3580 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3581 else if (elf_header.e_shstrndx != SHN_UNDEF
3582 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3583 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3584 putc ('\n', stdout);
3585 }
3586
3587 if (section_headers != NULL)
3588 {
2046a35d
AM
3589 if (elf_header.e_phnum == PN_XNUM
3590 && section_headers[0].sh_info != 0)
3591 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3592 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3593 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3594 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3595 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3596 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3597 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3598 free (section_headers);
3599 section_headers = NULL;
252b5132 3600 }
103f02d3 3601
9ea033b2
NC
3602 return 1;
3603}
3604
252b5132 3605
9ea033b2 3606static int
91d6fa6a 3607get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3608{
2cf0635d
NC
3609 Elf32_External_Phdr * phdrs;
3610 Elf32_External_Phdr * external;
3611 Elf_Internal_Phdr * internal;
b34976b6 3612 unsigned int i;
103f02d3 3613
3f5e193b
NC
3614 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3615 elf_header.e_phentsize,
3616 elf_header.e_phnum,
3617 _("program headers"));
a6e9f9df
AM
3618 if (!phdrs)
3619 return 0;
9ea033b2 3620
91d6fa6a 3621 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3622 i < elf_header.e_phnum;
b34976b6 3623 i++, internal++, external++)
252b5132 3624 {
9ea033b2
NC
3625 internal->p_type = BYTE_GET (external->p_type);
3626 internal->p_offset = BYTE_GET (external->p_offset);
3627 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3628 internal->p_paddr = BYTE_GET (external->p_paddr);
3629 internal->p_filesz = BYTE_GET (external->p_filesz);
3630 internal->p_memsz = BYTE_GET (external->p_memsz);
3631 internal->p_flags = BYTE_GET (external->p_flags);
3632 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3633 }
3634
9ea033b2
NC
3635 free (phdrs);
3636
252b5132
RH
3637 return 1;
3638}
3639
9ea033b2 3640static int
91d6fa6a 3641get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3642{
2cf0635d
NC
3643 Elf64_External_Phdr * phdrs;
3644 Elf64_External_Phdr * external;
3645 Elf_Internal_Phdr * internal;
b34976b6 3646 unsigned int i;
103f02d3 3647
3f5e193b
NC
3648 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3649 elf_header.e_phentsize,
3650 elf_header.e_phnum,
3651 _("program headers"));
a6e9f9df
AM
3652 if (!phdrs)
3653 return 0;
9ea033b2 3654
91d6fa6a 3655 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3656 i < elf_header.e_phnum;
b34976b6 3657 i++, internal++, external++)
9ea033b2
NC
3658 {
3659 internal->p_type = BYTE_GET (external->p_type);
3660 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3661 internal->p_offset = BYTE_GET (external->p_offset);
3662 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3663 internal->p_paddr = BYTE_GET (external->p_paddr);
3664 internal->p_filesz = BYTE_GET (external->p_filesz);
3665 internal->p_memsz = BYTE_GET (external->p_memsz);
3666 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3667 }
3668
3669 free (phdrs);
3670
3671 return 1;
3672}
252b5132 3673
d93f0186
NC
3674/* Returns 1 if the program headers were read into `program_headers'. */
3675
3676static int
2cf0635d 3677get_program_headers (FILE * file)
d93f0186 3678{
2cf0635d 3679 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3680
3681 /* Check cache of prior read. */
3682 if (program_headers != NULL)
3683 return 1;
3684
3f5e193b
NC
3685 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3686 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3687
3688 if (phdrs == NULL)
3689 {
3690 error (_("Out of memory\n"));
3691 return 0;
3692 }
3693
3694 if (is_32bit_elf
3695 ? get_32bit_program_headers (file, phdrs)
3696 : get_64bit_program_headers (file, phdrs))
3697 {
3698 program_headers = phdrs;
3699 return 1;
3700 }
3701
3702 free (phdrs);
3703 return 0;
3704}
3705
2f62977e
NC
3706/* Returns 1 if the program headers were loaded. */
3707
252b5132 3708static int
2cf0635d 3709process_program_headers (FILE * file)
252b5132 3710{
2cf0635d 3711 Elf_Internal_Phdr * segment;
b34976b6 3712 unsigned int i;
252b5132
RH
3713
3714 if (elf_header.e_phnum == 0)
3715 {
3716 if (do_segments)
3717 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3718 return 0;
252b5132
RH
3719 }
3720
3721 if (do_segments && !do_header)
3722 {
f7a99963
NC
3723 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3724 printf (_("Entry point "));
3725 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3726 printf (_("\nThere are %d program headers, starting at offset "),
3727 elf_header.e_phnum);
3728 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3729 printf ("\n");
252b5132
RH
3730 }
3731
d93f0186 3732 if (! get_program_headers (file))
252b5132 3733 return 0;
103f02d3 3734
252b5132
RH
3735 if (do_segments)
3736 {
3a1a2036
NC
3737 if (elf_header.e_phnum > 1)
3738 printf (_("\nProgram Headers:\n"));
3739 else
3740 printf (_("\nProgram Headers:\n"));
76da6bbe 3741
f7a99963
NC
3742 if (is_32bit_elf)
3743 printf
3744 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3745 else if (do_wide)
3746 printf
3747 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3748 else
3749 {
3750 printf
3751 (_(" Type Offset VirtAddr PhysAddr\n"));
3752 printf
3753 (_(" FileSiz MemSiz Flags Align\n"));
3754 }
252b5132
RH
3755 }
3756
252b5132 3757 dynamic_addr = 0;
1b228002 3758 dynamic_size = 0;
252b5132
RH
3759
3760 for (i = 0, segment = program_headers;
3761 i < elf_header.e_phnum;
b34976b6 3762 i++, segment++)
252b5132
RH
3763 {
3764 if (do_segments)
3765 {
103f02d3 3766 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3767
3768 if (is_32bit_elf)
3769 {
3770 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3771 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3772 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3773 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3774 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3775 printf ("%c%c%c ",
3776 (segment->p_flags & PF_R ? 'R' : ' '),
3777 (segment->p_flags & PF_W ? 'W' : ' '),
3778 (segment->p_flags & PF_X ? 'E' : ' '));
3779 printf ("%#lx", (unsigned long) segment->p_align);
3780 }
d974e256
JJ
3781 else if (do_wide)
3782 {
3783 if ((unsigned long) segment->p_offset == segment->p_offset)
3784 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3785 else
3786 {
3787 print_vma (segment->p_offset, FULL_HEX);
3788 putchar (' ');
3789 }
3790
3791 print_vma (segment->p_vaddr, FULL_HEX);
3792 putchar (' ');
3793 print_vma (segment->p_paddr, FULL_HEX);
3794 putchar (' ');
3795
3796 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3797 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3798 else
3799 {
3800 print_vma (segment->p_filesz, FULL_HEX);
3801 putchar (' ');
3802 }
3803
3804 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3805 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3806 else
3807 {
3808 print_vma (segment->p_offset, FULL_HEX);
3809 }
3810
3811 printf (" %c%c%c ",
3812 (segment->p_flags & PF_R ? 'R' : ' '),
3813 (segment->p_flags & PF_W ? 'W' : ' '),
3814 (segment->p_flags & PF_X ? 'E' : ' '));
3815
3816 if ((unsigned long) segment->p_align == segment->p_align)
3817 printf ("%#lx", (unsigned long) segment->p_align);
3818 else
3819 {
3820 print_vma (segment->p_align, PREFIX_HEX);
3821 }
3822 }
f7a99963
NC
3823 else
3824 {
3825 print_vma (segment->p_offset, FULL_HEX);
3826 putchar (' ');
3827 print_vma (segment->p_vaddr, FULL_HEX);
3828 putchar (' ');
3829 print_vma (segment->p_paddr, FULL_HEX);
3830 printf ("\n ");
3831 print_vma (segment->p_filesz, FULL_HEX);
3832 putchar (' ');
3833 print_vma (segment->p_memsz, FULL_HEX);
3834 printf (" %c%c%c ",
3835 (segment->p_flags & PF_R ? 'R' : ' '),
3836 (segment->p_flags & PF_W ? 'W' : ' '),
3837 (segment->p_flags & PF_X ? 'E' : ' '));
3838 print_vma (segment->p_align, HEX);
3839 }
252b5132
RH
3840 }
3841
3842 switch (segment->p_type)
3843 {
252b5132
RH
3844 case PT_DYNAMIC:
3845 if (dynamic_addr)
3846 error (_("more than one dynamic segment\n"));
3847
20737c13
AM
3848 /* By default, assume that the .dynamic section is the first
3849 section in the DYNAMIC segment. */
3850 dynamic_addr = segment->p_offset;
3851 dynamic_size = segment->p_filesz;
3852
b2d38a17
NC
3853 /* Try to locate the .dynamic section. If there is
3854 a section header table, we can easily locate it. */
3855 if (section_headers != NULL)
3856 {
2cf0635d 3857 Elf_Internal_Shdr * sec;
b2d38a17 3858
89fac5e3
RS
3859 sec = find_section (".dynamic");
3860 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3861 {
28f997cf
TG
3862 /* A corresponding .dynamic section is expected, but on
3863 IA-64/OpenVMS it is OK for it to be missing. */
3864 if (!is_ia64_vms ())
3865 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3866 break;
3867 }
3868
42bb2e33 3869 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3870 {
3871 dynamic_size = 0;
3872 break;
3873 }
42bb2e33 3874
b2d38a17
NC
3875 dynamic_addr = sec->sh_offset;
3876 dynamic_size = sec->sh_size;
3877
3878 if (dynamic_addr < segment->p_offset
3879 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3880 warn (_("the .dynamic section is not contained"
3881 " within the dynamic segment\n"));
b2d38a17 3882 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3883 warn (_("the .dynamic section is not the first section"
3884 " in the dynamic segment.\n"));
b2d38a17 3885 }
252b5132
RH
3886 break;
3887
3888 case PT_INTERP:
fb52b2f4
NC
3889 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3890 SEEK_SET))
252b5132
RH
3891 error (_("Unable to find program interpreter name\n"));
3892 else
3893 {
f8eae8b2
L
3894 char fmt [32];
3895 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3896
3897 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3898 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3899
252b5132 3900 program_interpreter[0] = 0;
7bd7b3ef
AM
3901 if (fscanf (file, fmt, program_interpreter) <= 0)
3902 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3903
3904 if (do_segments)
3905 printf (_("\n [Requesting program interpreter: %s]"),
3906 program_interpreter);
3907 }
3908 break;
3909 }
3910
3911 if (do_segments)
3912 putc ('\n', stdout);
3913 }
3914
c256ffe7 3915 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3916 {
3917 printf (_("\n Section to Segment mapping:\n"));
3918 printf (_(" Segment Sections...\n"));
3919
252b5132
RH
3920 for (i = 0; i < elf_header.e_phnum; i++)
3921 {
9ad5cbcf 3922 unsigned int j;
2cf0635d 3923 Elf_Internal_Shdr * section;
252b5132
RH
3924
3925 segment = program_headers + i;
b391a3e3 3926 section = section_headers + 1;
252b5132
RH
3927
3928 printf (" %2.2d ", i);
3929
b34976b6 3930 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3931 {
f4638467
AM
3932 if (!ELF_TBSS_SPECIAL (section, segment)
3933 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
3934 printf ("%s ", SECTION_NAME (section));
3935 }
3936
3937 putc ('\n',stdout);
3938 }
3939 }
3940
252b5132
RH
3941 return 1;
3942}
3943
3944
d93f0186
NC
3945/* Find the file offset corresponding to VMA by using the program headers. */
3946
3947static long
2cf0635d 3948offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 3949{
2cf0635d 3950 Elf_Internal_Phdr * seg;
d93f0186
NC
3951
3952 if (! get_program_headers (file))
3953 {
3954 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3955 return (long) vma;
3956 }
3957
3958 for (seg = program_headers;
3959 seg < program_headers + elf_header.e_phnum;
3960 ++seg)
3961 {
3962 if (seg->p_type != PT_LOAD)
3963 continue;
3964
3965 if (vma >= (seg->p_vaddr & -seg->p_align)
3966 && vma + size <= seg->p_vaddr + seg->p_filesz)
3967 return vma - seg->p_vaddr + seg->p_offset;
3968 }
3969
3970 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 3971 (unsigned long) vma);
d93f0186
NC
3972 return (long) vma;
3973}
3974
3975
252b5132 3976static int
2cf0635d 3977get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 3978{
2cf0635d
NC
3979 Elf32_External_Shdr * shdrs;
3980 Elf_Internal_Shdr * internal;
b34976b6 3981 unsigned int i;
252b5132 3982
3f5e193b
NC
3983 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3984 elf_header.e_shentsize, num,
3985 _("section headers"));
a6e9f9df
AM
3986 if (!shdrs)
3987 return 0;
252b5132 3988
3f5e193b
NC
3989 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3990 sizeof (Elf_Internal_Shdr));
252b5132
RH
3991
3992 if (section_headers == NULL)
3993 {
3994 error (_("Out of memory\n"));
3995 return 0;
3996 }
3997
3998 for (i = 0, internal = section_headers;
560f3c1c 3999 i < num;
b34976b6 4000 i++, internal++)
252b5132
RH
4001 {
4002 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4003 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4004 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4005 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4006 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4007 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4008 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4009 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4010 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4011 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4012 }
4013
4014 free (shdrs);
4015
4016 return 1;
4017}
4018
9ea033b2 4019static int
2cf0635d 4020get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4021{
2cf0635d
NC
4022 Elf64_External_Shdr * shdrs;
4023 Elf_Internal_Shdr * internal;
b34976b6 4024 unsigned int i;
9ea033b2 4025
3f5e193b
NC
4026 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4027 elf_header.e_shentsize, num,
4028 _("section headers"));
a6e9f9df
AM
4029 if (!shdrs)
4030 return 0;
9ea033b2 4031
3f5e193b
NC
4032 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4033 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4034
4035 if (section_headers == NULL)
4036 {
4037 error (_("Out of memory\n"));
4038 return 0;
4039 }
4040
4041 for (i = 0, internal = section_headers;
560f3c1c 4042 i < num;
b34976b6 4043 i++, internal++)
9ea033b2
NC
4044 {
4045 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4046 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4047 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4048 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4049 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4050 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4051 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4052 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4053 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4054 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4055 }
4056
4057 free (shdrs);
4058
4059 return 1;
4060}
4061
252b5132 4062static Elf_Internal_Sym *
2cf0635d 4063get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
252b5132 4064{
9ad5cbcf 4065 unsigned long number;
dd24e3da 4066 Elf32_External_Sym * esyms = NULL;
2cf0635d 4067 Elf_External_Sym_Shndx * shndx;
dd24e3da 4068 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4069 Elf_Internal_Sym * psym;
b34976b6 4070 unsigned int j;
252b5132 4071
dd24e3da
NC
4072 /* Run some sanity checks first. */
4073 if (section->sh_entsize == 0)
4074 {
4075 error (_("sh_entsize is zero\n"));
4076 return NULL;
4077 }
4078
4079 number = section->sh_size / section->sh_entsize;
4080
4081 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4082 {
4083 error (_("Invalid sh_entsize\n"));
4084 return NULL;
4085 }
4086
3f5e193b
NC
4087 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4088 section->sh_size, _("symbols"));
dd24e3da 4089 if (esyms == NULL)
a6e9f9df 4090 return NULL;
252b5132 4091
9ad5cbcf
AM
4092 shndx = NULL;
4093 if (symtab_shndx_hdr != NULL
4094 && (symtab_shndx_hdr->sh_link
4fbb74a6 4095 == (unsigned long) (section - section_headers)))
9ad5cbcf 4096 {
3f5e193b
NC
4097 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4098 symtab_shndx_hdr->sh_offset,
4099 1, symtab_shndx_hdr->sh_size,
4100 _("symtab shndx"));
dd24e3da
NC
4101 if (shndx == NULL)
4102 goto exit_point;
9ad5cbcf
AM
4103 }
4104
3f5e193b 4105 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4106
4107 if (isyms == NULL)
4108 {
4109 error (_("Out of memory\n"));
dd24e3da 4110 goto exit_point;
252b5132
RH
4111 }
4112
dd24e3da 4113 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4114 {
4115 psym->st_name = BYTE_GET (esyms[j].st_name);
4116 psym->st_value = BYTE_GET (esyms[j].st_value);
4117 psym->st_size = BYTE_GET (esyms[j].st_size);
4118 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4119 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4120 psym->st_shndx
4121 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4122 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4123 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4124 psym->st_info = BYTE_GET (esyms[j].st_info);
4125 psym->st_other = BYTE_GET (esyms[j].st_other);
4126 }
4127
dd24e3da 4128 exit_point:
9ad5cbcf
AM
4129 if (shndx)
4130 free (shndx);
dd24e3da
NC
4131 if (esyms)
4132 free (esyms);
252b5132
RH
4133
4134 return isyms;
4135}
4136
9ea033b2 4137static Elf_Internal_Sym *
2cf0635d 4138get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
9ea033b2 4139{
9ad5cbcf 4140 unsigned long number;
2cf0635d
NC
4141 Elf64_External_Sym * esyms;
4142 Elf_External_Sym_Shndx * shndx;
4143 Elf_Internal_Sym * isyms;
4144 Elf_Internal_Sym * psym;
b34976b6 4145 unsigned int j;
9ea033b2 4146
dd24e3da
NC
4147 /* Run some sanity checks first. */
4148 if (section->sh_entsize == 0)
4149 {
4150 error (_("sh_entsize is zero\n"));
4151 return NULL;
4152 }
4153
4154 number = section->sh_size / section->sh_entsize;
4155
4156 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4157 {
4158 error (_("Invalid sh_entsize\n"));
4159 return NULL;
4160 }
4161
3f5e193b
NC
4162 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4163 section->sh_size, _("symbols"));
a6e9f9df
AM
4164 if (!esyms)
4165 return NULL;
9ea033b2 4166
9ad5cbcf
AM
4167 shndx = NULL;
4168 if (symtab_shndx_hdr != NULL
4169 && (symtab_shndx_hdr->sh_link
4fbb74a6 4170 == (unsigned long) (section - section_headers)))
9ad5cbcf 4171 {
3f5e193b
NC
4172 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4173 symtab_shndx_hdr->sh_offset,
4174 1, symtab_shndx_hdr->sh_size,
4175 _("symtab shndx"));
9ad5cbcf
AM
4176 if (!shndx)
4177 {
4178 free (esyms);
4179 return NULL;
4180 }
4181 }
4182
3f5e193b 4183 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4184
4185 if (isyms == NULL)
4186 {
4187 error (_("Out of memory\n"));
9ad5cbcf
AM
4188 if (shndx)
4189 free (shndx);
9ea033b2 4190 free (esyms);
9ea033b2
NC
4191 return NULL;
4192 }
4193
4194 for (j = 0, psym = isyms;
4195 j < number;
b34976b6 4196 j++, psym++)
9ea033b2
NC
4197 {
4198 psym->st_name = BYTE_GET (esyms[j].st_name);
4199 psym->st_info = BYTE_GET (esyms[j].st_info);
4200 psym->st_other = BYTE_GET (esyms[j].st_other);
4201 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4202 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4203 psym->st_shndx
4204 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4205 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4206 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
66543521
AM
4207 psym->st_value = BYTE_GET (esyms[j].st_value);
4208 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4209 }
4210
9ad5cbcf
AM
4211 if (shndx)
4212 free (shndx);
9ea033b2
NC
4213 free (esyms);
4214
4215 return isyms;
4216}
4217
d1133906 4218static const char *
d3ba0551 4219get_elf_section_flags (bfd_vma sh_flags)
d1133906 4220{
5477e8a0 4221 static char buff[1024];
2cf0635d 4222 char * p = buff;
8d5ff12c 4223 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4224 int sindex;
4225 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4226 bfd_vma os_flags = 0;
4227 bfd_vma proc_flags = 0;
4228 bfd_vma unknown_flags = 0;
148b93f2 4229 static const struct
5477e8a0 4230 {
2cf0635d 4231 const char * str;
5477e8a0
L
4232 int len;
4233 }
4234 flags [] =
4235 {
cfcac11d
NC
4236 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4237 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4238 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4239 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4240 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4241 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4242 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4243 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4244 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4245 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4246 /* IA-64 specific. */
4247 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4248 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4249 /* IA-64 OpenVMS specific. */
4250 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4251 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4252 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4253 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4254 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4255 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4256 /* Generic. */
cfcac11d 4257 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4258 /* SPARC specific. */
cfcac11d 4259 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4260 };
4261
4262 if (do_section_details)
4263 {
8d5ff12c
L
4264 sprintf (buff, "[%*.*lx]: ",
4265 field_size, field_size, (unsigned long) sh_flags);
4266 p += field_size + 4;
5477e8a0 4267 }
76da6bbe 4268
d1133906
NC
4269 while (sh_flags)
4270 {
4271 bfd_vma flag;
4272
4273 flag = sh_flags & - sh_flags;
4274 sh_flags &= ~ flag;
76da6bbe 4275
5477e8a0 4276 if (do_section_details)
d1133906 4277 {
5477e8a0
L
4278 switch (flag)
4279 {
91d6fa6a
NC
4280 case SHF_WRITE: sindex = 0; break;
4281 case SHF_ALLOC: sindex = 1; break;
4282 case SHF_EXECINSTR: sindex = 2; break;
4283 case SHF_MERGE: sindex = 3; break;
4284 case SHF_STRINGS: sindex = 4; break;
4285 case SHF_INFO_LINK: sindex = 5; break;
4286 case SHF_LINK_ORDER: sindex = 6; break;
4287 case SHF_OS_NONCONFORMING: sindex = 7; break;
4288 case SHF_GROUP: sindex = 8; break;
4289 case SHF_TLS: sindex = 9; break;
18ae9cc1 4290 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4291
5477e8a0 4292 default:
91d6fa6a 4293 sindex = -1;
cfcac11d 4294 switch (elf_header.e_machine)
148b93f2 4295 {
cfcac11d 4296 case EM_IA_64:
148b93f2 4297 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4298 sindex = 10;
148b93f2 4299 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4300 sindex = 11;
148b93f2
NC
4301#ifdef BFD64
4302 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4303 switch (flag)
4304 {
91d6fa6a
NC
4305 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4306 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4307 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4308 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4309 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4310 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4311 default: break;
4312 }
4313#endif
cfcac11d
NC
4314 break;
4315
caa83f8b
NC
4316 case EM_386:
4317 case EM_486:
4318 case EM_X86_64:
7f502d6c 4319 case EM_L1OM:
cfcac11d
NC
4320 case EM_OLD_SPARCV9:
4321 case EM_SPARC32PLUS:
4322 case EM_SPARCV9:
4323 case EM_SPARC:
18ae9cc1 4324 if (flag == SHF_ORDERED)
91d6fa6a 4325 sindex = 19;
cfcac11d
NC
4326 break;
4327 default:
4328 break;
148b93f2 4329 }
5477e8a0
L
4330 }
4331
91d6fa6a 4332 if (sindex != -1)
5477e8a0 4333 {
8d5ff12c
L
4334 if (p != buff + field_size + 4)
4335 {
4336 if (size < (10 + 2))
4337 abort ();
4338 size -= 2;
4339 *p++ = ',';
4340 *p++ = ' ';
4341 }
4342
91d6fa6a
NC
4343 size -= flags [sindex].len;
4344 p = stpcpy (p, flags [sindex].str);
5477e8a0 4345 }
3b22753a 4346 else if (flag & SHF_MASKOS)
8d5ff12c 4347 os_flags |= flag;
d1133906 4348 else if (flag & SHF_MASKPROC)
8d5ff12c 4349 proc_flags |= flag;
d1133906 4350 else
8d5ff12c 4351 unknown_flags |= flag;
5477e8a0
L
4352 }
4353 else
4354 {
4355 switch (flag)
4356 {
4357 case SHF_WRITE: *p = 'W'; break;
4358 case SHF_ALLOC: *p = 'A'; break;
4359 case SHF_EXECINSTR: *p = 'X'; break;
4360 case SHF_MERGE: *p = 'M'; break;
4361 case SHF_STRINGS: *p = 'S'; break;
4362 case SHF_INFO_LINK: *p = 'I'; break;
4363 case SHF_LINK_ORDER: *p = 'L'; break;
4364 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4365 case SHF_GROUP: *p = 'G'; break;
4366 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4367 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4368
4369 default:
8a9036a4
L
4370 if ((elf_header.e_machine == EM_X86_64
4371 || elf_header.e_machine == EM_L1OM)
5477e8a0
L
4372 && flag == SHF_X86_64_LARGE)
4373 *p = 'l';
4374 else if (flag & SHF_MASKOS)
4375 {
4376 *p = 'o';
4377 sh_flags &= ~ SHF_MASKOS;
4378 }
4379 else if (flag & SHF_MASKPROC)
4380 {
4381 *p = 'p';
4382 sh_flags &= ~ SHF_MASKPROC;
4383 }
4384 else
4385 *p = 'x';
4386 break;
4387 }
4388 p++;
d1133906
NC
4389 }
4390 }
76da6bbe 4391
8d5ff12c
L
4392 if (do_section_details)
4393 {
4394 if (os_flags)
4395 {
4396 size -= 5 + field_size;
4397 if (p != buff + field_size + 4)
4398 {
4399 if (size < (2 + 1))
4400 abort ();
4401 size -= 2;
4402 *p++ = ',';
4403 *p++ = ' ';
4404 }
4405 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4406 (unsigned long) os_flags);
4407 p += 5 + field_size;
4408 }
4409 if (proc_flags)
4410 {
4411 size -= 7 + field_size;
4412 if (p != buff + field_size + 4)
4413 {
4414 if (size < (2 + 1))
4415 abort ();
4416 size -= 2;
4417 *p++ = ',';
4418 *p++ = ' ';
4419 }
4420 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4421 (unsigned long) proc_flags);
4422 p += 7 + field_size;
4423 }
4424 if (unknown_flags)
4425 {
4426 size -= 10 + field_size;
4427 if (p != buff + field_size + 4)
4428 {
4429 if (size < (2 + 1))
4430 abort ();
4431 size -= 2;
4432 *p++ = ',';
4433 *p++ = ' ';
4434 }
2b692964 4435 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4436 (unsigned long) unknown_flags);
4437 p += 10 + field_size;
4438 }
4439 }
4440
e9e44622 4441 *p = '\0';
d1133906
NC
4442 return buff;
4443}
4444
252b5132 4445static int
2cf0635d 4446process_section_headers (FILE * file)
252b5132 4447{
2cf0635d 4448 Elf_Internal_Shdr * section;
b34976b6 4449 unsigned int i;
252b5132
RH
4450
4451 section_headers = NULL;
4452
4453 if (elf_header.e_shnum == 0)
4454 {
4455 if (do_sections)
4456 printf (_("\nThere are no sections in this file.\n"));
4457
4458 return 1;
4459 }
4460
4461 if (do_sections && !do_header)
9ea033b2 4462 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4463 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4464
9ea033b2
NC
4465 if (is_32bit_elf)
4466 {
560f3c1c 4467 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4468 return 0;
4469 }
560f3c1c 4470 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4471 return 0;
4472
4473 /* Read in the string table, so that we have names to display. */
0b49d371 4474 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4475 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4476 {
4fbb74a6 4477 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4478
c256ffe7
JJ
4479 if (section->sh_size != 0)
4480 {
3f5e193b
NC
4481 string_table = (char *) get_data (NULL, file, section->sh_offset,
4482 1, section->sh_size,
4483 _("string table"));
0de14b54 4484
c256ffe7
JJ
4485 string_table_length = string_table != NULL ? section->sh_size : 0;
4486 }
252b5132
RH
4487 }
4488
4489 /* Scan the sections for the dynamic symbol table
e3c8793a 4490 and dynamic string table and debug sections. */
252b5132
RH
4491 dynamic_symbols = NULL;
4492 dynamic_strings = NULL;
4493 dynamic_syminfo = NULL;
f1ef08cb 4494 symtab_shndx_hdr = NULL;
103f02d3 4495
89fac5e3
RS
4496 eh_addr_size = is_32bit_elf ? 4 : 8;
4497 switch (elf_header.e_machine)
4498 {
4499 case EM_MIPS:
4500 case EM_MIPS_RS3_LE:
4501 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4502 FDE addresses. However, the ABI also has a semi-official ILP32
4503 variant for which the normal FDE address size rules apply.
4504
4505 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4506 section, where XX is the size of longs in bits. Unfortunately,
4507 earlier compilers provided no way of distinguishing ILP32 objects
4508 from LP64 objects, so if there's any doubt, we should assume that
4509 the official LP64 form is being used. */
4510 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4511 && find_section (".gcc_compiled_long32") == NULL)
4512 eh_addr_size = 8;
4513 break;
0f56a26a
DD
4514
4515 case EM_H8_300:
4516 case EM_H8_300H:
4517 switch (elf_header.e_flags & EF_H8_MACH)
4518 {
4519 case E_H8_MACH_H8300:
4520 case E_H8_MACH_H8300HN:
4521 case E_H8_MACH_H8300SN:
4522 case E_H8_MACH_H8300SXN:
4523 eh_addr_size = 2;
4524 break;
4525 case E_H8_MACH_H8300H:
4526 case E_H8_MACH_H8300S:
4527 case E_H8_MACH_H8300SX:
4528 eh_addr_size = 4;
4529 break;
4530 }
f4236fe4
DD
4531 break;
4532
ff7eeb89 4533 case EM_M32C_OLD:
f4236fe4
DD
4534 case EM_M32C:
4535 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4536 {
4537 case EF_M32C_CPU_M16C:
4538 eh_addr_size = 2;
4539 break;
4540 }
4541 break;
89fac5e3
RS
4542 }
4543
08d8fa11
JJ
4544#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4545 do \
4546 { \
4547 size_t expected_entsize \
4548 = is_32bit_elf ? size32 : size64; \
4549 if (section->sh_entsize != expected_entsize) \
4550 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4551 i, (unsigned long int) section->sh_entsize, \
4552 (unsigned long int) expected_entsize); \
4553 section->sh_entsize = expected_entsize; \
4554 } \
4555 while (0)
4556#define CHECK_ENTSIZE(section, i, type) \
4557 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4558 sizeof (Elf64_External_##type))
4559
252b5132
RH
4560 for (i = 0, section = section_headers;
4561 i < elf_header.e_shnum;
b34976b6 4562 i++, section++)
252b5132 4563 {
2cf0635d 4564 char * name = SECTION_NAME (section);
252b5132
RH
4565
4566 if (section->sh_type == SHT_DYNSYM)
4567 {
4568 if (dynamic_symbols != NULL)
4569 {
4570 error (_("File contains multiple dynamic symbol tables\n"));
4571 continue;
4572 }
4573
08d8fa11 4574 CHECK_ENTSIZE (section, i, Sym);
19936277 4575 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4576 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4577 }
4578 else if (section->sh_type == SHT_STRTAB
18bd398b 4579 && streq (name, ".dynstr"))
252b5132
RH
4580 {
4581 if (dynamic_strings != NULL)
4582 {
4583 error (_("File contains multiple dynamic string tables\n"));
4584 continue;
4585 }
4586
3f5e193b
NC
4587 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4588 1, section->sh_size,
4589 _("dynamic strings"));
d79b3d50 4590 dynamic_strings_length = section->sh_size;
252b5132 4591 }
9ad5cbcf
AM
4592 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4593 {
4594 if (symtab_shndx_hdr != NULL)
4595 {
4596 error (_("File contains multiple symtab shndx tables\n"));
4597 continue;
4598 }
4599 symtab_shndx_hdr = section;
4600 }
08d8fa11
JJ
4601 else if (section->sh_type == SHT_SYMTAB)
4602 CHECK_ENTSIZE (section, i, Sym);
4603 else if (section->sh_type == SHT_GROUP)
4604 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4605 else if (section->sh_type == SHT_REL)
4606 CHECK_ENTSIZE (section, i, Rel);
4607 else if (section->sh_type == SHT_RELA)
4608 CHECK_ENTSIZE (section, i, Rela);
252b5132 4609 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4610 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4611 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4612 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4613 && (const_strneq (name, ".debug_")
4614 || const_strneq (name, ".zdebug_")))
252b5132 4615 {
1b315056
CS
4616 if (name[1] == 'z')
4617 name += sizeof (".zdebug_") - 1;
4618 else
4619 name += sizeof (".debug_") - 1;
252b5132
RH
4620
4621 if (do_debugging
18bd398b 4622 || (do_debug_info && streq (name, "info"))
2b6f5997 4623 || (do_debug_info && streq (name, "types"))
18bd398b 4624 || (do_debug_abbrevs && streq (name, "abbrev"))
4cb93e3b 4625 || (do_debug_lines && streq (name, "line"))
18bd398b 4626 || (do_debug_pubnames && streq (name, "pubnames"))
f9f0e732 4627 || (do_debug_pubtypes && streq (name, "pubtypes"))
18bd398b
NC
4628 || (do_debug_aranges && streq (name, "aranges"))
4629 || (do_debug_ranges && streq (name, "ranges"))
4630 || (do_debug_frames && streq (name, "frame"))
4631 || (do_debug_macinfo && streq (name, "macinfo"))
4632 || (do_debug_str && streq (name, "str"))
4633 || (do_debug_loc && streq (name, "loc"))
252b5132 4634 )
09c11c86 4635 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4636 }
a262ae96 4637 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4638 else if ((do_debugging || do_debug_info)
0112cd26 4639 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4640 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4641 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4642 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4643 /* Trace sections for Itanium VMS. */
4644 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4645 || do_trace_aranges)
4646 && const_strneq (name, ".trace_"))
4647 {
4648 name += sizeof (".trace_") - 1;
4649
4650 if (do_debugging
4651 || (do_trace_info && streq (name, "info"))
4652 || (do_trace_abbrevs && streq (name, "abbrev"))
4653 || (do_trace_aranges && streq (name, "aranges"))
4654 )
4655 request_dump_bynumber (i, DEBUG_DUMP);
4656 }
4657
252b5132
RH
4658 }
4659
4660 if (! do_sections)
4661 return 1;
4662
3a1a2036
NC
4663 if (elf_header.e_shnum > 1)
4664 printf (_("\nSection Headers:\n"));
4665 else
4666 printf (_("\nSection Header:\n"));
76da6bbe 4667
f7a99963 4668 if (is_32bit_elf)
595cf52e 4669 {
5477e8a0 4670 if (do_section_details)
595cf52e
L
4671 {
4672 printf (_(" [Nr] Name\n"));
5477e8a0 4673 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4674 }
4675 else
4676 printf
4677 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4678 }
d974e256 4679 else if (do_wide)
595cf52e 4680 {
5477e8a0 4681 if (do_section_details)
595cf52e
L
4682 {
4683 printf (_(" [Nr] Name\n"));
5477e8a0 4684 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4685 }
4686 else
4687 printf
4688 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4689 }
f7a99963
NC
4690 else
4691 {
5477e8a0 4692 if (do_section_details)
595cf52e
L
4693 {
4694 printf (_(" [Nr] Name\n"));
5477e8a0
L
4695 printf (_(" Type Address Offset Link\n"));
4696 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4697 }
4698 else
4699 {
4700 printf (_(" [Nr] Name Type Address Offset\n"));
4701 printf (_(" Size EntSize Flags Link Info Align\n"));
4702 }
f7a99963 4703 }
252b5132 4704
5477e8a0
L
4705 if (do_section_details)
4706 printf (_(" Flags\n"));
4707
252b5132
RH
4708 for (i = 0, section = section_headers;
4709 i < elf_header.e_shnum;
b34976b6 4710 i++, section++)
252b5132 4711 {
5477e8a0 4712 if (do_section_details)
595cf52e
L
4713 {
4714 printf (" [%2u] %s\n",
4fbb74a6 4715 i,
595cf52e
L
4716 SECTION_NAME (section));
4717 if (is_32bit_elf || do_wide)
4718 printf (" %-15.15s ",
4719 get_section_type_name (section->sh_type));
4720 }
4721 else
b9eb56c1
NC
4722 printf ((do_wide ? " [%2u] %-17s %-15s "
4723 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4724 i,
595cf52e
L
4725 SECTION_NAME (section),
4726 get_section_type_name (section->sh_type));
252b5132 4727
f7a99963
NC
4728 if (is_32bit_elf)
4729 {
cfcac11d
NC
4730 const char * link_too_big = NULL;
4731
f7a99963 4732 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4733
f7a99963
NC
4734 printf ( " %6.6lx %6.6lx %2.2lx",
4735 (unsigned long) section->sh_offset,
4736 (unsigned long) section->sh_size,
4737 (unsigned long) section->sh_entsize);
d1133906 4738
5477e8a0
L
4739 if (do_section_details)
4740 fputs (" ", stdout);
4741 else
4742 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4743
cfcac11d
NC
4744 if (section->sh_link >= elf_header.e_shnum)
4745 {
4746 link_too_big = "";
4747 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4748 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4749 switch (elf_header.e_machine)
4750 {
caa83f8b
NC
4751 case EM_386:
4752 case EM_486:
4753 case EM_X86_64:
7f502d6c 4754 case EM_L1OM:
cfcac11d
NC
4755 case EM_OLD_SPARCV9:
4756 case EM_SPARC32PLUS:
4757 case EM_SPARCV9:
4758 case EM_SPARC:
4759 if (section->sh_link == (SHN_BEFORE & 0xffff))
4760 link_too_big = "BEFORE";
4761 else if (section->sh_link == (SHN_AFTER & 0xffff))
4762 link_too_big = "AFTER";
4763 break;
4764 default:
4765 break;
4766 }
4767 }
4768
4769 if (do_section_details)
4770 {
4771 if (link_too_big != NULL && * link_too_big)
4772 printf ("<%s> ", link_too_big);
4773 else
4774 printf ("%2u ", section->sh_link);
4775 printf ("%3u %2lu\n", section->sh_info,
4776 (unsigned long) section->sh_addralign);
4777 }
4778 else
4779 printf ("%2u %3u %2lu\n",
4780 section->sh_link,
4781 section->sh_info,
4782 (unsigned long) section->sh_addralign);
4783
4784 if (link_too_big && ! * link_too_big)
4785 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4786 i, section->sh_link);
f7a99963 4787 }
d974e256
JJ
4788 else if (do_wide)
4789 {
4790 print_vma (section->sh_addr, LONG_HEX);
4791
4792 if ((long) section->sh_offset == section->sh_offset)
4793 printf (" %6.6lx", (unsigned long) section->sh_offset);
4794 else
4795 {
4796 putchar (' ');
4797 print_vma (section->sh_offset, LONG_HEX);
4798 }
4799
4800 if ((unsigned long) section->sh_size == section->sh_size)
4801 printf (" %6.6lx", (unsigned long) section->sh_size);
4802 else
4803 {
4804 putchar (' ');
4805 print_vma (section->sh_size, LONG_HEX);
4806 }
4807
4808 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4809 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4810 else
4811 {
4812 putchar (' ');
4813 print_vma (section->sh_entsize, LONG_HEX);
4814 }
4815
5477e8a0
L
4816 if (do_section_details)
4817 fputs (" ", stdout);
4818 else
4819 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4820
72de5009 4821 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4822
4823 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4824 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4825 else
4826 {
4827 print_vma (section->sh_addralign, DEC);
4828 putchar ('\n');
4829 }
4830 }
5477e8a0 4831 else if (do_section_details)
595cf52e 4832 {
5477e8a0 4833 printf (" %-15.15s ",
595cf52e 4834 get_section_type_name (section->sh_type));
595cf52e
L
4835 print_vma (section->sh_addr, LONG_HEX);
4836 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4837 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4838 else
4839 {
4840 printf (" ");
4841 print_vma (section->sh_offset, LONG_HEX);
4842 }
72de5009 4843 printf (" %u\n ", section->sh_link);
595cf52e 4844 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4845 putchar (' ');
595cf52e
L
4846 print_vma (section->sh_entsize, LONG_HEX);
4847
72de5009
AM
4848 printf (" %-16u %lu\n",
4849 section->sh_info,
595cf52e
L
4850 (unsigned long) section->sh_addralign);
4851 }
f7a99963
NC
4852 else
4853 {
4854 putchar (' ');
4855 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4856 if ((long) section->sh_offset == section->sh_offset)
4857 printf (" %8.8lx", (unsigned long) section->sh_offset);
4858 else
4859 {
4860 printf (" ");
4861 print_vma (section->sh_offset, LONG_HEX);
4862 }
f7a99963
NC
4863 printf ("\n ");
4864 print_vma (section->sh_size, LONG_HEX);
4865 printf (" ");
4866 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4867
d1133906 4868 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4869
72de5009
AM
4870 printf (" %2u %3u %lu\n",
4871 section->sh_link,
4872 section->sh_info,
f7a99963
NC
4873 (unsigned long) section->sh_addralign);
4874 }
5477e8a0
L
4875
4876 if (do_section_details)
4877 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4878 }
4879
5477e8a0 4880 if (!do_section_details)
3dbcc61d
NC
4881 {
4882 if (elf_header.e_machine == EM_X86_64
4883 || elf_header.e_machine == EM_L1OM)
4884 printf (_("Key to Flags:\n\
4885 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
4886 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
4887 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
4888 else
4889 printf (_("Key to Flags:\n\
e3c8793a 4890 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 4891 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 4892 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 4893 }
d1133906 4894
252b5132
RH
4895 return 1;
4896}
4897
f5842774
L
4898static const char *
4899get_group_flags (unsigned int flags)
4900{
4901 static char buff[32];
4902 switch (flags)
4903 {
220453ec
AM
4904 case 0:
4905 return "";
4906
f5842774 4907 case GRP_COMDAT:
220453ec 4908 return "COMDAT ";
f5842774
L
4909
4910 default:
220453ec 4911 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
4912 break;
4913 }
4914 return buff;
4915}
4916
4917static int
2cf0635d 4918process_section_groups (FILE * file)
f5842774 4919{
2cf0635d 4920 Elf_Internal_Shdr * section;
f5842774 4921 unsigned int i;
2cf0635d
NC
4922 struct group * group;
4923 Elf_Internal_Shdr * symtab_sec;
4924 Elf_Internal_Shdr * strtab_sec;
4925 Elf_Internal_Sym * symtab;
4926 char * strtab;
c256ffe7 4927 size_t strtab_size;
d1f5c6e3
L
4928
4929 /* Don't process section groups unless needed. */
4930 if (!do_unwind && !do_section_groups)
4931 return 1;
f5842774
L
4932
4933 if (elf_header.e_shnum == 0)
4934 {
4935 if (do_section_groups)
d1f5c6e3 4936 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
4937
4938 return 1;
4939 }
4940
4941 if (section_headers == NULL)
4942 {
4943 error (_("Section headers are not available!\n"));
4944 abort ();
4945 }
4946
3f5e193b
NC
4947 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
4948 sizeof (struct group *));
e4b17d5c
L
4949
4950 if (section_headers_groups == NULL)
4951 {
4952 error (_("Out of memory\n"));
4953 return 0;
4954 }
4955
f5842774 4956 /* Scan the sections for the group section. */
d1f5c6e3 4957 group_count = 0;
f5842774
L
4958 for (i = 0, section = section_headers;
4959 i < elf_header.e_shnum;
4960 i++, section++)
e4b17d5c
L
4961 if (section->sh_type == SHT_GROUP)
4962 group_count++;
4963
d1f5c6e3
L
4964 if (group_count == 0)
4965 {
4966 if (do_section_groups)
4967 printf (_("\nThere are no section groups in this file.\n"));
4968
4969 return 1;
4970 }
4971
3f5e193b 4972 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
4973
4974 if (section_groups == NULL)
4975 {
4976 error (_("Out of memory\n"));
4977 return 0;
4978 }
4979
d1f5c6e3
L
4980 symtab_sec = NULL;
4981 strtab_sec = NULL;
4982 symtab = NULL;
4983 strtab = NULL;
c256ffe7 4984 strtab_size = 0;
e4b17d5c
L
4985 for (i = 0, section = section_headers, group = section_groups;
4986 i < elf_header.e_shnum;
4987 i++, section++)
f5842774
L
4988 {
4989 if (section->sh_type == SHT_GROUP)
4990 {
2cf0635d
NC
4991 char * name = SECTION_NAME (section);
4992 char * group_name;
4993 unsigned char * start;
4994 unsigned char * indices;
f5842774 4995 unsigned int entry, j, size;
2cf0635d
NC
4996 Elf_Internal_Shdr * sec;
4997 Elf_Internal_Sym * sym;
f5842774
L
4998
4999 /* Get the symbol table. */
4fbb74a6
AM
5000 if (section->sh_link >= elf_header.e_shnum
5001 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5002 != SHT_SYMTAB))
f5842774
L
5003 {
5004 error (_("Bad sh_link in group section `%s'\n"), name);
5005 continue;
5006 }
d1f5c6e3
L
5007
5008 if (symtab_sec != sec)
5009 {
5010 symtab_sec = sec;
5011 if (symtab)
5012 free (symtab);
5013 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
5014 }
f5842774 5015
dd24e3da
NC
5016 if (symtab == NULL)
5017 {
5018 error (_("Corrupt header in group section `%s'\n"), name);
5019 continue;
5020 }
5021
f5842774
L
5022 sym = symtab + section->sh_info;
5023
5024 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5025 {
4fbb74a6
AM
5026 if (sym->st_shndx == 0
5027 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5028 {
5029 error (_("Bad sh_info in group section `%s'\n"), name);
5030 continue;
5031 }
ba2685cc 5032
4fbb74a6 5033 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5034 strtab_sec = NULL;
5035 if (strtab)
5036 free (strtab);
f5842774 5037 strtab = NULL;
c256ffe7 5038 strtab_size = 0;
f5842774
L
5039 }
5040 else
5041 {
5042 /* Get the string table. */
4fbb74a6 5043 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5044 {
5045 strtab_sec = NULL;
5046 if (strtab)
5047 free (strtab);
5048 strtab = NULL;
5049 strtab_size = 0;
5050 }
5051 else if (strtab_sec
4fbb74a6 5052 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5053 {
5054 strtab_sec = sec;
5055 if (strtab)
5056 free (strtab);
3f5e193b
NC
5057 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5058 1, strtab_sec->sh_size,
5059 _("string table"));
c256ffe7 5060 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5061 }
c256ffe7 5062 group_name = sym->st_name < strtab_size
2b692964 5063 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5064 }
5065
3f5e193b
NC
5066 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5067 1, section->sh_size,
5068 _("section data"));
f5842774
L
5069
5070 indices = start;
5071 size = (section->sh_size / section->sh_entsize) - 1;
5072 entry = byte_get (indices, 4);
5073 indices += 4;
e4b17d5c
L
5074
5075 if (do_section_groups)
5076 {
2b692964 5077 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5078 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5079
e4b17d5c
L
5080 printf (_(" [Index] Name\n"));
5081 }
5082
5083 group->group_index = i;
5084
f5842774
L
5085 for (j = 0; j < size; j++)
5086 {
2cf0635d 5087 struct group_list * g;
e4b17d5c 5088
f5842774
L
5089 entry = byte_get (indices, 4);
5090 indices += 4;
5091
4fbb74a6 5092 if (entry >= elf_header.e_shnum)
391cb864
L
5093 {
5094 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5095 entry, i, elf_header.e_shnum - 1);
5096 continue;
5097 }
391cb864 5098
4fbb74a6 5099 if (section_headers_groups [entry] != NULL)
e4b17d5c 5100 {
d1f5c6e3
L
5101 if (entry)
5102 {
391cb864
L
5103 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5104 entry, i,
4fbb74a6 5105 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5106 continue;
5107 }
5108 else
5109 {
5110 /* Intel C/C++ compiler may put section 0 in a
5111 section group. We just warn it the first time
5112 and ignore it afterwards. */
5113 static int warned = 0;
5114 if (!warned)
5115 {
5116 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5117 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5118 warned++;
5119 }
5120 }
e4b17d5c
L
5121 }
5122
4fbb74a6 5123 section_headers_groups [entry] = group;
e4b17d5c
L
5124
5125 if (do_section_groups)
5126 {
4fbb74a6 5127 sec = section_headers + entry;
c256ffe7 5128 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5129 }
5130
3f5e193b 5131 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5132 g->section_index = entry;
5133 g->next = group->root;
5134 group->root = g;
f5842774
L
5135 }
5136
f5842774
L
5137 if (start)
5138 free (start);
e4b17d5c
L
5139
5140 group++;
f5842774
L
5141 }
5142 }
5143
d1f5c6e3
L
5144 if (symtab)
5145 free (symtab);
5146 if (strtab)
5147 free (strtab);
f5842774
L
5148 return 1;
5149}
5150
28f997cf
TG
5151/* Data used to display dynamic fixups. */
5152
5153struct ia64_vms_dynfixup
5154{
5155 bfd_vma needed_ident; /* Library ident number. */
5156 bfd_vma needed; /* Index in the dstrtab of the library name. */
5157 bfd_vma fixup_needed; /* Index of the library. */
5158 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5159 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5160};
5161
5162/* Data used to display dynamic relocations. */
5163
5164struct ia64_vms_dynimgrela
5165{
5166 bfd_vma img_rela_cnt; /* Number of relocations. */
5167 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5168};
5169
5170/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5171 library). */
5172
5173static void
5174dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5175 const char *strtab, unsigned int strtab_sz)
5176{
5177 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5178 long i;
5179 const char *lib_name;
5180
5181 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5182 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5183 _("dynamic section image fixups"));
5184 if (!imfs)
5185 return;
5186
5187 if (fixup->needed < strtab_sz)
5188 lib_name = strtab + fixup->needed;
5189 else
5190 {
5191 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5192 (unsigned long) fixup->needed);
28f997cf
TG
5193 lib_name = "???";
5194 }
5195 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5196 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5197 printf
5198 (_("Seg Offset Type SymVec DataType\n"));
5199
5200 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5201 {
5202 unsigned int type;
5203 const char *rtype;
5204
5205 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5206 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5207 type = BYTE_GET (imfs [i].type);
5208 rtype = elf_ia64_reloc_type (type);
5209 if (rtype == NULL)
5210 printf (" 0x%08x ", type);
5211 else
5212 printf (" %-32s ", rtype);
5213 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5214 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5215 }
5216
5217 free (imfs);
5218}
5219
5220/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5221
5222static void
5223dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5224{
5225 Elf64_External_VMS_IMAGE_RELA *imrs;
5226 long i;
5227
5228 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5229 1, imgrela->img_rela_cnt * sizeof (*imrs),
5230 _("dynamic section image relas"));
5231 if (!imrs)
5232 return;
5233
5234 printf (_("\nImage relocs\n"));
5235 printf
5236 (_("Seg Offset Type Addend Seg Sym Off\n"));
5237
5238 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5239 {
5240 unsigned int type;
5241 const char *rtype;
5242
5243 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5244 printf ("%08" BFD_VMA_FMT "x ",
5245 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5246 type = BYTE_GET (imrs [i].type);
5247 rtype = elf_ia64_reloc_type (type);
5248 if (rtype == NULL)
5249 printf ("0x%08x ", type);
5250 else
5251 printf ("%-31s ", rtype);
5252 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5253 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5254 printf ("%08" BFD_VMA_FMT "x\n",
5255 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5256 }
5257
5258 free (imrs);
5259}
5260
5261/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5262
5263static int
5264process_ia64_vms_dynamic_relocs (FILE *file)
5265{
5266 struct ia64_vms_dynfixup fixup;
5267 struct ia64_vms_dynimgrela imgrela;
5268 Elf_Internal_Dyn *entry;
5269 int res = 0;
5270 bfd_vma strtab_off = 0;
5271 bfd_vma strtab_sz = 0;
5272 char *strtab = NULL;
5273
5274 memset (&fixup, 0, sizeof (fixup));
5275 memset (&imgrela, 0, sizeof (imgrela));
5276
5277 /* Note: the order of the entries is specified by the OpenVMS specs. */
5278 for (entry = dynamic_section;
5279 entry < dynamic_section + dynamic_nent;
5280 entry++)
5281 {
5282 switch (entry->d_tag)
5283 {
5284 case DT_IA_64_VMS_STRTAB_OFFSET:
5285 strtab_off = entry->d_un.d_val;
5286 break;
5287 case DT_STRSZ:
5288 strtab_sz = entry->d_un.d_val;
5289 if (strtab == NULL)
5290 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5291 1, strtab_sz, _("dynamic string section"));
5292 break;
5293
5294 case DT_IA_64_VMS_NEEDED_IDENT:
5295 fixup.needed_ident = entry->d_un.d_val;
5296 break;
5297 case DT_NEEDED:
5298 fixup.needed = entry->d_un.d_val;
5299 break;
5300 case DT_IA_64_VMS_FIXUP_NEEDED:
5301 fixup.fixup_needed = entry->d_un.d_val;
5302 break;
5303 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5304 fixup.fixup_rela_cnt = entry->d_un.d_val;
5305 break;
5306 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5307 fixup.fixup_rela_off = entry->d_un.d_val;
5308 res++;
5309 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5310 break;
5311
5312 case DT_IA_64_VMS_IMG_RELA_CNT:
5313 imgrela.img_rela_cnt = entry->d_un.d_val;
5314 break;
5315 case DT_IA_64_VMS_IMG_RELA_OFF:
5316 imgrela.img_rela_off = entry->d_un.d_val;
5317 res++;
5318 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5319 break;
5320
5321 default:
5322 break;
5323 }
5324 }
5325
5326 if (strtab != NULL)
5327 free (strtab);
5328
5329 return res;
5330}
5331
85b1c36d 5332static struct
566b0d53 5333{
2cf0635d 5334 const char * name;
566b0d53
L
5335 int reloc;
5336 int size;
5337 int rela;
5338} dynamic_relocations [] =
5339{
5340 { "REL", DT_REL, DT_RELSZ, FALSE },
5341 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5342 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5343};
5344
252b5132 5345/* Process the reloc section. */
18bd398b 5346
252b5132 5347static int
2cf0635d 5348process_relocs (FILE * file)
252b5132 5349{
b34976b6
AM
5350 unsigned long rel_size;
5351 unsigned long rel_offset;
252b5132
RH
5352
5353
5354 if (!do_reloc)
5355 return 1;
5356
5357 if (do_using_dynamic)
5358 {
566b0d53 5359 int is_rela;
2cf0635d 5360 const char * name;
566b0d53
L
5361 int has_dynamic_reloc;
5362 unsigned int i;
0de14b54 5363
566b0d53 5364 has_dynamic_reloc = 0;
252b5132 5365
566b0d53 5366 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5367 {
566b0d53
L
5368 is_rela = dynamic_relocations [i].rela;
5369 name = dynamic_relocations [i].name;
5370 rel_size = dynamic_info [dynamic_relocations [i].size];
5371 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5372
566b0d53
L
5373 has_dynamic_reloc |= rel_size;
5374
5375 if (is_rela == UNKNOWN)
aa903cfb 5376 {
566b0d53
L
5377 if (dynamic_relocations [i].reloc == DT_JMPREL)
5378 switch (dynamic_info[DT_PLTREL])
5379 {
5380 case DT_REL:
5381 is_rela = FALSE;
5382 break;
5383 case DT_RELA:
5384 is_rela = TRUE;
5385 break;
5386 }
aa903cfb 5387 }
252b5132 5388
566b0d53
L
5389 if (rel_size)
5390 {
5391 printf
5392 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5393 name, rel_offset, rel_size);
252b5132 5394
d93f0186
NC
5395 dump_relocations (file,
5396 offset_from_vma (file, rel_offset, rel_size),
5397 rel_size,
566b0d53 5398 dynamic_symbols, num_dynamic_syms,
d79b3d50 5399 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5400 }
252b5132 5401 }
566b0d53 5402
28f997cf
TG
5403 if (is_ia64_vms ())
5404 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5405
566b0d53 5406 if (! has_dynamic_reloc)
252b5132
RH
5407 printf (_("\nThere are no dynamic relocations in this file.\n"));
5408 }
5409 else
5410 {
2cf0635d 5411 Elf_Internal_Shdr * section;
b34976b6
AM
5412 unsigned long i;
5413 int found = 0;
252b5132
RH
5414
5415 for (i = 0, section = section_headers;
5416 i < elf_header.e_shnum;
b34976b6 5417 i++, section++)
252b5132
RH
5418 {
5419 if ( section->sh_type != SHT_RELA
5420 && section->sh_type != SHT_REL)
5421 continue;
5422
5423 rel_offset = section->sh_offset;
5424 rel_size = section->sh_size;
5425
5426 if (rel_size)
5427 {
2cf0635d 5428 Elf_Internal_Shdr * strsec;
b34976b6 5429 int is_rela;
103f02d3 5430
252b5132
RH
5431 printf (_("\nRelocation section "));
5432
5433 if (string_table == NULL)
19936277 5434 printf ("%d", section->sh_name);
252b5132 5435 else
3a1a2036 5436 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
5437
5438 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5439 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5440
d79b3d50
NC
5441 is_rela = section->sh_type == SHT_RELA;
5442
4fbb74a6
AM
5443 if (section->sh_link != 0
5444 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5445 {
2cf0635d
NC
5446 Elf_Internal_Shdr * symsec;
5447 Elf_Internal_Sym * symtab;
d79b3d50 5448 unsigned long nsyms;
c256ffe7 5449 unsigned long strtablen = 0;
2cf0635d 5450 char * strtab = NULL;
57346661 5451
4fbb74a6 5452 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5453 if (symsec->sh_type != SHT_SYMTAB
5454 && symsec->sh_type != SHT_DYNSYM)
5455 continue;
5456
af3fc3bc 5457 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 5458 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 5459
af3fc3bc
AM
5460 if (symtab == NULL)
5461 continue;
252b5132 5462
4fbb74a6
AM
5463 if (symsec->sh_link != 0
5464 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5465 {
4fbb74a6 5466 strsec = section_headers + symsec->sh_link;
103f02d3 5467
3f5e193b
NC
5468 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5469 1, strsec->sh_size,
5470 _("string table"));
c256ffe7
JJ
5471 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5472 }
252b5132 5473
d79b3d50
NC
5474 dump_relocations (file, rel_offset, rel_size,
5475 symtab, nsyms, strtab, strtablen, is_rela);
5476 if (strtab)
5477 free (strtab);
5478 free (symtab);
5479 }
5480 else
5481 dump_relocations (file, rel_offset, rel_size,
5482 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5483
5484 found = 1;
5485 }
5486 }
5487
5488 if (! found)
5489 printf (_("\nThere are no relocations in this file.\n"));
5490 }
5491
5492 return 1;
5493}
5494
57346661
AM
5495/* Process the unwind section. */
5496
4d6ed7c8
NC
5497#include "unwind-ia64.h"
5498
5499/* An absolute address consists of a section and an offset. If the
5500 section is NULL, the offset itself is the address, otherwise, the
5501 address equals to LOAD_ADDRESS(section) + offset. */
5502
5503struct absaddr
5504 {
5505 unsigned short section;
5506 bfd_vma offset;
5507 };
5508
1949de15
L
5509#define ABSADDR(a) \
5510 ((a).section \
5511 ? section_headers [(a).section].sh_addr + (a).offset \
5512 : (a).offset)
5513
3f5e193b
NC
5514struct ia64_unw_table_entry
5515 {
5516 struct absaddr start;
5517 struct absaddr end;
5518 struct absaddr info;
5519 };
5520
57346661 5521struct ia64_unw_aux_info
4d6ed7c8 5522 {
3f5e193b
NC
5523
5524 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5525 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5526 unsigned char * info; /* Unwind info. */
b34976b6
AM
5527 unsigned long info_size; /* Size of unwind info. */
5528 bfd_vma info_addr; /* starting address of unwind info. */
5529 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5530 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5531 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5532 char * strtab; /* The string table. */
b34976b6 5533 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5534 };
5535
4d6ed7c8 5536static void
2cf0635d 5537find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5538 unsigned long nsyms,
2cf0635d 5539 const char * strtab,
57346661 5540 unsigned long strtab_size,
d3ba0551 5541 struct absaddr addr,
2cf0635d
NC
5542 const char ** symname,
5543 bfd_vma * offset)
4d6ed7c8 5544{
d3ba0551 5545 bfd_vma dist = 0x100000;
2cf0635d
NC
5546 Elf_Internal_Sym * sym;
5547 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5548 unsigned long i;
5549
0b6ae522
DJ
5550 REMOVE_ARCH_BITS (addr.offset);
5551
57346661 5552 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5553 {
0b6ae522
DJ
5554 bfd_vma value = sym->st_value;
5555
5556 REMOVE_ARCH_BITS (value);
5557
4d6ed7c8
NC
5558 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5559 && sym->st_name != 0
5560 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5561 && addr.offset >= value
5562 && addr.offset - value < dist)
4d6ed7c8
NC
5563 {
5564 best = sym;
0b6ae522 5565 dist = addr.offset - value;
4d6ed7c8
NC
5566 if (!dist)
5567 break;
5568 }
5569 }
5570 if (best)
5571 {
57346661 5572 *symname = (best->st_name >= strtab_size
2b692964 5573 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5574 *offset = dist;
5575 return;
5576 }
5577 *symname = NULL;
5578 *offset = addr.offset;
5579}
5580
5581static void
2cf0635d 5582dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5583{
2cf0635d 5584 struct ia64_unw_table_entry * tp;
4d6ed7c8 5585 int in_body;
7036c0e1 5586
4d6ed7c8
NC
5587 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5588 {
5589 bfd_vma stamp;
5590 bfd_vma offset;
2cf0635d
NC
5591 const unsigned char * dp;
5592 const unsigned char * head;
5593 const char * procname;
4d6ed7c8 5594
57346661
AM
5595 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5596 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5597
5598 fputs ("\n<", stdout);
5599
5600 if (procname)
5601 {
5602 fputs (procname, stdout);
5603
5604 if (offset)
5605 printf ("+%lx", (unsigned long) offset);
5606 }
5607
5608 fputs (">: [", stdout);
5609 print_vma (tp->start.offset, PREFIX_HEX);
5610 fputc ('-', stdout);
5611 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5612 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5613 (unsigned long) (tp->info.offset - aux->seg_base));
5614
1949de15 5615 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5616 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5617
86f55779 5618 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5619 (unsigned) UNW_VER (stamp),
5620 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5621 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5622 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5623 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5624
5625 if (UNW_VER (stamp) != 1)
5626 {
2b692964 5627 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5628 continue;
5629 }
5630
5631 in_body = 0;
89fac5e3 5632 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5633 dp = unw_decode (dp, in_body, & in_body);
5634 }
5635}
5636
5637static int
2cf0635d
NC
5638slurp_ia64_unwind_table (FILE * file,
5639 struct ia64_unw_aux_info * aux,
5640 Elf_Internal_Shdr * sec)
4d6ed7c8 5641{
89fac5e3 5642 unsigned long size, nrelas, i;
2cf0635d
NC
5643 Elf_Internal_Phdr * seg;
5644 struct ia64_unw_table_entry * tep;
5645 Elf_Internal_Shdr * relsec;
5646 Elf_Internal_Rela * rela;
5647 Elf_Internal_Rela * rp;
5648 unsigned char * table;
5649 unsigned char * tp;
5650 Elf_Internal_Sym * sym;
5651 const char * relname;
4d6ed7c8 5652
4d6ed7c8
NC
5653 /* First, find the starting address of the segment that includes
5654 this section: */
5655
5656 if (elf_header.e_phnum)
5657 {
d93f0186 5658 if (! get_program_headers (file))
4d6ed7c8 5659 return 0;
4d6ed7c8 5660
d93f0186
NC
5661 for (seg = program_headers;
5662 seg < program_headers + elf_header.e_phnum;
5663 ++seg)
4d6ed7c8
NC
5664 {
5665 if (seg->p_type != PT_LOAD)
5666 continue;
5667
5668 if (sec->sh_addr >= seg->p_vaddr
5669 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5670 {
5671 aux->seg_base = seg->p_vaddr;
5672 break;
5673 }
5674 }
4d6ed7c8
NC
5675 }
5676
5677 /* Second, build the unwind table from the contents of the unwind section: */
5678 size = sec->sh_size;
3f5e193b
NC
5679 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5680 _("unwind table"));
a6e9f9df
AM
5681 if (!table)
5682 return 0;
4d6ed7c8 5683
3f5e193b
NC
5684 aux->table = (struct ia64_unw_table_entry *)
5685 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5686 tep = aux->table;
c6a0c689 5687 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5688 {
5689 tep->start.section = SHN_UNDEF;
5690 tep->end.section = SHN_UNDEF;
5691 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5692 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5693 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5694 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5695 tep->start.offset += aux->seg_base;
5696 tep->end.offset += aux->seg_base;
5697 tep->info.offset += aux->seg_base;
5698 }
5699 free (table);
5700
41e92641 5701 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5702 for (relsec = section_headers;
5703 relsec < section_headers + elf_header.e_shnum;
5704 ++relsec)
5705 {
5706 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5707 || relsec->sh_info >= elf_header.e_shnum
5708 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5709 continue;
5710
5711 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5712 & rela, & nrelas))
5713 return 0;
5714
5715 for (rp = rela; rp < rela + nrelas; ++rp)
5716 {
aca88567
NC
5717 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5718 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5719
0112cd26 5720 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5721 {
e5fb9629 5722 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5723 continue;
5724 }
5725
89fac5e3 5726 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5727
89fac5e3 5728 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5729 {
5730 case 0:
5731 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5732 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5733 break;
5734 case 1:
5735 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5736 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5737 break;
5738 case 2:
5739 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5740 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5741 break;
5742 default:
5743 break;
5744 }
5745 }
5746
5747 free (rela);
5748 }
5749
89fac5e3 5750 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5751 return 1;
5752}
5753
5754static int
2cf0635d 5755ia64_process_unwind (FILE * file)
4d6ed7c8 5756{
2cf0635d
NC
5757 Elf_Internal_Shdr * sec;
5758 Elf_Internal_Shdr * unwsec = NULL;
5759 Elf_Internal_Shdr * strsec;
89fac5e3 5760 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5761 struct ia64_unw_aux_info aux;
f1467e33 5762
4d6ed7c8
NC
5763 memset (& aux, 0, sizeof (aux));
5764
4d6ed7c8
NC
5765 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5766 {
c256ffe7 5767 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5768 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5769 {
5770 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5771 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5772
4fbb74a6 5773 strsec = section_headers + sec->sh_link;
3f5e193b
NC
5774 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5775 1, strsec->sh_size,
5776 _("string table"));
c256ffe7 5777 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5778 }
5779 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5780 unwcount++;
5781 }
5782
5783 if (!unwcount)
5784 printf (_("\nThere are no unwind sections in this file.\n"));
5785
5786 while (unwcount-- > 0)
5787 {
2cf0635d 5788 char * suffix;
579f31ac
JJ
5789 size_t len, len2;
5790
5791 for (i = unwstart, sec = section_headers + unwstart;
5792 i < elf_header.e_shnum; ++i, ++sec)
5793 if (sec->sh_type == SHT_IA_64_UNWIND)
5794 {
5795 unwsec = sec;
5796 break;
5797 }
5798
5799 unwstart = i + 1;
5800 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5801
e4b17d5c
L
5802 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5803 {
5804 /* We need to find which section group it is in. */
2cf0635d 5805 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5806
5807 for (; g != NULL; g = g->next)
5808 {
4fbb74a6 5809 sec = section_headers + g->section_index;
18bd398b
NC
5810
5811 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5812 break;
e4b17d5c
L
5813 }
5814
5815 if (g == NULL)
5816 i = elf_header.e_shnum;
5817 }
18bd398b 5818 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5819 {
18bd398b 5820 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5821 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5822 suffix = SECTION_NAME (unwsec) + len;
5823 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5824 ++i, ++sec)
18bd398b
NC
5825 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5826 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5827 break;
5828 }
5829 else
5830 {
5831 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5832 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5833 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5834 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5835 suffix = "";
18bd398b 5836 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5837 suffix = SECTION_NAME (unwsec) + len;
5838 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5839 ++i, ++sec)
18bd398b
NC
5840 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5841 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5842 break;
5843 }
5844
5845 if (i == elf_header.e_shnum)
5846 {
5847 printf (_("\nCould not find unwind info section for "));
5848
5849 if (string_table == NULL)
5850 printf ("%d", unwsec->sh_name);
5851 else
3a1a2036 5852 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5853 }
5854 else
4d6ed7c8
NC
5855 {
5856 aux.info_size = sec->sh_size;
5857 aux.info_addr = sec->sh_addr;
3f5e193b
NC
5858 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
5859 aux.info_size,
5860 _("unwind info"));
4d6ed7c8 5861
579f31ac 5862 printf (_("\nUnwind section "));
4d6ed7c8 5863
579f31ac
JJ
5864 if (string_table == NULL)
5865 printf ("%d", unwsec->sh_name);
5866 else
3a1a2036 5867 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5868
579f31ac 5869 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5870 (unsigned long) unwsec->sh_offset,
89fac5e3 5871 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5872
579f31ac 5873 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5874
579f31ac
JJ
5875 if (aux.table_len > 0)
5876 dump_ia64_unwind (& aux);
5877
5878 if (aux.table)
5879 free ((char *) aux.table);
5880 if (aux.info)
5881 free ((char *) aux.info);
5882 aux.table = NULL;
5883 aux.info = NULL;
5884 }
4d6ed7c8 5885 }
4d6ed7c8 5886
4d6ed7c8
NC
5887 if (aux.symtab)
5888 free (aux.symtab);
5889 if (aux.strtab)
5890 free ((char *) aux.strtab);
5891
5892 return 1;
5893}
5894
3f5e193b
NC
5895struct hppa_unw_table_entry
5896 {
5897 struct absaddr start;
5898 struct absaddr end;
5899 unsigned int Cannot_unwind:1; /* 0 */
5900 unsigned int Millicode:1; /* 1 */
5901 unsigned int Millicode_save_sr0:1; /* 2 */
5902 unsigned int Region_description:2; /* 3..4 */
5903 unsigned int reserved1:1; /* 5 */
5904 unsigned int Entry_SR:1; /* 6 */
5905 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5906 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5907 unsigned int Args_stored:1; /* 16 */
5908 unsigned int Variable_Frame:1; /* 17 */
5909 unsigned int Separate_Package_Body:1; /* 18 */
5910 unsigned int Frame_Extension_Millicode:1; /* 19 */
5911 unsigned int Stack_Overflow_Check:1; /* 20 */
5912 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5913 unsigned int Ada_Region:1; /* 22 */
5914 unsigned int cxx_info:1; /* 23 */
5915 unsigned int cxx_try_catch:1; /* 24 */
5916 unsigned int sched_entry_seq:1; /* 25 */
5917 unsigned int reserved2:1; /* 26 */
5918 unsigned int Save_SP:1; /* 27 */
5919 unsigned int Save_RP:1; /* 28 */
5920 unsigned int Save_MRP_in_frame:1; /* 29 */
5921 unsigned int extn_ptr_defined:1; /* 30 */
5922 unsigned int Cleanup_defined:1; /* 31 */
5923
5924 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5925 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5926 unsigned int Large_frame:1; /* 2 */
5927 unsigned int Pseudo_SP_Set:1; /* 3 */
5928 unsigned int reserved4:1; /* 4 */
5929 unsigned int Total_frame_size:27; /* 5..31 */
5930 };
5931
57346661
AM
5932struct hppa_unw_aux_info
5933 {
3f5e193b 5934 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
5935 unsigned long table_len; /* Length of unwind table. */
5936 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5937 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5938 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5939 char * strtab; /* The string table. */
57346661
AM
5940 unsigned long strtab_size; /* Size of string table. */
5941 };
5942
5943static void
2cf0635d 5944dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5945{
2cf0635d 5946 struct hppa_unw_table_entry * tp;
57346661 5947
57346661
AM
5948 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5949 {
5950 bfd_vma offset;
2cf0635d 5951 const char * procname;
57346661
AM
5952
5953 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5954 aux->strtab_size, tp->start, &procname,
5955 &offset);
5956
5957 fputs ("\n<", stdout);
5958
5959 if (procname)
5960 {
5961 fputs (procname, stdout);
5962
5963 if (offset)
5964 printf ("+%lx", (unsigned long) offset);
5965 }
5966
5967 fputs (">: [", stdout);
5968 print_vma (tp->start.offset, PREFIX_HEX);
5969 fputc ('-', stdout);
5970 print_vma (tp->end.offset, PREFIX_HEX);
5971 printf ("]\n\t");
5972
18bd398b
NC
5973#define PF(_m) if (tp->_m) printf (#_m " ");
5974#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5975 PF(Cannot_unwind);
5976 PF(Millicode);
5977 PF(Millicode_save_sr0);
18bd398b 5978 /* PV(Region_description); */
57346661
AM
5979 PF(Entry_SR);
5980 PV(Entry_FR);
5981 PV(Entry_GR);
5982 PF(Args_stored);
5983 PF(Variable_Frame);
5984 PF(Separate_Package_Body);
5985 PF(Frame_Extension_Millicode);
5986 PF(Stack_Overflow_Check);
5987 PF(Two_Instruction_SP_Increment);
5988 PF(Ada_Region);
5989 PF(cxx_info);
5990 PF(cxx_try_catch);
5991 PF(sched_entry_seq);
5992 PF(Save_SP);
5993 PF(Save_RP);
5994 PF(Save_MRP_in_frame);
5995 PF(extn_ptr_defined);
5996 PF(Cleanup_defined);
5997 PF(MPE_XL_interrupt_marker);
5998 PF(HP_UX_interrupt_marker);
5999 PF(Large_frame);
6000 PF(Pseudo_SP_Set);
6001 PV(Total_frame_size);
6002#undef PF
6003#undef PV
6004 }
6005
18bd398b 6006 printf ("\n");
57346661
AM
6007}
6008
6009static int
2cf0635d
NC
6010slurp_hppa_unwind_table (FILE * file,
6011 struct hppa_unw_aux_info * aux,
6012 Elf_Internal_Shdr * sec)
57346661 6013{
1c0751b2 6014 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6015 Elf_Internal_Phdr * seg;
6016 struct hppa_unw_table_entry * tep;
6017 Elf_Internal_Shdr * relsec;
6018 Elf_Internal_Rela * rela;
6019 Elf_Internal_Rela * rp;
6020 unsigned char * table;
6021 unsigned char * tp;
6022 Elf_Internal_Sym * sym;
6023 const char * relname;
57346661 6024
57346661
AM
6025 /* First, find the starting address of the segment that includes
6026 this section. */
6027
6028 if (elf_header.e_phnum)
6029 {
6030 if (! get_program_headers (file))
6031 return 0;
6032
6033 for (seg = program_headers;
6034 seg < program_headers + elf_header.e_phnum;
6035 ++seg)
6036 {
6037 if (seg->p_type != PT_LOAD)
6038 continue;
6039
6040 if (sec->sh_addr >= seg->p_vaddr
6041 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6042 {
6043 aux->seg_base = seg->p_vaddr;
6044 break;
6045 }
6046 }
6047 }
6048
6049 /* Second, build the unwind table from the contents of the unwind
6050 section. */
6051 size = sec->sh_size;
3f5e193b
NC
6052 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6053 _("unwind table"));
57346661
AM
6054 if (!table)
6055 return 0;
6056
1c0751b2
DA
6057 unw_ent_size = 16;
6058 nentries = size / unw_ent_size;
6059 size = unw_ent_size * nentries;
57346661 6060
3f5e193b
NC
6061 tep = aux->table = (struct hppa_unw_table_entry *)
6062 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6063
1c0751b2 6064 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6065 {
6066 unsigned int tmp1, tmp2;
6067
6068 tep->start.section = SHN_UNDEF;
6069 tep->end.section = SHN_UNDEF;
6070
1c0751b2
DA
6071 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6072 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6073 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6074 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6075
6076 tep->start.offset += aux->seg_base;
6077 tep->end.offset += aux->seg_base;
57346661
AM
6078
6079 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6080 tep->Millicode = (tmp1 >> 30) & 0x1;
6081 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6082 tep->Region_description = (tmp1 >> 27) & 0x3;
6083 tep->reserved1 = (tmp1 >> 26) & 0x1;
6084 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6085 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6086 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6087 tep->Args_stored = (tmp1 >> 15) & 0x1;
6088 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6089 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6090 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6091 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6092 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6093 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6094 tep->cxx_info = (tmp1 >> 8) & 0x1;
6095 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6096 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6097 tep->reserved2 = (tmp1 >> 5) & 0x1;
6098 tep->Save_SP = (tmp1 >> 4) & 0x1;
6099 tep->Save_RP = (tmp1 >> 3) & 0x1;
6100 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6101 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6102 tep->Cleanup_defined = tmp1 & 0x1;
6103
6104 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6105 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6106 tep->Large_frame = (tmp2 >> 29) & 0x1;
6107 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6108 tep->reserved4 = (tmp2 >> 27) & 0x1;
6109 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6110 }
6111 free (table);
6112
6113 /* Third, apply any relocations to the unwind table. */
57346661
AM
6114 for (relsec = section_headers;
6115 relsec < section_headers + elf_header.e_shnum;
6116 ++relsec)
6117 {
6118 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6119 || relsec->sh_info >= elf_header.e_shnum
6120 || section_headers + relsec->sh_info != sec)
57346661
AM
6121 continue;
6122
6123 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6124 & rela, & nrelas))
6125 return 0;
6126
6127 for (rp = rela; rp < rela + nrelas; ++rp)
6128 {
aca88567
NC
6129 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6130 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6131
6132 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6133 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6134 {
6135 warn (_("Skipping unexpected relocation type %s\n"), relname);
6136 continue;
6137 }
6138
6139 i = rp->r_offset / unw_ent_size;
6140
89fac5e3 6141 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6142 {
6143 case 0:
6144 aux->table[i].start.section = sym->st_shndx;
1e456d54 6145 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6146 break;
6147 case 1:
6148 aux->table[i].end.section = sym->st_shndx;
1e456d54 6149 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6150 break;
6151 default:
6152 break;
6153 }
6154 }
6155
6156 free (rela);
6157 }
6158
1c0751b2 6159 aux->table_len = nentries;
57346661
AM
6160
6161 return 1;
6162}
6163
6164static int
2cf0635d 6165hppa_process_unwind (FILE * file)
57346661 6166{
57346661 6167 struct hppa_unw_aux_info aux;
2cf0635d
NC
6168 Elf_Internal_Shdr * unwsec = NULL;
6169 Elf_Internal_Shdr * strsec;
6170 Elf_Internal_Shdr * sec;
18bd398b 6171 unsigned long i;
57346661
AM
6172
6173 memset (& aux, 0, sizeof (aux));
6174
c256ffe7
JJ
6175 if (string_table == NULL)
6176 return 1;
57346661
AM
6177
6178 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6179 {
c256ffe7 6180 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6181 && sec->sh_link < elf_header.e_shnum)
57346661
AM
6182 {
6183 aux.nsyms = sec->sh_size / sec->sh_entsize;
6184 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6185
4fbb74a6 6186 strsec = section_headers + sec->sh_link;
3f5e193b
NC
6187 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6188 1, strsec->sh_size,
6189 _("string table"));
c256ffe7 6190 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6191 }
18bd398b 6192 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6193 unwsec = sec;
6194 }
6195
6196 if (!unwsec)
6197 printf (_("\nThere are no unwind sections in this file.\n"));
6198
6199 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6200 {
18bd398b 6201 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6202 {
57346661
AM
6203 printf (_("\nUnwind section "));
6204 printf (_("'%s'"), SECTION_NAME (sec));
6205
6206 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6207 (unsigned long) sec->sh_offset,
89fac5e3 6208 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6209
6210 slurp_hppa_unwind_table (file, &aux, sec);
6211 if (aux.table_len > 0)
6212 dump_hppa_unwind (&aux);
6213
6214 if (aux.table)
6215 free ((char *) aux.table);
6216 aux.table = NULL;
6217 }
6218 }
6219
6220 if (aux.symtab)
6221 free (aux.symtab);
6222 if (aux.strtab)
6223 free ((char *) aux.strtab);
6224
6225 return 1;
6226}
6227
0b6ae522
DJ
6228struct arm_section
6229{
6230 unsigned char *data;
6231
6232 Elf_Internal_Shdr *sec;
6233 Elf_Internal_Rela *rela;
6234 unsigned long nrelas;
6235 unsigned int rel_type;
6236
6237 Elf_Internal_Rela *next_rela;
6238};
6239
6240struct arm_unw_aux_info
6241{
6242 FILE *file;
6243
6244 Elf_Internal_Sym *symtab; /* The symbol table. */
6245 unsigned long nsyms; /* Number of symbols. */
6246 char *strtab; /* The string table. */
6247 unsigned long strtab_size; /* Size of string table. */
6248};
6249
6250static const char *
6251arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6252 bfd_vma fn, struct absaddr addr)
6253{
6254 const char *procname;
6255 bfd_vma sym_offset;
6256
6257 if (addr.section == SHN_UNDEF)
6258 addr.offset = fn;
6259
6260 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6261 aux->strtab_size, addr, &procname,
6262 &sym_offset);
6263
6264 print_vma (fn, PREFIX_HEX);
6265
6266 if (procname)
6267 {
6268 fputs (" <", stdout);
6269 fputs (procname, stdout);
6270
6271 if (sym_offset)
6272 printf ("+0x%lx", (unsigned long) sym_offset);
6273 fputc ('>', stdout);
6274 }
6275
6276 return procname;
6277}
6278
6279static void
6280arm_free_section (struct arm_section *arm_sec)
6281{
6282 if (arm_sec->data != NULL)
6283 free (arm_sec->data);
6284
6285 if (arm_sec->rela != NULL)
6286 free (arm_sec->rela);
6287}
6288
6289static int
6290arm_section_get_word (struct arm_unw_aux_info *aux,
6291 struct arm_section *arm_sec,
6292 Elf_Internal_Shdr *sec, bfd_vma word_offset,
6293 unsigned int *wordp, struct absaddr *addr)
6294{
6295 Elf_Internal_Rela *rp;
6296 Elf_Internal_Sym *sym;
6297 const char * relname;
6298 unsigned int word;
6299 bfd_boolean wrapped;
6300
6301 addr->section = SHN_UNDEF;
6302 addr->offset = 0;
6303
6304 if (sec != arm_sec->sec)
6305 {
6306 Elf_Internal_Shdr *relsec;
6307
6308 arm_free_section (arm_sec);
6309
6310 arm_sec->sec = sec;
6311 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6312 sec->sh_size, _("unwind data"));
6313
6314 arm_sec->rela = NULL;
6315 arm_sec->nrelas = 0;
6316
6317 for (relsec = section_headers;
6318 relsec < section_headers + elf_header.e_shnum;
6319 ++relsec)
6320 {
6321 if (relsec->sh_info >= elf_header.e_shnum
6322 || section_headers + relsec->sh_info != sec)
6323 continue;
6324
6325 if (relsec->sh_type == SHT_REL)
6326 {
6327 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6328 relsec->sh_size,
6329 & arm_sec->rela, & arm_sec->nrelas))
6330 return 0;
6331 break;
6332 }
6333 else if (relsec->sh_type == SHT_RELA)
6334 {
6335 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6336 relsec->sh_size,
6337 & arm_sec->rela, & arm_sec->nrelas))
6338 return 0;
6339 break;
6340 }
6341 }
6342
6343 arm_sec->next_rela = arm_sec->rela;
6344 }
6345
6346 if (arm_sec->data == NULL)
6347 return 0;
6348
6349 word = byte_get (arm_sec->data + word_offset, 4);
6350
6351 wrapped = FALSE;
6352 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6353 {
6354 bfd_vma prelval, offset;
6355
6356 if (rp->r_offset > word_offset && !wrapped)
6357 {
6358 rp = arm_sec->rela;
6359 wrapped = TRUE;
6360 }
6361 if (rp->r_offset > word_offset)
6362 break;
6363
6364 if (rp->r_offset & 3)
6365 {
6366 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6367 (unsigned long) rp->r_offset);
6368 continue;
6369 }
6370
6371 if (rp->r_offset < word_offset)
6372 continue;
6373
6374 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6375
6376 if (streq (relname, "R_ARM_NONE"))
6377 continue;
6378
6379 if (! streq (relname, "R_ARM_PREL31"))
6380 {
6381 warn (_("Skipping unexpected relocation type %s\n"), relname);
6382 continue;
6383 }
6384
6385 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6386
6387 if (arm_sec->rel_type == SHT_REL)
6388 {
6389 offset = word & 0x7fffffff;
6390 if (offset & 0x40000000)
6391 offset |= ~ (bfd_vma) 0x7fffffff;
6392 }
6393 else
6394 offset = rp->r_addend;
6395
6396 offset += sym->st_value;
6397 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6398
6399 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6400 addr->section = sym->st_shndx;
6401 addr->offset = offset;
6402 break;
6403 }
6404
6405 *wordp = word;
6406 arm_sec->next_rela = rp;
6407
6408 return 1;
6409}
6410
6411static void
6412decode_arm_unwind (struct arm_unw_aux_info *aux,
6413 unsigned int word, unsigned int remaining,
6414 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6415 struct arm_section *data_arm_sec)
6416{
6417 int per_index;
6418 unsigned int more_words;
6419 struct absaddr addr;
6420
6421#define ADVANCE \
6422 if (remaining == 0 && more_words) \
6423 { \
6424 data_offset += 4; \
6425 if (!arm_section_get_word (aux, data_arm_sec, data_sec, \
6426 data_offset, &word, &addr)) \
6427 return; \
6428 remaining = 4; \
6429 more_words--; \
6430 } \
6431
6432#define GET_OP(OP) \
6433 ADVANCE; \
6434 if (remaining) \
6435 { \
6436 remaining--; \
6437 (OP) = word >> 24; \
6438 word <<= 8; \
6439 } \
6440 else \
6441 { \
2b692964 6442 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6443 return; \
6444 } \
cc5914eb 6445 printf ("0x%02x ", OP)
0b6ae522
DJ
6446
6447 if (remaining == 0)
6448 {
6449 /* Fetch the first word. */
6450 if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
6451 &word, &addr))
6452 return;
6453 remaining = 4;
6454 }
6455
6456 if ((word & 0x80000000) == 0)
6457 {
6458 /* Expand prel31 for personality routine. */
6459 bfd_vma fn;
6460 const char *procname;
6461
6462 fn = word;
6463 if (fn & 0x40000000)
6464 fn |= ~ (bfd_vma) 0x7fffffff;
6465 fn = fn + data_sec->sh_addr + data_offset;
6466
6467 printf (_(" Personality routine: "));
6468 procname = arm_print_vma_and_name (aux, fn, addr);
6469 fputc ('\n', stdout);
6470
6471 /* The GCC personality routines use the standard compact
6472 encoding, starting with one byte giving the number of
6473 words. */
6474 if (procname != NULL
6475 && (const_strneq (procname, "__gcc_personality_v0")
6476 || const_strneq (procname, "__gxx_personality_v0")
6477 || const_strneq (procname, "__gcj_personality_v0")
6478 || const_strneq (procname, "__gnu_objc_personality_v0")))
6479 {
6480 remaining = 0;
6481 more_words = 1;
6482 ADVANCE;
6483 if (!remaining)
6484 {
6485 printf (_(" [Truncated data]\n"));
6486 return;
6487 }
6488 more_words = word >> 24;
6489 word <<= 8;
6490 remaining--;
6491 }
6492 else
6493 return;
6494 }
6495 else
6496 {
0b6ae522
DJ
6497 per_index = (word >> 24) & 0x7f;
6498 if (per_index != 0 && per_index != 1 && per_index != 2)
6499 {
6500 printf (_(" [reserved compact index %d]\n"), per_index);
6501 return;
6502 }
6503
6504 printf (_(" Compact model %d\n"), per_index);
6505 if (per_index == 0)
6506 {
6507 more_words = 0;
6508 word <<= 8;
6509 remaining--;
6510 }
6511 else
6512 {
6513 more_words = (word >> 16) & 0xff;
6514 word <<= 16;
6515 remaining -= 2;
6516 }
6517 }
6518
6519 /* Decode the unwinding instructions. */
6520 while (1)
6521 {
6522 unsigned int op, op2;
6523
6524 ADVANCE;
6525 if (remaining == 0)
6526 break;
6527 remaining--;
6528 op = word >> 24;
6529 word <<= 8;
6530
cc5914eb 6531 printf (" 0x%02x ", op);
0b6ae522
DJ
6532
6533 if ((op & 0xc0) == 0x00)
6534 {
6535 int offset = ((op & 0x3f) << 2) + 4;
cc5914eb 6536 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6537 }
6538 else if ((op & 0xc0) == 0x40)
6539 {
6540 int offset = ((op & 0x3f) << 2) + 4;
cc5914eb 6541 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6542 }
6543 else if ((op & 0xf0) == 0x80)
6544 {
6545 GET_OP (op2);
6546 if (op == 0x80 && op2 == 0)
6547 printf (_("Refuse to unwind"));
6548 else
6549 {
6550 unsigned int mask = ((op & 0x0f) << 8) | op2;
6551 int first = 1;
6552 int i;
2b692964 6553
0b6ae522
DJ
6554 printf ("pop {");
6555 for (i = 0; i < 12; i++)
6556 if (mask & (1 << i))
6557 {
6558 if (first)
6559 first = 0;
6560 else
6561 printf (", ");
6562 printf ("r%d", 4 + i);
6563 }
6564 printf ("}");
6565 }
6566 }
6567 else if ((op & 0xf0) == 0x90)
6568 {
6569 if (op == 0x9d || op == 0x9f)
6570 printf (_(" [Reserved]"));
6571 else
cc5914eb 6572 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6573 }
6574 else if ((op & 0xf0) == 0xa0)
6575 {
6576 int end = 4 + (op & 0x07);
6577 int first = 1;
6578 int i;
6579 printf (" pop {");
6580 for (i = 4; i <= end; i++)
6581 {
6582 if (first)
6583 first = 0;
6584 else
6585 printf (", ");
6586 printf ("r%d", i);
6587 }
6588 if (op & 0x08)
6589 {
6590 if (first)
6591 printf (", ");
6592 printf ("r14");
6593 }
6594 printf ("}");
6595 }
6596 else if (op == 0xb0)
6597 printf (_(" finish"));
6598 else if (op == 0xb1)
6599 {
6600 GET_OP (op2);
6601 if (op2 == 0 || (op2 & 0xf0) != 0)
6602 printf (_("[Spare]"));
6603 else
6604 {
6605 unsigned int mask = op2 & 0x0f;
6606 int first = 1;
6607 int i;
6608 printf ("pop {");
6609 for (i = 0; i < 12; i++)
6610 if (mask & (1 << i))
6611 {
6612 if (first)
6613 first = 0;
6614 else
6615 printf (", ");
6616 printf ("r%d", i);
6617 }
6618 printf ("}");
6619 }
6620 }
6621 else if (op == 0xb2)
6622 {
b115cf96 6623 unsigned char buf[9];
0b6ae522
DJ
6624 unsigned int i, len;
6625 unsigned long offset;
b115cf96 6626 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6627 {
6628 GET_OP (buf[i]);
6629 if ((buf[i] & 0x80) == 0)
6630 break;
6631 }
6632 assert (i < sizeof (buf));
6633 offset = read_uleb128 (buf, &len);
6634 assert (len == i + 1);
6635 offset = offset * 4 + 0x204;
cc5914eb 6636 printf ("vsp = vsp + %ld", offset);
0b6ae522
DJ
6637 }
6638 else
6639 {
6640 if (op == 0xb3 || op == 0xc6 || op == 0xc7 || op == 0xc8 || op == 0xc9)
6641 {
6642 GET_OP (op2);
6643 printf (_("[unsupported two-byte opcode]"));
6644 }
6645 else
6646 {
6647 printf (_(" [unsupported opcode]"));
6648 }
6649 }
6650 printf ("\n");
6651 }
6652
6653 /* Decode the descriptors. Not implemented. */
6654}
6655
6656static void
6657dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
6658{
6659 struct arm_section exidx_arm_sec, extab_arm_sec;
6660 unsigned int i, exidx_len;
6661
6662 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
6663 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
6664 exidx_len = exidx_sec->sh_size / 8;
6665
6666 for (i = 0; i < exidx_len; i++)
6667 {
6668 unsigned int exidx_fn, exidx_entry;
6669 struct absaddr fn_addr, entry_addr;
6670 bfd_vma fn;
6671
6672 fputc ('\n', stdout);
6673
6674 if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6675 8 * i, &exidx_fn, &fn_addr)
6676 || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6677 8 * i + 4, &exidx_entry, &entry_addr))
6678 {
6679 arm_free_section (&exidx_arm_sec);
6680 arm_free_section (&extab_arm_sec);
6681 return;
6682 }
6683
6684 fn = exidx_fn & 0x7fffffff;
6685 if (fn & 0x40000000)
6686 fn |= ~ (bfd_vma) 0x7fffffff;
6687 fn = fn + exidx_sec->sh_addr + 8 * i;
6688
6689 arm_print_vma_and_name (aux, fn, entry_addr);
6690 fputs (": ", stdout);
6691
6692 if (exidx_entry == 1)
6693 {
6694 print_vma (exidx_entry, PREFIX_HEX);
6695 fputs (" [cantunwind]\n", stdout);
6696 }
6697 else if (exidx_entry & 0x80000000)
6698 {
6699 print_vma (exidx_entry, PREFIX_HEX);
6700 fputc ('\n', stdout);
6701 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
6702 }
6703 else
6704 {
8f73510c 6705 bfd_vma table, table_offset = 0;
0b6ae522
DJ
6706 Elf_Internal_Shdr *table_sec;
6707
6708 fputs ("@", stdout);
6709 table = exidx_entry;
6710 if (table & 0x40000000)
6711 table |= ~ (bfd_vma) 0x7fffffff;
6712 table = table + exidx_sec->sh_addr + 8 * i + 4;
6713 print_vma (table, PREFIX_HEX);
6714 printf ("\n");
6715
6716 /* Locate the matching .ARM.extab. */
6717 if (entry_addr.section != SHN_UNDEF
6718 && entry_addr.section < elf_header.e_shnum)
6719 {
6720 table_sec = section_headers + entry_addr.section;
6721 table_offset = entry_addr.offset;
6722 }
6723 else
6724 {
6725 table_sec = find_section_by_address (table);
6726 if (table_sec != NULL)
6727 table_offset = table - table_sec->sh_addr;
6728 }
6729 if (table_sec == NULL)
6730 {
6731 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
6732 (unsigned long) table);
6733 continue;
6734 }
6735 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
6736 &extab_arm_sec);
6737 }
6738 }
6739
6740 printf ("\n");
6741
6742 arm_free_section (&exidx_arm_sec);
6743 arm_free_section (&extab_arm_sec);
6744}
6745
6746static int
6747arm_process_unwind (FILE *file)
6748{
6749 struct arm_unw_aux_info aux;
6750 Elf_Internal_Shdr *unwsec = NULL;
6751 Elf_Internal_Shdr *strsec;
6752 Elf_Internal_Shdr *sec;
6753 unsigned long i;
6754
6755 memset (& aux, 0, sizeof (aux));
6756 aux.file = file;
6757
6758 if (string_table == NULL)
6759 return 1;
6760
6761 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6762 {
6763 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
6764 {
6765 aux.nsyms = sec->sh_size / sec->sh_entsize;
6766 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6767
6768 strsec = section_headers + sec->sh_link;
6769 aux.strtab = get_data (NULL, file, strsec->sh_offset,
6770 1, strsec->sh_size, _("string table"));
6771 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
6772 }
6773 else if (sec->sh_type == SHT_ARM_EXIDX)
6774 unwsec = sec;
6775 }
6776
6777 if (!unwsec)
6778 printf (_("\nThere are no unwind sections in this file.\n"));
6779
6780 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6781 {
6782 if (sec->sh_type == SHT_ARM_EXIDX)
6783 {
6784 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
6785 SECTION_NAME (sec),
6786 (unsigned long) sec->sh_offset,
6787 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
6788
6789 dump_arm_unwind (&aux, sec);
6790 }
6791 }
6792
6793 if (aux.symtab)
6794 free (aux.symtab);
6795 if (aux.strtab)
6796 free ((char *) aux.strtab);
6797
6798 return 1;
6799}
6800
57346661 6801static int
2cf0635d 6802process_unwind (FILE * file)
57346661 6803{
2cf0635d
NC
6804 struct unwind_handler
6805 {
57346661 6806 int machtype;
2cf0635d
NC
6807 int (* handler)(FILE *);
6808 } handlers[] =
6809 {
0b6ae522 6810 { EM_ARM, arm_process_unwind },
57346661
AM
6811 { EM_IA_64, ia64_process_unwind },
6812 { EM_PARISC, hppa_process_unwind },
6813 { 0, 0 }
6814 };
6815 int i;
6816
6817 if (!do_unwind)
6818 return 1;
6819
6820 for (i = 0; handlers[i].handler != NULL; i++)
6821 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 6822 return handlers[i].handler (file);
57346661
AM
6823
6824 printf (_("\nThere are no unwind sections in this file.\n"));
6825 return 1;
6826}
6827
252b5132 6828static void
2cf0635d 6829dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
6830{
6831 switch (entry->d_tag)
6832 {
6833 case DT_MIPS_FLAGS:
6834 if (entry->d_un.d_val == 0)
2b692964 6835 printf (_("NONE\n"));
252b5132
RH
6836 else
6837 {
6838 static const char * opts[] =
6839 {
6840 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
6841 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
6842 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
6843 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
6844 "RLD_ORDER_SAFE"
6845 };
6846 unsigned int cnt;
6847 int first = 1;
2b692964 6848
60bca95a 6849 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
6850 if (entry->d_un.d_val & (1 << cnt))
6851 {
6852 printf ("%s%s", first ? "" : " ", opts[cnt]);
6853 first = 0;
6854 }
6855 puts ("");
6856 }
6857 break;
103f02d3 6858
252b5132 6859 case DT_MIPS_IVERSION:
d79b3d50 6860 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
2b692964 6861 printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6862 else
2b692964 6863 printf (_("<corrupt: %ld>\n"), (long) entry->d_un.d_ptr);
252b5132 6864 break;
103f02d3 6865
252b5132
RH
6866 case DT_MIPS_TIME_STAMP:
6867 {
6868 char timebuf[20];
2cf0635d 6869 struct tm * tmp;
50da7a9c 6870
91d6fa6a
NC
6871 time_t atime = entry->d_un.d_val;
6872 tmp = gmtime (&atime);
e9e44622
JJ
6873 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
6874 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6875 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
2b692964 6876 printf (_("Time Stamp: %s\n"), timebuf);
252b5132
RH
6877 }
6878 break;
103f02d3 6879
252b5132
RH
6880 case DT_MIPS_RLD_VERSION:
6881 case DT_MIPS_LOCAL_GOTNO:
6882 case DT_MIPS_CONFLICTNO:
6883 case DT_MIPS_LIBLISTNO:
6884 case DT_MIPS_SYMTABNO:
6885 case DT_MIPS_UNREFEXTNO:
6886 case DT_MIPS_HIPAGENO:
6887 case DT_MIPS_DELTA_CLASS_NO:
6888 case DT_MIPS_DELTA_INSTANCE_NO:
6889 case DT_MIPS_DELTA_RELOC_NO:
6890 case DT_MIPS_DELTA_SYM_NO:
6891 case DT_MIPS_DELTA_CLASSSYM_NO:
6892 case DT_MIPS_COMPACT_SIZE:
6893 printf ("%ld\n", (long) entry->d_un.d_ptr);
6894 break;
103f02d3
UD
6895
6896 default:
0af1713e 6897 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
6898 }
6899}
6900
103f02d3 6901static void
2cf0635d 6902dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
6903{
6904 switch (entry->d_tag)
6905 {
6906 case DT_HP_DLD_FLAGS:
6907 {
6908 static struct
6909 {
6910 long int bit;
2cf0635d 6911 const char * str;
5e220199
NC
6912 }
6913 flags[] =
6914 {
6915 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
6916 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
6917 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
6918 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
6919 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
6920 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
6921 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
6922 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
6923 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
6924 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
6925 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
6926 { DT_HP_GST, "HP_GST" },
6927 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
6928 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
6929 { DT_HP_NODELETE, "HP_NODELETE" },
6930 { DT_HP_GROUP, "HP_GROUP" },
6931 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 6932 };
103f02d3 6933 int first = 1;
5e220199 6934 size_t cnt;
f7a99963 6935 bfd_vma val = entry->d_un.d_val;
103f02d3 6936
60bca95a 6937 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 6938 if (val & flags[cnt].bit)
30800947
NC
6939 {
6940 if (! first)
6941 putchar (' ');
6942 fputs (flags[cnt].str, stdout);
6943 first = 0;
6944 val ^= flags[cnt].bit;
6945 }
76da6bbe 6946
103f02d3 6947 if (val != 0 || first)
f7a99963
NC
6948 {
6949 if (! first)
6950 putchar (' ');
6951 print_vma (val, HEX);
6952 }
103f02d3
UD
6953 }
6954 break;
76da6bbe 6955
252b5132 6956 default:
f7a99963
NC
6957 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6958 break;
252b5132 6959 }
35b1837e 6960 putchar ('\n');
252b5132
RH
6961}
6962
28f997cf
TG
6963#ifdef BFD64
6964
6965/* VMS vs Unix time offset and factor. */
6966
6967#define VMS_EPOCH_OFFSET 35067168000000000LL
6968#define VMS_GRANULARITY_FACTOR 10000000
6969
6970/* Display a VMS time in a human readable format. */
6971
6972static void
6973print_vms_time (bfd_int64_t vmstime)
6974{
6975 struct tm *tm;
6976 time_t unxtime;
6977
6978 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
6979 tm = gmtime (&unxtime);
6980 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
6981 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
6982 tm->tm_hour, tm->tm_min, tm->tm_sec);
6983}
6984#endif /* BFD64 */
6985
ecc51f48 6986static void
2cf0635d 6987dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
6988{
6989 switch (entry->d_tag)
6990 {
0de14b54 6991 case DT_IA_64_PLT_RESERVE:
bdf4d63a 6992 /* First 3 slots reserved. */
ecc51f48
NC
6993 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
6994 printf (" -- ");
6995 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
6996 break;
6997
28f997cf
TG
6998 case DT_IA_64_VMS_LINKTIME:
6999#ifdef BFD64
7000 print_vms_time (entry->d_un.d_val);
7001#endif
7002 break;
7003
7004 case DT_IA_64_VMS_LNKFLAGS:
7005 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7006 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7007 printf (" CALL_DEBUG");
7008 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7009 printf (" NOP0BUFS");
7010 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7011 printf (" P0IMAGE");
7012 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7013 printf (" MKTHREADS");
7014 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7015 printf (" UPCALLS");
7016 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7017 printf (" IMGSTA");
7018 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7019 printf (" INITIALIZE");
7020 if (entry->d_un.d_val & VMS_LF_MAIN)
7021 printf (" MAIN");
7022 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7023 printf (" EXE_INIT");
7024 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7025 printf (" TBK_IN_IMG");
7026 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7027 printf (" DBG_IN_IMG");
7028 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7029 printf (" TBK_IN_DSF");
7030 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7031 printf (" DBG_IN_DSF");
7032 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7033 printf (" SIGNATURES");
7034 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7035 printf (" REL_SEG_OFF");
7036 break;
7037
bdf4d63a
JJ
7038 default:
7039 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7040 break;
ecc51f48 7041 }
bdf4d63a 7042 putchar ('\n');
ecc51f48
NC
7043}
7044
252b5132 7045static int
2cf0635d 7046get_32bit_dynamic_section (FILE * file)
252b5132 7047{
2cf0635d
NC
7048 Elf32_External_Dyn * edyn;
7049 Elf32_External_Dyn * ext;
7050 Elf_Internal_Dyn * entry;
103f02d3 7051
3f5e193b
NC
7052 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7053 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7054 if (!edyn)
7055 return 0;
103f02d3 7056
ba2685cc
AM
7057/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7058 might not have the luxury of section headers. Look for the DT_NULL
7059 terminator to determine the number of entries. */
7060 for (ext = edyn, dynamic_nent = 0;
7061 (char *) ext < (char *) edyn + dynamic_size;
7062 ext++)
7063 {
7064 dynamic_nent++;
7065 if (BYTE_GET (ext->d_tag) == DT_NULL)
7066 break;
7067 }
252b5132 7068
3f5e193b
NC
7069 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7070 sizeof (* entry));
b2d38a17 7071 if (dynamic_section == NULL)
252b5132 7072 {
9ea033b2
NC
7073 error (_("Out of memory\n"));
7074 free (edyn);
7075 return 0;
7076 }
252b5132 7077
fb514b26 7078 for (ext = edyn, entry = dynamic_section;
ba2685cc 7079 entry < dynamic_section + dynamic_nent;
fb514b26 7080 ext++, entry++)
9ea033b2 7081 {
fb514b26
AM
7082 entry->d_tag = BYTE_GET (ext->d_tag);
7083 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7084 }
7085
9ea033b2
NC
7086 free (edyn);
7087
7088 return 1;
7089}
7090
7091static int
2cf0635d 7092get_64bit_dynamic_section (FILE * file)
9ea033b2 7093{
2cf0635d
NC
7094 Elf64_External_Dyn * edyn;
7095 Elf64_External_Dyn * ext;
7096 Elf_Internal_Dyn * entry;
103f02d3 7097
3f5e193b
NC
7098 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7099 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7100 if (!edyn)
7101 return 0;
103f02d3 7102
ba2685cc
AM
7103/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7104 might not have the luxury of section headers. Look for the DT_NULL
7105 terminator to determine the number of entries. */
7106 for (ext = edyn, dynamic_nent = 0;
7107 (char *) ext < (char *) edyn + dynamic_size;
7108 ext++)
7109 {
7110 dynamic_nent++;
66543521 7111 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7112 break;
7113 }
252b5132 7114
3f5e193b
NC
7115 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7116 sizeof (* entry));
b2d38a17 7117 if (dynamic_section == NULL)
252b5132
RH
7118 {
7119 error (_("Out of memory\n"));
7120 free (edyn);
7121 return 0;
7122 }
7123
fb514b26 7124 for (ext = edyn, entry = dynamic_section;
ba2685cc 7125 entry < dynamic_section + dynamic_nent;
fb514b26 7126 ext++, entry++)
252b5132 7127 {
66543521
AM
7128 entry->d_tag = BYTE_GET (ext->d_tag);
7129 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7130 }
7131
7132 free (edyn);
7133
9ea033b2
NC
7134 return 1;
7135}
7136
e9e44622
JJ
7137static void
7138print_dynamic_flags (bfd_vma flags)
d1133906 7139{
e9e44622 7140 int first = 1;
13ae64f3 7141
d1133906
NC
7142 while (flags)
7143 {
7144 bfd_vma flag;
7145
7146 flag = flags & - flags;
7147 flags &= ~ flag;
7148
e9e44622
JJ
7149 if (first)
7150 first = 0;
7151 else
7152 putc (' ', stdout);
13ae64f3 7153
d1133906
NC
7154 switch (flag)
7155 {
e9e44622
JJ
7156 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7157 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7158 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7159 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7160 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7161 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7162 }
7163 }
e9e44622 7164 puts ("");
d1133906
NC
7165}
7166
b2d38a17
NC
7167/* Parse and display the contents of the dynamic section. */
7168
9ea033b2 7169static int
2cf0635d 7170process_dynamic_section (FILE * file)
9ea033b2 7171{
2cf0635d 7172 Elf_Internal_Dyn * entry;
9ea033b2
NC
7173
7174 if (dynamic_size == 0)
7175 {
7176 if (do_dynamic)
b2d38a17 7177 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7178
7179 return 1;
7180 }
7181
7182 if (is_32bit_elf)
7183 {
b2d38a17 7184 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7185 return 0;
7186 }
b2d38a17 7187 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7188 return 0;
7189
252b5132
RH
7190 /* Find the appropriate symbol table. */
7191 if (dynamic_symbols == NULL)
7192 {
86dba8ee
AM
7193 for (entry = dynamic_section;
7194 entry < dynamic_section + dynamic_nent;
7195 ++entry)
252b5132 7196 {
c8286bd1 7197 Elf_Internal_Shdr section;
252b5132
RH
7198
7199 if (entry->d_tag != DT_SYMTAB)
7200 continue;
7201
7202 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7203
7204 /* Since we do not know how big the symbol table is,
7205 we default to reading in the entire file (!) and
7206 processing that. This is overkill, I know, but it
e3c8793a 7207 should work. */
d93f0186 7208 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7209
fb52b2f4
NC
7210 if (archive_file_offset != 0)
7211 section.sh_size = archive_file_size - section.sh_offset;
7212 else
7213 {
7214 if (fseek (file, 0, SEEK_END))
591a748a 7215 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7216
7217 section.sh_size = ftell (file) - section.sh_offset;
7218 }
252b5132 7219
9ea033b2 7220 if (is_32bit_elf)
9ad5cbcf 7221 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7222 else
9ad5cbcf 7223 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7224
9ad5cbcf 7225 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 7226 if (num_dynamic_syms < 1)
252b5132
RH
7227 {
7228 error (_("Unable to determine the number of symbols to load\n"));
7229 continue;
7230 }
7231
9ad5cbcf 7232 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
7233 }
7234 }
7235
7236 /* Similarly find a string table. */
7237 if (dynamic_strings == NULL)
7238 {
86dba8ee
AM
7239 for (entry = dynamic_section;
7240 entry < dynamic_section + dynamic_nent;
7241 ++entry)
252b5132
RH
7242 {
7243 unsigned long offset;
b34976b6 7244 long str_tab_len;
252b5132
RH
7245
7246 if (entry->d_tag != DT_STRTAB)
7247 continue;
7248
7249 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7250
7251 /* Since we do not know how big the string table is,
7252 we default to reading in the entire file (!) and
7253 processing that. This is overkill, I know, but it
e3c8793a 7254 should work. */
252b5132 7255
d93f0186 7256 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7257
7258 if (archive_file_offset != 0)
7259 str_tab_len = archive_file_size - offset;
7260 else
7261 {
7262 if (fseek (file, 0, SEEK_END))
7263 error (_("Unable to seek to end of file\n"));
7264 str_tab_len = ftell (file) - offset;
7265 }
252b5132
RH
7266
7267 if (str_tab_len < 1)
7268 {
7269 error
7270 (_("Unable to determine the length of the dynamic string table\n"));
7271 continue;
7272 }
7273
3f5e193b
NC
7274 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7275 str_tab_len,
7276 _("dynamic string table"));
d79b3d50 7277 dynamic_strings_length = str_tab_len;
252b5132
RH
7278 break;
7279 }
7280 }
7281
7282 /* And find the syminfo section if available. */
7283 if (dynamic_syminfo == NULL)
7284 {
3e8bba36 7285 unsigned long syminsz = 0;
252b5132 7286
86dba8ee
AM
7287 for (entry = dynamic_section;
7288 entry < dynamic_section + dynamic_nent;
7289 ++entry)
252b5132
RH
7290 {
7291 if (entry->d_tag == DT_SYMINENT)
7292 {
7293 /* Note: these braces are necessary to avoid a syntax
7294 error from the SunOS4 C compiler. */
7295 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7296 }
7297 else if (entry->d_tag == DT_SYMINSZ)
7298 syminsz = entry->d_un.d_val;
7299 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7300 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7301 syminsz);
252b5132
RH
7302 }
7303
7304 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7305 {
2cf0635d
NC
7306 Elf_External_Syminfo * extsyminfo;
7307 Elf_External_Syminfo * extsym;
7308 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7309
7310 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7311 extsyminfo = (Elf_External_Syminfo *)
7312 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7313 _("symbol information"));
a6e9f9df
AM
7314 if (!extsyminfo)
7315 return 0;
252b5132 7316
3f5e193b 7317 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7318 if (dynamic_syminfo == NULL)
7319 {
7320 error (_("Out of memory\n"));
7321 return 0;
7322 }
7323
7324 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7325 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7326 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7327 ++syminfo, ++extsym)
252b5132 7328 {
86dba8ee
AM
7329 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7330 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7331 }
7332
7333 free (extsyminfo);
7334 }
7335 }
7336
7337 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7338 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7339 dynamic_addr, dynamic_nent);
252b5132
RH
7340 if (do_dynamic)
7341 printf (_(" Tag Type Name/Value\n"));
7342
86dba8ee
AM
7343 for (entry = dynamic_section;
7344 entry < dynamic_section + dynamic_nent;
7345 entry++)
252b5132
RH
7346 {
7347 if (do_dynamic)
f7a99963 7348 {
2cf0635d 7349 const char * dtype;
e699b9ff 7350
f7a99963
NC
7351 putchar (' ');
7352 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7353 dtype = get_dynamic_type (entry->d_tag);
7354 printf (" (%s)%*s", dtype,
7355 ((is_32bit_elf ? 27 : 19)
7356 - (int) strlen (dtype)),
f7a99963
NC
7357 " ");
7358 }
252b5132
RH
7359
7360 switch (entry->d_tag)
7361 {
d1133906
NC
7362 case DT_FLAGS:
7363 if (do_dynamic)
e9e44622 7364 print_dynamic_flags (entry->d_un.d_val);
d1133906 7365 break;
76da6bbe 7366
252b5132
RH
7367 case DT_AUXILIARY:
7368 case DT_FILTER:
019148e4
L
7369 case DT_CONFIG:
7370 case DT_DEPAUDIT:
7371 case DT_AUDIT:
252b5132
RH
7372 if (do_dynamic)
7373 {
019148e4 7374 switch (entry->d_tag)
b34976b6 7375 {
019148e4
L
7376 case DT_AUXILIARY:
7377 printf (_("Auxiliary library"));
7378 break;
7379
7380 case DT_FILTER:
7381 printf (_("Filter library"));
7382 break;
7383
b34976b6 7384 case DT_CONFIG:
019148e4
L
7385 printf (_("Configuration file"));
7386 break;
7387
7388 case DT_DEPAUDIT:
7389 printf (_("Dependency audit library"));
7390 break;
7391
7392 case DT_AUDIT:
7393 printf (_("Audit library"));
7394 break;
7395 }
252b5132 7396
d79b3d50
NC
7397 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7398 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7399 else
f7a99963
NC
7400 {
7401 printf (": ");
7402 print_vma (entry->d_un.d_val, PREFIX_HEX);
7403 putchar ('\n');
7404 }
252b5132
RH
7405 }
7406 break;
7407
dcefbbbd 7408 case DT_FEATURE:
252b5132
RH
7409 if (do_dynamic)
7410 {
7411 printf (_("Flags:"));
86f55779 7412
252b5132
RH
7413 if (entry->d_un.d_val == 0)
7414 printf (_(" None\n"));
7415 else
7416 {
7417 unsigned long int val = entry->d_un.d_val;
86f55779 7418
252b5132
RH
7419 if (val & DTF_1_PARINIT)
7420 {
7421 printf (" PARINIT");
7422 val ^= DTF_1_PARINIT;
7423 }
dcefbbbd
L
7424 if (val & DTF_1_CONFEXP)
7425 {
7426 printf (" CONFEXP");
7427 val ^= DTF_1_CONFEXP;
7428 }
252b5132
RH
7429 if (val != 0)
7430 printf (" %lx", val);
7431 puts ("");
7432 }
7433 }
7434 break;
7435
7436 case DT_POSFLAG_1:
7437 if (do_dynamic)
7438 {
7439 printf (_("Flags:"));
86f55779 7440
252b5132
RH
7441 if (entry->d_un.d_val == 0)
7442 printf (_(" None\n"));
7443 else
7444 {
7445 unsigned long int val = entry->d_un.d_val;
86f55779 7446
252b5132
RH
7447 if (val & DF_P1_LAZYLOAD)
7448 {
7449 printf (" LAZYLOAD");
7450 val ^= DF_P1_LAZYLOAD;
7451 }
7452 if (val & DF_P1_GROUPPERM)
7453 {
7454 printf (" GROUPPERM");
7455 val ^= DF_P1_GROUPPERM;
7456 }
7457 if (val != 0)
7458 printf (" %lx", val);
7459 puts ("");
7460 }
7461 }
7462 break;
7463
7464 case DT_FLAGS_1:
7465 if (do_dynamic)
7466 {
7467 printf (_("Flags:"));
7468 if (entry->d_un.d_val == 0)
7469 printf (_(" None\n"));
7470 else
7471 {
7472 unsigned long int val = entry->d_un.d_val;
86f55779 7473
252b5132
RH
7474 if (val & DF_1_NOW)
7475 {
7476 printf (" NOW");
7477 val ^= DF_1_NOW;
7478 }
7479 if (val & DF_1_GLOBAL)
7480 {
7481 printf (" GLOBAL");
7482 val ^= DF_1_GLOBAL;
7483 }
7484 if (val & DF_1_GROUP)
7485 {
7486 printf (" GROUP");
7487 val ^= DF_1_GROUP;
7488 }
7489 if (val & DF_1_NODELETE)
7490 {
7491 printf (" NODELETE");
7492 val ^= DF_1_NODELETE;
7493 }
7494 if (val & DF_1_LOADFLTR)
7495 {
7496 printf (" LOADFLTR");
7497 val ^= DF_1_LOADFLTR;
7498 }
7499 if (val & DF_1_INITFIRST)
7500 {
7501 printf (" INITFIRST");
7502 val ^= DF_1_INITFIRST;
7503 }
7504 if (val & DF_1_NOOPEN)
7505 {
7506 printf (" NOOPEN");
7507 val ^= DF_1_NOOPEN;
7508 }
7509 if (val & DF_1_ORIGIN)
7510 {
7511 printf (" ORIGIN");
7512 val ^= DF_1_ORIGIN;
7513 }
7514 if (val & DF_1_DIRECT)
7515 {
7516 printf (" DIRECT");
7517 val ^= DF_1_DIRECT;
7518 }
7519 if (val & DF_1_TRANS)
7520 {
7521 printf (" TRANS");
7522 val ^= DF_1_TRANS;
7523 }
7524 if (val & DF_1_INTERPOSE)
7525 {
7526 printf (" INTERPOSE");
7527 val ^= DF_1_INTERPOSE;
7528 }
f7db6139 7529 if (val & DF_1_NODEFLIB)
dcefbbbd 7530 {
f7db6139
L
7531 printf (" NODEFLIB");
7532 val ^= DF_1_NODEFLIB;
dcefbbbd
L
7533 }
7534 if (val & DF_1_NODUMP)
7535 {
7536 printf (" NODUMP");
7537 val ^= DF_1_NODUMP;
7538 }
7539 if (val & DF_1_CONLFAT)
7540 {
7541 printf (" CONLFAT");
7542 val ^= DF_1_CONLFAT;
7543 }
252b5132
RH
7544 if (val != 0)
7545 printf (" %lx", val);
7546 puts ("");
7547 }
7548 }
7549 break;
7550
7551 case DT_PLTREL:
566b0d53 7552 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7553 if (do_dynamic)
7554 puts (get_dynamic_type (entry->d_un.d_val));
7555 break;
7556
7557 case DT_NULL :
7558 case DT_NEEDED :
7559 case DT_PLTGOT :
7560 case DT_HASH :
7561 case DT_STRTAB :
7562 case DT_SYMTAB :
7563 case DT_RELA :
7564 case DT_INIT :
7565 case DT_FINI :
7566 case DT_SONAME :
7567 case DT_RPATH :
7568 case DT_SYMBOLIC:
7569 case DT_REL :
7570 case DT_DEBUG :
7571 case DT_TEXTREL :
7572 case DT_JMPREL :
019148e4 7573 case DT_RUNPATH :
252b5132
RH
7574 dynamic_info[entry->d_tag] = entry->d_un.d_val;
7575
7576 if (do_dynamic)
7577 {
2cf0635d 7578 char * name;
252b5132 7579
d79b3d50
NC
7580 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7581 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7582 else
d79b3d50 7583 name = NULL;
252b5132
RH
7584
7585 if (name)
7586 {
7587 switch (entry->d_tag)
7588 {
7589 case DT_NEEDED:
7590 printf (_("Shared library: [%s]"), name);
7591
18bd398b 7592 if (streq (name, program_interpreter))
f7a99963 7593 printf (_(" program interpreter"));
252b5132
RH
7594 break;
7595
7596 case DT_SONAME:
f7a99963 7597 printf (_("Library soname: [%s]"), name);
252b5132
RH
7598 break;
7599
7600 case DT_RPATH:
f7a99963 7601 printf (_("Library rpath: [%s]"), name);
252b5132
RH
7602 break;
7603
019148e4
L
7604 case DT_RUNPATH:
7605 printf (_("Library runpath: [%s]"), name);
7606 break;
7607
252b5132 7608 default:
f7a99963
NC
7609 print_vma (entry->d_un.d_val, PREFIX_HEX);
7610 break;
252b5132
RH
7611 }
7612 }
7613 else
f7a99963
NC
7614 print_vma (entry->d_un.d_val, PREFIX_HEX);
7615
7616 putchar ('\n');
252b5132
RH
7617 }
7618 break;
7619
7620 case DT_PLTRELSZ:
7621 case DT_RELASZ :
7622 case DT_STRSZ :
7623 case DT_RELSZ :
7624 case DT_RELAENT :
7625 case DT_SYMENT :
7626 case DT_RELENT :
566b0d53 7627 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7628 case DT_PLTPADSZ:
7629 case DT_MOVEENT :
7630 case DT_MOVESZ :
7631 case DT_INIT_ARRAYSZ:
7632 case DT_FINI_ARRAYSZ:
047b2264
JJ
7633 case DT_GNU_CONFLICTSZ:
7634 case DT_GNU_LIBLISTSZ:
252b5132 7635 if (do_dynamic)
f7a99963
NC
7636 {
7637 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 7638 printf (_(" (bytes)\n"));
f7a99963 7639 }
252b5132
RH
7640 break;
7641
7642 case DT_VERDEFNUM:
7643 case DT_VERNEEDNUM:
7644 case DT_RELACOUNT:
7645 case DT_RELCOUNT:
7646 if (do_dynamic)
f7a99963
NC
7647 {
7648 print_vma (entry->d_un.d_val, UNSIGNED);
7649 putchar ('\n');
7650 }
252b5132
RH
7651 break;
7652
7653 case DT_SYMINSZ:
7654 case DT_SYMINENT:
7655 case DT_SYMINFO:
7656 case DT_USED:
7657 case DT_INIT_ARRAY:
7658 case DT_FINI_ARRAY:
7659 if (do_dynamic)
7660 {
d79b3d50
NC
7661 if (entry->d_tag == DT_USED
7662 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 7663 {
2cf0635d 7664 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7665
b34976b6 7666 if (*name)
252b5132
RH
7667 {
7668 printf (_("Not needed object: [%s]\n"), name);
7669 break;
7670 }
7671 }
103f02d3 7672
f7a99963
NC
7673 print_vma (entry->d_un.d_val, PREFIX_HEX);
7674 putchar ('\n');
252b5132
RH
7675 }
7676 break;
7677
7678 case DT_BIND_NOW:
7679 /* The value of this entry is ignored. */
35b1837e
AM
7680 if (do_dynamic)
7681 putchar ('\n');
252b5132 7682 break;
103f02d3 7683
047b2264
JJ
7684 case DT_GNU_PRELINKED:
7685 if (do_dynamic)
7686 {
2cf0635d 7687 struct tm * tmp;
91d6fa6a 7688 time_t atime = entry->d_un.d_val;
047b2264 7689
91d6fa6a 7690 tmp = gmtime (&atime);
047b2264
JJ
7691 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
7692 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7693 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
7694
7695 }
7696 break;
7697
fdc90cb4
JJ
7698 case DT_GNU_HASH:
7699 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
7700 if (do_dynamic)
7701 {
7702 print_vma (entry->d_un.d_val, PREFIX_HEX);
7703 putchar ('\n');
7704 }
7705 break;
7706
252b5132
RH
7707 default:
7708 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 7709 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
7710 entry->d_un.d_val;
7711
7712 if (do_dynamic)
7713 {
7714 switch (elf_header.e_machine)
7715 {
7716 case EM_MIPS:
4fe85591 7717 case EM_MIPS_RS3_LE:
b2d38a17 7718 dynamic_section_mips_val (entry);
252b5132 7719 break;
103f02d3 7720 case EM_PARISC:
b2d38a17 7721 dynamic_section_parisc_val (entry);
103f02d3 7722 break;
ecc51f48 7723 case EM_IA_64:
b2d38a17 7724 dynamic_section_ia64_val (entry);
ecc51f48 7725 break;
252b5132 7726 default:
f7a99963
NC
7727 print_vma (entry->d_un.d_val, PREFIX_HEX);
7728 putchar ('\n');
252b5132
RH
7729 }
7730 }
7731 break;
7732 }
7733 }
7734
7735 return 1;
7736}
7737
7738static char *
d3ba0551 7739get_ver_flags (unsigned int flags)
252b5132 7740{
b34976b6 7741 static char buff[32];
252b5132
RH
7742
7743 buff[0] = 0;
7744
7745 if (flags == 0)
7746 return _("none");
7747
7748 if (flags & VER_FLG_BASE)
7749 strcat (buff, "BASE ");
7750
7751 if (flags & VER_FLG_WEAK)
7752 {
7753 if (flags & VER_FLG_BASE)
7754 strcat (buff, "| ");
7755
7756 strcat (buff, "WEAK ");
7757 }
7758
44ec90b9
RO
7759 if (flags & VER_FLG_INFO)
7760 {
7761 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7762 strcat (buff, "| ");
7763
7764 strcat (buff, "INFO ");
7765 }
7766
7767 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 7768 strcat (buff, _("| <unknown>"));
252b5132
RH
7769
7770 return buff;
7771}
7772
7773/* Display the contents of the version sections. */
98fb390a 7774
252b5132 7775static int
2cf0635d 7776process_version_sections (FILE * file)
252b5132 7777{
2cf0635d 7778 Elf_Internal_Shdr * section;
b34976b6
AM
7779 unsigned i;
7780 int found = 0;
252b5132
RH
7781
7782 if (! do_version)
7783 return 1;
7784
7785 for (i = 0, section = section_headers;
7786 i < elf_header.e_shnum;
b34976b6 7787 i++, section++)
252b5132
RH
7788 {
7789 switch (section->sh_type)
7790 {
7791 case SHT_GNU_verdef:
7792 {
2cf0635d 7793 Elf_External_Verdef * edefs;
b34976b6
AM
7794 unsigned int idx;
7795 unsigned int cnt;
2cf0635d 7796 char * endbuf;
252b5132
RH
7797
7798 found = 1;
7799
7800 printf
72de5009 7801 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
7802 SECTION_NAME (section), section->sh_info);
7803
7804 printf (_(" Addr: 0x"));
7805 printf_vma (section->sh_addr);
72de5009 7806 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7807 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
7808 section->sh_link < elf_header.e_shnum
7809 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 7810 : _("<corrupt>"));
252b5132 7811
3f5e193b
NC
7812 edefs = (Elf_External_Verdef *)
7813 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
7814 _("version definition section"));
54806181 7815 endbuf = (char *) edefs + section->sh_size;
a6e9f9df
AM
7816 if (!edefs)
7817 break;
252b5132 7818
b34976b6 7819 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 7820 {
2cf0635d
NC
7821 char * vstart;
7822 Elf_External_Verdef * edef;
b34976b6 7823 Elf_Internal_Verdef ent;
2cf0635d 7824 Elf_External_Verdaux * eaux;
b34976b6
AM
7825 Elf_Internal_Verdaux aux;
7826 int j;
7827 int isum;
103f02d3 7828
dd24e3da
NC
7829 /* Check for negative or very large indicies. */
7830 if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
7831 break;
7832
252b5132 7833 vstart = ((char *) edefs) + idx;
54806181
AM
7834 if (vstart + sizeof (*edef) > endbuf)
7835 break;
252b5132
RH
7836
7837 edef = (Elf_External_Verdef *) vstart;
7838
7839 ent.vd_version = BYTE_GET (edef->vd_version);
7840 ent.vd_flags = BYTE_GET (edef->vd_flags);
7841 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
7842 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
7843 ent.vd_hash = BYTE_GET (edef->vd_hash);
7844 ent.vd_aux = BYTE_GET (edef->vd_aux);
7845 ent.vd_next = BYTE_GET (edef->vd_next);
7846
7847 printf (_(" %#06x: Rev: %d Flags: %s"),
7848 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
7849
7850 printf (_(" Index: %d Cnt: %d "),
7851 ent.vd_ndx, ent.vd_cnt);
7852
dd24e3da
NC
7853 /* Check for overflow. */
7854 if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
7855 || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
7856 break;
7857
252b5132
RH
7858 vstart += ent.vd_aux;
7859
7860 eaux = (Elf_External_Verdaux *) vstart;
7861
7862 aux.vda_name = BYTE_GET (eaux->vda_name);
7863 aux.vda_next = BYTE_GET (eaux->vda_next);
7864
d79b3d50
NC
7865 if (VALID_DYNAMIC_NAME (aux.vda_name))
7866 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
7867 else
7868 printf (_("Name index: %ld\n"), aux.vda_name);
7869
7870 isum = idx + ent.vd_aux;
7871
b34976b6 7872 for (j = 1; j < ent.vd_cnt; j++)
252b5132 7873 {
dd24e3da
NC
7874 /* Check for overflow. */
7875 if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
7876 || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
7877 break;
7878
252b5132
RH
7879 isum += aux.vda_next;
7880 vstart += aux.vda_next;
7881
7882 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
7883 if (vstart + sizeof (*eaux) > endbuf)
7884 break;
252b5132
RH
7885
7886 aux.vda_name = BYTE_GET (eaux->vda_name);
7887 aux.vda_next = BYTE_GET (eaux->vda_next);
7888
d79b3d50 7889 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 7890 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 7891 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
7892 else
7893 printf (_(" %#06x: Parent %d, name index: %ld\n"),
7894 isum, j, aux.vda_name);
7895 }
dd24e3da 7896
54806181
AM
7897 if (j < ent.vd_cnt)
7898 printf (_(" Version def aux past end of section\n"));
252b5132
RH
7899
7900 idx += ent.vd_next;
7901 }
dd24e3da 7902
54806181
AM
7903 if (cnt < section->sh_info)
7904 printf (_(" Version definition past end of section\n"));
252b5132
RH
7905
7906 free (edefs);
7907 }
7908 break;
103f02d3 7909
252b5132
RH
7910 case SHT_GNU_verneed:
7911 {
2cf0635d 7912 Elf_External_Verneed * eneed;
b34976b6
AM
7913 unsigned int idx;
7914 unsigned int cnt;
2cf0635d 7915 char * endbuf;
252b5132
RH
7916
7917 found = 1;
7918
72de5009 7919 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
7920 SECTION_NAME (section), section->sh_info);
7921
7922 printf (_(" Addr: 0x"));
7923 printf_vma (section->sh_addr);
72de5009 7924 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 7925 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
7926 section->sh_link < elf_header.e_shnum
7927 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 7928 : _("<corrupt>"));
252b5132 7929
3f5e193b
NC
7930 eneed = (Elf_External_Verneed *) get_data (NULL, file,
7931 section->sh_offset, 1,
7932 section->sh_size,
7933 _("version need section"));
54806181 7934 endbuf = (char *) eneed + section->sh_size;
a6e9f9df
AM
7935 if (!eneed)
7936 break;
252b5132
RH
7937
7938 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
7939 {
2cf0635d 7940 Elf_External_Verneed * entry;
b34976b6
AM
7941 Elf_Internal_Verneed ent;
7942 int j;
7943 int isum;
2cf0635d 7944 char * vstart;
252b5132 7945
dd24e3da
NC
7946 if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
7947 break;
7948
252b5132 7949 vstart = ((char *) eneed) + idx;
54806181
AM
7950 if (vstart + sizeof (*entry) > endbuf)
7951 break;
252b5132
RH
7952
7953 entry = (Elf_External_Verneed *) vstart;
7954
7955 ent.vn_version = BYTE_GET (entry->vn_version);
7956 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
7957 ent.vn_file = BYTE_GET (entry->vn_file);
7958 ent.vn_aux = BYTE_GET (entry->vn_aux);
7959 ent.vn_next = BYTE_GET (entry->vn_next);
7960
7961 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
7962
d79b3d50
NC
7963 if (VALID_DYNAMIC_NAME (ent.vn_file))
7964 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
7965 else
7966 printf (_(" File: %lx"), ent.vn_file);
7967
7968 printf (_(" Cnt: %d\n"), ent.vn_cnt);
7969
dd24e3da
NC
7970 /* Check for overflow. */
7971 if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
7972 || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
7973 break;
7974
252b5132
RH
7975 vstart += ent.vn_aux;
7976
7977 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
7978 {
2cf0635d 7979 Elf_External_Vernaux * eaux;
b34976b6 7980 Elf_Internal_Vernaux aux;
252b5132 7981
54806181
AM
7982 if (vstart + sizeof (*eaux) > endbuf)
7983 break;
252b5132
RH
7984 eaux = (Elf_External_Vernaux *) vstart;
7985
7986 aux.vna_hash = BYTE_GET (eaux->vna_hash);
7987 aux.vna_flags = BYTE_GET (eaux->vna_flags);
7988 aux.vna_other = BYTE_GET (eaux->vna_other);
7989 aux.vna_name = BYTE_GET (eaux->vna_name);
7990 aux.vna_next = BYTE_GET (eaux->vna_next);
7991
d79b3d50 7992 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 7993 printf (_(" %#06x: Name: %s"),
d79b3d50 7994 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 7995 else
ecc2063b 7996 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
7997 isum, aux.vna_name);
7998
7999 printf (_(" Flags: %s Version: %d\n"),
8000 get_ver_flags (aux.vna_flags), aux.vna_other);
8001
dd24e3da
NC
8002 /* Check for overflow. */
8003 if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
8004 || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
8005 break;
8006
252b5132
RH
8007 isum += aux.vna_next;
8008 vstart += aux.vna_next;
8009 }
54806181
AM
8010 if (j < ent.vn_cnt)
8011 printf (_(" Version need aux past end of section\n"));
252b5132
RH
8012
8013 idx += ent.vn_next;
8014 }
54806181
AM
8015 if (cnt < section->sh_info)
8016 printf (_(" Version need past end of section\n"));
103f02d3 8017
252b5132
RH
8018 free (eneed);
8019 }
8020 break;
8021
8022 case SHT_GNU_versym:
8023 {
2cf0635d 8024 Elf_Internal_Shdr * link_section;
b34976b6
AM
8025 int total;
8026 int cnt;
2cf0635d
NC
8027 unsigned char * edata;
8028 unsigned short * data;
8029 char * strtab;
8030 Elf_Internal_Sym * symbols;
8031 Elf_Internal_Shdr * string_sec;
d3ba0551 8032 long off;
252b5132 8033
4fbb74a6 8034 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8035 break;
8036
4fbb74a6 8037 link_section = section_headers + section->sh_link;
08d8fa11 8038 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8039
4fbb74a6 8040 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8041 break;
8042
252b5132
RH
8043 found = 1;
8044
9ad5cbcf 8045 symbols = GET_ELF_SYMBOLS (file, link_section);
dd24e3da
NC
8046 if (symbols == NULL)
8047 break;
252b5132 8048
4fbb74a6 8049 string_sec = section_headers + link_section->sh_link;
252b5132 8050
3f5e193b
NC
8051 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8052 string_sec->sh_size,
8053 _("version string table"));
a6e9f9df
AM
8054 if (!strtab)
8055 break;
252b5132
RH
8056
8057 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8058 SECTION_NAME (section), total);
8059
8060 printf (_(" Addr: "));
8061 printf_vma (section->sh_addr);
72de5009 8062 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8063 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8064 SECTION_NAME (link_section));
8065
d3ba0551
AM
8066 off = offset_from_vma (file,
8067 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8068 total * sizeof (short));
3f5e193b
NC
8069 edata = (unsigned char *) get_data (NULL, file, off, total,
8070 sizeof (short),
8071 _("version symbol data"));
a6e9f9df
AM
8072 if (!edata)
8073 {
8074 free (strtab);
8075 break;
8076 }
252b5132 8077
3f5e193b 8078 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8079
8080 for (cnt = total; cnt --;)
b34976b6
AM
8081 data[cnt] = byte_get (edata + cnt * sizeof (short),
8082 sizeof (short));
252b5132
RH
8083
8084 free (edata);
8085
8086 for (cnt = 0; cnt < total; cnt += 4)
8087 {
8088 int j, nn;
00d93f34 8089 int check_def, check_need;
2cf0635d 8090 char * name;
252b5132
RH
8091
8092 printf (" %03x:", cnt);
8093
8094 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8095 switch (data[cnt + j])
252b5132
RH
8096 {
8097 case 0:
8098 fputs (_(" 0 (*local*) "), stdout);
8099 break;
8100
8101 case 1:
8102 fputs (_(" 1 (*global*) "), stdout);
8103 break;
8104
8105 default:
c244d050
NC
8106 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8107 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8108
dd24e3da
NC
8109 /* If this index value is greater than the size of the symbols
8110 array, break to avoid an out-of-bounds read, */
8111 if ((unsigned long)(cnt + j) >=
8112 ((unsigned long)link_section->sh_size /
8113 (unsigned long)link_section->sh_entsize))
8114 {
8115 warn (_("invalid index into symbol array\n"));
8116 break;
8117 }
8118
00d93f34
JJ
8119 check_def = 1;
8120 check_need = 1;
4fbb74a6
AM
8121 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8122 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8123 != SHT_NOBITS)
252b5132 8124 {
b34976b6 8125 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8126 check_def = 0;
8127 else
8128 check_need = 0;
252b5132 8129 }
00d93f34
JJ
8130
8131 if (check_need
b34976b6 8132 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8133 {
b34976b6
AM
8134 Elf_Internal_Verneed ivn;
8135 unsigned long offset;
252b5132 8136
d93f0186
NC
8137 offset = offset_from_vma
8138 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8139 sizeof (Elf_External_Verneed));
252b5132 8140
b34976b6 8141 do
252b5132 8142 {
b34976b6
AM
8143 Elf_Internal_Vernaux ivna;
8144 Elf_External_Verneed evn;
8145 Elf_External_Vernaux evna;
8146 unsigned long a_off;
252b5132 8147
c256ffe7 8148 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 8149 _("version need"));
252b5132
RH
8150
8151 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8152 ivn.vn_next = BYTE_GET (evn.vn_next);
8153
8154 a_off = offset + ivn.vn_aux;
8155
8156 do
8157 {
a6e9f9df 8158 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 8159 1, _("version need aux (2)"));
252b5132
RH
8160
8161 ivna.vna_next = BYTE_GET (evna.vna_next);
8162 ivna.vna_other = BYTE_GET (evna.vna_other);
8163
8164 a_off += ivna.vna_next;
8165 }
b34976b6 8166 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8167 && ivna.vna_next != 0);
8168
b34976b6 8169 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8170 {
8171 ivna.vna_name = BYTE_GET (evna.vna_name);
8172
54806181
AM
8173 if (ivna.vna_name >= string_sec->sh_size)
8174 name = _("*invalid*");
8175 else
8176 name = strtab + ivna.vna_name;
252b5132 8177 nn += printf ("(%s%-*s",
16062207
ILT
8178 name,
8179 12 - (int) strlen (name),
252b5132 8180 ")");
00d93f34 8181 check_def = 0;
252b5132
RH
8182 break;
8183 }
8184
8185 offset += ivn.vn_next;
8186 }
8187 while (ivn.vn_next);
8188 }
00d93f34 8189
b34976b6
AM
8190 if (check_def && data[cnt + j] != 0x8001
8191 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8192 {
b34976b6
AM
8193 Elf_Internal_Verdef ivd;
8194 Elf_External_Verdef evd;
8195 unsigned long offset;
252b5132 8196
d93f0186
NC
8197 offset = offset_from_vma
8198 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8199 sizeof evd);
252b5132
RH
8200
8201 do
8202 {
c256ffe7 8203 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 8204 _("version def"));
252b5132
RH
8205
8206 ivd.vd_next = BYTE_GET (evd.vd_next);
8207 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8208
8209 offset += ivd.vd_next;
8210 }
c244d050 8211 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8212 && ivd.vd_next != 0);
8213
c244d050 8214 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8215 {
b34976b6
AM
8216 Elf_External_Verdaux evda;
8217 Elf_Internal_Verdaux ivda;
252b5132
RH
8218
8219 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8220
a6e9f9df
AM
8221 get_data (&evda, file,
8222 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
8223 sizeof (evda), 1,
8224 _("version def aux"));
252b5132
RH
8225
8226 ivda.vda_name = BYTE_GET (evda.vda_name);
8227
54806181
AM
8228 if (ivda.vda_name >= string_sec->sh_size)
8229 name = _("*invalid*");
8230 else
8231 name = strtab + ivda.vda_name;
252b5132 8232 nn += printf ("(%s%-*s",
16062207
ILT
8233 name,
8234 12 - (int) strlen (name),
252b5132
RH
8235 ")");
8236 }
8237 }
8238
8239 if (nn < 18)
8240 printf ("%*c", 18 - nn, ' ');
8241 }
8242
8243 putchar ('\n');
8244 }
8245
8246 free (data);
8247 free (strtab);
8248 free (symbols);
8249 }
8250 break;
103f02d3 8251
252b5132
RH
8252 default:
8253 break;
8254 }
8255 }
8256
8257 if (! found)
8258 printf (_("\nNo version information found in this file.\n"));
8259
8260 return 1;
8261}
8262
d1133906 8263static const char *
d3ba0551 8264get_symbol_binding (unsigned int binding)
252b5132 8265{
b34976b6 8266 static char buff[32];
252b5132
RH
8267
8268 switch (binding)
8269 {
b34976b6
AM
8270 case STB_LOCAL: return "LOCAL";
8271 case STB_GLOBAL: return "GLOBAL";
8272 case STB_WEAK: return "WEAK";
252b5132
RH
8273 default:
8274 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8275 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8276 binding);
252b5132 8277 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8278 {
8279 if (binding == STB_GNU_UNIQUE
8280 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
8281 /* GNU/Linux is still using the default value 0. */
8282 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8283 return "UNIQUE";
8284 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8285 }
252b5132 8286 else
e9e44622 8287 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8288 return buff;
8289 }
8290}
8291
d1133906 8292static const char *
d3ba0551 8293get_symbol_type (unsigned int type)
252b5132 8294{
b34976b6 8295 static char buff[32];
252b5132
RH
8296
8297 switch (type)
8298 {
b34976b6
AM
8299 case STT_NOTYPE: return "NOTYPE";
8300 case STT_OBJECT: return "OBJECT";
8301 case STT_FUNC: return "FUNC";
8302 case STT_SECTION: return "SECTION";
8303 case STT_FILE: return "FILE";
8304 case STT_COMMON: return "COMMON";
8305 case STT_TLS: return "TLS";
15ab5209
DB
8306 case STT_RELC: return "RELC";
8307 case STT_SRELC: return "SRELC";
252b5132
RH
8308 default:
8309 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8310 {
8311 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8312 return "THUMB_FUNC";
8313
351b4b40 8314 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8315 return "REGISTER";
8316
8317 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8318 return "PARISC_MILLI";
8319
e9e44622 8320 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8321 }
252b5132 8322 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8323 {
8324 if (elf_header.e_machine == EM_PARISC)
8325 {
8326 if (type == STT_HP_OPAQUE)
8327 return "HP_OPAQUE";
8328 if (type == STT_HP_STUB)
8329 return "HP_STUB";
8330 }
8331
d8045f23
NC
8332 if (type == STT_GNU_IFUNC
8333 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
8334 /* GNU/Linux is still using the default value 0. */
8335 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8336 return "IFUNC";
8337
e9e44622 8338 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8339 }
252b5132 8340 else
e9e44622 8341 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8342 return buff;
8343 }
8344}
8345
d1133906 8346static const char *
d3ba0551 8347get_symbol_visibility (unsigned int visibility)
d1133906
NC
8348{
8349 switch (visibility)
8350 {
b34976b6
AM
8351 case STV_DEFAULT: return "DEFAULT";
8352 case STV_INTERNAL: return "INTERNAL";
8353 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
8354 case STV_PROTECTED: return "PROTECTED";
8355 default: abort ();
8356 }
8357}
8358
5e2b0d47
NC
8359static const char *
8360get_mips_symbol_other (unsigned int other)
8361{
8362 switch (other)
8363 {
8364 case STO_OPTIONAL: return "OPTIONAL";
8365 case STO_MIPS16: return "MIPS16";
861fb55a
DJ
8366 case STO_MIPS_PLT: return "MIPS PLT";
8367 case STO_MIPS_PIC: return "MIPS PIC";
5e2b0d47
NC
8368 default: return NULL;
8369 }
8370}
8371
28f997cf
TG
8372static const char *
8373get_ia64_symbol_other (unsigned int other)
8374{
8375 if (is_ia64_vms ())
8376 {
8377 static char res[32];
8378
8379 res[0] = 0;
8380
8381 /* Function types is for images and .STB files only. */
8382 switch (elf_header.e_type)
8383 {
8384 case ET_DYN:
8385 case ET_EXEC:
8386 switch (VMS_ST_FUNC_TYPE (other))
8387 {
8388 case VMS_SFT_CODE_ADDR:
8389 strcat (res, " CA");
8390 break;
8391 case VMS_SFT_SYMV_IDX:
8392 strcat (res, " VEC");
8393 break;
8394 case VMS_SFT_FD:
8395 strcat (res, " FD");
8396 break;
8397 case VMS_SFT_RESERVE:
8398 strcat (res, " RSV");
8399 break;
8400 default:
8401 abort ();
8402 }
8403 break;
8404 default:
8405 break;
8406 }
8407 switch (VMS_ST_LINKAGE (other))
8408 {
8409 case VMS_STL_IGNORE:
8410 strcat (res, " IGN");
8411 break;
8412 case VMS_STL_RESERVE:
8413 strcat (res, " RSV");
8414 break;
8415 case VMS_STL_STD:
8416 strcat (res, " STD");
8417 break;
8418 case VMS_STL_LNK:
8419 strcat (res, " LNK");
8420 break;
8421 default:
8422 abort ();
8423 }
8424
8425 if (res[0] != 0)
8426 return res + 1;
8427 else
8428 return res;
8429 }
8430 return NULL;
8431}
8432
5e2b0d47
NC
8433static const char *
8434get_symbol_other (unsigned int other)
8435{
8436 const char * result = NULL;
8437 static char buff [32];
8438
8439 if (other == 0)
8440 return "";
8441
8442 switch (elf_header.e_machine)
8443 {
8444 case EM_MIPS:
8445 result = get_mips_symbol_other (other);
28f997cf
TG
8446 break;
8447 case EM_IA_64:
8448 result = get_ia64_symbol_other (other);
8449 break;
5e2b0d47
NC
8450 default:
8451 break;
8452 }
8453
8454 if (result)
8455 return result;
8456
8457 snprintf (buff, sizeof buff, _("<other>: %x"), other);
8458 return buff;
8459}
8460
d1133906 8461static const char *
d3ba0551 8462get_symbol_index_type (unsigned int type)
252b5132 8463{
b34976b6 8464 static char buff[32];
5cf1065c 8465
252b5132
RH
8466 switch (type)
8467 {
b34976b6
AM
8468 case SHN_UNDEF: return "UND";
8469 case SHN_ABS: return "ABS";
8470 case SHN_COMMON: return "COM";
252b5132 8471 default:
9ce701e2
L
8472 if (type == SHN_IA_64_ANSI_COMMON
8473 && elf_header.e_machine == EM_IA_64
8474 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
8475 return "ANSI_COM";
8a9036a4
L
8476 else if ((elf_header.e_machine == EM_X86_64
8477 || elf_header.e_machine == EM_L1OM)
3b22753a
L
8478 && type == SHN_X86_64_LCOMMON)
8479 return "LARGE_COM";
172553c7
TS
8480 else if (type == SHN_MIPS_SCOMMON
8481 && elf_header.e_machine == EM_MIPS)
8482 return "SCOM";
8483 else if (type == SHN_MIPS_SUNDEFINED
8484 && elf_header.e_machine == EM_MIPS)
8485 return "SUND";
9ce701e2 8486 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 8487 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 8488 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
8489 sprintf (buff, "OS [0x%04x]", type & 0xffff);
8490 else if (type >= SHN_LORESERVE)
8491 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 8492 else
232e7cb8 8493 sprintf (buff, "%3d", type);
5cf1065c 8494 break;
252b5132 8495 }
5cf1065c
NC
8496
8497 return buff;
252b5132
RH
8498}
8499
66543521 8500static bfd_vma *
2cf0635d 8501get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 8502{
2cf0635d
NC
8503 unsigned char * e_data;
8504 bfd_vma * i_data;
252b5132 8505
3f5e193b 8506 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
8507
8508 if (e_data == NULL)
8509 {
8510 error (_("Out of memory\n"));
8511 return NULL;
8512 }
8513
66543521 8514 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
8515 {
8516 error (_("Unable to read in dynamic data\n"));
8517 return NULL;
8518 }
8519
3f5e193b 8520 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
8521
8522 if (i_data == NULL)
8523 {
8524 error (_("Out of memory\n"));
8525 free (e_data);
8526 return NULL;
8527 }
8528
8529 while (number--)
66543521 8530 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
8531
8532 free (e_data);
8533
8534 return i_data;
8535}
8536
6bd1a22c
L
8537static void
8538print_dynamic_symbol (bfd_vma si, unsigned long hn)
8539{
2cf0635d 8540 Elf_Internal_Sym * psym;
6bd1a22c
L
8541 int n;
8542
8543 psym = dynamic_symbols + si;
8544
8545 n = print_vma (si, DEC_5);
8546 if (n < 5)
8547 fputs (" " + n, stdout);
8548 printf (" %3lu: ", hn);
8549 print_vma (psym->st_value, LONG_HEX);
8550 putchar (' ');
8551 print_vma (psym->st_size, DEC_5);
8552
f4be36b3
AM
8553 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8554 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
8555 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
8556 /* Check to see if any other bits in the st_other field are set.
8557 Note - displaying this information disrupts the layout of the
8558 table being generated, but for the moment this case is very
8559 rare. */
8560 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8561 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
8562 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
8563 if (VALID_DYNAMIC_NAME (psym->st_name))
8564 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
8565 else
2b692964 8566 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
8567 putchar ('\n');
8568}
8569
e3c8793a 8570/* Dump the symbol table. */
252b5132 8571static int
2cf0635d 8572process_symbol_table (FILE * file)
252b5132 8573{
2cf0635d 8574 Elf_Internal_Shdr * section;
66543521
AM
8575 bfd_vma nbuckets = 0;
8576 bfd_vma nchains = 0;
2cf0635d
NC
8577 bfd_vma * buckets = NULL;
8578 bfd_vma * chains = NULL;
fdc90cb4 8579 bfd_vma ngnubuckets = 0;
2cf0635d
NC
8580 bfd_vma * gnubuckets = NULL;
8581 bfd_vma * gnuchains = NULL;
6bd1a22c 8582 bfd_vma gnusymidx = 0;
252b5132 8583
2c610e4b 8584 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
8585 return 1;
8586
6bd1a22c
L
8587 if (dynamic_info[DT_HASH]
8588 && (do_histogram
2c610e4b
L
8589 || (do_using_dynamic
8590 && !do_dyn_syms
8591 && dynamic_strings != NULL)))
252b5132 8592 {
66543521
AM
8593 unsigned char nb[8];
8594 unsigned char nc[8];
8595 int hash_ent_size = 4;
8596
8597 if ((elf_header.e_machine == EM_ALPHA
8598 || elf_header.e_machine == EM_S390
8599 || elf_header.e_machine == EM_S390_OLD)
8600 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
8601 hash_ent_size = 8;
8602
fb52b2f4
NC
8603 if (fseek (file,
8604 (archive_file_offset
8605 + offset_from_vma (file, dynamic_info[DT_HASH],
8606 sizeof nb + sizeof nc)),
d93f0186 8607 SEEK_SET))
252b5132 8608 {
591a748a 8609 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8610 goto no_hash;
252b5132
RH
8611 }
8612
66543521 8613 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
8614 {
8615 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8616 goto no_hash;
252b5132
RH
8617 }
8618
66543521 8619 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
8620 {
8621 error (_("Failed to read in number of chains\n"));
d3a44ec6 8622 goto no_hash;
252b5132
RH
8623 }
8624
66543521
AM
8625 nbuckets = byte_get (nb, hash_ent_size);
8626 nchains = byte_get (nc, hash_ent_size);
252b5132 8627
66543521
AM
8628 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
8629 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 8630
d3a44ec6 8631 no_hash:
252b5132 8632 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
8633 {
8634 if (do_using_dynamic)
8635 return 0;
8636 free (buckets);
8637 free (chains);
8638 buckets = NULL;
8639 chains = NULL;
8640 nbuckets = 0;
8641 nchains = 0;
8642 }
252b5132
RH
8643 }
8644
6bd1a22c
L
8645 if (dynamic_info_DT_GNU_HASH
8646 && (do_histogram
2c610e4b
L
8647 || (do_using_dynamic
8648 && !do_dyn_syms
8649 && dynamic_strings != NULL)))
252b5132 8650 {
6bd1a22c
L
8651 unsigned char nb[16];
8652 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
8653 bfd_vma buckets_vma;
8654
8655 if (fseek (file,
8656 (archive_file_offset
8657 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
8658 sizeof nb)),
8659 SEEK_SET))
8660 {
8661 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8662 goto no_gnu_hash;
6bd1a22c 8663 }
252b5132 8664
6bd1a22c
L
8665 if (fread (nb, 16, 1, file) != 1)
8666 {
8667 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8668 goto no_gnu_hash;
6bd1a22c
L
8669 }
8670
8671 ngnubuckets = byte_get (nb, 4);
8672 gnusymidx = byte_get (nb + 4, 4);
8673 bitmaskwords = byte_get (nb + 8, 4);
8674 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 8675 if (is_32bit_elf)
6bd1a22c 8676 buckets_vma += bitmaskwords * 4;
f7a99963 8677 else
6bd1a22c 8678 buckets_vma += bitmaskwords * 8;
252b5132 8679
6bd1a22c
L
8680 if (fseek (file,
8681 (archive_file_offset
8682 + offset_from_vma (file, buckets_vma, 4)),
8683 SEEK_SET))
252b5132 8684 {
6bd1a22c 8685 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8686 goto no_gnu_hash;
6bd1a22c
L
8687 }
8688
8689 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 8690
6bd1a22c 8691 if (gnubuckets == NULL)
d3a44ec6 8692 goto no_gnu_hash;
6bd1a22c
L
8693
8694 for (i = 0; i < ngnubuckets; i++)
8695 if (gnubuckets[i] != 0)
8696 {
8697 if (gnubuckets[i] < gnusymidx)
8698 return 0;
8699
8700 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
8701 maxchain = gnubuckets[i];
8702 }
8703
8704 if (maxchain == 0xffffffff)
d3a44ec6 8705 goto no_gnu_hash;
6bd1a22c
L
8706
8707 maxchain -= gnusymidx;
8708
8709 if (fseek (file,
8710 (archive_file_offset
8711 + offset_from_vma (file, buckets_vma
8712 + 4 * (ngnubuckets + maxchain), 4)),
8713 SEEK_SET))
8714 {
8715 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8716 goto no_gnu_hash;
6bd1a22c
L
8717 }
8718
8719 do
8720 {
8721 if (fread (nb, 4, 1, file) != 1)
252b5132 8722 {
6bd1a22c 8723 error (_("Failed to determine last chain length\n"));
d3a44ec6 8724 goto no_gnu_hash;
6bd1a22c 8725 }
252b5132 8726
6bd1a22c 8727 if (maxchain + 1 == 0)
d3a44ec6 8728 goto no_gnu_hash;
252b5132 8729
6bd1a22c
L
8730 ++maxchain;
8731 }
8732 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 8733
6bd1a22c
L
8734 if (fseek (file,
8735 (archive_file_offset
8736 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
8737 SEEK_SET))
8738 {
8739 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8740 goto no_gnu_hash;
6bd1a22c
L
8741 }
8742
8743 gnuchains = get_dynamic_data (file, maxchain, 4);
8744
d3a44ec6 8745 no_gnu_hash:
6bd1a22c 8746 if (gnuchains == NULL)
d3a44ec6
JJ
8747 {
8748 free (gnubuckets);
d3a44ec6
JJ
8749 gnubuckets = NULL;
8750 ngnubuckets = 0;
f64fddf1
NC
8751 if (do_using_dynamic)
8752 return 0;
d3a44ec6 8753 }
6bd1a22c
L
8754 }
8755
8756 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
8757 && do_syms
8758 && do_using_dynamic
8759 && dynamic_strings != NULL)
8760 {
8761 unsigned long hn;
8762
8763 if (dynamic_info[DT_HASH])
8764 {
8765 bfd_vma si;
8766
8767 printf (_("\nSymbol table for image:\n"));
8768 if (is_32bit_elf)
8769 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8770 else
8771 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8772
8773 for (hn = 0; hn < nbuckets; hn++)
8774 {
8775 if (! buckets[hn])
8776 continue;
8777
8778 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
8779 print_dynamic_symbol (si, hn);
252b5132
RH
8780 }
8781 }
6bd1a22c
L
8782
8783 if (dynamic_info_DT_GNU_HASH)
8784 {
8785 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
8786 if (is_32bit_elf)
8787 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8788 else
8789 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
8790
8791 for (hn = 0; hn < ngnubuckets; ++hn)
8792 if (gnubuckets[hn] != 0)
8793 {
8794 bfd_vma si = gnubuckets[hn];
8795 bfd_vma off = si - gnusymidx;
8796
8797 do
8798 {
8799 print_dynamic_symbol (si, hn);
8800 si++;
8801 }
8802 while ((gnuchains[off++] & 1) == 0);
8803 }
8804 }
252b5132 8805 }
2c610e4b 8806 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 8807 {
b34976b6 8808 unsigned int i;
252b5132
RH
8809
8810 for (i = 0, section = section_headers;
8811 i < elf_header.e_shnum;
8812 i++, section++)
8813 {
b34976b6 8814 unsigned int si;
2cf0635d 8815 char * strtab = NULL;
c256ffe7 8816 unsigned long int strtab_size = 0;
2cf0635d
NC
8817 Elf_Internal_Sym * symtab;
8818 Elf_Internal_Sym * psym;
252b5132 8819
2c610e4b
L
8820 if ((section->sh_type != SHT_SYMTAB
8821 && section->sh_type != SHT_DYNSYM)
8822 || (!do_syms
8823 && section->sh_type == SHT_SYMTAB))
252b5132
RH
8824 continue;
8825
dd24e3da
NC
8826 if (section->sh_entsize == 0)
8827 {
8828 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
8829 SECTION_NAME (section));
8830 continue;
8831 }
8832
252b5132
RH
8833 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
8834 SECTION_NAME (section),
8835 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 8836
f7a99963 8837 if (is_32bit_elf)
ca47b30c 8838 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 8839 else
ca47b30c 8840 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 8841
9ad5cbcf 8842 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
8843 if (symtab == NULL)
8844 continue;
8845
8846 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
8847 {
8848 strtab = string_table;
8849 strtab_size = string_table_length;
8850 }
4fbb74a6 8851 else if (section->sh_link < elf_header.e_shnum)
252b5132 8852 {
2cf0635d 8853 Elf_Internal_Shdr * string_sec;
252b5132 8854
4fbb74a6 8855 string_sec = section_headers + section->sh_link;
252b5132 8856
3f5e193b
NC
8857 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
8858 1, string_sec->sh_size,
8859 _("string table"));
c256ffe7 8860 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
8861 }
8862
8863 for (si = 0, psym = symtab;
8864 si < section->sh_size / section->sh_entsize;
b34976b6 8865 si++, psym++)
252b5132 8866 {
5e220199 8867 printf ("%6d: ", si);
f7a99963
NC
8868 print_vma (psym->st_value, LONG_HEX);
8869 putchar (' ');
8870 print_vma (psym->st_size, DEC_5);
d1133906
NC
8871 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8872 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 8873 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
8874 /* Check to see if any other bits in the st_other field are set.
8875 Note - displaying this information disrupts the layout of the
8876 table being generated, but for the moment this case is very rare. */
8877 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8878 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 8879 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 8880 print_symbol (25, psym->st_name < strtab_size
2b692964 8881 ? strtab + psym->st_name : _("<corrupt>"));
252b5132
RH
8882
8883 if (section->sh_type == SHT_DYNSYM &&
b34976b6 8884 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 8885 {
b34976b6
AM
8886 unsigned char data[2];
8887 unsigned short vers_data;
8888 unsigned long offset;
8889 int is_nobits;
8890 int check_def;
252b5132 8891
d93f0186
NC
8892 offset = offset_from_vma
8893 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8894 sizeof data + si * sizeof (vers_data));
252b5132 8895
a6e9f9df 8896 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 8897 sizeof (data), 1, _("version data"));
252b5132
RH
8898
8899 vers_data = byte_get (data, 2);
8900
4fbb74a6
AM
8901 is_nobits = (psym->st_shndx < elf_header.e_shnum
8902 && section_headers[psym->st_shndx].sh_type
c256ffe7 8903 == SHT_NOBITS);
252b5132
RH
8904
8905 check_def = (psym->st_shndx != SHN_UNDEF);
8906
c244d050 8907 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 8908 {
b34976b6 8909 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 8910 && (is_nobits || ! check_def))
252b5132 8911 {
b34976b6
AM
8912 Elf_External_Verneed evn;
8913 Elf_Internal_Verneed ivn;
8914 Elf_Internal_Vernaux ivna;
252b5132
RH
8915
8916 /* We must test both. */
d93f0186
NC
8917 offset = offset_from_vma
8918 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8919 sizeof evn);
252b5132 8920
252b5132
RH
8921 do
8922 {
b34976b6 8923 unsigned long vna_off;
252b5132 8924
c256ffe7 8925 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 8926 _("version need"));
dd27201e
L
8927
8928 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8929 ivn.vn_next = BYTE_GET (evn.vn_next);
8930
252b5132
RH
8931 vna_off = offset + ivn.vn_aux;
8932
8933 do
8934 {
b34976b6 8935 Elf_External_Vernaux evna;
252b5132 8936
a6e9f9df 8937 get_data (&evna, file, vna_off,
c256ffe7 8938 sizeof (evna), 1,
a6e9f9df 8939 _("version need aux (3)"));
252b5132
RH
8940
8941 ivna.vna_other = BYTE_GET (evna.vna_other);
8942 ivna.vna_next = BYTE_GET (evna.vna_next);
8943 ivna.vna_name = BYTE_GET (evna.vna_name);
8944
8945 vna_off += ivna.vna_next;
8946 }
8947 while (ivna.vna_other != vers_data
8948 && ivna.vna_next != 0);
8949
8950 if (ivna.vna_other == vers_data)
8951 break;
8952
8953 offset += ivn.vn_next;
8954 }
8955 while (ivn.vn_next != 0);
8956
8957 if (ivna.vna_other == vers_data)
8958 {
8959 printf ("@%s (%d)",
c256ffe7 8960 ivna.vna_name < strtab_size
2b692964 8961 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 8962 ivna.vna_other);
252b5132
RH
8963 check_def = 0;
8964 }
8965 else if (! is_nobits)
591a748a 8966 error (_("bad dynamic symbol\n"));
252b5132
RH
8967 else
8968 check_def = 1;
8969 }
8970
8971 if (check_def)
8972 {
00d93f34 8973 if (vers_data != 0x8001
b34976b6 8974 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8975 {
b34976b6
AM
8976 Elf_Internal_Verdef ivd;
8977 Elf_Internal_Verdaux ivda;
8978 Elf_External_Verdaux evda;
91d6fa6a 8979 unsigned long off;
252b5132 8980
91d6fa6a 8981 off = offset_from_vma
d93f0186
NC
8982 (file,
8983 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8984 sizeof (Elf_External_Verdef));
252b5132
RH
8985
8986 do
8987 {
b34976b6 8988 Elf_External_Verdef evd;
252b5132 8989
91d6fa6a 8990 get_data (&evd, file, off, sizeof (evd),
c256ffe7 8991 1, _("version def"));
252b5132 8992
b34976b6
AM
8993 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8994 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
8995 ivd.vd_next = BYTE_GET (evd.vd_next);
8996
91d6fa6a 8997 off += ivd.vd_next;
252b5132 8998 }
c244d050 8999 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9000 && ivd.vd_next != 0);
9001
91d6fa6a
NC
9002 off -= ivd.vd_next;
9003 off += ivd.vd_aux;
252b5132 9004
91d6fa6a 9005 get_data (&evda, file, off, sizeof (evda),
c256ffe7 9006 1, _("version def aux"));
252b5132
RH
9007
9008 ivda.vda_name = BYTE_GET (evda.vda_name);
9009
9010 if (psym->st_name != ivda.vda_name)
c244d050 9011 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9012 ? "@%s" : "@@%s",
c256ffe7 9013 ivda.vda_name < strtab_size
2b692964 9014 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9015 }
9016 }
9017 }
9018 }
9019
9020 putchar ('\n');
9021 }
9022
9023 free (symtab);
9024 if (strtab != string_table)
9025 free (strtab);
9026 }
9027 }
9028 else if (do_syms)
9029 printf
9030 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9031
9032 if (do_histogram && buckets != NULL)
9033 {
2cf0635d
NC
9034 unsigned long * lengths;
9035 unsigned long * counts;
66543521
AM
9036 unsigned long hn;
9037 bfd_vma si;
9038 unsigned long maxlength = 0;
9039 unsigned long nzero_counts = 0;
9040 unsigned long nsyms = 0;
252b5132 9041
66543521
AM
9042 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9043 (unsigned long) nbuckets);
252b5132
RH
9044 printf (_(" Length Number %% of total Coverage\n"));
9045
3f5e193b 9046 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9047 if (lengths == NULL)
9048 {
591a748a 9049 error (_("Out of memory\n"));
252b5132
RH
9050 return 0;
9051 }
9052 for (hn = 0; hn < nbuckets; ++hn)
9053 {
f7a99963 9054 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9055 {
b34976b6 9056 ++nsyms;
252b5132 9057 if (maxlength < ++lengths[hn])
b34976b6 9058 ++maxlength;
252b5132
RH
9059 }
9060 }
9061
3f5e193b 9062 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9063 if (counts == NULL)
9064 {
591a748a 9065 error (_("Out of memory\n"));
252b5132
RH
9066 return 0;
9067 }
9068
9069 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9070 ++counts[lengths[hn]];
252b5132 9071
103f02d3 9072 if (nbuckets > 0)
252b5132 9073 {
66543521
AM
9074 unsigned long i;
9075 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9076 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9077 for (i = 1; i <= maxlength; ++i)
103f02d3 9078 {
66543521
AM
9079 nzero_counts += counts[i] * i;
9080 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9081 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9082 (nzero_counts * 100.0) / nsyms);
9083 }
252b5132
RH
9084 }
9085
9086 free (counts);
9087 free (lengths);
9088 }
9089
9090 if (buckets != NULL)
9091 {
9092 free (buckets);
9093 free (chains);
9094 }
9095
d3a44ec6 9096 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9097 {
2cf0635d
NC
9098 unsigned long * lengths;
9099 unsigned long * counts;
fdc90cb4
JJ
9100 unsigned long hn;
9101 unsigned long maxlength = 0;
9102 unsigned long nzero_counts = 0;
9103 unsigned long nsyms = 0;
fdc90cb4 9104
3f5e193b 9105 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9106 if (lengths == NULL)
9107 {
591a748a 9108 error (_("Out of memory\n"));
fdc90cb4
JJ
9109 return 0;
9110 }
9111
9112 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9113 (unsigned long) ngnubuckets);
9114 printf (_(" Length Number %% of total Coverage\n"));
9115
9116 for (hn = 0; hn < ngnubuckets; ++hn)
9117 if (gnubuckets[hn] != 0)
9118 {
9119 bfd_vma off, length = 1;
9120
6bd1a22c 9121 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9122 (gnuchains[off] & 1) == 0; ++off)
9123 ++length;
9124 lengths[hn] = length;
9125 if (length > maxlength)
9126 maxlength = length;
9127 nsyms += length;
9128 }
9129
3f5e193b 9130 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9131 if (counts == NULL)
9132 {
591a748a 9133 error (_("Out of memory\n"));
fdc90cb4
JJ
9134 return 0;
9135 }
9136
9137 for (hn = 0; hn < ngnubuckets; ++hn)
9138 ++counts[lengths[hn]];
9139
9140 if (ngnubuckets > 0)
9141 {
9142 unsigned long j;
9143 printf (" 0 %-10lu (%5.1f%%)\n",
9144 counts[0], (counts[0] * 100.0) / ngnubuckets);
9145 for (j = 1; j <= maxlength; ++j)
9146 {
9147 nzero_counts += counts[j] * j;
9148 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9149 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9150 (nzero_counts * 100.0) / nsyms);
9151 }
9152 }
9153
9154 free (counts);
9155 free (lengths);
9156 free (gnubuckets);
9157 free (gnuchains);
9158 }
9159
252b5132
RH
9160 return 1;
9161}
9162
9163static int
2cf0635d 9164process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9165{
b4c96d0d 9166 unsigned int i;
252b5132
RH
9167
9168 if (dynamic_syminfo == NULL
9169 || !do_dynamic)
9170 /* No syminfo, this is ok. */
9171 return 1;
9172
9173 /* There better should be a dynamic symbol section. */
9174 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9175 return 0;
9176
9177 if (dynamic_addr)
9178 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9179 dynamic_syminfo_offset, dynamic_syminfo_nent);
9180
9181 printf (_(" Num: Name BoundTo Flags\n"));
9182 for (i = 0; i < dynamic_syminfo_nent; ++i)
9183 {
9184 unsigned short int flags = dynamic_syminfo[i].si_flags;
9185
31104126 9186 printf ("%4d: ", i);
d79b3d50
NC
9187 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9188 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9189 else
2b692964 9190 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9191 putchar (' ');
252b5132
RH
9192
9193 switch (dynamic_syminfo[i].si_boundto)
9194 {
9195 case SYMINFO_BT_SELF:
9196 fputs ("SELF ", stdout);
9197 break;
9198 case SYMINFO_BT_PARENT:
9199 fputs ("PARENT ", stdout);
9200 break;
9201 default:
9202 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9203 && dynamic_syminfo[i].si_boundto < dynamic_nent
9204 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9205 {
d79b3d50 9206 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9207 putchar (' ' );
9208 }
252b5132
RH
9209 else
9210 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9211 break;
9212 }
9213
9214 if (flags & SYMINFO_FLG_DIRECT)
9215 printf (" DIRECT");
9216 if (flags & SYMINFO_FLG_PASSTHRU)
9217 printf (" PASSTHRU");
9218 if (flags & SYMINFO_FLG_COPY)
9219 printf (" COPY");
9220 if (flags & SYMINFO_FLG_LAZYLOAD)
9221 printf (" LAZYLOAD");
9222
9223 puts ("");
9224 }
9225
9226 return 1;
9227}
9228
cf13d699
NC
9229/* Check to see if the given reloc needs to be handled in a target specific
9230 manner. If so then process the reloc and return TRUE otherwise return
9231 FALSE. */
09c11c86 9232
cf13d699
NC
9233static bfd_boolean
9234target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9235 unsigned char * start,
9236 Elf_Internal_Sym * symtab)
252b5132 9237{
cf13d699 9238 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9239
cf13d699 9240 switch (elf_header.e_machine)
252b5132 9241 {
cf13d699
NC
9242 case EM_MN10300:
9243 case EM_CYGNUS_MN10300:
9244 {
9245 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9246
cf13d699
NC
9247 switch (reloc_type)
9248 {
9249 case 34: /* R_MN10300_ALIGN */
9250 return TRUE;
9251 case 33: /* R_MN10300_SYM_DIFF */
9252 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9253 return TRUE;
9254 case 1: /* R_MN10300_32 */
9255 case 2: /* R_MN10300_16 */
9256 if (saved_sym != NULL)
9257 {
9258 bfd_vma value;
252b5132 9259
cf13d699
NC
9260 value = reloc->r_addend
9261 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9262 - saved_sym->st_value);
252b5132 9263
cf13d699 9264 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9265
cf13d699
NC
9266 saved_sym = NULL;
9267 return TRUE;
9268 }
9269 break;
9270 default:
9271 if (saved_sym != NULL)
9272 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9273 break;
9274 }
9275 break;
9276 }
252b5132
RH
9277 }
9278
cf13d699 9279 return FALSE;
252b5132
RH
9280}
9281
aca88567
NC
9282/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9283 DWARF debug sections. This is a target specific test. Note - we do not
9284 go through the whole including-target-headers-multiple-times route, (as
9285 we have already done with <elf/h8.h>) because this would become very
9286 messy and even then this function would have to contain target specific
9287 information (the names of the relocs instead of their numeric values).
9288 FIXME: This is not the correct way to solve this problem. The proper way
9289 is to have target specific reloc sizing and typing functions created by
9290 the reloc-macros.h header, in the same way that it already creates the
9291 reloc naming functions. */
9292
9293static bfd_boolean
9294is_32bit_abs_reloc (unsigned int reloc_type)
9295{
9296 switch (elf_header.e_machine)
9297 {
41e92641
NC
9298 case EM_386:
9299 case EM_486:
9300 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9301 case EM_68K:
9302 return reloc_type == 1; /* R_68K_32. */
9303 case EM_860:
9304 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9305 case EM_960:
9306 return reloc_type == 2; /* R_960_32. */
aca88567 9307 case EM_ALPHA:
137b6b5f 9308 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
9309 case EM_ARC:
9310 return reloc_type == 1; /* R_ARC_32. */
9311 case EM_ARM:
9312 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 9313 case EM_AVR_OLD:
aca88567
NC
9314 case EM_AVR:
9315 return reloc_type == 1;
9316 case EM_BLACKFIN:
9317 return reloc_type == 0x12; /* R_byte4_data. */
9318 case EM_CRIS:
9319 return reloc_type == 3; /* R_CRIS_32. */
9320 case EM_CR16:
6c03b1ed 9321 case EM_CR16_OLD:
aca88567
NC
9322 return reloc_type == 3; /* R_CR16_NUM32. */
9323 case EM_CRX:
9324 return reloc_type == 15; /* R_CRX_NUM32. */
9325 case EM_CYGNUS_FRV:
9326 return reloc_type == 1;
41e92641
NC
9327 case EM_CYGNUS_D10V:
9328 case EM_D10V:
9329 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
9330 case EM_CYGNUS_D30V:
9331 case EM_D30V:
9332 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
9333 case EM_DLX:
9334 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
9335 case EM_CYGNUS_FR30:
9336 case EM_FR30:
9337 return reloc_type == 3; /* R_FR30_32. */
9338 case EM_H8S:
9339 case EM_H8_300:
9340 case EM_H8_300H:
9341 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
9342 case EM_IA_64:
9343 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
9344 case EM_IP2K_OLD:
9345 case EM_IP2K:
9346 return reloc_type == 2; /* R_IP2K_32. */
9347 case EM_IQ2000:
9348 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
9349 case EM_LATTICEMICO32:
9350 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 9351 case EM_M32C_OLD:
aca88567
NC
9352 case EM_M32C:
9353 return reloc_type == 3; /* R_M32C_32. */
9354 case EM_M32R:
9355 return reloc_type == 34; /* R_M32R_32_RELA. */
9356 case EM_MCORE:
9357 return reloc_type == 1; /* R_MCORE_ADDR32. */
9358 case EM_CYGNUS_MEP:
9359 return reloc_type == 4; /* R_MEP_32. */
137b6b5f
AM
9360 case EM_MICROBLAZE:
9361 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
9362 case EM_MIPS:
9363 return reloc_type == 2; /* R_MIPS_32. */
9364 case EM_MMIX:
9365 return reloc_type == 4; /* R_MMIX_32. */
9366 case EM_CYGNUS_MN10200:
9367 case EM_MN10200:
9368 return reloc_type == 1; /* R_MN10200_32. */
9369 case EM_CYGNUS_MN10300:
9370 case EM_MN10300:
9371 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
9372 case EM_MOXIE:
9373 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
9374 case EM_MSP430_OLD:
9375 case EM_MSP430:
9376 return reloc_type == 1; /* R_MSP43_32. */
9377 case EM_MT:
9378 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
9379 case EM_ALTERA_NIOS2:
9380 case EM_NIOS32:
9381 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
9382 case EM_OPENRISC:
9383 case EM_OR32:
9384 return reloc_type == 1; /* R_OR32_32. */
aca88567 9385 case EM_PARISC:
5fda8eca
NC
9386 return (reloc_type == 1 /* R_PARISC_DIR32. */
9387 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
9388 case EM_PJ:
9389 case EM_PJ_OLD:
9390 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
9391 case EM_PPC64:
9392 return reloc_type == 1; /* R_PPC64_ADDR32. */
9393 case EM_PPC:
9394 return reloc_type == 1; /* R_PPC_ADDR32. */
c7927a3c
NC
9395 case EM_RX:
9396 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
9397 case EM_S370:
9398 return reloc_type == 1; /* R_I370_ADDR31. */
9399 case EM_S390_OLD:
9400 case EM_S390:
9401 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
9402 case EM_SCORE:
9403 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
9404 case EM_SH:
9405 return reloc_type == 1; /* R_SH_DIR32. */
9406 case EM_SPARC32PLUS:
9407 case EM_SPARCV9:
9408 case EM_SPARC:
9409 return reloc_type == 3 /* R_SPARC_32. */
9410 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
9411 case EM_SPU:
9412 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
9413 case EM_TI_C6000:
9414 return reloc_type == 1; /* R_C6000_ABS32. */
aca88567
NC
9415 case EM_CYGNUS_V850:
9416 case EM_V850:
9417 return reloc_type == 6; /* R_V850_ABS32. */
9418 case EM_VAX:
9419 return reloc_type == 1; /* R_VAX_32. */
9420 case EM_X86_64:
8a9036a4 9421 case EM_L1OM:
aca88567 9422 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
9423 case EM_XC16X:
9424 case EM_C166:
9425 return reloc_type == 3; /* R_XC16C_ABS_32. */
aca88567
NC
9426 case EM_XSTORMY16:
9427 return reloc_type == 1; /* R_XSTROMY16_32. */
9428 case EM_XTENSA_OLD:
9429 case EM_XTENSA:
9430 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
9431 default:
9432 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
9433 elf_header.e_machine);
9434 abort ();
9435 }
9436}
9437
9438/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9439 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
9440
9441static bfd_boolean
9442is_32bit_pcrel_reloc (unsigned int reloc_type)
9443{
9444 switch (elf_header.e_machine)
9445 {
41e92641
NC
9446 case EM_386:
9447 case EM_486:
3e0873ac 9448 return reloc_type == 2; /* R_386_PC32. */
aca88567 9449 case EM_68K:
3e0873ac 9450 return reloc_type == 4; /* R_68K_PC32. */
aca88567
NC
9451 case EM_ALPHA:
9452 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 9453 case EM_ARM:
3e0873ac 9454 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
9455 case EM_MICROBLAZE:
9456 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 9457 case EM_PARISC:
85acf597 9458 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
9459 case EM_PPC:
9460 return reloc_type == 26; /* R_PPC_REL32. */
9461 case EM_PPC64:
3e0873ac 9462 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
9463 case EM_S390_OLD:
9464 case EM_S390:
3e0873ac 9465 return reloc_type == 5; /* R_390_PC32. */
aca88567 9466 case EM_SH:
3e0873ac 9467 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
9468 case EM_SPARC32PLUS:
9469 case EM_SPARCV9:
9470 case EM_SPARC:
3e0873ac 9471 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
9472 case EM_SPU:
9473 return reloc_type == 13; /* R_SPU_REL32. */
aca88567 9474 case EM_X86_64:
8a9036a4 9475 case EM_L1OM:
3e0873ac 9476 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
9477 case EM_XTENSA_OLD:
9478 case EM_XTENSA:
9479 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
9480 default:
9481 /* Do not abort or issue an error message here. Not all targets use
9482 pc-relative 32-bit relocs in their DWARF debug information and we
9483 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
9484 more helpful warning message will be generated by apply_relocations
9485 anyway, so just return. */
aca88567
NC
9486 return FALSE;
9487 }
9488}
9489
9490/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9491 a 64-bit absolute RELA relocation used in DWARF debug sections. */
9492
9493static bfd_boolean
9494is_64bit_abs_reloc (unsigned int reloc_type)
9495{
9496 switch (elf_header.e_machine)
9497 {
9498 case EM_ALPHA:
9499 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
9500 case EM_IA_64:
9501 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
9502 case EM_PARISC:
9503 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
9504 case EM_PPC64:
9505 return reloc_type == 38; /* R_PPC64_ADDR64. */
9506 case EM_SPARC32PLUS:
9507 case EM_SPARCV9:
9508 case EM_SPARC:
9509 return reloc_type == 54; /* R_SPARC_UA64. */
9510 case EM_X86_64:
8a9036a4 9511 case EM_L1OM:
aca88567 9512 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
9513 case EM_S390_OLD:
9514 case EM_S390:
9515 return reloc_type == 22; /* R_S390_64 */
85a82265
AM
9516 case EM_MIPS:
9517 return reloc_type == 18; /* R_MIPS_64 */
aca88567
NC
9518 default:
9519 return FALSE;
9520 }
9521}
9522
85acf597
RH
9523/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
9524 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
9525
9526static bfd_boolean
9527is_64bit_pcrel_reloc (unsigned int reloc_type)
9528{
9529 switch (elf_header.e_machine)
9530 {
9531 case EM_ALPHA:
9532 return reloc_type == 11; /* R_ALPHA_SREL64 */
9533 case EM_IA_64:
9534 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB */
9535 case EM_PARISC:
9536 return reloc_type == 72; /* R_PARISC_PCREL64 */
9537 case EM_PPC64:
9538 return reloc_type == 44; /* R_PPC64_REL64 */
9539 case EM_SPARC32PLUS:
9540 case EM_SPARCV9:
9541 case EM_SPARC:
9542 return reloc_type == 46; /* R_SPARC_DISP64 */
9543 case EM_X86_64:
8a9036a4 9544 case EM_L1OM:
85acf597
RH
9545 return reloc_type == 24; /* R_X86_64_PC64 */
9546 case EM_S390_OLD:
9547 case EM_S390:
9548 return reloc_type == 23; /* R_S390_PC64 */
9549 default:
9550 return FALSE;
9551 }
9552}
9553
4dc3c23d
AM
9554/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9555 a 24-bit absolute RELA relocation used in DWARF debug sections. */
9556
9557static bfd_boolean
9558is_24bit_abs_reloc (unsigned int reloc_type)
9559{
9560 switch (elf_header.e_machine)
9561 {
9562 case EM_CYGNUS_MN10200:
9563 case EM_MN10200:
9564 return reloc_type == 4; /* R_MN10200_24. */
9565 default:
9566 return FALSE;
9567 }
9568}
9569
aca88567
NC
9570/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9571 a 16-bit absolute RELA relocation used in DWARF debug sections. */
9572
9573static bfd_boolean
9574is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
9575{
9576 switch (elf_header.e_machine)
9577 {
aca88567
NC
9578 case EM_AVR_OLD:
9579 case EM_AVR:
9580 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
9581 case EM_CYGNUS_D10V:
9582 case EM_D10V:
9583 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
9584 case EM_H8S:
9585 case EM_H8_300:
9586 case EM_H8_300H:
aca88567
NC
9587 return reloc_type == R_H8_DIR16;
9588 case EM_IP2K_OLD:
9589 case EM_IP2K:
9590 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 9591 case EM_M32C_OLD:
f4236fe4
DD
9592 case EM_M32C:
9593 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
9594 case EM_MSP430_OLD:
9595 case EM_MSP430:
9596 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
9597 case EM_ALTERA_NIOS2:
9598 case EM_NIOS32:
9599 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
9600 case EM_TI_C6000:
9601 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
9602 case EM_XC16X:
9603 case EM_C166:
9604 return reloc_type == 2; /* R_XC16C_ABS_16. */
4b78141a 9605 default:
aca88567 9606 return FALSE;
4b78141a
NC
9607 }
9608}
9609
2a7b2e88
JK
9610/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
9611 relocation entries (possibly formerly used for SHT_GROUP sections). */
9612
9613static bfd_boolean
9614is_none_reloc (unsigned int reloc_type)
9615{
9616 switch (elf_header.e_machine)
9617 {
cb8f3167
NC
9618 case EM_68K: /* R_68K_NONE. */
9619 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
9620 case EM_SPARC32PLUS:
9621 case EM_SPARCV9:
cb8f3167
NC
9622 case EM_SPARC: /* R_SPARC_NONE. */
9623 case EM_MIPS: /* R_MIPS_NONE. */
9624 case EM_PARISC: /* R_PARISC_NONE. */
9625 case EM_ALPHA: /* R_ALPHA_NONE. */
9626 case EM_PPC: /* R_PPC_NONE. */
9627 case EM_PPC64: /* R_PPC64_NONE. */
9628 case EM_ARM: /* R_ARM_NONE. */
9629 case EM_IA_64: /* R_IA64_NONE. */
9630 case EM_SH: /* R_SH_NONE. */
2a7b2e88 9631 case EM_S390_OLD:
cb8f3167
NC
9632 case EM_S390: /* R_390_NONE. */
9633 case EM_CRIS: /* R_CRIS_NONE. */
9634 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 9635 case EM_L1OM: /* R_X86_64_NONE. */
cb8f3167 9636 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 9637 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 9638 case EM_M32R: /* R_M32R_NONE. */
40b36596 9639 case EM_TI_C6000:/* R_C6000_NONE. */
c29aca4a
NC
9640 case EM_XC16X:
9641 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 9642 return reloc_type == 0;
58332dda
JK
9643 case EM_XTENSA_OLD:
9644 case EM_XTENSA:
4dc3c23d
AM
9645 return (reloc_type == 0 /* R_XTENSA_NONE. */
9646 || reloc_type == 17 /* R_XTENSA_DIFF8. */
9647 || reloc_type == 18 /* R_XTENSA_DIFF16. */
9648 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
9649 }
9650 return FALSE;
9651}
9652
cf13d699
NC
9653/* Apply relocations to a section.
9654 Note: So far support has been added only for those relocations
9655 which can be found in debug sections.
9656 FIXME: Add support for more relocations ? */
1b315056 9657
cf13d699
NC
9658static void
9659apply_relocations (void * file,
9660 Elf_Internal_Shdr * section,
9661 unsigned char * start)
1b315056 9662{
cf13d699
NC
9663 Elf_Internal_Shdr * relsec;
9664 unsigned char * end = start + section->sh_size;
cb8f3167 9665
cf13d699
NC
9666 if (elf_header.e_type != ET_REL)
9667 return;
1b315056 9668
cf13d699 9669 /* Find the reloc section associated with the section. */
5b18a4bc
NC
9670 for (relsec = section_headers;
9671 relsec < section_headers + elf_header.e_shnum;
9672 ++relsec)
252b5132 9673 {
41e92641
NC
9674 bfd_boolean is_rela;
9675 unsigned long num_relocs;
2cf0635d
NC
9676 Elf_Internal_Rela * relocs;
9677 Elf_Internal_Rela * rp;
9678 Elf_Internal_Shdr * symsec;
9679 Elf_Internal_Sym * symtab;
9680 Elf_Internal_Sym * sym;
252b5132 9681
41e92641 9682 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
9683 || relsec->sh_info >= elf_header.e_shnum
9684 || section_headers + relsec->sh_info != section
c256ffe7 9685 || relsec->sh_size == 0
4fbb74a6 9686 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 9687 continue;
428409d5 9688
41e92641
NC
9689 is_rela = relsec->sh_type == SHT_RELA;
9690
9691 if (is_rela)
9692 {
3f5e193b
NC
9693 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
9694 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
9695 return;
9696 }
9697 else
9698 {
3f5e193b
NC
9699 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
9700 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
9701 return;
9702 }
9703
9704 /* SH uses RELA but uses in place value instead of the addend field. */
9705 if (elf_header.e_machine == EM_SH)
9706 is_rela = FALSE;
428409d5 9707
4fbb74a6 9708 symsec = section_headers + relsec->sh_link;
3f5e193b 9709 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
103f02d3 9710
41e92641 9711 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 9712 {
41e92641
NC
9713 bfd_vma addend;
9714 unsigned int reloc_type;
9715 unsigned int reloc_size;
91d6fa6a 9716 unsigned char * rloc;
4b78141a 9717
aca88567 9718 reloc_type = get_reloc_type (rp->r_info);
41e92641 9719
98fb390a 9720 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 9721 continue;
98fb390a
NC
9722 else if (is_none_reloc (reloc_type))
9723 continue;
9724 else if (is_32bit_abs_reloc (reloc_type)
9725 || is_32bit_pcrel_reloc (reloc_type))
aca88567 9726 reloc_size = 4;
85acf597
RH
9727 else if (is_64bit_abs_reloc (reloc_type)
9728 || is_64bit_pcrel_reloc (reloc_type))
aca88567 9729 reloc_size = 8;
4dc3c23d
AM
9730 else if (is_24bit_abs_reloc (reloc_type))
9731 reloc_size = 3;
aca88567
NC
9732 else if (is_16bit_abs_reloc (reloc_type))
9733 reloc_size = 2;
9734 else
4b78141a 9735 {
41e92641 9736 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 9737 reloc_type, SECTION_NAME (section));
4b78141a
NC
9738 continue;
9739 }
103f02d3 9740
91d6fa6a
NC
9741 rloc = start + rp->r_offset;
9742 if ((rloc + reloc_size) > end)
700dd8b7
L
9743 {
9744 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
9745 (unsigned long) rp->r_offset,
9746 SECTION_NAME (section));
9747 continue;
9748 }
103f02d3 9749
41e92641
NC
9750 sym = symtab + get_reloc_symindex (rp->r_info);
9751
9752 /* If the reloc has a symbol associated with it,
55f25fc3
L
9753 make sure that it is of an appropriate type.
9754
9755 Relocations against symbols without type can happen.
9756 Gcc -feliminate-dwarf2-dups may generate symbols
9757 without type for debug info.
9758
9759 Icc generates relocations against function symbols
9760 instead of local labels.
9761
9762 Relocations against object symbols can happen, eg when
9763 referencing a global array. For an example of this see
9764 the _clz.o binary in libgcc.a. */
aca88567 9765 if (sym != symtab
55f25fc3 9766 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 9767 {
41e92641 9768 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 9769 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 9770 (long int)(rp - relocs),
41e92641 9771 SECTION_NAME (relsec));
aca88567 9772 continue;
5b18a4bc 9773 }
252b5132 9774
4dc3c23d
AM
9775 addend = 0;
9776 if (is_rela)
9777 addend += rp->r_addend;
c47320c3
AM
9778 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
9779 partial_inplace. */
4dc3c23d
AM
9780 if (!is_rela
9781 || (elf_header.e_machine == EM_XTENSA
9782 && reloc_type == 1)
9783 || ((elf_header.e_machine == EM_PJ
9784 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
9785 && reloc_type == 1)
9786 || ((elf_header.e_machine == EM_D30V
9787 || elf_header.e_machine == EM_CYGNUS_D30V)
9788 && reloc_type == 12))
91d6fa6a 9789 addend += byte_get (rloc, reloc_size);
cb8f3167 9790
85acf597
RH
9791 if (is_32bit_pcrel_reloc (reloc_type)
9792 || is_64bit_pcrel_reloc (reloc_type))
9793 {
9794 /* On HPPA, all pc-relative relocations are biased by 8. */
9795 if (elf_header.e_machine == EM_PARISC)
9796 addend -= 8;
91d6fa6a 9797 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
9798 reloc_size);
9799 }
41e92641 9800 else
91d6fa6a 9801 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 9802 }
252b5132 9803
5b18a4bc 9804 free (symtab);
41e92641 9805 free (relocs);
5b18a4bc
NC
9806 break;
9807 }
5b18a4bc 9808}
103f02d3 9809
cf13d699
NC
9810#ifdef SUPPORT_DISASSEMBLY
9811static int
9812disassemble_section (Elf_Internal_Shdr * section, FILE * file)
9813{
9814 printf (_("\nAssembly dump of section %s\n"),
9815 SECTION_NAME (section));
9816
9817 /* XXX -- to be done --- XXX */
9818
9819 return 1;
9820}
9821#endif
9822
9823/* Reads in the contents of SECTION from FILE, returning a pointer
9824 to a malloc'ed buffer or NULL if something went wrong. */
9825
9826static char *
9827get_section_contents (Elf_Internal_Shdr * section, FILE * file)
9828{
9829 bfd_size_type num_bytes;
9830
9831 num_bytes = section->sh_size;
9832
9833 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
9834 {
9835 printf (_("\nSection '%s' has no data to dump.\n"),
9836 SECTION_NAME (section));
9837 return NULL;
9838 }
9839
3f5e193b
NC
9840 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
9841 _("section contents"));
cf13d699
NC
9842}
9843
dd24e3da 9844
cf13d699
NC
9845static void
9846dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
9847{
9848 Elf_Internal_Shdr * relsec;
9849 bfd_size_type num_bytes;
cf13d699
NC
9850 char * data;
9851 char * end;
9852 char * start;
9853 char * name = SECTION_NAME (section);
9854 bfd_boolean some_strings_shown;
9855
9856 start = get_section_contents (section, file);
9857 if (start == NULL)
9858 return;
9859
9860 printf (_("\nString dump of section '%s':\n"), name);
9861
9862 /* If the section being dumped has relocations against it the user might
9863 be expecting these relocations to have been applied. Check for this
9864 case and issue a warning message in order to avoid confusion.
9865 FIXME: Maybe we ought to have an option that dumps a section with
9866 relocs applied ? */
9867 for (relsec = section_headers;
9868 relsec < section_headers + elf_header.e_shnum;
9869 ++relsec)
9870 {
9871 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
9872 || relsec->sh_info >= elf_header.e_shnum
9873 || section_headers + relsec->sh_info != section
9874 || relsec->sh_size == 0
9875 || relsec->sh_link >= elf_header.e_shnum)
9876 continue;
9877
9878 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
9879 break;
9880 }
9881
9882 num_bytes = section->sh_size;
cf13d699
NC
9883 data = start;
9884 end = start + num_bytes;
9885 some_strings_shown = FALSE;
9886
9887 while (data < end)
9888 {
9889 while (!ISPRINT (* data))
9890 if (++ data >= end)
9891 break;
9892
9893 if (data < end)
9894 {
9895#ifndef __MSVCRT__
c975cc98
NC
9896 /* PR 11128: Use two separate invocations in order to work
9897 around bugs in the Solaris 8 implementation of printf. */
9898 printf (" [%6tx] ", data - start);
9899 printf ("%s\n", data);
cf13d699
NC
9900#else
9901 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
9902#endif
9903 data += strlen (data);
9904 some_strings_shown = TRUE;
9905 }
9906 }
9907
9908 if (! some_strings_shown)
9909 printf (_(" No strings found in this section."));
9910
9911 free (start);
9912
9913 putchar ('\n');
9914}
9915
9916static void
9917dump_section_as_bytes (Elf_Internal_Shdr * section,
9918 FILE * file,
9919 bfd_boolean relocate)
9920{
9921 Elf_Internal_Shdr * relsec;
9922 bfd_size_type bytes;
9923 bfd_vma addr;
9924 unsigned char * data;
9925 unsigned char * start;
9926
9927 start = (unsigned char *) get_section_contents (section, file);
9928 if (start == NULL)
9929 return;
9930
9931 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
9932
9933 if (relocate)
9934 {
9935 apply_relocations (file, section, start);
9936 }
9937 else
9938 {
9939 /* If the section being dumped has relocations against it the user might
9940 be expecting these relocations to have been applied. Check for this
9941 case and issue a warning message in order to avoid confusion.
9942 FIXME: Maybe we ought to have an option that dumps a section with
9943 relocs applied ? */
9944 for (relsec = section_headers;
9945 relsec < section_headers + elf_header.e_shnum;
9946 ++relsec)
9947 {
9948 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
9949 || relsec->sh_info >= elf_header.e_shnum
9950 || section_headers + relsec->sh_info != section
9951 || relsec->sh_size == 0
9952 || relsec->sh_link >= elf_header.e_shnum)
9953 continue;
9954
9955 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
9956 break;
9957 }
9958 }
9959
9960 addr = section->sh_addr;
9961 bytes = section->sh_size;
9962 data = start;
9963
9964 while (bytes)
9965 {
9966 int j;
9967 int k;
9968 int lbytes;
9969
9970 lbytes = (bytes > 16 ? 16 : bytes);
9971
9972 printf (" 0x%8.8lx ", (unsigned long) addr);
9973
9974 for (j = 0; j < 16; j++)
9975 {
9976 if (j < lbytes)
9977 printf ("%2.2x", data[j]);
9978 else
9979 printf (" ");
9980
9981 if ((j & 3) == 3)
9982 printf (" ");
9983 }
9984
9985 for (j = 0; j < lbytes; j++)
9986 {
9987 k = data[j];
9988 if (k >= ' ' && k < 0x7f)
9989 printf ("%c", k);
9990 else
9991 printf (".");
9992 }
9993
9994 putchar ('\n');
9995
9996 data += lbytes;
9997 addr += lbytes;
9998 bytes -= lbytes;
9999 }
10000
10001 free (start);
10002
10003 putchar ('\n');
10004}
10005
4a114e3e 10006/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10007
10008static int
d3dbc530
AM
10009uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10010 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10011{
10012#ifndef HAVE_ZLIB_H
cf13d699
NC
10013 return FALSE;
10014#else
10015 dwarf_size_type compressed_size = *size;
10016 unsigned char * compressed_buffer = *buffer;
10017 dwarf_size_type uncompressed_size;
10018 unsigned char * uncompressed_buffer;
10019 z_stream strm;
10020 int rc;
10021 dwarf_size_type header_size = 12;
10022
10023 /* Read the zlib header. In this case, it should be "ZLIB" followed
10024 by the uncompressed section size, 8 bytes in big-endian order. */
10025 if (compressed_size < header_size
10026 || ! streq ((char *) compressed_buffer, "ZLIB"))
10027 return 0;
10028
10029 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10030 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10031 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10032 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10033 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10034 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10035 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10036 uncompressed_size += compressed_buffer[11];
10037
10038 /* It is possible the section consists of several compressed
10039 buffers concatenated together, so we uncompress in a loop. */
10040 strm.zalloc = NULL;
10041 strm.zfree = NULL;
10042 strm.opaque = NULL;
10043 strm.avail_in = compressed_size - header_size;
10044 strm.next_in = (Bytef *) compressed_buffer + header_size;
10045 strm.avail_out = uncompressed_size;
3f5e193b 10046 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10047
10048 rc = inflateInit (& strm);
10049 while (strm.avail_in > 0)
10050 {
10051 if (rc != Z_OK)
10052 goto fail;
10053 strm.next_out = ((Bytef *) uncompressed_buffer
10054 + (uncompressed_size - strm.avail_out));
10055 rc = inflate (&strm, Z_FINISH);
10056 if (rc != Z_STREAM_END)
10057 goto fail;
10058 rc = inflateReset (& strm);
10059 }
10060 rc = inflateEnd (& strm);
10061 if (rc != Z_OK
10062 || strm.avail_out != 0)
10063 goto fail;
10064
10065 free (compressed_buffer);
10066 *buffer = uncompressed_buffer;
10067 *size = uncompressed_size;
10068 return 1;
10069
10070 fail:
10071 free (uncompressed_buffer);
4a114e3e
L
10072 /* Indicate decompression failure. */
10073 *buffer = NULL;
cf13d699
NC
10074 return 0;
10075#endif /* HAVE_ZLIB_H */
10076}
10077
d966045b
DJ
10078static int
10079load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10080 Elf_Internal_Shdr * sec, void * file)
1007acb3 10081{
2cf0635d 10082 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10083 char buf [64];
1007acb3 10084
19e6b90e
L
10085 /* If it is already loaded, do nothing. */
10086 if (section->start != NULL)
10087 return 1;
1007acb3 10088
19e6b90e
L
10089 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10090 section->address = sec->sh_addr;
10091 section->size = sec->sh_size;
3f5e193b
NC
10092 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10093 sec->sh_offset, 1,
10094 sec->sh_size, buf);
4a114e3e
L
10095 if (uncompress_section_contents (&section->start, &section->size))
10096 sec->sh_size = section->size;
10097
1b315056
CS
10098 if (section->start == NULL)
10099 return 0;
10100
19e6b90e 10101 if (debug_displays [debug].relocate)
3f5e193b 10102 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10103
1b315056 10104 return 1;
1007acb3
L
10105}
10106
d966045b 10107int
2cf0635d 10108load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10109{
2cf0635d
NC
10110 struct dwarf_section * section = &debug_displays [debug].section;
10111 Elf_Internal_Shdr * sec;
d966045b
DJ
10112
10113 /* Locate the debug section. */
10114 sec = find_section (section->uncompressed_name);
10115 if (sec != NULL)
10116 section->name = section->uncompressed_name;
10117 else
10118 {
10119 sec = find_section (section->compressed_name);
10120 if (sec != NULL)
10121 section->name = section->compressed_name;
10122 }
10123 if (sec == NULL)
10124 return 0;
10125
3f5e193b 10126 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10127}
10128
19e6b90e
L
10129void
10130free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10131{
2cf0635d 10132 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10133
19e6b90e
L
10134 if (section->start == NULL)
10135 return;
1007acb3 10136
19e6b90e
L
10137 free ((char *) section->start);
10138 section->start = NULL;
10139 section->address = 0;
10140 section->size = 0;
1007acb3
L
10141}
10142
1007acb3 10143static int
2cf0635d 10144display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 10145{
2cf0635d 10146 char * name = SECTION_NAME (section);
19e6b90e
L
10147 bfd_size_type length;
10148 int result = 1;
3f5e193b 10149 int i;
1007acb3 10150
19e6b90e
L
10151 length = section->sh_size;
10152 if (length == 0)
1007acb3 10153 {
19e6b90e
L
10154 printf (_("\nSection '%s' has no debugging data.\n"), name);
10155 return 0;
1007acb3 10156 }
5dff79d8
NC
10157 if (section->sh_type == SHT_NOBITS)
10158 {
10159 /* There is no point in dumping the contents of a debugging section
10160 which has the NOBITS type - the bits in the file will be random.
10161 This can happen when a file containing a .eh_frame section is
10162 stripped with the --only-keep-debug command line option. */
10163 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10164 return 0;
10165 }
1007acb3 10166
0112cd26 10167 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10168 name = ".debug_info";
1007acb3 10169
19e6b90e
L
10170 /* See if we know how to display the contents of this section. */
10171 for (i = 0; i < max; i++)
1b315056
CS
10172 if (streq (debug_displays[i].section.uncompressed_name, name)
10173 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10174 {
2cf0635d 10175 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10176 int secondary = (section != find_section (name));
10177
10178 if (secondary)
3f5e193b 10179 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10180
2b6f5997 10181 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10182 sec->name = sec->uncompressed_name;
10183 else
10184 sec->name = sec->compressed_name;
3f5e193b
NC
10185 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10186 section, file))
19e6b90e
L
10187 {
10188 result &= debug_displays[i].display (sec, file);
1007acb3 10189
d966045b 10190 if (secondary || (i != info && i != abbrev))
3f5e193b 10191 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10192 }
1007acb3 10193
19e6b90e
L
10194 break;
10195 }
1007acb3 10196
19e6b90e 10197 if (i == max)
1007acb3 10198 {
19e6b90e
L
10199 printf (_("Unrecognized debug section: %s\n"), name);
10200 result = 0;
1007acb3
L
10201 }
10202
19e6b90e 10203 return result;
5b18a4bc 10204}
103f02d3 10205
aef1f6d0
DJ
10206/* Set DUMP_SECTS for all sections where dumps were requested
10207 based on section name. */
10208
10209static void
10210initialise_dumps_byname (void)
10211{
2cf0635d 10212 struct dump_list_entry * cur;
aef1f6d0
DJ
10213
10214 for (cur = dump_sects_byname; cur; cur = cur->next)
10215 {
10216 unsigned int i;
10217 int any;
10218
10219 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10220 if (streq (SECTION_NAME (section_headers + i), cur->name))
10221 {
09c11c86 10222 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10223 any = 1;
10224 }
10225
10226 if (!any)
10227 warn (_("Section '%s' was not dumped because it does not exist!\n"),
10228 cur->name);
10229 }
10230}
10231
5b18a4bc 10232static void
2cf0635d 10233process_section_contents (FILE * file)
5b18a4bc 10234{
2cf0635d 10235 Elf_Internal_Shdr * section;
19e6b90e 10236 unsigned int i;
103f02d3 10237
19e6b90e
L
10238 if (! do_dump)
10239 return;
103f02d3 10240
aef1f6d0
DJ
10241 initialise_dumps_byname ();
10242
19e6b90e
L
10243 for (i = 0, section = section_headers;
10244 i < elf_header.e_shnum && i < num_dump_sects;
10245 i++, section++)
10246 {
10247#ifdef SUPPORT_DISASSEMBLY
10248 if (dump_sects[i] & DISASS_DUMP)
10249 disassemble_section (section, file);
10250#endif
10251 if (dump_sects[i] & HEX_DUMP)
cf13d699 10252 dump_section_as_bytes (section, file, FALSE);
103f02d3 10253
cf13d699
NC
10254 if (dump_sects[i] & RELOC_DUMP)
10255 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
10256
10257 if (dump_sects[i] & STRING_DUMP)
10258 dump_section_as_strings (section, file);
cf13d699
NC
10259
10260 if (dump_sects[i] & DEBUG_DUMP)
10261 display_debug_section (section, file);
5b18a4bc 10262 }
103f02d3 10263
19e6b90e
L
10264 /* Check to see if the user requested a
10265 dump of a section that does not exist. */
10266 while (i++ < num_dump_sects)
10267 if (dump_sects[i])
10268 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 10269}
103f02d3 10270
5b18a4bc 10271static void
19e6b90e 10272process_mips_fpe_exception (int mask)
5b18a4bc 10273{
19e6b90e
L
10274 if (mask)
10275 {
10276 int first = 1;
10277 if (mask & OEX_FPU_INEX)
10278 fputs ("INEX", stdout), first = 0;
10279 if (mask & OEX_FPU_UFLO)
10280 printf ("%sUFLO", first ? "" : "|"), first = 0;
10281 if (mask & OEX_FPU_OFLO)
10282 printf ("%sOFLO", first ? "" : "|"), first = 0;
10283 if (mask & OEX_FPU_DIV0)
10284 printf ("%sDIV0", first ? "" : "|"), first = 0;
10285 if (mask & OEX_FPU_INVAL)
10286 printf ("%sINVAL", first ? "" : "|");
10287 }
5b18a4bc 10288 else
19e6b90e 10289 fputs ("0", stdout);
5b18a4bc 10290}
103f02d3 10291
11c1ff18
PB
10292/* ARM EABI attributes section. */
10293typedef struct
10294{
10295 int tag;
2cf0635d 10296 const char * name;
11c1ff18
PB
10297 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
10298 int type;
2cf0635d 10299 const char ** table;
11c1ff18
PB
10300} arm_attr_public_tag;
10301
2cf0635d 10302static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 10303 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
9e3c6df6 10304 "v6K", "v7", "v6-M", "v6S-M", "v7E-M"};
2cf0635d
NC
10305static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
10306static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 10307 {"No", "Thumb-1", "Thumb-2"};
75375b3e 10308static const char * arm_attr_tag_FP_arch[] =
62f3b8c8 10309 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
2cf0635d 10310static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 10311static const char * arm_attr_tag_Advanced_SIMD_arch[] =
cd21e546 10312 {"No", "NEONv1", "NEONv1 with Fused-MAC"};
2cf0635d 10313static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
10314 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
10315 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 10316static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 10317 {"V6", "SB", "TLS", "Unused"};
2cf0635d 10318static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 10319 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 10320static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 10321 {"Absolute", "PC-relative", "None"};
2cf0635d 10322static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 10323 {"None", "direct", "GOT-indirect"};
2cf0635d 10324static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 10325 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
10326static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
10327static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 10328 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
10329static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
10330static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
10331static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 10332 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 10333static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 10334 {"Unused", "small", "int", "forced to int"};
2cf0635d 10335static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 10336 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 10337static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 10338 {"AAPCS", "VFP registers", "custom"};
2cf0635d 10339static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 10340 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 10341static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
10342 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10343 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 10344static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
10345 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10346 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 10347static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 10348static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 10349 {"Not Allowed", "Allowed"};
2cf0635d 10350static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 10351 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 10352static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
10353 {"Not Allowed", "Allowed"};
10354static const char * arm_attr_tag_DIV_use[] =
dd24e3da 10355 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 10356 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
10357static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
10358static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 10359 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 10360 "TrustZone and Virtualization Extensions"};
dd24e3da 10361static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 10362 {"Not Allowed", "Allowed"};
11c1ff18
PB
10363
10364#define LOOKUP(id, name) \
10365 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 10366static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
10367{
10368 {4, "CPU_raw_name", 1, NULL},
10369 {5, "CPU_name", 1, NULL},
10370 LOOKUP(6, CPU_arch),
10371 {7, "CPU_arch_profile", 0, NULL},
10372 LOOKUP(8, ARM_ISA_use),
10373 LOOKUP(9, THUMB_ISA_use),
75375b3e 10374 LOOKUP(10, FP_arch),
11c1ff18 10375 LOOKUP(11, WMMX_arch),
f5f53991
AS
10376 LOOKUP(12, Advanced_SIMD_arch),
10377 LOOKUP(13, PCS_config),
11c1ff18
PB
10378 LOOKUP(14, ABI_PCS_R9_use),
10379 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 10380 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
10381 LOOKUP(17, ABI_PCS_GOT_use),
10382 LOOKUP(18, ABI_PCS_wchar_t),
10383 LOOKUP(19, ABI_FP_rounding),
10384 LOOKUP(20, ABI_FP_denormal),
10385 LOOKUP(21, ABI_FP_exceptions),
10386 LOOKUP(22, ABI_FP_user_exceptions),
10387 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
10388 {24, "ABI_align_needed", 0, NULL},
10389 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
10390 LOOKUP(26, ABI_enum_size),
10391 LOOKUP(27, ABI_HardFP_use),
10392 LOOKUP(28, ABI_VFP_args),
10393 LOOKUP(29, ABI_WMMX_args),
10394 LOOKUP(30, ABI_optimization_goals),
10395 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 10396 {32, "compatibility", 0, NULL},
f5f53991 10397 LOOKUP(34, CPU_unaligned_access),
75375b3e 10398 LOOKUP(36, FP_HP_extension),
8e79c3df 10399 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
10400 LOOKUP(42, MPextension_use),
10401 LOOKUP(44, DIV_use),
f5f53991
AS
10402 {64, "nodefaults", 0, NULL},
10403 {65, "also_compatible_with", 0, NULL},
10404 LOOKUP(66, T2EE_use),
10405 {67, "conformance", 1, NULL},
10406 LOOKUP(68, Virtualization_use),
cd21e546 10407 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
10408};
10409#undef LOOKUP
10410
11c1ff18 10411static unsigned char *
2cf0635d 10412display_arm_attribute (unsigned char * p)
11c1ff18
PB
10413{
10414 int tag;
10415 unsigned int len;
10416 int val;
2cf0635d 10417 arm_attr_public_tag * attr;
11c1ff18
PB
10418 unsigned i;
10419 int type;
10420
10421 tag = read_uleb128 (p, &len);
10422 p += len;
10423 attr = NULL;
2cf0635d 10424 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
10425 {
10426 if (arm_attr_public_tags[i].tag == tag)
10427 {
10428 attr = &arm_attr_public_tags[i];
10429 break;
10430 }
10431 }
10432
10433 if (attr)
10434 {
10435 printf (" Tag_%s: ", attr->name);
10436 switch (attr->type)
10437 {
10438 case 0:
10439 switch (tag)
10440 {
10441 case 7: /* Tag_CPU_arch_profile. */
10442 val = read_uleb128 (p, &len);
10443 p += len;
10444 switch (val)
10445 {
2b692964
NC
10446 case 0: printf (_("None\n")); break;
10447 case 'A': printf (_("Application\n")); break;
10448 case 'R': printf (_("Realtime\n")); break;
10449 case 'M': printf (_("Microcontroller\n")); break;
10450 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
10451 default: printf ("??? (%d)\n", val); break;
10452 }
10453 break;
10454
75375b3e
MGD
10455 case 24: /* Tag_align_needed. */
10456 val = read_uleb128 (p, &len);
10457 p += len;
10458 switch (val)
10459 {
2b692964
NC
10460 case 0: printf (_("None\n")); break;
10461 case 1: printf (_("8-byte\n")); break;
10462 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
10463 case 3: printf ("??? 3\n"); break;
10464 default:
10465 if (val <= 12)
dd24e3da 10466 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10467 1 << val);
10468 else
10469 printf ("??? (%d)\n", val);
10470 break;
10471 }
10472 break;
10473
10474 case 25: /* Tag_align_preserved. */
10475 val = read_uleb128 (p, &len);
10476 p += len;
10477 switch (val)
10478 {
2b692964
NC
10479 case 0: printf (_("None\n")); break;
10480 case 1: printf (_("8-byte, except leaf SP\n")); break;
10481 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
10482 case 3: printf ("??? 3\n"); break;
10483 default:
10484 if (val <= 12)
dd24e3da 10485 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10486 1 << val);
10487 else
10488 printf ("??? (%d)\n", val);
10489 break;
10490 }
10491 break;
10492
11c1ff18
PB
10493 case 32: /* Tag_compatibility. */
10494 val = read_uleb128 (p, &len);
10495 p += len;
2b692964 10496 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 10497 p += strlen ((char *) p) + 1;
11c1ff18
PB
10498 break;
10499
f5f53991
AS
10500 case 64: /* Tag_nodefaults. */
10501 p++;
2b692964 10502 printf (_("True\n"));
f5f53991
AS
10503 break;
10504
10505 case 65: /* Tag_also_compatible_with. */
10506 val = read_uleb128 (p, &len);
10507 p += len;
10508 if (val == 6 /* Tag_CPU_arch. */)
10509 {
10510 val = read_uleb128 (p, &len);
10511 p += len;
2cf0635d 10512 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
10513 printf ("??? (%d)\n", val);
10514 else
10515 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
10516 }
10517 else
10518 printf ("???\n");
10519 while (*(p++) != '\0' /* NUL terminator. */);
10520 break;
10521
11c1ff18 10522 default:
2cf0635d 10523 abort ();
11c1ff18
PB
10524 }
10525 return p;
10526
10527 case 1:
10528 case 2:
10529 type = attr->type;
10530 break;
10531
10532 default:
10533 assert (attr->type & 0x80);
10534 val = read_uleb128 (p, &len);
10535 p += len;
10536 type = attr->type & 0x7f;
10537 if (val >= type)
10538 printf ("??? (%d)\n", val);
10539 else
10540 printf ("%s\n", attr->table[val]);
10541 return p;
10542 }
10543 }
10544 else
10545 {
10546 if (tag & 1)
10547 type = 1; /* String. */
10548 else
10549 type = 2; /* uleb128. */
10550 printf (" Tag_unknown_%d: ", tag);
10551 }
10552
10553 if (type == 1)
10554 {
10555 printf ("\"%s\"\n", p);
2cf0635d 10556 p += strlen ((char *) p) + 1;
11c1ff18
PB
10557 }
10558 else
10559 {
10560 val = read_uleb128 (p, &len);
10561 p += len;
10562 printf ("%d (0x%x)\n", val, val);
10563 }
10564
10565 return p;
10566}
10567
104d59d1 10568static unsigned char *
60bca95a
NC
10569display_gnu_attribute (unsigned char * p,
10570 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
10571{
10572 int tag;
10573 unsigned int len;
10574 int val;
10575 int type;
10576
10577 tag = read_uleb128 (p, &len);
10578 p += len;
10579
10580 /* Tag_compatibility is the only generic GNU attribute defined at
10581 present. */
10582 if (tag == 32)
10583 {
10584 val = read_uleb128 (p, &len);
10585 p += len;
2b692964 10586 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 10587 p += strlen ((char *) p) + 1;
104d59d1
JM
10588 return p;
10589 }
10590
10591 if ((tag & 2) == 0 && display_proc_gnu_attribute)
10592 return display_proc_gnu_attribute (p, tag);
10593
10594 if (tag & 1)
10595 type = 1; /* String. */
10596 else
10597 type = 2; /* uleb128. */
10598 printf (" Tag_unknown_%d: ", tag);
10599
10600 if (type == 1)
10601 {
10602 printf ("\"%s\"\n", p);
60bca95a 10603 p += strlen ((char *) p) + 1;
104d59d1
JM
10604 }
10605 else
10606 {
10607 val = read_uleb128 (p, &len);
10608 p += len;
10609 printf ("%d (0x%x)\n", val, val);
10610 }
10611
10612 return p;
10613}
10614
34c8bcba 10615static unsigned char *
2cf0635d 10616display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
10617{
10618 int type;
10619 unsigned int len;
10620 int val;
10621
10622 if (tag == Tag_GNU_Power_ABI_FP)
10623 {
10624 val = read_uleb128 (p, &len);
10625 p += len;
10626 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 10627
34c8bcba
JM
10628 switch (val)
10629 {
10630 case 0:
2b692964 10631 printf (_("Hard or soft float\n"));
34c8bcba
JM
10632 break;
10633 case 1:
2b692964 10634 printf (_("Hard float\n"));
34c8bcba
JM
10635 break;
10636 case 2:
2b692964 10637 printf (_("Soft float\n"));
34c8bcba 10638 break;
3c7b9897 10639 case 3:
2b692964 10640 printf (_("Single-precision hard float\n"));
3c7b9897 10641 break;
34c8bcba
JM
10642 default:
10643 printf ("??? (%d)\n", val);
10644 break;
10645 }
10646 return p;
10647 }
10648
c6e65352
DJ
10649 if (tag == Tag_GNU_Power_ABI_Vector)
10650 {
10651 val = read_uleb128 (p, &len);
10652 p += len;
10653 printf (" Tag_GNU_Power_ABI_Vector: ");
10654 switch (val)
10655 {
10656 case 0:
2b692964 10657 printf (_("Any\n"));
c6e65352
DJ
10658 break;
10659 case 1:
2b692964 10660 printf (_("Generic\n"));
c6e65352
DJ
10661 break;
10662 case 2:
10663 printf ("AltiVec\n");
10664 break;
10665 case 3:
10666 printf ("SPE\n");
10667 break;
10668 default:
10669 printf ("??? (%d)\n", val);
10670 break;
10671 }
10672 return p;
10673 }
10674
f82e0623
NF
10675 if (tag == Tag_GNU_Power_ABI_Struct_Return)
10676 {
10677 val = read_uleb128 (p, &len);
10678 p += len;
10679 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
10680 switch (val)
10681 {
10682 case 0:
2b692964 10683 printf (_("Any\n"));
f82e0623
NF
10684 break;
10685 case 1:
10686 printf ("r3/r4\n");
10687 break;
10688 case 2:
2b692964 10689 printf (_("Memory\n"));
f82e0623
NF
10690 break;
10691 default:
10692 printf ("??? (%d)\n", val);
10693 break;
10694 }
10695 return p;
10696 }
10697
34c8bcba
JM
10698 if (tag & 1)
10699 type = 1; /* String. */
10700 else
10701 type = 2; /* uleb128. */
10702 printf (" Tag_unknown_%d: ", tag);
10703
10704 if (type == 1)
10705 {
10706 printf ("\"%s\"\n", p);
60bca95a 10707 p += strlen ((char *) p) + 1;
34c8bcba
JM
10708 }
10709 else
10710 {
10711 val = read_uleb128 (p, &len);
10712 p += len;
10713 printf ("%d (0x%x)\n", val, val);
10714 }
10715
10716 return p;
10717}
10718
2cf19d5c 10719static unsigned char *
2cf0635d 10720display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
10721{
10722 int type;
10723 unsigned int len;
10724 int val;
10725
10726 if (tag == Tag_GNU_MIPS_ABI_FP)
10727 {
10728 val = read_uleb128 (p, &len);
10729 p += len;
10730 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 10731
2cf19d5c
JM
10732 switch (val)
10733 {
10734 case 0:
2b692964 10735 printf (_("Hard or soft float\n"));
2cf19d5c
JM
10736 break;
10737 case 1:
2b692964 10738 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
10739 break;
10740 case 2:
2b692964 10741 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
10742 break;
10743 case 3:
2b692964 10744 printf (_("Soft float\n"));
2cf19d5c 10745 break;
42554f6a 10746 case 4:
9eeefea8 10747 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 10748 break;
2cf19d5c
JM
10749 default:
10750 printf ("??? (%d)\n", val);
10751 break;
10752 }
10753 return p;
10754 }
10755
10756 if (tag & 1)
10757 type = 1; /* String. */
10758 else
10759 type = 2; /* uleb128. */
10760 printf (" Tag_unknown_%d: ", tag);
10761
10762 if (type == 1)
10763 {
10764 printf ("\"%s\"\n", p);
60bca95a 10765 p += strlen ((char *) p) + 1;
2cf19d5c
JM
10766 }
10767 else
10768 {
10769 val = read_uleb128 (p, &len);
10770 p += len;
10771 printf ("%d (0x%x)\n", val, val);
10772 }
10773
10774 return p;
10775}
10776
59e6276b
JM
10777static unsigned char *
10778display_tic6x_attribute (unsigned char * p)
10779{
10780 int tag;
10781 unsigned int len;
10782 int val;
10783
10784 tag = read_uleb128 (p, &len);
10785 p += len;
10786
10787 switch (tag)
10788 {
75fa6dc1 10789 case Tag_ISA:
59e6276b
JM
10790 val = read_uleb128 (p, &len);
10791 p += len;
75fa6dc1 10792 printf (" Tag_ISA: ");
59e6276b
JM
10793
10794 switch (val)
10795 {
75fa6dc1 10796 case C6XABI_Tag_ISA_none:
59e6276b
JM
10797 printf (_("None\n"));
10798 break;
75fa6dc1 10799 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
10800 printf ("C62x\n");
10801 break;
75fa6dc1 10802 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
10803 printf ("C67x\n");
10804 break;
75fa6dc1 10805 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
10806 printf ("C67x+\n");
10807 break;
75fa6dc1 10808 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
10809 printf ("C64x\n");
10810 break;
75fa6dc1 10811 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
10812 printf ("C64x+\n");
10813 break;
75fa6dc1 10814 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
10815 printf ("C674x\n");
10816 break;
10817 default:
10818 printf ("??? (%d)\n", val);
10819 break;
10820 }
10821 return p;
10822
87779176
JM
10823 case Tag_ABI_wchar_t:
10824 val = read_uleb128 (p, &len);
10825 p += len;
10826 printf (" Tag_ABI_wchar_t: ");
10827 switch (val)
10828 {
10829 case 0:
10830 printf (_("Not used\n"));
10831 break;
10832 case 1:
10833 printf (_("2 bytes\n"));
10834 break;
10835 case 2:
10836 printf (_("4 bytes\n"));
10837 break;
10838 default:
10839 printf ("??? (%d)\n", val);
10840 break;
10841 }
10842 return p;
10843
10844 case Tag_ABI_stack_align_needed:
10845 val = read_uleb128 (p, &len);
10846 p += len;
10847 printf (" Tag_ABI_stack_align_needed: ");
10848 switch (val)
10849 {
10850 case 0:
10851 printf (_("8-byte\n"));
10852 break;
10853 case 1:
10854 printf (_("16-byte\n"));
10855 break;
10856 default:
10857 printf ("??? (%d)\n", val);
10858 break;
10859 }
10860 return p;
10861
10862 case Tag_ABI_stack_align_preserved:
10863 val = read_uleb128 (p, &len);
10864 p += len;
10865 printf (" Tag_ABI_stack_align_preserved: ");
10866 switch (val)
10867 {
10868 case 0:
10869 printf (_("8-byte\n"));
10870 break;
10871 case 1:
10872 printf (_("16-byte\n"));
10873 break;
10874 default:
10875 printf ("??? (%d)\n", val);
10876 break;
10877 }
10878 return p;
10879
b5593623
JM
10880 case Tag_ABI_DSBT:
10881 val = read_uleb128 (p, &len);
10882 p += len;
10883 printf (" Tag_ABI_DSBT: ");
10884 switch (val)
10885 {
10886 case 0:
10887 printf (_("DSBT addressing not used\n"));
10888 break;
10889 case 1:
10890 printf (_("DSBT addressing used\n"));
10891 break;
10892 default:
10893 printf ("??? (%d)\n", val);
10894 break;
10895 }
10896 return p;
10897
87779176
JM
10898 case Tag_ABI_PID:
10899 val = read_uleb128 (p, &len);
10900 p += len;
10901 printf (" Tag_ABI_PID: ");
10902 switch (val)
10903 {
10904 case 0:
10905 printf (_("Data addressing position-dependent\n"));
10906 break;
10907 case 1:
10908 printf (_("Data addressing position-independent, GOT near DP\n"));
10909 break;
10910 case 2:
10911 printf (_("Data addressing position-independent, GOT far from DP\n"));
10912 break;
10913 default:
10914 printf ("??? (%d)\n", val);
10915 break;
10916 }
10917 return p;
10918
10919 case Tag_ABI_PIC:
10920 val = read_uleb128 (p, &len);
10921 p += len;
10922 printf (" Tag_ABI_PIC: ");
10923 switch (val)
10924 {
10925 case 0:
10926 printf (_("Code addressing position-dependent\n"));
10927 break;
10928 case 1:
10929 printf (_("Code addressing position-independent\n"));
10930 break;
10931 default:
10932 printf ("??? (%d)\n", val);
10933 break;
10934 }
10935 return p;
10936
10937 case Tag_ABI_array_object_alignment:
10938 val = read_uleb128 (p, &len);
10939 p += len;
10940 printf (" Tag_ABI_array_object_alignment: ");
10941 switch (val)
10942 {
10943 case 0:
10944 printf (_("8-byte\n"));
10945 break;
10946 case 1:
10947 printf (_("4-byte\n"));
10948 break;
10949 case 2:
10950 printf (_("16-byte\n"));
10951 break;
10952 default:
10953 printf ("??? (%d)\n", val);
10954 break;
10955 }
10956 return p;
10957
10958 case Tag_ABI_array_object_align_expected:
10959 val = read_uleb128 (p, &len);
10960 p += len;
10961 printf (" Tag_ABI_array_object_align_expected: ");
10962 switch (val)
10963 {
10964 case 0:
10965 printf (_("8-byte\n"));
10966 break;
10967 case 1:
10968 printf (_("4-byte\n"));
10969 break;
10970 case 2:
10971 printf (_("16-byte\n"));
10972 break;
10973 default:
10974 printf ("??? (%d)\n", val);
10975 break;
10976 }
10977 return p;
10978
3cbd1c06 10979 case Tag_ABI_compatibility:
59e6276b
JM
10980 val = read_uleb128 (p, &len);
10981 p += len;
3cbd1c06 10982 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
10983 printf (_("flag = %d, vendor = %s\n"), val, p);
10984 p += strlen ((char *) p) + 1;
10985 return p;
87779176
JM
10986
10987 case Tag_ABI_conformance:
10988 printf (" Tag_ABI_conformance: ");
10989 printf ("\"%s\"\n", p);
10990 p += strlen ((char *) p) + 1;
10991 return p;
59e6276b
JM
10992 }
10993
10994 printf (" Tag_unknown_%d: ", tag);
10995
87779176
JM
10996 if (tag & 1)
10997 {
10998 printf ("\"%s\"\n", p);
10999 p += strlen ((char *) p) + 1;
11000 }
11001 else
11002 {
11003 val = read_uleb128 (p, &len);
11004 p += len;
11005 printf ("%d (0x%x)\n", val, val);
11006 }
59e6276b
JM
11007
11008 return p;
11009}
11010
11c1ff18 11011static int
60bca95a
NC
11012process_attributes (FILE * file,
11013 const char * public_name,
104d59d1 11014 unsigned int proc_type,
60bca95a
NC
11015 unsigned char * (* display_pub_attribute) (unsigned char *),
11016 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11017{
2cf0635d
NC
11018 Elf_Internal_Shdr * sect;
11019 unsigned char * contents;
11020 unsigned char * p;
11021 unsigned char * end;
11c1ff18
PB
11022 bfd_vma section_len;
11023 bfd_vma len;
11024 unsigned i;
11025
11026 /* Find the section header so that we get the size. */
11027 for (i = 0, sect = section_headers;
11028 i < elf_header.e_shnum;
11029 i++, sect++)
11030 {
104d59d1 11031 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11032 continue;
11033
3f5e193b
NC
11034 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11035 sect->sh_size, _("attributes"));
60bca95a 11036 if (contents == NULL)
11c1ff18 11037 continue;
60bca95a 11038
11c1ff18
PB
11039 p = contents;
11040 if (*p == 'A')
11041 {
11042 len = sect->sh_size - 1;
11043 p++;
60bca95a 11044
11c1ff18
PB
11045 while (len > 0)
11046 {
11047 int namelen;
11048 bfd_boolean public_section;
104d59d1 11049 bfd_boolean gnu_section;
11c1ff18
PB
11050
11051 section_len = byte_get (p, 4);
11052 p += 4;
60bca95a 11053
11c1ff18
PB
11054 if (section_len > len)
11055 {
11056 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11057 (int) section_len, (int) len);
11c1ff18
PB
11058 section_len = len;
11059 }
60bca95a 11060
11c1ff18 11061 len -= section_len;
2b692964 11062 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11063
11064 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11065 public_section = TRUE;
11066 else
11067 public_section = FALSE;
60bca95a
NC
11068
11069 if (streq ((char *) p, "gnu"))
104d59d1
JM
11070 gnu_section = TRUE;
11071 else
11072 gnu_section = FALSE;
60bca95a
NC
11073
11074 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11075 p += namelen;
11076 section_len -= namelen + 4;
60bca95a 11077
11c1ff18
PB
11078 while (section_len > 0)
11079 {
11080 int tag = *(p++);
11081 int val;
11082 bfd_vma size;
60bca95a 11083
11c1ff18
PB
11084 size = byte_get (p, 4);
11085 if (size > section_len)
11086 {
11087 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11088 (int) size, (int) section_len);
11c1ff18
PB
11089 size = section_len;
11090 }
60bca95a 11091
11c1ff18
PB
11092 section_len -= size;
11093 end = p + size - 1;
11094 p += 4;
60bca95a 11095
11c1ff18
PB
11096 switch (tag)
11097 {
11098 case 1:
2b692964 11099 printf (_("File Attributes\n"));
11c1ff18
PB
11100 break;
11101 case 2:
2b692964 11102 printf (_("Section Attributes:"));
11c1ff18
PB
11103 goto do_numlist;
11104 case 3:
2b692964 11105 printf (_("Symbol Attributes:"));
11c1ff18
PB
11106 do_numlist:
11107 for (;;)
11108 {
91d6fa6a 11109 unsigned int j;
60bca95a 11110
91d6fa6a
NC
11111 val = read_uleb128 (p, &j);
11112 p += j;
11c1ff18
PB
11113 if (val == 0)
11114 break;
11115 printf (" %d", val);
11116 }
11117 printf ("\n");
11118 break;
11119 default:
2b692964 11120 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
11121 public_section = FALSE;
11122 break;
11123 }
60bca95a 11124
11c1ff18
PB
11125 if (public_section)
11126 {
11127 while (p < end)
104d59d1
JM
11128 p = display_pub_attribute (p);
11129 }
11130 else if (gnu_section)
11131 {
11132 while (p < end)
11133 p = display_gnu_attribute (p,
11134 display_proc_gnu_attribute);
11c1ff18
PB
11135 }
11136 else
11137 {
11138 /* ??? Do something sensible, like dump hex. */
2b692964 11139 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
11140 p = end;
11141 }
11142 }
11143 }
11144 }
11145 else
60bca95a 11146 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 11147
60bca95a 11148 free (contents);
11c1ff18
PB
11149 }
11150 return 1;
11151}
11152
104d59d1 11153static int
2cf0635d 11154process_arm_specific (FILE * file)
104d59d1
JM
11155{
11156 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
11157 display_arm_attribute, NULL);
11158}
11159
34c8bcba 11160static int
2cf0635d 11161process_power_specific (FILE * file)
34c8bcba
JM
11162{
11163 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11164 display_power_gnu_attribute);
11165}
11166
59e6276b
JM
11167static int
11168process_tic6x_specific (FILE * file)
11169{
11170 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
11171 display_tic6x_attribute, NULL);
11172}
11173
ccb4c951
RS
11174/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
11175 Print the Address, Access and Initial fields of an entry at VMA ADDR
11176 and return the VMA of the next entry. */
11177
11178static bfd_vma
2cf0635d 11179print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
11180{
11181 printf (" ");
11182 print_vma (addr, LONG_HEX);
11183 printf (" ");
11184 if (addr < pltgot + 0xfff0)
11185 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
11186 else
11187 printf ("%10s", "");
11188 printf (" ");
11189 if (data == NULL)
2b692964 11190 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
11191 else
11192 {
11193 bfd_vma entry;
11194
11195 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11196 print_vma (entry, LONG_HEX);
11197 }
11198 return addr + (is_32bit_elf ? 4 : 8);
11199}
11200
861fb55a
DJ
11201/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
11202 PLTGOT. Print the Address and Initial fields of an entry at VMA
11203 ADDR and return the VMA of the next entry. */
11204
11205static bfd_vma
2cf0635d 11206print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
11207{
11208 printf (" ");
11209 print_vma (addr, LONG_HEX);
11210 printf (" ");
11211 if (data == NULL)
2b692964 11212 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
11213 else
11214 {
11215 bfd_vma entry;
11216
11217 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11218 print_vma (entry, LONG_HEX);
11219 }
11220 return addr + (is_32bit_elf ? 4 : 8);
11221}
11222
19e6b90e 11223static int
2cf0635d 11224process_mips_specific (FILE * file)
5b18a4bc 11225{
2cf0635d 11226 Elf_Internal_Dyn * entry;
19e6b90e
L
11227 size_t liblist_offset = 0;
11228 size_t liblistno = 0;
11229 size_t conflictsno = 0;
11230 size_t options_offset = 0;
11231 size_t conflicts_offset = 0;
861fb55a
DJ
11232 size_t pltrelsz = 0;
11233 size_t pltrel = 0;
ccb4c951 11234 bfd_vma pltgot = 0;
861fb55a
DJ
11235 bfd_vma mips_pltgot = 0;
11236 bfd_vma jmprel = 0;
ccb4c951
RS
11237 bfd_vma local_gotno = 0;
11238 bfd_vma gotsym = 0;
11239 bfd_vma symtabno = 0;
103f02d3 11240
2cf19d5c
JM
11241 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11242 display_mips_gnu_attribute);
11243
19e6b90e
L
11244 /* We have a lot of special sections. Thanks SGI! */
11245 if (dynamic_section == NULL)
11246 /* No information available. */
11247 return 0;
252b5132 11248
b2d38a17 11249 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
11250 switch (entry->d_tag)
11251 {
11252 case DT_MIPS_LIBLIST:
d93f0186
NC
11253 liblist_offset
11254 = offset_from_vma (file, entry->d_un.d_val,
11255 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
11256 break;
11257 case DT_MIPS_LIBLISTNO:
11258 liblistno = entry->d_un.d_val;
11259 break;
11260 case DT_MIPS_OPTIONS:
d93f0186 11261 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
11262 break;
11263 case DT_MIPS_CONFLICT:
d93f0186
NC
11264 conflicts_offset
11265 = offset_from_vma (file, entry->d_un.d_val,
11266 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
11267 break;
11268 case DT_MIPS_CONFLICTNO:
11269 conflictsno = entry->d_un.d_val;
11270 break;
ccb4c951 11271 case DT_PLTGOT:
861fb55a
DJ
11272 pltgot = entry->d_un.d_ptr;
11273 break;
ccb4c951
RS
11274 case DT_MIPS_LOCAL_GOTNO:
11275 local_gotno = entry->d_un.d_val;
11276 break;
11277 case DT_MIPS_GOTSYM:
11278 gotsym = entry->d_un.d_val;
11279 break;
11280 case DT_MIPS_SYMTABNO:
11281 symtabno = entry->d_un.d_val;
11282 break;
861fb55a
DJ
11283 case DT_MIPS_PLTGOT:
11284 mips_pltgot = entry->d_un.d_ptr;
11285 break;
11286 case DT_PLTREL:
11287 pltrel = entry->d_un.d_val;
11288 break;
11289 case DT_PLTRELSZ:
11290 pltrelsz = entry->d_un.d_val;
11291 break;
11292 case DT_JMPREL:
11293 jmprel = entry->d_un.d_ptr;
11294 break;
252b5132
RH
11295 default:
11296 break;
11297 }
11298
11299 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
11300 {
2cf0635d 11301 Elf32_External_Lib * elib;
252b5132
RH
11302 size_t cnt;
11303
3f5e193b
NC
11304 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
11305 liblistno,
11306 sizeof (Elf32_External_Lib),
11307 _("liblist"));
a6e9f9df 11308 if (elib)
252b5132 11309 {
2b692964 11310 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 11311 (unsigned long) liblistno);
2b692964 11312 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
11313 stdout);
11314
11315 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 11316 {
a6e9f9df 11317 Elf32_Lib liblist;
91d6fa6a 11318 time_t atime;
a6e9f9df 11319 char timebuf[20];
2cf0635d 11320 struct tm * tmp;
a6e9f9df
AM
11321
11322 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 11323 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
11324 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11325 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11326 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11327
91d6fa6a 11328 tmp = gmtime (&atime);
e9e44622
JJ
11329 snprintf (timebuf, sizeof (timebuf),
11330 "%04u-%02u-%02uT%02u:%02u:%02u",
11331 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11332 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 11333
31104126 11334 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
11335 if (VALID_DYNAMIC_NAME (liblist.l_name))
11336 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
11337 else
2b692964 11338 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
11339 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
11340 liblist.l_version);
a6e9f9df
AM
11341
11342 if (liblist.l_flags == 0)
2b692964 11343 puts (_(" NONE"));
a6e9f9df
AM
11344 else
11345 {
11346 static const struct
252b5132 11347 {
2cf0635d 11348 const char * name;
a6e9f9df 11349 int bit;
252b5132 11350 }
a6e9f9df
AM
11351 l_flags_vals[] =
11352 {
11353 { " EXACT_MATCH", LL_EXACT_MATCH },
11354 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
11355 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
11356 { " EXPORTS", LL_EXPORTS },
11357 { " DELAY_LOAD", LL_DELAY_LOAD },
11358 { " DELTA", LL_DELTA }
11359 };
11360 int flags = liblist.l_flags;
11361 size_t fcnt;
11362
60bca95a 11363 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
11364 if ((flags & l_flags_vals[fcnt].bit) != 0)
11365 {
11366 fputs (l_flags_vals[fcnt].name, stdout);
11367 flags ^= l_flags_vals[fcnt].bit;
11368 }
11369 if (flags != 0)
11370 printf (" %#x", (unsigned int) flags);
252b5132 11371
a6e9f9df
AM
11372 puts ("");
11373 }
252b5132 11374 }
252b5132 11375
a6e9f9df
AM
11376 free (elib);
11377 }
252b5132
RH
11378 }
11379
11380 if (options_offset != 0)
11381 {
2cf0635d
NC
11382 Elf_External_Options * eopt;
11383 Elf_Internal_Shdr * sect = section_headers;
11384 Elf_Internal_Options * iopt;
11385 Elf_Internal_Options * option;
252b5132
RH
11386 size_t offset;
11387 int cnt;
11388
11389 /* Find the section header so that we get the size. */
11390 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 11391 ++sect;
252b5132 11392
3f5e193b
NC
11393 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
11394 sect->sh_size, _("options"));
a6e9f9df 11395 if (eopt)
252b5132 11396 {
3f5e193b
NC
11397 iopt = (Elf_Internal_Options *)
11398 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
11399 if (iopt == NULL)
11400 {
591a748a 11401 error (_("Out of memory\n"));
a6e9f9df
AM
11402 return 0;
11403 }
76da6bbe 11404
a6e9f9df
AM
11405 offset = cnt = 0;
11406 option = iopt;
252b5132 11407
a6e9f9df
AM
11408 while (offset < sect->sh_size)
11409 {
2cf0635d 11410 Elf_External_Options * eoption;
252b5132 11411
a6e9f9df 11412 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 11413
a6e9f9df
AM
11414 option->kind = BYTE_GET (eoption->kind);
11415 option->size = BYTE_GET (eoption->size);
11416 option->section = BYTE_GET (eoption->section);
11417 option->info = BYTE_GET (eoption->info);
76da6bbe 11418
a6e9f9df 11419 offset += option->size;
252b5132 11420
a6e9f9df
AM
11421 ++option;
11422 ++cnt;
11423 }
252b5132 11424
a6e9f9df
AM
11425 printf (_("\nSection '%s' contains %d entries:\n"),
11426 SECTION_NAME (sect), cnt);
76da6bbe 11427
a6e9f9df 11428 option = iopt;
252b5132 11429
a6e9f9df 11430 while (cnt-- > 0)
252b5132 11431 {
a6e9f9df
AM
11432 size_t len;
11433
11434 switch (option->kind)
252b5132 11435 {
a6e9f9df
AM
11436 case ODK_NULL:
11437 /* This shouldn't happen. */
11438 printf (" NULL %d %lx", option->section, option->info);
11439 break;
11440 case ODK_REGINFO:
11441 printf (" REGINFO ");
11442 if (elf_header.e_machine == EM_MIPS)
11443 {
11444 /* 32bit form. */
2cf0635d 11445 Elf32_External_RegInfo * ereg;
b34976b6 11446 Elf32_RegInfo reginfo;
a6e9f9df
AM
11447
11448 ereg = (Elf32_External_RegInfo *) (option + 1);
11449 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11450 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11451 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11452 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11453 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
11454 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
11455
11456 printf ("GPR %08lx GP 0x%lx\n",
11457 reginfo.ri_gprmask,
11458 (unsigned long) reginfo.ri_gp_value);
11459 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11460 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11461 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11462 }
11463 else
11464 {
11465 /* 64 bit form. */
2cf0635d 11466 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
11467 Elf64_Internal_RegInfo reginfo;
11468
11469 ereg = (Elf64_External_RegInfo *) (option + 1);
11470 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11471 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11472 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11473 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11474 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 11475 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
11476
11477 printf ("GPR %08lx GP 0x",
11478 reginfo.ri_gprmask);
11479 printf_vma (reginfo.ri_gp_value);
11480 printf ("\n");
11481
11482 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11483 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11484 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11485 }
11486 ++option;
11487 continue;
11488 case ODK_EXCEPTIONS:
11489 fputs (" EXCEPTIONS fpe_min(", stdout);
11490 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
11491 fputs (") fpe_max(", stdout);
11492 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
11493 fputs (")", stdout);
11494
11495 if (option->info & OEX_PAGE0)
11496 fputs (" PAGE0", stdout);
11497 if (option->info & OEX_SMM)
11498 fputs (" SMM", stdout);
11499 if (option->info & OEX_FPDBUG)
11500 fputs (" FPDBUG", stdout);
11501 if (option->info & OEX_DISMISS)
11502 fputs (" DISMISS", stdout);
11503 break;
11504 case ODK_PAD:
11505 fputs (" PAD ", stdout);
11506 if (option->info & OPAD_PREFIX)
11507 fputs (" PREFIX", stdout);
11508 if (option->info & OPAD_POSTFIX)
11509 fputs (" POSTFIX", stdout);
11510 if (option->info & OPAD_SYMBOL)
11511 fputs (" SYMBOL", stdout);
11512 break;
11513 case ODK_HWPATCH:
11514 fputs (" HWPATCH ", stdout);
11515 if (option->info & OHW_R4KEOP)
11516 fputs (" R4KEOP", stdout);
11517 if (option->info & OHW_R8KPFETCH)
11518 fputs (" R8KPFETCH", stdout);
11519 if (option->info & OHW_R5KEOP)
11520 fputs (" R5KEOP", stdout);
11521 if (option->info & OHW_R5KCVTL)
11522 fputs (" R5KCVTL", stdout);
11523 break;
11524 case ODK_FILL:
11525 fputs (" FILL ", stdout);
11526 /* XXX Print content of info word? */
11527 break;
11528 case ODK_TAGS:
11529 fputs (" TAGS ", stdout);
11530 /* XXX Print content of info word? */
11531 break;
11532 case ODK_HWAND:
11533 fputs (" HWAND ", stdout);
11534 if (option->info & OHWA0_R4KEOP_CHECKED)
11535 fputs (" R4KEOP_CHECKED", stdout);
11536 if (option->info & OHWA0_R4KEOP_CLEAN)
11537 fputs (" R4KEOP_CLEAN", stdout);
11538 break;
11539 case ODK_HWOR:
11540 fputs (" HWOR ", stdout);
11541 if (option->info & OHWA0_R4KEOP_CHECKED)
11542 fputs (" R4KEOP_CHECKED", stdout);
11543 if (option->info & OHWA0_R4KEOP_CLEAN)
11544 fputs (" R4KEOP_CLEAN", stdout);
11545 break;
11546 case ODK_GP_GROUP:
11547 printf (" GP_GROUP %#06lx self-contained %#06lx",
11548 option->info & OGP_GROUP,
11549 (option->info & OGP_SELF) >> 16);
11550 break;
11551 case ODK_IDENT:
11552 printf (" IDENT %#06lx self-contained %#06lx",
11553 option->info & OGP_GROUP,
11554 (option->info & OGP_SELF) >> 16);
11555 break;
11556 default:
11557 /* This shouldn't happen. */
11558 printf (" %3d ??? %d %lx",
11559 option->kind, option->section, option->info);
11560 break;
252b5132 11561 }
a6e9f9df 11562
2cf0635d 11563 len = sizeof (* eopt);
a6e9f9df
AM
11564 while (len < option->size)
11565 if (((char *) option)[len] >= ' '
11566 && ((char *) option)[len] < 0x7f)
11567 printf ("%c", ((char *) option)[len++]);
11568 else
11569 printf ("\\%03o", ((char *) option)[len++]);
11570
11571 fputs ("\n", stdout);
252b5132 11572 ++option;
252b5132
RH
11573 }
11574
a6e9f9df 11575 free (eopt);
252b5132 11576 }
252b5132
RH
11577 }
11578
11579 if (conflicts_offset != 0 && conflictsno != 0)
11580 {
2cf0635d 11581 Elf32_Conflict * iconf;
252b5132
RH
11582 size_t cnt;
11583
11584 if (dynamic_symbols == NULL)
11585 {
591a748a 11586 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
11587 return 0;
11588 }
11589
3f5e193b 11590 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
11591 if (iconf == NULL)
11592 {
591a748a 11593 error (_("Out of memory\n"));
252b5132
RH
11594 return 0;
11595 }
11596
9ea033b2 11597 if (is_32bit_elf)
252b5132 11598 {
2cf0635d 11599 Elf32_External_Conflict * econf32;
a6e9f9df 11600
3f5e193b
NC
11601 econf32 = (Elf32_External_Conflict *)
11602 get_data (NULL, file, conflicts_offset, conflictsno,
11603 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
11604 if (!econf32)
11605 return 0;
252b5132
RH
11606
11607 for (cnt = 0; cnt < conflictsno; ++cnt)
11608 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
11609
11610 free (econf32);
252b5132
RH
11611 }
11612 else
11613 {
2cf0635d 11614 Elf64_External_Conflict * econf64;
a6e9f9df 11615
3f5e193b
NC
11616 econf64 = (Elf64_External_Conflict *)
11617 get_data (NULL, file, conflicts_offset, conflictsno,
11618 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
11619 if (!econf64)
11620 return 0;
252b5132
RH
11621
11622 for (cnt = 0; cnt < conflictsno; ++cnt)
11623 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
11624
11625 free (econf64);
252b5132
RH
11626 }
11627
c7e7ca54
NC
11628 printf (_("\nSection '.conflict' contains %lu entries:\n"),
11629 (unsigned long) conflictsno);
252b5132
RH
11630 puts (_(" Num: Index Value Name"));
11631
11632 for (cnt = 0; cnt < conflictsno; ++cnt)
11633 {
2cf0635d 11634 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 11635
b34976b6 11636 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 11637 print_vma (psym->st_value, FULL_HEX);
31104126 11638 putchar (' ');
d79b3d50
NC
11639 if (VALID_DYNAMIC_NAME (psym->st_name))
11640 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
11641 else
2b692964 11642 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 11643 putchar ('\n');
252b5132
RH
11644 }
11645
252b5132
RH
11646 free (iconf);
11647 }
11648
ccb4c951
RS
11649 if (pltgot != 0 && local_gotno != 0)
11650 {
91d6fa6a 11651 bfd_vma ent, local_end, global_end;
bbeee7ea 11652 size_t i, offset;
2cf0635d 11653 unsigned char * data;
bbeee7ea 11654 int addr_size;
ccb4c951 11655
91d6fa6a 11656 ent = pltgot;
ccb4c951
RS
11657 addr_size = (is_32bit_elf ? 4 : 8);
11658 local_end = pltgot + local_gotno * addr_size;
11659 global_end = local_end + (symtabno - gotsym) * addr_size;
11660
11661 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b
NC
11662 data = (unsigned char *) get_data (NULL, file, offset,
11663 global_end - pltgot, 1, _("GOT"));
ccb4c951
RS
11664 printf (_("\nPrimary GOT:\n"));
11665 printf (_(" Canonical gp value: "));
11666 print_vma (pltgot + 0x7ff0, LONG_HEX);
11667 printf ("\n\n");
11668
11669 printf (_(" Reserved entries:\n"));
11670 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
11671 addr_size * 2, _("Address"), _("Access"),
11672 addr_size * 2, _("Initial"));
91d6fa6a 11673 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 11674 printf (_(" Lazy resolver\n"));
ccb4c951 11675 if (data
91d6fa6a 11676 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
11677 >> (addr_size * 8 - 1)) != 0)
11678 {
91d6fa6a 11679 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 11680 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
11681 }
11682 printf ("\n");
11683
91d6fa6a 11684 if (ent < local_end)
ccb4c951
RS
11685 {
11686 printf (_(" Local entries:\n"));
cc5914eb 11687 printf (" %*s %10s %*s\n",
2b692964
NC
11688 addr_size * 2, _("Address"), _("Access"),
11689 addr_size * 2, _("Initial"));
91d6fa6a 11690 while (ent < local_end)
ccb4c951 11691 {
91d6fa6a 11692 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
11693 printf ("\n");
11694 }
11695 printf ("\n");
11696 }
11697
11698 if (gotsym < symtabno)
11699 {
11700 int sym_width;
11701
11702 printf (_(" Global entries:\n"));
cc5914eb 11703 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
2b692964
NC
11704 addr_size * 2, _("Address"), _("Access"),
11705 addr_size * 2, _("Initial"),
11706 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
ccb4c951
RS
11707 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
11708 for (i = gotsym; i < symtabno; i++)
11709 {
2cf0635d 11710 Elf_Internal_Sym * psym;
ccb4c951
RS
11711
11712 psym = dynamic_symbols + i;
91d6fa6a 11713 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
11714 printf (" ");
11715 print_vma (psym->st_value, LONG_HEX);
11716 printf (" %-7s %3s ",
11717 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
11718 get_symbol_index_type (psym->st_shndx));
11719 if (VALID_DYNAMIC_NAME (psym->st_name))
11720 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
11721 else
2b692964 11722 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
11723 printf ("\n");
11724 }
11725 printf ("\n");
11726 }
11727
11728 if (data)
11729 free (data);
11730 }
11731
861fb55a
DJ
11732 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
11733 {
91d6fa6a 11734 bfd_vma ent, end;
861fb55a
DJ
11735 size_t offset, rel_offset;
11736 unsigned long count, i;
2cf0635d 11737 unsigned char * data;
861fb55a 11738 int addr_size, sym_width;
2cf0635d 11739 Elf_Internal_Rela * rels;
861fb55a
DJ
11740
11741 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
11742 if (pltrel == DT_RELA)
11743 {
11744 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
11745 return 0;
11746 }
11747 else
11748 {
11749 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
11750 return 0;
11751 }
11752
91d6fa6a 11753 ent = mips_pltgot;
861fb55a
DJ
11754 addr_size = (is_32bit_elf ? 4 : 8);
11755 end = mips_pltgot + (2 + count) * addr_size;
11756
11757 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b
NC
11758 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
11759 1, _("PLT GOT"));
861fb55a
DJ
11760 printf (_("\nPLT GOT:\n\n"));
11761 printf (_(" Reserved entries:\n"));
11762 printf (_(" %*s %*s Purpose\n"),
2b692964 11763 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 11764 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 11765 printf (_(" PLT lazy resolver\n"));
91d6fa6a 11766 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 11767 printf (_(" Module pointer\n"));
861fb55a
DJ
11768 printf ("\n");
11769
11770 printf (_(" Entries:\n"));
cc5914eb 11771 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
11772 addr_size * 2, _("Address"),
11773 addr_size * 2, _("Initial"),
11774 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
11775 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
11776 for (i = 0; i < count; i++)
11777 {
2cf0635d 11778 Elf_Internal_Sym * psym;
861fb55a
DJ
11779
11780 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 11781 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
11782 printf (" ");
11783 print_vma (psym->st_value, LONG_HEX);
11784 printf (" %-7s %3s ",
11785 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
11786 get_symbol_index_type (psym->st_shndx));
11787 if (VALID_DYNAMIC_NAME (psym->st_name))
11788 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
11789 else
2b692964 11790 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
11791 printf ("\n");
11792 }
11793 printf ("\n");
11794
11795 if (data)
11796 free (data);
11797 free (rels);
11798 }
11799
252b5132
RH
11800 return 1;
11801}
11802
047b2264 11803static int
2cf0635d 11804process_gnu_liblist (FILE * file)
047b2264 11805{
2cf0635d
NC
11806 Elf_Internal_Shdr * section;
11807 Elf_Internal_Shdr * string_sec;
11808 Elf32_External_Lib * elib;
11809 char * strtab;
c256ffe7 11810 size_t strtab_size;
047b2264
JJ
11811 size_t cnt;
11812 unsigned i;
11813
11814 if (! do_arch)
11815 return 0;
11816
11817 for (i = 0, section = section_headers;
11818 i < elf_header.e_shnum;
b34976b6 11819 i++, section++)
047b2264
JJ
11820 {
11821 switch (section->sh_type)
11822 {
11823 case SHT_GNU_LIBLIST:
4fbb74a6 11824 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
11825 break;
11826
3f5e193b
NC
11827 elib = (Elf32_External_Lib *)
11828 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
11829 _("liblist"));
047b2264
JJ
11830
11831 if (elib == NULL)
11832 break;
4fbb74a6 11833 string_sec = section_headers + section->sh_link;
047b2264 11834
3f5e193b
NC
11835 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
11836 string_sec->sh_size,
11837 _("liblist string table"));
c256ffe7 11838 strtab_size = string_sec->sh_size;
047b2264
JJ
11839
11840 if (strtab == NULL
11841 || section->sh_entsize != sizeof (Elf32_External_Lib))
11842 {
11843 free (elib);
11844 break;
11845 }
11846
11847 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
11848 SECTION_NAME (section),
0af1713e 11849 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 11850
2b692964 11851 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
11852
11853 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
11854 ++cnt)
11855 {
11856 Elf32_Lib liblist;
91d6fa6a 11857 time_t atime;
047b2264 11858 char timebuf[20];
2cf0635d 11859 struct tm * tmp;
047b2264
JJ
11860
11861 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 11862 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
11863 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11864 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11865 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11866
91d6fa6a 11867 tmp = gmtime (&atime);
e9e44622
JJ
11868 snprintf (timebuf, sizeof (timebuf),
11869 "%04u-%02u-%02uT%02u:%02u:%02u",
11870 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11871 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11872
11873 printf ("%3lu: ", (unsigned long) cnt);
11874 if (do_wide)
c256ffe7 11875 printf ("%-20s", liblist.l_name < strtab_size
2b692964 11876 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 11877 else
c256ffe7 11878 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 11879 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
11880 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
11881 liblist.l_version, liblist.l_flags);
11882 }
11883
11884 free (elib);
11885 }
11886 }
11887
11888 return 1;
11889}
11890
9437c45b 11891static const char *
d3ba0551 11892get_note_type (unsigned e_type)
779fe533
NC
11893{
11894 static char buff[64];
103f02d3 11895
1ec5cd37
NC
11896 if (elf_header.e_type == ET_CORE)
11897 switch (e_type)
11898 {
57346661 11899 case NT_AUXV:
1ec5cd37 11900 return _("NT_AUXV (auxiliary vector)");
57346661 11901 case NT_PRSTATUS:
1ec5cd37 11902 return _("NT_PRSTATUS (prstatus structure)");
57346661 11903 case NT_FPREGSET:
1ec5cd37 11904 return _("NT_FPREGSET (floating point registers)");
57346661 11905 case NT_PRPSINFO:
1ec5cd37 11906 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 11907 case NT_TASKSTRUCT:
1ec5cd37 11908 return _("NT_TASKSTRUCT (task structure)");
57346661 11909 case NT_PRXFPREG:
1ec5cd37 11910 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
11911 case NT_PPC_VMX:
11912 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
11913 case NT_PPC_VSX:
11914 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
11915 case NT_X86_XSTATE:
11916 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
11917 case NT_S390_HIGH_GPRS:
11918 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
11919 case NT_S390_TIMER:
11920 return _("NT_S390_TIMER (s390 timer register)");
11921 case NT_S390_TODCMP:
11922 return _("NT_S390_TODCMP (s390 TOD comparator register)");
11923 case NT_S390_TODPREG:
11924 return _("NT_S390_TODPREG (s390 TOD programmable register)");
11925 case NT_S390_CTRS:
11926 return _("NT_S390_CTRS (s390 control registers)");
11927 case NT_S390_PREFIX:
11928 return _("NT_S390_PREFIX (s390 prefix register)");
57346661 11929 case NT_PSTATUS:
1ec5cd37 11930 return _("NT_PSTATUS (pstatus structure)");
57346661 11931 case NT_FPREGS:
1ec5cd37 11932 return _("NT_FPREGS (floating point registers)");
57346661 11933 case NT_PSINFO:
1ec5cd37 11934 return _("NT_PSINFO (psinfo structure)");
57346661 11935 case NT_LWPSTATUS:
1ec5cd37 11936 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 11937 case NT_LWPSINFO:
1ec5cd37 11938 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 11939 case NT_WIN32PSTATUS:
1ec5cd37
NC
11940 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
11941 default:
11942 break;
11943 }
11944 else
11945 switch (e_type)
11946 {
11947 case NT_VERSION:
11948 return _("NT_VERSION (version)");
11949 case NT_ARCH:
11950 return _("NT_ARCH (architecture)");
11951 default:
11952 break;
11953 }
11954
e9e44622 11955 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 11956 return buff;
779fe533
NC
11957}
11958
1118d252
RM
11959static const char *
11960get_gnu_elf_note_type (unsigned e_type)
11961{
11962 static char buff[64];
11963
11964 switch (e_type)
11965 {
11966 case NT_GNU_ABI_TAG:
11967 return _("NT_GNU_ABI_TAG (ABI version tag)");
11968 case NT_GNU_HWCAP:
11969 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
11970 case NT_GNU_BUILD_ID:
11971 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
11972 case NT_GNU_GOLD_VERSION:
11973 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
11974 default:
11975 break;
11976 }
11977
11978 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
11979 return buff;
11980}
11981
9437c45b 11982static const char *
d3ba0551 11983get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
11984{
11985 static char buff[64];
11986
b4db1224 11987 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
11988 {
11989 /* NetBSD core "procinfo" structure. */
11990 return _("NetBSD procinfo structure");
11991 }
11992
11993 /* As of Jan 2002 there are no other machine-independent notes
11994 defined for NetBSD core files. If the note type is less
11995 than the start of the machine-dependent note types, we don't
11996 understand it. */
11997
b4db1224 11998 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 11999 {
e9e44622 12000 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
12001 return buff;
12002 }
12003
12004 switch (elf_header.e_machine)
12005 {
12006 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
12007 and PT_GETFPREGS == mach+2. */
12008
12009 case EM_OLD_ALPHA:
12010 case EM_ALPHA:
12011 case EM_SPARC:
12012 case EM_SPARC32PLUS:
12013 case EM_SPARCV9:
12014 switch (e_type)
12015 {
2b692964 12016 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 12017 return _("PT_GETREGS (reg structure)");
2b692964 12018 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 12019 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12020 default:
12021 break;
12022 }
12023 break;
12024
12025 /* On all other arch's, PT_GETREGS == mach+1 and
12026 PT_GETFPREGS == mach+3. */
12027 default:
12028 switch (e_type)
12029 {
2b692964 12030 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 12031 return _("PT_GETREGS (reg structure)");
2b692964 12032 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 12033 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12034 default:
12035 break;
12036 }
12037 }
12038
e9e44622
JJ
12039 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
12040 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
12041 return buff;
12042}
12043
6d118b09
NC
12044/* Note that by the ELF standard, the name field is already null byte
12045 terminated, and namesz includes the terminating null byte.
12046 I.E. the value of namesz for the name "FSF" is 4.
12047
e3c8793a 12048 If the value of namesz is zero, there is no name present. */
779fe533 12049static int
2cf0635d 12050process_note (Elf_Internal_Note * pnote)
779fe533 12051{
2cf0635d
NC
12052 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
12053 const char * nt;
9437c45b
JT
12054
12055 if (pnote->namesz == 0)
1ec5cd37
NC
12056 /* If there is no note name, then use the default set of
12057 note type strings. */
12058 nt = get_note_type (pnote->type);
12059
1118d252
RM
12060 else if (const_strneq (pnote->namedata, "GNU"))
12061 /* GNU-specific object file notes. */
12062 nt = get_gnu_elf_note_type (pnote->type);
12063
0112cd26 12064 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
12065 /* NetBSD-specific core file notes. */
12066 nt = get_netbsd_elfcore_note_type (pnote->type);
12067
b15fa79e
AM
12068 else if (strneq (pnote->namedata, "SPU/", 4))
12069 {
12070 /* SPU-specific core file notes. */
12071 nt = pnote->namedata + 4;
12072 name = "SPU";
12073 }
12074
9437c45b 12075 else
1ec5cd37
NC
12076 /* Don't recognize this note name; just use the default set of
12077 note type strings. */
9437c45b 12078 nt = get_note_type (pnote->type);
9437c45b 12079
b15fa79e 12080 printf (" %s\t\t0x%08lx\t%s\n", name, pnote->descsz, nt);
779fe533
NC
12081 return 1;
12082}
12083
6d118b09 12084
779fe533 12085static int
2cf0635d 12086process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 12087{
2cf0635d
NC
12088 Elf_External_Note * pnotes;
12089 Elf_External_Note * external;
b34976b6 12090 int res = 1;
103f02d3 12091
779fe533
NC
12092 if (length <= 0)
12093 return 0;
103f02d3 12094
3f5e193b
NC
12095 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
12096 _("notes"));
dd24e3da 12097 if (pnotes == NULL)
a6e9f9df 12098 return 0;
779fe533 12099
103f02d3 12100 external = pnotes;
103f02d3 12101
305c7206 12102 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 12103 (unsigned long) offset, (unsigned long) length);
779fe533 12104 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 12105
2cf0635d 12106 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 12107 {
2cf0635d 12108 Elf_External_Note * next;
b34976b6 12109 Elf_Internal_Note inote;
2cf0635d 12110 char * temp = NULL;
6d118b09
NC
12111
12112 inote.type = BYTE_GET (external->type);
12113 inote.namesz = BYTE_GET (external->namesz);
12114 inote.namedata = external->name;
12115 inote.descsz = BYTE_GET (external->descsz);
12116 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
12117 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 12118
2cf0635d 12119 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
3e55a963 12120
dd24e3da
NC
12121 if ( ((char *) next > ((char *) pnotes) + length)
12122 || ((char *) next < (char *) pnotes))
3e55a963 12123 {
0fd3a477 12124 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 12125 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 12126 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
12127 inote.type, inote.namesz, inote.descsz);
12128 break;
12129 }
12130
12131 external = next;
6d118b09 12132
dd24e3da
NC
12133 /* Prevent out-of-bounds indexing. */
12134 if (inote.namedata + inote.namesz >= (char *) pnotes + length
12135 || inote.namedata + inote.namesz < inote.namedata)
12136 {
12137 warn (_("corrupt note found at offset %lx into core notes\n"),
12138 (unsigned long) ((char *) external - (char *) pnotes));
12139 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
12140 inote.type, inote.namesz, inote.descsz);
12141 break;
12142 }
12143
6d118b09
NC
12144 /* Verify that name is null terminated. It appears that at least
12145 one version of Linux (RedHat 6.0) generates corefiles that don't
12146 comply with the ELF spec by failing to include the null byte in
12147 namesz. */
12148 if (inote.namedata[inote.namesz] != '\0')
12149 {
3f5e193b 12150 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 12151
6d118b09
NC
12152 if (temp == NULL)
12153 {
12154 error (_("Out of memory\n"));
12155 res = 0;
12156 break;
12157 }
76da6bbe 12158
6d118b09
NC
12159 strncpy (temp, inote.namedata, inote.namesz);
12160 temp[inote.namesz] = 0;
76da6bbe 12161
6d118b09
NC
12162 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
12163 inote.namedata = temp;
12164 }
12165
12166 res &= process_note (& inote);
103f02d3 12167
6d118b09
NC
12168 if (temp != NULL)
12169 {
12170 free (temp);
12171 temp = NULL;
12172 }
779fe533
NC
12173 }
12174
12175 free (pnotes);
103f02d3 12176
779fe533
NC
12177 return res;
12178}
12179
12180static int
2cf0635d 12181process_corefile_note_segments (FILE * file)
779fe533 12182{
2cf0635d 12183 Elf_Internal_Phdr * segment;
b34976b6
AM
12184 unsigned int i;
12185 int res = 1;
103f02d3 12186
d93f0186 12187 if (! get_program_headers (file))
779fe533 12188 return 0;
103f02d3 12189
779fe533
NC
12190 for (i = 0, segment = program_headers;
12191 i < elf_header.e_phnum;
b34976b6 12192 i++, segment++)
779fe533
NC
12193 {
12194 if (segment->p_type == PT_NOTE)
103f02d3 12195 res &= process_corefile_note_segment (file,
30800947
NC
12196 (bfd_vma) segment->p_offset,
12197 (bfd_vma) segment->p_filesz);
779fe533 12198 }
103f02d3 12199
779fe533
NC
12200 return res;
12201}
12202
12203static int
2cf0635d 12204process_note_sections (FILE * file)
1ec5cd37 12205{
2cf0635d 12206 Elf_Internal_Shdr * section;
1ec5cd37
NC
12207 unsigned long i;
12208 int res = 1;
12209
12210 for (i = 0, section = section_headers;
12211 i < elf_header.e_shnum;
12212 i++, section++)
12213 if (section->sh_type == SHT_NOTE)
12214 res &= process_corefile_note_segment (file,
12215 (bfd_vma) section->sh_offset,
12216 (bfd_vma) section->sh_size);
12217
12218 return res;
12219}
12220
12221static int
2cf0635d 12222process_notes (FILE * file)
779fe533
NC
12223{
12224 /* If we have not been asked to display the notes then do nothing. */
12225 if (! do_notes)
12226 return 1;
103f02d3 12227
779fe533 12228 if (elf_header.e_type != ET_CORE)
1ec5cd37 12229 return process_note_sections (file);
103f02d3 12230
779fe533 12231 /* No program headers means no NOTE segment. */
1ec5cd37
NC
12232 if (elf_header.e_phnum > 0)
12233 return process_corefile_note_segments (file);
779fe533 12234
1ec5cd37
NC
12235 printf (_("No note segments present in the core file.\n"));
12236 return 1;
779fe533
NC
12237}
12238
252b5132 12239static int
2cf0635d 12240process_arch_specific (FILE * file)
252b5132 12241{
a952a375
NC
12242 if (! do_arch)
12243 return 1;
12244
252b5132
RH
12245 switch (elf_header.e_machine)
12246 {
11c1ff18
PB
12247 case EM_ARM:
12248 return process_arm_specific (file);
252b5132 12249 case EM_MIPS:
4fe85591 12250 case EM_MIPS_RS3_LE:
252b5132
RH
12251 return process_mips_specific (file);
12252 break;
34c8bcba
JM
12253 case EM_PPC:
12254 return process_power_specific (file);
12255 break;
59e6276b
JM
12256 case EM_TI_C6000:
12257 return process_tic6x_specific (file);
12258 break;
252b5132
RH
12259 default:
12260 break;
12261 }
12262 return 1;
12263}
12264
12265static int
2cf0635d 12266get_file_header (FILE * file)
252b5132 12267{
9ea033b2
NC
12268 /* Read in the identity array. */
12269 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
12270 return 0;
12271
9ea033b2 12272 /* Determine how to read the rest of the header. */
b34976b6 12273 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
12274 {
12275 default: /* fall through */
12276 case ELFDATANONE: /* fall through */
adab8cdc
AO
12277 case ELFDATA2LSB:
12278 byte_get = byte_get_little_endian;
12279 byte_put = byte_put_little_endian;
12280 break;
12281 case ELFDATA2MSB:
12282 byte_get = byte_get_big_endian;
12283 byte_put = byte_put_big_endian;
12284 break;
9ea033b2
NC
12285 }
12286
12287 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 12288 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
12289
12290 /* Read in the rest of the header. */
12291 if (is_32bit_elf)
12292 {
12293 Elf32_External_Ehdr ehdr32;
252b5132 12294
9ea033b2
NC
12295 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
12296 return 0;
103f02d3 12297
9ea033b2
NC
12298 elf_header.e_type = BYTE_GET (ehdr32.e_type);
12299 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
12300 elf_header.e_version = BYTE_GET (ehdr32.e_version);
12301 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
12302 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
12303 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
12304 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
12305 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
12306 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
12307 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
12308 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
12309 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
12310 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
12311 }
252b5132 12312 else
9ea033b2
NC
12313 {
12314 Elf64_External_Ehdr ehdr64;
a952a375
NC
12315
12316 /* If we have been compiled with sizeof (bfd_vma) == 4, then
12317 we will not be able to cope with the 64bit data found in
12318 64 ELF files. Detect this now and abort before we start
50c2245b 12319 overwriting things. */
a952a375
NC
12320 if (sizeof (bfd_vma) < 8)
12321 {
e3c8793a
NC
12322 error (_("This instance of readelf has been built without support for a\n\
1232364 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
12324 return 0;
12325 }
103f02d3 12326
9ea033b2
NC
12327 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
12328 return 0;
103f02d3 12329
9ea033b2
NC
12330 elf_header.e_type = BYTE_GET (ehdr64.e_type);
12331 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
12332 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
12333 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
12334 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
12335 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
12336 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
12337 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
12338 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
12339 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
12340 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
12341 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
12342 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
12343 }
252b5132 12344
7ece0d85
JJ
12345 if (elf_header.e_shoff)
12346 {
12347 /* There may be some extensions in the first section header. Don't
12348 bomb if we can't read it. */
12349 if (is_32bit_elf)
12350 get_32bit_section_headers (file, 1);
12351 else
12352 get_64bit_section_headers (file, 1);
12353 }
560f3c1c 12354
252b5132
RH
12355 return 1;
12356}
12357
fb52b2f4
NC
12358/* Process one ELF object file according to the command line options.
12359 This file may actually be stored in an archive. The file is
12360 positioned at the start of the ELF object. */
12361
ff78d6d6 12362static int
2cf0635d 12363process_object (char * file_name, FILE * file)
252b5132 12364{
252b5132
RH
12365 unsigned int i;
12366
252b5132
RH
12367 if (! get_file_header (file))
12368 {
12369 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 12370 return 1;
252b5132
RH
12371 }
12372
12373 /* Initialise per file variables. */
60bca95a 12374 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
12375 version_info[i] = 0;
12376
60bca95a 12377 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132
RH
12378 dynamic_info[i] = 0;
12379
12380 /* Process the file. */
12381 if (show_name)
12382 printf (_("\nFile: %s\n"), file_name);
12383
18bd398b
NC
12384 /* Initialise the dump_sects array from the cmdline_dump_sects array.
12385 Note we do this even if cmdline_dump_sects is empty because we
12386 must make sure that the dump_sets array is zeroed out before each
12387 object file is processed. */
12388 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 12389 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
12390
12391 if (num_cmdline_dump_sects > 0)
12392 {
12393 if (num_dump_sects == 0)
12394 /* A sneaky way of allocating the dump_sects array. */
09c11c86 12395 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
12396
12397 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
12398 memcpy (dump_sects, cmdline_dump_sects,
12399 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 12400 }
d70c5fc7 12401
252b5132 12402 if (! process_file_header ())
fb52b2f4 12403 return 1;
252b5132 12404
d1f5c6e3 12405 if (! process_section_headers (file))
2f62977e 12406 {
d1f5c6e3
L
12407 /* Without loaded section headers we cannot process lots of
12408 things. */
2f62977e 12409 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 12410
2f62977e 12411 if (! do_using_dynamic)
2c610e4b 12412 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 12413 }
252b5132 12414
d1f5c6e3
L
12415 if (! process_section_groups (file))
12416 {
12417 /* Without loaded section groups we cannot process unwind. */
12418 do_unwind = 0;
12419 }
12420
2f62977e 12421 if (process_program_headers (file))
b2d38a17 12422 process_dynamic_section (file);
252b5132
RH
12423
12424 process_relocs (file);
12425
4d6ed7c8
NC
12426 process_unwind (file);
12427
252b5132
RH
12428 process_symbol_table (file);
12429
12430 process_syminfo (file);
12431
12432 process_version_sections (file);
12433
12434 process_section_contents (file);
f5842774 12435
1ec5cd37 12436 process_notes (file);
103f02d3 12437
047b2264
JJ
12438 process_gnu_liblist (file);
12439
252b5132
RH
12440 process_arch_specific (file);
12441
d93f0186
NC
12442 if (program_headers)
12443 {
12444 free (program_headers);
12445 program_headers = NULL;
12446 }
12447
252b5132
RH
12448 if (section_headers)
12449 {
12450 free (section_headers);
12451 section_headers = NULL;
12452 }
12453
12454 if (string_table)
12455 {
12456 free (string_table);
12457 string_table = NULL;
d40ac9bd 12458 string_table_length = 0;
252b5132
RH
12459 }
12460
12461 if (dynamic_strings)
12462 {
12463 free (dynamic_strings);
12464 dynamic_strings = NULL;
d79b3d50 12465 dynamic_strings_length = 0;
252b5132
RH
12466 }
12467
12468 if (dynamic_symbols)
12469 {
12470 free (dynamic_symbols);
12471 dynamic_symbols = NULL;
19936277 12472 num_dynamic_syms = 0;
252b5132
RH
12473 }
12474
12475 if (dynamic_syminfo)
12476 {
12477 free (dynamic_syminfo);
12478 dynamic_syminfo = NULL;
12479 }
ff78d6d6 12480
e4b17d5c
L
12481 if (section_headers_groups)
12482 {
12483 free (section_headers_groups);
12484 section_headers_groups = NULL;
12485 }
12486
12487 if (section_groups)
12488 {
2cf0635d
NC
12489 struct group_list * g;
12490 struct group_list * next;
e4b17d5c
L
12491
12492 for (i = 0; i < group_count; i++)
12493 {
12494 for (g = section_groups [i].root; g != NULL; g = next)
12495 {
12496 next = g->next;
12497 free (g);
12498 }
12499 }
12500
12501 free (section_groups);
12502 section_groups = NULL;
12503 }
12504
19e6b90e 12505 free_debug_memory ();
18bd398b 12506
ff78d6d6 12507 return 0;
252b5132
RH
12508}
12509
2cf0635d
NC
12510/* Return the path name for a proxy entry in a thin archive, adjusted relative
12511 to the path name of the thin archive itself if necessary. Always returns
12512 a pointer to malloc'ed memory. */
12513
12514static char *
12515adjust_relative_path (char * file_name, char * name, int name_len)
12516{
12517 char * member_file_name;
12518 const char * base_name = lbasename (file_name);
12519
12520 /* This is a proxy entry for a thin archive member.
12521 If the extended name table contains an absolute path
12522 name, or if the archive is in the current directory,
12523 use the path name as given. Otherwise, we need to
12524 find the member relative to the directory where the
12525 archive is located. */
12526 if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
12527 {
3f5e193b 12528 member_file_name = (char *) malloc (name_len + 1);
2cf0635d
NC
12529 if (member_file_name == NULL)
12530 {
12531 error (_("Out of memory\n"));
12532 return NULL;
12533 }
12534 memcpy (member_file_name, name, name_len);
12535 member_file_name[name_len] = '\0';
12536 }
12537 else
12538 {
12539 /* Concatenate the path components of the archive file name
12540 to the relative path name from the extended name table. */
12541 size_t prefix_len = base_name - file_name;
3f5e193b 12542 member_file_name = (char *) malloc (prefix_len + name_len + 1);
2cf0635d
NC
12543 if (member_file_name == NULL)
12544 {
12545 error (_("Out of memory\n"));
12546 return NULL;
12547 }
12548 memcpy (member_file_name, file_name, prefix_len);
12549 memcpy (member_file_name + prefix_len, name, name_len);
12550 member_file_name[prefix_len + name_len] = '\0';
12551 }
12552 return member_file_name;
12553}
12554
12555/* Structure to hold information about an archive file. */
12556
12557struct archive_info
12558{
12559 char * file_name; /* Archive file name. */
12560 FILE * file; /* Open file descriptor. */
12561 unsigned long index_num; /* Number of symbols in table. */
12562 unsigned long * index_array; /* The array of member offsets. */
12563 char * sym_table; /* The symbol table. */
12564 unsigned long sym_size; /* Size of the symbol table. */
12565 char * longnames; /* The long file names table. */
12566 unsigned long longnames_size; /* Size of the long file names table. */
12567 unsigned long nested_member_origin; /* Origin in the nested archive of the current member. */
12568 unsigned long next_arhdr_offset; /* Offset of the next archive header. */
12569 bfd_boolean is_thin_archive; /* TRUE if this is a thin archive. */
12570 struct ar_hdr arhdr; /* Current archive header. */
12571};
12572
12573/* Read the symbol table and long-name table from an archive. */
fb52b2f4
NC
12574
12575static int
2cf0635d
NC
12576setup_archive (struct archive_info * arch, char * file_name, FILE * file,
12577 bfd_boolean is_thin_archive, bfd_boolean read_symbols)
fb52b2f4 12578{
fb52b2f4
NC
12579 size_t got;
12580 unsigned long size;
fb52b2f4 12581
2cf0635d
NC
12582 arch->file_name = strdup (file_name);
12583 arch->file = file;
12584 arch->index_num = 0;
12585 arch->index_array = NULL;
12586 arch->sym_table = NULL;
12587 arch->sym_size = 0;
12588 arch->longnames = NULL;
12589 arch->longnames_size = 0;
12590 arch->nested_member_origin = 0;
12591 arch->is_thin_archive = is_thin_archive;
12592 arch->next_arhdr_offset = SARMAG;
12593
12594 /* Read the first archive member header. */
12595 if (fseek (file, SARMAG, SEEK_SET) != 0)
12596 {
12597 error (_("%s: failed to seek to first archive header\n"), file_name);
12598 return 1;
12599 }
12600 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
12601 if (got != sizeof arch->arhdr)
fb52b2f4
NC
12602 {
12603 if (got == 0)
12604 return 0;
12605
12606 error (_("%s: failed to read archive header\n"), file_name);
12607 return 1;
12608 }
12609
4145f1d5 12610 /* See if this is the archive symbol table. */
2cf0635d
NC
12611 if (const_strneq (arch->arhdr.ar_name, "/ ")
12612 || const_strneq (arch->arhdr.ar_name, "/SYM64/ "))
fb52b2f4 12613 {
2cf0635d 12614 size = strtoul (arch->arhdr.ar_size, NULL, 10);
4145f1d5
NC
12615 size = size + (size & 1);
12616
2cf0635d
NC
12617 arch->next_arhdr_offset += sizeof arch->arhdr + size;
12618
12619 if (read_symbols)
fb52b2f4 12620 {
4145f1d5
NC
12621 unsigned long i;
12622 /* A buffer used to hold numbers read in from an archive index.
12623 These are always 4 bytes long and stored in big-endian format. */
12624#define SIZEOF_AR_INDEX_NUMBERS 4
12625 unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
12626 unsigned char * index_buffer;
12627
12628 /* Check the size of the archive index. */
12629 if (size < SIZEOF_AR_INDEX_NUMBERS)
12630 {
12631 error (_("%s: the archive index is empty\n"), file_name);
12632 return 1;
12633 }
12634
12635 /* Read the numer of entries in the archive index. */
12636 got = fread (integer_buffer, 1, sizeof integer_buffer, file);
12637 if (got != sizeof (integer_buffer))
12638 {
12639 error (_("%s: failed to read archive index\n"), file_name);
12640 return 1;
12641 }
2cf0635d 12642 arch->index_num = byte_get_big_endian (integer_buffer, sizeof integer_buffer);
4145f1d5
NC
12643 size -= SIZEOF_AR_INDEX_NUMBERS;
12644
12645 /* Read in the archive index. */
2cf0635d 12646 if (size < arch->index_num * SIZEOF_AR_INDEX_NUMBERS)
4145f1d5
NC
12647 {
12648 error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
2cf0635d 12649 file_name, arch->index_num);
4145f1d5
NC
12650 return 1;
12651 }
3f5e193b
NC
12652 index_buffer = (unsigned char *)
12653 malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
12654 if (index_buffer == NULL)
12655 {
12656 error (_("Out of memory whilst trying to read archive symbol index\n"));
12657 return 1;
12658 }
2cf0635d
NC
12659 got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, arch->index_num, file);
12660 if (got != arch->index_num)
4145f1d5
NC
12661 {
12662 free (index_buffer);
12663 error (_("%s: failed to read archive index\n"), file_name);
2cf0635d 12664 return 1;
4145f1d5 12665 }
2cf0635d 12666 size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS;
4145f1d5
NC
12667
12668 /* Convert the index numbers into the host's numeric format. */
3f5e193b
NC
12669 arch->index_array = (long unsigned int *)
12670 malloc (arch->index_num * sizeof (* arch->index_array));
2cf0635d 12671 if (arch->index_array == NULL)
4145f1d5
NC
12672 {
12673 free (index_buffer);
12674 error (_("Out of memory whilst trying to convert the archive symbol index\n"));
12675 return 1;
12676 }
12677
2cf0635d
NC
12678 for (i = 0; i < arch->index_num; i++)
12679 arch->index_array[i] = byte_get_big_endian ((unsigned char *) (index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
12680 SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
12681 free (index_buffer);
12682
12683 /* The remaining space in the header is taken up by the symbol table. */
12684 if (size < 1)
12685 {
12686 error (_("%s: the archive has an index but no symbols\n"), file_name);
2cf0635d 12687 return 1;
4145f1d5 12688 }
3f5e193b 12689 arch->sym_table = (char *) malloc (size);
2cf0635d
NC
12690 arch->sym_size = size;
12691 if (arch->sym_table == NULL)
4145f1d5
NC
12692 {
12693 error (_("Out of memory whilst trying to read archive index symbol table\n"));
2cf0635d 12694 return 1;
4145f1d5 12695 }
2cf0635d 12696 got = fread (arch->sym_table, 1, size, file);
4145f1d5
NC
12697 if (got != size)
12698 {
12699 error (_("%s: failed to read archive index symbol table\n"), file_name);
2cf0635d 12700 return 1;
cb8f3167 12701 }
4145f1d5
NC
12702 }
12703 else
12704 {
12705 if (fseek (file, size, SEEK_CUR) != 0)
12706 {
12707 error (_("%s: failed to skip archive symbol table\n"), file_name);
12708 return 1;
12709 }
fb52b2f4
NC
12710 }
12711
2cf0635d
NC
12712 /* Read the next archive header. */
12713 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
12714 if (got != sizeof arch->arhdr)
fb52b2f4
NC
12715 {
12716 if (got == 0)
2cf0635d 12717 return 0;
4145f1d5 12718 error (_("%s: failed to read archive header following archive index\n"), file_name);
2cf0635d 12719 return 1;
fb52b2f4
NC
12720 }
12721 }
2cf0635d 12722 else if (read_symbols)
4145f1d5 12723 printf (_("%s has no archive index\n"), file_name);
fb52b2f4 12724
2cf0635d 12725 if (const_strneq (arch->arhdr.ar_name, "// "))
fb52b2f4 12726 {
2cf0635d
NC
12727 /* This is the archive string table holding long member names. */
12728 arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
12729 arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
fb52b2f4 12730
3f5e193b 12731 arch->longnames = (char *) malloc (arch->longnames_size);
2cf0635d 12732 if (arch->longnames == NULL)
fb52b2f4 12733 {
4145f1d5 12734 error (_("Out of memory reading long symbol names in archive\n"));
2cf0635d 12735 return 1;
fb52b2f4
NC
12736 }
12737
2cf0635d 12738 if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
fb52b2f4 12739 {
2cf0635d
NC
12740 free (arch->longnames);
12741 arch->longnames = NULL;
4145f1d5 12742 error (_("%s: failed to read long symbol name string table\n"), file_name);
2cf0635d 12743 return 1;
fb52b2f4
NC
12744 }
12745
2cf0635d 12746 if ((arch->longnames_size & 1) != 0)
fb52b2f4 12747 getc (file);
2cf0635d 12748 }
fb52b2f4 12749
2cf0635d
NC
12750 return 0;
12751}
12752
12753/* Release the memory used for the archive information. */
12754
12755static void
12756release_archive (struct archive_info * arch)
12757{
12758 if (arch->file_name != NULL)
12759 free (arch->file_name);
12760 if (arch->index_array != NULL)
12761 free (arch->index_array);
12762 if (arch->sym_table != NULL)
12763 free (arch->sym_table);
12764 if (arch->longnames != NULL)
12765 free (arch->longnames);
12766}
12767
12768/* Open and setup a nested archive, if not already open. */
12769
12770static int
12771setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
12772{
12773 FILE * member_file;
12774
12775 /* Have we already setup this archive? */
12776 if (nested_arch->file_name != NULL
12777 && streq (nested_arch->file_name, member_file_name))
12778 return 0;
12779
12780 /* Close previous file and discard cached information. */
12781 if (nested_arch->file != NULL)
12782 fclose (nested_arch->file);
12783 release_archive (nested_arch);
12784
12785 member_file = fopen (member_file_name, "rb");
12786 if (member_file == NULL)
12787 return 1;
12788 return setup_archive (nested_arch, member_file_name, member_file, FALSE, FALSE);
12789}
12790
12791static char *
12792get_archive_member_name_at (struct archive_info * arch,
12793 unsigned long offset,
12794 struct archive_info * nested_arch);
12795
12796/* Get the name of an archive member from the current archive header.
12797 For simple names, this will modify the ar_name field of the current
12798 archive header. For long names, it will return a pointer to the
12799 longnames table. For nested archives, it will open the nested archive
12800 and get the name recursively. NESTED_ARCH is a single-entry cache so
12801 we don't keep rereading the same information from a nested archive. */
12802
12803static char *
12804get_archive_member_name (struct archive_info * arch,
12805 struct archive_info * nested_arch)
12806{
12807 unsigned long j, k;
12808
12809 if (arch->arhdr.ar_name[0] == '/')
12810 {
12811 /* We have a long name. */
12812 char * endp;
12813 char * member_file_name;
12814 char * member_name;
12815
12816 arch->nested_member_origin = 0;
12817 k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
12818 if (arch->is_thin_archive && endp != NULL && * endp == ':')
12819 arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
12820
12821 while ((j < arch->longnames_size)
12822 && (arch->longnames[j] != '\n')
12823 && (arch->longnames[j] != '\0'))
12824 j++;
12825 if (arch->longnames[j-1] == '/')
12826 j--;
12827 arch->longnames[j] = '\0';
12828
12829 if (!arch->is_thin_archive || arch->nested_member_origin == 0)
12830 return arch->longnames + k;
12831
12832 /* This is a proxy for a member of a nested archive.
12833 Find the name of the member in that archive. */
3832723d
AM
12834 member_file_name = adjust_relative_path (arch->file_name,
12835 arch->longnames + k, j - k);
2cf0635d 12836 if (member_file_name != NULL
3832723d
AM
12837 && setup_nested_archive (nested_arch, member_file_name) == 0)
12838 {
12839 member_name = get_archive_member_name_at (nested_arch,
12840 arch->nested_member_origin,
12841 NULL);
12842 if (member_name != NULL)
12843 {
12844 free (member_file_name);
12845 return member_name;
12846 }
12847 }
2cf0635d
NC
12848 free (member_file_name);
12849
12850 /* Last resort: just return the name of the nested archive. */
12851 return arch->longnames + k;
12852 }
12853
12854 /* We have a normal (short) name. */
3832723d
AM
12855 for (j = 0; j < sizeof (arch->arhdr.ar_name); j++)
12856 if (arch->arhdr.ar_name[j] == '/')
12857 {
12858 arch->arhdr.ar_name[j] = '\0';
12859 return arch->arhdr.ar_name;
12860 }
12861
12862 /* The full ar_name field is used. Don't rely on ar_date starting
12863 with a zero byte. */
12864 {
12865 char *name = xmalloc (sizeof (arch->arhdr.ar_name) + 1);
12866 memcpy (name, arch->arhdr.ar_name, sizeof (arch->arhdr.ar_name));
12867 name[sizeof (arch->arhdr.ar_name)] = '\0';
12868 return name;
12869 }
2cf0635d
NC
12870}
12871
12872/* Get the name of an archive member at a given OFFSET within an archive ARCH. */
12873
12874static char *
12875get_archive_member_name_at (struct archive_info * arch,
12876 unsigned long offset,
12877 struct archive_info * nested_arch)
12878{
12879 size_t got;
12880
12881 if (fseek (arch->file, offset, SEEK_SET) != 0)
12882 {
12883 error (_("%s: failed to seek to next file name\n"), arch->file_name);
12884 return NULL;
12885 }
12886 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
12887 if (got != sizeof arch->arhdr)
12888 {
12889 error (_("%s: failed to read archive header\n"), arch->file_name);
12890 return NULL;
12891 }
12892 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
12893 {
12894 error (_("%s: did not find a valid archive header\n"), arch->file_name);
12895 return NULL;
12896 }
12897
12898 return get_archive_member_name (arch, nested_arch);
12899}
12900
12901/* Construct a string showing the name of the archive member, qualified
12902 with the name of the containing archive file. For thin archives, we
12903 use square brackets to denote the indirection. For nested archives,
12904 we show the qualified name of the external member inside the square
12905 brackets (e.g., "thin.a[normal.a(foo.o)]"). */
12906
12907static char *
12908make_qualified_name (struct archive_info * arch,
12909 struct archive_info * nested_arch,
12910 char * member_name)
12911{
12912 size_t len;
12913 char * name;
12914
12915 len = strlen (arch->file_name) + strlen (member_name) + 3;
12916 if (arch->is_thin_archive && arch->nested_member_origin != 0)
12917 len += strlen (nested_arch->file_name) + 2;
12918
3f5e193b 12919 name = (char *) malloc (len);
2cf0635d
NC
12920 if (name == NULL)
12921 {
12922 error (_("Out of memory\n"));
12923 return NULL;
12924 }
12925
12926 if (arch->is_thin_archive && arch->nested_member_origin != 0)
12927 snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name);
12928 else if (arch->is_thin_archive)
12929 snprintf (name, len, "%s[%s]", arch->file_name, member_name);
12930 else
12931 snprintf (name, len, "%s(%s)", arch->file_name, member_name);
12932
12933 return name;
12934}
12935
12936/* Process an ELF archive.
12937 On entry the file is positioned just after the ARMAG string. */
12938
12939static int
12940process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
12941{
12942 struct archive_info arch;
12943 struct archive_info nested_arch;
12944 size_t got;
2cf0635d
NC
12945 int ret;
12946
12947 show_name = 1;
12948
12949 /* The ARCH structure is used to hold information about this archive. */
12950 arch.file_name = NULL;
12951 arch.file = NULL;
12952 arch.index_array = NULL;
12953 arch.sym_table = NULL;
12954 arch.longnames = NULL;
12955
12956 /* The NESTED_ARCH structure is used as a single-item cache of information
12957 about a nested archive (when members of a thin archive reside within
12958 another regular archive file). */
12959 nested_arch.file_name = NULL;
12960 nested_arch.file = NULL;
12961 nested_arch.index_array = NULL;
12962 nested_arch.sym_table = NULL;
12963 nested_arch.longnames = NULL;
12964
12965 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
12966 {
12967 ret = 1;
12968 goto out;
4145f1d5 12969 }
fb52b2f4 12970
4145f1d5
NC
12971 if (do_archive_index)
12972 {
2cf0635d 12973 if (arch.sym_table == NULL)
4145f1d5
NC
12974 error (_("%s: unable to dump the index as none was found\n"), file_name);
12975 else
12976 {
2cf0635d 12977 unsigned int i, l;
4145f1d5
NC
12978 unsigned long current_pos;
12979
12980 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 12981 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
12982 current_pos = ftell (file);
12983
2cf0635d 12984 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 12985 {
2cf0635d
NC
12986 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
12987 {
12988 char * member_name;
4145f1d5 12989
2cf0635d
NC
12990 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
12991
12992 if (member_name != NULL)
12993 {
12994 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
12995
12996 if (qualified_name != NULL)
12997 {
12998 printf (_("Binary %s contains:\n"), qualified_name);
12999 free (qualified_name);
13000 }
4145f1d5
NC
13001 }
13002 }
2cf0635d
NC
13003
13004 if (l >= arch.sym_size)
4145f1d5
NC
13005 {
13006 error (_("%s: end of the symbol table reached before the end of the index\n"),
13007 file_name);
cb8f3167 13008 break;
4145f1d5 13009 }
2cf0635d
NC
13010 printf ("\t%s\n", arch.sym_table + l);
13011 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13012 }
13013
2cf0635d
NC
13014 if (l & 01)
13015 ++l;
13016 if (l < arch.sym_size)
4145f1d5
NC
13017 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
13018 file_name);
13019
4145f1d5
NC
13020 if (fseek (file, current_pos, SEEK_SET) != 0)
13021 {
13022 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13023 ret = 1;
13024 goto out;
4145f1d5 13025 }
fb52b2f4 13026 }
4145f1d5
NC
13027
13028 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13029 && !do_segments && !do_header && !do_dump && !do_version
13030 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13031 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13032 {
13033 ret = 0; /* Archive index only. */
13034 goto out;
13035 }
fb52b2f4
NC
13036 }
13037
d989285c 13038 ret = 0;
fb52b2f4
NC
13039
13040 while (1)
13041 {
2cf0635d
NC
13042 char * name;
13043 size_t namelen;
13044 char * qualified_name;
13045
13046 /* Read the next archive header. */
13047 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13048 {
13049 error (_("%s: failed to seek to next archive header\n"), file_name);
13050 return 1;
13051 }
13052 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13053 if (got != sizeof arch.arhdr)
13054 {
13055 if (got == 0)
13056 break;
13057 error (_("%s: failed to read archive header\n"), file_name);
13058 ret = 1;
13059 break;
13060 }
13061 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13062 {
13063 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13064 ret = 1;
13065 break;
13066 }
13067
13068 arch.next_arhdr_offset += sizeof arch.arhdr;
13069
13070 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13071 if (archive_file_size & 01)
13072 ++archive_file_size;
13073
13074 name = get_archive_member_name (&arch, &nested_arch);
13075 if (name == NULL)
fb52b2f4 13076 {
0fd3a477 13077 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13078 ret = 1;
13079 break;
fb52b2f4 13080 }
2cf0635d 13081 namelen = strlen (name);
fb52b2f4 13082
2cf0635d
NC
13083 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13084 if (qualified_name == NULL)
fb52b2f4 13085 {
2cf0635d 13086 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13087 ret = 1;
13088 break;
fb52b2f4
NC
13089 }
13090
2cf0635d
NC
13091 if (is_thin_archive && arch.nested_member_origin == 0)
13092 {
13093 /* This is a proxy for an external member of a thin archive. */
13094 FILE * member_file;
13095 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13096 if (member_file_name == NULL)
13097 {
13098 ret = 1;
13099 break;
13100 }
13101
13102 member_file = fopen (member_file_name, "rb");
13103 if (member_file == NULL)
13104 {
13105 error (_("Input file '%s' is not readable.\n"), member_file_name);
13106 free (member_file_name);
13107 ret = 1;
13108 break;
13109 }
13110
13111 archive_file_offset = arch.nested_member_origin;
13112
13113 ret |= process_object (qualified_name, member_file);
13114
13115 fclose (member_file);
13116 free (member_file_name);
13117 }
13118 else if (is_thin_archive)
13119 {
13120 /* This is a proxy for a member of a nested archive. */
13121 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
13122
13123 /* The nested archive file will have been opened and setup by
13124 get_archive_member_name. */
13125 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
13126 {
13127 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
13128 ret = 1;
13129 break;
13130 }
13131
13132 ret |= process_object (qualified_name, nested_arch.file);
13133 }
13134 else
13135 {
13136 archive_file_offset = arch.next_arhdr_offset;
13137 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 13138
2cf0635d
NC
13139 ret |= process_object (qualified_name, file);
13140 }
fb52b2f4 13141
2cf0635d 13142 free (qualified_name);
fb52b2f4
NC
13143 }
13144
4145f1d5 13145 out:
2cf0635d
NC
13146 if (nested_arch.file != NULL)
13147 fclose (nested_arch.file);
13148 release_archive (&nested_arch);
13149 release_archive (&arch);
fb52b2f4 13150
d989285c 13151 return ret;
fb52b2f4
NC
13152}
13153
13154static int
2cf0635d 13155process_file (char * file_name)
fb52b2f4 13156{
2cf0635d 13157 FILE * file;
fb52b2f4
NC
13158 struct stat statbuf;
13159 char armag[SARMAG];
13160 int ret;
13161
13162 if (stat (file_name, &statbuf) < 0)
13163 {
f24ddbdd
NC
13164 if (errno == ENOENT)
13165 error (_("'%s': No such file\n"), file_name);
13166 else
13167 error (_("Could not locate '%s'. System error message: %s\n"),
13168 file_name, strerror (errno));
13169 return 1;
13170 }
13171
13172 if (! S_ISREG (statbuf.st_mode))
13173 {
13174 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
13175 return 1;
13176 }
13177
13178 file = fopen (file_name, "rb");
13179 if (file == NULL)
13180 {
f24ddbdd 13181 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
13182 return 1;
13183 }
13184
13185 if (fread (armag, SARMAG, 1, file) != 1)
13186 {
4145f1d5 13187 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
13188 fclose (file);
13189 return 1;
13190 }
13191
13192 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
13193 ret = process_archive (file_name, file, FALSE);
13194 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
13195 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
13196 else
13197 {
4145f1d5
NC
13198 if (do_archive_index)
13199 error (_("File %s is not an archive so its index cannot be displayed.\n"),
13200 file_name);
13201
fb52b2f4
NC
13202 rewind (file);
13203 archive_file_size = archive_file_offset = 0;
13204 ret = process_object (file_name, file);
13205 }
13206
13207 fclose (file);
13208
13209 return ret;
13210}
13211
252b5132
RH
13212#ifdef SUPPORT_DISASSEMBLY
13213/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 13214 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 13215 symbols. */
252b5132
RH
13216
13217void
2cf0635d 13218print_address (unsigned int addr, FILE * outfile)
252b5132
RH
13219{
13220 fprintf (outfile,"0x%8.8x", addr);
13221}
13222
e3c8793a 13223/* Needed by the i386 disassembler. */
252b5132
RH
13224void
13225db_task_printsym (unsigned int addr)
13226{
13227 print_address (addr, stderr);
13228}
13229#endif
13230
13231int
2cf0635d 13232main (int argc, char ** argv)
252b5132 13233{
ff78d6d6
L
13234 int err;
13235
252b5132
RH
13236#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
13237 setlocale (LC_MESSAGES, "");
3882b010
L
13238#endif
13239#if defined (HAVE_SETLOCALE)
13240 setlocale (LC_CTYPE, "");
252b5132
RH
13241#endif
13242 bindtextdomain (PACKAGE, LOCALEDIR);
13243 textdomain (PACKAGE);
13244
869b9d07
MM
13245 expandargv (&argc, &argv);
13246
252b5132
RH
13247 parse_args (argc, argv);
13248
18bd398b 13249 if (num_dump_sects > 0)
59f14fc0 13250 {
18bd398b 13251 /* Make a copy of the dump_sects array. */
3f5e193b
NC
13252 cmdline_dump_sects = (dump_type *)
13253 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 13254 if (cmdline_dump_sects == NULL)
591a748a 13255 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
13256 else
13257 {
09c11c86
NC
13258 memcpy (cmdline_dump_sects, dump_sects,
13259 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
13260 num_cmdline_dump_sects = num_dump_sects;
13261 }
13262 }
13263
18bd398b
NC
13264 if (optind < (argc - 1))
13265 show_name = 1;
13266
ff78d6d6 13267 err = 0;
252b5132 13268 while (optind < argc)
18bd398b 13269 err |= process_file (argv[optind++]);
252b5132
RH
13270
13271 if (dump_sects != NULL)
13272 free (dump_sects);
59f14fc0
AS
13273 if (cmdline_dump_sects != NULL)
13274 free (cmdline_dump_sects);
252b5132 13275
ff78d6d6 13276 return err;
252b5132 13277}