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