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