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