]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
PR gdb/12703
[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,
7a88bc9c 3 2008, 2009, 2010, 2011
a0f19280 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"
3284fe0c 64#include "elfcomm.h"
19e6b90e 65#include "dwarf.h"
252b5132
RH
66
67#include "elf/common.h"
68#include "elf/external.h"
69#include "elf/internal.h"
252b5132 70
4b78141a
NC
71
72/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
73 we can obtain the H8 reloc numbers. We need these for the
74 get_reloc_size() function. We include h8.h again after defining
75 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
76
77#include "elf/h8.h"
78#undef _ELF_H8_H
79
80/* Undo the effects of #including reloc-macros.h. */
81
82#undef START_RELOC_NUMBERS
83#undef RELOC_NUMBER
84#undef FAKE_RELOC
85#undef EMPTY_RELOC
86#undef END_RELOC_NUMBERS
87#undef _RELOC_MACROS_H
88
252b5132
RH
89/* The following headers use the elf/reloc-macros.h file to
90 automatically generate relocation recognition functions
91 such as elf_mips_reloc_type() */
92
93#define RELOC_MACROS_GEN_FUNC
94
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
252b5132 106#include "elf/fr30.h"
5c70f934 107#include "elf/frv.h"
3b16e843
NC
108#include "elf/h8.h"
109#include "elf/hppa.h"
110#include "elf/i386.h"
35b1837e 111#include "elf/i370.h"
3b16e843
NC
112#include "elf/i860.h"
113#include "elf/i960.h"
114#include "elf/ia64.h"
1e4cf259 115#include "elf/ip2k.h"
84e94c90 116#include "elf/lm32.h"
1c0d3aa6 117#include "elf/iq2000.h"
49f58d10 118#include "elf/m32c.h"
3b16e843
NC
119#include "elf/m32r.h"
120#include "elf/m68k.h"
75751cd9 121#include "elf/m68hc11.h"
252b5132 122#include "elf/mcore.h"
15ab5209 123#include "elf/mep.h"
7ba29e2a 124#include "elf/microblaze.h"
3b16e843 125#include "elf/mips.h"
3c3bdf30 126#include "elf/mmix.h"
3b16e843
NC
127#include "elf/mn10200.h"
128#include "elf/mn10300.h"
5506d11a 129#include "elf/moxie.h"
4970f871 130#include "elf/mt.h"
2469cfa2 131#include "elf/msp430.h"
3b16e843 132#include "elf/or32.h"
7d466069 133#include "elf/pj.h"
3b16e843 134#include "elf/ppc.h"
c833c019 135#include "elf/ppc64.h"
c7927a3c 136#include "elf/rx.h"
a85d7ed0 137#include "elf/s390.h"
1c0d3aa6 138#include "elf/score.h"
3b16e843
NC
139#include "elf/sh.h"
140#include "elf/sparc.h"
e9f53129 141#include "elf/spu.h"
40b36596 142#include "elf/tic6x.h"
aa137e4d
NC
143#include "elf/tilegx.h"
144#include "elf/tilepro.h"
3b16e843 145#include "elf/v850.h"
179d3252 146#include "elf/vax.h"
3b16e843 147#include "elf/x86-64.h"
c29aca4a 148#include "elf/xc16x.h"
93fbbb04 149#include "elf/xstormy16.h"
88da6820 150#include "elf/xtensa.h"
252b5132 151
252b5132 152#include "getopt.h"
566b0d53 153#include "libiberty.h"
09c11c86 154#include "safe-ctype.h"
2cf0635d 155#include "filenames.h"
252b5132 156
2cf0635d 157char * program_name = "readelf";
85b1c36d
BE
158static long archive_file_offset;
159static unsigned long archive_file_size;
160static unsigned long dynamic_addr;
161static bfd_size_type dynamic_size;
162static unsigned int dynamic_nent;
2cf0635d 163static char * dynamic_strings;
85b1c36d 164static unsigned long dynamic_strings_length;
2cf0635d 165static char * string_table;
85b1c36d
BE
166static unsigned long string_table_length;
167static unsigned long num_dynamic_syms;
2cf0635d
NC
168static Elf_Internal_Sym * dynamic_symbols;
169static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
170static unsigned long dynamic_syminfo_offset;
171static unsigned int dynamic_syminfo_nent;
f8eae8b2 172static char program_interpreter[PATH_MAX];
bb8a0291 173static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 174static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
175static bfd_vma version_info[16];
176static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
177static Elf_Internal_Shdr * section_headers;
178static Elf_Internal_Phdr * program_headers;
179static Elf_Internal_Dyn * dynamic_section;
180static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
181static int show_name;
182static int do_dynamic;
183static int do_syms;
2c610e4b 184static int do_dyn_syms;
85b1c36d
BE
185static int do_reloc;
186static int do_sections;
187static int do_section_groups;
5477e8a0 188static int do_section_details;
85b1c36d
BE
189static int do_segments;
190static int do_unwind;
191static int do_using_dynamic;
192static int do_header;
193static int do_dump;
194static int do_version;
85b1c36d
BE
195static int do_histogram;
196static int do_debugging;
85b1c36d
BE
197static int do_arch;
198static int do_notes;
4145f1d5 199static int do_archive_index;
85b1c36d 200static int is_32bit_elf;
252b5132 201
e4b17d5c
L
202struct group_list
203{
2cf0635d 204 struct group_list * next;
e4b17d5c
L
205 unsigned int section_index;
206};
207
208struct group
209{
2cf0635d 210 struct group_list * root;
e4b17d5c
L
211 unsigned int group_index;
212};
213
85b1c36d 214static size_t group_count;
2cf0635d
NC
215static struct group * section_groups;
216static struct group ** section_headers_groups;
e4b17d5c 217
09c11c86
NC
218
219/* Flag bits indicating particular types of dump. */
220#define HEX_DUMP (1 << 0) /* The -x command line switch. */
221#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
222#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
223#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 224#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
225
226typedef unsigned char dump_type;
227
228/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
229struct dump_list_entry
230{
2cf0635d 231 char * name;
09c11c86 232 dump_type type;
2cf0635d 233 struct dump_list_entry * next;
aef1f6d0 234};
2cf0635d 235static struct dump_list_entry * dump_sects_byname;
aef1f6d0 236
09c11c86
NC
237/* A dynamic array of flags indicating for which sections a dump
238 has been requested via command line switches. */
239static dump_type * cmdline_dump_sects = NULL;
240static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
241
242/* A dynamic array of flags indicating for which sections a dump of
243 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
244 basis and then initialised from the cmdline_dump_sects array,
245 the results of interpreting the -w switch, and the
246 dump_sects_byname list. */
09c11c86
NC
247static dump_type * dump_sects = NULL;
248static unsigned int num_dump_sects = 0;
252b5132 249
252b5132 250
c256ffe7 251/* How to print a vma value. */
843dd992
NC
252typedef enum print_mode
253{
254 HEX,
255 DEC,
256 DEC_5,
257 UNSIGNED,
258 PREFIX_HEX,
259 FULL_HEX,
260 LONG_HEX
261}
262print_mode;
263
9c19a809
NC
264#define UNKNOWN -1
265
2b692964
NC
266#define SECTION_NAME(X) \
267 ((X) == NULL ? _("<none>") \
268 : string_table == NULL ? _("<no-name>") \
269 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 270 : string_table + (X)->sh_name))
252b5132 271
ee42cf8c 272#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 273
9ad5cbcf
AM
274#define GET_ELF_SYMBOLS(file, section) \
275 (is_32bit_elf ? get_32bit_elf_symbols (file, section) \
276 : get_64bit_elf_symbols (file, section))
9ea033b2 277
d79b3d50
NC
278#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
279/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
280 already been called and verified that the string exists. */
281#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 282
61865e30
NC
283#define REMOVE_ARCH_BITS(ADDR) \
284 do \
285 { \
286 if (elf_header.e_machine == EM_ARM) \
287 (ADDR) &= ~1; \
288 } \
289 while (0)
d79b3d50 290\f
59245841
NC
291/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET.
292 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
293 using malloc and fill that. In either case return the pointer to the start of
294 the retrieved data or NULL if something went wrong. If something does go wrong
295 emit an error message using REASON as part of the context. */
296
c256ffe7 297static void *
2cf0635d
NC
298get_data (void * var, FILE * file, long offset, size_t size, size_t nmemb,
299 const char * reason)
a6e9f9df 300{
2cf0635d 301 void * mvar;
a6e9f9df 302
c256ffe7 303 if (size == 0 || nmemb == 0)
a6e9f9df
AM
304 return NULL;
305
fb52b2f4 306 if (fseek (file, archive_file_offset + offset, SEEK_SET))
a6e9f9df 307 {
0fd3a477 308 error (_("Unable to seek to 0x%lx for %s\n"),
0af1713e 309 (unsigned long) archive_file_offset + offset, reason);
a6e9f9df
AM
310 return NULL;
311 }
312
313 mvar = var;
314 if (mvar == NULL)
315 {
c256ffe7
JJ
316 /* Check for overflow. */
317 if (nmemb < (~(size_t) 0 - 1) / size)
318 /* + 1 so that we can '\0' terminate invalid string table sections. */
319 mvar = malloc (size * nmemb + 1);
a6e9f9df
AM
320
321 if (mvar == NULL)
322 {
0fd3a477
JW
323 error (_("Out of memory allocating 0x%lx bytes for %s\n"),
324 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
325 return NULL;
326 }
c256ffe7
JJ
327
328 ((char *) mvar)[size * nmemb] = '\0';
a6e9f9df
AM
329 }
330
c256ffe7 331 if (fread (mvar, size, nmemb, file) != nmemb)
a6e9f9df 332 {
0fd3a477
JW
333 error (_("Unable to read in 0x%lx bytes of %s\n"),
334 (unsigned long)(size * nmemb), reason);
a6e9f9df
AM
335 if (mvar != var)
336 free (mvar);
337 return NULL;
338 }
339
340 return mvar;
341}
342
14a91970 343/* Print a VMA value. */
cb8f3167 344
66543521 345static int
14a91970 346print_vma (bfd_vma vma, print_mode mode)
66543521 347{
66543521
AM
348 int nc = 0;
349
14a91970 350 switch (mode)
66543521 351 {
14a91970
AM
352 case FULL_HEX:
353 nc = printf ("0x");
354 /* Drop through. */
66543521 355
14a91970 356 case LONG_HEX:
f7a99963 357#ifdef BFD64
14a91970 358 if (is_32bit_elf)
437c2fb7 359 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 360#endif
14a91970
AM
361 printf_vma (vma);
362 return nc + 16;
b19aac67 363
14a91970
AM
364 case DEC_5:
365 if (vma <= 99999)
366 return printf ("%5" BFD_VMA_FMT "d", vma);
367 /* Drop through. */
66543521 368
14a91970
AM
369 case PREFIX_HEX:
370 nc = printf ("0x");
371 /* Drop through. */
66543521 372
14a91970
AM
373 case HEX:
374 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 375
14a91970
AM
376 case DEC:
377 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 378
14a91970
AM
379 case UNSIGNED:
380 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 381 }
66543521 382 return 0;
f7a99963
NC
383}
384
171191ba 385/* Display a symbol on stdout. Handles the display of non-printing characters.
31104126 386
171191ba
NC
387 If DO_WIDE is not true then format the symbol to be at most WIDTH characters,
388 truncating as necessary. If WIDTH is negative then format the string to be
389 exactly - WIDTH characters, truncating or padding as necessary.
390
391 Returns the number of emitted characters. */
392
393static unsigned int
7a88bc9c 394print_symbol (int width, const char *symbol)
31104126 395{
7a88bc9c 396 const char *c;
171191ba
NC
397 bfd_boolean extra_padding = FALSE;
398 unsigned int num_printed = 0;
961c521f 399
31104126 400 if (do_wide)
961c521f 401 {
7a88bc9c
AS
402 /* Set the width to a very large value. This simplifies the
403 code below. */
961c521f
NC
404 width = INT_MAX;
405 }
31104126 406 else if (width < 0)
961c521f 407 {
961c521f
NC
408 /* Keep the width positive. This also helps. */
409 width = - width;
171191ba 410 extra_padding = TRUE;
961c521f
NC
411 }
412
413 while (width)
414 {
415 int len;
416
417 c = symbol;
418
419 /* Look for non-printing symbols inside the symbol's name.
420 This test is triggered in particular by the names generated
421 by the assembler for local labels. */
7a88bc9c 422 while (ISPRINT (*c))
961c521f
NC
423 c++;
424
425 len = c - symbol;
426
427 if (len)
428 {
429 if (len > width)
430 len = width;
cb8f3167 431
171191ba 432 printf ("%.*s", len, symbol);
961c521f
NC
433
434 width -= len;
171191ba 435 num_printed += len;
961c521f
NC
436 }
437
7a88bc9c 438 if (*c == 0 || width == 0)
961c521f
NC
439 break;
440
441 /* Now display the non-printing character, if
442 there is room left in which to dipslay it. */
7a88bc9c 443 if ((unsigned char) *c < 32)
961c521f
NC
444 {
445 if (width < 2)
446 break;
447
448 printf ("^%c", *c + 0x40);
449
450 width -= 2;
171191ba 451 num_printed += 2;
961c521f
NC
452 }
453 else
454 {
455 if (width < 6)
456 break;
cb8f3167 457
7a88bc9c 458 printf ("<0x%.2x>", (unsigned char) *c);
961c521f
NC
459
460 width -= 6;
171191ba 461 num_printed += 6;
961c521f
NC
462 }
463
464 symbol = c + 1;
465 }
171191ba
NC
466
467 if (extra_padding && width > 0)
468 {
469 /* Fill in the remaining spaces. */
470 printf ("%-*s", width, " ");
471 num_printed += 2;
472 }
473
474 return num_printed;
31104126
NC
475}
476
89fac5e3
RS
477/* Return a pointer to section NAME, or NULL if no such section exists. */
478
479static Elf_Internal_Shdr *
2cf0635d 480find_section (const char * name)
89fac5e3
RS
481{
482 unsigned int i;
483
484 for (i = 0; i < elf_header.e_shnum; i++)
485 if (streq (SECTION_NAME (section_headers + i), name))
486 return section_headers + i;
487
488 return NULL;
489}
490
0b6ae522
DJ
491/* Return a pointer to a section containing ADDR, or NULL if no such
492 section exists. */
493
494static Elf_Internal_Shdr *
495find_section_by_address (bfd_vma addr)
496{
497 unsigned int i;
498
499 for (i = 0; i < elf_header.e_shnum; i++)
500 {
501 Elf_Internal_Shdr *sec = section_headers + i;
502 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
503 return sec;
504 }
505
506 return NULL;
507}
508
509/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
510 bytes read. */
511
512static unsigned long
513read_uleb128 (unsigned char *data, unsigned int *length_return)
514{
515 return read_leb128 (data, length_return, 0);
516}
517
28f997cf
TG
518/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
519 This OS has so many departures from the ELF standard that we test it at
520 many places. */
521
522static inline int
523is_ia64_vms (void)
524{
525 return elf_header.e_machine == EM_IA_64
526 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
527}
528
bcedfee6 529/* Guess the relocation size commonly used by the specific machines. */
252b5132 530
252b5132 531static int
2dc4cec1 532guess_is_rela (unsigned int e_machine)
252b5132 533{
9c19a809 534 switch (e_machine)
252b5132
RH
535 {
536 /* Targets that use REL relocations. */
252b5132
RH
537 case EM_386:
538 case EM_486:
63fcb9e9 539 case EM_960:
e9f53129 540 case EM_ARM:
2b0337b0 541 case EM_D10V:
252b5132 542 case EM_CYGNUS_D10V:
e9f53129 543 case EM_DLX:
252b5132 544 case EM_MIPS:
4fe85591 545 case EM_MIPS_RS3_LE:
e9f53129
AM
546 case EM_CYGNUS_M32R:
547 case EM_OPENRISC:
548 case EM_OR32:
1c0d3aa6 549 case EM_SCORE:
9c19a809 550 return FALSE;
103f02d3 551
252b5132
RH
552 /* Targets that use RELA relocations. */
553 case EM_68K:
e9f53129
AM
554 case EM_860:
555 case EM_ALPHA:
556 case EM_ALTERA_NIOS2:
557 case EM_AVR:
558 case EM_AVR_OLD:
559 case EM_BLACKFIN:
60bca95a 560 case EM_CR16:
6c03b1ed 561 case EM_CR16_OLD:
e9f53129
AM
562 case EM_CRIS:
563 case EM_CRX:
2b0337b0 564 case EM_D30V:
252b5132 565 case EM_CYGNUS_D30V:
2b0337b0 566 case EM_FR30:
252b5132 567 case EM_CYGNUS_FR30:
5c70f934 568 case EM_CYGNUS_FRV:
e9f53129
AM
569 case EM_H8S:
570 case EM_H8_300:
571 case EM_H8_300H:
800eeca4 572 case EM_IA_64:
1e4cf259
NC
573 case EM_IP2K:
574 case EM_IP2K_OLD:
3b36097d 575 case EM_IQ2000:
84e94c90 576 case EM_LATTICEMICO32:
ff7eeb89 577 case EM_M32C_OLD:
49f58d10 578 case EM_M32C:
e9f53129
AM
579 case EM_M32R:
580 case EM_MCORE:
15ab5209 581 case EM_CYGNUS_MEP:
e9f53129
AM
582 case EM_MMIX:
583 case EM_MN10200:
584 case EM_CYGNUS_MN10200:
585 case EM_MN10300:
586 case EM_CYGNUS_MN10300:
5506d11a 587 case EM_MOXIE:
e9f53129
AM
588 case EM_MSP430:
589 case EM_MSP430_OLD:
d031aafb 590 case EM_MT:
64fd6348 591 case EM_NIOS32:
e9f53129
AM
592 case EM_PPC64:
593 case EM_PPC:
c7927a3c 594 case EM_RX:
e9f53129
AM
595 case EM_S390:
596 case EM_S390_OLD:
597 case EM_SH:
598 case EM_SPARC:
599 case EM_SPARC32PLUS:
600 case EM_SPARCV9:
601 case EM_SPU:
40b36596 602 case EM_TI_C6000:
aa137e4d
NC
603 case EM_TILEGX:
604 case EM_TILEPRO:
e9f53129
AM
605 case EM_V850:
606 case EM_CYGNUS_V850:
607 case EM_VAX:
608 case EM_X86_64:
8a9036a4 609 case EM_L1OM:
7a9068fe 610 case EM_K1OM:
e9f53129
AM
611 case EM_XSTORMY16:
612 case EM_XTENSA:
613 case EM_XTENSA_OLD:
7ba29e2a
NC
614 case EM_MICROBLAZE:
615 case EM_MICROBLAZE_OLD:
9c19a809 616 return TRUE;
103f02d3 617
e9f53129
AM
618 case EM_68HC05:
619 case EM_68HC08:
620 case EM_68HC11:
621 case EM_68HC16:
622 case EM_FX66:
623 case EM_ME16:
d1133906 624 case EM_MMA:
d1133906
NC
625 case EM_NCPU:
626 case EM_NDR1:
e9f53129 627 case EM_PCP:
d1133906 628 case EM_ST100:
e9f53129 629 case EM_ST19:
d1133906 630 case EM_ST7:
e9f53129
AM
631 case EM_ST9PLUS:
632 case EM_STARCORE:
d1133906 633 case EM_SVX:
e9f53129 634 case EM_TINYJ:
9c19a809
NC
635 default:
636 warn (_("Don't know about relocations on this machine architecture\n"));
637 return FALSE;
638 }
639}
252b5132 640
9c19a809 641static int
2cf0635d 642slurp_rela_relocs (FILE * file,
d3ba0551
AM
643 unsigned long rel_offset,
644 unsigned long rel_size,
2cf0635d
NC
645 Elf_Internal_Rela ** relasp,
646 unsigned long * nrelasp)
9c19a809 647{
2cf0635d 648 Elf_Internal_Rela * relas;
4d6ed7c8
NC
649 unsigned long nrelas;
650 unsigned int i;
252b5132 651
4d6ed7c8
NC
652 if (is_32bit_elf)
653 {
2cf0635d 654 Elf32_External_Rela * erelas;
103f02d3 655
3f5e193b
NC
656 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
657 rel_size, _("relocs"));
a6e9f9df
AM
658 if (!erelas)
659 return 0;
252b5132 660
4d6ed7c8 661 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 662
3f5e193b
NC
663 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
664 sizeof (Elf_Internal_Rela));
103f02d3 665
4d6ed7c8
NC
666 if (relas == NULL)
667 {
c256ffe7 668 free (erelas);
591a748a 669 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
670 return 0;
671 }
103f02d3 672
4d6ed7c8
NC
673 for (i = 0; i < nrelas; i++)
674 {
675 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
676 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 677 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 678 }
103f02d3 679
4d6ed7c8
NC
680 free (erelas);
681 }
682 else
683 {
2cf0635d 684 Elf64_External_Rela * erelas;
103f02d3 685
3f5e193b
NC
686 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
687 rel_size, _("relocs"));
a6e9f9df
AM
688 if (!erelas)
689 return 0;
4d6ed7c8
NC
690
691 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 692
3f5e193b
NC
693 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
694 sizeof (Elf_Internal_Rela));
103f02d3 695
4d6ed7c8
NC
696 if (relas == NULL)
697 {
c256ffe7 698 free (erelas);
591a748a 699 error (_("out of memory parsing relocs\n"));
4d6ed7c8 700 return 0;
9c19a809 701 }
4d6ed7c8
NC
702
703 for (i = 0; i < nrelas; i++)
9c19a809 704 {
66543521
AM
705 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
706 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 707 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
708
709 /* The #ifdef BFD64 below is to prevent a compile time
710 warning. We know that if we do not have a 64 bit data
711 type that we will never execute this code anyway. */
712#ifdef BFD64
713 if (elf_header.e_machine == EM_MIPS
714 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
715 {
716 /* In little-endian objects, r_info isn't really a
717 64-bit little-endian value: it has a 32-bit
718 little-endian symbol index followed by four
719 individual byte fields. Reorder INFO
720 accordingly. */
91d6fa6a
NC
721 bfd_vma inf = relas[i].r_info;
722 inf = (((inf & 0xffffffff) << 32)
723 | ((inf >> 56) & 0xff)
724 | ((inf >> 40) & 0xff00)
725 | ((inf >> 24) & 0xff0000)
726 | ((inf >> 8) & 0xff000000));
727 relas[i].r_info = inf;
861fb55a
DJ
728 }
729#endif /* BFD64 */
4d6ed7c8 730 }
103f02d3 731
4d6ed7c8
NC
732 free (erelas);
733 }
734 *relasp = relas;
735 *nrelasp = nrelas;
736 return 1;
737}
103f02d3 738
4d6ed7c8 739static int
2cf0635d 740slurp_rel_relocs (FILE * file,
d3ba0551
AM
741 unsigned long rel_offset,
742 unsigned long rel_size,
2cf0635d
NC
743 Elf_Internal_Rela ** relsp,
744 unsigned long * nrelsp)
4d6ed7c8 745{
2cf0635d 746 Elf_Internal_Rela * rels;
4d6ed7c8
NC
747 unsigned long nrels;
748 unsigned int i;
103f02d3 749
4d6ed7c8
NC
750 if (is_32bit_elf)
751 {
2cf0635d 752 Elf32_External_Rel * erels;
103f02d3 753
3f5e193b
NC
754 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
755 rel_size, _("relocs"));
a6e9f9df
AM
756 if (!erels)
757 return 0;
103f02d3 758
4d6ed7c8 759 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 760
3f5e193b 761 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 762
4d6ed7c8
NC
763 if (rels == NULL)
764 {
c256ffe7 765 free (erels);
591a748a 766 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
767 return 0;
768 }
769
770 for (i = 0; i < nrels; i++)
771 {
772 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
773 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 774 rels[i].r_addend = 0;
9ea033b2 775 }
4d6ed7c8
NC
776
777 free (erels);
9c19a809
NC
778 }
779 else
780 {
2cf0635d 781 Elf64_External_Rel * erels;
9ea033b2 782
3f5e193b
NC
783 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
784 rel_size, _("relocs"));
a6e9f9df
AM
785 if (!erels)
786 return 0;
103f02d3 787
4d6ed7c8 788 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 789
3f5e193b 790 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 791
4d6ed7c8 792 if (rels == NULL)
9c19a809 793 {
c256ffe7 794 free (erels);
591a748a 795 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
796 return 0;
797 }
103f02d3 798
4d6ed7c8
NC
799 for (i = 0; i < nrels; i++)
800 {
66543521
AM
801 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
802 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 803 rels[i].r_addend = 0;
861fb55a
DJ
804
805 /* The #ifdef BFD64 below is to prevent a compile time
806 warning. We know that if we do not have a 64 bit data
807 type that we will never execute this code anyway. */
808#ifdef BFD64
809 if (elf_header.e_machine == EM_MIPS
810 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
811 {
812 /* In little-endian objects, r_info isn't really a
813 64-bit little-endian value: it has a 32-bit
814 little-endian symbol index followed by four
815 individual byte fields. Reorder INFO
816 accordingly. */
91d6fa6a
NC
817 bfd_vma inf = rels[i].r_info;
818 inf = (((inf & 0xffffffff) << 32)
819 | ((inf >> 56) & 0xff)
820 | ((inf >> 40) & 0xff00)
821 | ((inf >> 24) & 0xff0000)
822 | ((inf >> 8) & 0xff000000));
823 rels[i].r_info = inf;
861fb55a
DJ
824 }
825#endif /* BFD64 */
4d6ed7c8 826 }
103f02d3 827
4d6ed7c8
NC
828 free (erels);
829 }
830 *relsp = rels;
831 *nrelsp = nrels;
832 return 1;
833}
103f02d3 834
aca88567
NC
835/* Returns the reloc type extracted from the reloc info field. */
836
837static unsigned int
838get_reloc_type (bfd_vma reloc_info)
839{
840 if (is_32bit_elf)
841 return ELF32_R_TYPE (reloc_info);
842
843 switch (elf_header.e_machine)
844 {
845 case EM_MIPS:
846 /* Note: We assume that reloc_info has already been adjusted for us. */
847 return ELF64_MIPS_R_TYPE (reloc_info);
848
849 case EM_SPARCV9:
850 return ELF64_R_TYPE_ID (reloc_info);
851
852 default:
853 return ELF64_R_TYPE (reloc_info);
854 }
855}
856
857/* Return the symbol index extracted from the reloc info field. */
858
859static bfd_vma
860get_reloc_symindex (bfd_vma reloc_info)
861{
862 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
863}
864
d3ba0551
AM
865/* Display the contents of the relocation data found at the specified
866 offset. */
ee42cf8c 867
41e92641 868static void
2cf0635d 869dump_relocations (FILE * file,
d3ba0551
AM
870 unsigned long rel_offset,
871 unsigned long rel_size,
2cf0635d 872 Elf_Internal_Sym * symtab,
d3ba0551 873 unsigned long nsyms,
2cf0635d 874 char * strtab,
d79b3d50 875 unsigned long strtablen,
d3ba0551 876 int is_rela)
4d6ed7c8 877{
b34976b6 878 unsigned int i;
2cf0635d 879 Elf_Internal_Rela * rels;
103f02d3 880
4d6ed7c8
NC
881 if (is_rela == UNKNOWN)
882 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 883
4d6ed7c8
NC
884 if (is_rela)
885 {
c8286bd1 886 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 887 return;
4d6ed7c8
NC
888 }
889 else
890 {
891 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 892 return;
252b5132
RH
893 }
894
410f7a12
L
895 if (is_32bit_elf)
896 {
897 if (is_rela)
2c71103e
NC
898 {
899 if (do_wide)
900 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
901 else
902 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
903 }
410f7a12 904 else
2c71103e
NC
905 {
906 if (do_wide)
907 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
908 else
909 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
910 }
410f7a12 911 }
252b5132 912 else
410f7a12
L
913 {
914 if (is_rela)
2c71103e
NC
915 {
916 if (do_wide)
8beeaeb7 917 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
918 else
919 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
920 }
410f7a12 921 else
2c71103e
NC
922 {
923 if (do_wide)
8beeaeb7 924 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
925 else
926 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
927 }
410f7a12 928 }
252b5132
RH
929
930 for (i = 0; i < rel_size; i++)
931 {
2cf0635d 932 const char * rtype;
b34976b6 933 bfd_vma offset;
91d6fa6a 934 bfd_vma inf;
b34976b6
AM
935 bfd_vma symtab_index;
936 bfd_vma type;
103f02d3 937
b34976b6 938 offset = rels[i].r_offset;
91d6fa6a 939 inf = rels[i].r_info;
103f02d3 940
91d6fa6a
NC
941 type = get_reloc_type (inf);
942 symtab_index = get_reloc_symindex (inf);
252b5132 943
410f7a12
L
944 if (is_32bit_elf)
945 {
39dbeff8
AM
946 printf ("%8.8lx %8.8lx ",
947 (unsigned long) offset & 0xffffffff,
91d6fa6a 948 (unsigned long) inf & 0xffffffff);
410f7a12
L
949 }
950 else
951 {
39dbeff8
AM
952#if BFD_HOST_64BIT_LONG
953 printf (do_wide
954 ? "%16.16lx %16.16lx "
955 : "%12.12lx %12.12lx ",
91d6fa6a 956 offset, inf);
39dbeff8 957#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 958#ifndef __MSVCRT__
39dbeff8
AM
959 printf (do_wide
960 ? "%16.16llx %16.16llx "
961 : "%12.12llx %12.12llx ",
91d6fa6a 962 offset, inf);
6e3d6dc1
NC
963#else
964 printf (do_wide
965 ? "%16.16I64x %16.16I64x "
966 : "%12.12I64x %12.12I64x ",
91d6fa6a 967 offset, inf);
6e3d6dc1 968#endif
39dbeff8 969#else
2c71103e
NC
970 printf (do_wide
971 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
972 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
973 _bfd_int64_high (offset),
974 _bfd_int64_low (offset),
91d6fa6a
NC
975 _bfd_int64_high (inf),
976 _bfd_int64_low (inf));
9ea033b2 977#endif
410f7a12 978 }
103f02d3 979
252b5132
RH
980 switch (elf_header.e_machine)
981 {
982 default:
983 rtype = NULL;
984 break;
985
2b0337b0 986 case EM_M32R:
252b5132 987 case EM_CYGNUS_M32R:
9ea033b2 988 rtype = elf_m32r_reloc_type (type);
252b5132
RH
989 break;
990
991 case EM_386:
992 case EM_486:
9ea033b2 993 rtype = elf_i386_reloc_type (type);
252b5132
RH
994 break;
995
ba2685cc
AM
996 case EM_68HC11:
997 case EM_68HC12:
998 rtype = elf_m68hc11_reloc_type (type);
999 break;
75751cd9 1000
252b5132 1001 case EM_68K:
9ea033b2 1002 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1003 break;
1004
63fcb9e9 1005 case EM_960:
9ea033b2 1006 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1007 break;
1008
adde6300 1009 case EM_AVR:
2b0337b0 1010 case EM_AVR_OLD:
adde6300
AM
1011 rtype = elf_avr_reloc_type (type);
1012 break;
1013
9ea033b2
NC
1014 case EM_OLD_SPARCV9:
1015 case EM_SPARC32PLUS:
1016 case EM_SPARCV9:
252b5132 1017 case EM_SPARC:
9ea033b2 1018 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1019 break;
1020
e9f53129
AM
1021 case EM_SPU:
1022 rtype = elf_spu_reloc_type (type);
1023 break;
1024
2b0337b0 1025 case EM_V850:
252b5132 1026 case EM_CYGNUS_V850:
9ea033b2 1027 rtype = v850_reloc_type (type);
252b5132
RH
1028 break;
1029
2b0337b0 1030 case EM_D10V:
252b5132 1031 case EM_CYGNUS_D10V:
9ea033b2 1032 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1033 break;
1034
2b0337b0 1035 case EM_D30V:
252b5132 1036 case EM_CYGNUS_D30V:
9ea033b2 1037 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1038 break;
1039
d172d4ba
NC
1040 case EM_DLX:
1041 rtype = elf_dlx_reloc_type (type);
1042 break;
1043
252b5132 1044 case EM_SH:
9ea033b2 1045 rtype = elf_sh_reloc_type (type);
252b5132
RH
1046 break;
1047
2b0337b0 1048 case EM_MN10300:
252b5132 1049 case EM_CYGNUS_MN10300:
9ea033b2 1050 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1051 break;
1052
2b0337b0 1053 case EM_MN10200:
252b5132 1054 case EM_CYGNUS_MN10200:
9ea033b2 1055 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1056 break;
1057
2b0337b0 1058 case EM_FR30:
252b5132 1059 case EM_CYGNUS_FR30:
9ea033b2 1060 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1061 break;
1062
ba2685cc
AM
1063 case EM_CYGNUS_FRV:
1064 rtype = elf_frv_reloc_type (type);
1065 break;
5c70f934 1066
252b5132 1067 case EM_MCORE:
9ea033b2 1068 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1069 break;
1070
3c3bdf30
NC
1071 case EM_MMIX:
1072 rtype = elf_mmix_reloc_type (type);
1073 break;
1074
5506d11a
AM
1075 case EM_MOXIE:
1076 rtype = elf_moxie_reloc_type (type);
1077 break;
1078
2469cfa2
NC
1079 case EM_MSP430:
1080 case EM_MSP430_OLD:
1081 rtype = elf_msp430_reloc_type (type);
1082 break;
1083
252b5132 1084 case EM_PPC:
9ea033b2 1085 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1086 break;
1087
c833c019
AM
1088 case EM_PPC64:
1089 rtype = elf_ppc64_reloc_type (type);
1090 break;
1091
252b5132 1092 case EM_MIPS:
4fe85591 1093 case EM_MIPS_RS3_LE:
9ea033b2 1094 rtype = elf_mips_reloc_type (type);
252b5132
RH
1095 break;
1096
1097 case EM_ALPHA:
9ea033b2 1098 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1099 break;
1100
1101 case EM_ARM:
9ea033b2 1102 rtype = elf_arm_reloc_type (type);
252b5132
RH
1103 break;
1104
584da044 1105 case EM_ARC:
9ea033b2 1106 rtype = elf_arc_reloc_type (type);
252b5132
RH
1107 break;
1108
1109 case EM_PARISC:
69e617ca 1110 rtype = elf_hppa_reloc_type (type);
252b5132 1111 break;
7d466069 1112
b8720f9d
JL
1113 case EM_H8_300:
1114 case EM_H8_300H:
1115 case EM_H8S:
1116 rtype = elf_h8_reloc_type (type);
1117 break;
1118
3b16e843
NC
1119 case EM_OPENRISC:
1120 case EM_OR32:
1121 rtype = elf_or32_reloc_type (type);
1122 break;
1123
7d466069 1124 case EM_PJ:
2b0337b0 1125 case EM_PJ_OLD:
7d466069
ILT
1126 rtype = elf_pj_reloc_type (type);
1127 break;
800eeca4
JW
1128 case EM_IA_64:
1129 rtype = elf_ia64_reloc_type (type);
1130 break;
1b61cf92
HPN
1131
1132 case EM_CRIS:
1133 rtype = elf_cris_reloc_type (type);
1134 break;
535c37ff
JE
1135
1136 case EM_860:
1137 rtype = elf_i860_reloc_type (type);
1138 break;
bcedfee6
NC
1139
1140 case EM_X86_64:
8a9036a4 1141 case EM_L1OM:
7a9068fe 1142 case EM_K1OM:
bcedfee6
NC
1143 rtype = elf_x86_64_reloc_type (type);
1144 break;
a85d7ed0 1145
35b1837e
AM
1146 case EM_S370:
1147 rtype = i370_reloc_type (type);
1148 break;
1149
53c7db4b
KH
1150 case EM_S390_OLD:
1151 case EM_S390:
1152 rtype = elf_s390_reloc_type (type);
1153 break;
93fbbb04 1154
1c0d3aa6
NC
1155 case EM_SCORE:
1156 rtype = elf_score_reloc_type (type);
1157 break;
1158
93fbbb04
GK
1159 case EM_XSTORMY16:
1160 rtype = elf_xstormy16_reloc_type (type);
1161 break;
179d3252 1162
1fe1f39c
NC
1163 case EM_CRX:
1164 rtype = elf_crx_reloc_type (type);
1165 break;
1166
179d3252
JT
1167 case EM_VAX:
1168 rtype = elf_vax_reloc_type (type);
1169 break;
1e4cf259
NC
1170
1171 case EM_IP2K:
1172 case EM_IP2K_OLD:
1173 rtype = elf_ip2k_reloc_type (type);
1174 break;
3b36097d
SC
1175
1176 case EM_IQ2000:
1177 rtype = elf_iq2000_reloc_type (type);
1178 break;
88da6820
NC
1179
1180 case EM_XTENSA_OLD:
1181 case EM_XTENSA:
1182 rtype = elf_xtensa_reloc_type (type);
1183 break;
a34e3ecb 1184
84e94c90
NC
1185 case EM_LATTICEMICO32:
1186 rtype = elf_lm32_reloc_type (type);
1187 break;
1188
ff7eeb89 1189 case EM_M32C_OLD:
49f58d10
JB
1190 case EM_M32C:
1191 rtype = elf_m32c_reloc_type (type);
1192 break;
1193
d031aafb
NS
1194 case EM_MT:
1195 rtype = elf_mt_reloc_type (type);
a34e3ecb 1196 break;
1d65ded4
CM
1197
1198 case EM_BLACKFIN:
1199 rtype = elf_bfin_reloc_type (type);
1200 break;
15ab5209
DB
1201
1202 case EM_CYGNUS_MEP:
1203 rtype = elf_mep_reloc_type (type);
1204 break;
60bca95a
NC
1205
1206 case EM_CR16:
6c03b1ed 1207 case EM_CR16_OLD:
60bca95a
NC
1208 rtype = elf_cr16_reloc_type (type);
1209 break;
dd24e3da 1210
7ba29e2a
NC
1211 case EM_MICROBLAZE:
1212 case EM_MICROBLAZE_OLD:
1213 rtype = elf_microblaze_reloc_type (type);
1214 break;
c7927a3c
NC
1215
1216 case EM_RX:
1217 rtype = elf_rx_reloc_type (type);
1218 break;
c29aca4a
NC
1219
1220 case EM_XC16X:
1221 case EM_C166:
1222 rtype = elf_xc16x_reloc_type (type);
1223 break;
40b36596
JM
1224
1225 case EM_TI_C6000:
1226 rtype = elf_tic6x_reloc_type (type);
1227 break;
aa137e4d
NC
1228
1229 case EM_TILEGX:
1230 rtype = elf_tilegx_reloc_type (type);
1231 break;
1232
1233 case EM_TILEPRO:
1234 rtype = elf_tilepro_reloc_type (type);
1235 break;
252b5132
RH
1236 }
1237
1238 if (rtype == NULL)
39dbeff8 1239 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1240 else
8beeaeb7 1241 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1242
7ace3541 1243 if (elf_header.e_machine == EM_ALPHA
157c2599 1244 && rtype != NULL
7ace3541
RH
1245 && streq (rtype, "R_ALPHA_LITUSE")
1246 && is_rela)
1247 {
1248 switch (rels[i].r_addend)
1249 {
1250 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1251 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1252 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1253 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1254 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1255 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1256 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1257 default: rtype = NULL;
1258 }
1259 if (rtype)
1260 printf (" (%s)", rtype);
1261 else
1262 {
1263 putchar (' ');
1264 printf (_("<unknown addend: %lx>"),
1265 (unsigned long) rels[i].r_addend);
1266 }
1267 }
1268 else if (symtab_index)
252b5132 1269 {
af3fc3bc 1270 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1271 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1272 else
19936277 1273 {
2cf0635d 1274 Elf_Internal_Sym * psym;
19936277 1275
af3fc3bc 1276 psym = symtab + symtab_index;
103f02d3 1277
af3fc3bc 1278 printf (" ");
171191ba 1279
d8045f23
NC
1280 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1281 {
1282 const char * name;
1283 unsigned int len;
1284 unsigned int width = is_32bit_elf ? 8 : 14;
1285
1286 /* Relocations against GNU_IFUNC symbols do not use the value
1287 of the symbol as the address to relocate against. Instead
1288 they invoke the function named by the symbol and use its
1289 result as the address for relocation.
1290
1291 To indicate this to the user, do not display the value of
1292 the symbol in the "Symbols's Value" field. Instead show
1293 its name followed by () as a hint that the symbol is
1294 invoked. */
1295
1296 if (strtab == NULL
1297 || psym->st_name == 0
1298 || psym->st_name >= strtablen)
1299 name = "??";
1300 else
1301 name = strtab + psym->st_name;
1302
1303 len = print_symbol (width, name);
1304 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1305 }
1306 else
1307 {
1308 print_vma (psym->st_value, LONG_HEX);
171191ba 1309
d8045f23
NC
1310 printf (is_32bit_elf ? " " : " ");
1311 }
103f02d3 1312
af3fc3bc 1313 if (psym->st_name == 0)
f1ef08cb 1314 {
2cf0635d 1315 const char * sec_name = "<null>";
f1ef08cb
AM
1316 char name_buf[40];
1317
1318 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1319 {
4fbb74a6
AM
1320 if (psym->st_shndx < elf_header.e_shnum)
1321 sec_name
1322 = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1323 else if (psym->st_shndx == SHN_ABS)
1324 sec_name = "ABS";
1325 else if (psym->st_shndx == SHN_COMMON)
1326 sec_name = "COMMON";
ac145307
BS
1327 else if ((elf_header.e_machine == EM_MIPS
1328 && psym->st_shndx == SHN_MIPS_SCOMMON)
1329 || (elf_header.e_machine == EM_TI_C6000
1330 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1331 sec_name = "SCOMMON";
1332 else if (elf_header.e_machine == EM_MIPS
1333 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1334 sec_name = "SUNDEF";
8a9036a4 1335 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1336 || elf_header.e_machine == EM_L1OM
1337 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1338 && psym->st_shndx == SHN_X86_64_LCOMMON)
1339 sec_name = "LARGE_COMMON";
9ce701e2
L
1340 else if (elf_header.e_machine == EM_IA_64
1341 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1342 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1343 sec_name = "ANSI_COM";
28f997cf 1344 else if (is_ia64_vms ()
148b93f2
NC
1345 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1346 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1347 else
1348 {
1349 sprintf (name_buf, "<section 0x%x>",
1350 (unsigned int) psym->st_shndx);
1351 sec_name = name_buf;
1352 }
1353 }
1354 print_symbol (22, sec_name);
1355 }
af3fc3bc 1356 else if (strtab == NULL)
d79b3d50 1357 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1358 else if (psym->st_name >= strtablen)
d79b3d50 1359 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1360 else
2c71103e 1361 print_symbol (22, strtab + psym->st_name);
103f02d3 1362
af3fc3bc 1363 if (is_rela)
171191ba 1364 {
598aaa76 1365 bfd_signed_vma off = rels[i].r_addend;
171191ba 1366
91d6fa6a 1367 if (off < 0)
598aaa76 1368 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1369 else
598aaa76 1370 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1371 }
19936277 1372 }
252b5132 1373 }
1b228002 1374 else if (is_rela)
f7a99963 1375 {
18bd398b
NC
1376 printf ("%*c", is_32bit_elf ?
1377 (do_wide ? 34 : 28) : (do_wide ? 26 : 20), ' ');
c8286bd1 1378 print_vma (rels[i].r_addend, LONG_HEX);
f7a99963 1379 }
252b5132 1380
157c2599
NC
1381 if (elf_header.e_machine == EM_SPARCV9
1382 && rtype != NULL
1383 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1384 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1385
252b5132 1386 putchar ('\n');
2c71103e 1387
aca88567 1388#ifdef BFD64
53c7db4b 1389 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1390 {
91d6fa6a
NC
1391 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1392 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1393 const char * rtype2 = elf_mips_reloc_type (type2);
1394 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1395
2c71103e
NC
1396 printf (" Type2: ");
1397
1398 if (rtype2 == NULL)
39dbeff8
AM
1399 printf (_("unrecognized: %-7lx"),
1400 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1401 else
1402 printf ("%-17.17s", rtype2);
1403
18bd398b 1404 printf ("\n Type3: ");
2c71103e
NC
1405
1406 if (rtype3 == NULL)
39dbeff8
AM
1407 printf (_("unrecognized: %-7lx"),
1408 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1409 else
1410 printf ("%-17.17s", rtype3);
1411
53c7db4b 1412 putchar ('\n');
2c71103e 1413 }
aca88567 1414#endif /* BFD64 */
252b5132
RH
1415 }
1416
c8286bd1 1417 free (rels);
252b5132
RH
1418}
1419
1420static const char *
d3ba0551 1421get_mips_dynamic_type (unsigned long type)
252b5132
RH
1422{
1423 switch (type)
1424 {
1425 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1426 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1427 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1428 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1429 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1430 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1431 case DT_MIPS_MSYM: return "MIPS_MSYM";
1432 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1433 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1434 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1435 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1436 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1437 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1438 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1439 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1440 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1441 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1442 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1443 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1444 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1445 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1446 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1447 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1448 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1449 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1450 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1451 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1452 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1453 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1454 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1455 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1456 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1457 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1458 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1459 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1460 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1461 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1462 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1463 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1464 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1465 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1466 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1467 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1468 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1469 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1470 default:
1471 return NULL;
1472 }
1473}
1474
9a097730 1475static const char *
d3ba0551 1476get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1477{
1478 switch (type)
1479 {
1480 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1481 default:
1482 return NULL;
1483 }
103f02d3
UD
1484}
1485
7490d522
AM
1486static const char *
1487get_ppc_dynamic_type (unsigned long type)
1488{
1489 switch (type)
1490 {
a7f2871e
AM
1491 case DT_PPC_GOT: return "PPC_GOT";
1492 case DT_PPC_TLSOPT: return "PPC_TLSOPT";
7490d522
AM
1493 default:
1494 return NULL;
1495 }
1496}
1497
f1cb7e17 1498static const char *
d3ba0551 1499get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1500{
1501 switch (type)
1502 {
a7f2871e
AM
1503 case DT_PPC64_GLINK: return "PPC64_GLINK";
1504 case DT_PPC64_OPD: return "PPC64_OPD";
1505 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
1506 case DT_PPC64_TLSOPT: return "PPC64_TLSOPT";
f1cb7e17
AM
1507 default:
1508 return NULL;
1509 }
1510}
1511
103f02d3 1512static const char *
d3ba0551 1513get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1514{
1515 switch (type)
1516 {
1517 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1518 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1519 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1520 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1521 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1522 case DT_HP_PREINIT: return "HP_PREINIT";
1523 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1524 case DT_HP_NEEDED: return "HP_NEEDED";
1525 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1526 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1527 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1528 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1529 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1530 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1531 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1532 case DT_HP_FILTERED: return "HP_FILTERED";
1533 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1534 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1535 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1536 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1537 case DT_PLT: return "PLT";
1538 case DT_PLT_SIZE: return "PLT_SIZE";
1539 case DT_DLT: return "DLT";
1540 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1541 default:
1542 return NULL;
1543 }
1544}
9a097730 1545
ecc51f48 1546static const char *
d3ba0551 1547get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1548{
1549 switch (type)
1550 {
148b93f2
NC
1551 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1552 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1553 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1554 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1555 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1556 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1557 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1558 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1559 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1560 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1561 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1562 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1563 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1564 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1565 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1566 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1567 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1568 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1569 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1570 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1571 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1572 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1573 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1574 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1575 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1576 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1577 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1578 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1579 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1580 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1581 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1582 default:
1583 return NULL;
1584 }
1585}
1586
fabcb361
RH
1587static const char *
1588get_alpha_dynamic_type (unsigned long type)
1589{
1590 switch (type)
1591 {
1592 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1593 default:
1594 return NULL;
1595 }
1596}
1597
1c0d3aa6
NC
1598static const char *
1599get_score_dynamic_type (unsigned long type)
1600{
1601 switch (type)
1602 {
1603 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1604 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1605 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1606 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1607 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1608 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1609 default:
1610 return NULL;
1611 }
1612}
1613
40b36596
JM
1614static const char *
1615get_tic6x_dynamic_type (unsigned long type)
1616{
1617 switch (type)
1618 {
1619 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1620 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1621 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1622 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1623 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1624 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1625 default:
1626 return NULL;
1627 }
1628}
1c0d3aa6 1629
252b5132 1630static const char *
d3ba0551 1631get_dynamic_type (unsigned long type)
252b5132 1632{
e9e44622 1633 static char buff[64];
252b5132
RH
1634
1635 switch (type)
1636 {
1637 case DT_NULL: return "NULL";
1638 case DT_NEEDED: return "NEEDED";
1639 case DT_PLTRELSZ: return "PLTRELSZ";
1640 case DT_PLTGOT: return "PLTGOT";
1641 case DT_HASH: return "HASH";
1642 case DT_STRTAB: return "STRTAB";
1643 case DT_SYMTAB: return "SYMTAB";
1644 case DT_RELA: return "RELA";
1645 case DT_RELASZ: return "RELASZ";
1646 case DT_RELAENT: return "RELAENT";
1647 case DT_STRSZ: return "STRSZ";
1648 case DT_SYMENT: return "SYMENT";
1649 case DT_INIT: return "INIT";
1650 case DT_FINI: return "FINI";
1651 case DT_SONAME: return "SONAME";
1652 case DT_RPATH: return "RPATH";
1653 case DT_SYMBOLIC: return "SYMBOLIC";
1654 case DT_REL: return "REL";
1655 case DT_RELSZ: return "RELSZ";
1656 case DT_RELENT: return "RELENT";
1657 case DT_PLTREL: return "PLTREL";
1658 case DT_DEBUG: return "DEBUG";
1659 case DT_TEXTREL: return "TEXTREL";
1660 case DT_JMPREL: return "JMPREL";
1661 case DT_BIND_NOW: return "BIND_NOW";
1662 case DT_INIT_ARRAY: return "INIT_ARRAY";
1663 case DT_FINI_ARRAY: return "FINI_ARRAY";
1664 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1665 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1666 case DT_RUNPATH: return "RUNPATH";
1667 case DT_FLAGS: return "FLAGS";
2d0e6f43 1668
d1133906
NC
1669 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1670 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1671
05107a46 1672 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1673 case DT_PLTPADSZ: return "PLTPADSZ";
1674 case DT_MOVEENT: return "MOVEENT";
1675 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1676 case DT_FEATURE: return "FEATURE";
252b5132
RH
1677 case DT_POSFLAG_1: return "POSFLAG_1";
1678 case DT_SYMINSZ: return "SYMINSZ";
1679 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1680
252b5132 1681 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1682 case DT_CONFIG: return "CONFIG";
1683 case DT_DEPAUDIT: return "DEPAUDIT";
1684 case DT_AUDIT: return "AUDIT";
1685 case DT_PLTPAD: return "PLTPAD";
1686 case DT_MOVETAB: return "MOVETAB";
252b5132 1687 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1688
252b5132 1689 case DT_VERSYM: return "VERSYM";
103f02d3 1690
67a4f2b7
AO
1691 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1692 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1693 case DT_RELACOUNT: return "RELACOUNT";
1694 case DT_RELCOUNT: return "RELCOUNT";
1695 case DT_FLAGS_1: return "FLAGS_1";
1696 case DT_VERDEF: return "VERDEF";
1697 case DT_VERDEFNUM: return "VERDEFNUM";
1698 case DT_VERNEED: return "VERNEED";
1699 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1700
019148e4 1701 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1702 case DT_USED: return "USED";
1703 case DT_FILTER: return "FILTER";
103f02d3 1704
047b2264
JJ
1705 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1706 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1707 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1708 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1709 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1710 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1711
252b5132
RH
1712 default:
1713 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1714 {
2cf0635d 1715 const char * result;
103f02d3 1716
252b5132
RH
1717 switch (elf_header.e_machine)
1718 {
1719 case EM_MIPS:
4fe85591 1720 case EM_MIPS_RS3_LE:
252b5132
RH
1721 result = get_mips_dynamic_type (type);
1722 break;
9a097730
RH
1723 case EM_SPARCV9:
1724 result = get_sparc64_dynamic_type (type);
1725 break;
7490d522
AM
1726 case EM_PPC:
1727 result = get_ppc_dynamic_type (type);
1728 break;
f1cb7e17
AM
1729 case EM_PPC64:
1730 result = get_ppc64_dynamic_type (type);
1731 break;
ecc51f48
NC
1732 case EM_IA_64:
1733 result = get_ia64_dynamic_type (type);
1734 break;
fabcb361
RH
1735 case EM_ALPHA:
1736 result = get_alpha_dynamic_type (type);
1737 break;
1c0d3aa6
NC
1738 case EM_SCORE:
1739 result = get_score_dynamic_type (type);
1740 break;
40b36596
JM
1741 case EM_TI_C6000:
1742 result = get_tic6x_dynamic_type (type);
1743 break;
252b5132
RH
1744 default:
1745 result = NULL;
1746 break;
1747 }
1748
1749 if (result != NULL)
1750 return result;
1751
e9e44622 1752 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 1753 }
eec8f817
DA
1754 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
1755 || (elf_header.e_machine == EM_PARISC
1756 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 1757 {
2cf0635d 1758 const char * result;
103f02d3
UD
1759
1760 switch (elf_header.e_machine)
1761 {
1762 case EM_PARISC:
1763 result = get_parisc_dynamic_type (type);
1764 break;
148b93f2
NC
1765 case EM_IA_64:
1766 result = get_ia64_dynamic_type (type);
1767 break;
103f02d3
UD
1768 default:
1769 result = NULL;
1770 break;
1771 }
1772
1773 if (result != NULL)
1774 return result;
1775
e9e44622
JJ
1776 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
1777 type);
103f02d3 1778 }
252b5132 1779 else
e9e44622 1780 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 1781
252b5132
RH
1782 return buff;
1783 }
1784}
1785
1786static char *
d3ba0551 1787get_file_type (unsigned e_type)
252b5132 1788{
b34976b6 1789 static char buff[32];
252b5132
RH
1790
1791 switch (e_type)
1792 {
1793 case ET_NONE: return _("NONE (None)");
1794 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
1795 case ET_EXEC: return _("EXEC (Executable file)");
1796 case ET_DYN: return _("DYN (Shared object file)");
1797 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
1798
1799 default:
1800 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 1801 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 1802 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 1803 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 1804 else
e9e44622 1805 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
1806 return buff;
1807 }
1808}
1809
1810static char *
d3ba0551 1811get_machine_name (unsigned e_machine)
252b5132 1812{
b34976b6 1813 static char buff[64]; /* XXX */
252b5132
RH
1814
1815 switch (e_machine)
1816 {
c45021f2
NC
1817 case EM_NONE: return _("None");
1818 case EM_M32: return "WE32100";
1819 case EM_SPARC: return "Sparc";
e9f53129 1820 case EM_SPU: return "SPU";
c45021f2
NC
1821 case EM_386: return "Intel 80386";
1822 case EM_68K: return "MC68000";
1823 case EM_88K: return "MC88000";
1824 case EM_486: return "Intel 80486";
1825 case EM_860: return "Intel 80860";
1826 case EM_MIPS: return "MIPS R3000";
1827 case EM_S370: return "IBM System/370";
7036c0e1 1828 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 1829 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 1830 case EM_PARISC: return "HPPA";
252b5132 1831 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 1832 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
1833 case EM_960: return "Intel 90860";
1834 case EM_PPC: return "PowerPC";
285d1771 1835 case EM_PPC64: return "PowerPC64";
c45021f2
NC
1836 case EM_V800: return "NEC V800";
1837 case EM_FR20: return "Fujitsu FR20";
1838 case EM_RH32: return "TRW RH32";
b34976b6 1839 case EM_MCORE: return "MCORE";
7036c0e1
AJ
1840 case EM_ARM: return "ARM";
1841 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 1842 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
1843 case EM_SPARCV9: return "Sparc v9";
1844 case EM_TRICORE: return "Siemens Tricore";
584da044 1845 case EM_ARC: return "ARC";
c2dcd04e
NC
1846 case EM_H8_300: return "Renesas H8/300";
1847 case EM_H8_300H: return "Renesas H8/300H";
1848 case EM_H8S: return "Renesas H8S";
1849 case EM_H8_500: return "Renesas H8/500";
30800947 1850 case EM_IA_64: return "Intel IA-64";
252b5132
RH
1851 case EM_MIPS_X: return "Stanford MIPS-X";
1852 case EM_COLDFIRE: return "Motorola Coldfire";
1853 case EM_68HC12: return "Motorola M68HC12";
c45021f2 1854 case EM_ALPHA: return "Alpha";
2b0337b0
AO
1855 case EM_CYGNUS_D10V:
1856 case EM_D10V: return "d10v";
1857 case EM_CYGNUS_D30V:
b34976b6 1858 case EM_D30V: return "d30v";
2b0337b0 1859 case EM_CYGNUS_M32R:
26597c86 1860 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 1861 case EM_CYGNUS_V850:
8f7e76d0 1862 case EM_V850: return "Renesas v850";
2b0337b0
AO
1863 case EM_CYGNUS_MN10300:
1864 case EM_MN10300: return "mn10300";
1865 case EM_CYGNUS_MN10200:
1866 case EM_MN10200: return "mn10200";
5506d11a 1867 case EM_MOXIE: return "Moxie";
2b0337b0
AO
1868 case EM_CYGNUS_FR30:
1869 case EM_FR30: return "Fujitsu FR30";
b34976b6 1870 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 1871 case EM_PJ_OLD:
b34976b6 1872 case EM_PJ: return "picoJava";
7036c0e1
AJ
1873 case EM_MMA: return "Fujitsu Multimedia Accelerator";
1874 case EM_PCP: return "Siemens PCP";
1875 case EM_NCPU: return "Sony nCPU embedded RISC processor";
1876 case EM_NDR1: return "Denso NDR1 microprocesspr";
1877 case EM_STARCORE: return "Motorola Star*Core processor";
1878 case EM_ME16: return "Toyota ME16 processor";
1879 case EM_ST100: return "STMicroelectronics ST100 processor";
1880 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
1881 case EM_PDSP: return "Sony DSP processor";
1882 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
1883 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
1884 case EM_FX66: return "Siemens FX66 microcontroller";
1885 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
1886 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
1887 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
1888 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
1889 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
1890 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
1891 case EM_SVX: return "Silicon Graphics SVx";
1892 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
1893 case EM_VAX: return "Digital VAX";
2b0337b0 1894 case EM_AVR_OLD:
b34976b6 1895 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 1896 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
1897 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
1898 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
1899 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 1900 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 1901 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 1902 case EM_PRISM: return "Vitesse Prism";
bcedfee6 1903 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 1904 case EM_L1OM: return "Intel L1OM";
7a9068fe 1905 case EM_K1OM: return "Intel K1OM";
b7498e0e 1906 case EM_S390_OLD:
b34976b6 1907 case EM_S390: return "IBM S/390";
1c0d3aa6 1908 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 1909 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3b16e843
NC
1910 case EM_OPENRISC:
1911 case EM_OR32: return "OpenRISC";
11636f9e 1912 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 1913 case EM_CRX: return "National Semiconductor CRX microprocessor";
d172d4ba 1914 case EM_DLX: return "OpenDLX";
1e4cf259 1915 case EM_IP2K_OLD:
b34976b6 1916 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 1917 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
1918 case EM_XTENSA_OLD:
1919 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
1920 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
1921 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
1922 case EM_NS32K: return "National Semiconductor 32000 series";
1923 case EM_TPC: return "Tenor Network TPC processor";
1924 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
1925 case EM_MAX: return "MAX Processor";
1926 case EM_CR: return "National Semiconductor CompactRISC";
1927 case EM_F2MC16: return "Fujitsu F2MC16";
1928 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 1929 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 1930 case EM_M32C_OLD:
49f58d10 1931 case EM_M32C: return "Renesas M32c";
d031aafb 1932 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 1933 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
1934 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
1935 case EM_SEP: return "Sharp embedded microprocessor";
1936 case EM_ARCA: return "Arca RISC microprocessor";
1937 case EM_UNICORE: return "Unicore";
1938 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
1939 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
1940 case EM_NIOS32: return "Altera Nios";
1941 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 1942 case EM_C166:
d70c5fc7 1943 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
1944 case EM_M16C: return "Renesas M16C series microprocessors";
1945 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
1946 case EM_CE: return "Freescale Communication Engine RISC core";
1947 case EM_TSK3000: return "Altium TSK3000 core";
1948 case EM_RS08: return "Freescale RS08 embedded processor";
1949 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
1950 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
1951 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
1952 case EM_SE_C17: return "Seiko Epson C17 family";
1953 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
1954 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
1955 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
1956 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
1957 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
1958 case EM_R32C: return "Renesas R32C series microprocessors";
1959 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
1960 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
1961 case EM_8051: return "Intel 8051 and variants";
1962 case EM_STXP7X: return "STMicroelectronics STxP7x family";
1963 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
1964 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
1965 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
1966 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
1967 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
1968 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 1969 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 1970 case EM_CR16:
6c03b1ed 1971 case EM_CR16_OLD: return "National Semiconductor's CR16";
7ba29e2a
NC
1972 case EM_MICROBLAZE: return "Xilinx MicroBlaze";
1973 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
c7927a3c 1974 case EM_RX: return "Renesas RX";
11636f9e
JM
1975 case EM_METAG: return "Imagination Technologies META processor architecture";
1976 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
1977 case EM_ECOG16: return "Cyan Technology eCOG16 family";
1978 case EM_ETPU: return "Freescale Extended Time Processing Unit";
1979 case EM_SLE9X: return "Infineon Technologies SLE9X core";
1980 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
1981 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
1982 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
1983 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 1984 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 1985 case EM_CUDA: return "NVIDIA CUDA architecture";
252b5132 1986 default:
35d9dd2f 1987 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
1988 return buff;
1989 }
1990}
1991
f3485b74 1992static void
d3ba0551 1993decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
1994{
1995 unsigned eabi;
1996 int unknown = 0;
1997
1998 eabi = EF_ARM_EABI_VERSION (e_flags);
1999 e_flags &= ~ EF_ARM_EABIMASK;
2000
2001 /* Handle "generic" ARM flags. */
2002 if (e_flags & EF_ARM_RELEXEC)
2003 {
2004 strcat (buf, ", relocatable executable");
2005 e_flags &= ~ EF_ARM_RELEXEC;
2006 }
76da6bbe 2007
f3485b74
NC
2008 if (e_flags & EF_ARM_HASENTRY)
2009 {
2010 strcat (buf, ", has entry point");
2011 e_flags &= ~ EF_ARM_HASENTRY;
2012 }
76da6bbe 2013
f3485b74
NC
2014 /* Now handle EABI specific flags. */
2015 switch (eabi)
2016 {
2017 default:
2c71103e 2018 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2019 if (e_flags)
2020 unknown = 1;
2021 break;
2022
2023 case EF_ARM_EABI_VER1:
a5bcd848 2024 strcat (buf, ", Version1 EABI");
f3485b74
NC
2025 while (e_flags)
2026 {
2027 unsigned flag;
76da6bbe 2028
f3485b74
NC
2029 /* Process flags one bit at a time. */
2030 flag = e_flags & - e_flags;
2031 e_flags &= ~ flag;
76da6bbe 2032
f3485b74
NC
2033 switch (flag)
2034 {
a5bcd848 2035 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2036 strcat (buf, ", sorted symbol tables");
2037 break;
76da6bbe 2038
f3485b74
NC
2039 default:
2040 unknown = 1;
2041 break;
2042 }
2043 }
2044 break;
76da6bbe 2045
a5bcd848
PB
2046 case EF_ARM_EABI_VER2:
2047 strcat (buf, ", Version2 EABI");
2048 while (e_flags)
2049 {
2050 unsigned flag;
2051
2052 /* Process flags one bit at a time. */
2053 flag = e_flags & - e_flags;
2054 e_flags &= ~ flag;
2055
2056 switch (flag)
2057 {
2058 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2059 strcat (buf, ", sorted symbol tables");
2060 break;
2061
2062 case EF_ARM_DYNSYMSUSESEGIDX:
2063 strcat (buf, ", dynamic symbols use segment index");
2064 break;
2065
2066 case EF_ARM_MAPSYMSFIRST:
2067 strcat (buf, ", mapping symbols precede others");
2068 break;
2069
2070 default:
2071 unknown = 1;
2072 break;
2073 }
2074 }
2075 break;
2076
d507cf36
PB
2077 case EF_ARM_EABI_VER3:
2078 strcat (buf, ", Version3 EABI");
8cb51566
PB
2079 break;
2080
2081 case EF_ARM_EABI_VER4:
2082 strcat (buf, ", Version4 EABI");
3a4a14e9
PB
2083 goto eabi;
2084
2085 case EF_ARM_EABI_VER5:
2086 strcat (buf, ", Version5 EABI");
2087 eabi:
d507cf36
PB
2088 while (e_flags)
2089 {
2090 unsigned flag;
2091
2092 /* Process flags one bit at a time. */
2093 flag = e_flags & - e_flags;
2094 e_flags &= ~ flag;
2095
2096 switch (flag)
2097 {
2098 case EF_ARM_BE8:
2099 strcat (buf, ", BE8");
2100 break;
2101
2102 case EF_ARM_LE8:
2103 strcat (buf, ", LE8");
2104 break;
2105
2106 default:
2107 unknown = 1;
2108 break;
2109 }
2110 }
2111 break;
2112
f3485b74 2113 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2114 strcat (buf, ", GNU EABI");
f3485b74
NC
2115 while (e_flags)
2116 {
2117 unsigned flag;
76da6bbe 2118
f3485b74
NC
2119 /* Process flags one bit at a time. */
2120 flag = e_flags & - e_flags;
2121 e_flags &= ~ flag;
76da6bbe 2122
f3485b74
NC
2123 switch (flag)
2124 {
a5bcd848 2125 case EF_ARM_INTERWORK:
f3485b74
NC
2126 strcat (buf, ", interworking enabled");
2127 break;
76da6bbe 2128
a5bcd848 2129 case EF_ARM_APCS_26:
f3485b74
NC
2130 strcat (buf, ", uses APCS/26");
2131 break;
76da6bbe 2132
a5bcd848 2133 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2134 strcat (buf, ", uses APCS/float");
2135 break;
76da6bbe 2136
a5bcd848 2137 case EF_ARM_PIC:
f3485b74
NC
2138 strcat (buf, ", position independent");
2139 break;
76da6bbe 2140
a5bcd848 2141 case EF_ARM_ALIGN8:
f3485b74
NC
2142 strcat (buf, ", 8 bit structure alignment");
2143 break;
76da6bbe 2144
a5bcd848 2145 case EF_ARM_NEW_ABI:
f3485b74
NC
2146 strcat (buf, ", uses new ABI");
2147 break;
76da6bbe 2148
a5bcd848 2149 case EF_ARM_OLD_ABI:
f3485b74
NC
2150 strcat (buf, ", uses old ABI");
2151 break;
76da6bbe 2152
a5bcd848 2153 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2154 strcat (buf, ", software FP");
2155 break;
76da6bbe 2156
90e01f86
ILT
2157 case EF_ARM_VFP_FLOAT:
2158 strcat (buf, ", VFP");
2159 break;
2160
fde78edd
NC
2161 case EF_ARM_MAVERICK_FLOAT:
2162 strcat (buf, ", Maverick FP");
2163 break;
2164
f3485b74
NC
2165 default:
2166 unknown = 1;
2167 break;
2168 }
2169 }
2170 }
f3485b74
NC
2171
2172 if (unknown)
2b692964 2173 strcat (buf,_(", <unknown>"));
f3485b74
NC
2174}
2175
252b5132 2176static char *
d3ba0551 2177get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2178{
b34976b6 2179 static char buf[1024];
252b5132
RH
2180
2181 buf[0] = '\0';
76da6bbe 2182
252b5132
RH
2183 if (e_flags)
2184 {
2185 switch (e_machine)
2186 {
2187 default:
2188 break;
2189
f3485b74
NC
2190 case EM_ARM:
2191 decode_ARM_machine_flags (e_flags, buf);
2192 break;
76da6bbe 2193
781303ce
MF
2194 case EM_BLACKFIN:
2195 if (e_flags & EF_BFIN_PIC)
2196 strcat (buf, ", PIC");
2197
2198 if (e_flags & EF_BFIN_FDPIC)
2199 strcat (buf, ", FDPIC");
2200
2201 if (e_flags & EF_BFIN_CODE_IN_L1)
2202 strcat (buf, ", code in L1");
2203
2204 if (e_flags & EF_BFIN_DATA_IN_L1)
2205 strcat (buf, ", data in L1");
2206
2207 break;
2208
ec2dfb42
AO
2209 case EM_CYGNUS_FRV:
2210 switch (e_flags & EF_FRV_CPU_MASK)
2211 {
2212 case EF_FRV_CPU_GENERIC:
2213 break;
2214
2215 default:
2216 strcat (buf, ", fr???");
2217 break;
57346661 2218
ec2dfb42
AO
2219 case EF_FRV_CPU_FR300:
2220 strcat (buf, ", fr300");
2221 break;
2222
2223 case EF_FRV_CPU_FR400:
2224 strcat (buf, ", fr400");
2225 break;
2226 case EF_FRV_CPU_FR405:
2227 strcat (buf, ", fr405");
2228 break;
2229
2230 case EF_FRV_CPU_FR450:
2231 strcat (buf, ", fr450");
2232 break;
2233
2234 case EF_FRV_CPU_FR500:
2235 strcat (buf, ", fr500");
2236 break;
2237 case EF_FRV_CPU_FR550:
2238 strcat (buf, ", fr550");
2239 break;
2240
2241 case EF_FRV_CPU_SIMPLE:
2242 strcat (buf, ", simple");
2243 break;
2244 case EF_FRV_CPU_TOMCAT:
2245 strcat (buf, ", tomcat");
2246 break;
2247 }
1c877e87 2248 break;
ec2dfb42 2249
53c7db4b 2250 case EM_68K:
425c6cb0 2251 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2252 strcat (buf, ", m68000");
425c6cb0 2253 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2254 strcat (buf, ", cpu32");
2255 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2256 strcat (buf, ", fido_a");
425c6cb0 2257 else
266abb8f 2258 {
2cf0635d
NC
2259 char const * isa = _("unknown");
2260 char const * mac = _("unknown mac");
2261 char const * additional = NULL;
0112cd26 2262
c694fd50 2263 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2264 {
c694fd50 2265 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2266 isa = "A";
2267 additional = ", nodiv";
2268 break;
c694fd50 2269 case EF_M68K_CF_ISA_A:
266abb8f
NS
2270 isa = "A";
2271 break;
c694fd50 2272 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2273 isa = "A+";
2274 break;
c694fd50 2275 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2276 isa = "B";
2277 additional = ", nousp";
2278 break;
c694fd50 2279 case EF_M68K_CF_ISA_B:
266abb8f
NS
2280 isa = "B";
2281 break;
f608cd77
NS
2282 case EF_M68K_CF_ISA_C:
2283 isa = "C";
2284 break;
2285 case EF_M68K_CF_ISA_C_NODIV:
2286 isa = "C";
2287 additional = ", nodiv";
2288 break;
266abb8f
NS
2289 }
2290 strcat (buf, ", cf, isa ");
2291 strcat (buf, isa);
0b2e31dc
NS
2292 if (additional)
2293 strcat (buf, additional);
c694fd50 2294 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2295 strcat (buf, ", float");
c694fd50 2296 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2297 {
2298 case 0:
2299 mac = NULL;
2300 break;
c694fd50 2301 case EF_M68K_CF_MAC:
266abb8f
NS
2302 mac = "mac";
2303 break;
c694fd50 2304 case EF_M68K_CF_EMAC:
266abb8f
NS
2305 mac = "emac";
2306 break;
f608cd77
NS
2307 case EF_M68K_CF_EMAC_B:
2308 mac = "emac_b";
2309 break;
266abb8f
NS
2310 }
2311 if (mac)
2312 {
2313 strcat (buf, ", ");
2314 strcat (buf, mac);
2315 }
266abb8f 2316 }
53c7db4b 2317 break;
33c63f9d 2318
252b5132
RH
2319 case EM_PPC:
2320 if (e_flags & EF_PPC_EMB)
2321 strcat (buf, ", emb");
2322
2323 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2324 strcat (buf, _(", relocatable"));
252b5132
RH
2325
2326 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2327 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2328 break;
2329
2b0337b0 2330 case EM_V850:
252b5132
RH
2331 case EM_CYGNUS_V850:
2332 switch (e_flags & EF_V850_ARCH)
2333 {
1cd986c5
NC
2334 case E_V850E2V3_ARCH:
2335 strcat (buf, ", v850e2v3");
2336 break;
2337 case E_V850E2_ARCH:
2338 strcat (buf, ", v850e2");
2339 break;
2340 case E_V850E1_ARCH:
2341 strcat (buf, ", v850e1");
8ad30312 2342 break;
252b5132
RH
2343 case E_V850E_ARCH:
2344 strcat (buf, ", v850e");
2345 break;
252b5132
RH
2346 case E_V850_ARCH:
2347 strcat (buf, ", v850");
2348 break;
2349 default:
2b692964 2350 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2351 break;
2352 }
2353 break;
2354
2b0337b0 2355 case EM_M32R:
252b5132
RH
2356 case EM_CYGNUS_M32R:
2357 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2358 strcat (buf, ", m32r");
252b5132
RH
2359 break;
2360
2361 case EM_MIPS:
4fe85591 2362 case EM_MIPS_RS3_LE:
252b5132
RH
2363 if (e_flags & EF_MIPS_NOREORDER)
2364 strcat (buf, ", noreorder");
2365
2366 if (e_flags & EF_MIPS_PIC)
2367 strcat (buf, ", pic");
2368
2369 if (e_flags & EF_MIPS_CPIC)
2370 strcat (buf, ", cpic");
2371
d1bdd336
TS
2372 if (e_flags & EF_MIPS_UCODE)
2373 strcat (buf, ", ugen_reserved");
2374
252b5132
RH
2375 if (e_flags & EF_MIPS_ABI2)
2376 strcat (buf, ", abi2");
2377
43521d43
TS
2378 if (e_flags & EF_MIPS_OPTIONS_FIRST)
2379 strcat (buf, ", odk first");
2380
a5d22d2a
TS
2381 if (e_flags & EF_MIPS_32BITMODE)
2382 strcat (buf, ", 32bitmode");
2383
156c2f8b
NC
2384 switch ((e_flags & EF_MIPS_MACH))
2385 {
2386 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
2387 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
2388 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 2389 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
2390 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
2391 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
2392 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
2393 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 2394 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 2395 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
2396 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
2397 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 2398 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 2399 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 2400 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
52b6b6b9 2401 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
2402 case 0:
2403 /* We simply ignore the field in this case to avoid confusion:
2404 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
2405 extension. */
2406 break;
2b692964 2407 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 2408 }
43521d43
TS
2409
2410 switch ((e_flags & EF_MIPS_ABI))
2411 {
2412 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
2413 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
2414 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
2415 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
2416 case 0:
2417 /* We simply ignore the field in this case to avoid confusion:
2418 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
2419 This means it is likely to be an o32 file, but not for
2420 sure. */
2421 break;
2b692964 2422 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
2423 }
2424
2425 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
2426 strcat (buf, ", mdmx");
2427
2428 if (e_flags & EF_MIPS_ARCH_ASE_M16)
2429 strcat (buf, ", mips16");
2430
df58fc94
RS
2431 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
2432 strcat (buf, ", micromips");
2433
43521d43
TS
2434 switch ((e_flags & EF_MIPS_ARCH))
2435 {
2436 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
2437 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
2438 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
2439 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
2440 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
2441 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 2442 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
43521d43 2443 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 2444 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
2b692964 2445 default: strcat (buf, _(", unknown ISA")); break;
43521d43
TS
2446 }
2447
8e45593f
NC
2448 if (e_flags & EF_SH_PIC)
2449 strcat (buf, ", pic");
2450
2451 if (e_flags & EF_SH_FDPIC)
2452 strcat (buf, ", fdpic");
252b5132 2453 break;
351b4b40 2454
ccde1100
AO
2455 case EM_SH:
2456 switch ((e_flags & EF_SH_MACH_MASK))
2457 {
2458 case EF_SH1: strcat (buf, ", sh1"); break;
2459 case EF_SH2: strcat (buf, ", sh2"); break;
2460 case EF_SH3: strcat (buf, ", sh3"); break;
2461 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
2462 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
2463 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
2464 case EF_SH3E: strcat (buf, ", sh3e"); break;
2465 case EF_SH4: strcat (buf, ", sh4"); break;
2466 case EF_SH5: strcat (buf, ", sh5"); break;
2467 case EF_SH2E: strcat (buf, ", sh2e"); break;
2468 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 2469 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
2470 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
2471 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 2472 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
2473 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
2474 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
2475 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
2476 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
2477 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
2478 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 2479 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
2480 }
2481
2482 break;
57346661 2483
351b4b40
RH
2484 case EM_SPARCV9:
2485 if (e_flags & EF_SPARC_32PLUS)
2486 strcat (buf, ", v8+");
2487
2488 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
2489 strcat (buf, ", ultrasparcI");
2490
2491 if (e_flags & EF_SPARC_SUN_US3)
2492 strcat (buf, ", ultrasparcIII");
351b4b40
RH
2493
2494 if (e_flags & EF_SPARC_HAL_R1)
2495 strcat (buf, ", halr1");
2496
2497 if (e_flags & EF_SPARC_LEDATA)
2498 strcat (buf, ", ledata");
2499
2500 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
2501 strcat (buf, ", tso");
2502
2503 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
2504 strcat (buf, ", pso");
2505
2506 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
2507 strcat (buf, ", rmo");
2508 break;
7d466069 2509
103f02d3
UD
2510 case EM_PARISC:
2511 switch (e_flags & EF_PARISC_ARCH)
2512 {
2513 case EFA_PARISC_1_0:
2514 strcpy (buf, ", PA-RISC 1.0");
2515 break;
2516 case EFA_PARISC_1_1:
2517 strcpy (buf, ", PA-RISC 1.1");
2518 break;
2519 case EFA_PARISC_2_0:
2520 strcpy (buf, ", PA-RISC 2.0");
2521 break;
2522 default:
2523 break;
2524 }
2525 if (e_flags & EF_PARISC_TRAPNIL)
2526 strcat (buf, ", trapnil");
2527 if (e_flags & EF_PARISC_EXT)
2528 strcat (buf, ", ext");
2529 if (e_flags & EF_PARISC_LSB)
2530 strcat (buf, ", lsb");
2531 if (e_flags & EF_PARISC_WIDE)
2532 strcat (buf, ", wide");
2533 if (e_flags & EF_PARISC_NO_KABP)
2534 strcat (buf, ", no kabp");
2535 if (e_flags & EF_PARISC_LAZYSWAP)
2536 strcat (buf, ", lazyswap");
30800947 2537 break;
76da6bbe 2538
7d466069 2539 case EM_PJ:
2b0337b0 2540 case EM_PJ_OLD:
7d466069
ILT
2541 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
2542 strcat (buf, ", new calling convention");
2543
2544 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
2545 strcat (buf, ", gnu calling convention");
2546 break;
4d6ed7c8
NC
2547
2548 case EM_IA_64:
2549 if ((e_flags & EF_IA_64_ABI64))
2550 strcat (buf, ", 64-bit");
2551 else
2552 strcat (buf, ", 32-bit");
2553 if ((e_flags & EF_IA_64_REDUCEDFP))
2554 strcat (buf, ", reduced fp model");
2555 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
2556 strcat (buf, ", no function descriptors, constant gp");
2557 else if ((e_flags & EF_IA_64_CONS_GP))
2558 strcat (buf, ", constant gp");
2559 if ((e_flags & EF_IA_64_ABSOLUTE))
2560 strcat (buf, ", absolute");
28f997cf
TG
2561 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
2562 {
2563 if ((e_flags & EF_IA_64_VMS_LINKAGES))
2564 strcat (buf, ", vms_linkages");
2565 switch ((e_flags & EF_IA_64_VMS_COMCOD))
2566 {
2567 case EF_IA_64_VMS_COMCOD_SUCCESS:
2568 break;
2569 case EF_IA_64_VMS_COMCOD_WARNING:
2570 strcat (buf, ", warning");
2571 break;
2572 case EF_IA_64_VMS_COMCOD_ERROR:
2573 strcat (buf, ", error");
2574 break;
2575 case EF_IA_64_VMS_COMCOD_ABORT:
2576 strcat (buf, ", abort");
2577 break;
2578 default:
2579 abort ();
2580 }
2581 }
4d6ed7c8 2582 break;
179d3252
JT
2583
2584 case EM_VAX:
2585 if ((e_flags & EF_VAX_NONPIC))
2586 strcat (buf, ", non-PIC");
2587 if ((e_flags & EF_VAX_DFLOAT))
2588 strcat (buf, ", D-Float");
2589 if ((e_flags & EF_VAX_GFLOAT))
2590 strcat (buf, ", G-Float");
2591 break;
c7927a3c
NC
2592
2593 case EM_RX:
2594 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
2595 strcat (buf, ", 64-bit doubles");
2596 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 2597 strcat (buf, ", dsp");
d4cb0ea0
NC
2598 if (e_flags & E_FLAG_RX_PID)
2599 strcat (buf, ", pid");
2600 break;
55786da2
AK
2601
2602 case EM_S390:
2603 if (e_flags & EF_S390_HIGH_GPRS)
2604 strcat (buf, ", highgprs");
d4cb0ea0 2605 break;
40b36596
JM
2606
2607 case EM_TI_C6000:
2608 if ((e_flags & EF_C6000_REL))
2609 strcat (buf, ", relocatable module");
d4cb0ea0 2610 break;
252b5132
RH
2611 }
2612 }
2613
2614 return buf;
2615}
2616
252b5132 2617static const char *
d3ba0551
AM
2618get_osabi_name (unsigned int osabi)
2619{
2620 static char buff[32];
2621
2622 switch (osabi)
2623 {
2624 case ELFOSABI_NONE: return "UNIX - System V";
2625 case ELFOSABI_HPUX: return "UNIX - HP-UX";
2626 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 2627 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
2628 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
2629 case ELFOSABI_AIX: return "UNIX - AIX";
2630 case ELFOSABI_IRIX: return "UNIX - IRIX";
2631 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
2632 case ELFOSABI_TRU64: return "UNIX - TRU64";
2633 case ELFOSABI_MODESTO: return "Novell - Modesto";
2634 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
2635 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
2636 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 2637 case ELFOSABI_AROS: return "AROS";
11636f9e 2638 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 2639 default:
40b36596
JM
2640 if (osabi >= 64)
2641 switch (elf_header.e_machine)
2642 {
2643 case EM_ARM:
2644 switch (osabi)
2645 {
2646 case ELFOSABI_ARM: return "ARM";
2647 default:
2648 break;
2649 }
2650 break;
2651
2652 case EM_MSP430:
2653 case EM_MSP430_OLD:
2654 switch (osabi)
2655 {
2656 case ELFOSABI_STANDALONE: return _("Standalone App");
2657 default:
2658 break;
2659 }
2660 break;
2661
2662 case EM_TI_C6000:
2663 switch (osabi)
2664 {
2665 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
2666 case ELFOSABI_C6000_LINUX: return "Linux C6000";
2667 default:
2668 break;
2669 }
2670 break;
2671
2672 default:
2673 break;
2674 }
e9e44622 2675 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
2676 return buff;
2677 }
2678}
2679
b294bdf8
MM
2680static const char *
2681get_arm_segment_type (unsigned long type)
2682{
2683 switch (type)
2684 {
2685 case PT_ARM_EXIDX:
2686 return "EXIDX";
2687 default:
2688 break;
2689 }
2690
2691 return NULL;
2692}
2693
d3ba0551
AM
2694static const char *
2695get_mips_segment_type (unsigned long type)
252b5132
RH
2696{
2697 switch (type)
2698 {
2699 case PT_MIPS_REGINFO:
2700 return "REGINFO";
2701 case PT_MIPS_RTPROC:
2702 return "RTPROC";
2703 case PT_MIPS_OPTIONS:
2704 return "OPTIONS";
2705 default:
2706 break;
2707 }
2708
2709 return NULL;
2710}
2711
103f02d3 2712static const char *
d3ba0551 2713get_parisc_segment_type (unsigned long type)
103f02d3
UD
2714{
2715 switch (type)
2716 {
2717 case PT_HP_TLS: return "HP_TLS";
2718 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
2719 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
2720 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
2721 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
2722 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
2723 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
2724 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
2725 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
2726 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
2727 case PT_HP_PARALLEL: return "HP_PARALLEL";
2728 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
2729 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
2730 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
2731 case PT_HP_STACK: return "HP_STACK";
2732 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
2733 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
2734 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 2735 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
2736 default:
2737 break;
2738 }
2739
2740 return NULL;
2741}
2742
4d6ed7c8 2743static const char *
d3ba0551 2744get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
2745{
2746 switch (type)
2747 {
2748 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
2749 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
2750 case PT_HP_TLS: return "HP_TLS";
2751 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
2752 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
2753 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
2754 default:
2755 break;
2756 }
2757
2758 return NULL;
2759}
2760
40b36596
JM
2761static const char *
2762get_tic6x_segment_type (unsigned long type)
2763{
2764 switch (type)
2765 {
2766 case PT_C6000_PHATTR: return "C6000_PHATTR";
2767 default:
2768 break;
2769 }
2770
2771 return NULL;
2772}
2773
252b5132 2774static const char *
d3ba0551 2775get_segment_type (unsigned long p_type)
252b5132 2776{
b34976b6 2777 static char buff[32];
252b5132
RH
2778
2779 switch (p_type)
2780 {
b34976b6
AM
2781 case PT_NULL: return "NULL";
2782 case PT_LOAD: return "LOAD";
252b5132 2783 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
2784 case PT_INTERP: return "INTERP";
2785 case PT_NOTE: return "NOTE";
2786 case PT_SHLIB: return "SHLIB";
2787 case PT_PHDR: return "PHDR";
13ae64f3 2788 case PT_TLS: return "TLS";
252b5132 2789
65765700
JJ
2790 case PT_GNU_EH_FRAME:
2791 return "GNU_EH_FRAME";
2b05f1b7 2792 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 2793 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 2794
252b5132
RH
2795 default:
2796 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
2797 {
2cf0635d 2798 const char * result;
103f02d3 2799
252b5132
RH
2800 switch (elf_header.e_machine)
2801 {
b294bdf8
MM
2802 case EM_ARM:
2803 result = get_arm_segment_type (p_type);
2804 break;
252b5132 2805 case EM_MIPS:
4fe85591 2806 case EM_MIPS_RS3_LE:
252b5132
RH
2807 result = get_mips_segment_type (p_type);
2808 break;
103f02d3
UD
2809 case EM_PARISC:
2810 result = get_parisc_segment_type (p_type);
2811 break;
4d6ed7c8
NC
2812 case EM_IA_64:
2813 result = get_ia64_segment_type (p_type);
2814 break;
40b36596
JM
2815 case EM_TI_C6000:
2816 result = get_tic6x_segment_type (p_type);
2817 break;
252b5132
RH
2818 default:
2819 result = NULL;
2820 break;
2821 }
103f02d3 2822
252b5132
RH
2823 if (result != NULL)
2824 return result;
103f02d3 2825
252b5132
RH
2826 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
2827 }
2828 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 2829 {
2cf0635d 2830 const char * result;
103f02d3
UD
2831
2832 switch (elf_header.e_machine)
2833 {
2834 case EM_PARISC:
2835 result = get_parisc_segment_type (p_type);
2836 break;
00428cca
AM
2837 case EM_IA_64:
2838 result = get_ia64_segment_type (p_type);
2839 break;
103f02d3
UD
2840 default:
2841 result = NULL;
2842 break;
2843 }
2844
2845 if (result != NULL)
2846 return result;
2847
2848 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
2849 }
252b5132 2850 else
e9e44622 2851 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
2852
2853 return buff;
2854 }
2855}
2856
2857static const char *
d3ba0551 2858get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
2859{
2860 switch (sh_type)
2861 {
b34976b6
AM
2862 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2863 case SHT_MIPS_MSYM: return "MIPS_MSYM";
2864 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2865 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
2866 case SHT_MIPS_UCODE: return "MIPS_UCODE";
2867 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
2868 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
2869 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
2870 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
2871 case SHT_MIPS_RELD: return "MIPS_RELD";
2872 case SHT_MIPS_IFACE: return "MIPS_IFACE";
2873 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
2874 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2875 case SHT_MIPS_SHDR: return "MIPS_SHDR";
2876 case SHT_MIPS_FDESC: return "MIPS_FDESC";
2877 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
2878 case SHT_MIPS_DENSE: return "MIPS_DENSE";
2879 case SHT_MIPS_PDESC: return "MIPS_PDESC";
2880 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
2881 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
2882 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
2883 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
2884 case SHT_MIPS_LINE: return "MIPS_LINE";
2885 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
2886 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
2887 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
2888 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
2889 case SHT_MIPS_DWARF: return "MIPS_DWARF";
2890 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
2891 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2892 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
2893 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
2894 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
2895 case SHT_MIPS_XLATE: return "MIPS_XLATE";
2896 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
2897 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
2898 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
2899 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132
RH
2900 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
2901 default:
2902 break;
2903 }
2904 return NULL;
2905}
2906
103f02d3 2907static const char *
d3ba0551 2908get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
2909{
2910 switch (sh_type)
2911 {
2912 case SHT_PARISC_EXT: return "PARISC_EXT";
2913 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
2914 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
2915 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
2916 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
2917 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 2918 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
2919 default:
2920 break;
2921 }
2922 return NULL;
2923}
2924
4d6ed7c8 2925static const char *
d3ba0551 2926get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 2927{
18bd398b 2928 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
2929 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
2930 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 2931
4d6ed7c8
NC
2932 switch (sh_type)
2933 {
148b93f2
NC
2934 case SHT_IA_64_EXT: return "IA_64_EXT";
2935 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
2936 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
2937 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
2938 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
2939 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
2940 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
2941 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
2942 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
2943 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
2944 default:
2945 break;
2946 }
2947 return NULL;
2948}
2949
d2b2c203
DJ
2950static const char *
2951get_x86_64_section_type_name (unsigned int sh_type)
2952{
2953 switch (sh_type)
2954 {
2955 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
2956 default:
2957 break;
2958 }
2959 return NULL;
2960}
2961
40a18ebd
NC
2962static const char *
2963get_arm_section_type_name (unsigned int sh_type)
2964{
2965 switch (sh_type)
2966 {
7f6fed87
NC
2967 case SHT_ARM_EXIDX: return "ARM_EXIDX";
2968 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
2969 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
2970 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
2971 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
2972 default:
2973 break;
2974 }
2975 return NULL;
2976}
2977
40b36596
JM
2978static const char *
2979get_tic6x_section_type_name (unsigned int sh_type)
2980{
2981 switch (sh_type)
2982 {
2983 case SHT_C6000_UNWIND:
2984 return "C6000_UNWIND";
2985 case SHT_C6000_PREEMPTMAP:
2986 return "C6000_PREEMPTMAP";
2987 case SHT_C6000_ATTRIBUTES:
2988 return "C6000_ATTRIBUTES";
2989 case SHT_TI_ICODE:
2990 return "TI_ICODE";
2991 case SHT_TI_XREF:
2992 return "TI_XREF";
2993 case SHT_TI_HANDLER:
2994 return "TI_HANDLER";
2995 case SHT_TI_INITINFO:
2996 return "TI_INITINFO";
2997 case SHT_TI_PHATTRS:
2998 return "TI_PHATTRS";
2999 default:
3000 break;
3001 }
3002 return NULL;
3003}
3004
252b5132 3005static const char *
d3ba0551 3006get_section_type_name (unsigned int sh_type)
252b5132 3007{
b34976b6 3008 static char buff[32];
252b5132
RH
3009
3010 switch (sh_type)
3011 {
3012 case SHT_NULL: return "NULL";
3013 case SHT_PROGBITS: return "PROGBITS";
3014 case SHT_SYMTAB: return "SYMTAB";
3015 case SHT_STRTAB: return "STRTAB";
3016 case SHT_RELA: return "RELA";
3017 case SHT_HASH: return "HASH";
3018 case SHT_DYNAMIC: return "DYNAMIC";
3019 case SHT_NOTE: return "NOTE";
3020 case SHT_NOBITS: return "NOBITS";
3021 case SHT_REL: return "REL";
3022 case SHT_SHLIB: return "SHLIB";
3023 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3024 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3025 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3026 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3027 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3028 case SHT_GROUP: return "GROUP";
3029 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3030 case SHT_GNU_verdef: return "VERDEF";
3031 case SHT_GNU_verneed: return "VERNEED";
3032 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3033 case 0x6ffffff0: return "VERSYM";
3034 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3035 case 0x7ffffffd: return "AUXILIARY";
3036 case 0x7fffffff: return "FILTER";
047b2264 3037 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3038
3039 default:
3040 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3041 {
2cf0635d 3042 const char * result;
252b5132
RH
3043
3044 switch (elf_header.e_machine)
3045 {
3046 case EM_MIPS:
4fe85591 3047 case EM_MIPS_RS3_LE:
252b5132
RH
3048 result = get_mips_section_type_name (sh_type);
3049 break;
103f02d3
UD
3050 case EM_PARISC:
3051 result = get_parisc_section_type_name (sh_type);
3052 break;
4d6ed7c8
NC
3053 case EM_IA_64:
3054 result = get_ia64_section_type_name (sh_type);
3055 break;
d2b2c203 3056 case EM_X86_64:
8a9036a4 3057 case EM_L1OM:
7a9068fe 3058 case EM_K1OM:
d2b2c203
DJ
3059 result = get_x86_64_section_type_name (sh_type);
3060 break;
40a18ebd
NC
3061 case EM_ARM:
3062 result = get_arm_section_type_name (sh_type);
3063 break;
40b36596
JM
3064 case EM_TI_C6000:
3065 result = get_tic6x_section_type_name (sh_type);
3066 break;
252b5132
RH
3067 default:
3068 result = NULL;
3069 break;
3070 }
3071
3072 if (result != NULL)
3073 return result;
3074
c91d0dfb 3075 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3076 }
3077 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3078 {
2cf0635d 3079 const char * result;
148b93f2
NC
3080
3081 switch (elf_header.e_machine)
3082 {
3083 case EM_IA_64:
3084 result = get_ia64_section_type_name (sh_type);
3085 break;
3086 default:
3087 result = NULL;
3088 break;
3089 }
3090
3091 if (result != NULL)
3092 return result;
3093
3094 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3095 }
252b5132 3096 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3097 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3098 else
a7dbfd1c
NC
3099 /* This message is probably going to be displayed in a 15
3100 character wide field, so put the hex value first. */
3101 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3102
252b5132
RH
3103 return buff;
3104 }
3105}
3106
2979dc34 3107#define OPTION_DEBUG_DUMP 512
2c610e4b 3108#define OPTION_DYN_SYMS 513
fd2f0033
TT
3109#define OPTION_DWARF_DEPTH 514
3110#define OPTION_DWARF_START 515
2979dc34 3111
85b1c36d 3112static struct option options[] =
252b5132 3113{
b34976b6 3114 {"all", no_argument, 0, 'a'},
252b5132
RH
3115 {"file-header", no_argument, 0, 'h'},
3116 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3117 {"headers", no_argument, 0, 'e'},
3118 {"histogram", no_argument, 0, 'I'},
3119 {"segments", no_argument, 0, 'l'},
3120 {"sections", no_argument, 0, 'S'},
252b5132 3121 {"section-headers", no_argument, 0, 'S'},
f5842774 3122 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3123 {"section-details", no_argument, 0, 't'},
595cf52e 3124 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3125 {"symbols", no_argument, 0, 's'},
3126 {"syms", no_argument, 0, 's'},
2c610e4b 3127 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3128 {"relocs", no_argument, 0, 'r'},
3129 {"notes", no_argument, 0, 'n'},
3130 {"dynamic", no_argument, 0, 'd'},
a952a375 3131 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3132 {"version-info", no_argument, 0, 'V'},
3133 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3134 {"unwind", no_argument, 0, 'u'},
4145f1d5 3135 {"archive-index", no_argument, 0, 'c'},
b34976b6 3136 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3137 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3138 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3139#ifdef SUPPORT_DISASSEMBLY
3140 {"instruction-dump", required_argument, 0, 'i'},
3141#endif
cf13d699 3142 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3143
fd2f0033
TT
3144 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3145 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
3146
b34976b6
AM
3147 {"version", no_argument, 0, 'v'},
3148 {"wide", no_argument, 0, 'W'},
3149 {"help", no_argument, 0, 'H'},
3150 {0, no_argument, 0, 0}
252b5132
RH
3151};
3152
3153static void
2cf0635d 3154usage (FILE * stream)
252b5132 3155{
92f01d61
JM
3156 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3157 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3158 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3159 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3160 -h --file-header Display the ELF file header\n\
3161 -l --program-headers Display the program headers\n\
3162 --segments An alias for --program-headers\n\
3163 -S --section-headers Display the sections' header\n\
3164 --sections An alias for --section-headers\n\
f5842774 3165 -g --section-groups Display the section groups\n\
5477e8a0 3166 -t --section-details Display the section details\n\
8b53311e
NC
3167 -e --headers Equivalent to: -h -l -S\n\
3168 -s --syms Display the symbol table\n\
3f08eb35 3169 --symbols An alias for --syms\n\
2c610e4b 3170 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3171 -n --notes Display the core notes (if present)\n\
3172 -r --relocs Display the relocations (if present)\n\
3173 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3174 -d --dynamic Display the dynamic section (if present)\n\
8b53311e
NC
3175 -V --version-info Display the version sections (if present)\n\
3176 -A --arch-specific Display architecture specific information (if any).\n\
4145f1d5 3177 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3178 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3179 -x --hex-dump=<number|name>\n\
3180 Dump the contents of section <number|name> as bytes\n\
3181 -p --string-dump=<number|name>\n\
3182 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3183 -R --relocated-dump=<number|name>\n\
3184 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3185 -w[lLiaprmfFsoRt] or\n\
1ed06042 3186 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3187 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
5bbdf3d5 3188 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges]\n\
8b53311e 3189 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3190 fprintf (stream, _("\
3191 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3192 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3193 or deeper\n"));
252b5132 3194#ifdef SUPPORT_DISASSEMBLY
92f01d61 3195 fprintf (stream, _("\
09c11c86
NC
3196 -i --instruction-dump=<number|name>\n\
3197 Disassemble the contents of section <number|name>\n"));
252b5132 3198#endif
92f01d61 3199 fprintf (stream, _("\
8b53311e
NC
3200 -I --histogram Display histogram of bucket list lengths\n\
3201 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3202 @<file> Read options from <file>\n\
8b53311e
NC
3203 -H --help Display this information\n\
3204 -v --version Display the version number of readelf\n"));
1118d252 3205
92f01d61
JM
3206 if (REPORT_BUGS_TO[0] && stream == stdout)
3207 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3208
92f01d61 3209 exit (stream == stdout ? 0 : 1);
252b5132
RH
3210}
3211
18bd398b
NC
3212/* Record the fact that the user wants the contents of section number
3213 SECTION to be displayed using the method(s) encoded as flags bits
3214 in TYPE. Note, TYPE can be zero if we are creating the array for
3215 the first time. */
3216
252b5132 3217static void
09c11c86 3218request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3219{
3220 if (section >= num_dump_sects)
3221 {
2cf0635d 3222 dump_type * new_dump_sects;
252b5132 3223
3f5e193b
NC
3224 new_dump_sects = (dump_type *) calloc (section + 1,
3225 sizeof (* dump_sects));
252b5132
RH
3226
3227 if (new_dump_sects == NULL)
591a748a 3228 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3229 else
3230 {
3231 /* Copy current flag settings. */
09c11c86 3232 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3233
3234 free (dump_sects);
3235
3236 dump_sects = new_dump_sects;
3237 num_dump_sects = section + 1;
3238 }
3239 }
3240
3241 if (dump_sects)
b34976b6 3242 dump_sects[section] |= type;
252b5132
RH
3243
3244 return;
3245}
3246
aef1f6d0
DJ
3247/* Request a dump by section name. */
3248
3249static void
2cf0635d 3250request_dump_byname (const char * section, dump_type type)
aef1f6d0 3251{
2cf0635d 3252 struct dump_list_entry * new_request;
aef1f6d0 3253
3f5e193b
NC
3254 new_request = (struct dump_list_entry *)
3255 malloc (sizeof (struct dump_list_entry));
aef1f6d0 3256 if (!new_request)
591a748a 3257 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3258
3259 new_request->name = strdup (section);
3260 if (!new_request->name)
591a748a 3261 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
3262
3263 new_request->type = type;
3264
3265 new_request->next = dump_sects_byname;
3266 dump_sects_byname = new_request;
3267}
3268
cf13d699
NC
3269static inline void
3270request_dump (dump_type type)
3271{
3272 int section;
3273 char * cp;
3274
3275 do_dump++;
3276 section = strtoul (optarg, & cp, 0);
3277
3278 if (! *cp && section >= 0)
3279 request_dump_bynumber (section, type);
3280 else
3281 request_dump_byname (optarg, type);
3282}
3283
3284
252b5132 3285static void
2cf0635d 3286parse_args (int argc, char ** argv)
252b5132
RH
3287{
3288 int c;
3289
3290 if (argc < 2)
92f01d61 3291 usage (stderr);
252b5132
RH
3292
3293 while ((c = getopt_long
cf13d699 3294 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 3295 {
252b5132
RH
3296 switch (c)
3297 {
3298 case 0:
3299 /* Long options. */
3300 break;
3301 case 'H':
92f01d61 3302 usage (stdout);
252b5132
RH
3303 break;
3304
3305 case 'a':
b34976b6
AM
3306 do_syms++;
3307 do_reloc++;
3308 do_unwind++;
3309 do_dynamic++;
3310 do_header++;
3311 do_sections++;
f5842774 3312 do_section_groups++;
b34976b6
AM
3313 do_segments++;
3314 do_version++;
3315 do_histogram++;
3316 do_arch++;
3317 do_notes++;
252b5132 3318 break;
f5842774
L
3319 case 'g':
3320 do_section_groups++;
3321 break;
5477e8a0 3322 case 't':
595cf52e 3323 case 'N':
5477e8a0
L
3324 do_sections++;
3325 do_section_details++;
595cf52e 3326 break;
252b5132 3327 case 'e':
b34976b6
AM
3328 do_header++;
3329 do_sections++;
3330 do_segments++;
252b5132 3331 break;
a952a375 3332 case 'A':
b34976b6 3333 do_arch++;
a952a375 3334 break;
252b5132 3335 case 'D':
b34976b6 3336 do_using_dynamic++;
252b5132
RH
3337 break;
3338 case 'r':
b34976b6 3339 do_reloc++;
252b5132 3340 break;
4d6ed7c8 3341 case 'u':
b34976b6 3342 do_unwind++;
4d6ed7c8 3343 break;
252b5132 3344 case 'h':
b34976b6 3345 do_header++;
252b5132
RH
3346 break;
3347 case 'l':
b34976b6 3348 do_segments++;
252b5132
RH
3349 break;
3350 case 's':
b34976b6 3351 do_syms++;
252b5132
RH
3352 break;
3353 case 'S':
b34976b6 3354 do_sections++;
252b5132
RH
3355 break;
3356 case 'd':
b34976b6 3357 do_dynamic++;
252b5132 3358 break;
a952a375 3359 case 'I':
b34976b6 3360 do_histogram++;
a952a375 3361 break;
779fe533 3362 case 'n':
b34976b6 3363 do_notes++;
779fe533 3364 break;
4145f1d5
NC
3365 case 'c':
3366 do_archive_index++;
3367 break;
252b5132 3368 case 'x':
cf13d699 3369 request_dump (HEX_DUMP);
aef1f6d0 3370 break;
09c11c86 3371 case 'p':
cf13d699
NC
3372 request_dump (STRING_DUMP);
3373 break;
3374 case 'R':
3375 request_dump (RELOC_DUMP);
09c11c86 3376 break;
252b5132 3377 case 'w':
b34976b6 3378 do_dump++;
252b5132 3379 if (optarg == 0)
613ff48b
CC
3380 {
3381 do_debugging = 1;
3382 dwarf_select_sections_all ();
3383 }
252b5132
RH
3384 else
3385 {
3386 do_debugging = 0;
4cb93e3b 3387 dwarf_select_sections_by_letters (optarg);
252b5132
RH
3388 }
3389 break;
2979dc34 3390 case OPTION_DEBUG_DUMP:
b34976b6 3391 do_dump++;
2979dc34
JJ
3392 if (optarg == 0)
3393 do_debugging = 1;
3394 else
3395 {
2979dc34 3396 do_debugging = 0;
4cb93e3b 3397 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
3398 }
3399 break;
fd2f0033
TT
3400 case OPTION_DWARF_DEPTH:
3401 {
3402 char *cp;
3403
3404 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
3405 }
3406 break;
3407 case OPTION_DWARF_START:
3408 {
3409 char *cp;
3410
3411 dwarf_start_die = strtoul (optarg, & cp, 0);
3412 }
3413 break;
2c610e4b
L
3414 case OPTION_DYN_SYMS:
3415 do_dyn_syms++;
3416 break;
252b5132
RH
3417#ifdef SUPPORT_DISASSEMBLY
3418 case 'i':
cf13d699
NC
3419 request_dump (DISASS_DUMP);
3420 break;
252b5132
RH
3421#endif
3422 case 'v':
3423 print_version (program_name);
3424 break;
3425 case 'V':
b34976b6 3426 do_version++;
252b5132 3427 break;
d974e256 3428 case 'W':
b34976b6 3429 do_wide++;
d974e256 3430 break;
252b5132 3431 default:
252b5132
RH
3432 /* xgettext:c-format */
3433 error (_("Invalid option '-%c'\n"), c);
3434 /* Drop through. */
3435 case '?':
92f01d61 3436 usage (stderr);
252b5132
RH
3437 }
3438 }
3439
4d6ed7c8 3440 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 3441 && !do_segments && !do_header && !do_dump && !do_version
f5842774 3442 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
3443 && !do_section_groups && !do_archive_index
3444 && !do_dyn_syms)
92f01d61 3445 usage (stderr);
252b5132
RH
3446 else if (argc < 3)
3447 {
3448 warn (_("Nothing to do.\n"));
92f01d61 3449 usage (stderr);
252b5132
RH
3450 }
3451}
3452
3453static const char *
d3ba0551 3454get_elf_class (unsigned int elf_class)
252b5132 3455{
b34976b6 3456 static char buff[32];
103f02d3 3457
252b5132
RH
3458 switch (elf_class)
3459 {
3460 case ELFCLASSNONE: return _("none");
e3c8793a
NC
3461 case ELFCLASS32: return "ELF32";
3462 case ELFCLASS64: return "ELF64";
ab5e7794 3463 default:
e9e44622 3464 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 3465 return buff;
252b5132
RH
3466 }
3467}
3468
3469static const char *
d3ba0551 3470get_data_encoding (unsigned int encoding)
252b5132 3471{
b34976b6 3472 static char buff[32];
103f02d3 3473
252b5132
RH
3474 switch (encoding)
3475 {
3476 case ELFDATANONE: return _("none");
33c63f9d
CM
3477 case ELFDATA2LSB: return _("2's complement, little endian");
3478 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 3479 default:
e9e44622 3480 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 3481 return buff;
252b5132
RH
3482 }
3483}
3484
252b5132 3485/* Decode the data held in 'elf_header'. */
ee42cf8c 3486
252b5132 3487static int
d3ba0551 3488process_file_header (void)
252b5132 3489{
b34976b6
AM
3490 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
3491 || elf_header.e_ident[EI_MAG1] != ELFMAG1
3492 || elf_header.e_ident[EI_MAG2] != ELFMAG2
3493 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
3494 {
3495 error
3496 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
3497 return 0;
3498 }
3499
2dc4cec1
L
3500 init_dwarf_regnames (elf_header.e_machine);
3501
252b5132
RH
3502 if (do_header)
3503 {
3504 int i;
3505
3506 printf (_("ELF Header:\n"));
3507 printf (_(" Magic: "));
b34976b6
AM
3508 for (i = 0; i < EI_NIDENT; i++)
3509 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
3510 printf ("\n");
3511 printf (_(" Class: %s\n"),
b34976b6 3512 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 3513 printf (_(" Data: %s\n"),
b34976b6 3514 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 3515 printf (_(" Version: %d %s\n"),
b34976b6
AM
3516 elf_header.e_ident[EI_VERSION],
3517 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 3518 ? "(current)"
b34976b6 3519 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 3520 ? _("<unknown: %lx>")
789be9f7 3521 : "")));
252b5132 3522 printf (_(" OS/ABI: %s\n"),
b34976b6 3523 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 3524 printf (_(" ABI Version: %d\n"),
b34976b6 3525 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
3526 printf (_(" Type: %s\n"),
3527 get_file_type (elf_header.e_type));
3528 printf (_(" Machine: %s\n"),
3529 get_machine_name (elf_header.e_machine));
3530 printf (_(" Version: 0x%lx\n"),
3531 (unsigned long) elf_header.e_version);
76da6bbe 3532
f7a99963
NC
3533 printf (_(" Entry point address: "));
3534 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3535 printf (_("\n Start of program headers: "));
3536 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3537 printf (_(" (bytes into file)\n Start of section headers: "));
3538 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
3539 printf (_(" (bytes into file)\n"));
76da6bbe 3540
252b5132
RH
3541 printf (_(" Flags: 0x%lx%s\n"),
3542 (unsigned long) elf_header.e_flags,
3543 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
3544 printf (_(" Size of this header: %ld (bytes)\n"),
3545 (long) elf_header.e_ehsize);
3546 printf (_(" Size of program headers: %ld (bytes)\n"),
3547 (long) elf_header.e_phentsize);
2046a35d 3548 printf (_(" Number of program headers: %ld"),
252b5132 3549 (long) elf_header.e_phnum);
2046a35d
AM
3550 if (section_headers != NULL
3551 && elf_header.e_phnum == PN_XNUM
3552 && section_headers[0].sh_info != 0)
cc5914eb 3553 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 3554 putc ('\n', stdout);
252b5132
RH
3555 printf (_(" Size of section headers: %ld (bytes)\n"),
3556 (long) elf_header.e_shentsize);
560f3c1c 3557 printf (_(" Number of section headers: %ld"),
252b5132 3558 (long) elf_header.e_shnum);
4fbb74a6 3559 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
3560 printf (" (%ld)", (long) section_headers[0].sh_size);
3561 putc ('\n', stdout);
3562 printf (_(" Section header string table index: %ld"),
252b5132 3563 (long) elf_header.e_shstrndx);
4fbb74a6
AM
3564 if (section_headers != NULL
3565 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 3566 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
3567 else if (elf_header.e_shstrndx != SHN_UNDEF
3568 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 3569 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
3570 putc ('\n', stdout);
3571 }
3572
3573 if (section_headers != NULL)
3574 {
2046a35d
AM
3575 if (elf_header.e_phnum == PN_XNUM
3576 && section_headers[0].sh_info != 0)
3577 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 3578 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 3579 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 3580 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 3581 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 3582 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 3583 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
3584 free (section_headers);
3585 section_headers = NULL;
252b5132 3586 }
103f02d3 3587
9ea033b2
NC
3588 return 1;
3589}
3590
252b5132 3591
9ea033b2 3592static int
91d6fa6a 3593get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3594{
2cf0635d
NC
3595 Elf32_External_Phdr * phdrs;
3596 Elf32_External_Phdr * external;
3597 Elf_Internal_Phdr * internal;
b34976b6 3598 unsigned int i;
103f02d3 3599
3f5e193b
NC
3600 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3601 elf_header.e_phentsize,
3602 elf_header.e_phnum,
3603 _("program headers"));
a6e9f9df
AM
3604 if (!phdrs)
3605 return 0;
9ea033b2 3606
91d6fa6a 3607 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3608 i < elf_header.e_phnum;
b34976b6 3609 i++, internal++, external++)
252b5132 3610 {
9ea033b2
NC
3611 internal->p_type = BYTE_GET (external->p_type);
3612 internal->p_offset = BYTE_GET (external->p_offset);
3613 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3614 internal->p_paddr = BYTE_GET (external->p_paddr);
3615 internal->p_filesz = BYTE_GET (external->p_filesz);
3616 internal->p_memsz = BYTE_GET (external->p_memsz);
3617 internal->p_flags = BYTE_GET (external->p_flags);
3618 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
3619 }
3620
9ea033b2
NC
3621 free (phdrs);
3622
252b5132
RH
3623 return 1;
3624}
3625
9ea033b2 3626static int
91d6fa6a 3627get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 3628{
2cf0635d
NC
3629 Elf64_External_Phdr * phdrs;
3630 Elf64_External_Phdr * external;
3631 Elf_Internal_Phdr * internal;
b34976b6 3632 unsigned int i;
103f02d3 3633
3f5e193b
NC
3634 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
3635 elf_header.e_phentsize,
3636 elf_header.e_phnum,
3637 _("program headers"));
a6e9f9df
AM
3638 if (!phdrs)
3639 return 0;
9ea033b2 3640
91d6fa6a 3641 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 3642 i < elf_header.e_phnum;
b34976b6 3643 i++, internal++, external++)
9ea033b2
NC
3644 {
3645 internal->p_type = BYTE_GET (external->p_type);
3646 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
3647 internal->p_offset = BYTE_GET (external->p_offset);
3648 internal->p_vaddr = BYTE_GET (external->p_vaddr);
3649 internal->p_paddr = BYTE_GET (external->p_paddr);
3650 internal->p_filesz = BYTE_GET (external->p_filesz);
3651 internal->p_memsz = BYTE_GET (external->p_memsz);
3652 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
3653 }
3654
3655 free (phdrs);
3656
3657 return 1;
3658}
252b5132 3659
d93f0186
NC
3660/* Returns 1 if the program headers were read into `program_headers'. */
3661
3662static int
2cf0635d 3663get_program_headers (FILE * file)
d93f0186 3664{
2cf0635d 3665 Elf_Internal_Phdr * phdrs;
d93f0186
NC
3666
3667 /* Check cache of prior read. */
3668 if (program_headers != NULL)
3669 return 1;
3670
3f5e193b
NC
3671 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
3672 sizeof (Elf_Internal_Phdr));
d93f0186
NC
3673
3674 if (phdrs == NULL)
3675 {
3676 error (_("Out of memory\n"));
3677 return 0;
3678 }
3679
3680 if (is_32bit_elf
3681 ? get_32bit_program_headers (file, phdrs)
3682 : get_64bit_program_headers (file, phdrs))
3683 {
3684 program_headers = phdrs;
3685 return 1;
3686 }
3687
3688 free (phdrs);
3689 return 0;
3690}
3691
2f62977e
NC
3692/* Returns 1 if the program headers were loaded. */
3693
252b5132 3694static int
2cf0635d 3695process_program_headers (FILE * file)
252b5132 3696{
2cf0635d 3697 Elf_Internal_Phdr * segment;
b34976b6 3698 unsigned int i;
252b5132
RH
3699
3700 if (elf_header.e_phnum == 0)
3701 {
82f2dbf7
NC
3702 /* PR binutils/12467. */
3703 if (elf_header.e_phoff != 0)
3704 warn (_("possibly corrupt ELF header - it has a non-zero program"
3705 " header offset, but no program headers"));
3706 else if (do_segments)
252b5132 3707 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 3708 return 0;
252b5132
RH
3709 }
3710
3711 if (do_segments && !do_header)
3712 {
f7a99963
NC
3713 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
3714 printf (_("Entry point "));
3715 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
3716 printf (_("\nThere are %d program headers, starting at offset "),
3717 elf_header.e_phnum);
3718 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
3719 printf ("\n");
252b5132
RH
3720 }
3721
d93f0186 3722 if (! get_program_headers (file))
252b5132 3723 return 0;
103f02d3 3724
252b5132
RH
3725 if (do_segments)
3726 {
3a1a2036
NC
3727 if (elf_header.e_phnum > 1)
3728 printf (_("\nProgram Headers:\n"));
3729 else
3730 printf (_("\nProgram Headers:\n"));
76da6bbe 3731
f7a99963
NC
3732 if (is_32bit_elf)
3733 printf
3734 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
3735 else if (do_wide)
3736 printf
3737 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
3738 else
3739 {
3740 printf
3741 (_(" Type Offset VirtAddr PhysAddr\n"));
3742 printf
3743 (_(" FileSiz MemSiz Flags Align\n"));
3744 }
252b5132
RH
3745 }
3746
252b5132 3747 dynamic_addr = 0;
1b228002 3748 dynamic_size = 0;
252b5132
RH
3749
3750 for (i = 0, segment = program_headers;
3751 i < elf_header.e_phnum;
b34976b6 3752 i++, segment++)
252b5132
RH
3753 {
3754 if (do_segments)
3755 {
103f02d3 3756 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
3757
3758 if (is_32bit_elf)
3759 {
3760 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3761 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
3762 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
3763 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
3764 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
3765 printf ("%c%c%c ",
3766 (segment->p_flags & PF_R ? 'R' : ' '),
3767 (segment->p_flags & PF_W ? 'W' : ' '),
3768 (segment->p_flags & PF_X ? 'E' : ' '));
3769 printf ("%#lx", (unsigned long) segment->p_align);
3770 }
d974e256
JJ
3771 else if (do_wide)
3772 {
3773 if ((unsigned long) segment->p_offset == segment->p_offset)
3774 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
3775 else
3776 {
3777 print_vma (segment->p_offset, FULL_HEX);
3778 putchar (' ');
3779 }
3780
3781 print_vma (segment->p_vaddr, FULL_HEX);
3782 putchar (' ');
3783 print_vma (segment->p_paddr, FULL_HEX);
3784 putchar (' ');
3785
3786 if ((unsigned long) segment->p_filesz == segment->p_filesz)
3787 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
3788 else
3789 {
3790 print_vma (segment->p_filesz, FULL_HEX);
3791 putchar (' ');
3792 }
3793
3794 if ((unsigned long) segment->p_memsz == segment->p_memsz)
3795 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
3796 else
3797 {
3798 print_vma (segment->p_offset, FULL_HEX);
3799 }
3800
3801 printf (" %c%c%c ",
3802 (segment->p_flags & PF_R ? 'R' : ' '),
3803 (segment->p_flags & PF_W ? 'W' : ' '),
3804 (segment->p_flags & PF_X ? 'E' : ' '));
3805
3806 if ((unsigned long) segment->p_align == segment->p_align)
3807 printf ("%#lx", (unsigned long) segment->p_align);
3808 else
3809 {
3810 print_vma (segment->p_align, PREFIX_HEX);
3811 }
3812 }
f7a99963
NC
3813 else
3814 {
3815 print_vma (segment->p_offset, FULL_HEX);
3816 putchar (' ');
3817 print_vma (segment->p_vaddr, FULL_HEX);
3818 putchar (' ');
3819 print_vma (segment->p_paddr, FULL_HEX);
3820 printf ("\n ");
3821 print_vma (segment->p_filesz, FULL_HEX);
3822 putchar (' ');
3823 print_vma (segment->p_memsz, FULL_HEX);
3824 printf (" %c%c%c ",
3825 (segment->p_flags & PF_R ? 'R' : ' '),
3826 (segment->p_flags & PF_W ? 'W' : ' '),
3827 (segment->p_flags & PF_X ? 'E' : ' '));
3828 print_vma (segment->p_align, HEX);
3829 }
252b5132
RH
3830 }
3831
3832 switch (segment->p_type)
3833 {
252b5132
RH
3834 case PT_DYNAMIC:
3835 if (dynamic_addr)
3836 error (_("more than one dynamic segment\n"));
3837
20737c13
AM
3838 /* By default, assume that the .dynamic section is the first
3839 section in the DYNAMIC segment. */
3840 dynamic_addr = segment->p_offset;
3841 dynamic_size = segment->p_filesz;
3842
b2d38a17
NC
3843 /* Try to locate the .dynamic section. If there is
3844 a section header table, we can easily locate it. */
3845 if (section_headers != NULL)
3846 {
2cf0635d 3847 Elf_Internal_Shdr * sec;
b2d38a17 3848
89fac5e3
RS
3849 sec = find_section (".dynamic");
3850 if (sec == NULL || sec->sh_size == 0)
b2d38a17 3851 {
28f997cf
TG
3852 /* A corresponding .dynamic section is expected, but on
3853 IA-64/OpenVMS it is OK for it to be missing. */
3854 if (!is_ia64_vms ())
3855 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
3856 break;
3857 }
3858
42bb2e33 3859 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
3860 {
3861 dynamic_size = 0;
3862 break;
3863 }
42bb2e33 3864
b2d38a17
NC
3865 dynamic_addr = sec->sh_offset;
3866 dynamic_size = sec->sh_size;
3867
3868 if (dynamic_addr < segment->p_offset
3869 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
3870 warn (_("the .dynamic section is not contained"
3871 " within the dynamic segment\n"));
b2d38a17 3872 else if (dynamic_addr > segment->p_offset)
20737c13
AM
3873 warn (_("the .dynamic section is not the first section"
3874 " in the dynamic segment.\n"));
b2d38a17 3875 }
252b5132
RH
3876 break;
3877
3878 case PT_INTERP:
fb52b2f4
NC
3879 if (fseek (file, archive_file_offset + (long) segment->p_offset,
3880 SEEK_SET))
252b5132
RH
3881 error (_("Unable to find program interpreter name\n"));
3882 else
3883 {
f8eae8b2
L
3884 char fmt [32];
3885 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX);
3886
3887 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 3888 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 3889
252b5132 3890 program_interpreter[0] = 0;
7bd7b3ef
AM
3891 if (fscanf (file, fmt, program_interpreter) <= 0)
3892 error (_("Unable to read program interpreter name\n"));
252b5132
RH
3893
3894 if (do_segments)
3895 printf (_("\n [Requesting program interpreter: %s]"),
3896 program_interpreter);
3897 }
3898 break;
3899 }
3900
3901 if (do_segments)
3902 putc ('\n', stdout);
3903 }
3904
c256ffe7 3905 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
3906 {
3907 printf (_("\n Section to Segment mapping:\n"));
3908 printf (_(" Segment Sections...\n"));
3909
252b5132
RH
3910 for (i = 0; i < elf_header.e_phnum; i++)
3911 {
9ad5cbcf 3912 unsigned int j;
2cf0635d 3913 Elf_Internal_Shdr * section;
252b5132
RH
3914
3915 segment = program_headers + i;
b391a3e3 3916 section = section_headers + 1;
252b5132
RH
3917
3918 printf (" %2.2d ", i);
3919
b34976b6 3920 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 3921 {
f4638467
AM
3922 if (!ELF_TBSS_SPECIAL (section, segment)
3923 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
252b5132
RH
3924 printf ("%s ", SECTION_NAME (section));
3925 }
3926
3927 putc ('\n',stdout);
3928 }
3929 }
3930
252b5132
RH
3931 return 1;
3932}
3933
3934
d93f0186
NC
3935/* Find the file offset corresponding to VMA by using the program headers. */
3936
3937static long
2cf0635d 3938offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 3939{
2cf0635d 3940 Elf_Internal_Phdr * seg;
d93f0186
NC
3941
3942 if (! get_program_headers (file))
3943 {
3944 warn (_("Cannot interpret virtual addresses without program headers.\n"));
3945 return (long) vma;
3946 }
3947
3948 for (seg = program_headers;
3949 seg < program_headers + elf_header.e_phnum;
3950 ++seg)
3951 {
3952 if (seg->p_type != PT_LOAD)
3953 continue;
3954
3955 if (vma >= (seg->p_vaddr & -seg->p_align)
3956 && vma + size <= seg->p_vaddr + seg->p_filesz)
3957 return vma - seg->p_vaddr + seg->p_offset;
3958 }
3959
3960 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 3961 (unsigned long) vma);
d93f0186
NC
3962 return (long) vma;
3963}
3964
3965
252b5132 3966static int
2cf0635d 3967get_32bit_section_headers (FILE * file, unsigned int num)
252b5132 3968{
2cf0635d
NC
3969 Elf32_External_Shdr * shdrs;
3970 Elf_Internal_Shdr * internal;
b34976b6 3971 unsigned int i;
252b5132 3972
3f5e193b
NC
3973 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
3974 elf_header.e_shentsize, num,
3975 _("section headers"));
a6e9f9df
AM
3976 if (!shdrs)
3977 return 0;
252b5132 3978
3f5e193b
NC
3979 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
3980 sizeof (Elf_Internal_Shdr));
252b5132
RH
3981
3982 if (section_headers == NULL)
3983 {
3984 error (_("Out of memory\n"));
3985 return 0;
3986 }
3987
3988 for (i = 0, internal = section_headers;
560f3c1c 3989 i < num;
b34976b6 3990 i++, internal++)
252b5132
RH
3991 {
3992 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
3993 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
3994 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
3995 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
3996 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
3997 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
3998 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
3999 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4000 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4001 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4002 }
4003
4004 free (shdrs);
4005
4006 return 1;
4007}
4008
9ea033b2 4009static int
2cf0635d 4010get_64bit_section_headers (FILE * file, unsigned int num)
9ea033b2 4011{
2cf0635d
NC
4012 Elf64_External_Shdr * shdrs;
4013 Elf_Internal_Shdr * internal;
b34976b6 4014 unsigned int i;
9ea033b2 4015
3f5e193b
NC
4016 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
4017 elf_header.e_shentsize, num,
4018 _("section headers"));
a6e9f9df
AM
4019 if (!shdrs)
4020 return 0;
9ea033b2 4021
3f5e193b
NC
4022 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4023 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4024
4025 if (section_headers == NULL)
4026 {
4027 error (_("Out of memory\n"));
4028 return 0;
4029 }
4030
4031 for (i = 0, internal = section_headers;
560f3c1c 4032 i < num;
b34976b6 4033 i++, internal++)
9ea033b2
NC
4034 {
4035 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4036 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4037 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4038 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4039 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4040 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4041 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4042 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4043 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4044 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4045 }
4046
4047 free (shdrs);
4048
4049 return 1;
4050}
4051
252b5132 4052static Elf_Internal_Sym *
2cf0635d 4053get_32bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
252b5132 4054{
9ad5cbcf 4055 unsigned long number;
dd24e3da 4056 Elf32_External_Sym * esyms = NULL;
2cf0635d 4057 Elf_External_Sym_Shndx * shndx;
dd24e3da 4058 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4059 Elf_Internal_Sym * psym;
b34976b6 4060 unsigned int j;
252b5132 4061
dd24e3da
NC
4062 /* Run some sanity checks first. */
4063 if (section->sh_entsize == 0)
4064 {
4065 error (_("sh_entsize is zero\n"));
4066 return NULL;
4067 }
4068
4069 number = section->sh_size / section->sh_entsize;
4070
4071 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4072 {
4073 error (_("Invalid sh_entsize\n"));
4074 return NULL;
4075 }
4076
3f5e193b
NC
4077 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4078 section->sh_size, _("symbols"));
dd24e3da 4079 if (esyms == NULL)
a6e9f9df 4080 return NULL;
252b5132 4081
9ad5cbcf
AM
4082 shndx = NULL;
4083 if (symtab_shndx_hdr != NULL
4084 && (symtab_shndx_hdr->sh_link
4fbb74a6 4085 == (unsigned long) (section - section_headers)))
9ad5cbcf 4086 {
3f5e193b
NC
4087 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4088 symtab_shndx_hdr->sh_offset,
4089 1, symtab_shndx_hdr->sh_size,
4090 _("symtab shndx"));
dd24e3da
NC
4091 if (shndx == NULL)
4092 goto exit_point;
9ad5cbcf
AM
4093 }
4094
3f5e193b 4095 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4096
4097 if (isyms == NULL)
4098 {
4099 error (_("Out of memory\n"));
dd24e3da 4100 goto exit_point;
252b5132
RH
4101 }
4102
dd24e3da 4103 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4104 {
4105 psym->st_name = BYTE_GET (esyms[j].st_name);
4106 psym->st_value = BYTE_GET (esyms[j].st_value);
4107 psym->st_size = BYTE_GET (esyms[j].st_size);
4108 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4109 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4110 psym->st_shndx
4111 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4112 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4113 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4114 psym->st_info = BYTE_GET (esyms[j].st_info);
4115 psym->st_other = BYTE_GET (esyms[j].st_other);
4116 }
4117
dd24e3da 4118 exit_point:
9ad5cbcf
AM
4119 if (shndx)
4120 free (shndx);
dd24e3da
NC
4121 if (esyms)
4122 free (esyms);
252b5132
RH
4123
4124 return isyms;
4125}
4126
9ea033b2 4127static Elf_Internal_Sym *
2cf0635d 4128get_64bit_elf_symbols (FILE * file, Elf_Internal_Shdr * section)
9ea033b2 4129{
9ad5cbcf 4130 unsigned long number;
2cf0635d
NC
4131 Elf64_External_Sym * esyms;
4132 Elf_External_Sym_Shndx * shndx;
4133 Elf_Internal_Sym * isyms;
4134 Elf_Internal_Sym * psym;
b34976b6 4135 unsigned int j;
9ea033b2 4136
dd24e3da
NC
4137 /* Run some sanity checks first. */
4138 if (section->sh_entsize == 0)
4139 {
4140 error (_("sh_entsize is zero\n"));
4141 return NULL;
4142 }
4143
4144 number = section->sh_size / section->sh_entsize;
4145
4146 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
4147 {
4148 error (_("Invalid sh_entsize\n"));
4149 return NULL;
4150 }
4151
3f5e193b
NC
4152 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4153 section->sh_size, _("symbols"));
a6e9f9df
AM
4154 if (!esyms)
4155 return NULL;
9ea033b2 4156
9ad5cbcf
AM
4157 shndx = NULL;
4158 if (symtab_shndx_hdr != NULL
4159 && (symtab_shndx_hdr->sh_link
4fbb74a6 4160 == (unsigned long) (section - section_headers)))
9ad5cbcf 4161 {
3f5e193b
NC
4162 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4163 symtab_shndx_hdr->sh_offset,
4164 1, symtab_shndx_hdr->sh_size,
4165 _("symtab shndx"));
9ad5cbcf
AM
4166 if (!shndx)
4167 {
4168 free (esyms);
4169 return NULL;
4170 }
4171 }
4172
3f5e193b 4173 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
4174
4175 if (isyms == NULL)
4176 {
4177 error (_("Out of memory\n"));
9ad5cbcf
AM
4178 if (shndx)
4179 free (shndx);
9ea033b2 4180 free (esyms);
9ea033b2
NC
4181 return NULL;
4182 }
4183
4184 for (j = 0, psym = isyms;
4185 j < number;
b34976b6 4186 j++, psym++)
9ea033b2
NC
4187 {
4188 psym->st_name = BYTE_GET (esyms[j].st_name);
4189 psym->st_info = BYTE_GET (esyms[j].st_info);
4190 psym->st_other = BYTE_GET (esyms[j].st_other);
4191 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4192 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4193 psym->st_shndx
4194 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4195 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4196 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
66543521
AM
4197 psym->st_value = BYTE_GET (esyms[j].st_value);
4198 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
4199 }
4200
9ad5cbcf
AM
4201 if (shndx)
4202 free (shndx);
9ea033b2
NC
4203 free (esyms);
4204
4205 return isyms;
4206}
4207
d1133906 4208static const char *
d3ba0551 4209get_elf_section_flags (bfd_vma sh_flags)
d1133906 4210{
5477e8a0 4211 static char buff[1024];
2cf0635d 4212 char * p = buff;
8d5ff12c 4213 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
4214 int sindex;
4215 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
4216 bfd_vma os_flags = 0;
4217 bfd_vma proc_flags = 0;
4218 bfd_vma unknown_flags = 0;
148b93f2 4219 static const struct
5477e8a0 4220 {
2cf0635d 4221 const char * str;
5477e8a0
L
4222 int len;
4223 }
4224 flags [] =
4225 {
cfcac11d
NC
4226 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
4227 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
4228 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
4229 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
4230 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
4231 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
4232 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
4233 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
4234 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
4235 /* 9 */ { STRING_COMMA_LEN ("TLS") },
4236 /* IA-64 specific. */
4237 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
4238 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
4239 /* IA-64 OpenVMS specific. */
4240 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
4241 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
4242 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
4243 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
4244 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
4245 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 4246 /* Generic. */
cfcac11d 4247 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 4248 /* SPARC specific. */
cfcac11d 4249 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
4250 };
4251
4252 if (do_section_details)
4253 {
8d5ff12c
L
4254 sprintf (buff, "[%*.*lx]: ",
4255 field_size, field_size, (unsigned long) sh_flags);
4256 p += field_size + 4;
5477e8a0 4257 }
76da6bbe 4258
d1133906
NC
4259 while (sh_flags)
4260 {
4261 bfd_vma flag;
4262
4263 flag = sh_flags & - sh_flags;
4264 sh_flags &= ~ flag;
76da6bbe 4265
5477e8a0 4266 if (do_section_details)
d1133906 4267 {
5477e8a0
L
4268 switch (flag)
4269 {
91d6fa6a
NC
4270 case SHF_WRITE: sindex = 0; break;
4271 case SHF_ALLOC: sindex = 1; break;
4272 case SHF_EXECINSTR: sindex = 2; break;
4273 case SHF_MERGE: sindex = 3; break;
4274 case SHF_STRINGS: sindex = 4; break;
4275 case SHF_INFO_LINK: sindex = 5; break;
4276 case SHF_LINK_ORDER: sindex = 6; break;
4277 case SHF_OS_NONCONFORMING: sindex = 7; break;
4278 case SHF_GROUP: sindex = 8; break;
4279 case SHF_TLS: sindex = 9; break;
18ae9cc1 4280 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 4281
5477e8a0 4282 default:
91d6fa6a 4283 sindex = -1;
cfcac11d 4284 switch (elf_header.e_machine)
148b93f2 4285 {
cfcac11d 4286 case EM_IA_64:
148b93f2 4287 if (flag == SHF_IA_64_SHORT)
91d6fa6a 4288 sindex = 10;
148b93f2 4289 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 4290 sindex = 11;
148b93f2
NC
4291#ifdef BFD64
4292 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
4293 switch (flag)
4294 {
91d6fa6a
NC
4295 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
4296 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
4297 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
4298 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
4299 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
4300 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
4301 default: break;
4302 }
4303#endif
cfcac11d
NC
4304 break;
4305
caa83f8b
NC
4306 case EM_386:
4307 case EM_486:
4308 case EM_X86_64:
7f502d6c 4309 case EM_L1OM:
7a9068fe 4310 case EM_K1OM:
cfcac11d
NC
4311 case EM_OLD_SPARCV9:
4312 case EM_SPARC32PLUS:
4313 case EM_SPARCV9:
4314 case EM_SPARC:
18ae9cc1 4315 if (flag == SHF_ORDERED)
91d6fa6a 4316 sindex = 19;
cfcac11d
NC
4317 break;
4318 default:
4319 break;
148b93f2 4320 }
5477e8a0
L
4321 }
4322
91d6fa6a 4323 if (sindex != -1)
5477e8a0 4324 {
8d5ff12c
L
4325 if (p != buff + field_size + 4)
4326 {
4327 if (size < (10 + 2))
4328 abort ();
4329 size -= 2;
4330 *p++ = ',';
4331 *p++ = ' ';
4332 }
4333
91d6fa6a
NC
4334 size -= flags [sindex].len;
4335 p = stpcpy (p, flags [sindex].str);
5477e8a0 4336 }
3b22753a 4337 else if (flag & SHF_MASKOS)
8d5ff12c 4338 os_flags |= flag;
d1133906 4339 else if (flag & SHF_MASKPROC)
8d5ff12c 4340 proc_flags |= flag;
d1133906 4341 else
8d5ff12c 4342 unknown_flags |= flag;
5477e8a0
L
4343 }
4344 else
4345 {
4346 switch (flag)
4347 {
4348 case SHF_WRITE: *p = 'W'; break;
4349 case SHF_ALLOC: *p = 'A'; break;
4350 case SHF_EXECINSTR: *p = 'X'; break;
4351 case SHF_MERGE: *p = 'M'; break;
4352 case SHF_STRINGS: *p = 'S'; break;
4353 case SHF_INFO_LINK: *p = 'I'; break;
4354 case SHF_LINK_ORDER: *p = 'L'; break;
4355 case SHF_OS_NONCONFORMING: *p = 'O'; break;
4356 case SHF_GROUP: *p = 'G'; break;
4357 case SHF_TLS: *p = 'T'; break;
18ae9cc1 4358 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
4359
4360 default:
8a9036a4 4361 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
4362 || elf_header.e_machine == EM_L1OM
4363 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
4364 && flag == SHF_X86_64_LARGE)
4365 *p = 'l';
4366 else if (flag & SHF_MASKOS)
4367 {
4368 *p = 'o';
4369 sh_flags &= ~ SHF_MASKOS;
4370 }
4371 else if (flag & SHF_MASKPROC)
4372 {
4373 *p = 'p';
4374 sh_flags &= ~ SHF_MASKPROC;
4375 }
4376 else
4377 *p = 'x';
4378 break;
4379 }
4380 p++;
d1133906
NC
4381 }
4382 }
76da6bbe 4383
8d5ff12c
L
4384 if (do_section_details)
4385 {
4386 if (os_flags)
4387 {
4388 size -= 5 + field_size;
4389 if (p != buff + field_size + 4)
4390 {
4391 if (size < (2 + 1))
4392 abort ();
4393 size -= 2;
4394 *p++ = ',';
4395 *p++ = ' ';
4396 }
4397 sprintf (p, "OS (%*.*lx)", field_size, field_size,
4398 (unsigned long) os_flags);
4399 p += 5 + field_size;
4400 }
4401 if (proc_flags)
4402 {
4403 size -= 7 + field_size;
4404 if (p != buff + field_size + 4)
4405 {
4406 if (size < (2 + 1))
4407 abort ();
4408 size -= 2;
4409 *p++ = ',';
4410 *p++ = ' ';
4411 }
4412 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
4413 (unsigned long) proc_flags);
4414 p += 7 + field_size;
4415 }
4416 if (unknown_flags)
4417 {
4418 size -= 10 + field_size;
4419 if (p != buff + field_size + 4)
4420 {
4421 if (size < (2 + 1))
4422 abort ();
4423 size -= 2;
4424 *p++ = ',';
4425 *p++ = ' ';
4426 }
2b692964 4427 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
4428 (unsigned long) unknown_flags);
4429 p += 10 + field_size;
4430 }
4431 }
4432
e9e44622 4433 *p = '\0';
d1133906
NC
4434 return buff;
4435}
4436
252b5132 4437static int
2cf0635d 4438process_section_headers (FILE * file)
252b5132 4439{
2cf0635d 4440 Elf_Internal_Shdr * section;
b34976b6 4441 unsigned int i;
252b5132
RH
4442
4443 section_headers = NULL;
4444
4445 if (elf_header.e_shnum == 0)
4446 {
82f2dbf7
NC
4447 /* PR binutils/12467. */
4448 if (elf_header.e_shoff != 0)
4449 warn (_("possibly corrupt ELF file header - it has a non-zero"
4450 " section header offset, but no section headers\n"));
4451 else if (do_sections)
252b5132
RH
4452 printf (_("\nThere are no sections in this file.\n"));
4453
4454 return 1;
4455 }
4456
4457 if (do_sections && !do_header)
9ea033b2 4458 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
4459 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
4460
9ea033b2
NC
4461 if (is_32bit_elf)
4462 {
560f3c1c 4463 if (! get_32bit_section_headers (file, elf_header.e_shnum))
9ea033b2
NC
4464 return 0;
4465 }
560f3c1c 4466 else if (! get_64bit_section_headers (file, elf_header.e_shnum))
252b5132
RH
4467 return 0;
4468
4469 /* Read in the string table, so that we have names to display. */
0b49d371 4470 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 4471 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 4472 {
4fbb74a6 4473 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 4474
c256ffe7
JJ
4475 if (section->sh_size != 0)
4476 {
3f5e193b
NC
4477 string_table = (char *) get_data (NULL, file, section->sh_offset,
4478 1, section->sh_size,
4479 _("string table"));
0de14b54 4480
c256ffe7
JJ
4481 string_table_length = string_table != NULL ? section->sh_size : 0;
4482 }
252b5132
RH
4483 }
4484
4485 /* Scan the sections for the dynamic symbol table
e3c8793a 4486 and dynamic string table and debug sections. */
252b5132
RH
4487 dynamic_symbols = NULL;
4488 dynamic_strings = NULL;
4489 dynamic_syminfo = NULL;
f1ef08cb 4490 symtab_shndx_hdr = NULL;
103f02d3 4491
89fac5e3
RS
4492 eh_addr_size = is_32bit_elf ? 4 : 8;
4493 switch (elf_header.e_machine)
4494 {
4495 case EM_MIPS:
4496 case EM_MIPS_RS3_LE:
4497 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
4498 FDE addresses. However, the ABI also has a semi-official ILP32
4499 variant for which the normal FDE address size rules apply.
4500
4501 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
4502 section, where XX is the size of longs in bits. Unfortunately,
4503 earlier compilers provided no way of distinguishing ILP32 objects
4504 from LP64 objects, so if there's any doubt, we should assume that
4505 the official LP64 form is being used. */
4506 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
4507 && find_section (".gcc_compiled_long32") == NULL)
4508 eh_addr_size = 8;
4509 break;
0f56a26a
DD
4510
4511 case EM_H8_300:
4512 case EM_H8_300H:
4513 switch (elf_header.e_flags & EF_H8_MACH)
4514 {
4515 case E_H8_MACH_H8300:
4516 case E_H8_MACH_H8300HN:
4517 case E_H8_MACH_H8300SN:
4518 case E_H8_MACH_H8300SXN:
4519 eh_addr_size = 2;
4520 break;
4521 case E_H8_MACH_H8300H:
4522 case E_H8_MACH_H8300S:
4523 case E_H8_MACH_H8300SX:
4524 eh_addr_size = 4;
4525 break;
4526 }
f4236fe4
DD
4527 break;
4528
ff7eeb89 4529 case EM_M32C_OLD:
f4236fe4
DD
4530 case EM_M32C:
4531 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
4532 {
4533 case EF_M32C_CPU_M16C:
4534 eh_addr_size = 2;
4535 break;
4536 }
4537 break;
89fac5e3
RS
4538 }
4539
08d8fa11
JJ
4540#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
4541 do \
4542 { \
4543 size_t expected_entsize \
4544 = is_32bit_elf ? size32 : size64; \
4545 if (section->sh_entsize != expected_entsize) \
4546 error (_("Section %d has invalid sh_entsize %lx (expected %lx)\n"), \
4547 i, (unsigned long int) section->sh_entsize, \
4548 (unsigned long int) expected_entsize); \
4549 section->sh_entsize = expected_entsize; \
4550 } \
4551 while (0)
4552#define CHECK_ENTSIZE(section, i, type) \
4553 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
4554 sizeof (Elf64_External_##type))
4555
252b5132
RH
4556 for (i = 0, section = section_headers;
4557 i < elf_header.e_shnum;
b34976b6 4558 i++, section++)
252b5132 4559 {
2cf0635d 4560 char * name = SECTION_NAME (section);
252b5132
RH
4561
4562 if (section->sh_type == SHT_DYNSYM)
4563 {
4564 if (dynamic_symbols != NULL)
4565 {
4566 error (_("File contains multiple dynamic symbol tables\n"));
4567 continue;
4568 }
4569
08d8fa11 4570 CHECK_ENTSIZE (section, i, Sym);
19936277 4571 num_dynamic_syms = section->sh_size / section->sh_entsize;
9ad5cbcf 4572 dynamic_symbols = GET_ELF_SYMBOLS (file, section);
252b5132
RH
4573 }
4574 else if (section->sh_type == SHT_STRTAB
18bd398b 4575 && streq (name, ".dynstr"))
252b5132
RH
4576 {
4577 if (dynamic_strings != NULL)
4578 {
4579 error (_("File contains multiple dynamic string tables\n"));
4580 continue;
4581 }
4582
3f5e193b
NC
4583 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
4584 1, section->sh_size,
4585 _("dynamic strings"));
59245841 4586 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 4587 }
9ad5cbcf
AM
4588 else if (section->sh_type == SHT_SYMTAB_SHNDX)
4589 {
4590 if (symtab_shndx_hdr != NULL)
4591 {
4592 error (_("File contains multiple symtab shndx tables\n"));
4593 continue;
4594 }
4595 symtab_shndx_hdr = section;
4596 }
08d8fa11
JJ
4597 else if (section->sh_type == SHT_SYMTAB)
4598 CHECK_ENTSIZE (section, i, Sym);
4599 else if (section->sh_type == SHT_GROUP)
4600 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
4601 else if (section->sh_type == SHT_REL)
4602 CHECK_ENTSIZE (section, i, Rel);
4603 else if (section->sh_type == SHT_RELA)
4604 CHECK_ENTSIZE (section, i, Rela);
252b5132 4605 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 4606 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 4607 || do_debug_aranges || do_debug_frames || do_debug_macinfo
a262ae96 4608 || do_debug_str || do_debug_loc || do_debug_ranges)
1b315056
CS
4609 && (const_strneq (name, ".debug_")
4610 || const_strneq (name, ".zdebug_")))
252b5132 4611 {
1b315056
CS
4612 if (name[1] == 'z')
4613 name += sizeof (".zdebug_") - 1;
4614 else
4615 name += sizeof (".debug_") - 1;
252b5132
RH
4616
4617 if (do_debugging
18bd398b 4618 || (do_debug_info && streq (name, "info"))
2b6f5997 4619 || (do_debug_info && streq (name, "types"))
18bd398b 4620 || (do_debug_abbrevs && streq (name, "abbrev"))
4cb93e3b 4621 || (do_debug_lines && streq (name, "line"))
18bd398b 4622 || (do_debug_pubnames && streq (name, "pubnames"))
f9f0e732 4623 || (do_debug_pubtypes && streq (name, "pubtypes"))
18bd398b
NC
4624 || (do_debug_aranges && streq (name, "aranges"))
4625 || (do_debug_ranges && streq (name, "ranges"))
4626 || (do_debug_frames && streq (name, "frame"))
4627 || (do_debug_macinfo && streq (name, "macinfo"))
4ccf1e31 4628 || (do_debug_macinfo && streq (name, "macro"))
18bd398b
NC
4629 || (do_debug_str && streq (name, "str"))
4630 || (do_debug_loc && streq (name, "loc"))
252b5132 4631 )
09c11c86 4632 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 4633 }
a262ae96 4634 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 4635 else if ((do_debugging || do_debug_info)
0112cd26 4636 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 4637 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 4638 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 4639 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
4640 else if (do_gdb_index && streq (name, ".gdb_index"))
4641 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
4642 /* Trace sections for Itanium VMS. */
4643 else if ((do_debugging || do_trace_info || do_trace_abbrevs
4644 || do_trace_aranges)
4645 && const_strneq (name, ".trace_"))
4646 {
4647 name += sizeof (".trace_") - 1;
4648
4649 if (do_debugging
4650 || (do_trace_info && streq (name, "info"))
4651 || (do_trace_abbrevs && streq (name, "abbrev"))
4652 || (do_trace_aranges && streq (name, "aranges"))
4653 )
4654 request_dump_bynumber (i, DEBUG_DUMP);
4655 }
4656
252b5132
RH
4657 }
4658
4659 if (! do_sections)
4660 return 1;
4661
3a1a2036
NC
4662 if (elf_header.e_shnum > 1)
4663 printf (_("\nSection Headers:\n"));
4664 else
4665 printf (_("\nSection Header:\n"));
76da6bbe 4666
f7a99963 4667 if (is_32bit_elf)
595cf52e 4668 {
5477e8a0 4669 if (do_section_details)
595cf52e
L
4670 {
4671 printf (_(" [Nr] Name\n"));
5477e8a0 4672 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
4673 }
4674 else
4675 printf
4676 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
4677 }
d974e256 4678 else if (do_wide)
595cf52e 4679 {
5477e8a0 4680 if (do_section_details)
595cf52e
L
4681 {
4682 printf (_(" [Nr] Name\n"));
5477e8a0 4683 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
4684 }
4685 else
4686 printf
4687 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
4688 }
f7a99963
NC
4689 else
4690 {
5477e8a0 4691 if (do_section_details)
595cf52e
L
4692 {
4693 printf (_(" [Nr] Name\n"));
5477e8a0
L
4694 printf (_(" Type Address Offset Link\n"));
4695 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
4696 }
4697 else
4698 {
4699 printf (_(" [Nr] Name Type Address Offset\n"));
4700 printf (_(" Size EntSize Flags Link Info Align\n"));
4701 }
f7a99963 4702 }
252b5132 4703
5477e8a0
L
4704 if (do_section_details)
4705 printf (_(" Flags\n"));
4706
252b5132
RH
4707 for (i = 0, section = section_headers;
4708 i < elf_header.e_shnum;
b34976b6 4709 i++, section++)
252b5132 4710 {
5477e8a0 4711 if (do_section_details)
595cf52e
L
4712 {
4713 printf (" [%2u] %s\n",
4fbb74a6 4714 i,
595cf52e
L
4715 SECTION_NAME (section));
4716 if (is_32bit_elf || do_wide)
4717 printf (" %-15.15s ",
4718 get_section_type_name (section->sh_type));
4719 }
4720 else
b9eb56c1
NC
4721 printf ((do_wide ? " [%2u] %-17s %-15s "
4722 : " [%2u] %-17.17s %-15.15s "),
4fbb74a6 4723 i,
595cf52e
L
4724 SECTION_NAME (section),
4725 get_section_type_name (section->sh_type));
252b5132 4726
f7a99963
NC
4727 if (is_32bit_elf)
4728 {
cfcac11d
NC
4729 const char * link_too_big = NULL;
4730
f7a99963 4731 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 4732
f7a99963
NC
4733 printf ( " %6.6lx %6.6lx %2.2lx",
4734 (unsigned long) section->sh_offset,
4735 (unsigned long) section->sh_size,
4736 (unsigned long) section->sh_entsize);
d1133906 4737
5477e8a0
L
4738 if (do_section_details)
4739 fputs (" ", stdout);
4740 else
4741 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4742
cfcac11d
NC
4743 if (section->sh_link >= elf_header.e_shnum)
4744 {
4745 link_too_big = "";
4746 /* The sh_link value is out of range. Normally this indicates
caa83f8b 4747 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
4748 switch (elf_header.e_machine)
4749 {
caa83f8b
NC
4750 case EM_386:
4751 case EM_486:
4752 case EM_X86_64:
7f502d6c 4753 case EM_L1OM:
7a9068fe 4754 case EM_K1OM:
cfcac11d
NC
4755 case EM_OLD_SPARCV9:
4756 case EM_SPARC32PLUS:
4757 case EM_SPARCV9:
4758 case EM_SPARC:
4759 if (section->sh_link == (SHN_BEFORE & 0xffff))
4760 link_too_big = "BEFORE";
4761 else if (section->sh_link == (SHN_AFTER & 0xffff))
4762 link_too_big = "AFTER";
4763 break;
4764 default:
4765 break;
4766 }
4767 }
4768
4769 if (do_section_details)
4770 {
4771 if (link_too_big != NULL && * link_too_big)
4772 printf ("<%s> ", link_too_big);
4773 else
4774 printf ("%2u ", section->sh_link);
4775 printf ("%3u %2lu\n", section->sh_info,
4776 (unsigned long) section->sh_addralign);
4777 }
4778 else
4779 printf ("%2u %3u %2lu\n",
4780 section->sh_link,
4781 section->sh_info,
4782 (unsigned long) section->sh_addralign);
4783
4784 if (link_too_big && ! * link_too_big)
4785 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
4786 i, section->sh_link);
f7a99963 4787 }
d974e256
JJ
4788 else if (do_wide)
4789 {
4790 print_vma (section->sh_addr, LONG_HEX);
4791
4792 if ((long) section->sh_offset == section->sh_offset)
4793 printf (" %6.6lx", (unsigned long) section->sh_offset);
4794 else
4795 {
4796 putchar (' ');
4797 print_vma (section->sh_offset, LONG_HEX);
4798 }
4799
4800 if ((unsigned long) section->sh_size == section->sh_size)
4801 printf (" %6.6lx", (unsigned long) section->sh_size);
4802 else
4803 {
4804 putchar (' ');
4805 print_vma (section->sh_size, LONG_HEX);
4806 }
4807
4808 if ((unsigned long) section->sh_entsize == section->sh_entsize)
4809 printf (" %2.2lx", (unsigned long) section->sh_entsize);
4810 else
4811 {
4812 putchar (' ');
4813 print_vma (section->sh_entsize, LONG_HEX);
4814 }
4815
5477e8a0
L
4816 if (do_section_details)
4817 fputs (" ", stdout);
4818 else
4819 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 4820
72de5009 4821 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
4822
4823 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 4824 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
4825 else
4826 {
4827 print_vma (section->sh_addralign, DEC);
4828 putchar ('\n');
4829 }
4830 }
5477e8a0 4831 else if (do_section_details)
595cf52e 4832 {
5477e8a0 4833 printf (" %-15.15s ",
595cf52e 4834 get_section_type_name (section->sh_type));
595cf52e
L
4835 print_vma (section->sh_addr, LONG_HEX);
4836 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 4837 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
4838 else
4839 {
4840 printf (" ");
4841 print_vma (section->sh_offset, LONG_HEX);
4842 }
72de5009 4843 printf (" %u\n ", section->sh_link);
595cf52e 4844 print_vma (section->sh_size, LONG_HEX);
5477e8a0 4845 putchar (' ');
595cf52e
L
4846 print_vma (section->sh_entsize, LONG_HEX);
4847
72de5009
AM
4848 printf (" %-16u %lu\n",
4849 section->sh_info,
595cf52e
L
4850 (unsigned long) section->sh_addralign);
4851 }
f7a99963
NC
4852 else
4853 {
4854 putchar (' ');
4855 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
4856 if ((long) section->sh_offset == section->sh_offset)
4857 printf (" %8.8lx", (unsigned long) section->sh_offset);
4858 else
4859 {
4860 printf (" ");
4861 print_vma (section->sh_offset, LONG_HEX);
4862 }
f7a99963
NC
4863 printf ("\n ");
4864 print_vma (section->sh_size, LONG_HEX);
4865 printf (" ");
4866 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 4867
d1133906 4868 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 4869
72de5009
AM
4870 printf (" %2u %3u %lu\n",
4871 section->sh_link,
4872 section->sh_info,
f7a99963
NC
4873 (unsigned long) section->sh_addralign);
4874 }
5477e8a0
L
4875
4876 if (do_section_details)
4877 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
4878 }
4879
5477e8a0 4880 if (!do_section_details)
3dbcc61d
NC
4881 {
4882 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
4883 || elf_header.e_machine == EM_L1OM
4884 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
4885 printf (_("Key to Flags:\n\
4886 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
4887 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
4888 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
4889 else
4890 printf (_("Key to Flags:\n\
e3c8793a 4891 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 4892 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 4893 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
3dbcc61d 4894 }
d1133906 4895
252b5132
RH
4896 return 1;
4897}
4898
f5842774
L
4899static const char *
4900get_group_flags (unsigned int flags)
4901{
4902 static char buff[32];
4903 switch (flags)
4904 {
220453ec
AM
4905 case 0:
4906 return "";
4907
f5842774 4908 case GRP_COMDAT:
220453ec 4909 return "COMDAT ";
f5842774
L
4910
4911 default:
220453ec 4912 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
4913 break;
4914 }
4915 return buff;
4916}
4917
4918static int
2cf0635d 4919process_section_groups (FILE * file)
f5842774 4920{
2cf0635d 4921 Elf_Internal_Shdr * section;
f5842774 4922 unsigned int i;
2cf0635d
NC
4923 struct group * group;
4924 Elf_Internal_Shdr * symtab_sec;
4925 Elf_Internal_Shdr * strtab_sec;
4926 Elf_Internal_Sym * symtab;
4927 char * strtab;
c256ffe7 4928 size_t strtab_size;
d1f5c6e3
L
4929
4930 /* Don't process section groups unless needed. */
4931 if (!do_unwind && !do_section_groups)
4932 return 1;
f5842774
L
4933
4934 if (elf_header.e_shnum == 0)
4935 {
4936 if (do_section_groups)
82f2dbf7 4937 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
4938
4939 return 1;
4940 }
4941
4942 if (section_headers == NULL)
4943 {
4944 error (_("Section headers are not available!\n"));
4945 abort ();
4946 }
4947
3f5e193b
NC
4948 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
4949 sizeof (struct group *));
e4b17d5c
L
4950
4951 if (section_headers_groups == NULL)
4952 {
4953 error (_("Out of memory\n"));
4954 return 0;
4955 }
4956
f5842774 4957 /* Scan the sections for the group section. */
d1f5c6e3 4958 group_count = 0;
f5842774
L
4959 for (i = 0, section = section_headers;
4960 i < elf_header.e_shnum;
4961 i++, section++)
e4b17d5c
L
4962 if (section->sh_type == SHT_GROUP)
4963 group_count++;
4964
d1f5c6e3
L
4965 if (group_count == 0)
4966 {
4967 if (do_section_groups)
4968 printf (_("\nThere are no section groups in this file.\n"));
4969
4970 return 1;
4971 }
4972
3f5e193b 4973 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
4974
4975 if (section_groups == NULL)
4976 {
4977 error (_("Out of memory\n"));
4978 return 0;
4979 }
4980
d1f5c6e3
L
4981 symtab_sec = NULL;
4982 strtab_sec = NULL;
4983 symtab = NULL;
4984 strtab = NULL;
c256ffe7 4985 strtab_size = 0;
e4b17d5c
L
4986 for (i = 0, section = section_headers, group = section_groups;
4987 i < elf_header.e_shnum;
4988 i++, section++)
f5842774
L
4989 {
4990 if (section->sh_type == SHT_GROUP)
4991 {
2cf0635d
NC
4992 char * name = SECTION_NAME (section);
4993 char * group_name;
4994 unsigned char * start;
4995 unsigned char * indices;
f5842774 4996 unsigned int entry, j, size;
2cf0635d
NC
4997 Elf_Internal_Shdr * sec;
4998 Elf_Internal_Sym * sym;
f5842774
L
4999
5000 /* Get the symbol table. */
4fbb74a6
AM
5001 if (section->sh_link >= elf_header.e_shnum
5002 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5003 != SHT_SYMTAB))
f5842774
L
5004 {
5005 error (_("Bad sh_link in group section `%s'\n"), name);
5006 continue;
5007 }
d1f5c6e3
L
5008
5009 if (symtab_sec != sec)
5010 {
5011 symtab_sec = sec;
5012 if (symtab)
5013 free (symtab);
5014 symtab = GET_ELF_SYMBOLS (file, symtab_sec);
5015 }
f5842774 5016
dd24e3da
NC
5017 if (symtab == NULL)
5018 {
5019 error (_("Corrupt header in group section `%s'\n"), name);
5020 continue;
5021 }
5022
f5842774
L
5023 sym = symtab + section->sh_info;
5024
5025 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5026 {
4fbb74a6
AM
5027 if (sym->st_shndx == 0
5028 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5029 {
5030 error (_("Bad sh_info in group section `%s'\n"), name);
5031 continue;
5032 }
ba2685cc 5033
4fbb74a6 5034 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5035 strtab_sec = NULL;
5036 if (strtab)
5037 free (strtab);
f5842774 5038 strtab = NULL;
c256ffe7 5039 strtab_size = 0;
f5842774
L
5040 }
5041 else
5042 {
5043 /* Get the string table. */
4fbb74a6 5044 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5045 {
5046 strtab_sec = NULL;
5047 if (strtab)
5048 free (strtab);
5049 strtab = NULL;
5050 strtab_size = 0;
5051 }
5052 else if (strtab_sec
4fbb74a6 5053 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5054 {
5055 strtab_sec = sec;
5056 if (strtab)
5057 free (strtab);
3f5e193b
NC
5058 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
5059 1, strtab_sec->sh_size,
5060 _("string table"));
c256ffe7 5061 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5062 }
c256ffe7 5063 group_name = sym->st_name < strtab_size
2b692964 5064 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5065 }
5066
3f5e193b
NC
5067 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5068 1, section->sh_size,
5069 _("section data"));
59245841
NC
5070 if (start == NULL)
5071 continue;
f5842774
L
5072
5073 indices = start;
5074 size = (section->sh_size / section->sh_entsize) - 1;
5075 entry = byte_get (indices, 4);
5076 indices += 4;
e4b17d5c
L
5077
5078 if (do_section_groups)
5079 {
2b692964 5080 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 5081 get_group_flags (entry), i, name, group_name, size);
ba2685cc 5082
e4b17d5c
L
5083 printf (_(" [Index] Name\n"));
5084 }
5085
5086 group->group_index = i;
5087
f5842774
L
5088 for (j = 0; j < size; j++)
5089 {
2cf0635d 5090 struct group_list * g;
e4b17d5c 5091
f5842774
L
5092 entry = byte_get (indices, 4);
5093 indices += 4;
5094
4fbb74a6 5095 if (entry >= elf_header.e_shnum)
391cb864
L
5096 {
5097 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
5098 entry, i, elf_header.e_shnum - 1);
5099 continue;
5100 }
391cb864 5101
4fbb74a6 5102 if (section_headers_groups [entry] != NULL)
e4b17d5c 5103 {
d1f5c6e3
L
5104 if (entry)
5105 {
391cb864
L
5106 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
5107 entry, i,
4fbb74a6 5108 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5109 continue;
5110 }
5111 else
5112 {
5113 /* Intel C/C++ compiler may put section 0 in a
5114 section group. We just warn it the first time
5115 and ignore it afterwards. */
5116 static int warned = 0;
5117 if (!warned)
5118 {
5119 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 5120 section_headers_groups [entry]->group_index);
d1f5c6e3
L
5121 warned++;
5122 }
5123 }
e4b17d5c
L
5124 }
5125
4fbb74a6 5126 section_headers_groups [entry] = group;
e4b17d5c
L
5127
5128 if (do_section_groups)
5129 {
4fbb74a6 5130 sec = section_headers + entry;
c256ffe7 5131 printf (" [%5u] %s\n", entry, SECTION_NAME (sec));
ba2685cc
AM
5132 }
5133
3f5e193b 5134 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
5135 g->section_index = entry;
5136 g->next = group->root;
5137 group->root = g;
f5842774
L
5138 }
5139
f5842774
L
5140 if (start)
5141 free (start);
e4b17d5c
L
5142
5143 group++;
f5842774
L
5144 }
5145 }
5146
d1f5c6e3
L
5147 if (symtab)
5148 free (symtab);
5149 if (strtab)
5150 free (strtab);
f5842774
L
5151 return 1;
5152}
5153
28f997cf
TG
5154/* Data used to display dynamic fixups. */
5155
5156struct ia64_vms_dynfixup
5157{
5158 bfd_vma needed_ident; /* Library ident number. */
5159 bfd_vma needed; /* Index in the dstrtab of the library name. */
5160 bfd_vma fixup_needed; /* Index of the library. */
5161 bfd_vma fixup_rela_cnt; /* Number of fixups. */
5162 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
5163};
5164
5165/* Data used to display dynamic relocations. */
5166
5167struct ia64_vms_dynimgrela
5168{
5169 bfd_vma img_rela_cnt; /* Number of relocations. */
5170 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
5171};
5172
5173/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
5174 library). */
5175
5176static void
5177dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
5178 const char *strtab, unsigned int strtab_sz)
5179{
5180 Elf64_External_VMS_IMAGE_FIXUP *imfs;
5181 long i;
5182 const char *lib_name;
5183
5184 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
5185 1, fixup->fixup_rela_cnt * sizeof (*imfs),
5186 _("dynamic section image fixups"));
5187 if (!imfs)
5188 return;
5189
5190 if (fixup->needed < strtab_sz)
5191 lib_name = strtab + fixup->needed;
5192 else
5193 {
5194 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 5195 (unsigned long) fixup->needed);
28f997cf
TG
5196 lib_name = "???";
5197 }
5198 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
5199 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
5200 printf
5201 (_("Seg Offset Type SymVec DataType\n"));
5202
5203 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
5204 {
5205 unsigned int type;
5206 const char *rtype;
5207
5208 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
5209 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
5210 type = BYTE_GET (imfs [i].type);
5211 rtype = elf_ia64_reloc_type (type);
5212 if (rtype == NULL)
5213 printf (" 0x%08x ", type);
5214 else
5215 printf (" %-32s ", rtype);
5216 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
5217 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
5218 }
5219
5220 free (imfs);
5221}
5222
5223/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
5224
5225static void
5226dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
5227{
5228 Elf64_External_VMS_IMAGE_RELA *imrs;
5229 long i;
5230
5231 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
5232 1, imgrela->img_rela_cnt * sizeof (*imrs),
5233 _("dynamic section image relas"));
5234 if (!imrs)
5235 return;
5236
5237 printf (_("\nImage relocs\n"));
5238 printf
5239 (_("Seg Offset Type Addend Seg Sym Off\n"));
5240
5241 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
5242 {
5243 unsigned int type;
5244 const char *rtype;
5245
5246 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
5247 printf ("%08" BFD_VMA_FMT "x ",
5248 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
5249 type = BYTE_GET (imrs [i].type);
5250 rtype = elf_ia64_reloc_type (type);
5251 if (rtype == NULL)
5252 printf ("0x%08x ", type);
5253 else
5254 printf ("%-31s ", rtype);
5255 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
5256 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
5257 printf ("%08" BFD_VMA_FMT "x\n",
5258 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
5259 }
5260
5261 free (imrs);
5262}
5263
5264/* Display IA-64 OpenVMS dynamic relocations and fixups. */
5265
5266static int
5267process_ia64_vms_dynamic_relocs (FILE *file)
5268{
5269 struct ia64_vms_dynfixup fixup;
5270 struct ia64_vms_dynimgrela imgrela;
5271 Elf_Internal_Dyn *entry;
5272 int res = 0;
5273 bfd_vma strtab_off = 0;
5274 bfd_vma strtab_sz = 0;
5275 char *strtab = NULL;
5276
5277 memset (&fixup, 0, sizeof (fixup));
5278 memset (&imgrela, 0, sizeof (imgrela));
5279
5280 /* Note: the order of the entries is specified by the OpenVMS specs. */
5281 for (entry = dynamic_section;
5282 entry < dynamic_section + dynamic_nent;
5283 entry++)
5284 {
5285 switch (entry->d_tag)
5286 {
5287 case DT_IA_64_VMS_STRTAB_OFFSET:
5288 strtab_off = entry->d_un.d_val;
5289 break;
5290 case DT_STRSZ:
5291 strtab_sz = entry->d_un.d_val;
5292 if (strtab == NULL)
5293 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
5294 1, strtab_sz, _("dynamic string section"));
5295 break;
5296
5297 case DT_IA_64_VMS_NEEDED_IDENT:
5298 fixup.needed_ident = entry->d_un.d_val;
5299 break;
5300 case DT_NEEDED:
5301 fixup.needed = entry->d_un.d_val;
5302 break;
5303 case DT_IA_64_VMS_FIXUP_NEEDED:
5304 fixup.fixup_needed = entry->d_un.d_val;
5305 break;
5306 case DT_IA_64_VMS_FIXUP_RELA_CNT:
5307 fixup.fixup_rela_cnt = entry->d_un.d_val;
5308 break;
5309 case DT_IA_64_VMS_FIXUP_RELA_OFF:
5310 fixup.fixup_rela_off = entry->d_un.d_val;
5311 res++;
5312 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
5313 break;
5314
5315 case DT_IA_64_VMS_IMG_RELA_CNT:
5316 imgrela.img_rela_cnt = entry->d_un.d_val;
5317 break;
5318 case DT_IA_64_VMS_IMG_RELA_OFF:
5319 imgrela.img_rela_off = entry->d_un.d_val;
5320 res++;
5321 dump_ia64_vms_dynamic_relocs (file, &imgrela);
5322 break;
5323
5324 default:
5325 break;
5326 }
5327 }
5328
5329 if (strtab != NULL)
5330 free (strtab);
5331
5332 return res;
5333}
5334
85b1c36d 5335static struct
566b0d53 5336{
2cf0635d 5337 const char * name;
566b0d53
L
5338 int reloc;
5339 int size;
5340 int rela;
5341} dynamic_relocations [] =
5342{
5343 { "REL", DT_REL, DT_RELSZ, FALSE },
5344 { "RELA", DT_RELA, DT_RELASZ, TRUE },
5345 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
5346};
5347
252b5132 5348/* Process the reloc section. */
18bd398b 5349
252b5132 5350static int
2cf0635d 5351process_relocs (FILE * file)
252b5132 5352{
b34976b6
AM
5353 unsigned long rel_size;
5354 unsigned long rel_offset;
252b5132
RH
5355
5356
5357 if (!do_reloc)
5358 return 1;
5359
5360 if (do_using_dynamic)
5361 {
566b0d53 5362 int is_rela;
2cf0635d 5363 const char * name;
566b0d53
L
5364 int has_dynamic_reloc;
5365 unsigned int i;
0de14b54 5366
566b0d53 5367 has_dynamic_reloc = 0;
252b5132 5368
566b0d53 5369 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 5370 {
566b0d53
L
5371 is_rela = dynamic_relocations [i].rela;
5372 name = dynamic_relocations [i].name;
5373 rel_size = dynamic_info [dynamic_relocations [i].size];
5374 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 5375
566b0d53
L
5376 has_dynamic_reloc |= rel_size;
5377
5378 if (is_rela == UNKNOWN)
aa903cfb 5379 {
566b0d53
L
5380 if (dynamic_relocations [i].reloc == DT_JMPREL)
5381 switch (dynamic_info[DT_PLTREL])
5382 {
5383 case DT_REL:
5384 is_rela = FALSE;
5385 break;
5386 case DT_RELA:
5387 is_rela = TRUE;
5388 break;
5389 }
aa903cfb 5390 }
252b5132 5391
566b0d53
L
5392 if (rel_size)
5393 {
5394 printf
5395 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
5396 name, rel_offset, rel_size);
252b5132 5397
d93f0186
NC
5398 dump_relocations (file,
5399 offset_from_vma (file, rel_offset, rel_size),
5400 rel_size,
566b0d53 5401 dynamic_symbols, num_dynamic_syms,
d79b3d50 5402 dynamic_strings, dynamic_strings_length, is_rela);
566b0d53 5403 }
252b5132 5404 }
566b0d53 5405
28f997cf
TG
5406 if (is_ia64_vms ())
5407 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
5408
566b0d53 5409 if (! has_dynamic_reloc)
252b5132
RH
5410 printf (_("\nThere are no dynamic relocations in this file.\n"));
5411 }
5412 else
5413 {
2cf0635d 5414 Elf_Internal_Shdr * section;
b34976b6
AM
5415 unsigned long i;
5416 int found = 0;
252b5132
RH
5417
5418 for (i = 0, section = section_headers;
5419 i < elf_header.e_shnum;
b34976b6 5420 i++, section++)
252b5132
RH
5421 {
5422 if ( section->sh_type != SHT_RELA
5423 && section->sh_type != SHT_REL)
5424 continue;
5425
5426 rel_offset = section->sh_offset;
5427 rel_size = section->sh_size;
5428
5429 if (rel_size)
5430 {
2cf0635d 5431 Elf_Internal_Shdr * strsec;
b34976b6 5432 int is_rela;
103f02d3 5433
252b5132
RH
5434 printf (_("\nRelocation section "));
5435
5436 if (string_table == NULL)
19936277 5437 printf ("%d", section->sh_name);
252b5132 5438 else
3a1a2036 5439 printf (_("'%s'"), SECTION_NAME (section));
252b5132
RH
5440
5441 printf (_(" at offset 0x%lx contains %lu entries:\n"),
5442 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
5443
d79b3d50
NC
5444 is_rela = section->sh_type == SHT_RELA;
5445
4fbb74a6
AM
5446 if (section->sh_link != 0
5447 && section->sh_link < elf_header.e_shnum)
af3fc3bc 5448 {
2cf0635d
NC
5449 Elf_Internal_Shdr * symsec;
5450 Elf_Internal_Sym * symtab;
d79b3d50 5451 unsigned long nsyms;
c256ffe7 5452 unsigned long strtablen = 0;
2cf0635d 5453 char * strtab = NULL;
57346661 5454
4fbb74a6 5455 symsec = section_headers + section->sh_link;
08d8fa11
JJ
5456 if (symsec->sh_type != SHT_SYMTAB
5457 && symsec->sh_type != SHT_DYNSYM)
5458 continue;
5459
af3fc3bc 5460 nsyms = symsec->sh_size / symsec->sh_entsize;
9ad5cbcf 5461 symtab = GET_ELF_SYMBOLS (file, symsec);
252b5132 5462
af3fc3bc
AM
5463 if (symtab == NULL)
5464 continue;
252b5132 5465
4fbb74a6
AM
5466 if (symsec->sh_link != 0
5467 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 5468 {
4fbb74a6 5469 strsec = section_headers + symsec->sh_link;
103f02d3 5470
3f5e193b
NC
5471 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5472 1, strsec->sh_size,
5473 _("string table"));
c256ffe7
JJ
5474 strtablen = strtab == NULL ? 0 : strsec->sh_size;
5475 }
252b5132 5476
d79b3d50
NC
5477 dump_relocations (file, rel_offset, rel_size,
5478 symtab, nsyms, strtab, strtablen, is_rela);
5479 if (strtab)
5480 free (strtab);
5481 free (symtab);
5482 }
5483 else
5484 dump_relocations (file, rel_offset, rel_size,
5485 NULL, 0, NULL, 0, is_rela);
252b5132
RH
5486
5487 found = 1;
5488 }
5489 }
5490
5491 if (! found)
5492 printf (_("\nThere are no relocations in this file.\n"));
5493 }
5494
5495 return 1;
5496}
5497
57346661
AM
5498/* Process the unwind section. */
5499
4d6ed7c8
NC
5500#include "unwind-ia64.h"
5501
5502/* An absolute address consists of a section and an offset. If the
5503 section is NULL, the offset itself is the address, otherwise, the
5504 address equals to LOAD_ADDRESS(section) + offset. */
5505
5506struct absaddr
5507 {
5508 unsigned short section;
5509 bfd_vma offset;
5510 };
5511
1949de15
L
5512#define ABSADDR(a) \
5513 ((a).section \
5514 ? section_headers [(a).section].sh_addr + (a).offset \
5515 : (a).offset)
5516
3f5e193b
NC
5517struct ia64_unw_table_entry
5518 {
5519 struct absaddr start;
5520 struct absaddr end;
5521 struct absaddr info;
5522 };
5523
57346661 5524struct ia64_unw_aux_info
4d6ed7c8 5525 {
3f5e193b
NC
5526
5527 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 5528 unsigned long table_len; /* Length of unwind table. */
2cf0635d 5529 unsigned char * info; /* Unwind info. */
b34976b6
AM
5530 unsigned long info_size; /* Size of unwind info. */
5531 bfd_vma info_addr; /* starting address of unwind info. */
5532 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5533 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 5534 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5535 char * strtab; /* The string table. */
b34976b6 5536 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
5537 };
5538
4d6ed7c8 5539static void
2cf0635d 5540find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 5541 unsigned long nsyms,
2cf0635d 5542 const char * strtab,
57346661 5543 unsigned long strtab_size,
d3ba0551 5544 struct absaddr addr,
2cf0635d
NC
5545 const char ** symname,
5546 bfd_vma * offset)
4d6ed7c8 5547{
d3ba0551 5548 bfd_vma dist = 0x100000;
2cf0635d
NC
5549 Elf_Internal_Sym * sym;
5550 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
5551 unsigned long i;
5552
0b6ae522
DJ
5553 REMOVE_ARCH_BITS (addr.offset);
5554
57346661 5555 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 5556 {
0b6ae522
DJ
5557 bfd_vma value = sym->st_value;
5558
5559 REMOVE_ARCH_BITS (value);
5560
4d6ed7c8
NC
5561 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
5562 && sym->st_name != 0
5563 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
5564 && addr.offset >= value
5565 && addr.offset - value < dist)
4d6ed7c8
NC
5566 {
5567 best = sym;
0b6ae522 5568 dist = addr.offset - value;
4d6ed7c8
NC
5569 if (!dist)
5570 break;
5571 }
5572 }
5573 if (best)
5574 {
57346661 5575 *symname = (best->st_name >= strtab_size
2b692964 5576 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
5577 *offset = dist;
5578 return;
5579 }
5580 *symname = NULL;
5581 *offset = addr.offset;
5582}
5583
5584static void
2cf0635d 5585dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 5586{
2cf0635d 5587 struct ia64_unw_table_entry * tp;
4d6ed7c8 5588 int in_body;
7036c0e1 5589
4d6ed7c8
NC
5590 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5591 {
5592 bfd_vma stamp;
5593 bfd_vma offset;
2cf0635d
NC
5594 const unsigned char * dp;
5595 const unsigned char * head;
5596 const char * procname;
4d6ed7c8 5597
57346661
AM
5598 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5599 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
5600
5601 fputs ("\n<", stdout);
5602
5603 if (procname)
5604 {
5605 fputs (procname, stdout);
5606
5607 if (offset)
5608 printf ("+%lx", (unsigned long) offset);
5609 }
5610
5611 fputs (">: [", stdout);
5612 print_vma (tp->start.offset, PREFIX_HEX);
5613 fputc ('-', stdout);
5614 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 5615 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
5616 (unsigned long) (tp->info.offset - aux->seg_base));
5617
1949de15 5618 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 5619 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 5620
86f55779 5621 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
5622 (unsigned) UNW_VER (stamp),
5623 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
5624 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
5625 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 5626 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
5627
5628 if (UNW_VER (stamp) != 1)
5629 {
2b692964 5630 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
5631 continue;
5632 }
5633
5634 in_body = 0;
89fac5e3 5635 for (dp = head + 8; dp < head + 8 + eh_addr_size * UNW_LENGTH (stamp);)
4d6ed7c8
NC
5636 dp = unw_decode (dp, in_body, & in_body);
5637 }
5638}
5639
5640static int
2cf0635d
NC
5641slurp_ia64_unwind_table (FILE * file,
5642 struct ia64_unw_aux_info * aux,
5643 Elf_Internal_Shdr * sec)
4d6ed7c8 5644{
89fac5e3 5645 unsigned long size, nrelas, i;
2cf0635d
NC
5646 Elf_Internal_Phdr * seg;
5647 struct ia64_unw_table_entry * tep;
5648 Elf_Internal_Shdr * relsec;
5649 Elf_Internal_Rela * rela;
5650 Elf_Internal_Rela * rp;
5651 unsigned char * table;
5652 unsigned char * tp;
5653 Elf_Internal_Sym * sym;
5654 const char * relname;
4d6ed7c8 5655
4d6ed7c8
NC
5656 /* First, find the starting address of the segment that includes
5657 this section: */
5658
5659 if (elf_header.e_phnum)
5660 {
d93f0186 5661 if (! get_program_headers (file))
4d6ed7c8 5662 return 0;
4d6ed7c8 5663
d93f0186
NC
5664 for (seg = program_headers;
5665 seg < program_headers + elf_header.e_phnum;
5666 ++seg)
4d6ed7c8
NC
5667 {
5668 if (seg->p_type != PT_LOAD)
5669 continue;
5670
5671 if (sec->sh_addr >= seg->p_vaddr
5672 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
5673 {
5674 aux->seg_base = seg->p_vaddr;
5675 break;
5676 }
5677 }
4d6ed7c8
NC
5678 }
5679
5680 /* Second, build the unwind table from the contents of the unwind section: */
5681 size = sec->sh_size;
3f5e193b
NC
5682 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
5683 _("unwind table"));
a6e9f9df
AM
5684 if (!table)
5685 return 0;
4d6ed7c8 5686
3f5e193b
NC
5687 aux->table = (struct ia64_unw_table_entry *)
5688 xcmalloc (size / (3 * eh_addr_size), sizeof (aux->table[0]));
89fac5e3 5689 tep = aux->table;
c6a0c689 5690 for (tp = table; tp < table + size; ++tep)
4d6ed7c8
NC
5691 {
5692 tep->start.section = SHN_UNDEF;
5693 tep->end.section = SHN_UNDEF;
5694 tep->info.section = SHN_UNDEF;
c6a0c689
AM
5695 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5696 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
5697 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
5698 tep->start.offset += aux->seg_base;
5699 tep->end.offset += aux->seg_base;
5700 tep->info.offset += aux->seg_base;
5701 }
5702 free (table);
5703
41e92641 5704 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
5705 for (relsec = section_headers;
5706 relsec < section_headers + elf_header.e_shnum;
5707 ++relsec)
5708 {
5709 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
5710 || relsec->sh_info >= elf_header.e_shnum
5711 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
5712 continue;
5713
5714 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
5715 & rela, & nrelas))
5716 return 0;
5717
5718 for (rp = rela; rp < rela + nrelas; ++rp)
5719 {
aca88567
NC
5720 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
5721 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 5722
0112cd26 5723 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 5724 {
e5fb9629 5725 warn (_("Skipping unexpected relocation type %s\n"), relname);
4d6ed7c8
NC
5726 continue;
5727 }
5728
89fac5e3 5729 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 5730
89fac5e3 5731 switch (rp->r_offset/eh_addr_size % 3)
4d6ed7c8
NC
5732 {
5733 case 0:
5734 aux->table[i].start.section = sym->st_shndx;
e466bc6e 5735 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5736 break;
5737 case 1:
5738 aux->table[i].end.section = sym->st_shndx;
e466bc6e 5739 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5740 break;
5741 case 2:
5742 aux->table[i].info.section = sym->st_shndx;
e466bc6e 5743 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
5744 break;
5745 default:
5746 break;
5747 }
5748 }
5749
5750 free (rela);
5751 }
5752
89fac5e3 5753 aux->table_len = size / (3 * eh_addr_size);
4d6ed7c8
NC
5754 return 1;
5755}
5756
5757static int
2cf0635d 5758ia64_process_unwind (FILE * file)
4d6ed7c8 5759{
2cf0635d
NC
5760 Elf_Internal_Shdr * sec;
5761 Elf_Internal_Shdr * unwsec = NULL;
5762 Elf_Internal_Shdr * strsec;
89fac5e3 5763 unsigned long i, unwcount = 0, unwstart = 0;
57346661 5764 struct ia64_unw_aux_info aux;
f1467e33 5765
4d6ed7c8
NC
5766 memset (& aux, 0, sizeof (aux));
5767
4d6ed7c8
NC
5768 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
5769 {
c256ffe7 5770 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 5771 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8
NC
5772 {
5773 aux.nsyms = sec->sh_size / sec->sh_entsize;
9ad5cbcf 5774 aux.symtab = GET_ELF_SYMBOLS (file, sec);
4d6ed7c8 5775
4fbb74a6 5776 strsec = section_headers + sec->sh_link;
59245841 5777 assert (aux.strtab == NULL);
3f5e193b
NC
5778 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
5779 1, strsec->sh_size,
5780 _("string table"));
c256ffe7 5781 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
5782 }
5783 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
5784 unwcount++;
5785 }
5786
5787 if (!unwcount)
5788 printf (_("\nThere are no unwind sections in this file.\n"));
5789
5790 while (unwcount-- > 0)
5791 {
2cf0635d 5792 char * suffix;
579f31ac
JJ
5793 size_t len, len2;
5794
5795 for (i = unwstart, sec = section_headers + unwstart;
5796 i < elf_header.e_shnum; ++i, ++sec)
5797 if (sec->sh_type == SHT_IA_64_UNWIND)
5798 {
5799 unwsec = sec;
5800 break;
5801 }
5802
5803 unwstart = i + 1;
5804 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
5805
e4b17d5c
L
5806 if ((unwsec->sh_flags & SHF_GROUP) != 0)
5807 {
5808 /* We need to find which section group it is in. */
2cf0635d 5809 struct group_list * g = section_headers_groups [i]->root;
e4b17d5c
L
5810
5811 for (; g != NULL; g = g->next)
5812 {
4fbb74a6 5813 sec = section_headers + g->section_index;
18bd398b
NC
5814
5815 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
57346661 5816 break;
e4b17d5c
L
5817 }
5818
5819 if (g == NULL)
5820 i = elf_header.e_shnum;
5821 }
18bd398b 5822 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 5823 {
18bd398b 5824 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
5825 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
5826 suffix = SECTION_NAME (unwsec) + len;
5827 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5828 ++i, ++sec)
18bd398b
NC
5829 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
5830 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5831 break;
5832 }
5833 else
5834 {
5835 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 5836 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
5837 len = sizeof (ELF_STRING_ia64_unwind) - 1;
5838 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
5839 suffix = "";
18bd398b 5840 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
5841 suffix = SECTION_NAME (unwsec) + len;
5842 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
5843 ++i, ++sec)
18bd398b
NC
5844 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
5845 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
5846 break;
5847 }
5848
5849 if (i == elf_header.e_shnum)
5850 {
5851 printf (_("\nCould not find unwind info section for "));
5852
5853 if (string_table == NULL)
5854 printf ("%d", unwsec->sh_name);
5855 else
3a1a2036 5856 printf (_("'%s'"), SECTION_NAME (unwsec));
579f31ac
JJ
5857 }
5858 else
4d6ed7c8 5859 {
4d6ed7c8 5860 aux.info_addr = sec->sh_addr;
3f5e193b 5861 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
59245841 5862 sec->sh_size,
3f5e193b 5863 _("unwind info"));
59245841 5864 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 5865
579f31ac 5866 printf (_("\nUnwind section "));
4d6ed7c8 5867
579f31ac
JJ
5868 if (string_table == NULL)
5869 printf ("%d", unwsec->sh_name);
5870 else
3a1a2036 5871 printf (_("'%s'"), SECTION_NAME (unwsec));
4d6ed7c8 5872
579f31ac 5873 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 5874 (unsigned long) unwsec->sh_offset,
89fac5e3 5875 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 5876
579f31ac 5877 (void) slurp_ia64_unwind_table (file, & aux, unwsec);
4d6ed7c8 5878
579f31ac
JJ
5879 if (aux.table_len > 0)
5880 dump_ia64_unwind (& aux);
5881
5882 if (aux.table)
5883 free ((char *) aux.table);
5884 if (aux.info)
5885 free ((char *) aux.info);
5886 aux.table = NULL;
5887 aux.info = NULL;
5888 }
4d6ed7c8 5889 }
4d6ed7c8 5890
4d6ed7c8
NC
5891 if (aux.symtab)
5892 free (aux.symtab);
5893 if (aux.strtab)
5894 free ((char *) aux.strtab);
5895
5896 return 1;
5897}
5898
3f5e193b
NC
5899struct hppa_unw_table_entry
5900 {
5901 struct absaddr start;
5902 struct absaddr end;
5903 unsigned int Cannot_unwind:1; /* 0 */
5904 unsigned int Millicode:1; /* 1 */
5905 unsigned int Millicode_save_sr0:1; /* 2 */
5906 unsigned int Region_description:2; /* 3..4 */
5907 unsigned int reserved1:1; /* 5 */
5908 unsigned int Entry_SR:1; /* 6 */
5909 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
5910 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
5911 unsigned int Args_stored:1; /* 16 */
5912 unsigned int Variable_Frame:1; /* 17 */
5913 unsigned int Separate_Package_Body:1; /* 18 */
5914 unsigned int Frame_Extension_Millicode:1; /* 19 */
5915 unsigned int Stack_Overflow_Check:1; /* 20 */
5916 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
5917 unsigned int Ada_Region:1; /* 22 */
5918 unsigned int cxx_info:1; /* 23 */
5919 unsigned int cxx_try_catch:1; /* 24 */
5920 unsigned int sched_entry_seq:1; /* 25 */
5921 unsigned int reserved2:1; /* 26 */
5922 unsigned int Save_SP:1; /* 27 */
5923 unsigned int Save_RP:1; /* 28 */
5924 unsigned int Save_MRP_in_frame:1; /* 29 */
5925 unsigned int extn_ptr_defined:1; /* 30 */
5926 unsigned int Cleanup_defined:1; /* 31 */
5927
5928 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
5929 unsigned int HP_UX_interrupt_marker:1; /* 1 */
5930 unsigned int Large_frame:1; /* 2 */
5931 unsigned int Pseudo_SP_Set:1; /* 3 */
5932 unsigned int reserved4:1; /* 4 */
5933 unsigned int Total_frame_size:27; /* 5..31 */
5934 };
5935
57346661
AM
5936struct hppa_unw_aux_info
5937 {
3f5e193b 5938 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
5939 unsigned long table_len; /* Length of unwind table. */
5940 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 5941 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 5942 unsigned long nsyms; /* Number of symbols. */
2cf0635d 5943 char * strtab; /* The string table. */
57346661
AM
5944 unsigned long strtab_size; /* Size of string table. */
5945 };
5946
5947static void
2cf0635d 5948dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 5949{
2cf0635d 5950 struct hppa_unw_table_entry * tp;
57346661 5951
57346661
AM
5952 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
5953 {
5954 bfd_vma offset;
2cf0635d 5955 const char * procname;
57346661
AM
5956
5957 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
5958 aux->strtab_size, tp->start, &procname,
5959 &offset);
5960
5961 fputs ("\n<", stdout);
5962
5963 if (procname)
5964 {
5965 fputs (procname, stdout);
5966
5967 if (offset)
5968 printf ("+%lx", (unsigned long) offset);
5969 }
5970
5971 fputs (">: [", stdout);
5972 print_vma (tp->start.offset, PREFIX_HEX);
5973 fputc ('-', stdout);
5974 print_vma (tp->end.offset, PREFIX_HEX);
5975 printf ("]\n\t");
5976
18bd398b
NC
5977#define PF(_m) if (tp->_m) printf (#_m " ");
5978#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
5979 PF(Cannot_unwind);
5980 PF(Millicode);
5981 PF(Millicode_save_sr0);
18bd398b 5982 /* PV(Region_description); */
57346661
AM
5983 PF(Entry_SR);
5984 PV(Entry_FR);
5985 PV(Entry_GR);
5986 PF(Args_stored);
5987 PF(Variable_Frame);
5988 PF(Separate_Package_Body);
5989 PF(Frame_Extension_Millicode);
5990 PF(Stack_Overflow_Check);
5991 PF(Two_Instruction_SP_Increment);
5992 PF(Ada_Region);
5993 PF(cxx_info);
5994 PF(cxx_try_catch);
5995 PF(sched_entry_seq);
5996 PF(Save_SP);
5997 PF(Save_RP);
5998 PF(Save_MRP_in_frame);
5999 PF(extn_ptr_defined);
6000 PF(Cleanup_defined);
6001 PF(MPE_XL_interrupt_marker);
6002 PF(HP_UX_interrupt_marker);
6003 PF(Large_frame);
6004 PF(Pseudo_SP_Set);
6005 PV(Total_frame_size);
6006#undef PF
6007#undef PV
6008 }
6009
18bd398b 6010 printf ("\n");
57346661
AM
6011}
6012
6013static int
2cf0635d
NC
6014slurp_hppa_unwind_table (FILE * file,
6015 struct hppa_unw_aux_info * aux,
6016 Elf_Internal_Shdr * sec)
57346661 6017{
1c0751b2 6018 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
6019 Elf_Internal_Phdr * seg;
6020 struct hppa_unw_table_entry * tep;
6021 Elf_Internal_Shdr * relsec;
6022 Elf_Internal_Rela * rela;
6023 Elf_Internal_Rela * rp;
6024 unsigned char * table;
6025 unsigned char * tp;
6026 Elf_Internal_Sym * sym;
6027 const char * relname;
57346661 6028
57346661
AM
6029 /* First, find the starting address of the segment that includes
6030 this section. */
6031
6032 if (elf_header.e_phnum)
6033 {
6034 if (! get_program_headers (file))
6035 return 0;
6036
6037 for (seg = program_headers;
6038 seg < program_headers + elf_header.e_phnum;
6039 ++seg)
6040 {
6041 if (seg->p_type != PT_LOAD)
6042 continue;
6043
6044 if (sec->sh_addr >= seg->p_vaddr
6045 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6046 {
6047 aux->seg_base = seg->p_vaddr;
6048 break;
6049 }
6050 }
6051 }
6052
6053 /* Second, build the unwind table from the contents of the unwind
6054 section. */
6055 size = sec->sh_size;
3f5e193b
NC
6056 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6057 _("unwind table"));
57346661
AM
6058 if (!table)
6059 return 0;
6060
1c0751b2
DA
6061 unw_ent_size = 16;
6062 nentries = size / unw_ent_size;
6063 size = unw_ent_size * nentries;
57346661 6064
3f5e193b
NC
6065 tep = aux->table = (struct hppa_unw_table_entry *)
6066 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 6067
1c0751b2 6068 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
6069 {
6070 unsigned int tmp1, tmp2;
6071
6072 tep->start.section = SHN_UNDEF;
6073 tep->end.section = SHN_UNDEF;
6074
1c0751b2
DA
6075 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
6076 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
6077 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
6078 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
6079
6080 tep->start.offset += aux->seg_base;
6081 tep->end.offset += aux->seg_base;
57346661
AM
6082
6083 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
6084 tep->Millicode = (tmp1 >> 30) & 0x1;
6085 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
6086 tep->Region_description = (tmp1 >> 27) & 0x3;
6087 tep->reserved1 = (tmp1 >> 26) & 0x1;
6088 tep->Entry_SR = (tmp1 >> 25) & 0x1;
6089 tep->Entry_FR = (tmp1 >> 21) & 0xf;
6090 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
6091 tep->Args_stored = (tmp1 >> 15) & 0x1;
6092 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
6093 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
6094 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
6095 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
6096 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
6097 tep->Ada_Region = (tmp1 >> 9) & 0x1;
6098 tep->cxx_info = (tmp1 >> 8) & 0x1;
6099 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
6100 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
6101 tep->reserved2 = (tmp1 >> 5) & 0x1;
6102 tep->Save_SP = (tmp1 >> 4) & 0x1;
6103 tep->Save_RP = (tmp1 >> 3) & 0x1;
6104 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
6105 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
6106 tep->Cleanup_defined = tmp1 & 0x1;
6107
6108 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
6109 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
6110 tep->Large_frame = (tmp2 >> 29) & 0x1;
6111 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
6112 tep->reserved4 = (tmp2 >> 27) & 0x1;
6113 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
6114 }
6115 free (table);
6116
6117 /* Third, apply any relocations to the unwind table. */
57346661
AM
6118 for (relsec = section_headers;
6119 relsec < section_headers + elf_header.e_shnum;
6120 ++relsec)
6121 {
6122 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6123 || relsec->sh_info >= elf_header.e_shnum
6124 || section_headers + relsec->sh_info != sec)
57346661
AM
6125 continue;
6126
6127 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6128 & rela, & nrelas))
6129 return 0;
6130
6131 for (rp = rela; rp < rela + nrelas; ++rp)
6132 {
aca88567
NC
6133 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
6134 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
6135
6136 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 6137 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
6138 {
6139 warn (_("Skipping unexpected relocation type %s\n"), relname);
6140 continue;
6141 }
6142
6143 i = rp->r_offset / unw_ent_size;
6144
89fac5e3 6145 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
6146 {
6147 case 0:
6148 aux->table[i].start.section = sym->st_shndx;
1e456d54 6149 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
6150 break;
6151 case 1:
6152 aux->table[i].end.section = sym->st_shndx;
1e456d54 6153 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
6154 break;
6155 default:
6156 break;
6157 }
6158 }
6159
6160 free (rela);
6161 }
6162
1c0751b2 6163 aux->table_len = nentries;
57346661
AM
6164
6165 return 1;
6166}
6167
6168static int
2cf0635d 6169hppa_process_unwind (FILE * file)
57346661 6170{
57346661 6171 struct hppa_unw_aux_info aux;
2cf0635d
NC
6172 Elf_Internal_Shdr * unwsec = NULL;
6173 Elf_Internal_Shdr * strsec;
6174 Elf_Internal_Shdr * sec;
18bd398b 6175 unsigned long i;
57346661
AM
6176
6177 memset (& aux, 0, sizeof (aux));
6178
c256ffe7
JJ
6179 if (string_table == NULL)
6180 return 1;
57346661
AM
6181
6182 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6183 {
c256ffe7 6184 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6185 && sec->sh_link < elf_header.e_shnum)
57346661
AM
6186 {
6187 aux.nsyms = sec->sh_size / sec->sh_entsize;
6188 aux.symtab = GET_ELF_SYMBOLS (file, sec);
6189
4fbb74a6 6190 strsec = section_headers + sec->sh_link;
59245841 6191 assert (aux.strtab == NULL);
3f5e193b
NC
6192 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6193 1, strsec->sh_size,
6194 _("string table"));
c256ffe7 6195 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 6196 }
18bd398b 6197 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
6198 unwsec = sec;
6199 }
6200
6201 if (!unwsec)
6202 printf (_("\nThere are no unwind sections in this file.\n"));
6203
6204 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6205 {
18bd398b 6206 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 6207 {
57346661
AM
6208 printf (_("\nUnwind section "));
6209 printf (_("'%s'"), SECTION_NAME (sec));
6210
6211 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6212 (unsigned long) sec->sh_offset,
89fac5e3 6213 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
6214
6215 slurp_hppa_unwind_table (file, &aux, sec);
6216 if (aux.table_len > 0)
6217 dump_hppa_unwind (&aux);
6218
6219 if (aux.table)
6220 free ((char *) aux.table);
6221 aux.table = NULL;
6222 }
6223 }
6224
6225 if (aux.symtab)
6226 free (aux.symtab);
6227 if (aux.strtab)
6228 free ((char *) aux.strtab);
6229
6230 return 1;
6231}
6232
0b6ae522
DJ
6233struct arm_section
6234{
6235 unsigned char *data;
6236
6237 Elf_Internal_Shdr *sec;
6238 Elf_Internal_Rela *rela;
6239 unsigned long nrelas;
6240 unsigned int rel_type;
6241
6242 Elf_Internal_Rela *next_rela;
6243};
6244
6245struct arm_unw_aux_info
6246{
6247 FILE *file;
6248
6249 Elf_Internal_Sym *symtab; /* The symbol table. */
6250 unsigned long nsyms; /* Number of symbols. */
6251 char *strtab; /* The string table. */
6252 unsigned long strtab_size; /* Size of string table. */
6253};
6254
6255static const char *
6256arm_print_vma_and_name (struct arm_unw_aux_info *aux,
6257 bfd_vma fn, struct absaddr addr)
6258{
6259 const char *procname;
6260 bfd_vma sym_offset;
6261
6262 if (addr.section == SHN_UNDEF)
6263 addr.offset = fn;
6264
6265 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6266 aux->strtab_size, addr, &procname,
6267 &sym_offset);
6268
6269 print_vma (fn, PREFIX_HEX);
6270
6271 if (procname)
6272 {
6273 fputs (" <", stdout);
6274 fputs (procname, stdout);
6275
6276 if (sym_offset)
6277 printf ("+0x%lx", (unsigned long) sym_offset);
6278 fputc ('>', stdout);
6279 }
6280
6281 return procname;
6282}
6283
6284static void
6285arm_free_section (struct arm_section *arm_sec)
6286{
6287 if (arm_sec->data != NULL)
6288 free (arm_sec->data);
6289
6290 if (arm_sec->rela != NULL)
6291 free (arm_sec->rela);
6292}
6293
6294static int
6295arm_section_get_word (struct arm_unw_aux_info *aux,
6296 struct arm_section *arm_sec,
6297 Elf_Internal_Shdr *sec, bfd_vma word_offset,
6298 unsigned int *wordp, struct absaddr *addr)
6299{
6300 Elf_Internal_Rela *rp;
6301 Elf_Internal_Sym *sym;
6302 const char * relname;
6303 unsigned int word;
6304 bfd_boolean wrapped;
6305
6306 addr->section = SHN_UNDEF;
6307 addr->offset = 0;
6308
6309 if (sec != arm_sec->sec)
6310 {
6311 Elf_Internal_Shdr *relsec;
6312
6313 arm_free_section (arm_sec);
6314
6315 arm_sec->sec = sec;
6316 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
6317 sec->sh_size, _("unwind data"));
0b6ae522
DJ
6318 arm_sec->rela = NULL;
6319 arm_sec->nrelas = 0;
6320
6321 for (relsec = section_headers;
6322 relsec < section_headers + elf_header.e_shnum;
6323 ++relsec)
6324 {
6325 if (relsec->sh_info >= elf_header.e_shnum
6326 || section_headers + relsec->sh_info != sec)
6327 continue;
6328
6329 if (relsec->sh_type == SHT_REL)
6330 {
6331 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
6332 relsec->sh_size,
6333 & arm_sec->rela, & arm_sec->nrelas))
6334 return 0;
6335 break;
6336 }
6337 else if (relsec->sh_type == SHT_RELA)
6338 {
6339 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
6340 relsec->sh_size,
6341 & arm_sec->rela, & arm_sec->nrelas))
6342 return 0;
6343 break;
6344 }
6345 }
6346
6347 arm_sec->next_rela = arm_sec->rela;
6348 }
6349
6350 if (arm_sec->data == NULL)
6351 return 0;
6352
6353 word = byte_get (arm_sec->data + word_offset, 4);
6354
6355 wrapped = FALSE;
6356 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
6357 {
6358 bfd_vma prelval, offset;
6359
6360 if (rp->r_offset > word_offset && !wrapped)
6361 {
6362 rp = arm_sec->rela;
6363 wrapped = TRUE;
6364 }
6365 if (rp->r_offset > word_offset)
6366 break;
6367
6368 if (rp->r_offset & 3)
6369 {
6370 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
6371 (unsigned long) rp->r_offset);
6372 continue;
6373 }
6374
6375 if (rp->r_offset < word_offset)
6376 continue;
6377
fa197c1c
PB
6378 switch (elf_header.e_machine)
6379 {
6380 case EM_ARM:
6381 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
6382 break;
6383
6384 case EM_TI_C6000:
6385 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
6386 break;
6387
6388 default:
6389 abort();
6390 }
0b6ae522 6391
fa197c1c
PB
6392 if (streq (relname, "R_ARM_NONE")
6393 || streq (relname, "R_C6000_NONE"))
0b6ae522
DJ
6394 continue;
6395
fa197c1c
PB
6396 if (!(streq (relname, "R_ARM_PREL31")
6397 || streq (relname, "R_C6000_PREL31")))
0b6ae522
DJ
6398 {
6399 warn (_("Skipping unexpected relocation type %s\n"), relname);
6400 continue;
6401 }
6402
6403 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
6404
6405 if (arm_sec->rel_type == SHT_REL)
6406 {
6407 offset = word & 0x7fffffff;
6408 if (offset & 0x40000000)
6409 offset |= ~ (bfd_vma) 0x7fffffff;
6410 }
6411 else
6412 offset = rp->r_addend;
6413
6414 offset += sym->st_value;
6415 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
6416
fa197c1c
PB
6417 if (streq (relname, "R_C6000_PREL31"))
6418 prelval >>= 1;
6419
0b6ae522
DJ
6420 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
6421 addr->section = sym->st_shndx;
6422 addr->offset = offset;
6423 break;
6424 }
6425
6426 *wordp = word;
6427 arm_sec->next_rela = rp;
6428
6429 return 1;
6430}
6431
fa197c1c
PB
6432static const char *tic6x_unwind_regnames[16] = {
6433 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
6434 "A14", "A13", "A12", "A11", "A10",
6435 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"};
6436
0b6ae522 6437static void
fa197c1c 6438decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 6439{
fa197c1c
PB
6440 int i;
6441
6442 for (i = 12; mask; mask >>= 1, i--)
6443 {
6444 if (mask & 1)
6445 {
6446 fputs (tic6x_unwind_regnames[i], stdout);
6447 if (mask > 1)
6448 fputs (", ", stdout);
6449 }
6450 }
6451}
0b6ae522
DJ
6452
6453#define ADVANCE \
6454 if (remaining == 0 && more_words) \
6455 { \
6456 data_offset += 4; \
6457 if (!arm_section_get_word (aux, data_arm_sec, data_sec, \
6458 data_offset, &word, &addr)) \
6459 return; \
6460 remaining = 4; \
6461 more_words--; \
6462 } \
6463
6464#define GET_OP(OP) \
6465 ADVANCE; \
6466 if (remaining) \
6467 { \
6468 remaining--; \
6469 (OP) = word >> 24; \
6470 word <<= 8; \
6471 } \
6472 else \
6473 { \
2b692964 6474 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
6475 return; \
6476 } \
cc5914eb 6477 printf ("0x%02x ", OP)
0b6ae522 6478
fa197c1c
PB
6479static void
6480decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
6481 unsigned int word, unsigned int remaining,
6482 unsigned int more_words,
6483 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6484 struct arm_section *data_arm_sec)
6485{
6486 struct absaddr addr;
0b6ae522
DJ
6487
6488 /* Decode the unwinding instructions. */
6489 while (1)
6490 {
6491 unsigned int op, op2;
6492
6493 ADVANCE;
6494 if (remaining == 0)
6495 break;
6496 remaining--;
6497 op = word >> 24;
6498 word <<= 8;
6499
cc5914eb 6500 printf (" 0x%02x ", op);
0b6ae522
DJ
6501
6502 if ((op & 0xc0) == 0x00)
6503 {
6504 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6505
cc5914eb 6506 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
6507 }
6508 else if ((op & 0xc0) == 0x40)
6509 {
6510 int offset = ((op & 0x3f) << 2) + 4;
61865e30 6511
cc5914eb 6512 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
6513 }
6514 else if ((op & 0xf0) == 0x80)
6515 {
6516 GET_OP (op2);
6517 if (op == 0x80 && op2 == 0)
6518 printf (_("Refuse to unwind"));
6519 else
6520 {
6521 unsigned int mask = ((op & 0x0f) << 8) | op2;
6522 int first = 1;
6523 int i;
2b692964 6524
0b6ae522
DJ
6525 printf ("pop {");
6526 for (i = 0; i < 12; i++)
6527 if (mask & (1 << i))
6528 {
6529 if (first)
6530 first = 0;
6531 else
6532 printf (", ");
6533 printf ("r%d", 4 + i);
6534 }
6535 printf ("}");
6536 }
6537 }
6538 else if ((op & 0xf0) == 0x90)
6539 {
6540 if (op == 0x9d || op == 0x9f)
6541 printf (_(" [Reserved]"));
6542 else
cc5914eb 6543 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
6544 }
6545 else if ((op & 0xf0) == 0xa0)
6546 {
6547 int end = 4 + (op & 0x07);
6548 int first = 1;
6549 int i;
61865e30 6550
0b6ae522
DJ
6551 printf (" pop {");
6552 for (i = 4; i <= end; i++)
6553 {
6554 if (first)
6555 first = 0;
6556 else
6557 printf (", ");
6558 printf ("r%d", i);
6559 }
6560 if (op & 0x08)
6561 {
6562 if (first)
6563 printf (", ");
6564 printf ("r14");
6565 }
6566 printf ("}");
6567 }
6568 else if (op == 0xb0)
6569 printf (_(" finish"));
6570 else if (op == 0xb1)
6571 {
6572 GET_OP (op2);
6573 if (op2 == 0 || (op2 & 0xf0) != 0)
6574 printf (_("[Spare]"));
6575 else
6576 {
6577 unsigned int mask = op2 & 0x0f;
6578 int first = 1;
6579 int i;
61865e30 6580
0b6ae522
DJ
6581 printf ("pop {");
6582 for (i = 0; i < 12; i++)
6583 if (mask & (1 << i))
6584 {
6585 if (first)
6586 first = 0;
6587 else
6588 printf (", ");
6589 printf ("r%d", i);
6590 }
6591 printf ("}");
6592 }
6593 }
6594 else if (op == 0xb2)
6595 {
b115cf96 6596 unsigned char buf[9];
0b6ae522
DJ
6597 unsigned int i, len;
6598 unsigned long offset;
61865e30 6599
b115cf96 6600 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
6601 {
6602 GET_OP (buf[i]);
6603 if ((buf[i] & 0x80) == 0)
6604 break;
6605 }
6606 assert (i < sizeof (buf));
6607 offset = read_uleb128 (buf, &len);
6608 assert (len == i + 1);
6609 offset = offset * 4 + 0x204;
cc5914eb 6610 printf ("vsp = vsp + %ld", offset);
0b6ae522 6611 }
61865e30 6612 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 6613 {
61865e30
NC
6614 unsigned int first, last;
6615
6616 GET_OP (op2);
6617 first = op2 >> 4;
6618 last = op2 & 0x0f;
6619 if (op == 0xc8)
6620 first = first + 16;
6621 printf ("pop {D%d", first);
6622 if (last)
6623 printf ("-D%d", first + last);
6624 printf ("}");
6625 }
6626 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
6627 {
6628 unsigned int count = op & 0x07;
6629
6630 printf ("pop {D8");
6631 if (count)
6632 printf ("-D%d", 8 + count);
6633 printf ("}");
6634 }
6635 else if (op >= 0xc0 && op <= 0xc5)
6636 {
6637 unsigned int count = op & 0x07;
6638
6639 printf (" pop {wR10");
6640 if (count)
6641 printf ("-wR%d", 10 + count);
6642 printf ("}");
6643 }
6644 else if (op == 0xc6)
6645 {
6646 unsigned int first, last;
6647
6648 GET_OP (op2);
6649 first = op2 >> 4;
6650 last = op2 & 0x0f;
6651 printf ("pop {wR%d", first);
6652 if (last)
6653 printf ("-wR%d", first + last);
6654 printf ("}");
6655 }
6656 else if (op == 0xc7)
6657 {
6658 GET_OP (op2);
6659 if (op2 == 0 || (op2 & 0xf0) != 0)
6660 printf (_("[Spare]"));
0b6ae522
DJ
6661 else
6662 {
61865e30
NC
6663 unsigned int mask = op2 & 0x0f;
6664 int first = 1;
6665 int i;
6666
6667 printf ("pop {");
6668 for (i = 0; i < 4; i++)
6669 if (mask & (1 << i))
6670 {
6671 if (first)
6672 first = 0;
6673 else
6674 printf (", ");
6675 printf ("wCGR%d", i);
6676 }
6677 printf ("}");
0b6ae522
DJ
6678 }
6679 }
61865e30
NC
6680 else
6681 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
6682 printf ("\n");
6683 }
fa197c1c
PB
6684}
6685
6686static void
6687decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
6688 unsigned int word, unsigned int remaining,
6689 unsigned int more_words,
6690 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6691 struct arm_section *data_arm_sec)
6692{
6693 struct absaddr addr;
6694
6695 /* Decode the unwinding instructions. */
6696 while (1)
6697 {
6698 unsigned int op, op2;
6699
6700 ADVANCE;
6701 if (remaining == 0)
6702 break;
6703 remaining--;
6704 op = word >> 24;
6705 word <<= 8;
6706
6707 printf (_(" 0x%02x "), op);
6708
6709 if ((op & 0xc0) == 0x00)
6710 {
6711 int offset = ((op & 0x3f) << 3) + 8;
6712 printf (_(" sp = sp + %d"), offset);
6713 }
6714 else if ((op & 0xc0) == 0x80)
6715 {
6716 GET_OP (op2);
6717 if (op == 0x80 && op2 == 0)
6718 printf (_("Refuse to unwind"));
6719 else
6720 {
6721 unsigned int mask = ((op & 0x1f) << 8) | op2;
6722 if (op & 0x20)
6723 printf ("pop compact {");
6724 else
6725 printf ("pop {");
6726
6727 decode_tic6x_unwind_regmask (mask);
6728 printf("}");
6729 }
6730 }
6731 else if ((op & 0xf0) == 0xc0)
6732 {
6733 unsigned int reg;
6734 unsigned int nregs;
6735 unsigned int i;
6736 const char *name;
6737 struct {
6738 unsigned int offset;
6739 unsigned int reg;
6740 } regpos[16];
6741
6742 /* Scan entire instruction first so that GET_OP output is not
6743 interleaved with disassembly. */
6744 nregs = 0;
6745 for (i = 0; nregs < (op & 0xf); i++)
6746 {
6747 GET_OP (op2);
6748 reg = op2 >> 4;
6749 if (reg != 0xf)
6750 {
6751 regpos[nregs].offset = i * 2;
6752 regpos[nregs].reg = reg;
6753 nregs++;
6754 }
6755
6756 reg = op2 & 0xf;
6757 if (reg != 0xf)
6758 {
6759 regpos[nregs].offset = i * 2 + 1;
6760 regpos[nregs].reg = reg;
6761 nregs++;
6762 }
6763 }
6764
6765 printf (_("pop frame {"));
6766 reg = nregs - 1;
6767 for (i = i * 2; i > 0; i--)
6768 {
6769 if (regpos[reg].offset == i - 1)
6770 {
6771 name = tic6x_unwind_regnames[regpos[reg].reg];
6772 if (reg > 0)
6773 reg--;
6774 }
6775 else
6776 name = _("[pad]");
6777
6778 fputs (name, stdout);
6779 if (i > 1)
6780 printf (", ");
6781 }
6782
6783 printf ("}");
6784 }
6785 else if (op == 0xd0)
6786 printf (" MOV FP, SP");
6787 else if (op == 0xd1)
6788 printf (" __c6xabi_pop_rts");
6789 else if (op == 0xd2)
6790 {
6791 unsigned char buf[9];
6792 unsigned int i, len;
6793 unsigned long offset;
6794 for (i = 0; i < sizeof (buf); i++)
6795 {
6796 GET_OP (buf[i]);
6797 if ((buf[i] & 0x80) == 0)
6798 break;
6799 }
6800 assert (i < sizeof (buf));
6801 offset = read_uleb128 (buf, &len);
6802 assert (len == i + 1);
6803 offset = offset * 8 + 0x408;
6804 printf (_("sp = sp + %ld"), offset);
6805 }
6806 else if ((op & 0xf0) == 0xe0)
6807 {
6808 if ((op & 0x0f) == 7)
6809 printf (" RETURN");
6810 else
6811 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
6812 }
6813 else
6814 {
6815 printf (_(" [unsupported opcode]"));
6816 }
6817 putchar ('\n');
6818 }
6819}
6820
6821static bfd_vma
6822expand_prel31 (bfd_vma word, bfd_vma where)
6823{
6824 bfd_vma offset;
6825
6826 offset = word & 0x7fffffff;
6827 if (offset & 0x40000000)
6828 offset |= ~ (bfd_vma) 0x7fffffff;
6829
6830 if (elf_header.e_machine == EM_TI_C6000)
6831 offset <<= 1;
6832
6833 return offset + where;
6834}
6835
6836static void
6837decode_arm_unwind (struct arm_unw_aux_info *aux,
6838 unsigned int word, unsigned int remaining,
6839 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
6840 struct arm_section *data_arm_sec)
6841{
6842 int per_index;
6843 unsigned int more_words = 0;
6844 struct absaddr addr;
6845
6846 if (remaining == 0)
6847 {
6848 /* Fetch the first word. */
6849 if (!arm_section_get_word (aux, data_arm_sec, data_sec, data_offset,
6850 &word, &addr))
6851 return;
6852 remaining = 4;
6853 }
6854
6855 if ((word & 0x80000000) == 0)
6856 {
6857 /* Expand prel31 for personality routine. */
6858 bfd_vma fn;
6859 const char *procname;
6860
6861 fn = expand_prel31 (word, data_sec->sh_addr + data_offset);
6862 printf (_(" Personality routine: "));
6863 procname = arm_print_vma_and_name (aux, fn, addr);
6864 fputc ('\n', stdout);
6865
6866 /* The GCC personality routines use the standard compact
6867 encoding, starting with one byte giving the number of
6868 words. */
6869 if (procname != NULL
6870 && (const_strneq (procname, "__gcc_personality_v0")
6871 || const_strneq (procname, "__gxx_personality_v0")
6872 || const_strneq (procname, "__gcj_personality_v0")
6873 || const_strneq (procname, "__gnu_objc_personality_v0")))
6874 {
6875 remaining = 0;
6876 more_words = 1;
6877 ADVANCE;
6878 if (!remaining)
6879 {
6880 printf (_(" [Truncated data]\n"));
6881 return;
6882 }
6883 more_words = word >> 24;
6884 word <<= 8;
6885 remaining--;
6886 per_index = -1;
6887 }
6888 else
6889 return;
6890 }
6891 else
6892 {
6893
6894 per_index = (word >> 24) & 0x7f;
6895 printf (_(" Compact model %d\n"), per_index);
6896 if (per_index == 0)
6897 {
6898 more_words = 0;
6899 word <<= 8;
6900 remaining--;
6901 }
6902 else if (per_index < 3)
6903 {
6904 more_words = (word >> 16) & 0xff;
6905 word <<= 16;
6906 remaining -= 2;
6907 }
6908 }
6909
6910 switch (elf_header.e_machine)
6911 {
6912 case EM_ARM:
6913 if (per_index < 3)
6914 {
6915 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
6916 data_offset, data_sec, data_arm_sec);
6917 }
6918 else
6919 printf (" [reserved]\n");
6920 break;
6921
6922 case EM_TI_C6000:
6923 if (per_index < 3)
6924 {
6925 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
6926 data_offset, data_sec, data_arm_sec);
6927 }
6928 else if (per_index < 5)
6929 {
6930 if (((word >> 17) & 0x7f) == 0x7f)
6931 printf (_(" Restore stack from frame pointer\n"));
6932 else
6933 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
6934 printf (_(" Registers restored: "));
6935 if (per_index == 4)
6936 printf (" (compact) ");
6937 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
6938 putchar ('\n');
6939 printf (_(" Return register: %s\n"),
6940 tic6x_unwind_regnames[word & 0xf]);
6941 }
6942 else
6943 printf (" [reserved]\n");
6944 break;
6945
6946 default:
6947 abort ();
6948 }
0b6ae522
DJ
6949
6950 /* Decode the descriptors. Not implemented. */
6951}
6952
6953static void
6954dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
6955{
6956 struct arm_section exidx_arm_sec, extab_arm_sec;
6957 unsigned int i, exidx_len;
6958
6959 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
6960 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
6961 exidx_len = exidx_sec->sh_size / 8;
6962
6963 for (i = 0; i < exidx_len; i++)
6964 {
6965 unsigned int exidx_fn, exidx_entry;
6966 struct absaddr fn_addr, entry_addr;
6967 bfd_vma fn;
6968
6969 fputc ('\n', stdout);
6970
6971 if (!arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6972 8 * i, &exidx_fn, &fn_addr)
6973 || !arm_section_get_word (aux, &exidx_arm_sec, exidx_sec,
6974 8 * i + 4, &exidx_entry, &entry_addr))
6975 {
6976 arm_free_section (&exidx_arm_sec);
6977 arm_free_section (&extab_arm_sec);
6978 return;
6979 }
6980
fa197c1c 6981 fn = expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522
DJ
6982
6983 arm_print_vma_and_name (aux, fn, entry_addr);
6984 fputs (": ", stdout);
6985
6986 if (exidx_entry == 1)
6987 {
6988 print_vma (exidx_entry, PREFIX_HEX);
6989 fputs (" [cantunwind]\n", stdout);
6990 }
6991 else if (exidx_entry & 0x80000000)
6992 {
6993 print_vma (exidx_entry, PREFIX_HEX);
6994 fputc ('\n', stdout);
6995 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
6996 }
6997 else
6998 {
8f73510c 6999 bfd_vma table, table_offset = 0;
0b6ae522
DJ
7000 Elf_Internal_Shdr *table_sec;
7001
7002 fputs ("@", stdout);
fa197c1c 7003 table = expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
7004 print_vma (table, PREFIX_HEX);
7005 printf ("\n");
7006
7007 /* Locate the matching .ARM.extab. */
7008 if (entry_addr.section != SHN_UNDEF
7009 && entry_addr.section < elf_header.e_shnum)
7010 {
7011 table_sec = section_headers + entry_addr.section;
7012 table_offset = entry_addr.offset;
7013 }
7014 else
7015 {
7016 table_sec = find_section_by_address (table);
7017 if (table_sec != NULL)
7018 table_offset = table - table_sec->sh_addr;
7019 }
7020 if (table_sec == NULL)
7021 {
7022 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
7023 (unsigned long) table);
7024 continue;
7025 }
7026 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
7027 &extab_arm_sec);
7028 }
7029 }
7030
7031 printf ("\n");
7032
7033 arm_free_section (&exidx_arm_sec);
7034 arm_free_section (&extab_arm_sec);
7035}
7036
fa197c1c 7037/* Used for both ARM and C6X unwinding tables. */
0b6ae522
DJ
7038static int
7039arm_process_unwind (FILE *file)
7040{
7041 struct arm_unw_aux_info aux;
7042 Elf_Internal_Shdr *unwsec = NULL;
7043 Elf_Internal_Shdr *strsec;
7044 Elf_Internal_Shdr *sec;
7045 unsigned long i;
fa197c1c 7046 unsigned int sec_type;
0b6ae522
DJ
7047
7048 memset (& aux, 0, sizeof (aux));
7049 aux.file = file;
7050
fa197c1c
PB
7051 switch (elf_header.e_machine)
7052 {
7053 case EM_ARM:
7054 sec_type = SHT_ARM_EXIDX;
7055 break;
7056
7057 case EM_TI_C6000:
7058 sec_type = SHT_C6000_UNWIND;
7059 break;
7060
7061 default:
7062 abort();
7063 }
7064
0b6ae522
DJ
7065 if (string_table == NULL)
7066 return 1;
7067
7068 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7069 {
7070 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
7071 {
7072 aux.nsyms = sec->sh_size / sec->sh_entsize;
7073 aux.symtab = GET_ELF_SYMBOLS (file, sec);
7074
7075 strsec = section_headers + sec->sh_link;
59245841 7076 assert (aux.strtab == NULL);
0b6ae522
DJ
7077 aux.strtab = get_data (NULL, file, strsec->sh_offset,
7078 1, strsec->sh_size, _("string table"));
7079 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
7080 }
fa197c1c 7081 else if (sec->sh_type == sec_type)
0b6ae522
DJ
7082 unwsec = sec;
7083 }
7084
7085 if (!unwsec)
7086 printf (_("\nThere are no unwind sections in this file.\n"));
7087
7088 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7089 {
fa197c1c 7090 if (sec->sh_type == sec_type)
0b6ae522
DJ
7091 {
7092 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
7093 SECTION_NAME (sec),
7094 (unsigned long) sec->sh_offset,
7095 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
7096
7097 dump_arm_unwind (&aux, sec);
7098 }
7099 }
7100
7101 if (aux.symtab)
7102 free (aux.symtab);
7103 if (aux.strtab)
7104 free ((char *) aux.strtab);
7105
7106 return 1;
7107}
7108
57346661 7109static int
2cf0635d 7110process_unwind (FILE * file)
57346661 7111{
2cf0635d
NC
7112 struct unwind_handler
7113 {
57346661 7114 int machtype;
2cf0635d
NC
7115 int (* handler)(FILE *);
7116 } handlers[] =
7117 {
0b6ae522 7118 { EM_ARM, arm_process_unwind },
57346661
AM
7119 { EM_IA_64, ia64_process_unwind },
7120 { EM_PARISC, hppa_process_unwind },
fa197c1c 7121 { EM_TI_C6000, arm_process_unwind },
57346661
AM
7122 { 0, 0 }
7123 };
7124 int i;
7125
7126 if (!do_unwind)
7127 return 1;
7128
7129 for (i = 0; handlers[i].handler != NULL; i++)
7130 if (elf_header.e_machine == handlers[i].machtype)
18bd398b 7131 return handlers[i].handler (file);
57346661
AM
7132
7133 printf (_("\nThere are no unwind sections in this file.\n"));
7134 return 1;
7135}
7136
252b5132 7137static void
2cf0635d 7138dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
7139{
7140 switch (entry->d_tag)
7141 {
7142 case DT_MIPS_FLAGS:
7143 if (entry->d_un.d_val == 0)
2b692964 7144 printf (_("NONE\n"));
252b5132
RH
7145 else
7146 {
7147 static const char * opts[] =
7148 {
7149 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
7150 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
7151 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
7152 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
7153 "RLD_ORDER_SAFE"
7154 };
7155 unsigned int cnt;
7156 int first = 1;
2b692964 7157
60bca95a 7158 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
7159 if (entry->d_un.d_val & (1 << cnt))
7160 {
7161 printf ("%s%s", first ? "" : " ", opts[cnt]);
7162 first = 0;
7163 }
7164 puts ("");
7165 }
7166 break;
103f02d3 7167
252b5132 7168 case DT_MIPS_IVERSION:
d79b3d50 7169 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
2b692964 7170 printf (_("Interface Version: %s\n"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7171 else
2b692964 7172 printf (_("<corrupt: %ld>\n"), (long) entry->d_un.d_ptr);
252b5132 7173 break;
103f02d3 7174
252b5132
RH
7175 case DT_MIPS_TIME_STAMP:
7176 {
7177 char timebuf[20];
2cf0635d 7178 struct tm * tmp;
50da7a9c 7179
91d6fa6a
NC
7180 time_t atime = entry->d_un.d_val;
7181 tmp = gmtime (&atime);
e9e44622
JJ
7182 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
7183 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
7184 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
2b692964 7185 printf (_("Time Stamp: %s\n"), timebuf);
252b5132
RH
7186 }
7187 break;
103f02d3 7188
252b5132
RH
7189 case DT_MIPS_RLD_VERSION:
7190 case DT_MIPS_LOCAL_GOTNO:
7191 case DT_MIPS_CONFLICTNO:
7192 case DT_MIPS_LIBLISTNO:
7193 case DT_MIPS_SYMTABNO:
7194 case DT_MIPS_UNREFEXTNO:
7195 case DT_MIPS_HIPAGENO:
7196 case DT_MIPS_DELTA_CLASS_NO:
7197 case DT_MIPS_DELTA_INSTANCE_NO:
7198 case DT_MIPS_DELTA_RELOC_NO:
7199 case DT_MIPS_DELTA_SYM_NO:
7200 case DT_MIPS_DELTA_CLASSSYM_NO:
7201 case DT_MIPS_COMPACT_SIZE:
7202 printf ("%ld\n", (long) entry->d_un.d_ptr);
7203 break;
103f02d3
UD
7204
7205 default:
0af1713e 7206 printf ("%#lx\n", (unsigned long) entry->d_un.d_ptr);
103f02d3
UD
7207 }
7208}
7209
103f02d3 7210static void
2cf0635d 7211dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
7212{
7213 switch (entry->d_tag)
7214 {
7215 case DT_HP_DLD_FLAGS:
7216 {
7217 static struct
7218 {
7219 long int bit;
2cf0635d 7220 const char * str;
5e220199
NC
7221 }
7222 flags[] =
7223 {
7224 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
7225 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
7226 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
7227 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
7228 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
7229 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
7230 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
7231 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
7232 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
7233 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
7234 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
7235 { DT_HP_GST, "HP_GST" },
7236 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
7237 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
7238 { DT_HP_NODELETE, "HP_NODELETE" },
7239 { DT_HP_GROUP, "HP_GROUP" },
7240 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 7241 };
103f02d3 7242 int first = 1;
5e220199 7243 size_t cnt;
f7a99963 7244 bfd_vma val = entry->d_un.d_val;
103f02d3 7245
60bca95a 7246 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 7247 if (val & flags[cnt].bit)
30800947
NC
7248 {
7249 if (! first)
7250 putchar (' ');
7251 fputs (flags[cnt].str, stdout);
7252 first = 0;
7253 val ^= flags[cnt].bit;
7254 }
76da6bbe 7255
103f02d3 7256 if (val != 0 || first)
f7a99963
NC
7257 {
7258 if (! first)
7259 putchar (' ');
7260 print_vma (val, HEX);
7261 }
103f02d3
UD
7262 }
7263 break;
76da6bbe 7264
252b5132 7265 default:
f7a99963
NC
7266 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7267 break;
252b5132 7268 }
35b1837e 7269 putchar ('\n');
252b5132
RH
7270}
7271
28f997cf
TG
7272#ifdef BFD64
7273
7274/* VMS vs Unix time offset and factor. */
7275
7276#define VMS_EPOCH_OFFSET 35067168000000000LL
7277#define VMS_GRANULARITY_FACTOR 10000000
7278
7279/* Display a VMS time in a human readable format. */
7280
7281static void
7282print_vms_time (bfd_int64_t vmstime)
7283{
7284 struct tm *tm;
7285 time_t unxtime;
7286
7287 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
7288 tm = gmtime (&unxtime);
7289 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
7290 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
7291 tm->tm_hour, tm->tm_min, tm->tm_sec);
7292}
7293#endif /* BFD64 */
7294
ecc51f48 7295static void
2cf0635d 7296dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
7297{
7298 switch (entry->d_tag)
7299 {
0de14b54 7300 case DT_IA_64_PLT_RESERVE:
bdf4d63a 7301 /* First 3 slots reserved. */
ecc51f48
NC
7302 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7303 printf (" -- ");
7304 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
7305 break;
7306
28f997cf
TG
7307 case DT_IA_64_VMS_LINKTIME:
7308#ifdef BFD64
7309 print_vms_time (entry->d_un.d_val);
7310#endif
7311 break;
7312
7313 case DT_IA_64_VMS_LNKFLAGS:
7314 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7315 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
7316 printf (" CALL_DEBUG");
7317 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
7318 printf (" NOP0BUFS");
7319 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
7320 printf (" P0IMAGE");
7321 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
7322 printf (" MKTHREADS");
7323 if (entry->d_un.d_val & VMS_LF_UPCALLS)
7324 printf (" UPCALLS");
7325 if (entry->d_un.d_val & VMS_LF_IMGSTA)
7326 printf (" IMGSTA");
7327 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
7328 printf (" INITIALIZE");
7329 if (entry->d_un.d_val & VMS_LF_MAIN)
7330 printf (" MAIN");
7331 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
7332 printf (" EXE_INIT");
7333 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
7334 printf (" TBK_IN_IMG");
7335 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
7336 printf (" DBG_IN_IMG");
7337 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
7338 printf (" TBK_IN_DSF");
7339 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
7340 printf (" DBG_IN_DSF");
7341 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
7342 printf (" SIGNATURES");
7343 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
7344 printf (" REL_SEG_OFF");
7345 break;
7346
bdf4d63a
JJ
7347 default:
7348 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
7349 break;
ecc51f48 7350 }
bdf4d63a 7351 putchar ('\n');
ecc51f48
NC
7352}
7353
252b5132 7354static int
2cf0635d 7355get_32bit_dynamic_section (FILE * file)
252b5132 7356{
2cf0635d
NC
7357 Elf32_External_Dyn * edyn;
7358 Elf32_External_Dyn * ext;
7359 Elf_Internal_Dyn * entry;
103f02d3 7360
3f5e193b
NC
7361 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7362 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7363 if (!edyn)
7364 return 0;
103f02d3 7365
ba2685cc
AM
7366/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7367 might not have the luxury of section headers. Look for the DT_NULL
7368 terminator to determine the number of entries. */
7369 for (ext = edyn, dynamic_nent = 0;
7370 (char *) ext < (char *) edyn + dynamic_size;
7371 ext++)
7372 {
7373 dynamic_nent++;
7374 if (BYTE_GET (ext->d_tag) == DT_NULL)
7375 break;
7376 }
252b5132 7377
3f5e193b
NC
7378 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7379 sizeof (* entry));
b2d38a17 7380 if (dynamic_section == NULL)
252b5132 7381 {
9ea033b2
NC
7382 error (_("Out of memory\n"));
7383 free (edyn);
7384 return 0;
7385 }
252b5132 7386
fb514b26 7387 for (ext = edyn, entry = dynamic_section;
ba2685cc 7388 entry < dynamic_section + dynamic_nent;
fb514b26 7389 ext++, entry++)
9ea033b2 7390 {
fb514b26
AM
7391 entry->d_tag = BYTE_GET (ext->d_tag);
7392 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7393 }
7394
9ea033b2
NC
7395 free (edyn);
7396
7397 return 1;
7398}
7399
7400static int
2cf0635d 7401get_64bit_dynamic_section (FILE * file)
9ea033b2 7402{
2cf0635d
NC
7403 Elf64_External_Dyn * edyn;
7404 Elf64_External_Dyn * ext;
7405 Elf_Internal_Dyn * entry;
103f02d3 7406
3f5e193b
NC
7407 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
7408 dynamic_size, _("dynamic section"));
a6e9f9df
AM
7409 if (!edyn)
7410 return 0;
103f02d3 7411
ba2685cc
AM
7412/* SGI's ELF has more than one section in the DYNAMIC segment, and we
7413 might not have the luxury of section headers. Look for the DT_NULL
7414 terminator to determine the number of entries. */
7415 for (ext = edyn, dynamic_nent = 0;
7416 (char *) ext < (char *) edyn + dynamic_size;
7417 ext++)
7418 {
7419 dynamic_nent++;
66543521 7420 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
7421 break;
7422 }
252b5132 7423
3f5e193b
NC
7424 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
7425 sizeof (* entry));
b2d38a17 7426 if (dynamic_section == NULL)
252b5132
RH
7427 {
7428 error (_("Out of memory\n"));
7429 free (edyn);
7430 return 0;
7431 }
7432
fb514b26 7433 for (ext = edyn, entry = dynamic_section;
ba2685cc 7434 entry < dynamic_section + dynamic_nent;
fb514b26 7435 ext++, entry++)
252b5132 7436 {
66543521
AM
7437 entry->d_tag = BYTE_GET (ext->d_tag);
7438 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
7439 }
7440
7441 free (edyn);
7442
9ea033b2
NC
7443 return 1;
7444}
7445
e9e44622
JJ
7446static void
7447print_dynamic_flags (bfd_vma flags)
d1133906 7448{
e9e44622 7449 int first = 1;
13ae64f3 7450
d1133906
NC
7451 while (flags)
7452 {
7453 bfd_vma flag;
7454
7455 flag = flags & - flags;
7456 flags &= ~ flag;
7457
e9e44622
JJ
7458 if (first)
7459 first = 0;
7460 else
7461 putc (' ', stdout);
13ae64f3 7462
d1133906
NC
7463 switch (flag)
7464 {
e9e44622
JJ
7465 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
7466 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
7467 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
7468 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
7469 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 7470 default: fputs (_("unknown"), stdout); break;
d1133906
NC
7471 }
7472 }
e9e44622 7473 puts ("");
d1133906
NC
7474}
7475
b2d38a17
NC
7476/* Parse and display the contents of the dynamic section. */
7477
9ea033b2 7478static int
2cf0635d 7479process_dynamic_section (FILE * file)
9ea033b2 7480{
2cf0635d 7481 Elf_Internal_Dyn * entry;
9ea033b2
NC
7482
7483 if (dynamic_size == 0)
7484 {
7485 if (do_dynamic)
b2d38a17 7486 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
7487
7488 return 1;
7489 }
7490
7491 if (is_32bit_elf)
7492 {
b2d38a17 7493 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
7494 return 0;
7495 }
b2d38a17 7496 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
7497 return 0;
7498
252b5132
RH
7499 /* Find the appropriate symbol table. */
7500 if (dynamic_symbols == NULL)
7501 {
86dba8ee
AM
7502 for (entry = dynamic_section;
7503 entry < dynamic_section + dynamic_nent;
7504 ++entry)
252b5132 7505 {
c8286bd1 7506 Elf_Internal_Shdr section;
252b5132
RH
7507
7508 if (entry->d_tag != DT_SYMTAB)
7509 continue;
7510
7511 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
7512
7513 /* Since we do not know how big the symbol table is,
7514 we default to reading in the entire file (!) and
7515 processing that. This is overkill, I know, but it
e3c8793a 7516 should work. */
d93f0186 7517 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 7518
fb52b2f4
NC
7519 if (archive_file_offset != 0)
7520 section.sh_size = archive_file_size - section.sh_offset;
7521 else
7522 {
7523 if (fseek (file, 0, SEEK_END))
591a748a 7524 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
7525
7526 section.sh_size = ftell (file) - section.sh_offset;
7527 }
252b5132 7528
9ea033b2 7529 if (is_32bit_elf)
9ad5cbcf 7530 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 7531 else
9ad5cbcf 7532 section.sh_entsize = sizeof (Elf64_External_Sym);
252b5132 7533
9ad5cbcf 7534 num_dynamic_syms = section.sh_size / section.sh_entsize;
19936277 7535 if (num_dynamic_syms < 1)
252b5132
RH
7536 {
7537 error (_("Unable to determine the number of symbols to load\n"));
7538 continue;
7539 }
7540
9ad5cbcf 7541 dynamic_symbols = GET_ELF_SYMBOLS (file, &section);
252b5132
RH
7542 }
7543 }
7544
7545 /* Similarly find a string table. */
7546 if (dynamic_strings == NULL)
7547 {
86dba8ee
AM
7548 for (entry = dynamic_section;
7549 entry < dynamic_section + dynamic_nent;
7550 ++entry)
252b5132
RH
7551 {
7552 unsigned long offset;
b34976b6 7553 long str_tab_len;
252b5132
RH
7554
7555 if (entry->d_tag != DT_STRTAB)
7556 continue;
7557
7558 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
7559
7560 /* Since we do not know how big the string table is,
7561 we default to reading in the entire file (!) and
7562 processing that. This is overkill, I know, but it
e3c8793a 7563 should work. */
252b5132 7564
d93f0186 7565 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
7566
7567 if (archive_file_offset != 0)
7568 str_tab_len = archive_file_size - offset;
7569 else
7570 {
7571 if (fseek (file, 0, SEEK_END))
7572 error (_("Unable to seek to end of file\n"));
7573 str_tab_len = ftell (file) - offset;
7574 }
252b5132
RH
7575
7576 if (str_tab_len < 1)
7577 {
7578 error
7579 (_("Unable to determine the length of the dynamic string table\n"));
7580 continue;
7581 }
7582
3f5e193b
NC
7583 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
7584 str_tab_len,
7585 _("dynamic string table"));
59245841 7586 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
7587 break;
7588 }
7589 }
7590
7591 /* And find the syminfo section if available. */
7592 if (dynamic_syminfo == NULL)
7593 {
3e8bba36 7594 unsigned long syminsz = 0;
252b5132 7595
86dba8ee
AM
7596 for (entry = dynamic_section;
7597 entry < dynamic_section + dynamic_nent;
7598 ++entry)
252b5132
RH
7599 {
7600 if (entry->d_tag == DT_SYMINENT)
7601 {
7602 /* Note: these braces are necessary to avoid a syntax
7603 error from the SunOS4 C compiler. */
7604 assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
7605 }
7606 else if (entry->d_tag == DT_SYMINSZ)
7607 syminsz = entry->d_un.d_val;
7608 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
7609 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
7610 syminsz);
252b5132
RH
7611 }
7612
7613 if (dynamic_syminfo_offset != 0 && syminsz != 0)
7614 {
2cf0635d
NC
7615 Elf_External_Syminfo * extsyminfo;
7616 Elf_External_Syminfo * extsym;
7617 Elf_Internal_Syminfo * syminfo;
252b5132
RH
7618
7619 /* There is a syminfo section. Read the data. */
3f5e193b
NC
7620 extsyminfo = (Elf_External_Syminfo *)
7621 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
7622 _("symbol information"));
a6e9f9df
AM
7623 if (!extsyminfo)
7624 return 0;
252b5132 7625
3f5e193b 7626 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
7627 if (dynamic_syminfo == NULL)
7628 {
7629 error (_("Out of memory\n"));
7630 return 0;
7631 }
7632
7633 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
7634 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
7635 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
7636 ++syminfo, ++extsym)
252b5132 7637 {
86dba8ee
AM
7638 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
7639 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
7640 }
7641
7642 free (extsyminfo);
7643 }
7644 }
7645
7646 if (do_dynamic && dynamic_addr)
86dba8ee
AM
7647 printf (_("\nDynamic section at offset 0x%lx contains %u entries:\n"),
7648 dynamic_addr, dynamic_nent);
252b5132
RH
7649 if (do_dynamic)
7650 printf (_(" Tag Type Name/Value\n"));
7651
86dba8ee
AM
7652 for (entry = dynamic_section;
7653 entry < dynamic_section + dynamic_nent;
7654 entry++)
252b5132
RH
7655 {
7656 if (do_dynamic)
f7a99963 7657 {
2cf0635d 7658 const char * dtype;
e699b9ff 7659
f7a99963
NC
7660 putchar (' ');
7661 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
7662 dtype = get_dynamic_type (entry->d_tag);
7663 printf (" (%s)%*s", dtype,
7664 ((is_32bit_elf ? 27 : 19)
7665 - (int) strlen (dtype)),
f7a99963
NC
7666 " ");
7667 }
252b5132
RH
7668
7669 switch (entry->d_tag)
7670 {
d1133906
NC
7671 case DT_FLAGS:
7672 if (do_dynamic)
e9e44622 7673 print_dynamic_flags (entry->d_un.d_val);
d1133906 7674 break;
76da6bbe 7675
252b5132
RH
7676 case DT_AUXILIARY:
7677 case DT_FILTER:
019148e4
L
7678 case DT_CONFIG:
7679 case DT_DEPAUDIT:
7680 case DT_AUDIT:
252b5132
RH
7681 if (do_dynamic)
7682 {
019148e4 7683 switch (entry->d_tag)
b34976b6 7684 {
019148e4
L
7685 case DT_AUXILIARY:
7686 printf (_("Auxiliary library"));
7687 break;
7688
7689 case DT_FILTER:
7690 printf (_("Filter library"));
7691 break;
7692
b34976b6 7693 case DT_CONFIG:
019148e4
L
7694 printf (_("Configuration file"));
7695 break;
7696
7697 case DT_DEPAUDIT:
7698 printf (_("Dependency audit library"));
7699 break;
7700
7701 case DT_AUDIT:
7702 printf (_("Audit library"));
7703 break;
7704 }
252b5132 7705
d79b3d50
NC
7706 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7707 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 7708 else
f7a99963
NC
7709 {
7710 printf (": ");
7711 print_vma (entry->d_un.d_val, PREFIX_HEX);
7712 putchar ('\n');
7713 }
252b5132
RH
7714 }
7715 break;
7716
dcefbbbd 7717 case DT_FEATURE:
252b5132
RH
7718 if (do_dynamic)
7719 {
7720 printf (_("Flags:"));
86f55779 7721
252b5132
RH
7722 if (entry->d_un.d_val == 0)
7723 printf (_(" None\n"));
7724 else
7725 {
7726 unsigned long int val = entry->d_un.d_val;
86f55779 7727
252b5132
RH
7728 if (val & DTF_1_PARINIT)
7729 {
7730 printf (" PARINIT");
7731 val ^= DTF_1_PARINIT;
7732 }
dcefbbbd
L
7733 if (val & DTF_1_CONFEXP)
7734 {
7735 printf (" CONFEXP");
7736 val ^= DTF_1_CONFEXP;
7737 }
252b5132
RH
7738 if (val != 0)
7739 printf (" %lx", val);
7740 puts ("");
7741 }
7742 }
7743 break;
7744
7745 case DT_POSFLAG_1:
7746 if (do_dynamic)
7747 {
7748 printf (_("Flags:"));
86f55779 7749
252b5132
RH
7750 if (entry->d_un.d_val == 0)
7751 printf (_(" None\n"));
7752 else
7753 {
7754 unsigned long int val = entry->d_un.d_val;
86f55779 7755
252b5132
RH
7756 if (val & DF_P1_LAZYLOAD)
7757 {
7758 printf (" LAZYLOAD");
7759 val ^= DF_P1_LAZYLOAD;
7760 }
7761 if (val & DF_P1_GROUPPERM)
7762 {
7763 printf (" GROUPPERM");
7764 val ^= DF_P1_GROUPPERM;
7765 }
7766 if (val != 0)
7767 printf (" %lx", val);
7768 puts ("");
7769 }
7770 }
7771 break;
7772
7773 case DT_FLAGS_1:
7774 if (do_dynamic)
7775 {
7776 printf (_("Flags:"));
7777 if (entry->d_un.d_val == 0)
7778 printf (_(" None\n"));
7779 else
7780 {
7781 unsigned long int val = entry->d_un.d_val;
86f55779 7782
252b5132
RH
7783 if (val & DF_1_NOW)
7784 {
7785 printf (" NOW");
7786 val ^= DF_1_NOW;
7787 }
7788 if (val & DF_1_GLOBAL)
7789 {
7790 printf (" GLOBAL");
7791 val ^= DF_1_GLOBAL;
7792 }
7793 if (val & DF_1_GROUP)
7794 {
7795 printf (" GROUP");
7796 val ^= DF_1_GROUP;
7797 }
7798 if (val & DF_1_NODELETE)
7799 {
7800 printf (" NODELETE");
7801 val ^= DF_1_NODELETE;
7802 }
7803 if (val & DF_1_LOADFLTR)
7804 {
7805 printf (" LOADFLTR");
7806 val ^= DF_1_LOADFLTR;
7807 }
7808 if (val & DF_1_INITFIRST)
7809 {
7810 printf (" INITFIRST");
7811 val ^= DF_1_INITFIRST;
7812 }
7813 if (val & DF_1_NOOPEN)
7814 {
7815 printf (" NOOPEN");
7816 val ^= DF_1_NOOPEN;
7817 }
7818 if (val & DF_1_ORIGIN)
7819 {
7820 printf (" ORIGIN");
7821 val ^= DF_1_ORIGIN;
7822 }
7823 if (val & DF_1_DIRECT)
7824 {
7825 printf (" DIRECT");
7826 val ^= DF_1_DIRECT;
7827 }
7828 if (val & DF_1_TRANS)
7829 {
7830 printf (" TRANS");
7831 val ^= DF_1_TRANS;
7832 }
7833 if (val & DF_1_INTERPOSE)
7834 {
7835 printf (" INTERPOSE");
7836 val ^= DF_1_INTERPOSE;
7837 }
f7db6139 7838 if (val & DF_1_NODEFLIB)
dcefbbbd 7839 {
f7db6139
L
7840 printf (" NODEFLIB");
7841 val ^= DF_1_NODEFLIB;
dcefbbbd
L
7842 }
7843 if (val & DF_1_NODUMP)
7844 {
7845 printf (" NODUMP");
7846 val ^= DF_1_NODUMP;
7847 }
7848 if (val & DF_1_CONLFAT)
7849 {
7850 printf (" CONLFAT");
7851 val ^= DF_1_CONLFAT;
7852 }
252b5132
RH
7853 if (val != 0)
7854 printf (" %lx", val);
7855 puts ("");
7856 }
7857 }
7858 break;
7859
7860 case DT_PLTREL:
566b0d53 7861 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7862 if (do_dynamic)
7863 puts (get_dynamic_type (entry->d_un.d_val));
7864 break;
7865
7866 case DT_NULL :
7867 case DT_NEEDED :
7868 case DT_PLTGOT :
7869 case DT_HASH :
7870 case DT_STRTAB :
7871 case DT_SYMTAB :
7872 case DT_RELA :
7873 case DT_INIT :
7874 case DT_FINI :
7875 case DT_SONAME :
7876 case DT_RPATH :
7877 case DT_SYMBOLIC:
7878 case DT_REL :
7879 case DT_DEBUG :
7880 case DT_TEXTREL :
7881 case DT_JMPREL :
019148e4 7882 case DT_RUNPATH :
252b5132
RH
7883 dynamic_info[entry->d_tag] = entry->d_un.d_val;
7884
7885 if (do_dynamic)
7886 {
2cf0635d 7887 char * name;
252b5132 7888
d79b3d50
NC
7889 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
7890 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7891 else
d79b3d50 7892 name = NULL;
252b5132
RH
7893
7894 if (name)
7895 {
7896 switch (entry->d_tag)
7897 {
7898 case DT_NEEDED:
7899 printf (_("Shared library: [%s]"), name);
7900
18bd398b 7901 if (streq (name, program_interpreter))
f7a99963 7902 printf (_(" program interpreter"));
252b5132
RH
7903 break;
7904
7905 case DT_SONAME:
f7a99963 7906 printf (_("Library soname: [%s]"), name);
252b5132
RH
7907 break;
7908
7909 case DT_RPATH:
f7a99963 7910 printf (_("Library rpath: [%s]"), name);
252b5132
RH
7911 break;
7912
019148e4
L
7913 case DT_RUNPATH:
7914 printf (_("Library runpath: [%s]"), name);
7915 break;
7916
252b5132 7917 default:
f7a99963
NC
7918 print_vma (entry->d_un.d_val, PREFIX_HEX);
7919 break;
252b5132
RH
7920 }
7921 }
7922 else
f7a99963
NC
7923 print_vma (entry->d_un.d_val, PREFIX_HEX);
7924
7925 putchar ('\n');
252b5132
RH
7926 }
7927 break;
7928
7929 case DT_PLTRELSZ:
7930 case DT_RELASZ :
7931 case DT_STRSZ :
7932 case DT_RELSZ :
7933 case DT_RELAENT :
7934 case DT_SYMENT :
7935 case DT_RELENT :
566b0d53 7936 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
7937 case DT_PLTPADSZ:
7938 case DT_MOVEENT :
7939 case DT_MOVESZ :
7940 case DT_INIT_ARRAYSZ:
7941 case DT_FINI_ARRAYSZ:
047b2264
JJ
7942 case DT_GNU_CONFLICTSZ:
7943 case DT_GNU_LIBLISTSZ:
252b5132 7944 if (do_dynamic)
f7a99963
NC
7945 {
7946 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 7947 printf (_(" (bytes)\n"));
f7a99963 7948 }
252b5132
RH
7949 break;
7950
7951 case DT_VERDEFNUM:
7952 case DT_VERNEEDNUM:
7953 case DT_RELACOUNT:
7954 case DT_RELCOUNT:
7955 if (do_dynamic)
f7a99963
NC
7956 {
7957 print_vma (entry->d_un.d_val, UNSIGNED);
7958 putchar ('\n');
7959 }
252b5132
RH
7960 break;
7961
7962 case DT_SYMINSZ:
7963 case DT_SYMINENT:
7964 case DT_SYMINFO:
7965 case DT_USED:
7966 case DT_INIT_ARRAY:
7967 case DT_FINI_ARRAY:
7968 if (do_dynamic)
7969 {
d79b3d50
NC
7970 if (entry->d_tag == DT_USED
7971 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 7972 {
2cf0635d 7973 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 7974
b34976b6 7975 if (*name)
252b5132
RH
7976 {
7977 printf (_("Not needed object: [%s]\n"), name);
7978 break;
7979 }
7980 }
103f02d3 7981
f7a99963
NC
7982 print_vma (entry->d_un.d_val, PREFIX_HEX);
7983 putchar ('\n');
252b5132
RH
7984 }
7985 break;
7986
7987 case DT_BIND_NOW:
7988 /* The value of this entry is ignored. */
35b1837e
AM
7989 if (do_dynamic)
7990 putchar ('\n');
252b5132 7991 break;
103f02d3 7992
047b2264
JJ
7993 case DT_GNU_PRELINKED:
7994 if (do_dynamic)
7995 {
2cf0635d 7996 struct tm * tmp;
91d6fa6a 7997 time_t atime = entry->d_un.d_val;
047b2264 7998
91d6fa6a 7999 tmp = gmtime (&atime);
047b2264
JJ
8000 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
8001 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8002 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
8003
8004 }
8005 break;
8006
fdc90cb4
JJ
8007 case DT_GNU_HASH:
8008 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
8009 if (do_dynamic)
8010 {
8011 print_vma (entry->d_un.d_val, PREFIX_HEX);
8012 putchar ('\n');
8013 }
8014 break;
8015
252b5132
RH
8016 default:
8017 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 8018 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
8019 entry->d_un.d_val;
8020
8021 if (do_dynamic)
8022 {
8023 switch (elf_header.e_machine)
8024 {
8025 case EM_MIPS:
4fe85591 8026 case EM_MIPS_RS3_LE:
b2d38a17 8027 dynamic_section_mips_val (entry);
252b5132 8028 break;
103f02d3 8029 case EM_PARISC:
b2d38a17 8030 dynamic_section_parisc_val (entry);
103f02d3 8031 break;
ecc51f48 8032 case EM_IA_64:
b2d38a17 8033 dynamic_section_ia64_val (entry);
ecc51f48 8034 break;
252b5132 8035 default:
f7a99963
NC
8036 print_vma (entry->d_un.d_val, PREFIX_HEX);
8037 putchar ('\n');
252b5132
RH
8038 }
8039 }
8040 break;
8041 }
8042 }
8043
8044 return 1;
8045}
8046
8047static char *
d3ba0551 8048get_ver_flags (unsigned int flags)
252b5132 8049{
b34976b6 8050 static char buff[32];
252b5132
RH
8051
8052 buff[0] = 0;
8053
8054 if (flags == 0)
8055 return _("none");
8056
8057 if (flags & VER_FLG_BASE)
8058 strcat (buff, "BASE ");
8059
8060 if (flags & VER_FLG_WEAK)
8061 {
8062 if (flags & VER_FLG_BASE)
8063 strcat (buff, "| ");
8064
8065 strcat (buff, "WEAK ");
8066 }
8067
44ec90b9
RO
8068 if (flags & VER_FLG_INFO)
8069 {
8070 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
8071 strcat (buff, "| ");
8072
8073 strcat (buff, "INFO ");
8074 }
8075
8076 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 8077 strcat (buff, _("| <unknown>"));
252b5132
RH
8078
8079 return buff;
8080}
8081
8082/* Display the contents of the version sections. */
98fb390a 8083
252b5132 8084static int
2cf0635d 8085process_version_sections (FILE * file)
252b5132 8086{
2cf0635d 8087 Elf_Internal_Shdr * section;
b34976b6
AM
8088 unsigned i;
8089 int found = 0;
252b5132
RH
8090
8091 if (! do_version)
8092 return 1;
8093
8094 for (i = 0, section = section_headers;
8095 i < elf_header.e_shnum;
b34976b6 8096 i++, section++)
252b5132
RH
8097 {
8098 switch (section->sh_type)
8099 {
8100 case SHT_GNU_verdef:
8101 {
2cf0635d 8102 Elf_External_Verdef * edefs;
b34976b6
AM
8103 unsigned int idx;
8104 unsigned int cnt;
2cf0635d 8105 char * endbuf;
252b5132
RH
8106
8107 found = 1;
8108
8109 printf
72de5009 8110 (_("\nVersion definition section '%s' contains %u entries:\n"),
252b5132
RH
8111 SECTION_NAME (section), section->sh_info);
8112
8113 printf (_(" Addr: 0x"));
8114 printf_vma (section->sh_addr);
72de5009 8115 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8116 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8117 section->sh_link < elf_header.e_shnum
8118 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8119 : _("<corrupt>"));
252b5132 8120
3f5e193b
NC
8121 edefs = (Elf_External_Verdef *)
8122 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
8123 _("version definition section"));
a6e9f9df
AM
8124 if (!edefs)
8125 break;
59245841 8126 endbuf = (char *) edefs + section->sh_size;
252b5132 8127
b34976b6 8128 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 8129 {
2cf0635d
NC
8130 char * vstart;
8131 Elf_External_Verdef * edef;
b34976b6 8132 Elf_Internal_Verdef ent;
2cf0635d 8133 Elf_External_Verdaux * eaux;
b34976b6
AM
8134 Elf_Internal_Verdaux aux;
8135 int j;
8136 int isum;
103f02d3 8137
dd24e3da
NC
8138 /* Check for negative or very large indicies. */
8139 if ((unsigned char *) edefs + idx < (unsigned char *) edefs)
8140 break;
8141
252b5132 8142 vstart = ((char *) edefs) + idx;
54806181
AM
8143 if (vstart + sizeof (*edef) > endbuf)
8144 break;
252b5132
RH
8145
8146 edef = (Elf_External_Verdef *) vstart;
8147
8148 ent.vd_version = BYTE_GET (edef->vd_version);
8149 ent.vd_flags = BYTE_GET (edef->vd_flags);
8150 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
8151 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
8152 ent.vd_hash = BYTE_GET (edef->vd_hash);
8153 ent.vd_aux = BYTE_GET (edef->vd_aux);
8154 ent.vd_next = BYTE_GET (edef->vd_next);
8155
8156 printf (_(" %#06x: Rev: %d Flags: %s"),
8157 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
8158
8159 printf (_(" Index: %d Cnt: %d "),
8160 ent.vd_ndx, ent.vd_cnt);
8161
dd24e3da
NC
8162 /* Check for overflow. */
8163 if ((unsigned char *)(vstart + ent.vd_aux) < (unsigned char *) vstart
8164 || (unsigned char *)(vstart + ent.vd_aux) > (unsigned char *) endbuf)
8165 break;
8166
252b5132
RH
8167 vstart += ent.vd_aux;
8168
8169 eaux = (Elf_External_Verdaux *) vstart;
8170
8171 aux.vda_name = BYTE_GET (eaux->vda_name);
8172 aux.vda_next = BYTE_GET (eaux->vda_next);
8173
d79b3d50
NC
8174 if (VALID_DYNAMIC_NAME (aux.vda_name))
8175 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8176 else
8177 printf (_("Name index: %ld\n"), aux.vda_name);
8178
8179 isum = idx + ent.vd_aux;
8180
b34976b6 8181 for (j = 1; j < ent.vd_cnt; j++)
252b5132 8182 {
dd24e3da
NC
8183 /* Check for overflow. */
8184 if ((unsigned char *)(vstart + aux.vda_next) < (unsigned char *) vstart
8185 || (unsigned char *)(vstart + aux.vda_next) > (unsigned char *) endbuf)
8186 break;
8187
252b5132
RH
8188 isum += aux.vda_next;
8189 vstart += aux.vda_next;
8190
8191 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
8192 if (vstart + sizeof (*eaux) > endbuf)
8193 break;
252b5132
RH
8194
8195 aux.vda_name = BYTE_GET (eaux->vda_name);
8196 aux.vda_next = BYTE_GET (eaux->vda_next);
8197
d79b3d50 8198 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 8199 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 8200 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
8201 else
8202 printf (_(" %#06x: Parent %d, name index: %ld\n"),
8203 isum, j, aux.vda_name);
8204 }
dd24e3da 8205
54806181
AM
8206 if (j < ent.vd_cnt)
8207 printf (_(" Version def aux past end of section\n"));
252b5132
RH
8208
8209 idx += ent.vd_next;
8210 }
dd24e3da 8211
54806181
AM
8212 if (cnt < section->sh_info)
8213 printf (_(" Version definition past end of section\n"));
252b5132
RH
8214
8215 free (edefs);
8216 }
8217 break;
103f02d3 8218
252b5132
RH
8219 case SHT_GNU_verneed:
8220 {
2cf0635d 8221 Elf_External_Verneed * eneed;
b34976b6
AM
8222 unsigned int idx;
8223 unsigned int cnt;
2cf0635d 8224 char * endbuf;
252b5132
RH
8225
8226 found = 1;
8227
72de5009 8228 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
252b5132
RH
8229 SECTION_NAME (section), section->sh_info);
8230
8231 printf (_(" Addr: 0x"));
8232 printf_vma (section->sh_addr);
72de5009 8233 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8234 (unsigned long) section->sh_offset, section->sh_link,
4fbb74a6
AM
8235 section->sh_link < elf_header.e_shnum
8236 ? SECTION_NAME (section_headers + section->sh_link)
2b692964 8237 : _("<corrupt>"));
252b5132 8238
3f5e193b
NC
8239 eneed = (Elf_External_Verneed *) get_data (NULL, file,
8240 section->sh_offset, 1,
8241 section->sh_size,
8242 _("version need section"));
a6e9f9df
AM
8243 if (!eneed)
8244 break;
59245841 8245 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
8246
8247 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
8248 {
2cf0635d 8249 Elf_External_Verneed * entry;
b34976b6
AM
8250 Elf_Internal_Verneed ent;
8251 int j;
8252 int isum;
2cf0635d 8253 char * vstart;
252b5132 8254
dd24e3da
NC
8255 if ((unsigned char *) eneed + idx < (unsigned char *) eneed)
8256 break;
8257
252b5132 8258 vstart = ((char *) eneed) + idx;
54806181
AM
8259 if (vstart + sizeof (*entry) > endbuf)
8260 break;
252b5132
RH
8261
8262 entry = (Elf_External_Verneed *) vstart;
8263
8264 ent.vn_version = BYTE_GET (entry->vn_version);
8265 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
8266 ent.vn_file = BYTE_GET (entry->vn_file);
8267 ent.vn_aux = BYTE_GET (entry->vn_aux);
8268 ent.vn_next = BYTE_GET (entry->vn_next);
8269
8270 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
8271
d79b3d50
NC
8272 if (VALID_DYNAMIC_NAME (ent.vn_file))
8273 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
8274 else
8275 printf (_(" File: %lx"), ent.vn_file);
8276
8277 printf (_(" Cnt: %d\n"), ent.vn_cnt);
8278
dd24e3da
NC
8279 /* Check for overflow. */
8280 if ((unsigned char *)(vstart + ent.vn_aux) < (unsigned char *) vstart
8281 || (unsigned char *)(vstart + ent.vn_aux) > (unsigned char *) endbuf)
8282 break;
8283
252b5132
RH
8284 vstart += ent.vn_aux;
8285
8286 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
8287 {
2cf0635d 8288 Elf_External_Vernaux * eaux;
b34976b6 8289 Elf_Internal_Vernaux aux;
252b5132 8290
54806181
AM
8291 if (vstart + sizeof (*eaux) > endbuf)
8292 break;
252b5132
RH
8293 eaux = (Elf_External_Vernaux *) vstart;
8294
8295 aux.vna_hash = BYTE_GET (eaux->vna_hash);
8296 aux.vna_flags = BYTE_GET (eaux->vna_flags);
8297 aux.vna_other = BYTE_GET (eaux->vna_other);
8298 aux.vna_name = BYTE_GET (eaux->vna_name);
8299 aux.vna_next = BYTE_GET (eaux->vna_next);
8300
d79b3d50 8301 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 8302 printf (_(" %#06x: Name: %s"),
d79b3d50 8303 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 8304 else
ecc2063b 8305 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
8306 isum, aux.vna_name);
8307
8308 printf (_(" Flags: %s Version: %d\n"),
8309 get_ver_flags (aux.vna_flags), aux.vna_other);
8310
dd24e3da
NC
8311 /* Check for overflow. */
8312 if ((unsigned char *)(vstart + aux.vna_next) < (unsigned char *) vstart
8313 || (unsigned char *)(vstart + aux.vna_next) > (unsigned char *) endbuf)
8314 break;
8315
252b5132
RH
8316 isum += aux.vna_next;
8317 vstart += aux.vna_next;
8318 }
54806181
AM
8319 if (j < ent.vn_cnt)
8320 printf (_(" Version need aux past end of section\n"));
252b5132
RH
8321
8322 idx += ent.vn_next;
8323 }
54806181
AM
8324 if (cnt < section->sh_info)
8325 printf (_(" Version need past end of section\n"));
103f02d3 8326
252b5132
RH
8327 free (eneed);
8328 }
8329 break;
8330
8331 case SHT_GNU_versym:
8332 {
2cf0635d 8333 Elf_Internal_Shdr * link_section;
b34976b6
AM
8334 int total;
8335 int cnt;
2cf0635d
NC
8336 unsigned char * edata;
8337 unsigned short * data;
8338 char * strtab;
8339 Elf_Internal_Sym * symbols;
8340 Elf_Internal_Shdr * string_sec;
d3ba0551 8341 long off;
252b5132 8342
4fbb74a6 8343 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8344 break;
8345
4fbb74a6 8346 link_section = section_headers + section->sh_link;
08d8fa11 8347 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 8348
4fbb74a6 8349 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
8350 break;
8351
252b5132
RH
8352 found = 1;
8353
9ad5cbcf 8354 symbols = GET_ELF_SYMBOLS (file, link_section);
dd24e3da
NC
8355 if (symbols == NULL)
8356 break;
252b5132 8357
4fbb74a6 8358 string_sec = section_headers + link_section->sh_link;
252b5132 8359
3f5e193b
NC
8360 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
8361 string_sec->sh_size,
8362 _("version string table"));
a6e9f9df 8363 if (!strtab)
0429c154
MS
8364 {
8365 free (symbols);
8366 break;
8367 }
252b5132
RH
8368
8369 printf (_("\nVersion symbols section '%s' contains %d entries:\n"),
8370 SECTION_NAME (section), total);
8371
8372 printf (_(" Addr: "));
8373 printf_vma (section->sh_addr);
72de5009 8374 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 8375 (unsigned long) section->sh_offset, section->sh_link,
252b5132
RH
8376 SECTION_NAME (link_section));
8377
d3ba0551
AM
8378 off = offset_from_vma (file,
8379 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
8380 total * sizeof (short));
3f5e193b
NC
8381 edata = (unsigned char *) get_data (NULL, file, off, total,
8382 sizeof (short),
8383 _("version symbol data"));
a6e9f9df
AM
8384 if (!edata)
8385 {
8386 free (strtab);
0429c154 8387 free (symbols);
a6e9f9df
AM
8388 break;
8389 }
252b5132 8390
3f5e193b 8391 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
8392
8393 for (cnt = total; cnt --;)
b34976b6
AM
8394 data[cnt] = byte_get (edata + cnt * sizeof (short),
8395 sizeof (short));
252b5132
RH
8396
8397 free (edata);
8398
8399 for (cnt = 0; cnt < total; cnt += 4)
8400 {
8401 int j, nn;
00d93f34 8402 int check_def, check_need;
2cf0635d 8403 char * name;
252b5132
RH
8404
8405 printf (" %03x:", cnt);
8406
8407 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 8408 switch (data[cnt + j])
252b5132
RH
8409 {
8410 case 0:
8411 fputs (_(" 0 (*local*) "), stdout);
8412 break;
8413
8414 case 1:
8415 fputs (_(" 1 (*global*) "), stdout);
8416 break;
8417
8418 default:
c244d050
NC
8419 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
8420 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 8421
dd24e3da
NC
8422 /* If this index value is greater than the size of the symbols
8423 array, break to avoid an out-of-bounds read, */
8424 if ((unsigned long)(cnt + j) >=
8425 ((unsigned long)link_section->sh_size /
8426 (unsigned long)link_section->sh_entsize))
8427 {
8428 warn (_("invalid index into symbol array\n"));
8429 break;
8430 }
8431
00d93f34
JJ
8432 check_def = 1;
8433 check_need = 1;
4fbb74a6
AM
8434 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
8435 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 8436 != SHT_NOBITS)
252b5132 8437 {
b34976b6 8438 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
8439 check_def = 0;
8440 else
8441 check_need = 0;
252b5132 8442 }
00d93f34
JJ
8443
8444 if (check_need
b34976b6 8445 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 8446 {
b34976b6
AM
8447 Elf_Internal_Verneed ivn;
8448 unsigned long offset;
252b5132 8449
d93f0186
NC
8450 offset = offset_from_vma
8451 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
8452 sizeof (Elf_External_Verneed));
252b5132 8453
b34976b6 8454 do
252b5132 8455 {
b34976b6
AM
8456 Elf_Internal_Vernaux ivna;
8457 Elf_External_Verneed evn;
8458 Elf_External_Vernaux evna;
8459 unsigned long a_off;
252b5132 8460
59245841
NC
8461 if (get_data (&evn, file, offset, sizeof (evn), 1,
8462 _("version need")) == NULL)
8463 break;
8464
252b5132
RH
8465 ivn.vn_aux = BYTE_GET (evn.vn_aux);
8466 ivn.vn_next = BYTE_GET (evn.vn_next);
8467
8468 a_off = offset + ivn.vn_aux;
8469
8470 do
8471 {
59245841
NC
8472 if (get_data (&evna, file, a_off, sizeof (evna),
8473 1, _("version need aux (2)")) == NULL)
8474 {
8475 ivna.vna_next = 0;
8476 ivna.vna_other = 0;
8477 }
8478 else
8479 {
8480 ivna.vna_next = BYTE_GET (evna.vna_next);
8481 ivna.vna_other = BYTE_GET (evna.vna_other);
8482 }
252b5132
RH
8483
8484 a_off += ivna.vna_next;
8485 }
b34976b6 8486 while (ivna.vna_other != data[cnt + j]
252b5132
RH
8487 && ivna.vna_next != 0);
8488
b34976b6 8489 if (ivna.vna_other == data[cnt + j])
252b5132
RH
8490 {
8491 ivna.vna_name = BYTE_GET (evna.vna_name);
8492
54806181
AM
8493 if (ivna.vna_name >= string_sec->sh_size)
8494 name = _("*invalid*");
8495 else
8496 name = strtab + ivna.vna_name;
252b5132 8497 nn += printf ("(%s%-*s",
16062207
ILT
8498 name,
8499 12 - (int) strlen (name),
252b5132 8500 ")");
00d93f34 8501 check_def = 0;
252b5132
RH
8502 break;
8503 }
8504
8505 offset += ivn.vn_next;
8506 }
8507 while (ivn.vn_next);
8508 }
00d93f34 8509
b34976b6
AM
8510 if (check_def && data[cnt + j] != 0x8001
8511 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 8512 {
b34976b6
AM
8513 Elf_Internal_Verdef ivd;
8514 Elf_External_Verdef evd;
8515 unsigned long offset;
252b5132 8516
d93f0186
NC
8517 offset = offset_from_vma
8518 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
8519 sizeof evd);
252b5132
RH
8520
8521 do
8522 {
59245841
NC
8523 if (get_data (&evd, file, offset, sizeof (evd), 1,
8524 _("version def")) == NULL)
8525 {
8526 ivd.vd_next = 0;
8527 ivd.vd_ndx = 0;
8528 }
8529 else
8530 {
8531 ivd.vd_next = BYTE_GET (evd.vd_next);
8532 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
8533 }
252b5132
RH
8534
8535 offset += ivd.vd_next;
8536 }
c244d050 8537 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
8538 && ivd.vd_next != 0);
8539
c244d050 8540 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 8541 {
b34976b6
AM
8542 Elf_External_Verdaux evda;
8543 Elf_Internal_Verdaux ivda;
252b5132
RH
8544
8545 ivd.vd_aux = BYTE_GET (evd.vd_aux);
8546
59245841
NC
8547 if (get_data (&evda, file,
8548 offset - ivd.vd_next + ivd.vd_aux,
8549 sizeof (evda), 1,
8550 _("version def aux")) == NULL)
8551 break;
252b5132
RH
8552
8553 ivda.vda_name = BYTE_GET (evda.vda_name);
8554
54806181
AM
8555 if (ivda.vda_name >= string_sec->sh_size)
8556 name = _("*invalid*");
8557 else
8558 name = strtab + ivda.vda_name;
252b5132 8559 nn += printf ("(%s%-*s",
16062207
ILT
8560 name,
8561 12 - (int) strlen (name),
252b5132
RH
8562 ")");
8563 }
8564 }
8565
8566 if (nn < 18)
8567 printf ("%*c", 18 - nn, ' ');
8568 }
8569
8570 putchar ('\n');
8571 }
8572
8573 free (data);
8574 free (strtab);
8575 free (symbols);
8576 }
8577 break;
103f02d3 8578
252b5132
RH
8579 default:
8580 break;
8581 }
8582 }
8583
8584 if (! found)
8585 printf (_("\nNo version information found in this file.\n"));
8586
8587 return 1;
8588}
8589
d1133906 8590static const char *
d3ba0551 8591get_symbol_binding (unsigned int binding)
252b5132 8592{
b34976b6 8593 static char buff[32];
252b5132
RH
8594
8595 switch (binding)
8596 {
b34976b6
AM
8597 case STB_LOCAL: return "LOCAL";
8598 case STB_GLOBAL: return "GLOBAL";
8599 case STB_WEAK: return "WEAK";
252b5132
RH
8600 default:
8601 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
8602 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
8603 binding);
252b5132 8604 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
8605 {
8606 if (binding == STB_GNU_UNIQUE
9c55345c
TS
8607 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8608 /* GNU is still using the default value 0. */
3e7a7d11
NC
8609 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8610 return "UNIQUE";
8611 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
8612 }
252b5132 8613 else
e9e44622 8614 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
8615 return buff;
8616 }
8617}
8618
d1133906 8619static const char *
d3ba0551 8620get_symbol_type (unsigned int type)
252b5132 8621{
b34976b6 8622 static char buff[32];
252b5132
RH
8623
8624 switch (type)
8625 {
b34976b6
AM
8626 case STT_NOTYPE: return "NOTYPE";
8627 case STT_OBJECT: return "OBJECT";
8628 case STT_FUNC: return "FUNC";
8629 case STT_SECTION: return "SECTION";
8630 case STT_FILE: return "FILE";
8631 case STT_COMMON: return "COMMON";
8632 case STT_TLS: return "TLS";
15ab5209
DB
8633 case STT_RELC: return "RELC";
8634 case STT_SRELC: return "SRELC";
252b5132
RH
8635 default:
8636 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af
NC
8637 {
8638 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
103f02d3
UD
8639 return "THUMB_FUNC";
8640
351b4b40 8641 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
8642 return "REGISTER";
8643
8644 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
8645 return "PARISC_MILLI";
8646
e9e44622 8647 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 8648 }
252b5132 8649 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
8650 {
8651 if (elf_header.e_machine == EM_PARISC)
8652 {
8653 if (type == STT_HP_OPAQUE)
8654 return "HP_OPAQUE";
8655 if (type == STT_HP_STUB)
8656 return "HP_STUB";
8657 }
8658
d8045f23 8659 if (type == STT_GNU_IFUNC
9c55345c
TS
8660 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
8661 /* GNU is still using the default value 0. */
d8045f23
NC
8662 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
8663 return "IFUNC";
8664
e9e44622 8665 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 8666 }
252b5132 8667 else
e9e44622 8668 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
8669 return buff;
8670 }
8671}
8672
d1133906 8673static const char *
d3ba0551 8674get_symbol_visibility (unsigned int visibility)
d1133906
NC
8675{
8676 switch (visibility)
8677 {
b34976b6
AM
8678 case STV_DEFAULT: return "DEFAULT";
8679 case STV_INTERNAL: return "INTERNAL";
8680 case STV_HIDDEN: return "HIDDEN";
d1133906
NC
8681 case STV_PROTECTED: return "PROTECTED";
8682 default: abort ();
8683 }
8684}
8685
5e2b0d47
NC
8686static const char *
8687get_mips_symbol_other (unsigned int other)
8688{
8689 switch (other)
8690 {
df58fc94
RS
8691 case STO_OPTIONAL:
8692 return "OPTIONAL";
8693 case STO_MIPS_PLT:
8694 return "MIPS PLT";
8695 case STO_MIPS_PIC:
8696 return "MIPS PIC";
8697 case STO_MICROMIPS:
8698 return "MICROMIPS";
8699 case STO_MICROMIPS | STO_MIPS_PIC:
8700 return "MICROMIPS, MIPS PIC";
8701 case STO_MIPS16:
8702 return "MIPS16";
8703 default:
8704 return NULL;
5e2b0d47
NC
8705 }
8706}
8707
28f997cf
TG
8708static const char *
8709get_ia64_symbol_other (unsigned int other)
8710{
8711 if (is_ia64_vms ())
8712 {
8713 static char res[32];
8714
8715 res[0] = 0;
8716
8717 /* Function types is for images and .STB files only. */
8718 switch (elf_header.e_type)
8719 {
8720 case ET_DYN:
8721 case ET_EXEC:
8722 switch (VMS_ST_FUNC_TYPE (other))
8723 {
8724 case VMS_SFT_CODE_ADDR:
8725 strcat (res, " CA");
8726 break;
8727 case VMS_SFT_SYMV_IDX:
8728 strcat (res, " VEC");
8729 break;
8730 case VMS_SFT_FD:
8731 strcat (res, " FD");
8732 break;
8733 case VMS_SFT_RESERVE:
8734 strcat (res, " RSV");
8735 break;
8736 default:
8737 abort ();
8738 }
8739 break;
8740 default:
8741 break;
8742 }
8743 switch (VMS_ST_LINKAGE (other))
8744 {
8745 case VMS_STL_IGNORE:
8746 strcat (res, " IGN");
8747 break;
8748 case VMS_STL_RESERVE:
8749 strcat (res, " RSV");
8750 break;
8751 case VMS_STL_STD:
8752 strcat (res, " STD");
8753 break;
8754 case VMS_STL_LNK:
8755 strcat (res, " LNK");
8756 break;
8757 default:
8758 abort ();
8759 }
8760
8761 if (res[0] != 0)
8762 return res + 1;
8763 else
8764 return res;
8765 }
8766 return NULL;
8767}
8768
5e2b0d47
NC
8769static const char *
8770get_symbol_other (unsigned int other)
8771{
8772 const char * result = NULL;
8773 static char buff [32];
8774
8775 if (other == 0)
8776 return "";
8777
8778 switch (elf_header.e_machine)
8779 {
8780 case EM_MIPS:
8781 result = get_mips_symbol_other (other);
28f997cf
TG
8782 break;
8783 case EM_IA_64:
8784 result = get_ia64_symbol_other (other);
8785 break;
5e2b0d47
NC
8786 default:
8787 break;
8788 }
8789
8790 if (result)
8791 return result;
8792
8793 snprintf (buff, sizeof buff, _("<other>: %x"), other);
8794 return buff;
8795}
8796
d1133906 8797static const char *
d3ba0551 8798get_symbol_index_type (unsigned int type)
252b5132 8799{
b34976b6 8800 static char buff[32];
5cf1065c 8801
252b5132
RH
8802 switch (type)
8803 {
b34976b6
AM
8804 case SHN_UNDEF: return "UND";
8805 case SHN_ABS: return "ABS";
8806 case SHN_COMMON: return "COM";
252b5132 8807 default:
9ce701e2
L
8808 if (type == SHN_IA_64_ANSI_COMMON
8809 && elf_header.e_machine == EM_IA_64
8810 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
8811 return "ANSI_COM";
8a9036a4 8812 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
8813 || elf_header.e_machine == EM_L1OM
8814 || elf_header.e_machine == EM_K1OM)
3b22753a
L
8815 && type == SHN_X86_64_LCOMMON)
8816 return "LARGE_COM";
ac145307
BS
8817 else if ((type == SHN_MIPS_SCOMMON
8818 && elf_header.e_machine == EM_MIPS)
8819 || (type == SHN_TIC6X_SCOMMON
8820 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
8821 return "SCOM";
8822 else if (type == SHN_MIPS_SUNDEFINED
8823 && elf_header.e_machine == EM_MIPS)
8824 return "SUND";
9ce701e2 8825 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 8826 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 8827 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
8828 sprintf (buff, "OS [0x%04x]", type & 0xffff);
8829 else if (type >= SHN_LORESERVE)
8830 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
252b5132 8831 else
232e7cb8 8832 sprintf (buff, "%3d", type);
5cf1065c 8833 break;
252b5132 8834 }
5cf1065c
NC
8835
8836 return buff;
252b5132
RH
8837}
8838
66543521 8839static bfd_vma *
2cf0635d 8840get_dynamic_data (FILE * file, unsigned int number, unsigned int ent_size)
252b5132 8841{
2cf0635d
NC
8842 unsigned char * e_data;
8843 bfd_vma * i_data;
252b5132 8844
3f5e193b 8845 e_data = (unsigned char *) cmalloc (number, ent_size);
252b5132
RH
8846
8847 if (e_data == NULL)
8848 {
8849 error (_("Out of memory\n"));
8850 return NULL;
8851 }
8852
66543521 8853 if (fread (e_data, ent_size, number, file) != number)
252b5132
RH
8854 {
8855 error (_("Unable to read in dynamic data\n"));
8856 return NULL;
8857 }
8858
3f5e193b 8859 i_data = (bfd_vma *) cmalloc (number, sizeof (*i_data));
252b5132
RH
8860
8861 if (i_data == NULL)
8862 {
8863 error (_("Out of memory\n"));
8864 free (e_data);
8865 return NULL;
8866 }
8867
8868 while (number--)
66543521 8869 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
8870
8871 free (e_data);
8872
8873 return i_data;
8874}
8875
6bd1a22c
L
8876static void
8877print_dynamic_symbol (bfd_vma si, unsigned long hn)
8878{
2cf0635d 8879 Elf_Internal_Sym * psym;
6bd1a22c
L
8880 int n;
8881
8882 psym = dynamic_symbols + si;
8883
8884 n = print_vma (si, DEC_5);
8885 if (n < 5)
8886 fputs (" " + n, stdout);
8887 printf (" %3lu: ", hn);
8888 print_vma (psym->st_value, LONG_HEX);
8889 putchar (' ');
8890 print_vma (psym->st_size, DEC_5);
8891
f4be36b3
AM
8892 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
8893 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
8894 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
8895 /* Check to see if any other bits in the st_other field are set.
8896 Note - displaying this information disrupts the layout of the
8897 table being generated, but for the moment this case is very
8898 rare. */
8899 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
8900 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
8901 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
8902 if (VALID_DYNAMIC_NAME (psym->st_name))
8903 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
8904 else
2b692964 8905 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
8906 putchar ('\n');
8907}
8908
e3c8793a 8909/* Dump the symbol table. */
252b5132 8910static int
2cf0635d 8911process_symbol_table (FILE * file)
252b5132 8912{
2cf0635d 8913 Elf_Internal_Shdr * section;
66543521
AM
8914 bfd_vma nbuckets = 0;
8915 bfd_vma nchains = 0;
2cf0635d
NC
8916 bfd_vma * buckets = NULL;
8917 bfd_vma * chains = NULL;
fdc90cb4 8918 bfd_vma ngnubuckets = 0;
2cf0635d
NC
8919 bfd_vma * gnubuckets = NULL;
8920 bfd_vma * gnuchains = NULL;
6bd1a22c 8921 bfd_vma gnusymidx = 0;
252b5132 8922
2c610e4b 8923 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
8924 return 1;
8925
6bd1a22c
L
8926 if (dynamic_info[DT_HASH]
8927 && (do_histogram
2c610e4b
L
8928 || (do_using_dynamic
8929 && !do_dyn_syms
8930 && dynamic_strings != NULL)))
252b5132 8931 {
66543521
AM
8932 unsigned char nb[8];
8933 unsigned char nc[8];
8934 int hash_ent_size = 4;
8935
8936 if ((elf_header.e_machine == EM_ALPHA
8937 || elf_header.e_machine == EM_S390
8938 || elf_header.e_machine == EM_S390_OLD)
8939 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
8940 hash_ent_size = 8;
8941
fb52b2f4
NC
8942 if (fseek (file,
8943 (archive_file_offset
8944 + offset_from_vma (file, dynamic_info[DT_HASH],
8945 sizeof nb + sizeof nc)),
d93f0186 8946 SEEK_SET))
252b5132 8947 {
591a748a 8948 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 8949 goto no_hash;
252b5132
RH
8950 }
8951
66543521 8952 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
8953 {
8954 error (_("Failed to read in number of buckets\n"));
d3a44ec6 8955 goto no_hash;
252b5132
RH
8956 }
8957
66543521 8958 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
8959 {
8960 error (_("Failed to read in number of chains\n"));
d3a44ec6 8961 goto no_hash;
252b5132
RH
8962 }
8963
66543521
AM
8964 nbuckets = byte_get (nb, hash_ent_size);
8965 nchains = byte_get (nc, hash_ent_size);
252b5132 8966
66543521
AM
8967 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
8968 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 8969
d3a44ec6 8970 no_hash:
252b5132 8971 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
8972 {
8973 if (do_using_dynamic)
8974 return 0;
8975 free (buckets);
8976 free (chains);
8977 buckets = NULL;
8978 chains = NULL;
8979 nbuckets = 0;
8980 nchains = 0;
8981 }
252b5132
RH
8982 }
8983
6bd1a22c
L
8984 if (dynamic_info_DT_GNU_HASH
8985 && (do_histogram
2c610e4b
L
8986 || (do_using_dynamic
8987 && !do_dyn_syms
8988 && dynamic_strings != NULL)))
252b5132 8989 {
6bd1a22c
L
8990 unsigned char nb[16];
8991 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
8992 bfd_vma buckets_vma;
8993
8994 if (fseek (file,
8995 (archive_file_offset
8996 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
8997 sizeof nb)),
8998 SEEK_SET))
8999 {
9000 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9001 goto no_gnu_hash;
6bd1a22c 9002 }
252b5132 9003
6bd1a22c
L
9004 if (fread (nb, 16, 1, file) != 1)
9005 {
9006 error (_("Failed to read in number of buckets\n"));
d3a44ec6 9007 goto no_gnu_hash;
6bd1a22c
L
9008 }
9009
9010 ngnubuckets = byte_get (nb, 4);
9011 gnusymidx = byte_get (nb + 4, 4);
9012 bitmaskwords = byte_get (nb + 8, 4);
9013 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 9014 if (is_32bit_elf)
6bd1a22c 9015 buckets_vma += bitmaskwords * 4;
f7a99963 9016 else
6bd1a22c 9017 buckets_vma += bitmaskwords * 8;
252b5132 9018
6bd1a22c
L
9019 if (fseek (file,
9020 (archive_file_offset
9021 + offset_from_vma (file, buckets_vma, 4)),
9022 SEEK_SET))
252b5132 9023 {
6bd1a22c 9024 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9025 goto no_gnu_hash;
6bd1a22c
L
9026 }
9027
9028 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 9029
6bd1a22c 9030 if (gnubuckets == NULL)
d3a44ec6 9031 goto no_gnu_hash;
6bd1a22c
L
9032
9033 for (i = 0; i < ngnubuckets; i++)
9034 if (gnubuckets[i] != 0)
9035 {
9036 if (gnubuckets[i] < gnusymidx)
9037 return 0;
9038
9039 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
9040 maxchain = gnubuckets[i];
9041 }
9042
9043 if (maxchain == 0xffffffff)
d3a44ec6 9044 goto no_gnu_hash;
6bd1a22c
L
9045
9046 maxchain -= gnusymidx;
9047
9048 if (fseek (file,
9049 (archive_file_offset
9050 + offset_from_vma (file, buckets_vma
9051 + 4 * (ngnubuckets + maxchain), 4)),
9052 SEEK_SET))
9053 {
9054 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9055 goto no_gnu_hash;
6bd1a22c
L
9056 }
9057
9058 do
9059 {
9060 if (fread (nb, 4, 1, file) != 1)
252b5132 9061 {
6bd1a22c 9062 error (_("Failed to determine last chain length\n"));
d3a44ec6 9063 goto no_gnu_hash;
6bd1a22c 9064 }
252b5132 9065
6bd1a22c 9066 if (maxchain + 1 == 0)
d3a44ec6 9067 goto no_gnu_hash;
252b5132 9068
6bd1a22c
L
9069 ++maxchain;
9070 }
9071 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 9072
6bd1a22c
L
9073 if (fseek (file,
9074 (archive_file_offset
9075 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
9076 SEEK_SET))
9077 {
9078 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 9079 goto no_gnu_hash;
6bd1a22c
L
9080 }
9081
9082 gnuchains = get_dynamic_data (file, maxchain, 4);
9083
d3a44ec6 9084 no_gnu_hash:
6bd1a22c 9085 if (gnuchains == NULL)
d3a44ec6
JJ
9086 {
9087 free (gnubuckets);
d3a44ec6
JJ
9088 gnubuckets = NULL;
9089 ngnubuckets = 0;
f64fddf1
NC
9090 if (do_using_dynamic)
9091 return 0;
d3a44ec6 9092 }
6bd1a22c
L
9093 }
9094
9095 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
9096 && do_syms
9097 && do_using_dynamic
9098 && dynamic_strings != NULL)
9099 {
9100 unsigned long hn;
9101
9102 if (dynamic_info[DT_HASH])
9103 {
9104 bfd_vma si;
9105
9106 printf (_("\nSymbol table for image:\n"));
9107 if (is_32bit_elf)
9108 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9109 else
9110 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9111
9112 for (hn = 0; hn < nbuckets; hn++)
9113 {
9114 if (! buckets[hn])
9115 continue;
9116
9117 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
9118 print_dynamic_symbol (si, hn);
252b5132
RH
9119 }
9120 }
6bd1a22c
L
9121
9122 if (dynamic_info_DT_GNU_HASH)
9123 {
9124 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
9125 if (is_32bit_elf)
9126 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9127 else
9128 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
9129
9130 for (hn = 0; hn < ngnubuckets; ++hn)
9131 if (gnubuckets[hn] != 0)
9132 {
9133 bfd_vma si = gnubuckets[hn];
9134 bfd_vma off = si - gnusymidx;
9135
9136 do
9137 {
9138 print_dynamic_symbol (si, hn);
9139 si++;
9140 }
9141 while ((gnuchains[off++] & 1) == 0);
9142 }
9143 }
252b5132 9144 }
2c610e4b 9145 else if (do_dyn_syms || (do_syms && !do_using_dynamic))
252b5132 9146 {
b34976b6 9147 unsigned int i;
252b5132
RH
9148
9149 for (i = 0, section = section_headers;
9150 i < elf_header.e_shnum;
9151 i++, section++)
9152 {
b34976b6 9153 unsigned int si;
2cf0635d 9154 char * strtab = NULL;
c256ffe7 9155 unsigned long int strtab_size = 0;
2cf0635d
NC
9156 Elf_Internal_Sym * symtab;
9157 Elf_Internal_Sym * psym;
252b5132 9158
2c610e4b
L
9159 if ((section->sh_type != SHT_SYMTAB
9160 && section->sh_type != SHT_DYNSYM)
9161 || (!do_syms
9162 && section->sh_type == SHT_SYMTAB))
252b5132
RH
9163 continue;
9164
dd24e3da
NC
9165 if (section->sh_entsize == 0)
9166 {
9167 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
9168 SECTION_NAME (section));
9169 continue;
9170 }
9171
252b5132
RH
9172 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
9173 SECTION_NAME (section),
9174 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 9175
f7a99963 9176 if (is_32bit_elf)
ca47b30c 9177 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 9178 else
ca47b30c 9179 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 9180
9ad5cbcf 9181 symtab = GET_ELF_SYMBOLS (file, section);
252b5132
RH
9182 if (symtab == NULL)
9183 continue;
9184
9185 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
9186 {
9187 strtab = string_table;
9188 strtab_size = string_table_length;
9189 }
4fbb74a6 9190 else if (section->sh_link < elf_header.e_shnum)
252b5132 9191 {
2cf0635d 9192 Elf_Internal_Shdr * string_sec;
252b5132 9193
4fbb74a6 9194 string_sec = section_headers + section->sh_link;
252b5132 9195
3f5e193b
NC
9196 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
9197 1, string_sec->sh_size,
9198 _("string table"));
c256ffe7 9199 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
9200 }
9201
9202 for (si = 0, psym = symtab;
9203 si < section->sh_size / section->sh_entsize;
b34976b6 9204 si++, psym++)
252b5132 9205 {
5e220199 9206 printf ("%6d: ", si);
f7a99963
NC
9207 print_vma (psym->st_value, LONG_HEX);
9208 putchar (' ');
9209 print_vma (psym->st_size, DEC_5);
d1133906
NC
9210 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
9211 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 9212 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
9213 /* Check to see if any other bits in the st_other field are set.
9214 Note - displaying this information disrupts the layout of the
9215 table being generated, but for the moment this case is very rare. */
9216 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
9217 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 9218 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 9219 print_symbol (25, psym->st_name < strtab_size
2b692964 9220 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 9221
59245841
NC
9222 if (section->sh_type == SHT_DYNSYM
9223 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
252b5132 9224 {
b34976b6
AM
9225 unsigned char data[2];
9226 unsigned short vers_data;
9227 unsigned long offset;
9228 int is_nobits;
9229 int check_def;
252b5132 9230
d93f0186
NC
9231 offset = offset_from_vma
9232 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9233 sizeof data + si * sizeof (vers_data));
252b5132 9234
59245841
NC
9235 if (get_data (&data, file, offset + si * sizeof (vers_data),
9236 sizeof (data), 1, _("version data")) == NULL)
9237 break;
252b5132
RH
9238
9239 vers_data = byte_get (data, 2);
9240
4fbb74a6
AM
9241 is_nobits = (psym->st_shndx < elf_header.e_shnum
9242 && section_headers[psym->st_shndx].sh_type
c256ffe7 9243 == SHT_NOBITS);
252b5132
RH
9244
9245 check_def = (psym->st_shndx != SHN_UNDEF);
9246
c244d050 9247 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
252b5132 9248 {
b34976b6 9249 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
00d93f34 9250 && (is_nobits || ! check_def))
252b5132 9251 {
b34976b6
AM
9252 Elf_External_Verneed evn;
9253 Elf_Internal_Verneed ivn;
9254 Elf_Internal_Vernaux ivna;
252b5132
RH
9255
9256 /* We must test both. */
d93f0186
NC
9257 offset = offset_from_vma
9258 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9259 sizeof evn);
252b5132 9260
252b5132
RH
9261 do
9262 {
b34976b6 9263 unsigned long vna_off;
252b5132 9264
59245841
NC
9265 if (get_data (&evn, file, offset, sizeof (evn), 1,
9266 _("version need")) == NULL)
9267 {
9268 ivna.vna_next = 0;
9269 ivna.vna_other = 0;
9270 ivna.vna_name = 0;
9271 break;
9272 }
dd27201e
L
9273
9274 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9275 ivn.vn_next = BYTE_GET (evn.vn_next);
9276
252b5132
RH
9277 vna_off = offset + ivn.vn_aux;
9278
9279 do
9280 {
b34976b6 9281 Elf_External_Vernaux evna;
252b5132 9282
59245841
NC
9283 if (get_data (&evna, file, vna_off,
9284 sizeof (evna), 1,
9285 _("version need aux (3)")) == NULL)
9286 {
9287 ivna.vna_next = 0;
9288 ivna.vna_other = 0;
9289 ivna.vna_name = 0;
9290 }
9291 else
9292 {
9293 ivna.vna_other = BYTE_GET (evna.vna_other);
9294 ivna.vna_next = BYTE_GET (evna.vna_next);
9295 ivna.vna_name = BYTE_GET (evna.vna_name);
9296 }
252b5132
RH
9297
9298 vna_off += ivna.vna_next;
9299 }
9300 while (ivna.vna_other != vers_data
9301 && ivna.vna_next != 0);
9302
9303 if (ivna.vna_other == vers_data)
9304 break;
9305
9306 offset += ivn.vn_next;
9307 }
9308 while (ivn.vn_next != 0);
9309
9310 if (ivna.vna_other == vers_data)
9311 {
9312 printf ("@%s (%d)",
c256ffe7 9313 ivna.vna_name < strtab_size
2b692964 9314 ? strtab + ivna.vna_name : _("<corrupt>"),
c256ffe7 9315 ivna.vna_other);
252b5132
RH
9316 check_def = 0;
9317 }
9318 else if (! is_nobits)
591a748a 9319 error (_("bad dynamic symbol\n"));
252b5132
RH
9320 else
9321 check_def = 1;
9322 }
9323
9324 if (check_def)
9325 {
00d93f34 9326 if (vers_data != 0x8001
b34976b6 9327 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9328 {
b34976b6
AM
9329 Elf_Internal_Verdef ivd;
9330 Elf_Internal_Verdaux ivda;
9331 Elf_External_Verdaux evda;
91d6fa6a 9332 unsigned long off;
252b5132 9333
91d6fa6a 9334 off = offset_from_vma
d93f0186
NC
9335 (file,
9336 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9337 sizeof (Elf_External_Verdef));
252b5132
RH
9338
9339 do
9340 {
b34976b6 9341 Elf_External_Verdef evd;
252b5132 9342
59245841
NC
9343 if (get_data (&evd, file, off, sizeof (evd),
9344 1, _("version def")) == NULL)
9345 {
9346 ivd.vd_ndx = 0;
9347 ivd.vd_aux = 0;
9348 ivd.vd_next = 0;
9349 }
9350 else
9351 {
9352 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9353 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9354 ivd.vd_next = BYTE_GET (evd.vd_next);
9355 }
252b5132 9356
91d6fa6a 9357 off += ivd.vd_next;
252b5132 9358 }
c244d050 9359 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
252b5132
RH
9360 && ivd.vd_next != 0);
9361
91d6fa6a
NC
9362 off -= ivd.vd_next;
9363 off += ivd.vd_aux;
252b5132 9364
59245841
NC
9365 if (get_data (&evda, file, off, sizeof (evda),
9366 1, _("version def aux")) == NULL)
9367 break;
252b5132
RH
9368
9369 ivda.vda_name = BYTE_GET (evda.vda_name);
9370
9371 if (psym->st_name != ivda.vda_name)
c244d050 9372 printf ((vers_data & VERSYM_HIDDEN)
252b5132 9373 ? "@%s" : "@@%s",
c256ffe7 9374 ivda.vda_name < strtab_size
2b692964 9375 ? strtab + ivda.vda_name : _("<corrupt>"));
252b5132
RH
9376 }
9377 }
9378 }
9379 }
9380
9381 putchar ('\n');
9382 }
9383
9384 free (symtab);
9385 if (strtab != string_table)
9386 free (strtab);
9387 }
9388 }
9389 else if (do_syms)
9390 printf
9391 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
9392
9393 if (do_histogram && buckets != NULL)
9394 {
2cf0635d
NC
9395 unsigned long * lengths;
9396 unsigned long * counts;
66543521
AM
9397 unsigned long hn;
9398 bfd_vma si;
9399 unsigned long maxlength = 0;
9400 unsigned long nzero_counts = 0;
9401 unsigned long nsyms = 0;
252b5132 9402
66543521
AM
9403 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
9404 (unsigned long) nbuckets);
252b5132
RH
9405 printf (_(" Length Number %% of total Coverage\n"));
9406
3f5e193b 9407 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
9408 if (lengths == NULL)
9409 {
591a748a 9410 error (_("Out of memory\n"));
252b5132
RH
9411 return 0;
9412 }
9413 for (hn = 0; hn < nbuckets; ++hn)
9414 {
f7a99963 9415 for (si = buckets[hn]; si > 0 && si < nchains; si = chains[si])
252b5132 9416 {
b34976b6 9417 ++nsyms;
252b5132 9418 if (maxlength < ++lengths[hn])
b34976b6 9419 ++maxlength;
252b5132
RH
9420 }
9421 }
9422
3f5e193b 9423 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
9424 if (counts == NULL)
9425 {
591a748a 9426 error (_("Out of memory\n"));
252b5132
RH
9427 return 0;
9428 }
9429
9430 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 9431 ++counts[lengths[hn]];
252b5132 9432
103f02d3 9433 if (nbuckets > 0)
252b5132 9434 {
66543521
AM
9435 unsigned long i;
9436 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 9437 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 9438 for (i = 1; i <= maxlength; ++i)
103f02d3 9439 {
66543521
AM
9440 nzero_counts += counts[i] * i;
9441 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9442 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
9443 (nzero_counts * 100.0) / nsyms);
9444 }
252b5132
RH
9445 }
9446
9447 free (counts);
9448 free (lengths);
9449 }
9450
9451 if (buckets != NULL)
9452 {
9453 free (buckets);
9454 free (chains);
9455 }
9456
d3a44ec6 9457 if (do_histogram && gnubuckets != NULL)
fdc90cb4 9458 {
2cf0635d
NC
9459 unsigned long * lengths;
9460 unsigned long * counts;
fdc90cb4
JJ
9461 unsigned long hn;
9462 unsigned long maxlength = 0;
9463 unsigned long nzero_counts = 0;
9464 unsigned long nsyms = 0;
fdc90cb4 9465
3f5e193b 9466 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
9467 if (lengths == NULL)
9468 {
591a748a 9469 error (_("Out of memory\n"));
fdc90cb4
JJ
9470 return 0;
9471 }
9472
9473 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
9474 (unsigned long) ngnubuckets);
9475 printf (_(" Length Number %% of total Coverage\n"));
9476
9477 for (hn = 0; hn < ngnubuckets; ++hn)
9478 if (gnubuckets[hn] != 0)
9479 {
9480 bfd_vma off, length = 1;
9481
6bd1a22c 9482 for (off = gnubuckets[hn] - gnusymidx;
fdc90cb4
JJ
9483 (gnuchains[off] & 1) == 0; ++off)
9484 ++length;
9485 lengths[hn] = length;
9486 if (length > maxlength)
9487 maxlength = length;
9488 nsyms += length;
9489 }
9490
3f5e193b 9491 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
9492 if (counts == NULL)
9493 {
591a748a 9494 error (_("Out of memory\n"));
fdc90cb4
JJ
9495 return 0;
9496 }
9497
9498 for (hn = 0; hn < ngnubuckets; ++hn)
9499 ++counts[lengths[hn]];
9500
9501 if (ngnubuckets > 0)
9502 {
9503 unsigned long j;
9504 printf (" 0 %-10lu (%5.1f%%)\n",
9505 counts[0], (counts[0] * 100.0) / ngnubuckets);
9506 for (j = 1; j <= maxlength; ++j)
9507 {
9508 nzero_counts += counts[j] * j;
9509 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
9510 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
9511 (nzero_counts * 100.0) / nsyms);
9512 }
9513 }
9514
9515 free (counts);
9516 free (lengths);
9517 free (gnubuckets);
9518 free (gnuchains);
9519 }
9520
252b5132
RH
9521 return 1;
9522}
9523
9524static int
2cf0635d 9525process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 9526{
b4c96d0d 9527 unsigned int i;
252b5132
RH
9528
9529 if (dynamic_syminfo == NULL
9530 || !do_dynamic)
9531 /* No syminfo, this is ok. */
9532 return 1;
9533
9534 /* There better should be a dynamic symbol section. */
9535 if (dynamic_symbols == NULL || dynamic_strings == NULL)
9536 return 0;
9537
9538 if (dynamic_addr)
9539 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
9540 dynamic_syminfo_offset, dynamic_syminfo_nent);
9541
9542 printf (_(" Num: Name BoundTo Flags\n"));
9543 for (i = 0; i < dynamic_syminfo_nent; ++i)
9544 {
9545 unsigned short int flags = dynamic_syminfo[i].si_flags;
9546
31104126 9547 printf ("%4d: ", i);
d79b3d50
NC
9548 if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
9549 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
9550 else
2b692964 9551 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 9552 putchar (' ');
252b5132
RH
9553
9554 switch (dynamic_syminfo[i].si_boundto)
9555 {
9556 case SYMINFO_BT_SELF:
9557 fputs ("SELF ", stdout);
9558 break;
9559 case SYMINFO_BT_PARENT:
9560 fputs ("PARENT ", stdout);
9561 break;
9562 default:
9563 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
9564 && dynamic_syminfo[i].si_boundto < dynamic_nent
9565 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 9566 {
d79b3d50 9567 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
9568 putchar (' ' );
9569 }
252b5132
RH
9570 else
9571 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
9572 break;
9573 }
9574
9575 if (flags & SYMINFO_FLG_DIRECT)
9576 printf (" DIRECT");
9577 if (flags & SYMINFO_FLG_PASSTHRU)
9578 printf (" PASSTHRU");
9579 if (flags & SYMINFO_FLG_COPY)
9580 printf (" COPY");
9581 if (flags & SYMINFO_FLG_LAZYLOAD)
9582 printf (" LAZYLOAD");
9583
9584 puts ("");
9585 }
9586
9587 return 1;
9588}
9589
cf13d699
NC
9590/* Check to see if the given reloc needs to be handled in a target specific
9591 manner. If so then process the reloc and return TRUE otherwise return
9592 FALSE. */
09c11c86 9593
cf13d699
NC
9594static bfd_boolean
9595target_specific_reloc_handling (Elf_Internal_Rela * reloc,
9596 unsigned char * start,
9597 Elf_Internal_Sym * symtab)
252b5132 9598{
cf13d699 9599 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 9600
cf13d699 9601 switch (elf_header.e_machine)
252b5132 9602 {
cf13d699
NC
9603 case EM_MN10300:
9604 case EM_CYGNUS_MN10300:
9605 {
9606 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 9607
cf13d699
NC
9608 switch (reloc_type)
9609 {
9610 case 34: /* R_MN10300_ALIGN */
9611 return TRUE;
9612 case 33: /* R_MN10300_SYM_DIFF */
9613 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
9614 return TRUE;
9615 case 1: /* R_MN10300_32 */
9616 case 2: /* R_MN10300_16 */
9617 if (saved_sym != NULL)
9618 {
9619 bfd_vma value;
252b5132 9620
cf13d699
NC
9621 value = reloc->r_addend
9622 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
9623 - saved_sym->st_value);
252b5132 9624
cf13d699 9625 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 9626
cf13d699
NC
9627 saved_sym = NULL;
9628 return TRUE;
9629 }
9630 break;
9631 default:
9632 if (saved_sym != NULL)
9633 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc"));
9634 break;
9635 }
9636 break;
9637 }
252b5132
RH
9638 }
9639
cf13d699 9640 return FALSE;
252b5132
RH
9641}
9642
aca88567
NC
9643/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
9644 DWARF debug sections. This is a target specific test. Note - we do not
9645 go through the whole including-target-headers-multiple-times route, (as
9646 we have already done with <elf/h8.h>) because this would become very
9647 messy and even then this function would have to contain target specific
9648 information (the names of the relocs instead of their numeric values).
9649 FIXME: This is not the correct way to solve this problem. The proper way
9650 is to have target specific reloc sizing and typing functions created by
9651 the reloc-macros.h header, in the same way that it already creates the
9652 reloc naming functions. */
9653
9654static bfd_boolean
9655is_32bit_abs_reloc (unsigned int reloc_type)
9656{
9657 switch (elf_header.e_machine)
9658 {
41e92641
NC
9659 case EM_386:
9660 case EM_486:
9661 return reloc_type == 1; /* R_386_32. */
aca88567
NC
9662 case EM_68K:
9663 return reloc_type == 1; /* R_68K_32. */
9664 case EM_860:
9665 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
9666 case EM_960:
9667 return reloc_type == 2; /* R_960_32. */
aca88567 9668 case EM_ALPHA:
137b6b5f 9669 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
9670 case EM_ARC:
9671 return reloc_type == 1; /* R_ARC_32. */
9672 case EM_ARM:
9673 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 9674 case EM_AVR_OLD:
aca88567
NC
9675 case EM_AVR:
9676 return reloc_type == 1;
9677 case EM_BLACKFIN:
9678 return reloc_type == 0x12; /* R_byte4_data. */
9679 case EM_CRIS:
9680 return reloc_type == 3; /* R_CRIS_32. */
9681 case EM_CR16:
6c03b1ed 9682 case EM_CR16_OLD:
aca88567
NC
9683 return reloc_type == 3; /* R_CR16_NUM32. */
9684 case EM_CRX:
9685 return reloc_type == 15; /* R_CRX_NUM32. */
9686 case EM_CYGNUS_FRV:
9687 return reloc_type == 1;
41e92641
NC
9688 case EM_CYGNUS_D10V:
9689 case EM_D10V:
9690 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
9691 case EM_CYGNUS_D30V:
9692 case EM_D30V:
9693 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
9694 case EM_DLX:
9695 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
9696 case EM_CYGNUS_FR30:
9697 case EM_FR30:
9698 return reloc_type == 3; /* R_FR30_32. */
9699 case EM_H8S:
9700 case EM_H8_300:
9701 case EM_H8_300H:
9702 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
9703 case EM_IA_64:
9704 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
9705 case EM_IP2K_OLD:
9706 case EM_IP2K:
9707 return reloc_type == 2; /* R_IP2K_32. */
9708 case EM_IQ2000:
9709 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
9710 case EM_LATTICEMICO32:
9711 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 9712 case EM_M32C_OLD:
aca88567
NC
9713 case EM_M32C:
9714 return reloc_type == 3; /* R_M32C_32. */
9715 case EM_M32R:
9716 return reloc_type == 34; /* R_M32R_32_RELA. */
9717 case EM_MCORE:
9718 return reloc_type == 1; /* R_MCORE_ADDR32. */
9719 case EM_CYGNUS_MEP:
9720 return reloc_type == 4; /* R_MEP_32. */
137b6b5f
AM
9721 case EM_MICROBLAZE:
9722 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
9723 case EM_MIPS:
9724 return reloc_type == 2; /* R_MIPS_32. */
9725 case EM_MMIX:
9726 return reloc_type == 4; /* R_MMIX_32. */
9727 case EM_CYGNUS_MN10200:
9728 case EM_MN10200:
9729 return reloc_type == 1; /* R_MN10200_32. */
9730 case EM_CYGNUS_MN10300:
9731 case EM_MN10300:
9732 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
9733 case EM_MOXIE:
9734 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
9735 case EM_MSP430_OLD:
9736 case EM_MSP430:
9737 return reloc_type == 1; /* R_MSP43_32. */
9738 case EM_MT:
9739 return reloc_type == 2; /* R_MT_32. */
3e0873ac
NC
9740 case EM_ALTERA_NIOS2:
9741 case EM_NIOS32:
9742 return reloc_type == 1; /* R_NIOS_32. */
41e92641
NC
9743 case EM_OPENRISC:
9744 case EM_OR32:
9745 return reloc_type == 1; /* R_OR32_32. */
aca88567 9746 case EM_PARISC:
5fda8eca
NC
9747 return (reloc_type == 1 /* R_PARISC_DIR32. */
9748 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
9749 case EM_PJ:
9750 case EM_PJ_OLD:
9751 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
9752 case EM_PPC64:
9753 return reloc_type == 1; /* R_PPC64_ADDR32. */
9754 case EM_PPC:
9755 return reloc_type == 1; /* R_PPC_ADDR32. */
c7927a3c
NC
9756 case EM_RX:
9757 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
9758 case EM_S370:
9759 return reloc_type == 1; /* R_I370_ADDR31. */
9760 case EM_S390_OLD:
9761 case EM_S390:
9762 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
9763 case EM_SCORE:
9764 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
9765 case EM_SH:
9766 return reloc_type == 1; /* R_SH_DIR32. */
9767 case EM_SPARC32PLUS:
9768 case EM_SPARCV9:
9769 case EM_SPARC:
9770 return reloc_type == 3 /* R_SPARC_32. */
9771 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
9772 case EM_SPU:
9773 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
9774 case EM_TI_C6000:
9775 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
9776 case EM_TILEGX:
9777 return reloc_type == 2; /* R_TILEGX_32. */
9778 case EM_TILEPRO:
9779 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
9780 case EM_CYGNUS_V850:
9781 case EM_V850:
9782 return reloc_type == 6; /* R_V850_ABS32. */
9783 case EM_VAX:
9784 return reloc_type == 1; /* R_VAX_32. */
9785 case EM_X86_64:
8a9036a4 9786 case EM_L1OM:
7a9068fe 9787 case EM_K1OM:
aca88567 9788 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
9789 case EM_XC16X:
9790 case EM_C166:
9791 return reloc_type == 3; /* R_XC16C_ABS_32. */
aca88567
NC
9792 case EM_XSTORMY16:
9793 return reloc_type == 1; /* R_XSTROMY16_32. */
9794 case EM_XTENSA_OLD:
9795 case EM_XTENSA:
9796 return reloc_type == 1; /* R_XTENSA_32. */
aca88567
NC
9797 default:
9798 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
9799 elf_header.e_machine);
9800 abort ();
9801 }
9802}
9803
9804/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9805 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
9806
9807static bfd_boolean
9808is_32bit_pcrel_reloc (unsigned int reloc_type)
9809{
9810 switch (elf_header.e_machine)
9811 {
41e92641
NC
9812 case EM_386:
9813 case EM_486:
3e0873ac 9814 return reloc_type == 2; /* R_386_PC32. */
aca88567 9815 case EM_68K:
3e0873ac 9816 return reloc_type == 4; /* R_68K_PC32. */
aca88567
NC
9817 case EM_ALPHA:
9818 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 9819 case EM_ARM:
3e0873ac 9820 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
9821 case EM_MICROBLAZE:
9822 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
aca88567 9823 case EM_PARISC:
85acf597 9824 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
9825 case EM_PPC:
9826 return reloc_type == 26; /* R_PPC_REL32. */
9827 case EM_PPC64:
3e0873ac 9828 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
9829 case EM_S390_OLD:
9830 case EM_S390:
3e0873ac 9831 return reloc_type == 5; /* R_390_PC32. */
aca88567 9832 case EM_SH:
3e0873ac 9833 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
9834 case EM_SPARC32PLUS:
9835 case EM_SPARCV9:
9836 case EM_SPARC:
3e0873ac 9837 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
9838 case EM_SPU:
9839 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
9840 case EM_TILEGX:
9841 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
9842 case EM_TILEPRO:
9843 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
aca88567 9844 case EM_X86_64:
8a9036a4 9845 case EM_L1OM:
7a9068fe 9846 case EM_K1OM:
3e0873ac 9847 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
9848 case EM_XTENSA_OLD:
9849 case EM_XTENSA:
9850 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
9851 default:
9852 /* Do not abort or issue an error message here. Not all targets use
9853 pc-relative 32-bit relocs in their DWARF debug information and we
9854 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
9855 more helpful warning message will be generated by apply_relocations
9856 anyway, so just return. */
aca88567
NC
9857 return FALSE;
9858 }
9859}
9860
9861/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9862 a 64-bit absolute RELA relocation used in DWARF debug sections. */
9863
9864static bfd_boolean
9865is_64bit_abs_reloc (unsigned int reloc_type)
9866{
9867 switch (elf_header.e_machine)
9868 {
9869 case EM_ALPHA:
9870 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
9871 case EM_IA_64:
9872 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
9873 case EM_PARISC:
9874 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
9875 case EM_PPC64:
9876 return reloc_type == 38; /* R_PPC64_ADDR64. */
9877 case EM_SPARC32PLUS:
9878 case EM_SPARCV9:
9879 case EM_SPARC:
9880 return reloc_type == 54; /* R_SPARC_UA64. */
9881 case EM_X86_64:
8a9036a4 9882 case EM_L1OM:
7a9068fe 9883 case EM_K1OM:
aca88567 9884 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
9885 case EM_S390_OLD:
9886 case EM_S390:
aa137e4d
NC
9887 return reloc_type == 22; /* R_S390_64. */
9888 case EM_TILEGX:
9889 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 9890 case EM_MIPS:
aa137e4d 9891 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
9892 default:
9893 return FALSE;
9894 }
9895}
9896
85acf597
RH
9897/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
9898 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
9899
9900static bfd_boolean
9901is_64bit_pcrel_reloc (unsigned int reloc_type)
9902{
9903 switch (elf_header.e_machine)
9904 {
9905 case EM_ALPHA:
aa137e4d 9906 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 9907 case EM_IA_64:
aa137e4d 9908 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 9909 case EM_PARISC:
aa137e4d 9910 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 9911 case EM_PPC64:
aa137e4d 9912 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
9913 case EM_SPARC32PLUS:
9914 case EM_SPARCV9:
9915 case EM_SPARC:
aa137e4d 9916 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 9917 case EM_X86_64:
8a9036a4 9918 case EM_L1OM:
7a9068fe 9919 case EM_K1OM:
aa137e4d 9920 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
9921 case EM_S390_OLD:
9922 case EM_S390:
aa137e4d
NC
9923 return reloc_type == 23; /* R_S390_PC64. */
9924 case EM_TILEGX:
9925 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
9926 default:
9927 return FALSE;
9928 }
9929}
9930
4dc3c23d
AM
9931/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9932 a 24-bit absolute RELA relocation used in DWARF debug sections. */
9933
9934static bfd_boolean
9935is_24bit_abs_reloc (unsigned int reloc_type)
9936{
9937 switch (elf_header.e_machine)
9938 {
9939 case EM_CYGNUS_MN10200:
9940 case EM_MN10200:
9941 return reloc_type == 4; /* R_MN10200_24. */
9942 default:
9943 return FALSE;
9944 }
9945}
9946
aca88567
NC
9947/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
9948 a 16-bit absolute RELA relocation used in DWARF debug sections. */
9949
9950static bfd_boolean
9951is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
9952{
9953 switch (elf_header.e_machine)
9954 {
aca88567
NC
9955 case EM_AVR_OLD:
9956 case EM_AVR:
9957 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
9958 case EM_CYGNUS_D10V:
9959 case EM_D10V:
9960 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
9961 case EM_H8S:
9962 case EM_H8_300:
9963 case EM_H8_300H:
aca88567
NC
9964 return reloc_type == R_H8_DIR16;
9965 case EM_IP2K_OLD:
9966 case EM_IP2K:
9967 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 9968 case EM_M32C_OLD:
f4236fe4
DD
9969 case EM_M32C:
9970 return reloc_type == 1; /* R_M32C_16 */
aca88567
NC
9971 case EM_MSP430_OLD:
9972 case EM_MSP430:
9973 return reloc_type == 5; /* R_MSP430_16_BYTE. */
3e0873ac
NC
9974 case EM_ALTERA_NIOS2:
9975 case EM_NIOS32:
9976 return reloc_type == 9; /* R_NIOS_16. */
40b36596
JM
9977 case EM_TI_C6000:
9978 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
9979 case EM_XC16X:
9980 case EM_C166:
9981 return reloc_type == 2; /* R_XC16C_ABS_16. */
4b78141a 9982 default:
aca88567 9983 return FALSE;
4b78141a
NC
9984 }
9985}
9986
2a7b2e88
JK
9987/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
9988 relocation entries (possibly formerly used for SHT_GROUP sections). */
9989
9990static bfd_boolean
9991is_none_reloc (unsigned int reloc_type)
9992{
9993 switch (elf_header.e_machine)
9994 {
cb8f3167
NC
9995 case EM_68K: /* R_68K_NONE. */
9996 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
9997 case EM_SPARC32PLUS:
9998 case EM_SPARCV9:
cb8f3167
NC
9999 case EM_SPARC: /* R_SPARC_NONE. */
10000 case EM_MIPS: /* R_MIPS_NONE. */
10001 case EM_PARISC: /* R_PARISC_NONE. */
10002 case EM_ALPHA: /* R_ALPHA_NONE. */
10003 case EM_PPC: /* R_PPC_NONE. */
10004 case EM_PPC64: /* R_PPC64_NONE. */
10005 case EM_ARM: /* R_ARM_NONE. */
10006 case EM_IA_64: /* R_IA64_NONE. */
10007 case EM_SH: /* R_SH_NONE. */
2a7b2e88 10008 case EM_S390_OLD:
cb8f3167
NC
10009 case EM_S390: /* R_390_NONE. */
10010 case EM_CRIS: /* R_CRIS_NONE. */
10011 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 10012 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 10013 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 10014 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 10015 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 10016 case EM_M32R: /* R_M32R_NONE. */
40b36596 10017 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
10018 case EM_TILEGX: /* R_TILEGX_NONE. */
10019 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
10020 case EM_XC16X:
10021 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 10022 return reloc_type == 0;
58332dda
JK
10023 case EM_XTENSA_OLD:
10024 case EM_XTENSA:
4dc3c23d
AM
10025 return (reloc_type == 0 /* R_XTENSA_NONE. */
10026 || reloc_type == 17 /* R_XTENSA_DIFF8. */
10027 || reloc_type == 18 /* R_XTENSA_DIFF16. */
10028 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
2a7b2e88
JK
10029 }
10030 return FALSE;
10031}
10032
cf13d699
NC
10033/* Apply relocations to a section.
10034 Note: So far support has been added only for those relocations
10035 which can be found in debug sections.
10036 FIXME: Add support for more relocations ? */
1b315056 10037
cf13d699
NC
10038static void
10039apply_relocations (void * file,
10040 Elf_Internal_Shdr * section,
10041 unsigned char * start)
1b315056 10042{
cf13d699
NC
10043 Elf_Internal_Shdr * relsec;
10044 unsigned char * end = start + section->sh_size;
cb8f3167 10045
cf13d699
NC
10046 if (elf_header.e_type != ET_REL)
10047 return;
1b315056 10048
cf13d699 10049 /* Find the reloc section associated with the section. */
5b18a4bc
NC
10050 for (relsec = section_headers;
10051 relsec < section_headers + elf_header.e_shnum;
10052 ++relsec)
252b5132 10053 {
41e92641
NC
10054 bfd_boolean is_rela;
10055 unsigned long num_relocs;
2cf0635d
NC
10056 Elf_Internal_Rela * relocs;
10057 Elf_Internal_Rela * rp;
10058 Elf_Internal_Shdr * symsec;
10059 Elf_Internal_Sym * symtab;
10060 Elf_Internal_Sym * sym;
252b5132 10061
41e92641 10062 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
10063 || relsec->sh_info >= elf_header.e_shnum
10064 || section_headers + relsec->sh_info != section
c256ffe7 10065 || relsec->sh_size == 0
4fbb74a6 10066 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 10067 continue;
428409d5 10068
41e92641
NC
10069 is_rela = relsec->sh_type == SHT_RELA;
10070
10071 if (is_rela)
10072 {
3f5e193b
NC
10073 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
10074 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10075 return;
10076 }
10077 else
10078 {
3f5e193b
NC
10079 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
10080 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
10081 return;
10082 }
10083
10084 /* SH uses RELA but uses in place value instead of the addend field. */
10085 if (elf_header.e_machine == EM_SH)
10086 is_rela = FALSE;
428409d5 10087
4fbb74a6 10088 symsec = section_headers + relsec->sh_link;
3f5e193b 10089 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec);
103f02d3 10090
41e92641 10091 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 10092 {
41e92641
NC
10093 bfd_vma addend;
10094 unsigned int reloc_type;
10095 unsigned int reloc_size;
91d6fa6a 10096 unsigned char * rloc;
4b78141a 10097
aca88567 10098 reloc_type = get_reloc_type (rp->r_info);
41e92641 10099
98fb390a 10100 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 10101 continue;
98fb390a
NC
10102 else if (is_none_reloc (reloc_type))
10103 continue;
10104 else if (is_32bit_abs_reloc (reloc_type)
10105 || is_32bit_pcrel_reloc (reloc_type))
aca88567 10106 reloc_size = 4;
85acf597
RH
10107 else if (is_64bit_abs_reloc (reloc_type)
10108 || is_64bit_pcrel_reloc (reloc_type))
aca88567 10109 reloc_size = 8;
4dc3c23d
AM
10110 else if (is_24bit_abs_reloc (reloc_type))
10111 reloc_size = 3;
aca88567
NC
10112 else if (is_16bit_abs_reloc (reloc_type))
10113 reloc_size = 2;
10114 else
4b78141a 10115 {
41e92641 10116 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
aca88567 10117 reloc_type, SECTION_NAME (section));
4b78141a
NC
10118 continue;
10119 }
103f02d3 10120
91d6fa6a
NC
10121 rloc = start + rp->r_offset;
10122 if ((rloc + reloc_size) > end)
700dd8b7
L
10123 {
10124 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
10125 (unsigned long) rp->r_offset,
10126 SECTION_NAME (section));
10127 continue;
10128 }
103f02d3 10129
41e92641
NC
10130 sym = symtab + get_reloc_symindex (rp->r_info);
10131
10132 /* If the reloc has a symbol associated with it,
55f25fc3
L
10133 make sure that it is of an appropriate type.
10134
10135 Relocations against symbols without type can happen.
10136 Gcc -feliminate-dwarf2-dups may generate symbols
10137 without type for debug info.
10138
10139 Icc generates relocations against function symbols
10140 instead of local labels.
10141
10142 Relocations against object symbols can happen, eg when
10143 referencing a global array. For an example of this see
10144 the _clz.o binary in libgcc.a. */
aca88567 10145 if (sym != symtab
55f25fc3 10146 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 10147 {
41e92641 10148 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 10149 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 10150 (long int)(rp - relocs),
41e92641 10151 SECTION_NAME (relsec));
aca88567 10152 continue;
5b18a4bc 10153 }
252b5132 10154
4dc3c23d
AM
10155 addend = 0;
10156 if (is_rela)
10157 addend += rp->r_addend;
c47320c3
AM
10158 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
10159 partial_inplace. */
4dc3c23d
AM
10160 if (!is_rela
10161 || (elf_header.e_machine == EM_XTENSA
10162 && reloc_type == 1)
10163 || ((elf_header.e_machine == EM_PJ
10164 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
10165 && reloc_type == 1)
10166 || ((elf_header.e_machine == EM_D30V
10167 || elf_header.e_machine == EM_CYGNUS_D30V)
10168 && reloc_type == 12))
91d6fa6a 10169 addend += byte_get (rloc, reloc_size);
cb8f3167 10170
85acf597
RH
10171 if (is_32bit_pcrel_reloc (reloc_type)
10172 || is_64bit_pcrel_reloc (reloc_type))
10173 {
10174 /* On HPPA, all pc-relative relocations are biased by 8. */
10175 if (elf_header.e_machine == EM_PARISC)
10176 addend -= 8;
91d6fa6a 10177 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
10178 reloc_size);
10179 }
41e92641 10180 else
91d6fa6a 10181 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 10182 }
252b5132 10183
5b18a4bc 10184 free (symtab);
41e92641 10185 free (relocs);
5b18a4bc
NC
10186 break;
10187 }
5b18a4bc 10188}
103f02d3 10189
cf13d699
NC
10190#ifdef SUPPORT_DISASSEMBLY
10191static int
10192disassemble_section (Elf_Internal_Shdr * section, FILE * file)
10193{
10194 printf (_("\nAssembly dump of section %s\n"),
10195 SECTION_NAME (section));
10196
10197 /* XXX -- to be done --- XXX */
10198
10199 return 1;
10200}
10201#endif
10202
10203/* Reads in the contents of SECTION from FILE, returning a pointer
10204 to a malloc'ed buffer or NULL if something went wrong. */
10205
10206static char *
10207get_section_contents (Elf_Internal_Shdr * section, FILE * file)
10208{
10209 bfd_size_type num_bytes;
10210
10211 num_bytes = section->sh_size;
10212
10213 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
10214 {
10215 printf (_("\nSection '%s' has no data to dump.\n"),
10216 SECTION_NAME (section));
10217 return NULL;
10218 }
10219
3f5e193b
NC
10220 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
10221 _("section contents"));
cf13d699
NC
10222}
10223
dd24e3da 10224
cf13d699
NC
10225static void
10226dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
10227{
10228 Elf_Internal_Shdr * relsec;
10229 bfd_size_type num_bytes;
cf13d699
NC
10230 char * data;
10231 char * end;
10232 char * start;
10233 char * name = SECTION_NAME (section);
10234 bfd_boolean some_strings_shown;
10235
10236 start = get_section_contents (section, file);
10237 if (start == NULL)
10238 return;
10239
10240 printf (_("\nString dump of section '%s':\n"), name);
10241
10242 /* If the section being dumped has relocations against it the user might
10243 be expecting these relocations to have been applied. Check for this
10244 case and issue a warning message in order to avoid confusion.
10245 FIXME: Maybe we ought to have an option that dumps a section with
10246 relocs applied ? */
10247 for (relsec = section_headers;
10248 relsec < section_headers + elf_header.e_shnum;
10249 ++relsec)
10250 {
10251 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10252 || relsec->sh_info >= elf_header.e_shnum
10253 || section_headers + relsec->sh_info != section
10254 || relsec->sh_size == 0
10255 || relsec->sh_link >= elf_header.e_shnum)
10256 continue;
10257
10258 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10259 break;
10260 }
10261
10262 num_bytes = section->sh_size;
cf13d699
NC
10263 data = start;
10264 end = start + num_bytes;
10265 some_strings_shown = FALSE;
10266
10267 while (data < end)
10268 {
10269 while (!ISPRINT (* data))
10270 if (++ data >= end)
10271 break;
10272
10273 if (data < end)
10274 {
10275#ifndef __MSVCRT__
c975cc98
NC
10276 /* PR 11128: Use two separate invocations in order to work
10277 around bugs in the Solaris 8 implementation of printf. */
10278 printf (" [%6tx] ", data - start);
10279 printf ("%s\n", data);
cf13d699
NC
10280#else
10281 printf (" [%6Ix] %s\n", (size_t) (data - start), data);
10282#endif
10283 data += strlen (data);
10284 some_strings_shown = TRUE;
10285 }
10286 }
10287
10288 if (! some_strings_shown)
10289 printf (_(" No strings found in this section."));
10290
10291 free (start);
10292
10293 putchar ('\n');
10294}
10295
10296static void
10297dump_section_as_bytes (Elf_Internal_Shdr * section,
10298 FILE * file,
10299 bfd_boolean relocate)
10300{
10301 Elf_Internal_Shdr * relsec;
10302 bfd_size_type bytes;
10303 bfd_vma addr;
10304 unsigned char * data;
10305 unsigned char * start;
10306
10307 start = (unsigned char *) get_section_contents (section, file);
10308 if (start == NULL)
10309 return;
10310
10311 printf (_("\nHex dump of section '%s':\n"), SECTION_NAME (section));
10312
10313 if (relocate)
10314 {
10315 apply_relocations (file, section, start);
10316 }
10317 else
10318 {
10319 /* If the section being dumped has relocations against it the user might
10320 be expecting these relocations to have been applied. Check for this
10321 case and issue a warning message in order to avoid confusion.
10322 FIXME: Maybe we ought to have an option that dumps a section with
10323 relocs applied ? */
10324 for (relsec = section_headers;
10325 relsec < section_headers + elf_header.e_shnum;
10326 ++relsec)
10327 {
10328 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
10329 || relsec->sh_info >= elf_header.e_shnum
10330 || section_headers + relsec->sh_info != section
10331 || relsec->sh_size == 0
10332 || relsec->sh_link >= elf_header.e_shnum)
10333 continue;
10334
10335 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
10336 break;
10337 }
10338 }
10339
10340 addr = section->sh_addr;
10341 bytes = section->sh_size;
10342 data = start;
10343
10344 while (bytes)
10345 {
10346 int j;
10347 int k;
10348 int lbytes;
10349
10350 lbytes = (bytes > 16 ? 16 : bytes);
10351
10352 printf (" 0x%8.8lx ", (unsigned long) addr);
10353
10354 for (j = 0; j < 16; j++)
10355 {
10356 if (j < lbytes)
10357 printf ("%2.2x", data[j]);
10358 else
10359 printf (" ");
10360
10361 if ((j & 3) == 3)
10362 printf (" ");
10363 }
10364
10365 for (j = 0; j < lbytes; j++)
10366 {
10367 k = data[j];
10368 if (k >= ' ' && k < 0x7f)
10369 printf ("%c", k);
10370 else
10371 printf (".");
10372 }
10373
10374 putchar ('\n');
10375
10376 data += lbytes;
10377 addr += lbytes;
10378 bytes -= lbytes;
10379 }
10380
10381 free (start);
10382
10383 putchar ('\n');
10384}
10385
4a114e3e 10386/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
10387
10388static int
d3dbc530
AM
10389uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
10390 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
10391{
10392#ifndef HAVE_ZLIB_H
cf13d699
NC
10393 return FALSE;
10394#else
10395 dwarf_size_type compressed_size = *size;
10396 unsigned char * compressed_buffer = *buffer;
10397 dwarf_size_type uncompressed_size;
10398 unsigned char * uncompressed_buffer;
10399 z_stream strm;
10400 int rc;
10401 dwarf_size_type header_size = 12;
10402
10403 /* Read the zlib header. In this case, it should be "ZLIB" followed
10404 by the uncompressed section size, 8 bytes in big-endian order. */
10405 if (compressed_size < header_size
10406 || ! streq ((char *) compressed_buffer, "ZLIB"))
10407 return 0;
10408
10409 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
10410 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
10411 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
10412 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
10413 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
10414 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
10415 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
10416 uncompressed_size += compressed_buffer[11];
10417
10418 /* It is possible the section consists of several compressed
10419 buffers concatenated together, so we uncompress in a loop. */
10420 strm.zalloc = NULL;
10421 strm.zfree = NULL;
10422 strm.opaque = NULL;
10423 strm.avail_in = compressed_size - header_size;
10424 strm.next_in = (Bytef *) compressed_buffer + header_size;
10425 strm.avail_out = uncompressed_size;
3f5e193b 10426 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
10427
10428 rc = inflateInit (& strm);
10429 while (strm.avail_in > 0)
10430 {
10431 if (rc != Z_OK)
10432 goto fail;
10433 strm.next_out = ((Bytef *) uncompressed_buffer
10434 + (uncompressed_size - strm.avail_out));
10435 rc = inflate (&strm, Z_FINISH);
10436 if (rc != Z_STREAM_END)
10437 goto fail;
10438 rc = inflateReset (& strm);
10439 }
10440 rc = inflateEnd (& strm);
10441 if (rc != Z_OK
10442 || strm.avail_out != 0)
10443 goto fail;
10444
10445 free (compressed_buffer);
10446 *buffer = uncompressed_buffer;
10447 *size = uncompressed_size;
10448 return 1;
10449
10450 fail:
10451 free (uncompressed_buffer);
4a114e3e
L
10452 /* Indicate decompression failure. */
10453 *buffer = NULL;
cf13d699
NC
10454 return 0;
10455#endif /* HAVE_ZLIB_H */
10456}
10457
d966045b
DJ
10458static int
10459load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 10460 Elf_Internal_Shdr * sec, void * file)
1007acb3 10461{
2cf0635d 10462 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 10463 char buf [64];
1007acb3 10464
19e6b90e
L
10465 /* If it is already loaded, do nothing. */
10466 if (section->start != NULL)
10467 return 1;
1007acb3 10468
19e6b90e
L
10469 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
10470 section->address = sec->sh_addr;
3f5e193b
NC
10471 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
10472 sec->sh_offset, 1,
10473 sec->sh_size, buf);
59245841
NC
10474 if (section->start == NULL)
10475 section->size = 0;
10476 else
10477 {
10478 section->size = sec->sh_size;
10479 if (uncompress_section_contents (&section->start, &section->size))
10480 sec->sh_size = section->size;
10481 }
4a114e3e 10482
1b315056
CS
10483 if (section->start == NULL)
10484 return 0;
10485
19e6b90e 10486 if (debug_displays [debug].relocate)
3f5e193b 10487 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 10488
1b315056 10489 return 1;
1007acb3
L
10490}
10491
d966045b 10492int
2cf0635d 10493load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 10494{
2cf0635d
NC
10495 struct dwarf_section * section = &debug_displays [debug].section;
10496 Elf_Internal_Shdr * sec;
d966045b
DJ
10497
10498 /* Locate the debug section. */
10499 sec = find_section (section->uncompressed_name);
10500 if (sec != NULL)
10501 section->name = section->uncompressed_name;
10502 else
10503 {
10504 sec = find_section (section->compressed_name);
10505 if (sec != NULL)
10506 section->name = section->compressed_name;
10507 }
10508 if (sec == NULL)
10509 return 0;
10510
3f5e193b 10511 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
10512}
10513
19e6b90e
L
10514void
10515free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 10516{
2cf0635d 10517 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 10518
19e6b90e
L
10519 if (section->start == NULL)
10520 return;
1007acb3 10521
19e6b90e
L
10522 free ((char *) section->start);
10523 section->start = NULL;
10524 section->address = 0;
10525 section->size = 0;
1007acb3
L
10526}
10527
1007acb3 10528static int
2cf0635d 10529display_debug_section (Elf_Internal_Shdr * section, FILE * file)
1007acb3 10530{
2cf0635d 10531 char * name = SECTION_NAME (section);
19e6b90e
L
10532 bfd_size_type length;
10533 int result = 1;
3f5e193b 10534 int i;
1007acb3 10535
19e6b90e
L
10536 length = section->sh_size;
10537 if (length == 0)
1007acb3 10538 {
19e6b90e
L
10539 printf (_("\nSection '%s' has no debugging data.\n"), name);
10540 return 0;
1007acb3 10541 }
5dff79d8
NC
10542 if (section->sh_type == SHT_NOBITS)
10543 {
10544 /* There is no point in dumping the contents of a debugging section
10545 which has the NOBITS type - the bits in the file will be random.
10546 This can happen when a file containing a .eh_frame section is
10547 stripped with the --only-keep-debug command line option. */
10548 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"), name);
10549 return 0;
10550 }
1007acb3 10551
0112cd26 10552 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 10553 name = ".debug_info";
1007acb3 10554
19e6b90e
L
10555 /* See if we know how to display the contents of this section. */
10556 for (i = 0; i < max; i++)
1b315056
CS
10557 if (streq (debug_displays[i].section.uncompressed_name, name)
10558 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 10559 {
2cf0635d 10560 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
10561 int secondary = (section != find_section (name));
10562
10563 if (secondary)
3f5e193b 10564 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 10565
2b6f5997 10566 if (streq (sec->uncompressed_name, name))
d966045b
DJ
10567 sec->name = sec->uncompressed_name;
10568 else
10569 sec->name = sec->compressed_name;
3f5e193b
NC
10570 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
10571 section, file))
19e6b90e
L
10572 {
10573 result &= debug_displays[i].display (sec, file);
1007acb3 10574
d966045b 10575 if (secondary || (i != info && i != abbrev))
3f5e193b 10576 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 10577 }
1007acb3 10578
19e6b90e
L
10579 break;
10580 }
1007acb3 10581
19e6b90e 10582 if (i == max)
1007acb3 10583 {
19e6b90e
L
10584 printf (_("Unrecognized debug section: %s\n"), name);
10585 result = 0;
1007acb3
L
10586 }
10587
19e6b90e 10588 return result;
5b18a4bc 10589}
103f02d3 10590
aef1f6d0
DJ
10591/* Set DUMP_SECTS for all sections where dumps were requested
10592 based on section name. */
10593
10594static void
10595initialise_dumps_byname (void)
10596{
2cf0635d 10597 struct dump_list_entry * cur;
aef1f6d0
DJ
10598
10599 for (cur = dump_sects_byname; cur; cur = cur->next)
10600 {
10601 unsigned int i;
10602 int any;
10603
10604 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
10605 if (streq (SECTION_NAME (section_headers + i), cur->name))
10606 {
09c11c86 10607 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
10608 any = 1;
10609 }
10610
10611 if (!any)
10612 warn (_("Section '%s' was not dumped because it does not exist!\n"),
10613 cur->name);
10614 }
10615}
10616
5b18a4bc 10617static void
2cf0635d 10618process_section_contents (FILE * file)
5b18a4bc 10619{
2cf0635d 10620 Elf_Internal_Shdr * section;
19e6b90e 10621 unsigned int i;
103f02d3 10622
19e6b90e
L
10623 if (! do_dump)
10624 return;
103f02d3 10625
aef1f6d0
DJ
10626 initialise_dumps_byname ();
10627
19e6b90e
L
10628 for (i = 0, section = section_headers;
10629 i < elf_header.e_shnum && i < num_dump_sects;
10630 i++, section++)
10631 {
10632#ifdef SUPPORT_DISASSEMBLY
10633 if (dump_sects[i] & DISASS_DUMP)
10634 disassemble_section (section, file);
10635#endif
10636 if (dump_sects[i] & HEX_DUMP)
cf13d699 10637 dump_section_as_bytes (section, file, FALSE);
103f02d3 10638
cf13d699
NC
10639 if (dump_sects[i] & RELOC_DUMP)
10640 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
10641
10642 if (dump_sects[i] & STRING_DUMP)
10643 dump_section_as_strings (section, file);
cf13d699
NC
10644
10645 if (dump_sects[i] & DEBUG_DUMP)
10646 display_debug_section (section, file);
5b18a4bc 10647 }
103f02d3 10648
19e6b90e
L
10649 /* Check to see if the user requested a
10650 dump of a section that does not exist. */
10651 while (i++ < num_dump_sects)
10652 if (dump_sects[i])
10653 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 10654}
103f02d3 10655
5b18a4bc 10656static void
19e6b90e 10657process_mips_fpe_exception (int mask)
5b18a4bc 10658{
19e6b90e
L
10659 if (mask)
10660 {
10661 int first = 1;
10662 if (mask & OEX_FPU_INEX)
10663 fputs ("INEX", stdout), first = 0;
10664 if (mask & OEX_FPU_UFLO)
10665 printf ("%sUFLO", first ? "" : "|"), first = 0;
10666 if (mask & OEX_FPU_OFLO)
10667 printf ("%sOFLO", first ? "" : "|"), first = 0;
10668 if (mask & OEX_FPU_DIV0)
10669 printf ("%sDIV0", first ? "" : "|"), first = 0;
10670 if (mask & OEX_FPU_INVAL)
10671 printf ("%sINVAL", first ? "" : "|");
10672 }
5b18a4bc 10673 else
19e6b90e 10674 fputs ("0", stdout);
5b18a4bc 10675}
103f02d3 10676
11c1ff18
PB
10677/* ARM EABI attributes section. */
10678typedef struct
10679{
10680 int tag;
2cf0635d 10681 const char * name;
11c1ff18
PB
10682 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
10683 int type;
2cf0635d 10684 const char ** table;
11c1ff18
PB
10685} arm_attr_public_tag;
10686
2cf0635d 10687static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 10688 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
9e3c6df6 10689 "v6K", "v7", "v6-M", "v6S-M", "v7E-M"};
2cf0635d
NC
10690static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
10691static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 10692 {"No", "Thumb-1", "Thumb-2"};
75375b3e 10693static const char * arm_attr_tag_FP_arch[] =
62f3b8c8 10694 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16"};
2cf0635d 10695static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 10696static const char * arm_attr_tag_Advanced_SIMD_arch[] =
cd21e546 10697 {"No", "NEONv1", "NEONv1 with Fused-MAC"};
2cf0635d 10698static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
10699 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
10700 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 10701static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 10702 {"V6", "SB", "TLS", "Unused"};
2cf0635d 10703static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 10704 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 10705static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 10706 {"Absolute", "PC-relative", "None"};
2cf0635d 10707static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 10708 {"None", "direct", "GOT-indirect"};
2cf0635d 10709static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 10710 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
10711static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
10712static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 10713 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
10714static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
10715static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
10716static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 10717 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 10718static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 10719 {"Unused", "small", "int", "forced to int"};
2cf0635d 10720static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 10721 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 10722static const char * arm_attr_tag_ABI_VFP_args[] =
11c1ff18 10723 {"AAPCS", "VFP registers", "custom"};
2cf0635d 10724static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 10725 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 10726static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
10727 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10728 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 10729static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
10730 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
10731 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 10732static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 10733static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 10734 {"Not Allowed", "Allowed"};
2cf0635d 10735static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 10736 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 10737static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
10738 {"Not Allowed", "Allowed"};
10739static const char * arm_attr_tag_DIV_use[] =
dd24e3da 10740 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 10741 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
10742static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
10743static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 10744 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 10745 "TrustZone and Virtualization Extensions"};
dd24e3da 10746static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 10747 {"Not Allowed", "Allowed"};
11c1ff18
PB
10748
10749#define LOOKUP(id, name) \
10750 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 10751static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
10752{
10753 {4, "CPU_raw_name", 1, NULL},
10754 {5, "CPU_name", 1, NULL},
10755 LOOKUP(6, CPU_arch),
10756 {7, "CPU_arch_profile", 0, NULL},
10757 LOOKUP(8, ARM_ISA_use),
10758 LOOKUP(9, THUMB_ISA_use),
75375b3e 10759 LOOKUP(10, FP_arch),
11c1ff18 10760 LOOKUP(11, WMMX_arch),
f5f53991
AS
10761 LOOKUP(12, Advanced_SIMD_arch),
10762 LOOKUP(13, PCS_config),
11c1ff18
PB
10763 LOOKUP(14, ABI_PCS_R9_use),
10764 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 10765 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
10766 LOOKUP(17, ABI_PCS_GOT_use),
10767 LOOKUP(18, ABI_PCS_wchar_t),
10768 LOOKUP(19, ABI_FP_rounding),
10769 LOOKUP(20, ABI_FP_denormal),
10770 LOOKUP(21, ABI_FP_exceptions),
10771 LOOKUP(22, ABI_FP_user_exceptions),
10772 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
10773 {24, "ABI_align_needed", 0, NULL},
10774 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
10775 LOOKUP(26, ABI_enum_size),
10776 LOOKUP(27, ABI_HardFP_use),
10777 LOOKUP(28, ABI_VFP_args),
10778 LOOKUP(29, ABI_WMMX_args),
10779 LOOKUP(30, ABI_optimization_goals),
10780 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 10781 {32, "compatibility", 0, NULL},
f5f53991 10782 LOOKUP(34, CPU_unaligned_access),
75375b3e 10783 LOOKUP(36, FP_HP_extension),
8e79c3df 10784 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
10785 LOOKUP(42, MPextension_use),
10786 LOOKUP(44, DIV_use),
f5f53991
AS
10787 {64, "nodefaults", 0, NULL},
10788 {65, "also_compatible_with", 0, NULL},
10789 LOOKUP(66, T2EE_use),
10790 {67, "conformance", 1, NULL},
10791 LOOKUP(68, Virtualization_use),
cd21e546 10792 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
10793};
10794#undef LOOKUP
10795
11c1ff18 10796static unsigned char *
2cf0635d 10797display_arm_attribute (unsigned char * p)
11c1ff18
PB
10798{
10799 int tag;
10800 unsigned int len;
10801 int val;
2cf0635d 10802 arm_attr_public_tag * attr;
11c1ff18
PB
10803 unsigned i;
10804 int type;
10805
10806 tag = read_uleb128 (p, &len);
10807 p += len;
10808 attr = NULL;
2cf0635d 10809 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
10810 {
10811 if (arm_attr_public_tags[i].tag == tag)
10812 {
10813 attr = &arm_attr_public_tags[i];
10814 break;
10815 }
10816 }
10817
10818 if (attr)
10819 {
10820 printf (" Tag_%s: ", attr->name);
10821 switch (attr->type)
10822 {
10823 case 0:
10824 switch (tag)
10825 {
10826 case 7: /* Tag_CPU_arch_profile. */
10827 val = read_uleb128 (p, &len);
10828 p += len;
10829 switch (val)
10830 {
2b692964
NC
10831 case 0: printf (_("None\n")); break;
10832 case 'A': printf (_("Application\n")); break;
10833 case 'R': printf (_("Realtime\n")); break;
10834 case 'M': printf (_("Microcontroller\n")); break;
10835 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
10836 default: printf ("??? (%d)\n", val); break;
10837 }
10838 break;
10839
75375b3e
MGD
10840 case 24: /* Tag_align_needed. */
10841 val = read_uleb128 (p, &len);
10842 p += len;
10843 switch (val)
10844 {
2b692964
NC
10845 case 0: printf (_("None\n")); break;
10846 case 1: printf (_("8-byte\n")); break;
10847 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
10848 case 3: printf ("??? 3\n"); break;
10849 default:
10850 if (val <= 12)
dd24e3da 10851 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10852 1 << val);
10853 else
10854 printf ("??? (%d)\n", val);
10855 break;
10856 }
10857 break;
10858
10859 case 25: /* Tag_align_preserved. */
10860 val = read_uleb128 (p, &len);
10861 p += len;
10862 switch (val)
10863 {
2b692964
NC
10864 case 0: printf (_("None\n")); break;
10865 case 1: printf (_("8-byte, except leaf SP\n")); break;
10866 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
10867 case 3: printf ("??? 3\n"); break;
10868 default:
10869 if (val <= 12)
dd24e3da 10870 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
10871 1 << val);
10872 else
10873 printf ("??? (%d)\n", val);
10874 break;
10875 }
10876 break;
10877
11c1ff18
PB
10878 case 32: /* Tag_compatibility. */
10879 val = read_uleb128 (p, &len);
10880 p += len;
2b692964 10881 printf (_("flag = %d, vendor = %s\n"), val, p);
2cf0635d 10882 p += strlen ((char *) p) + 1;
11c1ff18
PB
10883 break;
10884
f5f53991
AS
10885 case 64: /* Tag_nodefaults. */
10886 p++;
2b692964 10887 printf (_("True\n"));
f5f53991
AS
10888 break;
10889
10890 case 65: /* Tag_also_compatible_with. */
10891 val = read_uleb128 (p, &len);
10892 p += len;
10893 if (val == 6 /* Tag_CPU_arch. */)
10894 {
10895 val = read_uleb128 (p, &len);
10896 p += len;
2cf0635d 10897 if ((unsigned int)val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
10898 printf ("??? (%d)\n", val);
10899 else
10900 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
10901 }
10902 else
10903 printf ("???\n");
10904 while (*(p++) != '\0' /* NUL terminator. */);
10905 break;
10906
11c1ff18 10907 default:
2cf0635d 10908 abort ();
11c1ff18
PB
10909 }
10910 return p;
10911
10912 case 1:
10913 case 2:
10914 type = attr->type;
10915 break;
10916
10917 default:
10918 assert (attr->type & 0x80);
10919 val = read_uleb128 (p, &len);
10920 p += len;
10921 type = attr->type & 0x7f;
10922 if (val >= type)
10923 printf ("??? (%d)\n", val);
10924 else
10925 printf ("%s\n", attr->table[val]);
10926 return p;
10927 }
10928 }
10929 else
10930 {
10931 if (tag & 1)
10932 type = 1; /* String. */
10933 else
10934 type = 2; /* uleb128. */
10935 printf (" Tag_unknown_%d: ", tag);
10936 }
10937
10938 if (type == 1)
10939 {
10940 printf ("\"%s\"\n", p);
2cf0635d 10941 p += strlen ((char *) p) + 1;
11c1ff18
PB
10942 }
10943 else
10944 {
10945 val = read_uleb128 (p, &len);
10946 p += len;
10947 printf ("%d (0x%x)\n", val, val);
10948 }
10949
10950 return p;
10951}
10952
104d59d1 10953static unsigned char *
60bca95a
NC
10954display_gnu_attribute (unsigned char * p,
10955 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
104d59d1
JM
10956{
10957 int tag;
10958 unsigned int len;
10959 int val;
10960 int type;
10961
10962 tag = read_uleb128 (p, &len);
10963 p += len;
10964
10965 /* Tag_compatibility is the only generic GNU attribute defined at
10966 present. */
10967 if (tag == 32)
10968 {
10969 val = read_uleb128 (p, &len);
10970 p += len;
2b692964 10971 printf (_("flag = %d, vendor = %s\n"), val, p);
60bca95a 10972 p += strlen ((char *) p) + 1;
104d59d1
JM
10973 return p;
10974 }
10975
10976 if ((tag & 2) == 0 && display_proc_gnu_attribute)
10977 return display_proc_gnu_attribute (p, tag);
10978
10979 if (tag & 1)
10980 type = 1; /* String. */
10981 else
10982 type = 2; /* uleb128. */
10983 printf (" Tag_unknown_%d: ", tag);
10984
10985 if (type == 1)
10986 {
10987 printf ("\"%s\"\n", p);
60bca95a 10988 p += strlen ((char *) p) + 1;
104d59d1
JM
10989 }
10990 else
10991 {
10992 val = read_uleb128 (p, &len);
10993 p += len;
10994 printf ("%d (0x%x)\n", val, val);
10995 }
10996
10997 return p;
10998}
10999
34c8bcba 11000static unsigned char *
2cf0635d 11001display_power_gnu_attribute (unsigned char * p, int tag)
34c8bcba
JM
11002{
11003 int type;
11004 unsigned int len;
11005 int val;
11006
11007 if (tag == Tag_GNU_Power_ABI_FP)
11008 {
11009 val = read_uleb128 (p, &len);
11010 p += len;
11011 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 11012
34c8bcba
JM
11013 switch (val)
11014 {
11015 case 0:
2b692964 11016 printf (_("Hard or soft float\n"));
34c8bcba
JM
11017 break;
11018 case 1:
2b692964 11019 printf (_("Hard float\n"));
34c8bcba
JM
11020 break;
11021 case 2:
2b692964 11022 printf (_("Soft float\n"));
34c8bcba 11023 break;
3c7b9897 11024 case 3:
2b692964 11025 printf (_("Single-precision hard float\n"));
3c7b9897 11026 break;
34c8bcba
JM
11027 default:
11028 printf ("??? (%d)\n", val);
11029 break;
11030 }
11031 return p;
11032 }
11033
c6e65352
DJ
11034 if (tag == Tag_GNU_Power_ABI_Vector)
11035 {
11036 val = read_uleb128 (p, &len);
11037 p += len;
11038 printf (" Tag_GNU_Power_ABI_Vector: ");
11039 switch (val)
11040 {
11041 case 0:
2b692964 11042 printf (_("Any\n"));
c6e65352
DJ
11043 break;
11044 case 1:
2b692964 11045 printf (_("Generic\n"));
c6e65352
DJ
11046 break;
11047 case 2:
11048 printf ("AltiVec\n");
11049 break;
11050 case 3:
11051 printf ("SPE\n");
11052 break;
11053 default:
11054 printf ("??? (%d)\n", val);
11055 break;
11056 }
11057 return p;
11058 }
11059
f82e0623
NF
11060 if (tag == Tag_GNU_Power_ABI_Struct_Return)
11061 {
11062 val = read_uleb128 (p, &len);
11063 p += len;
11064 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
11065 switch (val)
11066 {
11067 case 0:
2b692964 11068 printf (_("Any\n"));
f82e0623
NF
11069 break;
11070 case 1:
11071 printf ("r3/r4\n");
11072 break;
11073 case 2:
2b692964 11074 printf (_("Memory\n"));
f82e0623
NF
11075 break;
11076 default:
11077 printf ("??? (%d)\n", val);
11078 break;
11079 }
11080 return p;
11081 }
11082
34c8bcba
JM
11083 if (tag & 1)
11084 type = 1; /* String. */
11085 else
11086 type = 2; /* uleb128. */
11087 printf (" Tag_unknown_%d: ", tag);
11088
11089 if (type == 1)
11090 {
11091 printf ("\"%s\"\n", p);
60bca95a 11092 p += strlen ((char *) p) + 1;
34c8bcba
JM
11093 }
11094 else
11095 {
11096 val = read_uleb128 (p, &len);
11097 p += len;
11098 printf ("%d (0x%x)\n", val, val);
11099 }
11100
11101 return p;
11102}
11103
9e8c70f9
DM
11104static void
11105display_sparc_hwcaps (int mask)
11106{
11107 if (mask)
11108 {
11109 int first = 1;
11110 if (mask & ELF_SPARC_HWCAP_MUL32)
11111 fputs ("mul32", stdout), first = 0;
11112 if (mask & ELF_SPARC_HWCAP_DIV32)
11113 printf ("%sdiv32", first ? "" : "|"), first = 0;
11114 if (mask & ELF_SPARC_HWCAP_FSMULD)
11115 printf ("%sfsmuld", first ? "" : "|"), first = 0;
11116 if (mask & ELF_SPARC_HWCAP_V8PLUS)
11117 printf ("%sv8plus", first ? "" : "|"), first = 0;
11118 if (mask & ELF_SPARC_HWCAP_POPC)
11119 printf ("%spopc", first ? "" : "|"), first = 0;
11120 if (mask & ELF_SPARC_HWCAP_VIS)
11121 printf ("%svis", first ? "" : "|"), first = 0;
11122 if (mask & ELF_SPARC_HWCAP_VIS2)
11123 printf ("%svis2", first ? "" : "|"), first = 0;
11124 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
11125 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
11126 if (mask & ELF_SPARC_HWCAP_FMAF)
11127 printf ("%sfmaf", first ? "" : "|"), first = 0;
11128 if (mask & ELF_SPARC_HWCAP_VIS3)
11129 printf ("%svis3", first ? "" : "|"), first = 0;
11130 if (mask & ELF_SPARC_HWCAP_HPC)
11131 printf ("%shpc", first ? "" : "|"), first = 0;
11132 if (mask & ELF_SPARC_HWCAP_RANDOM)
11133 printf ("%srandom", first ? "" : "|"), first = 0;
11134 if (mask & ELF_SPARC_HWCAP_TRANS)
11135 printf ("%strans", first ? "" : "|"), first = 0;
11136 if (mask & ELF_SPARC_HWCAP_FJFMAU)
11137 printf ("%sfjfmau", first ? "" : "|"), first = 0;
11138 if (mask & ELF_SPARC_HWCAP_IMA)
11139 printf ("%sima", first ? "" : "|"), first = 0;
11140 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
11141 printf ("%scspare", first ? "" : "|"), first = 0;
11142 }
11143 else
11144 fputc('0', stdout);
11145 fputc('\n', stdout);
11146}
11147
11148static unsigned char *
11149display_sparc_gnu_attribute (unsigned char * p, int tag)
11150{
11151 int type;
11152 unsigned int len;
11153 int val;
11154
11155 if (tag == Tag_GNU_Sparc_HWCAPS)
11156 {
11157 val = read_uleb128 (p, &len);
11158 p += len;
11159 printf (" Tag_GNU_Sparc_HWCAPS: ");
11160
11161 display_sparc_hwcaps (val);
11162 return p;
11163 }
11164
11165 if (tag & 1)
11166 type = 1; /* String. */
11167 else
11168 type = 2; /* uleb128. */
11169 printf (" Tag_unknown_%d: ", tag);
11170
11171 if (type == 1)
11172 {
11173 printf ("\"%s\"\n", p);
11174 p += strlen ((char *) p) + 1;
11175 }
11176 else
11177 {
11178 val = read_uleb128 (p, &len);
11179 p += len;
11180 printf ("%d (0x%x)\n", val, val);
11181 }
11182
11183 return p;
11184}
11185
2cf19d5c 11186static unsigned char *
2cf0635d 11187display_mips_gnu_attribute (unsigned char * p, int tag)
2cf19d5c
JM
11188{
11189 int type;
11190 unsigned int len;
11191 int val;
11192
11193 if (tag == Tag_GNU_MIPS_ABI_FP)
11194 {
11195 val = read_uleb128 (p, &len);
11196 p += len;
11197 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 11198
2cf19d5c
JM
11199 switch (val)
11200 {
11201 case 0:
2b692964 11202 printf (_("Hard or soft float\n"));
2cf19d5c
JM
11203 break;
11204 case 1:
2b692964 11205 printf (_("Hard float (double precision)\n"));
2cf19d5c
JM
11206 break;
11207 case 2:
2b692964 11208 printf (_("Hard float (single precision)\n"));
2cf19d5c
JM
11209 break;
11210 case 3:
2b692964 11211 printf (_("Soft float\n"));
2cf19d5c 11212 break;
42554f6a 11213 case 4:
9eeefea8 11214 printf (_("Hard float (MIPS32r2 64-bit FPU)\n"));
42554f6a 11215 break;
2cf19d5c
JM
11216 default:
11217 printf ("??? (%d)\n", val);
11218 break;
11219 }
11220 return p;
11221 }
11222
11223 if (tag & 1)
11224 type = 1; /* String. */
11225 else
11226 type = 2; /* uleb128. */
11227 printf (" Tag_unknown_%d: ", tag);
11228
11229 if (type == 1)
11230 {
11231 printf ("\"%s\"\n", p);
60bca95a 11232 p += strlen ((char *) p) + 1;
2cf19d5c
JM
11233 }
11234 else
11235 {
11236 val = read_uleb128 (p, &len);
11237 p += len;
11238 printf ("%d (0x%x)\n", val, val);
11239 }
11240
11241 return p;
11242}
11243
59e6276b
JM
11244static unsigned char *
11245display_tic6x_attribute (unsigned char * p)
11246{
11247 int tag;
11248 unsigned int len;
11249 int val;
11250
11251 tag = read_uleb128 (p, &len);
11252 p += len;
11253
11254 switch (tag)
11255 {
75fa6dc1 11256 case Tag_ISA:
59e6276b
JM
11257 val = read_uleb128 (p, &len);
11258 p += len;
75fa6dc1 11259 printf (" Tag_ISA: ");
59e6276b
JM
11260
11261 switch (val)
11262 {
75fa6dc1 11263 case C6XABI_Tag_ISA_none:
59e6276b
JM
11264 printf (_("None\n"));
11265 break;
75fa6dc1 11266 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
11267 printf ("C62x\n");
11268 break;
75fa6dc1 11269 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
11270 printf ("C67x\n");
11271 break;
75fa6dc1 11272 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
11273 printf ("C67x+\n");
11274 break;
75fa6dc1 11275 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
11276 printf ("C64x\n");
11277 break;
75fa6dc1 11278 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
11279 printf ("C64x+\n");
11280 break;
75fa6dc1 11281 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
11282 printf ("C674x\n");
11283 break;
11284 default:
11285 printf ("??? (%d)\n", val);
11286 break;
11287 }
11288 return p;
11289
87779176
JM
11290 case Tag_ABI_wchar_t:
11291 val = read_uleb128 (p, &len);
11292 p += len;
11293 printf (" Tag_ABI_wchar_t: ");
11294 switch (val)
11295 {
11296 case 0:
11297 printf (_("Not used\n"));
11298 break;
11299 case 1:
11300 printf (_("2 bytes\n"));
11301 break;
11302 case 2:
11303 printf (_("4 bytes\n"));
11304 break;
11305 default:
11306 printf ("??? (%d)\n", val);
11307 break;
11308 }
11309 return p;
11310
11311 case Tag_ABI_stack_align_needed:
11312 val = read_uleb128 (p, &len);
11313 p += len;
11314 printf (" Tag_ABI_stack_align_needed: ");
11315 switch (val)
11316 {
11317 case 0:
11318 printf (_("8-byte\n"));
11319 break;
11320 case 1:
11321 printf (_("16-byte\n"));
11322 break;
11323 default:
11324 printf ("??? (%d)\n", val);
11325 break;
11326 }
11327 return p;
11328
11329 case Tag_ABI_stack_align_preserved:
11330 val = read_uleb128 (p, &len);
11331 p += len;
11332 printf (" Tag_ABI_stack_align_preserved: ");
11333 switch (val)
11334 {
11335 case 0:
11336 printf (_("8-byte\n"));
11337 break;
11338 case 1:
11339 printf (_("16-byte\n"));
11340 break;
11341 default:
11342 printf ("??? (%d)\n", val);
11343 break;
11344 }
11345 return p;
11346
b5593623
JM
11347 case Tag_ABI_DSBT:
11348 val = read_uleb128 (p, &len);
11349 p += len;
11350 printf (" Tag_ABI_DSBT: ");
11351 switch (val)
11352 {
11353 case 0:
11354 printf (_("DSBT addressing not used\n"));
11355 break;
11356 case 1:
11357 printf (_("DSBT addressing used\n"));
11358 break;
11359 default:
11360 printf ("??? (%d)\n", val);
11361 break;
11362 }
11363 return p;
11364
87779176
JM
11365 case Tag_ABI_PID:
11366 val = read_uleb128 (p, &len);
11367 p += len;
11368 printf (" Tag_ABI_PID: ");
11369 switch (val)
11370 {
11371 case 0:
11372 printf (_("Data addressing position-dependent\n"));
11373 break;
11374 case 1:
11375 printf (_("Data addressing position-independent, GOT near DP\n"));
11376 break;
11377 case 2:
11378 printf (_("Data addressing position-independent, GOT far from DP\n"));
11379 break;
11380 default:
11381 printf ("??? (%d)\n", val);
11382 break;
11383 }
11384 return p;
11385
11386 case Tag_ABI_PIC:
11387 val = read_uleb128 (p, &len);
11388 p += len;
11389 printf (" Tag_ABI_PIC: ");
11390 switch (val)
11391 {
11392 case 0:
11393 printf (_("Code addressing position-dependent\n"));
11394 break;
11395 case 1:
11396 printf (_("Code addressing position-independent\n"));
11397 break;
11398 default:
11399 printf ("??? (%d)\n", val);
11400 break;
11401 }
11402 return p;
11403
11404 case Tag_ABI_array_object_alignment:
11405 val = read_uleb128 (p, &len);
11406 p += len;
11407 printf (" Tag_ABI_array_object_alignment: ");
11408 switch (val)
11409 {
11410 case 0:
11411 printf (_("8-byte\n"));
11412 break;
11413 case 1:
11414 printf (_("4-byte\n"));
11415 break;
11416 case 2:
11417 printf (_("16-byte\n"));
11418 break;
11419 default:
11420 printf ("??? (%d)\n", val);
11421 break;
11422 }
11423 return p;
11424
11425 case Tag_ABI_array_object_align_expected:
11426 val = read_uleb128 (p, &len);
11427 p += len;
11428 printf (" Tag_ABI_array_object_align_expected: ");
11429 switch (val)
11430 {
11431 case 0:
11432 printf (_("8-byte\n"));
11433 break;
11434 case 1:
11435 printf (_("4-byte\n"));
11436 break;
11437 case 2:
11438 printf (_("16-byte\n"));
11439 break;
11440 default:
11441 printf ("??? (%d)\n", val);
11442 break;
11443 }
11444 return p;
11445
3cbd1c06 11446 case Tag_ABI_compatibility:
59e6276b
JM
11447 val = read_uleb128 (p, &len);
11448 p += len;
3cbd1c06 11449 printf (" Tag_ABI_compatibility: ");
59e6276b
JM
11450 printf (_("flag = %d, vendor = %s\n"), val, p);
11451 p += strlen ((char *) p) + 1;
11452 return p;
87779176
JM
11453
11454 case Tag_ABI_conformance:
11455 printf (" Tag_ABI_conformance: ");
11456 printf ("\"%s\"\n", p);
11457 p += strlen ((char *) p) + 1;
11458 return p;
59e6276b
JM
11459 }
11460
11461 printf (" Tag_unknown_%d: ", tag);
11462
87779176
JM
11463 if (tag & 1)
11464 {
11465 printf ("\"%s\"\n", p);
11466 p += strlen ((char *) p) + 1;
11467 }
11468 else
11469 {
11470 val = read_uleb128 (p, &len);
11471 p += len;
11472 printf ("%d (0x%x)\n", val, val);
11473 }
59e6276b
JM
11474
11475 return p;
11476}
11477
11c1ff18 11478static int
60bca95a
NC
11479process_attributes (FILE * file,
11480 const char * public_name,
104d59d1 11481 unsigned int proc_type,
60bca95a
NC
11482 unsigned char * (* display_pub_attribute) (unsigned char *),
11483 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int))
11c1ff18 11484{
2cf0635d
NC
11485 Elf_Internal_Shdr * sect;
11486 unsigned char * contents;
11487 unsigned char * p;
11488 unsigned char * end;
11c1ff18
PB
11489 bfd_vma section_len;
11490 bfd_vma len;
11491 unsigned i;
11492
11493 /* Find the section header so that we get the size. */
11494 for (i = 0, sect = section_headers;
11495 i < elf_header.e_shnum;
11496 i++, sect++)
11497 {
104d59d1 11498 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
11499 continue;
11500
3f5e193b
NC
11501 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
11502 sect->sh_size, _("attributes"));
60bca95a 11503 if (contents == NULL)
11c1ff18 11504 continue;
60bca95a 11505
11c1ff18
PB
11506 p = contents;
11507 if (*p == 'A')
11508 {
11509 len = sect->sh_size - 1;
11510 p++;
60bca95a 11511
11c1ff18
PB
11512 while (len > 0)
11513 {
11514 int namelen;
11515 bfd_boolean public_section;
104d59d1 11516 bfd_boolean gnu_section;
11c1ff18
PB
11517
11518 section_len = byte_get (p, 4);
11519 p += 4;
60bca95a 11520
11c1ff18
PB
11521 if (section_len > len)
11522 {
11523 printf (_("ERROR: Bad section length (%d > %d)\n"),
60bca95a 11524 (int) section_len, (int) len);
11c1ff18
PB
11525 section_len = len;
11526 }
60bca95a 11527
11c1ff18 11528 len -= section_len;
2b692964 11529 printf (_("Attribute Section: %s\n"), p);
60bca95a
NC
11530
11531 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
11532 public_section = TRUE;
11533 else
11534 public_section = FALSE;
60bca95a
NC
11535
11536 if (streq ((char *) p, "gnu"))
104d59d1
JM
11537 gnu_section = TRUE;
11538 else
11539 gnu_section = FALSE;
60bca95a
NC
11540
11541 namelen = strlen ((char *) p) + 1;
11c1ff18
PB
11542 p += namelen;
11543 section_len -= namelen + 4;
60bca95a 11544
11c1ff18
PB
11545 while (section_len > 0)
11546 {
11547 int tag = *(p++);
11548 int val;
11549 bfd_vma size;
60bca95a 11550
11c1ff18
PB
11551 size = byte_get (p, 4);
11552 if (size > section_len)
11553 {
11554 printf (_("ERROR: Bad subsection length (%d > %d)\n"),
60bca95a 11555 (int) size, (int) section_len);
11c1ff18
PB
11556 size = section_len;
11557 }
60bca95a 11558
11c1ff18
PB
11559 section_len -= size;
11560 end = p + size - 1;
11561 p += 4;
60bca95a 11562
11c1ff18
PB
11563 switch (tag)
11564 {
11565 case 1:
2b692964 11566 printf (_("File Attributes\n"));
11c1ff18
PB
11567 break;
11568 case 2:
2b692964 11569 printf (_("Section Attributes:"));
11c1ff18
PB
11570 goto do_numlist;
11571 case 3:
2b692964 11572 printf (_("Symbol Attributes:"));
11c1ff18
PB
11573 do_numlist:
11574 for (;;)
11575 {
91d6fa6a 11576 unsigned int j;
60bca95a 11577
91d6fa6a
NC
11578 val = read_uleb128 (p, &j);
11579 p += j;
11c1ff18
PB
11580 if (val == 0)
11581 break;
11582 printf (" %d", val);
11583 }
11584 printf ("\n");
11585 break;
11586 default:
2b692964 11587 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
11588 public_section = FALSE;
11589 break;
11590 }
60bca95a 11591
11c1ff18
PB
11592 if (public_section)
11593 {
11594 while (p < end)
104d59d1
JM
11595 p = display_pub_attribute (p);
11596 }
11597 else if (gnu_section)
11598 {
11599 while (p < end)
11600 p = display_gnu_attribute (p,
11601 display_proc_gnu_attribute);
11c1ff18
PB
11602 }
11603 else
11604 {
11605 /* ??? Do something sensible, like dump hex. */
2b692964 11606 printf (_(" Unknown section contexts\n"));
11c1ff18
PB
11607 p = end;
11608 }
11609 }
11610 }
11611 }
11612 else
60bca95a 11613 printf (_("Unknown format '%c'\n"), *p);
d70c5fc7 11614
60bca95a 11615 free (contents);
11c1ff18
PB
11616 }
11617 return 1;
11618}
11619
104d59d1 11620static int
2cf0635d 11621process_arm_specific (FILE * file)
104d59d1
JM
11622{
11623 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
11624 display_arm_attribute, NULL);
11625}
11626
34c8bcba 11627static int
2cf0635d 11628process_power_specific (FILE * file)
34c8bcba
JM
11629{
11630 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11631 display_power_gnu_attribute);
11632}
11633
9e8c70f9
DM
11634static int
11635process_sparc_specific (FILE * file)
11636{
11637 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11638 display_sparc_gnu_attribute);
11639}
11640
59e6276b
JM
11641static int
11642process_tic6x_specific (FILE * file)
11643{
11644 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
11645 display_tic6x_attribute, NULL);
11646}
11647
ccb4c951
RS
11648/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
11649 Print the Address, Access and Initial fields of an entry at VMA ADDR
11650 and return the VMA of the next entry. */
11651
11652static bfd_vma
2cf0635d 11653print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
ccb4c951
RS
11654{
11655 printf (" ");
11656 print_vma (addr, LONG_HEX);
11657 printf (" ");
11658 if (addr < pltgot + 0xfff0)
11659 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
11660 else
11661 printf ("%10s", "");
11662 printf (" ");
11663 if (data == NULL)
2b692964 11664 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
11665 else
11666 {
11667 bfd_vma entry;
11668
11669 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11670 print_vma (entry, LONG_HEX);
11671 }
11672 return addr + (is_32bit_elf ? 4 : 8);
11673}
11674
861fb55a
DJ
11675/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
11676 PLTGOT. Print the Address and Initial fields of an entry at VMA
11677 ADDR and return the VMA of the next entry. */
11678
11679static bfd_vma
2cf0635d 11680print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
11681{
11682 printf (" ");
11683 print_vma (addr, LONG_HEX);
11684 printf (" ");
11685 if (data == NULL)
2b692964 11686 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
11687 else
11688 {
11689 bfd_vma entry;
11690
11691 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
11692 print_vma (entry, LONG_HEX);
11693 }
11694 return addr + (is_32bit_elf ? 4 : 8);
11695}
11696
19e6b90e 11697static int
2cf0635d 11698process_mips_specific (FILE * file)
5b18a4bc 11699{
2cf0635d 11700 Elf_Internal_Dyn * entry;
19e6b90e
L
11701 size_t liblist_offset = 0;
11702 size_t liblistno = 0;
11703 size_t conflictsno = 0;
11704 size_t options_offset = 0;
11705 size_t conflicts_offset = 0;
861fb55a
DJ
11706 size_t pltrelsz = 0;
11707 size_t pltrel = 0;
ccb4c951 11708 bfd_vma pltgot = 0;
861fb55a
DJ
11709 bfd_vma mips_pltgot = 0;
11710 bfd_vma jmprel = 0;
ccb4c951
RS
11711 bfd_vma local_gotno = 0;
11712 bfd_vma gotsym = 0;
11713 bfd_vma symtabno = 0;
103f02d3 11714
2cf19d5c
JM
11715 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
11716 display_mips_gnu_attribute);
11717
19e6b90e
L
11718 /* We have a lot of special sections. Thanks SGI! */
11719 if (dynamic_section == NULL)
11720 /* No information available. */
11721 return 0;
252b5132 11722
b2d38a17 11723 for (entry = dynamic_section; entry->d_tag != DT_NULL; ++entry)
252b5132
RH
11724 switch (entry->d_tag)
11725 {
11726 case DT_MIPS_LIBLIST:
d93f0186
NC
11727 liblist_offset
11728 = offset_from_vma (file, entry->d_un.d_val,
11729 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
11730 break;
11731 case DT_MIPS_LIBLISTNO:
11732 liblistno = entry->d_un.d_val;
11733 break;
11734 case DT_MIPS_OPTIONS:
d93f0186 11735 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
11736 break;
11737 case DT_MIPS_CONFLICT:
d93f0186
NC
11738 conflicts_offset
11739 = offset_from_vma (file, entry->d_un.d_val,
11740 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
11741 break;
11742 case DT_MIPS_CONFLICTNO:
11743 conflictsno = entry->d_un.d_val;
11744 break;
ccb4c951 11745 case DT_PLTGOT:
861fb55a
DJ
11746 pltgot = entry->d_un.d_ptr;
11747 break;
ccb4c951
RS
11748 case DT_MIPS_LOCAL_GOTNO:
11749 local_gotno = entry->d_un.d_val;
11750 break;
11751 case DT_MIPS_GOTSYM:
11752 gotsym = entry->d_un.d_val;
11753 break;
11754 case DT_MIPS_SYMTABNO:
11755 symtabno = entry->d_un.d_val;
11756 break;
861fb55a
DJ
11757 case DT_MIPS_PLTGOT:
11758 mips_pltgot = entry->d_un.d_ptr;
11759 break;
11760 case DT_PLTREL:
11761 pltrel = entry->d_un.d_val;
11762 break;
11763 case DT_PLTRELSZ:
11764 pltrelsz = entry->d_un.d_val;
11765 break;
11766 case DT_JMPREL:
11767 jmprel = entry->d_un.d_ptr;
11768 break;
252b5132
RH
11769 default:
11770 break;
11771 }
11772
11773 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
11774 {
2cf0635d 11775 Elf32_External_Lib * elib;
252b5132
RH
11776 size_t cnt;
11777
3f5e193b
NC
11778 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
11779 liblistno,
11780 sizeof (Elf32_External_Lib),
11781 _("liblist"));
a6e9f9df 11782 if (elib)
252b5132 11783 {
2b692964 11784 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 11785 (unsigned long) liblistno);
2b692964 11786 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
11787 stdout);
11788
11789 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 11790 {
a6e9f9df 11791 Elf32_Lib liblist;
91d6fa6a 11792 time_t atime;
a6e9f9df 11793 char timebuf[20];
2cf0635d 11794 struct tm * tmp;
a6e9f9df
AM
11795
11796 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 11797 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
11798 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
11799 liblist.l_version = BYTE_GET (elib[cnt].l_version);
11800 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
11801
91d6fa6a 11802 tmp = gmtime (&atime);
e9e44622
JJ
11803 snprintf (timebuf, sizeof (timebuf),
11804 "%04u-%02u-%02uT%02u:%02u:%02u",
11805 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11806 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 11807
31104126 11808 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
11809 if (VALID_DYNAMIC_NAME (liblist.l_name))
11810 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
11811 else
2b692964 11812 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
11813 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
11814 liblist.l_version);
a6e9f9df
AM
11815
11816 if (liblist.l_flags == 0)
2b692964 11817 puts (_(" NONE"));
a6e9f9df
AM
11818 else
11819 {
11820 static const struct
252b5132 11821 {
2cf0635d 11822 const char * name;
a6e9f9df 11823 int bit;
252b5132 11824 }
a6e9f9df
AM
11825 l_flags_vals[] =
11826 {
11827 { " EXACT_MATCH", LL_EXACT_MATCH },
11828 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
11829 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
11830 { " EXPORTS", LL_EXPORTS },
11831 { " DELAY_LOAD", LL_DELAY_LOAD },
11832 { " DELTA", LL_DELTA }
11833 };
11834 int flags = liblist.l_flags;
11835 size_t fcnt;
11836
60bca95a 11837 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
11838 if ((flags & l_flags_vals[fcnt].bit) != 0)
11839 {
11840 fputs (l_flags_vals[fcnt].name, stdout);
11841 flags ^= l_flags_vals[fcnt].bit;
11842 }
11843 if (flags != 0)
11844 printf (" %#x", (unsigned int) flags);
252b5132 11845
a6e9f9df
AM
11846 puts ("");
11847 }
252b5132 11848 }
252b5132 11849
a6e9f9df
AM
11850 free (elib);
11851 }
252b5132
RH
11852 }
11853
11854 if (options_offset != 0)
11855 {
2cf0635d
NC
11856 Elf_External_Options * eopt;
11857 Elf_Internal_Shdr * sect = section_headers;
11858 Elf_Internal_Options * iopt;
11859 Elf_Internal_Options * option;
252b5132
RH
11860 size_t offset;
11861 int cnt;
11862
11863 /* Find the section header so that we get the size. */
11864 while (sect->sh_type != SHT_MIPS_OPTIONS)
b34976b6 11865 ++sect;
252b5132 11866
3f5e193b
NC
11867 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
11868 sect->sh_size, _("options"));
a6e9f9df 11869 if (eopt)
252b5132 11870 {
3f5e193b
NC
11871 iopt = (Elf_Internal_Options *)
11872 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
11873 if (iopt == NULL)
11874 {
591a748a 11875 error (_("Out of memory\n"));
a6e9f9df
AM
11876 return 0;
11877 }
76da6bbe 11878
a6e9f9df
AM
11879 offset = cnt = 0;
11880 option = iopt;
252b5132 11881
a6e9f9df
AM
11882 while (offset < sect->sh_size)
11883 {
2cf0635d 11884 Elf_External_Options * eoption;
252b5132 11885
a6e9f9df 11886 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 11887
a6e9f9df
AM
11888 option->kind = BYTE_GET (eoption->kind);
11889 option->size = BYTE_GET (eoption->size);
11890 option->section = BYTE_GET (eoption->section);
11891 option->info = BYTE_GET (eoption->info);
76da6bbe 11892
a6e9f9df 11893 offset += option->size;
252b5132 11894
a6e9f9df
AM
11895 ++option;
11896 ++cnt;
11897 }
252b5132 11898
a6e9f9df
AM
11899 printf (_("\nSection '%s' contains %d entries:\n"),
11900 SECTION_NAME (sect), cnt);
76da6bbe 11901
a6e9f9df 11902 option = iopt;
252b5132 11903
a6e9f9df 11904 while (cnt-- > 0)
252b5132 11905 {
a6e9f9df
AM
11906 size_t len;
11907
11908 switch (option->kind)
252b5132 11909 {
a6e9f9df
AM
11910 case ODK_NULL:
11911 /* This shouldn't happen. */
11912 printf (" NULL %d %lx", option->section, option->info);
11913 break;
11914 case ODK_REGINFO:
11915 printf (" REGINFO ");
11916 if (elf_header.e_machine == EM_MIPS)
11917 {
11918 /* 32bit form. */
2cf0635d 11919 Elf32_External_RegInfo * ereg;
b34976b6 11920 Elf32_RegInfo reginfo;
a6e9f9df
AM
11921
11922 ereg = (Elf32_External_RegInfo *) (option + 1);
11923 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11924 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11925 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11926 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11927 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
11928 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
11929
11930 printf ("GPR %08lx GP 0x%lx\n",
11931 reginfo.ri_gprmask,
11932 (unsigned long) reginfo.ri_gp_value);
11933 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11934 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11935 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11936 }
11937 else
11938 {
11939 /* 64 bit form. */
2cf0635d 11940 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
11941 Elf64_Internal_RegInfo reginfo;
11942
11943 ereg = (Elf64_External_RegInfo *) (option + 1);
11944 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
11945 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
11946 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
11947 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
11948 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 11949 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
11950
11951 printf ("GPR %08lx GP 0x",
11952 reginfo.ri_gprmask);
11953 printf_vma (reginfo.ri_gp_value);
11954 printf ("\n");
11955
11956 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
11957 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
11958 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
11959 }
11960 ++option;
11961 continue;
11962 case ODK_EXCEPTIONS:
11963 fputs (" EXCEPTIONS fpe_min(", stdout);
11964 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
11965 fputs (") fpe_max(", stdout);
11966 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
11967 fputs (")", stdout);
11968
11969 if (option->info & OEX_PAGE0)
11970 fputs (" PAGE0", stdout);
11971 if (option->info & OEX_SMM)
11972 fputs (" SMM", stdout);
11973 if (option->info & OEX_FPDBUG)
11974 fputs (" FPDBUG", stdout);
11975 if (option->info & OEX_DISMISS)
11976 fputs (" DISMISS", stdout);
11977 break;
11978 case ODK_PAD:
11979 fputs (" PAD ", stdout);
11980 if (option->info & OPAD_PREFIX)
11981 fputs (" PREFIX", stdout);
11982 if (option->info & OPAD_POSTFIX)
11983 fputs (" POSTFIX", stdout);
11984 if (option->info & OPAD_SYMBOL)
11985 fputs (" SYMBOL", stdout);
11986 break;
11987 case ODK_HWPATCH:
11988 fputs (" HWPATCH ", stdout);
11989 if (option->info & OHW_R4KEOP)
11990 fputs (" R4KEOP", stdout);
11991 if (option->info & OHW_R8KPFETCH)
11992 fputs (" R8KPFETCH", stdout);
11993 if (option->info & OHW_R5KEOP)
11994 fputs (" R5KEOP", stdout);
11995 if (option->info & OHW_R5KCVTL)
11996 fputs (" R5KCVTL", stdout);
11997 break;
11998 case ODK_FILL:
11999 fputs (" FILL ", stdout);
12000 /* XXX Print content of info word? */
12001 break;
12002 case ODK_TAGS:
12003 fputs (" TAGS ", stdout);
12004 /* XXX Print content of info word? */
12005 break;
12006 case ODK_HWAND:
12007 fputs (" HWAND ", stdout);
12008 if (option->info & OHWA0_R4KEOP_CHECKED)
12009 fputs (" R4KEOP_CHECKED", stdout);
12010 if (option->info & OHWA0_R4KEOP_CLEAN)
12011 fputs (" R4KEOP_CLEAN", stdout);
12012 break;
12013 case ODK_HWOR:
12014 fputs (" HWOR ", stdout);
12015 if (option->info & OHWA0_R4KEOP_CHECKED)
12016 fputs (" R4KEOP_CHECKED", stdout);
12017 if (option->info & OHWA0_R4KEOP_CLEAN)
12018 fputs (" R4KEOP_CLEAN", stdout);
12019 break;
12020 case ODK_GP_GROUP:
12021 printf (" GP_GROUP %#06lx self-contained %#06lx",
12022 option->info & OGP_GROUP,
12023 (option->info & OGP_SELF) >> 16);
12024 break;
12025 case ODK_IDENT:
12026 printf (" IDENT %#06lx self-contained %#06lx",
12027 option->info & OGP_GROUP,
12028 (option->info & OGP_SELF) >> 16);
12029 break;
12030 default:
12031 /* This shouldn't happen. */
12032 printf (" %3d ??? %d %lx",
12033 option->kind, option->section, option->info);
12034 break;
252b5132 12035 }
a6e9f9df 12036
2cf0635d 12037 len = sizeof (* eopt);
a6e9f9df
AM
12038 while (len < option->size)
12039 if (((char *) option)[len] >= ' '
12040 && ((char *) option)[len] < 0x7f)
12041 printf ("%c", ((char *) option)[len++]);
12042 else
12043 printf ("\\%03o", ((char *) option)[len++]);
12044
12045 fputs ("\n", stdout);
252b5132 12046 ++option;
252b5132
RH
12047 }
12048
a6e9f9df 12049 free (eopt);
252b5132 12050 }
252b5132
RH
12051 }
12052
12053 if (conflicts_offset != 0 && conflictsno != 0)
12054 {
2cf0635d 12055 Elf32_Conflict * iconf;
252b5132
RH
12056 size_t cnt;
12057
12058 if (dynamic_symbols == NULL)
12059 {
591a748a 12060 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
12061 return 0;
12062 }
12063
3f5e193b 12064 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
12065 if (iconf == NULL)
12066 {
591a748a 12067 error (_("Out of memory\n"));
252b5132
RH
12068 return 0;
12069 }
12070
9ea033b2 12071 if (is_32bit_elf)
252b5132 12072 {
2cf0635d 12073 Elf32_External_Conflict * econf32;
a6e9f9df 12074
3f5e193b
NC
12075 econf32 = (Elf32_External_Conflict *)
12076 get_data (NULL, file, conflicts_offset, conflictsno,
12077 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
12078 if (!econf32)
12079 return 0;
252b5132
RH
12080
12081 for (cnt = 0; cnt < conflictsno; ++cnt)
12082 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
12083
12084 free (econf32);
252b5132
RH
12085 }
12086 else
12087 {
2cf0635d 12088 Elf64_External_Conflict * econf64;
a6e9f9df 12089
3f5e193b
NC
12090 econf64 = (Elf64_External_Conflict *)
12091 get_data (NULL, file, conflicts_offset, conflictsno,
12092 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
12093 if (!econf64)
12094 return 0;
252b5132
RH
12095
12096 for (cnt = 0; cnt < conflictsno; ++cnt)
12097 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
12098
12099 free (econf64);
252b5132
RH
12100 }
12101
c7e7ca54
NC
12102 printf (_("\nSection '.conflict' contains %lu entries:\n"),
12103 (unsigned long) conflictsno);
252b5132
RH
12104 puts (_(" Num: Index Value Name"));
12105
12106 for (cnt = 0; cnt < conflictsno; ++cnt)
12107 {
2cf0635d 12108 Elf_Internal_Sym * psym = & dynamic_symbols[iconf[cnt]];
252b5132 12109
b34976b6 12110 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
f7a99963 12111 print_vma (psym->st_value, FULL_HEX);
31104126 12112 putchar (' ');
d79b3d50
NC
12113 if (VALID_DYNAMIC_NAME (psym->st_name))
12114 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
12115 else
2b692964 12116 printf (_("<corrupt: %14ld>"), psym->st_name);
31104126 12117 putchar ('\n');
252b5132
RH
12118 }
12119
252b5132
RH
12120 free (iconf);
12121 }
12122
ccb4c951
RS
12123 if (pltgot != 0 && local_gotno != 0)
12124 {
91d6fa6a 12125 bfd_vma ent, local_end, global_end;
bbeee7ea 12126 size_t i, offset;
2cf0635d 12127 unsigned char * data;
bbeee7ea 12128 int addr_size;
ccb4c951 12129
91d6fa6a 12130 ent = pltgot;
ccb4c951
RS
12131 addr_size = (is_32bit_elf ? 4 : 8);
12132 local_end = pltgot + local_gotno * addr_size;
12133 global_end = local_end + (symtabno - gotsym) * addr_size;
12134
12135 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b
NC
12136 data = (unsigned char *) get_data (NULL, file, offset,
12137 global_end - pltgot, 1, _("GOT"));
59245841
NC
12138 if (data == NULL)
12139 return 0;
12140
ccb4c951
RS
12141 printf (_("\nPrimary GOT:\n"));
12142 printf (_(" Canonical gp value: "));
12143 print_vma (pltgot + 0x7ff0, LONG_HEX);
12144 printf ("\n\n");
12145
12146 printf (_(" Reserved entries:\n"));
12147 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
12148 addr_size * 2, _("Address"), _("Access"),
12149 addr_size * 2, _("Initial"));
91d6fa6a 12150 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12151 printf (_(" Lazy resolver\n"));
ccb4c951 12152 if (data
91d6fa6a 12153 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
12154 >> (addr_size * 8 - 1)) != 0)
12155 {
91d6fa6a 12156 ent = print_mips_got_entry (data, pltgot, ent);
2b692964 12157 printf (_(" Module pointer (GNU extension)\n"));
ccb4c951
RS
12158 }
12159 printf ("\n");
12160
91d6fa6a 12161 if (ent < local_end)
ccb4c951
RS
12162 {
12163 printf (_(" Local entries:\n"));
cc5914eb 12164 printf (" %*s %10s %*s\n",
2b692964
NC
12165 addr_size * 2, _("Address"), _("Access"),
12166 addr_size * 2, _("Initial"));
91d6fa6a 12167 while (ent < local_end)
ccb4c951 12168 {
91d6fa6a 12169 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12170 printf ("\n");
12171 }
12172 printf ("\n");
12173 }
12174
12175 if (gotsym < symtabno)
12176 {
12177 int sym_width;
12178
12179 printf (_(" Global entries:\n"));
cc5914eb 12180 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
2b692964
NC
12181 addr_size * 2, _("Address"), _("Access"),
12182 addr_size * 2, _("Initial"),
12183 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
ccb4c951
RS
12184 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
12185 for (i = gotsym; i < symtabno; i++)
12186 {
2cf0635d 12187 Elf_Internal_Sym * psym;
ccb4c951
RS
12188
12189 psym = dynamic_symbols + i;
91d6fa6a 12190 ent = print_mips_got_entry (data, pltgot, ent);
ccb4c951
RS
12191 printf (" ");
12192 print_vma (psym->st_value, LONG_HEX);
12193 printf (" %-7s %3s ",
12194 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12195 get_symbol_index_type (psym->st_shndx));
12196 if (VALID_DYNAMIC_NAME (psym->st_name))
12197 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12198 else
2b692964 12199 printf (_("<corrupt: %14ld>"), psym->st_name);
ccb4c951
RS
12200 printf ("\n");
12201 }
12202 printf ("\n");
12203 }
12204
12205 if (data)
12206 free (data);
12207 }
12208
861fb55a
DJ
12209 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
12210 {
91d6fa6a 12211 bfd_vma ent, end;
861fb55a
DJ
12212 size_t offset, rel_offset;
12213 unsigned long count, i;
2cf0635d 12214 unsigned char * data;
861fb55a 12215 int addr_size, sym_width;
2cf0635d 12216 Elf_Internal_Rela * rels;
861fb55a
DJ
12217
12218 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
12219 if (pltrel == DT_RELA)
12220 {
12221 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
12222 return 0;
12223 }
12224 else
12225 {
12226 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
12227 return 0;
12228 }
12229
91d6fa6a 12230 ent = mips_pltgot;
861fb55a
DJ
12231 addr_size = (is_32bit_elf ? 4 : 8);
12232 end = mips_pltgot + (2 + count) * addr_size;
12233
12234 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b
NC
12235 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
12236 1, _("PLT GOT"));
59245841
NC
12237 if (data == NULL)
12238 return 0;
12239
861fb55a
DJ
12240 printf (_("\nPLT GOT:\n\n"));
12241 printf (_(" Reserved entries:\n"));
12242 printf (_(" %*s %*s Purpose\n"),
2b692964 12243 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 12244 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12245 printf (_(" PLT lazy resolver\n"));
91d6fa6a 12246 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 12247 printf (_(" Module pointer\n"));
861fb55a
DJ
12248 printf ("\n");
12249
12250 printf (_(" Entries:\n"));
cc5914eb 12251 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
12252 addr_size * 2, _("Address"),
12253 addr_size * 2, _("Initial"),
12254 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
12255 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
12256 for (i = 0; i < count; i++)
12257 {
2cf0635d 12258 Elf_Internal_Sym * psym;
861fb55a
DJ
12259
12260 psym = dynamic_symbols + get_reloc_symindex (rels[i].r_info);
91d6fa6a 12261 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a
DJ
12262 printf (" ");
12263 print_vma (psym->st_value, LONG_HEX);
12264 printf (" %-7s %3s ",
12265 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
12266 get_symbol_index_type (psym->st_shndx));
12267 if (VALID_DYNAMIC_NAME (psym->st_name))
12268 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
12269 else
2b692964 12270 printf (_("<corrupt: %14ld>"), psym->st_name);
861fb55a
DJ
12271 printf ("\n");
12272 }
12273 printf ("\n");
12274
12275 if (data)
12276 free (data);
12277 free (rels);
12278 }
12279
252b5132
RH
12280 return 1;
12281}
12282
047b2264 12283static int
2cf0635d 12284process_gnu_liblist (FILE * file)
047b2264 12285{
2cf0635d
NC
12286 Elf_Internal_Shdr * section;
12287 Elf_Internal_Shdr * string_sec;
12288 Elf32_External_Lib * elib;
12289 char * strtab;
c256ffe7 12290 size_t strtab_size;
047b2264
JJ
12291 size_t cnt;
12292 unsigned i;
12293
12294 if (! do_arch)
12295 return 0;
12296
12297 for (i = 0, section = section_headers;
12298 i < elf_header.e_shnum;
b34976b6 12299 i++, section++)
047b2264
JJ
12300 {
12301 switch (section->sh_type)
12302 {
12303 case SHT_GNU_LIBLIST:
4fbb74a6 12304 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
12305 break;
12306
3f5e193b
NC
12307 elib = (Elf32_External_Lib *)
12308 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
12309 _("liblist"));
047b2264
JJ
12310
12311 if (elib == NULL)
12312 break;
4fbb74a6 12313 string_sec = section_headers + section->sh_link;
047b2264 12314
3f5e193b
NC
12315 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
12316 string_sec->sh_size,
12317 _("liblist string table"));
047b2264
JJ
12318 if (strtab == NULL
12319 || section->sh_entsize != sizeof (Elf32_External_Lib))
12320 {
12321 free (elib);
2842702f 12322 free (strtab);
047b2264
JJ
12323 break;
12324 }
59245841 12325 strtab_size = string_sec->sh_size;
047b2264
JJ
12326
12327 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
12328 SECTION_NAME (section),
0af1713e 12329 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 12330
2b692964 12331 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
12332
12333 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
12334 ++cnt)
12335 {
12336 Elf32_Lib liblist;
91d6fa6a 12337 time_t atime;
047b2264 12338 char timebuf[20];
2cf0635d 12339 struct tm * tmp;
047b2264
JJ
12340
12341 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 12342 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
12343 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
12344 liblist.l_version = BYTE_GET (elib[cnt].l_version);
12345 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
12346
91d6fa6a 12347 tmp = gmtime (&atime);
e9e44622
JJ
12348 snprintf (timebuf, sizeof (timebuf),
12349 "%04u-%02u-%02uT%02u:%02u:%02u",
12350 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12351 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12352
12353 printf ("%3lu: ", (unsigned long) cnt);
12354 if (do_wide)
c256ffe7 12355 printf ("%-20s", liblist.l_name < strtab_size
2b692964 12356 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 12357 else
c256ffe7 12358 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 12359 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
12360 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
12361 liblist.l_version, liblist.l_flags);
12362 }
12363
12364 free (elib);
2842702f 12365 free (strtab);
047b2264
JJ
12366 }
12367 }
12368
12369 return 1;
12370}
12371
9437c45b 12372static const char *
d3ba0551 12373get_note_type (unsigned e_type)
779fe533
NC
12374{
12375 static char buff[64];
103f02d3 12376
1ec5cd37
NC
12377 if (elf_header.e_type == ET_CORE)
12378 switch (e_type)
12379 {
57346661 12380 case NT_AUXV:
1ec5cd37 12381 return _("NT_AUXV (auxiliary vector)");
57346661 12382 case NT_PRSTATUS:
1ec5cd37 12383 return _("NT_PRSTATUS (prstatus structure)");
57346661 12384 case NT_FPREGSET:
1ec5cd37 12385 return _("NT_FPREGSET (floating point registers)");
57346661 12386 case NT_PRPSINFO:
1ec5cd37 12387 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 12388 case NT_TASKSTRUCT:
1ec5cd37 12389 return _("NT_TASKSTRUCT (task structure)");
57346661 12390 case NT_PRXFPREG:
1ec5cd37 12391 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
12392 case NT_PPC_VMX:
12393 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
12394 case NT_PPC_VSX:
12395 return _("NT_PPC_VSX (ppc VSX registers)");
4339cae0
L
12396 case NT_X86_XSTATE:
12397 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
12398 case NT_S390_HIGH_GPRS:
12399 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
12400 case NT_S390_TIMER:
12401 return _("NT_S390_TIMER (s390 timer register)");
12402 case NT_S390_TODCMP:
12403 return _("NT_S390_TODCMP (s390 TOD comparator register)");
12404 case NT_S390_TODPREG:
12405 return _("NT_S390_TODPREG (s390 TOD programmable register)");
12406 case NT_S390_CTRS:
12407 return _("NT_S390_CTRS (s390 control registers)");
12408 case NT_S390_PREFIX:
12409 return _("NT_S390_PREFIX (s390 prefix register)");
faa9a424
UW
12410 case NT_ARM_VFP:
12411 return _("NT_ARM_VFP (arm VFP registers)");
57346661 12412 case NT_PSTATUS:
1ec5cd37 12413 return _("NT_PSTATUS (pstatus structure)");
57346661 12414 case NT_FPREGS:
1ec5cd37 12415 return _("NT_FPREGS (floating point registers)");
57346661 12416 case NT_PSINFO:
1ec5cd37 12417 return _("NT_PSINFO (psinfo structure)");
57346661 12418 case NT_LWPSTATUS:
1ec5cd37 12419 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 12420 case NT_LWPSINFO:
1ec5cd37 12421 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 12422 case NT_WIN32PSTATUS:
1ec5cd37
NC
12423 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
12424 default:
12425 break;
12426 }
12427 else
12428 switch (e_type)
12429 {
12430 case NT_VERSION:
12431 return _("NT_VERSION (version)");
12432 case NT_ARCH:
12433 return _("NT_ARCH (architecture)");
12434 default:
12435 break;
12436 }
12437
e9e44622 12438 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 12439 return buff;
779fe533
NC
12440}
12441
1118d252
RM
12442static const char *
12443get_gnu_elf_note_type (unsigned e_type)
12444{
12445 static char buff[64];
12446
12447 switch (e_type)
12448 {
12449 case NT_GNU_ABI_TAG:
12450 return _("NT_GNU_ABI_TAG (ABI version tag)");
12451 case NT_GNU_HWCAP:
12452 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
12453 case NT_GNU_BUILD_ID:
12454 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
12455 case NT_GNU_GOLD_VERSION:
12456 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
12457 default:
12458 break;
12459 }
12460
12461 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12462 return buff;
12463}
12464
664f90a3
TT
12465static int
12466print_gnu_note (Elf_Internal_Note *pnote)
12467{
12468 switch (pnote->type)
12469 {
12470 case NT_GNU_BUILD_ID:
12471 {
12472 unsigned long i;
12473
12474 printf (_(" Build ID: "));
12475 for (i = 0; i < pnote->descsz; ++i)
12476 printf ("%02x", pnote->descdata[i] & 0xff);
12477 printf (_("\n"));
12478 }
12479 break;
12480
12481 case NT_GNU_ABI_TAG:
12482 {
12483 unsigned long os, major, minor, subminor;
12484 const char *osname;
12485
12486 os = byte_get ((unsigned char *) pnote->descdata, 4);
12487 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
12488 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
12489 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
12490
12491 switch (os)
12492 {
12493 case GNU_ABI_TAG_LINUX:
12494 osname = "Linux";
12495 break;
12496 case GNU_ABI_TAG_HURD:
12497 osname = "Hurd";
12498 break;
12499 case GNU_ABI_TAG_SOLARIS:
12500 osname = "Solaris";
12501 break;
12502 case GNU_ABI_TAG_FREEBSD:
12503 osname = "FreeBSD";
12504 break;
12505 case GNU_ABI_TAG_NETBSD:
12506 osname = "NetBSD";
12507 break;
12508 default:
12509 osname = "Unknown";
12510 break;
12511 }
12512
12513 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
12514 major, minor, subminor);
12515 }
12516 break;
12517 }
12518
12519 return 1;
12520}
12521
9437c45b 12522static const char *
d3ba0551 12523get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
12524{
12525 static char buff[64];
12526
b4db1224 12527 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
12528 {
12529 /* NetBSD core "procinfo" structure. */
12530 return _("NetBSD procinfo structure");
12531 }
12532
12533 /* As of Jan 2002 there are no other machine-independent notes
12534 defined for NetBSD core files. If the note type is less
12535 than the start of the machine-dependent note types, we don't
12536 understand it. */
12537
b4db1224 12538 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 12539 {
e9e44622 12540 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
12541 return buff;
12542 }
12543
12544 switch (elf_header.e_machine)
12545 {
12546 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
12547 and PT_GETFPREGS == mach+2. */
12548
12549 case EM_OLD_ALPHA:
12550 case EM_ALPHA:
12551 case EM_SPARC:
12552 case EM_SPARC32PLUS:
12553 case EM_SPARCV9:
12554 switch (e_type)
12555 {
2b692964 12556 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 12557 return _("PT_GETREGS (reg structure)");
2b692964 12558 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 12559 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12560 default:
12561 break;
12562 }
12563 break;
12564
12565 /* On all other arch's, PT_GETREGS == mach+1 and
12566 PT_GETFPREGS == mach+3. */
12567 default:
12568 switch (e_type)
12569 {
2b692964 12570 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 12571 return _("PT_GETREGS (reg structure)");
2b692964 12572 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 12573 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
12574 default:
12575 break;
12576 }
12577 }
12578
e9e44622
JJ
12579 snprintf (buff, sizeof (buff), _("PT_FIRSTMACH+%d"),
12580 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
12581 return buff;
12582}
12583
70616151
TT
12584static const char *
12585get_stapsdt_note_type (unsigned e_type)
12586{
12587 static char buff[64];
12588
12589 switch (e_type)
12590 {
12591 case NT_STAPSDT:
12592 return _("NT_STAPSDT (SystemTap probe descriptors)");
12593
12594 default:
12595 break;
12596 }
12597
12598 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12599 return buff;
12600}
12601
c6a9fc58
TT
12602static int
12603print_stapsdt_note (Elf_Internal_Note *pnote)
12604{
12605 int addr_size = is_32bit_elf ? 4 : 8;
12606 char *data = pnote->descdata;
12607 char *data_end = pnote->descdata + pnote->descsz;
12608 bfd_vma pc, base_addr, semaphore;
12609 char *provider, *probe, *arg_fmt;
12610
12611 pc = byte_get ((unsigned char *) data, addr_size);
12612 data += addr_size;
12613 base_addr = byte_get ((unsigned char *) data, addr_size);
12614 data += addr_size;
12615 semaphore = byte_get ((unsigned char *) data, addr_size);
12616 data += addr_size;
12617
12618 provider = data;
12619 data += strlen (data) + 1;
12620 probe = data;
12621 data += strlen (data) + 1;
12622 arg_fmt = data;
12623 data += strlen (data) + 1;
12624
12625 printf (_(" Provider: %s\n"), provider);
12626 printf (_(" Name: %s\n"), probe);
12627 printf (_(" Location: "));
12628 print_vma (pc, FULL_HEX);
12629 printf (_(", Base: "));
12630 print_vma (base_addr, FULL_HEX);
12631 printf (_(", Semaphore: "));
12632 print_vma (semaphore, FULL_HEX);
12633 printf (_("\n"));
12634 printf (_(" Arguments: %s\n"), arg_fmt);
12635
12636 return data == data_end;
12637}
12638
00e98fc7
TG
12639static const char *
12640get_ia64_vms_note_type (unsigned e_type)
12641{
12642 static char buff[64];
12643
12644 switch (e_type)
12645 {
12646 case NT_VMS_MHD:
12647 return _("NT_VMS_MHD (module header)");
12648 case NT_VMS_LNM:
12649 return _("NT_VMS_LNM (language name)");
12650 case NT_VMS_SRC:
12651 return _("NT_VMS_SRC (source files)");
12652 case NT_VMS_TITLE:
12653 return _("NT_VMS_TITLE");
12654 case NT_VMS_EIDC:
12655 return _("NT_VMS_EIDC (consistency check)");
12656 case NT_VMS_FPMODE:
12657 return _("NT_VMS_FPMODE (FP mode)");
12658 case NT_VMS_LINKTIME:
12659 return _("NT_VMS_LINKTIME");
12660 case NT_VMS_IMGNAM:
12661 return _("NT_VMS_IMGNAM (image name)");
12662 case NT_VMS_IMGID:
12663 return _("NT_VMS_IMGID (image id)");
12664 case NT_VMS_LINKID:
12665 return _("NT_VMS_LINKID (link id)");
12666 case NT_VMS_IMGBID:
12667 return _("NT_VMS_IMGBID (build id)");
12668 case NT_VMS_GSTNAM:
12669 return _("NT_VMS_GSTNAM (sym table name)");
12670 case NT_VMS_ORIG_DYN:
12671 return _("NT_VMS_ORIG_DYN");
12672 case NT_VMS_PATCHTIME:
12673 return _("NT_VMS_PATCHTIME");
12674 default:
12675 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
12676 return buff;
12677 }
12678}
12679
12680static int
12681print_ia64_vms_note (Elf_Internal_Note * pnote)
12682{
12683 switch (pnote->type)
12684 {
12685 case NT_VMS_MHD:
12686 if (pnote->descsz > 36)
12687 {
12688 size_t l = strlen (pnote->descdata + 34);
12689 printf (_(" Creation date : %.17s\n"), pnote->descdata);
12690 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
12691 printf (_(" Module name : %s\n"), pnote->descdata + 34);
12692 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
12693 }
12694 else
12695 printf (_(" Invalid size\n"));
12696 break;
12697 case NT_VMS_LNM:
12698 printf (_(" Language: %s\n"), pnote->descdata);
12699 break;
12700#ifdef BFD64
12701 case NT_VMS_FPMODE:
4a5cb34f
TG
12702 printf (_(" FP mode: "));
12703 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
12704 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
12705 break;
12706 case NT_VMS_LINKTIME:
12707 printf (_(" Link time: "));
12708 print_vms_time
12709 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12710 printf ("\n");
12711 break;
12712 case NT_VMS_PATCHTIME:
12713 printf (_(" Patch time: "));
12714 print_vms_time
12715 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
12716 printf ("\n");
12717 break;
12718 case NT_VMS_ORIG_DYN:
12719 printf (_(" Major id: %u, minor id: %u\n"),
12720 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
12721 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
12722 printf (_(" Manip date : "));
12723 print_vms_time
12724 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
12725 printf (_("\n"
4a5cb34f
TG
12726 " Link flags : "));
12727 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
12728 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
12729 printf (_(" Header flags: 0x%08x\n"),
12730 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
12731 printf (_(" Image id : %s\n"), pnote->descdata + 32);
12732 break;
12733#endif
12734 case NT_VMS_IMGNAM:
12735 printf (_(" Image name: %s\n"), pnote->descdata);
12736 break;
12737 case NT_VMS_GSTNAM:
12738 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
12739 break;
12740 case NT_VMS_IMGID:
12741 printf (_(" Image id: %s\n"), pnote->descdata);
12742 break;
12743 case NT_VMS_LINKID:
12744 printf (_(" Linker id: %s\n"), pnote->descdata);
12745 break;
12746 default:
12747 break;
12748 }
12749 return 1;
12750}
12751
6d118b09
NC
12752/* Note that by the ELF standard, the name field is already null byte
12753 terminated, and namesz includes the terminating null byte.
12754 I.E. the value of namesz for the name "FSF" is 4.
12755
e3c8793a 12756 If the value of namesz is zero, there is no name present. */
779fe533 12757static int
2cf0635d 12758process_note (Elf_Internal_Note * pnote)
779fe533 12759{
2cf0635d
NC
12760 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
12761 const char * nt;
9437c45b
JT
12762
12763 if (pnote->namesz == 0)
1ec5cd37
NC
12764 /* If there is no note name, then use the default set of
12765 note type strings. */
12766 nt = get_note_type (pnote->type);
12767
1118d252
RM
12768 else if (const_strneq (pnote->namedata, "GNU"))
12769 /* GNU-specific object file notes. */
12770 nt = get_gnu_elf_note_type (pnote->type);
12771
0112cd26 12772 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
12773 /* NetBSD-specific core file notes. */
12774 nt = get_netbsd_elfcore_note_type (pnote->type);
12775
b15fa79e
AM
12776 else if (strneq (pnote->namedata, "SPU/", 4))
12777 {
12778 /* SPU-specific core file notes. */
12779 nt = pnote->namedata + 4;
12780 name = "SPU";
12781 }
12782
00e98fc7
TG
12783 else if (const_strneq (pnote->namedata, "IPF/VMS"))
12784 /* VMS/ia64-specific file notes. */
12785 nt = get_ia64_vms_note_type (pnote->type);
12786
70616151
TT
12787 else if (const_strneq (pnote->namedata, "stapsdt"))
12788 nt = get_stapsdt_note_type (pnote->type);
12789
9437c45b 12790 else
1ec5cd37
NC
12791 /* Don't recognize this note name; just use the default set of
12792 note type strings. */
00e98fc7 12793 nt = get_note_type (pnote->type);
9437c45b 12794
2aee03ae 12795 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
12796
12797 if (const_strneq (pnote->namedata, "IPF/VMS"))
12798 return print_ia64_vms_note (pnote);
664f90a3
TT
12799 else if (const_strneq (pnote->namedata, "GNU"))
12800 return print_gnu_note (pnote);
c6a9fc58
TT
12801 else if (const_strneq (pnote->namedata, "stapsdt"))
12802 return print_stapsdt_note (pnote);
00e98fc7
TG
12803 else
12804 return 1;
779fe533
NC
12805}
12806
6d118b09 12807
779fe533 12808static int
2cf0635d 12809process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 12810{
2cf0635d
NC
12811 Elf_External_Note * pnotes;
12812 Elf_External_Note * external;
b34976b6 12813 int res = 1;
103f02d3 12814
779fe533
NC
12815 if (length <= 0)
12816 return 0;
103f02d3 12817
3f5e193b
NC
12818 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
12819 _("notes"));
dd24e3da 12820 if (pnotes == NULL)
a6e9f9df 12821 return 0;
779fe533 12822
103f02d3 12823 external = pnotes;
103f02d3 12824
305c7206 12825 printf (_("\nNotes at offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 12826 (unsigned long) offset, (unsigned long) length);
2aee03ae 12827 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 12828
2cf0635d 12829 while (external < (Elf_External_Note *) ((char *) pnotes + length))
779fe533 12830 {
2cf0635d 12831 Elf_External_Note * next;
b34976b6 12832 Elf_Internal_Note inote;
2cf0635d 12833 char * temp = NULL;
6d118b09 12834
00e98fc7
TG
12835 if (!is_ia64_vms ())
12836 {
12837 inote.type = BYTE_GET (external->type);
12838 inote.namesz = BYTE_GET (external->namesz);
12839 inote.namedata = external->name;
12840 inote.descsz = BYTE_GET (external->descsz);
12841 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
12842 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12843
12844 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
12845 }
12846 else
12847 {
12848 Elf64_External_VMS_Note *vms_external;
12849
12850 vms_external = (Elf64_External_VMS_Note *)external;
12851 inote.type = BYTE_GET (vms_external->type);
12852 inote.namesz = BYTE_GET (vms_external->namesz);
12853 inote.namedata = vms_external->name;
12854 inote.descsz = BYTE_GET (vms_external->descsz);
12855 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
12856 inote.descpos = offset + (inote.descdata - (char *) pnotes);
12857
12858 next = (Elf_External_Note *)
12859 (inote.descdata + align_power (inote.descsz, 3));
12860 }
3e55a963 12861
dd24e3da
NC
12862 if ( ((char *) next > ((char *) pnotes) + length)
12863 || ((char *) next < (char *) pnotes))
3e55a963 12864 {
0fd3a477 12865 warn (_("corrupt note found at offset %lx into core notes\n"),
0af1713e 12866 (unsigned long) ((char *) external - (char *) pnotes));
0fd3a477 12867 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
3e55a963
NC
12868 inote.type, inote.namesz, inote.descsz);
12869 break;
12870 }
12871
12872 external = next;
6d118b09 12873
dd24e3da
NC
12874 /* Prevent out-of-bounds indexing. */
12875 if (inote.namedata + inote.namesz >= (char *) pnotes + length
12876 || inote.namedata + inote.namesz < inote.namedata)
12877 {
12878 warn (_("corrupt note found at offset %lx into core notes\n"),
12879 (unsigned long) ((char *) external - (char *) pnotes));
12880 warn (_(" type: %lx, namesize: %08lx, descsize: %08lx\n"),
12881 inote.type, inote.namesz, inote.descsz);
12882 break;
12883 }
12884
6d118b09
NC
12885 /* Verify that name is null terminated. It appears that at least
12886 one version of Linux (RedHat 6.0) generates corefiles that don't
12887 comply with the ELF spec by failing to include the null byte in
12888 namesz. */
12889 if (inote.namedata[inote.namesz] != '\0')
12890 {
3f5e193b 12891 temp = (char *) malloc (inote.namesz + 1);
76da6bbe 12892
6d118b09
NC
12893 if (temp == NULL)
12894 {
12895 error (_("Out of memory\n"));
12896 res = 0;
12897 break;
12898 }
76da6bbe 12899
6d118b09
NC
12900 strncpy (temp, inote.namedata, inote.namesz);
12901 temp[inote.namesz] = 0;
76da6bbe 12902
6d118b09
NC
12903 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
12904 inote.namedata = temp;
12905 }
12906
12907 res &= process_note (& inote);
103f02d3 12908
6d118b09
NC
12909 if (temp != NULL)
12910 {
12911 free (temp);
12912 temp = NULL;
12913 }
779fe533
NC
12914 }
12915
12916 free (pnotes);
103f02d3 12917
779fe533
NC
12918 return res;
12919}
12920
12921static int
2cf0635d 12922process_corefile_note_segments (FILE * file)
779fe533 12923{
2cf0635d 12924 Elf_Internal_Phdr * segment;
b34976b6
AM
12925 unsigned int i;
12926 int res = 1;
103f02d3 12927
d93f0186 12928 if (! get_program_headers (file))
779fe533 12929 return 0;
103f02d3 12930
779fe533
NC
12931 for (i = 0, segment = program_headers;
12932 i < elf_header.e_phnum;
b34976b6 12933 i++, segment++)
779fe533
NC
12934 {
12935 if (segment->p_type == PT_NOTE)
103f02d3 12936 res &= process_corefile_note_segment (file,
30800947
NC
12937 (bfd_vma) segment->p_offset,
12938 (bfd_vma) segment->p_filesz);
779fe533 12939 }
103f02d3 12940
779fe533
NC
12941 return res;
12942}
12943
12944static int
2cf0635d 12945process_note_sections (FILE * file)
1ec5cd37 12946{
2cf0635d 12947 Elf_Internal_Shdr * section;
1ec5cd37
NC
12948 unsigned long i;
12949 int res = 1;
12950
12951 for (i = 0, section = section_headers;
12952 i < elf_header.e_shnum;
12953 i++, section++)
12954 if (section->sh_type == SHT_NOTE)
12955 res &= process_corefile_note_segment (file,
12956 (bfd_vma) section->sh_offset,
12957 (bfd_vma) section->sh_size);
12958
12959 return res;
12960}
12961
12962static int
2cf0635d 12963process_notes (FILE * file)
779fe533
NC
12964{
12965 /* If we have not been asked to display the notes then do nothing. */
12966 if (! do_notes)
12967 return 1;
103f02d3 12968
779fe533 12969 if (elf_header.e_type != ET_CORE)
1ec5cd37 12970 return process_note_sections (file);
103f02d3 12971
779fe533 12972 /* No program headers means no NOTE segment. */
1ec5cd37
NC
12973 if (elf_header.e_phnum > 0)
12974 return process_corefile_note_segments (file);
779fe533 12975
1ec5cd37
NC
12976 printf (_("No note segments present in the core file.\n"));
12977 return 1;
779fe533
NC
12978}
12979
252b5132 12980static int
2cf0635d 12981process_arch_specific (FILE * file)
252b5132 12982{
a952a375
NC
12983 if (! do_arch)
12984 return 1;
12985
252b5132
RH
12986 switch (elf_header.e_machine)
12987 {
11c1ff18
PB
12988 case EM_ARM:
12989 return process_arm_specific (file);
252b5132 12990 case EM_MIPS:
4fe85591 12991 case EM_MIPS_RS3_LE:
252b5132
RH
12992 return process_mips_specific (file);
12993 break;
34c8bcba
JM
12994 case EM_PPC:
12995 return process_power_specific (file);
12996 break;
9e8c70f9
DM
12997 case EM_SPARC:
12998 case EM_SPARC32PLUS:
12999 case EM_SPARCV9:
13000 return process_sparc_specific (file);
13001 break;
59e6276b
JM
13002 case EM_TI_C6000:
13003 return process_tic6x_specific (file);
13004 break;
252b5132
RH
13005 default:
13006 break;
13007 }
13008 return 1;
13009}
13010
13011static int
2cf0635d 13012get_file_header (FILE * file)
252b5132 13013{
9ea033b2
NC
13014 /* Read in the identity array. */
13015 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
13016 return 0;
13017
9ea033b2 13018 /* Determine how to read the rest of the header. */
b34976b6 13019 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
13020 {
13021 default: /* fall through */
13022 case ELFDATANONE: /* fall through */
adab8cdc
AO
13023 case ELFDATA2LSB:
13024 byte_get = byte_get_little_endian;
13025 byte_put = byte_put_little_endian;
13026 break;
13027 case ELFDATA2MSB:
13028 byte_get = byte_get_big_endian;
13029 byte_put = byte_put_big_endian;
13030 break;
9ea033b2
NC
13031 }
13032
13033 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 13034 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
13035
13036 /* Read in the rest of the header. */
13037 if (is_32bit_elf)
13038 {
13039 Elf32_External_Ehdr ehdr32;
252b5132 13040
9ea033b2
NC
13041 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
13042 return 0;
103f02d3 13043
9ea033b2
NC
13044 elf_header.e_type = BYTE_GET (ehdr32.e_type);
13045 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
13046 elf_header.e_version = BYTE_GET (ehdr32.e_version);
13047 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
13048 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
13049 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
13050 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
13051 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
13052 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
13053 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
13054 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
13055 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
13056 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
13057 }
252b5132 13058 else
9ea033b2
NC
13059 {
13060 Elf64_External_Ehdr ehdr64;
a952a375
NC
13061
13062 /* If we have been compiled with sizeof (bfd_vma) == 4, then
13063 we will not be able to cope with the 64bit data found in
13064 64 ELF files. Detect this now and abort before we start
50c2245b 13065 overwriting things. */
a952a375
NC
13066 if (sizeof (bfd_vma) < 8)
13067 {
e3c8793a
NC
13068 error (_("This instance of readelf has been built without support for a\n\
1306964 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
13070 return 0;
13071 }
103f02d3 13072
9ea033b2
NC
13073 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
13074 return 0;
103f02d3 13075
9ea033b2
NC
13076 elf_header.e_type = BYTE_GET (ehdr64.e_type);
13077 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
13078 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
13079 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
13080 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
13081 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
13082 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
13083 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
13084 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
13085 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
13086 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
13087 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
13088 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
13089 }
252b5132 13090
7ece0d85
JJ
13091 if (elf_header.e_shoff)
13092 {
13093 /* There may be some extensions in the first section header. Don't
13094 bomb if we can't read it. */
13095 if (is_32bit_elf)
13096 get_32bit_section_headers (file, 1);
13097 else
13098 get_64bit_section_headers (file, 1);
13099 }
560f3c1c 13100
252b5132
RH
13101 return 1;
13102}
13103
fb52b2f4
NC
13104/* Process one ELF object file according to the command line options.
13105 This file may actually be stored in an archive. The file is
13106 positioned at the start of the ELF object. */
13107
ff78d6d6 13108static int
2cf0635d 13109process_object (char * file_name, FILE * file)
252b5132 13110{
252b5132
RH
13111 unsigned int i;
13112
252b5132
RH
13113 if (! get_file_header (file))
13114 {
13115 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 13116 return 1;
252b5132
RH
13117 }
13118
13119 /* Initialise per file variables. */
60bca95a 13120 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
13121 version_info[i] = 0;
13122
60bca95a 13123 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 13124 dynamic_info[i] = 0;
5115b233 13125 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
13126
13127 /* Process the file. */
13128 if (show_name)
13129 printf (_("\nFile: %s\n"), file_name);
13130
18bd398b
NC
13131 /* Initialise the dump_sects array from the cmdline_dump_sects array.
13132 Note we do this even if cmdline_dump_sects is empty because we
13133 must make sure that the dump_sets array is zeroed out before each
13134 object file is processed. */
13135 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 13136 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
13137
13138 if (num_cmdline_dump_sects > 0)
13139 {
13140 if (num_dump_sects == 0)
13141 /* A sneaky way of allocating the dump_sects array. */
09c11c86 13142 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
13143
13144 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
13145 memcpy (dump_sects, cmdline_dump_sects,
13146 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 13147 }
d70c5fc7 13148
252b5132 13149 if (! process_file_header ())
fb52b2f4 13150 return 1;
252b5132 13151
d1f5c6e3 13152 if (! process_section_headers (file))
2f62977e 13153 {
d1f5c6e3
L
13154 /* Without loaded section headers we cannot process lots of
13155 things. */
2f62977e 13156 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 13157
2f62977e 13158 if (! do_using_dynamic)
2c610e4b 13159 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 13160 }
252b5132 13161
d1f5c6e3
L
13162 if (! process_section_groups (file))
13163 {
13164 /* Without loaded section groups we cannot process unwind. */
13165 do_unwind = 0;
13166 }
13167
2f62977e 13168 if (process_program_headers (file))
b2d38a17 13169 process_dynamic_section (file);
252b5132
RH
13170
13171 process_relocs (file);
13172
4d6ed7c8
NC
13173 process_unwind (file);
13174
252b5132
RH
13175 process_symbol_table (file);
13176
13177 process_syminfo (file);
13178
13179 process_version_sections (file);
13180
13181 process_section_contents (file);
f5842774 13182
1ec5cd37 13183 process_notes (file);
103f02d3 13184
047b2264
JJ
13185 process_gnu_liblist (file);
13186
252b5132
RH
13187 process_arch_specific (file);
13188
d93f0186
NC
13189 if (program_headers)
13190 {
13191 free (program_headers);
13192 program_headers = NULL;
13193 }
13194
252b5132
RH
13195 if (section_headers)
13196 {
13197 free (section_headers);
13198 section_headers = NULL;
13199 }
13200
13201 if (string_table)
13202 {
13203 free (string_table);
13204 string_table = NULL;
d40ac9bd 13205 string_table_length = 0;
252b5132
RH
13206 }
13207
13208 if (dynamic_strings)
13209 {
13210 free (dynamic_strings);
13211 dynamic_strings = NULL;
d79b3d50 13212 dynamic_strings_length = 0;
252b5132
RH
13213 }
13214
13215 if (dynamic_symbols)
13216 {
13217 free (dynamic_symbols);
13218 dynamic_symbols = NULL;
19936277 13219 num_dynamic_syms = 0;
252b5132
RH
13220 }
13221
13222 if (dynamic_syminfo)
13223 {
13224 free (dynamic_syminfo);
13225 dynamic_syminfo = NULL;
13226 }
ff78d6d6 13227
293c573e
MR
13228 if (dynamic_section)
13229 {
13230 free (dynamic_section);
13231 dynamic_section = NULL;
13232 }
13233
e4b17d5c
L
13234 if (section_headers_groups)
13235 {
13236 free (section_headers_groups);
13237 section_headers_groups = NULL;
13238 }
13239
13240 if (section_groups)
13241 {
2cf0635d
NC
13242 struct group_list * g;
13243 struct group_list * next;
e4b17d5c
L
13244
13245 for (i = 0; i < group_count; i++)
13246 {
13247 for (g = section_groups [i].root; g != NULL; g = next)
13248 {
13249 next = g->next;
13250 free (g);
13251 }
13252 }
13253
13254 free (section_groups);
13255 section_groups = NULL;
13256 }
13257
19e6b90e 13258 free_debug_memory ();
18bd398b 13259
ff78d6d6 13260 return 0;
252b5132
RH
13261}
13262
2cf0635d
NC
13263/* Process an ELF archive.
13264 On entry the file is positioned just after the ARMAG string. */
13265
13266static int
13267process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
13268{
13269 struct archive_info arch;
13270 struct archive_info nested_arch;
13271 size_t got;
2cf0635d
NC
13272 int ret;
13273
13274 show_name = 1;
13275
13276 /* The ARCH structure is used to hold information about this archive. */
13277 arch.file_name = NULL;
13278 arch.file = NULL;
13279 arch.index_array = NULL;
13280 arch.sym_table = NULL;
13281 arch.longnames = NULL;
13282
13283 /* The NESTED_ARCH structure is used as a single-item cache of information
13284 about a nested archive (when members of a thin archive reside within
13285 another regular archive file). */
13286 nested_arch.file_name = NULL;
13287 nested_arch.file = NULL;
13288 nested_arch.index_array = NULL;
13289 nested_arch.sym_table = NULL;
13290 nested_arch.longnames = NULL;
13291
13292 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
13293 {
13294 ret = 1;
13295 goto out;
4145f1d5 13296 }
fb52b2f4 13297
4145f1d5
NC
13298 if (do_archive_index)
13299 {
2cf0635d 13300 if (arch.sym_table == NULL)
4145f1d5
NC
13301 error (_("%s: unable to dump the index as none was found\n"), file_name);
13302 else
13303 {
2cf0635d 13304 unsigned int i, l;
4145f1d5
NC
13305 unsigned long current_pos;
13306
13307 printf (_("Index of archive %s: (%ld entries, 0x%lx bytes in the symbol table)\n"),
2cf0635d 13308 file_name, arch.index_num, arch.sym_size);
4145f1d5
NC
13309 current_pos = ftell (file);
13310
2cf0635d 13311 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 13312 {
2cf0635d
NC
13313 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
13314 {
13315 char * member_name;
4145f1d5 13316
2cf0635d
NC
13317 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
13318
13319 if (member_name != NULL)
13320 {
13321 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
13322
13323 if (qualified_name != NULL)
13324 {
13325 printf (_("Binary %s contains:\n"), qualified_name);
13326 free (qualified_name);
13327 }
4145f1d5
NC
13328 }
13329 }
2cf0635d
NC
13330
13331 if (l >= arch.sym_size)
4145f1d5
NC
13332 {
13333 error (_("%s: end of the symbol table reached before the end of the index\n"),
13334 file_name);
cb8f3167 13335 break;
4145f1d5 13336 }
2cf0635d
NC
13337 printf ("\t%s\n", arch.sym_table + l);
13338 l += strlen (arch.sym_table + l) + 1;
4145f1d5
NC
13339 }
13340
2cf0635d
NC
13341 if (l & 01)
13342 ++l;
13343 if (l < arch.sym_size)
4145f1d5
NC
13344 error (_("%s: symbols remain in the index symbol table, but without corresponding entries in the index table\n"),
13345 file_name);
13346
4145f1d5
NC
13347 if (fseek (file, current_pos, SEEK_SET) != 0)
13348 {
13349 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
13350 ret = 1;
13351 goto out;
4145f1d5 13352 }
fb52b2f4 13353 }
4145f1d5
NC
13354
13355 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
13356 && !do_segments && !do_header && !do_dump && !do_version
13357 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 13358 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
13359 {
13360 ret = 0; /* Archive index only. */
13361 goto out;
13362 }
fb52b2f4
NC
13363 }
13364
d989285c 13365 ret = 0;
fb52b2f4
NC
13366
13367 while (1)
13368 {
2cf0635d
NC
13369 char * name;
13370 size_t namelen;
13371 char * qualified_name;
13372
13373 /* Read the next archive header. */
13374 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
13375 {
13376 error (_("%s: failed to seek to next archive header\n"), file_name);
13377 return 1;
13378 }
13379 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
13380 if (got != sizeof arch.arhdr)
13381 {
13382 if (got == 0)
13383 break;
13384 error (_("%s: failed to read archive header\n"), file_name);
13385 ret = 1;
13386 break;
13387 }
13388 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
13389 {
13390 error (_("%s: did not find a valid archive header\n"), arch.file_name);
13391 ret = 1;
13392 break;
13393 }
13394
13395 arch.next_arhdr_offset += sizeof arch.arhdr;
13396
13397 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
13398 if (archive_file_size & 01)
13399 ++archive_file_size;
13400
13401 name = get_archive_member_name (&arch, &nested_arch);
13402 if (name == NULL)
fb52b2f4 13403 {
0fd3a477 13404 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13405 ret = 1;
13406 break;
fb52b2f4 13407 }
2cf0635d 13408 namelen = strlen (name);
fb52b2f4 13409
2cf0635d
NC
13410 qualified_name = make_qualified_name (&arch, &nested_arch, name);
13411 if (qualified_name == NULL)
fb52b2f4 13412 {
2cf0635d 13413 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
13414 ret = 1;
13415 break;
fb52b2f4
NC
13416 }
13417
2cf0635d
NC
13418 if (is_thin_archive && arch.nested_member_origin == 0)
13419 {
13420 /* This is a proxy for an external member of a thin archive. */
13421 FILE * member_file;
13422 char * member_file_name = adjust_relative_path (file_name, name, namelen);
13423 if (member_file_name == NULL)
13424 {
13425 ret = 1;
13426 break;
13427 }
13428
13429 member_file = fopen (member_file_name, "rb");
13430 if (member_file == NULL)
13431 {
13432 error (_("Input file '%s' is not readable.\n"), member_file_name);
13433 free (member_file_name);
13434 ret = 1;
13435 break;
13436 }
13437
13438 archive_file_offset = arch.nested_member_origin;
13439
13440 ret |= process_object (qualified_name, member_file);
13441
13442 fclose (member_file);
13443 free (member_file_name);
13444 }
13445 else if (is_thin_archive)
13446 {
13447 /* This is a proxy for a member of a nested archive. */
13448 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
13449
13450 /* The nested archive file will have been opened and setup by
13451 get_archive_member_name. */
13452 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
13453 {
13454 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
13455 ret = 1;
13456 break;
13457 }
13458
13459 ret |= process_object (qualified_name, nested_arch.file);
13460 }
13461 else
13462 {
13463 archive_file_offset = arch.next_arhdr_offset;
13464 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 13465
2cf0635d
NC
13466 ret |= process_object (qualified_name, file);
13467 }
fb52b2f4 13468
2b52916e
L
13469 if (dump_sects != NULL)
13470 {
13471 free (dump_sects);
13472 dump_sects = NULL;
13473 num_dump_sects = 0;
13474 }
13475
2cf0635d 13476 free (qualified_name);
fb52b2f4
NC
13477 }
13478
4145f1d5 13479 out:
2cf0635d
NC
13480 if (nested_arch.file != NULL)
13481 fclose (nested_arch.file);
13482 release_archive (&nested_arch);
13483 release_archive (&arch);
fb52b2f4 13484
d989285c 13485 return ret;
fb52b2f4
NC
13486}
13487
13488static int
2cf0635d 13489process_file (char * file_name)
fb52b2f4 13490{
2cf0635d 13491 FILE * file;
fb52b2f4
NC
13492 struct stat statbuf;
13493 char armag[SARMAG];
13494 int ret;
13495
13496 if (stat (file_name, &statbuf) < 0)
13497 {
f24ddbdd
NC
13498 if (errno == ENOENT)
13499 error (_("'%s': No such file\n"), file_name);
13500 else
13501 error (_("Could not locate '%s'. System error message: %s\n"),
13502 file_name, strerror (errno));
13503 return 1;
13504 }
13505
13506 if (! S_ISREG (statbuf.st_mode))
13507 {
13508 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
13509 return 1;
13510 }
13511
13512 file = fopen (file_name, "rb");
13513 if (file == NULL)
13514 {
f24ddbdd 13515 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
13516 return 1;
13517 }
13518
13519 if (fread (armag, SARMAG, 1, file) != 1)
13520 {
4145f1d5 13521 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
13522 fclose (file);
13523 return 1;
13524 }
13525
13526 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
13527 ret = process_archive (file_name, file, FALSE);
13528 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
13529 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
13530 else
13531 {
4145f1d5
NC
13532 if (do_archive_index)
13533 error (_("File %s is not an archive so its index cannot be displayed.\n"),
13534 file_name);
13535
fb52b2f4
NC
13536 rewind (file);
13537 archive_file_size = archive_file_offset = 0;
13538 ret = process_object (file_name, file);
13539 }
13540
13541 fclose (file);
13542
13543 return ret;
13544}
13545
252b5132
RH
13546#ifdef SUPPORT_DISASSEMBLY
13547/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 13548 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 13549 symbols. */
252b5132
RH
13550
13551void
2cf0635d 13552print_address (unsigned int addr, FILE * outfile)
252b5132
RH
13553{
13554 fprintf (outfile,"0x%8.8x", addr);
13555}
13556
e3c8793a 13557/* Needed by the i386 disassembler. */
252b5132
RH
13558void
13559db_task_printsym (unsigned int addr)
13560{
13561 print_address (addr, stderr);
13562}
13563#endif
13564
13565int
2cf0635d 13566main (int argc, char ** argv)
252b5132 13567{
ff78d6d6
L
13568 int err;
13569
252b5132
RH
13570#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
13571 setlocale (LC_MESSAGES, "");
3882b010
L
13572#endif
13573#if defined (HAVE_SETLOCALE)
13574 setlocale (LC_CTYPE, "");
252b5132
RH
13575#endif
13576 bindtextdomain (PACKAGE, LOCALEDIR);
13577 textdomain (PACKAGE);
13578
869b9d07
MM
13579 expandargv (&argc, &argv);
13580
252b5132
RH
13581 parse_args (argc, argv);
13582
18bd398b 13583 if (num_dump_sects > 0)
59f14fc0 13584 {
18bd398b 13585 /* Make a copy of the dump_sects array. */
3f5e193b
NC
13586 cmdline_dump_sects = (dump_type *)
13587 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 13588 if (cmdline_dump_sects == NULL)
591a748a 13589 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
13590 else
13591 {
09c11c86
NC
13592 memcpy (cmdline_dump_sects, dump_sects,
13593 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
13594 num_cmdline_dump_sects = num_dump_sects;
13595 }
13596 }
13597
18bd398b
NC
13598 if (optind < (argc - 1))
13599 show_name = 1;
13600
ff78d6d6 13601 err = 0;
252b5132 13602 while (optind < argc)
18bd398b 13603 err |= process_file (argv[optind++]);
252b5132
RH
13604
13605 if (dump_sects != NULL)
13606 free (dump_sects);
59f14fc0
AS
13607 if (cmdline_dump_sects != NULL)
13608 free (cmdline_dump_sects);
252b5132 13609
ff78d6d6 13610 return err;
252b5132 13611}