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