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