]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
* elf32-m68k.c (elf_m68k_final_write_processing): New function.
[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
3974 case EM_OLD_SPARCV9:
3975 case EM_SPARC32PLUS:
3976 case EM_SPARCV9:
3977 case EM_SPARC:
3978 if (flag == SHF_EXCLUDE)
3979 index = 18;
3980 else if (flag == SHF_ORDERED)
3981 index = 19;
3982 break;
3983 default:
3984 break;
148b93f2 3985 }
5477e8a0
L
3986 }
3987
5477e8a0
L
3988 if (index != -1)
3989 {
8d5ff12c
L
3990 if (p != buff + field_size + 4)
3991 {
3992 if (size < (10 + 2))
3993 abort ();
3994 size -= 2;
3995 *p++ = ',';
3996 *p++ = ' ';
3997 }
3998
5477e8a0
L
3999 size -= flags [index].len;
4000 p = stpcpy (p, flags [index].str);
4001 }
3b22753a 4002 else if (flag & SHF_MASKOS)
8d5ff12c 4003 os_flags |= flag;
d1133906 4004 else if (flag & SHF_MASKPROC)
8d5ff12c 4005 proc_flags |= flag;
d1133906 4006 else
8d5ff12c 4007 unknown_flags |= flag;
5477e8a0
L
4008 }
4009 else
4010 {
4011 switch (flag)
4012 {
4013 case SHF_WRITE: *p = 'W'; break;
4014 case SHF_ALLOC: *p = 'A'; break;
4015 case SHF_EXECINSTR: *p = 'X'; break;
4016 case SHF_MERGE: *p = 'M'; break;
4017 case SHF_STRINGS: *p = 'S'; break;
4018 case SHF_INFO_LINK: *p = 'I'; break;
4019 case SHF_LINK_ORDER: *p = 'L'; break;
4020 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4021 case SHF_GROUP: *p = 'G'; break;
4022 case SHF_TLS: *p = 'T'; break;
4023
4024 default:
8a9036a4
L
4025 if ((elf_header.e_machine == EM_X86_64
4026 || elf_header.e_machine == EM_L1OM)
5477e8a0
L
4027 && flag == SHF_X86_64_LARGE)
4028 *p = 'l';
4029 else if (flag & SHF_MASKOS)
4030 {
4031 *p = 'o';
4032 sh_flags &= ~ SHF_MASKOS;
4033 }
4034 else if (flag & SHF_MASKPROC)
4035 {
4036 *p = 'p';
4037 sh_flags &= ~ SHF_MASKPROC;
4038 }
4039 else
4040 *p = 'x';
4041 break;
4042 }
4043 p++;
d1133906
NC
4044 }
4045 }
76da6bbe 4046
8d5ff12c
L
4047 if (do_section_details)
4048 {
4049 if (os_flags)
4050 {
4051 size -= 5 + field_size;
4052 if (p != buff + field_size + 4)
4053 {
4054 if (size < (2 + 1))
4055 abort ();
4056 size -= 2;
4057 *p++ = ',';
4058 *p++ = ' ';
4059 }
4060 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4061 (unsigned long) os_flags);
4062 p += 5 + field_size;
4063 }
4064 if (proc_flags)
4065 {
4066 size -= 7 + field_size;
4067 if (p != buff + field_size + 4)
4068 {
4069 if (size < (2 + 1))
4070 abort ();
4071 size -= 2;
4072 *p++ = ',';
4073 *p++ = ' ';
4074 }
4075 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4076 (unsigned long) proc_flags);
4077 p += 7 + field_size;
4078 }
4079 if (unknown_flags)
4080 {
4081 size -= 10 + field_size;
4082 if (p != buff + field_size + 4)
4083 {
4084 if (size < (2 + 1))
4085 abort ();
4086 size -= 2;
4087 *p++ = ',';
4088 *p++ = ' ';
4089 }
4090 sprintf (p, "UNKNOWN (%*.*lx)", field_size, field_size,
4091 (unsigned long) unknown_flags);
4092 p += 10 + field_size;
4093 }
4094 }
4095
e9e44622 4096 *p = '\0';
d1133906
NC
4097 return buff;
4098}
4099
252b5132 4100static int
2cf0635d 4101process_section_headers (FILE * file)
252b5132 4102{
2cf0635d 4103 Elf_Internal_Shdr * section;
b34976b6 4104 unsigned int i;
252b5132
RH
4105
4106 section_headers = NULL;
4107
4108 if (elf_header.e_shnum == 0)
4109 {
4110 if (do_sections)
4111 printf (_("\nThere are no sections in this file.\n"));
4112
4113 return 1;
4114 }
4115
4116 if (do_sections && !do_header)
9ea033b2 4117 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4118 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4119
9ea033b2
NC
4120 if (is_32bit_elf)
4121 {
560f3c1c 4122 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4123 return 0;
4124 }
560f3c1c 4125 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4126 return 0;
4127
4128 /* Read in the string table, so that we have names to display. */
0b49d371 4129 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4130 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4131 {
4fbb74a6 4132 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4133
c256ffe7
JJ
4134 if (section->sh_size != 0)
4135 {
3f5e193b
NC
4136 string_table = (char *) get_data (NULL, file, section->sh_offset,
4137 1, section->sh_size,
4138 _("string table"));
0de14b54 4139
c256ffe7
JJ
4140 string_table_length = string_table != NULL ? section->sh_size : 0;
4141 }
252b5132
RH
4142 }
4143
4144 /* Scan the sections for the dynamic symbol table
e3c8793a 4145 and dynamic string table and debug sections. */
252b5132
RH
4146 dynamic_symbols = NULL;
4147 dynamic_strings = NULL;
4148 dynamic_syminfo = NULL;
f1ef08cb 4149 symtab_shndx_hdr = NULL;
103f02d3 4150
89fac5e3
RS
4151 eh_addr_size = is_32bit_elf ? 4 : 8;
4152 switch (elf_header.e_machine)
4153 {
4154 case EM_MIPS:
4155 case EM_MIPS_RS3_LE:
4156 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4157 FDE addresses. However, the ABI also has a semi-official ILP32
4158 variant for which the normal FDE address size rules apply.
4159
4160 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4161 section, where XX is the size of longs in bits. Unfortunately,
4162 earlier compilers provided no way of distinguishing ILP32 objects
4163 from LP64 objects, so if there's any doubt, we should assume that
4164 the official LP64 form is being used. */
4165 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4166 && find_section (".gcc_compiled_long32") == NULL)
4167 eh_addr_size = 8;
4168 break;
0f56a26a
DD
4169
4170 case EM_H8_300:
4171 case EM_H8_300H:
4172 switch (elf_header.e_flags & EF_H8_MACH)
4173 {
4174 case E_H8_MACH_H8300:
4175 case E_H8_MACH_H8300HN:
4176 case E_H8_MACH_H8300SN:
4177 case E_H8_MACH_H8300SXN:
4178 eh_addr_size = 2;
4179 break;
4180 case E_H8_MACH_H8300H:
4181 case E_H8_MACH_H8300S:
4182 case E_H8_MACH_H8300SX:
4183 eh_addr_size = 4;
4184 break;
4185 }
f4236fe4
DD
4186 break;
4187
ff7eeb89 4188 case EM_M32C_OLD:
f4236fe4
DD
4189 case EM_M32C:
4190 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4191 {
4192 case EF_M32C_CPU_M16C:
4193 eh_addr_size = 2;
4194 break;
4195 }
4196 break;
89fac5e3
RS
4197 }
4198
08d8fa11
JJ
4199#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4200 do \
4201 { \
4202 size_t expected_entsize \
4203 = is_32bit_elf ? size32 : size64; \
4204 if (section->sh_entsize != expected_entsize) \
4205 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4206 i, (unsigned long int) section->sh_entsize, \
4207 (unsigned long int) expected_entsize); \
4208 section->sh_entsize = expected_entsize; \
4209 } \
4210 while (0)
4211#define CHECK_ENTSIZE(section, i, type) \
4212 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4213 sizeof (Elf64_External_##type))
4214
252b5132
RH
4215 for (i = 0, section = section_headers;
4216 i < elf_header.e_shnum;
b34976b6 4217 i++, section++)
252b5132 4218 {
2cf0635d 4219 char * name = SECTION_NAME (section);
252b5132
RH
4220
4221 if (section->sh_type == SHT_DYNSYM)
4222 {
4223 if (dynamic_symbols != NULL)
4224 {
4225 error (_("File contains multiple dynamic symbol tables\n"));
4226 continue;
4227 }
4228
08d8fa11 4229 CHECK_ENTSIZE (section, i, Sym);
19936277 4230 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4231 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4232 }
4233 else if (section->sh_type == SHT_STRTAB
18bd398b 4234 && streq (name, ".dynstr"))
252b5132
RH
4235 {
4236 if (dynamic_strings != NULL)
4237 {
4238 error (_("File contains multiple dynamic string tables\n"));
4239 continue;
4240 }
4241
3f5e193b
NC
4242 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4243 1, section->sh_size,
4244 _("dynamic strings"));
d79b3d50 4245 dynamic_strings_length = section->sh_size;
252b5132 4246 }
9ad5cbcf
AM
4247 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4248 {
4249 if (symtab_shndx_hdr != NULL)
4250 {
4251 error (_("File contains multiple symtab shndx tables\n"));
4252 continue;
4253 }
4254 symtab_shndx_hdr = section;
4255 }
08d8fa11
JJ
4256 else if (section->sh_type == SHT_SYMTAB)
4257 CHECK_ENTSIZE (section, i, Sym);
4258 else if (section->sh_type == SHT_GROUP)
4259 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4260 else if (section->sh_type == SHT_REL)
4261 CHECK_ENTSIZE (section, i, Rel);
4262 else if (section->sh_type == SHT_RELA)
4263 CHECK_ENTSIZE (section, i, Rela);
252b5132 4264 else if ((do_debugging || do_debug_info || do_debug_abbrevs
4cb93e3b 4265 || do_debug_lines || do_debug_pubnames
cb8f3167 4266 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4267 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4268 && (const_strneq (name, ".debug_")
4269 || const_strneq (name, ".zdebug_")))
252b5132 4270 {
1b315056
CS
4271 if (name[1] == 'z')
4272 name += sizeof (".zdebug_") - 1;
4273 else
4274 name += sizeof (".debug_") - 1;
252b5132
RH
4275
4276 if (do_debugging
18bd398b 4277 || (do_debug_info && streq (name, "info"))
2b6f5997 4278 || (do_debug_info && streq (name, "types"))
18bd398b 4279 || (do_debug_abbrevs && streq (name, "abbrev"))
4cb93e3b 4280 || (do_debug_lines && streq (name, "line"))
18bd398b
NC
4281 || (do_debug_pubnames && streq (name, "pubnames"))
4282 || (do_debug_aranges && streq (name, "aranges"))
4283 || (do_debug_ranges && streq (name, "ranges"))
4284 || (do_debug_frames && streq (name, "frame"))
4285 || (do_debug_macinfo && streq (name, "macinfo"))
4286 || (do_debug_str && streq (name, "str"))
4287 || (do_debug_loc && streq (name, "loc"))
252b5132 4288 )
09c11c86 4289 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4290 }
a262ae96 4291 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4292 else if ((do_debugging || do_debug_info)
0112cd26 4293 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4294 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4295 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4296 request_dump_bynumber (i, DEBUG_DUMP);
252b5132
RH
4297 }
4298
4299 if (! do_sections)
4300 return 1;
4301
3a1a2036
NC
4302 if (elf_header.e_shnum > 1)
4303 printf (_("\nSection Headers:\n"));
4304 else
4305 printf (_("\nSection Header:\n"));
76da6bbe 4306
f7a99963 4307 if (is_32bit_elf)
595cf52e 4308 {
5477e8a0 4309 if (do_section_details)
595cf52e
L
4310 {
4311 printf (_(" [Nr] Name\n"));
5477e8a0 4312 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4313 }
4314 else
4315 printf
4316 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4317 }
d974e256 4318 else if (do_wide)
595cf52e 4319 {
5477e8a0 4320 if (do_section_details)
595cf52e
L
4321 {
4322 printf (_(" [Nr] Name\n"));
5477e8a0 4323 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4324 }
4325 else
4326 printf
4327 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4328 }
f7a99963
NC
4329 else
4330 {
5477e8a0 4331 if (do_section_details)
595cf52e
L
4332 {
4333 printf (_(" [Nr] Name\n"));
5477e8a0
L
4334 printf (_(" Type Address Offset Link\n"));
4335 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4336 }
4337 else
4338 {
4339 printf (_(" [Nr] Name Type Address Offset\n"));
4340 printf (_(" Size EntSize Flags Link Info Align\n"));
4341 }
f7a99963 4342 }
252b5132 4343
5477e8a0
L
4344 if (do_section_details)
4345 printf (_(" Flags\n"));
4346
252b5132
RH
4347 for (i = 0, section = section_headers;
4348 i < elf_header.e_shnum;
b34976b6 4349 i++, section++)
252b5132 4350 {
5477e8a0 4351 if (do_section_details)
595cf52e
L
4352 {
4353 printf (" [%2u] %s\n",
4fbb74a6 4354 i,
595cf52e
L
4355 SECTION_NAME (section));
4356 if (is_32bit_elf || do_wide)
4357 printf (" %-15.15s ",
4358 get_section_type_name (section->sh_type));
4359 }
4360 else
b9eb56c1
NC
4361 printf ((do_wide ? " [%2u] %-17s %-15s "
4362 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4363 i,
595cf52e
L
4364 SECTION_NAME (section),
4365 get_section_type_name (section->sh_type));
252b5132 4366
f7a99963
NC
4367 if (is_32bit_elf)
4368 {
cfcac11d
NC
4369 const char * link_too_big = NULL;
4370
f7a99963 4371 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4372
f7a99963
NC
4373 printf ( " %6.6lx %6.6lx %2.2lx",
4374 (unsigned long) section->sh_offset,
4375 (unsigned long) section->sh_size,
4376 (unsigned long) section->sh_entsize);
d1133906 4377
5477e8a0
L
4378 if (do_section_details)
4379 fputs (" ", stdout);
4380 else
4381 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4382
cfcac11d
NC
4383 if (section->sh_link >= elf_header.e_shnum)
4384 {
4385 link_too_big = "";
4386 /* The sh_link value is out of range. Normally this indicates
4387 an error but it can have special values in SPARC binaries. */
4388 switch (elf_header.e_machine)
4389 {
4390 case EM_OLD_SPARCV9:
4391 case EM_SPARC32PLUS:
4392 case EM_SPARCV9:
4393 case EM_SPARC:
4394 if (section->sh_link == (SHN_BEFORE & 0xffff))
4395 link_too_big = "BEFORE";
4396 else if (section->sh_link == (SHN_AFTER & 0xffff))
4397 link_too_big = "AFTER";
4398 break;
4399 default:
4400 break;
4401 }
4402 }
4403
4404 if (do_section_details)
4405 {
4406 if (link_too_big != NULL && * link_too_big)
4407 printf ("<%s> ", link_too_big);
4408 else
4409 printf ("%2u ", section->sh_link);
4410 printf ("%3u %2lu\n", section->sh_info,
4411 (unsigned long) section->sh_addralign);
4412 }
4413 else
4414 printf ("%2u %3u %2lu\n",
4415 section->sh_link,
4416 section->sh_info,
4417 (unsigned long) section->sh_addralign);
4418
4419 if (link_too_big && ! * link_too_big)
4420 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4421 i, section->sh_link);
f7a99963 4422 }
d974e256
JJ
4423 else if (do_wide)
4424 {
4425 print_vma (section->sh_addr, LONG_HEX);
4426
4427 if ((long) section->sh_offset == section->sh_offset)
4428 printf (" %6.6lx", (unsigned long) section->sh_offset);
4429 else
4430 {
4431 putchar (' ');
4432 print_vma (section->sh_offset, LONG_HEX);
4433 }
4434
4435 if ((unsigned long) section->sh_size == section->sh_size)
4436 printf (" %6.6lx", (unsigned long) section->sh_size);
4437 else
4438 {
4439 putchar (' ');
4440 print_vma (section->sh_size, LONG_HEX);
4441 }
4442
4443 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4444 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4445 else
4446 {
4447 putchar (' ');
4448 print_vma (section->sh_entsize, LONG_HEX);
4449 }
4450
5477e8a0
L
4451 if (do_section_details)
4452 fputs (" ", stdout);
4453 else
4454 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4455
72de5009 4456 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4457
4458 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4459 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4460 else
4461 {
4462 print_vma (section->sh_addralign, DEC);
4463 putchar ('\n');
4464 }
4465 }
5477e8a0 4466 else if (do_section_details)
595cf52e 4467 {
5477e8a0 4468 printf (" %-15.15s ",
595cf52e 4469 get_section_type_name (section->sh_type));
595cf52e
L
4470 print_vma (section->sh_addr, LONG_HEX);
4471 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4472 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4473 else
4474 {
4475 printf (" ");
4476 print_vma (section->sh_offset, LONG_HEX);
4477 }
72de5009 4478 printf (" %u\n ", section->sh_link);
595cf52e 4479 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4480 putchar (' ');
595cf52e
L
4481 print_vma (section->sh_entsize, LONG_HEX);
4482
72de5009
AM
4483 printf (" %-16u %lu\n",
4484 section->sh_info,
595cf52e
L
4485 (unsigned long) section->sh_addralign);
4486 }
f7a99963
NC
4487 else
4488 {
4489 putchar (' ');
4490 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4491 if ((long) section->sh_offset == section->sh_offset)
4492 printf (" %8.8lx", (unsigned long) section->sh_offset);
4493 else
4494 {
4495 printf (" ");
4496 print_vma (section->sh_offset, LONG_HEX);
4497 }
f7a99963
NC
4498 printf ("\n ");
4499 print_vma (section->sh_size, LONG_HEX);
4500 printf (" ");
4501 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4502
d1133906 4503 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4504
72de5009
AM
4505 printf (" %2u %3u %lu\n",
4506 section->sh_link,
4507 section->sh_info,
f7a99963
NC
4508 (unsigned long) section->sh_addralign);
4509 }
5477e8a0
L
4510
4511 if (do_section_details)
4512 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4513 }
4514
5477e8a0
L
4515 if (!do_section_details)
4516 printf (_("Key to Flags:\n\
e3c8793a
NC
4517 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
4518 I (info), L (link order), G (group), x (unknown)\n\
4519 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
d1133906 4520
252b5132
RH
4521 return 1;
4522}
4523
f5842774
L
4524static const char *
4525get_group_flags (unsigned int flags)
4526{
4527 static char buff[32];
4528 switch (flags)
4529 {
4530 case GRP_COMDAT:
4531 return "COMDAT";
4532
4533 default:
e9e44622 4534 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x]"), flags);
f5842774
L
4535 break;
4536 }
4537 return buff;
4538}
4539
4540static int
2cf0635d 4541process_section_groups (FILE * file)
f5842774 4542{
2cf0635d 4543 Elf_Internal_Shdr * section;
f5842774 4544 unsigned int i;
2cf0635d
NC
4545 struct group * group;
4546 Elf_Internal_Shdr * symtab_sec;
4547 Elf_Internal_Shdr * strtab_sec;
4548 Elf_Internal_Sym * symtab;
4549 char * strtab;
c256ffe7 4550 size_t strtab_size;
d1f5c6e3
L
4551
4552 /* Don't process section groups unless needed. */
4553 if (!do_unwind && !do_section_groups)
4554 return 1;
f5842774
L
4555
4556 if (elf_header.e_shnum == 0)
4557 {
4558 if (do_section_groups)
d1f5c6e3 4559 printf (_("\nThere are no sections in this file.\n"));
f5842774
L
4560
4561 return 1;
4562 }
4563
4564 if (section_headers == NULL)
4565 {
4566 error (_("Section headers are not available!\n"));
4567 abort ();
4568 }
4569
3f5e193b
NC
4570 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
4571 sizeof (struct group *));
e4b17d5c
L
4572
4573 if (section_headers_groups == NULL)
4574 {
4575 error (_("Out of memory\n"));
4576 return 0;
4577 }
4578
f5842774 4579 /* Scan the sections for the group section. */
d1f5c6e3 4580 group_count = 0;
f5842774
L
4581 for (i = 0, section = section_headers;
4582 i < elf_header.e_shnum;
4583 i++, section++)
e4b17d5c
L
4584 if (section->sh_type == SHT_GROUP)
4585 group_count++;
4586
d1f5c6e3
L
4587 if (group_count == 0)
4588 {
4589 if (do_section_groups)
4590 printf (_("\nThere are no section groups in this file.\n"));
4591
4592 return 1;
4593 }
4594
3f5e193b 4595 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
4596
4597 if (section_groups == NULL)
4598 {
4599 error (_("Out of memory\n"));
4600 return 0;
4601 }
4602
d1f5c6e3
L
4603 symtab_sec = NULL;
4604 strtab_sec = NULL;
4605 symtab = NULL;
4606 strtab = NULL;
c256ffe7 4607 strtab_size = 0;
e4b17d5c
L
4608 for (i = 0, section = section_headers, group = section_groups;
4609 i < elf_header.e_shnum;
4610 i++, section++)
f5842774
L
4611 {
4612 if (section->sh_type == SHT_GROUP)
4613 {
2cf0635d
NC
4614 char * name = SECTION_NAME (section);
4615 char * group_name;
4616 unsigned char * start;
4617 unsigned char * indices;
f5842774 4618 unsigned int entry, j, size;
2cf0635d
NC
4619 Elf_Internal_Shdr * sec;
4620 Elf_Internal_Sym * sym;
f5842774
L
4621
4622 /* Get the symbol table. */
4fbb74a6
AM
4623 if (section->sh_link >= elf_header.e_shnum
4624 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 4625 != SHT_SYMTAB))
f5842774
L
4626 {
4627 error (_("Bad sh_link in group section `%s'\n"), name);
4628 continue;
4629 }
d1f5c6e3
L
4630
4631 if (symtab_sec != sec)
4632 {
4633 symtab_sec = sec;
4634 if (symtab)
4635 free (symtab);
4636 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
4637 }
f5842774
L
4638
4639 sym = symtab + section->sh_info;
4640
4641 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
4642 {
4fbb74a6
AM
4643 if (sym->st_shndx == 0
4644 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
4645 {
4646 error (_("Bad sh_info in group section `%s'\n"), name);
4647 continue;
4648 }
ba2685cc 4649
4fbb74a6 4650 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
4651 strtab_sec = NULL;
4652 if (strtab)
4653 free (strtab);
f5842774 4654 strtab = NULL;
c256ffe7 4655 strtab_size = 0;
f5842774
L
4656 }
4657 else
4658 {
4659 /* Get the string table. */
4fbb74a6 4660 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
4661 {
4662 strtab_sec = NULL;
4663 if (strtab)
4664 free (strtab);
4665 strtab = NULL;
4666 strtab_size = 0;
4667 }
4668 else if (strtab_sec
4fbb74a6 4669 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
4670 {
4671 strtab_sec = sec;
4672 if (strtab)
4673 free (strtab);
3f5e193b
NC
4674 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
4675 1, strtab_sec->sh_size,
4676 _("string table"));
c256ffe7 4677 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 4678 }
c256ffe7
JJ
4679 group_name = sym->st_name < strtab_size
4680 ? strtab + sym->st_name : "<corrupt>";
f5842774
L
4681 }
4682
3f5e193b
NC
4683 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
4684 1, section->sh_size,
4685 _("section data"));
f5842774
L
4686
4687 indices = start;
4688 size = (section->sh_size / section->sh_entsize) - 1;
4689 entry = byte_get (indices, 4);
4690 indices += 4;
e4b17d5c
L
4691
4692 if (do_section_groups)
4693 {
391cb864
L
4694 printf ("\n%s group section [%5u] `%s' [%s] contains %u sections:\n",
4695 get_group_flags (entry), i, name, group_name, size);
ba2685cc 4696
e4b17d5c
L
4697 printf (_(" [Index] Name\n"));
4698 }
4699
4700 group->group_index = i;
4701
f5842774
L
4702 for (j = 0; j < size; j++)
4703 {
2cf0635d 4704 struct group_list * g;
e4b17d5c 4705
f5842774
L
4706 entry = byte_get (indices, 4);
4707 indices += 4;
4708
4fbb74a6 4709 if (entry >= elf_header.e_shnum)
391cb864
L
4710 {
4711 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
4712 entry, i, elf_header.e_shnum - 1);
4713 continue;
4714 }
391cb864 4715
4fbb74a6 4716 if (section_headers_groups [entry] != NULL)
e4b17d5c 4717 {
d1f5c6e3
L
4718 if (entry)
4719 {
391cb864
L
4720 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
4721 entry, i,
4fbb74a6 4722 section_headers_groups [entry]->group_index);
d1f5c6e3
L
4723 continue;
4724 }
4725 else
4726 {
4727 /* Intel C/C++ compiler may put section 0 in a
4728 section group. We just warn it the first time
4729 and ignore it afterwards. */
4730 static int warned = 0;
4731 if (!warned)
4732 {
4733 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 4734 section_headers_groups [entry]->group_index);
d1f5c6e3
L
4735 warned++;
4736 }
4737 }
e4b17d5c
L
4738 }
4739
4fbb74a6 4740 section_headers_groups [entry] = group;
e4b17d5c
L
4741
4742 if (do_section_groups)
4743 {
4fbb74a6 4744 sec = section_headers + entry;
c256ffe7 4745 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
4746 }
4747
3f5e193b 4748 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
4749 g->section_index = entry;
4750 g->next = group->root;
4751 group->root = g;
f5842774
L
4752 }
4753
f5842774
L
4754 if (start)
4755 free (start);
e4b17d5c
L
4756
4757 group++;
f5842774
L
4758 }
4759 }
4760
d1f5c6e3
L
4761 if (symtab)
4762 free (symtab);
4763 if (strtab)
4764 free (strtab);
f5842774
L
4765 return 1;
4766}
4767
85b1c36d 4768static struct
566b0d53 4769{
2cf0635d 4770 const char * name;
566b0d53
L
4771 int reloc;
4772 int size;
4773 int rela;
4774} dynamic_relocations [] =
4775{
4776 { "REL", DT_REL, DT_RELSZ, FALSE },
4777 { "RELA", DT_RELA, DT_RELASZ, TRUE },
4778 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
4779};
4780
252b5132 4781/* Process the reloc section. */
18bd398b 4782
252b5132 4783static int
2cf0635d 4784process_relocs (FILE * file)
252b5132 4785{
b34976b6
AM
4786 unsigned long rel_size;
4787 unsigned long rel_offset;
252b5132
RH
4788
4789
4790 if (!do_reloc)
4791 return 1;
4792
4793 if (do_using_dynamic)
4794 {
566b0d53 4795 int is_rela;
2cf0635d 4796 const char * name;
566b0d53
L
4797 int has_dynamic_reloc;
4798 unsigned int i;
0de14b54 4799
566b0d53 4800 has_dynamic_reloc = 0;
252b5132 4801
566b0d53 4802 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 4803 {
566b0d53
L
4804 is_rela = dynamic_relocations [i].rela;
4805 name = dynamic_relocations [i].name;
4806 rel_size = dynamic_info [dynamic_relocations [i].size];
4807 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 4808
566b0d53
L
4809 has_dynamic_reloc |= rel_size;
4810
4811 if (is_rela == UNKNOWN)
aa903cfb 4812 {
566b0d53
L
4813 if (dynamic_relocations [i].reloc == DT_JMPREL)
4814 switch (dynamic_info[DT_PLTREL])
4815 {
4816 case DT_REL:
4817 is_rela = FALSE;
4818 break;
4819 case DT_RELA:
4820 is_rela = TRUE;
4821 break;
4822 }
aa903cfb 4823 }
252b5132 4824
566b0d53
L
4825 if (rel_size)
4826 {
4827 printf
4828 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
4829 name, rel_offset, rel_size);
252b5132 4830
d93f0186
NC
4831 dump_relocations (file,
4832 offset_from_vma (file, rel_offset, rel_size),
4833 rel_size,
566b0d53 4834 dynamic_symbols, num_dynamic_syms,
d79b3d50 4835 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 4836 }
252b5132 4837 }
566b0d53
L
4838
4839 if (! has_dynamic_reloc)
252b5132
RH
4840 printf (_("\nThere are no dynamic relocations in this file.\n"));
4841 }
4842 else
4843 {
2cf0635d 4844 Elf_Internal_Shdr * section;
b34976b6
AM
4845 unsigned long i;
4846 int found = 0;
252b5132
RH
4847
4848 for (i = 0, section = section_headers;
4849 i < elf_header.e_shnum;
b34976b6 4850 i++, section++)
252b5132
RH
4851 {
4852 if ( section->sh_type != SHT_RELA
4853 && section->sh_type != SHT_REL)
4854 continue;
4855
4856 rel_offset = section->sh_offset;
4857 rel_size = section->sh_size;
4858
4859 if (rel_size)
4860 {
2cf0635d 4861 Elf_Internal_Shdr * strsec;
b34976b6 4862 int is_rela;
103f02d3 4863
252b5132
RH
4864 printf (_("\nRelocation section "));
4865
4866 if (string_table == NULL)
19936277 4867 printf ("%d", section->sh_name);
252b5132 4868 else
3a1a2036 4869 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
4870
4871 printf (_(" at offset 0x%lx contains %lu entries:\n"),
4872 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
4873
d79b3d50
NC
4874 is_rela = section->sh_type == SHT_RELA;
4875
4fbb74a6
AM
4876 if (section->sh_link != 0
4877 && section->sh_link < elf_header.e_shnum)
af3fc3bc 4878 {
2cf0635d
NC
4879 Elf_Internal_Shdr * symsec;
4880 Elf_Internal_Sym * symtab;
d79b3d50 4881 unsigned long nsyms;
c256ffe7 4882 unsigned long strtablen = 0;
2cf0635d 4883 char * strtab = NULL;
57346661 4884
4fbb74a6 4885 symsec = section_headers + section->sh_link;
08d8fa11
JJ
4886 if (symsec->sh_type != SHT_SYMTAB
4887 && symsec->sh_type != SHT_DYNSYM)
4888 continue;
4889
af3fc3bc 4890 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 4891 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 4892
af3fc3bc
AM
4893 if (symtab == NULL)
4894 continue;
252b5132 4895
4fbb74a6
AM
4896 if (symsec->sh_link != 0
4897 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 4898 {
4fbb74a6 4899 strsec = section_headers + symsec->sh_link;
103f02d3 4900
3f5e193b
NC
4901 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
4902 1, strsec->sh_size,
4903 _("string table"));
c256ffe7
JJ
4904 strtablen = strtab == NULL ? 0 : strsec->sh_size;
4905 }
252b5132 4906
d79b3d50
NC
4907 dump_relocations (file, rel_offset, rel_size,
4908 symtab, nsyms, strtab, strtablen, is_rela);
4909 if (strtab)
4910 free (strtab);
4911 free (symtab);
4912 }
4913 else
4914 dump_relocations (file, rel_offset, rel_size,
4915 NULL, 0, NULL, 0, is_rela);
252b5132
RH
4916
4917 found = 1;
4918 }
4919 }
4920
4921 if (! found)
4922 printf (_("\nThere are no relocations in this file.\n"));
4923 }
4924
4925 return 1;
4926}
4927
57346661
AM
4928/* Process the unwind section. */
4929
4d6ed7c8
NC
4930#include "unwind-ia64.h"
4931
4932/* An absolute address consists of a section and an offset. If the
4933 section is NULL, the offset itself is the address, otherwise, the
4934 address equals to LOAD_ADDRESS(section) + offset. */
4935
4936struct absaddr
4937 {
4938 unsigned short section;
4939 bfd_vma offset;
4940 };
4941
1949de15
L
4942#define ABSADDR(a) \
4943 ((a).section \
4944 ? section_headers [(a).section].sh_addr + (a).offset \
4945 : (a).offset)
4946
3f5e193b
NC
4947struct ia64_unw_table_entry
4948 {
4949 struct absaddr start;
4950 struct absaddr end;
4951 struct absaddr info;
4952 };
4953
57346661 4954struct ia64_unw_aux_info
4d6ed7c8 4955 {
3f5e193b
NC
4956
4957 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 4958 unsigned long table_len; /* Length of unwind table. */
2cf0635d 4959 unsigned char * info; /* Unwind info. */
b34976b6
AM
4960 unsigned long info_size; /* Size of unwind info. */
4961 bfd_vma info_addr; /* starting address of unwind info. */
4962 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 4963 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 4964 unsigned long nsyms; /* Number of symbols. */
2cf0635d 4965 char * strtab; /* The string table. */
b34976b6 4966 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
4967 };
4968
4d6ed7c8 4969static void
2cf0635d 4970find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 4971 unsigned long nsyms,
2cf0635d 4972 const char * strtab,
57346661 4973 unsigned long strtab_size,
d3ba0551 4974 struct absaddr addr,
2cf0635d
NC
4975 const char ** symname,
4976 bfd_vma * offset)
4d6ed7c8 4977{
d3ba0551 4978 bfd_vma dist = 0x100000;
2cf0635d
NC
4979 Elf_Internal_Sym * sym;
4980 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
4981 unsigned long i;
4982
57346661 4983 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8
NC
4984 {
4985 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
4986 && sym->st_name != 0
4987 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
4988 && addr.offset >= sym->st_value
4989 && addr.offset - sym->st_value < dist)
4990 {
4991 best = sym;
4992 dist = addr.offset - sym->st_value;
4993 if (!dist)
4994 break;
4995 }
4996 }
4997 if (best)
4998 {
57346661
AM
4999 *symname = (best->st_name >= strtab_size
5000 ? "<corrupt>" : strtab + best->st_name);
4d6ed7c8
NC
5001 *offset = dist;
5002 return;
5003 }
5004 *symname = NULL;
5005 *offset = addr.offset;
5006}
5007
5008static void
2cf0635d 5009dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5010{
2cf0635d 5011 struct ia64_unw_table_entry * tp;
4d6ed7c8 5012 int in_body;
7036c0e1 5013
4d6ed7c8
NC
5014 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5015 {
5016 bfd_vma stamp;
5017 bfd_vma offset;
2cf0635d
NC
5018 const unsigned char * dp;
5019 const unsigned char * head;
5020 const char * procname;
4d6ed7c8 5021
57346661
AM
5022 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5023 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5024
5025 fputs ("\n<", stdout);
5026
5027 if (procname)
5028 {
5029 fputs (procname, stdout);
5030
5031 if (offset)
5032 printf ("+%lx", (unsigned long) offset);
5033 }
5034
5035 fputs (">: [", stdout);
5036 print_vma (tp->start.offset, PREFIX_HEX);
5037 fputc ('-', stdout);
5038 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5039 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5040 (unsigned long) (tp->info.offset - aux->seg_base));
5041
1949de15 5042 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5043 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5044
86f55779 5045 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5046 (unsigned) UNW_VER (stamp),
5047 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5048 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5049 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5050 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5051
5052 if (UNW_VER (stamp) != 1)
5053 {
5054 printf ("\tUnknown version.\n");
5055 continue;
5056 }
5057
5058 in_body = 0;
89fac5e3 5059 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5060 dp = unw_decode (dp, in_body, & in_body);
5061 }
5062}
5063
5064static int
2cf0635d
NC
5065slurp_ia64_unwind_table (FILE * file,
5066 struct ia64_unw_aux_info * aux,
5067 Elf_Internal_Shdr * sec)
4d6ed7c8 5068{
89fac5e3 5069 unsigned long size, nrelas, i;
2cf0635d
NC
5070 Elf_Internal_Phdr * seg;
5071 struct ia64_unw_table_entry * tep;
5072 Elf_Internal_Shdr * relsec;
5073 Elf_Internal_Rela * rela;
5074 Elf_Internal_Rela * rp;
5075 unsigned char * table;
5076 unsigned char * tp;
5077 Elf_Internal_Sym * sym;
5078 const char * relname;
4d6ed7c8 5079
4d6ed7c8
NC
5080 /* First, find the starting address of the segment that includes
5081 this section: */
5082
5083 if (elf_header.e_phnum)
5084 {
d93f0186 5085 if (! get_program_headers (file))
4d6ed7c8 5086 return 0;
4d6ed7c8 5087
d93f0186
NC
5088 for (seg = program_headers;
5089 seg < program_headers + elf_header.e_phnum;
5090 ++seg)
4d6ed7c8
NC
5091 {
5092 if (seg->p_type != PT_LOAD)
5093 continue;
5094
5095 if (sec->sh_addr >= seg->p_vaddr
5096 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5097 {
5098 aux->seg_base = seg->p_vaddr;
5099 break;
5100 }
5101 }
4d6ed7c8
NC
5102 }
5103
5104 /* Second, build the unwind table from the contents of the unwind section: */
5105 size = sec->sh_size;
3f5e193b
NC
5106 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5107 _("unwind table"));
a6e9f9df
AM
5108 if (!table)
5109 return 0;
4d6ed7c8 5110
3f5e193b
NC
5111 aux->table = (struct ia64_unw_table_entry *)
5112 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5113 tep = aux->table;
c6a0c689 5114 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5115 {
5116 tep->start.section = SHN_UNDEF;
5117 tep->end.section = SHN_UNDEF;
5118 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5119 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5120 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5121 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5122 tep->start.offset += aux->seg_base;
5123 tep->end.offset += aux->seg_base;
5124 tep->info.offset += aux->seg_base;
5125 }
5126 free (table);
5127
41e92641 5128 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5129 for (relsec = section_headers;
5130 relsec < section_headers + elf_header.e_shnum;
5131 ++relsec)
5132 {
5133 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5134 || relsec->sh_info >= elf_header.e_shnum
5135 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5136 continue;
5137
5138 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5139 & rela, & nrelas))
5140 return 0;
5141
5142 for (rp = rela; rp < rela + nrelas; ++rp)
5143 {
aca88567
NC
5144 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5145 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5146
0112cd26 5147 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5148 {
e5fb9629 5149 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5150 continue;
5151 }
5152
89fac5e3 5153 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5154
89fac5e3 5155 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5156 {
5157 case 0:
5158 aux->table[i].start.section = sym->st_shndx;
1ffa9a18 5159 aux->table[i].start.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5160 break;
5161 case 1:
5162 aux->table[i].end.section = sym->st_shndx;
1ffa9a18 5163 aux->table[i].end.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5164 break;
5165 case 2:
5166 aux->table[i].info.section = sym->st_shndx;
1ffa9a18 5167 aux->table[i].info.offset += rp->r_addend + sym->st_value;
4d6ed7c8
NC
5168 break;
5169 default:
5170 break;
5171 }
5172 }
5173
5174 free (rela);
5175 }
5176
89fac5e3 5177 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5178 return 1;
5179}
5180
5181static int
2cf0635d 5182ia64_process_unwind (FILE * file)
4d6ed7c8 5183{
2cf0635d
NC
5184 Elf_Internal_Shdr * sec;
5185 Elf_Internal_Shdr * unwsec = NULL;
5186 Elf_Internal_Shdr * strsec;
89fac5e3 5187 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5188 struct ia64_unw_aux_info aux;
f1467e33 5189
4d6ed7c8
NC
5190 memset (& aux, 0, sizeof (aux));
5191
4d6ed7c8
NC
5192 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5193 {
c256ffe7 5194 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5195 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5196 {
5197 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5198 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5199
4fbb74a6 5200 strsec = section_headers + sec->sh_link;
3f5e193b
NC
5201 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5202 1, strsec->sh_size,
5203 _("string table"));
c256ffe7 5204 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5205 }
5206 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5207 unwcount++;
5208 }
5209
5210 if (!unwcount)
5211 printf (_("\nThere are no unwind sections in this file.\n"));
5212
5213 while (unwcount-- > 0)
5214 {
2cf0635d 5215 char * suffix;
579f31ac
JJ
5216 size_t len, len2;
5217
5218 for (i = unwstart, sec = section_headers + unwstart;
5219 i < elf_header.e_shnum; ++i, ++sec)
5220 if (sec->sh_type == SHT_IA_64_UNWIND)
5221 {
5222 unwsec = sec;
5223 break;
5224 }
5225
5226 unwstart = i + 1;
5227 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5228
e4b17d5c
L
5229 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5230 {
5231 /* We need to find which section group it is in. */
2cf0635d 5232 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5233
5234 for (; g != NULL; g = g->next)
5235 {
4fbb74a6 5236 sec = section_headers + g->section_index;
18bd398b
NC
5237
5238 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5239 break;
e4b17d5c
L
5240 }
5241
5242 if (g == NULL)
5243 i = elf_header.e_shnum;
5244 }
18bd398b 5245 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5246 {
18bd398b 5247 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5248 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5249 suffix = SECTION_NAME (unwsec) + len;
5250 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5251 ++i, ++sec)
18bd398b
NC
5252 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5253 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5254 break;
5255 }
5256 else
5257 {
5258 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5259 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5260 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5261 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5262 suffix = "";
18bd398b 5263 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5264 suffix = SECTION_NAME (unwsec) + len;
5265 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5266 ++i, ++sec)
18bd398b
NC
5267 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5268 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5269 break;
5270 }
5271
5272 if (i == elf_header.e_shnum)
5273 {
5274 printf (_("\nCould not find unwind info section for "));
5275
5276 if (string_table == NULL)
5277 printf ("%d", unwsec->sh_name);
5278 else
3a1a2036 5279 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5280 }
5281 else
4d6ed7c8
NC
5282 {
5283 aux.info_size = sec->sh_size;
5284 aux.info_addr = sec->sh_addr;
3f5e193b
NC
5285 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
5286 aux.info_size,
5287 _("unwind info"));
4d6ed7c8 5288
579f31ac 5289 printf (_("\nUnwind section "));
4d6ed7c8 5290
579f31ac
JJ
5291 if (string_table == NULL)
5292 printf ("%d", unwsec->sh_name);
5293 else
3a1a2036 5294 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5295
579f31ac 5296 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5297 (unsigned long) unwsec->sh_offset,
89fac5e3 5298 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5299
579f31ac 5300 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5301
579f31ac
JJ
5302 if (aux.table_len > 0)
5303 dump_ia64_unwind (& aux);
5304
5305 if (aux.table)
5306 free ((char *) aux.table);
5307 if (aux.info)
5308 free ((char *) aux.info);
5309 aux.table = NULL;
5310 aux.info = NULL;
5311 }
4d6ed7c8 5312 }
4d6ed7c8 5313
4d6ed7c8
NC
5314 if (aux.symtab)
5315 free (aux.symtab);
5316 if (aux.strtab)
5317 free ((char *) aux.strtab);
5318
5319 return 1;
5320}
5321
3f5e193b
NC
5322struct hppa_unw_table_entry
5323 {
5324 struct absaddr start;
5325 struct absaddr end;
5326 unsigned int Cannot_unwind:1; /* 0 */
5327 unsigned int Millicode:1; /* 1 */
5328 unsigned int Millicode_save_sr0:1; /* 2 */
5329 unsigned int Region_description:2; /* 3..4 */
5330 unsigned int reserved1:1; /* 5 */
5331 unsigned int Entry_SR:1; /* 6 */
5332 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5333 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5334 unsigned int Args_stored:1; /* 16 */
5335 unsigned int Variable_Frame:1; /* 17 */
5336 unsigned int Separate_Package_Body:1; /* 18 */
5337 unsigned int Frame_Extension_Millicode:1; /* 19 */
5338 unsigned int Stack_Overflow_Check:1; /* 20 */
5339 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5340 unsigned int Ada_Region:1; /* 22 */
5341 unsigned int cxx_info:1; /* 23 */
5342 unsigned int cxx_try_catch:1; /* 24 */
5343 unsigned int sched_entry_seq:1; /* 25 */
5344 unsigned int reserved2:1; /* 26 */
5345 unsigned int Save_SP:1; /* 27 */
5346 unsigned int Save_RP:1; /* 28 */
5347 unsigned int Save_MRP_in_frame:1; /* 29 */
5348 unsigned int extn_ptr_defined:1; /* 30 */
5349 unsigned int Cleanup_defined:1; /* 31 */
5350
5351 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5352 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5353 unsigned int Large_frame:1; /* 2 */
5354 unsigned int Pseudo_SP_Set:1; /* 3 */
5355 unsigned int reserved4:1; /* 4 */
5356 unsigned int Total_frame_size:27; /* 5..31 */
5357 };
5358
57346661
AM
5359struct hppa_unw_aux_info
5360 {
3f5e193b 5361 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
5362 unsigned long table_len; /* Length of unwind table. */
5363 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5364 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5365 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5366 char * strtab; /* The string table. */
57346661
AM
5367 unsigned long strtab_size; /* Size of string table. */
5368 };
5369
5370static void
2cf0635d 5371dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5372{
2cf0635d 5373 struct hppa_unw_table_entry * tp;
57346661 5374
57346661
AM
5375 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5376 {
5377 bfd_vma offset;
2cf0635d 5378 const char * procname;
57346661
AM
5379
5380 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5381 aux->strtab_size, tp->start, &procname,
5382 &offset);
5383
5384 fputs ("\n<", stdout);
5385
5386 if (procname)
5387 {
5388 fputs (procname, stdout);
5389
5390 if (offset)
5391 printf ("+%lx", (unsigned long) offset);
5392 }
5393
5394 fputs (">: [", stdout);
5395 print_vma (tp->start.offset, PREFIX_HEX);
5396 fputc ('-', stdout);
5397 print_vma (tp->end.offset, PREFIX_HEX);
5398 printf ("]\n\t");
5399
18bd398b
NC
5400#define PF(_m) if (tp->_m) printf (#_m " ");
5401#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5402 PF(Cannot_unwind);
5403 PF(Millicode);
5404 PF(Millicode_save_sr0);
18bd398b 5405 /* PV(Region_description); */
57346661
AM
5406 PF(Entry_SR);
5407 PV(Entry_FR);
5408 PV(Entry_GR);
5409 PF(Args_stored);
5410 PF(Variable_Frame);
5411 PF(Separate_Package_Body);
5412 PF(Frame_Extension_Millicode);
5413 PF(Stack_Overflow_Check);
5414 PF(Two_Instruction_SP_Increment);
5415 PF(Ada_Region);
5416 PF(cxx_info);
5417 PF(cxx_try_catch);
5418 PF(sched_entry_seq);
5419 PF(Save_SP);
5420 PF(Save_RP);
5421 PF(Save_MRP_in_frame);
5422 PF(extn_ptr_defined);
5423 PF(Cleanup_defined);
5424 PF(MPE_XL_interrupt_marker);
5425 PF(HP_UX_interrupt_marker);
5426 PF(Large_frame);
5427 PF(Pseudo_SP_Set);
5428 PV(Total_frame_size);
5429#undef PF
5430#undef PV
5431 }
5432
18bd398b 5433 printf ("\n");
57346661
AM
5434}
5435
5436static int
2cf0635d
NC
5437slurp_hppa_unwind_table (FILE * file,
5438 struct hppa_unw_aux_info * aux,
5439 Elf_Internal_Shdr * sec)
57346661 5440{
1c0751b2 5441 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
5442 Elf_Internal_Phdr * seg;
5443 struct hppa_unw_table_entry * tep;
5444 Elf_Internal_Shdr * relsec;
5445 Elf_Internal_Rela * rela;
5446 Elf_Internal_Rela * rp;
5447 unsigned char * table;
5448 unsigned char * tp;
5449 Elf_Internal_Sym * sym;
5450 const char * relname;
57346661 5451
57346661
AM
5452 /* First, find the starting address of the segment that includes
5453 this section. */
5454
5455 if (elf_header.e_phnum)
5456 {
5457 if (! get_program_headers (file))
5458 return 0;
5459
5460 for (seg = program_headers;
5461 seg < program_headers + elf_header.e_phnum;
5462 ++seg)
5463 {
5464 if (seg->p_type != PT_LOAD)
5465 continue;
5466
5467 if (sec->sh_addr >= seg->p_vaddr
5468 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5469 {
5470 aux->seg_base = seg->p_vaddr;
5471 break;
5472 }
5473 }
5474 }
5475
5476 /* Second, build the unwind table from the contents of the unwind
5477 section. */
5478 size = sec->sh_size;
3f5e193b
NC
5479 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5480 _("unwind table"));
57346661
AM
5481 if (!table)
5482 return 0;
5483
1c0751b2
DA
5484 unw_ent_size = 16;
5485 nentries = size / unw_ent_size;
5486 size = unw_ent_size * nentries;
57346661 5487
3f5e193b
NC
5488 tep = aux->table = (struct hppa_unw_table_entry *)
5489 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 5490
1c0751b2 5491 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
5492 {
5493 unsigned int tmp1, tmp2;
5494
5495 tep->start.section = SHN_UNDEF;
5496 tep->end.section = SHN_UNDEF;
5497
1c0751b2
DA
5498 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
5499 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
5500 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
5501 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
5502
5503 tep->start.offset += aux->seg_base;
5504 tep->end.offset += aux->seg_base;
57346661
AM
5505
5506 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
5507 tep->Millicode = (tmp1 >> 30) & 0x1;
5508 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
5509 tep->Region_description = (tmp1 >> 27) & 0x3;
5510 tep->reserved1 = (tmp1 >> 26) & 0x1;
5511 tep->Entry_SR = (tmp1 >> 25) & 0x1;
5512 tep->Entry_FR = (tmp1 >> 21) & 0xf;
5513 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
5514 tep->Args_stored = (tmp1 >> 15) & 0x1;
5515 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
5516 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
5517 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
5518 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
5519 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
5520 tep->Ada_Region = (tmp1 >> 9) & 0x1;
5521 tep->cxx_info = (tmp1 >> 8) & 0x1;
5522 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
5523 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
5524 tep->reserved2 = (tmp1 >> 5) & 0x1;
5525 tep->Save_SP = (tmp1 >> 4) & 0x1;
5526 tep->Save_RP = (tmp1 >> 3) & 0x1;
5527 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
5528 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
5529 tep->Cleanup_defined = tmp1 & 0x1;
5530
5531 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
5532 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
5533 tep->Large_frame = (tmp2 >> 29) & 0x1;
5534 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
5535 tep->reserved4 = (tmp2 >> 27) & 0x1;
5536 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
5537 }
5538 free (table);
5539
5540 /* Third, apply any relocations to the unwind table. */
57346661
AM
5541 for (relsec = section_headers;
5542 relsec < section_headers + elf_header.e_shnum;
5543 ++relsec)
5544 {
5545 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5546 || relsec->sh_info >= elf_header.e_shnum
5547 || section_headers + relsec->sh_info != sec)
57346661
AM
5548 continue;
5549
5550 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5551 & rela, & nrelas))
5552 return 0;
5553
5554 for (rp = rela; rp < rela + nrelas; ++rp)
5555 {
aca88567
NC
5556 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
5557 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
5558
5559 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 5560 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
5561 {
5562 warn (_("Skipping unexpected relocation type %s\n"), relname);
5563 continue;
5564 }
5565
5566 i = rp->r_offset / unw_ent_size;
5567
89fac5e3 5568 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
5569 {
5570 case 0:
5571 aux->table[i].start.section = sym->st_shndx;
5572 aux->table[i].start.offset += sym->st_value + rp->r_addend;
5573 break;
5574 case 1:
5575 aux->table[i].end.section = sym->st_shndx;
5576 aux->table[i].end.offset += sym->st_value + rp->r_addend;
5577 break;
5578 default:
5579 break;
5580 }
5581 }
5582
5583 free (rela);
5584 }
5585
1c0751b2 5586 aux->table_len = nentries;
57346661
AM
5587
5588 return 1;
5589}
5590
5591static int
2cf0635d 5592hppa_process_unwind (FILE * file)
57346661 5593{
57346661 5594 struct hppa_unw_aux_info aux;
2cf0635d
NC
5595 Elf_Internal_Shdr * unwsec = NULL;
5596 Elf_Internal_Shdr * strsec;
5597 Elf_Internal_Shdr * sec;
18bd398b 5598 unsigned long i;
57346661
AM
5599
5600 memset (& aux, 0, sizeof (aux));
5601
c256ffe7
JJ
5602 if (string_table == NULL)
5603 return 1;
57346661
AM
5604
5605 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5606 {
c256ffe7 5607 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5608 && sec->sh_link < elf_header.e_shnum)
57346661
AM
5609 {
5610 aux.nsyms = sec->sh_size / sec->sh_entsize;
5611 aux.symtab = GET_ELF_SYMBOLS (file, sec);
5612
4fbb74a6 5613 strsec = section_headers + sec->sh_link;
3f5e193b
NC
5614 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5615 1, strsec->sh_size,
5616 _("string table"));
c256ffe7 5617 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 5618 }
18bd398b 5619 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
5620 unwsec = sec;
5621 }
5622
5623 if (!unwsec)
5624 printf (_("\nThere are no unwind sections in this file.\n"));
5625
5626 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5627 {
18bd398b 5628 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 5629 {
57346661
AM
5630 printf (_("\nUnwind section "));
5631 printf (_("'%s'"), SECTION_NAME (sec));
5632
5633 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5634 (unsigned long) sec->sh_offset,
89fac5e3 5635 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
5636
5637 slurp_hppa_unwind_table (file, &aux, sec);
5638 if (aux.table_len > 0)
5639 dump_hppa_unwind (&aux);
5640
5641 if (aux.table)
5642 free ((char *) aux.table);
5643 aux.table = NULL;
5644 }
5645 }
5646
5647 if (aux.symtab)
5648 free (aux.symtab);
5649 if (aux.strtab)
5650 free ((char *) aux.strtab);
5651
5652 return 1;
5653}
5654
5655static int
2cf0635d 5656process_unwind (FILE * file)
57346661 5657{
2cf0635d
NC
5658 struct unwind_handler
5659 {
57346661 5660 int machtype;
2cf0635d
NC
5661 int (* handler)(FILE *);
5662 } handlers[] =
5663 {
57346661
AM
5664 { EM_IA_64, ia64_process_unwind },
5665 { EM_PARISC, hppa_process_unwind },
5666 { 0, 0 }
5667 };
5668 int i;
5669
5670 if (!do_unwind)
5671 return 1;
5672
5673 for (i = 0; handlers[i].handler != NULL; i++)
5674 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 5675 return handlers[i].handler (file);
57346661
AM
5676
5677 printf (_("\nThere are no unwind sections in this file.\n"));
5678 return 1;
5679}
5680
252b5132 5681static void
2cf0635d 5682dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
5683{
5684 switch (entry->d_tag)
5685 {
5686 case DT_MIPS_FLAGS:
5687 if (entry->d_un.d_val == 0)
5688 printf ("NONE\n");
5689 else
5690 {
5691 static const char * opts[] =
5692 {
5693 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
5694 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
5695 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
5696 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
5697 "RLD_ORDER_SAFE"
5698 };
5699 unsigned int cnt;
5700 int first = 1;
60bca95a 5701 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
5702 if (entry->d_un.d_val & (1 << cnt))
5703 {
5704 printf ("%s%s", first ? "" : " ", opts[cnt]);
5705 first = 0;
5706 }
5707 puts ("");
5708 }
5709 break;
103f02d3 5710
252b5132 5711 case DT_MIPS_IVERSION:
d79b3d50
NC
5712 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
5713 printf ("Interface Version: %s\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 5714 else
d79b3d50 5715 printf ("<corrupt: %ld>\n", (long) entry->d_un.d_ptr);
252b5132 5716 break;
103f02d3 5717
252b5132
RH
5718 case DT_MIPS_TIME_STAMP:
5719 {
5720 char timebuf[20];
2cf0635d 5721 struct tm * tmp;
50da7a9c 5722
252b5132 5723 time_t time = entry->d_un.d_val;
50da7a9c 5724 tmp = gmtime (&time);
e9e44622
JJ
5725 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
5726 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
5727 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
252b5132
RH
5728 printf ("Time Stamp: %s\n", timebuf);
5729 }
5730 break;
103f02d3 5731
252b5132
RH
5732 case DT_MIPS_RLD_VERSION:
5733 case DT_MIPS_LOCAL_GOTNO:
5734 case DT_MIPS_CONFLICTNO:
5735 case DT_MIPS_LIBLISTNO:
5736 case DT_MIPS_SYMTABNO:
5737 case DT_MIPS_UNREFEXTNO:
5738 case DT_MIPS_HIPAGENO:
5739 case DT_MIPS_DELTA_CLASS_NO:
5740 case DT_MIPS_DELTA_INSTANCE_NO:
5741 case DT_MIPS_DELTA_RELOC_NO:
5742 case DT_MIPS_DELTA_SYM_NO:
5743 case DT_MIPS_DELTA_CLASSSYM_NO:
5744 case DT_MIPS_COMPACT_SIZE:
5745 printf ("%ld\n", (long) entry->d_un.d_ptr);
5746 break;
103f02d3
UD
5747
5748 default:
0af1713e 5749 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
5750 }
5751}
5752
5753
5754static void
2cf0635d 5755dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
5756{
5757 switch (entry->d_tag)
5758 {
5759 case DT_HP_DLD_FLAGS:
5760 {
5761 static struct
5762 {
5763 long int bit;
2cf0635d 5764 const char * str;
5e220199
NC
5765 }
5766 flags[] =
5767 {
5768 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
5769 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
5770 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
5771 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
5772 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
5773 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
5774 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
5775 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
5776 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
5777 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
5778 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
5779 { DT_HP_GST, "HP_GST" },
5780 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
5781 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
5782 { DT_HP_NODELETE, "HP_NODELETE" },
5783 { DT_HP_GROUP, "HP_GROUP" },
5784 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 5785 };
103f02d3 5786 int first = 1;
5e220199 5787 size_t cnt;
f7a99963 5788 bfd_vma val = entry->d_un.d_val;
103f02d3 5789
60bca95a 5790 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 5791 if (val & flags[cnt].bit)
30800947
NC
5792 {
5793 if (! first)
5794 putchar (' ');
5795 fputs (flags[cnt].str, stdout);
5796 first = 0;
5797 val ^= flags[cnt].bit;
5798 }
76da6bbe 5799
103f02d3 5800 if (val != 0 || first)
f7a99963
NC
5801 {
5802 if (! first)
5803 putchar (' ');
5804 print_vma (val, HEX);
5805 }
103f02d3
UD
5806 }
5807 break;
76da6bbe 5808
252b5132 5809 default:
f7a99963
NC
5810 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5811 break;
252b5132 5812 }
35b1837e 5813 putchar ('\n');
252b5132
RH
5814}
5815
ecc51f48 5816static void
2cf0635d 5817dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
5818{
5819 switch (entry->d_tag)
5820 {
0de14b54 5821 case DT_IA_64_PLT_RESERVE:
bdf4d63a 5822 /* First 3 slots reserved. */
ecc51f48
NC
5823 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5824 printf (" -- ");
5825 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
5826 break;
5827
5828 default:
5829 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
5830 break;
ecc51f48 5831 }
bdf4d63a 5832 putchar ('\n');
ecc51f48
NC
5833}
5834
252b5132 5835static int
2cf0635d 5836get_32bit_dynamic_section (FILE * file)
252b5132 5837{
2cf0635d
NC
5838 Elf32_External_Dyn * edyn;
5839 Elf32_External_Dyn * ext;
5840 Elf_Internal_Dyn * entry;
103f02d3 5841
3f5e193b
NC
5842 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
5843 dynamic_size, _("dynamic section"));
a6e9f9df
AM
5844 if (!edyn)
5845 return 0;
103f02d3 5846
ba2685cc
AM
5847/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5848 might not have the luxury of section headers. Look for the DT_NULL
5849 terminator to determine the number of entries. */
5850 for (ext = edyn, dynamic_nent = 0;
5851 (char *) ext < (char *) edyn + dynamic_size;
5852 ext++)
5853 {
5854 dynamic_nent++;
5855 if (BYTE_GET (ext->d_tag) == DT_NULL)
5856 break;
5857 }
252b5132 5858
3f5e193b
NC
5859 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
5860 sizeof (* entry));
b2d38a17 5861 if (dynamic_section == NULL)
252b5132 5862 {
9ea033b2
NC
5863 error (_("Out of memory\n"));
5864 free (edyn);
5865 return 0;
5866 }
252b5132 5867
fb514b26 5868 for (ext = edyn, entry = dynamic_section;
ba2685cc 5869 entry < dynamic_section + dynamic_nent;
fb514b26 5870 ext++, entry++)
9ea033b2 5871 {
fb514b26
AM
5872 entry->d_tag = BYTE_GET (ext->d_tag);
5873 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5874 }
5875
9ea033b2
NC
5876 free (edyn);
5877
5878 return 1;
5879}
5880
5881static int
2cf0635d 5882get_64bit_dynamic_section (FILE * file)
9ea033b2 5883{
2cf0635d
NC
5884 Elf64_External_Dyn * edyn;
5885 Elf64_External_Dyn * ext;
5886 Elf_Internal_Dyn * entry;
103f02d3 5887
3f5e193b
NC
5888 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
5889 dynamic_size, _("dynamic section"));
a6e9f9df
AM
5890 if (!edyn)
5891 return 0;
103f02d3 5892
ba2685cc
AM
5893/* SGI's ELF has more than one section in the DYNAMIC segment, and we
5894 might not have the luxury of section headers. Look for the DT_NULL
5895 terminator to determine the number of entries. */
5896 for (ext = edyn, dynamic_nent = 0;
5897 (char *) ext < (char *) edyn + dynamic_size;
5898 ext++)
5899 {
5900 dynamic_nent++;
66543521 5901 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
5902 break;
5903 }
252b5132 5904
3f5e193b
NC
5905 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
5906 sizeof (* entry));
b2d38a17 5907 if (dynamic_section == NULL)
252b5132
RH
5908 {
5909 error (_("Out of memory\n"));
5910 free (edyn);
5911 return 0;
5912 }
5913
fb514b26 5914 for (ext = edyn, entry = dynamic_section;
ba2685cc 5915 entry < dynamic_section + dynamic_nent;
fb514b26 5916 ext++, entry++)
252b5132 5917 {
66543521
AM
5918 entry->d_tag = BYTE_GET (ext->d_tag);
5919 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
5920 }
5921
5922 free (edyn);
5923
9ea033b2
NC
5924 return 1;
5925}
5926
e9e44622
JJ
5927static void
5928print_dynamic_flags (bfd_vma flags)
d1133906 5929{
e9e44622 5930 int first = 1;
13ae64f3 5931
d1133906
NC
5932 while (flags)
5933 {
5934 bfd_vma flag;
5935
5936 flag = flags & - flags;
5937 flags &= ~ flag;
5938
e9e44622
JJ
5939 if (first)
5940 first = 0;
5941 else
5942 putc (' ', stdout);
13ae64f3 5943
d1133906
NC
5944 switch (flag)
5945 {
e9e44622
JJ
5946 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
5947 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
5948 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
5949 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
5950 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
5951 default: fputs ("unknown", stdout); break;
d1133906
NC
5952 }
5953 }
e9e44622 5954 puts ("");
d1133906
NC
5955}
5956
b2d38a17
NC
5957/* Parse and display the contents of the dynamic section. */
5958
9ea033b2 5959static int
2cf0635d 5960process_dynamic_section (FILE * file)
9ea033b2 5961{
2cf0635d 5962 Elf_Internal_Dyn * entry;
9ea033b2
NC
5963
5964 if (dynamic_size == 0)
5965 {
5966 if (do_dynamic)
b2d38a17 5967 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
5968
5969 return 1;
5970 }
5971
5972 if (is_32bit_elf)
5973 {
b2d38a17 5974 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
5975 return 0;
5976 }
b2d38a17 5977 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
5978 return 0;
5979
252b5132
RH
5980 /* Find the appropriate symbol table. */
5981 if (dynamic_symbols == NULL)
5982 {
86dba8ee
AM
5983 for (entry = dynamic_section;
5984 entry < dynamic_section + dynamic_nent;
5985 ++entry)
252b5132 5986 {
c8286bd1 5987 Elf_Internal_Shdr section;
252b5132
RH
5988
5989 if (entry->d_tag != DT_SYMTAB)
5990 continue;
5991
5992 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
5993
5994 /* Since we do not know how big the symbol table is,
5995 we default to reading in the entire file (!) and
5996 processing that. This is overkill, I know, but it
e3c8793a 5997 should work. */
d93f0186 5998 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 5999
fb52b2f4
NC
6000 if (archive_file_offset != 0)
6001 section.sh_size = archive_file_size - section.sh_offset;
6002 else
6003 {
6004 if (fseek (file, 0, SEEK_END))
591a748a 6005 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
6006
6007 section.sh_size = ftell (file) - section.sh_offset;
6008 }
252b5132 6009
9ea033b2 6010 if (is_32bit_elf)
9ad5cbcf 6011 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 6012 else
9ad5cbcf 6013 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 6014
9ad5cbcf 6015 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 6016 if (num_dynamic_syms < 1)
252b5132
RH
6017 {
6018 error (_("Unable to determine the number of symbols to load\n"));
6019 continue;
6020 }
6021
9ad5cbcf 6022 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
6023 }
6024 }
6025
6026 /* Similarly find a string table. */
6027 if (dynamic_strings == NULL)
6028 {
86dba8ee
AM
6029 for (entry = dynamic_section;
6030 entry < dynamic_section + dynamic_nent;
6031 ++entry)
252b5132
RH
6032 {
6033 unsigned long offset;
b34976b6 6034 long str_tab_len;
252b5132
RH
6035
6036 if (entry->d_tag != DT_STRTAB)
6037 continue;
6038
6039 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
6040
6041 /* Since we do not know how big the string table is,
6042 we default to reading in the entire file (!) and
6043 processing that. This is overkill, I know, but it
e3c8793a 6044 should work. */
252b5132 6045
d93f0186 6046 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
6047
6048 if (archive_file_offset != 0)
6049 str_tab_len = archive_file_size - offset;
6050 else
6051 {
6052 if (fseek (file, 0, SEEK_END))
6053 error (_("Unable to seek to end of file\n"));
6054 str_tab_len = ftell (file) - offset;
6055 }
252b5132
RH
6056
6057 if (str_tab_len < 1)
6058 {
6059 error
6060 (_("Unable to determine the length of the dynamic string table\n"));
6061 continue;
6062 }
6063
3f5e193b
NC
6064 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
6065 str_tab_len,
6066 _("dynamic string table"));
d79b3d50 6067 dynamic_strings_length = str_tab_len;
252b5132
RH
6068 break;
6069 }
6070 }
6071
6072 /* And find the syminfo section if available. */
6073 if (dynamic_syminfo == NULL)
6074 {
3e8bba36 6075 unsigned long syminsz = 0;
252b5132 6076
86dba8ee
AM
6077 for (entry = dynamic_section;
6078 entry < dynamic_section + dynamic_nent;
6079 ++entry)
252b5132
RH
6080 {
6081 if (entry->d_tag == DT_SYMINENT)
6082 {
6083 /* Note: these braces are necessary to avoid a syntax
6084 error from the SunOS4 C compiler. */
6085 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
6086 }
6087 else if (entry->d_tag == DT_SYMINSZ)
6088 syminsz = entry->d_un.d_val;
6089 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
6090 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
6091 syminsz);
252b5132
RH
6092 }
6093
6094 if (dynamic_syminfo_offset != 0 && syminsz != 0)
6095 {
2cf0635d
NC
6096 Elf_External_Syminfo * extsyminfo;
6097 Elf_External_Syminfo * extsym;
6098 Elf_Internal_Syminfo * syminfo;
252b5132
RH
6099
6100 /* There is a syminfo section. Read the data. */
3f5e193b
NC
6101 extsyminfo = (Elf_External_Syminfo *)
6102 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
6103 _("symbol information"));
a6e9f9df
AM
6104 if (!extsyminfo)
6105 return 0;
252b5132 6106
3f5e193b 6107 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
6108 if (dynamic_syminfo == NULL)
6109 {
6110 error (_("Out of memory\n"));
6111 return 0;
6112 }
6113
6114 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
6115 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
6116 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
6117 ++syminfo, ++extsym)
252b5132 6118 {
86dba8ee
AM
6119 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
6120 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
6121 }
6122
6123 free (extsyminfo);
6124 }
6125 }
6126
6127 if (do_dynamic && dynamic_addr)
86dba8ee
AM
6128 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
6129 dynamic_addr, dynamic_nent);
252b5132
RH
6130 if (do_dynamic)
6131 printf (_(" Tag Type Name/Value\n"));
6132
86dba8ee
AM
6133 for (entry = dynamic_section;
6134 entry < dynamic_section + dynamic_nent;
6135 entry++)
252b5132
RH
6136 {
6137 if (do_dynamic)
f7a99963 6138 {
2cf0635d 6139 const char * dtype;
e699b9ff 6140
f7a99963
NC
6141 putchar (' ');
6142 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
6143 dtype = get_dynamic_type (entry->d_tag);
6144 printf (" (%s)%*s", dtype,
6145 ((is_32bit_elf ? 27 : 19)
6146 - (int) strlen (dtype)),
f7a99963
NC
6147 " ");
6148 }
252b5132
RH
6149
6150 switch (entry->d_tag)
6151 {
d1133906
NC
6152 case DT_FLAGS:
6153 if (do_dynamic)
e9e44622 6154 print_dynamic_flags (entry->d_un.d_val);
d1133906 6155 break;
76da6bbe 6156
252b5132
RH
6157 case DT_AUXILIARY:
6158 case DT_FILTER:
019148e4
L
6159 case DT_CONFIG:
6160 case DT_DEPAUDIT:
6161 case DT_AUDIT:
252b5132
RH
6162 if (do_dynamic)
6163 {
019148e4 6164 switch (entry->d_tag)
b34976b6 6165 {
019148e4
L
6166 case DT_AUXILIARY:
6167 printf (_("Auxiliary library"));
6168 break;
6169
6170 case DT_FILTER:
6171 printf (_("Filter library"));
6172 break;
6173
b34976b6 6174 case DT_CONFIG:
019148e4
L
6175 printf (_("Configuration file"));
6176 break;
6177
6178 case DT_DEPAUDIT:
6179 printf (_("Dependency audit library"));
6180 break;
6181
6182 case DT_AUDIT:
6183 printf (_("Audit library"));
6184 break;
6185 }
252b5132 6186
d79b3d50
NC
6187 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6188 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 6189 else
f7a99963
NC
6190 {
6191 printf (": ");
6192 print_vma (entry->d_un.d_val, PREFIX_HEX);
6193 putchar ('\n');
6194 }
252b5132
RH
6195 }
6196 break;
6197
dcefbbbd 6198 case DT_FEATURE:
252b5132
RH
6199 if (do_dynamic)
6200 {
6201 printf (_("Flags:"));
86f55779 6202
252b5132
RH
6203 if (entry->d_un.d_val == 0)
6204 printf (_(" None\n"));
6205 else
6206 {
6207 unsigned long int val = entry->d_un.d_val;
86f55779 6208
252b5132
RH
6209 if (val & DTF_1_PARINIT)
6210 {
6211 printf (" PARINIT");
6212 val ^= DTF_1_PARINIT;
6213 }
dcefbbbd
L
6214 if (val & DTF_1_CONFEXP)
6215 {
6216 printf (" CONFEXP");
6217 val ^= DTF_1_CONFEXP;
6218 }
252b5132
RH
6219 if (val != 0)
6220 printf (" %lx", val);
6221 puts ("");
6222 }
6223 }
6224 break;
6225
6226 case DT_POSFLAG_1:
6227 if (do_dynamic)
6228 {
6229 printf (_("Flags:"));
86f55779 6230
252b5132
RH
6231 if (entry->d_un.d_val == 0)
6232 printf (_(" None\n"));
6233 else
6234 {
6235 unsigned long int val = entry->d_un.d_val;
86f55779 6236
252b5132
RH
6237 if (val & DF_P1_LAZYLOAD)
6238 {
6239 printf (" LAZYLOAD");
6240 val ^= DF_P1_LAZYLOAD;
6241 }
6242 if (val & DF_P1_GROUPPERM)
6243 {
6244 printf (" GROUPPERM");
6245 val ^= DF_P1_GROUPPERM;
6246 }
6247 if (val != 0)
6248 printf (" %lx", val);
6249 puts ("");
6250 }
6251 }
6252 break;
6253
6254 case DT_FLAGS_1:
6255 if (do_dynamic)
6256 {
6257 printf (_("Flags:"));
6258 if (entry->d_un.d_val == 0)
6259 printf (_(" None\n"));
6260 else
6261 {
6262 unsigned long int val = entry->d_un.d_val;
86f55779 6263
252b5132
RH
6264 if (val & DF_1_NOW)
6265 {
6266 printf (" NOW");
6267 val ^= DF_1_NOW;
6268 }
6269 if (val & DF_1_GLOBAL)
6270 {
6271 printf (" GLOBAL");
6272 val ^= DF_1_GLOBAL;
6273 }
6274 if (val & DF_1_GROUP)
6275 {
6276 printf (" GROUP");
6277 val ^= DF_1_GROUP;
6278 }
6279 if (val & DF_1_NODELETE)
6280 {
6281 printf (" NODELETE");
6282 val ^= DF_1_NODELETE;
6283 }
6284 if (val & DF_1_LOADFLTR)
6285 {
6286 printf (" LOADFLTR");
6287 val ^= DF_1_LOADFLTR;
6288 }
6289 if (val & DF_1_INITFIRST)
6290 {
6291 printf (" INITFIRST");
6292 val ^= DF_1_INITFIRST;
6293 }
6294 if (val & DF_1_NOOPEN)
6295 {
6296 printf (" NOOPEN");
6297 val ^= DF_1_NOOPEN;
6298 }
6299 if (val & DF_1_ORIGIN)
6300 {
6301 printf (" ORIGIN");
6302 val ^= DF_1_ORIGIN;
6303 }
6304 if (val & DF_1_DIRECT)
6305 {
6306 printf (" DIRECT");
6307 val ^= DF_1_DIRECT;
6308 }
6309 if (val & DF_1_TRANS)
6310 {
6311 printf (" TRANS");
6312 val ^= DF_1_TRANS;
6313 }
6314 if (val & DF_1_INTERPOSE)
6315 {
6316 printf (" INTERPOSE");
6317 val ^= DF_1_INTERPOSE;
6318 }
f7db6139 6319 if (val & DF_1_NODEFLIB)
dcefbbbd 6320 {
f7db6139
L
6321 printf (" NODEFLIB");
6322 val ^= DF_1_NODEFLIB;
dcefbbbd
L
6323 }
6324 if (val & DF_1_NODUMP)
6325 {
6326 printf (" NODUMP");
6327 val ^= DF_1_NODUMP;
6328 }
6329 if (val & DF_1_CONLFAT)
6330 {
6331 printf (" CONLFAT");
6332 val ^= DF_1_CONLFAT;
6333 }
252b5132
RH
6334 if (val != 0)
6335 printf (" %lx", val);
6336 puts ("");
6337 }
6338 }
6339 break;
6340
6341 case DT_PLTREL:
566b0d53 6342 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6343 if (do_dynamic)
6344 puts (get_dynamic_type (entry->d_un.d_val));
6345 break;
6346
6347 case DT_NULL :
6348 case DT_NEEDED :
6349 case DT_PLTGOT :
6350 case DT_HASH :
6351 case DT_STRTAB :
6352 case DT_SYMTAB :
6353 case DT_RELA :
6354 case DT_INIT :
6355 case DT_FINI :
6356 case DT_SONAME :
6357 case DT_RPATH :
6358 case DT_SYMBOLIC:
6359 case DT_REL :
6360 case DT_DEBUG :
6361 case DT_TEXTREL :
6362 case DT_JMPREL :
019148e4 6363 case DT_RUNPATH :
252b5132
RH
6364 dynamic_info[entry->d_tag] = entry->d_un.d_val;
6365
6366 if (do_dynamic)
6367 {
2cf0635d 6368 char * name;
252b5132 6369
d79b3d50
NC
6370 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
6371 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6372 else
d79b3d50 6373 name = NULL;
252b5132
RH
6374
6375 if (name)
6376 {
6377 switch (entry->d_tag)
6378 {
6379 case DT_NEEDED:
6380 printf (_("Shared library: [%s]"), name);
6381
18bd398b 6382 if (streq (name, program_interpreter))
f7a99963 6383 printf (_(" program interpreter"));
252b5132
RH
6384 break;
6385
6386 case DT_SONAME:
f7a99963 6387 printf (_("Library soname: [%s]"), name);
252b5132
RH
6388 break;
6389
6390 case DT_RPATH:
f7a99963 6391 printf (_("Library rpath: [%s]"), name);
252b5132
RH
6392 break;
6393
019148e4
L
6394 case DT_RUNPATH:
6395 printf (_("Library runpath: [%s]"), name);
6396 break;
6397
252b5132 6398 default:
f7a99963
NC
6399 print_vma (entry->d_un.d_val, PREFIX_HEX);
6400 break;
252b5132
RH
6401 }
6402 }
6403 else
f7a99963
NC
6404 print_vma (entry->d_un.d_val, PREFIX_HEX);
6405
6406 putchar ('\n');
252b5132
RH
6407 }
6408 break;
6409
6410 case DT_PLTRELSZ:
6411 case DT_RELASZ :
6412 case DT_STRSZ :
6413 case DT_RELSZ :
6414 case DT_RELAENT :
6415 case DT_SYMENT :
6416 case DT_RELENT :
566b0d53 6417 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
6418 case DT_PLTPADSZ:
6419 case DT_MOVEENT :
6420 case DT_MOVESZ :
6421 case DT_INIT_ARRAYSZ:
6422 case DT_FINI_ARRAYSZ:
047b2264
JJ
6423 case DT_GNU_CONFLICTSZ:
6424 case DT_GNU_LIBLISTSZ:
252b5132 6425 if (do_dynamic)
f7a99963
NC
6426 {
6427 print_vma (entry->d_un.d_val, UNSIGNED);
6428 printf (" (bytes)\n");
6429 }
252b5132
RH
6430 break;
6431
6432 case DT_VERDEFNUM:
6433 case DT_VERNEEDNUM:
6434 case DT_RELACOUNT:
6435 case DT_RELCOUNT:
6436 if (do_dynamic)
f7a99963
NC
6437 {
6438 print_vma (entry->d_un.d_val, UNSIGNED);
6439 putchar ('\n');
6440 }
252b5132
RH
6441 break;
6442
6443 case DT_SYMINSZ:
6444 case DT_SYMINENT:
6445 case DT_SYMINFO:
6446 case DT_USED:
6447 case DT_INIT_ARRAY:
6448 case DT_FINI_ARRAY:
6449 if (do_dynamic)
6450 {
d79b3d50
NC
6451 if (entry->d_tag == DT_USED
6452 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 6453 {
2cf0635d 6454 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 6455
b34976b6 6456 if (*name)
252b5132
RH
6457 {
6458 printf (_("Not needed object: [%s]\n"), name);
6459 break;
6460 }
6461 }
103f02d3 6462
f7a99963
NC
6463 print_vma (entry->d_un.d_val, PREFIX_HEX);
6464 putchar ('\n');
252b5132
RH
6465 }
6466 break;
6467
6468 case DT_BIND_NOW:
6469 /* The value of this entry is ignored. */
35b1837e
AM
6470 if (do_dynamic)
6471 putchar ('\n');
252b5132 6472 break;
103f02d3 6473
047b2264
JJ
6474 case DT_GNU_PRELINKED:
6475 if (do_dynamic)
6476 {
2cf0635d 6477 struct tm * tmp;
047b2264
JJ
6478 time_t time = entry->d_un.d_val;
6479
6480 tmp = gmtime (&time);
6481 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
6482 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
6483 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
6484
6485 }
6486 break;
6487
fdc90cb4
JJ
6488 case DT_GNU_HASH:
6489 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
6490 if (do_dynamic)
6491 {
6492 print_vma (entry->d_un.d_val, PREFIX_HEX);
6493 putchar ('\n');
6494 }
6495 break;
6496
252b5132
RH
6497 default:
6498 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 6499 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
6500 entry->d_un.d_val;
6501
6502 if (do_dynamic)
6503 {
6504 switch (elf_header.e_machine)
6505 {
6506 case EM_MIPS:
4fe85591 6507 case EM_MIPS_RS3_LE:
b2d38a17 6508 dynamic_section_mips_val (entry);
252b5132 6509 break;
103f02d3 6510 case EM_PARISC:
b2d38a17 6511 dynamic_section_parisc_val (entry);
103f02d3 6512 break;
ecc51f48 6513 case EM_IA_64:
b2d38a17 6514 dynamic_section_ia64_val (entry);
ecc51f48 6515 break;
252b5132 6516 default:
f7a99963
NC
6517 print_vma (entry->d_un.d_val, PREFIX_HEX);
6518 putchar ('\n');
252b5132
RH
6519 }
6520 }
6521 break;
6522 }
6523 }
6524
6525 return 1;
6526}
6527
6528static char *
d3ba0551 6529get_ver_flags (unsigned int flags)
252b5132 6530{
b34976b6 6531 static char buff[32];
252b5132
RH
6532
6533 buff[0] = 0;
6534
6535 if (flags == 0)
6536 return _("none");
6537
6538 if (flags & VER_FLG_BASE)
6539 strcat (buff, "BASE ");
6540
6541 if (flags & VER_FLG_WEAK)
6542 {
6543 if (flags & VER_FLG_BASE)
6544 strcat (buff, "| ");
6545
6546 strcat (buff, "WEAK ");
6547 }
6548
6549 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
6550 strcat (buff, "| <unknown>");
6551
6552 return buff;
6553}
6554
6555/* Display the contents of the version sections. */
98fb390a 6556
252b5132 6557static int
2cf0635d 6558process_version_sections (FILE * file)
252b5132 6559{
2cf0635d 6560 Elf_Internal_Shdr * section;
b34976b6
AM
6561 unsigned i;
6562 int found = 0;
252b5132
RH
6563
6564 if (! do_version)
6565 return 1;
6566
6567 for (i = 0, section = section_headers;
6568 i < elf_header.e_shnum;
b34976b6 6569 i++, section++)
252b5132
RH
6570 {
6571 switch (section->sh_type)
6572 {
6573 case SHT_GNU_verdef:
6574 {
2cf0635d 6575 Elf_External_Verdef * edefs;
b34976b6
AM
6576 unsigned int idx;
6577 unsigned int cnt;
2cf0635d 6578 char * endbuf;
252b5132
RH
6579
6580 found = 1;
6581
6582 printf
72de5009 6583 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
6584 SECTION_NAME (section), section->sh_info);
6585
6586 printf (_(" Addr: 0x"));
6587 printf_vma (section->sh_addr);
72de5009 6588 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 6589 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
6590 section->sh_link < elf_header.e_shnum
6591 ? SECTION_NAME (section_headers + section->sh_link)
c256ffe7 6592 : "<corrupt>");
252b5132 6593
3f5e193b
NC
6594 edefs = (Elf_External_Verdef *)
6595 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
6596 _("version definition section"));
54806181 6597 endbuf = (char *) edefs + section->sh_size;
a6e9f9df
AM
6598 if (!edefs)
6599 break;
252b5132 6600
b34976b6 6601 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 6602 {
2cf0635d
NC
6603 char * vstart;
6604 Elf_External_Verdef * edef;
b34976b6 6605 Elf_Internal_Verdef ent;
2cf0635d 6606 Elf_External_Verdaux * eaux;
b34976b6
AM
6607 Elf_Internal_Verdaux aux;
6608 int j;
6609 int isum;
103f02d3 6610
252b5132 6611 vstart = ((char *) edefs) + idx;
54806181
AM
6612 if (vstart + sizeof (*edef) > endbuf)
6613 break;
252b5132
RH
6614
6615 edef = (Elf_External_Verdef *) vstart;
6616
6617 ent.vd_version = BYTE_GET (edef->vd_version);
6618 ent.vd_flags = BYTE_GET (edef->vd_flags);
6619 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
6620 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
6621 ent.vd_hash = BYTE_GET (edef->vd_hash);
6622 ent.vd_aux = BYTE_GET (edef->vd_aux);
6623 ent.vd_next = BYTE_GET (edef->vd_next);
6624
6625 printf (_(" %#06x: Rev: %d Flags: %s"),
6626 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
6627
6628 printf (_(" Index: %d Cnt: %d "),
6629 ent.vd_ndx, ent.vd_cnt);
6630
6631 vstart += ent.vd_aux;
6632
6633 eaux = (Elf_External_Verdaux *) vstart;
6634
6635 aux.vda_name = BYTE_GET (eaux->vda_name);
6636 aux.vda_next = BYTE_GET (eaux->vda_next);
6637
d79b3d50
NC
6638 if (VALID_DYNAMIC_NAME (aux.vda_name))
6639 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6640 else
6641 printf (_("Name index: %ld\n"), aux.vda_name);
6642
6643 isum = idx + ent.vd_aux;
6644
b34976b6 6645 for (j = 1; j < ent.vd_cnt; j++)
252b5132
RH
6646 {
6647 isum += aux.vda_next;
6648 vstart += aux.vda_next;
6649
6650 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
6651 if (vstart + sizeof (*eaux) > endbuf)
6652 break;
252b5132
RH
6653
6654 aux.vda_name = BYTE_GET (eaux->vda_name);
6655 aux.vda_next = BYTE_GET (eaux->vda_next);
6656
d79b3d50 6657 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 6658 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 6659 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
6660 else
6661 printf (_(" %#06x: Parent %d, name index: %ld\n"),
6662 isum, j, aux.vda_name);
6663 }
54806181
AM
6664 if (j < ent.vd_cnt)
6665 printf (_(" Version def aux past end of section\n"));
252b5132
RH
6666
6667 idx += ent.vd_next;
6668 }
54806181
AM
6669 if (cnt < section->sh_info)
6670 printf (_(" Version definition past end of section\n"));
252b5132
RH
6671
6672 free (edefs);
6673 }
6674 break;
103f02d3 6675
252b5132
RH
6676 case SHT_GNU_verneed:
6677 {
2cf0635d 6678 Elf_External_Verneed * eneed;
b34976b6
AM
6679 unsigned int idx;
6680 unsigned int cnt;
2cf0635d 6681 char * endbuf;
252b5132
RH
6682
6683 found = 1;
6684
72de5009 6685 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
6686 SECTION_NAME (section), section->sh_info);
6687
6688 printf (_(" Addr: 0x"));
6689 printf_vma (section->sh_addr);
72de5009 6690 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 6691 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
6692 section->sh_link < elf_header.e_shnum
6693 ? SECTION_NAME (section_headers + section->sh_link)
c256ffe7 6694 : "<corrupt>");
252b5132 6695
3f5e193b
NC
6696 eneed = (Elf_External_Verneed *) get_data (NULL, file,
6697 section->sh_offset, 1,
6698 section->sh_size,
6699 _("version need section"));
54806181 6700 endbuf = (char *) eneed + section->sh_size;
a6e9f9df
AM
6701 if (!eneed)
6702 break;
252b5132
RH
6703
6704 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
6705 {
2cf0635d 6706 Elf_External_Verneed * entry;
b34976b6
AM
6707 Elf_Internal_Verneed ent;
6708 int j;
6709 int isum;
2cf0635d 6710 char * vstart;
252b5132
RH
6711
6712 vstart = ((char *) eneed) + idx;
54806181
AM
6713 if (vstart + sizeof (*entry) > endbuf)
6714 break;
252b5132
RH
6715
6716 entry = (Elf_External_Verneed *) vstart;
6717
6718 ent.vn_version = BYTE_GET (entry->vn_version);
6719 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
6720 ent.vn_file = BYTE_GET (entry->vn_file);
6721 ent.vn_aux = BYTE_GET (entry->vn_aux);
6722 ent.vn_next = BYTE_GET (entry->vn_next);
6723
6724 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
6725
d79b3d50
NC
6726 if (VALID_DYNAMIC_NAME (ent.vn_file))
6727 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
6728 else
6729 printf (_(" File: %lx"), ent.vn_file);
6730
6731 printf (_(" Cnt: %d\n"), ent.vn_cnt);
6732
6733 vstart += ent.vn_aux;
6734
6735 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
6736 {
2cf0635d 6737 Elf_External_Vernaux * eaux;
b34976b6 6738 Elf_Internal_Vernaux aux;
252b5132 6739
54806181
AM
6740 if (vstart + sizeof (*eaux) > endbuf)
6741 break;
252b5132
RH
6742 eaux = (Elf_External_Vernaux *) vstart;
6743
6744 aux.vna_hash = BYTE_GET (eaux->vna_hash);
6745 aux.vna_flags = BYTE_GET (eaux->vna_flags);
6746 aux.vna_other = BYTE_GET (eaux->vna_other);
6747 aux.vna_name = BYTE_GET (eaux->vna_name);
6748 aux.vna_next = BYTE_GET (eaux->vna_next);
6749
d79b3d50 6750 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 6751 printf (_(" %#06x: Name: %s"),
d79b3d50 6752 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 6753 else
ecc2063b 6754 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
6755 isum, aux.vna_name);
6756
6757 printf (_(" Flags: %s Version: %d\n"),
6758 get_ver_flags (aux.vna_flags), aux.vna_other);
6759
6760 isum += aux.vna_next;
6761 vstart += aux.vna_next;
6762 }
54806181
AM
6763 if (j < ent.vn_cnt)
6764 printf (_(" Version need aux past end of section\n"));
252b5132
RH
6765
6766 idx += ent.vn_next;
6767 }
54806181
AM
6768 if (cnt < section->sh_info)
6769 printf (_(" Version need past end of section\n"));
103f02d3 6770
252b5132
RH
6771 free (eneed);
6772 }
6773 break;
6774
6775 case SHT_GNU_versym:
6776 {
2cf0635d 6777 Elf_Internal_Shdr * link_section;
b34976b6
AM
6778 int total;
6779 int cnt;
2cf0635d
NC
6780 unsigned char * edata;
6781 unsigned short * data;
6782 char * strtab;
6783 Elf_Internal_Sym * symbols;
6784 Elf_Internal_Shdr * string_sec;
d3ba0551 6785 long off;
252b5132 6786
4fbb74a6 6787 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
6788 break;
6789
4fbb74a6 6790 link_section = section_headers + section->sh_link;
08d8fa11 6791 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 6792
4fbb74a6 6793 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
6794 break;
6795
252b5132
RH
6796 found = 1;
6797
9ad5cbcf 6798 symbols = GET_ELF_SYMBOLS (file, link_section);
252b5132 6799
4fbb74a6 6800 string_sec = section_headers + link_section->sh_link;
252b5132 6801
3f5e193b
NC
6802 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
6803 string_sec->sh_size,
6804 _("version string table"));
a6e9f9df
AM
6805 if (!strtab)
6806 break;
252b5132
RH
6807
6808 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
6809 SECTION_NAME (section), total);
6810
6811 printf (_(" Addr: "));
6812 printf_vma (section->sh_addr);
72de5009 6813 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 6814 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
6815 SECTION_NAME (link_section));
6816
d3ba0551
AM
6817 off = offset_from_vma (file,
6818 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
6819 total * sizeof (short));
3f5e193b
NC
6820 edata = (unsigned char *) get_data (NULL, file, off, total,
6821 sizeof (short),
6822 _("version symbol data"));
a6e9f9df
AM
6823 if (!edata)
6824 {
6825 free (strtab);
6826 break;
6827 }
252b5132 6828
3f5e193b 6829 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
6830
6831 for (cnt = total; cnt --;)
b34976b6
AM
6832 data[cnt] = byte_get (edata + cnt * sizeof (short),
6833 sizeof (short));
252b5132
RH
6834
6835 free (edata);
6836
6837 for (cnt = 0; cnt < total; cnt += 4)
6838 {
6839 int j, nn;
00d93f34 6840 int check_def, check_need;
2cf0635d 6841 char * name;
252b5132
RH
6842
6843 printf (" %03x:", cnt);
6844
6845 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 6846 switch (data[cnt + j])
252b5132
RH
6847 {
6848 case 0:
6849 fputs (_(" 0 (*local*) "), stdout);
6850 break;
6851
6852 case 1:
6853 fputs (_(" 1 (*global*) "), stdout);
6854 break;
6855
6856 default:
c244d050
NC
6857 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
6858 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 6859
00d93f34
JJ
6860 check_def = 1;
6861 check_need = 1;
4fbb74a6
AM
6862 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
6863 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 6864 != SHT_NOBITS)
252b5132 6865 {
b34976b6 6866 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
6867 check_def = 0;
6868 else
6869 check_need = 0;
252b5132 6870 }
00d93f34
JJ
6871
6872 if (check_need
b34976b6 6873 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 6874 {
b34976b6
AM
6875 Elf_Internal_Verneed ivn;
6876 unsigned long offset;
252b5132 6877
d93f0186
NC
6878 offset = offset_from_vma
6879 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
6880 sizeof (Elf_External_Verneed));
252b5132 6881
b34976b6 6882 do
252b5132 6883 {
b34976b6
AM
6884 Elf_Internal_Vernaux ivna;
6885 Elf_External_Verneed evn;
6886 Elf_External_Vernaux evna;
6887 unsigned long a_off;
252b5132 6888
c256ffe7 6889 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 6890 _("version need"));
252b5132
RH
6891
6892 ivn.vn_aux = BYTE_GET (evn.vn_aux);
6893 ivn.vn_next = BYTE_GET (evn.vn_next);
6894
6895 a_off = offset + ivn.vn_aux;
6896
6897 do
6898 {
a6e9f9df 6899 get_data (&evna, file, a_off, sizeof (evna),
c256ffe7 6900 1, _("version need aux (2)"));
252b5132
RH
6901
6902 ivna.vna_next = BYTE_GET (evna.vna_next);
6903 ivna.vna_other = BYTE_GET (evna.vna_other);
6904
6905 a_off += ivna.vna_next;
6906 }
b34976b6 6907 while (ivna.vna_other != data[cnt + j]
252b5132
RH
6908 && ivna.vna_next != 0);
6909
b34976b6 6910 if (ivna.vna_other == data[cnt + j])
252b5132
RH
6911 {
6912 ivna.vna_name = BYTE_GET (evna.vna_name);
6913
54806181
AM
6914 if (ivna.vna_name >= string_sec->sh_size)
6915 name = _("*invalid*");
6916 else
6917 name = strtab + ivna.vna_name;
252b5132 6918 nn += printf ("(%s%-*s",
16062207
ILT
6919 name,
6920 12 - (int) strlen (name),
252b5132 6921 ")");
00d93f34 6922 check_def = 0;
252b5132
RH
6923 break;
6924 }
6925
6926 offset += ivn.vn_next;
6927 }
6928 while (ivn.vn_next);
6929 }
00d93f34 6930
b34976b6
AM
6931 if (check_def && data[cnt + j] != 0x8001
6932 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 6933 {
b34976b6
AM
6934 Elf_Internal_Verdef ivd;
6935 Elf_External_Verdef evd;
6936 unsigned long offset;
252b5132 6937
d93f0186
NC
6938 offset = offset_from_vma
6939 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
6940 sizeof evd);
252b5132
RH
6941
6942 do
6943 {
c256ffe7 6944 get_data (&evd, file, offset, sizeof (evd), 1,
a6e9f9df 6945 _("version def"));
252b5132
RH
6946
6947 ivd.vd_next = BYTE_GET (evd.vd_next);
6948 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
6949
6950 offset += ivd.vd_next;
6951 }
c244d050 6952 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
6953 && ivd.vd_next != 0);
6954
c244d050 6955 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 6956 {
b34976b6
AM
6957 Elf_External_Verdaux evda;
6958 Elf_Internal_Verdaux ivda;
252b5132
RH
6959
6960 ivd.vd_aux = BYTE_GET (evd.vd_aux);
6961
a6e9f9df
AM
6962 get_data (&evda, file,
6963 offset - ivd.vd_next + ivd.vd_aux,
c256ffe7
JJ
6964 sizeof (evda), 1,
6965 _("version def aux"));
252b5132
RH
6966
6967 ivda.vda_name = BYTE_GET (evda.vda_name);
6968
54806181
AM
6969 if (ivda.vda_name >= string_sec->sh_size)
6970 name = _("*invalid*");
6971 else
6972 name = strtab + ivda.vda_name;
252b5132 6973 nn += printf ("(%s%-*s",
16062207
ILT
6974 name,
6975 12 - (int) strlen (name),
252b5132
RH
6976 ")");
6977 }
6978 }
6979
6980 if (nn < 18)
6981 printf ("%*c", 18 - nn, ' ');
6982 }
6983
6984 putchar ('\n');
6985 }
6986
6987 free (data);
6988 free (strtab);
6989 free (symbols);
6990 }
6991 break;
103f02d3 6992
252b5132
RH
6993 default:
6994 break;
6995 }
6996 }
6997
6998 if (! found)
6999 printf (_("\nNo version information found in this file.\n"));
7000
7001 return 1;
7002}
7003
d1133906 7004static const char *
d3ba0551 7005get_symbol_binding (unsigned int binding)
252b5132 7006{
b34976b6 7007 static char buff[32];
252b5132
RH
7008
7009 switch (binding)
7010 {
b34976b6
AM
7011 case STB_LOCAL: return "LOCAL";
7012 case STB_GLOBAL: return "GLOBAL";
7013 case STB_WEAK: return "WEAK";
252b5132
RH
7014 default:
7015 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
7016 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
7017 binding);
252b5132 7018 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
7019 {
7020 if (binding == STB_GNU_UNIQUE
7021 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
7022 /* GNU/Linux is still using the default value 0. */
7023 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
7024 return "UNIQUE";
7025 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
7026 }
252b5132 7027 else
e9e44622 7028 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
7029 return buff;
7030 }
7031}
7032
d1133906 7033static const char *
d3ba0551 7034get_symbol_type (unsigned int type)
252b5132 7035{
b34976b6 7036 static char buff[32];
252b5132
RH
7037
7038 switch (type)
7039 {
b34976b6
AM
7040 case STT_NOTYPE: return "NOTYPE";
7041 case STT_OBJECT: return "OBJECT";
7042 case STT_FUNC: return "FUNC";
7043 case STT_SECTION: return "SECTION";
7044 case STT_FILE: return "FILE";
7045 case STT_COMMON: return "COMMON";
7046 case STT_TLS: return "TLS";
15ab5209
DB
7047 case STT_RELC: return "RELC";
7048 case STT_SRELC: return "SRELC";
252b5132
RH
7049 default:
7050 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
7051 {
7052 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
7053 return "THUMB_FUNC";
7054
351b4b40 7055 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
7056 return "REGISTER";
7057
7058 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
7059 return "PARISC_MILLI";
7060
e9e44622 7061 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 7062 }
252b5132 7063 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
7064 {
7065 if (elf_header.e_machine == EM_PARISC)
7066 {
7067 if (type == STT_HP_OPAQUE)
7068 return "HP_OPAQUE";
7069 if (type == STT_HP_STUB)
7070 return "HP_STUB";
7071 }
7072
d8045f23
NC
7073 if (type == STT_GNU_IFUNC
7074 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_LINUX
7075 /* GNU/Linux is still using the default value 0. */
7076 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
7077 return "IFUNC";
7078
e9e44622 7079 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 7080 }
252b5132 7081 else
e9e44622 7082 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
7083 return buff;
7084 }
7085}
7086
d1133906 7087static const char *
d3ba0551 7088get_symbol_visibility (unsigned int visibility)
d1133906
NC
7089{
7090 switch (visibility)
7091 {
b34976b6
AM
7092 case STV_DEFAULT: return "DEFAULT";
7093 case STV_INTERNAL: return "INTERNAL";
7094 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
7095 case STV_PROTECTED: return "PROTECTED";
7096 default: abort ();
7097 }
7098}
7099
5e2b0d47
NC
7100static const char *
7101get_mips_symbol_other (unsigned int other)
7102{
7103 switch (other)
7104 {
7105 case STO_OPTIONAL: return "OPTIONAL";
7106 case STO_MIPS16: return "MIPS16";
861fb55a
DJ
7107 case STO_MIPS_PLT: return "MIPS PLT";
7108 case STO_MIPS_PIC: return "MIPS PIC";
5e2b0d47
NC
7109 default: return NULL;
7110 }
7111}
7112
7113static const char *
7114get_symbol_other (unsigned int other)
7115{
7116 const char * result = NULL;
7117 static char buff [32];
7118
7119 if (other == 0)
7120 return "";
7121
7122 switch (elf_header.e_machine)
7123 {
7124 case EM_MIPS:
7125 result = get_mips_symbol_other (other);
7126 default:
7127 break;
7128 }
7129
7130 if (result)
7131 return result;
7132
7133 snprintf (buff, sizeof buff, _("<other>: %x"), other);
7134 return buff;
7135}
7136
d1133906 7137static const char *
d3ba0551 7138get_symbol_index_type (unsigned int type)
252b5132 7139{
b34976b6 7140 static char buff[32];
5cf1065c 7141
252b5132
RH
7142 switch (type)
7143 {
b34976b6
AM
7144 case SHN_UNDEF: return "UND";
7145 case SHN_ABS: return "ABS";
7146 case SHN_COMMON: return "COM";
252b5132 7147 default:
9ce701e2
L
7148 if (type == SHN_IA_64_ANSI_COMMON
7149 && elf_header.e_machine == EM_IA_64
7150 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
7151 return "ANSI_COM";
8a9036a4
L
7152 else if ((elf_header.e_machine == EM_X86_64
7153 || elf_header.e_machine == EM_L1OM)
3b22753a
L
7154 && type == SHN_X86_64_LCOMMON)
7155 return "LARGE_COM";
172553c7
TS
7156 else if (type == SHN_MIPS_SCOMMON
7157 && elf_header.e_machine == EM_MIPS)
7158 return "SCOM";
7159 else if (type == SHN_MIPS_SUNDEFINED
7160 && elf_header.e_machine == EM_MIPS)
7161 return "SUND";
9ce701e2 7162 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 7163 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 7164 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
7165 sprintf (buff, "OS [0x%04x]", type & 0xffff);
7166 else if (type >= SHN_LORESERVE)
7167 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 7168 else
232e7cb8 7169 sprintf (buff, "%3d", type);
5cf1065c 7170 break;
252b5132 7171 }
5cf1065c
NC
7172
7173 return buff;
252b5132
RH
7174}
7175
66543521 7176static bfd_vma *
2cf0635d 7177get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 7178{
2cf0635d
NC
7179 unsigned char * e_data;
7180 bfd_vma * i_data;
252b5132 7181
3f5e193b 7182 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
7183
7184 if (e_data == NULL)
7185 {
7186 error (_("Out of memory\n"));
7187 return NULL;
7188 }
7189
66543521 7190 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
7191 {
7192 error (_("Unable to read in dynamic data\n"));
7193 return NULL;
7194 }
7195
3f5e193b 7196 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
7197
7198 if (i_data == NULL)
7199 {
7200 error (_("Out of memory\n"));
7201 free (e_data);
7202 return NULL;
7203 }
7204
7205 while (number--)
66543521 7206 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
7207
7208 free (e_data);
7209
7210 return i_data;
7211}
7212
6bd1a22c
L
7213static void
7214print_dynamic_symbol (bfd_vma si, unsigned long hn)
7215{
2cf0635d 7216 Elf_Internal_Sym * psym;
6bd1a22c
L
7217 int n;
7218
7219 psym = dynamic_symbols + si;
7220
7221 n = print_vma (si, DEC_5);
7222 if (n < 5)
7223 fputs (" " + n, stdout);
7224 printf (" %3lu: ", hn);
7225 print_vma (psym->st_value, LONG_HEX);
7226 putchar (' ');
7227 print_vma (psym->st_size, DEC_5);
7228
f4be36b3
AM
7229 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7230 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
7231 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
7232 /* Check to see if any other bits in the st_other field are set.
7233 Note - displaying this information disrupts the layout of the
7234 table being generated, but for the moment this case is very
7235 rare. */
7236 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7237 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
7238 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
7239 if (VALID_DYNAMIC_NAME (psym->st_name))
7240 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
7241 else
7242 printf (" <corrupt: %14ld>", psym->st_name);
7243 putchar ('\n');
7244}
7245
e3c8793a 7246/* Dump the symbol table. */
252b5132 7247static int
2cf0635d 7248process_symbol_table (FILE * file)
252b5132 7249{
2cf0635d 7250 Elf_Internal_Shdr * section;
66543521
AM
7251 bfd_vma nbuckets = 0;
7252 bfd_vma nchains = 0;
2cf0635d
NC
7253 bfd_vma * buckets = NULL;
7254 bfd_vma * chains = NULL;
fdc90cb4 7255 bfd_vma ngnubuckets = 0;
2cf0635d
NC
7256 bfd_vma * gnubuckets = NULL;
7257 bfd_vma * gnuchains = NULL;
6bd1a22c 7258 bfd_vma gnusymidx = 0;
252b5132
RH
7259
7260 if (! do_syms && !do_histogram)
7261 return 1;
7262
6bd1a22c
L
7263 if (dynamic_info[DT_HASH]
7264 && (do_histogram
7265 || (do_using_dynamic && dynamic_strings != NULL)))
252b5132 7266 {
66543521
AM
7267 unsigned char nb[8];
7268 unsigned char nc[8];
7269 int hash_ent_size = 4;
7270
7271 if ((elf_header.e_machine == EM_ALPHA
7272 || elf_header.e_machine == EM_S390
7273 || elf_header.e_machine == EM_S390_OLD)
7274 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
7275 hash_ent_size = 8;
7276
fb52b2f4
NC
7277 if (fseek (file,
7278 (archive_file_offset
7279 + offset_from_vma (file, dynamic_info[DT_HASH],
7280 sizeof nb + sizeof nc)),
d93f0186 7281 SEEK_SET))
252b5132 7282 {
591a748a 7283 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 7284 goto no_hash;
252b5132
RH
7285 }
7286
66543521 7287 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
7288 {
7289 error (_("Failed to read in number of buckets\n"));
d3a44ec6 7290 goto no_hash;
252b5132
RH
7291 }
7292
66543521 7293 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
7294 {
7295 error (_("Failed to read in number of chains\n"));
d3a44ec6 7296 goto no_hash;
252b5132
RH
7297 }
7298
66543521
AM
7299 nbuckets = byte_get (nb, hash_ent_size);
7300 nchains = byte_get (nc, hash_ent_size);
252b5132 7301
66543521
AM
7302 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
7303 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 7304
d3a44ec6 7305 no_hash:
252b5132 7306 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
7307 {
7308 if (do_using_dynamic)
7309 return 0;
7310 free (buckets);
7311 free (chains);
7312 buckets = NULL;
7313 chains = NULL;
7314 nbuckets = 0;
7315 nchains = 0;
7316 }
252b5132
RH
7317 }
7318
6bd1a22c
L
7319 if (dynamic_info_DT_GNU_HASH
7320 && (do_histogram
7321 || (do_using_dynamic && dynamic_strings != NULL)))
252b5132 7322 {
6bd1a22c
L
7323 unsigned char nb[16];
7324 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
7325 bfd_vma buckets_vma;
7326
7327 if (fseek (file,
7328 (archive_file_offset
7329 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
7330 sizeof nb)),
7331 SEEK_SET))
7332 {
7333 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 7334 goto no_gnu_hash;
6bd1a22c 7335 }
252b5132 7336
6bd1a22c
L
7337 if (fread (nb, 16, 1, file) != 1)
7338 {
7339 error (_("Failed to read in number of buckets\n"));
d3a44ec6 7340 goto no_gnu_hash;
6bd1a22c
L
7341 }
7342
7343 ngnubuckets = byte_get (nb, 4);
7344 gnusymidx = byte_get (nb + 4, 4);
7345 bitmaskwords = byte_get (nb + 8, 4);
7346 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 7347 if (is_32bit_elf)
6bd1a22c 7348 buckets_vma += bitmaskwords * 4;
f7a99963 7349 else
6bd1a22c 7350 buckets_vma += bitmaskwords * 8;
252b5132 7351
6bd1a22c
L
7352 if (fseek (file,
7353 (archive_file_offset
7354 + offset_from_vma (file, buckets_vma, 4)),
7355 SEEK_SET))
252b5132 7356 {
6bd1a22c 7357 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 7358 goto no_gnu_hash;
6bd1a22c
L
7359 }
7360
7361 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 7362
6bd1a22c 7363 if (gnubuckets == NULL)
d3a44ec6 7364 goto no_gnu_hash;
6bd1a22c
L
7365
7366 for (i = 0; i < ngnubuckets; i++)
7367 if (gnubuckets[i] != 0)
7368 {
7369 if (gnubuckets[i] < gnusymidx)
7370 return 0;
7371
7372 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
7373 maxchain = gnubuckets[i];
7374 }
7375
7376 if (maxchain == 0xffffffff)
d3a44ec6 7377 goto no_gnu_hash;
6bd1a22c
L
7378
7379 maxchain -= gnusymidx;
7380
7381 if (fseek (file,
7382 (archive_file_offset
7383 + offset_from_vma (file, buckets_vma
7384 + 4 * (ngnubuckets + maxchain), 4)),
7385 SEEK_SET))
7386 {
7387 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 7388 goto no_gnu_hash;
6bd1a22c
L
7389 }
7390
7391 do
7392 {
7393 if (fread (nb, 4, 1, file) != 1)
252b5132 7394 {
6bd1a22c 7395 error (_("Failed to determine last chain length\n"));
d3a44ec6 7396 goto no_gnu_hash;
6bd1a22c 7397 }
252b5132 7398
6bd1a22c 7399 if (maxchain + 1 == 0)
d3a44ec6 7400 goto no_gnu_hash;
252b5132 7401
6bd1a22c
L
7402 ++maxchain;
7403 }
7404 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 7405
6bd1a22c
L
7406 if (fseek (file,
7407 (archive_file_offset
7408 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
7409 SEEK_SET))
7410 {
7411 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 7412 goto no_gnu_hash;
6bd1a22c
L
7413 }
7414
7415 gnuchains = get_dynamic_data (file, maxchain, 4);
7416
d3a44ec6 7417 no_gnu_hash:
6bd1a22c 7418 if (gnuchains == NULL)
d3a44ec6
JJ
7419 {
7420 free (gnubuckets);
d3a44ec6
JJ
7421 gnubuckets = NULL;
7422 ngnubuckets = 0;
f64fddf1
NC
7423 if (do_using_dynamic)
7424 return 0;
d3a44ec6 7425 }
6bd1a22c
L
7426 }
7427
7428 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
7429 && do_syms
7430 && do_using_dynamic
7431 && dynamic_strings != NULL)
7432 {
7433 unsigned long hn;
7434
7435 if (dynamic_info[DT_HASH])
7436 {
7437 bfd_vma si;
7438
7439 printf (_("\nSymbol table for image:\n"));
7440 if (is_32bit_elf)
7441 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7442 else
7443 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7444
7445 for (hn = 0; hn < nbuckets; hn++)
7446 {
7447 if (! buckets[hn])
7448 continue;
7449
7450 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
7451 print_dynamic_symbol (si, hn);
252b5132
RH
7452 }
7453 }
6bd1a22c
L
7454
7455 if (dynamic_info_DT_GNU_HASH)
7456 {
7457 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
7458 if (is_32bit_elf)
7459 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7460 else
7461 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
7462
7463 for (hn = 0; hn < ngnubuckets; ++hn)
7464 if (gnubuckets[hn] != 0)
7465 {
7466 bfd_vma si = gnubuckets[hn];
7467 bfd_vma off = si - gnusymidx;
7468
7469 do
7470 {
7471 print_dynamic_symbol (si, hn);
7472 si++;
7473 }
7474 while ((gnuchains[off++] & 1) == 0);
7475 }
7476 }
252b5132
RH
7477 }
7478 else if (do_syms && !do_using_dynamic)
7479 {
b34976b6 7480 unsigned int i;
252b5132
RH
7481
7482 for (i = 0, section = section_headers;
7483 i < elf_header.e_shnum;
7484 i++, section++)
7485 {
b34976b6 7486 unsigned int si;
2cf0635d 7487 char * strtab = NULL;
c256ffe7 7488 unsigned long int strtab_size = 0;
2cf0635d
NC
7489 Elf_Internal_Sym * symtab;
7490 Elf_Internal_Sym * psym;
252b5132
RH
7491
7492 if ( section->sh_type != SHT_SYMTAB
7493 && section->sh_type != SHT_DYNSYM)
7494 continue;
7495
7496 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
7497 SECTION_NAME (section),
7498 (unsigned long) (section->sh_size / section->sh_entsize));
f7a99963 7499 if (is_32bit_elf)
ca47b30c 7500 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 7501 else
ca47b30c 7502 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 7503
9ad5cbcf 7504 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
7505 if (symtab == NULL)
7506 continue;
7507
7508 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
7509 {
7510 strtab = string_table;
7511 strtab_size = string_table_length;
7512 }
4fbb74a6 7513 else if (section->sh_link < elf_header.e_shnum)
252b5132 7514 {
2cf0635d 7515 Elf_Internal_Shdr * string_sec;
252b5132 7516
4fbb74a6 7517 string_sec = section_headers + section->sh_link;
252b5132 7518
3f5e193b
NC
7519 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
7520 1, string_sec->sh_size,
7521 _("string table"));
c256ffe7 7522 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
7523 }
7524
7525 for (si = 0, psym = symtab;
7526 si < section->sh_size / section->sh_entsize;
b34976b6 7527 si++, psym++)
252b5132 7528 {
5e220199 7529 printf ("%6d: ", si);
f7a99963
NC
7530 print_vma (psym->st_value, LONG_HEX);
7531 putchar (' ');
7532 print_vma (psym->st_size, DEC_5);
d1133906
NC
7533 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
7534 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 7535 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
7536 /* Check to see if any other bits in the st_other field are set.
7537 Note - displaying this information disrupts the layout of the
7538 table being generated, but for the moment this case is very rare. */
7539 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
7540 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 7541 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7
JJ
7542 print_symbol (25, psym->st_name < strtab_size
7543 ? strtab + psym->st_name : "<corrupt>");
252b5132
RH
7544
7545 if (section->sh_type == SHT_DYNSYM &&
b34976b6 7546 version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 7547 {
b34976b6
AM
7548 unsigned char data[2];
7549 unsigned short vers_data;
7550 unsigned long offset;
7551 int is_nobits;
7552 int check_def;
252b5132 7553
d93f0186
NC
7554 offset = offset_from_vma
7555 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
7556 sizeof data + si * sizeof (vers_data));
252b5132 7557
a6e9f9df 7558 get_data (&data, file, offset + si * sizeof (vers_data),
c256ffe7 7559 sizeof (data), 1, _("version data"));
252b5132
RH
7560
7561 vers_data = byte_get (data, 2);
7562
4fbb74a6
AM
7563 is_nobits = (psym->st_shndx < elf_header.e_shnum
7564 && section_headers[psym->st_shndx].sh_type
c256ffe7 7565 == SHT_NOBITS);
252b5132
RH
7566
7567 check_def = (psym->st_shndx != SHN_UNDEF);
7568
c244d050 7569 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 7570 {
b34976b6 7571 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 7572 && (is_nobits || ! check_def))
252b5132 7573 {
b34976b6
AM
7574 Elf_External_Verneed evn;
7575 Elf_Internal_Verneed ivn;
7576 Elf_Internal_Vernaux ivna;
252b5132
RH
7577
7578 /* We must test both. */
d93f0186
NC
7579 offset = offset_from_vma
7580 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
7581 sizeof evn);
252b5132 7582
252b5132
RH
7583 do
7584 {
b34976b6 7585 unsigned long vna_off;
252b5132 7586
c256ffe7 7587 get_data (&evn, file, offset, sizeof (evn), 1,
a6e9f9df 7588 _("version need"));
dd27201e
L
7589
7590 ivn.vn_aux = BYTE_GET (evn.vn_aux);
7591 ivn.vn_next = BYTE_GET (evn.vn_next);
7592
252b5132
RH
7593 vna_off = offset + ivn.vn_aux;
7594
7595 do
7596 {
b34976b6 7597 Elf_External_Vernaux evna;
252b5132 7598
a6e9f9df 7599 get_data (&evna, file, vna_off,
c256ffe7 7600 sizeof (evna), 1,
a6e9f9df 7601 _("version need aux (3)"));
252b5132
RH
7602
7603 ivna.vna_other = BYTE_GET (evna.vna_other);
7604 ivna.vna_next = BYTE_GET (evna.vna_next);
7605 ivna.vna_name = BYTE_GET (evna.vna_name);
7606
7607 vna_off += ivna.vna_next;
7608 }
7609 while (ivna.vna_other != vers_data
7610 && ivna.vna_next != 0);
7611
7612 if (ivna.vna_other == vers_data)
7613 break;
7614
7615 offset += ivn.vn_next;
7616 }
7617 while (ivn.vn_next != 0);
7618
7619 if (ivna.vna_other == vers_data)
7620 {
7621 printf ("@%s (%d)",
c256ffe7
JJ
7622 ivna.vna_name < strtab_size
7623 ? strtab + ivna.vna_name : "<corrupt>",
7624 ivna.vna_other);
252b5132
RH
7625 check_def = 0;
7626 }
7627 else if (! is_nobits)
591a748a 7628 error (_("bad dynamic symbol\n"));
252b5132
RH
7629 else
7630 check_def = 1;
7631 }
7632
7633 if (check_def)
7634 {
00d93f34 7635 if (vers_data != 0x8001
b34976b6 7636 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 7637 {
b34976b6
AM
7638 Elf_Internal_Verdef ivd;
7639 Elf_Internal_Verdaux ivda;
7640 Elf_External_Verdaux evda;
7641 unsigned long offset;
252b5132 7642
d93f0186
NC
7643 offset = offset_from_vma
7644 (file,
7645 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
7646 sizeof (Elf_External_Verdef));
252b5132
RH
7647
7648 do
7649 {
b34976b6 7650 Elf_External_Verdef evd;
252b5132 7651
a6e9f9df 7652 get_data (&evd, file, offset, sizeof (evd),
c256ffe7 7653 1, _("version def"));
252b5132 7654
b34976b6
AM
7655 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
7656 ivd.vd_aux = BYTE_GET (evd.vd_aux);
252b5132
RH
7657 ivd.vd_next = BYTE_GET (evd.vd_next);
7658
7659 offset += ivd.vd_next;
7660 }
c244d050 7661 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
7662 && ivd.vd_next != 0);
7663
7664 offset -= ivd.vd_next;
7665 offset += ivd.vd_aux;
7666
a6e9f9df 7667 get_data (&evda, file, offset, sizeof (evda),
c256ffe7 7668 1, _("version def aux"));
252b5132
RH
7669
7670 ivda.vda_name = BYTE_GET (evda.vda_name);
7671
7672 if (psym->st_name != ivda.vda_name)
c244d050 7673 printf ((vers_data & VERSYM_HIDDEN)
252b5132 7674 ? "@%s" : "@@%s",
c256ffe7
JJ
7675 ivda.vda_name < strtab_size
7676 ? strtab + ivda.vda_name : "<corrupt>");
252b5132
RH
7677 }
7678 }
7679 }
7680 }
7681
7682 putchar ('\n');
7683 }
7684
7685 free (symtab);
7686 if (strtab != string_table)
7687 free (strtab);
7688 }
7689 }
7690 else if (do_syms)
7691 printf
7692 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
7693
7694 if (do_histogram && buckets != NULL)
7695 {
2cf0635d
NC
7696 unsigned long * lengths;
7697 unsigned long * counts;
66543521
AM
7698 unsigned long hn;
7699 bfd_vma si;
7700 unsigned long maxlength = 0;
7701 unsigned long nzero_counts = 0;
7702 unsigned long nsyms = 0;
252b5132 7703
66543521
AM
7704 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
7705 (unsigned long) nbuckets);
252b5132
RH
7706 printf (_(" Length Number %% of total Coverage\n"));
7707
3f5e193b 7708 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
7709 if (lengths == NULL)
7710 {
591a748a 7711 error (_("Out of memory\n"));
252b5132
RH
7712 return 0;
7713 }
7714 for (hn = 0; hn < nbuckets; ++hn)
7715 {
f7a99963 7716 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 7717 {
b34976b6 7718 ++nsyms;
252b5132 7719 if (maxlength < ++lengths[hn])
b34976b6 7720 ++maxlength;
252b5132
RH
7721 }
7722 }
7723
3f5e193b 7724 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
7725 if (counts == NULL)
7726 {
591a748a 7727 error (_("Out of memory\n"));
252b5132
RH
7728 return 0;
7729 }
7730
7731 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 7732 ++counts[lengths[hn]];
252b5132 7733
103f02d3 7734 if (nbuckets > 0)
252b5132 7735 {
66543521
AM
7736 unsigned long i;
7737 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 7738 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 7739 for (i = 1; i <= maxlength; ++i)
103f02d3 7740 {
66543521
AM
7741 nzero_counts += counts[i] * i;
7742 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7743 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
7744 (nzero_counts * 100.0) / nsyms);
7745 }
252b5132
RH
7746 }
7747
7748 free (counts);
7749 free (lengths);
7750 }
7751
7752 if (buckets != NULL)
7753 {
7754 free (buckets);
7755 free (chains);
7756 }
7757
d3a44ec6 7758 if (do_histogram && gnubuckets != NULL)
fdc90cb4 7759 {
2cf0635d
NC
7760 unsigned long * lengths;
7761 unsigned long * counts;
fdc90cb4
JJ
7762 unsigned long hn;
7763 unsigned long maxlength = 0;
7764 unsigned long nzero_counts = 0;
7765 unsigned long nsyms = 0;
fdc90cb4 7766
3f5e193b 7767 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
7768 if (lengths == NULL)
7769 {
591a748a 7770 error (_("Out of memory\n"));
fdc90cb4
JJ
7771 return 0;
7772 }
7773
7774 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
7775 (unsigned long) ngnubuckets);
7776 printf (_(" Length Number %% of total Coverage\n"));
7777
7778 for (hn = 0; hn < ngnubuckets; ++hn)
7779 if (gnubuckets[hn] != 0)
7780 {
7781 bfd_vma off, length = 1;
7782
6bd1a22c 7783 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
7784 (gnuchains[off] & 1) == 0; ++off)
7785 ++length;
7786 lengths[hn] = length;
7787 if (length > maxlength)
7788 maxlength = length;
7789 nsyms += length;
7790 }
7791
3f5e193b 7792 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
7793 if (counts == NULL)
7794 {
591a748a 7795 error (_("Out of memory\n"));
fdc90cb4
JJ
7796 return 0;
7797 }
7798
7799 for (hn = 0; hn < ngnubuckets; ++hn)
7800 ++counts[lengths[hn]];
7801
7802 if (ngnubuckets > 0)
7803 {
7804 unsigned long j;
7805 printf (" 0 %-10lu (%5.1f%%)\n",
7806 counts[0], (counts[0] * 100.0) / ngnubuckets);
7807 for (j = 1; j <= maxlength; ++j)
7808 {
7809 nzero_counts += counts[j] * j;
7810 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
7811 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
7812 (nzero_counts * 100.0) / nsyms);
7813 }
7814 }
7815
7816 free (counts);
7817 free (lengths);
7818 free (gnubuckets);
7819 free (gnuchains);
7820 }
7821
252b5132
RH
7822 return 1;
7823}
7824
7825static int
2cf0635d 7826process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 7827{
b4c96d0d 7828 unsigned int i;
252b5132
RH
7829
7830 if (dynamic_syminfo == NULL
7831 || !do_dynamic)
7832 /* No syminfo, this is ok. */
7833 return 1;
7834
7835 /* There better should be a dynamic symbol section. */
7836 if (dynamic_symbols == NULL || dynamic_strings == NULL)
7837 return 0;
7838
7839 if (dynamic_addr)
7840 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
7841 dynamic_syminfo_offset, dynamic_syminfo_nent);
7842
7843 printf (_(" Num: Name BoundTo Flags\n"));
7844 for (i = 0; i < dynamic_syminfo_nent; ++i)
7845 {
7846 unsigned short int flags = dynamic_syminfo[i].si_flags;
7847
31104126 7848 printf ("%4d: ", i);
d79b3d50
NC
7849 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
7850 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
7851 else
7852 printf ("<corrupt: %19ld>", dynamic_symbols[i].st_name);
31104126 7853 putchar (' ');
252b5132
RH
7854
7855 switch (dynamic_syminfo[i].si_boundto)
7856 {
7857 case SYMINFO_BT_SELF:
7858 fputs ("SELF ", stdout);
7859 break;
7860 case SYMINFO_BT_PARENT:
7861 fputs ("PARENT ", stdout);
7862 break;
7863 default:
7864 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
7865 && dynamic_syminfo[i].si_boundto < dynamic_nent
7866 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 7867 {
d79b3d50 7868 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
7869 putchar (' ' );
7870 }
252b5132
RH
7871 else
7872 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
7873 break;
7874 }
7875
7876 if (flags & SYMINFO_FLG_DIRECT)
7877 printf (" DIRECT");
7878 if (flags & SYMINFO_FLG_PASSTHRU)
7879 printf (" PASSTHRU");
7880 if (flags & SYMINFO_FLG_COPY)
7881 printf (" COPY");
7882 if (flags & SYMINFO_FLG_LAZYLOAD)
7883 printf (" LAZYLOAD");
7884
7885 puts ("");
7886 }
7887
7888 return 1;
7889}
7890
cf13d699
NC
7891/* Check to see if the given reloc needs to be handled in a target specific
7892 manner. If so then process the reloc and return TRUE otherwise return
7893 FALSE. */
09c11c86 7894
cf13d699
NC
7895static bfd_boolean
7896target_specific_reloc_handling (Elf_Internal_Rela * reloc,
7897 unsigned char * start,
7898 Elf_Internal_Sym * symtab)
252b5132 7899{
cf13d699 7900 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 7901
cf13d699 7902 switch (elf_header.e_machine)
252b5132 7903 {
cf13d699
NC
7904 case EM_MN10300:
7905 case EM_CYGNUS_MN10300:
7906 {
7907 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 7908
cf13d699
NC
7909 switch (reloc_type)
7910 {
7911 case 34: /* R_MN10300_ALIGN */
7912 return TRUE;
7913 case 33: /* R_MN10300_SYM_DIFF */
7914 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
7915 return TRUE;
7916 case 1: /* R_MN10300_32 */
7917 case 2: /* R_MN10300_16 */
7918 if (saved_sym != NULL)
7919 {
7920 bfd_vma value;
252b5132 7921
cf13d699
NC
7922 value = reloc->r_addend
7923 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
7924 - saved_sym->st_value);
252b5132 7925
cf13d699 7926 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 7927
cf13d699
NC
7928 saved_sym = NULL;
7929 return TRUE;
7930 }
7931 break;
7932 default:
7933 if (saved_sym != NULL)
7934 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
7935 break;
7936 }
7937 break;
7938 }
252b5132
RH
7939 }
7940
cf13d699 7941 return FALSE;
252b5132
RH
7942}
7943
aca88567
NC
7944/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
7945 DWARF debug sections. This is a target specific test. Note - we do not
7946 go through the whole including-target-headers-multiple-times route, (as
7947 we have already done with <elf/h8.h>) because this would become very
7948 messy and even then this function would have to contain target specific
7949 information (the names of the relocs instead of their numeric values).
7950 FIXME: This is not the correct way to solve this problem. The proper way
7951 is to have target specific reloc sizing and typing functions created by
7952 the reloc-macros.h header, in the same way that it already creates the
7953 reloc naming functions. */
7954
7955static bfd_boolean
7956is_32bit_abs_reloc (unsigned int reloc_type)
7957{
7958 switch (elf_header.e_machine)
7959 {
41e92641
NC
7960 case EM_386:
7961 case EM_486:
7962 return reloc_type == 1; /* R_386_32. */
aca88567
NC
7963 case EM_68K:
7964 return reloc_type == 1; /* R_68K_32. */
7965 case EM_860:
7966 return reloc_type == 1; /* R_860_32. */
7967 case EM_ALPHA:
7968 return reloc_type == 1; /* XXX Is this right ? */
41e92641
NC
7969 case EM_ARC:
7970 return reloc_type == 1; /* R_ARC_32. */
7971 case EM_ARM:
7972 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 7973 case EM_AVR_OLD:
aca88567
NC
7974 case EM_AVR:
7975 return reloc_type == 1;
7976 case EM_BLACKFIN:
7977 return reloc_type == 0x12; /* R_byte4_data. */
7978 case EM_CRIS:
7979 return reloc_type == 3; /* R_CRIS_32. */
7980 case EM_CR16:
6c03b1ed 7981 case EM_CR16_OLD:
aca88567
NC
7982 return reloc_type == 3; /* R_CR16_NUM32. */
7983 case EM_CRX:
7984 return reloc_type == 15; /* R_CRX_NUM32. */
7985 case EM_CYGNUS_FRV:
7986 return reloc_type == 1;
41e92641
NC
7987 case EM_CYGNUS_D10V:
7988 case EM_D10V:
7989 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
7990 case EM_CYGNUS_D30V:
7991 case EM_D30V:
7992 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
7993 case EM_DLX:
7994 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
7995 case EM_CYGNUS_FR30:
7996 case EM_FR30:
7997 return reloc_type == 3; /* R_FR30_32. */
7998 case EM_H8S:
7999 case EM_H8_300:
8000 case EM_H8_300H:
8001 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
8002 case EM_IA_64:
8003 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
8004 case EM_IP2K_OLD:
8005 case EM_IP2K:
8006 return reloc_type == 2; /* R_IP2K_32. */
8007 case EM_IQ2000:
8008 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
8009 case EM_LATTICEMICO32:
8010 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 8011 case EM_M32C_OLD:
aca88567
NC
8012 case EM_M32C:
8013 return reloc_type == 3; /* R_M32C_32. */
8014 case EM_M32R:
8015 return reloc_type == 34; /* R_M32R_32_RELA. */
8016 case EM_MCORE:
8017 return reloc_type == 1; /* R_MCORE_ADDR32. */
8018 case EM_CYGNUS_MEP:
8019 return reloc_type == 4; /* R_MEP_32. */
8020 case EM_MIPS:
8021 return reloc_type == 2; /* R_MIPS_32. */
8022 case EM_MMIX:
8023 return reloc_type == 4; /* R_MMIX_32. */
8024 case EM_CYGNUS_MN10200:
8025 case EM_MN10200:
8026 return reloc_type == 1; /* R_MN10200_32. */
8027 case EM_CYGNUS_MN10300:
8028 case EM_MN10300:
8029 return reloc_type == 1; /* R_MN10300_32. */
8030 case EM_MSP430_OLD:
8031 case EM_MSP430:
8032 return reloc_type == 1; /* R_MSP43_32. */
8033 case EM_MT:
8034 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
8035 case EM_ALTERA_NIOS2:
8036 case EM_NIOS32:
8037 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
8038 case EM_OPENRISC:
8039 case EM_OR32:
8040 return reloc_type == 1; /* R_OR32_32. */
aca88567 8041 case EM_PARISC:
5fda8eca
NC
8042 return (reloc_type == 1 /* R_PARISC_DIR32. */
8043 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
8044 case EM_PJ:
8045 case EM_PJ_OLD:
8046 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
8047 case EM_PPC64:
8048 return reloc_type == 1; /* R_PPC64_ADDR32. */
8049 case EM_PPC:
8050 return reloc_type == 1; /* R_PPC_ADDR32. */
8051 case EM_S370:
8052 return reloc_type == 1; /* R_I370_ADDR31. */
8053 case EM_S390_OLD:
8054 case EM_S390:
8055 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
8056 case EM_SCORE:
8057 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
8058 case EM_SH:
8059 return reloc_type == 1; /* R_SH_DIR32. */
8060 case EM_SPARC32PLUS:
8061 case EM_SPARCV9:
8062 case EM_SPARC:
8063 return reloc_type == 3 /* R_SPARC_32. */
8064 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
8065 case EM_SPU:
8066 return reloc_type == 6; /* R_SPU_ADDR32 */
aca88567
NC
8067 case EM_CYGNUS_V850:
8068 case EM_V850:
8069 return reloc_type == 6; /* R_V850_ABS32. */
8070 case EM_VAX:
8071 return reloc_type == 1; /* R_VAX_32. */
8072 case EM_X86_64:
8a9036a4 8073 case EM_L1OM:
aca88567
NC
8074 return reloc_type == 10; /* R_X86_64_32. */
8075 case EM_XSTORMY16:
8076 return reloc_type == 1; /* R_XSTROMY16_32. */
8077 case EM_XTENSA_OLD:
8078 case EM_XTENSA:
8079 return reloc_type == 1; /* R_XTENSA_32. */
4b78141a 8080
aca88567
NC
8081 default:
8082 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
8083 elf_header.e_machine);
8084 abort ();
8085 }
8086}
8087
8088/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8089 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
8090
8091static bfd_boolean
8092is_32bit_pcrel_reloc (unsigned int reloc_type)
8093{
8094 switch (elf_header.e_machine)
8095 {
41e92641
NC
8096 case EM_386:
8097 case EM_486:
3e0873ac 8098 return reloc_type == 2; /* R_386_PC32. */
aca88567 8099 case EM_68K:
3e0873ac 8100 return reloc_type == 4; /* R_68K_PC32. */
aca88567
NC
8101 case EM_ALPHA:
8102 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 8103 case EM_ARM:
3e0873ac 8104 return reloc_type == 3; /* R_ARM_REL32 */
aca88567 8105 case EM_PARISC:
85acf597 8106 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
8107 case EM_PPC:
8108 return reloc_type == 26; /* R_PPC_REL32. */
8109 case EM_PPC64:
3e0873ac 8110 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
8111 case EM_S390_OLD:
8112 case EM_S390:
3e0873ac 8113 return reloc_type == 5; /* R_390_PC32. */
aca88567 8114 case EM_SH:
3e0873ac 8115 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
8116 case EM_SPARC32PLUS:
8117 case EM_SPARCV9:
8118 case EM_SPARC:
3e0873ac 8119 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
8120 case EM_SPU:
8121 return reloc_type == 13; /* R_SPU_REL32. */
aca88567 8122 case EM_X86_64:
8a9036a4 8123 case EM_L1OM:
3e0873ac 8124 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
8125 case EM_XTENSA_OLD:
8126 case EM_XTENSA:
8127 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
8128 default:
8129 /* Do not abort or issue an error message here. Not all targets use
8130 pc-relative 32-bit relocs in their DWARF debug information and we
8131 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
8132 more helpful warning message will be generated by apply_relocations
8133 anyway, so just return. */
aca88567
NC
8134 return FALSE;
8135 }
8136}
8137
8138/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8139 a 64-bit absolute RELA relocation used in DWARF debug sections. */
8140
8141static bfd_boolean
8142is_64bit_abs_reloc (unsigned int reloc_type)
8143{
8144 switch (elf_header.e_machine)
8145 {
8146 case EM_ALPHA:
8147 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
8148 case EM_IA_64:
8149 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
8150 case EM_PARISC:
8151 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
8152 case EM_PPC64:
8153 return reloc_type == 38; /* R_PPC64_ADDR64. */
8154 case EM_SPARC32PLUS:
8155 case EM_SPARCV9:
8156 case EM_SPARC:
8157 return reloc_type == 54; /* R_SPARC_UA64. */
8158 case EM_X86_64:
8a9036a4 8159 case EM_L1OM:
aca88567 8160 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
8161 case EM_S390_OLD:
8162 case EM_S390:
8163 return reloc_type == 22; /* R_S390_64 */
85a82265
AM
8164 case EM_MIPS:
8165 return reloc_type == 18; /* R_MIPS_64 */
aca88567
NC
8166 default:
8167 return FALSE;
8168 }
8169}
8170
85acf597
RH
8171/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
8172 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
8173
8174static bfd_boolean
8175is_64bit_pcrel_reloc (unsigned int reloc_type)
8176{
8177 switch (elf_header.e_machine)
8178 {
8179 case EM_ALPHA:
8180 return reloc_type == 11; /* R_ALPHA_SREL64 */
8181 case EM_IA_64:
8182 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB */
8183 case EM_PARISC:
8184 return reloc_type == 72; /* R_PARISC_PCREL64 */
8185 case EM_PPC64:
8186 return reloc_type == 44; /* R_PPC64_REL64 */
8187 case EM_SPARC32PLUS:
8188 case EM_SPARCV9:
8189 case EM_SPARC:
8190 return reloc_type == 46; /* R_SPARC_DISP64 */
8191 case EM_X86_64:
8a9036a4 8192 case EM_L1OM:
85acf597
RH
8193 return reloc_type == 24; /* R_X86_64_PC64 */
8194 case EM_S390_OLD:
8195 case EM_S390:
8196 return reloc_type == 23; /* R_S390_PC64 */
8197 default:
8198 return FALSE;
8199 }
8200}
8201
4dc3c23d
AM
8202/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8203 a 24-bit absolute RELA relocation used in DWARF debug sections. */
8204
8205static bfd_boolean
8206is_24bit_abs_reloc (unsigned int reloc_type)
8207{
8208 switch (elf_header.e_machine)
8209 {
8210 case EM_CYGNUS_MN10200:
8211 case EM_MN10200:
8212 return reloc_type == 4; /* R_MN10200_24. */
8213 default:
8214 return FALSE;
8215 }
8216}
8217
aca88567
NC
8218/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
8219 a 16-bit absolute RELA relocation used in DWARF debug sections. */
8220
8221static bfd_boolean
8222is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
8223{
8224 switch (elf_header.e_machine)
8225 {
aca88567
NC
8226 case EM_AVR_OLD:
8227 case EM_AVR:
8228 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
8229 case EM_CYGNUS_D10V:
8230 case EM_D10V:
8231 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
8232 case EM_H8S:
8233 case EM_H8_300:
8234 case EM_H8_300H:
aca88567
NC
8235 return reloc_type == R_H8_DIR16;
8236 case EM_IP2K_OLD:
8237 case EM_IP2K:
8238 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 8239 case EM_M32C_OLD:
f4236fe4
DD
8240 case EM_M32C:
8241 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
8242 case EM_MSP430_OLD:
8243 case EM_MSP430:
8244 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
8245 case EM_ALTERA_NIOS2:
8246 case EM_NIOS32:
8247 return reloc_type == 9; /* R_NIOS_16. */
4b78141a 8248 default:
aca88567 8249 return FALSE;
4b78141a
NC
8250 }
8251}
8252
2a7b2e88
JK
8253/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
8254 relocation entries (possibly formerly used for SHT_GROUP sections). */
8255
8256static bfd_boolean
8257is_none_reloc (unsigned int reloc_type)
8258{
8259 switch (elf_header.e_machine)
8260 {
cb8f3167
NC
8261 case EM_68K: /* R_68K_NONE. */
8262 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
8263 case EM_SPARC32PLUS:
8264 case EM_SPARCV9:
cb8f3167
NC
8265 case EM_SPARC: /* R_SPARC_NONE. */
8266 case EM_MIPS: /* R_MIPS_NONE. */
8267 case EM_PARISC: /* R_PARISC_NONE. */
8268 case EM_ALPHA: /* R_ALPHA_NONE. */
8269 case EM_PPC: /* R_PPC_NONE. */
8270 case EM_PPC64: /* R_PPC64_NONE. */
8271 case EM_ARM: /* R_ARM_NONE. */
8272 case EM_IA_64: /* R_IA64_NONE. */
8273 case EM_SH: /* R_SH_NONE. */
2a7b2e88 8274 case EM_S390_OLD:
cb8f3167
NC
8275 case EM_S390: /* R_390_NONE. */
8276 case EM_CRIS: /* R_CRIS_NONE. */
8277 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 8278 case EM_L1OM: /* R_X86_64_NONE. */
cb8f3167
NC
8279 case EM_MN10300: /* R_MN10300_NONE. */
8280 case EM_M32R: /* R_M32R_NONE. */
8281 return reloc_type == 0;
58332dda
JK
8282 case EM_XTENSA_OLD:
8283 case EM_XTENSA:
4dc3c23d
AM
8284 return (reloc_type == 0 /* R_XTENSA_NONE. */
8285 || reloc_type == 17 /* R_XTENSA_DIFF8. */
8286 || reloc_type == 18 /* R_XTENSA_DIFF16. */
8287 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
8288 }
8289 return FALSE;
8290}
8291
cf13d699
NC
8292/* Apply relocations to a section.
8293 Note: So far support has been added only for those relocations
8294 which can be found in debug sections.
8295 FIXME: Add support for more relocations ? */
1b315056 8296
cf13d699
NC
8297static void
8298apply_relocations (void * file,
8299 Elf_Internal_Shdr * section,
8300 unsigned char * start)
1b315056 8301{
cf13d699
NC
8302 Elf_Internal_Shdr * relsec;
8303 unsigned char * end = start + section->sh_size;
cb8f3167 8304
cf13d699
NC
8305 if (elf_header.e_type != ET_REL)
8306 return;
1b315056 8307
cf13d699 8308 /* Find the reloc section associated with the section. */
5b18a4bc
NC
8309 for (relsec = section_headers;
8310 relsec < section_headers + elf_header.e_shnum;
8311 ++relsec)
252b5132 8312 {
41e92641
NC
8313 bfd_boolean is_rela;
8314 unsigned long num_relocs;
2cf0635d
NC
8315 Elf_Internal_Rela * relocs;
8316 Elf_Internal_Rela * rp;
8317 Elf_Internal_Shdr * symsec;
8318 Elf_Internal_Sym * symtab;
8319 Elf_Internal_Sym * sym;
252b5132 8320
41e92641 8321 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
8322 || relsec->sh_info >= elf_header.e_shnum
8323 || section_headers + relsec->sh_info != section
c256ffe7 8324 || relsec->sh_size == 0
4fbb74a6 8325 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 8326 continue;
428409d5 8327
41e92641
NC
8328 is_rela = relsec->sh_type == SHT_RELA;
8329
8330 if (is_rela)
8331 {
3f5e193b
NC
8332 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
8333 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
8334 return;
8335 }
8336 else
8337 {
3f5e193b
NC
8338 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
8339 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
8340 return;
8341 }
8342
8343 /* SH uses RELA but uses in place value instead of the addend field. */
8344 if (elf_header.e_machine == EM_SH)
8345 is_rela = FALSE;
428409d5 8346
4fbb74a6 8347 symsec = section_headers + relsec->sh_link;
3f5e193b 8348 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
103f02d3 8349
41e92641 8350 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 8351 {
41e92641
NC
8352 bfd_vma addend;
8353 unsigned int reloc_type;
8354 unsigned int reloc_size;
8355 unsigned char * loc;
4b78141a 8356
aca88567 8357 reloc_type = get_reloc_type (rp->r_info);
41e92641 8358
98fb390a 8359 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 8360 continue;
98fb390a
NC
8361 else if (is_none_reloc (reloc_type))
8362 continue;
8363 else if (is_32bit_abs_reloc (reloc_type)
8364 || is_32bit_pcrel_reloc (reloc_type))
aca88567 8365 reloc_size = 4;
85acf597
RH
8366 else if (is_64bit_abs_reloc (reloc_type)
8367 || is_64bit_pcrel_reloc (reloc_type))
aca88567 8368 reloc_size = 8;
4dc3c23d
AM
8369 else if (is_24bit_abs_reloc (reloc_type))
8370 reloc_size = 3;
aca88567
NC
8371 else if (is_16bit_abs_reloc (reloc_type))
8372 reloc_size = 2;
8373 else
4b78141a 8374 {
41e92641 8375 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 8376 reloc_type, SECTION_NAME (section));
4b78141a
NC
8377 continue;
8378 }
103f02d3 8379
700dd8b7
L
8380 loc = start + rp->r_offset;
8381 if ((loc + reloc_size) > end)
8382 {
8383 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
8384 (unsigned long) rp->r_offset,
8385 SECTION_NAME (section));
8386 continue;
8387 }
103f02d3 8388
41e92641
NC
8389 sym = symtab + get_reloc_symindex (rp->r_info);
8390
8391 /* If the reloc has a symbol associated with it,
55f25fc3
L
8392 make sure that it is of an appropriate type.
8393
8394 Relocations against symbols without type can happen.
8395 Gcc -feliminate-dwarf2-dups may generate symbols
8396 without type for debug info.
8397
8398 Icc generates relocations against function symbols
8399 instead of local labels.
8400
8401 Relocations against object symbols can happen, eg when
8402 referencing a global array. For an example of this see
8403 the _clz.o binary in libgcc.a. */
aca88567 8404 if (sym != symtab
55f25fc3 8405 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 8406 {
41e92641 8407 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 8408 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 8409 (long int)(rp - relocs),
41e92641 8410 SECTION_NAME (relsec));
aca88567 8411 continue;
5b18a4bc 8412 }
252b5132 8413
4dc3c23d
AM
8414 addend = 0;
8415 if (is_rela)
8416 addend += rp->r_addend;
8417 /* R_XTENSA_32 and R_PJ_DATA_DIR32 are partial_inplace. */
8418 if (!is_rela
8419 || (elf_header.e_machine == EM_XTENSA
8420 && reloc_type == 1)
8421 || ((elf_header.e_machine == EM_PJ
8422 || elf_header.e_machine == EM_PJ_OLD)
8423 && reloc_type == 1))
8424 addend += byte_get (loc, reloc_size);
cb8f3167 8425
85acf597
RH
8426 if (is_32bit_pcrel_reloc (reloc_type)
8427 || is_64bit_pcrel_reloc (reloc_type))
8428 {
8429 /* On HPPA, all pc-relative relocations are biased by 8. */
8430 if (elf_header.e_machine == EM_PARISC)
8431 addend -= 8;
8432 byte_put (loc, (addend + sym->st_value) - rp->r_offset,
8433 reloc_size);
8434 }
41e92641
NC
8435 else
8436 byte_put (loc, addend + sym->st_value, reloc_size);
5b18a4bc 8437 }
252b5132 8438
5b18a4bc 8439 free (symtab);
41e92641 8440 free (relocs);
5b18a4bc
NC
8441 break;
8442 }
5b18a4bc 8443}
103f02d3 8444
cf13d699
NC
8445#ifdef SUPPORT_DISASSEMBLY
8446static int
8447disassemble_section (Elf_Internal_Shdr * section, FILE * file)
8448{
8449 printf (_("\nAssembly dump of section %s\n"),
8450 SECTION_NAME (section));
8451
8452 /* XXX -- to be done --- XXX */
8453
8454 return 1;
8455}
8456#endif
8457
8458/* Reads in the contents of SECTION from FILE, returning a pointer
8459 to a malloc'ed buffer or NULL if something went wrong. */
8460
8461static char *
8462get_section_contents (Elf_Internal_Shdr * section, FILE * file)
8463{
8464 bfd_size_type num_bytes;
8465
8466 num_bytes = section->sh_size;
8467
8468 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
8469 {
8470 printf (_("\nSection '%s' has no data to dump.\n"),
8471 SECTION_NAME (section));
8472 return NULL;
8473 }
8474
3f5e193b
NC
8475 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
8476 _("section contents"));
cf13d699
NC
8477}
8478
8479
8480static void
8481dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
8482{
8483 Elf_Internal_Shdr * relsec;
8484 bfd_size_type num_bytes;
8485 bfd_vma addr;
8486 char * data;
8487 char * end;
8488 char * start;
8489 char * name = SECTION_NAME (section);
8490 bfd_boolean some_strings_shown;
8491
8492 start = get_section_contents (section, file);
8493 if (start == NULL)
8494 return;
8495
8496 printf (_("\nString dump of section '%s':\n"), name);
8497
8498 /* If the section being dumped has relocations against it the user might
8499 be expecting these relocations to have been applied. Check for this
8500 case and issue a warning message in order to avoid confusion.
8501 FIXME: Maybe we ought to have an option that dumps a section with
8502 relocs applied ? */
8503 for (relsec = section_headers;
8504 relsec < section_headers + elf_header.e_shnum;
8505 ++relsec)
8506 {
8507 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
8508 || relsec->sh_info >= elf_header.e_shnum
8509 || section_headers + relsec->sh_info != section
8510 || relsec->sh_size == 0
8511 || relsec->sh_link >= elf_header.e_shnum)
8512 continue;
8513
8514 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
8515 break;
8516 }
8517
8518 num_bytes = section->sh_size;
8519 addr = section->sh_addr;
8520 data = start;
8521 end = start + num_bytes;
8522 some_strings_shown = FALSE;
8523
8524 while (data < end)
8525 {
8526 while (!ISPRINT (* data))
8527 if (++ data >= end)
8528 break;
8529
8530 if (data < end)
8531 {
8532#ifndef __MSVCRT__
8533 printf (" [%6tx] %s\n", data - start, data);
8534#else
8535 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
8536#endif
8537 data += strlen (data);
8538 some_strings_shown = TRUE;
8539 }
8540 }
8541
8542 if (! some_strings_shown)
8543 printf (_(" No strings found in this section."));
8544
8545 free (start);
8546
8547 putchar ('\n');
8548}
8549
8550static void
8551dump_section_as_bytes (Elf_Internal_Shdr * section,
8552 FILE * file,
8553 bfd_boolean relocate)
8554{
8555 Elf_Internal_Shdr * relsec;
8556 bfd_size_type bytes;
8557 bfd_vma addr;
8558 unsigned char * data;
8559 unsigned char * start;
8560
8561 start = (unsigned char *) get_section_contents (section, file);
8562 if (start == NULL)
8563 return;
8564
8565 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
8566
8567 if (relocate)
8568 {
8569 apply_relocations (file, section, start);
8570 }
8571 else
8572 {
8573 /* If the section being dumped has relocations against it the user might
8574 be expecting these relocations to have been applied. Check for this
8575 case and issue a warning message in order to avoid confusion.
8576 FIXME: Maybe we ought to have an option that dumps a section with
8577 relocs applied ? */
8578 for (relsec = section_headers;
8579 relsec < section_headers + elf_header.e_shnum;
8580 ++relsec)
8581 {
8582 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
8583 || relsec->sh_info >= elf_header.e_shnum
8584 || section_headers + relsec->sh_info != section
8585 || relsec->sh_size == 0
8586 || relsec->sh_link >= elf_header.e_shnum)
8587 continue;
8588
8589 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
8590 break;
8591 }
8592 }
8593
8594 addr = section->sh_addr;
8595 bytes = section->sh_size;
8596 data = start;
8597
8598 while (bytes)
8599 {
8600 int j;
8601 int k;
8602 int lbytes;
8603
8604 lbytes = (bytes > 16 ? 16 : bytes);
8605
8606 printf (" 0x%8.8lx ", (unsigned long) addr);
8607
8608 for (j = 0; j < 16; j++)
8609 {
8610 if (j < lbytes)
8611 printf ("%2.2x", data[j]);
8612 else
8613 printf (" ");
8614
8615 if ((j & 3) == 3)
8616 printf (" ");
8617 }
8618
8619 for (j = 0; j < lbytes; j++)
8620 {
8621 k = data[j];
8622 if (k >= ' ' && k < 0x7f)
8623 printf ("%c", k);
8624 else
8625 printf (".");
8626 }
8627
8628 putchar ('\n');
8629
8630 data += lbytes;
8631 addr += lbytes;
8632 bytes -= lbytes;
8633 }
8634
8635 free (start);
8636
8637 putchar ('\n');
8638}
8639
8640/* Uncompresses a section that was compressed using zlib, in place.
8641 This is a copy of bfd_uncompress_section_contents, in bfd/compress.c */
8642
8643static int
8644uncompress_section_contents (unsigned char ** buffer, dwarf_size_type * size)
8645{
8646#ifndef HAVE_ZLIB_H
8647 /* These are just to quiet gcc. */
8648 buffer = 0;
8649 size = 0;
8650 return FALSE;
8651#else
8652 dwarf_size_type compressed_size = *size;
8653 unsigned char * compressed_buffer = *buffer;
8654 dwarf_size_type uncompressed_size;
8655 unsigned char * uncompressed_buffer;
8656 z_stream strm;
8657 int rc;
8658 dwarf_size_type header_size = 12;
8659
8660 /* Read the zlib header. In this case, it should be "ZLIB" followed
8661 by the uncompressed section size, 8 bytes in big-endian order. */
8662 if (compressed_size < header_size
8663 || ! streq ((char *) compressed_buffer, "ZLIB"))
8664 return 0;
8665
8666 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
8667 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
8668 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
8669 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
8670 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
8671 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
8672 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
8673 uncompressed_size += compressed_buffer[11];
8674
8675 /* It is possible the section consists of several compressed
8676 buffers concatenated together, so we uncompress in a loop. */
8677 strm.zalloc = NULL;
8678 strm.zfree = NULL;
8679 strm.opaque = NULL;
8680 strm.avail_in = compressed_size - header_size;
8681 strm.next_in = (Bytef *) compressed_buffer + header_size;
8682 strm.avail_out = uncompressed_size;
3f5e193b 8683 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
8684
8685 rc = inflateInit (& strm);
8686 while (strm.avail_in > 0)
8687 {
8688 if (rc != Z_OK)
8689 goto fail;
8690 strm.next_out = ((Bytef *) uncompressed_buffer
8691 + (uncompressed_size - strm.avail_out));
8692 rc = inflate (&strm, Z_FINISH);
8693 if (rc != Z_STREAM_END)
8694 goto fail;
8695 rc = inflateReset (& strm);
8696 }
8697 rc = inflateEnd (& strm);
8698 if (rc != Z_OK
8699 || strm.avail_out != 0)
8700 goto fail;
8701
8702 free (compressed_buffer);
8703 *buffer = uncompressed_buffer;
8704 *size = uncompressed_size;
8705 return 1;
8706
8707 fail:
8708 free (uncompressed_buffer);
8709 return 0;
8710#endif /* HAVE_ZLIB_H */
8711}
8712
d966045b
DJ
8713static int
8714load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 8715 Elf_Internal_Shdr * sec, void * file)
1007acb3 8716{
2cf0635d 8717 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 8718 char buf [64];
1b315056 8719 int section_is_compressed;
1007acb3 8720
19e6b90e
L
8721 /* If it is already loaded, do nothing. */
8722 if (section->start != NULL)
8723 return 1;
1007acb3 8724
a71cc8e0 8725 section_is_compressed = section->name == section->compressed_name;
1007acb3 8726
19e6b90e
L
8727 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
8728 section->address = sec->sh_addr;
8729 section->size = sec->sh_size;
3f5e193b
NC
8730 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
8731 sec->sh_offset, 1,
8732 sec->sh_size, buf);
1b315056
CS
8733 if (section->start == NULL)
8734 return 0;
8735
8736 if (section_is_compressed)
8737 if (! uncompress_section_contents (&section->start, &section->size))
8738 return 0;
1007acb3 8739
19e6b90e 8740 if (debug_displays [debug].relocate)
3f5e193b 8741 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 8742
1b315056 8743 return 1;
1007acb3
L
8744}
8745
d966045b 8746int
2cf0635d 8747load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 8748{
2cf0635d
NC
8749 struct dwarf_section * section = &debug_displays [debug].section;
8750 Elf_Internal_Shdr * sec;
d966045b
DJ
8751
8752 /* Locate the debug section. */
8753 sec = find_section (section->uncompressed_name);
8754 if (sec != NULL)
8755 section->name = section->uncompressed_name;
8756 else
8757 {
8758 sec = find_section (section->compressed_name);
8759 if (sec != NULL)
8760 section->name = section->compressed_name;
8761 }
8762 if (sec == NULL)
8763 return 0;
8764
3f5e193b 8765 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
8766}
8767
19e6b90e
L
8768void
8769free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 8770{
2cf0635d 8771 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 8772
19e6b90e
L
8773 if (section->start == NULL)
8774 return;
1007acb3 8775
19e6b90e
L
8776 free ((char *) section->start);
8777 section->start = NULL;
8778 section->address = 0;
8779 section->size = 0;
1007acb3
L
8780}
8781
1007acb3 8782static int
2cf0635d 8783display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 8784{
2cf0635d 8785 char * name = SECTION_NAME (section);
19e6b90e
L
8786 bfd_size_type length;
8787 int result = 1;
3f5e193b 8788 int i;
1007acb3 8789
19e6b90e
L
8790 length = section->sh_size;
8791 if (length == 0)
1007acb3 8792 {
19e6b90e
L
8793 printf (_("\nSection '%s' has no debugging data.\n"), name);
8794 return 0;
1007acb3 8795 }
5dff79d8
NC
8796 if (section->sh_type == SHT_NOBITS)
8797 {
8798 /* There is no point in dumping the contents of a debugging section
8799 which has the NOBITS type - the bits in the file will be random.
8800 This can happen when a file containing a .eh_frame section is
8801 stripped with the --only-keep-debug command line option. */
8802 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
8803 return 0;
8804 }
1007acb3 8805
0112cd26 8806 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 8807 name = ".debug_info";
1007acb3 8808
19e6b90e
L
8809 /* See if we know how to display the contents of this section. */
8810 for (i = 0; i < max; i++)
1b315056
CS
8811 if (streq (debug_displays[i].section.uncompressed_name, name)
8812 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 8813 {
2cf0635d 8814 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
8815 int secondary = (section != find_section (name));
8816
8817 if (secondary)
3f5e193b 8818 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 8819
2b6f5997 8820 if (streq (sec->uncompressed_name, name))
d966045b
DJ
8821 sec->name = sec->uncompressed_name;
8822 else
8823 sec->name = sec->compressed_name;
3f5e193b
NC
8824 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
8825 section, file))
19e6b90e
L
8826 {
8827 result &= debug_displays[i].display (sec, file);
1007acb3 8828
d966045b 8829 if (secondary || (i != info && i != abbrev))
3f5e193b 8830 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 8831 }
1007acb3 8832
19e6b90e
L
8833 break;
8834 }
1007acb3 8835
19e6b90e 8836 if (i == max)
1007acb3 8837 {
19e6b90e
L
8838 printf (_("Unrecognized debug section: %s\n"), name);
8839 result = 0;
1007acb3
L
8840 }
8841
19e6b90e 8842 return result;
5b18a4bc 8843}
103f02d3 8844
aef1f6d0
DJ
8845/* Set DUMP_SECTS for all sections where dumps were requested
8846 based on section name. */
8847
8848static void
8849initialise_dumps_byname (void)
8850{
2cf0635d 8851 struct dump_list_entry * cur;
aef1f6d0
DJ
8852
8853 for (cur = dump_sects_byname; cur; cur = cur->next)
8854 {
8855 unsigned int i;
8856 int any;
8857
8858 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
8859 if (streq (SECTION_NAME (section_headers + i), cur->name))
8860 {
09c11c86 8861 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
8862 any = 1;
8863 }
8864
8865 if (!any)
8866 warn (_("Section '%s' was not dumped because it does not exist!\n"),
8867 cur->name);
8868 }
8869}
8870
5b18a4bc 8871static void
2cf0635d 8872process_section_contents (FILE * file)
5b18a4bc 8873{
2cf0635d 8874 Elf_Internal_Shdr * section;
19e6b90e 8875 unsigned int i;
103f02d3 8876
19e6b90e
L
8877 if (! do_dump)
8878 return;
103f02d3 8879
aef1f6d0
DJ
8880 initialise_dumps_byname ();
8881
19e6b90e
L
8882 for (i = 0, section = section_headers;
8883 i < elf_header.e_shnum && i < num_dump_sects;
8884 i++, section++)
8885 {
8886#ifdef SUPPORT_DISASSEMBLY
8887 if (dump_sects[i] & DISASS_DUMP)
8888 disassemble_section (section, file);
8889#endif
8890 if (dump_sects[i] & HEX_DUMP)
cf13d699 8891 dump_section_as_bytes (section, file, FALSE);
103f02d3 8892
cf13d699
NC
8893 if (dump_sects[i] & RELOC_DUMP)
8894 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
8895
8896 if (dump_sects[i] & STRING_DUMP)
8897 dump_section_as_strings (section, file);
cf13d699
NC
8898
8899 if (dump_sects[i] & DEBUG_DUMP)
8900 display_debug_section (section, file);
5b18a4bc 8901 }
103f02d3 8902
19e6b90e
L
8903 /* Check to see if the user requested a
8904 dump of a section that does not exist. */
8905 while (i++ < num_dump_sects)
8906 if (dump_sects[i])
8907 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 8908}
103f02d3 8909
5b18a4bc 8910static void
19e6b90e 8911process_mips_fpe_exception (int mask)
5b18a4bc 8912{
19e6b90e
L
8913 if (mask)
8914 {
8915 int first = 1;
8916 if (mask & OEX_FPU_INEX)
8917 fputs ("INEX", stdout), first = 0;
8918 if (mask & OEX_FPU_UFLO)
8919 printf ("%sUFLO", first ? "" : "|"), first = 0;
8920 if (mask & OEX_FPU_OFLO)
8921 printf ("%sOFLO", first ? "" : "|"), first = 0;
8922 if (mask & OEX_FPU_DIV0)
8923 printf ("%sDIV0", first ? "" : "|"), first = 0;
8924 if (mask & OEX_FPU_INVAL)
8925 printf ("%sINVAL", first ? "" : "|");
8926 }
5b18a4bc 8927 else
19e6b90e 8928 fputs ("0", stdout);
5b18a4bc 8929}
103f02d3 8930
11c1ff18
PB
8931/* ARM EABI attributes section. */
8932typedef struct
8933{
8934 int tag;
2cf0635d 8935 const char * name;
11c1ff18
PB
8936 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
8937 int type;
2cf0635d 8938 const char ** table;
11c1ff18
PB
8939} arm_attr_public_tag;
8940
2cf0635d 8941static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 8942 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
f5f53991 8943 "v6K", "v7", "v6-M", "v6S-M"};
2cf0635d
NC
8944static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
8945static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 8946 {"No", "Thumb-1", "Thumb-2"};
2cf0635d 8947static const char * arm_attr_tag_VFP_arch[] =
b1cc4aeb 8948 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16"};
2cf0635d
NC
8949static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
8950static const char * arm_attr_tag_Advanced_SIMD_arch[] = {"No", "NEONv1"};
8951static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
8952 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
8953 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 8954static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 8955 {"V6", "SB", "TLS", "Unused"};
2cf0635d 8956static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 8957 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 8958static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 8959 {"Absolute", "PC-relative", "None"};
2cf0635d 8960static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 8961 {"None", "direct", "GOT-indirect"};
2cf0635d 8962static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 8963 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
8964static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
8965static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 8966 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
8967static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
8968static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
8969static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 8970 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d
NC
8971static const char * arm_attr_tag_ABI_align8_needed[] = {"No", "Yes", "4-byte"};
8972static const char * arm_attr_tag_ABI_align8_preserved[] =
11c1ff18 8973 {"No", "Yes, except leaf SP", "Yes"};
2cf0635d 8974static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 8975 {"Unused", "small", "int", "forced to int"};
2cf0635d 8976static const char * arm_attr_tag_ABI_HardFP_use[] =
11c1ff18 8977 {"As Tag_VFP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 8978static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 8979 {"AAPCS", "VFP registers", "custom"};
2cf0635d 8980static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 8981 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 8982static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
8983 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8984 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 8985static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
8986 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
8987 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d
NC
8988static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
8989static const char * arm_attr_tag_VFP_HP_extension[] =
8e79c3df 8990 {"Not Allowed", "Allowed"};
2cf0635d 8991static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 8992 {"None", "IEEE 754", "Alternative Format"};
2cf0635d
NC
8993static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
8994static const char * arm_attr_tag_Virtualization_use[] =
f5f53991 8995 {"Not Allowed", "Allowed"};
2cf0635d 8996static const char * arm_attr_tag_MPextension_use[] = {"Not Allowed", "Allowed"};
11c1ff18
PB
8997
8998#define LOOKUP(id, name) \
8999 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 9000static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
9001{
9002 {4, "CPU_raw_name", 1, NULL},
9003 {5, "CPU_name", 1, NULL},
9004 LOOKUP(6, CPU_arch),
9005 {7, "CPU_arch_profile", 0, NULL},
9006 LOOKUP(8, ARM_ISA_use),
9007 LOOKUP(9, THUMB_ISA_use),
9008 LOOKUP(10, VFP_arch),
9009 LOOKUP(11, WMMX_arch),
f5f53991
AS
9010 LOOKUP(12, Advanced_SIMD_arch),
9011 LOOKUP(13, PCS_config),
11c1ff18
PB
9012 LOOKUP(14, ABI_PCS_R9_use),
9013 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 9014 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
9015 LOOKUP(17, ABI_PCS_GOT_use),
9016 LOOKUP(18, ABI_PCS_wchar_t),
9017 LOOKUP(19, ABI_FP_rounding),
9018 LOOKUP(20, ABI_FP_denormal),
9019 LOOKUP(21, ABI_FP_exceptions),
9020 LOOKUP(22, ABI_FP_user_exceptions),
9021 LOOKUP(23, ABI_FP_number_model),
9022 LOOKUP(24, ABI_align8_needed),
9023 LOOKUP(25, ABI_align8_preserved),
9024 LOOKUP(26, ABI_enum_size),
9025 LOOKUP(27, ABI_HardFP_use),
9026 LOOKUP(28, ABI_VFP_args),
9027 LOOKUP(29, ABI_WMMX_args),
9028 LOOKUP(30, ABI_optimization_goals),
9029 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 9030 {32, "compatibility", 0, NULL},
f5f53991 9031 LOOKUP(34, CPU_unaligned_access),
8e79c3df
CM
9032 LOOKUP(36, VFP_HP_extension),
9033 LOOKUP(38, ABI_FP_16bit_format),
f5f53991
AS
9034 {64, "nodefaults", 0, NULL},
9035 {65, "also_compatible_with", 0, NULL},
9036 LOOKUP(66, T2EE_use),
9037 {67, "conformance", 1, NULL},
9038 LOOKUP(68, Virtualization_use),
9039 LOOKUP(70, MPextension_use)
11c1ff18
PB
9040};
9041#undef LOOKUP
9042
9043/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
9044 bytes read. */
2cf0635d 9045
11c1ff18 9046static unsigned int
2cf0635d 9047read_uleb128 (unsigned char * p, unsigned int * plen)
11c1ff18
PB
9048{
9049 unsigned char c;
9050 unsigned int val;
9051 int shift;
9052 int len;
9053
9054 val = 0;
9055 shift = 0;
9056 len = 0;
9057 do
9058 {
9059 c = *(p++);
9060 len++;
9061 val |= ((unsigned int)c & 0x7f) << shift;
9062 shift += 7;
9063 }
9064 while (c & 0x80);
9065
9066 *plen = len;
9067 return val;
9068}
9069
9070static unsigned char *
2cf0635d 9071display_arm_attribute (unsigned char * p)
11c1ff18
PB
9072{
9073 int tag;
9074 unsigned int len;
9075 int val;
2cf0635d 9076 arm_attr_public_tag * attr;
11c1ff18
PB
9077 unsigned i;
9078 int type;
9079
9080 tag = read_uleb128 (p, &len);
9081 p += len;
9082 attr = NULL;
2cf0635d 9083 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
9084 {
9085 if (arm_attr_public_tags[i].tag == tag)
9086 {
9087 attr = &arm_attr_public_tags[i];
9088 break;
9089 }
9090 }
9091
9092 if (attr)
9093 {
9094 printf (" Tag_%s: ", attr->name);
9095 switch (attr->type)
9096 {
9097 case 0:
9098 switch (tag)
9099 {
9100 case 7: /* Tag_CPU_arch_profile. */
9101 val = read_uleb128 (p, &len);
9102 p += len;
9103 switch (val)
9104 {
9105 case 0: printf ("None\n"); break;
9106 case 'A': printf ("Application\n"); break;
9107 case 'R': printf ("Realtime\n"); break;
9108 case 'M': printf ("Microcontroller\n"); break;
9109 default: printf ("??? (%d)\n", val); break;
9110 }
9111 break;
9112
9113 case 32: /* Tag_compatibility. */
9114 val = read_uleb128 (p, &len);
9115 p += len;
9116 printf ("flag = %d, vendor = %s\n", val, p);
2cf0635d 9117 p += strlen ((char *) p) + 1;
11c1ff18
PB
9118 break;
9119
f5f53991
AS
9120 case 64: /* Tag_nodefaults. */
9121 p++;
9122 printf ("True\n");
9123 break;
9124
9125 case 65: /* Tag_also_compatible_with. */
9126 val = read_uleb128 (p, &len);
9127 p += len;
9128 if (val == 6 /* Tag_CPU_arch. */)
9129 {
9130 val = read_uleb128 (p, &len);
9131 p += len;
2cf0635d 9132 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
9133 printf ("??? (%d)\n", val);
9134 else
9135 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
9136 }
9137 else
9138 printf ("???\n");
9139 while (*(p++) != '\0' /* NUL terminator. */);
9140 break;
9141
11c1ff18 9142 default:
2cf0635d 9143 abort ();
11c1ff18
PB
9144 }
9145 return p;
9146
9147 case 1:
9148 case 2:
9149 type = attr->type;
9150 break;
9151
9152 default:
9153 assert (attr->type & 0x80);
9154 val = read_uleb128 (p, &len);
9155 p += len;
9156 type = attr->type & 0x7f;
9157 if (val >= type)
9158 printf ("??? (%d)\n", val);
9159 else
9160 printf ("%s\n", attr->table[val]);
9161 return p;
9162 }
9163 }
9164 else
9165 {
9166 if (tag & 1)
9167 type = 1; /* String. */
9168 else
9169 type = 2; /* uleb128. */
9170 printf (" Tag_unknown_%d: ", tag);
9171 }
9172
9173 if (type == 1)
9174 {
9175 printf ("\"%s\"\n", p);
2cf0635d 9176 p += strlen ((char *) p) + 1;
11c1ff18
PB
9177 }
9178 else
9179 {
9180 val = read_uleb128 (p, &len);
9181 p += len;
9182 printf ("%d (0x%x)\n", val, val);
9183 }
9184
9185 return p;
9186}
9187
104d59d1 9188static unsigned char *
60bca95a
NC
9189display_gnu_attribute (unsigned char * p,
9190 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
9191{
9192 int tag;
9193 unsigned int len;
9194 int val;
9195 int type;
9196
9197 tag = read_uleb128 (p, &len);
9198 p += len;
9199
9200 /* Tag_compatibility is the only generic GNU attribute defined at
9201 present. */
9202 if (tag == 32)
9203 {
9204 val = read_uleb128 (p, &len);
9205 p += len;
9206 printf ("flag = %d, vendor = %s\n", val, p);
60bca95a 9207 p += strlen ((char *) p) + 1;
104d59d1
JM
9208 return p;
9209 }
9210
9211 if ((tag & 2) == 0 && display_proc_gnu_attribute)
9212 return display_proc_gnu_attribute (p, tag);
9213
9214 if (tag & 1)
9215 type = 1; /* String. */
9216 else
9217 type = 2; /* uleb128. */
9218 printf (" Tag_unknown_%d: ", tag);
9219
9220 if (type == 1)
9221 {
9222 printf ("\"%s\"\n", p);
60bca95a 9223 p += strlen ((char *) p) + 1;
104d59d1
JM
9224 }
9225 else
9226 {
9227 val = read_uleb128 (p, &len);
9228 p += len;
9229 printf ("%d (0x%x)\n", val, val);
9230 }
9231
9232 return p;
9233}
9234
34c8bcba 9235static unsigned char *
2cf0635d 9236display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
9237{
9238 int type;
9239 unsigned int len;
9240 int val;
9241
9242 if (tag == Tag_GNU_Power_ABI_FP)
9243 {
9244 val = read_uleb128 (p, &len);
9245 p += len;
9246 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 9247
34c8bcba
JM
9248 switch (val)
9249 {
9250 case 0:
9251 printf ("Hard or soft float\n");
9252 break;
9253 case 1:
9254 printf ("Hard float\n");
9255 break;
9256 case 2:
9257 printf ("Soft float\n");
9258 break;
3c7b9897
AM
9259 case 3:
9260 printf ("Single-precision hard float\n");
9261 break;
34c8bcba
JM
9262 default:
9263 printf ("??? (%d)\n", val);
9264 break;
9265 }
9266 return p;
9267 }
9268
c6e65352
DJ
9269 if (tag == Tag_GNU_Power_ABI_Vector)
9270 {
9271 val = read_uleb128 (p, &len);
9272 p += len;
9273 printf (" Tag_GNU_Power_ABI_Vector: ");
9274 switch (val)
9275 {
9276 case 0:
9277 printf ("Any\n");
9278 break;
9279 case 1:
9280 printf ("Generic\n");
9281 break;
9282 case 2:
9283 printf ("AltiVec\n");
9284 break;
9285 case 3:
9286 printf ("SPE\n");
9287 break;
9288 default:
9289 printf ("??? (%d)\n", val);
9290 break;
9291 }
9292 return p;
9293 }
9294
f82e0623
NF
9295 if (tag == Tag_GNU_Power_ABI_Struct_Return)
9296 {
9297 val = read_uleb128 (p, &len);
9298 p += len;
9299 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
9300 switch (val)
9301 {
9302 case 0:
9303 printf ("Any\n");
9304 break;
9305 case 1:
9306 printf ("r3/r4\n");
9307 break;
9308 case 2:
9309 printf ("Memory\n");
9310 break;
9311 default:
9312 printf ("??? (%d)\n", val);
9313 break;
9314 }
9315 return p;
9316 }
9317
34c8bcba
JM
9318 if (tag & 1)
9319 type = 1; /* String. */
9320 else
9321 type = 2; /* uleb128. */
9322 printf (" Tag_unknown_%d: ", tag);
9323
9324 if (type == 1)
9325 {
9326 printf ("\"%s\"\n", p);
60bca95a 9327 p += strlen ((char *) p) + 1;
34c8bcba
JM
9328 }
9329 else
9330 {
9331 val = read_uleb128 (p, &len);
9332 p += len;
9333 printf ("%d (0x%x)\n", val, val);
9334 }
9335
9336 return p;
9337}
9338
2cf19d5c 9339static unsigned char *
2cf0635d 9340display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
9341{
9342 int type;
9343 unsigned int len;
9344 int val;
9345
9346 if (tag == Tag_GNU_MIPS_ABI_FP)
9347 {
9348 val = read_uleb128 (p, &len);
9349 p += len;
9350 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 9351
2cf19d5c
JM
9352 switch (val)
9353 {
9354 case 0:
9355 printf ("Hard or soft float\n");
9356 break;
9357 case 1:
9358 printf ("Hard float (-mdouble-float)\n");
9359 break;
9360 case 2:
9361 printf ("Hard float (-msingle-float)\n");
9362 break;
9363 case 3:
9364 printf ("Soft float\n");
9365 break;
42554f6a
TS
9366 case 4:
9367 printf ("64-bit float (-mips32r2 -mfp64)\n");
9368 break;
2cf19d5c
JM
9369 default:
9370 printf ("??? (%d)\n", val);
9371 break;
9372 }
9373 return p;
9374 }
9375
9376 if (tag & 1)
9377 type = 1; /* String. */
9378 else
9379 type = 2; /* uleb128. */
9380 printf (" Tag_unknown_%d: ", tag);
9381
9382 if (type == 1)
9383 {
9384 printf ("\"%s\"\n", p);
60bca95a 9385 p += strlen ((char *) p) + 1;
2cf19d5c
JM
9386 }
9387 else
9388 {
9389 val = read_uleb128 (p, &len);
9390 p += len;
9391 printf ("%d (0x%x)\n", val, val);
9392 }
9393
9394 return p;
9395}
9396
11c1ff18 9397static int
60bca95a
NC
9398process_attributes (FILE * file,
9399 const char * public_name,
104d59d1 9400 unsigned int proc_type,
60bca95a
NC
9401 unsigned char * (* display_pub_attribute) (unsigned char *),
9402 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 9403{
2cf0635d
NC
9404 Elf_Internal_Shdr * sect;
9405 unsigned char * contents;
9406 unsigned char * p;
9407 unsigned char * end;
11c1ff18
PB
9408 bfd_vma section_len;
9409 bfd_vma len;
9410 unsigned i;
9411
9412 /* Find the section header so that we get the size. */
9413 for (i = 0, sect = section_headers;
9414 i < elf_header.e_shnum;
9415 i++, sect++)
9416 {
104d59d1 9417 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
9418 continue;
9419
3f5e193b
NC
9420 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
9421 sect->sh_size, _("attributes"));
60bca95a 9422 if (contents == NULL)
11c1ff18 9423 continue;
60bca95a 9424
11c1ff18
PB
9425 p = contents;
9426 if (*p == 'A')
9427 {
9428 len = sect->sh_size - 1;
9429 p++;
60bca95a 9430
11c1ff18
PB
9431 while (len > 0)
9432 {
9433 int namelen;
9434 bfd_boolean public_section;
104d59d1 9435 bfd_boolean gnu_section;
11c1ff18
PB
9436
9437 section_len = byte_get (p, 4);
9438 p += 4;
60bca95a 9439
11c1ff18
PB
9440 if (section_len > len)
9441 {
9442 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 9443 (int) section_len, (int) len);
11c1ff18
PB
9444 section_len = len;
9445 }
60bca95a 9446
11c1ff18
PB
9447 len -= section_len;
9448 printf ("Attribute Section: %s\n", p);
60bca95a
NC
9449
9450 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
9451 public_section = TRUE;
9452 else
9453 public_section = FALSE;
60bca95a
NC
9454
9455 if (streq ((char *) p, "gnu"))
104d59d1
JM
9456 gnu_section = TRUE;
9457 else
9458 gnu_section = FALSE;
60bca95a
NC
9459
9460 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
9461 p += namelen;
9462 section_len -= namelen + 4;
60bca95a 9463
11c1ff18
PB
9464 while (section_len > 0)
9465 {
9466 int tag = *(p++);
9467 int val;
9468 bfd_vma size;
60bca95a 9469
11c1ff18
PB
9470 size = byte_get (p, 4);
9471 if (size > section_len)
9472 {
9473 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 9474 (int) size, (int) section_len);
11c1ff18
PB
9475 size = section_len;
9476 }
60bca95a 9477
11c1ff18
PB
9478 section_len -= size;
9479 end = p + size - 1;
9480 p += 4;
60bca95a 9481
11c1ff18
PB
9482 switch (tag)
9483 {
9484 case 1:
9485 printf ("File Attributes\n");
9486 break;
9487 case 2:
9488 printf ("Section Attributes:");
9489 goto do_numlist;
9490 case 3:
9491 printf ("Symbol Attributes:");
9492 do_numlist:
9493 for (;;)
9494 {
9495 unsigned int i;
60bca95a 9496
11c1ff18
PB
9497 val = read_uleb128 (p, &i);
9498 p += i;
9499 if (val == 0)
9500 break;
9501 printf (" %d", val);
9502 }
9503 printf ("\n");
9504 break;
9505 default:
9506 printf ("Unknown tag: %d\n", tag);
9507 public_section = FALSE;
9508 break;
9509 }
60bca95a 9510
11c1ff18
PB
9511 if (public_section)
9512 {
9513 while (p < end)
104d59d1
JM
9514 p = display_pub_attribute (p);
9515 }
9516 else if (gnu_section)
9517 {
9518 while (p < end)
9519 p = display_gnu_attribute (p,
9520 display_proc_gnu_attribute);
11c1ff18
PB
9521 }
9522 else
9523 {
9524 /* ??? Do something sensible, like dump hex. */
9525 printf (" Unknown section contexts\n");
9526 p = end;
9527 }
9528 }
9529 }
9530 }
9531 else
60bca95a 9532 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 9533
60bca95a 9534 free (contents);
11c1ff18
PB
9535 }
9536 return 1;
9537}
9538
104d59d1 9539static int
2cf0635d 9540process_arm_specific (FILE * file)
104d59d1
JM
9541{
9542 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
9543 display_arm_attribute, NULL);
9544}
9545
34c8bcba 9546static int
2cf0635d 9547process_power_specific (FILE * file)
34c8bcba
JM
9548{
9549 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
9550 display_power_gnu_attribute);
9551}
9552
ccb4c951
RS
9553/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
9554 Print the Address, Access and Initial fields of an entry at VMA ADDR
9555 and return the VMA of the next entry. */
9556
9557static bfd_vma
2cf0635d 9558print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
9559{
9560 printf (" ");
9561 print_vma (addr, LONG_HEX);
9562 printf (" ");
9563 if (addr < pltgot + 0xfff0)
9564 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
9565 else
9566 printf ("%10s", "");
9567 printf (" ");
9568 if (data == NULL)
9569 printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
9570 else
9571 {
9572 bfd_vma entry;
9573
9574 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
9575 print_vma (entry, LONG_HEX);
9576 }
9577 return addr + (is_32bit_elf ? 4 : 8);
9578}
9579
861fb55a
DJ
9580/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
9581 PLTGOT. Print the Address and Initial fields of an entry at VMA
9582 ADDR and return the VMA of the next entry. */
9583
9584static bfd_vma
2cf0635d 9585print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
9586{
9587 printf (" ");
9588 print_vma (addr, LONG_HEX);
9589 printf (" ");
9590 if (data == NULL)
9591 printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
9592 else
9593 {
9594 bfd_vma entry;
9595
9596 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
9597 print_vma (entry, LONG_HEX);
9598 }
9599 return addr + (is_32bit_elf ? 4 : 8);
9600}
9601
19e6b90e 9602static int
2cf0635d 9603process_mips_specific (FILE * file)
5b18a4bc 9604{
2cf0635d 9605 Elf_Internal_Dyn * entry;
19e6b90e
L
9606 size_t liblist_offset = 0;
9607 size_t liblistno = 0;
9608 size_t conflictsno = 0;
9609 size_t options_offset = 0;
9610 size_t conflicts_offset = 0;
861fb55a
DJ
9611 size_t pltrelsz = 0;
9612 size_t pltrel = 0;
ccb4c951 9613 bfd_vma pltgot = 0;
861fb55a
DJ
9614 bfd_vma mips_pltgot = 0;
9615 bfd_vma jmprel = 0;
ccb4c951
RS
9616 bfd_vma local_gotno = 0;
9617 bfd_vma gotsym = 0;
9618 bfd_vma symtabno = 0;
103f02d3 9619
2cf19d5c
JM
9620 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
9621 display_mips_gnu_attribute);
9622
19e6b90e
L
9623 /* We have a lot of special sections. Thanks SGI! */
9624 if (dynamic_section == NULL)
9625 /* No information available. */
9626 return 0;
252b5132 9627
b2d38a17 9628 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
9629 switch (entry->d_tag)
9630 {
9631 case DT_MIPS_LIBLIST:
d93f0186
NC
9632 liblist_offset
9633 = offset_from_vma (file, entry->d_un.d_val,
9634 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
9635 break;
9636 case DT_MIPS_LIBLISTNO:
9637 liblistno = entry->d_un.d_val;
9638 break;
9639 case DT_MIPS_OPTIONS:
d93f0186 9640 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
9641 break;
9642 case DT_MIPS_CONFLICT:
d93f0186
NC
9643 conflicts_offset
9644 = offset_from_vma (file, entry->d_un.d_val,
9645 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
9646 break;
9647 case DT_MIPS_CONFLICTNO:
9648 conflictsno = entry->d_un.d_val;
9649 break;
ccb4c951 9650 case DT_PLTGOT:
861fb55a
DJ
9651 pltgot = entry->d_un.d_ptr;
9652 break;
ccb4c951
RS
9653 case DT_MIPS_LOCAL_GOTNO:
9654 local_gotno = entry->d_un.d_val;
9655 break;
9656 case DT_MIPS_GOTSYM:
9657 gotsym = entry->d_un.d_val;
9658 break;
9659 case DT_MIPS_SYMTABNO:
9660 symtabno = entry->d_un.d_val;
9661 break;
861fb55a
DJ
9662 case DT_MIPS_PLTGOT:
9663 mips_pltgot = entry->d_un.d_ptr;
9664 break;
9665 case DT_PLTREL:
9666 pltrel = entry->d_un.d_val;
9667 break;
9668 case DT_PLTRELSZ:
9669 pltrelsz = entry->d_un.d_val;
9670 break;
9671 case DT_JMPREL:
9672 jmprel = entry->d_un.d_ptr;
9673 break;
252b5132
RH
9674 default:
9675 break;
9676 }
9677
9678 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
9679 {
2cf0635d 9680 Elf32_External_Lib * elib;
252b5132
RH
9681 size_t cnt;
9682
3f5e193b
NC
9683 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
9684 liblistno,
9685 sizeof (Elf32_External_Lib),
9686 _("liblist"));
a6e9f9df 9687 if (elib)
252b5132 9688 {
a6e9f9df
AM
9689 printf ("\nSection '.liblist' contains %lu entries:\n",
9690 (unsigned long) liblistno);
9691 fputs (" Library Time Stamp Checksum Version Flags\n",
9692 stdout);
9693
9694 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 9695 {
a6e9f9df
AM
9696 Elf32_Lib liblist;
9697 time_t time;
9698 char timebuf[20];
2cf0635d 9699 struct tm * tmp;
a6e9f9df
AM
9700
9701 liblist.l_name = BYTE_GET (elib[cnt].l_name);
9702 time = BYTE_GET (elib[cnt].l_time_stamp);
9703 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
9704 liblist.l_version = BYTE_GET (elib[cnt].l_version);
9705 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
9706
9707 tmp = gmtime (&time);
e9e44622
JJ
9708 snprintf (timebuf, sizeof (timebuf),
9709 "%04u-%02u-%02uT%02u:%02u:%02u",
9710 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9711 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 9712
31104126 9713 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
9714 if (VALID_DYNAMIC_NAME (liblist.l_name))
9715 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
9716 else
9717 printf ("<corrupt: %9ld>", liblist.l_name);
31104126
NC
9718 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
9719 liblist.l_version);
a6e9f9df
AM
9720
9721 if (liblist.l_flags == 0)
9722 puts (" NONE");
9723 else
9724 {
9725 static const struct
252b5132 9726 {
2cf0635d 9727 const char * name;
a6e9f9df 9728 int bit;
252b5132 9729 }
a6e9f9df
AM
9730 l_flags_vals[] =
9731 {
9732 { " EXACT_MATCH", LL_EXACT_MATCH },
9733 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
9734 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
9735 { " EXPORTS", LL_EXPORTS },
9736 { " DELAY_LOAD", LL_DELAY_LOAD },
9737 { " DELTA", LL_DELTA }
9738 };
9739 int flags = liblist.l_flags;
9740 size_t fcnt;
9741
60bca95a 9742 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
9743 if ((flags & l_flags_vals[fcnt].bit) != 0)
9744 {
9745 fputs (l_flags_vals[fcnt].name, stdout);
9746 flags ^= l_flags_vals[fcnt].bit;
9747 }
9748 if (flags != 0)
9749 printf (" %#x", (unsigned int) flags);
252b5132 9750
a6e9f9df
AM
9751 puts ("");
9752 }
252b5132 9753 }
252b5132 9754
a6e9f9df
AM
9755 free (elib);
9756 }
252b5132
RH
9757 }
9758
9759 if (options_offset != 0)
9760 {
2cf0635d
NC
9761 Elf_External_Options * eopt;
9762 Elf_Internal_Shdr * sect = section_headers;
9763 Elf_Internal_Options * iopt;
9764 Elf_Internal_Options * option;
252b5132
RH
9765 size_t offset;
9766 int cnt;
9767
9768 /* Find the section header so that we get the size. */
9769 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 9770 ++sect;
252b5132 9771
3f5e193b
NC
9772 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
9773 sect->sh_size, _("options"));
a6e9f9df 9774 if (eopt)
252b5132 9775 {
3f5e193b
NC
9776 iopt = (Elf_Internal_Options *)
9777 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
9778 if (iopt == NULL)
9779 {
591a748a 9780 error (_("Out of memory\n"));
a6e9f9df
AM
9781 return 0;
9782 }
76da6bbe 9783
a6e9f9df
AM
9784 offset = cnt = 0;
9785 option = iopt;
252b5132 9786
a6e9f9df
AM
9787 while (offset < sect->sh_size)
9788 {
2cf0635d 9789 Elf_External_Options * eoption;
252b5132 9790
a6e9f9df 9791 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 9792
a6e9f9df
AM
9793 option->kind = BYTE_GET (eoption->kind);
9794 option->size = BYTE_GET (eoption->size);
9795 option->section = BYTE_GET (eoption->section);
9796 option->info = BYTE_GET (eoption->info);
76da6bbe 9797
a6e9f9df 9798 offset += option->size;
252b5132 9799
a6e9f9df
AM
9800 ++option;
9801 ++cnt;
9802 }
252b5132 9803
a6e9f9df
AM
9804 printf (_("\nSection '%s' contains %d entries:\n"),
9805 SECTION_NAME (sect), cnt);
76da6bbe 9806
a6e9f9df 9807 option = iopt;
252b5132 9808
a6e9f9df 9809 while (cnt-- > 0)
252b5132 9810 {
a6e9f9df
AM
9811 size_t len;
9812
9813 switch (option->kind)
252b5132 9814 {
a6e9f9df
AM
9815 case ODK_NULL:
9816 /* This shouldn't happen. */
9817 printf (" NULL %d %lx", option->section, option->info);
9818 break;
9819 case ODK_REGINFO:
9820 printf (" REGINFO ");
9821 if (elf_header.e_machine == EM_MIPS)
9822 {
9823 /* 32bit form. */
2cf0635d 9824 Elf32_External_RegInfo * ereg;
b34976b6 9825 Elf32_RegInfo reginfo;
a6e9f9df
AM
9826
9827 ereg = (Elf32_External_RegInfo *) (option + 1);
9828 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
9829 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
9830 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
9831 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
9832 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
9833 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
9834
9835 printf ("GPR %08lx GP 0x%lx\n",
9836 reginfo.ri_gprmask,
9837 (unsigned long) reginfo.ri_gp_value);
9838 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
9839 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
9840 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
9841 }
9842 else
9843 {
9844 /* 64 bit form. */
2cf0635d 9845 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
9846 Elf64_Internal_RegInfo reginfo;
9847
9848 ereg = (Elf64_External_RegInfo *) (option + 1);
9849 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
9850 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
9851 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
9852 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
9853 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 9854 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
9855
9856 printf ("GPR %08lx GP 0x",
9857 reginfo.ri_gprmask);
9858 printf_vma (reginfo.ri_gp_value);
9859 printf ("\n");
9860
9861 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
9862 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
9863 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
9864 }
9865 ++option;
9866 continue;
9867 case ODK_EXCEPTIONS:
9868 fputs (" EXCEPTIONS fpe_min(", stdout);
9869 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
9870 fputs (") fpe_max(", stdout);
9871 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
9872 fputs (")", stdout);
9873
9874 if (option->info & OEX_PAGE0)
9875 fputs (" PAGE0", stdout);
9876 if (option->info & OEX_SMM)
9877 fputs (" SMM", stdout);
9878 if (option->info & OEX_FPDBUG)
9879 fputs (" FPDBUG", stdout);
9880 if (option->info & OEX_DISMISS)
9881 fputs (" DISMISS", stdout);
9882 break;
9883 case ODK_PAD:
9884 fputs (" PAD ", stdout);
9885 if (option->info & OPAD_PREFIX)
9886 fputs (" PREFIX", stdout);
9887 if (option->info & OPAD_POSTFIX)
9888 fputs (" POSTFIX", stdout);
9889 if (option->info & OPAD_SYMBOL)
9890 fputs (" SYMBOL", stdout);
9891 break;
9892 case ODK_HWPATCH:
9893 fputs (" HWPATCH ", stdout);
9894 if (option->info & OHW_R4KEOP)
9895 fputs (" R4KEOP", stdout);
9896 if (option->info & OHW_R8KPFETCH)
9897 fputs (" R8KPFETCH", stdout);
9898 if (option->info & OHW_R5KEOP)
9899 fputs (" R5KEOP", stdout);
9900 if (option->info & OHW_R5KCVTL)
9901 fputs (" R5KCVTL", stdout);
9902 break;
9903 case ODK_FILL:
9904 fputs (" FILL ", stdout);
9905 /* XXX Print content of info word? */
9906 break;
9907 case ODK_TAGS:
9908 fputs (" TAGS ", stdout);
9909 /* XXX Print content of info word? */
9910 break;
9911 case ODK_HWAND:
9912 fputs (" HWAND ", stdout);
9913 if (option->info & OHWA0_R4KEOP_CHECKED)
9914 fputs (" R4KEOP_CHECKED", stdout);
9915 if (option->info & OHWA0_R4KEOP_CLEAN)
9916 fputs (" R4KEOP_CLEAN", stdout);
9917 break;
9918 case ODK_HWOR:
9919 fputs (" HWOR ", stdout);
9920 if (option->info & OHWA0_R4KEOP_CHECKED)
9921 fputs (" R4KEOP_CHECKED", stdout);
9922 if (option->info & OHWA0_R4KEOP_CLEAN)
9923 fputs (" R4KEOP_CLEAN", stdout);
9924 break;
9925 case ODK_GP_GROUP:
9926 printf (" GP_GROUP %#06lx self-contained %#06lx",
9927 option->info & OGP_GROUP,
9928 (option->info & OGP_SELF) >> 16);
9929 break;
9930 case ODK_IDENT:
9931 printf (" IDENT %#06lx self-contained %#06lx",
9932 option->info & OGP_GROUP,
9933 (option->info & OGP_SELF) >> 16);
9934 break;
9935 default:
9936 /* This shouldn't happen. */
9937 printf (" %3d ??? %d %lx",
9938 option->kind, option->section, option->info);
9939 break;
252b5132 9940 }
a6e9f9df 9941
2cf0635d 9942 len = sizeof (* eopt);
a6e9f9df
AM
9943 while (len < option->size)
9944 if (((char *) option)[len] >= ' '
9945 && ((char *) option)[len] < 0x7f)
9946 printf ("%c", ((char *) option)[len++]);
9947 else
9948 printf ("\\%03o", ((char *) option)[len++]);
9949
9950 fputs ("\n", stdout);
252b5132 9951 ++option;
252b5132
RH
9952 }
9953
a6e9f9df 9954 free (eopt);
252b5132 9955 }
252b5132
RH
9956 }
9957
9958 if (conflicts_offset != 0 && conflictsno != 0)
9959 {
2cf0635d 9960 Elf32_Conflict * iconf;
252b5132
RH
9961 size_t cnt;
9962
9963 if (dynamic_symbols == NULL)
9964 {
591a748a 9965 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
9966 return 0;
9967 }
9968
3f5e193b 9969 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
9970 if (iconf == NULL)
9971 {
591a748a 9972 error (_("Out of memory\n"));
252b5132
RH
9973 return 0;
9974 }
9975
9ea033b2 9976 if (is_32bit_elf)
252b5132 9977 {
2cf0635d 9978 Elf32_External_Conflict * econf32;
a6e9f9df 9979
3f5e193b
NC
9980 econf32 = (Elf32_External_Conflict *)
9981 get_data (NULL, file, conflicts_offset, conflictsno,
9982 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
9983 if (!econf32)
9984 return 0;
252b5132
RH
9985
9986 for (cnt = 0; cnt < conflictsno; ++cnt)
9987 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
9988
9989 free (econf32);
252b5132
RH
9990 }
9991 else
9992 {
2cf0635d 9993 Elf64_External_Conflict * econf64;
a6e9f9df 9994
3f5e193b
NC
9995 econf64 = (Elf64_External_Conflict *)
9996 get_data (NULL, file, conflicts_offset, conflictsno,
9997 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
9998 if (!econf64)
9999 return 0;
252b5132
RH
10000
10001 for (cnt = 0; cnt < conflictsno; ++cnt)
10002 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
10003
10004 free (econf64);
252b5132
RH
10005 }
10006
c7e7ca54
NC
10007 printf (_("\nSection '.conflict' contains %lu entries:\n"),
10008 (unsigned long) conflictsno);
252b5132
RH
10009 puts (_(" Num: Index Value Name"));
10010
10011 for (cnt = 0; cnt < conflictsno; ++cnt)
10012 {
2cf0635d 10013 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 10014
b34976b6 10015 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 10016 print_vma (psym->st_value, FULL_HEX);
31104126 10017 putchar (' ');
d79b3d50
NC
10018 if (VALID_DYNAMIC_NAME (psym->st_name))
10019 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10020 else
10021 printf ("<corrupt: %14ld>", psym->st_name);
31104126 10022 putchar ('\n');
252b5132
RH
10023 }
10024
252b5132
RH
10025 free (iconf);
10026 }
10027
ccb4c951
RS
10028 if (pltgot != 0 && local_gotno != 0)
10029 {
10030 bfd_vma entry, local_end, global_end;
bbeee7ea 10031 size_t i, offset;
2cf0635d 10032 unsigned char * data;
bbeee7ea 10033 int addr_size;
ccb4c951
RS
10034
10035 entry = pltgot;
10036 addr_size = (is_32bit_elf ? 4 : 8);
10037 local_end = pltgot + local_gotno * addr_size;
10038 global_end = local_end + (symtabno - gotsym) * addr_size;
10039
10040 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b
NC
10041 data = (unsigned char *) get_data (NULL, file, offset,
10042 global_end - pltgot, 1, _("GOT"));
ccb4c951
RS
10043 printf (_("\nPrimary GOT:\n"));
10044 printf (_(" Canonical gp value: "));
10045 print_vma (pltgot + 0x7ff0, LONG_HEX);
10046 printf ("\n\n");
10047
10048 printf (_(" Reserved entries:\n"));
10049 printf (_(" %*s %10s %*s Purpose\n"),
10050 addr_size * 2, "Address", "Access",
10051 addr_size * 2, "Initial");
10052 entry = print_mips_got_entry (data, pltgot, entry);
10053 printf (" Lazy resolver\n");
10054 if (data
10055 && (byte_get (data + entry - pltgot, addr_size)
10056 >> (addr_size * 8 - 1)) != 0)
10057 {
10058 entry = print_mips_got_entry (data, pltgot, entry);
10059 printf (" Module pointer (GNU extension)\n");
10060 }
10061 printf ("\n");
10062
10063 if (entry < local_end)
10064 {
10065 printf (_(" Local entries:\n"));
10066 printf (_(" %*s %10s %*s\n"),
10067 addr_size * 2, "Address", "Access",
10068 addr_size * 2, "Initial");
10069 while (entry < local_end)
10070 {
10071 entry = print_mips_got_entry (data, pltgot, entry);
10072 printf ("\n");
10073 }
10074 printf ("\n");
10075 }
10076
10077 if (gotsym < symtabno)
10078 {
10079 int sym_width;
10080
10081 printf (_(" Global entries:\n"));
10082 printf (_(" %*s %10s %*s %*s %-7s %3s %s\n"),
10083 addr_size * 2, "Address", "Access",
10084 addr_size * 2, "Initial",
10085 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
10086 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
10087 for (i = gotsym; i < symtabno; i++)
10088 {
2cf0635d 10089 Elf_Internal_Sym * psym;
ccb4c951
RS
10090
10091 psym = dynamic_symbols + i;
10092 entry = print_mips_got_entry (data, pltgot, entry);
10093 printf (" ");
10094 print_vma (psym->st_value, LONG_HEX);
10095 printf (" %-7s %3s ",
10096 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
10097 get_symbol_index_type (psym->st_shndx));
10098 if (VALID_DYNAMIC_NAME (psym->st_name))
10099 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
10100 else
10101 printf ("<corrupt: %14ld>", psym->st_name);
10102 printf ("\n");
10103 }
10104 printf ("\n");
10105 }
10106
10107 if (data)
10108 free (data);
10109 }
10110
861fb55a
DJ
10111 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
10112 {
10113 bfd_vma entry, end;
10114 size_t offset, rel_offset;
10115 unsigned long count, i;
2cf0635d 10116 unsigned char * data;
861fb55a 10117 int addr_size, sym_width;
2cf0635d 10118 Elf_Internal_Rela * rels;
861fb55a
DJ
10119
10120 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
10121 if (pltrel == DT_RELA)
10122 {
10123 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
10124 return 0;
10125 }
10126 else
10127 {
10128 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
10129 return 0;
10130 }
10131
10132 entry = mips_pltgot;
10133 addr_size = (is_32bit_elf ? 4 : 8);
10134 end = mips_pltgot + (2 + count) * addr_size;
10135
10136 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b
NC
10137 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
10138 1, _("PLT GOT"));
861fb55a
DJ
10139 printf (_("\nPLT GOT:\n\n"));
10140 printf (_(" Reserved entries:\n"));
10141 printf (_(" %*s %*s Purpose\n"),
10142 addr_size * 2, "Address", addr_size * 2, "Initial");
10143 entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
10144 printf (" PLT lazy resolver\n");
10145 entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
10146 printf (" Module pointer\n");
10147 printf ("\n");
10148
10149 printf (_(" Entries:\n"));
10150 printf (_(" %*s %*s %*s %-7s %3s %s\n"),
10151 addr_size * 2, "Address",
10152 addr_size * 2, "Initial",
10153 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
10154 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
10155 for (i = 0; i < count; i++)
10156 {
2cf0635d 10157 Elf_Internal_Sym * psym;
861fb55a
DJ
10158
10159 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
10160 entry = print_mips_pltgot_entry (data, mips_pltgot, entry);
10161 printf (" ");
10162 print_vma (psym->st_value, LONG_HEX);
10163 printf (" %-7s %3s ",
10164 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
10165 get_symbol_index_type (psym->st_shndx));
10166 if (VALID_DYNAMIC_NAME (psym->st_name))
10167 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
10168 else
10169 printf ("<corrupt: %14ld>", psym->st_name);
10170 printf ("\n");
10171 }
10172 printf ("\n");
10173
10174 if (data)
10175 free (data);
10176 free (rels);
10177 }
10178
252b5132
RH
10179 return 1;
10180}
10181
047b2264 10182static int
2cf0635d 10183process_gnu_liblist (FILE * file)
047b2264 10184{
2cf0635d
NC
10185 Elf_Internal_Shdr * section;
10186 Elf_Internal_Shdr * string_sec;
10187 Elf32_External_Lib * elib;
10188 char * strtab;
c256ffe7 10189 size_t strtab_size;
047b2264
JJ
10190 size_t cnt;
10191 unsigned i;
10192
10193 if (! do_arch)
10194 return 0;
10195
10196 for (i = 0, section = section_headers;
10197 i < elf_header.e_shnum;
b34976b6 10198 i++, section++)
047b2264
JJ
10199 {
10200 switch (section->sh_type)
10201 {
10202 case SHT_GNU_LIBLIST:
4fbb74a6 10203 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
10204 break;
10205
3f5e193b
NC
10206 elib = (Elf32_External_Lib *)
10207 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
10208 _("liblist"));
047b2264
JJ
10209
10210 if (elib == NULL)
10211 break;
4fbb74a6 10212 string_sec = section_headers + section->sh_link;
047b2264 10213
3f5e193b
NC
10214 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
10215 string_sec->sh_size,
10216 _("liblist string table"));
c256ffe7 10217 strtab_size = string_sec->sh_size;
047b2264
JJ
10218
10219 if (strtab == NULL
10220 || section->sh_entsize != sizeof (Elf32_External_Lib))
10221 {
10222 free (elib);
10223 break;
10224 }
10225
10226 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
10227 SECTION_NAME (section),
0af1713e 10228 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264
JJ
10229
10230 puts (" Library Time Stamp Checksum Version Flags");
10231
10232 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
10233 ++cnt)
10234 {
10235 Elf32_Lib liblist;
10236 time_t time;
10237 char timebuf[20];
2cf0635d 10238 struct tm * tmp;
047b2264
JJ
10239
10240 liblist.l_name = BYTE_GET (elib[cnt].l_name);
10241 time = BYTE_GET (elib[cnt].l_time_stamp);
10242 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
10243 liblist.l_version = BYTE_GET (elib[cnt].l_version);
10244 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
10245
10246 tmp = gmtime (&time);
e9e44622
JJ
10247 snprintf (timebuf, sizeof (timebuf),
10248 "%04u-%02u-%02uT%02u:%02u:%02u",
10249 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10250 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10251
10252 printf ("%3lu: ", (unsigned long) cnt);
10253 if (do_wide)
c256ffe7
JJ
10254 printf ("%-20s", liblist.l_name < strtab_size
10255 ? strtab + liblist.l_name : "<corrupt>");
047b2264 10256 else
c256ffe7
JJ
10257 printf ("%-20.20s", liblist.l_name < strtab_size
10258 ? strtab + liblist.l_name : "<corrupt>");
047b2264
JJ
10259 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
10260 liblist.l_version, liblist.l_flags);
10261 }
10262
10263 free (elib);
10264 }
10265 }
10266
10267 return 1;
10268}
10269
9437c45b 10270static const char *
d3ba0551 10271get_note_type (unsigned e_type)
779fe533
NC
10272{
10273 static char buff[64];
103f02d3 10274
1ec5cd37
NC
10275 if (elf_header.e_type == ET_CORE)
10276 switch (e_type)
10277 {
57346661 10278 case NT_AUXV:
1ec5cd37 10279 return _("NT_AUXV (auxiliary vector)");
57346661 10280 case NT_PRSTATUS:
1ec5cd37 10281 return _("NT_PRSTATUS (prstatus structure)");
57346661 10282 case NT_FPREGSET:
1ec5cd37 10283 return _("NT_FPREGSET (floating point registers)");
57346661 10284 case NT_PRPSINFO:
1ec5cd37 10285 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 10286 case NT_TASKSTRUCT:
1ec5cd37 10287 return _("NT_TASKSTRUCT (task structure)");
57346661 10288 case NT_PRXFPREG:
1ec5cd37 10289 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
10290 case NT_PPC_VMX:
10291 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
10292 case NT_PPC_VSX:
10293 return _("NT_PPC_VSX (ppc VSX registers)");
57346661 10294 case NT_PSTATUS:
1ec5cd37 10295 return _("NT_PSTATUS (pstatus structure)");
57346661 10296 case NT_FPREGS:
1ec5cd37 10297 return _("NT_FPREGS (floating point registers)");
57346661 10298 case NT_PSINFO:
1ec5cd37 10299 return _("NT_PSINFO (psinfo structure)");
57346661 10300 case NT_LWPSTATUS:
1ec5cd37 10301 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 10302 case NT_LWPSINFO:
1ec5cd37 10303 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 10304 case NT_WIN32PSTATUS:
1ec5cd37
NC
10305 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
10306 default:
10307 break;
10308 }
10309 else
10310 switch (e_type)
10311 {
10312 case NT_VERSION:
10313 return _("NT_VERSION (version)");
10314 case NT_ARCH:
10315 return _("NT_ARCH (architecture)");
10316 default:
10317 break;
10318 }
10319
e9e44622 10320 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 10321 return buff;
779fe533
NC
10322}
10323
1118d252
RM
10324static const char *
10325get_gnu_elf_note_type (unsigned e_type)
10326{
10327 static char buff[64];
10328
10329 switch (e_type)
10330 {
10331 case NT_GNU_ABI_TAG:
10332 return _("NT_GNU_ABI_TAG (ABI version tag)");
10333 case NT_GNU_HWCAP:
10334 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
10335 case NT_GNU_BUILD_ID:
10336 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
10337 case NT_GNU_GOLD_VERSION:
10338 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
10339 default:
10340 break;
10341 }
10342
10343 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
10344 return buff;
10345}
10346
9437c45b 10347static const char *
d3ba0551 10348get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
10349{
10350 static char buff[64];
10351
b4db1224 10352 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
10353 {
10354 /* NetBSD core "procinfo" structure. */
10355 return _("NetBSD procinfo structure");
10356 }
10357
10358 /* As of Jan 2002 there are no other machine-independent notes
10359 defined for NetBSD core files. If the note type is less
10360 than the start of the machine-dependent note types, we don't
10361 understand it. */
10362
b4db1224 10363 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 10364 {
e9e44622 10365 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
10366 return buff;
10367 }
10368
10369 switch (elf_header.e_machine)
10370 {
10371 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
10372 and PT_GETFPREGS == mach+2. */
10373
10374 case EM_OLD_ALPHA:
10375 case EM_ALPHA:
10376 case EM_SPARC:
10377 case EM_SPARC32PLUS:
10378 case EM_SPARCV9:
10379 switch (e_type)
10380 {
b4db1224
JT
10381 case NT_NETBSDCORE_FIRSTMACH+0:
10382 return _("PT_GETREGS (reg structure)");
10383 case NT_NETBSDCORE_FIRSTMACH+2:
10384 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10385 default:
10386 break;
10387 }
10388 break;
10389
10390 /* On all other arch's, PT_GETREGS == mach+1 and
10391 PT_GETFPREGS == mach+3. */
10392 default:
10393 switch (e_type)
10394 {
b4db1224
JT
10395 case NT_NETBSDCORE_FIRSTMACH+1:
10396 return _("PT_GETREGS (reg structure)");
10397 case NT_NETBSDCORE_FIRSTMACH+3:
10398 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
10399 default:
10400 break;
10401 }
10402 }
10403
e9e44622
JJ
10404 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
10405 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
10406 return buff;
10407}
10408
6d118b09
NC
10409/* Note that by the ELF standard, the name field is already null byte
10410 terminated, and namesz includes the terminating null byte.
10411 I.E. the value of namesz for the name "FSF" is 4.
10412
e3c8793a 10413 If the value of namesz is zero, there is no name present. */
779fe533 10414static int
2cf0635d 10415process_note (Elf_Internal_Note * pnote)
779fe533 10416{
2cf0635d
NC
10417 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
10418 const char * nt;
9437c45b
JT
10419
10420 if (pnote->namesz == 0)
1ec5cd37
NC
10421 /* If there is no note name, then use the default set of
10422 note type strings. */
10423 nt = get_note_type (pnote->type);
10424
1118d252
RM
10425 else if (const_strneq (pnote->namedata, "GNU"))
10426 /* GNU-specific object file notes. */
10427 nt = get_gnu_elf_note_type (pnote->type);
10428
0112cd26 10429 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
10430 /* NetBSD-specific core file notes. */
10431 nt = get_netbsd_elfcore_note_type (pnote->type);
10432
b15fa79e
AM
10433 else if (strneq (pnote->namedata, "SPU/", 4))
10434 {
10435 /* SPU-specific core file notes. */
10436 nt = pnote->namedata + 4;
10437 name = "SPU";
10438 }
10439
9437c45b 10440 else
1ec5cd37
NC
10441 /* Don't recognize this note name; just use the default set of
10442 note type strings. */
9437c45b 10443 nt = get_note_type (pnote->type);
9437c45b 10444
b15fa79e 10445 printf (" %s\t\t0x%08lx\t%s\n", name, pnote->descsz, nt);
779fe533
NC
10446 return 1;
10447}
10448
6d118b09 10449
779fe533 10450static int
2cf0635d 10451process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 10452{
2cf0635d
NC
10453 Elf_External_Note * pnotes;
10454 Elf_External_Note * external;
b34976b6 10455 int res = 1;
103f02d3 10456
779fe533
NC
10457 if (length <= 0)
10458 return 0;
103f02d3 10459
3f5e193b
NC
10460 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
10461 _("notes"));
a6e9f9df
AM
10462 if (!pnotes)
10463 return 0;
779fe533 10464
103f02d3 10465 external = pnotes;
103f02d3 10466
305c7206 10467 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 10468 (unsigned long) offset, (unsigned long) length);
779fe533 10469 printf (_(" Owner\t\tData size\tDescription\n"));
103f02d3 10470
2cf0635d 10471 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 10472 {
2cf0635d 10473 Elf_External_Note * next;
b34976b6 10474 Elf_Internal_Note inote;
2cf0635d 10475 char * temp = NULL;
6d118b09
NC
10476
10477 inote.type = BYTE_GET (external->type);
10478 inote.namesz = BYTE_GET (external->namesz);
10479 inote.namedata = external->name;
10480 inote.descsz = BYTE_GET (external->descsz);
10481 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
10482 inote.descpos = offset + (inote.descdata - (char *) pnotes);
76da6bbe 10483
2cf0635d 10484 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
3e55a963
NC
10485
10486 if (((char *) next) > (((char *) pnotes) + length))
10487 {
0fd3a477 10488 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 10489 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 10490 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
10491 inote.type, inote.namesz, inote.descsz);
10492 break;
10493 }
10494
10495 external = next;
6d118b09
NC
10496
10497 /* Verify that name is null terminated. It appears that at least
10498 one version of Linux (RedHat 6.0) generates corefiles that don't
10499 comply with the ELF spec by failing to include the null byte in
10500 namesz. */
10501 if (inote.namedata[inote.namesz] != '\0')
10502 {
3f5e193b 10503 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 10504
6d118b09
NC
10505 if (temp == NULL)
10506 {
10507 error (_("Out of memory\n"));
10508 res = 0;
10509 break;
10510 }
76da6bbe 10511
6d118b09
NC
10512 strncpy (temp, inote.namedata, inote.namesz);
10513 temp[inote.namesz] = 0;
76da6bbe 10514
6d118b09
NC
10515 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
10516 inote.namedata = temp;
10517 }
10518
10519 res &= process_note (& inote);
103f02d3 10520
6d118b09
NC
10521 if (temp != NULL)
10522 {
10523 free (temp);
10524 temp = NULL;
10525 }
779fe533
NC
10526 }
10527
10528 free (pnotes);
103f02d3 10529
779fe533
NC
10530 return res;
10531}
10532
10533static int
2cf0635d 10534process_corefile_note_segments (FILE * file)
779fe533 10535{
2cf0635d 10536 Elf_Internal_Phdr * segment;
b34976b6
AM
10537 unsigned int i;
10538 int res = 1;
103f02d3 10539
d93f0186 10540 if (! get_program_headers (file))
779fe533 10541 return 0;
103f02d3 10542
779fe533
NC
10543 for (i = 0, segment = program_headers;
10544 i < elf_header.e_phnum;
b34976b6 10545 i++, segment++)
779fe533
NC
10546 {
10547 if (segment->p_type == PT_NOTE)
103f02d3 10548 res &= process_corefile_note_segment (file,
30800947
NC
10549 (bfd_vma) segment->p_offset,
10550 (bfd_vma) segment->p_filesz);
779fe533 10551 }
103f02d3 10552
779fe533
NC
10553 return res;
10554}
10555
10556static int
2cf0635d 10557process_note_sections (FILE * file)
1ec5cd37 10558{
2cf0635d 10559 Elf_Internal_Shdr * section;
1ec5cd37
NC
10560 unsigned long i;
10561 int res = 1;
10562
10563 for (i = 0, section = section_headers;
10564 i < elf_header.e_shnum;
10565 i++, section++)
10566 if (section->sh_type == SHT_NOTE)
10567 res &= process_corefile_note_segment (file,
10568 (bfd_vma) section->sh_offset,
10569 (bfd_vma) section->sh_size);
10570
10571 return res;
10572}
10573
10574static int
2cf0635d 10575process_notes (FILE * file)
779fe533
NC
10576{
10577 /* If we have not been asked to display the notes then do nothing. */
10578 if (! do_notes)
10579 return 1;
103f02d3 10580
779fe533 10581 if (elf_header.e_type != ET_CORE)
1ec5cd37 10582 return process_note_sections (file);
103f02d3 10583
779fe533 10584 /* No program headers means no NOTE segment. */
1ec5cd37
NC
10585 if (elf_header.e_phnum > 0)
10586 return process_corefile_note_segments (file);
779fe533 10587
1ec5cd37
NC
10588 printf (_("No note segments present in the core file.\n"));
10589 return 1;
779fe533
NC
10590}
10591
252b5132 10592static int
2cf0635d 10593process_arch_specific (FILE * file)
252b5132 10594{
a952a375
NC
10595 if (! do_arch)
10596 return 1;
10597
252b5132
RH
10598 switch (elf_header.e_machine)
10599 {
11c1ff18
PB
10600 case EM_ARM:
10601 return process_arm_specific (file);
252b5132 10602 case EM_MIPS:
4fe85591 10603 case EM_MIPS_RS3_LE:
252b5132
RH
10604 return process_mips_specific (file);
10605 break;
34c8bcba
JM
10606 case EM_PPC:
10607 return process_power_specific (file);
10608 break;
252b5132
RH
10609 default:
10610 break;
10611 }
10612 return 1;
10613}
10614
10615static int
2cf0635d 10616get_file_header (FILE * file)
252b5132 10617{
9ea033b2
NC
10618 /* Read in the identity array. */
10619 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
10620 return 0;
10621
9ea033b2 10622 /* Determine how to read the rest of the header. */
b34976b6 10623 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
10624 {
10625 default: /* fall through */
10626 case ELFDATANONE: /* fall through */
adab8cdc
AO
10627 case ELFDATA2LSB:
10628 byte_get = byte_get_little_endian;
10629 byte_put = byte_put_little_endian;
10630 break;
10631 case ELFDATA2MSB:
10632 byte_get = byte_get_big_endian;
10633 byte_put = byte_put_big_endian;
10634 break;
9ea033b2
NC
10635 }
10636
10637 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 10638 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
10639
10640 /* Read in the rest of the header. */
10641 if (is_32bit_elf)
10642 {
10643 Elf32_External_Ehdr ehdr32;
252b5132 10644
9ea033b2
NC
10645 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
10646 return 0;
103f02d3 10647
9ea033b2
NC
10648 elf_header.e_type = BYTE_GET (ehdr32.e_type);
10649 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
10650 elf_header.e_version = BYTE_GET (ehdr32.e_version);
10651 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
10652 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
10653 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
10654 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
10655 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
10656 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
10657 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
10658 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
10659 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
10660 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
10661 }
252b5132 10662 else
9ea033b2
NC
10663 {
10664 Elf64_External_Ehdr ehdr64;
a952a375
NC
10665
10666 /* If we have been compiled with sizeof (bfd_vma) == 4, then
10667 we will not be able to cope with the 64bit data found in
10668 64 ELF files. Detect this now and abort before we start
50c2245b 10669 overwriting things. */
a952a375
NC
10670 if (sizeof (bfd_vma) < 8)
10671 {
e3c8793a
NC
10672 error (_("This instance of readelf has been built without support for a\n\
1067364 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
10674 return 0;
10675 }
103f02d3 10676
9ea033b2
NC
10677 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
10678 return 0;
103f02d3 10679
9ea033b2
NC
10680 elf_header.e_type = BYTE_GET (ehdr64.e_type);
10681 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
10682 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
10683 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
10684 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
10685 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
10686 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
10687 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
10688 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
10689 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
10690 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
10691 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
10692 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
10693 }
252b5132 10694
7ece0d85
JJ
10695 if (elf_header.e_shoff)
10696 {
10697 /* There may be some extensions in the first section header. Don't
10698 bomb if we can't read it. */
10699 if (is_32bit_elf)
10700 get_32bit_section_headers (file, 1);
10701 else
10702 get_64bit_section_headers (file, 1);
10703 }
560f3c1c 10704
252b5132
RH
10705 return 1;
10706}
10707
fb52b2f4
NC
10708/* Process one ELF object file according to the command line options.
10709 This file may actually be stored in an archive. The file is
10710 positioned at the start of the ELF object. */
10711
ff78d6d6 10712static int
2cf0635d 10713process_object (char * file_name, FILE * file)
252b5132 10714{
252b5132
RH
10715 unsigned int i;
10716
252b5132
RH
10717 if (! get_file_header (file))
10718 {
10719 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 10720 return 1;
252b5132
RH
10721 }
10722
10723 /* Initialise per file variables. */
60bca95a 10724 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
10725 version_info[i] = 0;
10726
60bca95a 10727 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132
RH
10728 dynamic_info[i] = 0;
10729
10730 /* Process the file. */
10731 if (show_name)
10732 printf (_("\nFile: %s\n"), file_name);
10733
18bd398b
NC
10734 /* Initialise the dump_sects array from the cmdline_dump_sects array.
10735 Note we do this even if cmdline_dump_sects is empty because we
10736 must make sure that the dump_sets array is zeroed out before each
10737 object file is processed. */
10738 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 10739 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
10740
10741 if (num_cmdline_dump_sects > 0)
10742 {
10743 if (num_dump_sects == 0)
10744 /* A sneaky way of allocating the dump_sects array. */
09c11c86 10745 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
10746
10747 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
10748 memcpy (dump_sects, cmdline_dump_sects,
10749 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 10750 }
d70c5fc7 10751
252b5132 10752 if (! process_file_header ())
fb52b2f4 10753 return 1;
252b5132 10754
d1f5c6e3 10755 if (! process_section_headers (file))
2f62977e 10756 {
d1f5c6e3
L
10757 /* Without loaded section headers we cannot process lots of
10758 things. */
2f62977e 10759 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 10760
2f62977e
NC
10761 if (! do_using_dynamic)
10762 do_syms = do_reloc = 0;
10763 }
252b5132 10764
d1f5c6e3
L
10765 if (! process_section_groups (file))
10766 {
10767 /* Without loaded section groups we cannot process unwind. */
10768 do_unwind = 0;
10769 }
10770
2f62977e 10771 if (process_program_headers (file))
b2d38a17 10772 process_dynamic_section (file);
252b5132
RH
10773
10774 process_relocs (file);
10775
4d6ed7c8
NC
10776 process_unwind (file);
10777
252b5132
RH
10778 process_symbol_table (file);
10779
10780 process_syminfo (file);
10781
10782 process_version_sections (file);
10783
10784 process_section_contents (file);
f5842774 10785
1ec5cd37 10786 process_notes (file);
103f02d3 10787
047b2264
JJ
10788 process_gnu_liblist (file);
10789
252b5132
RH
10790 process_arch_specific (file);
10791
d93f0186
NC
10792 if (program_headers)
10793 {
10794 free (program_headers);
10795 program_headers = NULL;
10796 }
10797
252b5132
RH
10798 if (section_headers)
10799 {
10800 free (section_headers);
10801 section_headers = NULL;
10802 }
10803
10804 if (string_table)
10805 {
10806 free (string_table);
10807 string_table = NULL;
d40ac9bd 10808 string_table_length = 0;
252b5132
RH
10809 }
10810
10811 if (dynamic_strings)
10812 {
10813 free (dynamic_strings);
10814 dynamic_strings = NULL;
d79b3d50 10815 dynamic_strings_length = 0;
252b5132
RH
10816 }
10817
10818 if (dynamic_symbols)
10819 {
10820 free (dynamic_symbols);
10821 dynamic_symbols = NULL;
19936277 10822 num_dynamic_syms = 0;
252b5132
RH
10823 }
10824
10825 if (dynamic_syminfo)
10826 {
10827 free (dynamic_syminfo);
10828 dynamic_syminfo = NULL;
10829 }
ff78d6d6 10830
e4b17d5c
L
10831 if (section_headers_groups)
10832 {
10833 free (section_headers_groups);
10834 section_headers_groups = NULL;
10835 }
10836
10837 if (section_groups)
10838 {
2cf0635d
NC
10839 struct group_list * g;
10840 struct group_list * next;
e4b17d5c
L
10841
10842 for (i = 0; i < group_count; i++)
10843 {
10844 for (g = section_groups [i].root; g != NULL; g = next)
10845 {
10846 next = g->next;
10847 free (g);
10848 }
10849 }
10850
10851 free (section_groups);
10852 section_groups = NULL;
10853 }
10854
19e6b90e 10855 free_debug_memory ();
18bd398b 10856
ff78d6d6 10857 return 0;
252b5132
RH
10858}
10859
2cf0635d
NC
10860/* Return the path name for a proxy entry in a thin archive, adjusted relative
10861 to the path name of the thin archive itself if necessary. Always returns
10862 a pointer to malloc'ed memory. */
10863
10864static char *
10865adjust_relative_path (char * file_name, char * name, int name_len)
10866{
10867 char * member_file_name;
10868 const char * base_name = lbasename (file_name);
10869
10870 /* This is a proxy entry for a thin archive member.
10871 If the extended name table contains an absolute path
10872 name, or if the archive is in the current directory,
10873 use the path name as given. Otherwise, we need to
10874 find the member relative to the directory where the
10875 archive is located. */
10876 if (IS_ABSOLUTE_PATH (name) || base_name == file_name)
10877 {
3f5e193b 10878 member_file_name = (char *) malloc (name_len + 1);
2cf0635d
NC
10879 if (member_file_name == NULL)
10880 {
10881 error (_("Out of memory\n"));
10882 return NULL;
10883 }
10884 memcpy (member_file_name, name, name_len);
10885 member_file_name[name_len] = '\0';
10886 }
10887 else
10888 {
10889 /* Concatenate the path components of the archive file name
10890 to the relative path name from the extended name table. */
10891 size_t prefix_len = base_name - file_name;
3f5e193b 10892 member_file_name = (char *) malloc (prefix_len + name_len + 1);
2cf0635d
NC
10893 if (member_file_name == NULL)
10894 {
10895 error (_("Out of memory\n"));
10896 return NULL;
10897 }
10898 memcpy (member_file_name, file_name, prefix_len);
10899 memcpy (member_file_name + prefix_len, name, name_len);
10900 member_file_name[prefix_len + name_len] = '\0';
10901 }
10902 return member_file_name;
10903}
10904
10905/* Structure to hold information about an archive file. */
10906
10907struct archive_info
10908{
10909 char * file_name; /* Archive file name. */
10910 FILE * file; /* Open file descriptor. */
10911 unsigned long index_num; /* Number of symbols in table. */
10912 unsigned long * index_array; /* The array of member offsets. */
10913 char * sym_table; /* The symbol table. */
10914 unsigned long sym_size; /* Size of the symbol table. */
10915 char * longnames; /* The long file names table. */
10916 unsigned long longnames_size; /* Size of the long file names table. */
10917 unsigned long nested_member_origin; /* Origin in the nested archive of the current member. */
10918 unsigned long next_arhdr_offset; /* Offset of the next archive header. */
10919 bfd_boolean is_thin_archive; /* TRUE if this is a thin archive. */
10920 struct ar_hdr arhdr; /* Current archive header. */
10921};
10922
10923/* Read the symbol table and long-name table from an archive. */
fb52b2f4
NC
10924
10925static int
2cf0635d
NC
10926setup_archive (struct archive_info * arch, char * file_name, FILE * file,
10927 bfd_boolean is_thin_archive, bfd_boolean read_symbols)
fb52b2f4 10928{
fb52b2f4
NC
10929 size_t got;
10930 unsigned long size;
fb52b2f4 10931
2cf0635d
NC
10932 arch->file_name = strdup (file_name);
10933 arch->file = file;
10934 arch->index_num = 0;
10935 arch->index_array = NULL;
10936 arch->sym_table = NULL;
10937 arch->sym_size = 0;
10938 arch->longnames = NULL;
10939 arch->longnames_size = 0;
10940 arch->nested_member_origin = 0;
10941 arch->is_thin_archive = is_thin_archive;
10942 arch->next_arhdr_offset = SARMAG;
10943
10944 /* Read the first archive member header. */
10945 if (fseek (file, SARMAG, SEEK_SET) != 0)
10946 {
10947 error (_("%s: failed to seek to first archive header\n"), file_name);
10948 return 1;
10949 }
10950 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
10951 if (got != sizeof arch->arhdr)
fb52b2f4
NC
10952 {
10953 if (got == 0)
10954 return 0;
10955
10956 error (_("%s: failed to read archive header\n"), file_name);
10957 return 1;
10958 }
10959
4145f1d5 10960 /* See if this is the archive symbol table. */
2cf0635d
NC
10961 if (const_strneq (arch->arhdr.ar_name, "/ ")
10962 || const_strneq (arch->arhdr.ar_name, "/SYM64/ "))
fb52b2f4 10963 {
2cf0635d 10964 size = strtoul (arch->arhdr.ar_size, NULL, 10);
4145f1d5
NC
10965 size = size + (size & 1);
10966
2cf0635d
NC
10967 arch->next_arhdr_offset += sizeof arch->arhdr + size;
10968
10969 if (read_symbols)
fb52b2f4 10970 {
4145f1d5
NC
10971 unsigned long i;
10972 /* A buffer used to hold numbers read in from an archive index.
10973 These are always 4 bytes long and stored in big-endian format. */
10974#define SIZEOF_AR_INDEX_NUMBERS 4
10975 unsigned char integer_buffer[SIZEOF_AR_INDEX_NUMBERS];
10976 unsigned char * index_buffer;
10977
10978 /* Check the size of the archive index. */
10979 if (size < SIZEOF_AR_INDEX_NUMBERS)
10980 {
10981 error (_("%s: the archive index is empty\n"), file_name);
10982 return 1;
10983 }
10984
10985 /* Read the numer of entries in the archive index. */
10986 got = fread (integer_buffer, 1, sizeof integer_buffer, file);
10987 if (got != sizeof (integer_buffer))
10988 {
10989 error (_("%s: failed to read archive index\n"), file_name);
10990 return 1;
10991 }
2cf0635d 10992 arch->index_num = byte_get_big_endian (integer_buffer, sizeof integer_buffer);
4145f1d5
NC
10993 size -= SIZEOF_AR_INDEX_NUMBERS;
10994
10995 /* Read in the archive index. */
2cf0635d 10996 if (size < arch->index_num * SIZEOF_AR_INDEX_NUMBERS)
4145f1d5
NC
10997 {
10998 error (_("%s: the archive index is supposed to have %ld entries, but the size in the header is too small\n"),
2cf0635d 10999 file_name, arch->index_num);
4145f1d5
NC
11000 return 1;
11001 }
3f5e193b
NC
11002 index_buffer = (unsigned char *)
11003 malloc (arch->index_num * SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
11004 if (index_buffer == NULL)
11005 {
11006 error (_("Out of memory whilst trying to read archive symbol index\n"));
11007 return 1;
11008 }
2cf0635d
NC
11009 got = fread (index_buffer, SIZEOF_AR_INDEX_NUMBERS, arch->index_num, file);
11010 if (got != arch->index_num)
4145f1d5
NC
11011 {
11012 free (index_buffer);
11013 error (_("%s: failed to read archive index\n"), file_name);
2cf0635d 11014 return 1;
4145f1d5 11015 }
2cf0635d 11016 size -= arch->index_num * SIZEOF_AR_INDEX_NUMBERS;
4145f1d5
NC
11017
11018 /* Convert the index numbers into the host's numeric format. */
3f5e193b
NC
11019 arch->index_array = (long unsigned int *)
11020 malloc (arch->index_num * sizeof (* arch->index_array));
2cf0635d 11021 if (arch->index_array == NULL)
4145f1d5
NC
11022 {
11023 free (index_buffer);
11024 error (_("Out of memory whilst trying to convert the archive symbol index\n"));
11025 return 1;
11026 }
11027
2cf0635d
NC
11028 for (i = 0; i < arch->index_num; i++)
11029 arch->index_array[i] = byte_get_big_endian ((unsigned char *) (index_buffer + (i * SIZEOF_AR_INDEX_NUMBERS)),
11030 SIZEOF_AR_INDEX_NUMBERS);
4145f1d5
NC
11031 free (index_buffer);
11032
11033 /* The remaining space in the header is taken up by the symbol table. */
11034 if (size < 1)
11035 {
11036 error (_("%s: the archive has an index but no symbols\n"), file_name);
2cf0635d 11037 return 1;
4145f1d5 11038 }
3f5e193b 11039 arch->sym_table = (char *) malloc (size);
2cf0635d
NC
11040 arch->sym_size = size;
11041 if (arch->sym_table == NULL)
4145f1d5
NC
11042 {
11043 error (_("Out of memory whilst trying to read archive index symbol table\n"));
2cf0635d 11044 return 1;
4145f1d5 11045 }
2cf0635d 11046 got = fread (arch->sym_table, 1, size, file);
4145f1d5
NC
11047 if (got != size)
11048 {
11049 error (_("%s: failed to read archive index symbol table\n"), file_name);
2cf0635d 11050 return 1;
cb8f3167 11051 }
4145f1d5
NC
11052 }
11053 else
11054 {
11055 if (fseek (file, size, SEEK_CUR) != 0)
11056 {
11057 error (_("%s: failed to skip archive symbol table\n"), file_name);
11058 return 1;
11059 }
fb52b2f4
NC
11060 }
11061
2cf0635d
NC
11062 /* Read the next archive header. */
11063 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, file);
11064 if (got != sizeof arch->arhdr)
fb52b2f4
NC
11065 {
11066 if (got == 0)
2cf0635d 11067 return 0;
4145f1d5 11068 error (_("%s: failed to read archive header following archive index\n"), file_name);
2cf0635d 11069 return 1;
fb52b2f4
NC
11070 }
11071 }
2cf0635d 11072 else if (read_symbols)
4145f1d5 11073 printf (_("%s has no archive index\n"), file_name);
fb52b2f4 11074
2cf0635d 11075 if (const_strneq (arch->arhdr.ar_name, "// "))
fb52b2f4 11076 {
2cf0635d
NC
11077 /* This is the archive string table holding long member names. */
11078 arch->longnames_size = strtoul (arch->arhdr.ar_size, NULL, 10);
11079 arch->next_arhdr_offset += sizeof arch->arhdr + arch->longnames_size;
fb52b2f4 11080
3f5e193b 11081 arch->longnames = (char *) malloc (arch->longnames_size);
2cf0635d 11082 if (arch->longnames == NULL)
fb52b2f4 11083 {
4145f1d5 11084 error (_("Out of memory reading long symbol names in archive\n"));
2cf0635d 11085 return 1;
fb52b2f4
NC
11086 }
11087
2cf0635d 11088 if (fread (arch->longnames, arch->longnames_size, 1, file) != 1)
fb52b2f4 11089 {
2cf0635d
NC
11090 free (arch->longnames);
11091 arch->longnames = NULL;
4145f1d5 11092 error (_("%s: failed to read long symbol name string table\n"), file_name);
2cf0635d 11093 return 1;
fb52b2f4
NC
11094 }
11095
2cf0635d 11096 if ((arch->longnames_size & 1) != 0)
fb52b2f4 11097 getc (file);
2cf0635d 11098 }
fb52b2f4 11099
2cf0635d
NC
11100 return 0;
11101}
11102
11103/* Release the memory used for the archive information. */
11104
11105static void
11106release_archive (struct archive_info * arch)
11107{
11108 if (arch->file_name != NULL)
11109 free (arch->file_name);
11110 if (arch->index_array != NULL)
11111 free (arch->index_array);
11112 if (arch->sym_table != NULL)
11113 free (arch->sym_table);
11114 if (arch->longnames != NULL)
11115 free (arch->longnames);
11116}
11117
11118/* Open and setup a nested archive, if not already open. */
11119
11120static int
11121setup_nested_archive (struct archive_info * nested_arch, char * member_file_name)
11122{
11123 FILE * member_file;
11124
11125 /* Have we already setup this archive? */
11126 if (nested_arch->file_name != NULL
11127 && streq (nested_arch->file_name, member_file_name))
11128 return 0;
11129
11130 /* Close previous file and discard cached information. */
11131 if (nested_arch->file != NULL)
11132 fclose (nested_arch->file);
11133 release_archive (nested_arch);
11134
11135 member_file = fopen (member_file_name, "rb");
11136 if (member_file == NULL)
11137 return 1;
11138 return setup_archive (nested_arch, member_file_name, member_file, FALSE, FALSE);
11139}
11140
11141static char *
11142get_archive_member_name_at (struct archive_info * arch,
11143 unsigned long offset,
11144 struct archive_info * nested_arch);
11145
11146/* Get the name of an archive member from the current archive header.
11147 For simple names, this will modify the ar_name field of the current
11148 archive header. For long names, it will return a pointer to the
11149 longnames table. For nested archives, it will open the nested archive
11150 and get the name recursively. NESTED_ARCH is a single-entry cache so
11151 we don't keep rereading the same information from a nested archive. */
11152
11153static char *
11154get_archive_member_name (struct archive_info * arch,
11155 struct archive_info * nested_arch)
11156{
11157 unsigned long j, k;
11158
11159 if (arch->arhdr.ar_name[0] == '/')
11160 {
11161 /* We have a long name. */
11162 char * endp;
11163 char * member_file_name;
11164 char * member_name;
11165
11166 arch->nested_member_origin = 0;
11167 k = j = strtoul (arch->arhdr.ar_name + 1, &endp, 10);
11168 if (arch->is_thin_archive && endp != NULL && * endp == ':')
11169 arch->nested_member_origin = strtoul (endp + 1, NULL, 10);
11170
11171 while ((j < arch->longnames_size)
11172 && (arch->longnames[j] != '\n')
11173 && (arch->longnames[j] != '\0'))
11174 j++;
11175 if (arch->longnames[j-1] == '/')
11176 j--;
11177 arch->longnames[j] = '\0';
11178
11179 if (!arch->is_thin_archive || arch->nested_member_origin == 0)
11180 return arch->longnames + k;
11181
11182 /* This is a proxy for a member of a nested archive.
11183 Find the name of the member in that archive. */
11184 member_file_name = adjust_relative_path (arch->file_name, arch->longnames + k, j - k);
11185 if (member_file_name != NULL
11186 && setup_nested_archive (nested_arch, member_file_name) == 0
11187 && (member_name = get_archive_member_name_at (nested_arch, arch->nested_member_origin, NULL)) != NULL)
11188 {
11189 free (member_file_name);
11190 return member_name;
11191 }
11192 free (member_file_name);
11193
11194 /* Last resort: just return the name of the nested archive. */
11195 return arch->longnames + k;
11196 }
11197
11198 /* We have a normal (short) name. */
11199 j = 0;
11200 while ((arch->arhdr.ar_name[j] != '/') && (j < 16))
11201 j++;
11202 arch->arhdr.ar_name[j] = '\0';
11203 return arch->arhdr.ar_name;
11204}
11205
11206/* Get the name of an archive member at a given OFFSET within an archive ARCH. */
11207
11208static char *
11209get_archive_member_name_at (struct archive_info * arch,
11210 unsigned long offset,
11211 struct archive_info * nested_arch)
11212{
11213 size_t got;
11214
11215 if (fseek (arch->file, offset, SEEK_SET) != 0)
11216 {
11217 error (_("%s: failed to seek to next file name\n"), arch->file_name);
11218 return NULL;
11219 }
11220 got = fread (&arch->arhdr, 1, sizeof arch->arhdr, arch->file);
11221 if (got != sizeof arch->arhdr)
11222 {
11223 error (_("%s: failed to read archive header\n"), arch->file_name);
11224 return NULL;
11225 }
11226 if (memcmp (arch->arhdr.ar_fmag, ARFMAG, 2) != 0)
11227 {
11228 error (_("%s: did not find a valid archive header\n"), arch->file_name);
11229 return NULL;
11230 }
11231
11232 return get_archive_member_name (arch, nested_arch);
11233}
11234
11235/* Construct a string showing the name of the archive member, qualified
11236 with the name of the containing archive file. For thin archives, we
11237 use square brackets to denote the indirection. For nested archives,
11238 we show the qualified name of the external member inside the square
11239 brackets (e.g., "thin.a[normal.a(foo.o)]"). */
11240
11241static char *
11242make_qualified_name (struct archive_info * arch,
11243 struct archive_info * nested_arch,
11244 char * member_name)
11245{
11246 size_t len;
11247 char * name;
11248
11249 len = strlen (arch->file_name) + strlen (member_name) + 3;
11250 if (arch->is_thin_archive && arch->nested_member_origin != 0)
11251 len += strlen (nested_arch->file_name) + 2;
11252
3f5e193b 11253 name = (char *) malloc (len);
2cf0635d
NC
11254 if (name == NULL)
11255 {
11256 error (_("Out of memory\n"));
11257 return NULL;
11258 }
11259
11260 if (arch->is_thin_archive && arch->nested_member_origin != 0)
11261 snprintf (name, len, "%s[%s(%s)]", arch->file_name, nested_arch->file_name, member_name);
11262 else if (arch->is_thin_archive)
11263 snprintf (name, len, "%s[%s]", arch->file_name, member_name);
11264 else
11265 snprintf (name, len, "%s(%s)", arch->file_name, member_name);
11266
11267 return name;
11268}
11269
11270/* Process an ELF archive.
11271 On entry the file is positioned just after the ARMAG string. */
11272
11273static int
11274process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
11275{
11276 struct archive_info arch;
11277 struct archive_info nested_arch;
11278 size_t got;
11279 size_t file_name_size;
11280 int ret;
11281
11282 show_name = 1;
11283
11284 /* The ARCH structure is used to hold information about this archive. */
11285 arch.file_name = NULL;
11286 arch.file = NULL;
11287 arch.index_array = NULL;
11288 arch.sym_table = NULL;
11289 arch.longnames = NULL;
11290
11291 /* The NESTED_ARCH structure is used as a single-item cache of information
11292 about a nested archive (when members of a thin archive reside within
11293 another regular archive file). */
11294 nested_arch.file_name = NULL;
11295 nested_arch.file = NULL;
11296 nested_arch.index_array = NULL;
11297 nested_arch.sym_table = NULL;
11298 nested_arch.longnames = NULL;
11299
11300 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
11301 {
11302 ret = 1;
11303 goto out;
4145f1d5 11304 }
fb52b2f4 11305
4145f1d5
NC
11306 if (do_archive_index)
11307 {
2cf0635d 11308 if (arch.sym_table == NULL)
4145f1d5
NC
11309 error (_("%s: unable to dump the index as none was found\n"), file_name);
11310 else
11311 {
2cf0635d 11312 unsigned int i, l;
4145f1d5
NC
11313 unsigned long current_pos;
11314
11315 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 11316 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
11317 current_pos = ftell (file);
11318
2cf0635d 11319 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 11320 {
2cf0635d
NC
11321 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
11322 {
11323 char * member_name;
4145f1d5 11324
2cf0635d
NC
11325 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
11326
11327 if (member_name != NULL)
11328 {
11329 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
11330
11331 if (qualified_name != NULL)
11332 {
11333 printf (_("Binary %s contains:\n"), qualified_name);
11334 free (qualified_name);
11335 }
4145f1d5
NC
11336 }
11337 }
2cf0635d
NC
11338
11339 if (l >= arch.sym_size)
4145f1d5
NC
11340 {
11341 error (_("%s: end of the symbol table reached before the end of the index\n"),
11342 file_name);
cb8f3167 11343 break;
4145f1d5 11344 }
2cf0635d
NC
11345 printf ("\t%s\n", arch.sym_table + l);
11346 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
11347 }
11348
2cf0635d
NC
11349 if (l & 01)
11350 ++l;
11351 if (l < arch.sym_size)
4145f1d5
NC
11352 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
11353 file_name);
11354
4145f1d5
NC
11355 if (fseek (file, current_pos, SEEK_SET) != 0)
11356 {
11357 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
11358 ret = 1;
11359 goto out;
4145f1d5 11360 }
fb52b2f4 11361 }
4145f1d5
NC
11362
11363 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
11364 && !do_segments && !do_header && !do_dump && !do_version
11365 && !do_histogram && !do_debugging && !do_arch && !do_notes
11366 && !do_section_groups)
2cf0635d
NC
11367 {
11368 ret = 0; /* Archive index only. */
11369 goto out;
11370 }
fb52b2f4
NC
11371 }
11372
11373 file_name_size = strlen (file_name);
d989285c 11374 ret = 0;
fb52b2f4
NC
11375
11376 while (1)
11377 {
2cf0635d
NC
11378 char * name;
11379 size_t namelen;
11380 char * qualified_name;
11381
11382 /* Read the next archive header. */
11383 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
11384 {
11385 error (_("%s: failed to seek to next archive header\n"), file_name);
11386 return 1;
11387 }
11388 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
11389 if (got != sizeof arch.arhdr)
11390 {
11391 if (got == 0)
11392 break;
11393 error (_("%s: failed to read archive header\n"), file_name);
11394 ret = 1;
11395 break;
11396 }
11397 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
11398 {
11399 error (_("%s: did not find a valid archive header\n"), arch.file_name);
11400 ret = 1;
11401 break;
11402 }
11403
11404 arch.next_arhdr_offset += sizeof arch.arhdr;
11405
11406 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
11407 if (archive_file_size & 01)
11408 ++archive_file_size;
11409
11410 name = get_archive_member_name (&arch, &nested_arch);
11411 if (name == NULL)
fb52b2f4 11412 {
0fd3a477 11413 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
11414 ret = 1;
11415 break;
fb52b2f4 11416 }
2cf0635d 11417 namelen = strlen (name);
fb52b2f4 11418
2cf0635d
NC
11419 qualified_name = make_qualified_name (&arch, &nested_arch, name);
11420 if (qualified_name == NULL)
fb52b2f4 11421 {
2cf0635d 11422 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
11423 ret = 1;
11424 break;
fb52b2f4
NC
11425 }
11426
2cf0635d
NC
11427 if (is_thin_archive && arch.nested_member_origin == 0)
11428 {
11429 /* This is a proxy for an external member of a thin archive. */
11430 FILE * member_file;
11431 char * member_file_name = adjust_relative_path (file_name, name, namelen);
11432 if (member_file_name == NULL)
11433 {
11434 ret = 1;
11435 break;
11436 }
11437
11438 member_file = fopen (member_file_name, "rb");
11439 if (member_file == NULL)
11440 {
11441 error (_("Input file '%s' is not readable.\n"), member_file_name);
11442 free (member_file_name);
11443 ret = 1;
11444 break;
11445 }
11446
11447 archive_file_offset = arch.nested_member_origin;
11448
11449 ret |= process_object (qualified_name, member_file);
11450
11451 fclose (member_file);
11452 free (member_file_name);
11453 }
11454 else if (is_thin_archive)
11455 {
11456 /* This is a proxy for a member of a nested archive. */
11457 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
11458
11459 /* The nested archive file will have been opened and setup by
11460 get_archive_member_name. */
11461 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
11462 {
11463 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
11464 ret = 1;
11465 break;
11466 }
11467
11468 ret |= process_object (qualified_name, nested_arch.file);
11469 }
11470 else
11471 {
11472 archive_file_offset = arch.next_arhdr_offset;
11473 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 11474
2cf0635d
NC
11475 ret |= process_object (qualified_name, file);
11476 }
fb52b2f4 11477
2cf0635d 11478 free (qualified_name);
fb52b2f4
NC
11479 }
11480
4145f1d5 11481 out:
2cf0635d
NC
11482 if (nested_arch.file != NULL)
11483 fclose (nested_arch.file);
11484 release_archive (&nested_arch);
11485 release_archive (&arch);
fb52b2f4 11486
d989285c 11487 return ret;
fb52b2f4
NC
11488}
11489
11490static int
2cf0635d 11491process_file (char * file_name)
fb52b2f4 11492{
2cf0635d 11493 FILE * file;
fb52b2f4
NC
11494 struct stat statbuf;
11495 char armag[SARMAG];
11496 int ret;
11497
11498 if (stat (file_name, &statbuf) < 0)
11499 {
f24ddbdd
NC
11500 if (errno == ENOENT)
11501 error (_("'%s': No such file\n"), file_name);
11502 else
11503 error (_("Could not locate '%s'. System error message: %s\n"),
11504 file_name, strerror (errno));
11505 return 1;
11506 }
11507
11508 if (! S_ISREG (statbuf.st_mode))
11509 {
11510 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
11511 return 1;
11512 }
11513
11514 file = fopen (file_name, "rb");
11515 if (file == NULL)
11516 {
f24ddbdd 11517 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
11518 return 1;
11519 }
11520
11521 if (fread (armag, SARMAG, 1, file) != 1)
11522 {
4145f1d5 11523 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
11524 fclose (file);
11525 return 1;
11526 }
11527
11528 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
11529 ret = process_archive (file_name, file, FALSE);
11530 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
11531 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
11532 else
11533 {
4145f1d5
NC
11534 if (do_archive_index)
11535 error (_("File %s is not an archive so its index cannot be displayed.\n"),
11536 file_name);
11537
fb52b2f4
NC
11538 rewind (file);
11539 archive_file_size = archive_file_offset = 0;
11540 ret = process_object (file_name, file);
11541 }
11542
11543 fclose (file);
11544
11545 return ret;
11546}
11547
252b5132
RH
11548#ifdef SUPPORT_DISASSEMBLY
11549/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 11550 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 11551 symbols. */
252b5132
RH
11552
11553void
2cf0635d 11554print_address (unsigned int addr, FILE * outfile)
252b5132
RH
11555{
11556 fprintf (outfile,"0x%8.8x", addr);
11557}
11558
e3c8793a 11559/* Needed by the i386 disassembler. */
252b5132
RH
11560void
11561db_task_printsym (unsigned int addr)
11562{
11563 print_address (addr, stderr);
11564}
11565#endif
11566
11567int
2cf0635d 11568main (int argc, char ** argv)
252b5132 11569{
ff78d6d6
L
11570 int err;
11571
252b5132
RH
11572#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
11573 setlocale (LC_MESSAGES, "");
3882b010
L
11574#endif
11575#if defined (HAVE_SETLOCALE)
11576 setlocale (LC_CTYPE, "");
252b5132
RH
11577#endif
11578 bindtextdomain (PACKAGE, LOCALEDIR);
11579 textdomain (PACKAGE);
11580
869b9d07
MM
11581 expandargv (&argc, &argv);
11582
252b5132
RH
11583 parse_args (argc, argv);
11584
18bd398b 11585 if (num_dump_sects > 0)
59f14fc0 11586 {
18bd398b 11587 /* Make a copy of the dump_sects array. */
3f5e193b
NC
11588 cmdline_dump_sects = (dump_type *)
11589 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 11590 if (cmdline_dump_sects == NULL)
591a748a 11591 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
11592 else
11593 {
09c11c86
NC
11594 memcpy (cmdline_dump_sects, dump_sects,
11595 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
11596 num_cmdline_dump_sects = num_dump_sects;
11597 }
11598 }
11599
18bd398b
NC
11600 if (optind < (argc - 1))
11601 show_name = 1;
11602
ff78d6d6 11603 err = 0;
252b5132 11604 while (optind < argc)
18bd398b 11605 err |= process_file (argv[optind++]);
252b5132
RH
11606
11607 if (dump_sects != NULL)
11608 free (dump_sects);
59f14fc0
AS
11609 if (cmdline_dump_sects != NULL)
11610 free (cmdline_dump_sects);
252b5132 11611
ff78d6d6 11612 return err;
252b5132 11613}