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