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