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