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