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