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