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