]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Fixes compiling peXXigen under MAC OS/X where the wcsncasecmp function is not available.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
b90efa5b 2 Copyright (C) 1998-2015 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056
CS
46#ifdef HAVE_ZLIB_H
47#include <zlib.h>
48#endif
3bfcb652 49#ifdef HAVE_WCHAR_H
7bfd842d 50#include <wchar.h>
3bfcb652 51#endif
252b5132 52
a952a375 53#if __GNUC__ >= 2
19936277 54/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 55 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 56 Only do this if we believe that the compiler can support a 64 bit
a952a375 57 data type. For now we only rely on GCC being able to do this. */
19936277 58#define BFD64
a952a375
NC
59#endif
60
3db64b00
AM
61#include "bfd.h"
62#include "bucomm.h"
3284fe0c 63#include "elfcomm.h"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
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"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3f8107ab 109#include "elf/ft32.h"
3b16e843
NC
110#include "elf/h8.h"
111#include "elf/hppa.h"
112#include "elf/i386.h"
35b1837e 113#include "elf/i370.h"
3b16e843
NC
114#include "elf/i860.h"
115#include "elf/i960.h"
116#include "elf/ia64.h"
1e4cf259 117#include "elf/ip2k.h"
84e94c90 118#include "elf/lm32.h"
1c0d3aa6 119#include "elf/iq2000.h"
49f58d10 120#include "elf/m32c.h"
3b16e843
NC
121#include "elf/m32r.h"
122#include "elf/m68k.h"
75751cd9 123#include "elf/m68hc11.h"
252b5132 124#include "elf/mcore.h"
15ab5209 125#include "elf/mep.h"
a3c62988 126#include "elf/metag.h"
7ba29e2a 127#include "elf/microblaze.h"
3b16e843 128#include "elf/mips.h"
3c3bdf30 129#include "elf/mmix.h"
3b16e843
NC
130#include "elf/mn10200.h"
131#include "elf/mn10300.h"
5506d11a 132#include "elf/moxie.h"
4970f871 133#include "elf/mt.h"
2469cfa2 134#include "elf/msp430.h"
35c08157 135#include "elf/nds32.h"
13761a11 136#include "elf/nios2.h"
73589c9d 137#include "elf/or1k.h"
7d466069 138#include "elf/pj.h"
3b16e843 139#include "elf/ppc.h"
c833c019 140#include "elf/ppc64.h"
99c513f6 141#include "elf/rl78.h"
c7927a3c 142#include "elf/rx.h"
a85d7ed0 143#include "elf/s390.h"
1c0d3aa6 144#include "elf/score.h"
3b16e843
NC
145#include "elf/sh.h"
146#include "elf/sparc.h"
e9f53129 147#include "elf/spu.h"
40b36596 148#include "elf/tic6x.h"
aa137e4d
NC
149#include "elf/tilegx.h"
150#include "elf/tilepro.h"
3b16e843 151#include "elf/v850.h"
179d3252 152#include "elf/vax.h"
619ed720 153#include "elf/visium.h"
3b16e843 154#include "elf/x86-64.h"
c29aca4a 155#include "elf/xc16x.h"
f6c1a2d5 156#include "elf/xgate.h"
93fbbb04 157#include "elf/xstormy16.h"
88da6820 158#include "elf/xtensa.h"
252b5132 159
252b5132 160#include "getopt.h"
566b0d53 161#include "libiberty.h"
09c11c86 162#include "safe-ctype.h"
2cf0635d 163#include "filenames.h"
252b5132 164
15b42fb0
AM
165#ifndef offsetof
166#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
167#endif
168
2cf0635d 169char * program_name = "readelf";
c9c1d674 170static unsigned long archive_file_offset;
85b1c36d 171static unsigned long archive_file_size;
f54498b4 172static bfd_size_type current_file_size;
85b1c36d
BE
173static unsigned long dynamic_addr;
174static bfd_size_type dynamic_size;
8b73c356 175static size_t dynamic_nent;
2cf0635d 176static char * dynamic_strings;
85b1c36d 177static unsigned long dynamic_strings_length;
2cf0635d 178static char * string_table;
85b1c36d
BE
179static unsigned long string_table_length;
180static unsigned long num_dynamic_syms;
2cf0635d
NC
181static Elf_Internal_Sym * dynamic_symbols;
182static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
183static unsigned long dynamic_syminfo_offset;
184static unsigned int dynamic_syminfo_nent;
f8eae8b2 185static char program_interpreter[PATH_MAX];
bb8a0291 186static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 187static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
188static bfd_vma version_info[16];
189static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
190static Elf_Internal_Shdr * section_headers;
191static Elf_Internal_Phdr * program_headers;
192static Elf_Internal_Dyn * dynamic_section;
193static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
194static int show_name;
195static int do_dynamic;
196static int do_syms;
2c610e4b 197static int do_dyn_syms;
85b1c36d
BE
198static int do_reloc;
199static int do_sections;
200static int do_section_groups;
5477e8a0 201static int do_section_details;
85b1c36d
BE
202static int do_segments;
203static int do_unwind;
204static int do_using_dynamic;
205static int do_header;
206static int do_dump;
207static int do_version;
85b1c36d
BE
208static int do_histogram;
209static int do_debugging;
85b1c36d
BE
210static int do_arch;
211static int do_notes;
4145f1d5 212static int do_archive_index;
85b1c36d 213static int is_32bit_elf;
252b5132 214
e4b17d5c
L
215struct group_list
216{
2cf0635d 217 struct group_list * next;
e4b17d5c
L
218 unsigned int section_index;
219};
220
221struct group
222{
2cf0635d 223 struct group_list * root;
e4b17d5c
L
224 unsigned int group_index;
225};
226
85b1c36d 227static size_t group_count;
2cf0635d
NC
228static struct group * section_groups;
229static struct group ** section_headers_groups;
e4b17d5c 230
09c11c86
NC
231
232/* Flag bits indicating particular types of dump. */
233#define HEX_DUMP (1 << 0) /* The -x command line switch. */
234#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
235#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
236#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 237#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
238
239typedef unsigned char dump_type;
240
241/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
242struct dump_list_entry
243{
2cf0635d 244 char * name;
09c11c86 245 dump_type type;
2cf0635d 246 struct dump_list_entry * next;
aef1f6d0 247};
2cf0635d 248static struct dump_list_entry * dump_sects_byname;
aef1f6d0 249
09c11c86
NC
250/* A dynamic array of flags indicating for which sections a dump
251 has been requested via command line switches. */
252static dump_type * cmdline_dump_sects = NULL;
253static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
254
255/* A dynamic array of flags indicating for which sections a dump of
256 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
257 basis and then initialised from the cmdline_dump_sects array,
258 the results of interpreting the -w switch, and the
259 dump_sects_byname list. */
09c11c86
NC
260static dump_type * dump_sects = NULL;
261static unsigned int num_dump_sects = 0;
252b5132 262
252b5132 263
c256ffe7 264/* How to print a vma value. */
843dd992
NC
265typedef enum print_mode
266{
267 HEX,
268 DEC,
269 DEC_5,
270 UNSIGNED,
271 PREFIX_HEX,
272 FULL_HEX,
273 LONG_HEX
274}
275print_mode;
276
bb4d2ac2
L
277/* Versioned symbol info. */
278enum versioned_symbol_info
279{
280 symbol_undefined,
281 symbol_hidden,
282 symbol_public
283};
284
285static const char *get_symbol_version_string
286 (FILE *file, int is_dynsym, const char *strtab,
287 unsigned long int strtab_size, unsigned int si,
288 Elf_Internal_Sym *psym, enum versioned_symbol_info *sym_info,
289 unsigned short *vna_other);
290
9c19a809
NC
291#define UNKNOWN -1
292
2b692964
NC
293#define SECTION_NAME(X) \
294 ((X) == NULL ? _("<none>") \
295 : string_table == NULL ? _("<no-name>") \
296 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 297 : string_table + (X)->sh_name))
252b5132 298
ee42cf8c 299#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 300
ba5cdace
NC
301#define GET_ELF_SYMBOLS(file, section, sym_count) \
302 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
303 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 304
d79b3d50
NC
305#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
306/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
307 already been called and verified that the string exists. */
308#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 309
61865e30
NC
310#define REMOVE_ARCH_BITS(ADDR) \
311 do \
312 { \
313 if (elf_header.e_machine == EM_ARM) \
314 (ADDR) &= ~1; \
315 } \
316 while (0)
d79b3d50 317\f
c9c1d674
EG
318/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET +
319 the offset of the current archive member, if we are examining an archive.
59245841
NC
320 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
321 using malloc and fill that. In either case return the pointer to the start of
322 the retrieved data or NULL if something went wrong. If something does go wrong
c9c1d674
EG
323 and REASON is not NULL then emit an error message using REASON as part of the
324 context. */
59245841 325
c256ffe7 326static void *
57028622
NC
327get_data (void * var, FILE * file, unsigned long offset, bfd_size_type size,
328 bfd_size_type nmemb, const char * reason)
a6e9f9df 329{
2cf0635d 330 void * mvar;
57028622 331 bfd_size_type amt = size * nmemb;
a6e9f9df 332
c256ffe7 333 if (size == 0 || nmemb == 0)
a6e9f9df
AM
334 return NULL;
335
57028622
NC
336 /* If the size_t type is smaller than the bfd_size_type, eg because
337 you are building a 32-bit tool on a 64-bit host, then make sure
338 that when the sizes are cast to (size_t) no information is lost. */
339 if (sizeof (size_t) < sizeof (bfd_size_type)
340 && ( (bfd_size_type) ((size_t) size) != size
341 || (bfd_size_type) ((size_t) nmemb) != nmemb))
342 {
343 if (reason)
344 error (_("Size truncation prevents reading 0x%llx elements of size 0x%llx for %s\n"),
345 (unsigned long long) nmemb, (unsigned long long) size, reason);
346 return NULL;
347 }
348
349 /* Check for size overflow. */
350 if (amt < nmemb)
351 {
352 if (reason)
353 error (_("Size overflow prevents reading 0x%llx elements of size 0x%llx for %s\n"),
354 (unsigned long long) nmemb, (unsigned long long) size, reason);
355 return NULL;
356 }
357
c9c1d674
EG
358 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
359 attempting to allocate memory when the read is bound to fail. */
360 if (amt > current_file_size
361 || offset + archive_file_offset + amt > current_file_size)
a6e9f9df 362 {
049b0c3a 363 if (reason)
57028622
NC
364 error (_("Reading 0x%llx bytes extends past end of file for %s\n"),
365 (unsigned long long) amt, reason);
a6e9f9df
AM
366 return NULL;
367 }
368
c9c1d674 369 if (fseek (file, archive_file_offset + offset, SEEK_SET))
071436c6
NC
370 {
371 if (reason)
c9c1d674
EG
372 error (_("Unable to seek to 0x%lx for %s\n"),
373 (unsigned long) archive_file_offset + offset, reason);
071436c6
NC
374 return NULL;
375 }
376
a6e9f9df
AM
377 mvar = var;
378 if (mvar == NULL)
379 {
c256ffe7 380 /* Check for overflow. */
57028622 381 if (nmemb < (~(bfd_size_type) 0 - 1) / size)
c256ffe7 382 /* + 1 so that we can '\0' terminate invalid string table sections. */
57028622 383 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
384
385 if (mvar == NULL)
386 {
049b0c3a 387 if (reason)
57028622
NC
388 error (_("Out of memory allocating 0x%llx bytes for %s\n"),
389 (unsigned long long) amt, reason);
a6e9f9df
AM
390 return NULL;
391 }
c256ffe7 392
c9c1d674 393 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
394 }
395
57028622 396 if (fread (mvar, (size_t) size, (size_t) nmemb, file) != nmemb)
a6e9f9df 397 {
049b0c3a 398 if (reason)
57028622
NC
399 error (_("Unable to read in 0x%llx bytes of %s\n"),
400 (unsigned long long) amt, reason);
a6e9f9df
AM
401 if (mvar != var)
402 free (mvar);
403 return NULL;
404 }
405
406 return mvar;
407}
408
14a91970 409/* Print a VMA value. */
cb8f3167 410
66543521 411static int
14a91970 412print_vma (bfd_vma vma, print_mode mode)
66543521 413{
66543521
AM
414 int nc = 0;
415
14a91970 416 switch (mode)
66543521 417 {
14a91970
AM
418 case FULL_HEX:
419 nc = printf ("0x");
420 /* Drop through. */
66543521 421
14a91970 422 case LONG_HEX:
f7a99963 423#ifdef BFD64
14a91970 424 if (is_32bit_elf)
437c2fb7 425 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 426#endif
14a91970
AM
427 printf_vma (vma);
428 return nc + 16;
b19aac67 429
14a91970
AM
430 case DEC_5:
431 if (vma <= 99999)
432 return printf ("%5" BFD_VMA_FMT "d", vma);
433 /* Drop through. */
66543521 434
14a91970
AM
435 case PREFIX_HEX:
436 nc = printf ("0x");
437 /* Drop through. */
66543521 438
14a91970
AM
439 case HEX:
440 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 441
14a91970
AM
442 case DEC:
443 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 444
14a91970
AM
445 case UNSIGNED:
446 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 447 }
66543521 448 return 0;
f7a99963
NC
449}
450
7bfd842d 451/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 452 multibye characters (assuming the host environment supports them).
31104126 453
7bfd842d
NC
454 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
455
456 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
457 padding as necessary.
171191ba
NC
458
459 Returns the number of emitted characters. */
460
461static unsigned int
7a88bc9c 462print_symbol (int width, const char *symbol)
31104126 463{
171191ba 464 bfd_boolean extra_padding = FALSE;
7bfd842d 465 int num_printed = 0;
3bfcb652 466#ifdef HAVE_MBSTATE_T
7bfd842d 467 mbstate_t state;
3bfcb652 468#endif
7bfd842d 469 int width_remaining;
961c521f 470
7bfd842d 471 if (width < 0)
961c521f 472 {
961c521f
NC
473 /* Keep the width positive. This also helps. */
474 width = - width;
171191ba 475 extra_padding = TRUE;
0b4362b0 476 }
74e1a04b 477 assert (width != 0);
961c521f 478
7bfd842d
NC
479 if (do_wide)
480 /* Set the remaining width to a very large value.
481 This simplifies the code below. */
482 width_remaining = INT_MAX;
483 else
484 width_remaining = width;
cb8f3167 485
3bfcb652 486#ifdef HAVE_MBSTATE_T
7bfd842d
NC
487 /* Initialise the multibyte conversion state. */
488 memset (& state, 0, sizeof (state));
3bfcb652 489#endif
961c521f 490
7bfd842d
NC
491 while (width_remaining)
492 {
493 size_t n;
7bfd842d 494 const char c = *symbol++;
961c521f 495
7bfd842d 496 if (c == 0)
961c521f
NC
497 break;
498
7bfd842d
NC
499 /* Do not print control characters directly as they can affect terminal
500 settings. Such characters usually appear in the names generated
501 by the assembler for local labels. */
502 if (ISCNTRL (c))
961c521f 503 {
7bfd842d 504 if (width_remaining < 2)
961c521f
NC
505 break;
506
7bfd842d
NC
507 printf ("^%c", c + 0x40);
508 width_remaining -= 2;
171191ba 509 num_printed += 2;
961c521f 510 }
7bfd842d
NC
511 else if (ISPRINT (c))
512 {
513 putchar (c);
514 width_remaining --;
515 num_printed ++;
516 }
961c521f
NC
517 else
518 {
3bfcb652
NC
519#ifdef HAVE_MBSTATE_T
520 wchar_t w;
521#endif
7bfd842d
NC
522 /* Let printf do the hard work of displaying multibyte characters. */
523 printf ("%.1s", symbol - 1);
524 width_remaining --;
525 num_printed ++;
526
3bfcb652 527#ifdef HAVE_MBSTATE_T
7bfd842d
NC
528 /* Try to find out how many bytes made up the character that was
529 just printed. Advance the symbol pointer past the bytes that
530 were displayed. */
531 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
532#else
533 n = 1;
534#endif
7bfd842d
NC
535 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
536 symbol += (n - 1);
961c521f 537 }
961c521f 538 }
171191ba 539
7bfd842d 540 if (extra_padding && num_printed < width)
171191ba
NC
541 {
542 /* Fill in the remaining spaces. */
7bfd842d
NC
543 printf ("%-*s", width - num_printed, " ");
544 num_printed = width;
171191ba
NC
545 }
546
547 return num_printed;
31104126
NC
548}
549
74e1a04b
NC
550/* Returns a pointer to a static buffer containing a printable version of
551 the given section's name. Like print_symbol, except that it does not try
552 to print multibyte characters, it just interprets them as hex values. */
553
554static const char *
555printable_section_name (Elf_Internal_Shdr * sec)
556{
557#define MAX_PRINT_SEC_NAME_LEN 128
558 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
559 const char * name = SECTION_NAME (sec);
560 char * buf = sec_name_buf;
561 char c;
562 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
563
564 while ((c = * name ++) != 0)
565 {
566 if (ISCNTRL (c))
567 {
568 if (remaining < 2)
569 break;
948f632f 570
74e1a04b
NC
571 * buf ++ = '^';
572 * buf ++ = c + 0x40;
573 remaining -= 2;
574 }
575 else if (ISPRINT (c))
576 {
577 * buf ++ = c;
578 remaining -= 1;
579 }
580 else
581 {
582 static char hex[17] = "0123456789ABCDEF";
583
584 if (remaining < 4)
585 break;
586 * buf ++ = '<';
587 * buf ++ = hex[(c & 0xf0) >> 4];
588 * buf ++ = hex[c & 0x0f];
589 * buf ++ = '>';
590 remaining -= 4;
591 }
592
593 if (remaining == 0)
594 break;
595 }
596
597 * buf = 0;
598 return sec_name_buf;
599}
600
601static const char *
602printable_section_name_from_index (unsigned long ndx)
603{
604 if (ndx >= elf_header.e_shnum)
605 return _("<corrupt>");
606
607 return printable_section_name (section_headers + ndx);
608}
609
89fac5e3
RS
610/* Return a pointer to section NAME, or NULL if no such section exists. */
611
612static Elf_Internal_Shdr *
2cf0635d 613find_section (const char * name)
89fac5e3
RS
614{
615 unsigned int i;
616
617 for (i = 0; i < elf_header.e_shnum; i++)
618 if (streq (SECTION_NAME (section_headers + i), name))
619 return section_headers + i;
620
621 return NULL;
622}
623
0b6ae522
DJ
624/* Return a pointer to a section containing ADDR, or NULL if no such
625 section exists. */
626
627static Elf_Internal_Shdr *
628find_section_by_address (bfd_vma addr)
629{
630 unsigned int i;
631
632 for (i = 0; i < elf_header.e_shnum; i++)
633 {
634 Elf_Internal_Shdr *sec = section_headers + i;
635 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
636 return sec;
637 }
638
639 return NULL;
640}
641
071436c6
NC
642static Elf_Internal_Shdr *
643find_section_by_type (unsigned int type)
644{
645 unsigned int i;
646
647 for (i = 0; i < elf_header.e_shnum; i++)
648 {
649 Elf_Internal_Shdr *sec = section_headers + i;
650 if (sec->sh_type == type)
651 return sec;
652 }
653
654 return NULL;
655}
656
657d0d47
CC
657/* Return a pointer to section NAME, or NULL if no such section exists,
658 restricted to the list of sections given in SET. */
659
660static Elf_Internal_Shdr *
661find_section_in_set (const char * name, unsigned int * set)
662{
663 unsigned int i;
664
665 if (set != NULL)
666 {
667 while ((i = *set++) > 0)
668 if (streq (SECTION_NAME (section_headers + i), name))
669 return section_headers + i;
670 }
671
672 return find_section (name);
673}
674
0b6ae522
DJ
675/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
676 bytes read. */
677
f6f0e17b
NC
678static inline unsigned long
679read_uleb128 (unsigned char *data,
680 unsigned int *length_return,
681 const unsigned char * const end)
0b6ae522 682{
f6f0e17b 683 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
684}
685
28f997cf
TG
686/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
687 This OS has so many departures from the ELF standard that we test it at
688 many places. */
689
690static inline int
691is_ia64_vms (void)
692{
693 return elf_header.e_machine == EM_IA_64
694 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
695}
696
bcedfee6 697/* Guess the relocation size commonly used by the specific machines. */
252b5132 698
252b5132 699static int
2dc4cec1 700guess_is_rela (unsigned int e_machine)
252b5132 701{
9c19a809 702 switch (e_machine)
252b5132
RH
703 {
704 /* Targets that use REL relocations. */
252b5132
RH
705 case EM_386:
706 case EM_486:
63fcb9e9 707 case EM_960:
e9f53129 708 case EM_ARM:
2b0337b0 709 case EM_D10V:
252b5132 710 case EM_CYGNUS_D10V:
e9f53129 711 case EM_DLX:
252b5132 712 case EM_MIPS:
4fe85591 713 case EM_MIPS_RS3_LE:
e9f53129 714 case EM_CYGNUS_M32R:
1c0d3aa6 715 case EM_SCORE:
f6c1a2d5 716 case EM_XGATE:
9c19a809 717 return FALSE;
103f02d3 718
252b5132
RH
719 /* Targets that use RELA relocations. */
720 case EM_68K:
e9f53129 721 case EM_860:
a06ea964 722 case EM_AARCH64:
cfb8c092 723 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
724 case EM_ALPHA:
725 case EM_ALTERA_NIOS2:
726 case EM_AVR:
727 case EM_AVR_OLD:
728 case EM_BLACKFIN:
60bca95a 729 case EM_CR16:
e9f53129
AM
730 case EM_CRIS:
731 case EM_CRX:
2b0337b0 732 case EM_D30V:
252b5132 733 case EM_CYGNUS_D30V:
2b0337b0 734 case EM_FR30:
3f8107ab 735 case EM_FT32:
252b5132 736 case EM_CYGNUS_FR30:
5c70f934 737 case EM_CYGNUS_FRV:
e9f53129
AM
738 case EM_H8S:
739 case EM_H8_300:
740 case EM_H8_300H:
800eeca4 741 case EM_IA_64:
1e4cf259
NC
742 case EM_IP2K:
743 case EM_IP2K_OLD:
3b36097d 744 case EM_IQ2000:
84e94c90 745 case EM_LATTICEMICO32:
ff7eeb89 746 case EM_M32C_OLD:
49f58d10 747 case EM_M32C:
e9f53129
AM
748 case EM_M32R:
749 case EM_MCORE:
15ab5209 750 case EM_CYGNUS_MEP:
a3c62988 751 case EM_METAG:
e9f53129
AM
752 case EM_MMIX:
753 case EM_MN10200:
754 case EM_CYGNUS_MN10200:
755 case EM_MN10300:
756 case EM_CYGNUS_MN10300:
5506d11a 757 case EM_MOXIE:
e9f53129
AM
758 case EM_MSP430:
759 case EM_MSP430_OLD:
d031aafb 760 case EM_MT:
35c08157 761 case EM_NDS32:
64fd6348 762 case EM_NIOS32:
73589c9d 763 case EM_OR1K:
e9f53129
AM
764 case EM_PPC64:
765 case EM_PPC:
99c513f6 766 case EM_RL78:
c7927a3c 767 case EM_RX:
e9f53129
AM
768 case EM_S390:
769 case EM_S390_OLD:
770 case EM_SH:
771 case EM_SPARC:
772 case EM_SPARC32PLUS:
773 case EM_SPARCV9:
774 case EM_SPU:
40b36596 775 case EM_TI_C6000:
aa137e4d
NC
776 case EM_TILEGX:
777 case EM_TILEPRO:
708e2187 778 case EM_V800:
e9f53129
AM
779 case EM_V850:
780 case EM_CYGNUS_V850:
781 case EM_VAX:
619ed720 782 case EM_VISIUM:
e9f53129 783 case EM_X86_64:
8a9036a4 784 case EM_L1OM:
7a9068fe 785 case EM_K1OM:
e9f53129
AM
786 case EM_XSTORMY16:
787 case EM_XTENSA:
788 case EM_XTENSA_OLD:
7ba29e2a
NC
789 case EM_MICROBLAZE:
790 case EM_MICROBLAZE_OLD:
9c19a809 791 return TRUE;
103f02d3 792
e9f53129
AM
793 case EM_68HC05:
794 case EM_68HC08:
795 case EM_68HC11:
796 case EM_68HC16:
797 case EM_FX66:
798 case EM_ME16:
d1133906 799 case EM_MMA:
d1133906
NC
800 case EM_NCPU:
801 case EM_NDR1:
e9f53129 802 case EM_PCP:
d1133906 803 case EM_ST100:
e9f53129 804 case EM_ST19:
d1133906 805 case EM_ST7:
e9f53129
AM
806 case EM_ST9PLUS:
807 case EM_STARCORE:
d1133906 808 case EM_SVX:
e9f53129 809 case EM_TINYJ:
9c19a809
NC
810 default:
811 warn (_("Don't know about relocations on this machine architecture\n"));
812 return FALSE;
813 }
814}
252b5132 815
9c19a809 816static int
2cf0635d 817slurp_rela_relocs (FILE * file,
d3ba0551
AM
818 unsigned long rel_offset,
819 unsigned long rel_size,
2cf0635d
NC
820 Elf_Internal_Rela ** relasp,
821 unsigned long * nrelasp)
9c19a809 822{
2cf0635d 823 Elf_Internal_Rela * relas;
8b73c356 824 size_t nrelas;
4d6ed7c8 825 unsigned int i;
252b5132 826
4d6ed7c8
NC
827 if (is_32bit_elf)
828 {
2cf0635d 829 Elf32_External_Rela * erelas;
103f02d3 830
3f5e193b 831 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 832 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
833 if (!erelas)
834 return 0;
252b5132 835
4d6ed7c8 836 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 837
3f5e193b
NC
838 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
839 sizeof (Elf_Internal_Rela));
103f02d3 840
4d6ed7c8
NC
841 if (relas == NULL)
842 {
c256ffe7 843 free (erelas);
591a748a 844 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
845 return 0;
846 }
103f02d3 847
4d6ed7c8
NC
848 for (i = 0; i < nrelas; i++)
849 {
850 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
851 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 852 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 853 }
103f02d3 854
4d6ed7c8
NC
855 free (erelas);
856 }
857 else
858 {
2cf0635d 859 Elf64_External_Rela * erelas;
103f02d3 860
3f5e193b 861 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 862 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
863 if (!erelas)
864 return 0;
4d6ed7c8
NC
865
866 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 867
3f5e193b
NC
868 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
869 sizeof (Elf_Internal_Rela));
103f02d3 870
4d6ed7c8
NC
871 if (relas == NULL)
872 {
c256ffe7 873 free (erelas);
591a748a 874 error (_("out of memory parsing relocs\n"));
4d6ed7c8 875 return 0;
9c19a809 876 }
4d6ed7c8
NC
877
878 for (i = 0; i < nrelas; i++)
9c19a809 879 {
66543521
AM
880 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
881 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 882 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
883
884 /* The #ifdef BFD64 below is to prevent a compile time
885 warning. We know that if we do not have a 64 bit data
886 type that we will never execute this code anyway. */
887#ifdef BFD64
888 if (elf_header.e_machine == EM_MIPS
889 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
890 {
891 /* In little-endian objects, r_info isn't really a
892 64-bit little-endian value: it has a 32-bit
893 little-endian symbol index followed by four
894 individual byte fields. Reorder INFO
895 accordingly. */
91d6fa6a
NC
896 bfd_vma inf = relas[i].r_info;
897 inf = (((inf & 0xffffffff) << 32)
898 | ((inf >> 56) & 0xff)
899 | ((inf >> 40) & 0xff00)
900 | ((inf >> 24) & 0xff0000)
901 | ((inf >> 8) & 0xff000000));
902 relas[i].r_info = inf;
861fb55a
DJ
903 }
904#endif /* BFD64 */
4d6ed7c8 905 }
103f02d3 906
4d6ed7c8
NC
907 free (erelas);
908 }
909 *relasp = relas;
910 *nrelasp = nrelas;
911 return 1;
912}
103f02d3 913
4d6ed7c8 914static int
2cf0635d 915slurp_rel_relocs (FILE * file,
d3ba0551
AM
916 unsigned long rel_offset,
917 unsigned long rel_size,
2cf0635d
NC
918 Elf_Internal_Rela ** relsp,
919 unsigned long * nrelsp)
4d6ed7c8 920{
2cf0635d 921 Elf_Internal_Rela * rels;
8b73c356 922 size_t nrels;
4d6ed7c8 923 unsigned int i;
103f02d3 924
4d6ed7c8
NC
925 if (is_32bit_elf)
926 {
2cf0635d 927 Elf32_External_Rel * erels;
103f02d3 928
3f5e193b 929 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 930 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
931 if (!erels)
932 return 0;
103f02d3 933
4d6ed7c8 934 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 935
3f5e193b 936 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 937
4d6ed7c8
NC
938 if (rels == NULL)
939 {
c256ffe7 940 free (erels);
591a748a 941 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
942 return 0;
943 }
944
945 for (i = 0; i < nrels; i++)
946 {
947 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
948 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 949 rels[i].r_addend = 0;
9ea033b2 950 }
4d6ed7c8
NC
951
952 free (erels);
9c19a809
NC
953 }
954 else
955 {
2cf0635d 956 Elf64_External_Rel * erels;
9ea033b2 957
3f5e193b 958 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 959 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
960 if (!erels)
961 return 0;
103f02d3 962
4d6ed7c8 963 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 964
3f5e193b 965 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 966
4d6ed7c8 967 if (rels == NULL)
9c19a809 968 {
c256ffe7 969 free (erels);
591a748a 970 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
971 return 0;
972 }
103f02d3 973
4d6ed7c8
NC
974 for (i = 0; i < nrels; i++)
975 {
66543521
AM
976 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
977 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 978 rels[i].r_addend = 0;
861fb55a
DJ
979
980 /* The #ifdef BFD64 below is to prevent a compile time
981 warning. We know that if we do not have a 64 bit data
982 type that we will never execute this code anyway. */
983#ifdef BFD64
984 if (elf_header.e_machine == EM_MIPS
985 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
986 {
987 /* In little-endian objects, r_info isn't really a
988 64-bit little-endian value: it has a 32-bit
989 little-endian symbol index followed by four
990 individual byte fields. Reorder INFO
991 accordingly. */
91d6fa6a
NC
992 bfd_vma inf = rels[i].r_info;
993 inf = (((inf & 0xffffffff) << 32)
994 | ((inf >> 56) & 0xff)
995 | ((inf >> 40) & 0xff00)
996 | ((inf >> 24) & 0xff0000)
997 | ((inf >> 8) & 0xff000000));
998 rels[i].r_info = inf;
861fb55a
DJ
999 }
1000#endif /* BFD64 */
4d6ed7c8 1001 }
103f02d3 1002
4d6ed7c8
NC
1003 free (erels);
1004 }
1005 *relsp = rels;
1006 *nrelsp = nrels;
1007 return 1;
1008}
103f02d3 1009
aca88567
NC
1010/* Returns the reloc type extracted from the reloc info field. */
1011
1012static unsigned int
1013get_reloc_type (bfd_vma reloc_info)
1014{
1015 if (is_32bit_elf)
1016 return ELF32_R_TYPE (reloc_info);
1017
1018 switch (elf_header.e_machine)
1019 {
1020 case EM_MIPS:
1021 /* Note: We assume that reloc_info has already been adjusted for us. */
1022 return ELF64_MIPS_R_TYPE (reloc_info);
1023
1024 case EM_SPARCV9:
1025 return ELF64_R_TYPE_ID (reloc_info);
1026
1027 default:
1028 return ELF64_R_TYPE (reloc_info);
1029 }
1030}
1031
1032/* Return the symbol index extracted from the reloc info field. */
1033
1034static bfd_vma
1035get_reloc_symindex (bfd_vma reloc_info)
1036{
1037 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1038}
1039
13761a11
NC
1040static inline bfd_boolean
1041uses_msp430x_relocs (void)
1042{
1043 return
1044 elf_header.e_machine == EM_MSP430 /* Paranoia. */
1045 /* GCC uses osabi == ELFOSBI_STANDALONE. */
1046 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
1047 /* TI compiler uses ELFOSABI_NONE. */
1048 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
1049}
1050
d3ba0551
AM
1051/* Display the contents of the relocation data found at the specified
1052 offset. */
ee42cf8c 1053
41e92641 1054static void
2cf0635d 1055dump_relocations (FILE * file,
d3ba0551
AM
1056 unsigned long rel_offset,
1057 unsigned long rel_size,
2cf0635d 1058 Elf_Internal_Sym * symtab,
d3ba0551 1059 unsigned long nsyms,
2cf0635d 1060 char * strtab,
d79b3d50 1061 unsigned long strtablen,
bb4d2ac2
L
1062 int is_rela,
1063 int is_dynsym)
4d6ed7c8 1064{
b34976b6 1065 unsigned int i;
2cf0635d 1066 Elf_Internal_Rela * rels;
103f02d3 1067
4d6ed7c8
NC
1068 if (is_rela == UNKNOWN)
1069 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 1070
4d6ed7c8
NC
1071 if (is_rela)
1072 {
c8286bd1 1073 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1074 return;
4d6ed7c8
NC
1075 }
1076 else
1077 {
1078 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1079 return;
252b5132
RH
1080 }
1081
410f7a12
L
1082 if (is_32bit_elf)
1083 {
1084 if (is_rela)
2c71103e
NC
1085 {
1086 if (do_wide)
1087 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1088 else
1089 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1090 }
410f7a12 1091 else
2c71103e
NC
1092 {
1093 if (do_wide)
1094 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1095 else
1096 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1097 }
410f7a12 1098 }
252b5132 1099 else
410f7a12
L
1100 {
1101 if (is_rela)
2c71103e
NC
1102 {
1103 if (do_wide)
8beeaeb7 1104 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1105 else
1106 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1107 }
410f7a12 1108 else
2c71103e
NC
1109 {
1110 if (do_wide)
8beeaeb7 1111 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1112 else
1113 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1114 }
410f7a12 1115 }
252b5132
RH
1116
1117 for (i = 0; i < rel_size; i++)
1118 {
2cf0635d 1119 const char * rtype;
b34976b6 1120 bfd_vma offset;
91d6fa6a 1121 bfd_vma inf;
b34976b6
AM
1122 bfd_vma symtab_index;
1123 bfd_vma type;
103f02d3 1124
b34976b6 1125 offset = rels[i].r_offset;
91d6fa6a 1126 inf = rels[i].r_info;
103f02d3 1127
91d6fa6a
NC
1128 type = get_reloc_type (inf);
1129 symtab_index = get_reloc_symindex (inf);
252b5132 1130
410f7a12
L
1131 if (is_32bit_elf)
1132 {
39dbeff8
AM
1133 printf ("%8.8lx %8.8lx ",
1134 (unsigned long) offset & 0xffffffff,
91d6fa6a 1135 (unsigned long) inf & 0xffffffff);
410f7a12
L
1136 }
1137 else
1138 {
39dbeff8
AM
1139#if BFD_HOST_64BIT_LONG
1140 printf (do_wide
1141 ? "%16.16lx %16.16lx "
1142 : "%12.12lx %12.12lx ",
91d6fa6a 1143 offset, inf);
39dbeff8 1144#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1145#ifndef __MSVCRT__
39dbeff8
AM
1146 printf (do_wide
1147 ? "%16.16llx %16.16llx "
1148 : "%12.12llx %12.12llx ",
91d6fa6a 1149 offset, inf);
6e3d6dc1
NC
1150#else
1151 printf (do_wide
1152 ? "%16.16I64x %16.16I64x "
1153 : "%12.12I64x %12.12I64x ",
91d6fa6a 1154 offset, inf);
6e3d6dc1 1155#endif
39dbeff8 1156#else
2c71103e
NC
1157 printf (do_wide
1158 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1159 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1160 _bfd_int64_high (offset),
1161 _bfd_int64_low (offset),
91d6fa6a
NC
1162 _bfd_int64_high (inf),
1163 _bfd_int64_low (inf));
9ea033b2 1164#endif
410f7a12 1165 }
103f02d3 1166
252b5132
RH
1167 switch (elf_header.e_machine)
1168 {
1169 default:
1170 rtype = NULL;
1171 break;
1172
a06ea964
NC
1173 case EM_AARCH64:
1174 rtype = elf_aarch64_reloc_type (type);
1175 break;
1176
2b0337b0 1177 case EM_M32R:
252b5132 1178 case EM_CYGNUS_M32R:
9ea033b2 1179 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1180 break;
1181
1182 case EM_386:
1183 case EM_486:
9ea033b2 1184 rtype = elf_i386_reloc_type (type);
252b5132
RH
1185 break;
1186
ba2685cc
AM
1187 case EM_68HC11:
1188 case EM_68HC12:
1189 rtype = elf_m68hc11_reloc_type (type);
1190 break;
75751cd9 1191
252b5132 1192 case EM_68K:
9ea033b2 1193 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1194 break;
1195
63fcb9e9 1196 case EM_960:
9ea033b2 1197 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1198 break;
1199
adde6300 1200 case EM_AVR:
2b0337b0 1201 case EM_AVR_OLD:
adde6300
AM
1202 rtype = elf_avr_reloc_type (type);
1203 break;
1204
9ea033b2
NC
1205 case EM_OLD_SPARCV9:
1206 case EM_SPARC32PLUS:
1207 case EM_SPARCV9:
252b5132 1208 case EM_SPARC:
9ea033b2 1209 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1210 break;
1211
e9f53129
AM
1212 case EM_SPU:
1213 rtype = elf_spu_reloc_type (type);
1214 break;
1215
708e2187
NC
1216 case EM_V800:
1217 rtype = v800_reloc_type (type);
1218 break;
2b0337b0 1219 case EM_V850:
252b5132 1220 case EM_CYGNUS_V850:
9ea033b2 1221 rtype = v850_reloc_type (type);
252b5132
RH
1222 break;
1223
2b0337b0 1224 case EM_D10V:
252b5132 1225 case EM_CYGNUS_D10V:
9ea033b2 1226 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1227 break;
1228
2b0337b0 1229 case EM_D30V:
252b5132 1230 case EM_CYGNUS_D30V:
9ea033b2 1231 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1232 break;
1233
d172d4ba
NC
1234 case EM_DLX:
1235 rtype = elf_dlx_reloc_type (type);
1236 break;
1237
252b5132 1238 case EM_SH:
9ea033b2 1239 rtype = elf_sh_reloc_type (type);
252b5132
RH
1240 break;
1241
2b0337b0 1242 case EM_MN10300:
252b5132 1243 case EM_CYGNUS_MN10300:
9ea033b2 1244 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1245 break;
1246
2b0337b0 1247 case EM_MN10200:
252b5132 1248 case EM_CYGNUS_MN10200:
9ea033b2 1249 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1250 break;
1251
2b0337b0 1252 case EM_FR30:
252b5132 1253 case EM_CYGNUS_FR30:
9ea033b2 1254 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1255 break;
1256
ba2685cc
AM
1257 case EM_CYGNUS_FRV:
1258 rtype = elf_frv_reloc_type (type);
1259 break;
5c70f934 1260
3f8107ab
AM
1261 case EM_FT32:
1262 rtype = elf_ft32_reloc_type (type);
1263 break;
1264
252b5132 1265 case EM_MCORE:
9ea033b2 1266 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1267 break;
1268
3c3bdf30
NC
1269 case EM_MMIX:
1270 rtype = elf_mmix_reloc_type (type);
1271 break;
1272
5506d11a
AM
1273 case EM_MOXIE:
1274 rtype = elf_moxie_reloc_type (type);
1275 break;
1276
2469cfa2 1277 case EM_MSP430:
13761a11
NC
1278 if (uses_msp430x_relocs ())
1279 {
1280 rtype = elf_msp430x_reloc_type (type);
1281 break;
1282 }
2469cfa2
NC
1283 case EM_MSP430_OLD:
1284 rtype = elf_msp430_reloc_type (type);
1285 break;
1286
35c08157
KLC
1287 case EM_NDS32:
1288 rtype = elf_nds32_reloc_type (type);
1289 break;
1290
252b5132 1291 case EM_PPC:
9ea033b2 1292 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1293 break;
1294
c833c019
AM
1295 case EM_PPC64:
1296 rtype = elf_ppc64_reloc_type (type);
1297 break;
1298
252b5132 1299 case EM_MIPS:
4fe85591 1300 case EM_MIPS_RS3_LE:
9ea033b2 1301 rtype = elf_mips_reloc_type (type);
252b5132
RH
1302 break;
1303
1304 case EM_ALPHA:
9ea033b2 1305 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1306 break;
1307
1308 case EM_ARM:
9ea033b2 1309 rtype = elf_arm_reloc_type (type);
252b5132
RH
1310 break;
1311
584da044 1312 case EM_ARC:
9ea033b2 1313 rtype = elf_arc_reloc_type (type);
252b5132
RH
1314 break;
1315
1316 case EM_PARISC:
69e617ca 1317 rtype = elf_hppa_reloc_type (type);
252b5132 1318 break;
7d466069 1319
b8720f9d
JL
1320 case EM_H8_300:
1321 case EM_H8_300H:
1322 case EM_H8S:
1323 rtype = elf_h8_reloc_type (type);
1324 break;
1325
73589c9d
CS
1326 case EM_OR1K:
1327 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1328 break;
1329
7d466069 1330 case EM_PJ:
2b0337b0 1331 case EM_PJ_OLD:
7d466069
ILT
1332 rtype = elf_pj_reloc_type (type);
1333 break;
800eeca4
JW
1334 case EM_IA_64:
1335 rtype = elf_ia64_reloc_type (type);
1336 break;
1b61cf92
HPN
1337
1338 case EM_CRIS:
1339 rtype = elf_cris_reloc_type (type);
1340 break;
535c37ff
JE
1341
1342 case EM_860:
1343 rtype = elf_i860_reloc_type (type);
1344 break;
bcedfee6
NC
1345
1346 case EM_X86_64:
8a9036a4 1347 case EM_L1OM:
7a9068fe 1348 case EM_K1OM:
bcedfee6
NC
1349 rtype = elf_x86_64_reloc_type (type);
1350 break;
a85d7ed0 1351
35b1837e
AM
1352 case EM_S370:
1353 rtype = i370_reloc_type (type);
1354 break;
1355
53c7db4b
KH
1356 case EM_S390_OLD:
1357 case EM_S390:
1358 rtype = elf_s390_reloc_type (type);
1359 break;
93fbbb04 1360
1c0d3aa6
NC
1361 case EM_SCORE:
1362 rtype = elf_score_reloc_type (type);
1363 break;
1364
93fbbb04
GK
1365 case EM_XSTORMY16:
1366 rtype = elf_xstormy16_reloc_type (type);
1367 break;
179d3252 1368
1fe1f39c
NC
1369 case EM_CRX:
1370 rtype = elf_crx_reloc_type (type);
1371 break;
1372
179d3252
JT
1373 case EM_VAX:
1374 rtype = elf_vax_reloc_type (type);
1375 break;
1e4cf259 1376
619ed720
EB
1377 case EM_VISIUM:
1378 rtype = elf_visium_reloc_type (type);
1379 break;
1380
cfb8c092
NC
1381 case EM_ADAPTEVA_EPIPHANY:
1382 rtype = elf_epiphany_reloc_type (type);
1383 break;
1384
1e4cf259
NC
1385 case EM_IP2K:
1386 case EM_IP2K_OLD:
1387 rtype = elf_ip2k_reloc_type (type);
1388 break;
3b36097d
SC
1389
1390 case EM_IQ2000:
1391 rtype = elf_iq2000_reloc_type (type);
1392 break;
88da6820
NC
1393
1394 case EM_XTENSA_OLD:
1395 case EM_XTENSA:
1396 rtype = elf_xtensa_reloc_type (type);
1397 break;
a34e3ecb 1398
84e94c90
NC
1399 case EM_LATTICEMICO32:
1400 rtype = elf_lm32_reloc_type (type);
1401 break;
1402
ff7eeb89 1403 case EM_M32C_OLD:
49f58d10
JB
1404 case EM_M32C:
1405 rtype = elf_m32c_reloc_type (type);
1406 break;
1407
d031aafb
NS
1408 case EM_MT:
1409 rtype = elf_mt_reloc_type (type);
a34e3ecb 1410 break;
1d65ded4
CM
1411
1412 case EM_BLACKFIN:
1413 rtype = elf_bfin_reloc_type (type);
1414 break;
15ab5209
DB
1415
1416 case EM_CYGNUS_MEP:
1417 rtype = elf_mep_reloc_type (type);
1418 break;
60bca95a
NC
1419
1420 case EM_CR16:
1421 rtype = elf_cr16_reloc_type (type);
1422 break;
dd24e3da 1423
7ba29e2a
NC
1424 case EM_MICROBLAZE:
1425 case EM_MICROBLAZE_OLD:
1426 rtype = elf_microblaze_reloc_type (type);
1427 break;
c7927a3c 1428
99c513f6
DD
1429 case EM_RL78:
1430 rtype = elf_rl78_reloc_type (type);
1431 break;
1432
c7927a3c
NC
1433 case EM_RX:
1434 rtype = elf_rx_reloc_type (type);
1435 break;
c29aca4a 1436
a3c62988
NC
1437 case EM_METAG:
1438 rtype = elf_metag_reloc_type (type);
1439 break;
1440
c29aca4a
NC
1441 case EM_XC16X:
1442 case EM_C166:
1443 rtype = elf_xc16x_reloc_type (type);
1444 break;
40b36596
JM
1445
1446 case EM_TI_C6000:
1447 rtype = elf_tic6x_reloc_type (type);
1448 break;
aa137e4d
NC
1449
1450 case EM_TILEGX:
1451 rtype = elf_tilegx_reloc_type (type);
1452 break;
1453
1454 case EM_TILEPRO:
1455 rtype = elf_tilepro_reloc_type (type);
1456 break;
f6c1a2d5
NC
1457
1458 case EM_XGATE:
1459 rtype = elf_xgate_reloc_type (type);
1460 break;
36591ba1
SL
1461
1462 case EM_ALTERA_NIOS2:
1463 rtype = elf_nios2_reloc_type (type);
1464 break;
252b5132
RH
1465 }
1466
1467 if (rtype == NULL)
39dbeff8 1468 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1469 else
8beeaeb7 1470 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1471
7ace3541 1472 if (elf_header.e_machine == EM_ALPHA
157c2599 1473 && rtype != NULL
7ace3541
RH
1474 && streq (rtype, "R_ALPHA_LITUSE")
1475 && is_rela)
1476 {
1477 switch (rels[i].r_addend)
1478 {
1479 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1480 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1481 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1482 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1483 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1484 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1485 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1486 default: rtype = NULL;
1487 }
1488 if (rtype)
1489 printf (" (%s)", rtype);
1490 else
1491 {
1492 putchar (' ');
1493 printf (_("<unknown addend: %lx>"),
1494 (unsigned long) rels[i].r_addend);
1495 }
1496 }
1497 else if (symtab_index)
252b5132 1498 {
af3fc3bc 1499 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1500 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1501 else
19936277 1502 {
2cf0635d 1503 Elf_Internal_Sym * psym;
bb4d2ac2
L
1504 const char * version_string;
1505 enum versioned_symbol_info sym_info;
1506 unsigned short vna_other;
19936277 1507
af3fc3bc 1508 psym = symtab + symtab_index;
103f02d3 1509
bb4d2ac2
L
1510 version_string
1511 = get_symbol_version_string (file, is_dynsym,
1512 strtab, strtablen,
1513 symtab_index,
1514 psym,
1515 &sym_info,
1516 &vna_other);
1517
af3fc3bc 1518 printf (" ");
171191ba 1519
d8045f23
NC
1520 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1521 {
1522 const char * name;
1523 unsigned int len;
1524 unsigned int width = is_32bit_elf ? 8 : 14;
1525
1526 /* Relocations against GNU_IFUNC symbols do not use the value
1527 of the symbol as the address to relocate against. Instead
1528 they invoke the function named by the symbol and use its
1529 result as the address for relocation.
1530
1531 To indicate this to the user, do not display the value of
1532 the symbol in the "Symbols's Value" field. Instead show
1533 its name followed by () as a hint that the symbol is
1534 invoked. */
1535
1536 if (strtab == NULL
1537 || psym->st_name == 0
1538 || psym->st_name >= strtablen)
1539 name = "??";
1540 else
1541 name = strtab + psym->st_name;
1542
1543 len = print_symbol (width, name);
bb4d2ac2
L
1544 if (version_string)
1545 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1546 version_string);
d8045f23
NC
1547 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1548 }
1549 else
1550 {
1551 print_vma (psym->st_value, LONG_HEX);
171191ba 1552
d8045f23
NC
1553 printf (is_32bit_elf ? " " : " ");
1554 }
103f02d3 1555
af3fc3bc 1556 if (psym->st_name == 0)
f1ef08cb 1557 {
2cf0635d 1558 const char * sec_name = "<null>";
f1ef08cb
AM
1559 char name_buf[40];
1560
1561 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1562 {
4fbb74a6 1563 if (psym->st_shndx < elf_header.e_shnum)
74e1a04b 1564 sec_name = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1565 else if (psym->st_shndx == SHN_ABS)
1566 sec_name = "ABS";
1567 else if (psym->st_shndx == SHN_COMMON)
1568 sec_name = "COMMON";
ac145307
BS
1569 else if ((elf_header.e_machine == EM_MIPS
1570 && psym->st_shndx == SHN_MIPS_SCOMMON)
1571 || (elf_header.e_machine == EM_TI_C6000
1572 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1573 sec_name = "SCOMMON";
1574 else if (elf_header.e_machine == EM_MIPS
1575 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1576 sec_name = "SUNDEF";
8a9036a4 1577 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1578 || elf_header.e_machine == EM_L1OM
1579 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1580 && psym->st_shndx == SHN_X86_64_LCOMMON)
1581 sec_name = "LARGE_COMMON";
9ce701e2
L
1582 else if (elf_header.e_machine == EM_IA_64
1583 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1584 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1585 sec_name = "ANSI_COM";
28f997cf 1586 else if (is_ia64_vms ()
148b93f2
NC
1587 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1588 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1589 else
1590 {
1591 sprintf (name_buf, "<section 0x%x>",
1592 (unsigned int) psym->st_shndx);
1593 sec_name = name_buf;
1594 }
1595 }
1596 print_symbol (22, sec_name);
1597 }
af3fc3bc 1598 else if (strtab == NULL)
d79b3d50 1599 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1600 else if (psym->st_name >= strtablen)
d79b3d50 1601 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1602 else
bb4d2ac2
L
1603 {
1604 print_symbol (22, strtab + psym->st_name);
1605 if (version_string)
1606 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1607 version_string);
1608 }
103f02d3 1609
af3fc3bc 1610 if (is_rela)
171191ba 1611 {
598aaa76 1612 bfd_signed_vma off = rels[i].r_addend;
171191ba 1613
834f871c
NC
1614 /* PR 17531: file: 2e63226f. */
1615 if (off == ((bfd_signed_vma) 1) << ((sizeof (bfd_signed_vma) * 8) - 1))
1616 printf (" + %" BFD_VMA_FMT "x", off);
1617 else if (off < 0)
598aaa76 1618 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1619 else
598aaa76 1620 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1621 }
19936277 1622 }
252b5132 1623 }
1b228002 1624 else if (is_rela)
f7a99963 1625 {
e04d7088
L
1626 bfd_signed_vma off = rels[i].r_addend;
1627
1628 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
834f871c
NC
1629 /* PR 17531: file: 2e63226f. */
1630 if (off == ((bfd_signed_vma) 1) << ((sizeof (bfd_signed_vma) * 8) - 1))
1631 printf ("%" BFD_VMA_FMT "x", off);
1632 else if (off < 0)
e04d7088
L
1633 printf ("-%" BFD_VMA_FMT "x", - off);
1634 else
1635 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1636 }
252b5132 1637
157c2599
NC
1638 if (elf_header.e_machine == EM_SPARCV9
1639 && rtype != NULL
1640 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1641 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1642
252b5132 1643 putchar ('\n');
2c71103e 1644
aca88567 1645#ifdef BFD64
53c7db4b 1646 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1647 {
91d6fa6a
NC
1648 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1649 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1650 const char * rtype2 = elf_mips_reloc_type (type2);
1651 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1652
2c71103e
NC
1653 printf (" Type2: ");
1654
1655 if (rtype2 == NULL)
39dbeff8
AM
1656 printf (_("unrecognized: %-7lx"),
1657 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1658 else
1659 printf ("%-17.17s", rtype2);
1660
18bd398b 1661 printf ("\n Type3: ");
2c71103e
NC
1662
1663 if (rtype3 == NULL)
39dbeff8
AM
1664 printf (_("unrecognized: %-7lx"),
1665 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1666 else
1667 printf ("%-17.17s", rtype3);
1668
53c7db4b 1669 putchar ('\n');
2c71103e 1670 }
aca88567 1671#endif /* BFD64 */
252b5132
RH
1672 }
1673
c8286bd1 1674 free (rels);
252b5132
RH
1675}
1676
1677static const char *
d3ba0551 1678get_mips_dynamic_type (unsigned long type)
252b5132
RH
1679{
1680 switch (type)
1681 {
1682 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1683 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1684 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1685 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1686 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1687 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1688 case DT_MIPS_MSYM: return "MIPS_MSYM";
1689 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1690 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1691 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1692 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1693 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1694 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1695 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1696 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1697 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1698 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1699 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1700 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1701 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1702 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1703 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1704 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1705 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1706 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1707 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1708 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1709 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1710 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1711 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1712 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1713 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1714 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1715 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1716 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1717 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1718 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1719 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1720 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1721 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1722 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1723 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1724 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1725 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1726 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1727 default:
1728 return NULL;
1729 }
1730}
1731
9a097730 1732static const char *
d3ba0551 1733get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1734{
1735 switch (type)
1736 {
1737 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1738 default:
1739 return NULL;
1740 }
103f02d3
UD
1741}
1742
7490d522
AM
1743static const char *
1744get_ppc_dynamic_type (unsigned long type)
1745{
1746 switch (type)
1747 {
a7f2871e 1748 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1749 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1750 default:
1751 return NULL;
1752 }
1753}
1754
f1cb7e17 1755static const char *
d3ba0551 1756get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1757{
1758 switch (type)
1759 {
a7f2871e
AM
1760 case DT_PPC64_GLINK: return "PPC64_GLINK";
1761 case DT_PPC64_OPD: return "PPC64_OPD";
1762 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1763 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1764 default:
1765 return NULL;
1766 }
1767}
1768
103f02d3 1769static const char *
d3ba0551 1770get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1771{
1772 switch (type)
1773 {
1774 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1775 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1776 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1777 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1778 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1779 case DT_HP_PREINIT: return "HP_PREINIT";
1780 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1781 case DT_HP_NEEDED: return "HP_NEEDED";
1782 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1783 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1784 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1785 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1786 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1787 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1788 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1789 case DT_HP_FILTERED: return "HP_FILTERED";
1790 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1791 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1792 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1793 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1794 case DT_PLT: return "PLT";
1795 case DT_PLT_SIZE: return "PLT_SIZE";
1796 case DT_DLT: return "DLT";
1797 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1798 default:
1799 return NULL;
1800 }
1801}
9a097730 1802
ecc51f48 1803static const char *
d3ba0551 1804get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1805{
1806 switch (type)
1807 {
148b93f2
NC
1808 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1809 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1810 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1811 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1812 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1813 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1814 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1815 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1816 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1817 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1818 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1819 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1820 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1821 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1822 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1823 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1824 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1825 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1826 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1827 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1828 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1829 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1830 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1831 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1832 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1833 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1834 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1835 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1836 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1837 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1838 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1839 default:
1840 return NULL;
1841 }
1842}
1843
fabcb361
RH
1844static const char *
1845get_alpha_dynamic_type (unsigned long type)
1846{
1847 switch (type)
1848 {
1849 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1850 default:
1851 return NULL;
1852 }
1853}
1854
1c0d3aa6
NC
1855static const char *
1856get_score_dynamic_type (unsigned long type)
1857{
1858 switch (type)
1859 {
1860 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1861 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1862 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1863 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1864 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1865 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1866 default:
1867 return NULL;
1868 }
1869}
1870
40b36596
JM
1871static const char *
1872get_tic6x_dynamic_type (unsigned long type)
1873{
1874 switch (type)
1875 {
1876 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1877 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1878 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1879 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1880 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1881 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1882 default:
1883 return NULL;
1884 }
1885}
1c0d3aa6 1886
36591ba1
SL
1887static const char *
1888get_nios2_dynamic_type (unsigned long type)
1889{
1890 switch (type)
1891 {
1892 case DT_NIOS2_GP: return "NIOS2_GP";
1893 default:
1894 return NULL;
1895 }
1896}
1897
252b5132 1898static const char *
d3ba0551 1899get_dynamic_type (unsigned long type)
252b5132 1900{
e9e44622 1901 static char buff[64];
252b5132
RH
1902
1903 switch (type)
1904 {
1905 case DT_NULL: return "NULL";
1906 case DT_NEEDED: return "NEEDED";
1907 case DT_PLTRELSZ: return "PLTRELSZ";
1908 case DT_PLTGOT: return "PLTGOT";
1909 case DT_HASH: return "HASH";
1910 case DT_STRTAB: return "STRTAB";
1911 case DT_SYMTAB: return "SYMTAB";
1912 case DT_RELA: return "RELA";
1913 case DT_RELASZ: return "RELASZ";
1914 case DT_RELAENT: return "RELAENT";
1915 case DT_STRSZ: return "STRSZ";
1916 case DT_SYMENT: return "SYMENT";
1917 case DT_INIT: return "INIT";
1918 case DT_FINI: return "FINI";
1919 case DT_SONAME: return "SONAME";
1920 case DT_RPATH: return "RPATH";
1921 case DT_SYMBOLIC: return "SYMBOLIC";
1922 case DT_REL: return "REL";
1923 case DT_RELSZ: return "RELSZ";
1924 case DT_RELENT: return "RELENT";
1925 case DT_PLTREL: return "PLTREL";
1926 case DT_DEBUG: return "DEBUG";
1927 case DT_TEXTREL: return "TEXTREL";
1928 case DT_JMPREL: return "JMPREL";
1929 case DT_BIND_NOW: return "BIND_NOW";
1930 case DT_INIT_ARRAY: return "INIT_ARRAY";
1931 case DT_FINI_ARRAY: return "FINI_ARRAY";
1932 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1933 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1934 case DT_RUNPATH: return "RUNPATH";
1935 case DT_FLAGS: return "FLAGS";
2d0e6f43 1936
d1133906
NC
1937 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1938 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1939
05107a46 1940 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1941 case DT_PLTPADSZ: return "PLTPADSZ";
1942 case DT_MOVEENT: return "MOVEENT";
1943 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1944 case DT_FEATURE: return "FEATURE";
252b5132
RH
1945 case DT_POSFLAG_1: return "POSFLAG_1";
1946 case DT_SYMINSZ: return "SYMINSZ";
1947 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1948
252b5132 1949 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1950 case DT_CONFIG: return "CONFIG";
1951 case DT_DEPAUDIT: return "DEPAUDIT";
1952 case DT_AUDIT: return "AUDIT";
1953 case DT_PLTPAD: return "PLTPAD";
1954 case DT_MOVETAB: return "MOVETAB";
252b5132 1955 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1956
252b5132 1957 case DT_VERSYM: return "VERSYM";
103f02d3 1958
67a4f2b7
AO
1959 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1960 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1961 case DT_RELACOUNT: return "RELACOUNT";
1962 case DT_RELCOUNT: return "RELCOUNT";
1963 case DT_FLAGS_1: return "FLAGS_1";
1964 case DT_VERDEF: return "VERDEF";
1965 case DT_VERDEFNUM: return "VERDEFNUM";
1966 case DT_VERNEED: return "VERNEED";
1967 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1968
019148e4 1969 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1970 case DT_USED: return "USED";
1971 case DT_FILTER: return "FILTER";
103f02d3 1972
047b2264
JJ
1973 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1974 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1975 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1976 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1977 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1978 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1979
252b5132
RH
1980 default:
1981 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1982 {
2cf0635d 1983 const char * result;
103f02d3 1984
252b5132
RH
1985 switch (elf_header.e_machine)
1986 {
1987 case EM_MIPS:
4fe85591 1988 case EM_MIPS_RS3_LE:
252b5132
RH
1989 result = get_mips_dynamic_type (type);
1990 break;
9a097730
RH
1991 case EM_SPARCV9:
1992 result = get_sparc64_dynamic_type (type);
1993 break;
7490d522
AM
1994 case EM_PPC:
1995 result = get_ppc_dynamic_type (type);
1996 break;
f1cb7e17
AM
1997 case EM_PPC64:
1998 result = get_ppc64_dynamic_type (type);
1999 break;
ecc51f48
NC
2000 case EM_IA_64:
2001 result = get_ia64_dynamic_type (type);
2002 break;
fabcb361
RH
2003 case EM_ALPHA:
2004 result = get_alpha_dynamic_type (type);
2005 break;
1c0d3aa6
NC
2006 case EM_SCORE:
2007 result = get_score_dynamic_type (type);
2008 break;
40b36596
JM
2009 case EM_TI_C6000:
2010 result = get_tic6x_dynamic_type (type);
2011 break;
36591ba1
SL
2012 case EM_ALTERA_NIOS2:
2013 result = get_nios2_dynamic_type (type);
2014 break;
252b5132
RH
2015 default:
2016 result = NULL;
2017 break;
2018 }
2019
2020 if (result != NULL)
2021 return result;
2022
e9e44622 2023 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2024 }
eec8f817
DA
2025 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
2026 || (elf_header.e_machine == EM_PARISC
2027 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2028 {
2cf0635d 2029 const char * result;
103f02d3
UD
2030
2031 switch (elf_header.e_machine)
2032 {
2033 case EM_PARISC:
2034 result = get_parisc_dynamic_type (type);
2035 break;
148b93f2
NC
2036 case EM_IA_64:
2037 result = get_ia64_dynamic_type (type);
2038 break;
103f02d3
UD
2039 default:
2040 result = NULL;
2041 break;
2042 }
2043
2044 if (result != NULL)
2045 return result;
2046
e9e44622
JJ
2047 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2048 type);
103f02d3 2049 }
252b5132 2050 else
e9e44622 2051 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2052
252b5132
RH
2053 return buff;
2054 }
2055}
2056
2057static char *
d3ba0551 2058get_file_type (unsigned e_type)
252b5132 2059{
b34976b6 2060 static char buff[32];
252b5132
RH
2061
2062 switch (e_type)
2063 {
2064 case ET_NONE: return _("NONE (None)");
2065 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
2066 case ET_EXEC: return _("EXEC (Executable file)");
2067 case ET_DYN: return _("DYN (Shared object file)");
2068 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2069
2070 default:
2071 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2072 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2073 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2074 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2075 else
e9e44622 2076 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2077 return buff;
2078 }
2079}
2080
2081static char *
d3ba0551 2082get_machine_name (unsigned e_machine)
252b5132 2083{
b34976b6 2084 static char buff[64]; /* XXX */
252b5132
RH
2085
2086 switch (e_machine)
2087 {
c45021f2 2088 case EM_NONE: return _("None");
a06ea964 2089 case EM_AARCH64: return "AArch64";
c45021f2
NC
2090 case EM_M32: return "WE32100";
2091 case EM_SPARC: return "Sparc";
e9f53129 2092 case EM_SPU: return "SPU";
c45021f2
NC
2093 case EM_386: return "Intel 80386";
2094 case EM_68K: return "MC68000";
2095 case EM_88K: return "MC88000";
2096 case EM_486: return "Intel 80486";
2097 case EM_860: return "Intel 80860";
2098 case EM_MIPS: return "MIPS R3000";
2099 case EM_S370: return "IBM System/370";
7036c0e1 2100 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2101 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2102 case EM_PARISC: return "HPPA";
252b5132 2103 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 2104 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
2105 case EM_960: return "Intel 90860";
2106 case EM_PPC: return "PowerPC";
285d1771 2107 case EM_PPC64: return "PowerPC64";
c45021f2 2108 case EM_FR20: return "Fujitsu FR20";
3f8107ab 2109 case EM_FT32: return "FTDI FT32";
c45021f2 2110 case EM_RH32: return "TRW RH32";
b34976b6 2111 case EM_MCORE: return "MCORE";
7036c0e1
AJ
2112 case EM_ARM: return "ARM";
2113 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2114 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2115 case EM_SPARCV9: return "Sparc v9";
2116 case EM_TRICORE: return "Siemens Tricore";
584da044 2117 case EM_ARC: return "ARC";
c2dcd04e
NC
2118 case EM_H8_300: return "Renesas H8/300";
2119 case EM_H8_300H: return "Renesas H8/300H";
2120 case EM_H8S: return "Renesas H8S";
2121 case EM_H8_500: return "Renesas H8/500";
30800947 2122 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2123 case EM_MIPS_X: return "Stanford MIPS-X";
2124 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 2125 case EM_ALPHA: return "Alpha";
2b0337b0
AO
2126 case EM_CYGNUS_D10V:
2127 case EM_D10V: return "d10v";
2128 case EM_CYGNUS_D30V:
b34976b6 2129 case EM_D30V: return "d30v";
2b0337b0 2130 case EM_CYGNUS_M32R:
26597c86 2131 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 2132 case EM_CYGNUS_V850:
708e2187 2133 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 2134 case EM_V850: return "Renesas V850";
2b0337b0
AO
2135 case EM_CYGNUS_MN10300:
2136 case EM_MN10300: return "mn10300";
2137 case EM_CYGNUS_MN10200:
2138 case EM_MN10200: return "mn10200";
5506d11a 2139 case EM_MOXIE: return "Moxie";
2b0337b0
AO
2140 case EM_CYGNUS_FR30:
2141 case EM_FR30: return "Fujitsu FR30";
b34976b6 2142 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 2143 case EM_PJ_OLD:
b34976b6 2144 case EM_PJ: return "picoJava";
7036c0e1
AJ
2145 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2146 case EM_PCP: return "Siemens PCP";
2147 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2148 case EM_NDR1: return "Denso NDR1 microprocesspr";
2149 case EM_STARCORE: return "Motorola Star*Core processor";
2150 case EM_ME16: return "Toyota ME16 processor";
2151 case EM_ST100: return "STMicroelectronics ST100 processor";
2152 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
2153 case EM_PDSP: return "Sony DSP processor";
2154 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2155 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2156 case EM_FX66: return "Siemens FX66 microcontroller";
2157 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2158 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2159 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 2160 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2161 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2162 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2163 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2164 case EM_SVX: return "Silicon Graphics SVx";
2165 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2166 case EM_VAX: return "Digital VAX";
619ed720 2167 case EM_VISIUM: return "CDS VISIUMcore processor";
2b0337b0 2168 case EM_AVR_OLD:
b34976b6 2169 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 2170 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2171 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2172 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2173 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2174 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2175 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2176 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2177 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2178 case EM_L1OM: return "Intel L1OM";
7a9068fe 2179 case EM_K1OM: return "Intel K1OM";
b7498e0e 2180 case EM_S390_OLD:
b34976b6 2181 case EM_S390: return "IBM S/390";
1c0d3aa6 2182 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2183 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
73589c9d 2184 case EM_OR1K: return "OpenRISC 1000";
11636f9e 2185 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 2186 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2187 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2188 case EM_DLX: return "OpenDLX";
1e4cf259 2189 case EM_IP2K_OLD:
b34976b6 2190 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2191 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2192 case EM_XTENSA_OLD:
2193 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2194 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2195 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2196 case EM_NS32K: return "National Semiconductor 32000 series";
2197 case EM_TPC: return "Tenor Network TPC processor";
2198 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2199 case EM_MAX: return "MAX Processor";
2200 case EM_CR: return "National Semiconductor CompactRISC";
2201 case EM_F2MC16: return "Fujitsu F2MC16";
2202 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2203 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2204 case EM_M32C_OLD:
49f58d10 2205 case EM_M32C: return "Renesas M32c";
d031aafb 2206 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2207 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2208 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2209 case EM_SEP: return "Sharp embedded microprocessor";
2210 case EM_ARCA: return "Arca RISC microprocessor";
2211 case EM_UNICORE: return "Unicore";
2212 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2213 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2214 case EM_NIOS32: return "Altera Nios";
2215 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2216 case EM_C166:
d70c5fc7 2217 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2218 case EM_M16C: return "Renesas M16C series microprocessors";
2219 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2220 case EM_CE: return "Freescale Communication Engine RISC core";
2221 case EM_TSK3000: return "Altium TSK3000 core";
2222 case EM_RS08: return "Freescale RS08 embedded processor";
2223 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2224 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2225 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2226 case EM_SE_C17: return "Seiko Epson C17 family";
2227 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2228 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2229 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2230 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2231 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2232 case EM_R32C: return "Renesas R32C series microprocessors";
2233 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2234 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2235 case EM_8051: return "Intel 8051 and variants";
2236 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2237 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2238 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2239 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2240 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2241 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2242 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2243 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2244 case EM_CR16:
f6c1a2d5 2245 case EM_MICROBLAZE:
7ba29e2a 2246 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2247 case EM_RL78: return "Renesas RL78";
c7927a3c 2248 case EM_RX: return "Renesas RX";
a3c62988 2249 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2250 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2251 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2252 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2253 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2254 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2255 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2256 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2257 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2258 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2259 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2260 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2261 default:
35d9dd2f 2262 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2263 return buff;
2264 }
2265}
2266
f3485b74 2267static void
d3ba0551 2268decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2269{
2270 unsigned eabi;
2271 int unknown = 0;
2272
2273 eabi = EF_ARM_EABI_VERSION (e_flags);
2274 e_flags &= ~ EF_ARM_EABIMASK;
2275
2276 /* Handle "generic" ARM flags. */
2277 if (e_flags & EF_ARM_RELEXEC)
2278 {
2279 strcat (buf, ", relocatable executable");
2280 e_flags &= ~ EF_ARM_RELEXEC;
2281 }
76da6bbe 2282
f3485b74
NC
2283 if (e_flags & EF_ARM_HASENTRY)
2284 {
2285 strcat (buf, ", has entry point");
2286 e_flags &= ~ EF_ARM_HASENTRY;
2287 }
76da6bbe 2288
f3485b74
NC
2289 /* Now handle EABI specific flags. */
2290 switch (eabi)
2291 {
2292 default:
2c71103e 2293 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2294 if (e_flags)
2295 unknown = 1;
2296 break;
2297
2298 case EF_ARM_EABI_VER1:
a5bcd848 2299 strcat (buf, ", Version1 EABI");
f3485b74
NC
2300 while (e_flags)
2301 {
2302 unsigned flag;
76da6bbe 2303
f3485b74
NC
2304 /* Process flags one bit at a time. */
2305 flag = e_flags & - e_flags;
2306 e_flags &= ~ flag;
76da6bbe 2307
f3485b74
NC
2308 switch (flag)
2309 {
a5bcd848 2310 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2311 strcat (buf, ", sorted symbol tables");
2312 break;
76da6bbe 2313
f3485b74
NC
2314 default:
2315 unknown = 1;
2316 break;
2317 }
2318 }
2319 break;
76da6bbe 2320
a5bcd848
PB
2321 case EF_ARM_EABI_VER2:
2322 strcat (buf, ", Version2 EABI");
2323 while (e_flags)
2324 {
2325 unsigned flag;
2326
2327 /* Process flags one bit at a time. */
2328 flag = e_flags & - e_flags;
2329 e_flags &= ~ flag;
2330
2331 switch (flag)
2332 {
2333 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2334 strcat (buf, ", sorted symbol tables");
2335 break;
2336
2337 case EF_ARM_DYNSYMSUSESEGIDX:
2338 strcat (buf, ", dynamic symbols use segment index");
2339 break;
2340
2341 case EF_ARM_MAPSYMSFIRST:
2342 strcat (buf, ", mapping symbols precede others");
2343 break;
2344
2345 default:
2346 unknown = 1;
2347 break;
2348 }
2349 }
2350 break;
2351
d507cf36
PB
2352 case EF_ARM_EABI_VER3:
2353 strcat (buf, ", Version3 EABI");
8cb51566
PB
2354 break;
2355
2356 case EF_ARM_EABI_VER4:
2357 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2358 while (e_flags)
2359 {
2360 unsigned flag;
2361
2362 /* Process flags one bit at a time. */
2363 flag = e_flags & - e_flags;
2364 e_flags &= ~ flag;
2365
2366 switch (flag)
2367 {
2368 case EF_ARM_BE8:
2369 strcat (buf, ", BE8");
2370 break;
2371
2372 case EF_ARM_LE8:
2373 strcat (buf, ", LE8");
2374 break;
2375
2376 default:
2377 unknown = 1;
2378 break;
2379 }
2380 break;
2381 }
2382 break;
3a4a14e9
PB
2383
2384 case EF_ARM_EABI_VER5:
2385 strcat (buf, ", Version5 EABI");
d507cf36
PB
2386 while (e_flags)
2387 {
2388 unsigned flag;
2389
2390 /* Process flags one bit at a time. */
2391 flag = e_flags & - e_flags;
2392 e_flags &= ~ flag;
2393
2394 switch (flag)
2395 {
2396 case EF_ARM_BE8:
2397 strcat (buf, ", BE8");
2398 break;
2399
2400 case EF_ARM_LE8:
2401 strcat (buf, ", LE8");
2402 break;
2403
3bfcb652
NC
2404 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2405 strcat (buf, ", soft-float ABI");
2406 break;
2407
2408 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2409 strcat (buf, ", hard-float ABI");
2410 break;
2411
d507cf36
PB
2412 default:
2413 unknown = 1;
2414 break;
2415 }
2416 }
2417 break;
2418
f3485b74 2419 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2420 strcat (buf, ", GNU EABI");
f3485b74
NC
2421 while (e_flags)
2422 {
2423 unsigned flag;
76da6bbe 2424
f3485b74
NC
2425 /* Process flags one bit at a time. */
2426 flag = e_flags & - e_flags;
2427 e_flags &= ~ flag;
76da6bbe 2428
f3485b74
NC
2429 switch (flag)
2430 {
a5bcd848 2431 case EF_ARM_INTERWORK:
f3485b74
NC
2432 strcat (buf, ", interworking enabled");
2433 break;
76da6bbe 2434
a5bcd848 2435 case EF_ARM_APCS_26:
f3485b74
NC
2436 strcat (buf, ", uses APCS/26");
2437 break;
76da6bbe 2438
a5bcd848 2439 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2440 strcat (buf, ", uses APCS/float");
2441 break;
76da6bbe 2442
a5bcd848 2443 case EF_ARM_PIC:
f3485b74
NC
2444 strcat (buf, ", position independent");
2445 break;
76da6bbe 2446
a5bcd848 2447 case EF_ARM_ALIGN8:
f3485b74
NC
2448 strcat (buf, ", 8 bit structure alignment");
2449 break;
76da6bbe 2450
a5bcd848 2451 case EF_ARM_NEW_ABI:
f3485b74
NC
2452 strcat (buf, ", uses new ABI");
2453 break;
76da6bbe 2454
a5bcd848 2455 case EF_ARM_OLD_ABI:
f3485b74
NC
2456 strcat (buf, ", uses old ABI");
2457 break;
76da6bbe 2458
a5bcd848 2459 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2460 strcat (buf, ", software FP");
2461 break;
76da6bbe 2462
90e01f86
ILT
2463 case EF_ARM_VFP_FLOAT:
2464 strcat (buf, ", VFP");
2465 break;
2466
fde78edd
NC
2467 case EF_ARM_MAVERICK_FLOAT:
2468 strcat (buf, ", Maverick FP");
2469 break;
2470
f3485b74
NC
2471 default:
2472 unknown = 1;
2473 break;
2474 }
2475 }
2476 }
f3485b74
NC
2477
2478 if (unknown)
2b692964 2479 strcat (buf,_(", <unknown>"));
f3485b74
NC
2480}
2481
343433df
AB
2482static void
2483decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2484{
2485 --size; /* Leave space for null terminator. */
2486
2487 switch (e_flags & EF_AVR_MACH)
2488 {
2489 case E_AVR_MACH_AVR1:
2490 strncat (buf, ", avr:1", size);
2491 break;
2492 case E_AVR_MACH_AVR2:
2493 strncat (buf, ", avr:2", size);
2494 break;
2495 case E_AVR_MACH_AVR25:
2496 strncat (buf, ", avr:25", size);
2497 break;
2498 case E_AVR_MACH_AVR3:
2499 strncat (buf, ", avr:3", size);
2500 break;
2501 case E_AVR_MACH_AVR31:
2502 strncat (buf, ", avr:31", size);
2503 break;
2504 case E_AVR_MACH_AVR35:
2505 strncat (buf, ", avr:35", size);
2506 break;
2507 case E_AVR_MACH_AVR4:
2508 strncat (buf, ", avr:4", size);
2509 break;
2510 case E_AVR_MACH_AVR5:
2511 strncat (buf, ", avr:5", size);
2512 break;
2513 case E_AVR_MACH_AVR51:
2514 strncat (buf, ", avr:51", size);
2515 break;
2516 case E_AVR_MACH_AVR6:
2517 strncat (buf, ", avr:6", size);
2518 break;
2519 case E_AVR_MACH_AVRTINY:
2520 strncat (buf, ", avr:100", size);
2521 break;
2522 case E_AVR_MACH_XMEGA1:
2523 strncat (buf, ", avr:101", size);
2524 break;
2525 case E_AVR_MACH_XMEGA2:
2526 strncat (buf, ", avr:102", size);
2527 break;
2528 case E_AVR_MACH_XMEGA3:
2529 strncat (buf, ", avr:103", size);
2530 break;
2531 case E_AVR_MACH_XMEGA4:
2532 strncat (buf, ", avr:104", size);
2533 break;
2534 case E_AVR_MACH_XMEGA5:
2535 strncat (buf, ", avr:105", size);
2536 break;
2537 case E_AVR_MACH_XMEGA6:
2538 strncat (buf, ", avr:106", size);
2539 break;
2540 case E_AVR_MACH_XMEGA7:
2541 strncat (buf, ", avr:107", size);
2542 break;
2543 default:
2544 strncat (buf, ", avr:<unknown>", size);
2545 break;
2546 }
2547
2548 size -= strlen (buf);
2549 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2550 strncat (buf, ", link-relax", size);
2551}
2552
35c08157
KLC
2553static void
2554decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2555{
2556 unsigned abi;
2557 unsigned arch;
2558 unsigned config;
2559 unsigned version;
2560 int has_fpu = 0;
2561 int r = 0;
2562
2563 static const char *ABI_STRINGS[] =
2564 {
2565 "ABI v0", /* use r5 as return register; only used in N1213HC */
2566 "ABI v1", /* use r0 as return register */
2567 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2568 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2569 "AABI",
2570 "ABI2 FP+"
35c08157
KLC
2571 };
2572 static const char *VER_STRINGS[] =
2573 {
2574 "Andes ELF V1.3 or older",
2575 "Andes ELF V1.3.1",
2576 "Andes ELF V1.4"
2577 };
2578 static const char *ARCH_STRINGS[] =
2579 {
2580 "",
2581 "Andes Star v1.0",
2582 "Andes Star v2.0",
2583 "Andes Star v3.0",
2584 "Andes Star v3.0m"
2585 };
2586
2587 abi = EF_NDS_ABI & e_flags;
2588 arch = EF_NDS_ARCH & e_flags;
2589 config = EF_NDS_INST & e_flags;
2590 version = EF_NDS32_ELF_VERSION & e_flags;
2591
2592 memset (buf, 0, size);
2593
2594 switch (abi)
2595 {
2596 case E_NDS_ABI_V0:
2597 case E_NDS_ABI_V1:
2598 case E_NDS_ABI_V2:
2599 case E_NDS_ABI_V2FP:
2600 case E_NDS_ABI_AABI:
40c7a7cb 2601 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2602 /* In case there are holes in the array. */
2603 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2604 break;
2605
2606 default:
2607 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2608 break;
2609 }
2610
2611 switch (version)
2612 {
2613 case E_NDS32_ELF_VER_1_2:
2614 case E_NDS32_ELF_VER_1_3:
2615 case E_NDS32_ELF_VER_1_4:
2616 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2617 break;
2618
2619 default:
2620 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2621 break;
2622 }
2623
2624 if (E_NDS_ABI_V0 == abi)
2625 {
2626 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2627 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2628 if (arch == E_NDS_ARCH_STAR_V1_0)
2629 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2630 return;
2631 }
2632
2633 switch (arch)
2634 {
2635 case E_NDS_ARCH_STAR_V1_0:
2636 case E_NDS_ARCH_STAR_V2_0:
2637 case E_NDS_ARCH_STAR_V3_0:
2638 case E_NDS_ARCH_STAR_V3_M:
2639 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2640 break;
2641
2642 default:
2643 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2644 /* ARCH version determines how the e_flags are interpreted.
2645 If it is unknown, we cannot proceed. */
2646 return;
2647 }
2648
2649 /* Newer ABI; Now handle architecture specific flags. */
2650 if (arch == E_NDS_ARCH_STAR_V1_0)
2651 {
2652 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2653 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2654
2655 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2656 r += snprintf (buf + r, size -r, ", MAC");
2657
2658 if (config & E_NDS32_HAS_DIV_INST)
2659 r += snprintf (buf + r, size -r, ", DIV");
2660
2661 if (config & E_NDS32_HAS_16BIT_INST)
2662 r += snprintf (buf + r, size -r, ", 16b");
2663 }
2664 else
2665 {
2666 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2667 {
2668 if (version <= E_NDS32_ELF_VER_1_3)
2669 r += snprintf (buf + r, size -r, ", [B8]");
2670 else
2671 r += snprintf (buf + r, size -r, ", EX9");
2672 }
2673
2674 if (config & E_NDS32_HAS_MAC_DX_INST)
2675 r += snprintf (buf + r, size -r, ", MAC_DX");
2676
2677 if (config & E_NDS32_HAS_DIV_DX_INST)
2678 r += snprintf (buf + r, size -r, ", DIV_DX");
2679
2680 if (config & E_NDS32_HAS_16BIT_INST)
2681 {
2682 if (version <= E_NDS32_ELF_VER_1_3)
2683 r += snprintf (buf + r, size -r, ", 16b");
2684 else
2685 r += snprintf (buf + r, size -r, ", IFC");
2686 }
2687 }
2688
2689 if (config & E_NDS32_HAS_EXT_INST)
2690 r += snprintf (buf + r, size -r, ", PERF1");
2691
2692 if (config & E_NDS32_HAS_EXT2_INST)
2693 r += snprintf (buf + r, size -r, ", PERF2");
2694
2695 if (config & E_NDS32_HAS_FPU_INST)
2696 {
2697 has_fpu = 1;
2698 r += snprintf (buf + r, size -r, ", FPU_SP");
2699 }
2700
2701 if (config & E_NDS32_HAS_FPU_DP_INST)
2702 {
2703 has_fpu = 1;
2704 r += snprintf (buf + r, size -r, ", FPU_DP");
2705 }
2706
2707 if (config & E_NDS32_HAS_FPU_MAC_INST)
2708 {
2709 has_fpu = 1;
2710 r += snprintf (buf + r, size -r, ", FPU_MAC");
2711 }
2712
2713 if (has_fpu)
2714 {
2715 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2716 {
2717 case E_NDS32_FPU_REG_8SP_4DP:
2718 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2719 break;
2720 case E_NDS32_FPU_REG_16SP_8DP:
2721 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2722 break;
2723 case E_NDS32_FPU_REG_32SP_16DP:
2724 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2725 break;
2726 case E_NDS32_FPU_REG_32SP_32DP:
2727 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
2728 break;
2729 }
2730 }
2731
2732 if (config & E_NDS32_HAS_AUDIO_INST)
2733 r += snprintf (buf + r, size -r, ", AUDIO");
2734
2735 if (config & E_NDS32_HAS_STRING_INST)
2736 r += snprintf (buf + r, size -r, ", STR");
2737
2738 if (config & E_NDS32_HAS_REDUCED_REGS)
2739 r += snprintf (buf + r, size -r, ", 16REG");
2740
2741 if (config & E_NDS32_HAS_VIDEO_INST)
2742 {
2743 if (version <= E_NDS32_ELF_VER_1_3)
2744 r += snprintf (buf + r, size -r, ", VIDEO");
2745 else
2746 r += snprintf (buf + r, size -r, ", SATURATION");
2747 }
2748
2749 if (config & E_NDS32_HAS_ENCRIPT_INST)
2750 r += snprintf (buf + r, size -r, ", ENCRP");
2751
2752 if (config & E_NDS32_HAS_L2C_INST)
2753 r += snprintf (buf + r, size -r, ", L2C");
2754}
2755
252b5132 2756static char *
d3ba0551 2757get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2758{
b34976b6 2759 static char buf[1024];
252b5132
RH
2760
2761 buf[0] = '\0';
76da6bbe 2762
252b5132
RH
2763 if (e_flags)
2764 {
2765 switch (e_machine)
2766 {
2767 default:
2768 break;
2769
f3485b74
NC
2770 case EM_ARM:
2771 decode_ARM_machine_flags (e_flags, buf);
2772 break;
76da6bbe 2773
343433df
AB
2774 case EM_AVR:
2775 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
2776 break;
2777
781303ce
MF
2778 case EM_BLACKFIN:
2779 if (e_flags & EF_BFIN_PIC)
2780 strcat (buf, ", PIC");
2781
2782 if (e_flags & EF_BFIN_FDPIC)
2783 strcat (buf, ", FDPIC");
2784
2785 if (e_flags & EF_BFIN_CODE_IN_L1)
2786 strcat (buf, ", code in L1");
2787
2788 if (e_flags & EF_BFIN_DATA_IN_L1)
2789 strcat (buf, ", data in L1");
2790
2791 break;
2792
ec2dfb42
AO
2793 case EM_CYGNUS_FRV:
2794 switch (e_flags & EF_FRV_CPU_MASK)
2795 {
2796 case EF_FRV_CPU_GENERIC:
2797 break;
2798
2799 default:
2800 strcat (buf, ", fr???");
2801 break;
57346661 2802
ec2dfb42
AO
2803 case EF_FRV_CPU_FR300:
2804 strcat (buf, ", fr300");
2805 break;
2806
2807 case EF_FRV_CPU_FR400:
2808 strcat (buf, ", fr400");
2809 break;
2810 case EF_FRV_CPU_FR405:
2811 strcat (buf, ", fr405");
2812 break;
2813
2814 case EF_FRV_CPU_FR450:
2815 strcat (buf, ", fr450");
2816 break;
2817
2818 case EF_FRV_CPU_FR500:
2819 strcat (buf, ", fr500");
2820 break;
2821 case EF_FRV_CPU_FR550:
2822 strcat (buf, ", fr550");
2823 break;
2824
2825 case EF_FRV_CPU_SIMPLE:
2826 strcat (buf, ", simple");
2827 break;
2828 case EF_FRV_CPU_TOMCAT:
2829 strcat (buf, ", tomcat");
2830 break;
2831 }
1c877e87 2832 break;
ec2dfb42 2833
53c7db4b 2834 case EM_68K:
425c6cb0 2835 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2836 strcat (buf, ", m68000");
425c6cb0 2837 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2838 strcat (buf, ", cpu32");
2839 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2840 strcat (buf, ", fido_a");
425c6cb0 2841 else
266abb8f 2842 {
2cf0635d
NC
2843 char const * isa = _("unknown");
2844 char const * mac = _("unknown mac");
2845 char const * additional = NULL;
0112cd26 2846
c694fd50 2847 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2848 {
c694fd50 2849 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2850 isa = "A";
2851 additional = ", nodiv";
2852 break;
c694fd50 2853 case EF_M68K_CF_ISA_A:
266abb8f
NS
2854 isa = "A";
2855 break;
c694fd50 2856 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2857 isa = "A+";
2858 break;
c694fd50 2859 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2860 isa = "B";
2861 additional = ", nousp";
2862 break;
c694fd50 2863 case EF_M68K_CF_ISA_B:
266abb8f
NS
2864 isa = "B";
2865 break;
f608cd77
NS
2866 case EF_M68K_CF_ISA_C:
2867 isa = "C";
2868 break;
2869 case EF_M68K_CF_ISA_C_NODIV:
2870 isa = "C";
2871 additional = ", nodiv";
2872 break;
266abb8f
NS
2873 }
2874 strcat (buf, ", cf, isa ");
2875 strcat (buf, isa);
0b2e31dc
NS
2876 if (additional)
2877 strcat (buf, additional);
c694fd50 2878 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2879 strcat (buf, ", float");
c694fd50 2880 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2881 {
2882 case 0:
2883 mac = NULL;
2884 break;
c694fd50 2885 case EF_M68K_CF_MAC:
266abb8f
NS
2886 mac = "mac";
2887 break;
c694fd50 2888 case EF_M68K_CF_EMAC:
266abb8f
NS
2889 mac = "emac";
2890 break;
f608cd77
NS
2891 case EF_M68K_CF_EMAC_B:
2892 mac = "emac_b";
2893 break;
266abb8f
NS
2894 }
2895 if (mac)
2896 {
2897 strcat (buf, ", ");
2898 strcat (buf, mac);
2899 }
266abb8f 2900 }
53c7db4b 2901 break;
33c63f9d 2902
252b5132
RH
2903 case EM_PPC:
2904 if (e_flags & EF_PPC_EMB)
2905 strcat (buf, ", emb");
2906
2907 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2908 strcat (buf, _(", relocatable"));
252b5132
RH
2909
2910 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2911 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2912 break;
2913
ee67d69a
AM
2914 case EM_PPC64:
2915 if (e_flags & EF_PPC64_ABI)
2916 {
2917 char abi[] = ", abiv0";
2918
2919 abi[6] += e_flags & EF_PPC64_ABI;
2920 strcat (buf, abi);
2921 }
2922 break;
2923
708e2187
NC
2924 case EM_V800:
2925 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2926 strcat (buf, ", RH850 ABI");
0b4362b0 2927
708e2187
NC
2928 if (e_flags & EF_V800_850E3)
2929 strcat (buf, ", V3 architecture");
2930
2931 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2932 strcat (buf, ", FPU not used");
2933
2934 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2935 strcat (buf, ", regmode: COMMON");
2936
2937 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2938 strcat (buf, ", r4 not used");
2939
2940 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2941 strcat (buf, ", r30 not used");
2942
2943 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2944 strcat (buf, ", r5 not used");
2945
2946 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2947 strcat (buf, ", r2 not used");
2948
2949 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2950 {
2951 switch (e_flags & - e_flags)
2952 {
2953 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2954 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2955 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2956 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2957 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2958 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2959 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2960 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2961 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2962 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2963 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2964 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2965 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2966 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2967 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2968 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2969 default: break;
2970 }
2971 }
2972 break;
2973
2b0337b0 2974 case EM_V850:
252b5132
RH
2975 case EM_CYGNUS_V850:
2976 switch (e_flags & EF_V850_ARCH)
2977 {
78c8d46c
NC
2978 case E_V850E3V5_ARCH:
2979 strcat (buf, ", v850e3v5");
2980 break;
1cd986c5
NC
2981 case E_V850E2V3_ARCH:
2982 strcat (buf, ", v850e2v3");
2983 break;
2984 case E_V850E2_ARCH:
2985 strcat (buf, ", v850e2");
2986 break;
2987 case E_V850E1_ARCH:
2988 strcat (buf, ", v850e1");
8ad30312 2989 break;
252b5132
RH
2990 case E_V850E_ARCH:
2991 strcat (buf, ", v850e");
2992 break;
252b5132
RH
2993 case E_V850_ARCH:
2994 strcat (buf, ", v850");
2995 break;
2996 default:
2b692964 2997 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2998 break;
2999 }
3000 break;
3001
2b0337b0 3002 case EM_M32R:
252b5132
RH
3003 case EM_CYGNUS_M32R:
3004 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3005 strcat (buf, ", m32r");
252b5132
RH
3006 break;
3007
3008 case EM_MIPS:
4fe85591 3009 case EM_MIPS_RS3_LE:
252b5132
RH
3010 if (e_flags & EF_MIPS_NOREORDER)
3011 strcat (buf, ", noreorder");
3012
3013 if (e_flags & EF_MIPS_PIC)
3014 strcat (buf, ", pic");
3015
3016 if (e_flags & EF_MIPS_CPIC)
3017 strcat (buf, ", cpic");
3018
d1bdd336
TS
3019 if (e_flags & EF_MIPS_UCODE)
3020 strcat (buf, ", ugen_reserved");
3021
252b5132
RH
3022 if (e_flags & EF_MIPS_ABI2)
3023 strcat (buf, ", abi2");
3024
43521d43
TS
3025 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3026 strcat (buf, ", odk first");
3027
a5d22d2a
TS
3028 if (e_flags & EF_MIPS_32BITMODE)
3029 strcat (buf, ", 32bitmode");
3030
ba92f887
MR
3031 if (e_flags & EF_MIPS_NAN2008)
3032 strcat (buf, ", nan2008");
3033
fef1b0b3
SE
3034 if (e_flags & EF_MIPS_FP64)
3035 strcat (buf, ", fp64");
3036
156c2f8b
NC
3037 switch ((e_flags & EF_MIPS_MACH))
3038 {
3039 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3040 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3041 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3042 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3043 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3044 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3045 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3046 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 3047 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3048 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3049 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3050 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 3051 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 3052 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3053 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3054 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3055 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
3056 case 0:
3057 /* We simply ignore the field in this case to avoid confusion:
3058 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3059 extension. */
3060 break;
2b692964 3061 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3062 }
43521d43
TS
3063
3064 switch ((e_flags & EF_MIPS_ABI))
3065 {
3066 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3067 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3068 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3069 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3070 case 0:
3071 /* We simply ignore the field in this case to avoid confusion:
3072 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3073 This means it is likely to be an o32 file, but not for
3074 sure. */
3075 break;
2b692964 3076 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3077 }
3078
3079 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3080 strcat (buf, ", mdmx");
3081
3082 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3083 strcat (buf, ", mips16");
3084
df58fc94
RS
3085 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3086 strcat (buf, ", micromips");
3087
43521d43
TS
3088 switch ((e_flags & EF_MIPS_ARCH))
3089 {
3090 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3091 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3092 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3093 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3094 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3095 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3096 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3097 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3098 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3099 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3100 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3101 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3102 }
252b5132 3103 break;
351b4b40 3104
35c08157
KLC
3105 case EM_NDS32:
3106 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3107 break;
3108
ccde1100
AO
3109 case EM_SH:
3110 switch ((e_flags & EF_SH_MACH_MASK))
3111 {
3112 case EF_SH1: strcat (buf, ", sh1"); break;
3113 case EF_SH2: strcat (buf, ", sh2"); break;
3114 case EF_SH3: strcat (buf, ", sh3"); break;
3115 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3116 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3117 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3118 case EF_SH3E: strcat (buf, ", sh3e"); break;
3119 case EF_SH4: strcat (buf, ", sh4"); break;
3120 case EF_SH5: strcat (buf, ", sh5"); break;
3121 case EF_SH2E: strcat (buf, ", sh2e"); break;
3122 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3123 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3124 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3125 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3126 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3127 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3128 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3129 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3130 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3131 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3132 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3133 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3134 }
3135
cec6a5b8
MR
3136 if (e_flags & EF_SH_PIC)
3137 strcat (buf, ", pic");
3138
3139 if (e_flags & EF_SH_FDPIC)
3140 strcat (buf, ", fdpic");
ccde1100 3141 break;
948f632f 3142
73589c9d
CS
3143 case EM_OR1K:
3144 if (e_flags & EF_OR1K_NODELAY)
3145 strcat (buf, ", no delay");
3146 break;
57346661 3147
351b4b40
RH
3148 case EM_SPARCV9:
3149 if (e_flags & EF_SPARC_32PLUS)
3150 strcat (buf, ", v8+");
3151
3152 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3153 strcat (buf, ", ultrasparcI");
3154
3155 if (e_flags & EF_SPARC_SUN_US3)
3156 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3157
3158 if (e_flags & EF_SPARC_HAL_R1)
3159 strcat (buf, ", halr1");
3160
3161 if (e_flags & EF_SPARC_LEDATA)
3162 strcat (buf, ", ledata");
3163
3164 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3165 strcat (buf, ", tso");
3166
3167 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3168 strcat (buf, ", pso");
3169
3170 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3171 strcat (buf, ", rmo");
3172 break;
7d466069 3173
103f02d3
UD
3174 case EM_PARISC:
3175 switch (e_flags & EF_PARISC_ARCH)
3176 {
3177 case EFA_PARISC_1_0:
3178 strcpy (buf, ", PA-RISC 1.0");
3179 break;
3180 case EFA_PARISC_1_1:
3181 strcpy (buf, ", PA-RISC 1.1");
3182 break;
3183 case EFA_PARISC_2_0:
3184 strcpy (buf, ", PA-RISC 2.0");
3185 break;
3186 default:
3187 break;
3188 }
3189 if (e_flags & EF_PARISC_TRAPNIL)
3190 strcat (buf, ", trapnil");
3191 if (e_flags & EF_PARISC_EXT)
3192 strcat (buf, ", ext");
3193 if (e_flags & EF_PARISC_LSB)
3194 strcat (buf, ", lsb");
3195 if (e_flags & EF_PARISC_WIDE)
3196 strcat (buf, ", wide");
3197 if (e_flags & EF_PARISC_NO_KABP)
3198 strcat (buf, ", no kabp");
3199 if (e_flags & EF_PARISC_LAZYSWAP)
3200 strcat (buf, ", lazyswap");
30800947 3201 break;
76da6bbe 3202
7d466069 3203 case EM_PJ:
2b0337b0 3204 case EM_PJ_OLD:
7d466069
ILT
3205 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3206 strcat (buf, ", new calling convention");
3207
3208 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3209 strcat (buf, ", gnu calling convention");
3210 break;
4d6ed7c8
NC
3211
3212 case EM_IA_64:
3213 if ((e_flags & EF_IA_64_ABI64))
3214 strcat (buf, ", 64-bit");
3215 else
3216 strcat (buf, ", 32-bit");
3217 if ((e_flags & EF_IA_64_REDUCEDFP))
3218 strcat (buf, ", reduced fp model");
3219 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3220 strcat (buf, ", no function descriptors, constant gp");
3221 else if ((e_flags & EF_IA_64_CONS_GP))
3222 strcat (buf, ", constant gp");
3223 if ((e_flags & EF_IA_64_ABSOLUTE))
3224 strcat (buf, ", absolute");
28f997cf
TG
3225 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3226 {
3227 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3228 strcat (buf, ", vms_linkages");
3229 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3230 {
3231 case EF_IA_64_VMS_COMCOD_SUCCESS:
3232 break;
3233 case EF_IA_64_VMS_COMCOD_WARNING:
3234 strcat (buf, ", warning");
3235 break;
3236 case EF_IA_64_VMS_COMCOD_ERROR:
3237 strcat (buf, ", error");
3238 break;
3239 case EF_IA_64_VMS_COMCOD_ABORT:
3240 strcat (buf, ", abort");
3241 break;
3242 default:
bee0ee85
NC
3243 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3244 e_flags & EF_IA_64_VMS_COMCOD);
3245 strcat (buf, ", <unknown>");
28f997cf
TG
3246 }
3247 }
4d6ed7c8 3248 break;
179d3252
JT
3249
3250 case EM_VAX:
3251 if ((e_flags & EF_VAX_NONPIC))
3252 strcat (buf, ", non-PIC");
3253 if ((e_flags & EF_VAX_DFLOAT))
3254 strcat (buf, ", D-Float");
3255 if ((e_flags & EF_VAX_GFLOAT))
3256 strcat (buf, ", G-Float");
3257 break;
c7927a3c 3258
619ed720
EB
3259 case EM_VISIUM:
3260 if (e_flags & EF_VISIUM_ARCH_MCM)
3261 strcat (buf, ", mcm");
3262 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3263 strcat (buf, ", mcm24");
3264 if (e_flags & EF_VISIUM_ARCH_GR6)
3265 strcat (buf, ", gr6");
3266 break;
3267
4046d87a
NC
3268 case EM_RL78:
3269 if (e_flags & E_FLAG_RL78_G10)
3270 strcat (buf, ", G10");
856ea05c
KP
3271 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3272 strcat (buf, ", 64-bit doubles");
4046d87a 3273 break;
0b4362b0 3274
c7927a3c
NC
3275 case EM_RX:
3276 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3277 strcat (buf, ", 64-bit doubles");
3278 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3279 strcat (buf, ", dsp");
d4cb0ea0 3280 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3281 strcat (buf, ", pid");
708e2187
NC
3282 if (e_flags & E_FLAG_RX_ABI)
3283 strcat (buf, ", RX ABI");
d4cb0ea0 3284 break;
55786da2
AK
3285
3286 case EM_S390:
3287 if (e_flags & EF_S390_HIGH_GPRS)
3288 strcat (buf, ", highgprs");
d4cb0ea0 3289 break;
40b36596
JM
3290
3291 case EM_TI_C6000:
3292 if ((e_flags & EF_C6000_REL))
3293 strcat (buf, ", relocatable module");
d4cb0ea0 3294 break;
13761a11
NC
3295
3296 case EM_MSP430:
3297 strcat (buf, _(": architecture variant: "));
3298 switch (e_flags & EF_MSP430_MACH)
3299 {
3300 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3301 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3302 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3303 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3304 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3305 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3306 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3307 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3308 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3309 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3310 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3311 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3312 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3313 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3314 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3315 default:
3316 strcat (buf, _(": unknown")); break;
3317 }
3318
3319 if (e_flags & ~ EF_MSP430_MACH)
3320 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3321 }
3322 }
3323
3324 return buf;
3325}
3326
252b5132 3327static const char *
d3ba0551
AM
3328get_osabi_name (unsigned int osabi)
3329{
3330 static char buff[32];
3331
3332 switch (osabi)
3333 {
3334 case ELFOSABI_NONE: return "UNIX - System V";
3335 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3336 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3337 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3338 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3339 case ELFOSABI_AIX: return "UNIX - AIX";
3340 case ELFOSABI_IRIX: return "UNIX - IRIX";
3341 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3342 case ELFOSABI_TRU64: return "UNIX - TRU64";
3343 case ELFOSABI_MODESTO: return "Novell - Modesto";
3344 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3345 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3346 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3347 case ELFOSABI_AROS: return "AROS";
11636f9e 3348 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 3349 default:
40b36596
JM
3350 if (osabi >= 64)
3351 switch (elf_header.e_machine)
3352 {
3353 case EM_ARM:
3354 switch (osabi)
3355 {
3356 case ELFOSABI_ARM: return "ARM";
3357 default:
3358 break;
3359 }
3360 break;
3361
3362 case EM_MSP430:
3363 case EM_MSP430_OLD:
619ed720 3364 case EM_VISIUM:
40b36596
JM
3365 switch (osabi)
3366 {
3367 case ELFOSABI_STANDALONE: return _("Standalone App");
3368 default:
3369 break;
3370 }
3371 break;
3372
3373 case EM_TI_C6000:
3374 switch (osabi)
3375 {
3376 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3377 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3378 default:
3379 break;
3380 }
3381 break;
3382
3383 default:
3384 break;
3385 }
e9e44622 3386 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3387 return buff;
3388 }
3389}
3390
a06ea964
NC
3391static const char *
3392get_aarch64_segment_type (unsigned long type)
3393{
3394 switch (type)
3395 {
3396 case PT_AARCH64_ARCHEXT:
3397 return "AARCH64_ARCHEXT";
3398 default:
3399 break;
3400 }
3401
3402 return NULL;
3403}
3404
b294bdf8
MM
3405static const char *
3406get_arm_segment_type (unsigned long type)
3407{
3408 switch (type)
3409 {
3410 case PT_ARM_EXIDX:
3411 return "EXIDX";
3412 default:
3413 break;
3414 }
3415
3416 return NULL;
3417}
3418
d3ba0551
AM
3419static const char *
3420get_mips_segment_type (unsigned long type)
252b5132
RH
3421{
3422 switch (type)
3423 {
3424 case PT_MIPS_REGINFO:
3425 return "REGINFO";
3426 case PT_MIPS_RTPROC:
3427 return "RTPROC";
3428 case PT_MIPS_OPTIONS:
3429 return "OPTIONS";
351cdf24
MF
3430 case PT_MIPS_ABIFLAGS:
3431 return "ABIFLAGS";
252b5132
RH
3432 default:
3433 break;
3434 }
3435
3436 return NULL;
3437}
3438
103f02d3 3439static const char *
d3ba0551 3440get_parisc_segment_type (unsigned long type)
103f02d3
UD
3441{
3442 switch (type)
3443 {
3444 case PT_HP_TLS: return "HP_TLS";
3445 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3446 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3447 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3448 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3449 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3450 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3451 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3452 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3453 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3454 case PT_HP_PARALLEL: return "HP_PARALLEL";
3455 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3456 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3457 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3458 case PT_HP_STACK: return "HP_STACK";
3459 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3460 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3461 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3462 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
3463 default:
3464 break;
3465 }
3466
3467 return NULL;
3468}
3469
4d6ed7c8 3470static const char *
d3ba0551 3471get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3472{
3473 switch (type)
3474 {
3475 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3476 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3477 case PT_HP_TLS: return "HP_TLS";
3478 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3479 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3480 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3481 default:
3482 break;
3483 }
3484
3485 return NULL;
3486}
3487
40b36596
JM
3488static const char *
3489get_tic6x_segment_type (unsigned long type)
3490{
3491 switch (type)
3492 {
3493 case PT_C6000_PHATTR: return "C6000_PHATTR";
3494 default:
3495 break;
3496 }
3497
3498 return NULL;
3499}
3500
252b5132 3501static const char *
d3ba0551 3502get_segment_type (unsigned long p_type)
252b5132 3503{
b34976b6 3504 static char buff[32];
252b5132
RH
3505
3506 switch (p_type)
3507 {
b34976b6
AM
3508 case PT_NULL: return "NULL";
3509 case PT_LOAD: return "LOAD";
252b5132 3510 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3511 case PT_INTERP: return "INTERP";
3512 case PT_NOTE: return "NOTE";
3513 case PT_SHLIB: return "SHLIB";
3514 case PT_PHDR: return "PHDR";
13ae64f3 3515 case PT_TLS: return "TLS";
252b5132 3516
65765700
JJ
3517 case PT_GNU_EH_FRAME:
3518 return "GNU_EH_FRAME";
2b05f1b7 3519 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3520 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3521
252b5132
RH
3522 default:
3523 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3524 {
2cf0635d 3525 const char * result;
103f02d3 3526
252b5132
RH
3527 switch (elf_header.e_machine)
3528 {
a06ea964
NC
3529 case EM_AARCH64:
3530 result = get_aarch64_segment_type (p_type);
3531 break;
b294bdf8
MM
3532 case EM_ARM:
3533 result = get_arm_segment_type (p_type);
3534 break;
252b5132 3535 case EM_MIPS:
4fe85591 3536 case EM_MIPS_RS3_LE:
252b5132
RH
3537 result = get_mips_segment_type (p_type);
3538 break;
103f02d3
UD
3539 case EM_PARISC:
3540 result = get_parisc_segment_type (p_type);
3541 break;
4d6ed7c8
NC
3542 case EM_IA_64:
3543 result = get_ia64_segment_type (p_type);
3544 break;
40b36596
JM
3545 case EM_TI_C6000:
3546 result = get_tic6x_segment_type (p_type);
3547 break;
252b5132
RH
3548 default:
3549 result = NULL;
3550 break;
3551 }
103f02d3 3552
252b5132
RH
3553 if (result != NULL)
3554 return result;
103f02d3 3555
252b5132
RH
3556 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3557 }
3558 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3559 {
2cf0635d 3560 const char * result;
103f02d3
UD
3561
3562 switch (elf_header.e_machine)
3563 {
3564 case EM_PARISC:
3565 result = get_parisc_segment_type (p_type);
3566 break;
00428cca
AM
3567 case EM_IA_64:
3568 result = get_ia64_segment_type (p_type);
3569 break;
103f02d3
UD
3570 default:
3571 result = NULL;
3572 break;
3573 }
3574
3575 if (result != NULL)
3576 return result;
3577
3578 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3579 }
252b5132 3580 else
e9e44622 3581 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3582
3583 return buff;
3584 }
3585}
3586
3587static const char *
d3ba0551 3588get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3589{
3590 switch (sh_type)
3591 {
b34976b6
AM
3592 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3593 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3594 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3595 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3596 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3597 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3598 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3599 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3600 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3601 case SHT_MIPS_RELD: return "MIPS_RELD";
3602 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3603 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3604 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3605 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3606 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3607 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3608 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3609 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3610 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3611 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3612 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3613 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3614 case SHT_MIPS_LINE: return "MIPS_LINE";
3615 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3616 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3617 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3618 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3619 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3620 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3621 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3622 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3623 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3624 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3625 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3626 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3627 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3628 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3629 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 3630 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 3631 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
3632 default:
3633 break;
3634 }
3635 return NULL;
3636}
3637
103f02d3 3638static const char *
d3ba0551 3639get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3640{
3641 switch (sh_type)
3642 {
3643 case SHT_PARISC_EXT: return "PARISC_EXT";
3644 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3645 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3646 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3647 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3648 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3649 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3650 default:
3651 break;
3652 }
3653 return NULL;
3654}
3655
4d6ed7c8 3656static const char *
d3ba0551 3657get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3658{
18bd398b 3659 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3660 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3661 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3662
4d6ed7c8
NC
3663 switch (sh_type)
3664 {
148b93f2
NC
3665 case SHT_IA_64_EXT: return "IA_64_EXT";
3666 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3667 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3668 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3669 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3670 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3671 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3672 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3673 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3674 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3675 default:
3676 break;
3677 }
3678 return NULL;
3679}
3680
d2b2c203
DJ
3681static const char *
3682get_x86_64_section_type_name (unsigned int sh_type)
3683{
3684 switch (sh_type)
3685 {
3686 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3687 default:
3688 break;
3689 }
3690 return NULL;
3691}
3692
a06ea964
NC
3693static const char *
3694get_aarch64_section_type_name (unsigned int sh_type)
3695{
3696 switch (sh_type)
3697 {
3698 case SHT_AARCH64_ATTRIBUTES:
3699 return "AARCH64_ATTRIBUTES";
3700 default:
3701 break;
3702 }
3703 return NULL;
3704}
3705
40a18ebd
NC
3706static const char *
3707get_arm_section_type_name (unsigned int sh_type)
3708{
3709 switch (sh_type)
3710 {
7f6fed87
NC
3711 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3712 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3713 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3714 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3715 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3716 default:
3717 break;
3718 }
3719 return NULL;
3720}
3721
40b36596
JM
3722static const char *
3723get_tic6x_section_type_name (unsigned int sh_type)
3724{
3725 switch (sh_type)
3726 {
3727 case SHT_C6000_UNWIND:
3728 return "C6000_UNWIND";
3729 case SHT_C6000_PREEMPTMAP:
3730 return "C6000_PREEMPTMAP";
3731 case SHT_C6000_ATTRIBUTES:
3732 return "C6000_ATTRIBUTES";
3733 case SHT_TI_ICODE:
3734 return "TI_ICODE";
3735 case SHT_TI_XREF:
3736 return "TI_XREF";
3737 case SHT_TI_HANDLER:
3738 return "TI_HANDLER";
3739 case SHT_TI_INITINFO:
3740 return "TI_INITINFO";
3741 case SHT_TI_PHATTRS:
3742 return "TI_PHATTRS";
3743 default:
3744 break;
3745 }
3746 return NULL;
3747}
3748
13761a11
NC
3749static const char *
3750get_msp430x_section_type_name (unsigned int sh_type)
3751{
3752 switch (sh_type)
3753 {
3754 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3755 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3756 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3757 default: return NULL;
3758 }
3759}
3760
252b5132 3761static const char *
d3ba0551 3762get_section_type_name (unsigned int sh_type)
252b5132 3763{
b34976b6 3764 static char buff[32];
252b5132
RH
3765
3766 switch (sh_type)
3767 {
3768 case SHT_NULL: return "NULL";
3769 case SHT_PROGBITS: return "PROGBITS";
3770 case SHT_SYMTAB: return "SYMTAB";
3771 case SHT_STRTAB: return "STRTAB";
3772 case SHT_RELA: return "RELA";
3773 case SHT_HASH: return "HASH";
3774 case SHT_DYNAMIC: return "DYNAMIC";
3775 case SHT_NOTE: return "NOTE";
3776 case SHT_NOBITS: return "NOBITS";
3777 case SHT_REL: return "REL";
3778 case SHT_SHLIB: return "SHLIB";
3779 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3780 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3781 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3782 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3783 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3784 case SHT_GROUP: return "GROUP";
3785 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3786 case SHT_GNU_verdef: return "VERDEF";
3787 case SHT_GNU_verneed: return "VERNEED";
3788 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3789 case 0x6ffffff0: return "VERSYM";
3790 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3791 case 0x7ffffffd: return "AUXILIARY";
3792 case 0x7fffffff: return "FILTER";
047b2264 3793 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3794
3795 default:
3796 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3797 {
2cf0635d 3798 const char * result;
252b5132
RH
3799
3800 switch (elf_header.e_machine)
3801 {
3802 case EM_MIPS:
4fe85591 3803 case EM_MIPS_RS3_LE:
252b5132
RH
3804 result = get_mips_section_type_name (sh_type);
3805 break;
103f02d3
UD
3806 case EM_PARISC:
3807 result = get_parisc_section_type_name (sh_type);
3808 break;
4d6ed7c8
NC
3809 case EM_IA_64:
3810 result = get_ia64_section_type_name (sh_type);
3811 break;
d2b2c203 3812 case EM_X86_64:
8a9036a4 3813 case EM_L1OM:
7a9068fe 3814 case EM_K1OM:
d2b2c203
DJ
3815 result = get_x86_64_section_type_name (sh_type);
3816 break;
a06ea964
NC
3817 case EM_AARCH64:
3818 result = get_aarch64_section_type_name (sh_type);
3819 break;
40a18ebd
NC
3820 case EM_ARM:
3821 result = get_arm_section_type_name (sh_type);
3822 break;
40b36596
JM
3823 case EM_TI_C6000:
3824 result = get_tic6x_section_type_name (sh_type);
3825 break;
13761a11
NC
3826 case EM_MSP430:
3827 result = get_msp430x_section_type_name (sh_type);
3828 break;
252b5132
RH
3829 default:
3830 result = NULL;
3831 break;
3832 }
3833
3834 if (result != NULL)
3835 return result;
3836
c91d0dfb 3837 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3838 }
3839 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3840 {
2cf0635d 3841 const char * result;
148b93f2
NC
3842
3843 switch (elf_header.e_machine)
3844 {
3845 case EM_IA_64:
3846 result = get_ia64_section_type_name (sh_type);
3847 break;
3848 default:
3849 result = NULL;
3850 break;
3851 }
3852
3853 if (result != NULL)
3854 return result;
3855
3856 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3857 }
252b5132 3858 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3859 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3860 else
a7dbfd1c
NC
3861 /* This message is probably going to be displayed in a 15
3862 character wide field, so put the hex value first. */
3863 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3864
252b5132
RH
3865 return buff;
3866 }
3867}
3868
2979dc34 3869#define OPTION_DEBUG_DUMP 512
2c610e4b 3870#define OPTION_DYN_SYMS 513
fd2f0033
TT
3871#define OPTION_DWARF_DEPTH 514
3872#define OPTION_DWARF_START 515
4723351a 3873#define OPTION_DWARF_CHECK 516
2979dc34 3874
85b1c36d 3875static struct option options[] =
252b5132 3876{
b34976b6 3877 {"all", no_argument, 0, 'a'},
252b5132
RH
3878 {"file-header", no_argument, 0, 'h'},
3879 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3880 {"headers", no_argument, 0, 'e'},
3881 {"histogram", no_argument, 0, 'I'},
3882 {"segments", no_argument, 0, 'l'},
3883 {"sections", no_argument, 0, 'S'},
252b5132 3884 {"section-headers", no_argument, 0, 'S'},
f5842774 3885 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3886 {"section-details", no_argument, 0, 't'},
595cf52e 3887 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3888 {"symbols", no_argument, 0, 's'},
3889 {"syms", no_argument, 0, 's'},
2c610e4b 3890 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3891 {"relocs", no_argument, 0, 'r'},
3892 {"notes", no_argument, 0, 'n'},
3893 {"dynamic", no_argument, 0, 'd'},
a952a375 3894 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3895 {"version-info", no_argument, 0, 'V'},
3896 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3897 {"unwind", no_argument, 0, 'u'},
4145f1d5 3898 {"archive-index", no_argument, 0, 'c'},
b34976b6 3899 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3900 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3901 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3902#ifdef SUPPORT_DISASSEMBLY
3903 {"instruction-dump", required_argument, 0, 'i'},
3904#endif
cf13d699 3905 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3906
fd2f0033
TT
3907 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3908 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3909 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3910
b34976b6
AM
3911 {"version", no_argument, 0, 'v'},
3912 {"wide", no_argument, 0, 'W'},
3913 {"help", no_argument, 0, 'H'},
3914 {0, no_argument, 0, 0}
252b5132
RH
3915};
3916
3917static void
2cf0635d 3918usage (FILE * stream)
252b5132 3919{
92f01d61
JM
3920 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3921 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3922 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3923 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3924 -h --file-header Display the ELF file header\n\
3925 -l --program-headers Display the program headers\n\
3926 --segments An alias for --program-headers\n\
3927 -S --section-headers Display the sections' header\n\
3928 --sections An alias for --section-headers\n\
f5842774 3929 -g --section-groups Display the section groups\n\
5477e8a0 3930 -t --section-details Display the section details\n\
8b53311e
NC
3931 -e --headers Equivalent to: -h -l -S\n\
3932 -s --syms Display the symbol table\n\
3f08eb35 3933 --symbols An alias for --syms\n\
2c610e4b 3934 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3935 -n --notes Display the core notes (if present)\n\
3936 -r --relocs Display the relocations (if present)\n\
3937 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3938 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3939 -V --version-info Display the version sections (if present)\n\
1b31d05e 3940 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3941 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3942 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3943 -x --hex-dump=<number|name>\n\
3944 Dump the contents of section <number|name> as bytes\n\
3945 -p --string-dump=<number|name>\n\
3946 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3947 -R --relocated-dump=<number|name>\n\
3948 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3949 -w[lLiaprmfFsoRt] or\n\
1ed06042 3950 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3951 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3952 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3953 =addr,=cu_index]\n\
8b53311e 3954 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3955 fprintf (stream, _("\
3956 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3957 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3958 or deeper\n"));
252b5132 3959#ifdef SUPPORT_DISASSEMBLY
92f01d61 3960 fprintf (stream, _("\
09c11c86
NC
3961 -i --instruction-dump=<number|name>\n\
3962 Disassemble the contents of section <number|name>\n"));
252b5132 3963#endif
92f01d61 3964 fprintf (stream, _("\
8b53311e
NC
3965 -I --histogram Display histogram of bucket list lengths\n\
3966 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3967 @<file> Read options from <file>\n\
8b53311e
NC
3968 -H --help Display this information\n\
3969 -v --version Display the version number of readelf\n"));
1118d252 3970
92f01d61
JM
3971 if (REPORT_BUGS_TO[0] && stream == stdout)
3972 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3973
92f01d61 3974 exit (stream == stdout ? 0 : 1);
252b5132
RH
3975}
3976
18bd398b
NC
3977/* Record the fact that the user wants the contents of section number
3978 SECTION to be displayed using the method(s) encoded as flags bits
3979 in TYPE. Note, TYPE can be zero if we are creating the array for
3980 the first time. */
3981
252b5132 3982static void
09c11c86 3983request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3984{
3985 if (section >= num_dump_sects)
3986 {
2cf0635d 3987 dump_type * new_dump_sects;
252b5132 3988
3f5e193b
NC
3989 new_dump_sects = (dump_type *) calloc (section + 1,
3990 sizeof (* dump_sects));
252b5132
RH
3991
3992 if (new_dump_sects == NULL)
591a748a 3993 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3994 else
3995 {
3996 /* Copy current flag settings. */
09c11c86 3997 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3998
3999 free (dump_sects);
4000
4001 dump_sects = new_dump_sects;
4002 num_dump_sects = section + 1;
4003 }
4004 }
4005
4006 if (dump_sects)
b34976b6 4007 dump_sects[section] |= type;
252b5132
RH
4008
4009 return;
4010}
4011
aef1f6d0
DJ
4012/* Request a dump by section name. */
4013
4014static void
2cf0635d 4015request_dump_byname (const char * section, dump_type type)
aef1f6d0 4016{
2cf0635d 4017 struct dump_list_entry * new_request;
aef1f6d0 4018
3f5e193b
NC
4019 new_request = (struct dump_list_entry *)
4020 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4021 if (!new_request)
591a748a 4022 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4023
4024 new_request->name = strdup (section);
4025 if (!new_request->name)
591a748a 4026 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4027
4028 new_request->type = type;
4029
4030 new_request->next = dump_sects_byname;
4031 dump_sects_byname = new_request;
4032}
4033
cf13d699
NC
4034static inline void
4035request_dump (dump_type type)
4036{
4037 int section;
4038 char * cp;
4039
4040 do_dump++;
4041 section = strtoul (optarg, & cp, 0);
4042
4043 if (! *cp && section >= 0)
4044 request_dump_bynumber (section, type);
4045 else
4046 request_dump_byname (optarg, type);
4047}
4048
4049
252b5132 4050static void
2cf0635d 4051parse_args (int argc, char ** argv)
252b5132
RH
4052{
4053 int c;
4054
4055 if (argc < 2)
92f01d61 4056 usage (stderr);
252b5132
RH
4057
4058 while ((c = getopt_long
cf13d699 4059 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 4060 {
252b5132
RH
4061 switch (c)
4062 {
4063 case 0:
4064 /* Long options. */
4065 break;
4066 case 'H':
92f01d61 4067 usage (stdout);
252b5132
RH
4068 break;
4069
4070 case 'a':
b34976b6
AM
4071 do_syms++;
4072 do_reloc++;
4073 do_unwind++;
4074 do_dynamic++;
4075 do_header++;
4076 do_sections++;
f5842774 4077 do_section_groups++;
b34976b6
AM
4078 do_segments++;
4079 do_version++;
4080 do_histogram++;
4081 do_arch++;
4082 do_notes++;
252b5132 4083 break;
f5842774
L
4084 case 'g':
4085 do_section_groups++;
4086 break;
5477e8a0 4087 case 't':
595cf52e 4088 case 'N':
5477e8a0
L
4089 do_sections++;
4090 do_section_details++;
595cf52e 4091 break;
252b5132 4092 case 'e':
b34976b6
AM
4093 do_header++;
4094 do_sections++;
4095 do_segments++;
252b5132 4096 break;
a952a375 4097 case 'A':
b34976b6 4098 do_arch++;
a952a375 4099 break;
252b5132 4100 case 'D':
b34976b6 4101 do_using_dynamic++;
252b5132
RH
4102 break;
4103 case 'r':
b34976b6 4104 do_reloc++;
252b5132 4105 break;
4d6ed7c8 4106 case 'u':
b34976b6 4107 do_unwind++;
4d6ed7c8 4108 break;
252b5132 4109 case 'h':
b34976b6 4110 do_header++;
252b5132
RH
4111 break;
4112 case 'l':
b34976b6 4113 do_segments++;
252b5132
RH
4114 break;
4115 case 's':
b34976b6 4116 do_syms++;
252b5132
RH
4117 break;
4118 case 'S':
b34976b6 4119 do_sections++;
252b5132
RH
4120 break;
4121 case 'd':
b34976b6 4122 do_dynamic++;
252b5132 4123 break;
a952a375 4124 case 'I':
b34976b6 4125 do_histogram++;
a952a375 4126 break;
779fe533 4127 case 'n':
b34976b6 4128 do_notes++;
779fe533 4129 break;
4145f1d5
NC
4130 case 'c':
4131 do_archive_index++;
4132 break;
252b5132 4133 case 'x':
cf13d699 4134 request_dump (HEX_DUMP);
aef1f6d0 4135 break;
09c11c86 4136 case 'p':
cf13d699
NC
4137 request_dump (STRING_DUMP);
4138 break;
4139 case 'R':
4140 request_dump (RELOC_DUMP);
09c11c86 4141 break;
252b5132 4142 case 'w':
b34976b6 4143 do_dump++;
252b5132 4144 if (optarg == 0)
613ff48b
CC
4145 {
4146 do_debugging = 1;
4147 dwarf_select_sections_all ();
4148 }
252b5132
RH
4149 else
4150 {
4151 do_debugging = 0;
4cb93e3b 4152 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4153 }
4154 break;
2979dc34 4155 case OPTION_DEBUG_DUMP:
b34976b6 4156 do_dump++;
2979dc34
JJ
4157 if (optarg == 0)
4158 do_debugging = 1;
4159 else
4160 {
2979dc34 4161 do_debugging = 0;
4cb93e3b 4162 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4163 }
4164 break;
fd2f0033
TT
4165 case OPTION_DWARF_DEPTH:
4166 {
4167 char *cp;
4168
4169 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4170 }
4171 break;
4172 case OPTION_DWARF_START:
4173 {
4174 char *cp;
4175
4176 dwarf_start_die = strtoul (optarg, & cp, 0);
4177 }
4178 break;
4723351a
CC
4179 case OPTION_DWARF_CHECK:
4180 dwarf_check = 1;
4181 break;
2c610e4b
L
4182 case OPTION_DYN_SYMS:
4183 do_dyn_syms++;
4184 break;
252b5132
RH
4185#ifdef SUPPORT_DISASSEMBLY
4186 case 'i':
cf13d699
NC
4187 request_dump (DISASS_DUMP);
4188 break;
252b5132
RH
4189#endif
4190 case 'v':
4191 print_version (program_name);
4192 break;
4193 case 'V':
b34976b6 4194 do_version++;
252b5132 4195 break;
d974e256 4196 case 'W':
b34976b6 4197 do_wide++;
d974e256 4198 break;
252b5132 4199 default:
252b5132
RH
4200 /* xgettext:c-format */
4201 error (_("Invalid option '-%c'\n"), c);
4202 /* Drop through. */
4203 case '?':
92f01d61 4204 usage (stderr);
252b5132
RH
4205 }
4206 }
4207
4d6ed7c8 4208 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4209 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4210 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4211 && !do_section_groups && !do_archive_index
4212 && !do_dyn_syms)
92f01d61 4213 usage (stderr);
252b5132
RH
4214 else if (argc < 3)
4215 {
4216 warn (_("Nothing to do.\n"));
92f01d61 4217 usage (stderr);
252b5132
RH
4218 }
4219}
4220
4221static const char *
d3ba0551 4222get_elf_class (unsigned int elf_class)
252b5132 4223{
b34976b6 4224 static char buff[32];
103f02d3 4225
252b5132
RH
4226 switch (elf_class)
4227 {
4228 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4229 case ELFCLASS32: return "ELF32";
4230 case ELFCLASS64: return "ELF64";
ab5e7794 4231 default:
e9e44622 4232 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4233 return buff;
252b5132
RH
4234 }
4235}
4236
4237static const char *
d3ba0551 4238get_data_encoding (unsigned int encoding)
252b5132 4239{
b34976b6 4240 static char buff[32];
103f02d3 4241
252b5132
RH
4242 switch (encoding)
4243 {
4244 case ELFDATANONE: return _("none");
33c63f9d
CM
4245 case ELFDATA2LSB: return _("2's complement, little endian");
4246 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4247 default:
e9e44622 4248 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4249 return buff;
252b5132
RH
4250 }
4251}
4252
252b5132 4253/* Decode the data held in 'elf_header'. */
ee42cf8c 4254
252b5132 4255static int
d3ba0551 4256process_file_header (void)
252b5132 4257{
b34976b6
AM
4258 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
4259 || elf_header.e_ident[EI_MAG1] != ELFMAG1
4260 || elf_header.e_ident[EI_MAG2] != ELFMAG2
4261 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4262 {
4263 error
4264 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
4265 return 0;
4266 }
4267
2dc4cec1
L
4268 init_dwarf_regnames (elf_header.e_machine);
4269
252b5132
RH
4270 if (do_header)
4271 {
4272 int i;
4273
4274 printf (_("ELF Header:\n"));
4275 printf (_(" Magic: "));
b34976b6
AM
4276 for (i = 0; i < EI_NIDENT; i++)
4277 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
4278 printf ("\n");
4279 printf (_(" Class: %s\n"),
b34976b6 4280 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 4281 printf (_(" Data: %s\n"),
b34976b6 4282 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 4283 printf (_(" Version: %d %s\n"),
b34976b6
AM
4284 elf_header.e_ident[EI_VERSION],
4285 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4286 ? "(current)"
b34976b6 4287 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 4288 ? _("<unknown: %lx>")
789be9f7 4289 : "")));
252b5132 4290 printf (_(" OS/ABI: %s\n"),
b34976b6 4291 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 4292 printf (_(" ABI Version: %d\n"),
b34976b6 4293 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
4294 printf (_(" Type: %s\n"),
4295 get_file_type (elf_header.e_type));
4296 printf (_(" Machine: %s\n"),
4297 get_machine_name (elf_header.e_machine));
4298 printf (_(" Version: 0x%lx\n"),
4299 (unsigned long) elf_header.e_version);
76da6bbe 4300
f7a99963
NC
4301 printf (_(" Entry point address: "));
4302 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4303 printf (_("\n Start of program headers: "));
4304 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4305 printf (_(" (bytes into file)\n Start of section headers: "));
4306 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
4307 printf (_(" (bytes into file)\n"));
76da6bbe 4308
252b5132
RH
4309 printf (_(" Flags: 0x%lx%s\n"),
4310 (unsigned long) elf_header.e_flags,
4311 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
4312 printf (_(" Size of this header: %ld (bytes)\n"),
4313 (long) elf_header.e_ehsize);
4314 printf (_(" Size of program headers: %ld (bytes)\n"),
4315 (long) elf_header.e_phentsize);
2046a35d 4316 printf (_(" Number of program headers: %ld"),
252b5132 4317 (long) elf_header.e_phnum);
2046a35d
AM
4318 if (section_headers != NULL
4319 && elf_header.e_phnum == PN_XNUM
4320 && section_headers[0].sh_info != 0)
cc5914eb 4321 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 4322 putc ('\n', stdout);
252b5132
RH
4323 printf (_(" Size of section headers: %ld (bytes)\n"),
4324 (long) elf_header.e_shentsize);
560f3c1c 4325 printf (_(" Number of section headers: %ld"),
252b5132 4326 (long) elf_header.e_shnum);
4fbb74a6 4327 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
4328 printf (" (%ld)", (long) section_headers[0].sh_size);
4329 putc ('\n', stdout);
4330 printf (_(" Section header string table index: %ld"),
252b5132 4331 (long) elf_header.e_shstrndx);
4fbb74a6
AM
4332 if (section_headers != NULL
4333 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 4334 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
4335 else if (elf_header.e_shstrndx != SHN_UNDEF
4336 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 4337 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4338 putc ('\n', stdout);
4339 }
4340
4341 if (section_headers != NULL)
4342 {
2046a35d
AM
4343 if (elf_header.e_phnum == PN_XNUM
4344 && section_headers[0].sh_info != 0)
4345 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 4346 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 4347 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 4348 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 4349 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 4350 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 4351 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
4352 free (section_headers);
4353 section_headers = NULL;
252b5132 4354 }
103f02d3 4355
9ea033b2
NC
4356 return 1;
4357}
4358
e0a31db1 4359static bfd_boolean
91d6fa6a 4360get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4361{
2cf0635d
NC
4362 Elf32_External_Phdr * phdrs;
4363 Elf32_External_Phdr * external;
4364 Elf_Internal_Phdr * internal;
b34976b6 4365 unsigned int i;
e0a31db1
NC
4366 unsigned int size = elf_header.e_phentsize;
4367 unsigned int num = elf_header.e_phnum;
4368
4369 /* PR binutils/17531: Cope with unexpected section header sizes. */
4370 if (size == 0 || num == 0)
4371 return FALSE;
4372 if (size < sizeof * phdrs)
4373 {
4374 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4375 return FALSE;
4376 }
4377 if (size > sizeof * phdrs)
4378 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4379
3f5e193b 4380 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1
NC
4381 size, num, _("program headers"));
4382 if (phdrs == NULL)
4383 return FALSE;
9ea033b2 4384
91d6fa6a 4385 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4386 i < elf_header.e_phnum;
b34976b6 4387 i++, internal++, external++)
252b5132 4388 {
9ea033b2
NC
4389 internal->p_type = BYTE_GET (external->p_type);
4390 internal->p_offset = BYTE_GET (external->p_offset);
4391 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4392 internal->p_paddr = BYTE_GET (external->p_paddr);
4393 internal->p_filesz = BYTE_GET (external->p_filesz);
4394 internal->p_memsz = BYTE_GET (external->p_memsz);
4395 internal->p_flags = BYTE_GET (external->p_flags);
4396 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4397 }
4398
9ea033b2 4399 free (phdrs);
e0a31db1 4400 return TRUE;
252b5132
RH
4401}
4402
e0a31db1 4403static bfd_boolean
91d6fa6a 4404get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4405{
2cf0635d
NC
4406 Elf64_External_Phdr * phdrs;
4407 Elf64_External_Phdr * external;
4408 Elf_Internal_Phdr * internal;
b34976b6 4409 unsigned int i;
e0a31db1
NC
4410 unsigned int size = elf_header.e_phentsize;
4411 unsigned int num = elf_header.e_phnum;
4412
4413 /* PR binutils/17531: Cope with unexpected section header sizes. */
4414 if (size == 0 || num == 0)
4415 return FALSE;
4416 if (size < sizeof * phdrs)
4417 {
4418 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4419 return FALSE;
4420 }
4421 if (size > sizeof * phdrs)
4422 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4423
3f5e193b 4424 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1 4425 size, num, _("program headers"));
a6e9f9df 4426 if (!phdrs)
e0a31db1 4427 return FALSE;
9ea033b2 4428
91d6fa6a 4429 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4430 i < elf_header.e_phnum;
b34976b6 4431 i++, internal++, external++)
9ea033b2
NC
4432 {
4433 internal->p_type = BYTE_GET (external->p_type);
4434 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4435 internal->p_offset = BYTE_GET (external->p_offset);
4436 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4437 internal->p_paddr = BYTE_GET (external->p_paddr);
4438 internal->p_filesz = BYTE_GET (external->p_filesz);
4439 internal->p_memsz = BYTE_GET (external->p_memsz);
4440 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4441 }
4442
4443 free (phdrs);
e0a31db1 4444 return TRUE;
9ea033b2 4445}
252b5132 4446
d93f0186
NC
4447/* Returns 1 if the program headers were read into `program_headers'. */
4448
4449static int
2cf0635d 4450get_program_headers (FILE * file)
d93f0186 4451{
2cf0635d 4452 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4453
4454 /* Check cache of prior read. */
4455 if (program_headers != NULL)
4456 return 1;
4457
3f5e193b
NC
4458 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
4459 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4460
4461 if (phdrs == NULL)
4462 {
8b73c356
NC
4463 error (_("Out of memory reading %u program headers\n"),
4464 elf_header.e_phnum);
d93f0186
NC
4465 return 0;
4466 }
4467
4468 if (is_32bit_elf
4469 ? get_32bit_program_headers (file, phdrs)
4470 : get_64bit_program_headers (file, phdrs))
4471 {
4472 program_headers = phdrs;
4473 return 1;
4474 }
4475
4476 free (phdrs);
4477 return 0;
4478}
4479
2f62977e
NC
4480/* Returns 1 if the program headers were loaded. */
4481
252b5132 4482static int
2cf0635d 4483process_program_headers (FILE * file)
252b5132 4484{
2cf0635d 4485 Elf_Internal_Phdr * segment;
b34976b6 4486 unsigned int i;
252b5132
RH
4487
4488 if (elf_header.e_phnum == 0)
4489 {
82f2dbf7
NC
4490 /* PR binutils/12467. */
4491 if (elf_header.e_phoff != 0)
4492 warn (_("possibly corrupt ELF header - it has a non-zero program"
9035ed51 4493 " header offset, but no program headers\n"));
82f2dbf7 4494 else if (do_segments)
252b5132 4495 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4496 return 0;
252b5132
RH
4497 }
4498
4499 if (do_segments && !do_header)
4500 {
f7a99963
NC
4501 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4502 printf (_("Entry point "));
4503 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4504 printf (_("\nThere are %d program headers, starting at offset "),
4505 elf_header.e_phnum);
4506 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4507 printf ("\n");
252b5132
RH
4508 }
4509
d93f0186 4510 if (! get_program_headers (file))
252b5132 4511 return 0;
103f02d3 4512
252b5132
RH
4513 if (do_segments)
4514 {
3a1a2036
NC
4515 if (elf_header.e_phnum > 1)
4516 printf (_("\nProgram Headers:\n"));
4517 else
4518 printf (_("\nProgram Headers:\n"));
76da6bbe 4519
f7a99963
NC
4520 if (is_32bit_elf)
4521 printf
4522 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4523 else if (do_wide)
4524 printf
4525 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4526 else
4527 {
4528 printf
4529 (_(" Type Offset VirtAddr PhysAddr\n"));
4530 printf
4531 (_(" FileSiz MemSiz Flags Align\n"));
4532 }
252b5132
RH
4533 }
4534
252b5132 4535 dynamic_addr = 0;
1b228002 4536 dynamic_size = 0;
252b5132
RH
4537
4538 for (i = 0, segment = program_headers;
4539 i < elf_header.e_phnum;
b34976b6 4540 i++, segment++)
252b5132
RH
4541 {
4542 if (do_segments)
4543 {
103f02d3 4544 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4545
4546 if (is_32bit_elf)
4547 {
4548 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4549 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4550 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4551 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4552 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4553 printf ("%c%c%c ",
4554 (segment->p_flags & PF_R ? 'R' : ' '),
4555 (segment->p_flags & PF_W ? 'W' : ' '),
4556 (segment->p_flags & PF_X ? 'E' : ' '));
4557 printf ("%#lx", (unsigned long) segment->p_align);
4558 }
d974e256
JJ
4559 else if (do_wide)
4560 {
4561 if ((unsigned long) segment->p_offset == segment->p_offset)
4562 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4563 else
4564 {
4565 print_vma (segment->p_offset, FULL_HEX);
4566 putchar (' ');
4567 }
4568
4569 print_vma (segment->p_vaddr, FULL_HEX);
4570 putchar (' ');
4571 print_vma (segment->p_paddr, FULL_HEX);
4572 putchar (' ');
4573
4574 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4575 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4576 else
4577 {
4578 print_vma (segment->p_filesz, FULL_HEX);
4579 putchar (' ');
4580 }
4581
4582 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4583 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4584 else
4585 {
f48e6c45 4586 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4587 }
4588
4589 printf (" %c%c%c ",
4590 (segment->p_flags & PF_R ? 'R' : ' '),
4591 (segment->p_flags & PF_W ? 'W' : ' '),
4592 (segment->p_flags & PF_X ? 'E' : ' '));
4593
4594 if ((unsigned long) segment->p_align == segment->p_align)
4595 printf ("%#lx", (unsigned long) segment->p_align);
4596 else
4597 {
4598 print_vma (segment->p_align, PREFIX_HEX);
4599 }
4600 }
f7a99963
NC
4601 else
4602 {
4603 print_vma (segment->p_offset, FULL_HEX);
4604 putchar (' ');
4605 print_vma (segment->p_vaddr, FULL_HEX);
4606 putchar (' ');
4607 print_vma (segment->p_paddr, FULL_HEX);
4608 printf ("\n ");
4609 print_vma (segment->p_filesz, FULL_HEX);
4610 putchar (' ');
4611 print_vma (segment->p_memsz, FULL_HEX);
4612 printf (" %c%c%c ",
4613 (segment->p_flags & PF_R ? 'R' : ' '),
4614 (segment->p_flags & PF_W ? 'W' : ' '),
4615 (segment->p_flags & PF_X ? 'E' : ' '));
4616 print_vma (segment->p_align, HEX);
4617 }
252b5132
RH
4618 }
4619
f54498b4
NC
4620 if (do_segments)
4621 putc ('\n', stdout);
4622
252b5132
RH
4623 switch (segment->p_type)
4624 {
252b5132
RH
4625 case PT_DYNAMIC:
4626 if (dynamic_addr)
4627 error (_("more than one dynamic segment\n"));
4628
20737c13
AM
4629 /* By default, assume that the .dynamic section is the first
4630 section in the DYNAMIC segment. */
4631 dynamic_addr = segment->p_offset;
4632 dynamic_size = segment->p_filesz;
f54498b4
NC
4633 /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
4634 if (dynamic_addr + dynamic_size >= current_file_size)
4635 {
4636 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
4637 dynamic_addr = dynamic_size = 0;
4638 }
20737c13 4639
b2d38a17
NC
4640 /* Try to locate the .dynamic section. If there is
4641 a section header table, we can easily locate it. */
4642 if (section_headers != NULL)
4643 {
2cf0635d 4644 Elf_Internal_Shdr * sec;
b2d38a17 4645
89fac5e3
RS
4646 sec = find_section (".dynamic");
4647 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4648 {
28f997cf
TG
4649 /* A corresponding .dynamic section is expected, but on
4650 IA-64/OpenVMS it is OK for it to be missing. */
4651 if (!is_ia64_vms ())
4652 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4653 break;
4654 }
4655
42bb2e33 4656 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4657 {
4658 dynamic_size = 0;
4659 break;
4660 }
42bb2e33 4661
b2d38a17
NC
4662 dynamic_addr = sec->sh_offset;
4663 dynamic_size = sec->sh_size;
4664
4665 if (dynamic_addr < segment->p_offset
4666 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4667 warn (_("the .dynamic section is not contained"
4668 " within the dynamic segment\n"));
b2d38a17 4669 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4670 warn (_("the .dynamic section is not the first section"
4671 " in the dynamic segment.\n"));
b2d38a17 4672 }
252b5132
RH
4673 break;
4674
4675 case PT_INTERP:
fb52b2f4
NC
4676 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4677 SEEK_SET))
252b5132
RH
4678 error (_("Unable to find program interpreter name\n"));
4679 else
4680 {
f8eae8b2 4681 char fmt [32];
9495b2e6 4682 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
4683
4684 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4685 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4686
252b5132 4687 program_interpreter[0] = 0;
7bd7b3ef
AM
4688 if (fscanf (file, fmt, program_interpreter) <= 0)
4689 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4690
4691 if (do_segments)
f54498b4 4692 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
4693 program_interpreter);
4694 }
4695 break;
4696 }
252b5132
RH
4697 }
4698
c256ffe7 4699 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4700 {
4701 printf (_("\n Section to Segment mapping:\n"));
4702 printf (_(" Segment Sections...\n"));
4703
252b5132
RH
4704 for (i = 0; i < elf_header.e_phnum; i++)
4705 {
9ad5cbcf 4706 unsigned int j;
2cf0635d 4707 Elf_Internal_Shdr * section;
252b5132
RH
4708
4709 segment = program_headers + i;
b391a3e3 4710 section = section_headers + 1;
252b5132
RH
4711
4712 printf (" %2.2d ", i);
4713
b34976b6 4714 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4715 {
f4638467
AM
4716 if (!ELF_TBSS_SPECIAL (section, segment)
4717 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
74e1a04b 4718 printf ("%s ", printable_section_name (section));
252b5132
RH
4719 }
4720
4721 putc ('\n',stdout);
4722 }
4723 }
4724
252b5132
RH
4725 return 1;
4726}
4727
4728
d93f0186
NC
4729/* Find the file offset corresponding to VMA by using the program headers. */
4730
4731static long
2cf0635d 4732offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4733{
2cf0635d 4734 Elf_Internal_Phdr * seg;
d93f0186
NC
4735
4736 if (! get_program_headers (file))
4737 {
4738 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4739 return (long) vma;
4740 }
4741
4742 for (seg = program_headers;
4743 seg < program_headers + elf_header.e_phnum;
4744 ++seg)
4745 {
4746 if (seg->p_type != PT_LOAD)
4747 continue;
4748
4749 if (vma >= (seg->p_vaddr & -seg->p_align)
4750 && vma + size <= seg->p_vaddr + seg->p_filesz)
4751 return vma - seg->p_vaddr + seg->p_offset;
4752 }
4753
4754 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4755 (unsigned long) vma);
d93f0186
NC
4756 return (long) vma;
4757}
4758
4759
049b0c3a
NC
4760/* Allocate memory and load the sections headers into the global pointer
4761 SECTION_HEADERS. If PROBE is true, this is just a probe and we do not
4762 generate any error messages if the load fails. */
4763
4764static bfd_boolean
4765get_32bit_section_headers (FILE * file, bfd_boolean probe)
252b5132 4766{
2cf0635d
NC
4767 Elf32_External_Shdr * shdrs;
4768 Elf_Internal_Shdr * internal;
b34976b6 4769 unsigned int i;
049b0c3a
NC
4770 unsigned int size = elf_header.e_shentsize;
4771 unsigned int num = probe ? 1 : elf_header.e_shnum;
4772
4773 /* PR binutils/17531: Cope with unexpected section header sizes. */
4774 if (size == 0 || num == 0)
4775 return FALSE;
4776 if (size < sizeof * shdrs)
4777 {
4778 if (! probe)
4779 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4780 return FALSE;
4781 }
4782 if (!probe && size > sizeof * shdrs)
4783 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 4784
3f5e193b 4785 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4786 size, num,
4787 probe ? NULL : _("section headers"));
4788 if (shdrs == NULL)
4789 return FALSE;
252b5132 4790
049b0c3a
NC
4791 if (section_headers != NULL)
4792 free (section_headers);
3f5e193b
NC
4793 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4794 sizeof (Elf_Internal_Shdr));
252b5132
RH
4795 if (section_headers == NULL)
4796 {
049b0c3a 4797 if (!probe)
8b73c356 4798 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4799 return FALSE;
252b5132
RH
4800 }
4801
4802 for (i = 0, internal = section_headers;
560f3c1c 4803 i < num;
b34976b6 4804 i++, internal++)
252b5132
RH
4805 {
4806 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4807 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4808 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4809 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4810 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4811 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4812 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4813 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4814 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4815 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4816 }
4817
4818 free (shdrs);
049b0c3a 4819 return TRUE;
252b5132
RH
4820}
4821
049b0c3a
NC
4822static bfd_boolean
4823get_64bit_section_headers (FILE * file, bfd_boolean probe)
9ea033b2 4824{
2cf0635d
NC
4825 Elf64_External_Shdr * shdrs;
4826 Elf_Internal_Shdr * internal;
b34976b6 4827 unsigned int i;
049b0c3a
NC
4828 unsigned int size = elf_header.e_shentsize;
4829 unsigned int num = probe ? 1 : elf_header.e_shnum;
4830
4831 /* PR binutils/17531: Cope with unexpected section header sizes. */
4832 if (size == 0 || num == 0)
4833 return FALSE;
4834 if (size < sizeof * shdrs)
4835 {
4836 if (! probe)
4837 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4838 return FALSE;
4839 }
4840 if (! probe && size > sizeof * shdrs)
4841 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 4842
3f5e193b 4843 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4844 size, num,
4845 probe ? NULL : _("section headers"));
4846 if (shdrs == NULL)
4847 return FALSE;
9ea033b2 4848
049b0c3a
NC
4849 if (section_headers != NULL)
4850 free (section_headers);
3f5e193b
NC
4851 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4852 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4853 if (section_headers == NULL)
4854 {
049b0c3a 4855 if (! probe)
8b73c356 4856 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4857 return FALSE;
9ea033b2
NC
4858 }
4859
4860 for (i = 0, internal = section_headers;
560f3c1c 4861 i < num;
b34976b6 4862 i++, internal++)
9ea033b2
NC
4863 {
4864 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4865 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4866 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4867 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4868 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4869 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4870 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4871 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4872 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4873 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4874 }
4875
4876 free (shdrs);
049b0c3a 4877 return TRUE;
9ea033b2
NC
4878}
4879
252b5132 4880static Elf_Internal_Sym *
ba5cdace
NC
4881get_32bit_elf_symbols (FILE * file,
4882 Elf_Internal_Shdr * section,
4883 unsigned long * num_syms_return)
252b5132 4884{
ba5cdace 4885 unsigned long number = 0;
dd24e3da 4886 Elf32_External_Sym * esyms = NULL;
ba5cdace 4887 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4888 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4889 Elf_Internal_Sym * psym;
b34976b6 4890 unsigned int j;
252b5132 4891
c9c1d674
EG
4892 if (section->sh_size == 0)
4893 {
4894 if (num_syms_return != NULL)
4895 * num_syms_return = 0;
4896 return NULL;
4897 }
4898
dd24e3da 4899 /* Run some sanity checks first. */
c9c1d674 4900 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 4901 {
c9c1d674
EG
4902 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
4903 printable_section_name (section), (unsigned long) section->sh_entsize);
ba5cdace 4904 goto exit_point;
dd24e3da
NC
4905 }
4906
f54498b4
NC
4907 if (section->sh_size > current_file_size)
4908 {
4909 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
74e1a04b 4910 printable_section_name (section), (unsigned long) section->sh_size);
f54498b4
NC
4911 goto exit_point;
4912 }
4913
dd24e3da
NC
4914 number = section->sh_size / section->sh_entsize;
4915
4916 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4917 {
c9c1d674 4918 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
4919 (unsigned long) section->sh_size,
4920 printable_section_name (section),
4921 (unsigned long) section->sh_entsize);
ba5cdace 4922 goto exit_point;
dd24e3da
NC
4923 }
4924
3f5e193b
NC
4925 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4926 section->sh_size, _("symbols"));
dd24e3da 4927 if (esyms == NULL)
ba5cdace 4928 goto exit_point;
252b5132 4929
9ad5cbcf
AM
4930 shndx = NULL;
4931 if (symtab_shndx_hdr != NULL
4932 && (symtab_shndx_hdr->sh_link
4fbb74a6 4933 == (unsigned long) (section - section_headers)))
9ad5cbcf 4934 {
3f5e193b
NC
4935 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4936 symtab_shndx_hdr->sh_offset,
4937 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4938 _("symbol table section indicies"));
dd24e3da
NC
4939 if (shndx == NULL)
4940 goto exit_point;
c9c1d674
EG
4941 /* PR17531: file: heap-buffer-overflow */
4942 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
4943 {
4944 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
4945 printable_section_name (symtab_shndx_hdr),
4946 (unsigned long) symtab_shndx_hdr->sh_size,
4947 (unsigned long) section->sh_size);
4948 goto exit_point;
4949 }
9ad5cbcf
AM
4950 }
4951
3f5e193b 4952 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4953
4954 if (isyms == NULL)
4955 {
8b73c356
NC
4956 error (_("Out of memory reading %lu symbols\n"),
4957 (unsigned long) number);
dd24e3da 4958 goto exit_point;
252b5132
RH
4959 }
4960
dd24e3da 4961 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4962 {
4963 psym->st_name = BYTE_GET (esyms[j].st_name);
4964 psym->st_value = BYTE_GET (esyms[j].st_value);
4965 psym->st_size = BYTE_GET (esyms[j].st_size);
4966 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4967 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4968 psym->st_shndx
4969 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4970 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4971 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4972 psym->st_info = BYTE_GET (esyms[j].st_info);
4973 psym->st_other = BYTE_GET (esyms[j].st_other);
4974 }
4975
dd24e3da 4976 exit_point:
ba5cdace 4977 if (shndx != NULL)
9ad5cbcf 4978 free (shndx);
ba5cdace 4979 if (esyms != NULL)
dd24e3da 4980 free (esyms);
252b5132 4981
ba5cdace
NC
4982 if (num_syms_return != NULL)
4983 * num_syms_return = isyms == NULL ? 0 : number;
4984
252b5132
RH
4985 return isyms;
4986}
4987
9ea033b2 4988static Elf_Internal_Sym *
ba5cdace
NC
4989get_64bit_elf_symbols (FILE * file,
4990 Elf_Internal_Shdr * section,
4991 unsigned long * num_syms_return)
9ea033b2 4992{
ba5cdace
NC
4993 unsigned long number = 0;
4994 Elf64_External_Sym * esyms = NULL;
4995 Elf_External_Sym_Shndx * shndx = NULL;
4996 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4997 Elf_Internal_Sym * psym;
b34976b6 4998 unsigned int j;
9ea033b2 4999
c9c1d674
EG
5000 if (section->sh_size == 0)
5001 {
5002 if (num_syms_return != NULL)
5003 * num_syms_return = 0;
5004 return NULL;
5005 }
5006
dd24e3da 5007 /* Run some sanity checks first. */
c9c1d674 5008 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5009 {
c9c1d674 5010 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
8066deb1
AM
5011 printable_section_name (section),
5012 (unsigned long) section->sh_entsize);
ba5cdace 5013 goto exit_point;
dd24e3da
NC
5014 }
5015
f54498b4
NC
5016 if (section->sh_size > current_file_size)
5017 {
5018 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
8066deb1
AM
5019 printable_section_name (section),
5020 (unsigned long) section->sh_size);
f54498b4
NC
5021 goto exit_point;
5022 }
5023
dd24e3da
NC
5024 number = section->sh_size / section->sh_entsize;
5025
5026 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5027 {
c9c1d674 5028 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
5029 (unsigned long) section->sh_size,
5030 printable_section_name (section),
5031 (unsigned long) section->sh_entsize);
ba5cdace 5032 goto exit_point;
dd24e3da
NC
5033 }
5034
3f5e193b
NC
5035 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
5036 section->sh_size, _("symbols"));
a6e9f9df 5037 if (!esyms)
ba5cdace 5038 goto exit_point;
9ea033b2 5039
9ad5cbcf
AM
5040 if (symtab_shndx_hdr != NULL
5041 && (symtab_shndx_hdr->sh_link
4fbb74a6 5042 == (unsigned long) (section - section_headers)))
9ad5cbcf 5043 {
3f5e193b
NC
5044 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
5045 symtab_shndx_hdr->sh_offset,
5046 1, symtab_shndx_hdr->sh_size,
9cf03b7e 5047 _("symbol table section indicies"));
ba5cdace
NC
5048 if (shndx == NULL)
5049 goto exit_point;
c9c1d674
EG
5050 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5051 {
5052 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5053 printable_section_name (symtab_shndx_hdr),
5054 (unsigned long) symtab_shndx_hdr->sh_size,
5055 (unsigned long) section->sh_size);
5056 goto exit_point;
5057 }
9ad5cbcf
AM
5058 }
5059
3f5e193b 5060 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5061
5062 if (isyms == NULL)
5063 {
8b73c356
NC
5064 error (_("Out of memory reading %lu symbols\n"),
5065 (unsigned long) number);
ba5cdace 5066 goto exit_point;
9ea033b2
NC
5067 }
5068
ba5cdace 5069 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5070 {
5071 psym->st_name = BYTE_GET (esyms[j].st_name);
5072 psym->st_info = BYTE_GET (esyms[j].st_info);
5073 psym->st_other = BYTE_GET (esyms[j].st_other);
5074 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5075
4fbb74a6 5076 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5077 psym->st_shndx
5078 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5079 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5080 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5081
66543521
AM
5082 psym->st_value = BYTE_GET (esyms[j].st_value);
5083 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5084 }
5085
ba5cdace
NC
5086 exit_point:
5087 if (shndx != NULL)
9ad5cbcf 5088 free (shndx);
ba5cdace
NC
5089 if (esyms != NULL)
5090 free (esyms);
5091
5092 if (num_syms_return != NULL)
5093 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5094
5095 return isyms;
5096}
5097
d1133906 5098static const char *
d3ba0551 5099get_elf_section_flags (bfd_vma sh_flags)
d1133906 5100{
5477e8a0 5101 static char buff[1024];
2cf0635d 5102 char * p = buff;
8d5ff12c 5103 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
5104 int sindex;
5105 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5106 bfd_vma os_flags = 0;
5107 bfd_vma proc_flags = 0;
5108 bfd_vma unknown_flags = 0;
148b93f2 5109 static const struct
5477e8a0 5110 {
2cf0635d 5111 const char * str;
5477e8a0
L
5112 int len;
5113 }
5114 flags [] =
5115 {
cfcac11d
NC
5116 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5117 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5118 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5119 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5120 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5121 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5122 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5123 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5124 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5125 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5126 /* IA-64 specific. */
5127 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5128 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5129 /* IA-64 OpenVMS specific. */
5130 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5131 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5132 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5133 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5134 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5135 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5136 /* Generic. */
cfcac11d 5137 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5138 /* SPARC specific. */
cfcac11d 5139 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
5140 };
5141
5142 if (do_section_details)
5143 {
8d5ff12c
L
5144 sprintf (buff, "[%*.*lx]: ",
5145 field_size, field_size, (unsigned long) sh_flags);
5146 p += field_size + 4;
5477e8a0 5147 }
76da6bbe 5148
d1133906
NC
5149 while (sh_flags)
5150 {
5151 bfd_vma flag;
5152
5153 flag = sh_flags & - sh_flags;
5154 sh_flags &= ~ flag;
76da6bbe 5155
5477e8a0 5156 if (do_section_details)
d1133906 5157 {
5477e8a0
L
5158 switch (flag)
5159 {
91d6fa6a
NC
5160 case SHF_WRITE: sindex = 0; break;
5161 case SHF_ALLOC: sindex = 1; break;
5162 case SHF_EXECINSTR: sindex = 2; break;
5163 case SHF_MERGE: sindex = 3; break;
5164 case SHF_STRINGS: sindex = 4; break;
5165 case SHF_INFO_LINK: sindex = 5; break;
5166 case SHF_LINK_ORDER: sindex = 6; break;
5167 case SHF_OS_NONCONFORMING: sindex = 7; break;
5168 case SHF_GROUP: sindex = 8; break;
5169 case SHF_TLS: sindex = 9; break;
18ae9cc1 5170 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 5171
5477e8a0 5172 default:
91d6fa6a 5173 sindex = -1;
cfcac11d 5174 switch (elf_header.e_machine)
148b93f2 5175 {
cfcac11d 5176 case EM_IA_64:
148b93f2 5177 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5178 sindex = 10;
148b93f2 5179 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5180 sindex = 11;
148b93f2
NC
5181#ifdef BFD64
5182 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
5183 switch (flag)
5184 {
91d6fa6a
NC
5185 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5186 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5187 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5188 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5189 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5190 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5191 default: break;
5192 }
5193#endif
cfcac11d
NC
5194 break;
5195
caa83f8b
NC
5196 case EM_386:
5197 case EM_486:
5198 case EM_X86_64:
7f502d6c 5199 case EM_L1OM:
7a9068fe 5200 case EM_K1OM:
cfcac11d
NC
5201 case EM_OLD_SPARCV9:
5202 case EM_SPARC32PLUS:
5203 case EM_SPARCV9:
5204 case EM_SPARC:
18ae9cc1 5205 if (flag == SHF_ORDERED)
91d6fa6a 5206 sindex = 19;
cfcac11d
NC
5207 break;
5208 default:
5209 break;
148b93f2 5210 }
5477e8a0
L
5211 }
5212
91d6fa6a 5213 if (sindex != -1)
5477e8a0 5214 {
8d5ff12c
L
5215 if (p != buff + field_size + 4)
5216 {
5217 if (size < (10 + 2))
bee0ee85
NC
5218 {
5219 warn (_("Internal error: not enough buffer room for section flag info"));
5220 return _("<unknown>");
5221 }
8d5ff12c
L
5222 size -= 2;
5223 *p++ = ',';
5224 *p++ = ' ';
5225 }
5226
91d6fa6a
NC
5227 size -= flags [sindex].len;
5228 p = stpcpy (p, flags [sindex].str);
5477e8a0 5229 }
3b22753a 5230 else if (flag & SHF_MASKOS)
8d5ff12c 5231 os_flags |= flag;
d1133906 5232 else if (flag & SHF_MASKPROC)
8d5ff12c 5233 proc_flags |= flag;
d1133906 5234 else
8d5ff12c 5235 unknown_flags |= flag;
5477e8a0
L
5236 }
5237 else
5238 {
5239 switch (flag)
5240 {
5241 case SHF_WRITE: *p = 'W'; break;
5242 case SHF_ALLOC: *p = 'A'; break;
5243 case SHF_EXECINSTR: *p = 'X'; break;
5244 case SHF_MERGE: *p = 'M'; break;
5245 case SHF_STRINGS: *p = 'S'; break;
5246 case SHF_INFO_LINK: *p = 'I'; break;
5247 case SHF_LINK_ORDER: *p = 'L'; break;
5248 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5249 case SHF_GROUP: *p = 'G'; break;
5250 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5251 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
5252
5253 default:
8a9036a4 5254 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
5255 || elf_header.e_machine == EM_L1OM
5256 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
5257 && flag == SHF_X86_64_LARGE)
5258 *p = 'l';
5259 else if (flag & SHF_MASKOS)
5260 {
5261 *p = 'o';
5262 sh_flags &= ~ SHF_MASKOS;
5263 }
5264 else if (flag & SHF_MASKPROC)
5265 {
5266 *p = 'p';
5267 sh_flags &= ~ SHF_MASKPROC;
5268 }
5269 else
5270 *p = 'x';
5271 break;
5272 }
5273 p++;
d1133906
NC
5274 }
5275 }
76da6bbe 5276
8d5ff12c
L
5277 if (do_section_details)
5278 {
5279 if (os_flags)
5280 {
5281 size -= 5 + field_size;
5282 if (p != buff + field_size + 4)
5283 {
5284 if (size < (2 + 1))
bee0ee85
NC
5285 {
5286 warn (_("Internal error: not enough buffer room for section flag info"));
5287 return _("<unknown>");
5288 }
8d5ff12c
L
5289 size -= 2;
5290 *p++ = ',';
5291 *p++ = ' ';
5292 }
5293 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5294 (unsigned long) os_flags);
5295 p += 5 + field_size;
5296 }
5297 if (proc_flags)
5298 {
5299 size -= 7 + field_size;
5300 if (p != buff + field_size + 4)
5301 {
5302 if (size < (2 + 1))
bee0ee85
NC
5303 {
5304 warn (_("Internal error: not enough buffer room for section flag info"));
5305 return _("<unknown>");
5306 }
8d5ff12c
L
5307 size -= 2;
5308 *p++ = ',';
5309 *p++ = ' ';
5310 }
5311 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5312 (unsigned long) proc_flags);
5313 p += 7 + field_size;
5314 }
5315 if (unknown_flags)
5316 {
5317 size -= 10 + field_size;
5318 if (p != buff + field_size + 4)
5319 {
5320 if (size < (2 + 1))
bee0ee85
NC
5321 {
5322 warn (_("Internal error: not enough buffer room for section flag info"));
5323 return _("<unknown>");
5324 }
8d5ff12c
L
5325 size -= 2;
5326 *p++ = ',';
5327 *p++ = ' ';
5328 }
2b692964 5329 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5330 (unsigned long) unknown_flags);
5331 p += 10 + field_size;
5332 }
5333 }
5334
e9e44622 5335 *p = '\0';
d1133906
NC
5336 return buff;
5337}
5338
252b5132 5339static int
2cf0635d 5340process_section_headers (FILE * file)
252b5132 5341{
2cf0635d 5342 Elf_Internal_Shdr * section;
b34976b6 5343 unsigned int i;
252b5132
RH
5344
5345 section_headers = NULL;
5346
5347 if (elf_header.e_shnum == 0)
5348 {
82f2dbf7
NC
5349 /* PR binutils/12467. */
5350 if (elf_header.e_shoff != 0)
5351 warn (_("possibly corrupt ELF file header - it has a non-zero"
5352 " section header offset, but no section headers\n"));
5353 else if (do_sections)
252b5132
RH
5354 printf (_("\nThere are no sections in this file.\n"));
5355
5356 return 1;
5357 }
5358
5359 if (do_sections && !do_header)
9ea033b2 5360 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
5361 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
5362
9ea033b2
NC
5363 if (is_32bit_elf)
5364 {
049b0c3a 5365 if (! get_32bit_section_headers (file, FALSE))
9ea033b2
NC
5366 return 0;
5367 }
049b0c3a 5368 else if (! get_64bit_section_headers (file, FALSE))
252b5132
RH
5369 return 0;
5370
5371 /* Read in the string table, so that we have names to display. */
0b49d371 5372 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 5373 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 5374 {
4fbb74a6 5375 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 5376
c256ffe7
JJ
5377 if (section->sh_size != 0)
5378 {
3f5e193b
NC
5379 string_table = (char *) get_data (NULL, file, section->sh_offset,
5380 1, section->sh_size,
5381 _("string table"));
0de14b54 5382
c256ffe7
JJ
5383 string_table_length = string_table != NULL ? section->sh_size : 0;
5384 }
252b5132
RH
5385 }
5386
5387 /* Scan the sections for the dynamic symbol table
e3c8793a 5388 and dynamic string table and debug sections. */
252b5132
RH
5389 dynamic_symbols = NULL;
5390 dynamic_strings = NULL;
5391 dynamic_syminfo = NULL;
f1ef08cb 5392 symtab_shndx_hdr = NULL;
103f02d3 5393
89fac5e3
RS
5394 eh_addr_size = is_32bit_elf ? 4 : 8;
5395 switch (elf_header.e_machine)
5396 {
5397 case EM_MIPS:
5398 case EM_MIPS_RS3_LE:
5399 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5400 FDE addresses. However, the ABI also has a semi-official ILP32
5401 variant for which the normal FDE address size rules apply.
5402
5403 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5404 section, where XX is the size of longs in bits. Unfortunately,
5405 earlier compilers provided no way of distinguishing ILP32 objects
5406 from LP64 objects, so if there's any doubt, we should assume that
5407 the official LP64 form is being used. */
5408 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5409 && find_section (".gcc_compiled_long32") == NULL)
5410 eh_addr_size = 8;
5411 break;
0f56a26a
DD
5412
5413 case EM_H8_300:
5414 case EM_H8_300H:
5415 switch (elf_header.e_flags & EF_H8_MACH)
5416 {
5417 case E_H8_MACH_H8300:
5418 case E_H8_MACH_H8300HN:
5419 case E_H8_MACH_H8300SN:
5420 case E_H8_MACH_H8300SXN:
5421 eh_addr_size = 2;
5422 break;
5423 case E_H8_MACH_H8300H:
5424 case E_H8_MACH_H8300S:
5425 case E_H8_MACH_H8300SX:
5426 eh_addr_size = 4;
5427 break;
5428 }
f4236fe4
DD
5429 break;
5430
ff7eeb89 5431 case EM_M32C_OLD:
f4236fe4
DD
5432 case EM_M32C:
5433 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5434 {
5435 case EF_M32C_CPU_M16C:
5436 eh_addr_size = 2;
5437 break;
5438 }
5439 break;
89fac5e3
RS
5440 }
5441
76ca31c0
NC
5442#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5443 do \
5444 { \
5445 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
5446 if (section->sh_entsize != expected_entsize) \
9dd3a467 5447 { \
76ca31c0
NC
5448 char buf[40]; \
5449 sprintf_vma (buf, section->sh_entsize); \
5450 /* Note: coded this way so that there is a single string for \
5451 translation. */ \
5452 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
5453 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
5454 (unsigned) expected_entsize); \
9dd3a467 5455 section->sh_entsize = expected_entsize; \
76ca31c0
NC
5456 } \
5457 } \
08d8fa11 5458 while (0)
9dd3a467
NC
5459
5460#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5461 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5462 sizeof (Elf64_External_##type))
5463
252b5132
RH
5464 for (i = 0, section = section_headers;
5465 i < elf_header.e_shnum;
b34976b6 5466 i++, section++)
252b5132 5467 {
2cf0635d 5468 char * name = SECTION_NAME (section);
252b5132
RH
5469
5470 if (section->sh_type == SHT_DYNSYM)
5471 {
5472 if (dynamic_symbols != NULL)
5473 {
5474 error (_("File contains multiple dynamic symbol tables\n"));
5475 continue;
5476 }
5477
08d8fa11 5478 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5479 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5480 }
5481 else if (section->sh_type == SHT_STRTAB
18bd398b 5482 && streq (name, ".dynstr"))
252b5132
RH
5483 {
5484 if (dynamic_strings != NULL)
5485 {
5486 error (_("File contains multiple dynamic string tables\n"));
5487 continue;
5488 }
5489
3f5e193b
NC
5490 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5491 1, section->sh_size,
5492 _("dynamic strings"));
59245841 5493 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5494 }
9ad5cbcf
AM
5495 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5496 {
5497 if (symtab_shndx_hdr != NULL)
5498 {
5499 error (_("File contains multiple symtab shndx tables\n"));
5500 continue;
5501 }
5502 symtab_shndx_hdr = section;
5503 }
08d8fa11
JJ
5504 else if (section->sh_type == SHT_SYMTAB)
5505 CHECK_ENTSIZE (section, i, Sym);
5506 else if (section->sh_type == SHT_GROUP)
5507 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5508 else if (section->sh_type == SHT_REL)
5509 CHECK_ENTSIZE (section, i, Rel);
5510 else if (section->sh_type == SHT_RELA)
5511 CHECK_ENTSIZE (section, i, Rela);
252b5132 5512 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5513 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5514 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5515 || do_debug_str || do_debug_loc || do_debug_ranges
5516 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5517 && (const_strneq (name, ".debug_")
5518 || const_strneq (name, ".zdebug_")))
252b5132 5519 {
1b315056
CS
5520 if (name[1] == 'z')
5521 name += sizeof (".zdebug_") - 1;
5522 else
5523 name += sizeof (".debug_") - 1;
252b5132
RH
5524
5525 if (do_debugging
4723351a
CC
5526 || (do_debug_info && const_strneq (name, "info"))
5527 || (do_debug_info && const_strneq (name, "types"))
5528 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5529 || (do_debug_lines && strcmp (name, "line") == 0)
5530 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5531 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5532 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5533 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5534 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5535 || (do_debug_aranges && const_strneq (name, "aranges"))
5536 || (do_debug_ranges && const_strneq (name, "ranges"))
5537 || (do_debug_frames && const_strneq (name, "frame"))
5538 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5539 || (do_debug_macinfo && const_strneq (name, "macro"))
5540 || (do_debug_str && const_strneq (name, "str"))
5541 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5542 || (do_debug_addr && const_strneq (name, "addr"))
5543 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5544 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5545 )
09c11c86 5546 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5547 }
a262ae96 5548 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5549 else if ((do_debugging || do_debug_info)
0112cd26 5550 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5551 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5552 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5553 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5554 else if (do_gdb_index && streq (name, ".gdb_index"))
5555 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5556 /* Trace sections for Itanium VMS. */
5557 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5558 || do_trace_aranges)
5559 && const_strneq (name, ".trace_"))
5560 {
5561 name += sizeof (".trace_") - 1;
5562
5563 if (do_debugging
5564 || (do_trace_info && streq (name, "info"))
5565 || (do_trace_abbrevs && streq (name, "abbrev"))
5566 || (do_trace_aranges && streq (name, "aranges"))
5567 )
5568 request_dump_bynumber (i, DEBUG_DUMP);
5569 }
252b5132
RH
5570 }
5571
5572 if (! do_sections)
5573 return 1;
5574
3a1a2036
NC
5575 if (elf_header.e_shnum > 1)
5576 printf (_("\nSection Headers:\n"));
5577 else
5578 printf (_("\nSection Header:\n"));
76da6bbe 5579
f7a99963 5580 if (is_32bit_elf)
595cf52e 5581 {
5477e8a0 5582 if (do_section_details)
595cf52e
L
5583 {
5584 printf (_(" [Nr] Name\n"));
5477e8a0 5585 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5586 }
5587 else
5588 printf
5589 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5590 }
d974e256 5591 else if (do_wide)
595cf52e 5592 {
5477e8a0 5593 if (do_section_details)
595cf52e
L
5594 {
5595 printf (_(" [Nr] Name\n"));
5477e8a0 5596 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5597 }
5598 else
5599 printf
5600 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5601 }
f7a99963
NC
5602 else
5603 {
5477e8a0 5604 if (do_section_details)
595cf52e
L
5605 {
5606 printf (_(" [Nr] Name\n"));
5477e8a0
L
5607 printf (_(" Type Address Offset Link\n"));
5608 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5609 }
5610 else
5611 {
5612 printf (_(" [Nr] Name Type Address Offset\n"));
5613 printf (_(" Size EntSize Flags Link Info Align\n"));
5614 }
f7a99963 5615 }
252b5132 5616
5477e8a0
L
5617 if (do_section_details)
5618 printf (_(" Flags\n"));
5619
252b5132
RH
5620 for (i = 0, section = section_headers;
5621 i < elf_header.e_shnum;
b34976b6 5622 i++, section++)
252b5132 5623 {
7bfd842d 5624 printf (" [%2u] ", i);
5477e8a0 5625 if (do_section_details)
74e1a04b 5626 printf ("%s\n ", printable_section_name (section));
595cf52e 5627 else
74e1a04b 5628 print_symbol (-17, SECTION_NAME (section));
0b4362b0 5629
ea52a088
NC
5630 printf (do_wide ? " %-15s " : " %-15.15s ",
5631 get_section_type_name (section->sh_type));
0b4362b0 5632
f7a99963
NC
5633 if (is_32bit_elf)
5634 {
cfcac11d
NC
5635 const char * link_too_big = NULL;
5636
f7a99963 5637 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5638
f7a99963
NC
5639 printf ( " %6.6lx %6.6lx %2.2lx",
5640 (unsigned long) section->sh_offset,
5641 (unsigned long) section->sh_size,
5642 (unsigned long) section->sh_entsize);
d1133906 5643
5477e8a0
L
5644 if (do_section_details)
5645 fputs (" ", stdout);
5646 else
5647 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5648
cfcac11d
NC
5649 if (section->sh_link >= elf_header.e_shnum)
5650 {
5651 link_too_big = "";
5652 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5653 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5654 switch (elf_header.e_machine)
5655 {
caa83f8b
NC
5656 case EM_386:
5657 case EM_486:
5658 case EM_X86_64:
7f502d6c 5659 case EM_L1OM:
7a9068fe 5660 case EM_K1OM:
cfcac11d
NC
5661 case EM_OLD_SPARCV9:
5662 case EM_SPARC32PLUS:
5663 case EM_SPARCV9:
5664 case EM_SPARC:
5665 if (section->sh_link == (SHN_BEFORE & 0xffff))
5666 link_too_big = "BEFORE";
5667 else if (section->sh_link == (SHN_AFTER & 0xffff))
5668 link_too_big = "AFTER";
5669 break;
5670 default:
5671 break;
5672 }
5673 }
5674
5675 if (do_section_details)
5676 {
5677 if (link_too_big != NULL && * link_too_big)
5678 printf ("<%s> ", link_too_big);
5679 else
5680 printf ("%2u ", section->sh_link);
5681 printf ("%3u %2lu\n", section->sh_info,
5682 (unsigned long) section->sh_addralign);
5683 }
5684 else
5685 printf ("%2u %3u %2lu\n",
5686 section->sh_link,
5687 section->sh_info,
5688 (unsigned long) section->sh_addralign);
5689
5690 if (link_too_big && ! * link_too_big)
5691 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5692 i, section->sh_link);
f7a99963 5693 }
d974e256
JJ
5694 else if (do_wide)
5695 {
5696 print_vma (section->sh_addr, LONG_HEX);
5697
5698 if ((long) section->sh_offset == section->sh_offset)
5699 printf (" %6.6lx", (unsigned long) section->sh_offset);
5700 else
5701 {
5702 putchar (' ');
5703 print_vma (section->sh_offset, LONG_HEX);
5704 }
5705
5706 if ((unsigned long) section->sh_size == section->sh_size)
5707 printf (" %6.6lx", (unsigned long) section->sh_size);
5708 else
5709 {
5710 putchar (' ');
5711 print_vma (section->sh_size, LONG_HEX);
5712 }
5713
5714 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5715 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5716 else
5717 {
5718 putchar (' ');
5719 print_vma (section->sh_entsize, LONG_HEX);
5720 }
5721
5477e8a0
L
5722 if (do_section_details)
5723 fputs (" ", stdout);
5724 else
5725 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5726
72de5009 5727 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5728
5729 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5730 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5731 else
5732 {
5733 print_vma (section->sh_addralign, DEC);
5734 putchar ('\n');
5735 }
5736 }
5477e8a0 5737 else if (do_section_details)
595cf52e 5738 {
5477e8a0 5739 printf (" %-15.15s ",
595cf52e 5740 get_section_type_name (section->sh_type));
595cf52e
L
5741 print_vma (section->sh_addr, LONG_HEX);
5742 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5743 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5744 else
5745 {
5746 printf (" ");
5747 print_vma (section->sh_offset, LONG_HEX);
5748 }
72de5009 5749 printf (" %u\n ", section->sh_link);
595cf52e 5750 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5751 putchar (' ');
595cf52e
L
5752 print_vma (section->sh_entsize, LONG_HEX);
5753
72de5009
AM
5754 printf (" %-16u %lu\n",
5755 section->sh_info,
595cf52e
L
5756 (unsigned long) section->sh_addralign);
5757 }
f7a99963
NC
5758 else
5759 {
5760 putchar (' ');
5761 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5762 if ((long) section->sh_offset == section->sh_offset)
5763 printf (" %8.8lx", (unsigned long) section->sh_offset);
5764 else
5765 {
5766 printf (" ");
5767 print_vma (section->sh_offset, LONG_HEX);
5768 }
f7a99963
NC
5769 printf ("\n ");
5770 print_vma (section->sh_size, LONG_HEX);
5771 printf (" ");
5772 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5773
d1133906 5774 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5775
72de5009
AM
5776 printf (" %2u %3u %lu\n",
5777 section->sh_link,
5778 section->sh_info,
f7a99963
NC
5779 (unsigned long) section->sh_addralign);
5780 }
5477e8a0
L
5781
5782 if (do_section_details)
5783 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5784 }
5785
5477e8a0 5786 if (!do_section_details)
3dbcc61d
NC
5787 {
5788 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5789 || elf_header.e_machine == EM_L1OM
5790 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5791 printf (_("Key to Flags:\n\
5792 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5793 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5794 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5795 else
5796 printf (_("Key to Flags:\n\
e3c8793a 5797 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5798 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5799 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 5800 }
d1133906 5801
252b5132
RH
5802 return 1;
5803}
5804
f5842774
L
5805static const char *
5806get_group_flags (unsigned int flags)
5807{
5808 static char buff[32];
5809 switch (flags)
5810 {
220453ec
AM
5811 case 0:
5812 return "";
5813
f5842774 5814 case GRP_COMDAT:
220453ec 5815 return "COMDAT ";
f5842774
L
5816
5817 default:
220453ec 5818 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5819 break;
5820 }
5821 return buff;
5822}
5823
5824static int
2cf0635d 5825process_section_groups (FILE * file)
f5842774 5826{
2cf0635d 5827 Elf_Internal_Shdr * section;
f5842774 5828 unsigned int i;
2cf0635d
NC
5829 struct group * group;
5830 Elf_Internal_Shdr * symtab_sec;
5831 Elf_Internal_Shdr * strtab_sec;
5832 Elf_Internal_Sym * symtab;
ba5cdace 5833 unsigned long num_syms;
2cf0635d 5834 char * strtab;
c256ffe7 5835 size_t strtab_size;
d1f5c6e3
L
5836
5837 /* Don't process section groups unless needed. */
5838 if (!do_unwind && !do_section_groups)
5839 return 1;
f5842774
L
5840
5841 if (elf_header.e_shnum == 0)
5842 {
5843 if (do_section_groups)
82f2dbf7 5844 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5845
5846 return 1;
5847 }
5848
5849 if (section_headers == NULL)
5850 {
5851 error (_("Section headers are not available!\n"));
fa1908fd
NC
5852 /* PR 13622: This can happen with a corrupt ELF header. */
5853 return 0;
f5842774
L
5854 }
5855
3f5e193b
NC
5856 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5857 sizeof (struct group *));
e4b17d5c
L
5858
5859 if (section_headers_groups == NULL)
5860 {
8b73c356
NC
5861 error (_("Out of memory reading %u section group headers\n"),
5862 elf_header.e_shnum);
e4b17d5c
L
5863 return 0;
5864 }
5865
f5842774 5866 /* Scan the sections for the group section. */
d1f5c6e3 5867 group_count = 0;
f5842774
L
5868 for (i = 0, section = section_headers;
5869 i < elf_header.e_shnum;
5870 i++, section++)
e4b17d5c
L
5871 if (section->sh_type == SHT_GROUP)
5872 group_count++;
5873
d1f5c6e3
L
5874 if (group_count == 0)
5875 {
5876 if (do_section_groups)
5877 printf (_("\nThere are no section groups in this file.\n"));
5878
5879 return 1;
5880 }
5881
3f5e193b 5882 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5883
5884 if (section_groups == NULL)
5885 {
8b73c356
NC
5886 error (_("Out of memory reading %lu groups\n"),
5887 (unsigned long) group_count);
e4b17d5c
L
5888 return 0;
5889 }
5890
d1f5c6e3
L
5891 symtab_sec = NULL;
5892 strtab_sec = NULL;
5893 symtab = NULL;
ba5cdace 5894 num_syms = 0;
d1f5c6e3 5895 strtab = NULL;
c256ffe7 5896 strtab_size = 0;
e4b17d5c
L
5897 for (i = 0, section = section_headers, group = section_groups;
5898 i < elf_header.e_shnum;
5899 i++, section++)
f5842774
L
5900 {
5901 if (section->sh_type == SHT_GROUP)
5902 {
74e1a04b
NC
5903 const char * name = printable_section_name (section);
5904 const char * group_name;
2cf0635d
NC
5905 unsigned char * start;
5906 unsigned char * indices;
f5842774 5907 unsigned int entry, j, size;
2cf0635d
NC
5908 Elf_Internal_Shdr * sec;
5909 Elf_Internal_Sym * sym;
f5842774
L
5910
5911 /* Get the symbol table. */
4fbb74a6
AM
5912 if (section->sh_link >= elf_header.e_shnum
5913 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5914 != SHT_SYMTAB))
f5842774
L
5915 {
5916 error (_("Bad sh_link in group section `%s'\n"), name);
5917 continue;
5918 }
d1f5c6e3
L
5919
5920 if (symtab_sec != sec)
5921 {
5922 symtab_sec = sec;
5923 if (symtab)
5924 free (symtab);
ba5cdace 5925 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5926 }
f5842774 5927
dd24e3da
NC
5928 if (symtab == NULL)
5929 {
5930 error (_("Corrupt header in group section `%s'\n"), name);
5931 continue;
5932 }
5933
ba5cdace
NC
5934 if (section->sh_info >= num_syms)
5935 {
5936 error (_("Bad sh_info in group section `%s'\n"), name);
5937 continue;
5938 }
5939
f5842774
L
5940 sym = symtab + section->sh_info;
5941
5942 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5943 {
4fbb74a6
AM
5944 if (sym->st_shndx == 0
5945 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5946 {
5947 error (_("Bad sh_info in group section `%s'\n"), name);
5948 continue;
5949 }
ba2685cc 5950
4fbb74a6 5951 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5952 strtab_sec = NULL;
5953 if (strtab)
5954 free (strtab);
f5842774 5955 strtab = NULL;
c256ffe7 5956 strtab_size = 0;
f5842774
L
5957 }
5958 else
5959 {
5960 /* Get the string table. */
4fbb74a6 5961 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5962 {
5963 strtab_sec = NULL;
5964 if (strtab)
5965 free (strtab);
5966 strtab = NULL;
5967 strtab_size = 0;
5968 }
5969 else if (strtab_sec
4fbb74a6 5970 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5971 {
5972 strtab_sec = sec;
5973 if (strtab)
5974 free (strtab);
071436c6 5975
3f5e193b 5976 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
071436c6
NC
5977 1, strtab_sec->sh_size,
5978 _("string table"));
c256ffe7 5979 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5980 }
c256ffe7 5981 group_name = sym->st_name < strtab_size
2b692964 5982 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5983 }
5984
c9c1d674
EG
5985 /* PR 17531: file: loop. */
5986 if (section->sh_entsize > section->sh_size)
5987 {
5988 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
5989 printable_section_name (section),
8066deb1
AM
5990 (unsigned long) section->sh_entsize,
5991 (unsigned long) section->sh_size);
c9c1d674
EG
5992 break;
5993 }
5994
3f5e193b
NC
5995 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5996 1, section->sh_size,
5997 _("section data"));
59245841
NC
5998 if (start == NULL)
5999 continue;
f5842774
L
6000
6001 indices = start;
6002 size = (section->sh_size / section->sh_entsize) - 1;
6003 entry = byte_get (indices, 4);
6004 indices += 4;
e4b17d5c
L
6005
6006 if (do_section_groups)
6007 {
2b692964 6008 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6009 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6010
e4b17d5c
L
6011 printf (_(" [Index] Name\n"));
6012 }
6013
6014 group->group_index = i;
6015
f5842774
L
6016 for (j = 0; j < size; j++)
6017 {
2cf0635d 6018 struct group_list * g;
e4b17d5c 6019
f5842774
L
6020 entry = byte_get (indices, 4);
6021 indices += 4;
6022
4fbb74a6 6023 if (entry >= elf_header.e_shnum)
391cb864 6024 {
57028622
NC
6025 static unsigned num_group_errors = 0;
6026
6027 if (num_group_errors ++ < 10)
6028 {
6029 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
6030 entry, i, elf_header.e_shnum - 1);
6031 if (num_group_errors == 10)
6032 warn (_("Futher error messages about overlarge group section indicies suppressed\n"));
6033 }
391cb864
L
6034 continue;
6035 }
391cb864 6036
4fbb74a6 6037 if (section_headers_groups [entry] != NULL)
e4b17d5c 6038 {
d1f5c6e3
L
6039 if (entry)
6040 {
57028622
NC
6041 static unsigned num_errs = 0;
6042
6043 if (num_errs ++ < 10)
6044 {
6045 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6046 entry, i,
6047 section_headers_groups [entry]->group_index);
6048 if (num_errs == 10)
6049 warn (_("Further error messages about already contained group sections suppressed\n"));
6050 }
d1f5c6e3
L
6051 continue;
6052 }
6053 else
6054 {
6055 /* Intel C/C++ compiler may put section 0 in a
6056 section group. We just warn it the first time
6057 and ignore it afterwards. */
6058 static int warned = 0;
6059 if (!warned)
6060 {
6061 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6062 section_headers_groups [entry]->group_index);
d1f5c6e3
L
6063 warned++;
6064 }
6065 }
e4b17d5c
L
6066 }
6067
4fbb74a6 6068 section_headers_groups [entry] = group;
e4b17d5c
L
6069
6070 if (do_section_groups)
6071 {
4fbb74a6 6072 sec = section_headers + entry;
74e1a04b 6073 printf (" [%5u] %s\n", entry, printable_section_name (sec));
ba2685cc
AM
6074 }
6075
3f5e193b 6076 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6077 g->section_index = entry;
6078 g->next = group->root;
6079 group->root = g;
f5842774
L
6080 }
6081
f5842774
L
6082 if (start)
6083 free (start);
e4b17d5c
L
6084
6085 group++;
f5842774
L
6086 }
6087 }
6088
d1f5c6e3
L
6089 if (symtab)
6090 free (symtab);
6091 if (strtab)
6092 free (strtab);
f5842774
L
6093 return 1;
6094}
6095
28f997cf
TG
6096/* Data used to display dynamic fixups. */
6097
6098struct ia64_vms_dynfixup
6099{
6100 bfd_vma needed_ident; /* Library ident number. */
6101 bfd_vma needed; /* Index in the dstrtab of the library name. */
6102 bfd_vma fixup_needed; /* Index of the library. */
6103 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6104 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6105};
6106
6107/* Data used to display dynamic relocations. */
6108
6109struct ia64_vms_dynimgrela
6110{
6111 bfd_vma img_rela_cnt; /* Number of relocations. */
6112 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6113};
6114
6115/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6116 library). */
6117
6118static void
6119dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
6120 const char *strtab, unsigned int strtab_sz)
6121{
6122 Elf64_External_VMS_IMAGE_FIXUP *imfs;
6123 long i;
6124 const char *lib_name;
6125
6126 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
6127 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6128 _("dynamic section image fixups"));
6129 if (!imfs)
6130 return;
6131
6132 if (fixup->needed < strtab_sz)
6133 lib_name = strtab + fixup->needed;
6134 else
6135 {
6136 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 6137 (unsigned long) fixup->needed);
28f997cf
TG
6138 lib_name = "???";
6139 }
6140 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6141 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6142 printf
6143 (_("Seg Offset Type SymVec DataType\n"));
6144
6145 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6146 {
6147 unsigned int type;
6148 const char *rtype;
6149
6150 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6151 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6152 type = BYTE_GET (imfs [i].type);
6153 rtype = elf_ia64_reloc_type (type);
6154 if (rtype == NULL)
6155 printf (" 0x%08x ", type);
6156 else
6157 printf (" %-32s ", rtype);
6158 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6159 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6160 }
6161
6162 free (imfs);
6163}
6164
6165/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6166
6167static void
6168dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
6169{
6170 Elf64_External_VMS_IMAGE_RELA *imrs;
6171 long i;
6172
6173 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
6174 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6175 _("dynamic section image relocations"));
28f997cf
TG
6176 if (!imrs)
6177 return;
6178
6179 printf (_("\nImage relocs\n"));
6180 printf
6181 (_("Seg Offset Type Addend Seg Sym Off\n"));
6182
6183 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6184 {
6185 unsigned int type;
6186 const char *rtype;
6187
6188 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6189 printf ("%08" BFD_VMA_FMT "x ",
6190 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6191 type = BYTE_GET (imrs [i].type);
6192 rtype = elf_ia64_reloc_type (type);
6193 if (rtype == NULL)
6194 printf ("0x%08x ", type);
6195 else
6196 printf ("%-31s ", rtype);
6197 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6198 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6199 printf ("%08" BFD_VMA_FMT "x\n",
6200 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6201 }
6202
6203 free (imrs);
6204}
6205
6206/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6207
6208static int
6209process_ia64_vms_dynamic_relocs (FILE *file)
6210{
6211 struct ia64_vms_dynfixup fixup;
6212 struct ia64_vms_dynimgrela imgrela;
6213 Elf_Internal_Dyn *entry;
6214 int res = 0;
6215 bfd_vma strtab_off = 0;
6216 bfd_vma strtab_sz = 0;
6217 char *strtab = NULL;
6218
6219 memset (&fixup, 0, sizeof (fixup));
6220 memset (&imgrela, 0, sizeof (imgrela));
6221
6222 /* Note: the order of the entries is specified by the OpenVMS specs. */
6223 for (entry = dynamic_section;
6224 entry < dynamic_section + dynamic_nent;
6225 entry++)
6226 {
6227 switch (entry->d_tag)
6228 {
6229 case DT_IA_64_VMS_STRTAB_OFFSET:
6230 strtab_off = entry->d_un.d_val;
6231 break;
6232 case DT_STRSZ:
6233 strtab_sz = entry->d_un.d_val;
6234 if (strtab == NULL)
6235 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
6236 1, strtab_sz, _("dynamic string section"));
6237 break;
6238
6239 case DT_IA_64_VMS_NEEDED_IDENT:
6240 fixup.needed_ident = entry->d_un.d_val;
6241 break;
6242 case DT_NEEDED:
6243 fixup.needed = entry->d_un.d_val;
6244 break;
6245 case DT_IA_64_VMS_FIXUP_NEEDED:
6246 fixup.fixup_needed = entry->d_un.d_val;
6247 break;
6248 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6249 fixup.fixup_rela_cnt = entry->d_un.d_val;
6250 break;
6251 case DT_IA_64_VMS_FIXUP_RELA_OFF:
6252 fixup.fixup_rela_off = entry->d_un.d_val;
6253 res++;
6254 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
6255 break;
6256
6257 case DT_IA_64_VMS_IMG_RELA_CNT:
6258 imgrela.img_rela_cnt = entry->d_un.d_val;
6259 break;
6260 case DT_IA_64_VMS_IMG_RELA_OFF:
6261 imgrela.img_rela_off = entry->d_un.d_val;
6262 res++;
6263 dump_ia64_vms_dynamic_relocs (file, &imgrela);
6264 break;
6265
6266 default:
6267 break;
6268 }
6269 }
6270
6271 if (strtab != NULL)
6272 free (strtab);
6273
6274 return res;
6275}
6276
85b1c36d 6277static struct
566b0d53 6278{
2cf0635d 6279 const char * name;
566b0d53
L
6280 int reloc;
6281 int size;
6282 int rela;
6283} dynamic_relocations [] =
6284{
6285 { "REL", DT_REL, DT_RELSZ, FALSE },
6286 { "RELA", DT_RELA, DT_RELASZ, TRUE },
6287 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
6288};
6289
252b5132 6290/* Process the reloc section. */
18bd398b 6291
252b5132 6292static int
2cf0635d 6293process_relocs (FILE * file)
252b5132 6294{
b34976b6
AM
6295 unsigned long rel_size;
6296 unsigned long rel_offset;
252b5132
RH
6297
6298
6299 if (!do_reloc)
6300 return 1;
6301
6302 if (do_using_dynamic)
6303 {
566b0d53 6304 int is_rela;
2cf0635d 6305 const char * name;
566b0d53
L
6306 int has_dynamic_reloc;
6307 unsigned int i;
0de14b54 6308
566b0d53 6309 has_dynamic_reloc = 0;
252b5132 6310
566b0d53 6311 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 6312 {
566b0d53
L
6313 is_rela = dynamic_relocations [i].rela;
6314 name = dynamic_relocations [i].name;
6315 rel_size = dynamic_info [dynamic_relocations [i].size];
6316 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 6317
566b0d53
L
6318 has_dynamic_reloc |= rel_size;
6319
6320 if (is_rela == UNKNOWN)
aa903cfb 6321 {
566b0d53
L
6322 if (dynamic_relocations [i].reloc == DT_JMPREL)
6323 switch (dynamic_info[DT_PLTREL])
6324 {
6325 case DT_REL:
6326 is_rela = FALSE;
6327 break;
6328 case DT_RELA:
6329 is_rela = TRUE;
6330 break;
6331 }
aa903cfb 6332 }
252b5132 6333
566b0d53
L
6334 if (rel_size)
6335 {
6336 printf
6337 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
6338 name, rel_offset, rel_size);
252b5132 6339
d93f0186
NC
6340 dump_relocations (file,
6341 offset_from_vma (file, rel_offset, rel_size),
6342 rel_size,
566b0d53 6343 dynamic_symbols, num_dynamic_syms,
bb4d2ac2
L
6344 dynamic_strings, dynamic_strings_length,
6345 is_rela, 1);
566b0d53 6346 }
252b5132 6347 }
566b0d53 6348
28f997cf
TG
6349 if (is_ia64_vms ())
6350 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
6351
566b0d53 6352 if (! has_dynamic_reloc)
252b5132
RH
6353 printf (_("\nThere are no dynamic relocations in this file.\n"));
6354 }
6355 else
6356 {
2cf0635d 6357 Elf_Internal_Shdr * section;
b34976b6
AM
6358 unsigned long i;
6359 int found = 0;
252b5132
RH
6360
6361 for (i = 0, section = section_headers;
6362 i < elf_header.e_shnum;
b34976b6 6363 i++, section++)
252b5132
RH
6364 {
6365 if ( section->sh_type != SHT_RELA
6366 && section->sh_type != SHT_REL)
6367 continue;
6368
6369 rel_offset = section->sh_offset;
6370 rel_size = section->sh_size;
6371
6372 if (rel_size)
6373 {
2cf0635d 6374 Elf_Internal_Shdr * strsec;
b34976b6 6375 int is_rela;
103f02d3 6376
252b5132
RH
6377 printf (_("\nRelocation section "));
6378
6379 if (string_table == NULL)
19936277 6380 printf ("%d", section->sh_name);
252b5132 6381 else
74e1a04b 6382 printf ("'%s'", printable_section_name (section));
252b5132
RH
6383
6384 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6385 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
6386
d79b3d50
NC
6387 is_rela = section->sh_type == SHT_RELA;
6388
4fbb74a6
AM
6389 if (section->sh_link != 0
6390 && section->sh_link < elf_header.e_shnum)
af3fc3bc 6391 {
2cf0635d
NC
6392 Elf_Internal_Shdr * symsec;
6393 Elf_Internal_Sym * symtab;
d79b3d50 6394 unsigned long nsyms;
c256ffe7 6395 unsigned long strtablen = 0;
2cf0635d 6396 char * strtab = NULL;
57346661 6397
4fbb74a6 6398 symsec = section_headers + section->sh_link;
08d8fa11
JJ
6399 if (symsec->sh_type != SHT_SYMTAB
6400 && symsec->sh_type != SHT_DYNSYM)
6401 continue;
6402
ba5cdace 6403 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 6404
af3fc3bc
AM
6405 if (symtab == NULL)
6406 continue;
252b5132 6407
4fbb74a6
AM
6408 if (symsec->sh_link != 0
6409 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 6410 {
4fbb74a6 6411 strsec = section_headers + symsec->sh_link;
103f02d3 6412
3f5e193b 6413 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
071436c6
NC
6414 1, strsec->sh_size,
6415 _("string table"));
c256ffe7
JJ
6416 strtablen = strtab == NULL ? 0 : strsec->sh_size;
6417 }
252b5132 6418
d79b3d50 6419 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2
L
6420 symtab, nsyms, strtab, strtablen,
6421 is_rela,
6422 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
6423 if (strtab)
6424 free (strtab);
6425 free (symtab);
6426 }
6427 else
6428 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2 6429 NULL, 0, NULL, 0, is_rela, 0);
252b5132
RH
6430
6431 found = 1;
6432 }
6433 }
6434
6435 if (! found)
6436 printf (_("\nThere are no relocations in this file.\n"));
6437 }
6438
6439 return 1;
6440}
6441
4d6ed7c8
NC
6442/* An absolute address consists of a section and an offset. If the
6443 section is NULL, the offset itself is the address, otherwise, the
6444 address equals to LOAD_ADDRESS(section) + offset. */
6445
6446struct absaddr
948f632f
DA
6447{
6448 unsigned short section;
6449 bfd_vma offset;
6450};
4d6ed7c8 6451
1949de15
L
6452#define ABSADDR(a) \
6453 ((a).section \
6454 ? section_headers [(a).section].sh_addr + (a).offset \
6455 : (a).offset)
6456
948f632f
DA
6457/* Find the nearest symbol at or below ADDR. Returns the symbol
6458 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 6459
4d6ed7c8 6460static void
2cf0635d 6461find_symbol_for_address (Elf_Internal_Sym * symtab,
948f632f
DA
6462 unsigned long nsyms,
6463 const char * strtab,
6464 unsigned long strtab_size,
6465 struct absaddr addr,
6466 const char ** symname,
6467 bfd_vma * offset)
4d6ed7c8 6468{
d3ba0551 6469 bfd_vma dist = 0x100000;
2cf0635d 6470 Elf_Internal_Sym * sym;
948f632f
DA
6471 Elf_Internal_Sym * beg;
6472 Elf_Internal_Sym * end;
2cf0635d 6473 Elf_Internal_Sym * best = NULL;
4d6ed7c8 6474
0b6ae522 6475 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
6476 beg = symtab;
6477 end = symtab + nsyms;
0b6ae522 6478
948f632f 6479 while (beg < end)
4d6ed7c8 6480 {
948f632f
DA
6481 bfd_vma value;
6482
6483 sym = beg + (end - beg) / 2;
0b6ae522 6484
948f632f 6485 value = sym->st_value;
0b6ae522
DJ
6486 REMOVE_ARCH_BITS (value);
6487
948f632f 6488 if (sym->st_name != 0
4d6ed7c8 6489 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
6490 && addr.offset >= value
6491 && addr.offset - value < dist)
4d6ed7c8
NC
6492 {
6493 best = sym;
0b6ae522 6494 dist = addr.offset - value;
4d6ed7c8
NC
6495 if (!dist)
6496 break;
6497 }
948f632f
DA
6498
6499 if (addr.offset < value)
6500 end = sym;
6501 else
6502 beg = sym + 1;
4d6ed7c8 6503 }
1b31d05e 6504
4d6ed7c8
NC
6505 if (best)
6506 {
57346661 6507 *symname = (best->st_name >= strtab_size
2b692964 6508 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
6509 *offset = dist;
6510 return;
6511 }
1b31d05e 6512
4d6ed7c8
NC
6513 *symname = NULL;
6514 *offset = addr.offset;
6515}
6516
948f632f
DA
6517static int
6518symcmp (const void *p, const void *q)
6519{
6520 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
6521 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
6522
6523 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
6524}
6525
6526/* Process the unwind section. */
6527
6528#include "unwind-ia64.h"
6529
6530struct ia64_unw_table_entry
6531{
6532 struct absaddr start;
6533 struct absaddr end;
6534 struct absaddr info;
6535};
6536
6537struct ia64_unw_aux_info
6538{
6539 struct ia64_unw_table_entry *table; /* Unwind table. */
6540 unsigned long table_len; /* Length of unwind table. */
6541 unsigned char * info; /* Unwind info. */
6542 unsigned long info_size; /* Size of unwind info. */
6543 bfd_vma info_addr; /* Starting address of unwind info. */
6544 bfd_vma seg_base; /* Starting address of segment. */
6545 Elf_Internal_Sym * symtab; /* The symbol table. */
6546 unsigned long nsyms; /* Number of symbols. */
6547 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
6548 unsigned long nfuns; /* Number of entries in funtab. */
6549 char * strtab; /* The string table. */
6550 unsigned long strtab_size; /* Size of string table. */
6551};
6552
4d6ed7c8 6553static void
2cf0635d 6554dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 6555{
2cf0635d 6556 struct ia64_unw_table_entry * tp;
948f632f 6557 unsigned long j, nfuns;
4d6ed7c8 6558 int in_body;
7036c0e1 6559
948f632f
DA
6560 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
6561 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
6562 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
6563 aux->funtab[nfuns++] = aux->symtab[j];
6564 aux->nfuns = nfuns;
6565 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
6566
4d6ed7c8
NC
6567 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6568 {
6569 bfd_vma stamp;
6570 bfd_vma offset;
2cf0635d
NC
6571 const unsigned char * dp;
6572 const unsigned char * head;
53774b7e 6573 const unsigned char * end;
2cf0635d 6574 const char * procname;
4d6ed7c8 6575
948f632f 6576 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
57346661 6577 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
6578
6579 fputs ("\n<", stdout);
6580
6581 if (procname)
6582 {
6583 fputs (procname, stdout);
6584
6585 if (offset)
6586 printf ("+%lx", (unsigned long) offset);
6587 }
6588
6589 fputs (">: [", stdout);
6590 print_vma (tp->start.offset, PREFIX_HEX);
6591 fputc ('-', stdout);
6592 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 6593 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
6594 (unsigned long) (tp->info.offset - aux->seg_base));
6595
53774b7e
NC
6596 /* PR 17531: file: 86232b32. */
6597 if (aux->info == NULL)
6598 continue;
6599
6600 /* PR 17531: file: 0997b4d1. */
6601 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
6602 {
6603 warn (_("Invalid offset %lx in table entry %ld\n"),
6604 (long) tp->info.offset, (long) (tp - aux->table));
6605 continue;
6606 }
6607
1949de15 6608 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 6609 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 6610
86f55779 6611 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
6612 (unsigned) UNW_VER (stamp),
6613 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
6614 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
6615 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 6616 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
6617
6618 if (UNW_VER (stamp) != 1)
6619 {
2b692964 6620 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
6621 continue;
6622 }
6623
6624 in_body = 0;
53774b7e
NC
6625 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
6626 /* PR 17531: file: 16ceda89. */
6627 if (end > aux->info + aux->info_size)
6628 end = aux->info + aux->info_size;
6629 for (dp = head + 8; dp < end;)
4d6ed7c8
NC
6630 dp = unw_decode (dp, in_body, & in_body);
6631 }
948f632f
DA
6632
6633 free (aux->funtab);
4d6ed7c8
NC
6634}
6635
53774b7e 6636static bfd_boolean
2cf0635d
NC
6637slurp_ia64_unwind_table (FILE * file,
6638 struct ia64_unw_aux_info * aux,
6639 Elf_Internal_Shdr * sec)
4d6ed7c8 6640{
89fac5e3 6641 unsigned long size, nrelas, i;
2cf0635d
NC
6642 Elf_Internal_Phdr * seg;
6643 struct ia64_unw_table_entry * tep;
6644 Elf_Internal_Shdr * relsec;
6645 Elf_Internal_Rela * rela;
6646 Elf_Internal_Rela * rp;
6647 unsigned char * table;
6648 unsigned char * tp;
6649 Elf_Internal_Sym * sym;
6650 const char * relname;
4d6ed7c8 6651
53774b7e
NC
6652 aux->table_len = 0;
6653
4d6ed7c8
NC
6654 /* First, find the starting address of the segment that includes
6655 this section: */
6656
6657 if (elf_header.e_phnum)
6658 {
d93f0186 6659 if (! get_program_headers (file))
53774b7e 6660 return FALSE;
4d6ed7c8 6661
d93f0186
NC
6662 for (seg = program_headers;
6663 seg < program_headers + elf_header.e_phnum;
6664 ++seg)
4d6ed7c8
NC
6665 {
6666 if (seg->p_type != PT_LOAD)
6667 continue;
6668
6669 if (sec->sh_addr >= seg->p_vaddr
6670 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6671 {
6672 aux->seg_base = seg->p_vaddr;
6673 break;
6674 }
6675 }
4d6ed7c8
NC
6676 }
6677
6678 /* Second, build the unwind table from the contents of the unwind section: */
6679 size = sec->sh_size;
3f5e193b
NC
6680 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6681 _("unwind table"));
a6e9f9df 6682 if (!table)
53774b7e 6683 return FALSE;
4d6ed7c8 6684
53774b7e 6685 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 6686 aux->table = (struct ia64_unw_table_entry *)
53774b7e 6687 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 6688 tep = aux->table;
53774b7e
NC
6689
6690 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
6691 {
6692 tep->start.section = SHN_UNDEF;
6693 tep->end.section = SHN_UNDEF;
6694 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6695 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6696 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6697 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6698 tep->start.offset += aux->seg_base;
6699 tep->end.offset += aux->seg_base;
6700 tep->info.offset += aux->seg_base;
6701 }
6702 free (table);
6703
41e92641 6704 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6705 for (relsec = section_headers;
6706 relsec < section_headers + elf_header.e_shnum;
6707 ++relsec)
6708 {
6709 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6710 || relsec->sh_info >= elf_header.e_shnum
6711 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6712 continue;
6713
6714 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6715 & rela, & nrelas))
53774b7e
NC
6716 {
6717 free (aux->table);
6718 aux->table = NULL;
6719 aux->table_len = 0;
6720 return FALSE;
6721 }
4d6ed7c8
NC
6722
6723 for (rp = rela; rp < rela + nrelas; ++rp)
6724 {
aca88567
NC
6725 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6726 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6727
82b1b41b
NC
6728 /* PR 17531: file: 9fa67536. */
6729 if (relname == NULL)
6730 {
6731 warn (_("Skipping unknown relocation type: %u\n"), get_reloc_type (rp->r_info));
6732 continue;
6733 }
948f632f 6734
0112cd26 6735 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6736 {
82b1b41b 6737 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
6738 continue;
6739 }
6740
89fac5e3 6741 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6742
53774b7e
NC
6743 /* PR 17531: file: 5bc8d9bf. */
6744 if (i >= aux->table_len)
6745 {
6746 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
6747 continue;
6748 }
6749
6750 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
6751 {
6752 case 0:
6753 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6754 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6755 break;
6756 case 1:
6757 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6758 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6759 break;
6760 case 2:
6761 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6762 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6763 break;
6764 default:
6765 break;
6766 }
6767 }
6768
6769 free (rela);
6770 }
6771
53774b7e 6772 return TRUE;
4d6ed7c8
NC
6773}
6774
1b31d05e 6775static void
2cf0635d 6776ia64_process_unwind (FILE * file)
4d6ed7c8 6777{
2cf0635d
NC
6778 Elf_Internal_Shdr * sec;
6779 Elf_Internal_Shdr * unwsec = NULL;
6780 Elf_Internal_Shdr * strsec;
89fac5e3 6781 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6782 struct ia64_unw_aux_info aux;
f1467e33 6783
4d6ed7c8
NC
6784 memset (& aux, 0, sizeof (aux));
6785
4d6ed7c8
NC
6786 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6787 {
c256ffe7 6788 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6789 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6790 {
ba5cdace 6791 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6792
4fbb74a6 6793 strsec = section_headers + sec->sh_link;
4082ef84
NC
6794 if (aux.strtab != NULL)
6795 {
6796 error (_("Multiple auxillary string tables encountered\n"));
6797 free (aux.strtab);
6798 }
3f5e193b
NC
6799 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6800 1, strsec->sh_size,
6801 _("string table"));
c256ffe7 6802 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6803 }
6804 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6805 unwcount++;
6806 }
6807
6808 if (!unwcount)
6809 printf (_("\nThere are no unwind sections in this file.\n"));
6810
6811 while (unwcount-- > 0)
6812 {
2cf0635d 6813 char * suffix;
579f31ac
JJ
6814 size_t len, len2;
6815
4082ef84 6816 for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
579f31ac
JJ
6817 i < elf_header.e_shnum; ++i, ++sec)
6818 if (sec->sh_type == SHT_IA_64_UNWIND)
6819 {
6820 unwsec = sec;
6821 break;
6822 }
4082ef84
NC
6823 /* We have already counted the number of SHT_IA64_UNWIND
6824 sections so the loop above should never fail. */
6825 assert (unwsec != NULL);
579f31ac
JJ
6826
6827 unwstart = i + 1;
6828 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6829
e4b17d5c
L
6830 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6831 {
6832 /* We need to find which section group it is in. */
4082ef84 6833 struct group_list * g;
e4b17d5c 6834
4082ef84
NC
6835 if (section_headers_groups == NULL
6836 || section_headers_groups [i] == NULL)
6837 i = elf_header.e_shnum;
6838 else
e4b17d5c 6839 {
4082ef84 6840 g = section_headers_groups [i]->root;
18bd398b 6841
4082ef84
NC
6842 for (; g != NULL; g = g->next)
6843 {
6844 sec = section_headers + g->section_index;
e4b17d5c 6845
4082ef84
NC
6846 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
6847 break;
6848 }
6849
6850 if (g == NULL)
6851 i = elf_header.e_shnum;
6852 }
e4b17d5c 6853 }
18bd398b 6854 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6855 {
18bd398b 6856 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6857 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6858 suffix = SECTION_NAME (unwsec) + len;
6859 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6860 ++i, ++sec)
18bd398b
NC
6861 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6862 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6863 break;
6864 }
6865 else
6866 {
6867 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6868 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6869 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6870 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6871 suffix = "";
18bd398b 6872 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6873 suffix = SECTION_NAME (unwsec) + len;
6874 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6875 ++i, ++sec)
18bd398b
NC
6876 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6877 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6878 break;
6879 }
6880
6881 if (i == elf_header.e_shnum)
6882 {
6883 printf (_("\nCould not find unwind info section for "));
6884
6885 if (string_table == NULL)
6886 printf ("%d", unwsec->sh_name);
6887 else
74e1a04b 6888 printf ("'%s'", printable_section_name (unwsec));
579f31ac
JJ
6889 }
6890 else
4d6ed7c8 6891 {
4d6ed7c8 6892 aux.info_addr = sec->sh_addr;
3f5e193b 6893 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
4082ef84
NC
6894 sec->sh_size,
6895 _("unwind info"));
59245841 6896 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6897
579f31ac 6898 printf (_("\nUnwind section "));
4d6ed7c8 6899
579f31ac
JJ
6900 if (string_table == NULL)
6901 printf ("%d", unwsec->sh_name);
6902 else
74e1a04b 6903 printf ("'%s'", printable_section_name (unwsec));
4d6ed7c8 6904
579f31ac 6905 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6906 (unsigned long) unwsec->sh_offset,
89fac5e3 6907 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6908
53774b7e
NC
6909 if (slurp_ia64_unwind_table (file, & aux, unwsec)
6910 && aux.table_len > 0)
579f31ac
JJ
6911 dump_ia64_unwind (& aux);
6912
6913 if (aux.table)
6914 free ((char *) aux.table);
6915 if (aux.info)
6916 free ((char *) aux.info);
6917 aux.table = NULL;
6918 aux.info = NULL;
6919 }
4d6ed7c8 6920 }
4d6ed7c8 6921
4d6ed7c8
NC
6922 if (aux.symtab)
6923 free (aux.symtab);
6924 if (aux.strtab)
6925 free ((char *) aux.strtab);
4d6ed7c8
NC
6926}
6927
3f5e193b
NC
6928struct hppa_unw_table_entry
6929 {
6930 struct absaddr start;
6931 struct absaddr end;
948f632f 6932 unsigned int Cannot_unwind:1; /* 0 */
3f5e193b
NC
6933 unsigned int Millicode:1; /* 1 */
6934 unsigned int Millicode_save_sr0:1; /* 2 */
6935 unsigned int Region_description:2; /* 3..4 */
6936 unsigned int reserved1:1; /* 5 */
6937 unsigned int Entry_SR:1; /* 6 */
6938 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6939 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6940 unsigned int Args_stored:1; /* 16 */
948f632f
DA
6941 unsigned int Variable_Frame:1; /* 17 */
6942 unsigned int Separate_Package_Body:1; /* 18 */
3f5e193b 6943 unsigned int Frame_Extension_Millicode:1; /* 19 */
948f632f
DA
6944 unsigned int Stack_Overflow_Check:1; /* 20 */
6945 unsigned int Two_Instruction_SP_Increment:1;/* 21 */
3f5e193b
NC
6946 unsigned int Ada_Region:1; /* 22 */
6947 unsigned int cxx_info:1; /* 23 */
948f632f
DA
6948 unsigned int cxx_try_catch:1; /* 24 */
6949 unsigned int sched_entry_seq:1; /* 25 */
3f5e193b 6950 unsigned int reserved2:1; /* 26 */
948f632f
DA
6951 unsigned int Save_SP:1; /* 27 */
6952 unsigned int Save_RP:1; /* 28 */
3f5e193b
NC
6953 unsigned int Save_MRP_in_frame:1; /* 29 */
6954 unsigned int extn_ptr_defined:1; /* 30 */
948f632f 6955 unsigned int Cleanup_defined:1; /* 31 */
3f5e193b 6956
948f632f
DA
6957 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6958 unsigned int HP_UX_interrupt_marker:1; /* 1 */
3f5e193b 6959 unsigned int Large_frame:1; /* 2 */
948f632f 6960 unsigned int Pseudo_SP_Set:1; /* 3 */
3f5e193b
NC
6961 unsigned int reserved4:1; /* 4 */
6962 unsigned int Total_frame_size:27; /* 5..31 */
6963 };
6964
57346661 6965struct hppa_unw_aux_info
948f632f
DA
6966{
6967 struct hppa_unw_table_entry * table; /* Unwind table. */
6968 unsigned long table_len; /* Length of unwind table. */
6969 bfd_vma seg_base; /* Starting address of segment. */
6970 Elf_Internal_Sym * symtab; /* The symbol table. */
6971 unsigned long nsyms; /* Number of symbols. */
6972 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
6973 unsigned long nfuns; /* Number of entries in funtab. */
6974 char * strtab; /* The string table. */
6975 unsigned long strtab_size; /* Size of string table. */
6976};
57346661
AM
6977
6978static void
2cf0635d 6979dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6980{
2cf0635d 6981 struct hppa_unw_table_entry * tp;
948f632f
DA
6982 unsigned long j, nfuns;
6983
6984 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
6985 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
6986 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
6987 aux->funtab[nfuns++] = aux->symtab[j];
6988 aux->nfuns = nfuns;
6989 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 6990
57346661
AM
6991 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6992 {
6993 bfd_vma offset;
2cf0635d 6994 const char * procname;
57346661 6995
948f632f 6996 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
6997 aux->strtab_size, tp->start, &procname,
6998 &offset);
6999
7000 fputs ("\n<", stdout);
7001
7002 if (procname)
7003 {
7004 fputs (procname, stdout);
7005
7006 if (offset)
7007 printf ("+%lx", (unsigned long) offset);
7008 }
7009
7010 fputs (">: [", stdout);
7011 print_vma (tp->start.offset, PREFIX_HEX);
7012 fputc ('-', stdout);
7013 print_vma (tp->end.offset, PREFIX_HEX);
7014 printf ("]\n\t");
7015
18bd398b
NC
7016#define PF(_m) if (tp->_m) printf (#_m " ");
7017#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
7018 PF(Cannot_unwind);
7019 PF(Millicode);
7020 PF(Millicode_save_sr0);
18bd398b 7021 /* PV(Region_description); */
57346661
AM
7022 PF(Entry_SR);
7023 PV(Entry_FR);
7024 PV(Entry_GR);
7025 PF(Args_stored);
7026 PF(Variable_Frame);
7027 PF(Separate_Package_Body);
7028 PF(Frame_Extension_Millicode);
7029 PF(Stack_Overflow_Check);
7030 PF(Two_Instruction_SP_Increment);
7031 PF(Ada_Region);
7032 PF(cxx_info);
7033 PF(cxx_try_catch);
7034 PF(sched_entry_seq);
7035 PF(Save_SP);
7036 PF(Save_RP);
7037 PF(Save_MRP_in_frame);
7038 PF(extn_ptr_defined);
7039 PF(Cleanup_defined);
7040 PF(MPE_XL_interrupt_marker);
7041 PF(HP_UX_interrupt_marker);
7042 PF(Large_frame);
7043 PF(Pseudo_SP_Set);
7044 PV(Total_frame_size);
7045#undef PF
7046#undef PV
7047 }
7048
18bd398b 7049 printf ("\n");
948f632f
DA
7050
7051 free (aux->funtab);
57346661
AM
7052}
7053
7054static int
2cf0635d
NC
7055slurp_hppa_unwind_table (FILE * file,
7056 struct hppa_unw_aux_info * aux,
7057 Elf_Internal_Shdr * sec)
57346661 7058{
1c0751b2 7059 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7060 Elf_Internal_Phdr * seg;
7061 struct hppa_unw_table_entry * tep;
7062 Elf_Internal_Shdr * relsec;
7063 Elf_Internal_Rela * rela;
7064 Elf_Internal_Rela * rp;
7065 unsigned char * table;
7066 unsigned char * tp;
7067 Elf_Internal_Sym * sym;
7068 const char * relname;
57346661 7069
57346661
AM
7070 /* First, find the starting address of the segment that includes
7071 this section. */
7072
7073 if (elf_header.e_phnum)
7074 {
7075 if (! get_program_headers (file))
7076 return 0;
7077
7078 for (seg = program_headers;
7079 seg < program_headers + elf_header.e_phnum;
7080 ++seg)
7081 {
7082 if (seg->p_type != PT_LOAD)
7083 continue;
7084
7085 if (sec->sh_addr >= seg->p_vaddr
7086 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7087 {
7088 aux->seg_base = seg->p_vaddr;
7089 break;
7090 }
7091 }
7092 }
7093
7094 /* Second, build the unwind table from the contents of the unwind
7095 section. */
7096 size = sec->sh_size;
3f5e193b
NC
7097 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
7098 _("unwind table"));
57346661
AM
7099 if (!table)
7100 return 0;
7101
1c0751b2
DA
7102 unw_ent_size = 16;
7103 nentries = size / unw_ent_size;
7104 size = unw_ent_size * nentries;
57346661 7105
3f5e193b
NC
7106 tep = aux->table = (struct hppa_unw_table_entry *)
7107 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7108
1c0751b2 7109 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7110 {
7111 unsigned int tmp1, tmp2;
7112
7113 tep->start.section = SHN_UNDEF;
7114 tep->end.section = SHN_UNDEF;
7115
1c0751b2
DA
7116 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7117 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7118 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7119 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7120
7121 tep->start.offset += aux->seg_base;
7122 tep->end.offset += aux->seg_base;
57346661
AM
7123
7124 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
7125 tep->Millicode = (tmp1 >> 30) & 0x1;
7126 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
7127 tep->Region_description = (tmp1 >> 27) & 0x3;
7128 tep->reserved1 = (tmp1 >> 26) & 0x1;
7129 tep->Entry_SR = (tmp1 >> 25) & 0x1;
7130 tep->Entry_FR = (tmp1 >> 21) & 0xf;
7131 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7132 tep->Args_stored = (tmp1 >> 15) & 0x1;
7133 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7134 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7135 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7136 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7137 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7138 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7139 tep->cxx_info = (tmp1 >> 8) & 0x1;
7140 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7141 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7142 tep->reserved2 = (tmp1 >> 5) & 0x1;
7143 tep->Save_SP = (tmp1 >> 4) & 0x1;
7144 tep->Save_RP = (tmp1 >> 3) & 0x1;
7145 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7146 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7147 tep->Cleanup_defined = tmp1 & 0x1;
7148
7149 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7150 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7151 tep->Large_frame = (tmp2 >> 29) & 0x1;
7152 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7153 tep->reserved4 = (tmp2 >> 27) & 0x1;
7154 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7155 }
7156 free (table);
7157
7158 /* Third, apply any relocations to the unwind table. */
57346661
AM
7159 for (relsec = section_headers;
7160 relsec < section_headers + elf_header.e_shnum;
7161 ++relsec)
7162 {
7163 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
7164 || relsec->sh_info >= elf_header.e_shnum
7165 || section_headers + relsec->sh_info != sec)
57346661
AM
7166 continue;
7167
7168 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7169 & rela, & nrelas))
7170 return 0;
7171
7172 for (rp = rela; rp < rela + nrelas; ++rp)
7173 {
aca88567
NC
7174 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
7175 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
7176
7177 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 7178 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
7179 {
7180 warn (_("Skipping unexpected relocation type %s\n"), relname);
7181 continue;
7182 }
7183
7184 i = rp->r_offset / unw_ent_size;
7185
89fac5e3 7186 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
7187 {
7188 case 0:
7189 aux->table[i].start.section = sym->st_shndx;
1e456d54 7190 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
7191 break;
7192 case 1:
7193 aux->table[i].end.section = sym->st_shndx;
1e456d54 7194 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
7195 break;
7196 default:
7197 break;
7198 }
7199 }
7200
7201 free (rela);
7202 }
7203
1c0751b2 7204 aux->table_len = nentries;
57346661
AM
7205
7206 return 1;
7207}
7208
1b31d05e 7209static void
2cf0635d 7210hppa_process_unwind (FILE * file)
57346661 7211{
57346661 7212 struct hppa_unw_aux_info aux;
2cf0635d
NC
7213 Elf_Internal_Shdr * unwsec = NULL;
7214 Elf_Internal_Shdr * strsec;
7215 Elf_Internal_Shdr * sec;
18bd398b 7216 unsigned long i;
57346661 7217
c256ffe7 7218 if (string_table == NULL)
1b31d05e
NC
7219 return;
7220
7221 memset (& aux, 0, sizeof (aux));
57346661
AM
7222
7223 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7224 {
c256ffe7 7225 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7226 && sec->sh_link < elf_header.e_shnum)
57346661 7227 {
ba5cdace 7228 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 7229
4fbb74a6 7230 strsec = section_headers + sec->sh_link;
4082ef84
NC
7231 if (aux.strtab != NULL)
7232 {
7233 error (_("Multiple auxillary string tables encountered\n"));
7234 free (aux.strtab);
7235 }
3f5e193b
NC
7236 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7237 1, strsec->sh_size,
7238 _("string table"));
c256ffe7 7239 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 7240 }
18bd398b 7241 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
7242 unwsec = sec;
7243 }
7244
7245 if (!unwsec)
7246 printf (_("\nThere are no unwind sections in this file.\n"));
7247
7248 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7249 {
18bd398b 7250 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 7251 {
74e1a04b
NC
7252 printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
7253 printable_section_name (sec),
57346661 7254 (unsigned long) sec->sh_offset,
89fac5e3 7255 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
7256
7257 slurp_hppa_unwind_table (file, &aux, sec);
7258 if (aux.table_len > 0)
7259 dump_hppa_unwind (&aux);
7260
7261 if (aux.table)
7262 free ((char *) aux.table);
7263 aux.table = NULL;
7264 }
7265 }
7266
7267 if (aux.symtab)
7268 free (aux.symtab);
7269 if (aux.strtab)
7270 free ((char *) aux.strtab);
57346661
AM
7271}
7272
0b6ae522
DJ
7273struct arm_section
7274{
a734115a
NC
7275 unsigned char * data; /* The unwind data. */
7276 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
7277 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
7278 unsigned long nrelas; /* The number of relocations. */
7279 unsigned int rel_type; /* REL or RELA ? */
7280 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
7281};
7282
7283struct arm_unw_aux_info
7284{
a734115a
NC
7285 FILE * file; /* The file containing the unwind sections. */
7286 Elf_Internal_Sym * symtab; /* The file's symbol table. */
7287 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
7288 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7289 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
7290 char * strtab; /* The file's string table. */
7291 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
7292};
7293
7294static const char *
7295arm_print_vma_and_name (struct arm_unw_aux_info *aux,
7296 bfd_vma fn, struct absaddr addr)
7297{
7298 const char *procname;
7299 bfd_vma sym_offset;
7300
7301 if (addr.section == SHN_UNDEF)
7302 addr.offset = fn;
7303
948f632f 7304 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
7305 aux->strtab_size, addr, &procname,
7306 &sym_offset);
7307
7308 print_vma (fn, PREFIX_HEX);
7309
7310 if (procname)
7311 {
7312 fputs (" <", stdout);
7313 fputs (procname, stdout);
7314
7315 if (sym_offset)
7316 printf ("+0x%lx", (unsigned long) sym_offset);
7317 fputc ('>', stdout);
7318 }
7319
7320 return procname;
7321}
7322
7323static void
7324arm_free_section (struct arm_section *arm_sec)
7325{
7326 if (arm_sec->data != NULL)
7327 free (arm_sec->data);
7328
7329 if (arm_sec->rela != NULL)
7330 free (arm_sec->rela);
7331}
7332
a734115a
NC
7333/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
7334 cached section and install SEC instead.
7335 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
7336 and return its valued in * WORDP, relocating if necessary.
1b31d05e 7337 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 7338 relocation's offset in ADDR.
1b31d05e
NC
7339 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
7340 into the string table of the symbol associated with the reloc. If no
7341 reloc was applied store -1 there.
7342 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
7343
7344static bfd_boolean
1b31d05e
NC
7345get_unwind_section_word (struct arm_unw_aux_info * aux,
7346 struct arm_section * arm_sec,
7347 Elf_Internal_Shdr * sec,
7348 bfd_vma word_offset,
7349 unsigned int * wordp,
7350 struct absaddr * addr,
7351 bfd_vma * sym_name)
0b6ae522
DJ
7352{
7353 Elf_Internal_Rela *rp;
7354 Elf_Internal_Sym *sym;
7355 const char * relname;
7356 unsigned int word;
7357 bfd_boolean wrapped;
7358
e0a31db1
NC
7359 if (sec == NULL || arm_sec == NULL)
7360 return FALSE;
7361
0b6ae522
DJ
7362 addr->section = SHN_UNDEF;
7363 addr->offset = 0;
7364
1b31d05e
NC
7365 if (sym_name != NULL)
7366 *sym_name = (bfd_vma) -1;
7367
a734115a 7368 /* If necessary, update the section cache. */
0b6ae522
DJ
7369 if (sec != arm_sec->sec)
7370 {
7371 Elf_Internal_Shdr *relsec;
7372
7373 arm_free_section (arm_sec);
7374
7375 arm_sec->sec = sec;
7376 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
7377 sec->sh_size, _("unwind data"));
0b6ae522
DJ
7378 arm_sec->rela = NULL;
7379 arm_sec->nrelas = 0;
7380
7381 for (relsec = section_headers;
7382 relsec < section_headers + elf_header.e_shnum;
7383 ++relsec)
7384 {
7385 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
7386 || section_headers + relsec->sh_info != sec
7387 /* PR 15745: Check the section type as well. */
7388 || (relsec->sh_type != SHT_REL
7389 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
7390 continue;
7391
a734115a 7392 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
7393 if (relsec->sh_type == SHT_REL)
7394 {
7395 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
7396 relsec->sh_size,
7397 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7398 return FALSE;
0b6ae522 7399 }
1ae40aa4 7400 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
7401 {
7402 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
7403 relsec->sh_size,
7404 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7405 return FALSE;
0b6ae522 7406 }
1ae40aa4 7407 break;
0b6ae522
DJ
7408 }
7409
7410 arm_sec->next_rela = arm_sec->rela;
7411 }
7412
a734115a 7413 /* If there is no unwind data we can do nothing. */
0b6ae522 7414 if (arm_sec->data == NULL)
a734115a 7415 return FALSE;
0b6ae522 7416
e0a31db1
NC
7417 /* If the offset is invalid then fail. */
7418 if (word_offset > sec->sh_size - 4)
7419 return FALSE;
7420
a734115a 7421 /* Get the word at the required offset. */
0b6ae522
DJ
7422 word = byte_get (arm_sec->data + word_offset, 4);
7423
0eff7165
NC
7424 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
7425 if (arm_sec->rela == NULL)
7426 {
7427 * wordp = word;
7428 return TRUE;
7429 }
7430
a734115a 7431 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
7432 wrapped = FALSE;
7433 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
7434 {
7435 bfd_vma prelval, offset;
7436
7437 if (rp->r_offset > word_offset && !wrapped)
7438 {
7439 rp = arm_sec->rela;
7440 wrapped = TRUE;
7441 }
7442 if (rp->r_offset > word_offset)
7443 break;
7444
7445 if (rp->r_offset & 3)
7446 {
7447 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
7448 (unsigned long) rp->r_offset);
7449 continue;
7450 }
7451
7452 if (rp->r_offset < word_offset)
7453 continue;
7454
74e1a04b
NC
7455 /* PR 17531: file: 027-161405-0.004 */
7456 if (aux->symtab == NULL)
7457 continue;
7458
0b6ae522
DJ
7459 if (arm_sec->rel_type == SHT_REL)
7460 {
7461 offset = word & 0x7fffffff;
7462 if (offset & 0x40000000)
7463 offset |= ~ (bfd_vma) 0x7fffffff;
7464 }
a734115a 7465 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 7466 offset = rp->r_addend;
a734115a 7467 else
74e1a04b
NC
7468 {
7469 error (_("Unknown section relocation type %d encountered\n"),
7470 arm_sec->rel_type);
7471 break;
7472 }
0b6ae522 7473
071436c6
NC
7474 /* PR 17531 file: 027-1241568-0.004. */
7475 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
7476 {
7477 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
7478 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
7479 break;
7480 }
7481
7482 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
7483 offset += sym->st_value;
7484 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
7485
a734115a
NC
7486 /* Check that we are processing the expected reloc type. */
7487 if (elf_header.e_machine == EM_ARM)
7488 {
7489 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7490 if (relname == NULL)
7491 {
7492 warn (_("Skipping unknown ARM relocation type: %d\n"),
7493 (int) ELF32_R_TYPE (rp->r_info));
7494 continue;
7495 }
a734115a
NC
7496
7497 if (streq (relname, "R_ARM_NONE"))
7498 continue;
0b4362b0 7499
a734115a
NC
7500 if (! streq (relname, "R_ARM_PREL31"))
7501 {
071436c6 7502 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
7503 continue;
7504 }
7505 }
7506 else if (elf_header.e_machine == EM_TI_C6000)
7507 {
7508 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7509 if (relname == NULL)
7510 {
7511 warn (_("Skipping unknown C6000 relocation type: %d\n"),
7512 (int) ELF32_R_TYPE (rp->r_info));
7513 continue;
7514 }
0b4362b0 7515
a734115a
NC
7516 if (streq (relname, "R_C6000_NONE"))
7517 continue;
7518
7519 if (! streq (relname, "R_C6000_PREL31"))
7520 {
071436c6 7521 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
7522 continue;
7523 }
7524
7525 prelval >>= 1;
7526 }
7527 else
74e1a04b
NC
7528 {
7529 /* This function currently only supports ARM and TI unwinders. */
7530 warn (_("Only TI and ARM unwinders are currently supported\n"));
7531 break;
7532 }
fa197c1c 7533
0b6ae522
DJ
7534 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
7535 addr->section = sym->st_shndx;
7536 addr->offset = offset;
74e1a04b 7537
1b31d05e
NC
7538 if (sym_name)
7539 * sym_name = sym->st_name;
0b6ae522
DJ
7540 break;
7541 }
7542
7543 *wordp = word;
7544 arm_sec->next_rela = rp;
7545
a734115a 7546 return TRUE;
0b6ae522
DJ
7547}
7548
a734115a
NC
7549static const char *tic6x_unwind_regnames[16] =
7550{
0b4362b0
RM
7551 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
7552 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
7553 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
7554};
fa197c1c 7555
0b6ae522 7556static void
fa197c1c 7557decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 7558{
fa197c1c
PB
7559 int i;
7560
7561 for (i = 12; mask; mask >>= 1, i--)
7562 {
7563 if (mask & 1)
7564 {
7565 fputs (tic6x_unwind_regnames[i], stdout);
7566 if (mask > 1)
7567 fputs (", ", stdout);
7568 }
7569 }
7570}
0b6ae522
DJ
7571
7572#define ADVANCE \
7573 if (remaining == 0 && more_words) \
7574 { \
7575 data_offset += 4; \
1b31d05e
NC
7576 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
7577 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
7578 return; \
7579 remaining = 4; \
7580 more_words--; \
7581 } \
7582
7583#define GET_OP(OP) \
7584 ADVANCE; \
7585 if (remaining) \
7586 { \
7587 remaining--; \
7588 (OP) = word >> 24; \
7589 word <<= 8; \
7590 } \
7591 else \
7592 { \
2b692964 7593 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
7594 return; \
7595 } \
cc5914eb 7596 printf ("0x%02x ", OP)
0b6ae522 7597
fa197c1c 7598static void
948f632f
DA
7599decode_arm_unwind_bytecode (struct arm_unw_aux_info * aux,
7600 unsigned int word,
7601 unsigned int remaining,
7602 unsigned int more_words,
7603 bfd_vma data_offset,
7604 Elf_Internal_Shdr * data_sec,
7605 struct arm_section * data_arm_sec)
fa197c1c
PB
7606{
7607 struct absaddr addr;
0b6ae522
DJ
7608
7609 /* Decode the unwinding instructions. */
7610 while (1)
7611 {
7612 unsigned int op, op2;
7613
7614 ADVANCE;
7615 if (remaining == 0)
7616 break;
7617 remaining--;
7618 op = word >> 24;
7619 word <<= 8;
7620
cc5914eb 7621 printf (" 0x%02x ", op);
0b6ae522
DJ
7622
7623 if ((op & 0xc0) == 0x00)
7624 {
7625 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7626
cc5914eb 7627 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
7628 }
7629 else if ((op & 0xc0) == 0x40)
7630 {
7631 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7632
cc5914eb 7633 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
7634 }
7635 else if ((op & 0xf0) == 0x80)
7636 {
7637 GET_OP (op2);
7638 if (op == 0x80 && op2 == 0)
7639 printf (_("Refuse to unwind"));
7640 else
7641 {
7642 unsigned int mask = ((op & 0x0f) << 8) | op2;
7643 int first = 1;
7644 int i;
2b692964 7645
0b6ae522
DJ
7646 printf ("pop {");
7647 for (i = 0; i < 12; i++)
7648 if (mask & (1 << i))
7649 {
7650 if (first)
7651 first = 0;
7652 else
7653 printf (", ");
7654 printf ("r%d", 4 + i);
7655 }
7656 printf ("}");
7657 }
7658 }
7659 else if ((op & 0xf0) == 0x90)
7660 {
7661 if (op == 0x9d || op == 0x9f)
7662 printf (_(" [Reserved]"));
7663 else
cc5914eb 7664 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
7665 }
7666 else if ((op & 0xf0) == 0xa0)
7667 {
7668 int end = 4 + (op & 0x07);
7669 int first = 1;
7670 int i;
61865e30 7671
0b6ae522
DJ
7672 printf (" pop {");
7673 for (i = 4; i <= end; i++)
7674 {
7675 if (first)
7676 first = 0;
7677 else
7678 printf (", ");
7679 printf ("r%d", i);
7680 }
7681 if (op & 0x08)
7682 {
1b31d05e 7683 if (!first)
0b6ae522
DJ
7684 printf (", ");
7685 printf ("r14");
7686 }
7687 printf ("}");
7688 }
7689 else if (op == 0xb0)
7690 printf (_(" finish"));
7691 else if (op == 0xb1)
7692 {
7693 GET_OP (op2);
7694 if (op2 == 0 || (op2 & 0xf0) != 0)
7695 printf (_("[Spare]"));
7696 else
7697 {
7698 unsigned int mask = op2 & 0x0f;
7699 int first = 1;
7700 int i;
61865e30 7701
0b6ae522
DJ
7702 printf ("pop {");
7703 for (i = 0; i < 12; i++)
7704 if (mask & (1 << i))
7705 {
7706 if (first)
7707 first = 0;
7708 else
7709 printf (", ");
7710 printf ("r%d", i);
7711 }
7712 printf ("}");
7713 }
7714 }
7715 else if (op == 0xb2)
7716 {
b115cf96 7717 unsigned char buf[9];
0b6ae522
DJ
7718 unsigned int i, len;
7719 unsigned long offset;
61865e30 7720
b115cf96 7721 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
7722 {
7723 GET_OP (buf[i]);
7724 if ((buf[i] & 0x80) == 0)
7725 break;
7726 }
4082ef84
NC
7727 if (i == sizeof (buf))
7728 printf (_("corrupt change to vsp"));
7729 else
7730 {
7731 offset = read_uleb128 (buf, &len, buf + i + 1);
7732 assert (len == i + 1);
7733 offset = offset * 4 + 0x204;
7734 printf ("vsp = vsp + %ld", offset);
7735 }
0b6ae522 7736 }
61865e30 7737 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 7738 {
61865e30
NC
7739 unsigned int first, last;
7740
7741 GET_OP (op2);
7742 first = op2 >> 4;
7743 last = op2 & 0x0f;
7744 if (op == 0xc8)
7745 first = first + 16;
7746 printf ("pop {D%d", first);
7747 if (last)
7748 printf ("-D%d", first + last);
7749 printf ("}");
7750 }
7751 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
7752 {
7753 unsigned int count = op & 0x07;
7754
7755 printf ("pop {D8");
7756 if (count)
7757 printf ("-D%d", 8 + count);
7758 printf ("}");
7759 }
7760 else if (op >= 0xc0 && op <= 0xc5)
7761 {
7762 unsigned int count = op & 0x07;
7763
7764 printf (" pop {wR10");
7765 if (count)
7766 printf ("-wR%d", 10 + count);
7767 printf ("}");
7768 }
7769 else if (op == 0xc6)
7770 {
7771 unsigned int first, last;
7772
7773 GET_OP (op2);
7774 first = op2 >> 4;
7775 last = op2 & 0x0f;
7776 printf ("pop {wR%d", first);
7777 if (last)
7778 printf ("-wR%d", first + last);
7779 printf ("}");
7780 }
7781 else if (op == 0xc7)
7782 {
7783 GET_OP (op2);
7784 if (op2 == 0 || (op2 & 0xf0) != 0)
7785 printf (_("[Spare]"));
0b6ae522
DJ
7786 else
7787 {
61865e30
NC
7788 unsigned int mask = op2 & 0x0f;
7789 int first = 1;
7790 int i;
7791
7792 printf ("pop {");
7793 for (i = 0; i < 4; i++)
7794 if (mask & (1 << i))
7795 {
7796 if (first)
7797 first = 0;
7798 else
7799 printf (", ");
7800 printf ("wCGR%d", i);
7801 }
7802 printf ("}");
0b6ae522
DJ
7803 }
7804 }
61865e30
NC
7805 else
7806 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7807 printf ("\n");
7808 }
fa197c1c
PB
7809}
7810
7811static void
948f632f
DA
7812decode_tic6x_unwind_bytecode (struct arm_unw_aux_info * aux,
7813 unsigned int word,
7814 unsigned int remaining,
7815 unsigned int more_words,
7816 bfd_vma data_offset,
7817 Elf_Internal_Shdr * data_sec,
7818 struct arm_section * data_arm_sec)
fa197c1c
PB
7819{
7820 struct absaddr addr;
7821
7822 /* Decode the unwinding instructions. */
7823 while (1)
7824 {
7825 unsigned int op, op2;
7826
7827 ADVANCE;
7828 if (remaining == 0)
7829 break;
7830 remaining--;
7831 op = word >> 24;
7832 word <<= 8;
7833
9cf03b7e 7834 printf (" 0x%02x ", op);
fa197c1c
PB
7835
7836 if ((op & 0xc0) == 0x00)
7837 {
7838 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7839 printf (" sp = sp + %d", offset);
fa197c1c
PB
7840 }
7841 else if ((op & 0xc0) == 0x80)
7842 {
7843 GET_OP (op2);
7844 if (op == 0x80 && op2 == 0)
7845 printf (_("Refuse to unwind"));
7846 else
7847 {
7848 unsigned int mask = ((op & 0x1f) << 8) | op2;
7849 if (op & 0x20)
7850 printf ("pop compact {");
7851 else
7852 printf ("pop {");
7853
7854 decode_tic6x_unwind_regmask (mask);
7855 printf("}");
7856 }
7857 }
7858 else if ((op & 0xf0) == 0xc0)
7859 {
7860 unsigned int reg;
7861 unsigned int nregs;
7862 unsigned int i;
7863 const char *name;
a734115a
NC
7864 struct
7865 {
fa197c1c
PB
7866 unsigned int offset;
7867 unsigned int reg;
7868 } regpos[16];
7869
7870 /* Scan entire instruction first so that GET_OP output is not
7871 interleaved with disassembly. */
7872 nregs = 0;
7873 for (i = 0; nregs < (op & 0xf); i++)
7874 {
7875 GET_OP (op2);
7876 reg = op2 >> 4;
7877 if (reg != 0xf)
7878 {
7879 regpos[nregs].offset = i * 2;
7880 regpos[nregs].reg = reg;
7881 nregs++;
7882 }
7883
7884 reg = op2 & 0xf;
7885 if (reg != 0xf)
7886 {
7887 regpos[nregs].offset = i * 2 + 1;
7888 regpos[nregs].reg = reg;
7889 nregs++;
7890 }
7891 }
7892
7893 printf (_("pop frame {"));
7894 reg = nregs - 1;
7895 for (i = i * 2; i > 0; i--)
7896 {
7897 if (regpos[reg].offset == i - 1)
7898 {
7899 name = tic6x_unwind_regnames[regpos[reg].reg];
7900 if (reg > 0)
7901 reg--;
7902 }
7903 else
7904 name = _("[pad]");
7905
7906 fputs (name, stdout);
7907 if (i > 1)
7908 printf (", ");
7909 }
7910
7911 printf ("}");
7912 }
7913 else if (op == 0xd0)
7914 printf (" MOV FP, SP");
7915 else if (op == 0xd1)
7916 printf (" __c6xabi_pop_rts");
7917 else if (op == 0xd2)
7918 {
7919 unsigned char buf[9];
7920 unsigned int i, len;
7921 unsigned long offset;
a734115a 7922
fa197c1c
PB
7923 for (i = 0; i < sizeof (buf); i++)
7924 {
7925 GET_OP (buf[i]);
7926 if ((buf[i] & 0x80) == 0)
7927 break;
7928 }
0eff7165
NC
7929 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
7930 if (i == sizeof (buf))
7931 {
7932 printf ("<corrupt sp adjust>\n");
7933 warn (_("Corrupt stack pointer adjustment detected\n"));
7934 return;
7935 }
948f632f 7936
f6f0e17b 7937 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7938 assert (len == i + 1);
7939 offset = offset * 8 + 0x408;
7940 printf (_("sp = sp + %ld"), offset);
7941 }
7942 else if ((op & 0xf0) == 0xe0)
7943 {
7944 if ((op & 0x0f) == 7)
7945 printf (" RETURN");
7946 else
7947 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7948 }
7949 else
7950 {
7951 printf (_(" [unsupported opcode]"));
7952 }
7953 putchar ('\n');
7954 }
7955}
7956
7957static bfd_vma
a734115a 7958arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7959{
7960 bfd_vma offset;
7961
7962 offset = word & 0x7fffffff;
7963 if (offset & 0x40000000)
7964 offset |= ~ (bfd_vma) 0x7fffffff;
7965
7966 if (elf_header.e_machine == EM_TI_C6000)
7967 offset <<= 1;
7968
7969 return offset + where;
7970}
7971
7972static void
1b31d05e
NC
7973decode_arm_unwind (struct arm_unw_aux_info * aux,
7974 unsigned int word,
7975 unsigned int remaining,
7976 bfd_vma data_offset,
7977 Elf_Internal_Shdr * data_sec,
7978 struct arm_section * data_arm_sec)
fa197c1c
PB
7979{
7980 int per_index;
7981 unsigned int more_words = 0;
37e14bc3 7982 struct absaddr addr;
1b31d05e 7983 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7984
7985 if (remaining == 0)
7986 {
1b31d05e
NC
7987 /* Fetch the first word.
7988 Note - when decoding an object file the address extracted
7989 here will always be 0. So we also pass in the sym_name
7990 parameter so that we can find the symbol associated with
7991 the personality routine. */
7992 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7993 & word, & addr, & sym_name))
fa197c1c 7994 return;
1b31d05e 7995
fa197c1c
PB
7996 remaining = 4;
7997 }
7998
7999 if ((word & 0x80000000) == 0)
8000 {
8001 /* Expand prel31 for personality routine. */
8002 bfd_vma fn;
8003 const char *procname;
8004
a734115a 8005 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 8006 printf (_(" Personality routine: "));
1b31d05e
NC
8007 if (fn == 0
8008 && addr.section == SHN_UNDEF && addr.offset == 0
8009 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
8010 {
8011 procname = aux->strtab + sym_name;
8012 print_vma (fn, PREFIX_HEX);
8013 if (procname)
8014 {
8015 fputs (" <", stdout);
8016 fputs (procname, stdout);
8017 fputc ('>', stdout);
8018 }
8019 }
8020 else
8021 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
8022 fputc ('\n', stdout);
8023
8024 /* The GCC personality routines use the standard compact
8025 encoding, starting with one byte giving the number of
8026 words. */
8027 if (procname != NULL
8028 && (const_strneq (procname, "__gcc_personality_v0")
8029 || const_strneq (procname, "__gxx_personality_v0")
8030 || const_strneq (procname, "__gcj_personality_v0")
8031 || const_strneq (procname, "__gnu_objc_personality_v0")))
8032 {
8033 remaining = 0;
8034 more_words = 1;
8035 ADVANCE;
8036 if (!remaining)
8037 {
8038 printf (_(" [Truncated data]\n"));
8039 return;
8040 }
8041 more_words = word >> 24;
8042 word <<= 8;
8043 remaining--;
8044 per_index = -1;
8045 }
8046 else
8047 return;
8048 }
8049 else
8050 {
1b31d05e 8051 /* ARM EHABI Section 6.3:
0b4362b0 8052
1b31d05e 8053 An exception-handling table entry for the compact model looks like:
0b4362b0 8054
1b31d05e
NC
8055 31 30-28 27-24 23-0
8056 -- ----- ----- ----
8057 1 0 index Data for personalityRoutine[index] */
8058
8059 if (elf_header.e_machine == EM_ARM
8060 && (word & 0x70000000))
83c257ca 8061 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 8062
fa197c1c 8063 per_index = (word >> 24) & 0x7f;
1b31d05e 8064 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
8065 if (per_index == 0)
8066 {
8067 more_words = 0;
8068 word <<= 8;
8069 remaining--;
8070 }
8071 else if (per_index < 3)
8072 {
8073 more_words = (word >> 16) & 0xff;
8074 word <<= 16;
8075 remaining -= 2;
8076 }
8077 }
8078
8079 switch (elf_header.e_machine)
8080 {
8081 case EM_ARM:
8082 if (per_index < 3)
8083 {
8084 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
8085 data_offset, data_sec, data_arm_sec);
8086 }
8087 else
1b31d05e
NC
8088 {
8089 warn (_("Unknown ARM compact model index encountered\n"));
8090 printf (_(" [reserved]\n"));
8091 }
fa197c1c
PB
8092 break;
8093
8094 case EM_TI_C6000:
8095 if (per_index < 3)
8096 {
8097 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 8098 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
8099 }
8100 else if (per_index < 5)
8101 {
8102 if (((word >> 17) & 0x7f) == 0x7f)
8103 printf (_(" Restore stack from frame pointer\n"));
8104 else
8105 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
8106 printf (_(" Registers restored: "));
8107 if (per_index == 4)
8108 printf (" (compact) ");
8109 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
8110 putchar ('\n');
8111 printf (_(" Return register: %s\n"),
8112 tic6x_unwind_regnames[word & 0xf]);
8113 }
8114 else
1b31d05e 8115 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
8116 break;
8117
8118 default:
74e1a04b 8119 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
1b31d05e 8120 elf_header.e_machine);
fa197c1c 8121 }
0b6ae522
DJ
8122
8123 /* Decode the descriptors. Not implemented. */
8124}
8125
8126static void
8127dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
8128{
8129 struct arm_section exidx_arm_sec, extab_arm_sec;
8130 unsigned int i, exidx_len;
948f632f 8131 unsigned long j, nfuns;
0b6ae522
DJ
8132
8133 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
8134 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
8135 exidx_len = exidx_sec->sh_size / 8;
8136
948f632f
DA
8137 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8138 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8139 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8140 aux->funtab[nfuns++] = aux->symtab[j];
8141 aux->nfuns = nfuns;
8142 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8143
0b6ae522
DJ
8144 for (i = 0; i < exidx_len; i++)
8145 {
8146 unsigned int exidx_fn, exidx_entry;
8147 struct absaddr fn_addr, entry_addr;
8148 bfd_vma fn;
8149
8150 fputc ('\n', stdout);
8151
1b31d05e
NC
8152 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8153 8 * i, & exidx_fn, & fn_addr, NULL)
8154 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8155 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 8156 {
948f632f 8157 free (aux->funtab);
1b31d05e
NC
8158 arm_free_section (& exidx_arm_sec);
8159 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
8160 return;
8161 }
8162
83c257ca
NC
8163 /* ARM EHABI, Section 5:
8164 An index table entry consists of 2 words.
8165 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
8166 if (exidx_fn & 0x80000000)
8167 warn (_("corrupt index table entry: %x\n"), exidx_fn);
8168
a734115a 8169 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 8170
a734115a 8171 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
8172 fputs (": ", stdout);
8173
8174 if (exidx_entry == 1)
8175 {
8176 print_vma (exidx_entry, PREFIX_HEX);
8177 fputs (" [cantunwind]\n", stdout);
8178 }
8179 else if (exidx_entry & 0x80000000)
8180 {
8181 print_vma (exidx_entry, PREFIX_HEX);
8182 fputc ('\n', stdout);
8183 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
8184 }
8185 else
8186 {
8f73510c 8187 bfd_vma table, table_offset = 0;
0b6ae522
DJ
8188 Elf_Internal_Shdr *table_sec;
8189
8190 fputs ("@", stdout);
a734115a 8191 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
8192 print_vma (table, PREFIX_HEX);
8193 printf ("\n");
8194
8195 /* Locate the matching .ARM.extab. */
8196 if (entry_addr.section != SHN_UNDEF
8197 && entry_addr.section < elf_header.e_shnum)
8198 {
8199 table_sec = section_headers + entry_addr.section;
8200 table_offset = entry_addr.offset;
8201 }
8202 else
8203 {
8204 table_sec = find_section_by_address (table);
8205 if (table_sec != NULL)
8206 table_offset = table - table_sec->sh_addr;
8207 }
8208 if (table_sec == NULL)
8209 {
8210 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
8211 (unsigned long) table);
8212 continue;
8213 }
8214 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
8215 &extab_arm_sec);
8216 }
8217 }
8218
8219 printf ("\n");
8220
948f632f 8221 free (aux->funtab);
0b6ae522
DJ
8222 arm_free_section (&exidx_arm_sec);
8223 arm_free_section (&extab_arm_sec);
8224}
8225
fa197c1c 8226/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
8227
8228static void
0b6ae522
DJ
8229arm_process_unwind (FILE *file)
8230{
8231 struct arm_unw_aux_info aux;
8232 Elf_Internal_Shdr *unwsec = NULL;
8233 Elf_Internal_Shdr *strsec;
8234 Elf_Internal_Shdr *sec;
8235 unsigned long i;
fa197c1c 8236 unsigned int sec_type;
0b6ae522 8237
fa197c1c
PB
8238 switch (elf_header.e_machine)
8239 {
8240 case EM_ARM:
8241 sec_type = SHT_ARM_EXIDX;
8242 break;
8243
8244 case EM_TI_C6000:
8245 sec_type = SHT_C6000_UNWIND;
8246 break;
8247
0b4362b0 8248 default:
74e1a04b 8249 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
1b31d05e
NC
8250 elf_header.e_machine);
8251 return;
fa197c1c
PB
8252 }
8253
0b6ae522 8254 if (string_table == NULL)
1b31d05e
NC
8255 return;
8256
8257 memset (& aux, 0, sizeof (aux));
8258 aux.file = file;
0b6ae522
DJ
8259
8260 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8261 {
8262 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
8263 {
ba5cdace 8264 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
8265
8266 strsec = section_headers + sec->sh_link;
74e1a04b
NC
8267
8268 /* PR binutils/17531 file: 011-12666-0.004. */
8269 if (aux.strtab != NULL)
8270 {
4082ef84 8271 error (_("Multiple string tables found in file.\n"));
74e1a04b
NC
8272 free (aux.strtab);
8273 }
0b6ae522
DJ
8274 aux.strtab = get_data (NULL, file, strsec->sh_offset,
8275 1, strsec->sh_size, _("string table"));
8276 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
8277 }
fa197c1c 8278 else if (sec->sh_type == sec_type)
0b6ae522
DJ
8279 unwsec = sec;
8280 }
8281
1b31d05e 8282 if (unwsec == NULL)
0b6ae522 8283 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
8284 else
8285 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8286 {
8287 if (sec->sh_type == sec_type)
8288 {
8289 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
74e1a04b 8290 printable_section_name (sec),
1b31d05e
NC
8291 (unsigned long) sec->sh_offset,
8292 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 8293
1b31d05e
NC
8294 dump_arm_unwind (&aux, sec);
8295 }
8296 }
0b6ae522
DJ
8297
8298 if (aux.symtab)
8299 free (aux.symtab);
8300 if (aux.strtab)
8301 free ((char *) aux.strtab);
0b6ae522
DJ
8302}
8303
1b31d05e 8304static void
2cf0635d 8305process_unwind (FILE * file)
57346661 8306{
2cf0635d
NC
8307 struct unwind_handler
8308 {
57346661 8309 int machtype;
1b31d05e 8310 void (* handler)(FILE *);
2cf0635d
NC
8311 } handlers[] =
8312 {
0b6ae522 8313 { EM_ARM, arm_process_unwind },
57346661
AM
8314 { EM_IA_64, ia64_process_unwind },
8315 { EM_PARISC, hppa_process_unwind },
fa197c1c 8316 { EM_TI_C6000, arm_process_unwind },
57346661
AM
8317 { 0, 0 }
8318 };
8319 int i;
8320
8321 if (!do_unwind)
1b31d05e 8322 return;
57346661
AM
8323
8324 for (i = 0; handlers[i].handler != NULL; i++)
8325 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
8326 {
8327 handlers[i].handler (file);
8328 return;
8329 }
57346661 8330
1b31d05e
NC
8331 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
8332 get_machine_name (elf_header.e_machine));
57346661
AM
8333}
8334
252b5132 8335static void
2cf0635d 8336dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
8337{
8338 switch (entry->d_tag)
8339 {
8340 case DT_MIPS_FLAGS:
8341 if (entry->d_un.d_val == 0)
4b68bca3 8342 printf (_("NONE"));
252b5132
RH
8343 else
8344 {
8345 static const char * opts[] =
8346 {
8347 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
8348 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
8349 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
8350 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
8351 "RLD_ORDER_SAFE"
8352 };
8353 unsigned int cnt;
8354 int first = 1;
2b692964 8355
60bca95a 8356 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
8357 if (entry->d_un.d_val & (1 << cnt))
8358 {
8359 printf ("%s%s", first ? "" : " ", opts[cnt]);
8360 first = 0;
8361 }
252b5132
RH
8362 }
8363 break;
103f02d3 8364
252b5132 8365 case DT_MIPS_IVERSION:
d79b3d50 8366 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 8367 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8368 else
76ca31c0
NC
8369 {
8370 char buf[40];
8371 sprintf_vma (buf, entry->d_un.d_ptr);
8372 /* Note: coded this way so that there is a single string for translation. */
8373 printf (_("<corrupt: %s>"), buf);
8374 }
252b5132 8375 break;
103f02d3 8376
252b5132
RH
8377 case DT_MIPS_TIME_STAMP:
8378 {
8379 char timebuf[20];
2cf0635d 8380 struct tm * tmp;
91d6fa6a 8381 time_t atime = entry->d_un.d_val;
82b1b41b 8382
91d6fa6a 8383 tmp = gmtime (&atime);
82b1b41b
NC
8384 /* PR 17531: file: 6accc532. */
8385 if (tmp == NULL)
8386 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
8387 else
8388 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
8389 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8390 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 8391 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
8392 }
8393 break;
103f02d3 8394
252b5132
RH
8395 case DT_MIPS_RLD_VERSION:
8396 case DT_MIPS_LOCAL_GOTNO:
8397 case DT_MIPS_CONFLICTNO:
8398 case DT_MIPS_LIBLISTNO:
8399 case DT_MIPS_SYMTABNO:
8400 case DT_MIPS_UNREFEXTNO:
8401 case DT_MIPS_HIPAGENO:
8402 case DT_MIPS_DELTA_CLASS_NO:
8403 case DT_MIPS_DELTA_INSTANCE_NO:
8404 case DT_MIPS_DELTA_RELOC_NO:
8405 case DT_MIPS_DELTA_SYM_NO:
8406 case DT_MIPS_DELTA_CLASSSYM_NO:
8407 case DT_MIPS_COMPACT_SIZE:
4b68bca3 8408 print_vma (entry->d_un.d_ptr, DEC);
252b5132 8409 break;
103f02d3
UD
8410
8411 default:
4b68bca3 8412 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 8413 }
4b68bca3 8414 putchar ('\n');
103f02d3
UD
8415}
8416
103f02d3 8417static void
2cf0635d 8418dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
8419{
8420 switch (entry->d_tag)
8421 {
8422 case DT_HP_DLD_FLAGS:
8423 {
8424 static struct
8425 {
8426 long int bit;
2cf0635d 8427 const char * str;
5e220199
NC
8428 }
8429 flags[] =
8430 {
8431 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
8432 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
8433 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
8434 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
8435 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
8436 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
8437 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
8438 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
8439 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
8440 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
8441 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
8442 { DT_HP_GST, "HP_GST" },
8443 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
8444 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
8445 { DT_HP_NODELETE, "HP_NODELETE" },
8446 { DT_HP_GROUP, "HP_GROUP" },
8447 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 8448 };
103f02d3 8449 int first = 1;
5e220199 8450 size_t cnt;
f7a99963 8451 bfd_vma val = entry->d_un.d_val;
103f02d3 8452
60bca95a 8453 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 8454 if (val & flags[cnt].bit)
30800947
NC
8455 {
8456 if (! first)
8457 putchar (' ');
8458 fputs (flags[cnt].str, stdout);
8459 first = 0;
8460 val ^= flags[cnt].bit;
8461 }
76da6bbe 8462
103f02d3 8463 if (val != 0 || first)
f7a99963
NC
8464 {
8465 if (! first)
8466 putchar (' ');
8467 print_vma (val, HEX);
8468 }
103f02d3
UD
8469 }
8470 break;
76da6bbe 8471
252b5132 8472 default:
f7a99963
NC
8473 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8474 break;
252b5132 8475 }
35b1837e 8476 putchar ('\n');
252b5132
RH
8477}
8478
28f997cf
TG
8479#ifdef BFD64
8480
8481/* VMS vs Unix time offset and factor. */
8482
8483#define VMS_EPOCH_OFFSET 35067168000000000LL
8484#define VMS_GRANULARITY_FACTOR 10000000
8485
8486/* Display a VMS time in a human readable format. */
8487
8488static void
8489print_vms_time (bfd_int64_t vmstime)
8490{
8491 struct tm *tm;
8492 time_t unxtime;
8493
8494 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
8495 tm = gmtime (&unxtime);
8496 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
8497 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
8498 tm->tm_hour, tm->tm_min, tm->tm_sec);
8499}
8500#endif /* BFD64 */
8501
ecc51f48 8502static void
2cf0635d 8503dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
8504{
8505 switch (entry->d_tag)
8506 {
0de14b54 8507 case DT_IA_64_PLT_RESERVE:
bdf4d63a 8508 /* First 3 slots reserved. */
ecc51f48
NC
8509 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8510 printf (" -- ");
8511 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
8512 break;
8513
28f997cf
TG
8514 case DT_IA_64_VMS_LINKTIME:
8515#ifdef BFD64
8516 print_vms_time (entry->d_un.d_val);
8517#endif
8518 break;
8519
8520 case DT_IA_64_VMS_LNKFLAGS:
8521 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8522 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
8523 printf (" CALL_DEBUG");
8524 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
8525 printf (" NOP0BUFS");
8526 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
8527 printf (" P0IMAGE");
8528 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
8529 printf (" MKTHREADS");
8530 if (entry->d_un.d_val & VMS_LF_UPCALLS)
8531 printf (" UPCALLS");
8532 if (entry->d_un.d_val & VMS_LF_IMGSTA)
8533 printf (" IMGSTA");
8534 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
8535 printf (" INITIALIZE");
8536 if (entry->d_un.d_val & VMS_LF_MAIN)
8537 printf (" MAIN");
8538 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
8539 printf (" EXE_INIT");
8540 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
8541 printf (" TBK_IN_IMG");
8542 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
8543 printf (" DBG_IN_IMG");
8544 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
8545 printf (" TBK_IN_DSF");
8546 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
8547 printf (" DBG_IN_DSF");
8548 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
8549 printf (" SIGNATURES");
8550 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
8551 printf (" REL_SEG_OFF");
8552 break;
8553
bdf4d63a
JJ
8554 default:
8555 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8556 break;
ecc51f48 8557 }
bdf4d63a 8558 putchar ('\n');
ecc51f48
NC
8559}
8560
252b5132 8561static int
2cf0635d 8562get_32bit_dynamic_section (FILE * file)
252b5132 8563{
2cf0635d
NC
8564 Elf32_External_Dyn * edyn;
8565 Elf32_External_Dyn * ext;
8566 Elf_Internal_Dyn * entry;
103f02d3 8567
3f5e193b
NC
8568 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8569 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8570 if (!edyn)
8571 return 0;
103f02d3 8572
071436c6
NC
8573 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8574 might not have the luxury of section headers. Look for the DT_NULL
8575 terminator to determine the number of entries. */
ba2685cc 8576 for (ext = edyn, dynamic_nent = 0;
071436c6 8577 (char *) ext < (char *) edyn + dynamic_size - sizeof (* entry);
ba2685cc
AM
8578 ext++)
8579 {
8580 dynamic_nent++;
8581 if (BYTE_GET (ext->d_tag) == DT_NULL)
8582 break;
8583 }
252b5132 8584
3f5e193b
NC
8585 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8586 sizeof (* entry));
b2d38a17 8587 if (dynamic_section == NULL)
252b5132 8588 {
8b73c356
NC
8589 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8590 (unsigned long) dynamic_nent);
9ea033b2
NC
8591 free (edyn);
8592 return 0;
8593 }
252b5132 8594
fb514b26 8595 for (ext = edyn, entry = dynamic_section;
ba2685cc 8596 entry < dynamic_section + dynamic_nent;
fb514b26 8597 ext++, entry++)
9ea033b2 8598 {
fb514b26
AM
8599 entry->d_tag = BYTE_GET (ext->d_tag);
8600 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8601 }
8602
9ea033b2
NC
8603 free (edyn);
8604
8605 return 1;
8606}
8607
8608static int
2cf0635d 8609get_64bit_dynamic_section (FILE * file)
9ea033b2 8610{
2cf0635d
NC
8611 Elf64_External_Dyn * edyn;
8612 Elf64_External_Dyn * ext;
8613 Elf_Internal_Dyn * entry;
103f02d3 8614
071436c6 8615 /* Read in the data. */
3f5e193b
NC
8616 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8617 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8618 if (!edyn)
8619 return 0;
103f02d3 8620
071436c6
NC
8621 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8622 might not have the luxury of section headers. Look for the DT_NULL
8623 terminator to determine the number of entries. */
ba2685cc 8624 for (ext = edyn, dynamic_nent = 0;
071436c6
NC
8625 /* PR 17533 file: 033-67080-0.004 - do not read off the end of the buffer. */
8626 (char *) ext < ((char *) edyn) + dynamic_size - sizeof (* ext);
ba2685cc
AM
8627 ext++)
8628 {
8629 dynamic_nent++;
66543521 8630 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
8631 break;
8632 }
252b5132 8633
3f5e193b
NC
8634 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8635 sizeof (* entry));
b2d38a17 8636 if (dynamic_section == NULL)
252b5132 8637 {
8b73c356
NC
8638 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8639 (unsigned long) dynamic_nent);
252b5132
RH
8640 free (edyn);
8641 return 0;
8642 }
8643
071436c6 8644 /* Convert from external to internal formats. */
fb514b26 8645 for (ext = edyn, entry = dynamic_section;
ba2685cc 8646 entry < dynamic_section + dynamic_nent;
fb514b26 8647 ext++, entry++)
252b5132 8648 {
66543521
AM
8649 entry->d_tag = BYTE_GET (ext->d_tag);
8650 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8651 }
8652
8653 free (edyn);
8654
9ea033b2
NC
8655 return 1;
8656}
8657
e9e44622
JJ
8658static void
8659print_dynamic_flags (bfd_vma flags)
d1133906 8660{
e9e44622 8661 int first = 1;
13ae64f3 8662
d1133906
NC
8663 while (flags)
8664 {
8665 bfd_vma flag;
8666
8667 flag = flags & - flags;
8668 flags &= ~ flag;
8669
e9e44622
JJ
8670 if (first)
8671 first = 0;
8672 else
8673 putc (' ', stdout);
13ae64f3 8674
d1133906
NC
8675 switch (flag)
8676 {
e9e44622
JJ
8677 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
8678 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
8679 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
8680 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
8681 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 8682 default: fputs (_("unknown"), stdout); break;
d1133906
NC
8683 }
8684 }
e9e44622 8685 puts ("");
d1133906
NC
8686}
8687
b2d38a17
NC
8688/* Parse and display the contents of the dynamic section. */
8689
9ea033b2 8690static int
2cf0635d 8691process_dynamic_section (FILE * file)
9ea033b2 8692{
2cf0635d 8693 Elf_Internal_Dyn * entry;
9ea033b2
NC
8694
8695 if (dynamic_size == 0)
8696 {
8697 if (do_dynamic)
b2d38a17 8698 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
8699
8700 return 1;
8701 }
8702
8703 if (is_32bit_elf)
8704 {
b2d38a17 8705 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
8706 return 0;
8707 }
b2d38a17 8708 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
8709 return 0;
8710
252b5132
RH
8711 /* Find the appropriate symbol table. */
8712 if (dynamic_symbols == NULL)
8713 {
86dba8ee
AM
8714 for (entry = dynamic_section;
8715 entry < dynamic_section + dynamic_nent;
8716 ++entry)
252b5132 8717 {
c8286bd1 8718 Elf_Internal_Shdr section;
252b5132
RH
8719
8720 if (entry->d_tag != DT_SYMTAB)
8721 continue;
8722
8723 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
8724
8725 /* Since we do not know how big the symbol table is,
8726 we default to reading in the entire file (!) and
8727 processing that. This is overkill, I know, but it
e3c8793a 8728 should work. */
d93f0186 8729 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 8730
fb52b2f4
NC
8731 if (archive_file_offset != 0)
8732 section.sh_size = archive_file_size - section.sh_offset;
8733 else
8734 {
8735 if (fseek (file, 0, SEEK_END))
591a748a 8736 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
8737
8738 section.sh_size = ftell (file) - section.sh_offset;
8739 }
252b5132 8740
9ea033b2 8741 if (is_32bit_elf)
9ad5cbcf 8742 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 8743 else
9ad5cbcf 8744 section.sh_entsize = sizeof (Elf64_External_Sym);
071436c6 8745 section.sh_name = string_table_length;
252b5132 8746
ba5cdace 8747 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 8748 if (num_dynamic_syms < 1)
252b5132
RH
8749 {
8750 error (_("Unable to determine the number of symbols to load\n"));
8751 continue;
8752 }
252b5132
RH
8753 }
8754 }
8755
8756 /* Similarly find a string table. */
8757 if (dynamic_strings == NULL)
8758 {
86dba8ee
AM
8759 for (entry = dynamic_section;
8760 entry < dynamic_section + dynamic_nent;
8761 ++entry)
252b5132
RH
8762 {
8763 unsigned long offset;
b34976b6 8764 long str_tab_len;
252b5132
RH
8765
8766 if (entry->d_tag != DT_STRTAB)
8767 continue;
8768
8769 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
8770
8771 /* Since we do not know how big the string table is,
8772 we default to reading in the entire file (!) and
8773 processing that. This is overkill, I know, but it
e3c8793a 8774 should work. */
252b5132 8775
d93f0186 8776 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
8777
8778 if (archive_file_offset != 0)
8779 str_tab_len = archive_file_size - offset;
8780 else
8781 {
8782 if (fseek (file, 0, SEEK_END))
8783 error (_("Unable to seek to end of file\n"));
8784 str_tab_len = ftell (file) - offset;
8785 }
252b5132
RH
8786
8787 if (str_tab_len < 1)
8788 {
8789 error
8790 (_("Unable to determine the length of the dynamic string table\n"));
8791 continue;
8792 }
8793
3f5e193b
NC
8794 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
8795 str_tab_len,
8796 _("dynamic string table"));
59245841 8797 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
8798 break;
8799 }
8800 }
8801
8802 /* And find the syminfo section if available. */
8803 if (dynamic_syminfo == NULL)
8804 {
3e8bba36 8805 unsigned long syminsz = 0;
252b5132 8806
86dba8ee
AM
8807 for (entry = dynamic_section;
8808 entry < dynamic_section + dynamic_nent;
8809 ++entry)
252b5132
RH
8810 {
8811 if (entry->d_tag == DT_SYMINENT)
8812 {
8813 /* Note: these braces are necessary to avoid a syntax
8814 error from the SunOS4 C compiler. */
049b0c3a
NC
8815 /* PR binutils/17531: A corrupt file can trigger this test.
8816 So do not use an assert, instead generate an error message. */
8817 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 8818 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 8819 (int) entry->d_un.d_val);
252b5132
RH
8820 }
8821 else if (entry->d_tag == DT_SYMINSZ)
8822 syminsz = entry->d_un.d_val;
8823 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
8824 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
8825 syminsz);
252b5132
RH
8826 }
8827
8828 if (dynamic_syminfo_offset != 0 && syminsz != 0)
8829 {
2cf0635d
NC
8830 Elf_External_Syminfo * extsyminfo;
8831 Elf_External_Syminfo * extsym;
8832 Elf_Internal_Syminfo * syminfo;
252b5132
RH
8833
8834 /* There is a syminfo section. Read the data. */
3f5e193b
NC
8835 extsyminfo = (Elf_External_Syminfo *)
8836 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
8837 _("symbol information"));
a6e9f9df
AM
8838 if (!extsyminfo)
8839 return 0;
252b5132 8840
3f5e193b 8841 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
8842 if (dynamic_syminfo == NULL)
8843 {
8b73c356
NC
8844 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
8845 (unsigned long) syminsz);
252b5132
RH
8846 return 0;
8847 }
8848
8849 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8850 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8851 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8852 ++syminfo, ++extsym)
252b5132 8853 {
86dba8ee
AM
8854 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8855 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8856 }
8857
8858 free (extsyminfo);
8859 }
8860 }
8861
8862 if (do_dynamic && dynamic_addr)
8b73c356
NC
8863 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
8864 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
8865 if (do_dynamic)
8866 printf (_(" Tag Type Name/Value\n"));
8867
86dba8ee
AM
8868 for (entry = dynamic_section;
8869 entry < dynamic_section + dynamic_nent;
8870 entry++)
252b5132
RH
8871 {
8872 if (do_dynamic)
f7a99963 8873 {
2cf0635d 8874 const char * dtype;
e699b9ff 8875
f7a99963
NC
8876 putchar (' ');
8877 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8878 dtype = get_dynamic_type (entry->d_tag);
8879 printf (" (%s)%*s", dtype,
8880 ((is_32bit_elf ? 27 : 19)
8881 - (int) strlen (dtype)),
f7a99963
NC
8882 " ");
8883 }
252b5132
RH
8884
8885 switch (entry->d_tag)
8886 {
d1133906
NC
8887 case DT_FLAGS:
8888 if (do_dynamic)
e9e44622 8889 print_dynamic_flags (entry->d_un.d_val);
d1133906 8890 break;
76da6bbe 8891
252b5132
RH
8892 case DT_AUXILIARY:
8893 case DT_FILTER:
019148e4
L
8894 case DT_CONFIG:
8895 case DT_DEPAUDIT:
8896 case DT_AUDIT:
252b5132
RH
8897 if (do_dynamic)
8898 {
019148e4 8899 switch (entry->d_tag)
b34976b6 8900 {
019148e4
L
8901 case DT_AUXILIARY:
8902 printf (_("Auxiliary library"));
8903 break;
8904
8905 case DT_FILTER:
8906 printf (_("Filter library"));
8907 break;
8908
b34976b6 8909 case DT_CONFIG:
019148e4
L
8910 printf (_("Configuration file"));
8911 break;
8912
8913 case DT_DEPAUDIT:
8914 printf (_("Dependency audit library"));
8915 break;
8916
8917 case DT_AUDIT:
8918 printf (_("Audit library"));
8919 break;
8920 }
252b5132 8921
d79b3d50
NC
8922 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8923 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8924 else
f7a99963
NC
8925 {
8926 printf (": ");
8927 print_vma (entry->d_un.d_val, PREFIX_HEX);
8928 putchar ('\n');
8929 }
252b5132
RH
8930 }
8931 break;
8932
dcefbbbd 8933 case DT_FEATURE:
252b5132
RH
8934 if (do_dynamic)
8935 {
8936 printf (_("Flags:"));
86f55779 8937
252b5132
RH
8938 if (entry->d_un.d_val == 0)
8939 printf (_(" None\n"));
8940 else
8941 {
8942 unsigned long int val = entry->d_un.d_val;
86f55779 8943
252b5132
RH
8944 if (val & DTF_1_PARINIT)
8945 {
8946 printf (" PARINIT");
8947 val ^= DTF_1_PARINIT;
8948 }
dcefbbbd
L
8949 if (val & DTF_1_CONFEXP)
8950 {
8951 printf (" CONFEXP");
8952 val ^= DTF_1_CONFEXP;
8953 }
252b5132
RH
8954 if (val != 0)
8955 printf (" %lx", val);
8956 puts ("");
8957 }
8958 }
8959 break;
8960
8961 case DT_POSFLAG_1:
8962 if (do_dynamic)
8963 {
8964 printf (_("Flags:"));
86f55779 8965
252b5132
RH
8966 if (entry->d_un.d_val == 0)
8967 printf (_(" None\n"));
8968 else
8969 {
8970 unsigned long int val = entry->d_un.d_val;
86f55779 8971
252b5132
RH
8972 if (val & DF_P1_LAZYLOAD)
8973 {
8974 printf (" LAZYLOAD");
8975 val ^= DF_P1_LAZYLOAD;
8976 }
8977 if (val & DF_P1_GROUPPERM)
8978 {
8979 printf (" GROUPPERM");
8980 val ^= DF_P1_GROUPPERM;
8981 }
8982 if (val != 0)
8983 printf (" %lx", val);
8984 puts ("");
8985 }
8986 }
8987 break;
8988
8989 case DT_FLAGS_1:
8990 if (do_dynamic)
8991 {
8992 printf (_("Flags:"));
8993 if (entry->d_un.d_val == 0)
8994 printf (_(" None\n"));
8995 else
8996 {
8997 unsigned long int val = entry->d_un.d_val;
86f55779 8998
252b5132
RH
8999 if (val & DF_1_NOW)
9000 {
9001 printf (" NOW");
9002 val ^= DF_1_NOW;
9003 }
9004 if (val & DF_1_GLOBAL)
9005 {
9006 printf (" GLOBAL");
9007 val ^= DF_1_GLOBAL;
9008 }
9009 if (val & DF_1_GROUP)
9010 {
9011 printf (" GROUP");
9012 val ^= DF_1_GROUP;
9013 }
9014 if (val & DF_1_NODELETE)
9015 {
9016 printf (" NODELETE");
9017 val ^= DF_1_NODELETE;
9018 }
9019 if (val & DF_1_LOADFLTR)
9020 {
9021 printf (" LOADFLTR");
9022 val ^= DF_1_LOADFLTR;
9023 }
9024 if (val & DF_1_INITFIRST)
9025 {
9026 printf (" INITFIRST");
9027 val ^= DF_1_INITFIRST;
9028 }
9029 if (val & DF_1_NOOPEN)
9030 {
9031 printf (" NOOPEN");
9032 val ^= DF_1_NOOPEN;
9033 }
9034 if (val & DF_1_ORIGIN)
9035 {
9036 printf (" ORIGIN");
9037 val ^= DF_1_ORIGIN;
9038 }
9039 if (val & DF_1_DIRECT)
9040 {
9041 printf (" DIRECT");
9042 val ^= DF_1_DIRECT;
9043 }
9044 if (val & DF_1_TRANS)
9045 {
9046 printf (" TRANS");
9047 val ^= DF_1_TRANS;
9048 }
9049 if (val & DF_1_INTERPOSE)
9050 {
9051 printf (" INTERPOSE");
9052 val ^= DF_1_INTERPOSE;
9053 }
f7db6139 9054 if (val & DF_1_NODEFLIB)
dcefbbbd 9055 {
f7db6139
L
9056 printf (" NODEFLIB");
9057 val ^= DF_1_NODEFLIB;
dcefbbbd
L
9058 }
9059 if (val & DF_1_NODUMP)
9060 {
9061 printf (" NODUMP");
9062 val ^= DF_1_NODUMP;
9063 }
34b60028 9064 if (val & DF_1_CONFALT)
dcefbbbd 9065 {
34b60028
L
9066 printf (" CONFALT");
9067 val ^= DF_1_CONFALT;
9068 }
9069 if (val & DF_1_ENDFILTEE)
9070 {
9071 printf (" ENDFILTEE");
9072 val ^= DF_1_ENDFILTEE;
9073 }
9074 if (val & DF_1_DISPRELDNE)
9075 {
9076 printf (" DISPRELDNE");
9077 val ^= DF_1_DISPRELDNE;
9078 }
9079 if (val & DF_1_DISPRELPND)
9080 {
9081 printf (" DISPRELPND");
9082 val ^= DF_1_DISPRELPND;
9083 }
9084 if (val & DF_1_NODIRECT)
9085 {
9086 printf (" NODIRECT");
9087 val ^= DF_1_NODIRECT;
9088 }
9089 if (val & DF_1_IGNMULDEF)
9090 {
9091 printf (" IGNMULDEF");
9092 val ^= DF_1_IGNMULDEF;
9093 }
9094 if (val & DF_1_NOKSYMS)
9095 {
9096 printf (" NOKSYMS");
9097 val ^= DF_1_NOKSYMS;
9098 }
9099 if (val & DF_1_NOHDR)
9100 {
9101 printf (" NOHDR");
9102 val ^= DF_1_NOHDR;
9103 }
9104 if (val & DF_1_EDITED)
9105 {
9106 printf (" EDITED");
9107 val ^= DF_1_EDITED;
9108 }
9109 if (val & DF_1_NORELOC)
9110 {
9111 printf (" NORELOC");
9112 val ^= DF_1_NORELOC;
9113 }
9114 if (val & DF_1_SYMINTPOSE)
9115 {
9116 printf (" SYMINTPOSE");
9117 val ^= DF_1_SYMINTPOSE;
9118 }
9119 if (val & DF_1_GLOBAUDIT)
9120 {
9121 printf (" GLOBAUDIT");
9122 val ^= DF_1_GLOBAUDIT;
9123 }
9124 if (val & DF_1_SINGLETON)
9125 {
9126 printf (" SINGLETON");
9127 val ^= DF_1_SINGLETON;
dcefbbbd 9128 }
252b5132
RH
9129 if (val != 0)
9130 printf (" %lx", val);
9131 puts ("");
9132 }
9133 }
9134 break;
9135
9136 case DT_PLTREL:
566b0d53 9137 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9138 if (do_dynamic)
9139 puts (get_dynamic_type (entry->d_un.d_val));
9140 break;
9141
9142 case DT_NULL :
9143 case DT_NEEDED :
9144 case DT_PLTGOT :
9145 case DT_HASH :
9146 case DT_STRTAB :
9147 case DT_SYMTAB :
9148 case DT_RELA :
9149 case DT_INIT :
9150 case DT_FINI :
9151 case DT_SONAME :
9152 case DT_RPATH :
9153 case DT_SYMBOLIC:
9154 case DT_REL :
9155 case DT_DEBUG :
9156 case DT_TEXTREL :
9157 case DT_JMPREL :
019148e4 9158 case DT_RUNPATH :
252b5132
RH
9159 dynamic_info[entry->d_tag] = entry->d_un.d_val;
9160
9161 if (do_dynamic)
9162 {
2cf0635d 9163 char * name;
252b5132 9164
d79b3d50
NC
9165 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9166 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9167 else
d79b3d50 9168 name = NULL;
252b5132
RH
9169
9170 if (name)
9171 {
9172 switch (entry->d_tag)
9173 {
9174 case DT_NEEDED:
9175 printf (_("Shared library: [%s]"), name);
9176
18bd398b 9177 if (streq (name, program_interpreter))
f7a99963 9178 printf (_(" program interpreter"));
252b5132
RH
9179 break;
9180
9181 case DT_SONAME:
f7a99963 9182 printf (_("Library soname: [%s]"), name);
252b5132
RH
9183 break;
9184
9185 case DT_RPATH:
f7a99963 9186 printf (_("Library rpath: [%s]"), name);
252b5132
RH
9187 break;
9188
019148e4
L
9189 case DT_RUNPATH:
9190 printf (_("Library runpath: [%s]"), name);
9191 break;
9192
252b5132 9193 default:
f7a99963
NC
9194 print_vma (entry->d_un.d_val, PREFIX_HEX);
9195 break;
252b5132
RH
9196 }
9197 }
9198 else
f7a99963
NC
9199 print_vma (entry->d_un.d_val, PREFIX_HEX);
9200
9201 putchar ('\n');
252b5132
RH
9202 }
9203 break;
9204
9205 case DT_PLTRELSZ:
9206 case DT_RELASZ :
9207 case DT_STRSZ :
9208 case DT_RELSZ :
9209 case DT_RELAENT :
9210 case DT_SYMENT :
9211 case DT_RELENT :
566b0d53 9212 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9213 case DT_PLTPADSZ:
9214 case DT_MOVEENT :
9215 case DT_MOVESZ :
9216 case DT_INIT_ARRAYSZ:
9217 case DT_FINI_ARRAYSZ:
047b2264
JJ
9218 case DT_GNU_CONFLICTSZ:
9219 case DT_GNU_LIBLISTSZ:
252b5132 9220 if (do_dynamic)
f7a99963
NC
9221 {
9222 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 9223 printf (_(" (bytes)\n"));
f7a99963 9224 }
252b5132
RH
9225 break;
9226
9227 case DT_VERDEFNUM:
9228 case DT_VERNEEDNUM:
9229 case DT_RELACOUNT:
9230 case DT_RELCOUNT:
9231 if (do_dynamic)
f7a99963
NC
9232 {
9233 print_vma (entry->d_un.d_val, UNSIGNED);
9234 putchar ('\n');
9235 }
252b5132
RH
9236 break;
9237
9238 case DT_SYMINSZ:
9239 case DT_SYMINENT:
9240 case DT_SYMINFO:
9241 case DT_USED:
9242 case DT_INIT_ARRAY:
9243 case DT_FINI_ARRAY:
9244 if (do_dynamic)
9245 {
d79b3d50
NC
9246 if (entry->d_tag == DT_USED
9247 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 9248 {
2cf0635d 9249 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9250
b34976b6 9251 if (*name)
252b5132
RH
9252 {
9253 printf (_("Not needed object: [%s]\n"), name);
9254 break;
9255 }
9256 }
103f02d3 9257
f7a99963
NC
9258 print_vma (entry->d_un.d_val, PREFIX_HEX);
9259 putchar ('\n');
252b5132
RH
9260 }
9261 break;
9262
9263 case DT_BIND_NOW:
9264 /* The value of this entry is ignored. */
35b1837e
AM
9265 if (do_dynamic)
9266 putchar ('\n');
252b5132 9267 break;
103f02d3 9268
047b2264
JJ
9269 case DT_GNU_PRELINKED:
9270 if (do_dynamic)
9271 {
2cf0635d 9272 struct tm * tmp;
91d6fa6a 9273 time_t atime = entry->d_un.d_val;
047b2264 9274
91d6fa6a 9275 tmp = gmtime (&atime);
071436c6
NC
9276 /* PR 17533 file: 041-1244816-0.004. */
9277 if (tmp == NULL)
5a2cbcf4
L
9278 printf (_("<corrupt time val: %lx"),
9279 (unsigned long) atime);
071436c6
NC
9280 else
9281 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
9282 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9283 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9284
9285 }
9286 break;
9287
fdc90cb4
JJ
9288 case DT_GNU_HASH:
9289 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9290 if (do_dynamic)
9291 {
9292 print_vma (entry->d_un.d_val, PREFIX_HEX);
9293 putchar ('\n');
9294 }
9295 break;
9296
252b5132
RH
9297 default:
9298 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 9299 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
9300 entry->d_un.d_val;
9301
9302 if (do_dynamic)
9303 {
9304 switch (elf_header.e_machine)
9305 {
9306 case EM_MIPS:
4fe85591 9307 case EM_MIPS_RS3_LE:
b2d38a17 9308 dynamic_section_mips_val (entry);
252b5132 9309 break;
103f02d3 9310 case EM_PARISC:
b2d38a17 9311 dynamic_section_parisc_val (entry);
103f02d3 9312 break;
ecc51f48 9313 case EM_IA_64:
b2d38a17 9314 dynamic_section_ia64_val (entry);
ecc51f48 9315 break;
252b5132 9316 default:
f7a99963
NC
9317 print_vma (entry->d_un.d_val, PREFIX_HEX);
9318 putchar ('\n');
252b5132
RH
9319 }
9320 }
9321 break;
9322 }
9323 }
9324
9325 return 1;
9326}
9327
9328static char *
d3ba0551 9329get_ver_flags (unsigned int flags)
252b5132 9330{
b34976b6 9331 static char buff[32];
252b5132
RH
9332
9333 buff[0] = 0;
9334
9335 if (flags == 0)
9336 return _("none");
9337
9338 if (flags & VER_FLG_BASE)
9339 strcat (buff, "BASE ");
9340
9341 if (flags & VER_FLG_WEAK)
9342 {
9343 if (flags & VER_FLG_BASE)
9344 strcat (buff, "| ");
9345
9346 strcat (buff, "WEAK ");
9347 }
9348
44ec90b9
RO
9349 if (flags & VER_FLG_INFO)
9350 {
9351 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
9352 strcat (buff, "| ");
9353
9354 strcat (buff, "INFO ");
9355 }
9356
9357 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 9358 strcat (buff, _("| <unknown>"));
252b5132
RH
9359
9360 return buff;
9361}
9362
9363/* Display the contents of the version sections. */
98fb390a 9364
252b5132 9365static int
2cf0635d 9366process_version_sections (FILE * file)
252b5132 9367{
2cf0635d 9368 Elf_Internal_Shdr * section;
b34976b6
AM
9369 unsigned i;
9370 int found = 0;
252b5132
RH
9371
9372 if (! do_version)
9373 return 1;
9374
9375 for (i = 0, section = section_headers;
9376 i < elf_header.e_shnum;
b34976b6 9377 i++, section++)
252b5132
RH
9378 {
9379 switch (section->sh_type)
9380 {
9381 case SHT_GNU_verdef:
9382 {
2cf0635d 9383 Elf_External_Verdef * edefs;
b34976b6
AM
9384 unsigned int idx;
9385 unsigned int cnt;
2cf0635d 9386 char * endbuf;
252b5132
RH
9387
9388 found = 1;
9389
74e1a04b
NC
9390 printf (_("\nVersion definition section '%s' contains %u entries:\n"),
9391 printable_section_name (section),
9392 section->sh_info);
252b5132
RH
9393
9394 printf (_(" Addr: 0x"));
9395 printf_vma (section->sh_addr);
74e1a04b 9396 printf (_(" Offset: %#08lx Link: %u (%s)"),
1b228002 9397 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9398 printable_section_name_from_index (section->sh_link));
252b5132 9399
3f5e193b
NC
9400 edefs = (Elf_External_Verdef *)
9401 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
9402 _("version definition section"));
a6e9f9df
AM
9403 if (!edefs)
9404 break;
59245841 9405 endbuf = (char *) edefs + section->sh_size;
252b5132 9406
b34976b6 9407 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 9408 {
2cf0635d
NC
9409 char * vstart;
9410 Elf_External_Verdef * edef;
b34976b6 9411 Elf_Internal_Verdef ent;
2cf0635d 9412 Elf_External_Verdaux * eaux;
b34976b6
AM
9413 Elf_Internal_Verdaux aux;
9414 int j;
9415 int isum;
103f02d3 9416
7e26601c
NC
9417 /* Check for very large indicies. */
9418 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
9419 break;
9420
252b5132 9421 vstart = ((char *) edefs) + idx;
54806181
AM
9422 if (vstart + sizeof (*edef) > endbuf)
9423 break;
252b5132
RH
9424
9425 edef = (Elf_External_Verdef *) vstart;
9426
9427 ent.vd_version = BYTE_GET (edef->vd_version);
9428 ent.vd_flags = BYTE_GET (edef->vd_flags);
9429 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
9430 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
9431 ent.vd_hash = BYTE_GET (edef->vd_hash);
9432 ent.vd_aux = BYTE_GET (edef->vd_aux);
9433 ent.vd_next = BYTE_GET (edef->vd_next);
9434
9435 printf (_(" %#06x: Rev: %d Flags: %s"),
9436 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
9437
9438 printf (_(" Index: %d Cnt: %d "),
9439 ent.vd_ndx, ent.vd_cnt);
9440
dd24e3da 9441 /* Check for overflow. */
7e26601c 9442 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9443 break;
9444
252b5132
RH
9445 vstart += ent.vd_aux;
9446
9447 eaux = (Elf_External_Verdaux *) vstart;
9448
9449 aux.vda_name = BYTE_GET (eaux->vda_name);
9450 aux.vda_next = BYTE_GET (eaux->vda_next);
9451
d79b3d50
NC
9452 if (VALID_DYNAMIC_NAME (aux.vda_name))
9453 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9454 else
9455 printf (_("Name index: %ld\n"), aux.vda_name);
9456
9457 isum = idx + ent.vd_aux;
9458
b34976b6 9459 for (j = 1; j < ent.vd_cnt; j++)
252b5132 9460 {
dd24e3da 9461 /* Check for overflow. */
7e26601c 9462 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9463 break;
9464
252b5132
RH
9465 isum += aux.vda_next;
9466 vstart += aux.vda_next;
9467
9468 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
9469 if (vstart + sizeof (*eaux) > endbuf)
9470 break;
252b5132
RH
9471
9472 aux.vda_name = BYTE_GET (eaux->vda_name);
9473 aux.vda_next = BYTE_GET (eaux->vda_next);
9474
d79b3d50 9475 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 9476 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 9477 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9478 else
9479 printf (_(" %#06x: Parent %d, name index: %ld\n"),
9480 isum, j, aux.vda_name);
9481 }
dd24e3da 9482
54806181
AM
9483 if (j < ent.vd_cnt)
9484 printf (_(" Version def aux past end of section\n"));
252b5132 9485
5d921cbd
NC
9486 /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
9487 if (idx + ent.vd_next <= idx)
9488 break;
9489
252b5132
RH
9490 idx += ent.vd_next;
9491 }
dd24e3da 9492
54806181
AM
9493 if (cnt < section->sh_info)
9494 printf (_(" Version definition past end of section\n"));
252b5132
RH
9495
9496 free (edefs);
9497 }
9498 break;
103f02d3 9499
252b5132
RH
9500 case SHT_GNU_verneed:
9501 {
2cf0635d 9502 Elf_External_Verneed * eneed;
b34976b6
AM
9503 unsigned int idx;
9504 unsigned int cnt;
2cf0635d 9505 char * endbuf;
252b5132
RH
9506
9507 found = 1;
9508
72de5009 9509 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
74e1a04b 9510 printable_section_name (section), section->sh_info);
252b5132
RH
9511
9512 printf (_(" Addr: 0x"));
9513 printf_vma (section->sh_addr);
72de5009 9514 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9515 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9516 printable_section_name_from_index (section->sh_link));
252b5132 9517
3f5e193b
NC
9518 eneed = (Elf_External_Verneed *) get_data (NULL, file,
9519 section->sh_offset, 1,
9520 section->sh_size,
9cf03b7e 9521 _("Version Needs section"));
a6e9f9df
AM
9522 if (!eneed)
9523 break;
59245841 9524 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
9525
9526 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
9527 {
2cf0635d 9528 Elf_External_Verneed * entry;
b34976b6
AM
9529 Elf_Internal_Verneed ent;
9530 int j;
9531 int isum;
2cf0635d 9532 char * vstart;
252b5132 9533
7e26601c 9534 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
9535 break;
9536
252b5132 9537 vstart = ((char *) eneed) + idx;
54806181
AM
9538 if (vstart + sizeof (*entry) > endbuf)
9539 break;
252b5132
RH
9540
9541 entry = (Elf_External_Verneed *) vstart;
9542
9543 ent.vn_version = BYTE_GET (entry->vn_version);
9544 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
9545 ent.vn_file = BYTE_GET (entry->vn_file);
9546 ent.vn_aux = BYTE_GET (entry->vn_aux);
9547 ent.vn_next = BYTE_GET (entry->vn_next);
9548
9549 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
9550
d79b3d50
NC
9551 if (VALID_DYNAMIC_NAME (ent.vn_file))
9552 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
9553 else
9554 printf (_(" File: %lx"), ent.vn_file);
9555
9556 printf (_(" Cnt: %d\n"), ent.vn_cnt);
9557
dd24e3da 9558 /* Check for overflow. */
7e26601c 9559 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 9560 break;
252b5132
RH
9561 vstart += ent.vn_aux;
9562
9563 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
9564 {
2cf0635d 9565 Elf_External_Vernaux * eaux;
b34976b6 9566 Elf_Internal_Vernaux aux;
252b5132 9567
54806181
AM
9568 if (vstart + sizeof (*eaux) > endbuf)
9569 break;
252b5132
RH
9570 eaux = (Elf_External_Vernaux *) vstart;
9571
9572 aux.vna_hash = BYTE_GET (eaux->vna_hash);
9573 aux.vna_flags = BYTE_GET (eaux->vna_flags);
9574 aux.vna_other = BYTE_GET (eaux->vna_other);
9575 aux.vna_name = BYTE_GET (eaux->vna_name);
9576 aux.vna_next = BYTE_GET (eaux->vna_next);
9577
d79b3d50 9578 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 9579 printf (_(" %#06x: Name: %s"),
d79b3d50 9580 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 9581 else
ecc2063b 9582 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
9583 isum, aux.vna_name);
9584
9585 printf (_(" Flags: %s Version: %d\n"),
9586 get_ver_flags (aux.vna_flags), aux.vna_other);
9587
dd24e3da 9588 /* Check for overflow. */
53774b7e
NC
9589 if (aux.vna_next > (size_t) (endbuf - vstart)
9590 || (aux.vna_next == 0 && j < ent.vn_cnt - 1))
9591 {
9592 warn (_("Invalid vna_next field of %lx\n"),
9593 aux.vna_next);
9594 j = ent.vn_cnt;
9595 break;
9596 }
252b5132
RH
9597 isum += aux.vna_next;
9598 vstart += aux.vna_next;
9599 }
9cf03b7e 9600
54806181 9601 if (j < ent.vn_cnt)
9cf03b7e 9602 warn (_("Missing Version Needs auxillary information\n"));
252b5132 9603
bcf83b2a 9604 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
9605 {
9606 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
9607 cnt = section->sh_info;
9608 break;
9609 }
252b5132
RH
9610 idx += ent.vn_next;
9611 }
9cf03b7e 9612
54806181 9613 if (cnt < section->sh_info)
9cf03b7e 9614 warn (_("Missing Version Needs information\n"));
103f02d3 9615
252b5132
RH
9616 free (eneed);
9617 }
9618 break;
9619
9620 case SHT_GNU_versym:
9621 {
2cf0635d 9622 Elf_Internal_Shdr * link_section;
8b73c356
NC
9623 size_t total;
9624 unsigned int cnt;
2cf0635d
NC
9625 unsigned char * edata;
9626 unsigned short * data;
9627 char * strtab;
9628 Elf_Internal_Sym * symbols;
9629 Elf_Internal_Shdr * string_sec;
ba5cdace 9630 unsigned long num_syms;
d3ba0551 9631 long off;
252b5132 9632
4fbb74a6 9633 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9634 break;
9635
4fbb74a6 9636 link_section = section_headers + section->sh_link;
08d8fa11 9637 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9638
4fbb74a6 9639 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9640 break;
9641
252b5132
RH
9642 found = 1;
9643
ba5cdace 9644 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9645 if (symbols == NULL)
9646 break;
252b5132 9647
4fbb74a6 9648 string_sec = section_headers + link_section->sh_link;
252b5132 9649
3f5e193b
NC
9650 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9651 string_sec->sh_size,
9652 _("version string table"));
a6e9f9df 9653 if (!strtab)
0429c154
MS
9654 {
9655 free (symbols);
9656 break;
9657 }
252b5132 9658
8b73c356
NC
9659 printf (_("\nVersion symbols section '%s' contains %lu entries:\n"),
9660 printable_section_name (section), (unsigned long) total);
252b5132
RH
9661
9662 printf (_(" Addr: "));
9663 printf_vma (section->sh_addr);
72de5009 9664 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9665 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9666 printable_section_name (link_section));
252b5132 9667
d3ba0551
AM
9668 off = offset_from_vma (file,
9669 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9670 total * sizeof (short));
3f5e193b
NC
9671 edata = (unsigned char *) get_data (NULL, file, off, total,
9672 sizeof (short),
9673 _("version symbol data"));
a6e9f9df
AM
9674 if (!edata)
9675 {
9676 free (strtab);
0429c154 9677 free (symbols);
a6e9f9df
AM
9678 break;
9679 }
252b5132 9680
3f5e193b 9681 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9682
9683 for (cnt = total; cnt --;)
b34976b6
AM
9684 data[cnt] = byte_get (edata + cnt * sizeof (short),
9685 sizeof (short));
252b5132
RH
9686
9687 free (edata);
9688
9689 for (cnt = 0; cnt < total; cnt += 4)
9690 {
9691 int j, nn;
00d93f34 9692 int check_def, check_need;
2cf0635d 9693 char * name;
252b5132
RH
9694
9695 printf (" %03x:", cnt);
9696
9697 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9698 switch (data[cnt + j])
252b5132
RH
9699 {
9700 case 0:
9701 fputs (_(" 0 (*local*) "), stdout);
9702 break;
9703
9704 case 1:
9705 fputs (_(" 1 (*global*) "), stdout);
9706 break;
9707
9708 default:
c244d050
NC
9709 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9710 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9711
dd24e3da 9712 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9713 array, break to avoid an out-of-bounds read. */
9714 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9715 {
9716 warn (_("invalid index into symbol array\n"));
9717 break;
9718 }
9719
00d93f34
JJ
9720 check_def = 1;
9721 check_need = 1;
4fbb74a6
AM
9722 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
9723 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 9724 != SHT_NOBITS)
252b5132 9725 {
b34976b6 9726 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
9727 check_def = 0;
9728 else
9729 check_need = 0;
252b5132 9730 }
00d93f34
JJ
9731
9732 if (check_need
b34976b6 9733 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9734 {
b34976b6
AM
9735 Elf_Internal_Verneed ivn;
9736 unsigned long offset;
252b5132 9737
d93f0186
NC
9738 offset = offset_from_vma
9739 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9740 sizeof (Elf_External_Verneed));
252b5132 9741
b34976b6 9742 do
252b5132 9743 {
b34976b6
AM
9744 Elf_Internal_Vernaux ivna;
9745 Elf_External_Verneed evn;
9746 Elf_External_Vernaux evna;
9747 unsigned long a_off;
252b5132 9748
59245841
NC
9749 if (get_data (&evn, file, offset, sizeof (evn), 1,
9750 _("version need")) == NULL)
9751 break;
0b4362b0 9752
252b5132
RH
9753 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9754 ivn.vn_next = BYTE_GET (evn.vn_next);
9755
9756 a_off = offset + ivn.vn_aux;
9757
9758 do
9759 {
59245841
NC
9760 if (get_data (&evna, file, a_off, sizeof (evna),
9761 1, _("version need aux (2)")) == NULL)
9762 {
9763 ivna.vna_next = 0;
9764 ivna.vna_other = 0;
9765 }
9766 else
9767 {
9768 ivna.vna_next = BYTE_GET (evna.vna_next);
9769 ivna.vna_other = BYTE_GET (evna.vna_other);
9770 }
252b5132
RH
9771
9772 a_off += ivna.vna_next;
9773 }
b34976b6 9774 while (ivna.vna_other != data[cnt + j]
252b5132
RH
9775 && ivna.vna_next != 0);
9776
b34976b6 9777 if (ivna.vna_other == data[cnt + j])
252b5132
RH
9778 {
9779 ivna.vna_name = BYTE_GET (evna.vna_name);
9780
54806181
AM
9781 if (ivna.vna_name >= string_sec->sh_size)
9782 name = _("*invalid*");
9783 else
9784 name = strtab + ivna.vna_name;
252b5132 9785 nn += printf ("(%s%-*s",
16062207
ILT
9786 name,
9787 12 - (int) strlen (name),
252b5132 9788 ")");
00d93f34 9789 check_def = 0;
252b5132
RH
9790 break;
9791 }
9792
9793 offset += ivn.vn_next;
9794 }
9795 while (ivn.vn_next);
9796 }
00d93f34 9797
b34976b6
AM
9798 if (check_def && data[cnt + j] != 0x8001
9799 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9800 {
b34976b6
AM
9801 Elf_Internal_Verdef ivd;
9802 Elf_External_Verdef evd;
9803 unsigned long offset;
252b5132 9804
d93f0186
NC
9805 offset = offset_from_vma
9806 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9807 sizeof evd);
252b5132
RH
9808
9809 do
9810 {
59245841
NC
9811 if (get_data (&evd, file, offset, sizeof (evd), 1,
9812 _("version def")) == NULL)
9813 {
9814 ivd.vd_next = 0;
948f632f 9815 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
9816 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
9817 break;
59245841
NC
9818 }
9819 else
9820 {
9821 ivd.vd_next = BYTE_GET (evd.vd_next);
9822 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9823 }
252b5132
RH
9824
9825 offset += ivd.vd_next;
9826 }
c244d050 9827 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
9828 && ivd.vd_next != 0);
9829
c244d050 9830 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 9831 {
b34976b6
AM
9832 Elf_External_Verdaux evda;
9833 Elf_Internal_Verdaux ivda;
252b5132
RH
9834
9835 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9836
59245841
NC
9837 if (get_data (&evda, file,
9838 offset - ivd.vd_next + ivd.vd_aux,
9839 sizeof (evda), 1,
9840 _("version def aux")) == NULL)
9841 break;
252b5132
RH
9842
9843 ivda.vda_name = BYTE_GET (evda.vda_name);
9844
54806181
AM
9845 if (ivda.vda_name >= string_sec->sh_size)
9846 name = _("*invalid*");
9847 else
9848 name = strtab + ivda.vda_name;
252b5132 9849 nn += printf ("(%s%-*s",
16062207
ILT
9850 name,
9851 12 - (int) strlen (name),
252b5132
RH
9852 ")");
9853 }
9854 }
9855
9856 if (nn < 18)
9857 printf ("%*c", 18 - nn, ' ');
9858 }
9859
9860 putchar ('\n');
9861 }
9862
9863 free (data);
9864 free (strtab);
9865 free (symbols);
9866 }
9867 break;
103f02d3 9868
252b5132
RH
9869 default:
9870 break;
9871 }
9872 }
9873
9874 if (! found)
9875 printf (_("\nNo version information found in this file.\n"));
9876
9877 return 1;
9878}
9879
d1133906 9880static const char *
d3ba0551 9881get_symbol_binding (unsigned int binding)
252b5132 9882{
b34976b6 9883 static char buff[32];
252b5132
RH
9884
9885 switch (binding)
9886 {
b34976b6
AM
9887 case STB_LOCAL: return "LOCAL";
9888 case STB_GLOBAL: return "GLOBAL";
9889 case STB_WEAK: return "WEAK";
252b5132
RH
9890 default:
9891 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9892 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9893 binding);
252b5132 9894 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9895 {
9896 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9897 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9898 /* GNU is still using the default value 0. */
3e7a7d11
NC
9899 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9900 return "UNIQUE";
9901 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9902 }
252b5132 9903 else
e9e44622 9904 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9905 return buff;
9906 }
9907}
9908
d1133906 9909static const char *
d3ba0551 9910get_symbol_type (unsigned int type)
252b5132 9911{
b34976b6 9912 static char buff[32];
252b5132
RH
9913
9914 switch (type)
9915 {
b34976b6
AM
9916 case STT_NOTYPE: return "NOTYPE";
9917 case STT_OBJECT: return "OBJECT";
9918 case STT_FUNC: return "FUNC";
9919 case STT_SECTION: return "SECTION";
9920 case STT_FILE: return "FILE";
9921 case STT_COMMON: return "COMMON";
9922 case STT_TLS: return "TLS";
15ab5209
DB
9923 case STT_RELC: return "RELC";
9924 case STT_SRELC: return "SRELC";
252b5132
RH
9925 default:
9926 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9927 {
3510a7b8
NC
9928 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
9929 return "THUMB_FUNC";
103f02d3 9930
351b4b40 9931 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9932 return "REGISTER";
9933
9934 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9935 return "PARISC_MILLI";
9936
e9e44622 9937 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9938 }
252b5132 9939 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9940 {
9941 if (elf_header.e_machine == EM_PARISC)
9942 {
9943 if (type == STT_HP_OPAQUE)
9944 return "HP_OPAQUE";
9945 if (type == STT_HP_STUB)
9946 return "HP_STUB";
9947 }
9948
d8045f23 9949 if (type == STT_GNU_IFUNC
9c55345c 9950 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9951 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9952 /* GNU is still using the default value 0. */
d8045f23
NC
9953 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9954 return "IFUNC";
9955
e9e44622 9956 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9957 }
252b5132 9958 else
e9e44622 9959 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9960 return buff;
9961 }
9962}
9963
d1133906 9964static const char *
d3ba0551 9965get_symbol_visibility (unsigned int visibility)
d1133906
NC
9966{
9967 switch (visibility)
9968 {
b34976b6
AM
9969 case STV_DEFAULT: return "DEFAULT";
9970 case STV_INTERNAL: return "INTERNAL";
9971 case STV_HIDDEN: return "HIDDEN";
d1133906 9972 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
9973 default:
9974 error (_("Unrecognized visibility value: %u"), visibility);
9975 return _("<unknown>");
d1133906
NC
9976 }
9977}
9978
5e2b0d47
NC
9979static const char *
9980get_mips_symbol_other (unsigned int other)
9981{
9982 switch (other)
9983 {
df58fc94
RS
9984 case STO_OPTIONAL:
9985 return "OPTIONAL";
9986 case STO_MIPS_PLT:
9987 return "MIPS PLT";
9988 case STO_MIPS_PIC:
9989 return "MIPS PIC";
9990 case STO_MICROMIPS:
9991 return "MICROMIPS";
9992 case STO_MICROMIPS | STO_MIPS_PIC:
9993 return "MICROMIPS, MIPS PIC";
9994 case STO_MIPS16:
9995 return "MIPS16";
9996 default:
9997 return NULL;
5e2b0d47
NC
9998 }
9999}
10000
28f997cf
TG
10001static const char *
10002get_ia64_symbol_other (unsigned int other)
10003{
10004 if (is_ia64_vms ())
10005 {
10006 static char res[32];
10007
10008 res[0] = 0;
10009
10010 /* Function types is for images and .STB files only. */
10011 switch (elf_header.e_type)
10012 {
10013 case ET_DYN:
10014 case ET_EXEC:
10015 switch (VMS_ST_FUNC_TYPE (other))
10016 {
10017 case VMS_SFT_CODE_ADDR:
10018 strcat (res, " CA");
10019 break;
10020 case VMS_SFT_SYMV_IDX:
10021 strcat (res, " VEC");
10022 break;
10023 case VMS_SFT_FD:
10024 strcat (res, " FD");
10025 break;
10026 case VMS_SFT_RESERVE:
10027 strcat (res, " RSV");
10028 break;
10029 default:
bee0ee85
NC
10030 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
10031 VMS_ST_FUNC_TYPE (other));
10032 strcat (res, " <unknown>");
10033 break;
28f997cf
TG
10034 }
10035 break;
10036 default:
10037 break;
10038 }
10039 switch (VMS_ST_LINKAGE (other))
10040 {
10041 case VMS_STL_IGNORE:
10042 strcat (res, " IGN");
10043 break;
10044 case VMS_STL_RESERVE:
10045 strcat (res, " RSV");
10046 break;
10047 case VMS_STL_STD:
10048 strcat (res, " STD");
10049 break;
10050 case VMS_STL_LNK:
10051 strcat (res, " LNK");
10052 break;
10053 default:
bee0ee85
NC
10054 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
10055 VMS_ST_LINKAGE (other));
10056 strcat (res, " <unknown>");
10057 break;
28f997cf
TG
10058 }
10059
10060 if (res[0] != 0)
10061 return res + 1;
10062 else
10063 return res;
10064 }
10065 return NULL;
10066}
10067
6911b7dc
AM
10068static const char *
10069get_ppc64_symbol_other (unsigned int other)
10070{
10071 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
10072 {
10073 static char buf[32];
10074 snprintf (buf, sizeof buf, _("<localentry>: %d"),
10075 PPC64_LOCAL_ENTRY_OFFSET (other));
10076 return buf;
10077 }
10078 return NULL;
10079}
10080
5e2b0d47
NC
10081static const char *
10082get_symbol_other (unsigned int other)
10083{
10084 const char * result = NULL;
10085 static char buff [32];
10086
10087 if (other == 0)
10088 return "";
10089
10090 switch (elf_header.e_machine)
10091 {
10092 case EM_MIPS:
10093 result = get_mips_symbol_other (other);
28f997cf
TG
10094 break;
10095 case EM_IA_64:
10096 result = get_ia64_symbol_other (other);
10097 break;
6911b7dc
AM
10098 case EM_PPC64:
10099 result = get_ppc64_symbol_other (other);
10100 break;
5e2b0d47
NC
10101 default:
10102 break;
10103 }
10104
10105 if (result)
10106 return result;
10107
10108 snprintf (buff, sizeof buff, _("<other>: %x"), other);
10109 return buff;
10110}
10111
d1133906 10112static const char *
d3ba0551 10113get_symbol_index_type (unsigned int type)
252b5132 10114{
b34976b6 10115 static char buff[32];
5cf1065c 10116
252b5132
RH
10117 switch (type)
10118 {
b34976b6
AM
10119 case SHN_UNDEF: return "UND";
10120 case SHN_ABS: return "ABS";
10121 case SHN_COMMON: return "COM";
252b5132 10122 default:
9ce701e2
L
10123 if (type == SHN_IA_64_ANSI_COMMON
10124 && elf_header.e_machine == EM_IA_64
10125 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
10126 return "ANSI_COM";
8a9036a4 10127 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
10128 || elf_header.e_machine == EM_L1OM
10129 || elf_header.e_machine == EM_K1OM)
3b22753a
L
10130 && type == SHN_X86_64_LCOMMON)
10131 return "LARGE_COM";
ac145307
BS
10132 else if ((type == SHN_MIPS_SCOMMON
10133 && elf_header.e_machine == EM_MIPS)
10134 || (type == SHN_TIC6X_SCOMMON
10135 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
10136 return "SCOM";
10137 else if (type == SHN_MIPS_SUNDEFINED
10138 && elf_header.e_machine == EM_MIPS)
10139 return "SUND";
9ce701e2 10140 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 10141 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 10142 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
10143 sprintf (buff, "OS [0x%04x]", type & 0xffff);
10144 else if (type >= SHN_LORESERVE)
10145 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4 10146 else if (type >= elf_header.e_shnum)
e0a31db1 10147 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 10148 else
232e7cb8 10149 sprintf (buff, "%3d", type);
5cf1065c 10150 break;
252b5132 10151 }
5cf1065c
NC
10152
10153 return buff;
252b5132
RH
10154}
10155
66543521 10156static bfd_vma *
57028622 10157get_dynamic_data (FILE * file, bfd_size_type number, unsigned int ent_size)
252b5132 10158{
2cf0635d
NC
10159 unsigned char * e_data;
10160 bfd_vma * i_data;
252b5132 10161
57028622
NC
10162 /* If the size_t type is smaller than the bfd_size_type, eg because
10163 you are building a 32-bit tool on a 64-bit host, then make sure
10164 that when (number) is cast to (size_t) no information is lost. */
10165 if (sizeof (size_t) < sizeof (bfd_size_type)
10166 && (bfd_size_type) ((size_t) number) != number)
10167 {
10168 error (_("Size truncation prevents reading %llu elements of size %u\n"),
10169 (unsigned long long) number, ent_size);
10170 return NULL;
10171 }
948f632f 10172
3102e897
NC
10173 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
10174 attempting to allocate memory when the read is bound to fail. */
10175 if (ent_size * number > current_file_size)
10176 {
57028622
NC
10177 error (_("Invalid number of dynamic entries: %llu\n"),
10178 (unsigned long long) number);
3102e897
NC
10179 return NULL;
10180 }
10181
57028622 10182 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
10183 if (e_data == NULL)
10184 {
57028622
NC
10185 error (_("Out of memory reading %llu dynamic entries\n"),
10186 (unsigned long long) number);
252b5132
RH
10187 return NULL;
10188 }
10189
57028622 10190 if (fread (e_data, ent_size, (size_t) number, file) != number)
252b5132 10191 {
57028622
NC
10192 error (_("Unable to read in %llu bytes of dynamic data\n"),
10193 (unsigned long long) (number * ent_size));
3102e897 10194 free (e_data);
252b5132
RH
10195 return NULL;
10196 }
10197
57028622 10198 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
10199 if (i_data == NULL)
10200 {
57028622
NC
10201 error (_("Out of memory allocating space for %llu dynamic entries\n"),
10202 (unsigned long long) number);
252b5132
RH
10203 free (e_data);
10204 return NULL;
10205 }
10206
10207 while (number--)
66543521 10208 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
10209
10210 free (e_data);
10211
10212 return i_data;
10213}
10214
6bd1a22c
L
10215static void
10216print_dynamic_symbol (bfd_vma si, unsigned long hn)
10217{
2cf0635d 10218 Elf_Internal_Sym * psym;
6bd1a22c
L
10219 int n;
10220
6bd1a22c
L
10221 n = print_vma (si, DEC_5);
10222 if (n < 5)
0b4362b0 10223 fputs (&" "[n], stdout);
6bd1a22c 10224 printf (" %3lu: ", hn);
e0a31db1
NC
10225
10226 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
10227 {
3102e897
NC
10228 printf (_("<No info available for dynamic symbol number %lu>\n"),
10229 (unsigned long) si);
e0a31db1
NC
10230 return;
10231 }
10232
10233 psym = dynamic_symbols + si;
6bd1a22c
L
10234 print_vma (psym->st_value, LONG_HEX);
10235 putchar (' ');
10236 print_vma (psym->st_size, DEC_5);
10237
f4be36b3
AM
10238 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10239 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
10240 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
10241 /* Check to see if any other bits in the st_other field are set.
10242 Note - displaying this information disrupts the layout of the
10243 table being generated, but for the moment this case is very
10244 rare. */
10245 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10246 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
10247 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
10248 if (VALID_DYNAMIC_NAME (psym->st_name))
10249 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10250 else
2b692964 10251 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
10252 putchar ('\n');
10253}
10254
bb4d2ac2
L
10255static const char *
10256get_symbol_version_string (FILE *file, int is_dynsym,
10257 const char *strtab,
10258 unsigned long int strtab_size,
10259 unsigned int si, Elf_Internal_Sym *psym,
10260 enum versioned_symbol_info *sym_info,
10261 unsigned short *vna_other)
10262{
10263 const char *version_string = NULL;
10264
10265 if (is_dynsym
10266 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
10267 {
10268 unsigned char data[2];
10269 unsigned short vers_data;
10270 unsigned long offset;
10271 int is_nobits;
10272 int check_def;
10273
10274 offset = offset_from_vma
10275 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10276 sizeof data + si * sizeof (vers_data));
10277
10278 if (get_data (&data, file, offset + si * sizeof (vers_data),
10279 sizeof (data), 1, _("version data")) == NULL)
10280 return NULL;
10281
10282 vers_data = byte_get (data, 2);
10283
53774b7e
NC
10284 is_nobits = (section_headers != NULL
10285 && psym->st_shndx < elf_header.e_shnum
bb4d2ac2
L
10286 && section_headers[psym->st_shndx].sh_type
10287 == SHT_NOBITS);
10288
10289 check_def = (psym->st_shndx != SHN_UNDEF);
10290
10291 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
10292 {
10293 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
10294 && (is_nobits || ! check_def))
10295 {
10296 Elf_External_Verneed evn;
10297 Elf_Internal_Verneed ivn;
10298 Elf_Internal_Vernaux ivna;
10299
10300 /* We must test both. */
10301 offset = offset_from_vma
10302 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10303 sizeof evn);
10304
10305 do
10306 {
10307 unsigned long vna_off;
10308
10309 if (get_data (&evn, file, offset, sizeof (evn), 1,
10310 _("version need")) == NULL)
10311 {
10312 ivna.vna_next = 0;
10313 ivna.vna_other = 0;
10314 ivna.vna_name = 0;
10315 break;
10316 }
10317
10318 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10319 ivn.vn_next = BYTE_GET (evn.vn_next);
10320
10321 vna_off = offset + ivn.vn_aux;
10322
10323 do
10324 {
10325 Elf_External_Vernaux evna;
10326
10327 if (get_data (&evna, file, vna_off,
10328 sizeof (evna), 1,
10329 _("version need aux (3)")) == NULL)
10330 {
10331 ivna.vna_next = 0;
10332 ivna.vna_other = 0;
10333 ivna.vna_name = 0;
10334 }
10335 else
10336 {
10337 ivna.vna_other = BYTE_GET (evna.vna_other);
10338 ivna.vna_next = BYTE_GET (evna.vna_next);
10339 ivna.vna_name = BYTE_GET (evna.vna_name);
10340 }
10341
10342 vna_off += ivna.vna_next;
10343 }
10344 while (ivna.vna_other != vers_data
10345 && ivna.vna_next != 0);
10346
10347 if (ivna.vna_other == vers_data)
10348 break;
10349
10350 offset += ivn.vn_next;
10351 }
10352 while (ivn.vn_next != 0);
10353
10354 if (ivna.vna_other == vers_data)
10355 {
10356 *sym_info = symbol_undefined;
10357 *vna_other = ivna.vna_other;
10358 version_string = (ivna.vna_name < strtab_size
10359 ? strtab + ivna.vna_name
10360 : _("<corrupt>"));
10361 check_def = 0;
10362 }
10363 else if (! is_nobits)
10364 error (_("bad dynamic symbol\n"));
10365 else
10366 check_def = 1;
10367 }
10368
10369 if (check_def)
10370 {
10371 if (vers_data != 0x8001
10372 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
10373 {
10374 Elf_Internal_Verdef ivd;
10375 Elf_Internal_Verdaux ivda;
10376 Elf_External_Verdaux evda;
10377 unsigned long off;
10378
10379 off = offset_from_vma
10380 (file,
10381 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10382 sizeof (Elf_External_Verdef));
10383
10384 do
10385 {
10386 Elf_External_Verdef evd;
10387
10388 if (get_data (&evd, file, off, sizeof (evd),
10389 1, _("version def")) == NULL)
10390 {
10391 ivd.vd_ndx = 0;
10392 ivd.vd_aux = 0;
10393 ivd.vd_next = 0;
10394 }
10395 else
10396 {
10397 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10398 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10399 ivd.vd_next = BYTE_GET (evd.vd_next);
10400 }
10401
10402 off += ivd.vd_next;
10403 }
10404 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
10405 && ivd.vd_next != 0);
10406
10407 off -= ivd.vd_next;
10408 off += ivd.vd_aux;
10409
10410 if (get_data (&evda, file, off, sizeof (evda),
10411 1, _("version def aux")) == NULL)
10412 return version_string;
10413
10414 ivda.vda_name = BYTE_GET (evda.vda_name);
10415
10416 if (psym->st_name != ivda.vda_name)
10417 {
10418 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
10419 ? symbol_hidden : symbol_public);
10420 version_string = (ivda.vda_name < strtab_size
10421 ? strtab + ivda.vda_name
10422 : _("<corrupt>"));
10423 }
10424 }
10425 }
10426 }
10427 }
10428 return version_string;
10429}
10430
e3c8793a 10431/* Dump the symbol table. */
252b5132 10432static int
2cf0635d 10433process_symbol_table (FILE * file)
252b5132 10434{
2cf0635d 10435 Elf_Internal_Shdr * section;
8b73c356
NC
10436 bfd_size_type nbuckets = 0;
10437 bfd_size_type nchains = 0;
2cf0635d
NC
10438 bfd_vma * buckets = NULL;
10439 bfd_vma * chains = NULL;
fdc90cb4 10440 bfd_vma ngnubuckets = 0;
2cf0635d
NC
10441 bfd_vma * gnubuckets = NULL;
10442 bfd_vma * gnuchains = NULL;
6bd1a22c 10443 bfd_vma gnusymidx = 0;
071436c6 10444 bfd_size_type ngnuchains = 0;
252b5132 10445
2c610e4b 10446 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
10447 return 1;
10448
6bd1a22c
L
10449 if (dynamic_info[DT_HASH]
10450 && (do_histogram
2c610e4b
L
10451 || (do_using_dynamic
10452 && !do_dyn_syms
10453 && dynamic_strings != NULL)))
252b5132 10454 {
66543521
AM
10455 unsigned char nb[8];
10456 unsigned char nc[8];
8b73c356 10457 unsigned int hash_ent_size = 4;
66543521
AM
10458
10459 if ((elf_header.e_machine == EM_ALPHA
10460 || elf_header.e_machine == EM_S390
10461 || elf_header.e_machine == EM_S390_OLD)
10462 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
10463 hash_ent_size = 8;
10464
fb52b2f4
NC
10465 if (fseek (file,
10466 (archive_file_offset
10467 + offset_from_vma (file, dynamic_info[DT_HASH],
10468 sizeof nb + sizeof nc)),
d93f0186 10469 SEEK_SET))
252b5132 10470 {
591a748a 10471 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10472 goto no_hash;
252b5132
RH
10473 }
10474
66543521 10475 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
10476 {
10477 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10478 goto no_hash;
252b5132
RH
10479 }
10480
66543521 10481 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
10482 {
10483 error (_("Failed to read in number of chains\n"));
d3a44ec6 10484 goto no_hash;
252b5132
RH
10485 }
10486
66543521
AM
10487 nbuckets = byte_get (nb, hash_ent_size);
10488 nchains = byte_get (nc, hash_ent_size);
252b5132 10489
66543521
AM
10490 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
10491 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 10492
d3a44ec6 10493 no_hash:
252b5132 10494 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
10495 {
10496 if (do_using_dynamic)
10497 return 0;
10498 free (buckets);
10499 free (chains);
10500 buckets = NULL;
10501 chains = NULL;
10502 nbuckets = 0;
10503 nchains = 0;
10504 }
252b5132
RH
10505 }
10506
6bd1a22c
L
10507 if (dynamic_info_DT_GNU_HASH
10508 && (do_histogram
2c610e4b
L
10509 || (do_using_dynamic
10510 && !do_dyn_syms
10511 && dynamic_strings != NULL)))
252b5132 10512 {
6bd1a22c
L
10513 unsigned char nb[16];
10514 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10515 bfd_vma buckets_vma;
10516
10517 if (fseek (file,
10518 (archive_file_offset
10519 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
10520 sizeof nb)),
10521 SEEK_SET))
10522 {
10523 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10524 goto no_gnu_hash;
6bd1a22c 10525 }
252b5132 10526
6bd1a22c
L
10527 if (fread (nb, 16, 1, file) != 1)
10528 {
10529 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10530 goto no_gnu_hash;
6bd1a22c
L
10531 }
10532
10533 ngnubuckets = byte_get (nb, 4);
10534 gnusymidx = byte_get (nb + 4, 4);
10535 bitmaskwords = byte_get (nb + 8, 4);
10536 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 10537 if (is_32bit_elf)
6bd1a22c 10538 buckets_vma += bitmaskwords * 4;
f7a99963 10539 else
6bd1a22c 10540 buckets_vma += bitmaskwords * 8;
252b5132 10541
6bd1a22c
L
10542 if (fseek (file,
10543 (archive_file_offset
10544 + offset_from_vma (file, buckets_vma, 4)),
10545 SEEK_SET))
252b5132 10546 {
6bd1a22c 10547 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10548 goto no_gnu_hash;
6bd1a22c
L
10549 }
10550
10551 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 10552
6bd1a22c 10553 if (gnubuckets == NULL)
d3a44ec6 10554 goto no_gnu_hash;
6bd1a22c
L
10555
10556 for (i = 0; i < ngnubuckets; i++)
10557 if (gnubuckets[i] != 0)
10558 {
10559 if (gnubuckets[i] < gnusymidx)
10560 return 0;
10561
10562 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
10563 maxchain = gnubuckets[i];
10564 }
10565
10566 if (maxchain == 0xffffffff)
d3a44ec6 10567 goto no_gnu_hash;
6bd1a22c
L
10568
10569 maxchain -= gnusymidx;
10570
10571 if (fseek (file,
10572 (archive_file_offset
10573 + offset_from_vma (file, buckets_vma
10574 + 4 * (ngnubuckets + maxchain), 4)),
10575 SEEK_SET))
10576 {
10577 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10578 goto no_gnu_hash;
6bd1a22c
L
10579 }
10580
10581 do
10582 {
10583 if (fread (nb, 4, 1, file) != 1)
252b5132 10584 {
6bd1a22c 10585 error (_("Failed to determine last chain length\n"));
d3a44ec6 10586 goto no_gnu_hash;
6bd1a22c 10587 }
252b5132 10588
6bd1a22c 10589 if (maxchain + 1 == 0)
d3a44ec6 10590 goto no_gnu_hash;
252b5132 10591
6bd1a22c
L
10592 ++maxchain;
10593 }
10594 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 10595
6bd1a22c
L
10596 if (fseek (file,
10597 (archive_file_offset
10598 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
10599 SEEK_SET))
10600 {
10601 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10602 goto no_gnu_hash;
6bd1a22c
L
10603 }
10604
10605 gnuchains = get_dynamic_data (file, maxchain, 4);
071436c6 10606 ngnuchains = maxchain;
6bd1a22c 10607
d3a44ec6 10608 no_gnu_hash:
6bd1a22c 10609 if (gnuchains == NULL)
d3a44ec6
JJ
10610 {
10611 free (gnubuckets);
d3a44ec6
JJ
10612 gnubuckets = NULL;
10613 ngnubuckets = 0;
f64fddf1
NC
10614 if (do_using_dynamic)
10615 return 0;
d3a44ec6 10616 }
6bd1a22c
L
10617 }
10618
10619 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
10620 && do_syms
10621 && do_using_dynamic
3102e897
NC
10622 && dynamic_strings != NULL
10623 && dynamic_symbols != NULL)
6bd1a22c
L
10624 {
10625 unsigned long hn;
10626
10627 if (dynamic_info[DT_HASH])
10628 {
10629 bfd_vma si;
10630
10631 printf (_("\nSymbol table for image:\n"));
10632 if (is_32bit_elf)
10633 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10634 else
10635 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10636
10637 for (hn = 0; hn < nbuckets; hn++)
10638 {
10639 if (! buckets[hn])
10640 continue;
10641
10642 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
10643 print_dynamic_symbol (si, hn);
252b5132
RH
10644 }
10645 }
6bd1a22c
L
10646
10647 if (dynamic_info_DT_GNU_HASH)
10648 {
10649 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
10650 if (is_32bit_elf)
10651 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10652 else
10653 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10654
10655 for (hn = 0; hn < ngnubuckets; ++hn)
10656 if (gnubuckets[hn] != 0)
10657 {
10658 bfd_vma si = gnubuckets[hn];
10659 bfd_vma off = si - gnusymidx;
10660
10661 do
10662 {
10663 print_dynamic_symbol (si, hn);
10664 si++;
10665 }
071436c6 10666 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
10667 }
10668 }
252b5132 10669 }
8b73c356
NC
10670 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
10671 && section_headers != NULL)
252b5132 10672 {
b34976b6 10673 unsigned int i;
252b5132
RH
10674
10675 for (i = 0, section = section_headers;
10676 i < elf_header.e_shnum;
10677 i++, section++)
10678 {
b34976b6 10679 unsigned int si;
2cf0635d 10680 char * strtab = NULL;
c256ffe7 10681 unsigned long int strtab_size = 0;
2cf0635d
NC
10682 Elf_Internal_Sym * symtab;
10683 Elf_Internal_Sym * psym;
ba5cdace 10684 unsigned long num_syms;
252b5132 10685
2c610e4b
L
10686 if ((section->sh_type != SHT_SYMTAB
10687 && section->sh_type != SHT_DYNSYM)
10688 || (!do_syms
10689 && section->sh_type == SHT_SYMTAB))
252b5132
RH
10690 continue;
10691
dd24e3da
NC
10692 if (section->sh_entsize == 0)
10693 {
10694 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
74e1a04b 10695 printable_section_name (section));
dd24e3da
NC
10696 continue;
10697 }
10698
252b5132 10699 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
74e1a04b 10700 printable_section_name (section),
252b5132 10701 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 10702
f7a99963 10703 if (is_32bit_elf)
ca47b30c 10704 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 10705 else
ca47b30c 10706 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 10707
ba5cdace 10708 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
10709 if (symtab == NULL)
10710 continue;
10711
10712 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
10713 {
10714 strtab = string_table;
10715 strtab_size = string_table_length;
10716 }
4fbb74a6 10717 else if (section->sh_link < elf_header.e_shnum)
252b5132 10718 {
2cf0635d 10719 Elf_Internal_Shdr * string_sec;
252b5132 10720
4fbb74a6 10721 string_sec = section_headers + section->sh_link;
252b5132 10722
3f5e193b
NC
10723 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
10724 1, string_sec->sh_size,
10725 _("string table"));
c256ffe7 10726 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
10727 }
10728
ba5cdace 10729 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 10730 {
bb4d2ac2
L
10731 const char *version_string;
10732 enum versioned_symbol_info sym_info;
10733 unsigned short vna_other;
10734
5e220199 10735 printf ("%6d: ", si);
f7a99963
NC
10736 print_vma (psym->st_value, LONG_HEX);
10737 putchar (' ');
10738 print_vma (psym->st_size, DEC_5);
d1133906
NC
10739 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10740 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 10741 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
10742 /* Check to see if any other bits in the st_other field are set.
10743 Note - displaying this information disrupts the layout of the
10744 table being generated, but for the moment this case is very rare. */
10745 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10746 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 10747 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 10748 print_symbol (25, psym->st_name < strtab_size
2b692964 10749 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 10750
bb4d2ac2
L
10751 version_string
10752 = get_symbol_version_string (file,
10753 section->sh_type == SHT_DYNSYM,
10754 strtab, strtab_size, si,
10755 psym, &sym_info, &vna_other);
10756 if (version_string)
252b5132 10757 {
bb4d2ac2
L
10758 if (sym_info == symbol_undefined)
10759 printf ("@%s (%d)", version_string, vna_other);
10760 else
10761 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
10762 version_string);
252b5132
RH
10763 }
10764
10765 putchar ('\n');
10766 }
10767
10768 free (symtab);
10769 if (strtab != string_table)
10770 free (strtab);
10771 }
10772 }
10773 else if (do_syms)
10774 printf
10775 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10776
10777 if (do_histogram && buckets != NULL)
10778 {
2cf0635d
NC
10779 unsigned long * lengths;
10780 unsigned long * counts;
66543521
AM
10781 unsigned long hn;
10782 bfd_vma si;
10783 unsigned long maxlength = 0;
10784 unsigned long nzero_counts = 0;
10785 unsigned long nsyms = 0;
94d15024 10786 unsigned long chained;
252b5132 10787
66543521
AM
10788 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10789 (unsigned long) nbuckets);
252b5132 10790
3f5e193b 10791 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10792 if (lengths == NULL)
10793 {
8b73c356 10794 error (_("Out of memory allocating space for histogram buckets\n"));
252b5132
RH
10795 return 0;
10796 }
8b73c356
NC
10797
10798 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
10799 for (hn = 0; hn < nbuckets; ++hn)
10800 {
94d15024
MF
10801 for (si = buckets[hn], chained = 0;
10802 si > 0 && si < nchains && si < nbuckets && chained <= nchains;
10803 si = chains[si], ++chained)
252b5132 10804 {
b34976b6 10805 ++nsyms;
252b5132 10806 if (maxlength < ++lengths[hn])
b34976b6 10807 ++maxlength;
252b5132 10808 }
94d15024
MF
10809
10810 /* PR binutils/17531: A corrupt binary could contain broken
10811 histogram data. Do not go into an infinite loop trying
10812 to process it. */
10813 if (chained > nchains)
10814 {
10815 error (_("histogram chain is corrupt\n"));
10816 break;
10817 }
252b5132
RH
10818 }
10819
3f5e193b 10820 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
10821 if (counts == NULL)
10822 {
b2e951ec 10823 free (lengths);
8b73c356 10824 error (_("Out of memory allocating space for histogram counts\n"));
252b5132
RH
10825 return 0;
10826 }
10827
10828 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 10829 ++counts[lengths[hn]];
252b5132 10830
103f02d3 10831 if (nbuckets > 0)
252b5132 10832 {
66543521
AM
10833 unsigned long i;
10834 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 10835 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 10836 for (i = 1; i <= maxlength; ++i)
103f02d3 10837 {
66543521
AM
10838 nzero_counts += counts[i] * i;
10839 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10840 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
10841 (nzero_counts * 100.0) / nsyms);
10842 }
252b5132
RH
10843 }
10844
10845 free (counts);
10846 free (lengths);
10847 }
10848
10849 if (buckets != NULL)
10850 {
10851 free (buckets);
10852 free (chains);
10853 }
10854
d3a44ec6 10855 if (do_histogram && gnubuckets != NULL)
fdc90cb4 10856 {
2cf0635d
NC
10857 unsigned long * lengths;
10858 unsigned long * counts;
fdc90cb4
JJ
10859 unsigned long hn;
10860 unsigned long maxlength = 0;
10861 unsigned long nzero_counts = 0;
10862 unsigned long nsyms = 0;
fdc90cb4 10863
8b73c356
NC
10864 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
10865 (unsigned long) ngnubuckets);
10866
3f5e193b 10867 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
10868 if (lengths == NULL)
10869 {
8b73c356 10870 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fdc90cb4
JJ
10871 return 0;
10872 }
10873
fdc90cb4
JJ
10874 printf (_(" Length Number %% of total Coverage\n"));
10875
10876 for (hn = 0; hn < ngnubuckets; ++hn)
10877 if (gnubuckets[hn] != 0)
10878 {
10879 bfd_vma off, length = 1;
10880
6bd1a22c 10881 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
10882 /* PR 17531 file: 010-77222-0.004. */
10883 off < ngnuchains && (gnuchains[off] & 1) == 0;
10884 ++off)
fdc90cb4
JJ
10885 ++length;
10886 lengths[hn] = length;
10887 if (length > maxlength)
10888 maxlength = length;
10889 nsyms += length;
10890 }
10891
3f5e193b 10892 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
10893 if (counts == NULL)
10894 {
b2e951ec 10895 free (lengths);
8b73c356 10896 error (_("Out of memory allocating space for gnu histogram counts\n"));
fdc90cb4
JJ
10897 return 0;
10898 }
10899
10900 for (hn = 0; hn < ngnubuckets; ++hn)
10901 ++counts[lengths[hn]];
10902
10903 if (ngnubuckets > 0)
10904 {
10905 unsigned long j;
10906 printf (" 0 %-10lu (%5.1f%%)\n",
10907 counts[0], (counts[0] * 100.0) / ngnubuckets);
10908 for (j = 1; j <= maxlength; ++j)
10909 {
10910 nzero_counts += counts[j] * j;
10911 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10912 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
10913 (nzero_counts * 100.0) / nsyms);
10914 }
10915 }
10916
10917 free (counts);
10918 free (lengths);
10919 free (gnubuckets);
10920 free (gnuchains);
10921 }
10922
252b5132
RH
10923 return 1;
10924}
10925
10926static int
2cf0635d 10927process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 10928{
b4c96d0d 10929 unsigned int i;
252b5132
RH
10930
10931 if (dynamic_syminfo == NULL
10932 || !do_dynamic)
10933 /* No syminfo, this is ok. */
10934 return 1;
10935
10936 /* There better should be a dynamic symbol section. */
10937 if (dynamic_symbols == NULL || dynamic_strings == NULL)
10938 return 0;
10939
10940 if (dynamic_addr)
10941 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10942 dynamic_syminfo_offset, dynamic_syminfo_nent);
10943
10944 printf (_(" Num: Name BoundTo Flags\n"));
10945 for (i = 0; i < dynamic_syminfo_nent; ++i)
10946 {
10947 unsigned short int flags = dynamic_syminfo[i].si_flags;
10948
31104126 10949 printf ("%4d: ", i);
4082ef84
NC
10950 if (i >= num_dynamic_syms)
10951 printf (_("<corrupt index>"));
10952 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
10953 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10954 else
2b692964 10955 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10956 putchar (' ');
252b5132
RH
10957
10958 switch (dynamic_syminfo[i].si_boundto)
10959 {
10960 case SYMINFO_BT_SELF:
10961 fputs ("SELF ", stdout);
10962 break;
10963 case SYMINFO_BT_PARENT:
10964 fputs ("PARENT ", stdout);
10965 break;
10966 default:
10967 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10968 && dynamic_syminfo[i].si_boundto < dynamic_nent
10969 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10970 {
d79b3d50 10971 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10972 putchar (' ' );
10973 }
252b5132
RH
10974 else
10975 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10976 break;
10977 }
10978
10979 if (flags & SYMINFO_FLG_DIRECT)
10980 printf (" DIRECT");
10981 if (flags & SYMINFO_FLG_PASSTHRU)
10982 printf (" PASSTHRU");
10983 if (flags & SYMINFO_FLG_COPY)
10984 printf (" COPY");
10985 if (flags & SYMINFO_FLG_LAZYLOAD)
10986 printf (" LAZYLOAD");
10987
10988 puts ("");
10989 }
10990
10991 return 1;
10992}
10993
cf13d699
NC
10994/* Check to see if the given reloc needs to be handled in a target specific
10995 manner. If so then process the reloc and return TRUE otherwise return
10996 FALSE. */
09c11c86 10997
cf13d699
NC
10998static bfd_boolean
10999target_specific_reloc_handling (Elf_Internal_Rela * reloc,
11000 unsigned char * start,
11001 Elf_Internal_Sym * symtab)
252b5132 11002{
cf13d699 11003 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 11004
cf13d699 11005 switch (elf_header.e_machine)
252b5132 11006 {
13761a11
NC
11007 case EM_MSP430:
11008 case EM_MSP430_OLD:
11009 {
11010 static Elf_Internal_Sym * saved_sym = NULL;
11011
11012 switch (reloc_type)
11013 {
11014 case 10: /* R_MSP430_SYM_DIFF */
11015 if (uses_msp430x_relocs ())
11016 break;
11017 case 21: /* R_MSP430X_SYM_DIFF */
11018 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
11019 return TRUE;
11020
11021 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
11022 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
11023 goto handle_sym_diff;
0b4362b0 11024
13761a11
NC
11025 case 5: /* R_MSP430_16_BYTE */
11026 case 9: /* R_MSP430_8 */
11027 if (uses_msp430x_relocs ())
11028 break;
11029 goto handle_sym_diff;
11030
11031 case 2: /* R_MSP430_ABS16 */
11032 case 15: /* R_MSP430X_ABS16 */
11033 if (! uses_msp430x_relocs ())
11034 break;
11035 goto handle_sym_diff;
0b4362b0 11036
13761a11
NC
11037 handle_sym_diff:
11038 if (saved_sym != NULL)
11039 {
11040 bfd_vma value;
11041
11042 value = reloc->r_addend
11043 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
11044 - saved_sym->st_value);
11045
11046 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
11047
11048 saved_sym = NULL;
11049 return TRUE;
11050 }
11051 break;
11052
11053 default:
11054 if (saved_sym != NULL)
071436c6 11055 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
11056 break;
11057 }
11058 break;
11059 }
11060
cf13d699
NC
11061 case EM_MN10300:
11062 case EM_CYGNUS_MN10300:
11063 {
11064 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 11065
cf13d699
NC
11066 switch (reloc_type)
11067 {
11068 case 34: /* R_MN10300_ALIGN */
11069 return TRUE;
11070 case 33: /* R_MN10300_SYM_DIFF */
11071 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
11072 return TRUE;
11073 case 1: /* R_MN10300_32 */
11074 case 2: /* R_MN10300_16 */
11075 if (saved_sym != NULL)
11076 {
11077 bfd_vma value;
252b5132 11078
cf13d699
NC
11079 value = reloc->r_addend
11080 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
11081 - saved_sym->st_value);
252b5132 11082
cf13d699 11083 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 11084
cf13d699
NC
11085 saved_sym = NULL;
11086 return TRUE;
11087 }
11088 break;
11089 default:
11090 if (saved_sym != NULL)
071436c6 11091 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
11092 break;
11093 }
11094 break;
11095 }
252b5132
RH
11096 }
11097
cf13d699 11098 return FALSE;
252b5132
RH
11099}
11100
aca88567
NC
11101/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
11102 DWARF debug sections. This is a target specific test. Note - we do not
11103 go through the whole including-target-headers-multiple-times route, (as
11104 we have already done with <elf/h8.h>) because this would become very
11105 messy and even then this function would have to contain target specific
11106 information (the names of the relocs instead of their numeric values).
11107 FIXME: This is not the correct way to solve this problem. The proper way
11108 is to have target specific reloc sizing and typing functions created by
11109 the reloc-macros.h header, in the same way that it already creates the
11110 reloc naming functions. */
11111
11112static bfd_boolean
11113is_32bit_abs_reloc (unsigned int reloc_type)
11114{
11115 switch (elf_header.e_machine)
11116 {
41e92641
NC
11117 case EM_386:
11118 case EM_486:
11119 return reloc_type == 1; /* R_386_32. */
aca88567
NC
11120 case EM_68K:
11121 return reloc_type == 1; /* R_68K_32. */
11122 case EM_860:
11123 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
11124 case EM_960:
11125 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
11126 case EM_AARCH64:
11127 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 11128 case EM_ALPHA:
137b6b5f 11129 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
11130 case EM_ARC:
11131 return reloc_type == 1; /* R_ARC_32. */
11132 case EM_ARM:
11133 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 11134 case EM_AVR_OLD:
aca88567
NC
11135 case EM_AVR:
11136 return reloc_type == 1;
cfb8c092
NC
11137 case EM_ADAPTEVA_EPIPHANY:
11138 return reloc_type == 3;
aca88567
NC
11139 case EM_BLACKFIN:
11140 return reloc_type == 0x12; /* R_byte4_data. */
11141 case EM_CRIS:
11142 return reloc_type == 3; /* R_CRIS_32. */
11143 case EM_CR16:
11144 return reloc_type == 3; /* R_CR16_NUM32. */
11145 case EM_CRX:
11146 return reloc_type == 15; /* R_CRX_NUM32. */
11147 case EM_CYGNUS_FRV:
11148 return reloc_type == 1;
41e92641
NC
11149 case EM_CYGNUS_D10V:
11150 case EM_D10V:
11151 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
11152 case EM_CYGNUS_D30V:
11153 case EM_D30V:
11154 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
11155 case EM_DLX:
11156 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
11157 case EM_CYGNUS_FR30:
11158 case EM_FR30:
11159 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
11160 case EM_FT32:
11161 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
11162 case EM_H8S:
11163 case EM_H8_300:
11164 case EM_H8_300H:
11165 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
11166 case EM_IA_64:
11167 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
11168 case EM_IP2K_OLD:
11169 case EM_IP2K:
11170 return reloc_type == 2; /* R_IP2K_32. */
11171 case EM_IQ2000:
11172 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
11173 case EM_LATTICEMICO32:
11174 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 11175 case EM_M32C_OLD:
aca88567
NC
11176 case EM_M32C:
11177 return reloc_type == 3; /* R_M32C_32. */
11178 case EM_M32R:
11179 return reloc_type == 34; /* R_M32R_32_RELA. */
11180 case EM_MCORE:
11181 return reloc_type == 1; /* R_MCORE_ADDR32. */
11182 case EM_CYGNUS_MEP:
11183 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
11184 case EM_METAG:
11185 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
11186 case EM_MICROBLAZE:
11187 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
11188 case EM_MIPS:
11189 return reloc_type == 2; /* R_MIPS_32. */
11190 case EM_MMIX:
11191 return reloc_type == 4; /* R_MMIX_32. */
11192 case EM_CYGNUS_MN10200:
11193 case EM_MN10200:
11194 return reloc_type == 1; /* R_MN10200_32. */
11195 case EM_CYGNUS_MN10300:
11196 case EM_MN10300:
11197 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
11198 case EM_MOXIE:
11199 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
11200 case EM_MSP430_OLD:
11201 case EM_MSP430:
13761a11 11202 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
11203 case EM_MT:
11204 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
11205 case EM_NDS32:
11206 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 11207 case EM_ALTERA_NIOS2:
36591ba1 11208 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
11209 case EM_NIOS32:
11210 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
11211 case EM_OR1K:
11212 return reloc_type == 1; /* R_OR1K_32. */
aca88567 11213 case EM_PARISC:
5fda8eca
NC
11214 return (reloc_type == 1 /* R_PARISC_DIR32. */
11215 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
11216 case EM_PJ:
11217 case EM_PJ_OLD:
11218 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
11219 case EM_PPC64:
11220 return reloc_type == 1; /* R_PPC64_ADDR32. */
11221 case EM_PPC:
11222 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
11223 case EM_RL78:
11224 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
11225 case EM_RX:
11226 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
11227 case EM_S370:
11228 return reloc_type == 1; /* R_I370_ADDR31. */
11229 case EM_S390_OLD:
11230 case EM_S390:
11231 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
11232 case EM_SCORE:
11233 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
11234 case EM_SH:
11235 return reloc_type == 1; /* R_SH_DIR32. */
11236 case EM_SPARC32PLUS:
11237 case EM_SPARCV9:
11238 case EM_SPARC:
11239 return reloc_type == 3 /* R_SPARC_32. */
11240 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
11241 case EM_SPU:
11242 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
11243 case EM_TI_C6000:
11244 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
11245 case EM_TILEGX:
11246 return reloc_type == 2; /* R_TILEGX_32. */
11247 case EM_TILEPRO:
11248 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
11249 case EM_CYGNUS_V850:
11250 case EM_V850:
11251 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
11252 case EM_V800:
11253 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
11254 case EM_VAX:
11255 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
11256 case EM_VISIUM:
11257 return reloc_type == 3; /* R_VISIUM_32. */
aca88567 11258 case EM_X86_64:
8a9036a4 11259 case EM_L1OM:
7a9068fe 11260 case EM_K1OM:
aca88567 11261 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
11262 case EM_XC16X:
11263 case EM_C166:
11264 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
11265 case EM_XGATE:
11266 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
11267 case EM_XSTORMY16:
11268 return reloc_type == 1; /* R_XSTROMY16_32. */
11269 case EM_XTENSA_OLD:
11270 case EM_XTENSA:
11271 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 11272 default:
bee0ee85
NC
11273 {
11274 static unsigned int prev_warn = 0;
11275
11276 /* Avoid repeating the same warning multiple times. */
11277 if (prev_warn != elf_header.e_machine)
11278 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
11279 elf_header.e_machine);
11280 prev_warn = elf_header.e_machine;
11281 return FALSE;
11282 }
aca88567
NC
11283 }
11284}
11285
11286/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11287 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
11288
11289static bfd_boolean
11290is_32bit_pcrel_reloc (unsigned int reloc_type)
11291{
11292 switch (elf_header.e_machine)
11293 {
41e92641
NC
11294 case EM_386:
11295 case EM_486:
3e0873ac 11296 return reloc_type == 2; /* R_386_PC32. */
aca88567 11297 case EM_68K:
3e0873ac 11298 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
11299 case EM_AARCH64:
11300 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
11301 case EM_ADAPTEVA_EPIPHANY:
11302 return reloc_type == 6;
aca88567
NC
11303 case EM_ALPHA:
11304 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 11305 case EM_ARM:
3e0873ac 11306 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
11307 case EM_MICROBLAZE:
11308 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
11309 case EM_OR1K:
11310 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 11311 case EM_PARISC:
85acf597 11312 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
11313 case EM_PPC:
11314 return reloc_type == 26; /* R_PPC_REL32. */
11315 case EM_PPC64:
3e0873ac 11316 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
11317 case EM_S390_OLD:
11318 case EM_S390:
3e0873ac 11319 return reloc_type == 5; /* R_390_PC32. */
aca88567 11320 case EM_SH:
3e0873ac 11321 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
11322 case EM_SPARC32PLUS:
11323 case EM_SPARCV9:
11324 case EM_SPARC:
3e0873ac 11325 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
11326 case EM_SPU:
11327 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
11328 case EM_TILEGX:
11329 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
11330 case EM_TILEPRO:
11331 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
11332 case EM_VISIUM:
11333 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 11334 case EM_X86_64:
8a9036a4 11335 case EM_L1OM:
7a9068fe 11336 case EM_K1OM:
3e0873ac 11337 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
11338 case EM_XTENSA_OLD:
11339 case EM_XTENSA:
11340 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
11341 default:
11342 /* Do not abort or issue an error message here. Not all targets use
11343 pc-relative 32-bit relocs in their DWARF debug information and we
11344 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
11345 more helpful warning message will be generated by apply_relocations
11346 anyway, so just return. */
aca88567
NC
11347 return FALSE;
11348 }
11349}
11350
11351/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11352 a 64-bit absolute RELA relocation used in DWARF debug sections. */
11353
11354static bfd_boolean
11355is_64bit_abs_reloc (unsigned int reloc_type)
11356{
11357 switch (elf_header.e_machine)
11358 {
a06ea964
NC
11359 case EM_AARCH64:
11360 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
11361 case EM_ALPHA:
11362 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
11363 case EM_IA_64:
11364 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
11365 case EM_PARISC:
11366 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
11367 case EM_PPC64:
11368 return reloc_type == 38; /* R_PPC64_ADDR64. */
11369 case EM_SPARC32PLUS:
11370 case EM_SPARCV9:
11371 case EM_SPARC:
11372 return reloc_type == 54; /* R_SPARC_UA64. */
11373 case EM_X86_64:
8a9036a4 11374 case EM_L1OM:
7a9068fe 11375 case EM_K1OM:
aca88567 11376 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
11377 case EM_S390_OLD:
11378 case EM_S390:
aa137e4d
NC
11379 return reloc_type == 22; /* R_S390_64. */
11380 case EM_TILEGX:
11381 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 11382 case EM_MIPS:
aa137e4d 11383 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
11384 default:
11385 return FALSE;
11386 }
11387}
11388
85acf597
RH
11389/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
11390 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
11391
11392static bfd_boolean
11393is_64bit_pcrel_reloc (unsigned int reloc_type)
11394{
11395 switch (elf_header.e_machine)
11396 {
a06ea964
NC
11397 case EM_AARCH64:
11398 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 11399 case EM_ALPHA:
aa137e4d 11400 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 11401 case EM_IA_64:
aa137e4d 11402 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 11403 case EM_PARISC:
aa137e4d 11404 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 11405 case EM_PPC64:
aa137e4d 11406 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
11407 case EM_SPARC32PLUS:
11408 case EM_SPARCV9:
11409 case EM_SPARC:
aa137e4d 11410 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 11411 case EM_X86_64:
8a9036a4 11412 case EM_L1OM:
7a9068fe 11413 case EM_K1OM:
aa137e4d 11414 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
11415 case EM_S390_OLD:
11416 case EM_S390:
aa137e4d
NC
11417 return reloc_type == 23; /* R_S390_PC64. */
11418 case EM_TILEGX:
11419 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
11420 default:
11421 return FALSE;
11422 }
11423}
11424
4dc3c23d
AM
11425/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11426 a 24-bit absolute RELA relocation used in DWARF debug sections. */
11427
11428static bfd_boolean
11429is_24bit_abs_reloc (unsigned int reloc_type)
11430{
11431 switch (elf_header.e_machine)
11432 {
11433 case EM_CYGNUS_MN10200:
11434 case EM_MN10200:
11435 return reloc_type == 4; /* R_MN10200_24. */
11436 default:
11437 return FALSE;
11438 }
11439}
11440
aca88567
NC
11441/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11442 a 16-bit absolute RELA relocation used in DWARF debug sections. */
11443
11444static bfd_boolean
11445is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
11446{
11447 switch (elf_header.e_machine)
11448 {
aca88567
NC
11449 case EM_AVR_OLD:
11450 case EM_AVR:
11451 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
11452 case EM_ADAPTEVA_EPIPHANY:
11453 return reloc_type == 5;
41e92641
NC
11454 case EM_CYGNUS_D10V:
11455 case EM_D10V:
11456 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
11457 case EM_H8S:
11458 case EM_H8_300:
11459 case EM_H8_300H:
aca88567
NC
11460 return reloc_type == R_H8_DIR16;
11461 case EM_IP2K_OLD:
11462 case EM_IP2K:
11463 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 11464 case EM_M32C_OLD:
f4236fe4
DD
11465 case EM_M32C:
11466 return reloc_type == 1; /* R_M32C_16 */
aca88567 11467 case EM_MSP430:
13761a11
NC
11468 if (uses_msp430x_relocs ())
11469 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 11470 case EM_MSP430_OLD:
aca88567 11471 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
11472 case EM_NDS32:
11473 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 11474 case EM_ALTERA_NIOS2:
36591ba1 11475 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
11476 case EM_NIOS32:
11477 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
11478 case EM_OR1K:
11479 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
11480 case EM_TI_C6000:
11481 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
11482 case EM_XC16X:
11483 case EM_C166:
11484 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
11485 case EM_CYGNUS_MN10200:
11486 case EM_MN10200:
11487 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
11488 case EM_CYGNUS_MN10300:
11489 case EM_MN10300:
11490 return reloc_type == 2; /* R_MN10300_16. */
619ed720
EB
11491 case EM_VISIUM:
11492 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
11493 case EM_XGATE:
11494 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 11495 default:
aca88567 11496 return FALSE;
4b78141a
NC
11497 }
11498}
11499
2a7b2e88
JK
11500/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
11501 relocation entries (possibly formerly used for SHT_GROUP sections). */
11502
11503static bfd_boolean
11504is_none_reloc (unsigned int reloc_type)
11505{
11506 switch (elf_header.e_machine)
11507 {
cb8f3167
NC
11508 case EM_68K: /* R_68K_NONE. */
11509 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
11510 case EM_SPARC32PLUS:
11511 case EM_SPARCV9:
cb8f3167
NC
11512 case EM_SPARC: /* R_SPARC_NONE. */
11513 case EM_MIPS: /* R_MIPS_NONE. */
11514 case EM_PARISC: /* R_PARISC_NONE. */
11515 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 11516 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
11517 case EM_PPC: /* R_PPC_NONE. */
11518 case EM_PPC64: /* R_PPC64_NONE. */
11519 case EM_ARM: /* R_ARM_NONE. */
11520 case EM_IA_64: /* R_IA64_NONE. */
11521 case EM_SH: /* R_SH_NONE. */
2a7b2e88 11522 case EM_S390_OLD:
cb8f3167
NC
11523 case EM_S390: /* R_390_NONE. */
11524 case EM_CRIS: /* R_CRIS_NONE. */
11525 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 11526 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 11527 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 11528 case EM_MN10300: /* R_MN10300_NONE. */
3f8107ab 11529 case EM_FT32: /* R_FT32_NONE. */
5506d11a 11530 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 11531 case EM_M32R: /* R_M32R_NONE. */
40b36596 11532 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
11533 case EM_TILEGX: /* R_TILEGX_NONE. */
11534 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
11535 case EM_XC16X:
11536 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
11537 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
11538 case EM_NIOS32: /* R_NIOS_NONE. */
73589c9d 11539 case EM_OR1K: /* R_OR1K_NONE. */
cb8f3167 11540 return reloc_type == 0;
a06ea964
NC
11541 case EM_AARCH64:
11542 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
11543 case EM_NDS32:
11544 return (reloc_type == 0 /* R_XTENSA_NONE. */
11545 || reloc_type == 204 /* R_NDS32_DIFF8. */
11546 || reloc_type == 205 /* R_NDS32_DIFF16. */
11547 || reloc_type == 206 /* R_NDS32_DIFF32. */
11548 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
11549 case EM_XTENSA_OLD:
11550 case EM_XTENSA:
4dc3c23d
AM
11551 return (reloc_type == 0 /* R_XTENSA_NONE. */
11552 || reloc_type == 17 /* R_XTENSA_DIFF8. */
11553 || reloc_type == 18 /* R_XTENSA_DIFF16. */
11554 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
11555 case EM_METAG:
11556 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
11557 }
11558 return FALSE;
11559}
11560
cf13d699
NC
11561/* Apply relocations to a section.
11562 Note: So far support has been added only for those relocations
11563 which can be found in debug sections.
11564 FIXME: Add support for more relocations ? */
1b315056 11565
cf13d699
NC
11566static void
11567apply_relocations (void * file,
11568 Elf_Internal_Shdr * section,
11569 unsigned char * start)
1b315056 11570{
cf13d699
NC
11571 Elf_Internal_Shdr * relsec;
11572 unsigned char * end = start + section->sh_size;
cb8f3167 11573
cf13d699
NC
11574 if (elf_header.e_type != ET_REL)
11575 return;
1b315056 11576
cf13d699 11577 /* Find the reloc section associated with the section. */
5b18a4bc
NC
11578 for (relsec = section_headers;
11579 relsec < section_headers + elf_header.e_shnum;
11580 ++relsec)
252b5132 11581 {
41e92641
NC
11582 bfd_boolean is_rela;
11583 unsigned long num_relocs;
2cf0635d
NC
11584 Elf_Internal_Rela * relocs;
11585 Elf_Internal_Rela * rp;
11586 Elf_Internal_Shdr * symsec;
11587 Elf_Internal_Sym * symtab;
ba5cdace 11588 unsigned long num_syms;
2cf0635d 11589 Elf_Internal_Sym * sym;
252b5132 11590
41e92641 11591 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
11592 || relsec->sh_info >= elf_header.e_shnum
11593 || section_headers + relsec->sh_info != section
c256ffe7 11594 || relsec->sh_size == 0
4fbb74a6 11595 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 11596 continue;
428409d5 11597
41e92641
NC
11598 is_rela = relsec->sh_type == SHT_RELA;
11599
11600 if (is_rela)
11601 {
3f5e193b
NC
11602 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
11603 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11604 return;
11605 }
11606 else
11607 {
3f5e193b
NC
11608 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
11609 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11610 return;
11611 }
11612
11613 /* SH uses RELA but uses in place value instead of the addend field. */
11614 if (elf_header.e_machine == EM_SH)
11615 is_rela = FALSE;
428409d5 11616
4fbb74a6 11617 symsec = section_headers + relsec->sh_link;
ba5cdace 11618 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 11619
41e92641 11620 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 11621 {
41e92641
NC
11622 bfd_vma addend;
11623 unsigned int reloc_type;
11624 unsigned int reloc_size;
91d6fa6a 11625 unsigned char * rloc;
ba5cdace 11626 unsigned long sym_index;
4b78141a 11627
aca88567 11628 reloc_type = get_reloc_type (rp->r_info);
41e92641 11629
98fb390a 11630 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 11631 continue;
98fb390a
NC
11632 else if (is_none_reloc (reloc_type))
11633 continue;
11634 else if (is_32bit_abs_reloc (reloc_type)
11635 || is_32bit_pcrel_reloc (reloc_type))
aca88567 11636 reloc_size = 4;
85acf597
RH
11637 else if (is_64bit_abs_reloc (reloc_type)
11638 || is_64bit_pcrel_reloc (reloc_type))
aca88567 11639 reloc_size = 8;
4dc3c23d
AM
11640 else if (is_24bit_abs_reloc (reloc_type))
11641 reloc_size = 3;
aca88567
NC
11642 else if (is_16bit_abs_reloc (reloc_type))
11643 reloc_size = 2;
11644 else
4b78141a 11645 {
bee0ee85
NC
11646 static unsigned int prev_reloc = 0;
11647 if (reloc_type != prev_reloc)
11648 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
11649 reloc_type, printable_section_name (section));
11650 prev_reloc = reloc_type;
4b78141a
NC
11651 continue;
11652 }
103f02d3 11653
91d6fa6a 11654 rloc = start + rp->r_offset;
c8da6823 11655 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
11656 {
11657 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
11658 (unsigned long) rp->r_offset,
74e1a04b 11659 printable_section_name (section));
700dd8b7
L
11660 continue;
11661 }
103f02d3 11662
ba5cdace
NC
11663 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
11664 if (sym_index >= num_syms)
11665 {
11666 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
74e1a04b 11667 sym_index, printable_section_name (section));
ba5cdace
NC
11668 continue;
11669 }
11670 sym = symtab + sym_index;
41e92641
NC
11671
11672 /* If the reloc has a symbol associated with it,
55f25fc3
L
11673 make sure that it is of an appropriate type.
11674
11675 Relocations against symbols without type can happen.
11676 Gcc -feliminate-dwarf2-dups may generate symbols
11677 without type for debug info.
11678
11679 Icc generates relocations against function symbols
11680 instead of local labels.
11681
11682 Relocations against object symbols can happen, eg when
11683 referencing a global array. For an example of this see
11684 the _clz.o binary in libgcc.a. */
aca88567 11685 if (sym != symtab
55f25fc3 11686 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 11687 {
41e92641 11688 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 11689 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 11690 (long int)(rp - relocs),
74e1a04b 11691 printable_section_name (relsec));
aca88567 11692 continue;
5b18a4bc 11693 }
252b5132 11694
4dc3c23d
AM
11695 addend = 0;
11696 if (is_rela)
11697 addend += rp->r_addend;
c47320c3
AM
11698 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
11699 partial_inplace. */
4dc3c23d
AM
11700 if (!is_rela
11701 || (elf_header.e_machine == EM_XTENSA
11702 && reloc_type == 1)
11703 || ((elf_header.e_machine == EM_PJ
11704 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
11705 && reloc_type == 1)
11706 || ((elf_header.e_machine == EM_D30V
11707 || elf_header.e_machine == EM_CYGNUS_D30V)
11708 && reloc_type == 12))
91d6fa6a 11709 addend += byte_get (rloc, reloc_size);
cb8f3167 11710
85acf597
RH
11711 if (is_32bit_pcrel_reloc (reloc_type)
11712 || is_64bit_pcrel_reloc (reloc_type))
11713 {
11714 /* On HPPA, all pc-relative relocations are biased by 8. */
11715 if (elf_header.e_machine == EM_PARISC)
11716 addend -= 8;
91d6fa6a 11717 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
11718 reloc_size);
11719 }
41e92641 11720 else
91d6fa6a 11721 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 11722 }
252b5132 11723
5b18a4bc 11724 free (symtab);
41e92641 11725 free (relocs);
5b18a4bc
NC
11726 break;
11727 }
5b18a4bc 11728}
103f02d3 11729
cf13d699
NC
11730#ifdef SUPPORT_DISASSEMBLY
11731static int
11732disassemble_section (Elf_Internal_Shdr * section, FILE * file)
11733{
74e1a04b 11734 printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
cf13d699 11735
74e1a04b 11736 /* FIXME: XXX -- to be done --- XXX */
cf13d699
NC
11737
11738 return 1;
11739}
11740#endif
11741
11742/* Reads in the contents of SECTION from FILE, returning a pointer
11743 to a malloc'ed buffer or NULL if something went wrong. */
11744
11745static char *
11746get_section_contents (Elf_Internal_Shdr * section, FILE * file)
11747{
11748 bfd_size_type num_bytes;
11749
11750 num_bytes = section->sh_size;
11751
11752 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
11753 {
11754 printf (_("\nSection '%s' has no data to dump.\n"),
74e1a04b 11755 printable_section_name (section));
cf13d699
NC
11756 return NULL;
11757 }
11758
3f5e193b
NC
11759 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
11760 _("section contents"));
cf13d699
NC
11761}
11762
dd24e3da 11763
cf13d699
NC
11764static void
11765dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
11766{
11767 Elf_Internal_Shdr * relsec;
11768 bfd_size_type num_bytes;
cf13d699
NC
11769 char * data;
11770 char * end;
11771 char * start;
cf13d699
NC
11772 bfd_boolean some_strings_shown;
11773
11774 start = get_section_contents (section, file);
11775 if (start == NULL)
11776 return;
11777
74e1a04b 11778 printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11779
11780 /* If the section being dumped has relocations against it the user might
11781 be expecting these relocations to have been applied. Check for this
11782 case and issue a warning message in order to avoid confusion.
11783 FIXME: Maybe we ought to have an option that dumps a section with
11784 relocs applied ? */
11785 for (relsec = section_headers;
11786 relsec < section_headers + elf_header.e_shnum;
11787 ++relsec)
11788 {
11789 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11790 || relsec->sh_info >= elf_header.e_shnum
11791 || section_headers + relsec->sh_info != section
11792 || relsec->sh_size == 0
11793 || relsec->sh_link >= elf_header.e_shnum)
11794 continue;
11795
11796 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11797 break;
11798 }
11799
11800 num_bytes = section->sh_size;
cf13d699
NC
11801 data = start;
11802 end = start + num_bytes;
11803 some_strings_shown = FALSE;
11804
11805 while (data < end)
11806 {
11807 while (!ISPRINT (* data))
11808 if (++ data >= end)
11809 break;
11810
11811 if (data < end)
11812 {
071436c6
NC
11813 size_t maxlen = end - data;
11814
cf13d699 11815#ifndef __MSVCRT__
c975cc98
NC
11816 /* PR 11128: Use two separate invocations in order to work
11817 around bugs in the Solaris 8 implementation of printf. */
11818 printf (" [%6tx] ", data - start);
cf13d699 11819#else
071436c6 11820 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 11821#endif
4082ef84
NC
11822 if (maxlen > 0)
11823 {
11824 print_symbol ((int) maxlen, data);
11825 putchar ('\n');
11826 data += strnlen (data, maxlen);
11827 }
11828 else
11829 {
11830 printf (_("<corrupt>\n"));
11831 data = end;
11832 }
cf13d699
NC
11833 some_strings_shown = TRUE;
11834 }
11835 }
11836
11837 if (! some_strings_shown)
11838 printf (_(" No strings found in this section."));
11839
11840 free (start);
11841
11842 putchar ('\n');
11843}
11844
11845static void
11846dump_section_as_bytes (Elf_Internal_Shdr * section,
11847 FILE * file,
11848 bfd_boolean relocate)
11849{
11850 Elf_Internal_Shdr * relsec;
11851 bfd_size_type bytes;
11852 bfd_vma addr;
11853 unsigned char * data;
11854 unsigned char * start;
11855
11856 start = (unsigned char *) get_section_contents (section, file);
11857 if (start == NULL)
11858 return;
11859
74e1a04b 11860 printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11861
11862 if (relocate)
11863 {
11864 apply_relocations (file, section, start);
11865 }
11866 else
11867 {
11868 /* If the section being dumped has relocations against it the user might
11869 be expecting these relocations to have been applied. Check for this
11870 case and issue a warning message in order to avoid confusion.
11871 FIXME: Maybe we ought to have an option that dumps a section with
11872 relocs applied ? */
11873 for (relsec = section_headers;
11874 relsec < section_headers + elf_header.e_shnum;
11875 ++relsec)
11876 {
11877 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11878 || relsec->sh_info >= elf_header.e_shnum
11879 || section_headers + relsec->sh_info != section
11880 || relsec->sh_size == 0
11881 || relsec->sh_link >= elf_header.e_shnum)
11882 continue;
11883
11884 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11885 break;
11886 }
11887 }
11888
11889 addr = section->sh_addr;
11890 bytes = section->sh_size;
11891 data = start;
11892
11893 while (bytes)
11894 {
11895 int j;
11896 int k;
11897 int lbytes;
11898
11899 lbytes = (bytes > 16 ? 16 : bytes);
11900
11901 printf (" 0x%8.8lx ", (unsigned long) addr);
11902
11903 for (j = 0; j < 16; j++)
11904 {
11905 if (j < lbytes)
11906 printf ("%2.2x", data[j]);
11907 else
11908 printf (" ");
11909
11910 if ((j & 3) == 3)
11911 printf (" ");
11912 }
11913
11914 for (j = 0; j < lbytes; j++)
11915 {
11916 k = data[j];
11917 if (k >= ' ' && k < 0x7f)
11918 printf ("%c", k);
11919 else
11920 printf (".");
11921 }
11922
11923 putchar ('\n');
11924
11925 data += lbytes;
11926 addr += lbytes;
11927 bytes -= lbytes;
11928 }
11929
11930 free (start);
11931
11932 putchar ('\n');
11933}
11934
4a114e3e 11935/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
11936
11937static int
d3dbc530
AM
11938uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
11939 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
11940{
11941#ifndef HAVE_ZLIB_H
cf13d699
NC
11942 return FALSE;
11943#else
11944 dwarf_size_type compressed_size = *size;
11945 unsigned char * compressed_buffer = *buffer;
11946 dwarf_size_type uncompressed_size;
11947 unsigned char * uncompressed_buffer;
11948 z_stream strm;
11949 int rc;
11950 dwarf_size_type header_size = 12;
11951
11952 /* Read the zlib header. In this case, it should be "ZLIB" followed
11953 by the uncompressed section size, 8 bytes in big-endian order. */
11954 if (compressed_size < header_size
11955 || ! streq ((char *) compressed_buffer, "ZLIB"))
11956 return 0;
11957
11958 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
11959 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
11960 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
11961 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
11962 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
11963 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
11964 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
11965 uncompressed_size += compressed_buffer[11];
11966
11967 /* It is possible the section consists of several compressed
11968 buffers concatenated together, so we uncompress in a loop. */
11969 strm.zalloc = NULL;
11970 strm.zfree = NULL;
11971 strm.opaque = NULL;
11972 strm.avail_in = compressed_size - header_size;
11973 strm.next_in = (Bytef *) compressed_buffer + header_size;
11974 strm.avail_out = uncompressed_size;
3f5e193b 11975 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
11976
11977 rc = inflateInit (& strm);
11978 while (strm.avail_in > 0)
11979 {
11980 if (rc != Z_OK)
11981 goto fail;
11982 strm.next_out = ((Bytef *) uncompressed_buffer
11983 + (uncompressed_size - strm.avail_out));
11984 rc = inflate (&strm, Z_FINISH);
11985 if (rc != Z_STREAM_END)
11986 goto fail;
11987 rc = inflateReset (& strm);
11988 }
11989 rc = inflateEnd (& strm);
11990 if (rc != Z_OK
11991 || strm.avail_out != 0)
11992 goto fail;
11993
11994 free (compressed_buffer);
11995 *buffer = uncompressed_buffer;
11996 *size = uncompressed_size;
11997 return 1;
11998
11999 fail:
12000 free (uncompressed_buffer);
4a114e3e
L
12001 /* Indicate decompression failure. */
12002 *buffer = NULL;
cf13d699
NC
12003 return 0;
12004#endif /* HAVE_ZLIB_H */
12005}
12006
d966045b
DJ
12007static int
12008load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 12009 Elf_Internal_Shdr * sec, void * file)
1007acb3 12010{
2cf0635d 12011 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 12012 char buf [64];
1007acb3 12013
19e6b90e
L
12014 /* If it is already loaded, do nothing. */
12015 if (section->start != NULL)
12016 return 1;
1007acb3 12017
19e6b90e
L
12018 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
12019 section->address = sec->sh_addr;
06614111 12020 section->user_data = NULL;
3f5e193b
NC
12021 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
12022 sec->sh_offset, 1,
12023 sec->sh_size, buf);
59245841
NC
12024 if (section->start == NULL)
12025 section->size = 0;
12026 else
12027 {
12028 section->size = sec->sh_size;
12029 if (uncompress_section_contents (&section->start, &section->size))
12030 sec->sh_size = section->size;
12031 }
4a114e3e 12032
1b315056
CS
12033 if (section->start == NULL)
12034 return 0;
12035
19e6b90e 12036 if (debug_displays [debug].relocate)
3f5e193b 12037 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 12038
1b315056 12039 return 1;
1007acb3
L
12040}
12041
657d0d47
CC
12042/* If this is not NULL, load_debug_section will only look for sections
12043 within the list of sections given here. */
12044unsigned int *section_subset = NULL;
12045
d966045b 12046int
2cf0635d 12047load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 12048{
2cf0635d
NC
12049 struct dwarf_section * section = &debug_displays [debug].section;
12050 Elf_Internal_Shdr * sec;
d966045b
DJ
12051
12052 /* Locate the debug section. */
657d0d47 12053 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
12054 if (sec != NULL)
12055 section->name = section->uncompressed_name;
12056 else
12057 {
657d0d47 12058 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
12059 if (sec != NULL)
12060 section->name = section->compressed_name;
12061 }
12062 if (sec == NULL)
12063 return 0;
12064
657d0d47
CC
12065 /* If we're loading from a subset of sections, and we've loaded
12066 a section matching this name before, it's likely that it's a
12067 different one. */
12068 if (section_subset != NULL)
12069 free_debug_section (debug);
12070
3f5e193b 12071 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
12072}
12073
19e6b90e
L
12074void
12075free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 12076{
2cf0635d 12077 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 12078
19e6b90e
L
12079 if (section->start == NULL)
12080 return;
1007acb3 12081
19e6b90e
L
12082 free ((char *) section->start);
12083 section->start = NULL;
12084 section->address = 0;
12085 section->size = 0;
1007acb3
L
12086}
12087
1007acb3 12088static int
657d0d47 12089display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 12090{
2cf0635d 12091 char * name = SECTION_NAME (section);
74e1a04b 12092 const char * print_name = printable_section_name (section);
19e6b90e
L
12093 bfd_size_type length;
12094 int result = 1;
3f5e193b 12095 int i;
1007acb3 12096
19e6b90e
L
12097 length = section->sh_size;
12098 if (length == 0)
1007acb3 12099 {
74e1a04b 12100 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
19e6b90e 12101 return 0;
1007acb3 12102 }
5dff79d8
NC
12103 if (section->sh_type == SHT_NOBITS)
12104 {
12105 /* There is no point in dumping the contents of a debugging section
12106 which has the NOBITS type - the bits in the file will be random.
12107 This can happen when a file containing a .eh_frame section is
12108 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
12109 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
12110 print_name);
5dff79d8
NC
12111 return 0;
12112 }
1007acb3 12113
0112cd26 12114 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 12115 name = ".debug_info";
1007acb3 12116
19e6b90e
L
12117 /* See if we know how to display the contents of this section. */
12118 for (i = 0; i < max; i++)
1b315056 12119 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 12120 || (i == line && const_strneq (name, ".debug_line."))
1b315056 12121 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 12122 {
2cf0635d 12123 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
12124 int secondary = (section != find_section (name));
12125
12126 if (secondary)
3f5e193b 12127 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 12128
b40bf0a2
NC
12129 if (i == line && const_strneq (name, ".debug_line."))
12130 sec->name = name;
12131 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
12132 sec->name = sec->uncompressed_name;
12133 else
12134 sec->name = sec->compressed_name;
3f5e193b
NC
12135 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
12136 section, file))
19e6b90e 12137 {
657d0d47
CC
12138 /* If this debug section is part of a CU/TU set in a .dwp file,
12139 restrict load_debug_section to the sections in that set. */
12140 section_subset = find_cu_tu_set (file, shndx);
12141
19e6b90e 12142 result &= debug_displays[i].display (sec, file);
1007acb3 12143
657d0d47
CC
12144 section_subset = NULL;
12145
d966045b 12146 if (secondary || (i != info && i != abbrev))
3f5e193b 12147 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 12148 }
1007acb3 12149
19e6b90e
L
12150 break;
12151 }
1007acb3 12152
19e6b90e 12153 if (i == max)
1007acb3 12154 {
74e1a04b 12155 printf (_("Unrecognized debug section: %s\n"), print_name);
19e6b90e 12156 result = 0;
1007acb3
L
12157 }
12158
19e6b90e 12159 return result;
5b18a4bc 12160}
103f02d3 12161
aef1f6d0
DJ
12162/* Set DUMP_SECTS for all sections where dumps were requested
12163 based on section name. */
12164
12165static void
12166initialise_dumps_byname (void)
12167{
2cf0635d 12168 struct dump_list_entry * cur;
aef1f6d0
DJ
12169
12170 for (cur = dump_sects_byname; cur; cur = cur->next)
12171 {
12172 unsigned int i;
12173 int any;
12174
12175 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
12176 if (streq (SECTION_NAME (section_headers + i), cur->name))
12177 {
09c11c86 12178 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
12179 any = 1;
12180 }
12181
12182 if (!any)
12183 warn (_("Section '%s' was not dumped because it does not exist!\n"),
12184 cur->name);
12185 }
12186}
12187
5b18a4bc 12188static void
2cf0635d 12189process_section_contents (FILE * file)
5b18a4bc 12190{
2cf0635d 12191 Elf_Internal_Shdr * section;
19e6b90e 12192 unsigned int i;
103f02d3 12193
19e6b90e
L
12194 if (! do_dump)
12195 return;
103f02d3 12196
aef1f6d0
DJ
12197 initialise_dumps_byname ();
12198
19e6b90e
L
12199 for (i = 0, section = section_headers;
12200 i < elf_header.e_shnum && i < num_dump_sects;
12201 i++, section++)
12202 {
12203#ifdef SUPPORT_DISASSEMBLY
12204 if (dump_sects[i] & DISASS_DUMP)
12205 disassemble_section (section, file);
12206#endif
12207 if (dump_sects[i] & HEX_DUMP)
cf13d699 12208 dump_section_as_bytes (section, file, FALSE);
103f02d3 12209
cf13d699
NC
12210 if (dump_sects[i] & RELOC_DUMP)
12211 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
12212
12213 if (dump_sects[i] & STRING_DUMP)
12214 dump_section_as_strings (section, file);
cf13d699
NC
12215
12216 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 12217 display_debug_section (i, section, file);
5b18a4bc 12218 }
103f02d3 12219
19e6b90e
L
12220 /* Check to see if the user requested a
12221 dump of a section that does not exist. */
12222 while (i++ < num_dump_sects)
12223 if (dump_sects[i])
12224 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 12225}
103f02d3 12226
5b18a4bc 12227static void
19e6b90e 12228process_mips_fpe_exception (int mask)
5b18a4bc 12229{
19e6b90e
L
12230 if (mask)
12231 {
12232 int first = 1;
12233 if (mask & OEX_FPU_INEX)
12234 fputs ("INEX", stdout), first = 0;
12235 if (mask & OEX_FPU_UFLO)
12236 printf ("%sUFLO", first ? "" : "|"), first = 0;
12237 if (mask & OEX_FPU_OFLO)
12238 printf ("%sOFLO", first ? "" : "|"), first = 0;
12239 if (mask & OEX_FPU_DIV0)
12240 printf ("%sDIV0", first ? "" : "|"), first = 0;
12241 if (mask & OEX_FPU_INVAL)
12242 printf ("%sINVAL", first ? "" : "|");
12243 }
5b18a4bc 12244 else
19e6b90e 12245 fputs ("0", stdout);
5b18a4bc 12246}
103f02d3 12247
f6f0e17b
NC
12248/* Display's the value of TAG at location P. If TAG is
12249 greater than 0 it is assumed to be an unknown tag, and
12250 a message is printed to this effect. Otherwise it is
12251 assumed that a message has already been printed.
12252
12253 If the bottom bit of TAG is set it assumed to have a
12254 string value, otherwise it is assumed to have an integer
12255 value.
12256
12257 Returns an updated P pointing to the first unread byte
12258 beyond the end of TAG's value.
12259
12260 Reads at or beyond END will not be made. */
12261
12262static unsigned char *
12263display_tag_value (int tag,
12264 unsigned char * p,
12265 const unsigned char * const end)
12266{
12267 unsigned long val;
12268
12269 if (tag > 0)
12270 printf (" Tag_unknown_%d: ", tag);
12271
12272 if (p >= end)
12273 {
4082ef84 12274 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
12275 }
12276 else if (tag & 1)
12277 {
071436c6
NC
12278 /* PR 17531 file: 027-19978-0.004. */
12279 size_t maxlen = (end - p) - 1;
12280
12281 putchar ('"');
4082ef84
NC
12282 if (maxlen > 0)
12283 {
12284 print_symbol ((int) maxlen, (const char *) p);
12285 p += strnlen ((char *) p, maxlen) + 1;
12286 }
12287 else
12288 {
12289 printf (_("<corrupt string tag>"));
12290 p = (unsigned char *) end;
12291 }
071436c6 12292 printf ("\"\n");
f6f0e17b
NC
12293 }
12294 else
12295 {
12296 unsigned int len;
12297
12298 val = read_uleb128 (p, &len, end);
12299 p += len;
12300 printf ("%ld (0x%lx)\n", val, val);
12301 }
12302
4082ef84 12303 assert (p <= end);
f6f0e17b
NC
12304 return p;
12305}
12306
11c1ff18
PB
12307/* ARM EABI attributes section. */
12308typedef struct
12309{
70e99720 12310 unsigned int tag;
2cf0635d 12311 const char * name;
11c1ff18 12312 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 12313 unsigned int type;
2cf0635d 12314 const char ** table;
11c1ff18
PB
12315} arm_attr_public_tag;
12316
2cf0635d 12317static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 12318 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 12319 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
12320static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
12321static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 12322 {"No", "Thumb-1", "Thumb-2"};
75375b3e 12323static const char * arm_attr_tag_FP_arch[] =
bca38921 12324 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 12325 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 12326static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 12327static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 12328 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 12329static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
12330 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
12331 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 12332static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 12333 {"V6", "SB", "TLS", "Unused"};
2cf0635d 12334static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 12335 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 12336static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 12337 {"Absolute", "PC-relative", "None"};
2cf0635d 12338static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 12339 {"None", "direct", "GOT-indirect"};
2cf0635d 12340static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 12341 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
12342static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
12343static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 12344 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
12345static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
12346static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
12347static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 12348 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 12349static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 12350 {"Unused", "small", "int", "forced to int"};
2cf0635d 12351static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 12352 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 12353static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 12354 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 12355static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 12356 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 12357static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
12358 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12359 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 12360static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
12361 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12362 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 12363static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 12364static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 12365 {"Not Allowed", "Allowed"};
2cf0635d 12366static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 12367 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 12368static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
12369 {"Not Allowed", "Allowed"};
12370static const char * arm_attr_tag_DIV_use[] =
dd24e3da 12371 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 12372 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
12373static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
12374static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 12375 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 12376 "TrustZone and Virtualization Extensions"};
dd24e3da 12377static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 12378 {"Not Allowed", "Allowed"};
11c1ff18
PB
12379
12380#define LOOKUP(id, name) \
12381 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 12382static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
12383{
12384 {4, "CPU_raw_name", 1, NULL},
12385 {5, "CPU_name", 1, NULL},
12386 LOOKUP(6, CPU_arch),
12387 {7, "CPU_arch_profile", 0, NULL},
12388 LOOKUP(8, ARM_ISA_use),
12389 LOOKUP(9, THUMB_ISA_use),
75375b3e 12390 LOOKUP(10, FP_arch),
11c1ff18 12391 LOOKUP(11, WMMX_arch),
f5f53991
AS
12392 LOOKUP(12, Advanced_SIMD_arch),
12393 LOOKUP(13, PCS_config),
11c1ff18
PB
12394 LOOKUP(14, ABI_PCS_R9_use),
12395 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 12396 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
12397 LOOKUP(17, ABI_PCS_GOT_use),
12398 LOOKUP(18, ABI_PCS_wchar_t),
12399 LOOKUP(19, ABI_FP_rounding),
12400 LOOKUP(20, ABI_FP_denormal),
12401 LOOKUP(21, ABI_FP_exceptions),
12402 LOOKUP(22, ABI_FP_user_exceptions),
12403 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
12404 {24, "ABI_align_needed", 0, NULL},
12405 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
12406 LOOKUP(26, ABI_enum_size),
12407 LOOKUP(27, ABI_HardFP_use),
12408 LOOKUP(28, ABI_VFP_args),
12409 LOOKUP(29, ABI_WMMX_args),
12410 LOOKUP(30, ABI_optimization_goals),
12411 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 12412 {32, "compatibility", 0, NULL},
f5f53991 12413 LOOKUP(34, CPU_unaligned_access),
75375b3e 12414 LOOKUP(36, FP_HP_extension),
8e79c3df 12415 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
12416 LOOKUP(42, MPextension_use),
12417 LOOKUP(44, DIV_use),
f5f53991
AS
12418 {64, "nodefaults", 0, NULL},
12419 {65, "also_compatible_with", 0, NULL},
12420 LOOKUP(66, T2EE_use),
12421 {67, "conformance", 1, NULL},
12422 LOOKUP(68, Virtualization_use),
cd21e546 12423 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
12424};
12425#undef LOOKUP
12426
11c1ff18 12427static unsigned char *
f6f0e17b
NC
12428display_arm_attribute (unsigned char * p,
12429 const unsigned char * const end)
11c1ff18 12430{
70e99720 12431 unsigned int tag;
11c1ff18 12432 unsigned int len;
70e99720 12433 unsigned int val;
2cf0635d 12434 arm_attr_public_tag * attr;
11c1ff18 12435 unsigned i;
70e99720 12436 unsigned int type;
11c1ff18 12437
f6f0e17b 12438 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
12439 p += len;
12440 attr = NULL;
2cf0635d 12441 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
12442 {
12443 if (arm_attr_public_tags[i].tag == tag)
12444 {
12445 attr = &arm_attr_public_tags[i];
12446 break;
12447 }
12448 }
12449
12450 if (attr)
12451 {
12452 printf (" Tag_%s: ", attr->name);
12453 switch (attr->type)
12454 {
12455 case 0:
12456 switch (tag)
12457 {
12458 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 12459 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12460 p += len;
12461 switch (val)
12462 {
2b692964
NC
12463 case 0: printf (_("None\n")); break;
12464 case 'A': printf (_("Application\n")); break;
12465 case 'R': printf (_("Realtime\n")); break;
12466 case 'M': printf (_("Microcontroller\n")); break;
12467 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
12468 default: printf ("??? (%d)\n", val); break;
12469 }
12470 break;
12471
75375b3e 12472 case 24: /* Tag_align_needed. */
f6f0e17b 12473 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12474 p += len;
12475 switch (val)
12476 {
2b692964
NC
12477 case 0: printf (_("None\n")); break;
12478 case 1: printf (_("8-byte\n")); break;
12479 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
12480 case 3: printf ("??? 3\n"); break;
12481 default:
12482 if (val <= 12)
dd24e3da 12483 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12484 1 << val);
12485 else
12486 printf ("??? (%d)\n", val);
12487 break;
12488 }
12489 break;
12490
12491 case 25: /* Tag_align_preserved. */
f6f0e17b 12492 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12493 p += len;
12494 switch (val)
12495 {
2b692964
NC
12496 case 0: printf (_("None\n")); break;
12497 case 1: printf (_("8-byte, except leaf SP\n")); break;
12498 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
12499 case 3: printf ("??? 3\n"); break;
12500 default:
12501 if (val <= 12)
dd24e3da 12502 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12503 1 << val);
12504 else
12505 printf ("??? (%d)\n", val);
12506 break;
12507 }
12508 break;
12509
11c1ff18 12510 case 32: /* Tag_compatibility. */
071436c6 12511 {
071436c6
NC
12512 val = read_uleb128 (p, &len, end);
12513 p += len;
071436c6 12514 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12515 if (p < end - 1)
12516 {
12517 size_t maxlen = (end - p) - 1;
12518
12519 print_symbol ((int) maxlen, (const char *) p);
12520 p += strnlen ((char *) p, maxlen) + 1;
12521 }
12522 else
12523 {
12524 printf (_("<corrupt>"));
12525 p = (unsigned char *) end;
12526 }
071436c6 12527 putchar ('\n');
071436c6 12528 }
11c1ff18
PB
12529 break;
12530
f5f53991 12531 case 64: /* Tag_nodefaults. */
541a3cbd
NC
12532 /* PR 17531: file: 001-505008-0.01. */
12533 if (p < end)
12534 p++;
2b692964 12535 printf (_("True\n"));
f5f53991
AS
12536 break;
12537
12538 case 65: /* Tag_also_compatible_with. */
f6f0e17b 12539 val = read_uleb128 (p, &len, end);
f5f53991
AS
12540 p += len;
12541 if (val == 6 /* Tag_CPU_arch. */)
12542 {
f6f0e17b 12543 val = read_uleb128 (p, &len, end);
f5f53991 12544 p += len;
071436c6 12545 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
12546 printf ("??? (%d)\n", val);
12547 else
12548 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
12549 }
12550 else
12551 printf ("???\n");
071436c6
NC
12552 while (p < end && *(p++) != '\0' /* NUL terminator. */)
12553 ;
f5f53991
AS
12554 break;
12555
11c1ff18 12556 default:
bee0ee85
NC
12557 printf (_("<unknown: %d>\n"), tag);
12558 break;
11c1ff18
PB
12559 }
12560 return p;
12561
12562 case 1:
f6f0e17b 12563 return display_tag_value (-1, p, end);
11c1ff18 12564 case 2:
f6f0e17b 12565 return display_tag_value (0, p, end);
11c1ff18
PB
12566
12567 default:
12568 assert (attr->type & 0x80);
f6f0e17b 12569 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12570 p += len;
12571 type = attr->type & 0x7f;
12572 if (val >= type)
12573 printf ("??? (%d)\n", val);
12574 else
12575 printf ("%s\n", attr->table[val]);
12576 return p;
12577 }
12578 }
11c1ff18 12579
f6f0e17b 12580 return display_tag_value (tag, p, end);
11c1ff18
PB
12581}
12582
104d59d1 12583static unsigned char *
60bca95a 12584display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
12585 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
12586 const unsigned char * const end)
104d59d1
JM
12587{
12588 int tag;
12589 unsigned int len;
12590 int val;
104d59d1 12591
f6f0e17b 12592 tag = read_uleb128 (p, &len, end);
104d59d1
JM
12593 p += len;
12594
12595 /* Tag_compatibility is the only generic GNU attribute defined at
12596 present. */
12597 if (tag == 32)
12598 {
f6f0e17b 12599 val = read_uleb128 (p, &len, end);
104d59d1 12600 p += len;
071436c6
NC
12601
12602 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
12603 if (p == end)
12604 {
071436c6 12605 printf (_("<corrupt>\n"));
f6f0e17b
NC
12606 warn (_("corrupt vendor attribute\n"));
12607 }
12608 else
12609 {
4082ef84
NC
12610 if (p < end - 1)
12611 {
12612 size_t maxlen = (end - p) - 1;
071436c6 12613
4082ef84
NC
12614 print_symbol ((int) maxlen, (const char *) p);
12615 p += strnlen ((char *) p, maxlen) + 1;
12616 }
12617 else
12618 {
12619 printf (_("<corrupt>"));
12620 p = (unsigned char *) end;
12621 }
071436c6 12622 putchar ('\n');
f6f0e17b 12623 }
104d59d1
JM
12624 return p;
12625 }
12626
12627 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 12628 return display_proc_gnu_attribute (p, tag, end);
104d59d1 12629
f6f0e17b 12630 return display_tag_value (tag, p, end);
104d59d1
JM
12631}
12632
34c8bcba 12633static unsigned char *
f6f0e17b
NC
12634display_power_gnu_attribute (unsigned char * p,
12635 int tag,
12636 const unsigned char * const end)
34c8bcba 12637{
34c8bcba
JM
12638 unsigned int len;
12639 int val;
12640
12641 if (tag == Tag_GNU_Power_ABI_FP)
12642 {
f6f0e17b 12643 val = read_uleb128 (p, &len, end);
34c8bcba
JM
12644 p += len;
12645 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 12646
34c8bcba
JM
12647 switch (val)
12648 {
12649 case 0:
2b692964 12650 printf (_("Hard or soft float\n"));
34c8bcba
JM
12651 break;
12652 case 1:
2b692964 12653 printf (_("Hard float\n"));
34c8bcba
JM
12654 break;
12655 case 2:
2b692964 12656 printf (_("Soft float\n"));
34c8bcba 12657 break;
3c7b9897 12658 case 3:
2b692964 12659 printf (_("Single-precision hard float\n"));
3c7b9897 12660 break;
34c8bcba
JM
12661 default:
12662 printf ("??? (%d)\n", val);
12663 break;
12664 }
12665 return p;
12666 }
12667
c6e65352
DJ
12668 if (tag == Tag_GNU_Power_ABI_Vector)
12669 {
f6f0e17b 12670 val = read_uleb128 (p, &len, end);
c6e65352
DJ
12671 p += len;
12672 printf (" Tag_GNU_Power_ABI_Vector: ");
12673 switch (val)
12674 {
12675 case 0:
2b692964 12676 printf (_("Any\n"));
c6e65352
DJ
12677 break;
12678 case 1:
2b692964 12679 printf (_("Generic\n"));
c6e65352
DJ
12680 break;
12681 case 2:
12682 printf ("AltiVec\n");
12683 break;
12684 case 3:
12685 printf ("SPE\n");
12686 break;
12687 default:
12688 printf ("??? (%d)\n", val);
12689 break;
12690 }
12691 return p;
12692 }
12693
f82e0623
NF
12694 if (tag == Tag_GNU_Power_ABI_Struct_Return)
12695 {
f6f0e17b
NC
12696 if (p == end)
12697 {
071436c6 12698 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return\n"));
f6f0e17b
NC
12699 return p;
12700 }
0b4362b0 12701
f6f0e17b 12702 val = read_uleb128 (p, &len, end);
f82e0623
NF
12703 p += len;
12704 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
12705 switch (val)
12706 {
12707 case 0:
2b692964 12708 printf (_("Any\n"));
f82e0623
NF
12709 break;
12710 case 1:
12711 printf ("r3/r4\n");
12712 break;
12713 case 2:
2b692964 12714 printf (_("Memory\n"));
f82e0623
NF
12715 break;
12716 default:
12717 printf ("??? (%d)\n", val);
12718 break;
12719 }
12720 return p;
12721 }
12722
f6f0e17b 12723 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
12724}
12725
9e8c70f9
DM
12726static void
12727display_sparc_hwcaps (int mask)
12728{
12729 if (mask)
12730 {
12731 int first = 1;
071436c6 12732
9e8c70f9
DM
12733 if (mask & ELF_SPARC_HWCAP_MUL32)
12734 fputs ("mul32", stdout), first = 0;
12735 if (mask & ELF_SPARC_HWCAP_DIV32)
12736 printf ("%sdiv32", first ? "" : "|"), first = 0;
12737 if (mask & ELF_SPARC_HWCAP_FSMULD)
12738 printf ("%sfsmuld", first ? "" : "|"), first = 0;
12739 if (mask & ELF_SPARC_HWCAP_V8PLUS)
12740 printf ("%sv8plus", first ? "" : "|"), first = 0;
12741 if (mask & ELF_SPARC_HWCAP_POPC)
12742 printf ("%spopc", first ? "" : "|"), first = 0;
12743 if (mask & ELF_SPARC_HWCAP_VIS)
12744 printf ("%svis", first ? "" : "|"), first = 0;
12745 if (mask & ELF_SPARC_HWCAP_VIS2)
12746 printf ("%svis2", first ? "" : "|"), first = 0;
12747 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
12748 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
12749 if (mask & ELF_SPARC_HWCAP_FMAF)
12750 printf ("%sfmaf", first ? "" : "|"), first = 0;
12751 if (mask & ELF_SPARC_HWCAP_VIS3)
12752 printf ("%svis3", first ? "" : "|"), first = 0;
12753 if (mask & ELF_SPARC_HWCAP_HPC)
12754 printf ("%shpc", first ? "" : "|"), first = 0;
12755 if (mask & ELF_SPARC_HWCAP_RANDOM)
12756 printf ("%srandom", first ? "" : "|"), first = 0;
12757 if (mask & ELF_SPARC_HWCAP_TRANS)
12758 printf ("%strans", first ? "" : "|"), first = 0;
12759 if (mask & ELF_SPARC_HWCAP_FJFMAU)
12760 printf ("%sfjfmau", first ? "" : "|"), first = 0;
12761 if (mask & ELF_SPARC_HWCAP_IMA)
12762 printf ("%sima", first ? "" : "|"), first = 0;
12763 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
12764 printf ("%scspare", first ? "" : "|"), first = 0;
12765 }
12766 else
071436c6
NC
12767 fputc ('0', stdout);
12768 fputc ('\n', stdout);
9e8c70f9
DM
12769}
12770
3d68f91c
JM
12771static void
12772display_sparc_hwcaps2 (int mask)
12773{
12774 if (mask)
12775 {
12776 int first = 1;
071436c6 12777
3d68f91c
JM
12778 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
12779 fputs ("fjathplus", stdout), first = 0;
12780 if (mask & ELF_SPARC_HWCAP2_VIS3B)
12781 printf ("%svis3b", first ? "" : "|"), first = 0;
12782 if (mask & ELF_SPARC_HWCAP2_ADP)
12783 printf ("%sadp", first ? "" : "|"), first = 0;
12784 if (mask & ELF_SPARC_HWCAP2_SPARC5)
12785 printf ("%ssparc5", first ? "" : "|"), first = 0;
12786 if (mask & ELF_SPARC_HWCAP2_MWAIT)
12787 printf ("%smwait", first ? "" : "|"), first = 0;
12788 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
12789 printf ("%sxmpmul", first ? "" : "|"), first = 0;
12790 if (mask & ELF_SPARC_HWCAP2_XMONT)
12791 printf ("%sxmont2", first ? "" : "|"), first = 0;
12792 if (mask & ELF_SPARC_HWCAP2_NSEC)
12793 printf ("%snsec", first ? "" : "|"), first = 0;
12794 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
12795 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
12796 if (mask & ELF_SPARC_HWCAP2_FJDES)
12797 printf ("%sfjdes", first ? "" : "|"), first = 0;
12798 if (mask & ELF_SPARC_HWCAP2_FJAES)
12799 printf ("%sfjaes", first ? "" : "|"), first = 0;
12800 }
12801 else
071436c6
NC
12802 fputc ('0', stdout);
12803 fputc ('\n', stdout);
3d68f91c
JM
12804}
12805
9e8c70f9 12806static unsigned char *
f6f0e17b
NC
12807display_sparc_gnu_attribute (unsigned char * p,
12808 int tag,
12809 const unsigned char * const end)
9e8c70f9 12810{
3d68f91c
JM
12811 unsigned int len;
12812 int val;
12813
9e8c70f9
DM
12814 if (tag == Tag_GNU_Sparc_HWCAPS)
12815 {
f6f0e17b 12816 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
12817 p += len;
12818 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
12819 display_sparc_hwcaps (val);
12820 return p;
3d68f91c
JM
12821 }
12822 if (tag == Tag_GNU_Sparc_HWCAPS2)
12823 {
12824 val = read_uleb128 (p, &len, end);
12825 p += len;
12826 printf (" Tag_GNU_Sparc_HWCAPS2: ");
12827 display_sparc_hwcaps2 (val);
12828 return p;
12829 }
9e8c70f9 12830
f6f0e17b 12831 return display_tag_value (tag, p, end);
9e8c70f9
DM
12832}
12833
351cdf24
MF
12834static void
12835print_mips_fp_abi_value (int val)
12836{
12837 switch (val)
12838 {
12839 case Val_GNU_MIPS_ABI_FP_ANY:
12840 printf (_("Hard or soft float\n"));
12841 break;
12842 case Val_GNU_MIPS_ABI_FP_DOUBLE:
12843 printf (_("Hard float (double precision)\n"));
12844 break;
12845 case Val_GNU_MIPS_ABI_FP_SINGLE:
12846 printf (_("Hard float (single precision)\n"));
12847 break;
12848 case Val_GNU_MIPS_ABI_FP_SOFT:
12849 printf (_("Soft float\n"));
12850 break;
12851 case Val_GNU_MIPS_ABI_FP_OLD_64:
12852 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
12853 break;
12854 case Val_GNU_MIPS_ABI_FP_XX:
12855 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
12856 break;
12857 case Val_GNU_MIPS_ABI_FP_64:
12858 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
12859 break;
12860 case Val_GNU_MIPS_ABI_FP_64A:
12861 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
12862 break;
12863 default:
12864 printf ("??? (%d)\n", val);
12865 break;
12866 }
12867}
12868
2cf19d5c 12869static unsigned char *
f6f0e17b
NC
12870display_mips_gnu_attribute (unsigned char * p,
12871 int tag,
12872 const unsigned char * const end)
2cf19d5c 12873{
2cf19d5c
JM
12874 if (tag == Tag_GNU_MIPS_ABI_FP)
12875 {
f6f0e17b
NC
12876 unsigned int len;
12877 int val;
12878
12879 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
12880 p += len;
12881 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 12882
351cdf24
MF
12883 print_mips_fp_abi_value (val);
12884
2cf19d5c
JM
12885 return p;
12886 }
12887
a9f58168
CF
12888 if (tag == Tag_GNU_MIPS_ABI_MSA)
12889 {
12890 unsigned int len;
12891 int val;
12892
12893 val = read_uleb128 (p, &len, end);
12894 p += len;
12895 printf (" Tag_GNU_MIPS_ABI_MSA: ");
12896
12897 switch (val)
12898 {
12899 case Val_GNU_MIPS_ABI_MSA_ANY:
12900 printf (_("Any MSA or not\n"));
12901 break;
12902 case Val_GNU_MIPS_ABI_MSA_128:
12903 printf (_("128-bit MSA\n"));
12904 break;
12905 default:
12906 printf ("??? (%d)\n", val);
12907 break;
12908 }
12909 return p;
12910 }
12911
f6f0e17b 12912 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
12913}
12914
59e6276b 12915static unsigned char *
f6f0e17b
NC
12916display_tic6x_attribute (unsigned char * p,
12917 const unsigned char * const end)
59e6276b
JM
12918{
12919 int tag;
12920 unsigned int len;
12921 int val;
12922
f6f0e17b 12923 tag = read_uleb128 (p, &len, end);
59e6276b
JM
12924 p += len;
12925
12926 switch (tag)
12927 {
75fa6dc1 12928 case Tag_ISA:
f6f0e17b 12929 val = read_uleb128 (p, &len, end);
59e6276b 12930 p += len;
75fa6dc1 12931 printf (" Tag_ISA: ");
59e6276b
JM
12932
12933 switch (val)
12934 {
75fa6dc1 12935 case C6XABI_Tag_ISA_none:
59e6276b
JM
12936 printf (_("None\n"));
12937 break;
75fa6dc1 12938 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
12939 printf ("C62x\n");
12940 break;
75fa6dc1 12941 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
12942 printf ("C67x\n");
12943 break;
75fa6dc1 12944 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
12945 printf ("C67x+\n");
12946 break;
75fa6dc1 12947 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
12948 printf ("C64x\n");
12949 break;
75fa6dc1 12950 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
12951 printf ("C64x+\n");
12952 break;
75fa6dc1 12953 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
12954 printf ("C674x\n");
12955 break;
12956 default:
12957 printf ("??? (%d)\n", val);
12958 break;
12959 }
12960 return p;
12961
87779176 12962 case Tag_ABI_wchar_t:
f6f0e17b 12963 val = read_uleb128 (p, &len, end);
87779176
JM
12964 p += len;
12965 printf (" Tag_ABI_wchar_t: ");
12966 switch (val)
12967 {
12968 case 0:
12969 printf (_("Not used\n"));
12970 break;
12971 case 1:
12972 printf (_("2 bytes\n"));
12973 break;
12974 case 2:
12975 printf (_("4 bytes\n"));
12976 break;
12977 default:
12978 printf ("??? (%d)\n", val);
12979 break;
12980 }
12981 return p;
12982
12983 case Tag_ABI_stack_align_needed:
f6f0e17b 12984 val = read_uleb128 (p, &len, end);
87779176
JM
12985 p += len;
12986 printf (" Tag_ABI_stack_align_needed: ");
12987 switch (val)
12988 {
12989 case 0:
12990 printf (_("8-byte\n"));
12991 break;
12992 case 1:
12993 printf (_("16-byte\n"));
12994 break;
12995 default:
12996 printf ("??? (%d)\n", val);
12997 break;
12998 }
12999 return p;
13000
13001 case Tag_ABI_stack_align_preserved:
f6f0e17b 13002 val = read_uleb128 (p, &len, end);
87779176
JM
13003 p += len;
13004 printf (" Tag_ABI_stack_align_preserved: ");
13005 switch (val)
13006 {
13007 case 0:
13008 printf (_("8-byte\n"));
13009 break;
13010 case 1:
13011 printf (_("16-byte\n"));
13012 break;
13013 default:
13014 printf ("??? (%d)\n", val);
13015 break;
13016 }
13017 return p;
13018
b5593623 13019 case Tag_ABI_DSBT:
f6f0e17b 13020 val = read_uleb128 (p, &len, end);
b5593623
JM
13021 p += len;
13022 printf (" Tag_ABI_DSBT: ");
13023 switch (val)
13024 {
13025 case 0:
13026 printf (_("DSBT addressing not used\n"));
13027 break;
13028 case 1:
13029 printf (_("DSBT addressing used\n"));
13030 break;
13031 default:
13032 printf ("??? (%d)\n", val);
13033 break;
13034 }
13035 return p;
13036
87779176 13037 case Tag_ABI_PID:
f6f0e17b 13038 val = read_uleb128 (p, &len, end);
87779176
JM
13039 p += len;
13040 printf (" Tag_ABI_PID: ");
13041 switch (val)
13042 {
13043 case 0:
13044 printf (_("Data addressing position-dependent\n"));
13045 break;
13046 case 1:
13047 printf (_("Data addressing position-independent, GOT near DP\n"));
13048 break;
13049 case 2:
13050 printf (_("Data addressing position-independent, GOT far from DP\n"));
13051 break;
13052 default:
13053 printf ("??? (%d)\n", val);
13054 break;
13055 }
13056 return p;
13057
13058 case Tag_ABI_PIC:
f6f0e17b 13059 val = read_uleb128 (p, &len, end);
87779176
JM
13060 p += len;
13061 printf (" Tag_ABI_PIC: ");
13062 switch (val)
13063 {
13064 case 0:
13065 printf (_("Code addressing position-dependent\n"));
13066 break;
13067 case 1:
13068 printf (_("Code addressing position-independent\n"));
13069 break;
13070 default:
13071 printf ("??? (%d)\n", val);
13072 break;
13073 }
13074 return p;
13075
13076 case Tag_ABI_array_object_alignment:
f6f0e17b 13077 val = read_uleb128 (p, &len, end);
87779176
JM
13078 p += len;
13079 printf (" Tag_ABI_array_object_alignment: ");
13080 switch (val)
13081 {
13082 case 0:
13083 printf (_("8-byte\n"));
13084 break;
13085 case 1:
13086 printf (_("4-byte\n"));
13087 break;
13088 case 2:
13089 printf (_("16-byte\n"));
13090 break;
13091 default:
13092 printf ("??? (%d)\n", val);
13093 break;
13094 }
13095 return p;
13096
13097 case Tag_ABI_array_object_align_expected:
f6f0e17b 13098 val = read_uleb128 (p, &len, end);
87779176
JM
13099 p += len;
13100 printf (" Tag_ABI_array_object_align_expected: ");
13101 switch (val)
13102 {
13103 case 0:
13104 printf (_("8-byte\n"));
13105 break;
13106 case 1:
13107 printf (_("4-byte\n"));
13108 break;
13109 case 2:
13110 printf (_("16-byte\n"));
13111 break;
13112 default:
13113 printf ("??? (%d)\n", val);
13114 break;
13115 }
13116 return p;
13117
3cbd1c06 13118 case Tag_ABI_compatibility:
071436c6 13119 {
071436c6
NC
13120 val = read_uleb128 (p, &len, end);
13121 p += len;
13122 printf (" Tag_ABI_compatibility: ");
071436c6 13123 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
13124 if (p < end - 1)
13125 {
13126 size_t maxlen = (end - p) - 1;
13127
13128 print_symbol ((int) maxlen, (const char *) p);
13129 p += strnlen ((char *) p, maxlen) + 1;
13130 }
13131 else
13132 {
13133 printf (_("<corrupt>"));
13134 p = (unsigned char *) end;
13135 }
071436c6 13136 putchar ('\n');
071436c6
NC
13137 return p;
13138 }
87779176
JM
13139
13140 case Tag_ABI_conformance:
071436c6 13141 {
4082ef84
NC
13142 printf (" Tag_ABI_conformance: \"");
13143 if (p < end - 1)
13144 {
13145 size_t maxlen = (end - p) - 1;
071436c6 13146
4082ef84
NC
13147 print_symbol ((int) maxlen, (const char *) p);
13148 p += strnlen ((char *) p, maxlen) + 1;
13149 }
13150 else
13151 {
13152 printf (_("<corrupt>"));
13153 p = (unsigned char *) end;
13154 }
071436c6 13155 printf ("\"\n");
071436c6
NC
13156 return p;
13157 }
59e6276b
JM
13158 }
13159
f6f0e17b
NC
13160 return display_tag_value (tag, p, end);
13161}
59e6276b 13162
f6f0e17b
NC
13163static void
13164display_raw_attribute (unsigned char * p, unsigned char * end)
13165{
13166 unsigned long addr = 0;
13167 size_t bytes = end - p;
13168
e0a31db1 13169 assert (end > p);
f6f0e17b 13170 while (bytes)
87779176 13171 {
f6f0e17b
NC
13172 int j;
13173 int k;
13174 int lbytes = (bytes > 16 ? 16 : bytes);
13175
13176 printf (" 0x%8.8lx ", addr);
13177
13178 for (j = 0; j < 16; j++)
13179 {
13180 if (j < lbytes)
13181 printf ("%2.2x", p[j]);
13182 else
13183 printf (" ");
13184
13185 if ((j & 3) == 3)
13186 printf (" ");
13187 }
13188
13189 for (j = 0; j < lbytes; j++)
13190 {
13191 k = p[j];
13192 if (k >= ' ' && k < 0x7f)
13193 printf ("%c", k);
13194 else
13195 printf (".");
13196 }
13197
13198 putchar ('\n');
13199
13200 p += lbytes;
13201 bytes -= lbytes;
13202 addr += lbytes;
87779176 13203 }
59e6276b 13204
f6f0e17b 13205 putchar ('\n');
59e6276b
JM
13206}
13207
13761a11
NC
13208static unsigned char *
13209display_msp430x_attribute (unsigned char * p,
13210 const unsigned char * const end)
13211{
13212 unsigned int len;
13213 int val;
13214 int tag;
13215
13216 tag = read_uleb128 (p, & len, end);
13217 p += len;
0b4362b0 13218
13761a11
NC
13219 switch (tag)
13220 {
13221 case OFBA_MSPABI_Tag_ISA:
13222 val = read_uleb128 (p, &len, end);
13223 p += len;
13224 printf (" Tag_ISA: ");
13225 switch (val)
13226 {
13227 case 0: printf (_("None\n")); break;
13228 case 1: printf (_("MSP430\n")); break;
13229 case 2: printf (_("MSP430X\n")); break;
13230 default: printf ("??? (%d)\n", val); break;
13231 }
13232 break;
13233
13234 case OFBA_MSPABI_Tag_Code_Model:
13235 val = read_uleb128 (p, &len, end);
13236 p += len;
13237 printf (" Tag_Code_Model: ");
13238 switch (val)
13239 {
13240 case 0: printf (_("None\n")); break;
13241 case 1: printf (_("Small\n")); break;
13242 case 2: printf (_("Large\n")); break;
13243 default: printf ("??? (%d)\n", val); break;
13244 }
13245 break;
13246
13247 case OFBA_MSPABI_Tag_Data_Model:
13248 val = read_uleb128 (p, &len, end);
13249 p += len;
13250 printf (" Tag_Data_Model: ");
13251 switch (val)
13252 {
13253 case 0: printf (_("None\n")); break;
13254 case 1: printf (_("Small\n")); break;
13255 case 2: printf (_("Large\n")); break;
13256 case 3: printf (_("Restricted Large\n")); break;
13257 default: printf ("??? (%d)\n", val); break;
13258 }
13259 break;
13260
13261 default:
13262 printf (_(" <unknown tag %d>: "), tag);
13263
13264 if (tag & 1)
13265 {
071436c6 13266 putchar ('"');
4082ef84
NC
13267 if (p < end - 1)
13268 {
13269 size_t maxlen = (end - p) - 1;
13270
13271 print_symbol ((int) maxlen, (const char *) p);
13272 p += strnlen ((char *) p, maxlen) + 1;
13273 }
13274 else
13275 {
13276 printf (_("<corrupt>"));
13277 p = (unsigned char *) end;
13278 }
071436c6 13279 printf ("\"\n");
13761a11
NC
13280 }
13281 else
13282 {
13283 val = read_uleb128 (p, &len, end);
13284 p += len;
13285 printf ("%d (0x%x)\n", val, val);
13286 }
13287 break;
13288 }
13289
4082ef84 13290 assert (p <= end);
13761a11
NC
13291 return p;
13292}
13293
11c1ff18 13294static int
60bca95a
NC
13295process_attributes (FILE * file,
13296 const char * public_name,
104d59d1 13297 unsigned int proc_type,
f6f0e17b
NC
13298 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
13299 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 13300{
2cf0635d 13301 Elf_Internal_Shdr * sect;
11c1ff18
PB
13302 unsigned i;
13303
13304 /* Find the section header so that we get the size. */
13305 for (i = 0, sect = section_headers;
13306 i < elf_header.e_shnum;
13307 i++, sect++)
13308 {
071436c6
NC
13309 unsigned char * contents;
13310 unsigned char * p;
13311
104d59d1 13312 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
13313 continue;
13314
3f5e193b
NC
13315 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
13316 sect->sh_size, _("attributes"));
60bca95a 13317 if (contents == NULL)
11c1ff18 13318 continue;
60bca95a 13319
11c1ff18
PB
13320 p = contents;
13321 if (*p == 'A')
13322 {
071436c6
NC
13323 bfd_vma section_len;
13324
13325 section_len = sect->sh_size - 1;
11c1ff18 13326 p++;
60bca95a 13327
071436c6 13328 while (section_len > 0)
11c1ff18 13329 {
071436c6 13330 bfd_vma attr_len;
e9847026 13331 unsigned int namelen;
11c1ff18 13332 bfd_boolean public_section;
104d59d1 13333 bfd_boolean gnu_section;
11c1ff18 13334
071436c6 13335 if (section_len <= 4)
e0a31db1
NC
13336 {
13337 error (_("Tag section ends prematurely\n"));
13338 break;
13339 }
071436c6 13340 attr_len = byte_get (p, 4);
11c1ff18 13341 p += 4;
60bca95a 13342
071436c6 13343 if (attr_len > section_len)
11c1ff18 13344 {
071436c6
NC
13345 error (_("Bad attribute length (%u > %u)\n"),
13346 (unsigned) attr_len, (unsigned) section_len);
13347 attr_len = section_len;
11c1ff18 13348 }
74e1a04b 13349 /* PR 17531: file: 001-101425-0.004 */
071436c6 13350 else if (attr_len < 5)
74e1a04b 13351 {
071436c6 13352 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
74e1a04b
NC
13353 break;
13354 }
e9847026 13355
071436c6
NC
13356 section_len -= attr_len;
13357 attr_len -= 4;
13358
13359 namelen = strnlen ((char *) p, attr_len) + 1;
13360 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
13361 {
13362 error (_("Corrupt attribute section name\n"));
13363 break;
13364 }
13365
071436c6
NC
13366 printf (_("Attribute Section: "));
13367 print_symbol (INT_MAX, (const char *) p);
13368 putchar ('\n');
60bca95a
NC
13369
13370 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
13371 public_section = TRUE;
13372 else
13373 public_section = FALSE;
60bca95a
NC
13374
13375 if (streq ((char *) p, "gnu"))
104d59d1
JM
13376 gnu_section = TRUE;
13377 else
13378 gnu_section = FALSE;
60bca95a 13379
11c1ff18 13380 p += namelen;
071436c6 13381 attr_len -= namelen;
e0a31db1 13382
071436c6 13383 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 13384 {
e0a31db1 13385 int tag;
11c1ff18
PB
13386 int val;
13387 bfd_vma size;
071436c6 13388 unsigned char * end;
60bca95a 13389
e0a31db1 13390 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 13391 if (attr_len < 6)
e0a31db1
NC
13392 {
13393 error (_("Unused bytes at end of section\n"));
13394 section_len = 0;
13395 break;
13396 }
13397
13398 tag = *(p++);
11c1ff18 13399 size = byte_get (p, 4);
071436c6 13400 if (size > attr_len)
11c1ff18 13401 {
e9847026 13402 error (_("Bad subsection length (%u > %u)\n"),
071436c6
NC
13403 (unsigned) size, (unsigned) attr_len);
13404 size = attr_len;
11c1ff18 13405 }
e0a31db1
NC
13406 /* PR binutils/17531: Safe handling of corrupt files. */
13407 if (size < 6)
13408 {
13409 error (_("Bad subsection length (%u < 6)\n"),
13410 (unsigned) size);
13411 section_len = 0;
13412 break;
13413 }
60bca95a 13414
071436c6 13415 attr_len -= size;
11c1ff18 13416 end = p + size - 1;
071436c6 13417 assert (end <= contents + sect->sh_size);
11c1ff18 13418 p += 4;
60bca95a 13419
11c1ff18
PB
13420 switch (tag)
13421 {
13422 case 1:
2b692964 13423 printf (_("File Attributes\n"));
11c1ff18
PB
13424 break;
13425 case 2:
2b692964 13426 printf (_("Section Attributes:"));
11c1ff18
PB
13427 goto do_numlist;
13428 case 3:
2b692964 13429 printf (_("Symbol Attributes:"));
11c1ff18
PB
13430 do_numlist:
13431 for (;;)
13432 {
91d6fa6a 13433 unsigned int j;
60bca95a 13434
f6f0e17b 13435 val = read_uleb128 (p, &j, end);
91d6fa6a 13436 p += j;
11c1ff18
PB
13437 if (val == 0)
13438 break;
13439 printf (" %d", val);
13440 }
13441 printf ("\n");
13442 break;
13443 default:
2b692964 13444 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
13445 public_section = FALSE;
13446 break;
13447 }
60bca95a 13448
071436c6 13449 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
13450 {
13451 while (p < end)
f6f0e17b 13452 p = display_pub_attribute (p, end);
071436c6 13453 assert (p <= end);
104d59d1 13454 }
071436c6 13455 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
13456 {
13457 while (p < end)
13458 p = display_gnu_attribute (p,
f6f0e17b
NC
13459 display_proc_gnu_attribute,
13460 end);
071436c6 13461 assert (p <= end);
11c1ff18 13462 }
071436c6 13463 else if (p < end)
11c1ff18 13464 {
071436c6 13465 printf (_(" Unknown attribute:\n"));
f6f0e17b 13466 display_raw_attribute (p, end);
11c1ff18
PB
13467 p = end;
13468 }
071436c6
NC
13469 else
13470 attr_len = 0;
11c1ff18
PB
13471 }
13472 }
13473 }
13474 else
e9847026 13475 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 13476
60bca95a 13477 free (contents);
11c1ff18
PB
13478 }
13479 return 1;
13480}
13481
104d59d1 13482static int
2cf0635d 13483process_arm_specific (FILE * file)
104d59d1
JM
13484{
13485 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
13486 display_arm_attribute, NULL);
13487}
13488
34c8bcba 13489static int
2cf0635d 13490process_power_specific (FILE * file)
34c8bcba
JM
13491{
13492 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13493 display_power_gnu_attribute);
13494}
13495
9e8c70f9
DM
13496static int
13497process_sparc_specific (FILE * file)
13498{
13499 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13500 display_sparc_gnu_attribute);
13501}
13502
59e6276b
JM
13503static int
13504process_tic6x_specific (FILE * file)
13505{
13506 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
13507 display_tic6x_attribute, NULL);
13508}
13509
13761a11
NC
13510static int
13511process_msp430x_specific (FILE * file)
13512{
13513 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
13514 display_msp430x_attribute, NULL);
13515}
13516
ccb4c951
RS
13517/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
13518 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
13519 and return the VMA of the next entry, or -1 if there was a problem.
13520 Does not read from DATA_END or beyond. */
ccb4c951
RS
13521
13522static bfd_vma
82b1b41b
NC
13523print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
13524 unsigned char * data_end)
ccb4c951
RS
13525{
13526 printf (" ");
13527 print_vma (addr, LONG_HEX);
13528 printf (" ");
13529 if (addr < pltgot + 0xfff0)
13530 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
13531 else
13532 printf ("%10s", "");
13533 printf (" ");
13534 if (data == NULL)
2b692964 13535 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
13536 else
13537 {
13538 bfd_vma entry;
82b1b41b 13539 unsigned char * from = data + addr - pltgot;
ccb4c951 13540
82b1b41b
NC
13541 if (from + (is_32bit_elf ? 4 : 8) > data_end)
13542 {
13543 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
13544 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
13545 return (bfd_vma) -1;
13546 }
13547 else
13548 {
13549 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13550 print_vma (entry, LONG_HEX);
13551 }
ccb4c951
RS
13552 }
13553 return addr + (is_32bit_elf ? 4 : 8);
13554}
13555
861fb55a
DJ
13556/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
13557 PLTGOT. Print the Address and Initial fields of an entry at VMA
13558 ADDR and return the VMA of the next entry. */
13559
13560static bfd_vma
2cf0635d 13561print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
13562{
13563 printf (" ");
13564 print_vma (addr, LONG_HEX);
13565 printf (" ");
13566 if (data == NULL)
2b692964 13567 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
13568 else
13569 {
13570 bfd_vma entry;
13571
13572 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13573 print_vma (entry, LONG_HEX);
13574 }
13575 return addr + (is_32bit_elf ? 4 : 8);
13576}
13577
351cdf24
MF
13578static void
13579print_mips_ases (unsigned int mask)
13580{
13581 if (mask & AFL_ASE_DSP)
13582 fputs ("\n\tDSP ASE", stdout);
13583 if (mask & AFL_ASE_DSPR2)
13584 fputs ("\n\tDSP R2 ASE", stdout);
13585 if (mask & AFL_ASE_EVA)
13586 fputs ("\n\tEnhanced VA Scheme", stdout);
13587 if (mask & AFL_ASE_MCU)
13588 fputs ("\n\tMCU (MicroController) ASE", stdout);
13589 if (mask & AFL_ASE_MDMX)
13590 fputs ("\n\tMDMX ASE", stdout);
13591 if (mask & AFL_ASE_MIPS3D)
13592 fputs ("\n\tMIPS-3D ASE", stdout);
13593 if (mask & AFL_ASE_MT)
13594 fputs ("\n\tMT ASE", stdout);
13595 if (mask & AFL_ASE_SMARTMIPS)
13596 fputs ("\n\tSmartMIPS ASE", stdout);
13597 if (mask & AFL_ASE_VIRT)
13598 fputs ("\n\tVZ ASE", stdout);
13599 if (mask & AFL_ASE_MSA)
13600 fputs ("\n\tMSA ASE", stdout);
13601 if (mask & AFL_ASE_MIPS16)
13602 fputs ("\n\tMIPS16 ASE", stdout);
13603 if (mask & AFL_ASE_MICROMIPS)
13604 fputs ("\n\tMICROMIPS ASE", stdout);
13605 if (mask & AFL_ASE_XPA)
13606 fputs ("\n\tXPA ASE", stdout);
13607 if (mask == 0)
13608 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
13609 else if ((mask & ~AFL_ASE_MASK) != 0)
13610 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
13611}
13612
13613static void
13614print_mips_isa_ext (unsigned int isa_ext)
13615{
13616 switch (isa_ext)
13617 {
13618 case 0:
13619 fputs (_("None"), stdout);
13620 break;
13621 case AFL_EXT_XLR:
13622 fputs ("RMI XLR", stdout);
13623 break;
2c629856
N
13624 case AFL_EXT_OCTEON3:
13625 fputs ("Cavium Networks Octeon3", stdout);
13626 break;
351cdf24
MF
13627 case AFL_EXT_OCTEON2:
13628 fputs ("Cavium Networks Octeon2", stdout);
13629 break;
13630 case AFL_EXT_OCTEONP:
13631 fputs ("Cavium Networks OcteonP", stdout);
13632 break;
13633 case AFL_EXT_LOONGSON_3A:
13634 fputs ("Loongson 3A", stdout);
13635 break;
13636 case AFL_EXT_OCTEON:
13637 fputs ("Cavium Networks Octeon", stdout);
13638 break;
13639 case AFL_EXT_5900:
13640 fputs ("Toshiba R5900", stdout);
13641 break;
13642 case AFL_EXT_4650:
13643 fputs ("MIPS R4650", stdout);
13644 break;
13645 case AFL_EXT_4010:
13646 fputs ("LSI R4010", stdout);
13647 break;
13648 case AFL_EXT_4100:
13649 fputs ("NEC VR4100", stdout);
13650 break;
13651 case AFL_EXT_3900:
13652 fputs ("Toshiba R3900", stdout);
13653 break;
13654 case AFL_EXT_10000:
13655 fputs ("MIPS R10000", stdout);
13656 break;
13657 case AFL_EXT_SB1:
13658 fputs ("Broadcom SB-1", stdout);
13659 break;
13660 case AFL_EXT_4111:
13661 fputs ("NEC VR4111/VR4181", stdout);
13662 break;
13663 case AFL_EXT_4120:
13664 fputs ("NEC VR4120", stdout);
13665 break;
13666 case AFL_EXT_5400:
13667 fputs ("NEC VR5400", stdout);
13668 break;
13669 case AFL_EXT_5500:
13670 fputs ("NEC VR5500", stdout);
13671 break;
13672 case AFL_EXT_LOONGSON_2E:
13673 fputs ("ST Microelectronics Loongson 2E", stdout);
13674 break;
13675 case AFL_EXT_LOONGSON_2F:
13676 fputs ("ST Microelectronics Loongson 2F", stdout);
13677 break;
13678 default:
00ac7aa0 13679 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
13680 }
13681}
13682
13683static int
13684get_mips_reg_size (int reg_size)
13685{
13686 return (reg_size == AFL_REG_NONE) ? 0
13687 : (reg_size == AFL_REG_32) ? 32
13688 : (reg_size == AFL_REG_64) ? 64
13689 : (reg_size == AFL_REG_128) ? 128
13690 : -1;
13691}
13692
19e6b90e 13693static int
2cf0635d 13694process_mips_specific (FILE * file)
5b18a4bc 13695{
2cf0635d 13696 Elf_Internal_Dyn * entry;
351cdf24 13697 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
13698 size_t liblist_offset = 0;
13699 size_t liblistno = 0;
13700 size_t conflictsno = 0;
13701 size_t options_offset = 0;
13702 size_t conflicts_offset = 0;
861fb55a
DJ
13703 size_t pltrelsz = 0;
13704 size_t pltrel = 0;
ccb4c951 13705 bfd_vma pltgot = 0;
861fb55a
DJ
13706 bfd_vma mips_pltgot = 0;
13707 bfd_vma jmprel = 0;
ccb4c951
RS
13708 bfd_vma local_gotno = 0;
13709 bfd_vma gotsym = 0;
13710 bfd_vma symtabno = 0;
103f02d3 13711
2cf19d5c
JM
13712 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13713 display_mips_gnu_attribute);
13714
351cdf24
MF
13715 sect = find_section (".MIPS.abiflags");
13716
13717 if (sect != NULL)
13718 {
13719 Elf_External_ABIFlags_v0 *abiflags_ext;
13720 Elf_Internal_ABIFlags_v0 abiflags_in;
13721
13722 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
13723 fputs ("\nCorrupt ABI Flags section.\n", stdout);
13724 else
13725 {
13726 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
13727 sect->sh_size, _("MIPS ABI Flags section"));
13728 if (abiflags_ext)
13729 {
13730 abiflags_in.version = BYTE_GET (abiflags_ext->version);
13731 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
13732 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
13733 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
13734 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
13735 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
13736 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
13737 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
13738 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
13739 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
13740 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
13741
13742 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
13743 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
13744 if (abiflags_in.isa_rev > 1)
13745 printf ("r%d", abiflags_in.isa_rev);
13746 printf ("\nGPR size: %d",
13747 get_mips_reg_size (abiflags_in.gpr_size));
13748 printf ("\nCPR1 size: %d",
13749 get_mips_reg_size (abiflags_in.cpr1_size));
13750 printf ("\nCPR2 size: %d",
13751 get_mips_reg_size (abiflags_in.cpr2_size));
13752 fputs ("\nFP ABI: ", stdout);
13753 print_mips_fp_abi_value (abiflags_in.fp_abi);
13754 fputs ("ISA Extension: ", stdout);
13755 print_mips_isa_ext (abiflags_in.isa_ext);
13756 fputs ("\nASEs:", stdout);
13757 print_mips_ases (abiflags_in.ases);
13758 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
13759 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
13760 fputc ('\n', stdout);
13761 free (abiflags_ext);
13762 }
13763 }
13764 }
13765
19e6b90e
L
13766 /* We have a lot of special sections. Thanks SGI! */
13767 if (dynamic_section == NULL)
13768 /* No information available. */
13769 return 0;
252b5132 13770
071436c6
NC
13771 for (entry = dynamic_section;
13772 /* PR 17531 file: 012-50589-0.004. */
13773 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
13774 ++entry)
252b5132
RH
13775 switch (entry->d_tag)
13776 {
13777 case DT_MIPS_LIBLIST:
d93f0186
NC
13778 liblist_offset
13779 = offset_from_vma (file, entry->d_un.d_val,
13780 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
13781 break;
13782 case DT_MIPS_LIBLISTNO:
13783 liblistno = entry->d_un.d_val;
13784 break;
13785 case DT_MIPS_OPTIONS:
d93f0186 13786 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
13787 break;
13788 case DT_MIPS_CONFLICT:
d93f0186
NC
13789 conflicts_offset
13790 = offset_from_vma (file, entry->d_un.d_val,
13791 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
13792 break;
13793 case DT_MIPS_CONFLICTNO:
13794 conflictsno = entry->d_un.d_val;
13795 break;
ccb4c951 13796 case DT_PLTGOT:
861fb55a
DJ
13797 pltgot = entry->d_un.d_ptr;
13798 break;
ccb4c951
RS
13799 case DT_MIPS_LOCAL_GOTNO:
13800 local_gotno = entry->d_un.d_val;
13801 break;
13802 case DT_MIPS_GOTSYM:
13803 gotsym = entry->d_un.d_val;
13804 break;
13805 case DT_MIPS_SYMTABNO:
13806 symtabno = entry->d_un.d_val;
13807 break;
861fb55a
DJ
13808 case DT_MIPS_PLTGOT:
13809 mips_pltgot = entry->d_un.d_ptr;
13810 break;
13811 case DT_PLTREL:
13812 pltrel = entry->d_un.d_val;
13813 break;
13814 case DT_PLTRELSZ:
13815 pltrelsz = entry->d_un.d_val;
13816 break;
13817 case DT_JMPREL:
13818 jmprel = entry->d_un.d_ptr;
13819 break;
252b5132
RH
13820 default:
13821 break;
13822 }
13823
13824 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
13825 {
2cf0635d 13826 Elf32_External_Lib * elib;
252b5132
RH
13827 size_t cnt;
13828
3f5e193b
NC
13829 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
13830 liblistno,
13831 sizeof (Elf32_External_Lib),
9cf03b7e 13832 _("liblist section data"));
a6e9f9df 13833 if (elib)
252b5132 13834 {
2b692964 13835 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 13836 (unsigned long) liblistno);
2b692964 13837 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
13838 stdout);
13839
13840 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 13841 {
a6e9f9df 13842 Elf32_Lib liblist;
91d6fa6a 13843 time_t atime;
a6e9f9df 13844 char timebuf[20];
2cf0635d 13845 struct tm * tmp;
a6e9f9df
AM
13846
13847 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13848 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
13849 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13850 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13851 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13852
91d6fa6a 13853 tmp = gmtime (&atime);
e9e44622
JJ
13854 snprintf (timebuf, sizeof (timebuf),
13855 "%04u-%02u-%02uT%02u:%02u:%02u",
13856 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13857 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 13858
31104126 13859 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
13860 if (VALID_DYNAMIC_NAME (liblist.l_name))
13861 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
13862 else
2b692964 13863 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
13864 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
13865 liblist.l_version);
a6e9f9df
AM
13866
13867 if (liblist.l_flags == 0)
2b692964 13868 puts (_(" NONE"));
a6e9f9df
AM
13869 else
13870 {
13871 static const struct
252b5132 13872 {
2cf0635d 13873 const char * name;
a6e9f9df 13874 int bit;
252b5132 13875 }
a6e9f9df
AM
13876 l_flags_vals[] =
13877 {
13878 { " EXACT_MATCH", LL_EXACT_MATCH },
13879 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
13880 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
13881 { " EXPORTS", LL_EXPORTS },
13882 { " DELAY_LOAD", LL_DELAY_LOAD },
13883 { " DELTA", LL_DELTA }
13884 };
13885 int flags = liblist.l_flags;
13886 size_t fcnt;
13887
60bca95a 13888 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
13889 if ((flags & l_flags_vals[fcnt].bit) != 0)
13890 {
13891 fputs (l_flags_vals[fcnt].name, stdout);
13892 flags ^= l_flags_vals[fcnt].bit;
13893 }
13894 if (flags != 0)
13895 printf (" %#x", (unsigned int) flags);
252b5132 13896
a6e9f9df
AM
13897 puts ("");
13898 }
252b5132 13899 }
252b5132 13900
a6e9f9df
AM
13901 free (elib);
13902 }
252b5132
RH
13903 }
13904
13905 if (options_offset != 0)
13906 {
2cf0635d 13907 Elf_External_Options * eopt;
2cf0635d
NC
13908 Elf_Internal_Options * iopt;
13909 Elf_Internal_Options * option;
252b5132
RH
13910 size_t offset;
13911 int cnt;
351cdf24 13912 sect = section_headers;
252b5132
RH
13913
13914 /* Find the section header so that we get the size. */
071436c6 13915 sect = find_section_by_type (SHT_MIPS_OPTIONS);
948f632f 13916 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
13917 if (sect == NULL)
13918 {
13919 error (_("No MIPS_OPTIONS header found\n"));
13920 return 0;
13921 }
252b5132 13922
3f5e193b
NC
13923 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
13924 sect->sh_size, _("options"));
a6e9f9df 13925 if (eopt)
252b5132 13926 {
3f5e193b
NC
13927 iopt = (Elf_Internal_Options *)
13928 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
13929 if (iopt == NULL)
13930 {
8b73c356 13931 error (_("Out of memory allocatinf space for MIPS options\n"));
a6e9f9df
AM
13932 return 0;
13933 }
76da6bbe 13934
a6e9f9df
AM
13935 offset = cnt = 0;
13936 option = iopt;
252b5132 13937
82b1b41b 13938 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 13939 {
2cf0635d 13940 Elf_External_Options * eoption;
252b5132 13941
a6e9f9df 13942 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 13943
a6e9f9df
AM
13944 option->kind = BYTE_GET (eoption->kind);
13945 option->size = BYTE_GET (eoption->size);
13946 option->section = BYTE_GET (eoption->section);
13947 option->info = BYTE_GET (eoption->info);
76da6bbe 13948
82b1b41b
NC
13949 /* PR 17531: file: ffa0fa3b. */
13950 if (option->size < sizeof (* eopt)
13951 || offset + option->size > sect->sh_size)
13952 {
55325047
NC
13953 error (_("Invalid size (%u) for MIPS option\n"), option->size);
13954 return 0;
82b1b41b 13955 }
a6e9f9df 13956 offset += option->size;
82b1b41b 13957
a6e9f9df
AM
13958 ++option;
13959 ++cnt;
13960 }
252b5132 13961
a6e9f9df 13962 printf (_("\nSection '%s' contains %d entries:\n"),
74e1a04b 13963 printable_section_name (sect), cnt);
76da6bbe 13964
a6e9f9df 13965 option = iopt;
82b1b41b 13966 offset = 0;
252b5132 13967
a6e9f9df 13968 while (cnt-- > 0)
252b5132 13969 {
a6e9f9df
AM
13970 size_t len;
13971
13972 switch (option->kind)
252b5132 13973 {
a6e9f9df
AM
13974 case ODK_NULL:
13975 /* This shouldn't happen. */
13976 printf (" NULL %d %lx", option->section, option->info);
13977 break;
13978 case ODK_REGINFO:
13979 printf (" REGINFO ");
13980 if (elf_header.e_machine == EM_MIPS)
13981 {
13982 /* 32bit form. */
2cf0635d 13983 Elf32_External_RegInfo * ereg;
b34976b6 13984 Elf32_RegInfo reginfo;
a6e9f9df
AM
13985
13986 ereg = (Elf32_External_RegInfo *) (option + 1);
13987 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13988 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13989 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13990 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13991 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
13992 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
13993
13994 printf ("GPR %08lx GP 0x%lx\n",
13995 reginfo.ri_gprmask,
13996 (unsigned long) reginfo.ri_gp_value);
13997 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13998 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13999 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
14000 }
14001 else
14002 {
14003 /* 64 bit form. */
2cf0635d 14004 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
14005 Elf64_Internal_RegInfo reginfo;
14006
14007 ereg = (Elf64_External_RegInfo *) (option + 1);
14008 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
14009 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
14010 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
14011 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
14012 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 14013 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
14014
14015 printf ("GPR %08lx GP 0x",
14016 reginfo.ri_gprmask);
14017 printf_vma (reginfo.ri_gp_value);
14018 printf ("\n");
14019
14020 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
14021 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
14022 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
14023 }
14024 ++option;
14025 continue;
14026 case ODK_EXCEPTIONS:
14027 fputs (" EXCEPTIONS fpe_min(", stdout);
14028 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
14029 fputs (") fpe_max(", stdout);
14030 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
14031 fputs (")", stdout);
14032
14033 if (option->info & OEX_PAGE0)
14034 fputs (" PAGE0", stdout);
14035 if (option->info & OEX_SMM)
14036 fputs (" SMM", stdout);
14037 if (option->info & OEX_FPDBUG)
14038 fputs (" FPDBUG", stdout);
14039 if (option->info & OEX_DISMISS)
14040 fputs (" DISMISS", stdout);
14041 break;
14042 case ODK_PAD:
14043 fputs (" PAD ", stdout);
14044 if (option->info & OPAD_PREFIX)
14045 fputs (" PREFIX", stdout);
14046 if (option->info & OPAD_POSTFIX)
14047 fputs (" POSTFIX", stdout);
14048 if (option->info & OPAD_SYMBOL)
14049 fputs (" SYMBOL", stdout);
14050 break;
14051 case ODK_HWPATCH:
14052 fputs (" HWPATCH ", stdout);
14053 if (option->info & OHW_R4KEOP)
14054 fputs (" R4KEOP", stdout);
14055 if (option->info & OHW_R8KPFETCH)
14056 fputs (" R8KPFETCH", stdout);
14057 if (option->info & OHW_R5KEOP)
14058 fputs (" R5KEOP", stdout);
14059 if (option->info & OHW_R5KCVTL)
14060 fputs (" R5KCVTL", stdout);
14061 break;
14062 case ODK_FILL:
14063 fputs (" FILL ", stdout);
14064 /* XXX Print content of info word? */
14065 break;
14066 case ODK_TAGS:
14067 fputs (" TAGS ", stdout);
14068 /* XXX Print content of info word? */
14069 break;
14070 case ODK_HWAND:
14071 fputs (" HWAND ", stdout);
14072 if (option->info & OHWA0_R4KEOP_CHECKED)
14073 fputs (" R4KEOP_CHECKED", stdout);
14074 if (option->info & OHWA0_R4KEOP_CLEAN)
14075 fputs (" R4KEOP_CLEAN", stdout);
14076 break;
14077 case ODK_HWOR:
14078 fputs (" HWOR ", stdout);
14079 if (option->info & OHWA0_R4KEOP_CHECKED)
14080 fputs (" R4KEOP_CHECKED", stdout);
14081 if (option->info & OHWA0_R4KEOP_CLEAN)
14082 fputs (" R4KEOP_CLEAN", stdout);
14083 break;
14084 case ODK_GP_GROUP:
14085 printf (" GP_GROUP %#06lx self-contained %#06lx",
14086 option->info & OGP_GROUP,
14087 (option->info & OGP_SELF) >> 16);
14088 break;
14089 case ODK_IDENT:
14090 printf (" IDENT %#06lx self-contained %#06lx",
14091 option->info & OGP_GROUP,
14092 (option->info & OGP_SELF) >> 16);
14093 break;
14094 default:
14095 /* This shouldn't happen. */
14096 printf (" %3d ??? %d %lx",
14097 option->kind, option->section, option->info);
14098 break;
252b5132 14099 }
a6e9f9df 14100
2cf0635d 14101 len = sizeof (* eopt);
a6e9f9df 14102 while (len < option->size)
82b1b41b
NC
14103 {
14104 char datum = * ((char *) eopt + offset + len);
a6e9f9df 14105
82b1b41b
NC
14106 if (ISPRINT (datum))
14107 printf ("%c", datum);
14108 else
14109 printf ("\\%03o", datum);
14110 len ++;
14111 }
a6e9f9df 14112 fputs ("\n", stdout);
82b1b41b
NC
14113
14114 offset += option->size;
252b5132 14115 ++option;
252b5132
RH
14116 }
14117
a6e9f9df 14118 free (eopt);
252b5132 14119 }
252b5132
RH
14120 }
14121
14122 if (conflicts_offset != 0 && conflictsno != 0)
14123 {
2cf0635d 14124 Elf32_Conflict * iconf;
252b5132
RH
14125 size_t cnt;
14126
14127 if (dynamic_symbols == NULL)
14128 {
591a748a 14129 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
14130 return 0;
14131 }
14132
3f5e193b 14133 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
14134 if (iconf == NULL)
14135 {
8b73c356 14136 error (_("Out of memory allocating space for dynamic conflicts\n"));
252b5132
RH
14137 return 0;
14138 }
14139
9ea033b2 14140 if (is_32bit_elf)
252b5132 14141 {
2cf0635d 14142 Elf32_External_Conflict * econf32;
a6e9f9df 14143
3f5e193b
NC
14144 econf32 = (Elf32_External_Conflict *)
14145 get_data (NULL, file, conflicts_offset, conflictsno,
14146 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
14147 if (!econf32)
14148 return 0;
252b5132
RH
14149
14150 for (cnt = 0; cnt < conflictsno; ++cnt)
14151 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
14152
14153 free (econf32);
252b5132
RH
14154 }
14155 else
14156 {
2cf0635d 14157 Elf64_External_Conflict * econf64;
a6e9f9df 14158
3f5e193b
NC
14159 econf64 = (Elf64_External_Conflict *)
14160 get_data (NULL, file, conflicts_offset, conflictsno,
14161 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
14162 if (!econf64)
14163 return 0;
252b5132
RH
14164
14165 for (cnt = 0; cnt < conflictsno; ++cnt)
14166 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
14167
14168 free (econf64);
252b5132
RH
14169 }
14170
c7e7ca54
NC
14171 printf (_("\nSection '.conflict' contains %lu entries:\n"),
14172 (unsigned long) conflictsno);
252b5132
RH
14173 puts (_(" Num: Index Value Name"));
14174
14175 for (cnt = 0; cnt < conflictsno; ++cnt)
14176 {
b34976b6 14177 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
14178
14179 if (iconf[cnt] >= num_dynamic_syms)
14180 printf (_("<corrupt symbol index>"));
d79b3d50 14181 else
e0a31db1
NC
14182 {
14183 Elf_Internal_Sym * psym;
14184
14185 psym = & dynamic_symbols[iconf[cnt]];
14186 print_vma (psym->st_value, FULL_HEX);
14187 putchar (' ');
14188 if (VALID_DYNAMIC_NAME (psym->st_name))
14189 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
14190 else
14191 printf (_("<corrupt: %14ld>"), psym->st_name);
14192 }
31104126 14193 putchar ('\n');
252b5132
RH
14194 }
14195
252b5132
RH
14196 free (iconf);
14197 }
14198
ccb4c951
RS
14199 if (pltgot != 0 && local_gotno != 0)
14200 {
91d6fa6a 14201 bfd_vma ent, local_end, global_end;
bbeee7ea 14202 size_t i, offset;
2cf0635d 14203 unsigned char * data;
82b1b41b 14204 unsigned char * data_end;
bbeee7ea 14205 int addr_size;
ccb4c951 14206
91d6fa6a 14207 ent = pltgot;
ccb4c951
RS
14208 addr_size = (is_32bit_elf ? 4 : 8);
14209 local_end = pltgot + local_gotno * addr_size;
ccb4c951 14210
74e1a04b
NC
14211 /* PR binutils/17533 file: 012-111227-0.004 */
14212 if (symtabno < gotsym)
14213 {
14214 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 14215 (unsigned long) gotsym, (unsigned long) symtabno);
74e1a04b
NC
14216 return 0;
14217 }
82b1b41b 14218
74e1a04b 14219 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
14220 /* PR 17531: file: 54c91a34. */
14221 if (global_end < local_end)
14222 {
14223 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
14224 return 0;
14225 }
948f632f 14226
ccb4c951 14227 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 14228 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
14229 global_end - pltgot, 1,
14230 _("Global Offset Table data"));
59245841
NC
14231 if (data == NULL)
14232 return 0;
82b1b41b 14233 data_end = data + (global_end - pltgot);
59245841 14234
ccb4c951
RS
14235 printf (_("\nPrimary GOT:\n"));
14236 printf (_(" Canonical gp value: "));
14237 print_vma (pltgot + 0x7ff0, LONG_HEX);
14238 printf ("\n\n");
14239
14240 printf (_(" Reserved entries:\n"));
14241 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
14242 addr_size * 2, _("Address"), _("Access"),
14243 addr_size * 2, _("Initial"));
82b1b41b 14244 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 14245 printf (_(" Lazy resolver\n"));
82b1b41b
NC
14246 if (ent == (bfd_vma) -1)
14247 goto got_print_fail;
ccb4c951 14248 if (data
91d6fa6a 14249 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
14250 >> (addr_size * 8 - 1)) != 0)
14251 {
82b1b41b 14252 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 14253 printf (_(" Module pointer (GNU extension)\n"));
82b1b41b
NC
14254 if (ent == (bfd_vma) -1)
14255 goto got_print_fail;
ccb4c951
RS
14256 }
14257 printf ("\n");
14258
91d6fa6a 14259 if (ent < local_end)
ccb4c951
RS
14260 {
14261 printf (_(" Local entries:\n"));
cc5914eb 14262 printf (" %*s %10s %*s\n",
2b692964
NC
14263 addr_size * 2, _("Address"), _("Access"),
14264 addr_size * 2, _("Initial"));
91d6fa6a 14265 while (ent < local_end)
ccb4c951 14266 {
82b1b41b 14267 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 14268 printf ("\n");
82b1b41b
NC
14269 if (ent == (bfd_vma) -1)
14270 goto got_print_fail;
ccb4c951
RS
14271 }
14272 printf ("\n");
14273 }
14274
14275 if (gotsym < symtabno)
14276 {
14277 int sym_width;
14278
14279 printf (_(" Global entries:\n"));
cc5914eb 14280 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
14281 addr_size * 2, _("Address"),
14282 _("Access"),
2b692964 14283 addr_size * 2, _("Initial"),
9cf03b7e
NC
14284 addr_size * 2, _("Sym.Val."),
14285 _("Type"),
14286 /* Note for translators: "Ndx" = abbreviated form of "Index". */
14287 _("Ndx"), _("Name"));
0b4362b0 14288
ccb4c951 14289 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 14290
ccb4c951
RS
14291 for (i = gotsym; i < symtabno; i++)
14292 {
82b1b41b 14293 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 14294 printf (" ");
e0a31db1
NC
14295
14296 if (dynamic_symbols == NULL)
14297 printf (_("<no dynamic symbols>"));
14298 else if (i < num_dynamic_syms)
14299 {
14300 Elf_Internal_Sym * psym = dynamic_symbols + i;
14301
14302 print_vma (psym->st_value, LONG_HEX);
14303 printf (" %-7s %3s ",
14304 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14305 get_symbol_index_type (psym->st_shndx));
14306
14307 if (VALID_DYNAMIC_NAME (psym->st_name))
14308 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14309 else
14310 printf (_("<corrupt: %14ld>"), psym->st_name);
14311 }
ccb4c951 14312 else
7fc5ac57
JBG
14313 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
14314 (unsigned long) i);
e0a31db1 14315
ccb4c951 14316 printf ("\n");
82b1b41b
NC
14317 if (ent == (bfd_vma) -1)
14318 break;
ccb4c951
RS
14319 }
14320 printf ("\n");
14321 }
14322
82b1b41b 14323 got_print_fail:
ccb4c951
RS
14324 if (data)
14325 free (data);
14326 }
14327
861fb55a
DJ
14328 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
14329 {
91d6fa6a 14330 bfd_vma ent, end;
861fb55a
DJ
14331 size_t offset, rel_offset;
14332 unsigned long count, i;
2cf0635d 14333 unsigned char * data;
861fb55a 14334 int addr_size, sym_width;
2cf0635d 14335 Elf_Internal_Rela * rels;
861fb55a
DJ
14336
14337 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
14338 if (pltrel == DT_RELA)
14339 {
14340 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
14341 return 0;
14342 }
14343 else
14344 {
14345 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
14346 return 0;
14347 }
14348
91d6fa6a 14349 ent = mips_pltgot;
861fb55a
DJ
14350 addr_size = (is_32bit_elf ? 4 : 8);
14351 end = mips_pltgot + (2 + count) * addr_size;
14352
14353 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 14354 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 14355 1, _("Procedure Linkage Table data"));
59245841
NC
14356 if (data == NULL)
14357 return 0;
14358
9cf03b7e 14359 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
14360 printf (_(" Reserved entries:\n"));
14361 printf (_(" %*s %*s Purpose\n"),
2b692964 14362 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 14363 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14364 printf (_(" PLT lazy resolver\n"));
91d6fa6a 14365 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14366 printf (_(" Module pointer\n"));
861fb55a
DJ
14367 printf ("\n");
14368
14369 printf (_(" Entries:\n"));
cc5914eb 14370 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
14371 addr_size * 2, _("Address"),
14372 addr_size * 2, _("Initial"),
14373 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
14374 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
14375 for (i = 0; i < count; i++)
14376 {
df97ab2a 14377 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 14378
91d6fa6a 14379 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 14380 printf (" ");
e0a31db1 14381
df97ab2a
MF
14382 if (idx >= num_dynamic_syms)
14383 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 14384 else
e0a31db1 14385 {
df97ab2a 14386 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
14387
14388 print_vma (psym->st_value, LONG_HEX);
14389 printf (" %-7s %3s ",
14390 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14391 get_symbol_index_type (psym->st_shndx));
14392 if (VALID_DYNAMIC_NAME (psym->st_name))
14393 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14394 else
14395 printf (_("<corrupt: %14ld>"), psym->st_name);
14396 }
861fb55a
DJ
14397 printf ("\n");
14398 }
14399 printf ("\n");
14400
14401 if (data)
14402 free (data);
14403 free (rels);
14404 }
14405
252b5132
RH
14406 return 1;
14407}
14408
35c08157
KLC
14409static int
14410process_nds32_specific (FILE * file)
14411{
14412 Elf_Internal_Shdr *sect = NULL;
14413
14414 sect = find_section (".nds32_e_flags");
14415 if (sect != NULL)
14416 {
14417 unsigned int *flag;
14418
14419 printf ("\nNDS32 elf flags section:\n");
14420 flag = get_data (NULL, file, sect->sh_offset, 1,
14421 sect->sh_size, _("NDS32 elf flags section"));
14422
14423 switch ((*flag) & 0x3)
14424 {
14425 case 0:
14426 printf ("(VEC_SIZE):\tNo entry.\n");
14427 break;
14428 case 1:
14429 printf ("(VEC_SIZE):\t4 bytes\n");
14430 break;
14431 case 2:
14432 printf ("(VEC_SIZE):\t16 bytes\n");
14433 break;
14434 case 3:
14435 printf ("(VEC_SIZE):\treserved\n");
14436 break;
14437 }
14438 }
14439
14440 return TRUE;
14441}
14442
047b2264 14443static int
2cf0635d 14444process_gnu_liblist (FILE * file)
047b2264 14445{
2cf0635d
NC
14446 Elf_Internal_Shdr * section;
14447 Elf_Internal_Shdr * string_sec;
14448 Elf32_External_Lib * elib;
14449 char * strtab;
c256ffe7 14450 size_t strtab_size;
047b2264
JJ
14451 size_t cnt;
14452 unsigned i;
14453
14454 if (! do_arch)
14455 return 0;
14456
14457 for (i = 0, section = section_headers;
14458 i < elf_header.e_shnum;
b34976b6 14459 i++, section++)
047b2264
JJ
14460 {
14461 switch (section->sh_type)
14462 {
14463 case SHT_GNU_LIBLIST:
4fbb74a6 14464 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
14465 break;
14466
3f5e193b
NC
14467 elib = (Elf32_External_Lib *)
14468 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 14469 _("liblist section data"));
047b2264
JJ
14470
14471 if (elib == NULL)
14472 break;
4fbb74a6 14473 string_sec = section_headers + section->sh_link;
047b2264 14474
3f5e193b
NC
14475 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
14476 string_sec->sh_size,
14477 _("liblist string table"));
047b2264
JJ
14478 if (strtab == NULL
14479 || section->sh_entsize != sizeof (Elf32_External_Lib))
14480 {
14481 free (elib);
2842702f 14482 free (strtab);
047b2264
JJ
14483 break;
14484 }
59245841 14485 strtab_size = string_sec->sh_size;
047b2264
JJ
14486
14487 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
74e1a04b 14488 printable_section_name (section),
0af1713e 14489 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 14490
2b692964 14491 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
14492
14493 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
14494 ++cnt)
14495 {
14496 Elf32_Lib liblist;
91d6fa6a 14497 time_t atime;
047b2264 14498 char timebuf[20];
2cf0635d 14499 struct tm * tmp;
047b2264
JJ
14500
14501 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14502 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
14503 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14504 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14505 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14506
91d6fa6a 14507 tmp = gmtime (&atime);
e9e44622
JJ
14508 snprintf (timebuf, sizeof (timebuf),
14509 "%04u-%02u-%02uT%02u:%02u:%02u",
14510 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14511 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
14512
14513 printf ("%3lu: ", (unsigned long) cnt);
14514 if (do_wide)
c256ffe7 14515 printf ("%-20s", liblist.l_name < strtab_size
2b692964 14516 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 14517 else
c256ffe7 14518 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 14519 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
14520 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
14521 liblist.l_version, liblist.l_flags);
14522 }
14523
14524 free (elib);
2842702f 14525 free (strtab);
047b2264
JJ
14526 }
14527 }
14528
14529 return 1;
14530}
14531
9437c45b 14532static const char *
d3ba0551 14533get_note_type (unsigned e_type)
779fe533
NC
14534{
14535 static char buff[64];
103f02d3 14536
1ec5cd37
NC
14537 if (elf_header.e_type == ET_CORE)
14538 switch (e_type)
14539 {
57346661 14540 case NT_AUXV:
1ec5cd37 14541 return _("NT_AUXV (auxiliary vector)");
57346661 14542 case NT_PRSTATUS:
1ec5cd37 14543 return _("NT_PRSTATUS (prstatus structure)");
57346661 14544 case NT_FPREGSET:
1ec5cd37 14545 return _("NT_FPREGSET (floating point registers)");
57346661 14546 case NT_PRPSINFO:
1ec5cd37 14547 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 14548 case NT_TASKSTRUCT:
1ec5cd37 14549 return _("NT_TASKSTRUCT (task structure)");
57346661 14550 case NT_PRXFPREG:
1ec5cd37 14551 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
14552 case NT_PPC_VMX:
14553 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
14554 case NT_PPC_VSX:
14555 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
14556 case NT_386_TLS:
14557 return _("NT_386_TLS (x86 TLS information)");
14558 case NT_386_IOPERM:
14559 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
14560 case NT_X86_XSTATE:
14561 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
14562 case NT_S390_HIGH_GPRS:
14563 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
14564 case NT_S390_TIMER:
14565 return _("NT_S390_TIMER (s390 timer register)");
14566 case NT_S390_TODCMP:
14567 return _("NT_S390_TODCMP (s390 TOD comparator register)");
14568 case NT_S390_TODPREG:
14569 return _("NT_S390_TODPREG (s390 TOD programmable register)");
14570 case NT_S390_CTRS:
14571 return _("NT_S390_CTRS (s390 control registers)");
14572 case NT_S390_PREFIX:
14573 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
14574 case NT_S390_LAST_BREAK:
14575 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
14576 case NT_S390_SYSTEM_CALL:
14577 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
14578 case NT_S390_TDB:
14579 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
14580 case NT_S390_VXRS_LOW:
14581 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
14582 case NT_S390_VXRS_HIGH:
14583 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
faa9a424
UW
14584 case NT_ARM_VFP:
14585 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
14586 case NT_ARM_TLS:
14587 return _("NT_ARM_TLS (AArch TLS registers)");
14588 case NT_ARM_HW_BREAK:
14589 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
14590 case NT_ARM_HW_WATCH:
14591 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 14592 case NT_PSTATUS:
1ec5cd37 14593 return _("NT_PSTATUS (pstatus structure)");
57346661 14594 case NT_FPREGS:
1ec5cd37 14595 return _("NT_FPREGS (floating point registers)");
57346661 14596 case NT_PSINFO:
1ec5cd37 14597 return _("NT_PSINFO (psinfo structure)");
57346661 14598 case NT_LWPSTATUS:
1ec5cd37 14599 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 14600 case NT_LWPSINFO:
1ec5cd37 14601 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 14602 case NT_WIN32PSTATUS:
1ec5cd37 14603 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
14604 case NT_SIGINFO:
14605 return _("NT_SIGINFO (siginfo_t data)");
14606 case NT_FILE:
14607 return _("NT_FILE (mapped files)");
1ec5cd37
NC
14608 default:
14609 break;
14610 }
14611 else
14612 switch (e_type)
14613 {
14614 case NT_VERSION:
14615 return _("NT_VERSION (version)");
14616 case NT_ARCH:
14617 return _("NT_ARCH (architecture)");
14618 default:
14619 break;
14620 }
14621
e9e44622 14622 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 14623 return buff;
779fe533
NC
14624}
14625
9ece1fa9
TT
14626static int
14627print_core_note (Elf_Internal_Note *pnote)
14628{
14629 unsigned int addr_size = is_32bit_elf ? 4 : 8;
14630 bfd_vma count, page_size;
14631 unsigned char *descdata, *filenames, *descend;
14632
14633 if (pnote->type != NT_FILE)
14634 return 1;
14635
14636#ifndef BFD64
14637 if (!is_32bit_elf)
14638 {
14639 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
14640 /* Still "successful". */
14641 return 1;
14642 }
14643#endif
14644
14645 if (pnote->descsz < 2 * addr_size)
14646 {
14647 printf (_(" Malformed note - too short for header\n"));
14648 return 0;
14649 }
14650
14651 descdata = (unsigned char *) pnote->descdata;
14652 descend = descdata + pnote->descsz;
14653
14654 if (descdata[pnote->descsz - 1] != '\0')
14655 {
14656 printf (_(" Malformed note - does not end with \\0\n"));
14657 return 0;
14658 }
14659
14660 count = byte_get (descdata, addr_size);
14661 descdata += addr_size;
14662
14663 page_size = byte_get (descdata, addr_size);
14664 descdata += addr_size;
14665
14666 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
14667 {
14668 printf (_(" Malformed note - too short for supplied file count\n"));
14669 return 0;
14670 }
14671
14672 printf (_(" Page size: "));
14673 print_vma (page_size, DEC);
14674 printf ("\n");
14675
14676 printf (_(" %*s%*s%*s\n"),
14677 (int) (2 + 2 * addr_size), _("Start"),
14678 (int) (4 + 2 * addr_size), _("End"),
14679 (int) (4 + 2 * addr_size), _("Page Offset"));
14680 filenames = descdata + count * 3 * addr_size;
14681 while (--count > 0)
14682 {
14683 bfd_vma start, end, file_ofs;
14684
14685 if (filenames == descend)
14686 {
14687 printf (_(" Malformed note - filenames end too early\n"));
14688 return 0;
14689 }
14690
14691 start = byte_get (descdata, addr_size);
14692 descdata += addr_size;
14693 end = byte_get (descdata, addr_size);
14694 descdata += addr_size;
14695 file_ofs = byte_get (descdata, addr_size);
14696 descdata += addr_size;
14697
14698 printf (" ");
14699 print_vma (start, FULL_HEX);
14700 printf (" ");
14701 print_vma (end, FULL_HEX);
14702 printf (" ");
14703 print_vma (file_ofs, FULL_HEX);
14704 printf ("\n %s\n", filenames);
14705
14706 filenames += 1 + strlen ((char *) filenames);
14707 }
14708
14709 return 1;
14710}
14711
1118d252
RM
14712static const char *
14713get_gnu_elf_note_type (unsigned e_type)
14714{
14715 static char buff[64];
14716
14717 switch (e_type)
14718 {
14719 case NT_GNU_ABI_TAG:
14720 return _("NT_GNU_ABI_TAG (ABI version tag)");
14721 case NT_GNU_HWCAP:
14722 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
14723 case NT_GNU_BUILD_ID:
14724 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
14725 case NT_GNU_GOLD_VERSION:
14726 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
14727 default:
14728 break;
14729 }
14730
14731 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14732 return buff;
14733}
14734
664f90a3
TT
14735static int
14736print_gnu_note (Elf_Internal_Note *pnote)
14737{
14738 switch (pnote->type)
14739 {
14740 case NT_GNU_BUILD_ID:
14741 {
14742 unsigned long i;
14743
14744 printf (_(" Build ID: "));
14745 for (i = 0; i < pnote->descsz; ++i)
14746 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 14747 printf ("\n");
664f90a3
TT
14748 }
14749 break;
14750
14751 case NT_GNU_ABI_TAG:
14752 {
14753 unsigned long os, major, minor, subminor;
14754 const char *osname;
14755
3102e897
NC
14756 /* PR 17531: file: 030-599401-0.004. */
14757 if (pnote->descsz < 16)
14758 {
14759 printf (_(" <corrupt GNU_ABI_TAG>\n"));
14760 break;
14761 }
14762
664f90a3
TT
14763 os = byte_get ((unsigned char *) pnote->descdata, 4);
14764 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
14765 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
14766 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
14767
14768 switch (os)
14769 {
14770 case GNU_ABI_TAG_LINUX:
14771 osname = "Linux";
14772 break;
14773 case GNU_ABI_TAG_HURD:
14774 osname = "Hurd";
14775 break;
14776 case GNU_ABI_TAG_SOLARIS:
14777 osname = "Solaris";
14778 break;
14779 case GNU_ABI_TAG_FREEBSD:
14780 osname = "FreeBSD";
14781 break;
14782 case GNU_ABI_TAG_NETBSD:
14783 osname = "NetBSD";
14784 break;
14785 default:
14786 osname = "Unknown";
14787 break;
14788 }
14789
14790 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
14791 major, minor, subminor);
14792 }
14793 break;
926c5385
CC
14794
14795 case NT_GNU_GOLD_VERSION:
14796 {
14797 unsigned long i;
14798
14799 printf (_(" Version: "));
14800 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
14801 printf ("%c", pnote->descdata[i]);
14802 printf ("\n");
14803 }
14804 break;
664f90a3
TT
14805 }
14806
14807 return 1;
14808}
14809
9437c45b 14810static const char *
d3ba0551 14811get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
14812{
14813 static char buff[64];
14814
b4db1224 14815 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
14816 {
14817 /* NetBSD core "procinfo" structure. */
14818 return _("NetBSD procinfo structure");
14819 }
14820
14821 /* As of Jan 2002 there are no other machine-independent notes
14822 defined for NetBSD core files. If the note type is less
14823 than the start of the machine-dependent note types, we don't
14824 understand it. */
14825
b4db1224 14826 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 14827 {
e9e44622 14828 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
14829 return buff;
14830 }
14831
14832 switch (elf_header.e_machine)
14833 {
14834 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
14835 and PT_GETFPREGS == mach+2. */
14836
14837 case EM_OLD_ALPHA:
14838 case EM_ALPHA:
14839 case EM_SPARC:
14840 case EM_SPARC32PLUS:
14841 case EM_SPARCV9:
14842 switch (e_type)
14843 {
2b692964 14844 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 14845 return _("PT_GETREGS (reg structure)");
2b692964 14846 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 14847 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14848 default:
14849 break;
14850 }
14851 break;
14852
14853 /* On all other arch's, PT_GETREGS == mach+1 and
14854 PT_GETFPREGS == mach+3. */
14855 default:
14856 switch (e_type)
14857 {
2b692964 14858 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 14859 return _("PT_GETREGS (reg structure)");
2b692964 14860 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 14861 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14862 default:
14863 break;
14864 }
14865 }
14866
9cf03b7e 14867 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 14868 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
14869 return buff;
14870}
14871
70616151
TT
14872static const char *
14873get_stapsdt_note_type (unsigned e_type)
14874{
14875 static char buff[64];
14876
14877 switch (e_type)
14878 {
14879 case NT_STAPSDT:
14880 return _("NT_STAPSDT (SystemTap probe descriptors)");
14881
14882 default:
14883 break;
14884 }
14885
14886 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14887 return buff;
14888}
14889
c6a9fc58
TT
14890static int
14891print_stapsdt_note (Elf_Internal_Note *pnote)
14892{
14893 int addr_size = is_32bit_elf ? 4 : 8;
14894 char *data = pnote->descdata;
14895 char *data_end = pnote->descdata + pnote->descsz;
14896 bfd_vma pc, base_addr, semaphore;
14897 char *provider, *probe, *arg_fmt;
14898
14899 pc = byte_get ((unsigned char *) data, addr_size);
14900 data += addr_size;
14901 base_addr = byte_get ((unsigned char *) data, addr_size);
14902 data += addr_size;
14903 semaphore = byte_get ((unsigned char *) data, addr_size);
14904 data += addr_size;
14905
14906 provider = data;
14907 data += strlen (data) + 1;
14908 probe = data;
14909 data += strlen (data) + 1;
14910 arg_fmt = data;
14911 data += strlen (data) + 1;
14912
14913 printf (_(" Provider: %s\n"), provider);
14914 printf (_(" Name: %s\n"), probe);
14915 printf (_(" Location: "));
14916 print_vma (pc, FULL_HEX);
14917 printf (_(", Base: "));
14918 print_vma (base_addr, FULL_HEX);
14919 printf (_(", Semaphore: "));
14920 print_vma (semaphore, FULL_HEX);
9cf03b7e 14921 printf ("\n");
c6a9fc58
TT
14922 printf (_(" Arguments: %s\n"), arg_fmt);
14923
14924 return data == data_end;
14925}
14926
00e98fc7
TG
14927static const char *
14928get_ia64_vms_note_type (unsigned e_type)
14929{
14930 static char buff[64];
14931
14932 switch (e_type)
14933 {
14934 case NT_VMS_MHD:
14935 return _("NT_VMS_MHD (module header)");
14936 case NT_VMS_LNM:
14937 return _("NT_VMS_LNM (language name)");
14938 case NT_VMS_SRC:
14939 return _("NT_VMS_SRC (source files)");
14940 case NT_VMS_TITLE:
9cf03b7e 14941 return "NT_VMS_TITLE";
00e98fc7
TG
14942 case NT_VMS_EIDC:
14943 return _("NT_VMS_EIDC (consistency check)");
14944 case NT_VMS_FPMODE:
14945 return _("NT_VMS_FPMODE (FP mode)");
14946 case NT_VMS_LINKTIME:
9cf03b7e 14947 return "NT_VMS_LINKTIME";
00e98fc7
TG
14948 case NT_VMS_IMGNAM:
14949 return _("NT_VMS_IMGNAM (image name)");
14950 case NT_VMS_IMGID:
14951 return _("NT_VMS_IMGID (image id)");
14952 case NT_VMS_LINKID:
14953 return _("NT_VMS_LINKID (link id)");
14954 case NT_VMS_IMGBID:
14955 return _("NT_VMS_IMGBID (build id)");
14956 case NT_VMS_GSTNAM:
14957 return _("NT_VMS_GSTNAM (sym table name)");
14958 case NT_VMS_ORIG_DYN:
9cf03b7e 14959 return "NT_VMS_ORIG_DYN";
00e98fc7 14960 case NT_VMS_PATCHTIME:
9cf03b7e 14961 return "NT_VMS_PATCHTIME";
00e98fc7
TG
14962 default:
14963 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14964 return buff;
14965 }
14966}
14967
14968static int
14969print_ia64_vms_note (Elf_Internal_Note * pnote)
14970{
14971 switch (pnote->type)
14972 {
14973 case NT_VMS_MHD:
14974 if (pnote->descsz > 36)
14975 {
14976 size_t l = strlen (pnote->descdata + 34);
14977 printf (_(" Creation date : %.17s\n"), pnote->descdata);
14978 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
14979 printf (_(" Module name : %s\n"), pnote->descdata + 34);
14980 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
14981 }
14982 else
14983 printf (_(" Invalid size\n"));
14984 break;
14985 case NT_VMS_LNM:
14986 printf (_(" Language: %s\n"), pnote->descdata);
14987 break;
14988#ifdef BFD64
14989 case NT_VMS_FPMODE:
9cf03b7e 14990 printf (_(" Floating Point mode: "));
4a5cb34f 14991 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 14992 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
14993 break;
14994 case NT_VMS_LINKTIME:
14995 printf (_(" Link time: "));
14996 print_vms_time
14997 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14998 printf ("\n");
14999 break;
15000 case NT_VMS_PATCHTIME:
15001 printf (_(" Patch time: "));
15002 print_vms_time
15003 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
15004 printf ("\n");
15005 break;
15006 case NT_VMS_ORIG_DYN:
15007 printf (_(" Major id: %u, minor id: %u\n"),
15008 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
15009 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 15010 printf (_(" Last modified : "));
00e98fc7
TG
15011 print_vms_time
15012 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 15013 printf (_("\n Link flags : "));
4a5cb34f 15014 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 15015 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 15016 printf (_(" Header flags: 0x%08x\n"),
948f632f 15017 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
00e98fc7
TG
15018 printf (_(" Image id : %s\n"), pnote->descdata + 32);
15019 break;
15020#endif
15021 case NT_VMS_IMGNAM:
15022 printf (_(" Image name: %s\n"), pnote->descdata);
15023 break;
15024 case NT_VMS_GSTNAM:
15025 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
15026 break;
15027 case NT_VMS_IMGID:
15028 printf (_(" Image id: %s\n"), pnote->descdata);
15029 break;
15030 case NT_VMS_LINKID:
15031 printf (_(" Linker id: %s\n"), pnote->descdata);
15032 break;
15033 default:
15034 break;
15035 }
15036 return 1;
15037}
15038
6d118b09
NC
15039/* Note that by the ELF standard, the name field is already null byte
15040 terminated, and namesz includes the terminating null byte.
15041 I.E. the value of namesz for the name "FSF" is 4.
15042
e3c8793a 15043 If the value of namesz is zero, there is no name present. */
779fe533 15044static int
2cf0635d 15045process_note (Elf_Internal_Note * pnote)
779fe533 15046{
2cf0635d
NC
15047 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
15048 const char * nt;
9437c45b
JT
15049
15050 if (pnote->namesz == 0)
1ec5cd37
NC
15051 /* If there is no note name, then use the default set of
15052 note type strings. */
15053 nt = get_note_type (pnote->type);
15054
1118d252
RM
15055 else if (const_strneq (pnote->namedata, "GNU"))
15056 /* GNU-specific object file notes. */
15057 nt = get_gnu_elf_note_type (pnote->type);
15058
0112cd26 15059 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
15060 /* NetBSD-specific core file notes. */
15061 nt = get_netbsd_elfcore_note_type (pnote->type);
15062
b15fa79e
AM
15063 else if (strneq (pnote->namedata, "SPU/", 4))
15064 {
15065 /* SPU-specific core file notes. */
15066 nt = pnote->namedata + 4;
15067 name = "SPU";
15068 }
15069
00e98fc7
TG
15070 else if (const_strneq (pnote->namedata, "IPF/VMS"))
15071 /* VMS/ia64-specific file notes. */
15072 nt = get_ia64_vms_note_type (pnote->type);
15073
70616151
TT
15074 else if (const_strneq (pnote->namedata, "stapsdt"))
15075 nt = get_stapsdt_note_type (pnote->type);
15076
9437c45b 15077 else
1ec5cd37
NC
15078 /* Don't recognize this note name; just use the default set of
15079 note type strings. */
00e98fc7 15080 nt = get_note_type (pnote->type);
9437c45b 15081
2aee03ae 15082 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
15083
15084 if (const_strneq (pnote->namedata, "IPF/VMS"))
15085 return print_ia64_vms_note (pnote);
664f90a3
TT
15086 else if (const_strneq (pnote->namedata, "GNU"))
15087 return print_gnu_note (pnote);
c6a9fc58
TT
15088 else if (const_strneq (pnote->namedata, "stapsdt"))
15089 return print_stapsdt_note (pnote);
9ece1fa9
TT
15090 else if (const_strneq (pnote->namedata, "CORE"))
15091 return print_core_note (pnote);
00e98fc7
TG
15092 else
15093 return 1;
779fe533
NC
15094}
15095
6d118b09 15096
779fe533 15097static int
2cf0635d 15098process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 15099{
2cf0635d
NC
15100 Elf_External_Note * pnotes;
15101 Elf_External_Note * external;
b34976b6 15102 int res = 1;
103f02d3 15103
779fe533
NC
15104 if (length <= 0)
15105 return 0;
103f02d3 15106
3f5e193b 15107 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 15108 _("notes"));
dd24e3da 15109 if (pnotes == NULL)
a6e9f9df 15110 return 0;
779fe533 15111
103f02d3 15112 external = pnotes;
103f02d3 15113
9dd3a467 15114 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 15115 (unsigned long) offset, (unsigned long) length);
2aee03ae 15116 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 15117
15b42fb0 15118 while ((char *) external < (char *) pnotes + length)
779fe533 15119 {
b34976b6 15120 Elf_Internal_Note inote;
15b42fb0
AM
15121 size_t min_notesz;
15122 char *next;
2cf0635d 15123 char * temp = NULL;
15b42fb0 15124 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 15125
00e98fc7 15126 if (!is_ia64_vms ())
15b42fb0 15127 {
9dd3a467
NC
15128 /* PR binutils/15191
15129 Make sure that there is enough data to read. */
15b42fb0
AM
15130 min_notesz = offsetof (Elf_External_Note, name);
15131 if (data_remaining < min_notesz)
9dd3a467
NC
15132 {
15133 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
15134 (int) data_remaining);
15135 break;
15136 }
15b42fb0
AM
15137 inote.type = BYTE_GET (external->type);
15138 inote.namesz = BYTE_GET (external->namesz);
15139 inote.namedata = external->name;
15140 inote.descsz = BYTE_GET (external->descsz);
15141 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
834f871c
NC
15142 /* PR 17531: file: 3443835e. */
15143 if (inote.descdata < (char *) pnotes)
15144 {
15145 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
15146 inote.descdata = inote.namedata;
15147 inote.namesz = 0;
15148 }
15b42fb0
AM
15149 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15150 next = inote.descdata + align_power (inote.descsz, 2);
15151 }
00e98fc7 15152 else
15b42fb0
AM
15153 {
15154 Elf64_External_VMS_Note *vms_external;
00e98fc7 15155
9dd3a467
NC
15156 /* PR binutils/15191
15157 Make sure that there is enough data to read. */
15b42fb0
AM
15158 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15159 if (data_remaining < min_notesz)
9dd3a467
NC
15160 {
15161 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
15162 (int) data_remaining);
15163 break;
15164 }
3e55a963 15165
15b42fb0
AM
15166 vms_external = (Elf64_External_VMS_Note *) external;
15167 inote.type = BYTE_GET (vms_external->type);
15168 inote.namesz = BYTE_GET (vms_external->namesz);
15169 inote.namedata = vms_external->name;
15170 inote.descsz = BYTE_GET (vms_external->descsz);
15171 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15172 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15173 next = inote.descdata + align_power (inote.descsz, 3);
15174 }
15175
15176 if (inote.descdata < (char *) external + min_notesz
15177 || next < (char *) external + min_notesz
5d921cbd
NC
15178 /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
15179 || inote.namedata + inote.namesz < inote.namedata
15180 || inote.descdata + inote.descsz < inote.descdata
15b42fb0 15181 || data_remaining < (size_t)(next - (char *) external))
3e55a963 15182 {
15b42fb0 15183 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 15184 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 15185 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
15186 inote.type, inote.namesz, inote.descsz);
15187 break;
15188 }
15189
15b42fb0 15190 external = (Elf_External_Note *) next;
dd24e3da 15191
6d118b09
NC
15192 /* Verify that name is null terminated. It appears that at least
15193 one version of Linux (RedHat 6.0) generates corefiles that don't
15194 comply with the ELF spec by failing to include the null byte in
15195 namesz. */
8b971f9f 15196 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 15197 {
3f5e193b 15198 temp = (char *) malloc (inote.namesz + 1);
6d118b09
NC
15199 if (temp == NULL)
15200 {
8b73c356 15201 error (_("Out of memory allocating space for inote name\n"));
6d118b09
NC
15202 res = 0;
15203 break;
15204 }
76da6bbe 15205
6d118b09
NC
15206 strncpy (temp, inote.namedata, inote.namesz);
15207 temp[inote.namesz] = 0;
76da6bbe 15208
6d118b09
NC
15209 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
15210 inote.namedata = temp;
15211 }
15212
15213 res &= process_note (& inote);
103f02d3 15214
6d118b09
NC
15215 if (temp != NULL)
15216 {
15217 free (temp);
15218 temp = NULL;
15219 }
779fe533
NC
15220 }
15221
15222 free (pnotes);
103f02d3 15223
779fe533
NC
15224 return res;
15225}
15226
15227static int
2cf0635d 15228process_corefile_note_segments (FILE * file)
779fe533 15229{
2cf0635d 15230 Elf_Internal_Phdr * segment;
b34976b6
AM
15231 unsigned int i;
15232 int res = 1;
103f02d3 15233
d93f0186 15234 if (! get_program_headers (file))
779fe533 15235 return 0;
103f02d3 15236
779fe533
NC
15237 for (i = 0, segment = program_headers;
15238 i < elf_header.e_phnum;
b34976b6 15239 i++, segment++)
779fe533
NC
15240 {
15241 if (segment->p_type == PT_NOTE)
103f02d3 15242 res &= process_corefile_note_segment (file,
30800947
NC
15243 (bfd_vma) segment->p_offset,
15244 (bfd_vma) segment->p_filesz);
779fe533 15245 }
103f02d3 15246
779fe533
NC
15247 return res;
15248}
15249
15250static int
2cf0635d 15251process_note_sections (FILE * file)
1ec5cd37 15252{
2cf0635d 15253 Elf_Internal_Shdr * section;
1ec5cd37 15254 unsigned long i;
df565f32 15255 int n = 0;
1ec5cd37
NC
15256 int res = 1;
15257
15258 for (i = 0, section = section_headers;
fa1908fd 15259 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
15260 i++, section++)
15261 if (section->sh_type == SHT_NOTE)
df565f32
NC
15262 {
15263 res &= process_corefile_note_segment (file,
15264 (bfd_vma) section->sh_offset,
15265 (bfd_vma) section->sh_size);
15266 n++;
15267 }
15268
15269 if (n == 0)
15270 /* Try processing NOTE segments instead. */
15271 return process_corefile_note_segments (file);
1ec5cd37
NC
15272
15273 return res;
15274}
15275
15276static int
2cf0635d 15277process_notes (FILE * file)
779fe533
NC
15278{
15279 /* If we have not been asked to display the notes then do nothing. */
15280 if (! do_notes)
15281 return 1;
103f02d3 15282
779fe533 15283 if (elf_header.e_type != ET_CORE)
1ec5cd37 15284 return process_note_sections (file);
103f02d3 15285
779fe533 15286 /* No program headers means no NOTE segment. */
1ec5cd37
NC
15287 if (elf_header.e_phnum > 0)
15288 return process_corefile_note_segments (file);
779fe533 15289
1ec5cd37
NC
15290 printf (_("No note segments present in the core file.\n"));
15291 return 1;
779fe533
NC
15292}
15293
252b5132 15294static int
2cf0635d 15295process_arch_specific (FILE * file)
252b5132 15296{
a952a375
NC
15297 if (! do_arch)
15298 return 1;
15299
252b5132
RH
15300 switch (elf_header.e_machine)
15301 {
11c1ff18
PB
15302 case EM_ARM:
15303 return process_arm_specific (file);
252b5132 15304 case EM_MIPS:
4fe85591 15305 case EM_MIPS_RS3_LE:
252b5132
RH
15306 return process_mips_specific (file);
15307 break;
35c08157
KLC
15308 case EM_NDS32:
15309 return process_nds32_specific (file);
15310 break;
34c8bcba
JM
15311 case EM_PPC:
15312 return process_power_specific (file);
15313 break;
9e8c70f9
DM
15314 case EM_SPARC:
15315 case EM_SPARC32PLUS:
15316 case EM_SPARCV9:
15317 return process_sparc_specific (file);
15318 break;
59e6276b
JM
15319 case EM_TI_C6000:
15320 return process_tic6x_specific (file);
15321 break;
13761a11
NC
15322 case EM_MSP430:
15323 return process_msp430x_specific (file);
252b5132
RH
15324 default:
15325 break;
15326 }
15327 return 1;
15328}
15329
15330static int
2cf0635d 15331get_file_header (FILE * file)
252b5132 15332{
9ea033b2
NC
15333 /* Read in the identity array. */
15334 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
15335 return 0;
15336
9ea033b2 15337 /* Determine how to read the rest of the header. */
b34976b6 15338 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
15339 {
15340 default: /* fall through */
15341 case ELFDATANONE: /* fall through */
adab8cdc
AO
15342 case ELFDATA2LSB:
15343 byte_get = byte_get_little_endian;
15344 byte_put = byte_put_little_endian;
15345 break;
15346 case ELFDATA2MSB:
15347 byte_get = byte_get_big_endian;
15348 byte_put = byte_put_big_endian;
15349 break;
9ea033b2
NC
15350 }
15351
15352 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 15353 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
15354
15355 /* Read in the rest of the header. */
15356 if (is_32bit_elf)
15357 {
15358 Elf32_External_Ehdr ehdr32;
252b5132 15359
9ea033b2
NC
15360 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
15361 return 0;
103f02d3 15362
9ea033b2
NC
15363 elf_header.e_type = BYTE_GET (ehdr32.e_type);
15364 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
15365 elf_header.e_version = BYTE_GET (ehdr32.e_version);
15366 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
15367 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
15368 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
15369 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
15370 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
15371 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
15372 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
15373 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
15374 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
15375 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
15376 }
252b5132 15377 else
9ea033b2
NC
15378 {
15379 Elf64_External_Ehdr ehdr64;
a952a375
NC
15380
15381 /* If we have been compiled with sizeof (bfd_vma) == 4, then
15382 we will not be able to cope with the 64bit data found in
15383 64 ELF files. Detect this now and abort before we start
50c2245b 15384 overwriting things. */
a952a375
NC
15385 if (sizeof (bfd_vma) < 8)
15386 {
e3c8793a
NC
15387 error (_("This instance of readelf has been built without support for a\n\
1538864 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
15389 return 0;
15390 }
103f02d3 15391
9ea033b2
NC
15392 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
15393 return 0;
103f02d3 15394
9ea033b2
NC
15395 elf_header.e_type = BYTE_GET (ehdr64.e_type);
15396 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
15397 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
15398 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
15399 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
15400 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
15401 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
15402 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
15403 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
15404 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
15405 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
15406 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
15407 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
15408 }
252b5132 15409
7ece0d85
JJ
15410 if (elf_header.e_shoff)
15411 {
15412 /* There may be some extensions in the first section header. Don't
15413 bomb if we can't read it. */
15414 if (is_32bit_elf)
049b0c3a 15415 get_32bit_section_headers (file, TRUE);
7ece0d85 15416 else
049b0c3a 15417 get_64bit_section_headers (file, TRUE);
7ece0d85 15418 }
560f3c1c 15419
252b5132
RH
15420 return 1;
15421}
15422
fb52b2f4
NC
15423/* Process one ELF object file according to the command line options.
15424 This file may actually be stored in an archive. The file is
15425 positioned at the start of the ELF object. */
15426
ff78d6d6 15427static int
2cf0635d 15428process_object (char * file_name, FILE * file)
252b5132 15429{
252b5132
RH
15430 unsigned int i;
15431
252b5132
RH
15432 if (! get_file_header (file))
15433 {
15434 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 15435 return 1;
252b5132
RH
15436 }
15437
15438 /* Initialise per file variables. */
60bca95a 15439 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
15440 version_info[i] = 0;
15441
60bca95a 15442 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 15443 dynamic_info[i] = 0;
5115b233 15444 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
15445
15446 /* Process the file. */
15447 if (show_name)
15448 printf (_("\nFile: %s\n"), file_name);
15449
18bd398b
NC
15450 /* Initialise the dump_sects array from the cmdline_dump_sects array.
15451 Note we do this even if cmdline_dump_sects is empty because we
15452 must make sure that the dump_sets array is zeroed out before each
15453 object file is processed. */
15454 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 15455 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
15456
15457 if (num_cmdline_dump_sects > 0)
15458 {
15459 if (num_dump_sects == 0)
15460 /* A sneaky way of allocating the dump_sects array. */
09c11c86 15461 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
15462
15463 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
15464 memcpy (dump_sects, cmdline_dump_sects,
15465 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 15466 }
d70c5fc7 15467
252b5132 15468 if (! process_file_header ())
fb52b2f4 15469 return 1;
252b5132 15470
d1f5c6e3 15471 if (! process_section_headers (file))
2f62977e 15472 {
d1f5c6e3
L
15473 /* Without loaded section headers we cannot process lots of
15474 things. */
2f62977e 15475 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 15476
2f62977e 15477 if (! do_using_dynamic)
2c610e4b 15478 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 15479 }
252b5132 15480
d1f5c6e3
L
15481 if (! process_section_groups (file))
15482 {
15483 /* Without loaded section groups we cannot process unwind. */
15484 do_unwind = 0;
15485 }
15486
2f62977e 15487 if (process_program_headers (file))
b2d38a17 15488 process_dynamic_section (file);
252b5132
RH
15489
15490 process_relocs (file);
15491
4d6ed7c8
NC
15492 process_unwind (file);
15493
252b5132
RH
15494 process_symbol_table (file);
15495
15496 process_syminfo (file);
15497
15498 process_version_sections (file);
15499
15500 process_section_contents (file);
f5842774 15501
1ec5cd37 15502 process_notes (file);
103f02d3 15503
047b2264
JJ
15504 process_gnu_liblist (file);
15505
252b5132
RH
15506 process_arch_specific (file);
15507
d93f0186
NC
15508 if (program_headers)
15509 {
15510 free (program_headers);
15511 program_headers = NULL;
15512 }
15513
252b5132
RH
15514 if (section_headers)
15515 {
15516 free (section_headers);
15517 section_headers = NULL;
15518 }
15519
15520 if (string_table)
15521 {
15522 free (string_table);
15523 string_table = NULL;
d40ac9bd 15524 string_table_length = 0;
252b5132
RH
15525 }
15526
15527 if (dynamic_strings)
15528 {
15529 free (dynamic_strings);
15530 dynamic_strings = NULL;
d79b3d50 15531 dynamic_strings_length = 0;
252b5132
RH
15532 }
15533
15534 if (dynamic_symbols)
15535 {
15536 free (dynamic_symbols);
15537 dynamic_symbols = NULL;
19936277 15538 num_dynamic_syms = 0;
252b5132
RH
15539 }
15540
15541 if (dynamic_syminfo)
15542 {
15543 free (dynamic_syminfo);
15544 dynamic_syminfo = NULL;
15545 }
ff78d6d6 15546
293c573e
MR
15547 if (dynamic_section)
15548 {
15549 free (dynamic_section);
15550 dynamic_section = NULL;
15551 }
15552
e4b17d5c
L
15553 if (section_headers_groups)
15554 {
15555 free (section_headers_groups);
15556 section_headers_groups = NULL;
15557 }
15558
15559 if (section_groups)
15560 {
2cf0635d
NC
15561 struct group_list * g;
15562 struct group_list * next;
e4b17d5c
L
15563
15564 for (i = 0; i < group_count; i++)
15565 {
15566 for (g = section_groups [i].root; g != NULL; g = next)
15567 {
15568 next = g->next;
15569 free (g);
15570 }
15571 }
15572
15573 free (section_groups);
15574 section_groups = NULL;
15575 }
15576
19e6b90e 15577 free_debug_memory ();
18bd398b 15578
ff78d6d6 15579 return 0;
252b5132
RH
15580}
15581
2cf0635d
NC
15582/* Process an ELF archive.
15583 On entry the file is positioned just after the ARMAG string. */
15584
15585static int
15586process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
15587{
15588 struct archive_info arch;
15589 struct archive_info nested_arch;
15590 size_t got;
2cf0635d
NC
15591 int ret;
15592
15593 show_name = 1;
15594
15595 /* The ARCH structure is used to hold information about this archive. */
15596 arch.file_name = NULL;
15597 arch.file = NULL;
15598 arch.index_array = NULL;
15599 arch.sym_table = NULL;
15600 arch.longnames = NULL;
15601
15602 /* The NESTED_ARCH structure is used as a single-item cache of information
15603 about a nested archive (when members of a thin archive reside within
15604 another regular archive file). */
15605 nested_arch.file_name = NULL;
15606 nested_arch.file = NULL;
15607 nested_arch.index_array = NULL;
15608 nested_arch.sym_table = NULL;
15609 nested_arch.longnames = NULL;
15610
15611 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
15612 {
15613 ret = 1;
15614 goto out;
4145f1d5 15615 }
fb52b2f4 15616
4145f1d5
NC
15617 if (do_archive_index)
15618 {
2cf0635d 15619 if (arch.sym_table == NULL)
4145f1d5
NC
15620 error (_("%s: unable to dump the index as none was found\n"), file_name);
15621 else
15622 {
591f7597 15623 unsigned long i, l;
4145f1d5
NC
15624 unsigned long current_pos;
15625
591f7597
NC
15626 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
15627 file_name, (unsigned long) arch.index_num, arch.sym_size);
4145f1d5
NC
15628 current_pos = ftell (file);
15629
2cf0635d 15630 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 15631 {
2cf0635d
NC
15632 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
15633 {
15634 char * member_name;
4145f1d5 15635
2cf0635d
NC
15636 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
15637
15638 if (member_name != NULL)
15639 {
15640 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
15641
15642 if (qualified_name != NULL)
15643 {
c2a7d3f5
NC
15644 printf (_("Contents of binary %s at offset "), qualified_name);
15645 (void) print_vma (arch.index_array[i], PREFIX_HEX);
15646 putchar ('\n');
2cf0635d
NC
15647 free (qualified_name);
15648 }
4145f1d5
NC
15649 }
15650 }
2cf0635d
NC
15651
15652 if (l >= arch.sym_size)
4145f1d5
NC
15653 {
15654 error (_("%s: end of the symbol table reached before the end of the index\n"),
15655 file_name);
cb8f3167 15656 break;
4145f1d5 15657 }
591f7597
NC
15658 /* PR 17531: file: 0b6630b2. */
15659 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
15660 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
15661 }
15662
c2a7d3f5
NC
15663 if (arch.uses_64bit_indicies)
15664 l = (l + 7) & ~ 7;
15665 else
15666 l += l & 1;
15667
2cf0635d 15668 if (l < arch.sym_size)
c2a7d3f5
NC
15669 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
15670 file_name, arch.sym_size - l);
4145f1d5 15671
4145f1d5
NC
15672 if (fseek (file, current_pos, SEEK_SET) != 0)
15673 {
15674 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
15675 ret = 1;
15676 goto out;
4145f1d5 15677 }
fb52b2f4 15678 }
4145f1d5
NC
15679
15680 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
15681 && !do_segments && !do_header && !do_dump && !do_version
15682 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 15683 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
15684 {
15685 ret = 0; /* Archive index only. */
15686 goto out;
15687 }
fb52b2f4
NC
15688 }
15689
d989285c 15690 ret = 0;
fb52b2f4
NC
15691
15692 while (1)
15693 {
2cf0635d
NC
15694 char * name;
15695 size_t namelen;
15696 char * qualified_name;
15697
15698 /* Read the next archive header. */
15699 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
15700 {
15701 error (_("%s: failed to seek to next archive header\n"), file_name);
15702 return 1;
15703 }
15704 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
15705 if (got != sizeof arch.arhdr)
15706 {
15707 if (got == 0)
15708 break;
15709 error (_("%s: failed to read archive header\n"), file_name);
15710 ret = 1;
15711 break;
15712 }
15713 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
15714 {
15715 error (_("%s: did not find a valid archive header\n"), arch.file_name);
15716 ret = 1;
15717 break;
15718 }
15719
15720 arch.next_arhdr_offset += sizeof arch.arhdr;
15721
15722 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
15723 if (archive_file_size & 01)
15724 ++archive_file_size;
15725
15726 name = get_archive_member_name (&arch, &nested_arch);
15727 if (name == NULL)
fb52b2f4 15728 {
0fd3a477 15729 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15730 ret = 1;
15731 break;
fb52b2f4 15732 }
2cf0635d 15733 namelen = strlen (name);
fb52b2f4 15734
2cf0635d
NC
15735 qualified_name = make_qualified_name (&arch, &nested_arch, name);
15736 if (qualified_name == NULL)
fb52b2f4 15737 {
2cf0635d 15738 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15739 ret = 1;
15740 break;
fb52b2f4
NC
15741 }
15742
2cf0635d
NC
15743 if (is_thin_archive && arch.nested_member_origin == 0)
15744 {
15745 /* This is a proxy for an external member of a thin archive. */
15746 FILE * member_file;
15747 char * member_file_name = adjust_relative_path (file_name, name, namelen);
15748 if (member_file_name == NULL)
15749 {
15750 ret = 1;
15751 break;
15752 }
15753
15754 member_file = fopen (member_file_name, "rb");
15755 if (member_file == NULL)
15756 {
15757 error (_("Input file '%s' is not readable.\n"), member_file_name);
15758 free (member_file_name);
15759 ret = 1;
15760 break;
15761 }
15762
15763 archive_file_offset = arch.nested_member_origin;
15764
15765 ret |= process_object (qualified_name, member_file);
15766
15767 fclose (member_file);
15768 free (member_file_name);
15769 }
15770 else if (is_thin_archive)
15771 {
a043396b
NC
15772 /* PR 15140: Allow for corrupt thin archives. */
15773 if (nested_arch.file == NULL)
15774 {
15775 error (_("%s: contains corrupt thin archive: %s\n"),
15776 file_name, name);
15777 ret = 1;
15778 break;
15779 }
15780
2cf0635d
NC
15781 /* This is a proxy for a member of a nested archive. */
15782 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
15783
15784 /* The nested archive file will have been opened and setup by
15785 get_archive_member_name. */
15786 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
15787 {
15788 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
15789 ret = 1;
15790 break;
15791 }
15792
15793 ret |= process_object (qualified_name, nested_arch.file);
15794 }
15795 else
15796 {
15797 archive_file_offset = arch.next_arhdr_offset;
15798 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 15799
2cf0635d
NC
15800 ret |= process_object (qualified_name, file);
15801 }
fb52b2f4 15802
2b52916e
L
15803 if (dump_sects != NULL)
15804 {
15805 free (dump_sects);
15806 dump_sects = NULL;
15807 num_dump_sects = 0;
15808 }
15809
2cf0635d 15810 free (qualified_name);
fb52b2f4
NC
15811 }
15812
4145f1d5 15813 out:
2cf0635d
NC
15814 if (nested_arch.file != NULL)
15815 fclose (nested_arch.file);
15816 release_archive (&nested_arch);
15817 release_archive (&arch);
fb52b2f4 15818
d989285c 15819 return ret;
fb52b2f4
NC
15820}
15821
15822static int
2cf0635d 15823process_file (char * file_name)
fb52b2f4 15824{
2cf0635d 15825 FILE * file;
fb52b2f4
NC
15826 struct stat statbuf;
15827 char armag[SARMAG];
15828 int ret;
15829
15830 if (stat (file_name, &statbuf) < 0)
15831 {
f24ddbdd
NC
15832 if (errno == ENOENT)
15833 error (_("'%s': No such file\n"), file_name);
15834 else
15835 error (_("Could not locate '%s'. System error message: %s\n"),
15836 file_name, strerror (errno));
15837 return 1;
15838 }
15839
15840 if (! S_ISREG (statbuf.st_mode))
15841 {
15842 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
15843 return 1;
15844 }
15845
15846 file = fopen (file_name, "rb");
15847 if (file == NULL)
15848 {
f24ddbdd 15849 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
15850 return 1;
15851 }
15852
15853 if (fread (armag, SARMAG, 1, file) != 1)
15854 {
4145f1d5 15855 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
15856 fclose (file);
15857 return 1;
15858 }
15859
f54498b4
NC
15860 current_file_size = (bfd_size_type) statbuf.st_size;
15861
fb52b2f4 15862 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
15863 ret = process_archive (file_name, file, FALSE);
15864 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
15865 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
15866 else
15867 {
4145f1d5
NC
15868 if (do_archive_index)
15869 error (_("File %s is not an archive so its index cannot be displayed.\n"),
15870 file_name);
15871
fb52b2f4
NC
15872 rewind (file);
15873 archive_file_size = archive_file_offset = 0;
15874 ret = process_object (file_name, file);
15875 }
15876
15877 fclose (file);
15878
f54498b4 15879 current_file_size = 0;
fb52b2f4
NC
15880 return ret;
15881}
15882
252b5132
RH
15883#ifdef SUPPORT_DISASSEMBLY
15884/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 15885 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 15886 symbols. */
252b5132
RH
15887
15888void
2cf0635d 15889print_address (unsigned int addr, FILE * outfile)
252b5132
RH
15890{
15891 fprintf (outfile,"0x%8.8x", addr);
15892}
15893
e3c8793a 15894/* Needed by the i386 disassembler. */
252b5132
RH
15895void
15896db_task_printsym (unsigned int addr)
15897{
15898 print_address (addr, stderr);
15899}
15900#endif
15901
15902int
2cf0635d 15903main (int argc, char ** argv)
252b5132 15904{
ff78d6d6
L
15905 int err;
15906
252b5132
RH
15907#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
15908 setlocale (LC_MESSAGES, "");
3882b010
L
15909#endif
15910#if defined (HAVE_SETLOCALE)
15911 setlocale (LC_CTYPE, "");
252b5132
RH
15912#endif
15913 bindtextdomain (PACKAGE, LOCALEDIR);
15914 textdomain (PACKAGE);
15915
869b9d07
MM
15916 expandargv (&argc, &argv);
15917
252b5132
RH
15918 parse_args (argc, argv);
15919
18bd398b 15920 if (num_dump_sects > 0)
59f14fc0 15921 {
18bd398b 15922 /* Make a copy of the dump_sects array. */
3f5e193b
NC
15923 cmdline_dump_sects = (dump_type *)
15924 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 15925 if (cmdline_dump_sects == NULL)
591a748a 15926 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
15927 else
15928 {
09c11c86
NC
15929 memcpy (cmdline_dump_sects, dump_sects,
15930 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
15931 num_cmdline_dump_sects = num_dump_sects;
15932 }
15933 }
15934
18bd398b
NC
15935 if (optind < (argc - 1))
15936 show_name = 1;
15937
ff78d6d6 15938 err = 0;
252b5132 15939 while (optind < argc)
18bd398b 15940 err |= process_file (argv[optind++]);
252b5132
RH
15941
15942 if (dump_sects != NULL)
15943 free (dump_sects);
59f14fc0
AS
15944 if (cmdline_dump_sects != NULL)
15945 free (cmdline_dump_sects);
252b5132 15946
ff78d6d6 15947 return err;
252b5132 15948}