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