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