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