]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Fixes "readelf -s --wide" not returning an error status or help message.
[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 /* Now handle EABI specific flags. */
2284 switch (eabi)
2285 {
2286 default:
2c71103e 2287 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2288 if (e_flags)
2289 unknown = 1;
2290 break;
2291
2292 case EF_ARM_EABI_VER1:
a5bcd848 2293 strcat (buf, ", Version1 EABI");
f3485b74
NC
2294 while (e_flags)
2295 {
2296 unsigned flag;
76da6bbe 2297
f3485b74
NC
2298 /* Process flags one bit at a time. */
2299 flag = e_flags & - e_flags;
2300 e_flags &= ~ flag;
76da6bbe 2301
f3485b74
NC
2302 switch (flag)
2303 {
a5bcd848 2304 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2305 strcat (buf, ", sorted symbol tables");
2306 break;
76da6bbe 2307
f3485b74
NC
2308 default:
2309 unknown = 1;
2310 break;
2311 }
2312 }
2313 break;
76da6bbe 2314
a5bcd848
PB
2315 case EF_ARM_EABI_VER2:
2316 strcat (buf, ", Version2 EABI");
2317 while (e_flags)
2318 {
2319 unsigned flag;
2320
2321 /* Process flags one bit at a time. */
2322 flag = e_flags & - e_flags;
2323 e_flags &= ~ flag;
2324
2325 switch (flag)
2326 {
2327 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2328 strcat (buf, ", sorted symbol tables");
2329 break;
2330
2331 case EF_ARM_DYNSYMSUSESEGIDX:
2332 strcat (buf, ", dynamic symbols use segment index");
2333 break;
2334
2335 case EF_ARM_MAPSYMSFIRST:
2336 strcat (buf, ", mapping symbols precede others");
2337 break;
2338
2339 default:
2340 unknown = 1;
2341 break;
2342 }
2343 }
2344 break;
2345
d507cf36
PB
2346 case EF_ARM_EABI_VER3:
2347 strcat (buf, ", Version3 EABI");
8cb51566
PB
2348 break;
2349
2350 case EF_ARM_EABI_VER4:
2351 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2352 while (e_flags)
2353 {
2354 unsigned flag;
2355
2356 /* Process flags one bit at a time. */
2357 flag = e_flags & - e_flags;
2358 e_flags &= ~ flag;
2359
2360 switch (flag)
2361 {
2362 case EF_ARM_BE8:
2363 strcat (buf, ", BE8");
2364 break;
2365
2366 case EF_ARM_LE8:
2367 strcat (buf, ", LE8");
2368 break;
2369
2370 default:
2371 unknown = 1;
2372 break;
2373 }
2374 break;
2375 }
2376 break;
3a4a14e9
PB
2377
2378 case EF_ARM_EABI_VER5:
2379 strcat (buf, ", Version5 EABI");
d507cf36
PB
2380 while (e_flags)
2381 {
2382 unsigned flag;
2383
2384 /* Process flags one bit at a time. */
2385 flag = e_flags & - e_flags;
2386 e_flags &= ~ flag;
2387
2388 switch (flag)
2389 {
2390 case EF_ARM_BE8:
2391 strcat (buf, ", BE8");
2392 break;
2393
2394 case EF_ARM_LE8:
2395 strcat (buf, ", LE8");
2396 break;
2397
3bfcb652
NC
2398 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2399 strcat (buf, ", soft-float ABI");
2400 break;
2401
2402 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2403 strcat (buf, ", hard-float ABI");
2404 break;
2405
d507cf36
PB
2406 default:
2407 unknown = 1;
2408 break;
2409 }
2410 }
2411 break;
2412
f3485b74 2413 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2414 strcat (buf, ", GNU EABI");
f3485b74
NC
2415 while (e_flags)
2416 {
2417 unsigned flag;
76da6bbe 2418
f3485b74
NC
2419 /* Process flags one bit at a time. */
2420 flag = e_flags & - e_flags;
2421 e_flags &= ~ flag;
76da6bbe 2422
f3485b74
NC
2423 switch (flag)
2424 {
a5bcd848 2425 case EF_ARM_INTERWORK:
f3485b74
NC
2426 strcat (buf, ", interworking enabled");
2427 break;
76da6bbe 2428
a5bcd848 2429 case EF_ARM_APCS_26:
f3485b74
NC
2430 strcat (buf, ", uses APCS/26");
2431 break;
76da6bbe 2432
a5bcd848 2433 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2434 strcat (buf, ", uses APCS/float");
2435 break;
76da6bbe 2436
a5bcd848 2437 case EF_ARM_PIC:
f3485b74
NC
2438 strcat (buf, ", position independent");
2439 break;
76da6bbe 2440
a5bcd848 2441 case EF_ARM_ALIGN8:
f3485b74
NC
2442 strcat (buf, ", 8 bit structure alignment");
2443 break;
76da6bbe 2444
a5bcd848 2445 case EF_ARM_NEW_ABI:
f3485b74
NC
2446 strcat (buf, ", uses new ABI");
2447 break;
76da6bbe 2448
a5bcd848 2449 case EF_ARM_OLD_ABI:
f3485b74
NC
2450 strcat (buf, ", uses old ABI");
2451 break;
76da6bbe 2452
a5bcd848 2453 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2454 strcat (buf, ", software FP");
2455 break;
76da6bbe 2456
90e01f86
ILT
2457 case EF_ARM_VFP_FLOAT:
2458 strcat (buf, ", VFP");
2459 break;
2460
fde78edd
NC
2461 case EF_ARM_MAVERICK_FLOAT:
2462 strcat (buf, ", Maverick FP");
2463 break;
2464
f3485b74
NC
2465 default:
2466 unknown = 1;
2467 break;
2468 }
2469 }
2470 }
f3485b74
NC
2471
2472 if (unknown)
2b692964 2473 strcat (buf,_(", <unknown>"));
f3485b74
NC
2474}
2475
343433df
AB
2476static void
2477decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2478{
2479 --size; /* Leave space for null terminator. */
2480
2481 switch (e_flags & EF_AVR_MACH)
2482 {
2483 case E_AVR_MACH_AVR1:
2484 strncat (buf, ", avr:1", size);
2485 break;
2486 case E_AVR_MACH_AVR2:
2487 strncat (buf, ", avr:2", size);
2488 break;
2489 case E_AVR_MACH_AVR25:
2490 strncat (buf, ", avr:25", size);
2491 break;
2492 case E_AVR_MACH_AVR3:
2493 strncat (buf, ", avr:3", size);
2494 break;
2495 case E_AVR_MACH_AVR31:
2496 strncat (buf, ", avr:31", size);
2497 break;
2498 case E_AVR_MACH_AVR35:
2499 strncat (buf, ", avr:35", size);
2500 break;
2501 case E_AVR_MACH_AVR4:
2502 strncat (buf, ", avr:4", size);
2503 break;
2504 case E_AVR_MACH_AVR5:
2505 strncat (buf, ", avr:5", size);
2506 break;
2507 case E_AVR_MACH_AVR51:
2508 strncat (buf, ", avr:51", size);
2509 break;
2510 case E_AVR_MACH_AVR6:
2511 strncat (buf, ", avr:6", size);
2512 break;
2513 case E_AVR_MACH_AVRTINY:
2514 strncat (buf, ", avr:100", size);
2515 break;
2516 case E_AVR_MACH_XMEGA1:
2517 strncat (buf, ", avr:101", size);
2518 break;
2519 case E_AVR_MACH_XMEGA2:
2520 strncat (buf, ", avr:102", size);
2521 break;
2522 case E_AVR_MACH_XMEGA3:
2523 strncat (buf, ", avr:103", size);
2524 break;
2525 case E_AVR_MACH_XMEGA4:
2526 strncat (buf, ", avr:104", size);
2527 break;
2528 case E_AVR_MACH_XMEGA5:
2529 strncat (buf, ", avr:105", size);
2530 break;
2531 case E_AVR_MACH_XMEGA6:
2532 strncat (buf, ", avr:106", size);
2533 break;
2534 case E_AVR_MACH_XMEGA7:
2535 strncat (buf, ", avr:107", size);
2536 break;
2537 default:
2538 strncat (buf, ", avr:<unknown>", size);
2539 break;
2540 }
2541
2542 size -= strlen (buf);
2543 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2544 strncat (buf, ", link-relax", size);
2545}
2546
35c08157
KLC
2547static void
2548decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2549{
2550 unsigned abi;
2551 unsigned arch;
2552 unsigned config;
2553 unsigned version;
2554 int has_fpu = 0;
2555 int r = 0;
2556
2557 static const char *ABI_STRINGS[] =
2558 {
2559 "ABI v0", /* use r5 as return register; only used in N1213HC */
2560 "ABI v1", /* use r0 as return register */
2561 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2562 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2563 "AABI",
2564 "ABI2 FP+"
35c08157
KLC
2565 };
2566 static const char *VER_STRINGS[] =
2567 {
2568 "Andes ELF V1.3 or older",
2569 "Andes ELF V1.3.1",
2570 "Andes ELF V1.4"
2571 };
2572 static const char *ARCH_STRINGS[] =
2573 {
2574 "",
2575 "Andes Star v1.0",
2576 "Andes Star v2.0",
2577 "Andes Star v3.0",
2578 "Andes Star v3.0m"
2579 };
2580
2581 abi = EF_NDS_ABI & e_flags;
2582 arch = EF_NDS_ARCH & e_flags;
2583 config = EF_NDS_INST & e_flags;
2584 version = EF_NDS32_ELF_VERSION & e_flags;
2585
2586 memset (buf, 0, size);
2587
2588 switch (abi)
2589 {
2590 case E_NDS_ABI_V0:
2591 case E_NDS_ABI_V1:
2592 case E_NDS_ABI_V2:
2593 case E_NDS_ABI_V2FP:
2594 case E_NDS_ABI_AABI:
40c7a7cb 2595 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2596 /* In case there are holes in the array. */
2597 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2598 break;
2599
2600 default:
2601 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2602 break;
2603 }
2604
2605 switch (version)
2606 {
2607 case E_NDS32_ELF_VER_1_2:
2608 case E_NDS32_ELF_VER_1_3:
2609 case E_NDS32_ELF_VER_1_4:
2610 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2611 break;
2612
2613 default:
2614 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2615 break;
2616 }
2617
2618 if (E_NDS_ABI_V0 == abi)
2619 {
2620 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2621 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2622 if (arch == E_NDS_ARCH_STAR_V1_0)
2623 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2624 return;
2625 }
2626
2627 switch (arch)
2628 {
2629 case E_NDS_ARCH_STAR_V1_0:
2630 case E_NDS_ARCH_STAR_V2_0:
2631 case E_NDS_ARCH_STAR_V3_0:
2632 case E_NDS_ARCH_STAR_V3_M:
2633 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2634 break;
2635
2636 default:
2637 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2638 /* ARCH version determines how the e_flags are interpreted.
2639 If it is unknown, we cannot proceed. */
2640 return;
2641 }
2642
2643 /* Newer ABI; Now handle architecture specific flags. */
2644 if (arch == E_NDS_ARCH_STAR_V1_0)
2645 {
2646 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2647 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2648
2649 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2650 r += snprintf (buf + r, size -r, ", MAC");
2651
2652 if (config & E_NDS32_HAS_DIV_INST)
2653 r += snprintf (buf + r, size -r, ", DIV");
2654
2655 if (config & E_NDS32_HAS_16BIT_INST)
2656 r += snprintf (buf + r, size -r, ", 16b");
2657 }
2658 else
2659 {
2660 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2661 {
2662 if (version <= E_NDS32_ELF_VER_1_3)
2663 r += snprintf (buf + r, size -r, ", [B8]");
2664 else
2665 r += snprintf (buf + r, size -r, ", EX9");
2666 }
2667
2668 if (config & E_NDS32_HAS_MAC_DX_INST)
2669 r += snprintf (buf + r, size -r, ", MAC_DX");
2670
2671 if (config & E_NDS32_HAS_DIV_DX_INST)
2672 r += snprintf (buf + r, size -r, ", DIV_DX");
2673
2674 if (config & E_NDS32_HAS_16BIT_INST)
2675 {
2676 if (version <= E_NDS32_ELF_VER_1_3)
2677 r += snprintf (buf + r, size -r, ", 16b");
2678 else
2679 r += snprintf (buf + r, size -r, ", IFC");
2680 }
2681 }
2682
2683 if (config & E_NDS32_HAS_EXT_INST)
2684 r += snprintf (buf + r, size -r, ", PERF1");
2685
2686 if (config & E_NDS32_HAS_EXT2_INST)
2687 r += snprintf (buf + r, size -r, ", PERF2");
2688
2689 if (config & E_NDS32_HAS_FPU_INST)
2690 {
2691 has_fpu = 1;
2692 r += snprintf (buf + r, size -r, ", FPU_SP");
2693 }
2694
2695 if (config & E_NDS32_HAS_FPU_DP_INST)
2696 {
2697 has_fpu = 1;
2698 r += snprintf (buf + r, size -r, ", FPU_DP");
2699 }
2700
2701 if (config & E_NDS32_HAS_FPU_MAC_INST)
2702 {
2703 has_fpu = 1;
2704 r += snprintf (buf + r, size -r, ", FPU_MAC");
2705 }
2706
2707 if (has_fpu)
2708 {
2709 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2710 {
2711 case E_NDS32_FPU_REG_8SP_4DP:
2712 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2713 break;
2714 case E_NDS32_FPU_REG_16SP_8DP:
2715 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2716 break;
2717 case E_NDS32_FPU_REG_32SP_16DP:
2718 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2719 break;
2720 case E_NDS32_FPU_REG_32SP_32DP:
2721 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
2722 break;
2723 }
2724 }
2725
2726 if (config & E_NDS32_HAS_AUDIO_INST)
2727 r += snprintf (buf + r, size -r, ", AUDIO");
2728
2729 if (config & E_NDS32_HAS_STRING_INST)
2730 r += snprintf (buf + r, size -r, ", STR");
2731
2732 if (config & E_NDS32_HAS_REDUCED_REGS)
2733 r += snprintf (buf + r, size -r, ", 16REG");
2734
2735 if (config & E_NDS32_HAS_VIDEO_INST)
2736 {
2737 if (version <= E_NDS32_ELF_VER_1_3)
2738 r += snprintf (buf + r, size -r, ", VIDEO");
2739 else
2740 r += snprintf (buf + r, size -r, ", SATURATION");
2741 }
2742
2743 if (config & E_NDS32_HAS_ENCRIPT_INST)
2744 r += snprintf (buf + r, size -r, ", ENCRP");
2745
2746 if (config & E_NDS32_HAS_L2C_INST)
2747 r += snprintf (buf + r, size -r, ", L2C");
2748}
2749
252b5132 2750static char *
d3ba0551 2751get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2752{
b34976b6 2753 static char buf[1024];
252b5132
RH
2754
2755 buf[0] = '\0';
76da6bbe 2756
252b5132
RH
2757 if (e_flags)
2758 {
2759 switch (e_machine)
2760 {
2761 default:
2762 break;
2763
f3485b74
NC
2764 case EM_ARM:
2765 decode_ARM_machine_flags (e_flags, buf);
2766 break;
76da6bbe 2767
343433df
AB
2768 case EM_AVR:
2769 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
2770 break;
2771
781303ce
MF
2772 case EM_BLACKFIN:
2773 if (e_flags & EF_BFIN_PIC)
2774 strcat (buf, ", PIC");
2775
2776 if (e_flags & EF_BFIN_FDPIC)
2777 strcat (buf, ", FDPIC");
2778
2779 if (e_flags & EF_BFIN_CODE_IN_L1)
2780 strcat (buf, ", code in L1");
2781
2782 if (e_flags & EF_BFIN_DATA_IN_L1)
2783 strcat (buf, ", data in L1");
2784
2785 break;
2786
ec2dfb42
AO
2787 case EM_CYGNUS_FRV:
2788 switch (e_flags & EF_FRV_CPU_MASK)
2789 {
2790 case EF_FRV_CPU_GENERIC:
2791 break;
2792
2793 default:
2794 strcat (buf, ", fr???");
2795 break;
57346661 2796
ec2dfb42
AO
2797 case EF_FRV_CPU_FR300:
2798 strcat (buf, ", fr300");
2799 break;
2800
2801 case EF_FRV_CPU_FR400:
2802 strcat (buf, ", fr400");
2803 break;
2804 case EF_FRV_CPU_FR405:
2805 strcat (buf, ", fr405");
2806 break;
2807
2808 case EF_FRV_CPU_FR450:
2809 strcat (buf, ", fr450");
2810 break;
2811
2812 case EF_FRV_CPU_FR500:
2813 strcat (buf, ", fr500");
2814 break;
2815 case EF_FRV_CPU_FR550:
2816 strcat (buf, ", fr550");
2817 break;
2818
2819 case EF_FRV_CPU_SIMPLE:
2820 strcat (buf, ", simple");
2821 break;
2822 case EF_FRV_CPU_TOMCAT:
2823 strcat (buf, ", tomcat");
2824 break;
2825 }
1c877e87 2826 break;
ec2dfb42 2827
53c7db4b 2828 case EM_68K:
425c6cb0 2829 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2830 strcat (buf, ", m68000");
425c6cb0 2831 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2832 strcat (buf, ", cpu32");
2833 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2834 strcat (buf, ", fido_a");
425c6cb0 2835 else
266abb8f 2836 {
2cf0635d
NC
2837 char const * isa = _("unknown");
2838 char const * mac = _("unknown mac");
2839 char const * additional = NULL;
0112cd26 2840
c694fd50 2841 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2842 {
c694fd50 2843 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2844 isa = "A";
2845 additional = ", nodiv";
2846 break;
c694fd50 2847 case EF_M68K_CF_ISA_A:
266abb8f
NS
2848 isa = "A";
2849 break;
c694fd50 2850 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2851 isa = "A+";
2852 break;
c694fd50 2853 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2854 isa = "B";
2855 additional = ", nousp";
2856 break;
c694fd50 2857 case EF_M68K_CF_ISA_B:
266abb8f
NS
2858 isa = "B";
2859 break;
f608cd77
NS
2860 case EF_M68K_CF_ISA_C:
2861 isa = "C";
2862 break;
2863 case EF_M68K_CF_ISA_C_NODIV:
2864 isa = "C";
2865 additional = ", nodiv";
2866 break;
266abb8f
NS
2867 }
2868 strcat (buf, ", cf, isa ");
2869 strcat (buf, isa);
0b2e31dc
NS
2870 if (additional)
2871 strcat (buf, additional);
c694fd50 2872 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2873 strcat (buf, ", float");
c694fd50 2874 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2875 {
2876 case 0:
2877 mac = NULL;
2878 break;
c694fd50 2879 case EF_M68K_CF_MAC:
266abb8f
NS
2880 mac = "mac";
2881 break;
c694fd50 2882 case EF_M68K_CF_EMAC:
266abb8f
NS
2883 mac = "emac";
2884 break;
f608cd77
NS
2885 case EF_M68K_CF_EMAC_B:
2886 mac = "emac_b";
2887 break;
266abb8f
NS
2888 }
2889 if (mac)
2890 {
2891 strcat (buf, ", ");
2892 strcat (buf, mac);
2893 }
266abb8f 2894 }
53c7db4b 2895 break;
33c63f9d 2896
252b5132
RH
2897 case EM_PPC:
2898 if (e_flags & EF_PPC_EMB)
2899 strcat (buf, ", emb");
2900
2901 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2902 strcat (buf, _(", relocatable"));
252b5132
RH
2903
2904 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2905 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2906 break;
2907
ee67d69a
AM
2908 case EM_PPC64:
2909 if (e_flags & EF_PPC64_ABI)
2910 {
2911 char abi[] = ", abiv0";
2912
2913 abi[6] += e_flags & EF_PPC64_ABI;
2914 strcat (buf, abi);
2915 }
2916 break;
2917
708e2187
NC
2918 case EM_V800:
2919 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2920 strcat (buf, ", RH850 ABI");
0b4362b0 2921
708e2187
NC
2922 if (e_flags & EF_V800_850E3)
2923 strcat (buf, ", V3 architecture");
2924
2925 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2926 strcat (buf, ", FPU not used");
2927
2928 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2929 strcat (buf, ", regmode: COMMON");
2930
2931 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2932 strcat (buf, ", r4 not used");
2933
2934 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2935 strcat (buf, ", r30 not used");
2936
2937 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2938 strcat (buf, ", r5 not used");
2939
2940 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2941 strcat (buf, ", r2 not used");
2942
2943 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2944 {
2945 switch (e_flags & - e_flags)
2946 {
2947 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2948 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
2949 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2950 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
2951 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2952 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2953 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2954 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2955 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2956 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2957 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2958 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2959 default: break;
2960 }
2961 }
2962 break;
2963
2b0337b0 2964 case EM_V850:
252b5132
RH
2965 case EM_CYGNUS_V850:
2966 switch (e_flags & EF_V850_ARCH)
2967 {
78c8d46c
NC
2968 case E_V850E3V5_ARCH:
2969 strcat (buf, ", v850e3v5");
2970 break;
1cd986c5
NC
2971 case E_V850E2V3_ARCH:
2972 strcat (buf, ", v850e2v3");
2973 break;
2974 case E_V850E2_ARCH:
2975 strcat (buf, ", v850e2");
2976 break;
2977 case E_V850E1_ARCH:
2978 strcat (buf, ", v850e1");
8ad30312 2979 break;
252b5132
RH
2980 case E_V850E_ARCH:
2981 strcat (buf, ", v850e");
2982 break;
252b5132
RH
2983 case E_V850_ARCH:
2984 strcat (buf, ", v850");
2985 break;
2986 default:
2b692964 2987 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2988 break;
2989 }
2990 break;
2991
2b0337b0 2992 case EM_M32R:
252b5132
RH
2993 case EM_CYGNUS_M32R:
2994 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2995 strcat (buf, ", m32r");
252b5132
RH
2996 break;
2997
2998 case EM_MIPS:
4fe85591 2999 case EM_MIPS_RS3_LE:
252b5132
RH
3000 if (e_flags & EF_MIPS_NOREORDER)
3001 strcat (buf, ", noreorder");
3002
3003 if (e_flags & EF_MIPS_PIC)
3004 strcat (buf, ", pic");
3005
3006 if (e_flags & EF_MIPS_CPIC)
3007 strcat (buf, ", cpic");
3008
d1bdd336
TS
3009 if (e_flags & EF_MIPS_UCODE)
3010 strcat (buf, ", ugen_reserved");
3011
252b5132
RH
3012 if (e_flags & EF_MIPS_ABI2)
3013 strcat (buf, ", abi2");
3014
43521d43
TS
3015 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3016 strcat (buf, ", odk first");
3017
a5d22d2a
TS
3018 if (e_flags & EF_MIPS_32BITMODE)
3019 strcat (buf, ", 32bitmode");
3020
ba92f887
MR
3021 if (e_flags & EF_MIPS_NAN2008)
3022 strcat (buf, ", nan2008");
3023
fef1b0b3
SE
3024 if (e_flags & EF_MIPS_FP64)
3025 strcat (buf, ", fp64");
3026
156c2f8b
NC
3027 switch ((e_flags & EF_MIPS_MACH))
3028 {
3029 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3030 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3031 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3032 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3033 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3034 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3035 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3036 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 3037 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3038 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3039 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3040 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 3041 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 3042 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3043 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3044 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3045 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
3046 case 0:
3047 /* We simply ignore the field in this case to avoid confusion:
3048 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3049 extension. */
3050 break;
2b692964 3051 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3052 }
43521d43
TS
3053
3054 switch ((e_flags & EF_MIPS_ABI))
3055 {
3056 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3057 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3058 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3059 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3060 case 0:
3061 /* We simply ignore the field in this case to avoid confusion:
3062 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3063 This means it is likely to be an o32 file, but not for
3064 sure. */
3065 break;
2b692964 3066 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3067 }
3068
3069 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3070 strcat (buf, ", mdmx");
3071
3072 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3073 strcat (buf, ", mips16");
3074
df58fc94
RS
3075 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3076 strcat (buf, ", micromips");
3077
43521d43
TS
3078 switch ((e_flags & EF_MIPS_ARCH))
3079 {
3080 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3081 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3082 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3083 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3084 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3085 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3086 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3087 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3088 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3089 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3090 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3091 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3092 }
252b5132 3093 break;
351b4b40 3094
35c08157
KLC
3095 case EM_NDS32:
3096 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3097 break;
3098
ccde1100
AO
3099 case EM_SH:
3100 switch ((e_flags & EF_SH_MACH_MASK))
3101 {
3102 case EF_SH1: strcat (buf, ", sh1"); break;
3103 case EF_SH2: strcat (buf, ", sh2"); break;
3104 case EF_SH3: strcat (buf, ", sh3"); break;
3105 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3106 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3107 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3108 case EF_SH3E: strcat (buf, ", sh3e"); break;
3109 case EF_SH4: strcat (buf, ", sh4"); break;
3110 case EF_SH5: strcat (buf, ", sh5"); break;
3111 case EF_SH2E: strcat (buf, ", sh2e"); break;
3112 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3113 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3114 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3115 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3116 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3117 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3118 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3119 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3120 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3121 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3122 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3123 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3124 }
3125
cec6a5b8
MR
3126 if (e_flags & EF_SH_PIC)
3127 strcat (buf, ", pic");
3128
3129 if (e_flags & EF_SH_FDPIC)
3130 strcat (buf, ", fdpic");
ccde1100 3131 break;
948f632f 3132
73589c9d
CS
3133 case EM_OR1K:
3134 if (e_flags & EF_OR1K_NODELAY)
3135 strcat (buf, ", no delay");
3136 break;
57346661 3137
351b4b40
RH
3138 case EM_SPARCV9:
3139 if (e_flags & EF_SPARC_32PLUS)
3140 strcat (buf, ", v8+");
3141
3142 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3143 strcat (buf, ", ultrasparcI");
3144
3145 if (e_flags & EF_SPARC_SUN_US3)
3146 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3147
3148 if (e_flags & EF_SPARC_HAL_R1)
3149 strcat (buf, ", halr1");
3150
3151 if (e_flags & EF_SPARC_LEDATA)
3152 strcat (buf, ", ledata");
3153
3154 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3155 strcat (buf, ", tso");
3156
3157 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3158 strcat (buf, ", pso");
3159
3160 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3161 strcat (buf, ", rmo");
3162 break;
7d466069 3163
103f02d3
UD
3164 case EM_PARISC:
3165 switch (e_flags & EF_PARISC_ARCH)
3166 {
3167 case EFA_PARISC_1_0:
3168 strcpy (buf, ", PA-RISC 1.0");
3169 break;
3170 case EFA_PARISC_1_1:
3171 strcpy (buf, ", PA-RISC 1.1");
3172 break;
3173 case EFA_PARISC_2_0:
3174 strcpy (buf, ", PA-RISC 2.0");
3175 break;
3176 default:
3177 break;
3178 }
3179 if (e_flags & EF_PARISC_TRAPNIL)
3180 strcat (buf, ", trapnil");
3181 if (e_flags & EF_PARISC_EXT)
3182 strcat (buf, ", ext");
3183 if (e_flags & EF_PARISC_LSB)
3184 strcat (buf, ", lsb");
3185 if (e_flags & EF_PARISC_WIDE)
3186 strcat (buf, ", wide");
3187 if (e_flags & EF_PARISC_NO_KABP)
3188 strcat (buf, ", no kabp");
3189 if (e_flags & EF_PARISC_LAZYSWAP)
3190 strcat (buf, ", lazyswap");
30800947 3191 break;
76da6bbe 3192
7d466069 3193 case EM_PJ:
2b0337b0 3194 case EM_PJ_OLD:
7d466069
ILT
3195 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3196 strcat (buf, ", new calling convention");
3197
3198 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3199 strcat (buf, ", gnu calling convention");
3200 break;
4d6ed7c8
NC
3201
3202 case EM_IA_64:
3203 if ((e_flags & EF_IA_64_ABI64))
3204 strcat (buf, ", 64-bit");
3205 else
3206 strcat (buf, ", 32-bit");
3207 if ((e_flags & EF_IA_64_REDUCEDFP))
3208 strcat (buf, ", reduced fp model");
3209 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3210 strcat (buf, ", no function descriptors, constant gp");
3211 else if ((e_flags & EF_IA_64_CONS_GP))
3212 strcat (buf, ", constant gp");
3213 if ((e_flags & EF_IA_64_ABSOLUTE))
3214 strcat (buf, ", absolute");
28f997cf
TG
3215 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3216 {
3217 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3218 strcat (buf, ", vms_linkages");
3219 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3220 {
3221 case EF_IA_64_VMS_COMCOD_SUCCESS:
3222 break;
3223 case EF_IA_64_VMS_COMCOD_WARNING:
3224 strcat (buf, ", warning");
3225 break;
3226 case EF_IA_64_VMS_COMCOD_ERROR:
3227 strcat (buf, ", error");
3228 break;
3229 case EF_IA_64_VMS_COMCOD_ABORT:
3230 strcat (buf, ", abort");
3231 break;
3232 default:
bee0ee85
NC
3233 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3234 e_flags & EF_IA_64_VMS_COMCOD);
3235 strcat (buf, ", <unknown>");
28f997cf
TG
3236 }
3237 }
4d6ed7c8 3238 break;
179d3252
JT
3239
3240 case EM_VAX:
3241 if ((e_flags & EF_VAX_NONPIC))
3242 strcat (buf, ", non-PIC");
3243 if ((e_flags & EF_VAX_DFLOAT))
3244 strcat (buf, ", D-Float");
3245 if ((e_flags & EF_VAX_GFLOAT))
3246 strcat (buf, ", G-Float");
3247 break;
c7927a3c 3248
619ed720
EB
3249 case EM_VISIUM:
3250 if (e_flags & EF_VISIUM_ARCH_MCM)
3251 strcat (buf, ", mcm");
3252 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3253 strcat (buf, ", mcm24");
3254 if (e_flags & EF_VISIUM_ARCH_GR6)
3255 strcat (buf, ", gr6");
3256 break;
3257
4046d87a
NC
3258 case EM_RL78:
3259 if (e_flags & E_FLAG_RL78_G10)
3260 strcat (buf, ", G10");
856ea05c
KP
3261 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3262 strcat (buf, ", 64-bit doubles");
4046d87a 3263 break;
0b4362b0 3264
c7927a3c
NC
3265 case EM_RX:
3266 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3267 strcat (buf, ", 64-bit doubles");
3268 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3269 strcat (buf, ", dsp");
d4cb0ea0 3270 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3271 strcat (buf, ", pid");
708e2187
NC
3272 if (e_flags & E_FLAG_RX_ABI)
3273 strcat (buf, ", RX ABI");
d4cb0ea0 3274 break;
55786da2
AK
3275
3276 case EM_S390:
3277 if (e_flags & EF_S390_HIGH_GPRS)
3278 strcat (buf, ", highgprs");
d4cb0ea0 3279 break;
40b36596
JM
3280
3281 case EM_TI_C6000:
3282 if ((e_flags & EF_C6000_REL))
3283 strcat (buf, ", relocatable module");
d4cb0ea0 3284 break;
13761a11
NC
3285
3286 case EM_MSP430:
3287 strcat (buf, _(": architecture variant: "));
3288 switch (e_flags & EF_MSP430_MACH)
3289 {
3290 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3291 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3292 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3293 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3294 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3295 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3296 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3297 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3298 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3299 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3300 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3301 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3302 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3303 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3304 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3305 default:
3306 strcat (buf, _(": unknown")); break;
3307 }
3308
3309 if (e_flags & ~ EF_MSP430_MACH)
3310 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3311 }
3312 }
3313
3314 return buf;
3315}
3316
252b5132 3317static const char *
d3ba0551
AM
3318get_osabi_name (unsigned int osabi)
3319{
3320 static char buff[32];
3321
3322 switch (osabi)
3323 {
3324 case ELFOSABI_NONE: return "UNIX - System V";
3325 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3326 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3327 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3328 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3329 case ELFOSABI_AIX: return "UNIX - AIX";
3330 case ELFOSABI_IRIX: return "UNIX - IRIX";
3331 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3332 case ELFOSABI_TRU64: return "UNIX - TRU64";
3333 case ELFOSABI_MODESTO: return "Novell - Modesto";
3334 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3335 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3336 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3337 case ELFOSABI_AROS: return "AROS";
11636f9e 3338 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 3339 default:
40b36596
JM
3340 if (osabi >= 64)
3341 switch (elf_header.e_machine)
3342 {
3343 case EM_ARM:
3344 switch (osabi)
3345 {
3346 case ELFOSABI_ARM: return "ARM";
3347 default:
3348 break;
3349 }
3350 break;
3351
3352 case EM_MSP430:
3353 case EM_MSP430_OLD:
619ed720 3354 case EM_VISIUM:
40b36596
JM
3355 switch (osabi)
3356 {
3357 case ELFOSABI_STANDALONE: return _("Standalone App");
3358 default:
3359 break;
3360 }
3361 break;
3362
3363 case EM_TI_C6000:
3364 switch (osabi)
3365 {
3366 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3367 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3368 default:
3369 break;
3370 }
3371 break;
3372
3373 default:
3374 break;
3375 }
e9e44622 3376 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3377 return buff;
3378 }
3379}
3380
a06ea964
NC
3381static const char *
3382get_aarch64_segment_type (unsigned long type)
3383{
3384 switch (type)
3385 {
3386 case PT_AARCH64_ARCHEXT:
3387 return "AARCH64_ARCHEXT";
3388 default:
3389 break;
3390 }
3391
3392 return NULL;
3393}
3394
b294bdf8
MM
3395static const char *
3396get_arm_segment_type (unsigned long type)
3397{
3398 switch (type)
3399 {
3400 case PT_ARM_EXIDX:
3401 return "EXIDX";
3402 default:
3403 break;
3404 }
3405
3406 return NULL;
3407}
3408
d3ba0551
AM
3409static const char *
3410get_mips_segment_type (unsigned long type)
252b5132
RH
3411{
3412 switch (type)
3413 {
3414 case PT_MIPS_REGINFO:
3415 return "REGINFO";
3416 case PT_MIPS_RTPROC:
3417 return "RTPROC";
3418 case PT_MIPS_OPTIONS:
3419 return "OPTIONS";
351cdf24
MF
3420 case PT_MIPS_ABIFLAGS:
3421 return "ABIFLAGS";
252b5132
RH
3422 default:
3423 break;
3424 }
3425
3426 return NULL;
3427}
3428
103f02d3 3429static const char *
d3ba0551 3430get_parisc_segment_type (unsigned long type)
103f02d3
UD
3431{
3432 switch (type)
3433 {
3434 case PT_HP_TLS: return "HP_TLS";
3435 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3436 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3437 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3438 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3439 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3440 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3441 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3442 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3443 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3444 case PT_HP_PARALLEL: return "HP_PARALLEL";
3445 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3446 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3447 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3448 case PT_HP_STACK: return "HP_STACK";
3449 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3450 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3451 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3452 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
3453 default:
3454 break;
3455 }
3456
3457 return NULL;
3458}
3459
4d6ed7c8 3460static const char *
d3ba0551 3461get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3462{
3463 switch (type)
3464 {
3465 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3466 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3467 case PT_HP_TLS: return "HP_TLS";
3468 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3469 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3470 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3471 default:
3472 break;
3473 }
3474
3475 return NULL;
3476}
3477
40b36596
JM
3478static const char *
3479get_tic6x_segment_type (unsigned long type)
3480{
3481 switch (type)
3482 {
3483 case PT_C6000_PHATTR: return "C6000_PHATTR";
3484 default:
3485 break;
3486 }
3487
3488 return NULL;
3489}
3490
252b5132 3491static const char *
d3ba0551 3492get_segment_type (unsigned long p_type)
252b5132 3493{
b34976b6 3494 static char buff[32];
252b5132
RH
3495
3496 switch (p_type)
3497 {
b34976b6
AM
3498 case PT_NULL: return "NULL";
3499 case PT_LOAD: return "LOAD";
252b5132 3500 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3501 case PT_INTERP: return "INTERP";
3502 case PT_NOTE: return "NOTE";
3503 case PT_SHLIB: return "SHLIB";
3504 case PT_PHDR: return "PHDR";
13ae64f3 3505 case PT_TLS: return "TLS";
252b5132 3506
65765700
JJ
3507 case PT_GNU_EH_FRAME:
3508 return "GNU_EH_FRAME";
2b05f1b7 3509 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3510 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3511
252b5132
RH
3512 default:
3513 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3514 {
2cf0635d 3515 const char * result;
103f02d3 3516
252b5132
RH
3517 switch (elf_header.e_machine)
3518 {
a06ea964
NC
3519 case EM_AARCH64:
3520 result = get_aarch64_segment_type (p_type);
3521 break;
b294bdf8
MM
3522 case EM_ARM:
3523 result = get_arm_segment_type (p_type);
3524 break;
252b5132 3525 case EM_MIPS:
4fe85591 3526 case EM_MIPS_RS3_LE:
252b5132
RH
3527 result = get_mips_segment_type (p_type);
3528 break;
103f02d3
UD
3529 case EM_PARISC:
3530 result = get_parisc_segment_type (p_type);
3531 break;
4d6ed7c8
NC
3532 case EM_IA_64:
3533 result = get_ia64_segment_type (p_type);
3534 break;
40b36596
JM
3535 case EM_TI_C6000:
3536 result = get_tic6x_segment_type (p_type);
3537 break;
252b5132
RH
3538 default:
3539 result = NULL;
3540 break;
3541 }
103f02d3 3542
252b5132
RH
3543 if (result != NULL)
3544 return result;
103f02d3 3545
252b5132
RH
3546 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3547 }
3548 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3549 {
2cf0635d 3550 const char * result;
103f02d3
UD
3551
3552 switch (elf_header.e_machine)
3553 {
3554 case EM_PARISC:
3555 result = get_parisc_segment_type (p_type);
3556 break;
00428cca
AM
3557 case EM_IA_64:
3558 result = get_ia64_segment_type (p_type);
3559 break;
103f02d3
UD
3560 default:
3561 result = NULL;
3562 break;
3563 }
3564
3565 if (result != NULL)
3566 return result;
3567
3568 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3569 }
252b5132 3570 else
e9e44622 3571 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3572
3573 return buff;
3574 }
3575}
3576
3577static const char *
d3ba0551 3578get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3579{
3580 switch (sh_type)
3581 {
b34976b6
AM
3582 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3583 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3584 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3585 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3586 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3587 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3588 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3589 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3590 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3591 case SHT_MIPS_RELD: return "MIPS_RELD";
3592 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3593 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3594 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3595 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3596 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3597 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3598 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3599 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3600 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3601 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3602 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3603 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3604 case SHT_MIPS_LINE: return "MIPS_LINE";
3605 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3606 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3607 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3608 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3609 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3610 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3611 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3612 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3613 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3614 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3615 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3616 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3617 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3618 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3619 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 3620 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 3621 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
3622 default:
3623 break;
3624 }
3625 return NULL;
3626}
3627
103f02d3 3628static const char *
d3ba0551 3629get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3630{
3631 switch (sh_type)
3632 {
3633 case SHT_PARISC_EXT: return "PARISC_EXT";
3634 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3635 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3636 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3637 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3638 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3639 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3640 default:
3641 break;
3642 }
3643 return NULL;
3644}
3645
4d6ed7c8 3646static const char *
d3ba0551 3647get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3648{
18bd398b 3649 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3650 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3651 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3652
4d6ed7c8
NC
3653 switch (sh_type)
3654 {
148b93f2
NC
3655 case SHT_IA_64_EXT: return "IA_64_EXT";
3656 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3657 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3658 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3659 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3660 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3661 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3662 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3663 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3664 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3665 default:
3666 break;
3667 }
3668 return NULL;
3669}
3670
d2b2c203
DJ
3671static const char *
3672get_x86_64_section_type_name (unsigned int sh_type)
3673{
3674 switch (sh_type)
3675 {
3676 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3677 default:
3678 break;
3679 }
3680 return NULL;
3681}
3682
a06ea964
NC
3683static const char *
3684get_aarch64_section_type_name (unsigned int sh_type)
3685{
3686 switch (sh_type)
3687 {
3688 case SHT_AARCH64_ATTRIBUTES:
3689 return "AARCH64_ATTRIBUTES";
3690 default:
3691 break;
3692 }
3693 return NULL;
3694}
3695
40a18ebd
NC
3696static const char *
3697get_arm_section_type_name (unsigned int sh_type)
3698{
3699 switch (sh_type)
3700 {
7f6fed87
NC
3701 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3702 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3703 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3704 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3705 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3706 default:
3707 break;
3708 }
3709 return NULL;
3710}
3711
40b36596
JM
3712static const char *
3713get_tic6x_section_type_name (unsigned int sh_type)
3714{
3715 switch (sh_type)
3716 {
3717 case SHT_C6000_UNWIND:
3718 return "C6000_UNWIND";
3719 case SHT_C6000_PREEMPTMAP:
3720 return "C6000_PREEMPTMAP";
3721 case SHT_C6000_ATTRIBUTES:
3722 return "C6000_ATTRIBUTES";
3723 case SHT_TI_ICODE:
3724 return "TI_ICODE";
3725 case SHT_TI_XREF:
3726 return "TI_XREF";
3727 case SHT_TI_HANDLER:
3728 return "TI_HANDLER";
3729 case SHT_TI_INITINFO:
3730 return "TI_INITINFO";
3731 case SHT_TI_PHATTRS:
3732 return "TI_PHATTRS";
3733 default:
3734 break;
3735 }
3736 return NULL;
3737}
3738
13761a11
NC
3739static const char *
3740get_msp430x_section_type_name (unsigned int sh_type)
3741{
3742 switch (sh_type)
3743 {
3744 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3745 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3746 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3747 default: return NULL;
3748 }
3749}
3750
685080f2
NC
3751static const char *
3752get_v850_section_type_name (unsigned int sh_type)
3753{
3754 switch (sh_type)
3755 {
3756 case SHT_V850_SCOMMON: return "V850 Small Common";
3757 case SHT_V850_TCOMMON: return "V850 Tiny Common";
3758 case SHT_V850_ZCOMMON: return "V850 Zero Common";
3759 case SHT_RENESAS_IOP: return "RENESAS IOP";
3760 case SHT_RENESAS_INFO: return "RENESAS INFO";
3761 default: return NULL;
3762 }
3763}
3764
252b5132 3765static const char *
d3ba0551 3766get_section_type_name (unsigned int sh_type)
252b5132 3767{
b34976b6 3768 static char buff[32];
252b5132
RH
3769
3770 switch (sh_type)
3771 {
3772 case SHT_NULL: return "NULL";
3773 case SHT_PROGBITS: return "PROGBITS";
3774 case SHT_SYMTAB: return "SYMTAB";
3775 case SHT_STRTAB: return "STRTAB";
3776 case SHT_RELA: return "RELA";
3777 case SHT_HASH: return "HASH";
3778 case SHT_DYNAMIC: return "DYNAMIC";
3779 case SHT_NOTE: return "NOTE";
3780 case SHT_NOBITS: return "NOBITS";
3781 case SHT_REL: return "REL";
3782 case SHT_SHLIB: return "SHLIB";
3783 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3784 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3785 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3786 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3787 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3788 case SHT_GROUP: return "GROUP";
3789 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3790 case SHT_GNU_verdef: return "VERDEF";
3791 case SHT_GNU_verneed: return "VERNEED";
3792 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3793 case 0x6ffffff0: return "VERSYM";
3794 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3795 case 0x7ffffffd: return "AUXILIARY";
3796 case 0x7fffffff: return "FILTER";
047b2264 3797 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3798
3799 default:
3800 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3801 {
2cf0635d 3802 const char * result;
252b5132
RH
3803
3804 switch (elf_header.e_machine)
3805 {
3806 case EM_MIPS:
4fe85591 3807 case EM_MIPS_RS3_LE:
252b5132
RH
3808 result = get_mips_section_type_name (sh_type);
3809 break;
103f02d3
UD
3810 case EM_PARISC:
3811 result = get_parisc_section_type_name (sh_type);
3812 break;
4d6ed7c8
NC
3813 case EM_IA_64:
3814 result = get_ia64_section_type_name (sh_type);
3815 break;
d2b2c203 3816 case EM_X86_64:
8a9036a4 3817 case EM_L1OM:
7a9068fe 3818 case EM_K1OM:
d2b2c203
DJ
3819 result = get_x86_64_section_type_name (sh_type);
3820 break;
a06ea964
NC
3821 case EM_AARCH64:
3822 result = get_aarch64_section_type_name (sh_type);
3823 break;
40a18ebd
NC
3824 case EM_ARM:
3825 result = get_arm_section_type_name (sh_type);
3826 break;
40b36596
JM
3827 case EM_TI_C6000:
3828 result = get_tic6x_section_type_name (sh_type);
3829 break;
13761a11
NC
3830 case EM_MSP430:
3831 result = get_msp430x_section_type_name (sh_type);
3832 break;
685080f2
NC
3833 case EM_V800:
3834 case EM_V850:
3835 case EM_CYGNUS_V850:
3836 result = get_v850_section_type_name (sh_type);
3837 break;
252b5132
RH
3838 default:
3839 result = NULL;
3840 break;
3841 }
3842
3843 if (result != NULL)
3844 return result;
3845
c91d0dfb 3846 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3847 }
3848 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3849 {
2cf0635d 3850 const char * result;
148b93f2
NC
3851
3852 switch (elf_header.e_machine)
3853 {
3854 case EM_IA_64:
3855 result = get_ia64_section_type_name (sh_type);
3856 break;
3857 default:
3858 result = NULL;
3859 break;
3860 }
3861
3862 if (result != NULL)
3863 return result;
3864
3865 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3866 }
252b5132 3867 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2
NC
3868 {
3869 switch (elf_header.e_machine)
3870 {
3871 case EM_V800:
3872 case EM_V850:
3873 case EM_CYGNUS_V850:
3874 return get_v850_section_type_name (sh_type);
3875 default:
3876 break;
3877 }
3878
3879 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
3880 }
252b5132 3881 else
a7dbfd1c
NC
3882 /* This message is probably going to be displayed in a 15
3883 character wide field, so put the hex value first. */
3884 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3885
252b5132
RH
3886 return buff;
3887 }
3888}
3889
2979dc34 3890#define OPTION_DEBUG_DUMP 512
2c610e4b 3891#define OPTION_DYN_SYMS 513
fd2f0033
TT
3892#define OPTION_DWARF_DEPTH 514
3893#define OPTION_DWARF_START 515
4723351a 3894#define OPTION_DWARF_CHECK 516
2979dc34 3895
85b1c36d 3896static struct option options[] =
252b5132 3897{
b34976b6 3898 {"all", no_argument, 0, 'a'},
252b5132
RH
3899 {"file-header", no_argument, 0, 'h'},
3900 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3901 {"headers", no_argument, 0, 'e'},
3902 {"histogram", no_argument, 0, 'I'},
3903 {"segments", no_argument, 0, 'l'},
3904 {"sections", no_argument, 0, 'S'},
252b5132 3905 {"section-headers", no_argument, 0, 'S'},
f5842774 3906 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3907 {"section-details", no_argument, 0, 't'},
595cf52e 3908 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3909 {"symbols", no_argument, 0, 's'},
3910 {"syms", no_argument, 0, 's'},
2c610e4b 3911 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3912 {"relocs", no_argument, 0, 'r'},
3913 {"notes", no_argument, 0, 'n'},
3914 {"dynamic", no_argument, 0, 'd'},
a952a375 3915 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3916 {"version-info", no_argument, 0, 'V'},
3917 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3918 {"unwind", no_argument, 0, 'u'},
4145f1d5 3919 {"archive-index", no_argument, 0, 'c'},
b34976b6 3920 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3921 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3922 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3923#ifdef SUPPORT_DISASSEMBLY
3924 {"instruction-dump", required_argument, 0, 'i'},
3925#endif
cf13d699 3926 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3927
fd2f0033
TT
3928 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3929 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3930 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3931
b34976b6
AM
3932 {"version", no_argument, 0, 'v'},
3933 {"wide", no_argument, 0, 'W'},
3934 {"help", no_argument, 0, 'H'},
3935 {0, no_argument, 0, 0}
252b5132
RH
3936};
3937
3938static void
2cf0635d 3939usage (FILE * stream)
252b5132 3940{
92f01d61
JM
3941 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3942 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3943 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3944 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3945 -h --file-header Display the ELF file header\n\
3946 -l --program-headers Display the program headers\n\
3947 --segments An alias for --program-headers\n\
3948 -S --section-headers Display the sections' header\n\
3949 --sections An alias for --section-headers\n\
f5842774 3950 -g --section-groups Display the section groups\n\
5477e8a0 3951 -t --section-details Display the section details\n\
8b53311e
NC
3952 -e --headers Equivalent to: -h -l -S\n\
3953 -s --syms Display the symbol table\n\
3f08eb35 3954 --symbols An alias for --syms\n\
2c610e4b 3955 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3956 -n --notes Display the core notes (if present)\n\
3957 -r --relocs Display the relocations (if present)\n\
3958 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3959 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3960 -V --version-info Display the version sections (if present)\n\
1b31d05e 3961 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3962 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3963 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3964 -x --hex-dump=<number|name>\n\
3965 Dump the contents of section <number|name> as bytes\n\
3966 -p --string-dump=<number|name>\n\
3967 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3968 -R --relocated-dump=<number|name>\n\
3969 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3970 -w[lLiaprmfFsoRt] or\n\
1ed06042 3971 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3972 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3973 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3974 =addr,=cu_index]\n\
8b53311e 3975 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3976 fprintf (stream, _("\
3977 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3978 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3979 or deeper\n"));
252b5132 3980#ifdef SUPPORT_DISASSEMBLY
92f01d61 3981 fprintf (stream, _("\
09c11c86
NC
3982 -i --instruction-dump=<number|name>\n\
3983 Disassemble the contents of section <number|name>\n"));
252b5132 3984#endif
92f01d61 3985 fprintf (stream, _("\
8b53311e
NC
3986 -I --histogram Display histogram of bucket list lengths\n\
3987 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3988 @<file> Read options from <file>\n\
8b53311e
NC
3989 -H --help Display this information\n\
3990 -v --version Display the version number of readelf\n"));
1118d252 3991
92f01d61
JM
3992 if (REPORT_BUGS_TO[0] && stream == stdout)
3993 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3994
92f01d61 3995 exit (stream == stdout ? 0 : 1);
252b5132
RH
3996}
3997
18bd398b
NC
3998/* Record the fact that the user wants the contents of section number
3999 SECTION to be displayed using the method(s) encoded as flags bits
4000 in TYPE. Note, TYPE can be zero if we are creating the array for
4001 the first time. */
4002
252b5132 4003static void
09c11c86 4004request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
4005{
4006 if (section >= num_dump_sects)
4007 {
2cf0635d 4008 dump_type * new_dump_sects;
252b5132 4009
3f5e193b
NC
4010 new_dump_sects = (dump_type *) calloc (section + 1,
4011 sizeof (* dump_sects));
252b5132
RH
4012
4013 if (new_dump_sects == NULL)
591a748a 4014 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4015 else
4016 {
4017 /* Copy current flag settings. */
09c11c86 4018 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
4019
4020 free (dump_sects);
4021
4022 dump_sects = new_dump_sects;
4023 num_dump_sects = section + 1;
4024 }
4025 }
4026
4027 if (dump_sects)
b34976b6 4028 dump_sects[section] |= type;
252b5132
RH
4029
4030 return;
4031}
4032
aef1f6d0
DJ
4033/* Request a dump by section name. */
4034
4035static void
2cf0635d 4036request_dump_byname (const char * section, dump_type type)
aef1f6d0 4037{
2cf0635d 4038 struct dump_list_entry * new_request;
aef1f6d0 4039
3f5e193b
NC
4040 new_request = (struct dump_list_entry *)
4041 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4042 if (!new_request)
591a748a 4043 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4044
4045 new_request->name = strdup (section);
4046 if (!new_request->name)
591a748a 4047 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4048
4049 new_request->type = type;
4050
4051 new_request->next = dump_sects_byname;
4052 dump_sects_byname = new_request;
4053}
4054
cf13d699
NC
4055static inline void
4056request_dump (dump_type type)
4057{
4058 int section;
4059 char * cp;
4060
4061 do_dump++;
4062 section = strtoul (optarg, & cp, 0);
4063
4064 if (! *cp && section >= 0)
4065 request_dump_bynumber (section, type);
4066 else
4067 request_dump_byname (optarg, type);
4068}
4069
4070
252b5132 4071static void
2cf0635d 4072parse_args (int argc, char ** argv)
252b5132
RH
4073{
4074 int c;
4075
4076 if (argc < 2)
92f01d61 4077 usage (stderr);
252b5132
RH
4078
4079 while ((c = getopt_long
cf13d699 4080 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 4081 {
252b5132
RH
4082 switch (c)
4083 {
4084 case 0:
4085 /* Long options. */
4086 break;
4087 case 'H':
92f01d61 4088 usage (stdout);
252b5132
RH
4089 break;
4090
4091 case 'a':
b34976b6
AM
4092 do_syms++;
4093 do_reloc++;
4094 do_unwind++;
4095 do_dynamic++;
4096 do_header++;
4097 do_sections++;
f5842774 4098 do_section_groups++;
b34976b6
AM
4099 do_segments++;
4100 do_version++;
4101 do_histogram++;
4102 do_arch++;
4103 do_notes++;
252b5132 4104 break;
f5842774
L
4105 case 'g':
4106 do_section_groups++;
4107 break;
5477e8a0 4108 case 't':
595cf52e 4109 case 'N':
5477e8a0
L
4110 do_sections++;
4111 do_section_details++;
595cf52e 4112 break;
252b5132 4113 case 'e':
b34976b6
AM
4114 do_header++;
4115 do_sections++;
4116 do_segments++;
252b5132 4117 break;
a952a375 4118 case 'A':
b34976b6 4119 do_arch++;
a952a375 4120 break;
252b5132 4121 case 'D':
b34976b6 4122 do_using_dynamic++;
252b5132
RH
4123 break;
4124 case 'r':
b34976b6 4125 do_reloc++;
252b5132 4126 break;
4d6ed7c8 4127 case 'u':
b34976b6 4128 do_unwind++;
4d6ed7c8 4129 break;
252b5132 4130 case 'h':
b34976b6 4131 do_header++;
252b5132
RH
4132 break;
4133 case 'l':
b34976b6 4134 do_segments++;
252b5132
RH
4135 break;
4136 case 's':
b34976b6 4137 do_syms++;
252b5132
RH
4138 break;
4139 case 'S':
b34976b6 4140 do_sections++;
252b5132
RH
4141 break;
4142 case 'd':
b34976b6 4143 do_dynamic++;
252b5132 4144 break;
a952a375 4145 case 'I':
b34976b6 4146 do_histogram++;
a952a375 4147 break;
779fe533 4148 case 'n':
b34976b6 4149 do_notes++;
779fe533 4150 break;
4145f1d5
NC
4151 case 'c':
4152 do_archive_index++;
4153 break;
252b5132 4154 case 'x':
cf13d699 4155 request_dump (HEX_DUMP);
aef1f6d0 4156 break;
09c11c86 4157 case 'p':
cf13d699
NC
4158 request_dump (STRING_DUMP);
4159 break;
4160 case 'R':
4161 request_dump (RELOC_DUMP);
09c11c86 4162 break;
252b5132 4163 case 'w':
b34976b6 4164 do_dump++;
252b5132 4165 if (optarg == 0)
613ff48b
CC
4166 {
4167 do_debugging = 1;
4168 dwarf_select_sections_all ();
4169 }
252b5132
RH
4170 else
4171 {
4172 do_debugging = 0;
4cb93e3b 4173 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4174 }
4175 break;
2979dc34 4176 case OPTION_DEBUG_DUMP:
b34976b6 4177 do_dump++;
2979dc34
JJ
4178 if (optarg == 0)
4179 do_debugging = 1;
4180 else
4181 {
2979dc34 4182 do_debugging = 0;
4cb93e3b 4183 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4184 }
4185 break;
fd2f0033
TT
4186 case OPTION_DWARF_DEPTH:
4187 {
4188 char *cp;
4189
4190 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4191 }
4192 break;
4193 case OPTION_DWARF_START:
4194 {
4195 char *cp;
4196
4197 dwarf_start_die = strtoul (optarg, & cp, 0);
4198 }
4199 break;
4723351a
CC
4200 case OPTION_DWARF_CHECK:
4201 dwarf_check = 1;
4202 break;
2c610e4b
L
4203 case OPTION_DYN_SYMS:
4204 do_dyn_syms++;
4205 break;
252b5132
RH
4206#ifdef SUPPORT_DISASSEMBLY
4207 case 'i':
cf13d699
NC
4208 request_dump (DISASS_DUMP);
4209 break;
252b5132
RH
4210#endif
4211 case 'v':
4212 print_version (program_name);
4213 break;
4214 case 'V':
b34976b6 4215 do_version++;
252b5132 4216 break;
d974e256 4217 case 'W':
b34976b6 4218 do_wide++;
d974e256 4219 break;
252b5132 4220 default:
252b5132
RH
4221 /* xgettext:c-format */
4222 error (_("Invalid option '-%c'\n"), c);
4223 /* Drop through. */
4224 case '?':
92f01d61 4225 usage (stderr);
252b5132
RH
4226 }
4227 }
4228
4d6ed7c8 4229 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4230 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4231 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4232 && !do_section_groups && !do_archive_index
4233 && !do_dyn_syms)
92f01d61 4234 usage (stderr);
b6370efb 4235 else if (argc < 3 || (do_wide && argc < 4))
252b5132
RH
4236 {
4237 warn (_("Nothing to do.\n"));
92f01d61 4238 usage (stderr);
252b5132
RH
4239 }
4240}
4241
4242static const char *
d3ba0551 4243get_elf_class (unsigned int elf_class)
252b5132 4244{
b34976b6 4245 static char buff[32];
103f02d3 4246
252b5132
RH
4247 switch (elf_class)
4248 {
4249 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4250 case ELFCLASS32: return "ELF32";
4251 case ELFCLASS64: return "ELF64";
ab5e7794 4252 default:
e9e44622 4253 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4254 return buff;
252b5132
RH
4255 }
4256}
4257
4258static const char *
d3ba0551 4259get_data_encoding (unsigned int encoding)
252b5132 4260{
b34976b6 4261 static char buff[32];
103f02d3 4262
252b5132
RH
4263 switch (encoding)
4264 {
4265 case ELFDATANONE: return _("none");
33c63f9d
CM
4266 case ELFDATA2LSB: return _("2's complement, little endian");
4267 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4268 default:
e9e44622 4269 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4270 return buff;
252b5132
RH
4271 }
4272}
4273
252b5132 4274/* Decode the data held in 'elf_header'. */
ee42cf8c 4275
252b5132 4276static int
d3ba0551 4277process_file_header (void)
252b5132 4278{
b34976b6
AM
4279 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
4280 || elf_header.e_ident[EI_MAG1] != ELFMAG1
4281 || elf_header.e_ident[EI_MAG2] != ELFMAG2
4282 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4283 {
4284 error
4285 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
4286 return 0;
4287 }
4288
2dc4cec1
L
4289 init_dwarf_regnames (elf_header.e_machine);
4290
252b5132
RH
4291 if (do_header)
4292 {
4293 int i;
4294
4295 printf (_("ELF Header:\n"));
4296 printf (_(" Magic: "));
b34976b6
AM
4297 for (i = 0; i < EI_NIDENT; i++)
4298 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
4299 printf ("\n");
4300 printf (_(" Class: %s\n"),
b34976b6 4301 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 4302 printf (_(" Data: %s\n"),
b34976b6 4303 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 4304 printf (_(" Version: %d %s\n"),
b34976b6
AM
4305 elf_header.e_ident[EI_VERSION],
4306 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4307 ? "(current)"
b34976b6 4308 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 4309 ? _("<unknown: %lx>")
789be9f7 4310 : "")));
252b5132 4311 printf (_(" OS/ABI: %s\n"),
b34976b6 4312 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 4313 printf (_(" ABI Version: %d\n"),
b34976b6 4314 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
4315 printf (_(" Type: %s\n"),
4316 get_file_type (elf_header.e_type));
4317 printf (_(" Machine: %s\n"),
4318 get_machine_name (elf_header.e_machine));
4319 printf (_(" Version: 0x%lx\n"),
4320 (unsigned long) elf_header.e_version);
76da6bbe 4321
f7a99963
NC
4322 printf (_(" Entry point address: "));
4323 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4324 printf (_("\n Start of program headers: "));
4325 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4326 printf (_(" (bytes into file)\n Start of section headers: "));
4327 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
4328 printf (_(" (bytes into file)\n"));
76da6bbe 4329
252b5132
RH
4330 printf (_(" Flags: 0x%lx%s\n"),
4331 (unsigned long) elf_header.e_flags,
4332 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
4333 printf (_(" Size of this header: %ld (bytes)\n"),
4334 (long) elf_header.e_ehsize);
4335 printf (_(" Size of program headers: %ld (bytes)\n"),
4336 (long) elf_header.e_phentsize);
2046a35d 4337 printf (_(" Number of program headers: %ld"),
252b5132 4338 (long) elf_header.e_phnum);
2046a35d
AM
4339 if (section_headers != NULL
4340 && elf_header.e_phnum == PN_XNUM
4341 && section_headers[0].sh_info != 0)
cc5914eb 4342 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 4343 putc ('\n', stdout);
252b5132
RH
4344 printf (_(" Size of section headers: %ld (bytes)\n"),
4345 (long) elf_header.e_shentsize);
560f3c1c 4346 printf (_(" Number of section headers: %ld"),
252b5132 4347 (long) elf_header.e_shnum);
4fbb74a6 4348 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
4349 printf (" (%ld)", (long) section_headers[0].sh_size);
4350 putc ('\n', stdout);
4351 printf (_(" Section header string table index: %ld"),
252b5132 4352 (long) elf_header.e_shstrndx);
4fbb74a6
AM
4353 if (section_headers != NULL
4354 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 4355 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
4356 else if (elf_header.e_shstrndx != SHN_UNDEF
4357 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 4358 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4359 putc ('\n', stdout);
4360 }
4361
4362 if (section_headers != NULL)
4363 {
2046a35d
AM
4364 if (elf_header.e_phnum == PN_XNUM
4365 && section_headers[0].sh_info != 0)
4366 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 4367 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 4368 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 4369 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 4370 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 4371 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 4372 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
4373 free (section_headers);
4374 section_headers = NULL;
252b5132 4375 }
103f02d3 4376
9ea033b2
NC
4377 return 1;
4378}
4379
e0a31db1 4380static bfd_boolean
91d6fa6a 4381get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4382{
2cf0635d
NC
4383 Elf32_External_Phdr * phdrs;
4384 Elf32_External_Phdr * external;
4385 Elf_Internal_Phdr * internal;
b34976b6 4386 unsigned int i;
e0a31db1
NC
4387 unsigned int size = elf_header.e_phentsize;
4388 unsigned int num = elf_header.e_phnum;
4389
4390 /* PR binutils/17531: Cope with unexpected section header sizes. */
4391 if (size == 0 || num == 0)
4392 return FALSE;
4393 if (size < sizeof * phdrs)
4394 {
4395 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4396 return FALSE;
4397 }
4398 if (size > sizeof * phdrs)
4399 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4400
3f5e193b 4401 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1
NC
4402 size, num, _("program headers"));
4403 if (phdrs == NULL)
4404 return FALSE;
9ea033b2 4405
91d6fa6a 4406 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4407 i < elf_header.e_phnum;
b34976b6 4408 i++, internal++, external++)
252b5132 4409 {
9ea033b2
NC
4410 internal->p_type = BYTE_GET (external->p_type);
4411 internal->p_offset = BYTE_GET (external->p_offset);
4412 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4413 internal->p_paddr = BYTE_GET (external->p_paddr);
4414 internal->p_filesz = BYTE_GET (external->p_filesz);
4415 internal->p_memsz = BYTE_GET (external->p_memsz);
4416 internal->p_flags = BYTE_GET (external->p_flags);
4417 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4418 }
4419
9ea033b2 4420 free (phdrs);
e0a31db1 4421 return TRUE;
252b5132
RH
4422}
4423
e0a31db1 4424static bfd_boolean
91d6fa6a 4425get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4426{
2cf0635d
NC
4427 Elf64_External_Phdr * phdrs;
4428 Elf64_External_Phdr * external;
4429 Elf_Internal_Phdr * internal;
b34976b6 4430 unsigned int i;
e0a31db1
NC
4431 unsigned int size = elf_header.e_phentsize;
4432 unsigned int num = elf_header.e_phnum;
4433
4434 /* PR binutils/17531: Cope with unexpected section header sizes. */
4435 if (size == 0 || num == 0)
4436 return FALSE;
4437 if (size < sizeof * phdrs)
4438 {
4439 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4440 return FALSE;
4441 }
4442 if (size > sizeof * phdrs)
4443 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4444
3f5e193b 4445 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1 4446 size, num, _("program headers"));
a6e9f9df 4447 if (!phdrs)
e0a31db1 4448 return FALSE;
9ea033b2 4449
91d6fa6a 4450 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4451 i < elf_header.e_phnum;
b34976b6 4452 i++, internal++, external++)
9ea033b2
NC
4453 {
4454 internal->p_type = BYTE_GET (external->p_type);
4455 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4456 internal->p_offset = BYTE_GET (external->p_offset);
4457 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4458 internal->p_paddr = BYTE_GET (external->p_paddr);
4459 internal->p_filesz = BYTE_GET (external->p_filesz);
4460 internal->p_memsz = BYTE_GET (external->p_memsz);
4461 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4462 }
4463
4464 free (phdrs);
e0a31db1 4465 return TRUE;
9ea033b2 4466}
252b5132 4467
d93f0186
NC
4468/* Returns 1 if the program headers were read into `program_headers'. */
4469
4470static int
2cf0635d 4471get_program_headers (FILE * file)
d93f0186 4472{
2cf0635d 4473 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4474
4475 /* Check cache of prior read. */
4476 if (program_headers != NULL)
4477 return 1;
4478
3f5e193b
NC
4479 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
4480 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4481
4482 if (phdrs == NULL)
4483 {
8b73c356
NC
4484 error (_("Out of memory reading %u program headers\n"),
4485 elf_header.e_phnum);
d93f0186
NC
4486 return 0;
4487 }
4488
4489 if (is_32bit_elf
4490 ? get_32bit_program_headers (file, phdrs)
4491 : get_64bit_program_headers (file, phdrs))
4492 {
4493 program_headers = phdrs;
4494 return 1;
4495 }
4496
4497 free (phdrs);
4498 return 0;
4499}
4500
2f62977e
NC
4501/* Returns 1 if the program headers were loaded. */
4502
252b5132 4503static int
2cf0635d 4504process_program_headers (FILE * file)
252b5132 4505{
2cf0635d 4506 Elf_Internal_Phdr * segment;
b34976b6 4507 unsigned int i;
252b5132
RH
4508
4509 if (elf_header.e_phnum == 0)
4510 {
82f2dbf7
NC
4511 /* PR binutils/12467. */
4512 if (elf_header.e_phoff != 0)
4513 warn (_("possibly corrupt ELF header - it has a non-zero program"
9035ed51 4514 " header offset, but no program headers\n"));
82f2dbf7 4515 else if (do_segments)
252b5132 4516 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4517 return 0;
252b5132
RH
4518 }
4519
4520 if (do_segments && !do_header)
4521 {
f7a99963
NC
4522 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4523 printf (_("Entry point "));
4524 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4525 printf (_("\nThere are %d program headers, starting at offset "),
4526 elf_header.e_phnum);
4527 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4528 printf ("\n");
252b5132
RH
4529 }
4530
d93f0186 4531 if (! get_program_headers (file))
252b5132 4532 return 0;
103f02d3 4533
252b5132
RH
4534 if (do_segments)
4535 {
3a1a2036
NC
4536 if (elf_header.e_phnum > 1)
4537 printf (_("\nProgram Headers:\n"));
4538 else
4539 printf (_("\nProgram Headers:\n"));
76da6bbe 4540
f7a99963
NC
4541 if (is_32bit_elf)
4542 printf
4543 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4544 else if (do_wide)
4545 printf
4546 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4547 else
4548 {
4549 printf
4550 (_(" Type Offset VirtAddr PhysAddr\n"));
4551 printf
4552 (_(" FileSiz MemSiz Flags Align\n"));
4553 }
252b5132
RH
4554 }
4555
252b5132 4556 dynamic_addr = 0;
1b228002 4557 dynamic_size = 0;
252b5132
RH
4558
4559 for (i = 0, segment = program_headers;
4560 i < elf_header.e_phnum;
b34976b6 4561 i++, segment++)
252b5132
RH
4562 {
4563 if (do_segments)
4564 {
103f02d3 4565 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4566
4567 if (is_32bit_elf)
4568 {
4569 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4570 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4571 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4572 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4573 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4574 printf ("%c%c%c ",
4575 (segment->p_flags & PF_R ? 'R' : ' '),
4576 (segment->p_flags & PF_W ? 'W' : ' '),
4577 (segment->p_flags & PF_X ? 'E' : ' '));
4578 printf ("%#lx", (unsigned long) segment->p_align);
4579 }
d974e256
JJ
4580 else if (do_wide)
4581 {
4582 if ((unsigned long) segment->p_offset == segment->p_offset)
4583 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4584 else
4585 {
4586 print_vma (segment->p_offset, FULL_HEX);
4587 putchar (' ');
4588 }
4589
4590 print_vma (segment->p_vaddr, FULL_HEX);
4591 putchar (' ');
4592 print_vma (segment->p_paddr, FULL_HEX);
4593 putchar (' ');
4594
4595 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4596 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4597 else
4598 {
4599 print_vma (segment->p_filesz, FULL_HEX);
4600 putchar (' ');
4601 }
4602
4603 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4604 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4605 else
4606 {
f48e6c45 4607 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4608 }
4609
4610 printf (" %c%c%c ",
4611 (segment->p_flags & PF_R ? 'R' : ' '),
4612 (segment->p_flags & PF_W ? 'W' : ' '),
4613 (segment->p_flags & PF_X ? 'E' : ' '));
4614
4615 if ((unsigned long) segment->p_align == segment->p_align)
4616 printf ("%#lx", (unsigned long) segment->p_align);
4617 else
4618 {
4619 print_vma (segment->p_align, PREFIX_HEX);
4620 }
4621 }
f7a99963
NC
4622 else
4623 {
4624 print_vma (segment->p_offset, FULL_HEX);
4625 putchar (' ');
4626 print_vma (segment->p_vaddr, FULL_HEX);
4627 putchar (' ');
4628 print_vma (segment->p_paddr, FULL_HEX);
4629 printf ("\n ");
4630 print_vma (segment->p_filesz, FULL_HEX);
4631 putchar (' ');
4632 print_vma (segment->p_memsz, FULL_HEX);
4633 printf (" %c%c%c ",
4634 (segment->p_flags & PF_R ? 'R' : ' '),
4635 (segment->p_flags & PF_W ? 'W' : ' '),
4636 (segment->p_flags & PF_X ? 'E' : ' '));
4637 print_vma (segment->p_align, HEX);
4638 }
252b5132
RH
4639 }
4640
f54498b4
NC
4641 if (do_segments)
4642 putc ('\n', stdout);
4643
252b5132
RH
4644 switch (segment->p_type)
4645 {
252b5132
RH
4646 case PT_DYNAMIC:
4647 if (dynamic_addr)
4648 error (_("more than one dynamic segment\n"));
4649
20737c13
AM
4650 /* By default, assume that the .dynamic section is the first
4651 section in the DYNAMIC segment. */
4652 dynamic_addr = segment->p_offset;
4653 dynamic_size = segment->p_filesz;
f54498b4
NC
4654 /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
4655 if (dynamic_addr + dynamic_size >= current_file_size)
4656 {
4657 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
4658 dynamic_addr = dynamic_size = 0;
4659 }
20737c13 4660
b2d38a17
NC
4661 /* Try to locate the .dynamic section. If there is
4662 a section header table, we can easily locate it. */
4663 if (section_headers != NULL)
4664 {
2cf0635d 4665 Elf_Internal_Shdr * sec;
b2d38a17 4666
89fac5e3
RS
4667 sec = find_section (".dynamic");
4668 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4669 {
28f997cf
TG
4670 /* A corresponding .dynamic section is expected, but on
4671 IA-64/OpenVMS it is OK for it to be missing. */
4672 if (!is_ia64_vms ())
4673 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4674 break;
4675 }
4676
42bb2e33 4677 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4678 {
4679 dynamic_size = 0;
4680 break;
4681 }
42bb2e33 4682
b2d38a17
NC
4683 dynamic_addr = sec->sh_offset;
4684 dynamic_size = sec->sh_size;
4685
4686 if (dynamic_addr < segment->p_offset
4687 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4688 warn (_("the .dynamic section is not contained"
4689 " within the dynamic segment\n"));
b2d38a17 4690 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4691 warn (_("the .dynamic section is not the first section"
4692 " in the dynamic segment.\n"));
b2d38a17 4693 }
252b5132
RH
4694 break;
4695
4696 case PT_INTERP:
fb52b2f4
NC
4697 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4698 SEEK_SET))
252b5132
RH
4699 error (_("Unable to find program interpreter name\n"));
4700 else
4701 {
f8eae8b2 4702 char fmt [32];
9495b2e6 4703 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
4704
4705 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4706 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4707
252b5132 4708 program_interpreter[0] = 0;
7bd7b3ef
AM
4709 if (fscanf (file, fmt, program_interpreter) <= 0)
4710 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4711
4712 if (do_segments)
f54498b4 4713 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
4714 program_interpreter);
4715 }
4716 break;
4717 }
252b5132
RH
4718 }
4719
c256ffe7 4720 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4721 {
4722 printf (_("\n Section to Segment mapping:\n"));
4723 printf (_(" Segment Sections...\n"));
4724
252b5132
RH
4725 for (i = 0; i < elf_header.e_phnum; i++)
4726 {
9ad5cbcf 4727 unsigned int j;
2cf0635d 4728 Elf_Internal_Shdr * section;
252b5132
RH
4729
4730 segment = program_headers + i;
b391a3e3 4731 section = section_headers + 1;
252b5132
RH
4732
4733 printf (" %2.2d ", i);
4734
b34976b6 4735 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4736 {
f4638467
AM
4737 if (!ELF_TBSS_SPECIAL (section, segment)
4738 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
74e1a04b 4739 printf ("%s ", printable_section_name (section));
252b5132
RH
4740 }
4741
4742 putc ('\n',stdout);
4743 }
4744 }
4745
252b5132
RH
4746 return 1;
4747}
4748
4749
d93f0186
NC
4750/* Find the file offset corresponding to VMA by using the program headers. */
4751
4752static long
2cf0635d 4753offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4754{
2cf0635d 4755 Elf_Internal_Phdr * seg;
d93f0186
NC
4756
4757 if (! get_program_headers (file))
4758 {
4759 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4760 return (long) vma;
4761 }
4762
4763 for (seg = program_headers;
4764 seg < program_headers + elf_header.e_phnum;
4765 ++seg)
4766 {
4767 if (seg->p_type != PT_LOAD)
4768 continue;
4769
4770 if (vma >= (seg->p_vaddr & -seg->p_align)
4771 && vma + size <= seg->p_vaddr + seg->p_filesz)
4772 return vma - seg->p_vaddr + seg->p_offset;
4773 }
4774
4775 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4776 (unsigned long) vma);
d93f0186
NC
4777 return (long) vma;
4778}
4779
4780
049b0c3a
NC
4781/* Allocate memory and load the sections headers into the global pointer
4782 SECTION_HEADERS. If PROBE is true, this is just a probe and we do not
4783 generate any error messages if the load fails. */
4784
4785static bfd_boolean
4786get_32bit_section_headers (FILE * file, bfd_boolean probe)
252b5132 4787{
2cf0635d
NC
4788 Elf32_External_Shdr * shdrs;
4789 Elf_Internal_Shdr * internal;
b34976b6 4790 unsigned int i;
049b0c3a
NC
4791 unsigned int size = elf_header.e_shentsize;
4792 unsigned int num = probe ? 1 : elf_header.e_shnum;
4793
4794 /* PR binutils/17531: Cope with unexpected section header sizes. */
4795 if (size == 0 || num == 0)
4796 return FALSE;
4797 if (size < sizeof * shdrs)
4798 {
4799 if (! probe)
4800 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4801 return FALSE;
4802 }
4803 if (!probe && size > sizeof * shdrs)
4804 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 4805
3f5e193b 4806 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4807 size, num,
4808 probe ? NULL : _("section headers"));
4809 if (shdrs == NULL)
4810 return FALSE;
252b5132 4811
049b0c3a
NC
4812 if (section_headers != NULL)
4813 free (section_headers);
3f5e193b
NC
4814 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4815 sizeof (Elf_Internal_Shdr));
252b5132
RH
4816 if (section_headers == NULL)
4817 {
049b0c3a 4818 if (!probe)
8b73c356 4819 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4820 return FALSE;
252b5132
RH
4821 }
4822
4823 for (i = 0, internal = section_headers;
560f3c1c 4824 i < num;
b34976b6 4825 i++, internal++)
252b5132
RH
4826 {
4827 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4828 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4829 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4830 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4831 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4832 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4833 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4834 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4835 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4836 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4837 }
4838
4839 free (shdrs);
049b0c3a 4840 return TRUE;
252b5132
RH
4841}
4842
049b0c3a
NC
4843static bfd_boolean
4844get_64bit_section_headers (FILE * file, bfd_boolean probe)
9ea033b2 4845{
2cf0635d
NC
4846 Elf64_External_Shdr * shdrs;
4847 Elf_Internal_Shdr * internal;
b34976b6 4848 unsigned int i;
049b0c3a
NC
4849 unsigned int size = elf_header.e_shentsize;
4850 unsigned int num = probe ? 1 : elf_header.e_shnum;
4851
4852 /* PR binutils/17531: Cope with unexpected section header sizes. */
4853 if (size == 0 || num == 0)
4854 return FALSE;
4855 if (size < sizeof * shdrs)
4856 {
4857 if (! probe)
4858 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4859 return FALSE;
4860 }
4861 if (! probe && size > sizeof * shdrs)
4862 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 4863
3f5e193b 4864 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4865 size, num,
4866 probe ? NULL : _("section headers"));
4867 if (shdrs == NULL)
4868 return FALSE;
9ea033b2 4869
049b0c3a
NC
4870 if (section_headers != NULL)
4871 free (section_headers);
3f5e193b
NC
4872 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4873 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4874 if (section_headers == NULL)
4875 {
049b0c3a 4876 if (! probe)
8b73c356 4877 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4878 return FALSE;
9ea033b2
NC
4879 }
4880
4881 for (i = 0, internal = section_headers;
560f3c1c 4882 i < num;
b34976b6 4883 i++, internal++)
9ea033b2
NC
4884 {
4885 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4886 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4887 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4888 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4889 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4890 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4891 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4892 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4893 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4894 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4895 }
4896
4897 free (shdrs);
049b0c3a 4898 return TRUE;
9ea033b2
NC
4899}
4900
252b5132 4901static Elf_Internal_Sym *
ba5cdace
NC
4902get_32bit_elf_symbols (FILE * file,
4903 Elf_Internal_Shdr * section,
4904 unsigned long * num_syms_return)
252b5132 4905{
ba5cdace 4906 unsigned long number = 0;
dd24e3da 4907 Elf32_External_Sym * esyms = NULL;
ba5cdace 4908 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4909 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4910 Elf_Internal_Sym * psym;
b34976b6 4911 unsigned int j;
252b5132 4912
c9c1d674
EG
4913 if (section->sh_size == 0)
4914 {
4915 if (num_syms_return != NULL)
4916 * num_syms_return = 0;
4917 return NULL;
4918 }
4919
dd24e3da 4920 /* Run some sanity checks first. */
c9c1d674 4921 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 4922 {
c9c1d674
EG
4923 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
4924 printable_section_name (section), (unsigned long) section->sh_entsize);
ba5cdace 4925 goto exit_point;
dd24e3da
NC
4926 }
4927
f54498b4
NC
4928 if (section->sh_size > current_file_size)
4929 {
4930 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
74e1a04b 4931 printable_section_name (section), (unsigned long) section->sh_size);
f54498b4
NC
4932 goto exit_point;
4933 }
4934
dd24e3da
NC
4935 number = section->sh_size / section->sh_entsize;
4936
4937 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4938 {
c9c1d674 4939 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
4940 (unsigned long) section->sh_size,
4941 printable_section_name (section),
4942 (unsigned long) section->sh_entsize);
ba5cdace 4943 goto exit_point;
dd24e3da
NC
4944 }
4945
3f5e193b
NC
4946 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4947 section->sh_size, _("symbols"));
dd24e3da 4948 if (esyms == NULL)
ba5cdace 4949 goto exit_point;
252b5132 4950
9ad5cbcf
AM
4951 shndx = NULL;
4952 if (symtab_shndx_hdr != NULL
4953 && (symtab_shndx_hdr->sh_link
4fbb74a6 4954 == (unsigned long) (section - section_headers)))
9ad5cbcf 4955 {
3f5e193b
NC
4956 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4957 symtab_shndx_hdr->sh_offset,
4958 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4959 _("symbol table section indicies"));
dd24e3da
NC
4960 if (shndx == NULL)
4961 goto exit_point;
c9c1d674
EG
4962 /* PR17531: file: heap-buffer-overflow */
4963 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
4964 {
4965 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
4966 printable_section_name (symtab_shndx_hdr),
4967 (unsigned long) symtab_shndx_hdr->sh_size,
4968 (unsigned long) section->sh_size);
4969 goto exit_point;
4970 }
9ad5cbcf
AM
4971 }
4972
3f5e193b 4973 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4974
4975 if (isyms == NULL)
4976 {
8b73c356
NC
4977 error (_("Out of memory reading %lu symbols\n"),
4978 (unsigned long) number);
dd24e3da 4979 goto exit_point;
252b5132
RH
4980 }
4981
dd24e3da 4982 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4983 {
4984 psym->st_name = BYTE_GET (esyms[j].st_name);
4985 psym->st_value = BYTE_GET (esyms[j].st_value);
4986 psym->st_size = BYTE_GET (esyms[j].st_size);
4987 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4988 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4989 psym->st_shndx
4990 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4991 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4992 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4993 psym->st_info = BYTE_GET (esyms[j].st_info);
4994 psym->st_other = BYTE_GET (esyms[j].st_other);
4995 }
4996
dd24e3da 4997 exit_point:
ba5cdace 4998 if (shndx != NULL)
9ad5cbcf 4999 free (shndx);
ba5cdace 5000 if (esyms != NULL)
dd24e3da 5001 free (esyms);
252b5132 5002
ba5cdace
NC
5003 if (num_syms_return != NULL)
5004 * num_syms_return = isyms == NULL ? 0 : number;
5005
252b5132
RH
5006 return isyms;
5007}
5008
9ea033b2 5009static Elf_Internal_Sym *
ba5cdace
NC
5010get_64bit_elf_symbols (FILE * file,
5011 Elf_Internal_Shdr * section,
5012 unsigned long * num_syms_return)
9ea033b2 5013{
ba5cdace
NC
5014 unsigned long number = 0;
5015 Elf64_External_Sym * esyms = NULL;
5016 Elf_External_Sym_Shndx * shndx = NULL;
5017 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5018 Elf_Internal_Sym * psym;
b34976b6 5019 unsigned int j;
9ea033b2 5020
c9c1d674
EG
5021 if (section->sh_size == 0)
5022 {
5023 if (num_syms_return != NULL)
5024 * num_syms_return = 0;
5025 return NULL;
5026 }
5027
dd24e3da 5028 /* Run some sanity checks first. */
c9c1d674 5029 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5030 {
c9c1d674 5031 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
8066deb1
AM
5032 printable_section_name (section),
5033 (unsigned long) section->sh_entsize);
ba5cdace 5034 goto exit_point;
dd24e3da
NC
5035 }
5036
f54498b4
NC
5037 if (section->sh_size > current_file_size)
5038 {
5039 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
8066deb1
AM
5040 printable_section_name (section),
5041 (unsigned long) section->sh_size);
f54498b4
NC
5042 goto exit_point;
5043 }
5044
dd24e3da
NC
5045 number = section->sh_size / section->sh_entsize;
5046
5047 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5048 {
c9c1d674 5049 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
5050 (unsigned long) section->sh_size,
5051 printable_section_name (section),
5052 (unsigned long) section->sh_entsize);
ba5cdace 5053 goto exit_point;
dd24e3da
NC
5054 }
5055
3f5e193b
NC
5056 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
5057 section->sh_size, _("symbols"));
a6e9f9df 5058 if (!esyms)
ba5cdace 5059 goto exit_point;
9ea033b2 5060
9ad5cbcf
AM
5061 if (symtab_shndx_hdr != NULL
5062 && (symtab_shndx_hdr->sh_link
4fbb74a6 5063 == (unsigned long) (section - section_headers)))
9ad5cbcf 5064 {
3f5e193b
NC
5065 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
5066 symtab_shndx_hdr->sh_offset,
5067 1, symtab_shndx_hdr->sh_size,
9cf03b7e 5068 _("symbol table section indicies"));
ba5cdace
NC
5069 if (shndx == NULL)
5070 goto exit_point;
c9c1d674
EG
5071 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5072 {
5073 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5074 printable_section_name (symtab_shndx_hdr),
5075 (unsigned long) symtab_shndx_hdr->sh_size,
5076 (unsigned long) section->sh_size);
5077 goto exit_point;
5078 }
9ad5cbcf
AM
5079 }
5080
3f5e193b 5081 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5082
5083 if (isyms == NULL)
5084 {
8b73c356
NC
5085 error (_("Out of memory reading %lu symbols\n"),
5086 (unsigned long) number);
ba5cdace 5087 goto exit_point;
9ea033b2
NC
5088 }
5089
ba5cdace 5090 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5091 {
5092 psym->st_name = BYTE_GET (esyms[j].st_name);
5093 psym->st_info = BYTE_GET (esyms[j].st_info);
5094 psym->st_other = BYTE_GET (esyms[j].st_other);
5095 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5096
4fbb74a6 5097 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5098 psym->st_shndx
5099 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5100 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5101 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5102
66543521
AM
5103 psym->st_value = BYTE_GET (esyms[j].st_value);
5104 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5105 }
5106
ba5cdace
NC
5107 exit_point:
5108 if (shndx != NULL)
9ad5cbcf 5109 free (shndx);
ba5cdace
NC
5110 if (esyms != NULL)
5111 free (esyms);
5112
5113 if (num_syms_return != NULL)
5114 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5115
5116 return isyms;
5117}
5118
d1133906 5119static const char *
d3ba0551 5120get_elf_section_flags (bfd_vma sh_flags)
d1133906 5121{
5477e8a0 5122 static char buff[1024];
2cf0635d 5123 char * p = buff;
8d5ff12c 5124 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
5125 int sindex;
5126 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5127 bfd_vma os_flags = 0;
5128 bfd_vma proc_flags = 0;
5129 bfd_vma unknown_flags = 0;
148b93f2 5130 static const struct
5477e8a0 5131 {
2cf0635d 5132 const char * str;
5477e8a0
L
5133 int len;
5134 }
5135 flags [] =
5136 {
cfcac11d
NC
5137 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5138 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5139 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5140 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5141 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5142 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5143 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5144 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5145 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5146 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5147 /* IA-64 specific. */
5148 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5149 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5150 /* IA-64 OpenVMS specific. */
5151 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5152 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5153 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5154 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5155 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5156 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5157 /* Generic. */
cfcac11d 5158 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5159 /* SPARC specific. */
cfcac11d 5160 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
5161 };
5162
5163 if (do_section_details)
5164 {
8d5ff12c
L
5165 sprintf (buff, "[%*.*lx]: ",
5166 field_size, field_size, (unsigned long) sh_flags);
5167 p += field_size + 4;
5477e8a0 5168 }
76da6bbe 5169
d1133906
NC
5170 while (sh_flags)
5171 {
5172 bfd_vma flag;
5173
5174 flag = sh_flags & - sh_flags;
5175 sh_flags &= ~ flag;
76da6bbe 5176
5477e8a0 5177 if (do_section_details)
d1133906 5178 {
5477e8a0
L
5179 switch (flag)
5180 {
91d6fa6a
NC
5181 case SHF_WRITE: sindex = 0; break;
5182 case SHF_ALLOC: sindex = 1; break;
5183 case SHF_EXECINSTR: sindex = 2; break;
5184 case SHF_MERGE: sindex = 3; break;
5185 case SHF_STRINGS: sindex = 4; break;
5186 case SHF_INFO_LINK: sindex = 5; break;
5187 case SHF_LINK_ORDER: sindex = 6; break;
5188 case SHF_OS_NONCONFORMING: sindex = 7; break;
5189 case SHF_GROUP: sindex = 8; break;
5190 case SHF_TLS: sindex = 9; break;
18ae9cc1 5191 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 5192
5477e8a0 5193 default:
91d6fa6a 5194 sindex = -1;
cfcac11d 5195 switch (elf_header.e_machine)
148b93f2 5196 {
cfcac11d 5197 case EM_IA_64:
148b93f2 5198 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5199 sindex = 10;
148b93f2 5200 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5201 sindex = 11;
148b93f2
NC
5202#ifdef BFD64
5203 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
5204 switch (flag)
5205 {
91d6fa6a
NC
5206 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5207 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5208 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5209 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5210 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5211 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5212 default: break;
5213 }
5214#endif
cfcac11d
NC
5215 break;
5216
caa83f8b
NC
5217 case EM_386:
5218 case EM_486:
5219 case EM_X86_64:
7f502d6c 5220 case EM_L1OM:
7a9068fe 5221 case EM_K1OM:
cfcac11d
NC
5222 case EM_OLD_SPARCV9:
5223 case EM_SPARC32PLUS:
5224 case EM_SPARCV9:
5225 case EM_SPARC:
18ae9cc1 5226 if (flag == SHF_ORDERED)
91d6fa6a 5227 sindex = 19;
cfcac11d
NC
5228 break;
5229 default:
5230 break;
148b93f2 5231 }
5477e8a0
L
5232 }
5233
91d6fa6a 5234 if (sindex != -1)
5477e8a0 5235 {
8d5ff12c
L
5236 if (p != buff + field_size + 4)
5237 {
5238 if (size < (10 + 2))
bee0ee85
NC
5239 {
5240 warn (_("Internal error: not enough buffer room for section flag info"));
5241 return _("<unknown>");
5242 }
8d5ff12c
L
5243 size -= 2;
5244 *p++ = ',';
5245 *p++ = ' ';
5246 }
5247
91d6fa6a
NC
5248 size -= flags [sindex].len;
5249 p = stpcpy (p, flags [sindex].str);
5477e8a0 5250 }
3b22753a 5251 else if (flag & SHF_MASKOS)
8d5ff12c 5252 os_flags |= flag;
d1133906 5253 else if (flag & SHF_MASKPROC)
8d5ff12c 5254 proc_flags |= flag;
d1133906 5255 else
8d5ff12c 5256 unknown_flags |= flag;
5477e8a0
L
5257 }
5258 else
5259 {
5260 switch (flag)
5261 {
5262 case SHF_WRITE: *p = 'W'; break;
5263 case SHF_ALLOC: *p = 'A'; break;
5264 case SHF_EXECINSTR: *p = 'X'; break;
5265 case SHF_MERGE: *p = 'M'; break;
5266 case SHF_STRINGS: *p = 'S'; break;
5267 case SHF_INFO_LINK: *p = 'I'; break;
5268 case SHF_LINK_ORDER: *p = 'L'; break;
5269 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5270 case SHF_GROUP: *p = 'G'; break;
5271 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5272 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
5273
5274 default:
8a9036a4 5275 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
5276 || elf_header.e_machine == EM_L1OM
5277 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
5278 && flag == SHF_X86_64_LARGE)
5279 *p = 'l';
5280 else if (flag & SHF_MASKOS)
5281 {
5282 *p = 'o';
5283 sh_flags &= ~ SHF_MASKOS;
5284 }
5285 else if (flag & SHF_MASKPROC)
5286 {
5287 *p = 'p';
5288 sh_flags &= ~ SHF_MASKPROC;
5289 }
5290 else
5291 *p = 'x';
5292 break;
5293 }
5294 p++;
d1133906
NC
5295 }
5296 }
76da6bbe 5297
8d5ff12c
L
5298 if (do_section_details)
5299 {
5300 if (os_flags)
5301 {
5302 size -= 5 + field_size;
5303 if (p != buff + field_size + 4)
5304 {
5305 if (size < (2 + 1))
bee0ee85
NC
5306 {
5307 warn (_("Internal error: not enough buffer room for section flag info"));
5308 return _("<unknown>");
5309 }
8d5ff12c
L
5310 size -= 2;
5311 *p++ = ',';
5312 *p++ = ' ';
5313 }
5314 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5315 (unsigned long) os_flags);
5316 p += 5 + field_size;
5317 }
5318 if (proc_flags)
5319 {
5320 size -= 7 + field_size;
5321 if (p != buff + field_size + 4)
5322 {
5323 if (size < (2 + 1))
bee0ee85
NC
5324 {
5325 warn (_("Internal error: not enough buffer room for section flag info"));
5326 return _("<unknown>");
5327 }
8d5ff12c
L
5328 size -= 2;
5329 *p++ = ',';
5330 *p++ = ' ';
5331 }
5332 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5333 (unsigned long) proc_flags);
5334 p += 7 + field_size;
5335 }
5336 if (unknown_flags)
5337 {
5338 size -= 10 + field_size;
5339 if (p != buff + field_size + 4)
5340 {
5341 if (size < (2 + 1))
bee0ee85
NC
5342 {
5343 warn (_("Internal error: not enough buffer room for section flag info"));
5344 return _("<unknown>");
5345 }
8d5ff12c
L
5346 size -= 2;
5347 *p++ = ',';
5348 *p++ = ' ';
5349 }
2b692964 5350 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5351 (unsigned long) unknown_flags);
5352 p += 10 + field_size;
5353 }
5354 }
5355
e9e44622 5356 *p = '\0';
d1133906
NC
5357 return buff;
5358}
5359
252b5132 5360static int
2cf0635d 5361process_section_headers (FILE * file)
252b5132 5362{
2cf0635d 5363 Elf_Internal_Shdr * section;
b34976b6 5364 unsigned int i;
252b5132
RH
5365
5366 section_headers = NULL;
5367
5368 if (elf_header.e_shnum == 0)
5369 {
82f2dbf7
NC
5370 /* PR binutils/12467. */
5371 if (elf_header.e_shoff != 0)
5372 warn (_("possibly corrupt ELF file header - it has a non-zero"
5373 " section header offset, but no section headers\n"));
5374 else if (do_sections)
252b5132
RH
5375 printf (_("\nThere are no sections in this file.\n"));
5376
5377 return 1;
5378 }
5379
5380 if (do_sections && !do_header)
9ea033b2 5381 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
5382 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
5383
9ea033b2
NC
5384 if (is_32bit_elf)
5385 {
049b0c3a 5386 if (! get_32bit_section_headers (file, FALSE))
9ea033b2
NC
5387 return 0;
5388 }
049b0c3a 5389 else if (! get_64bit_section_headers (file, FALSE))
252b5132
RH
5390 return 0;
5391
5392 /* Read in the string table, so that we have names to display. */
0b49d371 5393 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 5394 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 5395 {
4fbb74a6 5396 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 5397
c256ffe7
JJ
5398 if (section->sh_size != 0)
5399 {
3f5e193b
NC
5400 string_table = (char *) get_data (NULL, file, section->sh_offset,
5401 1, section->sh_size,
5402 _("string table"));
0de14b54 5403
c256ffe7
JJ
5404 string_table_length = string_table != NULL ? section->sh_size : 0;
5405 }
252b5132
RH
5406 }
5407
5408 /* Scan the sections for the dynamic symbol table
e3c8793a 5409 and dynamic string table and debug sections. */
252b5132
RH
5410 dynamic_symbols = NULL;
5411 dynamic_strings = NULL;
5412 dynamic_syminfo = NULL;
f1ef08cb 5413 symtab_shndx_hdr = NULL;
103f02d3 5414
89fac5e3
RS
5415 eh_addr_size = is_32bit_elf ? 4 : 8;
5416 switch (elf_header.e_machine)
5417 {
5418 case EM_MIPS:
5419 case EM_MIPS_RS3_LE:
5420 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5421 FDE addresses. However, the ABI also has a semi-official ILP32
5422 variant for which the normal FDE address size rules apply.
5423
5424 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5425 section, where XX is the size of longs in bits. Unfortunately,
5426 earlier compilers provided no way of distinguishing ILP32 objects
5427 from LP64 objects, so if there's any doubt, we should assume that
5428 the official LP64 form is being used. */
5429 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5430 && find_section (".gcc_compiled_long32") == NULL)
5431 eh_addr_size = 8;
5432 break;
0f56a26a
DD
5433
5434 case EM_H8_300:
5435 case EM_H8_300H:
5436 switch (elf_header.e_flags & EF_H8_MACH)
5437 {
5438 case E_H8_MACH_H8300:
5439 case E_H8_MACH_H8300HN:
5440 case E_H8_MACH_H8300SN:
5441 case E_H8_MACH_H8300SXN:
5442 eh_addr_size = 2;
5443 break;
5444 case E_H8_MACH_H8300H:
5445 case E_H8_MACH_H8300S:
5446 case E_H8_MACH_H8300SX:
5447 eh_addr_size = 4;
5448 break;
5449 }
f4236fe4
DD
5450 break;
5451
ff7eeb89 5452 case EM_M32C_OLD:
f4236fe4
DD
5453 case EM_M32C:
5454 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5455 {
5456 case EF_M32C_CPU_M16C:
5457 eh_addr_size = 2;
5458 break;
5459 }
5460 break;
89fac5e3
RS
5461 }
5462
76ca31c0
NC
5463#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5464 do \
5465 { \
5466 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
5467 if (section->sh_entsize != expected_entsize) \
9dd3a467 5468 { \
76ca31c0
NC
5469 char buf[40]; \
5470 sprintf_vma (buf, section->sh_entsize); \
5471 /* Note: coded this way so that there is a single string for \
5472 translation. */ \
5473 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
5474 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
5475 (unsigned) expected_entsize); \
9dd3a467 5476 section->sh_entsize = expected_entsize; \
76ca31c0
NC
5477 } \
5478 } \
08d8fa11 5479 while (0)
9dd3a467
NC
5480
5481#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5482 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5483 sizeof (Elf64_External_##type))
5484
252b5132
RH
5485 for (i = 0, section = section_headers;
5486 i < elf_header.e_shnum;
b34976b6 5487 i++, section++)
252b5132 5488 {
2cf0635d 5489 char * name = SECTION_NAME (section);
252b5132
RH
5490
5491 if (section->sh_type == SHT_DYNSYM)
5492 {
5493 if (dynamic_symbols != NULL)
5494 {
5495 error (_("File contains multiple dynamic symbol tables\n"));
5496 continue;
5497 }
5498
08d8fa11 5499 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5500 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5501 }
5502 else if (section->sh_type == SHT_STRTAB
18bd398b 5503 && streq (name, ".dynstr"))
252b5132
RH
5504 {
5505 if (dynamic_strings != NULL)
5506 {
5507 error (_("File contains multiple dynamic string tables\n"));
5508 continue;
5509 }
5510
3f5e193b
NC
5511 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5512 1, section->sh_size,
5513 _("dynamic strings"));
59245841 5514 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5515 }
9ad5cbcf
AM
5516 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5517 {
5518 if (symtab_shndx_hdr != NULL)
5519 {
5520 error (_("File contains multiple symtab shndx tables\n"));
5521 continue;
5522 }
5523 symtab_shndx_hdr = section;
5524 }
08d8fa11
JJ
5525 else if (section->sh_type == SHT_SYMTAB)
5526 CHECK_ENTSIZE (section, i, Sym);
5527 else if (section->sh_type == SHT_GROUP)
5528 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5529 else if (section->sh_type == SHT_REL)
5530 CHECK_ENTSIZE (section, i, Rel);
5531 else if (section->sh_type == SHT_RELA)
5532 CHECK_ENTSIZE (section, i, Rela);
252b5132 5533 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5534 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5535 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5536 || do_debug_str || do_debug_loc || do_debug_ranges
5537 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5538 && (const_strneq (name, ".debug_")
5539 || const_strneq (name, ".zdebug_")))
252b5132 5540 {
1b315056
CS
5541 if (name[1] == 'z')
5542 name += sizeof (".zdebug_") - 1;
5543 else
5544 name += sizeof (".debug_") - 1;
252b5132
RH
5545
5546 if (do_debugging
4723351a
CC
5547 || (do_debug_info && const_strneq (name, "info"))
5548 || (do_debug_info && const_strneq (name, "types"))
5549 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5550 || (do_debug_lines && strcmp (name, "line") == 0)
5551 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5552 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5553 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5554 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5555 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5556 || (do_debug_aranges && const_strneq (name, "aranges"))
5557 || (do_debug_ranges && const_strneq (name, "ranges"))
5558 || (do_debug_frames && const_strneq (name, "frame"))
5559 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5560 || (do_debug_macinfo && const_strneq (name, "macro"))
5561 || (do_debug_str && const_strneq (name, "str"))
5562 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5563 || (do_debug_addr && const_strneq (name, "addr"))
5564 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5565 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5566 )
09c11c86 5567 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5568 }
a262ae96 5569 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5570 else if ((do_debugging || do_debug_info)
0112cd26 5571 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5572 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5573 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5574 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5575 else if (do_gdb_index && streq (name, ".gdb_index"))
5576 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5577 /* Trace sections for Itanium VMS. */
5578 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5579 || do_trace_aranges)
5580 && const_strneq (name, ".trace_"))
5581 {
5582 name += sizeof (".trace_") - 1;
5583
5584 if (do_debugging
5585 || (do_trace_info && streq (name, "info"))
5586 || (do_trace_abbrevs && streq (name, "abbrev"))
5587 || (do_trace_aranges && streq (name, "aranges"))
5588 )
5589 request_dump_bynumber (i, DEBUG_DUMP);
5590 }
252b5132
RH
5591 }
5592
5593 if (! do_sections)
5594 return 1;
5595
3a1a2036
NC
5596 if (elf_header.e_shnum > 1)
5597 printf (_("\nSection Headers:\n"));
5598 else
5599 printf (_("\nSection Header:\n"));
76da6bbe 5600
f7a99963 5601 if (is_32bit_elf)
595cf52e 5602 {
5477e8a0 5603 if (do_section_details)
595cf52e
L
5604 {
5605 printf (_(" [Nr] Name\n"));
5477e8a0 5606 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5607 }
5608 else
5609 printf
5610 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5611 }
d974e256 5612 else if (do_wide)
595cf52e 5613 {
5477e8a0 5614 if (do_section_details)
595cf52e
L
5615 {
5616 printf (_(" [Nr] Name\n"));
5477e8a0 5617 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5618 }
5619 else
5620 printf
5621 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5622 }
f7a99963
NC
5623 else
5624 {
5477e8a0 5625 if (do_section_details)
595cf52e
L
5626 {
5627 printf (_(" [Nr] Name\n"));
5477e8a0
L
5628 printf (_(" Type Address Offset Link\n"));
5629 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5630 }
5631 else
5632 {
5633 printf (_(" [Nr] Name Type Address Offset\n"));
5634 printf (_(" Size EntSize Flags Link Info Align\n"));
5635 }
f7a99963 5636 }
252b5132 5637
5477e8a0
L
5638 if (do_section_details)
5639 printf (_(" Flags\n"));
5640
252b5132
RH
5641 for (i = 0, section = section_headers;
5642 i < elf_header.e_shnum;
b34976b6 5643 i++, section++)
252b5132 5644 {
7bfd842d 5645 printf (" [%2u] ", i);
5477e8a0 5646 if (do_section_details)
74e1a04b 5647 printf ("%s\n ", printable_section_name (section));
595cf52e 5648 else
74e1a04b 5649 print_symbol (-17, SECTION_NAME (section));
0b4362b0 5650
ea52a088
NC
5651 printf (do_wide ? " %-15s " : " %-15.15s ",
5652 get_section_type_name (section->sh_type));
0b4362b0 5653
f7a99963
NC
5654 if (is_32bit_elf)
5655 {
cfcac11d
NC
5656 const char * link_too_big = NULL;
5657
f7a99963 5658 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5659
f7a99963
NC
5660 printf ( " %6.6lx %6.6lx %2.2lx",
5661 (unsigned long) section->sh_offset,
5662 (unsigned long) section->sh_size,
5663 (unsigned long) section->sh_entsize);
d1133906 5664
5477e8a0
L
5665 if (do_section_details)
5666 fputs (" ", stdout);
5667 else
5668 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5669
cfcac11d
NC
5670 if (section->sh_link >= elf_header.e_shnum)
5671 {
5672 link_too_big = "";
5673 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5674 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5675 switch (elf_header.e_machine)
5676 {
caa83f8b
NC
5677 case EM_386:
5678 case EM_486:
5679 case EM_X86_64:
7f502d6c 5680 case EM_L1OM:
7a9068fe 5681 case EM_K1OM:
cfcac11d
NC
5682 case EM_OLD_SPARCV9:
5683 case EM_SPARC32PLUS:
5684 case EM_SPARCV9:
5685 case EM_SPARC:
5686 if (section->sh_link == (SHN_BEFORE & 0xffff))
5687 link_too_big = "BEFORE";
5688 else if (section->sh_link == (SHN_AFTER & 0xffff))
5689 link_too_big = "AFTER";
5690 break;
5691 default:
5692 break;
5693 }
5694 }
5695
5696 if (do_section_details)
5697 {
5698 if (link_too_big != NULL && * link_too_big)
5699 printf ("<%s> ", link_too_big);
5700 else
5701 printf ("%2u ", section->sh_link);
5702 printf ("%3u %2lu\n", section->sh_info,
5703 (unsigned long) section->sh_addralign);
5704 }
5705 else
5706 printf ("%2u %3u %2lu\n",
5707 section->sh_link,
5708 section->sh_info,
5709 (unsigned long) section->sh_addralign);
5710
5711 if (link_too_big && ! * link_too_big)
5712 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5713 i, section->sh_link);
f7a99963 5714 }
d974e256
JJ
5715 else if (do_wide)
5716 {
5717 print_vma (section->sh_addr, LONG_HEX);
5718
5719 if ((long) section->sh_offset == section->sh_offset)
5720 printf (" %6.6lx", (unsigned long) section->sh_offset);
5721 else
5722 {
5723 putchar (' ');
5724 print_vma (section->sh_offset, LONG_HEX);
5725 }
5726
5727 if ((unsigned long) section->sh_size == section->sh_size)
5728 printf (" %6.6lx", (unsigned long) section->sh_size);
5729 else
5730 {
5731 putchar (' ');
5732 print_vma (section->sh_size, LONG_HEX);
5733 }
5734
5735 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5736 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5737 else
5738 {
5739 putchar (' ');
5740 print_vma (section->sh_entsize, LONG_HEX);
5741 }
5742
5477e8a0
L
5743 if (do_section_details)
5744 fputs (" ", stdout);
5745 else
5746 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5747
72de5009 5748 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5749
5750 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5751 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5752 else
5753 {
5754 print_vma (section->sh_addralign, DEC);
5755 putchar ('\n');
5756 }
5757 }
5477e8a0 5758 else if (do_section_details)
595cf52e 5759 {
5477e8a0 5760 printf (" %-15.15s ",
595cf52e 5761 get_section_type_name (section->sh_type));
595cf52e
L
5762 print_vma (section->sh_addr, LONG_HEX);
5763 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5764 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5765 else
5766 {
5767 printf (" ");
5768 print_vma (section->sh_offset, LONG_HEX);
5769 }
72de5009 5770 printf (" %u\n ", section->sh_link);
595cf52e 5771 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5772 putchar (' ');
595cf52e
L
5773 print_vma (section->sh_entsize, LONG_HEX);
5774
72de5009
AM
5775 printf (" %-16u %lu\n",
5776 section->sh_info,
595cf52e
L
5777 (unsigned long) section->sh_addralign);
5778 }
f7a99963
NC
5779 else
5780 {
5781 putchar (' ');
5782 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5783 if ((long) section->sh_offset == section->sh_offset)
5784 printf (" %8.8lx", (unsigned long) section->sh_offset);
5785 else
5786 {
5787 printf (" ");
5788 print_vma (section->sh_offset, LONG_HEX);
5789 }
f7a99963
NC
5790 printf ("\n ");
5791 print_vma (section->sh_size, LONG_HEX);
5792 printf (" ");
5793 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5794
d1133906 5795 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5796
72de5009
AM
5797 printf (" %2u %3u %lu\n",
5798 section->sh_link,
5799 section->sh_info,
f7a99963
NC
5800 (unsigned long) section->sh_addralign);
5801 }
5477e8a0
L
5802
5803 if (do_section_details)
5804 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5805 }
5806
5477e8a0 5807 if (!do_section_details)
3dbcc61d
NC
5808 {
5809 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5810 || elf_header.e_machine == EM_L1OM
5811 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5812 printf (_("Key to Flags:\n\
5813 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5814 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5815 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5816 else
5817 printf (_("Key to Flags:\n\
e3c8793a 5818 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5819 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5820 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 5821 }
d1133906 5822
252b5132
RH
5823 return 1;
5824}
5825
f5842774
L
5826static const char *
5827get_group_flags (unsigned int flags)
5828{
5829 static char buff[32];
5830 switch (flags)
5831 {
220453ec
AM
5832 case 0:
5833 return "";
5834
f5842774 5835 case GRP_COMDAT:
220453ec 5836 return "COMDAT ";
f5842774
L
5837
5838 default:
220453ec 5839 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5840 break;
5841 }
5842 return buff;
5843}
5844
5845static int
2cf0635d 5846process_section_groups (FILE * file)
f5842774 5847{
2cf0635d 5848 Elf_Internal_Shdr * section;
f5842774 5849 unsigned int i;
2cf0635d
NC
5850 struct group * group;
5851 Elf_Internal_Shdr * symtab_sec;
5852 Elf_Internal_Shdr * strtab_sec;
5853 Elf_Internal_Sym * symtab;
ba5cdace 5854 unsigned long num_syms;
2cf0635d 5855 char * strtab;
c256ffe7 5856 size_t strtab_size;
d1f5c6e3
L
5857
5858 /* Don't process section groups unless needed. */
5859 if (!do_unwind && !do_section_groups)
5860 return 1;
f5842774
L
5861
5862 if (elf_header.e_shnum == 0)
5863 {
5864 if (do_section_groups)
82f2dbf7 5865 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5866
5867 return 1;
5868 }
5869
5870 if (section_headers == NULL)
5871 {
5872 error (_("Section headers are not available!\n"));
fa1908fd
NC
5873 /* PR 13622: This can happen with a corrupt ELF header. */
5874 return 0;
f5842774
L
5875 }
5876
3f5e193b
NC
5877 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5878 sizeof (struct group *));
e4b17d5c
L
5879
5880 if (section_headers_groups == NULL)
5881 {
8b73c356
NC
5882 error (_("Out of memory reading %u section group headers\n"),
5883 elf_header.e_shnum);
e4b17d5c
L
5884 return 0;
5885 }
5886
f5842774 5887 /* Scan the sections for the group section. */
d1f5c6e3 5888 group_count = 0;
f5842774
L
5889 for (i = 0, section = section_headers;
5890 i < elf_header.e_shnum;
5891 i++, section++)
e4b17d5c
L
5892 if (section->sh_type == SHT_GROUP)
5893 group_count++;
5894
d1f5c6e3
L
5895 if (group_count == 0)
5896 {
5897 if (do_section_groups)
5898 printf (_("\nThere are no section groups in this file.\n"));
5899
5900 return 1;
5901 }
5902
3f5e193b 5903 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5904
5905 if (section_groups == NULL)
5906 {
8b73c356
NC
5907 error (_("Out of memory reading %lu groups\n"),
5908 (unsigned long) group_count);
e4b17d5c
L
5909 return 0;
5910 }
5911
d1f5c6e3
L
5912 symtab_sec = NULL;
5913 strtab_sec = NULL;
5914 symtab = NULL;
ba5cdace 5915 num_syms = 0;
d1f5c6e3 5916 strtab = NULL;
c256ffe7 5917 strtab_size = 0;
e4b17d5c
L
5918 for (i = 0, section = section_headers, group = section_groups;
5919 i < elf_header.e_shnum;
5920 i++, section++)
f5842774
L
5921 {
5922 if (section->sh_type == SHT_GROUP)
5923 {
74e1a04b
NC
5924 const char * name = printable_section_name (section);
5925 const char * group_name;
2cf0635d
NC
5926 unsigned char * start;
5927 unsigned char * indices;
f5842774 5928 unsigned int entry, j, size;
2cf0635d
NC
5929 Elf_Internal_Shdr * sec;
5930 Elf_Internal_Sym * sym;
f5842774
L
5931
5932 /* Get the symbol table. */
4fbb74a6
AM
5933 if (section->sh_link >= elf_header.e_shnum
5934 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5935 != SHT_SYMTAB))
f5842774
L
5936 {
5937 error (_("Bad sh_link in group section `%s'\n"), name);
5938 continue;
5939 }
d1f5c6e3
L
5940
5941 if (symtab_sec != sec)
5942 {
5943 symtab_sec = sec;
5944 if (symtab)
5945 free (symtab);
ba5cdace 5946 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5947 }
f5842774 5948
dd24e3da
NC
5949 if (symtab == NULL)
5950 {
5951 error (_("Corrupt header in group section `%s'\n"), name);
5952 continue;
5953 }
5954
ba5cdace
NC
5955 if (section->sh_info >= num_syms)
5956 {
5957 error (_("Bad sh_info in group section `%s'\n"), name);
5958 continue;
5959 }
5960
f5842774
L
5961 sym = symtab + section->sh_info;
5962
5963 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5964 {
4fbb74a6
AM
5965 if (sym->st_shndx == 0
5966 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5967 {
5968 error (_("Bad sh_info in group section `%s'\n"), name);
5969 continue;
5970 }
ba2685cc 5971
4fbb74a6 5972 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5973 strtab_sec = NULL;
5974 if (strtab)
5975 free (strtab);
f5842774 5976 strtab = NULL;
c256ffe7 5977 strtab_size = 0;
f5842774
L
5978 }
5979 else
5980 {
5981 /* Get the string table. */
4fbb74a6 5982 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5983 {
5984 strtab_sec = NULL;
5985 if (strtab)
5986 free (strtab);
5987 strtab = NULL;
5988 strtab_size = 0;
5989 }
5990 else if (strtab_sec
4fbb74a6 5991 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5992 {
5993 strtab_sec = sec;
5994 if (strtab)
5995 free (strtab);
071436c6 5996
3f5e193b 5997 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
071436c6
NC
5998 1, strtab_sec->sh_size,
5999 _("string table"));
c256ffe7 6000 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 6001 }
c256ffe7 6002 group_name = sym->st_name < strtab_size
2b692964 6003 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
6004 }
6005
c9c1d674
EG
6006 /* PR 17531: file: loop. */
6007 if (section->sh_entsize > section->sh_size)
6008 {
6009 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
6010 printable_section_name (section),
8066deb1
AM
6011 (unsigned long) section->sh_entsize,
6012 (unsigned long) section->sh_size);
c9c1d674
EG
6013 break;
6014 }
6015
3f5e193b
NC
6016 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
6017 1, section->sh_size,
6018 _("section data"));
59245841
NC
6019 if (start == NULL)
6020 continue;
f5842774
L
6021
6022 indices = start;
6023 size = (section->sh_size / section->sh_entsize) - 1;
6024 entry = byte_get (indices, 4);
6025 indices += 4;
e4b17d5c
L
6026
6027 if (do_section_groups)
6028 {
2b692964 6029 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6030 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6031
e4b17d5c
L
6032 printf (_(" [Index] Name\n"));
6033 }
6034
6035 group->group_index = i;
6036
f5842774
L
6037 for (j = 0; j < size; j++)
6038 {
2cf0635d 6039 struct group_list * g;
e4b17d5c 6040
f5842774
L
6041 entry = byte_get (indices, 4);
6042 indices += 4;
6043
4fbb74a6 6044 if (entry >= elf_header.e_shnum)
391cb864 6045 {
57028622
NC
6046 static unsigned num_group_errors = 0;
6047
6048 if (num_group_errors ++ < 10)
6049 {
6050 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
6051 entry, i, elf_header.e_shnum - 1);
6052 if (num_group_errors == 10)
6053 warn (_("Futher error messages about overlarge group section indicies suppressed\n"));
6054 }
391cb864
L
6055 continue;
6056 }
391cb864 6057
4fbb74a6 6058 if (section_headers_groups [entry] != NULL)
e4b17d5c 6059 {
d1f5c6e3
L
6060 if (entry)
6061 {
57028622
NC
6062 static unsigned num_errs = 0;
6063
6064 if (num_errs ++ < 10)
6065 {
6066 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6067 entry, i,
6068 section_headers_groups [entry]->group_index);
6069 if (num_errs == 10)
6070 warn (_("Further error messages about already contained group sections suppressed\n"));
6071 }
d1f5c6e3
L
6072 continue;
6073 }
6074 else
6075 {
6076 /* Intel C/C++ compiler may put section 0 in a
6077 section group. We just warn it the first time
6078 and ignore it afterwards. */
6079 static int warned = 0;
6080 if (!warned)
6081 {
6082 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6083 section_headers_groups [entry]->group_index);
d1f5c6e3
L
6084 warned++;
6085 }
6086 }
e4b17d5c
L
6087 }
6088
4fbb74a6 6089 section_headers_groups [entry] = group;
e4b17d5c
L
6090
6091 if (do_section_groups)
6092 {
4fbb74a6 6093 sec = section_headers + entry;
74e1a04b 6094 printf (" [%5u] %s\n", entry, printable_section_name (sec));
ba2685cc
AM
6095 }
6096
3f5e193b 6097 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6098 g->section_index = entry;
6099 g->next = group->root;
6100 group->root = g;
f5842774
L
6101 }
6102
f5842774
L
6103 if (start)
6104 free (start);
e4b17d5c
L
6105
6106 group++;
f5842774
L
6107 }
6108 }
6109
d1f5c6e3
L
6110 if (symtab)
6111 free (symtab);
6112 if (strtab)
6113 free (strtab);
f5842774
L
6114 return 1;
6115}
6116
28f997cf
TG
6117/* Data used to display dynamic fixups. */
6118
6119struct ia64_vms_dynfixup
6120{
6121 bfd_vma needed_ident; /* Library ident number. */
6122 bfd_vma needed; /* Index in the dstrtab of the library name. */
6123 bfd_vma fixup_needed; /* Index of the library. */
6124 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6125 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6126};
6127
6128/* Data used to display dynamic relocations. */
6129
6130struct ia64_vms_dynimgrela
6131{
6132 bfd_vma img_rela_cnt; /* Number of relocations. */
6133 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6134};
6135
6136/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6137 library). */
6138
6139static void
6140dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
6141 const char *strtab, unsigned int strtab_sz)
6142{
6143 Elf64_External_VMS_IMAGE_FIXUP *imfs;
6144 long i;
6145 const char *lib_name;
6146
6147 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
6148 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6149 _("dynamic section image fixups"));
6150 if (!imfs)
6151 return;
6152
6153 if (fixup->needed < strtab_sz)
6154 lib_name = strtab + fixup->needed;
6155 else
6156 {
6157 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 6158 (unsigned long) fixup->needed);
28f997cf
TG
6159 lib_name = "???";
6160 }
6161 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6162 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6163 printf
6164 (_("Seg Offset Type SymVec DataType\n"));
6165
6166 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6167 {
6168 unsigned int type;
6169 const char *rtype;
6170
6171 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6172 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6173 type = BYTE_GET (imfs [i].type);
6174 rtype = elf_ia64_reloc_type (type);
6175 if (rtype == NULL)
6176 printf (" 0x%08x ", type);
6177 else
6178 printf (" %-32s ", rtype);
6179 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6180 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6181 }
6182
6183 free (imfs);
6184}
6185
6186/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6187
6188static void
6189dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
6190{
6191 Elf64_External_VMS_IMAGE_RELA *imrs;
6192 long i;
6193
6194 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
6195 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6196 _("dynamic section image relocations"));
28f997cf
TG
6197 if (!imrs)
6198 return;
6199
6200 printf (_("\nImage relocs\n"));
6201 printf
6202 (_("Seg Offset Type Addend Seg Sym Off\n"));
6203
6204 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6205 {
6206 unsigned int type;
6207 const char *rtype;
6208
6209 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6210 printf ("%08" BFD_VMA_FMT "x ",
6211 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6212 type = BYTE_GET (imrs [i].type);
6213 rtype = elf_ia64_reloc_type (type);
6214 if (rtype == NULL)
6215 printf ("0x%08x ", type);
6216 else
6217 printf ("%-31s ", rtype);
6218 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6219 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6220 printf ("%08" BFD_VMA_FMT "x\n",
6221 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6222 }
6223
6224 free (imrs);
6225}
6226
6227/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6228
6229static int
6230process_ia64_vms_dynamic_relocs (FILE *file)
6231{
6232 struct ia64_vms_dynfixup fixup;
6233 struct ia64_vms_dynimgrela imgrela;
6234 Elf_Internal_Dyn *entry;
6235 int res = 0;
6236 bfd_vma strtab_off = 0;
6237 bfd_vma strtab_sz = 0;
6238 char *strtab = NULL;
6239
6240 memset (&fixup, 0, sizeof (fixup));
6241 memset (&imgrela, 0, sizeof (imgrela));
6242
6243 /* Note: the order of the entries is specified by the OpenVMS specs. */
6244 for (entry = dynamic_section;
6245 entry < dynamic_section + dynamic_nent;
6246 entry++)
6247 {
6248 switch (entry->d_tag)
6249 {
6250 case DT_IA_64_VMS_STRTAB_OFFSET:
6251 strtab_off = entry->d_un.d_val;
6252 break;
6253 case DT_STRSZ:
6254 strtab_sz = entry->d_un.d_val;
6255 if (strtab == NULL)
6256 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
6257 1, strtab_sz, _("dynamic string section"));
6258 break;
6259
6260 case DT_IA_64_VMS_NEEDED_IDENT:
6261 fixup.needed_ident = entry->d_un.d_val;
6262 break;
6263 case DT_NEEDED:
6264 fixup.needed = entry->d_un.d_val;
6265 break;
6266 case DT_IA_64_VMS_FIXUP_NEEDED:
6267 fixup.fixup_needed = entry->d_un.d_val;
6268 break;
6269 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6270 fixup.fixup_rela_cnt = entry->d_un.d_val;
6271 break;
6272 case DT_IA_64_VMS_FIXUP_RELA_OFF:
6273 fixup.fixup_rela_off = entry->d_un.d_val;
6274 res++;
6275 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
6276 break;
6277
6278 case DT_IA_64_VMS_IMG_RELA_CNT:
6279 imgrela.img_rela_cnt = entry->d_un.d_val;
6280 break;
6281 case DT_IA_64_VMS_IMG_RELA_OFF:
6282 imgrela.img_rela_off = entry->d_un.d_val;
6283 res++;
6284 dump_ia64_vms_dynamic_relocs (file, &imgrela);
6285 break;
6286
6287 default:
6288 break;
6289 }
6290 }
6291
6292 if (strtab != NULL)
6293 free (strtab);
6294
6295 return res;
6296}
6297
85b1c36d 6298static struct
566b0d53 6299{
2cf0635d 6300 const char * name;
566b0d53
L
6301 int reloc;
6302 int size;
6303 int rela;
6304} dynamic_relocations [] =
6305{
6306 { "REL", DT_REL, DT_RELSZ, FALSE },
6307 { "RELA", DT_RELA, DT_RELASZ, TRUE },
6308 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
6309};
6310
252b5132 6311/* Process the reloc section. */
18bd398b 6312
252b5132 6313static int
2cf0635d 6314process_relocs (FILE * file)
252b5132 6315{
b34976b6
AM
6316 unsigned long rel_size;
6317 unsigned long rel_offset;
252b5132
RH
6318
6319
6320 if (!do_reloc)
6321 return 1;
6322
6323 if (do_using_dynamic)
6324 {
566b0d53 6325 int is_rela;
2cf0635d 6326 const char * name;
566b0d53
L
6327 int has_dynamic_reloc;
6328 unsigned int i;
0de14b54 6329
566b0d53 6330 has_dynamic_reloc = 0;
252b5132 6331
566b0d53 6332 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 6333 {
566b0d53
L
6334 is_rela = dynamic_relocations [i].rela;
6335 name = dynamic_relocations [i].name;
6336 rel_size = dynamic_info [dynamic_relocations [i].size];
6337 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 6338
566b0d53
L
6339 has_dynamic_reloc |= rel_size;
6340
6341 if (is_rela == UNKNOWN)
aa903cfb 6342 {
566b0d53
L
6343 if (dynamic_relocations [i].reloc == DT_JMPREL)
6344 switch (dynamic_info[DT_PLTREL])
6345 {
6346 case DT_REL:
6347 is_rela = FALSE;
6348 break;
6349 case DT_RELA:
6350 is_rela = TRUE;
6351 break;
6352 }
aa903cfb 6353 }
252b5132 6354
566b0d53
L
6355 if (rel_size)
6356 {
6357 printf
6358 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
6359 name, rel_offset, rel_size);
252b5132 6360
d93f0186
NC
6361 dump_relocations (file,
6362 offset_from_vma (file, rel_offset, rel_size),
6363 rel_size,
566b0d53 6364 dynamic_symbols, num_dynamic_syms,
bb4d2ac2
L
6365 dynamic_strings, dynamic_strings_length,
6366 is_rela, 1);
566b0d53 6367 }
252b5132 6368 }
566b0d53 6369
28f997cf
TG
6370 if (is_ia64_vms ())
6371 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
6372
566b0d53 6373 if (! has_dynamic_reloc)
252b5132
RH
6374 printf (_("\nThere are no dynamic relocations in this file.\n"));
6375 }
6376 else
6377 {
2cf0635d 6378 Elf_Internal_Shdr * section;
b34976b6
AM
6379 unsigned long i;
6380 int found = 0;
252b5132
RH
6381
6382 for (i = 0, section = section_headers;
6383 i < elf_header.e_shnum;
b34976b6 6384 i++, section++)
252b5132
RH
6385 {
6386 if ( section->sh_type != SHT_RELA
6387 && section->sh_type != SHT_REL)
6388 continue;
6389
6390 rel_offset = section->sh_offset;
6391 rel_size = section->sh_size;
6392
6393 if (rel_size)
6394 {
2cf0635d 6395 Elf_Internal_Shdr * strsec;
b34976b6 6396 int is_rela;
103f02d3 6397
252b5132
RH
6398 printf (_("\nRelocation section "));
6399
6400 if (string_table == NULL)
19936277 6401 printf ("%d", section->sh_name);
252b5132 6402 else
74e1a04b 6403 printf ("'%s'", printable_section_name (section));
252b5132
RH
6404
6405 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6406 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
6407
d79b3d50
NC
6408 is_rela = section->sh_type == SHT_RELA;
6409
4fbb74a6
AM
6410 if (section->sh_link != 0
6411 && section->sh_link < elf_header.e_shnum)
af3fc3bc 6412 {
2cf0635d
NC
6413 Elf_Internal_Shdr * symsec;
6414 Elf_Internal_Sym * symtab;
d79b3d50 6415 unsigned long nsyms;
c256ffe7 6416 unsigned long strtablen = 0;
2cf0635d 6417 char * strtab = NULL;
57346661 6418
4fbb74a6 6419 symsec = section_headers + section->sh_link;
08d8fa11
JJ
6420 if (symsec->sh_type != SHT_SYMTAB
6421 && symsec->sh_type != SHT_DYNSYM)
6422 continue;
6423
ba5cdace 6424 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 6425
af3fc3bc
AM
6426 if (symtab == NULL)
6427 continue;
252b5132 6428
4fbb74a6
AM
6429 if (symsec->sh_link != 0
6430 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 6431 {
4fbb74a6 6432 strsec = section_headers + symsec->sh_link;
103f02d3 6433
3f5e193b 6434 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
071436c6
NC
6435 1, strsec->sh_size,
6436 _("string table"));
c256ffe7
JJ
6437 strtablen = strtab == NULL ? 0 : strsec->sh_size;
6438 }
252b5132 6439
d79b3d50 6440 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2
L
6441 symtab, nsyms, strtab, strtablen,
6442 is_rela,
6443 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
6444 if (strtab)
6445 free (strtab);
6446 free (symtab);
6447 }
6448 else
6449 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2 6450 NULL, 0, NULL, 0, is_rela, 0);
252b5132
RH
6451
6452 found = 1;
6453 }
6454 }
6455
6456 if (! found)
6457 printf (_("\nThere are no relocations in this file.\n"));
6458 }
6459
6460 return 1;
6461}
6462
4d6ed7c8
NC
6463/* An absolute address consists of a section and an offset. If the
6464 section is NULL, the offset itself is the address, otherwise, the
6465 address equals to LOAD_ADDRESS(section) + offset. */
6466
6467struct absaddr
948f632f
DA
6468{
6469 unsigned short section;
6470 bfd_vma offset;
6471};
4d6ed7c8 6472
1949de15
L
6473#define ABSADDR(a) \
6474 ((a).section \
6475 ? section_headers [(a).section].sh_addr + (a).offset \
6476 : (a).offset)
6477
948f632f
DA
6478/* Find the nearest symbol at or below ADDR. Returns the symbol
6479 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 6480
4d6ed7c8 6481static void
2cf0635d 6482find_symbol_for_address (Elf_Internal_Sym * symtab,
948f632f
DA
6483 unsigned long nsyms,
6484 const char * strtab,
6485 unsigned long strtab_size,
6486 struct absaddr addr,
6487 const char ** symname,
6488 bfd_vma * offset)
4d6ed7c8 6489{
d3ba0551 6490 bfd_vma dist = 0x100000;
2cf0635d 6491 Elf_Internal_Sym * sym;
948f632f
DA
6492 Elf_Internal_Sym * beg;
6493 Elf_Internal_Sym * end;
2cf0635d 6494 Elf_Internal_Sym * best = NULL;
4d6ed7c8 6495
0b6ae522 6496 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
6497 beg = symtab;
6498 end = symtab + nsyms;
0b6ae522 6499
948f632f 6500 while (beg < end)
4d6ed7c8 6501 {
948f632f
DA
6502 bfd_vma value;
6503
6504 sym = beg + (end - beg) / 2;
0b6ae522 6505
948f632f 6506 value = sym->st_value;
0b6ae522
DJ
6507 REMOVE_ARCH_BITS (value);
6508
948f632f 6509 if (sym->st_name != 0
4d6ed7c8 6510 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
6511 && addr.offset >= value
6512 && addr.offset - value < dist)
4d6ed7c8
NC
6513 {
6514 best = sym;
0b6ae522 6515 dist = addr.offset - value;
4d6ed7c8
NC
6516 if (!dist)
6517 break;
6518 }
948f632f
DA
6519
6520 if (addr.offset < value)
6521 end = sym;
6522 else
6523 beg = sym + 1;
4d6ed7c8 6524 }
1b31d05e 6525
4d6ed7c8
NC
6526 if (best)
6527 {
57346661 6528 *symname = (best->st_name >= strtab_size
2b692964 6529 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
6530 *offset = dist;
6531 return;
6532 }
1b31d05e 6533
4d6ed7c8
NC
6534 *symname = NULL;
6535 *offset = addr.offset;
6536}
6537
948f632f
DA
6538static int
6539symcmp (const void *p, const void *q)
6540{
6541 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
6542 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
6543
6544 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
6545}
6546
6547/* Process the unwind section. */
6548
6549#include "unwind-ia64.h"
6550
6551struct ia64_unw_table_entry
6552{
6553 struct absaddr start;
6554 struct absaddr end;
6555 struct absaddr info;
6556};
6557
6558struct ia64_unw_aux_info
6559{
6560 struct ia64_unw_table_entry *table; /* Unwind table. */
6561 unsigned long table_len; /* Length of unwind table. */
6562 unsigned char * info; /* Unwind info. */
6563 unsigned long info_size; /* Size of unwind info. */
6564 bfd_vma info_addr; /* Starting address of unwind info. */
6565 bfd_vma seg_base; /* Starting address of segment. */
6566 Elf_Internal_Sym * symtab; /* The symbol table. */
6567 unsigned long nsyms; /* Number of symbols. */
6568 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
6569 unsigned long nfuns; /* Number of entries in funtab. */
6570 char * strtab; /* The string table. */
6571 unsigned long strtab_size; /* Size of string table. */
6572};
6573
4d6ed7c8 6574static void
2cf0635d 6575dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 6576{
2cf0635d 6577 struct ia64_unw_table_entry * tp;
948f632f 6578 unsigned long j, nfuns;
4d6ed7c8 6579 int in_body;
7036c0e1 6580
948f632f
DA
6581 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
6582 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
6583 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
6584 aux->funtab[nfuns++] = aux->symtab[j];
6585 aux->nfuns = nfuns;
6586 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
6587
4d6ed7c8
NC
6588 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6589 {
6590 bfd_vma stamp;
6591 bfd_vma offset;
2cf0635d
NC
6592 const unsigned char * dp;
6593 const unsigned char * head;
53774b7e 6594 const unsigned char * end;
2cf0635d 6595 const char * procname;
4d6ed7c8 6596
948f632f 6597 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
57346661 6598 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
6599
6600 fputs ("\n<", stdout);
6601
6602 if (procname)
6603 {
6604 fputs (procname, stdout);
6605
6606 if (offset)
6607 printf ("+%lx", (unsigned long) offset);
6608 }
6609
6610 fputs (">: [", stdout);
6611 print_vma (tp->start.offset, PREFIX_HEX);
6612 fputc ('-', stdout);
6613 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 6614 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
6615 (unsigned long) (tp->info.offset - aux->seg_base));
6616
53774b7e
NC
6617 /* PR 17531: file: 86232b32. */
6618 if (aux->info == NULL)
6619 continue;
6620
6621 /* PR 17531: file: 0997b4d1. */
6622 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
6623 {
6624 warn (_("Invalid offset %lx in table entry %ld\n"),
6625 (long) tp->info.offset, (long) (tp - aux->table));
6626 continue;
6627 }
6628
1949de15 6629 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 6630 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 6631
86f55779 6632 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
6633 (unsigned) UNW_VER (stamp),
6634 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
6635 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
6636 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 6637 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
6638
6639 if (UNW_VER (stamp) != 1)
6640 {
2b692964 6641 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
6642 continue;
6643 }
6644
6645 in_body = 0;
53774b7e
NC
6646 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
6647 /* PR 17531: file: 16ceda89. */
6648 if (end > aux->info + aux->info_size)
6649 end = aux->info + aux->info_size;
6650 for (dp = head + 8; dp < end;)
4d6ed7c8
NC
6651 dp = unw_decode (dp, in_body, & in_body);
6652 }
948f632f
DA
6653
6654 free (aux->funtab);
4d6ed7c8
NC
6655}
6656
53774b7e 6657static bfd_boolean
2cf0635d
NC
6658slurp_ia64_unwind_table (FILE * file,
6659 struct ia64_unw_aux_info * aux,
6660 Elf_Internal_Shdr * sec)
4d6ed7c8 6661{
89fac5e3 6662 unsigned long size, nrelas, i;
2cf0635d
NC
6663 Elf_Internal_Phdr * seg;
6664 struct ia64_unw_table_entry * tep;
6665 Elf_Internal_Shdr * relsec;
6666 Elf_Internal_Rela * rela;
6667 Elf_Internal_Rela * rp;
6668 unsigned char * table;
6669 unsigned char * tp;
6670 Elf_Internal_Sym * sym;
6671 const char * relname;
4d6ed7c8 6672
53774b7e
NC
6673 aux->table_len = 0;
6674
4d6ed7c8
NC
6675 /* First, find the starting address of the segment that includes
6676 this section: */
6677
6678 if (elf_header.e_phnum)
6679 {
d93f0186 6680 if (! get_program_headers (file))
53774b7e 6681 return FALSE;
4d6ed7c8 6682
d93f0186
NC
6683 for (seg = program_headers;
6684 seg < program_headers + elf_header.e_phnum;
6685 ++seg)
4d6ed7c8
NC
6686 {
6687 if (seg->p_type != PT_LOAD)
6688 continue;
6689
6690 if (sec->sh_addr >= seg->p_vaddr
6691 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6692 {
6693 aux->seg_base = seg->p_vaddr;
6694 break;
6695 }
6696 }
4d6ed7c8
NC
6697 }
6698
6699 /* Second, build the unwind table from the contents of the unwind section: */
6700 size = sec->sh_size;
3f5e193b
NC
6701 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6702 _("unwind table"));
a6e9f9df 6703 if (!table)
53774b7e 6704 return FALSE;
4d6ed7c8 6705
53774b7e 6706 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 6707 aux->table = (struct ia64_unw_table_entry *)
53774b7e 6708 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 6709 tep = aux->table;
53774b7e
NC
6710
6711 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
6712 {
6713 tep->start.section = SHN_UNDEF;
6714 tep->end.section = SHN_UNDEF;
6715 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6716 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6717 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6718 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6719 tep->start.offset += aux->seg_base;
6720 tep->end.offset += aux->seg_base;
6721 tep->info.offset += aux->seg_base;
6722 }
6723 free (table);
6724
41e92641 6725 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6726 for (relsec = section_headers;
6727 relsec < section_headers + elf_header.e_shnum;
6728 ++relsec)
6729 {
6730 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6731 || relsec->sh_info >= elf_header.e_shnum
6732 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6733 continue;
6734
6735 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6736 & rela, & nrelas))
53774b7e
NC
6737 {
6738 free (aux->table);
6739 aux->table = NULL;
6740 aux->table_len = 0;
6741 return FALSE;
6742 }
4d6ed7c8
NC
6743
6744 for (rp = rela; rp < rela + nrelas; ++rp)
6745 {
aca88567
NC
6746 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6747 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6748
82b1b41b
NC
6749 /* PR 17531: file: 9fa67536. */
6750 if (relname == NULL)
6751 {
6752 warn (_("Skipping unknown relocation type: %u\n"), get_reloc_type (rp->r_info));
6753 continue;
6754 }
948f632f 6755
0112cd26 6756 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6757 {
82b1b41b 6758 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
6759 continue;
6760 }
6761
89fac5e3 6762 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6763
53774b7e
NC
6764 /* PR 17531: file: 5bc8d9bf. */
6765 if (i >= aux->table_len)
6766 {
6767 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
6768 continue;
6769 }
6770
6771 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
6772 {
6773 case 0:
6774 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6775 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6776 break;
6777 case 1:
6778 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6779 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6780 break;
6781 case 2:
6782 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6783 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6784 break;
6785 default:
6786 break;
6787 }
6788 }
6789
6790 free (rela);
6791 }
6792
53774b7e 6793 return TRUE;
4d6ed7c8
NC
6794}
6795
1b31d05e 6796static void
2cf0635d 6797ia64_process_unwind (FILE * file)
4d6ed7c8 6798{
2cf0635d
NC
6799 Elf_Internal_Shdr * sec;
6800 Elf_Internal_Shdr * unwsec = NULL;
6801 Elf_Internal_Shdr * strsec;
89fac5e3 6802 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6803 struct ia64_unw_aux_info aux;
f1467e33 6804
4d6ed7c8
NC
6805 memset (& aux, 0, sizeof (aux));
6806
4d6ed7c8
NC
6807 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6808 {
c256ffe7 6809 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6810 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6811 {
ba5cdace 6812 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6813
4fbb74a6 6814 strsec = section_headers + sec->sh_link;
4082ef84
NC
6815 if (aux.strtab != NULL)
6816 {
6817 error (_("Multiple auxillary string tables encountered\n"));
6818 free (aux.strtab);
6819 }
3f5e193b
NC
6820 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6821 1, strsec->sh_size,
6822 _("string table"));
c256ffe7 6823 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6824 }
6825 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6826 unwcount++;
6827 }
6828
6829 if (!unwcount)
6830 printf (_("\nThere are no unwind sections in this file.\n"));
6831
6832 while (unwcount-- > 0)
6833 {
2cf0635d 6834 char * suffix;
579f31ac
JJ
6835 size_t len, len2;
6836
4082ef84 6837 for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
579f31ac
JJ
6838 i < elf_header.e_shnum; ++i, ++sec)
6839 if (sec->sh_type == SHT_IA_64_UNWIND)
6840 {
6841 unwsec = sec;
6842 break;
6843 }
4082ef84
NC
6844 /* We have already counted the number of SHT_IA64_UNWIND
6845 sections so the loop above should never fail. */
6846 assert (unwsec != NULL);
579f31ac
JJ
6847
6848 unwstart = i + 1;
6849 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6850
e4b17d5c
L
6851 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6852 {
6853 /* We need to find which section group it is in. */
4082ef84 6854 struct group_list * g;
e4b17d5c 6855
4082ef84
NC
6856 if (section_headers_groups == NULL
6857 || section_headers_groups [i] == NULL)
6858 i = elf_header.e_shnum;
6859 else
e4b17d5c 6860 {
4082ef84 6861 g = section_headers_groups [i]->root;
18bd398b 6862
4082ef84
NC
6863 for (; g != NULL; g = g->next)
6864 {
6865 sec = section_headers + g->section_index;
e4b17d5c 6866
4082ef84
NC
6867 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
6868 break;
6869 }
6870
6871 if (g == NULL)
6872 i = elf_header.e_shnum;
6873 }
e4b17d5c 6874 }
18bd398b 6875 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6876 {
18bd398b 6877 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6878 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6879 suffix = SECTION_NAME (unwsec) + len;
6880 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6881 ++i, ++sec)
18bd398b
NC
6882 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6883 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6884 break;
6885 }
6886 else
6887 {
6888 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6889 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6890 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6891 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6892 suffix = "";
18bd398b 6893 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6894 suffix = SECTION_NAME (unwsec) + len;
6895 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6896 ++i, ++sec)
18bd398b
NC
6897 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6898 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6899 break;
6900 }
6901
6902 if (i == elf_header.e_shnum)
6903 {
6904 printf (_("\nCould not find unwind info section for "));
6905
6906 if (string_table == NULL)
6907 printf ("%d", unwsec->sh_name);
6908 else
74e1a04b 6909 printf ("'%s'", printable_section_name (unwsec));
579f31ac
JJ
6910 }
6911 else
4d6ed7c8 6912 {
4d6ed7c8 6913 aux.info_addr = sec->sh_addr;
3f5e193b 6914 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
4082ef84
NC
6915 sec->sh_size,
6916 _("unwind info"));
59245841 6917 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6918
579f31ac 6919 printf (_("\nUnwind section "));
4d6ed7c8 6920
579f31ac
JJ
6921 if (string_table == NULL)
6922 printf ("%d", unwsec->sh_name);
6923 else
74e1a04b 6924 printf ("'%s'", printable_section_name (unwsec));
4d6ed7c8 6925
579f31ac 6926 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6927 (unsigned long) unwsec->sh_offset,
89fac5e3 6928 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6929
53774b7e
NC
6930 if (slurp_ia64_unwind_table (file, & aux, unwsec)
6931 && aux.table_len > 0)
579f31ac
JJ
6932 dump_ia64_unwind (& aux);
6933
6934 if (aux.table)
6935 free ((char *) aux.table);
6936 if (aux.info)
6937 free ((char *) aux.info);
6938 aux.table = NULL;
6939 aux.info = NULL;
6940 }
4d6ed7c8 6941 }
4d6ed7c8 6942
4d6ed7c8
NC
6943 if (aux.symtab)
6944 free (aux.symtab);
6945 if (aux.strtab)
6946 free ((char *) aux.strtab);
4d6ed7c8
NC
6947}
6948
3f5e193b
NC
6949struct hppa_unw_table_entry
6950 {
6951 struct absaddr start;
6952 struct absaddr end;
948f632f 6953 unsigned int Cannot_unwind:1; /* 0 */
3f5e193b
NC
6954 unsigned int Millicode:1; /* 1 */
6955 unsigned int Millicode_save_sr0:1; /* 2 */
6956 unsigned int Region_description:2; /* 3..4 */
6957 unsigned int reserved1:1; /* 5 */
6958 unsigned int Entry_SR:1; /* 6 */
6959 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6960 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6961 unsigned int Args_stored:1; /* 16 */
948f632f
DA
6962 unsigned int Variable_Frame:1; /* 17 */
6963 unsigned int Separate_Package_Body:1; /* 18 */
3f5e193b 6964 unsigned int Frame_Extension_Millicode:1; /* 19 */
948f632f
DA
6965 unsigned int Stack_Overflow_Check:1; /* 20 */
6966 unsigned int Two_Instruction_SP_Increment:1;/* 21 */
3f5e193b
NC
6967 unsigned int Ada_Region:1; /* 22 */
6968 unsigned int cxx_info:1; /* 23 */
948f632f
DA
6969 unsigned int cxx_try_catch:1; /* 24 */
6970 unsigned int sched_entry_seq:1; /* 25 */
3f5e193b 6971 unsigned int reserved2:1; /* 26 */
948f632f
DA
6972 unsigned int Save_SP:1; /* 27 */
6973 unsigned int Save_RP:1; /* 28 */
3f5e193b
NC
6974 unsigned int Save_MRP_in_frame:1; /* 29 */
6975 unsigned int extn_ptr_defined:1; /* 30 */
948f632f 6976 unsigned int Cleanup_defined:1; /* 31 */
3f5e193b 6977
948f632f
DA
6978 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6979 unsigned int HP_UX_interrupt_marker:1; /* 1 */
3f5e193b 6980 unsigned int Large_frame:1; /* 2 */
948f632f 6981 unsigned int Pseudo_SP_Set:1; /* 3 */
3f5e193b
NC
6982 unsigned int reserved4:1; /* 4 */
6983 unsigned int Total_frame_size:27; /* 5..31 */
6984 };
6985
57346661 6986struct hppa_unw_aux_info
948f632f
DA
6987{
6988 struct hppa_unw_table_entry * table; /* Unwind table. */
6989 unsigned long table_len; /* Length of unwind table. */
6990 bfd_vma seg_base; /* Starting address of segment. */
6991 Elf_Internal_Sym * symtab; /* The symbol table. */
6992 unsigned long nsyms; /* Number of symbols. */
6993 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
6994 unsigned long nfuns; /* Number of entries in funtab. */
6995 char * strtab; /* The string table. */
6996 unsigned long strtab_size; /* Size of string table. */
6997};
57346661
AM
6998
6999static void
2cf0635d 7000dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 7001{
2cf0635d 7002 struct hppa_unw_table_entry * tp;
948f632f
DA
7003 unsigned long j, nfuns;
7004
7005 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7006 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7007 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7008 aux->funtab[nfuns++] = aux->symtab[j];
7009 aux->nfuns = nfuns;
7010 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 7011
57346661
AM
7012 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7013 {
7014 bfd_vma offset;
2cf0635d 7015 const char * procname;
57346661 7016
948f632f 7017 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
7018 aux->strtab_size, tp->start, &procname,
7019 &offset);
7020
7021 fputs ("\n<", stdout);
7022
7023 if (procname)
7024 {
7025 fputs (procname, stdout);
7026
7027 if (offset)
7028 printf ("+%lx", (unsigned long) offset);
7029 }
7030
7031 fputs (">: [", stdout);
7032 print_vma (tp->start.offset, PREFIX_HEX);
7033 fputc ('-', stdout);
7034 print_vma (tp->end.offset, PREFIX_HEX);
7035 printf ("]\n\t");
7036
18bd398b
NC
7037#define PF(_m) if (tp->_m) printf (#_m " ");
7038#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
7039 PF(Cannot_unwind);
7040 PF(Millicode);
7041 PF(Millicode_save_sr0);
18bd398b 7042 /* PV(Region_description); */
57346661
AM
7043 PF(Entry_SR);
7044 PV(Entry_FR);
7045 PV(Entry_GR);
7046 PF(Args_stored);
7047 PF(Variable_Frame);
7048 PF(Separate_Package_Body);
7049 PF(Frame_Extension_Millicode);
7050 PF(Stack_Overflow_Check);
7051 PF(Two_Instruction_SP_Increment);
7052 PF(Ada_Region);
7053 PF(cxx_info);
7054 PF(cxx_try_catch);
7055 PF(sched_entry_seq);
7056 PF(Save_SP);
7057 PF(Save_RP);
7058 PF(Save_MRP_in_frame);
7059 PF(extn_ptr_defined);
7060 PF(Cleanup_defined);
7061 PF(MPE_XL_interrupt_marker);
7062 PF(HP_UX_interrupt_marker);
7063 PF(Large_frame);
7064 PF(Pseudo_SP_Set);
7065 PV(Total_frame_size);
7066#undef PF
7067#undef PV
7068 }
7069
18bd398b 7070 printf ("\n");
948f632f
DA
7071
7072 free (aux->funtab);
57346661
AM
7073}
7074
7075static int
2cf0635d
NC
7076slurp_hppa_unwind_table (FILE * file,
7077 struct hppa_unw_aux_info * aux,
7078 Elf_Internal_Shdr * sec)
57346661 7079{
1c0751b2 7080 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7081 Elf_Internal_Phdr * seg;
7082 struct hppa_unw_table_entry * tep;
7083 Elf_Internal_Shdr * relsec;
7084 Elf_Internal_Rela * rela;
7085 Elf_Internal_Rela * rp;
7086 unsigned char * table;
7087 unsigned char * tp;
7088 Elf_Internal_Sym * sym;
7089 const char * relname;
57346661 7090
57346661
AM
7091 /* First, find the starting address of the segment that includes
7092 this section. */
7093
7094 if (elf_header.e_phnum)
7095 {
7096 if (! get_program_headers (file))
7097 return 0;
7098
7099 for (seg = program_headers;
7100 seg < program_headers + elf_header.e_phnum;
7101 ++seg)
7102 {
7103 if (seg->p_type != PT_LOAD)
7104 continue;
7105
7106 if (sec->sh_addr >= seg->p_vaddr
7107 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7108 {
7109 aux->seg_base = seg->p_vaddr;
7110 break;
7111 }
7112 }
7113 }
7114
7115 /* Second, build the unwind table from the contents of the unwind
7116 section. */
7117 size = sec->sh_size;
3f5e193b
NC
7118 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
7119 _("unwind table"));
57346661
AM
7120 if (!table)
7121 return 0;
7122
1c0751b2
DA
7123 unw_ent_size = 16;
7124 nentries = size / unw_ent_size;
7125 size = unw_ent_size * nentries;
57346661 7126
3f5e193b
NC
7127 tep = aux->table = (struct hppa_unw_table_entry *)
7128 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7129
1c0751b2 7130 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7131 {
7132 unsigned int tmp1, tmp2;
7133
7134 tep->start.section = SHN_UNDEF;
7135 tep->end.section = SHN_UNDEF;
7136
1c0751b2
DA
7137 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7138 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7139 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7140 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7141
7142 tep->start.offset += aux->seg_base;
7143 tep->end.offset += aux->seg_base;
57346661
AM
7144
7145 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
7146 tep->Millicode = (tmp1 >> 30) & 0x1;
7147 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
7148 tep->Region_description = (tmp1 >> 27) & 0x3;
7149 tep->reserved1 = (tmp1 >> 26) & 0x1;
7150 tep->Entry_SR = (tmp1 >> 25) & 0x1;
7151 tep->Entry_FR = (tmp1 >> 21) & 0xf;
7152 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7153 tep->Args_stored = (tmp1 >> 15) & 0x1;
7154 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7155 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7156 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7157 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7158 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7159 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7160 tep->cxx_info = (tmp1 >> 8) & 0x1;
7161 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7162 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7163 tep->reserved2 = (tmp1 >> 5) & 0x1;
7164 tep->Save_SP = (tmp1 >> 4) & 0x1;
7165 tep->Save_RP = (tmp1 >> 3) & 0x1;
7166 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7167 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7168 tep->Cleanup_defined = tmp1 & 0x1;
7169
7170 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7171 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7172 tep->Large_frame = (tmp2 >> 29) & 0x1;
7173 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7174 tep->reserved4 = (tmp2 >> 27) & 0x1;
7175 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7176 }
7177 free (table);
7178
7179 /* Third, apply any relocations to the unwind table. */
57346661
AM
7180 for (relsec = section_headers;
7181 relsec < section_headers + elf_header.e_shnum;
7182 ++relsec)
7183 {
7184 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
7185 || relsec->sh_info >= elf_header.e_shnum
7186 || section_headers + relsec->sh_info != sec)
57346661
AM
7187 continue;
7188
7189 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7190 & rela, & nrelas))
7191 return 0;
7192
7193 for (rp = rela; rp < rela + nrelas; ++rp)
7194 {
aca88567
NC
7195 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
7196 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
7197
7198 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 7199 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
7200 {
7201 warn (_("Skipping unexpected relocation type %s\n"), relname);
7202 continue;
7203 }
7204
7205 i = rp->r_offset / unw_ent_size;
7206
89fac5e3 7207 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
7208 {
7209 case 0:
7210 aux->table[i].start.section = sym->st_shndx;
1e456d54 7211 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
7212 break;
7213 case 1:
7214 aux->table[i].end.section = sym->st_shndx;
1e456d54 7215 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
7216 break;
7217 default:
7218 break;
7219 }
7220 }
7221
7222 free (rela);
7223 }
7224
1c0751b2 7225 aux->table_len = nentries;
57346661
AM
7226
7227 return 1;
7228}
7229
1b31d05e 7230static void
2cf0635d 7231hppa_process_unwind (FILE * file)
57346661 7232{
57346661 7233 struct hppa_unw_aux_info aux;
2cf0635d
NC
7234 Elf_Internal_Shdr * unwsec = NULL;
7235 Elf_Internal_Shdr * strsec;
7236 Elf_Internal_Shdr * sec;
18bd398b 7237 unsigned long i;
57346661 7238
c256ffe7 7239 if (string_table == NULL)
1b31d05e
NC
7240 return;
7241
7242 memset (& aux, 0, sizeof (aux));
57346661
AM
7243
7244 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7245 {
c256ffe7 7246 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7247 && sec->sh_link < elf_header.e_shnum)
57346661 7248 {
ba5cdace 7249 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 7250
4fbb74a6 7251 strsec = section_headers + sec->sh_link;
4082ef84
NC
7252 if (aux.strtab != NULL)
7253 {
7254 error (_("Multiple auxillary string tables encountered\n"));
7255 free (aux.strtab);
7256 }
3f5e193b
NC
7257 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7258 1, strsec->sh_size,
7259 _("string table"));
c256ffe7 7260 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 7261 }
18bd398b 7262 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
7263 unwsec = sec;
7264 }
7265
7266 if (!unwsec)
7267 printf (_("\nThere are no unwind sections in this file.\n"));
7268
7269 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7270 {
18bd398b 7271 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 7272 {
74e1a04b
NC
7273 printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
7274 printable_section_name (sec),
57346661 7275 (unsigned long) sec->sh_offset,
89fac5e3 7276 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
7277
7278 slurp_hppa_unwind_table (file, &aux, sec);
7279 if (aux.table_len > 0)
7280 dump_hppa_unwind (&aux);
7281
7282 if (aux.table)
7283 free ((char *) aux.table);
7284 aux.table = NULL;
7285 }
7286 }
7287
7288 if (aux.symtab)
7289 free (aux.symtab);
7290 if (aux.strtab)
7291 free ((char *) aux.strtab);
57346661
AM
7292}
7293
0b6ae522
DJ
7294struct arm_section
7295{
a734115a
NC
7296 unsigned char * data; /* The unwind data. */
7297 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
7298 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
7299 unsigned long nrelas; /* The number of relocations. */
7300 unsigned int rel_type; /* REL or RELA ? */
7301 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
7302};
7303
7304struct arm_unw_aux_info
7305{
a734115a
NC
7306 FILE * file; /* The file containing the unwind sections. */
7307 Elf_Internal_Sym * symtab; /* The file's symbol table. */
7308 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
7309 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7310 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
7311 char * strtab; /* The file's string table. */
7312 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
7313};
7314
7315static const char *
7316arm_print_vma_and_name (struct arm_unw_aux_info *aux,
7317 bfd_vma fn, struct absaddr addr)
7318{
7319 const char *procname;
7320 bfd_vma sym_offset;
7321
7322 if (addr.section == SHN_UNDEF)
7323 addr.offset = fn;
7324
948f632f 7325 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
7326 aux->strtab_size, addr, &procname,
7327 &sym_offset);
7328
7329 print_vma (fn, PREFIX_HEX);
7330
7331 if (procname)
7332 {
7333 fputs (" <", stdout);
7334 fputs (procname, stdout);
7335
7336 if (sym_offset)
7337 printf ("+0x%lx", (unsigned long) sym_offset);
7338 fputc ('>', stdout);
7339 }
7340
7341 return procname;
7342}
7343
7344static void
7345arm_free_section (struct arm_section *arm_sec)
7346{
7347 if (arm_sec->data != NULL)
7348 free (arm_sec->data);
7349
7350 if (arm_sec->rela != NULL)
7351 free (arm_sec->rela);
7352}
7353
a734115a
NC
7354/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
7355 cached section and install SEC instead.
7356 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
7357 and return its valued in * WORDP, relocating if necessary.
1b31d05e 7358 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 7359 relocation's offset in ADDR.
1b31d05e
NC
7360 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
7361 into the string table of the symbol associated with the reloc. If no
7362 reloc was applied store -1 there.
7363 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
7364
7365static bfd_boolean
1b31d05e
NC
7366get_unwind_section_word (struct arm_unw_aux_info * aux,
7367 struct arm_section * arm_sec,
7368 Elf_Internal_Shdr * sec,
7369 bfd_vma word_offset,
7370 unsigned int * wordp,
7371 struct absaddr * addr,
7372 bfd_vma * sym_name)
0b6ae522
DJ
7373{
7374 Elf_Internal_Rela *rp;
7375 Elf_Internal_Sym *sym;
7376 const char * relname;
7377 unsigned int word;
7378 bfd_boolean wrapped;
7379
e0a31db1
NC
7380 if (sec == NULL || arm_sec == NULL)
7381 return FALSE;
7382
0b6ae522
DJ
7383 addr->section = SHN_UNDEF;
7384 addr->offset = 0;
7385
1b31d05e
NC
7386 if (sym_name != NULL)
7387 *sym_name = (bfd_vma) -1;
7388
a734115a 7389 /* If necessary, update the section cache. */
0b6ae522
DJ
7390 if (sec != arm_sec->sec)
7391 {
7392 Elf_Internal_Shdr *relsec;
7393
7394 arm_free_section (arm_sec);
7395
7396 arm_sec->sec = sec;
7397 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
7398 sec->sh_size, _("unwind data"));
0b6ae522
DJ
7399 arm_sec->rela = NULL;
7400 arm_sec->nrelas = 0;
7401
7402 for (relsec = section_headers;
7403 relsec < section_headers + elf_header.e_shnum;
7404 ++relsec)
7405 {
7406 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
7407 || section_headers + relsec->sh_info != sec
7408 /* PR 15745: Check the section type as well. */
7409 || (relsec->sh_type != SHT_REL
7410 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
7411 continue;
7412
a734115a 7413 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
7414 if (relsec->sh_type == SHT_REL)
7415 {
7416 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
7417 relsec->sh_size,
7418 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7419 return FALSE;
0b6ae522 7420 }
1ae40aa4 7421 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
7422 {
7423 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
7424 relsec->sh_size,
7425 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7426 return FALSE;
0b6ae522 7427 }
1ae40aa4 7428 break;
0b6ae522
DJ
7429 }
7430
7431 arm_sec->next_rela = arm_sec->rela;
7432 }
7433
a734115a 7434 /* If there is no unwind data we can do nothing. */
0b6ae522 7435 if (arm_sec->data == NULL)
a734115a 7436 return FALSE;
0b6ae522 7437
e0a31db1
NC
7438 /* If the offset is invalid then fail. */
7439 if (word_offset > sec->sh_size - 4)
7440 return FALSE;
7441
a734115a 7442 /* Get the word at the required offset. */
0b6ae522
DJ
7443 word = byte_get (arm_sec->data + word_offset, 4);
7444
0eff7165
NC
7445 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
7446 if (arm_sec->rela == NULL)
7447 {
7448 * wordp = word;
7449 return TRUE;
7450 }
7451
a734115a 7452 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
7453 wrapped = FALSE;
7454 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
7455 {
7456 bfd_vma prelval, offset;
7457
7458 if (rp->r_offset > word_offset && !wrapped)
7459 {
7460 rp = arm_sec->rela;
7461 wrapped = TRUE;
7462 }
7463 if (rp->r_offset > word_offset)
7464 break;
7465
7466 if (rp->r_offset & 3)
7467 {
7468 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
7469 (unsigned long) rp->r_offset);
7470 continue;
7471 }
7472
7473 if (rp->r_offset < word_offset)
7474 continue;
7475
74e1a04b
NC
7476 /* PR 17531: file: 027-161405-0.004 */
7477 if (aux->symtab == NULL)
7478 continue;
7479
0b6ae522
DJ
7480 if (arm_sec->rel_type == SHT_REL)
7481 {
7482 offset = word & 0x7fffffff;
7483 if (offset & 0x40000000)
7484 offset |= ~ (bfd_vma) 0x7fffffff;
7485 }
a734115a 7486 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 7487 offset = rp->r_addend;
a734115a 7488 else
74e1a04b
NC
7489 {
7490 error (_("Unknown section relocation type %d encountered\n"),
7491 arm_sec->rel_type);
7492 break;
7493 }
0b6ae522 7494
071436c6
NC
7495 /* PR 17531 file: 027-1241568-0.004. */
7496 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
7497 {
7498 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
7499 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
7500 break;
7501 }
7502
7503 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
7504 offset += sym->st_value;
7505 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
7506
a734115a
NC
7507 /* Check that we are processing the expected reloc type. */
7508 if (elf_header.e_machine == EM_ARM)
7509 {
7510 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7511 if (relname == NULL)
7512 {
7513 warn (_("Skipping unknown ARM relocation type: %d\n"),
7514 (int) ELF32_R_TYPE (rp->r_info));
7515 continue;
7516 }
a734115a
NC
7517
7518 if (streq (relname, "R_ARM_NONE"))
7519 continue;
0b4362b0 7520
a734115a
NC
7521 if (! streq (relname, "R_ARM_PREL31"))
7522 {
071436c6 7523 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
7524 continue;
7525 }
7526 }
7527 else if (elf_header.e_machine == EM_TI_C6000)
7528 {
7529 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7530 if (relname == NULL)
7531 {
7532 warn (_("Skipping unknown C6000 relocation type: %d\n"),
7533 (int) ELF32_R_TYPE (rp->r_info));
7534 continue;
7535 }
0b4362b0 7536
a734115a
NC
7537 if (streq (relname, "R_C6000_NONE"))
7538 continue;
7539
7540 if (! streq (relname, "R_C6000_PREL31"))
7541 {
071436c6 7542 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
7543 continue;
7544 }
7545
7546 prelval >>= 1;
7547 }
7548 else
74e1a04b
NC
7549 {
7550 /* This function currently only supports ARM and TI unwinders. */
7551 warn (_("Only TI and ARM unwinders are currently supported\n"));
7552 break;
7553 }
fa197c1c 7554
0b6ae522
DJ
7555 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
7556 addr->section = sym->st_shndx;
7557 addr->offset = offset;
74e1a04b 7558
1b31d05e
NC
7559 if (sym_name)
7560 * sym_name = sym->st_name;
0b6ae522
DJ
7561 break;
7562 }
7563
7564 *wordp = word;
7565 arm_sec->next_rela = rp;
7566
a734115a 7567 return TRUE;
0b6ae522
DJ
7568}
7569
a734115a
NC
7570static const char *tic6x_unwind_regnames[16] =
7571{
0b4362b0
RM
7572 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
7573 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
7574 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
7575};
fa197c1c 7576
0b6ae522 7577static void
fa197c1c 7578decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 7579{
fa197c1c
PB
7580 int i;
7581
7582 for (i = 12; mask; mask >>= 1, i--)
7583 {
7584 if (mask & 1)
7585 {
7586 fputs (tic6x_unwind_regnames[i], stdout);
7587 if (mask > 1)
7588 fputs (", ", stdout);
7589 }
7590 }
7591}
0b6ae522
DJ
7592
7593#define ADVANCE \
7594 if (remaining == 0 && more_words) \
7595 { \
7596 data_offset += 4; \
1b31d05e
NC
7597 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
7598 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
7599 return; \
7600 remaining = 4; \
7601 more_words--; \
7602 } \
7603
7604#define GET_OP(OP) \
7605 ADVANCE; \
7606 if (remaining) \
7607 { \
7608 remaining--; \
7609 (OP) = word >> 24; \
7610 word <<= 8; \
7611 } \
7612 else \
7613 { \
2b692964 7614 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
7615 return; \
7616 } \
cc5914eb 7617 printf ("0x%02x ", OP)
0b6ae522 7618
fa197c1c 7619static void
948f632f
DA
7620decode_arm_unwind_bytecode (struct arm_unw_aux_info * aux,
7621 unsigned int word,
7622 unsigned int remaining,
7623 unsigned int more_words,
7624 bfd_vma data_offset,
7625 Elf_Internal_Shdr * data_sec,
7626 struct arm_section * data_arm_sec)
fa197c1c
PB
7627{
7628 struct absaddr addr;
0b6ae522
DJ
7629
7630 /* Decode the unwinding instructions. */
7631 while (1)
7632 {
7633 unsigned int op, op2;
7634
7635 ADVANCE;
7636 if (remaining == 0)
7637 break;
7638 remaining--;
7639 op = word >> 24;
7640 word <<= 8;
7641
cc5914eb 7642 printf (" 0x%02x ", op);
0b6ae522
DJ
7643
7644 if ((op & 0xc0) == 0x00)
7645 {
7646 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7647
cc5914eb 7648 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
7649 }
7650 else if ((op & 0xc0) == 0x40)
7651 {
7652 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7653
cc5914eb 7654 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
7655 }
7656 else if ((op & 0xf0) == 0x80)
7657 {
7658 GET_OP (op2);
7659 if (op == 0x80 && op2 == 0)
7660 printf (_("Refuse to unwind"));
7661 else
7662 {
7663 unsigned int mask = ((op & 0x0f) << 8) | op2;
7664 int first = 1;
7665 int i;
2b692964 7666
0b6ae522
DJ
7667 printf ("pop {");
7668 for (i = 0; i < 12; i++)
7669 if (mask & (1 << i))
7670 {
7671 if (first)
7672 first = 0;
7673 else
7674 printf (", ");
7675 printf ("r%d", 4 + i);
7676 }
7677 printf ("}");
7678 }
7679 }
7680 else if ((op & 0xf0) == 0x90)
7681 {
7682 if (op == 0x9d || op == 0x9f)
7683 printf (_(" [Reserved]"));
7684 else
cc5914eb 7685 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
7686 }
7687 else if ((op & 0xf0) == 0xa0)
7688 {
7689 int end = 4 + (op & 0x07);
7690 int first = 1;
7691 int i;
61865e30 7692
0b6ae522
DJ
7693 printf (" pop {");
7694 for (i = 4; i <= end; i++)
7695 {
7696 if (first)
7697 first = 0;
7698 else
7699 printf (", ");
7700 printf ("r%d", i);
7701 }
7702 if (op & 0x08)
7703 {
1b31d05e 7704 if (!first)
0b6ae522
DJ
7705 printf (", ");
7706 printf ("r14");
7707 }
7708 printf ("}");
7709 }
7710 else if (op == 0xb0)
7711 printf (_(" finish"));
7712 else if (op == 0xb1)
7713 {
7714 GET_OP (op2);
7715 if (op2 == 0 || (op2 & 0xf0) != 0)
7716 printf (_("[Spare]"));
7717 else
7718 {
7719 unsigned int mask = op2 & 0x0f;
7720 int first = 1;
7721 int i;
61865e30 7722
0b6ae522
DJ
7723 printf ("pop {");
7724 for (i = 0; i < 12; i++)
7725 if (mask & (1 << i))
7726 {
7727 if (first)
7728 first = 0;
7729 else
7730 printf (", ");
7731 printf ("r%d", i);
7732 }
7733 printf ("}");
7734 }
7735 }
7736 else if (op == 0xb2)
7737 {
b115cf96 7738 unsigned char buf[9];
0b6ae522
DJ
7739 unsigned int i, len;
7740 unsigned long offset;
61865e30 7741
b115cf96 7742 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
7743 {
7744 GET_OP (buf[i]);
7745 if ((buf[i] & 0x80) == 0)
7746 break;
7747 }
4082ef84
NC
7748 if (i == sizeof (buf))
7749 printf (_("corrupt change to vsp"));
7750 else
7751 {
7752 offset = read_uleb128 (buf, &len, buf + i + 1);
7753 assert (len == i + 1);
7754 offset = offset * 4 + 0x204;
7755 printf ("vsp = vsp + %ld", offset);
7756 }
0b6ae522 7757 }
61865e30 7758 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 7759 {
61865e30
NC
7760 unsigned int first, last;
7761
7762 GET_OP (op2);
7763 first = op2 >> 4;
7764 last = op2 & 0x0f;
7765 if (op == 0xc8)
7766 first = first + 16;
7767 printf ("pop {D%d", first);
7768 if (last)
7769 printf ("-D%d", first + last);
7770 printf ("}");
7771 }
7772 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
7773 {
7774 unsigned int count = op & 0x07;
7775
7776 printf ("pop {D8");
7777 if (count)
7778 printf ("-D%d", 8 + count);
7779 printf ("}");
7780 }
7781 else if (op >= 0xc0 && op <= 0xc5)
7782 {
7783 unsigned int count = op & 0x07;
7784
7785 printf (" pop {wR10");
7786 if (count)
7787 printf ("-wR%d", 10 + count);
7788 printf ("}");
7789 }
7790 else if (op == 0xc6)
7791 {
7792 unsigned int first, last;
7793
7794 GET_OP (op2);
7795 first = op2 >> 4;
7796 last = op2 & 0x0f;
7797 printf ("pop {wR%d", first);
7798 if (last)
7799 printf ("-wR%d", first + last);
7800 printf ("}");
7801 }
7802 else if (op == 0xc7)
7803 {
7804 GET_OP (op2);
7805 if (op2 == 0 || (op2 & 0xf0) != 0)
7806 printf (_("[Spare]"));
0b6ae522
DJ
7807 else
7808 {
61865e30
NC
7809 unsigned int mask = op2 & 0x0f;
7810 int first = 1;
7811 int i;
7812
7813 printf ("pop {");
7814 for (i = 0; i < 4; i++)
7815 if (mask & (1 << i))
7816 {
7817 if (first)
7818 first = 0;
7819 else
7820 printf (", ");
7821 printf ("wCGR%d", i);
7822 }
7823 printf ("}");
0b6ae522
DJ
7824 }
7825 }
61865e30
NC
7826 else
7827 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7828 printf ("\n");
7829 }
fa197c1c
PB
7830}
7831
7832static void
948f632f
DA
7833decode_tic6x_unwind_bytecode (struct arm_unw_aux_info * aux,
7834 unsigned int word,
7835 unsigned int remaining,
7836 unsigned int more_words,
7837 bfd_vma data_offset,
7838 Elf_Internal_Shdr * data_sec,
7839 struct arm_section * data_arm_sec)
fa197c1c
PB
7840{
7841 struct absaddr addr;
7842
7843 /* Decode the unwinding instructions. */
7844 while (1)
7845 {
7846 unsigned int op, op2;
7847
7848 ADVANCE;
7849 if (remaining == 0)
7850 break;
7851 remaining--;
7852 op = word >> 24;
7853 word <<= 8;
7854
9cf03b7e 7855 printf (" 0x%02x ", op);
fa197c1c
PB
7856
7857 if ((op & 0xc0) == 0x00)
7858 {
7859 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7860 printf (" sp = sp + %d", offset);
fa197c1c
PB
7861 }
7862 else if ((op & 0xc0) == 0x80)
7863 {
7864 GET_OP (op2);
7865 if (op == 0x80 && op2 == 0)
7866 printf (_("Refuse to unwind"));
7867 else
7868 {
7869 unsigned int mask = ((op & 0x1f) << 8) | op2;
7870 if (op & 0x20)
7871 printf ("pop compact {");
7872 else
7873 printf ("pop {");
7874
7875 decode_tic6x_unwind_regmask (mask);
7876 printf("}");
7877 }
7878 }
7879 else if ((op & 0xf0) == 0xc0)
7880 {
7881 unsigned int reg;
7882 unsigned int nregs;
7883 unsigned int i;
7884 const char *name;
a734115a
NC
7885 struct
7886 {
fa197c1c
PB
7887 unsigned int offset;
7888 unsigned int reg;
7889 } regpos[16];
7890
7891 /* Scan entire instruction first so that GET_OP output is not
7892 interleaved with disassembly. */
7893 nregs = 0;
7894 for (i = 0; nregs < (op & 0xf); i++)
7895 {
7896 GET_OP (op2);
7897 reg = op2 >> 4;
7898 if (reg != 0xf)
7899 {
7900 regpos[nregs].offset = i * 2;
7901 regpos[nregs].reg = reg;
7902 nregs++;
7903 }
7904
7905 reg = op2 & 0xf;
7906 if (reg != 0xf)
7907 {
7908 regpos[nregs].offset = i * 2 + 1;
7909 regpos[nregs].reg = reg;
7910 nregs++;
7911 }
7912 }
7913
7914 printf (_("pop frame {"));
7915 reg = nregs - 1;
7916 for (i = i * 2; i > 0; i--)
7917 {
7918 if (regpos[reg].offset == i - 1)
7919 {
7920 name = tic6x_unwind_regnames[regpos[reg].reg];
7921 if (reg > 0)
7922 reg--;
7923 }
7924 else
7925 name = _("[pad]");
7926
7927 fputs (name, stdout);
7928 if (i > 1)
7929 printf (", ");
7930 }
7931
7932 printf ("}");
7933 }
7934 else if (op == 0xd0)
7935 printf (" MOV FP, SP");
7936 else if (op == 0xd1)
7937 printf (" __c6xabi_pop_rts");
7938 else if (op == 0xd2)
7939 {
7940 unsigned char buf[9];
7941 unsigned int i, len;
7942 unsigned long offset;
a734115a 7943
fa197c1c
PB
7944 for (i = 0; i < sizeof (buf); i++)
7945 {
7946 GET_OP (buf[i]);
7947 if ((buf[i] & 0x80) == 0)
7948 break;
7949 }
0eff7165
NC
7950 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
7951 if (i == sizeof (buf))
7952 {
7953 printf ("<corrupt sp adjust>\n");
7954 warn (_("Corrupt stack pointer adjustment detected\n"));
7955 return;
7956 }
948f632f 7957
f6f0e17b 7958 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7959 assert (len == i + 1);
7960 offset = offset * 8 + 0x408;
7961 printf (_("sp = sp + %ld"), offset);
7962 }
7963 else if ((op & 0xf0) == 0xe0)
7964 {
7965 if ((op & 0x0f) == 7)
7966 printf (" RETURN");
7967 else
7968 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7969 }
7970 else
7971 {
7972 printf (_(" [unsupported opcode]"));
7973 }
7974 putchar ('\n');
7975 }
7976}
7977
7978static bfd_vma
a734115a 7979arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7980{
7981 bfd_vma offset;
7982
7983 offset = word & 0x7fffffff;
7984 if (offset & 0x40000000)
7985 offset |= ~ (bfd_vma) 0x7fffffff;
7986
7987 if (elf_header.e_machine == EM_TI_C6000)
7988 offset <<= 1;
7989
7990 return offset + where;
7991}
7992
7993static void
1b31d05e
NC
7994decode_arm_unwind (struct arm_unw_aux_info * aux,
7995 unsigned int word,
7996 unsigned int remaining,
7997 bfd_vma data_offset,
7998 Elf_Internal_Shdr * data_sec,
7999 struct arm_section * data_arm_sec)
fa197c1c
PB
8000{
8001 int per_index;
8002 unsigned int more_words = 0;
37e14bc3 8003 struct absaddr addr;
1b31d05e 8004 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
8005
8006 if (remaining == 0)
8007 {
1b31d05e
NC
8008 /* Fetch the first word.
8009 Note - when decoding an object file the address extracted
8010 here will always be 0. So we also pass in the sym_name
8011 parameter so that we can find the symbol associated with
8012 the personality routine. */
8013 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
8014 & word, & addr, & sym_name))
fa197c1c 8015 return;
1b31d05e 8016
fa197c1c
PB
8017 remaining = 4;
8018 }
8019
8020 if ((word & 0x80000000) == 0)
8021 {
8022 /* Expand prel31 for personality routine. */
8023 bfd_vma fn;
8024 const char *procname;
8025
a734115a 8026 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 8027 printf (_(" Personality routine: "));
1b31d05e
NC
8028 if (fn == 0
8029 && addr.section == SHN_UNDEF && addr.offset == 0
8030 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
8031 {
8032 procname = aux->strtab + sym_name;
8033 print_vma (fn, PREFIX_HEX);
8034 if (procname)
8035 {
8036 fputs (" <", stdout);
8037 fputs (procname, stdout);
8038 fputc ('>', stdout);
8039 }
8040 }
8041 else
8042 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
8043 fputc ('\n', stdout);
8044
8045 /* The GCC personality routines use the standard compact
8046 encoding, starting with one byte giving the number of
8047 words. */
8048 if (procname != NULL
8049 && (const_strneq (procname, "__gcc_personality_v0")
8050 || const_strneq (procname, "__gxx_personality_v0")
8051 || const_strneq (procname, "__gcj_personality_v0")
8052 || const_strneq (procname, "__gnu_objc_personality_v0")))
8053 {
8054 remaining = 0;
8055 more_words = 1;
8056 ADVANCE;
8057 if (!remaining)
8058 {
8059 printf (_(" [Truncated data]\n"));
8060 return;
8061 }
8062 more_words = word >> 24;
8063 word <<= 8;
8064 remaining--;
8065 per_index = -1;
8066 }
8067 else
8068 return;
8069 }
8070 else
8071 {
1b31d05e 8072 /* ARM EHABI Section 6.3:
0b4362b0 8073
1b31d05e 8074 An exception-handling table entry for the compact model looks like:
0b4362b0 8075
1b31d05e
NC
8076 31 30-28 27-24 23-0
8077 -- ----- ----- ----
8078 1 0 index Data for personalityRoutine[index] */
8079
8080 if (elf_header.e_machine == EM_ARM
8081 && (word & 0x70000000))
83c257ca 8082 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 8083
fa197c1c 8084 per_index = (word >> 24) & 0x7f;
1b31d05e 8085 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
8086 if (per_index == 0)
8087 {
8088 more_words = 0;
8089 word <<= 8;
8090 remaining--;
8091 }
8092 else if (per_index < 3)
8093 {
8094 more_words = (word >> 16) & 0xff;
8095 word <<= 16;
8096 remaining -= 2;
8097 }
8098 }
8099
8100 switch (elf_header.e_machine)
8101 {
8102 case EM_ARM:
8103 if (per_index < 3)
8104 {
8105 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
8106 data_offset, data_sec, data_arm_sec);
8107 }
8108 else
1b31d05e
NC
8109 {
8110 warn (_("Unknown ARM compact model index encountered\n"));
8111 printf (_(" [reserved]\n"));
8112 }
fa197c1c
PB
8113 break;
8114
8115 case EM_TI_C6000:
8116 if (per_index < 3)
8117 {
8118 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 8119 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
8120 }
8121 else if (per_index < 5)
8122 {
8123 if (((word >> 17) & 0x7f) == 0x7f)
8124 printf (_(" Restore stack from frame pointer\n"));
8125 else
8126 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
8127 printf (_(" Registers restored: "));
8128 if (per_index == 4)
8129 printf (" (compact) ");
8130 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
8131 putchar ('\n');
8132 printf (_(" Return register: %s\n"),
8133 tic6x_unwind_regnames[word & 0xf]);
8134 }
8135 else
1b31d05e 8136 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
8137 break;
8138
8139 default:
74e1a04b 8140 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
1b31d05e 8141 elf_header.e_machine);
fa197c1c 8142 }
0b6ae522
DJ
8143
8144 /* Decode the descriptors. Not implemented. */
8145}
8146
8147static void
8148dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
8149{
8150 struct arm_section exidx_arm_sec, extab_arm_sec;
8151 unsigned int i, exidx_len;
948f632f 8152 unsigned long j, nfuns;
0b6ae522
DJ
8153
8154 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
8155 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
8156 exidx_len = exidx_sec->sh_size / 8;
8157
948f632f
DA
8158 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8159 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8160 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8161 aux->funtab[nfuns++] = aux->symtab[j];
8162 aux->nfuns = nfuns;
8163 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8164
0b6ae522
DJ
8165 for (i = 0; i < exidx_len; i++)
8166 {
8167 unsigned int exidx_fn, exidx_entry;
8168 struct absaddr fn_addr, entry_addr;
8169 bfd_vma fn;
8170
8171 fputc ('\n', stdout);
8172
1b31d05e
NC
8173 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8174 8 * i, & exidx_fn, & fn_addr, NULL)
8175 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8176 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 8177 {
948f632f 8178 free (aux->funtab);
1b31d05e
NC
8179 arm_free_section (& exidx_arm_sec);
8180 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
8181 return;
8182 }
8183
83c257ca
NC
8184 /* ARM EHABI, Section 5:
8185 An index table entry consists of 2 words.
8186 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
8187 if (exidx_fn & 0x80000000)
8188 warn (_("corrupt index table entry: %x\n"), exidx_fn);
8189
a734115a 8190 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 8191
a734115a 8192 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
8193 fputs (": ", stdout);
8194
8195 if (exidx_entry == 1)
8196 {
8197 print_vma (exidx_entry, PREFIX_HEX);
8198 fputs (" [cantunwind]\n", stdout);
8199 }
8200 else if (exidx_entry & 0x80000000)
8201 {
8202 print_vma (exidx_entry, PREFIX_HEX);
8203 fputc ('\n', stdout);
8204 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
8205 }
8206 else
8207 {
8f73510c 8208 bfd_vma table, table_offset = 0;
0b6ae522
DJ
8209 Elf_Internal_Shdr *table_sec;
8210
8211 fputs ("@", stdout);
a734115a 8212 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
8213 print_vma (table, PREFIX_HEX);
8214 printf ("\n");
8215
8216 /* Locate the matching .ARM.extab. */
8217 if (entry_addr.section != SHN_UNDEF
8218 && entry_addr.section < elf_header.e_shnum)
8219 {
8220 table_sec = section_headers + entry_addr.section;
8221 table_offset = entry_addr.offset;
8222 }
8223 else
8224 {
8225 table_sec = find_section_by_address (table);
8226 if (table_sec != NULL)
8227 table_offset = table - table_sec->sh_addr;
8228 }
8229 if (table_sec == NULL)
8230 {
8231 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
8232 (unsigned long) table);
8233 continue;
8234 }
8235 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
8236 &extab_arm_sec);
8237 }
8238 }
8239
8240 printf ("\n");
8241
948f632f 8242 free (aux->funtab);
0b6ae522
DJ
8243 arm_free_section (&exidx_arm_sec);
8244 arm_free_section (&extab_arm_sec);
8245}
8246
fa197c1c 8247/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
8248
8249static void
0b6ae522
DJ
8250arm_process_unwind (FILE *file)
8251{
8252 struct arm_unw_aux_info aux;
8253 Elf_Internal_Shdr *unwsec = NULL;
8254 Elf_Internal_Shdr *strsec;
8255 Elf_Internal_Shdr *sec;
8256 unsigned long i;
fa197c1c 8257 unsigned int sec_type;
0b6ae522 8258
fa197c1c
PB
8259 switch (elf_header.e_machine)
8260 {
8261 case EM_ARM:
8262 sec_type = SHT_ARM_EXIDX;
8263 break;
8264
8265 case EM_TI_C6000:
8266 sec_type = SHT_C6000_UNWIND;
8267 break;
8268
0b4362b0 8269 default:
74e1a04b 8270 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
1b31d05e
NC
8271 elf_header.e_machine);
8272 return;
fa197c1c
PB
8273 }
8274
0b6ae522 8275 if (string_table == NULL)
1b31d05e
NC
8276 return;
8277
8278 memset (& aux, 0, sizeof (aux));
8279 aux.file = file;
0b6ae522
DJ
8280
8281 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8282 {
8283 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
8284 {
ba5cdace 8285 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
8286
8287 strsec = section_headers + sec->sh_link;
74e1a04b
NC
8288
8289 /* PR binutils/17531 file: 011-12666-0.004. */
8290 if (aux.strtab != NULL)
8291 {
4082ef84 8292 error (_("Multiple string tables found in file.\n"));
74e1a04b
NC
8293 free (aux.strtab);
8294 }
0b6ae522
DJ
8295 aux.strtab = get_data (NULL, file, strsec->sh_offset,
8296 1, strsec->sh_size, _("string table"));
8297 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
8298 }
fa197c1c 8299 else if (sec->sh_type == sec_type)
0b6ae522
DJ
8300 unwsec = sec;
8301 }
8302
1b31d05e 8303 if (unwsec == NULL)
0b6ae522 8304 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
8305 else
8306 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8307 {
8308 if (sec->sh_type == sec_type)
8309 {
8310 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
74e1a04b 8311 printable_section_name (sec),
1b31d05e
NC
8312 (unsigned long) sec->sh_offset,
8313 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 8314
1b31d05e
NC
8315 dump_arm_unwind (&aux, sec);
8316 }
8317 }
0b6ae522
DJ
8318
8319 if (aux.symtab)
8320 free (aux.symtab);
8321 if (aux.strtab)
8322 free ((char *) aux.strtab);
0b6ae522
DJ
8323}
8324
1b31d05e 8325static void
2cf0635d 8326process_unwind (FILE * file)
57346661 8327{
2cf0635d
NC
8328 struct unwind_handler
8329 {
57346661 8330 int machtype;
1b31d05e 8331 void (* handler)(FILE *);
2cf0635d
NC
8332 } handlers[] =
8333 {
0b6ae522 8334 { EM_ARM, arm_process_unwind },
57346661
AM
8335 { EM_IA_64, ia64_process_unwind },
8336 { EM_PARISC, hppa_process_unwind },
fa197c1c 8337 { EM_TI_C6000, arm_process_unwind },
57346661
AM
8338 { 0, 0 }
8339 };
8340 int i;
8341
8342 if (!do_unwind)
1b31d05e 8343 return;
57346661
AM
8344
8345 for (i = 0; handlers[i].handler != NULL; i++)
8346 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
8347 {
8348 handlers[i].handler (file);
8349 return;
8350 }
57346661 8351
1b31d05e
NC
8352 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
8353 get_machine_name (elf_header.e_machine));
57346661
AM
8354}
8355
252b5132 8356static void
2cf0635d 8357dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
8358{
8359 switch (entry->d_tag)
8360 {
8361 case DT_MIPS_FLAGS:
8362 if (entry->d_un.d_val == 0)
4b68bca3 8363 printf (_("NONE"));
252b5132
RH
8364 else
8365 {
8366 static const char * opts[] =
8367 {
8368 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
8369 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
8370 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
8371 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
8372 "RLD_ORDER_SAFE"
8373 };
8374 unsigned int cnt;
8375 int first = 1;
2b692964 8376
60bca95a 8377 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
8378 if (entry->d_un.d_val & (1 << cnt))
8379 {
8380 printf ("%s%s", first ? "" : " ", opts[cnt]);
8381 first = 0;
8382 }
252b5132
RH
8383 }
8384 break;
103f02d3 8385
252b5132 8386 case DT_MIPS_IVERSION:
d79b3d50 8387 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 8388 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8389 else
76ca31c0
NC
8390 {
8391 char buf[40];
8392 sprintf_vma (buf, entry->d_un.d_ptr);
8393 /* Note: coded this way so that there is a single string for translation. */
8394 printf (_("<corrupt: %s>"), buf);
8395 }
252b5132 8396 break;
103f02d3 8397
252b5132
RH
8398 case DT_MIPS_TIME_STAMP:
8399 {
8400 char timebuf[20];
2cf0635d 8401 struct tm * tmp;
91d6fa6a 8402 time_t atime = entry->d_un.d_val;
82b1b41b 8403
91d6fa6a 8404 tmp = gmtime (&atime);
82b1b41b
NC
8405 /* PR 17531: file: 6accc532. */
8406 if (tmp == NULL)
8407 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
8408 else
8409 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
8410 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8411 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 8412 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
8413 }
8414 break;
103f02d3 8415
252b5132
RH
8416 case DT_MIPS_RLD_VERSION:
8417 case DT_MIPS_LOCAL_GOTNO:
8418 case DT_MIPS_CONFLICTNO:
8419 case DT_MIPS_LIBLISTNO:
8420 case DT_MIPS_SYMTABNO:
8421 case DT_MIPS_UNREFEXTNO:
8422 case DT_MIPS_HIPAGENO:
8423 case DT_MIPS_DELTA_CLASS_NO:
8424 case DT_MIPS_DELTA_INSTANCE_NO:
8425 case DT_MIPS_DELTA_RELOC_NO:
8426 case DT_MIPS_DELTA_SYM_NO:
8427 case DT_MIPS_DELTA_CLASSSYM_NO:
8428 case DT_MIPS_COMPACT_SIZE:
4b68bca3 8429 print_vma (entry->d_un.d_ptr, DEC);
252b5132 8430 break;
103f02d3
UD
8431
8432 default:
4b68bca3 8433 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 8434 }
4b68bca3 8435 putchar ('\n');
103f02d3
UD
8436}
8437
103f02d3 8438static void
2cf0635d 8439dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
8440{
8441 switch (entry->d_tag)
8442 {
8443 case DT_HP_DLD_FLAGS:
8444 {
8445 static struct
8446 {
8447 long int bit;
2cf0635d 8448 const char * str;
5e220199
NC
8449 }
8450 flags[] =
8451 {
8452 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
8453 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
8454 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
8455 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
8456 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
8457 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
8458 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
8459 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
8460 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
8461 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
8462 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
8463 { DT_HP_GST, "HP_GST" },
8464 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
8465 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
8466 { DT_HP_NODELETE, "HP_NODELETE" },
8467 { DT_HP_GROUP, "HP_GROUP" },
8468 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 8469 };
103f02d3 8470 int first = 1;
5e220199 8471 size_t cnt;
f7a99963 8472 bfd_vma val = entry->d_un.d_val;
103f02d3 8473
60bca95a 8474 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 8475 if (val & flags[cnt].bit)
30800947
NC
8476 {
8477 if (! first)
8478 putchar (' ');
8479 fputs (flags[cnt].str, stdout);
8480 first = 0;
8481 val ^= flags[cnt].bit;
8482 }
76da6bbe 8483
103f02d3 8484 if (val != 0 || first)
f7a99963
NC
8485 {
8486 if (! first)
8487 putchar (' ');
8488 print_vma (val, HEX);
8489 }
103f02d3
UD
8490 }
8491 break;
76da6bbe 8492
252b5132 8493 default:
f7a99963
NC
8494 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8495 break;
252b5132 8496 }
35b1837e 8497 putchar ('\n');
252b5132
RH
8498}
8499
28f997cf
TG
8500#ifdef BFD64
8501
8502/* VMS vs Unix time offset and factor. */
8503
8504#define VMS_EPOCH_OFFSET 35067168000000000LL
8505#define VMS_GRANULARITY_FACTOR 10000000
8506
8507/* Display a VMS time in a human readable format. */
8508
8509static void
8510print_vms_time (bfd_int64_t vmstime)
8511{
8512 struct tm *tm;
8513 time_t unxtime;
8514
8515 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
8516 tm = gmtime (&unxtime);
8517 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
8518 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
8519 tm->tm_hour, tm->tm_min, tm->tm_sec);
8520}
8521#endif /* BFD64 */
8522
ecc51f48 8523static void
2cf0635d 8524dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
8525{
8526 switch (entry->d_tag)
8527 {
0de14b54 8528 case DT_IA_64_PLT_RESERVE:
bdf4d63a 8529 /* First 3 slots reserved. */
ecc51f48
NC
8530 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8531 printf (" -- ");
8532 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
8533 break;
8534
28f997cf
TG
8535 case DT_IA_64_VMS_LINKTIME:
8536#ifdef BFD64
8537 print_vms_time (entry->d_un.d_val);
8538#endif
8539 break;
8540
8541 case DT_IA_64_VMS_LNKFLAGS:
8542 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8543 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
8544 printf (" CALL_DEBUG");
8545 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
8546 printf (" NOP0BUFS");
8547 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
8548 printf (" P0IMAGE");
8549 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
8550 printf (" MKTHREADS");
8551 if (entry->d_un.d_val & VMS_LF_UPCALLS)
8552 printf (" UPCALLS");
8553 if (entry->d_un.d_val & VMS_LF_IMGSTA)
8554 printf (" IMGSTA");
8555 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
8556 printf (" INITIALIZE");
8557 if (entry->d_un.d_val & VMS_LF_MAIN)
8558 printf (" MAIN");
8559 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
8560 printf (" EXE_INIT");
8561 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
8562 printf (" TBK_IN_IMG");
8563 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
8564 printf (" DBG_IN_IMG");
8565 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
8566 printf (" TBK_IN_DSF");
8567 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
8568 printf (" DBG_IN_DSF");
8569 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
8570 printf (" SIGNATURES");
8571 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
8572 printf (" REL_SEG_OFF");
8573 break;
8574
bdf4d63a
JJ
8575 default:
8576 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8577 break;
ecc51f48 8578 }
bdf4d63a 8579 putchar ('\n');
ecc51f48
NC
8580}
8581
252b5132 8582static int
2cf0635d 8583get_32bit_dynamic_section (FILE * file)
252b5132 8584{
2cf0635d
NC
8585 Elf32_External_Dyn * edyn;
8586 Elf32_External_Dyn * ext;
8587 Elf_Internal_Dyn * entry;
103f02d3 8588
3f5e193b
NC
8589 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8590 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8591 if (!edyn)
8592 return 0;
103f02d3 8593
071436c6
NC
8594 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8595 might not have the luxury of section headers. Look for the DT_NULL
8596 terminator to determine the number of entries. */
ba2685cc 8597 for (ext = edyn, dynamic_nent = 0;
071436c6 8598 (char *) ext < (char *) edyn + dynamic_size - sizeof (* entry);
ba2685cc
AM
8599 ext++)
8600 {
8601 dynamic_nent++;
8602 if (BYTE_GET (ext->d_tag) == DT_NULL)
8603 break;
8604 }
252b5132 8605
3f5e193b
NC
8606 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8607 sizeof (* entry));
b2d38a17 8608 if (dynamic_section == NULL)
252b5132 8609 {
8b73c356
NC
8610 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8611 (unsigned long) dynamic_nent);
9ea033b2
NC
8612 free (edyn);
8613 return 0;
8614 }
252b5132 8615
fb514b26 8616 for (ext = edyn, entry = dynamic_section;
ba2685cc 8617 entry < dynamic_section + dynamic_nent;
fb514b26 8618 ext++, entry++)
9ea033b2 8619 {
fb514b26
AM
8620 entry->d_tag = BYTE_GET (ext->d_tag);
8621 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8622 }
8623
9ea033b2
NC
8624 free (edyn);
8625
8626 return 1;
8627}
8628
8629static int
2cf0635d 8630get_64bit_dynamic_section (FILE * file)
9ea033b2 8631{
2cf0635d
NC
8632 Elf64_External_Dyn * edyn;
8633 Elf64_External_Dyn * ext;
8634 Elf_Internal_Dyn * entry;
103f02d3 8635
071436c6 8636 /* Read in the data. */
3f5e193b
NC
8637 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8638 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8639 if (!edyn)
8640 return 0;
103f02d3 8641
071436c6
NC
8642 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8643 might not have the luxury of section headers. Look for the DT_NULL
8644 terminator to determine the number of entries. */
ba2685cc 8645 for (ext = edyn, dynamic_nent = 0;
071436c6
NC
8646 /* PR 17533 file: 033-67080-0.004 - do not read off the end of the buffer. */
8647 (char *) ext < ((char *) edyn) + dynamic_size - sizeof (* ext);
ba2685cc
AM
8648 ext++)
8649 {
8650 dynamic_nent++;
66543521 8651 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
8652 break;
8653 }
252b5132 8654
3f5e193b
NC
8655 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8656 sizeof (* entry));
b2d38a17 8657 if (dynamic_section == NULL)
252b5132 8658 {
8b73c356
NC
8659 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8660 (unsigned long) dynamic_nent);
252b5132
RH
8661 free (edyn);
8662 return 0;
8663 }
8664
071436c6 8665 /* Convert from external to internal formats. */
fb514b26 8666 for (ext = edyn, entry = dynamic_section;
ba2685cc 8667 entry < dynamic_section + dynamic_nent;
fb514b26 8668 ext++, entry++)
252b5132 8669 {
66543521
AM
8670 entry->d_tag = BYTE_GET (ext->d_tag);
8671 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8672 }
8673
8674 free (edyn);
8675
9ea033b2
NC
8676 return 1;
8677}
8678
e9e44622
JJ
8679static void
8680print_dynamic_flags (bfd_vma flags)
d1133906 8681{
e9e44622 8682 int first = 1;
13ae64f3 8683
d1133906
NC
8684 while (flags)
8685 {
8686 bfd_vma flag;
8687
8688 flag = flags & - flags;
8689 flags &= ~ flag;
8690
e9e44622
JJ
8691 if (first)
8692 first = 0;
8693 else
8694 putc (' ', stdout);
13ae64f3 8695
d1133906
NC
8696 switch (flag)
8697 {
e9e44622
JJ
8698 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
8699 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
8700 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
8701 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
8702 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 8703 default: fputs (_("unknown"), stdout); break;
d1133906
NC
8704 }
8705 }
e9e44622 8706 puts ("");
d1133906
NC
8707}
8708
b2d38a17
NC
8709/* Parse and display the contents of the dynamic section. */
8710
9ea033b2 8711static int
2cf0635d 8712process_dynamic_section (FILE * file)
9ea033b2 8713{
2cf0635d 8714 Elf_Internal_Dyn * entry;
9ea033b2
NC
8715
8716 if (dynamic_size == 0)
8717 {
8718 if (do_dynamic)
b2d38a17 8719 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
8720
8721 return 1;
8722 }
8723
8724 if (is_32bit_elf)
8725 {
b2d38a17 8726 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
8727 return 0;
8728 }
b2d38a17 8729 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
8730 return 0;
8731
252b5132
RH
8732 /* Find the appropriate symbol table. */
8733 if (dynamic_symbols == NULL)
8734 {
86dba8ee
AM
8735 for (entry = dynamic_section;
8736 entry < dynamic_section + dynamic_nent;
8737 ++entry)
252b5132 8738 {
c8286bd1 8739 Elf_Internal_Shdr section;
252b5132
RH
8740
8741 if (entry->d_tag != DT_SYMTAB)
8742 continue;
8743
8744 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
8745
8746 /* Since we do not know how big the symbol table is,
8747 we default to reading in the entire file (!) and
8748 processing that. This is overkill, I know, but it
e3c8793a 8749 should work. */
d93f0186 8750 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 8751
fb52b2f4
NC
8752 if (archive_file_offset != 0)
8753 section.sh_size = archive_file_size - section.sh_offset;
8754 else
8755 {
8756 if (fseek (file, 0, SEEK_END))
591a748a 8757 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
8758
8759 section.sh_size = ftell (file) - section.sh_offset;
8760 }
252b5132 8761
9ea033b2 8762 if (is_32bit_elf)
9ad5cbcf 8763 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 8764 else
9ad5cbcf 8765 section.sh_entsize = sizeof (Elf64_External_Sym);
071436c6 8766 section.sh_name = string_table_length;
252b5132 8767
ba5cdace 8768 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 8769 if (num_dynamic_syms < 1)
252b5132
RH
8770 {
8771 error (_("Unable to determine the number of symbols to load\n"));
8772 continue;
8773 }
252b5132
RH
8774 }
8775 }
8776
8777 /* Similarly find a string table. */
8778 if (dynamic_strings == NULL)
8779 {
86dba8ee
AM
8780 for (entry = dynamic_section;
8781 entry < dynamic_section + dynamic_nent;
8782 ++entry)
252b5132
RH
8783 {
8784 unsigned long offset;
b34976b6 8785 long str_tab_len;
252b5132
RH
8786
8787 if (entry->d_tag != DT_STRTAB)
8788 continue;
8789
8790 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
8791
8792 /* Since we do not know how big the string table is,
8793 we default to reading in the entire file (!) and
8794 processing that. This is overkill, I know, but it
e3c8793a 8795 should work. */
252b5132 8796
d93f0186 8797 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
8798
8799 if (archive_file_offset != 0)
8800 str_tab_len = archive_file_size - offset;
8801 else
8802 {
8803 if (fseek (file, 0, SEEK_END))
8804 error (_("Unable to seek to end of file\n"));
8805 str_tab_len = ftell (file) - offset;
8806 }
252b5132
RH
8807
8808 if (str_tab_len < 1)
8809 {
8810 error
8811 (_("Unable to determine the length of the dynamic string table\n"));
8812 continue;
8813 }
8814
3f5e193b
NC
8815 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
8816 str_tab_len,
8817 _("dynamic string table"));
59245841 8818 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
8819 break;
8820 }
8821 }
8822
8823 /* And find the syminfo section if available. */
8824 if (dynamic_syminfo == NULL)
8825 {
3e8bba36 8826 unsigned long syminsz = 0;
252b5132 8827
86dba8ee
AM
8828 for (entry = dynamic_section;
8829 entry < dynamic_section + dynamic_nent;
8830 ++entry)
252b5132
RH
8831 {
8832 if (entry->d_tag == DT_SYMINENT)
8833 {
8834 /* Note: these braces are necessary to avoid a syntax
8835 error from the SunOS4 C compiler. */
049b0c3a
NC
8836 /* PR binutils/17531: A corrupt file can trigger this test.
8837 So do not use an assert, instead generate an error message. */
8838 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 8839 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 8840 (int) entry->d_un.d_val);
252b5132
RH
8841 }
8842 else if (entry->d_tag == DT_SYMINSZ)
8843 syminsz = entry->d_un.d_val;
8844 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
8845 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
8846 syminsz);
252b5132
RH
8847 }
8848
8849 if (dynamic_syminfo_offset != 0 && syminsz != 0)
8850 {
2cf0635d
NC
8851 Elf_External_Syminfo * extsyminfo;
8852 Elf_External_Syminfo * extsym;
8853 Elf_Internal_Syminfo * syminfo;
252b5132
RH
8854
8855 /* There is a syminfo section. Read the data. */
3f5e193b
NC
8856 extsyminfo = (Elf_External_Syminfo *)
8857 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
8858 _("symbol information"));
a6e9f9df
AM
8859 if (!extsyminfo)
8860 return 0;
252b5132 8861
3f5e193b 8862 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
8863 if (dynamic_syminfo == NULL)
8864 {
8b73c356
NC
8865 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
8866 (unsigned long) syminsz);
252b5132
RH
8867 return 0;
8868 }
8869
8870 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8871 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8872 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8873 ++syminfo, ++extsym)
252b5132 8874 {
86dba8ee
AM
8875 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8876 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8877 }
8878
8879 free (extsyminfo);
8880 }
8881 }
8882
8883 if (do_dynamic && dynamic_addr)
8b73c356
NC
8884 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
8885 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
8886 if (do_dynamic)
8887 printf (_(" Tag Type Name/Value\n"));
8888
86dba8ee
AM
8889 for (entry = dynamic_section;
8890 entry < dynamic_section + dynamic_nent;
8891 entry++)
252b5132
RH
8892 {
8893 if (do_dynamic)
f7a99963 8894 {
2cf0635d 8895 const char * dtype;
e699b9ff 8896
f7a99963
NC
8897 putchar (' ');
8898 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8899 dtype = get_dynamic_type (entry->d_tag);
8900 printf (" (%s)%*s", dtype,
8901 ((is_32bit_elf ? 27 : 19)
8902 - (int) strlen (dtype)),
f7a99963
NC
8903 " ");
8904 }
252b5132
RH
8905
8906 switch (entry->d_tag)
8907 {
d1133906
NC
8908 case DT_FLAGS:
8909 if (do_dynamic)
e9e44622 8910 print_dynamic_flags (entry->d_un.d_val);
d1133906 8911 break;
76da6bbe 8912
252b5132
RH
8913 case DT_AUXILIARY:
8914 case DT_FILTER:
019148e4
L
8915 case DT_CONFIG:
8916 case DT_DEPAUDIT:
8917 case DT_AUDIT:
252b5132
RH
8918 if (do_dynamic)
8919 {
019148e4 8920 switch (entry->d_tag)
b34976b6 8921 {
019148e4
L
8922 case DT_AUXILIARY:
8923 printf (_("Auxiliary library"));
8924 break;
8925
8926 case DT_FILTER:
8927 printf (_("Filter library"));
8928 break;
8929
b34976b6 8930 case DT_CONFIG:
019148e4
L
8931 printf (_("Configuration file"));
8932 break;
8933
8934 case DT_DEPAUDIT:
8935 printf (_("Dependency audit library"));
8936 break;
8937
8938 case DT_AUDIT:
8939 printf (_("Audit library"));
8940 break;
8941 }
252b5132 8942
d79b3d50
NC
8943 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8944 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8945 else
f7a99963
NC
8946 {
8947 printf (": ");
8948 print_vma (entry->d_un.d_val, PREFIX_HEX);
8949 putchar ('\n');
8950 }
252b5132
RH
8951 }
8952 break;
8953
dcefbbbd 8954 case DT_FEATURE:
252b5132
RH
8955 if (do_dynamic)
8956 {
8957 printf (_("Flags:"));
86f55779 8958
252b5132
RH
8959 if (entry->d_un.d_val == 0)
8960 printf (_(" None\n"));
8961 else
8962 {
8963 unsigned long int val = entry->d_un.d_val;
86f55779 8964
252b5132
RH
8965 if (val & DTF_1_PARINIT)
8966 {
8967 printf (" PARINIT");
8968 val ^= DTF_1_PARINIT;
8969 }
dcefbbbd
L
8970 if (val & DTF_1_CONFEXP)
8971 {
8972 printf (" CONFEXP");
8973 val ^= DTF_1_CONFEXP;
8974 }
252b5132
RH
8975 if (val != 0)
8976 printf (" %lx", val);
8977 puts ("");
8978 }
8979 }
8980 break;
8981
8982 case DT_POSFLAG_1:
8983 if (do_dynamic)
8984 {
8985 printf (_("Flags:"));
86f55779 8986
252b5132
RH
8987 if (entry->d_un.d_val == 0)
8988 printf (_(" None\n"));
8989 else
8990 {
8991 unsigned long int val = entry->d_un.d_val;
86f55779 8992
252b5132
RH
8993 if (val & DF_P1_LAZYLOAD)
8994 {
8995 printf (" LAZYLOAD");
8996 val ^= DF_P1_LAZYLOAD;
8997 }
8998 if (val & DF_P1_GROUPPERM)
8999 {
9000 printf (" GROUPPERM");
9001 val ^= DF_P1_GROUPPERM;
9002 }
9003 if (val != 0)
9004 printf (" %lx", val);
9005 puts ("");
9006 }
9007 }
9008 break;
9009
9010 case DT_FLAGS_1:
9011 if (do_dynamic)
9012 {
9013 printf (_("Flags:"));
9014 if (entry->d_un.d_val == 0)
9015 printf (_(" None\n"));
9016 else
9017 {
9018 unsigned long int val = entry->d_un.d_val;
86f55779 9019
252b5132
RH
9020 if (val & DF_1_NOW)
9021 {
9022 printf (" NOW");
9023 val ^= DF_1_NOW;
9024 }
9025 if (val & DF_1_GLOBAL)
9026 {
9027 printf (" GLOBAL");
9028 val ^= DF_1_GLOBAL;
9029 }
9030 if (val & DF_1_GROUP)
9031 {
9032 printf (" GROUP");
9033 val ^= DF_1_GROUP;
9034 }
9035 if (val & DF_1_NODELETE)
9036 {
9037 printf (" NODELETE");
9038 val ^= DF_1_NODELETE;
9039 }
9040 if (val & DF_1_LOADFLTR)
9041 {
9042 printf (" LOADFLTR");
9043 val ^= DF_1_LOADFLTR;
9044 }
9045 if (val & DF_1_INITFIRST)
9046 {
9047 printf (" INITFIRST");
9048 val ^= DF_1_INITFIRST;
9049 }
9050 if (val & DF_1_NOOPEN)
9051 {
9052 printf (" NOOPEN");
9053 val ^= DF_1_NOOPEN;
9054 }
9055 if (val & DF_1_ORIGIN)
9056 {
9057 printf (" ORIGIN");
9058 val ^= DF_1_ORIGIN;
9059 }
9060 if (val & DF_1_DIRECT)
9061 {
9062 printf (" DIRECT");
9063 val ^= DF_1_DIRECT;
9064 }
9065 if (val & DF_1_TRANS)
9066 {
9067 printf (" TRANS");
9068 val ^= DF_1_TRANS;
9069 }
9070 if (val & DF_1_INTERPOSE)
9071 {
9072 printf (" INTERPOSE");
9073 val ^= DF_1_INTERPOSE;
9074 }
f7db6139 9075 if (val & DF_1_NODEFLIB)
dcefbbbd 9076 {
f7db6139
L
9077 printf (" NODEFLIB");
9078 val ^= DF_1_NODEFLIB;
dcefbbbd
L
9079 }
9080 if (val & DF_1_NODUMP)
9081 {
9082 printf (" NODUMP");
9083 val ^= DF_1_NODUMP;
9084 }
34b60028 9085 if (val & DF_1_CONFALT)
dcefbbbd 9086 {
34b60028
L
9087 printf (" CONFALT");
9088 val ^= DF_1_CONFALT;
9089 }
9090 if (val & DF_1_ENDFILTEE)
9091 {
9092 printf (" ENDFILTEE");
9093 val ^= DF_1_ENDFILTEE;
9094 }
9095 if (val & DF_1_DISPRELDNE)
9096 {
9097 printf (" DISPRELDNE");
9098 val ^= DF_1_DISPRELDNE;
9099 }
9100 if (val & DF_1_DISPRELPND)
9101 {
9102 printf (" DISPRELPND");
9103 val ^= DF_1_DISPRELPND;
9104 }
9105 if (val & DF_1_NODIRECT)
9106 {
9107 printf (" NODIRECT");
9108 val ^= DF_1_NODIRECT;
9109 }
9110 if (val & DF_1_IGNMULDEF)
9111 {
9112 printf (" IGNMULDEF");
9113 val ^= DF_1_IGNMULDEF;
9114 }
9115 if (val & DF_1_NOKSYMS)
9116 {
9117 printf (" NOKSYMS");
9118 val ^= DF_1_NOKSYMS;
9119 }
9120 if (val & DF_1_NOHDR)
9121 {
9122 printf (" NOHDR");
9123 val ^= DF_1_NOHDR;
9124 }
9125 if (val & DF_1_EDITED)
9126 {
9127 printf (" EDITED");
9128 val ^= DF_1_EDITED;
9129 }
9130 if (val & DF_1_NORELOC)
9131 {
9132 printf (" NORELOC");
9133 val ^= DF_1_NORELOC;
9134 }
9135 if (val & DF_1_SYMINTPOSE)
9136 {
9137 printf (" SYMINTPOSE");
9138 val ^= DF_1_SYMINTPOSE;
9139 }
9140 if (val & DF_1_GLOBAUDIT)
9141 {
9142 printf (" GLOBAUDIT");
9143 val ^= DF_1_GLOBAUDIT;
9144 }
9145 if (val & DF_1_SINGLETON)
9146 {
9147 printf (" SINGLETON");
9148 val ^= DF_1_SINGLETON;
dcefbbbd 9149 }
252b5132
RH
9150 if (val != 0)
9151 printf (" %lx", val);
9152 puts ("");
9153 }
9154 }
9155 break;
9156
9157 case DT_PLTREL:
566b0d53 9158 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9159 if (do_dynamic)
9160 puts (get_dynamic_type (entry->d_un.d_val));
9161 break;
9162
9163 case DT_NULL :
9164 case DT_NEEDED :
9165 case DT_PLTGOT :
9166 case DT_HASH :
9167 case DT_STRTAB :
9168 case DT_SYMTAB :
9169 case DT_RELA :
9170 case DT_INIT :
9171 case DT_FINI :
9172 case DT_SONAME :
9173 case DT_RPATH :
9174 case DT_SYMBOLIC:
9175 case DT_REL :
9176 case DT_DEBUG :
9177 case DT_TEXTREL :
9178 case DT_JMPREL :
019148e4 9179 case DT_RUNPATH :
252b5132
RH
9180 dynamic_info[entry->d_tag] = entry->d_un.d_val;
9181
9182 if (do_dynamic)
9183 {
2cf0635d 9184 char * name;
252b5132 9185
d79b3d50
NC
9186 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9187 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9188 else
d79b3d50 9189 name = NULL;
252b5132
RH
9190
9191 if (name)
9192 {
9193 switch (entry->d_tag)
9194 {
9195 case DT_NEEDED:
9196 printf (_("Shared library: [%s]"), name);
9197
18bd398b 9198 if (streq (name, program_interpreter))
f7a99963 9199 printf (_(" program interpreter"));
252b5132
RH
9200 break;
9201
9202 case DT_SONAME:
f7a99963 9203 printf (_("Library soname: [%s]"), name);
252b5132
RH
9204 break;
9205
9206 case DT_RPATH:
f7a99963 9207 printf (_("Library rpath: [%s]"), name);
252b5132
RH
9208 break;
9209
019148e4
L
9210 case DT_RUNPATH:
9211 printf (_("Library runpath: [%s]"), name);
9212 break;
9213
252b5132 9214 default:
f7a99963
NC
9215 print_vma (entry->d_un.d_val, PREFIX_HEX);
9216 break;
252b5132
RH
9217 }
9218 }
9219 else
f7a99963
NC
9220 print_vma (entry->d_un.d_val, PREFIX_HEX);
9221
9222 putchar ('\n');
252b5132
RH
9223 }
9224 break;
9225
9226 case DT_PLTRELSZ:
9227 case DT_RELASZ :
9228 case DT_STRSZ :
9229 case DT_RELSZ :
9230 case DT_RELAENT :
9231 case DT_SYMENT :
9232 case DT_RELENT :
566b0d53 9233 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9234 case DT_PLTPADSZ:
9235 case DT_MOVEENT :
9236 case DT_MOVESZ :
9237 case DT_INIT_ARRAYSZ:
9238 case DT_FINI_ARRAYSZ:
047b2264
JJ
9239 case DT_GNU_CONFLICTSZ:
9240 case DT_GNU_LIBLISTSZ:
252b5132 9241 if (do_dynamic)
f7a99963
NC
9242 {
9243 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 9244 printf (_(" (bytes)\n"));
f7a99963 9245 }
252b5132
RH
9246 break;
9247
9248 case DT_VERDEFNUM:
9249 case DT_VERNEEDNUM:
9250 case DT_RELACOUNT:
9251 case DT_RELCOUNT:
9252 if (do_dynamic)
f7a99963
NC
9253 {
9254 print_vma (entry->d_un.d_val, UNSIGNED);
9255 putchar ('\n');
9256 }
252b5132
RH
9257 break;
9258
9259 case DT_SYMINSZ:
9260 case DT_SYMINENT:
9261 case DT_SYMINFO:
9262 case DT_USED:
9263 case DT_INIT_ARRAY:
9264 case DT_FINI_ARRAY:
9265 if (do_dynamic)
9266 {
d79b3d50
NC
9267 if (entry->d_tag == DT_USED
9268 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 9269 {
2cf0635d 9270 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9271
b34976b6 9272 if (*name)
252b5132
RH
9273 {
9274 printf (_("Not needed object: [%s]\n"), name);
9275 break;
9276 }
9277 }
103f02d3 9278
f7a99963
NC
9279 print_vma (entry->d_un.d_val, PREFIX_HEX);
9280 putchar ('\n');
252b5132
RH
9281 }
9282 break;
9283
9284 case DT_BIND_NOW:
9285 /* The value of this entry is ignored. */
35b1837e
AM
9286 if (do_dynamic)
9287 putchar ('\n');
252b5132 9288 break;
103f02d3 9289
047b2264
JJ
9290 case DT_GNU_PRELINKED:
9291 if (do_dynamic)
9292 {
2cf0635d 9293 struct tm * tmp;
91d6fa6a 9294 time_t atime = entry->d_un.d_val;
047b2264 9295
91d6fa6a 9296 tmp = gmtime (&atime);
071436c6
NC
9297 /* PR 17533 file: 041-1244816-0.004. */
9298 if (tmp == NULL)
5a2cbcf4
L
9299 printf (_("<corrupt time val: %lx"),
9300 (unsigned long) atime);
071436c6
NC
9301 else
9302 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
9303 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9304 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9305
9306 }
9307 break;
9308
fdc90cb4
JJ
9309 case DT_GNU_HASH:
9310 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9311 if (do_dynamic)
9312 {
9313 print_vma (entry->d_un.d_val, PREFIX_HEX);
9314 putchar ('\n');
9315 }
9316 break;
9317
252b5132
RH
9318 default:
9319 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 9320 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
9321 entry->d_un.d_val;
9322
9323 if (do_dynamic)
9324 {
9325 switch (elf_header.e_machine)
9326 {
9327 case EM_MIPS:
4fe85591 9328 case EM_MIPS_RS3_LE:
b2d38a17 9329 dynamic_section_mips_val (entry);
252b5132 9330 break;
103f02d3 9331 case EM_PARISC:
b2d38a17 9332 dynamic_section_parisc_val (entry);
103f02d3 9333 break;
ecc51f48 9334 case EM_IA_64:
b2d38a17 9335 dynamic_section_ia64_val (entry);
ecc51f48 9336 break;
252b5132 9337 default:
f7a99963
NC
9338 print_vma (entry->d_un.d_val, PREFIX_HEX);
9339 putchar ('\n');
252b5132
RH
9340 }
9341 }
9342 break;
9343 }
9344 }
9345
9346 return 1;
9347}
9348
9349static char *
d3ba0551 9350get_ver_flags (unsigned int flags)
252b5132 9351{
b34976b6 9352 static char buff[32];
252b5132
RH
9353
9354 buff[0] = 0;
9355
9356 if (flags == 0)
9357 return _("none");
9358
9359 if (flags & VER_FLG_BASE)
9360 strcat (buff, "BASE ");
9361
9362 if (flags & VER_FLG_WEAK)
9363 {
9364 if (flags & VER_FLG_BASE)
9365 strcat (buff, "| ");
9366
9367 strcat (buff, "WEAK ");
9368 }
9369
44ec90b9
RO
9370 if (flags & VER_FLG_INFO)
9371 {
9372 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
9373 strcat (buff, "| ");
9374
9375 strcat (buff, "INFO ");
9376 }
9377
9378 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 9379 strcat (buff, _("| <unknown>"));
252b5132
RH
9380
9381 return buff;
9382}
9383
9384/* Display the contents of the version sections. */
98fb390a 9385
252b5132 9386static int
2cf0635d 9387process_version_sections (FILE * file)
252b5132 9388{
2cf0635d 9389 Elf_Internal_Shdr * section;
b34976b6
AM
9390 unsigned i;
9391 int found = 0;
252b5132
RH
9392
9393 if (! do_version)
9394 return 1;
9395
9396 for (i = 0, section = section_headers;
9397 i < elf_header.e_shnum;
b34976b6 9398 i++, section++)
252b5132
RH
9399 {
9400 switch (section->sh_type)
9401 {
9402 case SHT_GNU_verdef:
9403 {
2cf0635d 9404 Elf_External_Verdef * edefs;
b34976b6
AM
9405 unsigned int idx;
9406 unsigned int cnt;
2cf0635d 9407 char * endbuf;
252b5132
RH
9408
9409 found = 1;
9410
74e1a04b
NC
9411 printf (_("\nVersion definition section '%s' contains %u entries:\n"),
9412 printable_section_name (section),
9413 section->sh_info);
252b5132
RH
9414
9415 printf (_(" Addr: 0x"));
9416 printf_vma (section->sh_addr);
74e1a04b 9417 printf (_(" Offset: %#08lx Link: %u (%s)"),
1b228002 9418 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9419 printable_section_name_from_index (section->sh_link));
252b5132 9420
3f5e193b
NC
9421 edefs = (Elf_External_Verdef *)
9422 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
9423 _("version definition section"));
a6e9f9df
AM
9424 if (!edefs)
9425 break;
59245841 9426 endbuf = (char *) edefs + section->sh_size;
252b5132 9427
b34976b6 9428 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 9429 {
2cf0635d
NC
9430 char * vstart;
9431 Elf_External_Verdef * edef;
b34976b6 9432 Elf_Internal_Verdef ent;
2cf0635d 9433 Elf_External_Verdaux * eaux;
b34976b6
AM
9434 Elf_Internal_Verdaux aux;
9435 int j;
9436 int isum;
103f02d3 9437
7e26601c
NC
9438 /* Check for very large indicies. */
9439 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
9440 break;
9441
252b5132 9442 vstart = ((char *) edefs) + idx;
54806181
AM
9443 if (vstart + sizeof (*edef) > endbuf)
9444 break;
252b5132
RH
9445
9446 edef = (Elf_External_Verdef *) vstart;
9447
9448 ent.vd_version = BYTE_GET (edef->vd_version);
9449 ent.vd_flags = BYTE_GET (edef->vd_flags);
9450 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
9451 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
9452 ent.vd_hash = BYTE_GET (edef->vd_hash);
9453 ent.vd_aux = BYTE_GET (edef->vd_aux);
9454 ent.vd_next = BYTE_GET (edef->vd_next);
9455
9456 printf (_(" %#06x: Rev: %d Flags: %s"),
9457 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
9458
9459 printf (_(" Index: %d Cnt: %d "),
9460 ent.vd_ndx, ent.vd_cnt);
9461
dd24e3da 9462 /* Check for overflow. */
7e26601c 9463 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9464 break;
9465
252b5132
RH
9466 vstart += ent.vd_aux;
9467
9468 eaux = (Elf_External_Verdaux *) vstart;
9469
9470 aux.vda_name = BYTE_GET (eaux->vda_name);
9471 aux.vda_next = BYTE_GET (eaux->vda_next);
9472
d79b3d50
NC
9473 if (VALID_DYNAMIC_NAME (aux.vda_name))
9474 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9475 else
9476 printf (_("Name index: %ld\n"), aux.vda_name);
9477
9478 isum = idx + ent.vd_aux;
9479
b34976b6 9480 for (j = 1; j < ent.vd_cnt; j++)
252b5132 9481 {
dd24e3da 9482 /* Check for overflow. */
7e26601c 9483 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9484 break;
9485
252b5132
RH
9486 isum += aux.vda_next;
9487 vstart += aux.vda_next;
9488
9489 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
9490 if (vstart + sizeof (*eaux) > endbuf)
9491 break;
252b5132
RH
9492
9493 aux.vda_name = BYTE_GET (eaux->vda_name);
9494 aux.vda_next = BYTE_GET (eaux->vda_next);
9495
d79b3d50 9496 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 9497 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 9498 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9499 else
9500 printf (_(" %#06x: Parent %d, name index: %ld\n"),
9501 isum, j, aux.vda_name);
9502 }
dd24e3da 9503
54806181
AM
9504 if (j < ent.vd_cnt)
9505 printf (_(" Version def aux past end of section\n"));
252b5132 9506
5d921cbd
NC
9507 /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
9508 if (idx + ent.vd_next <= idx)
9509 break;
9510
252b5132
RH
9511 idx += ent.vd_next;
9512 }
dd24e3da 9513
54806181
AM
9514 if (cnt < section->sh_info)
9515 printf (_(" Version definition past end of section\n"));
252b5132
RH
9516
9517 free (edefs);
9518 }
9519 break;
103f02d3 9520
252b5132
RH
9521 case SHT_GNU_verneed:
9522 {
2cf0635d 9523 Elf_External_Verneed * eneed;
b34976b6
AM
9524 unsigned int idx;
9525 unsigned int cnt;
2cf0635d 9526 char * endbuf;
252b5132
RH
9527
9528 found = 1;
9529
72de5009 9530 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
74e1a04b 9531 printable_section_name (section), section->sh_info);
252b5132
RH
9532
9533 printf (_(" Addr: 0x"));
9534 printf_vma (section->sh_addr);
72de5009 9535 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9536 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9537 printable_section_name_from_index (section->sh_link));
252b5132 9538
3f5e193b
NC
9539 eneed = (Elf_External_Verneed *) get_data (NULL, file,
9540 section->sh_offset, 1,
9541 section->sh_size,
9cf03b7e 9542 _("Version Needs section"));
a6e9f9df
AM
9543 if (!eneed)
9544 break;
59245841 9545 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
9546
9547 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
9548 {
2cf0635d 9549 Elf_External_Verneed * entry;
b34976b6
AM
9550 Elf_Internal_Verneed ent;
9551 int j;
9552 int isum;
2cf0635d 9553 char * vstart;
252b5132 9554
7e26601c 9555 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
9556 break;
9557
252b5132 9558 vstart = ((char *) eneed) + idx;
54806181
AM
9559 if (vstart + sizeof (*entry) > endbuf)
9560 break;
252b5132
RH
9561
9562 entry = (Elf_External_Verneed *) vstart;
9563
9564 ent.vn_version = BYTE_GET (entry->vn_version);
9565 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
9566 ent.vn_file = BYTE_GET (entry->vn_file);
9567 ent.vn_aux = BYTE_GET (entry->vn_aux);
9568 ent.vn_next = BYTE_GET (entry->vn_next);
9569
9570 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
9571
d79b3d50
NC
9572 if (VALID_DYNAMIC_NAME (ent.vn_file))
9573 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
9574 else
9575 printf (_(" File: %lx"), ent.vn_file);
9576
9577 printf (_(" Cnt: %d\n"), ent.vn_cnt);
9578
dd24e3da 9579 /* Check for overflow. */
7e26601c 9580 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 9581 break;
252b5132
RH
9582 vstart += ent.vn_aux;
9583
9584 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
9585 {
2cf0635d 9586 Elf_External_Vernaux * eaux;
b34976b6 9587 Elf_Internal_Vernaux aux;
252b5132 9588
54806181
AM
9589 if (vstart + sizeof (*eaux) > endbuf)
9590 break;
252b5132
RH
9591 eaux = (Elf_External_Vernaux *) vstart;
9592
9593 aux.vna_hash = BYTE_GET (eaux->vna_hash);
9594 aux.vna_flags = BYTE_GET (eaux->vna_flags);
9595 aux.vna_other = BYTE_GET (eaux->vna_other);
9596 aux.vna_name = BYTE_GET (eaux->vna_name);
9597 aux.vna_next = BYTE_GET (eaux->vna_next);
9598
d79b3d50 9599 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 9600 printf (_(" %#06x: Name: %s"),
d79b3d50 9601 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 9602 else
ecc2063b 9603 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
9604 isum, aux.vna_name);
9605
9606 printf (_(" Flags: %s Version: %d\n"),
9607 get_ver_flags (aux.vna_flags), aux.vna_other);
9608
dd24e3da 9609 /* Check for overflow. */
53774b7e
NC
9610 if (aux.vna_next > (size_t) (endbuf - vstart)
9611 || (aux.vna_next == 0 && j < ent.vn_cnt - 1))
9612 {
9613 warn (_("Invalid vna_next field of %lx\n"),
9614 aux.vna_next);
9615 j = ent.vn_cnt;
9616 break;
9617 }
252b5132
RH
9618 isum += aux.vna_next;
9619 vstart += aux.vna_next;
9620 }
9cf03b7e 9621
54806181 9622 if (j < ent.vn_cnt)
9cf03b7e 9623 warn (_("Missing Version Needs auxillary information\n"));
252b5132 9624
bcf83b2a 9625 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
9626 {
9627 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
9628 cnt = section->sh_info;
9629 break;
9630 }
252b5132
RH
9631 idx += ent.vn_next;
9632 }
9cf03b7e 9633
54806181 9634 if (cnt < section->sh_info)
9cf03b7e 9635 warn (_("Missing Version Needs information\n"));
103f02d3 9636
252b5132
RH
9637 free (eneed);
9638 }
9639 break;
9640
9641 case SHT_GNU_versym:
9642 {
2cf0635d 9643 Elf_Internal_Shdr * link_section;
8b73c356
NC
9644 size_t total;
9645 unsigned int cnt;
2cf0635d
NC
9646 unsigned char * edata;
9647 unsigned short * data;
9648 char * strtab;
9649 Elf_Internal_Sym * symbols;
9650 Elf_Internal_Shdr * string_sec;
ba5cdace 9651 unsigned long num_syms;
d3ba0551 9652 long off;
252b5132 9653
4fbb74a6 9654 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9655 break;
9656
4fbb74a6 9657 link_section = section_headers + section->sh_link;
08d8fa11 9658 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9659
4fbb74a6 9660 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9661 break;
9662
252b5132
RH
9663 found = 1;
9664
ba5cdace 9665 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9666 if (symbols == NULL)
9667 break;
252b5132 9668
4fbb74a6 9669 string_sec = section_headers + link_section->sh_link;
252b5132 9670
3f5e193b
NC
9671 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9672 string_sec->sh_size,
9673 _("version string table"));
a6e9f9df 9674 if (!strtab)
0429c154
MS
9675 {
9676 free (symbols);
9677 break;
9678 }
252b5132 9679
8b73c356
NC
9680 printf (_("\nVersion symbols section '%s' contains %lu entries:\n"),
9681 printable_section_name (section), (unsigned long) total);
252b5132
RH
9682
9683 printf (_(" Addr: "));
9684 printf_vma (section->sh_addr);
72de5009 9685 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9686 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9687 printable_section_name (link_section));
252b5132 9688
d3ba0551
AM
9689 off = offset_from_vma (file,
9690 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9691 total * sizeof (short));
3f5e193b
NC
9692 edata = (unsigned char *) get_data (NULL, file, off, total,
9693 sizeof (short),
9694 _("version symbol data"));
a6e9f9df
AM
9695 if (!edata)
9696 {
9697 free (strtab);
0429c154 9698 free (symbols);
a6e9f9df
AM
9699 break;
9700 }
252b5132 9701
3f5e193b 9702 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9703
9704 for (cnt = total; cnt --;)
b34976b6
AM
9705 data[cnt] = byte_get (edata + cnt * sizeof (short),
9706 sizeof (short));
252b5132
RH
9707
9708 free (edata);
9709
9710 for (cnt = 0; cnt < total; cnt += 4)
9711 {
9712 int j, nn;
00d93f34 9713 int check_def, check_need;
2cf0635d 9714 char * name;
252b5132
RH
9715
9716 printf (" %03x:", cnt);
9717
9718 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9719 switch (data[cnt + j])
252b5132
RH
9720 {
9721 case 0:
9722 fputs (_(" 0 (*local*) "), stdout);
9723 break;
9724
9725 case 1:
9726 fputs (_(" 1 (*global*) "), stdout);
9727 break;
9728
9729 default:
c244d050
NC
9730 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9731 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9732
dd24e3da 9733 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9734 array, break to avoid an out-of-bounds read. */
9735 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9736 {
9737 warn (_("invalid index into symbol array\n"));
9738 break;
9739 }
9740
00d93f34
JJ
9741 check_def = 1;
9742 check_need = 1;
4fbb74a6
AM
9743 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
9744 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 9745 != SHT_NOBITS)
252b5132 9746 {
b34976b6 9747 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
9748 check_def = 0;
9749 else
9750 check_need = 0;
252b5132 9751 }
00d93f34
JJ
9752
9753 if (check_need
b34976b6 9754 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9755 {
b34976b6
AM
9756 Elf_Internal_Verneed ivn;
9757 unsigned long offset;
252b5132 9758
d93f0186
NC
9759 offset = offset_from_vma
9760 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9761 sizeof (Elf_External_Verneed));
252b5132 9762
b34976b6 9763 do
252b5132 9764 {
b34976b6
AM
9765 Elf_Internal_Vernaux ivna;
9766 Elf_External_Verneed evn;
9767 Elf_External_Vernaux evna;
9768 unsigned long a_off;
252b5132 9769
59245841
NC
9770 if (get_data (&evn, file, offset, sizeof (evn), 1,
9771 _("version need")) == NULL)
9772 break;
0b4362b0 9773
252b5132
RH
9774 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9775 ivn.vn_next = BYTE_GET (evn.vn_next);
9776
9777 a_off = offset + ivn.vn_aux;
9778
9779 do
9780 {
59245841
NC
9781 if (get_data (&evna, file, a_off, sizeof (evna),
9782 1, _("version need aux (2)")) == NULL)
9783 {
9784 ivna.vna_next = 0;
9785 ivna.vna_other = 0;
9786 }
9787 else
9788 {
9789 ivna.vna_next = BYTE_GET (evna.vna_next);
9790 ivna.vna_other = BYTE_GET (evna.vna_other);
9791 }
252b5132
RH
9792
9793 a_off += ivna.vna_next;
9794 }
b34976b6 9795 while (ivna.vna_other != data[cnt + j]
252b5132
RH
9796 && ivna.vna_next != 0);
9797
b34976b6 9798 if (ivna.vna_other == data[cnt + j])
252b5132
RH
9799 {
9800 ivna.vna_name = BYTE_GET (evna.vna_name);
9801
54806181
AM
9802 if (ivna.vna_name >= string_sec->sh_size)
9803 name = _("*invalid*");
9804 else
9805 name = strtab + ivna.vna_name;
252b5132 9806 nn += printf ("(%s%-*s",
16062207
ILT
9807 name,
9808 12 - (int) strlen (name),
252b5132 9809 ")");
00d93f34 9810 check_def = 0;
252b5132
RH
9811 break;
9812 }
9813
9814 offset += ivn.vn_next;
9815 }
9816 while (ivn.vn_next);
9817 }
00d93f34 9818
b34976b6
AM
9819 if (check_def && data[cnt + j] != 0x8001
9820 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9821 {
b34976b6
AM
9822 Elf_Internal_Verdef ivd;
9823 Elf_External_Verdef evd;
9824 unsigned long offset;
252b5132 9825
d93f0186
NC
9826 offset = offset_from_vma
9827 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9828 sizeof evd);
252b5132
RH
9829
9830 do
9831 {
59245841
NC
9832 if (get_data (&evd, file, offset, sizeof (evd), 1,
9833 _("version def")) == NULL)
9834 {
9835 ivd.vd_next = 0;
948f632f 9836 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
9837 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
9838 break;
59245841
NC
9839 }
9840 else
9841 {
9842 ivd.vd_next = BYTE_GET (evd.vd_next);
9843 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9844 }
252b5132
RH
9845
9846 offset += ivd.vd_next;
9847 }
c244d050 9848 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
9849 && ivd.vd_next != 0);
9850
c244d050 9851 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 9852 {
b34976b6
AM
9853 Elf_External_Verdaux evda;
9854 Elf_Internal_Verdaux ivda;
252b5132
RH
9855
9856 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9857
59245841
NC
9858 if (get_data (&evda, file,
9859 offset - ivd.vd_next + ivd.vd_aux,
9860 sizeof (evda), 1,
9861 _("version def aux")) == NULL)
9862 break;
252b5132
RH
9863
9864 ivda.vda_name = BYTE_GET (evda.vda_name);
9865
54806181
AM
9866 if (ivda.vda_name >= string_sec->sh_size)
9867 name = _("*invalid*");
9868 else
9869 name = strtab + ivda.vda_name;
252b5132 9870 nn += printf ("(%s%-*s",
16062207
ILT
9871 name,
9872 12 - (int) strlen (name),
252b5132
RH
9873 ")");
9874 }
9875 }
9876
9877 if (nn < 18)
9878 printf ("%*c", 18 - nn, ' ');
9879 }
9880
9881 putchar ('\n');
9882 }
9883
9884 free (data);
9885 free (strtab);
9886 free (symbols);
9887 }
9888 break;
103f02d3 9889
252b5132
RH
9890 default:
9891 break;
9892 }
9893 }
9894
9895 if (! found)
9896 printf (_("\nNo version information found in this file.\n"));
9897
9898 return 1;
9899}
9900
d1133906 9901static const char *
d3ba0551 9902get_symbol_binding (unsigned int binding)
252b5132 9903{
b34976b6 9904 static char buff[32];
252b5132
RH
9905
9906 switch (binding)
9907 {
b34976b6
AM
9908 case STB_LOCAL: return "LOCAL";
9909 case STB_GLOBAL: return "GLOBAL";
9910 case STB_WEAK: return "WEAK";
252b5132
RH
9911 default:
9912 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9913 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9914 binding);
252b5132 9915 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9916 {
9917 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9918 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9919 /* GNU is still using the default value 0. */
3e7a7d11
NC
9920 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9921 return "UNIQUE";
9922 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9923 }
252b5132 9924 else
e9e44622 9925 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9926 return buff;
9927 }
9928}
9929
d1133906 9930static const char *
d3ba0551 9931get_symbol_type (unsigned int type)
252b5132 9932{
b34976b6 9933 static char buff[32];
252b5132
RH
9934
9935 switch (type)
9936 {
b34976b6
AM
9937 case STT_NOTYPE: return "NOTYPE";
9938 case STT_OBJECT: return "OBJECT";
9939 case STT_FUNC: return "FUNC";
9940 case STT_SECTION: return "SECTION";
9941 case STT_FILE: return "FILE";
9942 case STT_COMMON: return "COMMON";
9943 case STT_TLS: return "TLS";
15ab5209
DB
9944 case STT_RELC: return "RELC";
9945 case STT_SRELC: return "SRELC";
252b5132
RH
9946 default:
9947 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9948 {
3510a7b8
NC
9949 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
9950 return "THUMB_FUNC";
103f02d3 9951
351b4b40 9952 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9953 return "REGISTER";
9954
9955 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9956 return "PARISC_MILLI";
9957
e9e44622 9958 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9959 }
252b5132 9960 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9961 {
9962 if (elf_header.e_machine == EM_PARISC)
9963 {
9964 if (type == STT_HP_OPAQUE)
9965 return "HP_OPAQUE";
9966 if (type == STT_HP_STUB)
9967 return "HP_STUB";
9968 }
9969
d8045f23 9970 if (type == STT_GNU_IFUNC
9c55345c 9971 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9972 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9973 /* GNU is still using the default value 0. */
d8045f23
NC
9974 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9975 return "IFUNC";
9976
e9e44622 9977 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9978 }
252b5132 9979 else
e9e44622 9980 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9981 return buff;
9982 }
9983}
9984
d1133906 9985static const char *
d3ba0551 9986get_symbol_visibility (unsigned int visibility)
d1133906
NC
9987{
9988 switch (visibility)
9989 {
b34976b6
AM
9990 case STV_DEFAULT: return "DEFAULT";
9991 case STV_INTERNAL: return "INTERNAL";
9992 case STV_HIDDEN: return "HIDDEN";
d1133906 9993 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
9994 default:
9995 error (_("Unrecognized visibility value: %u"), visibility);
9996 return _("<unknown>");
d1133906
NC
9997 }
9998}
9999
5e2b0d47
NC
10000static const char *
10001get_mips_symbol_other (unsigned int other)
10002{
10003 switch (other)
10004 {
df58fc94
RS
10005 case STO_OPTIONAL:
10006 return "OPTIONAL";
10007 case STO_MIPS_PLT:
10008 return "MIPS PLT";
10009 case STO_MIPS_PIC:
10010 return "MIPS PIC";
10011 case STO_MICROMIPS:
10012 return "MICROMIPS";
10013 case STO_MICROMIPS | STO_MIPS_PIC:
10014 return "MICROMIPS, MIPS PIC";
10015 case STO_MIPS16:
10016 return "MIPS16";
10017 default:
10018 return NULL;
5e2b0d47
NC
10019 }
10020}
10021
28f997cf
TG
10022static const char *
10023get_ia64_symbol_other (unsigned int other)
10024{
10025 if (is_ia64_vms ())
10026 {
10027 static char res[32];
10028
10029 res[0] = 0;
10030
10031 /* Function types is for images and .STB files only. */
10032 switch (elf_header.e_type)
10033 {
10034 case ET_DYN:
10035 case ET_EXEC:
10036 switch (VMS_ST_FUNC_TYPE (other))
10037 {
10038 case VMS_SFT_CODE_ADDR:
10039 strcat (res, " CA");
10040 break;
10041 case VMS_SFT_SYMV_IDX:
10042 strcat (res, " VEC");
10043 break;
10044 case VMS_SFT_FD:
10045 strcat (res, " FD");
10046 break;
10047 case VMS_SFT_RESERVE:
10048 strcat (res, " RSV");
10049 break;
10050 default:
bee0ee85
NC
10051 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
10052 VMS_ST_FUNC_TYPE (other));
10053 strcat (res, " <unknown>");
10054 break;
28f997cf
TG
10055 }
10056 break;
10057 default:
10058 break;
10059 }
10060 switch (VMS_ST_LINKAGE (other))
10061 {
10062 case VMS_STL_IGNORE:
10063 strcat (res, " IGN");
10064 break;
10065 case VMS_STL_RESERVE:
10066 strcat (res, " RSV");
10067 break;
10068 case VMS_STL_STD:
10069 strcat (res, " STD");
10070 break;
10071 case VMS_STL_LNK:
10072 strcat (res, " LNK");
10073 break;
10074 default:
bee0ee85
NC
10075 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
10076 VMS_ST_LINKAGE (other));
10077 strcat (res, " <unknown>");
10078 break;
28f997cf
TG
10079 }
10080
10081 if (res[0] != 0)
10082 return res + 1;
10083 else
10084 return res;
10085 }
10086 return NULL;
10087}
10088
6911b7dc
AM
10089static const char *
10090get_ppc64_symbol_other (unsigned int other)
10091{
10092 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
10093 {
10094 static char buf[32];
10095 snprintf (buf, sizeof buf, _("<localentry>: %d"),
10096 PPC64_LOCAL_ENTRY_OFFSET (other));
10097 return buf;
10098 }
10099 return NULL;
10100}
10101
5e2b0d47
NC
10102static const char *
10103get_symbol_other (unsigned int other)
10104{
10105 const char * result = NULL;
10106 static char buff [32];
10107
10108 if (other == 0)
10109 return "";
10110
10111 switch (elf_header.e_machine)
10112 {
10113 case EM_MIPS:
10114 result = get_mips_symbol_other (other);
28f997cf
TG
10115 break;
10116 case EM_IA_64:
10117 result = get_ia64_symbol_other (other);
10118 break;
6911b7dc
AM
10119 case EM_PPC64:
10120 result = get_ppc64_symbol_other (other);
10121 break;
5e2b0d47
NC
10122 default:
10123 break;
10124 }
10125
10126 if (result)
10127 return result;
10128
10129 snprintf (buff, sizeof buff, _("<other>: %x"), other);
10130 return buff;
10131}
10132
d1133906 10133static const char *
d3ba0551 10134get_symbol_index_type (unsigned int type)
252b5132 10135{
b34976b6 10136 static char buff[32];
5cf1065c 10137
252b5132
RH
10138 switch (type)
10139 {
b34976b6
AM
10140 case SHN_UNDEF: return "UND";
10141 case SHN_ABS: return "ABS";
10142 case SHN_COMMON: return "COM";
252b5132 10143 default:
9ce701e2
L
10144 if (type == SHN_IA_64_ANSI_COMMON
10145 && elf_header.e_machine == EM_IA_64
10146 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
10147 return "ANSI_COM";
8a9036a4 10148 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
10149 || elf_header.e_machine == EM_L1OM
10150 || elf_header.e_machine == EM_K1OM)
3b22753a
L
10151 && type == SHN_X86_64_LCOMMON)
10152 return "LARGE_COM";
ac145307
BS
10153 else if ((type == SHN_MIPS_SCOMMON
10154 && elf_header.e_machine == EM_MIPS)
10155 || (type == SHN_TIC6X_SCOMMON
10156 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
10157 return "SCOM";
10158 else if (type == SHN_MIPS_SUNDEFINED
10159 && elf_header.e_machine == EM_MIPS)
10160 return "SUND";
9ce701e2 10161 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 10162 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 10163 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
10164 sprintf (buff, "OS [0x%04x]", type & 0xffff);
10165 else if (type >= SHN_LORESERVE)
10166 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4 10167 else if (type >= elf_header.e_shnum)
e0a31db1 10168 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 10169 else
232e7cb8 10170 sprintf (buff, "%3d", type);
5cf1065c 10171 break;
252b5132 10172 }
5cf1065c
NC
10173
10174 return buff;
252b5132
RH
10175}
10176
66543521 10177static bfd_vma *
57028622 10178get_dynamic_data (FILE * file, bfd_size_type number, unsigned int ent_size)
252b5132 10179{
2cf0635d
NC
10180 unsigned char * e_data;
10181 bfd_vma * i_data;
252b5132 10182
57028622
NC
10183 /* If the size_t type is smaller than the bfd_size_type, eg because
10184 you are building a 32-bit tool on a 64-bit host, then make sure
10185 that when (number) is cast to (size_t) no information is lost. */
10186 if (sizeof (size_t) < sizeof (bfd_size_type)
10187 && (bfd_size_type) ((size_t) number) != number)
10188 {
10189 error (_("Size truncation prevents reading %llu elements of size %u\n"),
10190 (unsigned long long) number, ent_size);
10191 return NULL;
10192 }
948f632f 10193
3102e897
NC
10194 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
10195 attempting to allocate memory when the read is bound to fail. */
10196 if (ent_size * number > current_file_size)
10197 {
57028622
NC
10198 error (_("Invalid number of dynamic entries: %llu\n"),
10199 (unsigned long long) number);
3102e897
NC
10200 return NULL;
10201 }
10202
57028622 10203 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
10204 if (e_data == NULL)
10205 {
57028622
NC
10206 error (_("Out of memory reading %llu dynamic entries\n"),
10207 (unsigned long long) number);
252b5132
RH
10208 return NULL;
10209 }
10210
57028622 10211 if (fread (e_data, ent_size, (size_t) number, file) != number)
252b5132 10212 {
57028622
NC
10213 error (_("Unable to read in %llu bytes of dynamic data\n"),
10214 (unsigned long long) (number * ent_size));
3102e897 10215 free (e_data);
252b5132
RH
10216 return NULL;
10217 }
10218
57028622 10219 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
10220 if (i_data == NULL)
10221 {
57028622
NC
10222 error (_("Out of memory allocating space for %llu dynamic entries\n"),
10223 (unsigned long long) number);
252b5132
RH
10224 free (e_data);
10225 return NULL;
10226 }
10227
10228 while (number--)
66543521 10229 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
10230
10231 free (e_data);
10232
10233 return i_data;
10234}
10235
6bd1a22c
L
10236static void
10237print_dynamic_symbol (bfd_vma si, unsigned long hn)
10238{
2cf0635d 10239 Elf_Internal_Sym * psym;
6bd1a22c
L
10240 int n;
10241
6bd1a22c
L
10242 n = print_vma (si, DEC_5);
10243 if (n < 5)
0b4362b0 10244 fputs (&" "[n], stdout);
6bd1a22c 10245 printf (" %3lu: ", hn);
e0a31db1
NC
10246
10247 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
10248 {
3102e897
NC
10249 printf (_("<No info available for dynamic symbol number %lu>\n"),
10250 (unsigned long) si);
e0a31db1
NC
10251 return;
10252 }
10253
10254 psym = dynamic_symbols + si;
6bd1a22c
L
10255 print_vma (psym->st_value, LONG_HEX);
10256 putchar (' ');
10257 print_vma (psym->st_size, DEC_5);
10258
f4be36b3
AM
10259 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10260 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
10261 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
10262 /* Check to see if any other bits in the st_other field are set.
10263 Note - displaying this information disrupts the layout of the
10264 table being generated, but for the moment this case is very
10265 rare. */
10266 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10267 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
10268 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
10269 if (VALID_DYNAMIC_NAME (psym->st_name))
10270 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10271 else
2b692964 10272 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
10273 putchar ('\n');
10274}
10275
bb4d2ac2
L
10276static const char *
10277get_symbol_version_string (FILE *file, int is_dynsym,
10278 const char *strtab,
10279 unsigned long int strtab_size,
10280 unsigned int si, Elf_Internal_Sym *psym,
10281 enum versioned_symbol_info *sym_info,
10282 unsigned short *vna_other)
10283{
10284 const char *version_string = NULL;
10285
10286 if (is_dynsym
10287 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
10288 {
10289 unsigned char data[2];
10290 unsigned short vers_data;
10291 unsigned long offset;
10292 int is_nobits;
10293 int check_def;
10294
10295 offset = offset_from_vma
10296 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10297 sizeof data + si * sizeof (vers_data));
10298
10299 if (get_data (&data, file, offset + si * sizeof (vers_data),
10300 sizeof (data), 1, _("version data")) == NULL)
10301 return NULL;
10302
10303 vers_data = byte_get (data, 2);
10304
53774b7e
NC
10305 is_nobits = (section_headers != NULL
10306 && psym->st_shndx < elf_header.e_shnum
bb4d2ac2
L
10307 && section_headers[psym->st_shndx].sh_type
10308 == SHT_NOBITS);
10309
10310 check_def = (psym->st_shndx != SHN_UNDEF);
10311
10312 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
10313 {
10314 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
10315 && (is_nobits || ! check_def))
10316 {
10317 Elf_External_Verneed evn;
10318 Elf_Internal_Verneed ivn;
10319 Elf_Internal_Vernaux ivna;
10320
10321 /* We must test both. */
10322 offset = offset_from_vma
10323 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10324 sizeof evn);
10325
10326 do
10327 {
10328 unsigned long vna_off;
10329
10330 if (get_data (&evn, file, offset, sizeof (evn), 1,
10331 _("version need")) == NULL)
10332 {
10333 ivna.vna_next = 0;
10334 ivna.vna_other = 0;
10335 ivna.vna_name = 0;
10336 break;
10337 }
10338
10339 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10340 ivn.vn_next = BYTE_GET (evn.vn_next);
10341
10342 vna_off = offset + ivn.vn_aux;
10343
10344 do
10345 {
10346 Elf_External_Vernaux evna;
10347
10348 if (get_data (&evna, file, vna_off,
10349 sizeof (evna), 1,
10350 _("version need aux (3)")) == NULL)
10351 {
10352 ivna.vna_next = 0;
10353 ivna.vna_other = 0;
10354 ivna.vna_name = 0;
10355 }
10356 else
10357 {
10358 ivna.vna_other = BYTE_GET (evna.vna_other);
10359 ivna.vna_next = BYTE_GET (evna.vna_next);
10360 ivna.vna_name = BYTE_GET (evna.vna_name);
10361 }
10362
10363 vna_off += ivna.vna_next;
10364 }
10365 while (ivna.vna_other != vers_data
10366 && ivna.vna_next != 0);
10367
10368 if (ivna.vna_other == vers_data)
10369 break;
10370
10371 offset += ivn.vn_next;
10372 }
10373 while (ivn.vn_next != 0);
10374
10375 if (ivna.vna_other == vers_data)
10376 {
10377 *sym_info = symbol_undefined;
10378 *vna_other = ivna.vna_other;
10379 version_string = (ivna.vna_name < strtab_size
10380 ? strtab + ivna.vna_name
10381 : _("<corrupt>"));
10382 check_def = 0;
10383 }
10384 else if (! is_nobits)
10385 error (_("bad dynamic symbol\n"));
10386 else
10387 check_def = 1;
10388 }
10389
10390 if (check_def)
10391 {
10392 if (vers_data != 0x8001
10393 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
10394 {
10395 Elf_Internal_Verdef ivd;
10396 Elf_Internal_Verdaux ivda;
10397 Elf_External_Verdaux evda;
10398 unsigned long off;
10399
10400 off = offset_from_vma
10401 (file,
10402 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10403 sizeof (Elf_External_Verdef));
10404
10405 do
10406 {
10407 Elf_External_Verdef evd;
10408
10409 if (get_data (&evd, file, off, sizeof (evd),
10410 1, _("version def")) == NULL)
10411 {
10412 ivd.vd_ndx = 0;
10413 ivd.vd_aux = 0;
10414 ivd.vd_next = 0;
10415 }
10416 else
10417 {
10418 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10419 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10420 ivd.vd_next = BYTE_GET (evd.vd_next);
10421 }
10422
10423 off += ivd.vd_next;
10424 }
10425 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
10426 && ivd.vd_next != 0);
10427
10428 off -= ivd.vd_next;
10429 off += ivd.vd_aux;
10430
10431 if (get_data (&evda, file, off, sizeof (evda),
10432 1, _("version def aux")) == NULL)
10433 return version_string;
10434
10435 ivda.vda_name = BYTE_GET (evda.vda_name);
10436
10437 if (psym->st_name != ivda.vda_name)
10438 {
10439 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
10440 ? symbol_hidden : symbol_public);
10441 version_string = (ivda.vda_name < strtab_size
10442 ? strtab + ivda.vda_name
10443 : _("<corrupt>"));
10444 }
10445 }
10446 }
10447 }
10448 }
10449 return version_string;
10450}
10451
e3c8793a 10452/* Dump the symbol table. */
252b5132 10453static int
2cf0635d 10454process_symbol_table (FILE * file)
252b5132 10455{
2cf0635d 10456 Elf_Internal_Shdr * section;
8b73c356
NC
10457 bfd_size_type nbuckets = 0;
10458 bfd_size_type nchains = 0;
2cf0635d
NC
10459 bfd_vma * buckets = NULL;
10460 bfd_vma * chains = NULL;
fdc90cb4 10461 bfd_vma ngnubuckets = 0;
2cf0635d
NC
10462 bfd_vma * gnubuckets = NULL;
10463 bfd_vma * gnuchains = NULL;
6bd1a22c 10464 bfd_vma gnusymidx = 0;
071436c6 10465 bfd_size_type ngnuchains = 0;
252b5132 10466
2c610e4b 10467 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
10468 return 1;
10469
6bd1a22c
L
10470 if (dynamic_info[DT_HASH]
10471 && (do_histogram
2c610e4b
L
10472 || (do_using_dynamic
10473 && !do_dyn_syms
10474 && dynamic_strings != NULL)))
252b5132 10475 {
66543521
AM
10476 unsigned char nb[8];
10477 unsigned char nc[8];
8b73c356 10478 unsigned int hash_ent_size = 4;
66543521
AM
10479
10480 if ((elf_header.e_machine == EM_ALPHA
10481 || elf_header.e_machine == EM_S390
10482 || elf_header.e_machine == EM_S390_OLD)
10483 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
10484 hash_ent_size = 8;
10485
fb52b2f4
NC
10486 if (fseek (file,
10487 (archive_file_offset
10488 + offset_from_vma (file, dynamic_info[DT_HASH],
10489 sizeof nb + sizeof nc)),
d93f0186 10490 SEEK_SET))
252b5132 10491 {
591a748a 10492 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10493 goto no_hash;
252b5132
RH
10494 }
10495
66543521 10496 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
10497 {
10498 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10499 goto no_hash;
252b5132
RH
10500 }
10501
66543521 10502 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
10503 {
10504 error (_("Failed to read in number of chains\n"));
d3a44ec6 10505 goto no_hash;
252b5132
RH
10506 }
10507
66543521
AM
10508 nbuckets = byte_get (nb, hash_ent_size);
10509 nchains = byte_get (nc, hash_ent_size);
252b5132 10510
66543521
AM
10511 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
10512 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 10513
d3a44ec6 10514 no_hash:
252b5132 10515 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
10516 {
10517 if (do_using_dynamic)
10518 return 0;
10519 free (buckets);
10520 free (chains);
10521 buckets = NULL;
10522 chains = NULL;
10523 nbuckets = 0;
10524 nchains = 0;
10525 }
252b5132
RH
10526 }
10527
6bd1a22c
L
10528 if (dynamic_info_DT_GNU_HASH
10529 && (do_histogram
2c610e4b
L
10530 || (do_using_dynamic
10531 && !do_dyn_syms
10532 && dynamic_strings != NULL)))
252b5132 10533 {
6bd1a22c
L
10534 unsigned char nb[16];
10535 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10536 bfd_vma buckets_vma;
10537
10538 if (fseek (file,
10539 (archive_file_offset
10540 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
10541 sizeof nb)),
10542 SEEK_SET))
10543 {
10544 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10545 goto no_gnu_hash;
6bd1a22c 10546 }
252b5132 10547
6bd1a22c
L
10548 if (fread (nb, 16, 1, file) != 1)
10549 {
10550 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10551 goto no_gnu_hash;
6bd1a22c
L
10552 }
10553
10554 ngnubuckets = byte_get (nb, 4);
10555 gnusymidx = byte_get (nb + 4, 4);
10556 bitmaskwords = byte_get (nb + 8, 4);
10557 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 10558 if (is_32bit_elf)
6bd1a22c 10559 buckets_vma += bitmaskwords * 4;
f7a99963 10560 else
6bd1a22c 10561 buckets_vma += bitmaskwords * 8;
252b5132 10562
6bd1a22c
L
10563 if (fseek (file,
10564 (archive_file_offset
10565 + offset_from_vma (file, buckets_vma, 4)),
10566 SEEK_SET))
252b5132 10567 {
6bd1a22c 10568 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10569 goto no_gnu_hash;
6bd1a22c
L
10570 }
10571
10572 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 10573
6bd1a22c 10574 if (gnubuckets == NULL)
d3a44ec6 10575 goto no_gnu_hash;
6bd1a22c
L
10576
10577 for (i = 0; i < ngnubuckets; i++)
10578 if (gnubuckets[i] != 0)
10579 {
10580 if (gnubuckets[i] < gnusymidx)
10581 return 0;
10582
10583 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
10584 maxchain = gnubuckets[i];
10585 }
10586
10587 if (maxchain == 0xffffffff)
d3a44ec6 10588 goto no_gnu_hash;
6bd1a22c
L
10589
10590 maxchain -= gnusymidx;
10591
10592 if (fseek (file,
10593 (archive_file_offset
10594 + offset_from_vma (file, buckets_vma
10595 + 4 * (ngnubuckets + maxchain), 4)),
10596 SEEK_SET))
10597 {
10598 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10599 goto no_gnu_hash;
6bd1a22c
L
10600 }
10601
10602 do
10603 {
10604 if (fread (nb, 4, 1, file) != 1)
252b5132 10605 {
6bd1a22c 10606 error (_("Failed to determine last chain length\n"));
d3a44ec6 10607 goto no_gnu_hash;
6bd1a22c 10608 }
252b5132 10609
6bd1a22c 10610 if (maxchain + 1 == 0)
d3a44ec6 10611 goto no_gnu_hash;
252b5132 10612
6bd1a22c
L
10613 ++maxchain;
10614 }
10615 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 10616
6bd1a22c
L
10617 if (fseek (file,
10618 (archive_file_offset
10619 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
10620 SEEK_SET))
10621 {
10622 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10623 goto no_gnu_hash;
6bd1a22c
L
10624 }
10625
10626 gnuchains = get_dynamic_data (file, maxchain, 4);
071436c6 10627 ngnuchains = maxchain;
6bd1a22c 10628
d3a44ec6 10629 no_gnu_hash:
6bd1a22c 10630 if (gnuchains == NULL)
d3a44ec6
JJ
10631 {
10632 free (gnubuckets);
d3a44ec6
JJ
10633 gnubuckets = NULL;
10634 ngnubuckets = 0;
f64fddf1
NC
10635 if (do_using_dynamic)
10636 return 0;
d3a44ec6 10637 }
6bd1a22c
L
10638 }
10639
10640 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
10641 && do_syms
10642 && do_using_dynamic
3102e897
NC
10643 && dynamic_strings != NULL
10644 && dynamic_symbols != NULL)
6bd1a22c
L
10645 {
10646 unsigned long hn;
10647
10648 if (dynamic_info[DT_HASH])
10649 {
10650 bfd_vma si;
10651
10652 printf (_("\nSymbol table for image:\n"));
10653 if (is_32bit_elf)
10654 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10655 else
10656 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10657
10658 for (hn = 0; hn < nbuckets; hn++)
10659 {
10660 if (! buckets[hn])
10661 continue;
10662
10663 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
10664 print_dynamic_symbol (si, hn);
252b5132
RH
10665 }
10666 }
6bd1a22c
L
10667
10668 if (dynamic_info_DT_GNU_HASH)
10669 {
10670 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
10671 if (is_32bit_elf)
10672 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10673 else
10674 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10675
10676 for (hn = 0; hn < ngnubuckets; ++hn)
10677 if (gnubuckets[hn] != 0)
10678 {
10679 bfd_vma si = gnubuckets[hn];
10680 bfd_vma off = si - gnusymidx;
10681
10682 do
10683 {
10684 print_dynamic_symbol (si, hn);
10685 si++;
10686 }
071436c6 10687 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
10688 }
10689 }
252b5132 10690 }
8b73c356
NC
10691 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
10692 && section_headers != NULL)
252b5132 10693 {
b34976b6 10694 unsigned int i;
252b5132
RH
10695
10696 for (i = 0, section = section_headers;
10697 i < elf_header.e_shnum;
10698 i++, section++)
10699 {
b34976b6 10700 unsigned int si;
2cf0635d 10701 char * strtab = NULL;
c256ffe7 10702 unsigned long int strtab_size = 0;
2cf0635d
NC
10703 Elf_Internal_Sym * symtab;
10704 Elf_Internal_Sym * psym;
ba5cdace 10705 unsigned long num_syms;
252b5132 10706
2c610e4b
L
10707 if ((section->sh_type != SHT_SYMTAB
10708 && section->sh_type != SHT_DYNSYM)
10709 || (!do_syms
10710 && section->sh_type == SHT_SYMTAB))
252b5132
RH
10711 continue;
10712
dd24e3da
NC
10713 if (section->sh_entsize == 0)
10714 {
10715 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
74e1a04b 10716 printable_section_name (section));
dd24e3da
NC
10717 continue;
10718 }
10719
252b5132 10720 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
74e1a04b 10721 printable_section_name (section),
252b5132 10722 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 10723
f7a99963 10724 if (is_32bit_elf)
ca47b30c 10725 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 10726 else
ca47b30c 10727 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 10728
ba5cdace 10729 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
10730 if (symtab == NULL)
10731 continue;
10732
10733 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
10734 {
10735 strtab = string_table;
10736 strtab_size = string_table_length;
10737 }
4fbb74a6 10738 else if (section->sh_link < elf_header.e_shnum)
252b5132 10739 {
2cf0635d 10740 Elf_Internal_Shdr * string_sec;
252b5132 10741
4fbb74a6 10742 string_sec = section_headers + section->sh_link;
252b5132 10743
3f5e193b
NC
10744 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
10745 1, string_sec->sh_size,
10746 _("string table"));
c256ffe7 10747 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
10748 }
10749
ba5cdace 10750 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 10751 {
bb4d2ac2
L
10752 const char *version_string;
10753 enum versioned_symbol_info sym_info;
10754 unsigned short vna_other;
10755
5e220199 10756 printf ("%6d: ", si);
f7a99963
NC
10757 print_vma (psym->st_value, LONG_HEX);
10758 putchar (' ');
10759 print_vma (psym->st_size, DEC_5);
d1133906
NC
10760 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10761 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 10762 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
10763 /* Check to see if any other bits in the st_other field are set.
10764 Note - displaying this information disrupts the layout of the
10765 table being generated, but for the moment this case is very rare. */
10766 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10767 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 10768 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 10769 print_symbol (25, psym->st_name < strtab_size
2b692964 10770 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 10771
bb4d2ac2
L
10772 version_string
10773 = get_symbol_version_string (file,
10774 section->sh_type == SHT_DYNSYM,
10775 strtab, strtab_size, si,
10776 psym, &sym_info, &vna_other);
10777 if (version_string)
252b5132 10778 {
bb4d2ac2
L
10779 if (sym_info == symbol_undefined)
10780 printf ("@%s (%d)", version_string, vna_other);
10781 else
10782 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
10783 version_string);
252b5132
RH
10784 }
10785
10786 putchar ('\n');
10787 }
10788
10789 free (symtab);
10790 if (strtab != string_table)
10791 free (strtab);
10792 }
10793 }
10794 else if (do_syms)
10795 printf
10796 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10797
10798 if (do_histogram && buckets != NULL)
10799 {
2cf0635d
NC
10800 unsigned long * lengths;
10801 unsigned long * counts;
66543521
AM
10802 unsigned long hn;
10803 bfd_vma si;
10804 unsigned long maxlength = 0;
10805 unsigned long nzero_counts = 0;
10806 unsigned long nsyms = 0;
94d15024 10807 unsigned long chained;
252b5132 10808
66543521
AM
10809 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10810 (unsigned long) nbuckets);
252b5132 10811
3f5e193b 10812 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10813 if (lengths == NULL)
10814 {
8b73c356 10815 error (_("Out of memory allocating space for histogram buckets\n"));
252b5132
RH
10816 return 0;
10817 }
8b73c356
NC
10818
10819 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
10820 for (hn = 0; hn < nbuckets; ++hn)
10821 {
94d15024
MF
10822 for (si = buckets[hn], chained = 0;
10823 si > 0 && si < nchains && si < nbuckets && chained <= nchains;
10824 si = chains[si], ++chained)
252b5132 10825 {
b34976b6 10826 ++nsyms;
252b5132 10827 if (maxlength < ++lengths[hn])
b34976b6 10828 ++maxlength;
252b5132 10829 }
94d15024
MF
10830
10831 /* PR binutils/17531: A corrupt binary could contain broken
10832 histogram data. Do not go into an infinite loop trying
10833 to process it. */
10834 if (chained > nchains)
10835 {
10836 error (_("histogram chain is corrupt\n"));
10837 break;
10838 }
252b5132
RH
10839 }
10840
3f5e193b 10841 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
10842 if (counts == NULL)
10843 {
b2e951ec 10844 free (lengths);
8b73c356 10845 error (_("Out of memory allocating space for histogram counts\n"));
252b5132
RH
10846 return 0;
10847 }
10848
10849 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 10850 ++counts[lengths[hn]];
252b5132 10851
103f02d3 10852 if (nbuckets > 0)
252b5132 10853 {
66543521
AM
10854 unsigned long i;
10855 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 10856 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 10857 for (i = 1; i <= maxlength; ++i)
103f02d3 10858 {
66543521
AM
10859 nzero_counts += counts[i] * i;
10860 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10861 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
10862 (nzero_counts * 100.0) / nsyms);
10863 }
252b5132
RH
10864 }
10865
10866 free (counts);
10867 free (lengths);
10868 }
10869
10870 if (buckets != NULL)
10871 {
10872 free (buckets);
10873 free (chains);
10874 }
10875
d3a44ec6 10876 if (do_histogram && gnubuckets != NULL)
fdc90cb4 10877 {
2cf0635d
NC
10878 unsigned long * lengths;
10879 unsigned long * counts;
fdc90cb4
JJ
10880 unsigned long hn;
10881 unsigned long maxlength = 0;
10882 unsigned long nzero_counts = 0;
10883 unsigned long nsyms = 0;
fdc90cb4 10884
8b73c356
NC
10885 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
10886 (unsigned long) ngnubuckets);
10887
3f5e193b 10888 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
10889 if (lengths == NULL)
10890 {
8b73c356 10891 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fdc90cb4
JJ
10892 return 0;
10893 }
10894
fdc90cb4
JJ
10895 printf (_(" Length Number %% of total Coverage\n"));
10896
10897 for (hn = 0; hn < ngnubuckets; ++hn)
10898 if (gnubuckets[hn] != 0)
10899 {
10900 bfd_vma off, length = 1;
10901
6bd1a22c 10902 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
10903 /* PR 17531 file: 010-77222-0.004. */
10904 off < ngnuchains && (gnuchains[off] & 1) == 0;
10905 ++off)
fdc90cb4
JJ
10906 ++length;
10907 lengths[hn] = length;
10908 if (length > maxlength)
10909 maxlength = length;
10910 nsyms += length;
10911 }
10912
3f5e193b 10913 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
10914 if (counts == NULL)
10915 {
b2e951ec 10916 free (lengths);
8b73c356 10917 error (_("Out of memory allocating space for gnu histogram counts\n"));
fdc90cb4
JJ
10918 return 0;
10919 }
10920
10921 for (hn = 0; hn < ngnubuckets; ++hn)
10922 ++counts[lengths[hn]];
10923
10924 if (ngnubuckets > 0)
10925 {
10926 unsigned long j;
10927 printf (" 0 %-10lu (%5.1f%%)\n",
10928 counts[0], (counts[0] * 100.0) / ngnubuckets);
10929 for (j = 1; j <= maxlength; ++j)
10930 {
10931 nzero_counts += counts[j] * j;
10932 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10933 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
10934 (nzero_counts * 100.0) / nsyms);
10935 }
10936 }
10937
10938 free (counts);
10939 free (lengths);
10940 free (gnubuckets);
10941 free (gnuchains);
10942 }
10943
252b5132
RH
10944 return 1;
10945}
10946
10947static int
2cf0635d 10948process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 10949{
b4c96d0d 10950 unsigned int i;
252b5132
RH
10951
10952 if (dynamic_syminfo == NULL
10953 || !do_dynamic)
10954 /* No syminfo, this is ok. */
10955 return 1;
10956
10957 /* There better should be a dynamic symbol section. */
10958 if (dynamic_symbols == NULL || dynamic_strings == NULL)
10959 return 0;
10960
10961 if (dynamic_addr)
10962 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10963 dynamic_syminfo_offset, dynamic_syminfo_nent);
10964
10965 printf (_(" Num: Name BoundTo Flags\n"));
10966 for (i = 0; i < dynamic_syminfo_nent; ++i)
10967 {
10968 unsigned short int flags = dynamic_syminfo[i].si_flags;
10969
31104126 10970 printf ("%4d: ", i);
4082ef84
NC
10971 if (i >= num_dynamic_syms)
10972 printf (_("<corrupt index>"));
10973 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
10974 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10975 else
2b692964 10976 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10977 putchar (' ');
252b5132
RH
10978
10979 switch (dynamic_syminfo[i].si_boundto)
10980 {
10981 case SYMINFO_BT_SELF:
10982 fputs ("SELF ", stdout);
10983 break;
10984 case SYMINFO_BT_PARENT:
10985 fputs ("PARENT ", stdout);
10986 break;
10987 default:
10988 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10989 && dynamic_syminfo[i].si_boundto < dynamic_nent
10990 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10991 {
d79b3d50 10992 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10993 putchar (' ' );
10994 }
252b5132
RH
10995 else
10996 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10997 break;
10998 }
10999
11000 if (flags & SYMINFO_FLG_DIRECT)
11001 printf (" DIRECT");
11002 if (flags & SYMINFO_FLG_PASSTHRU)
11003 printf (" PASSTHRU");
11004 if (flags & SYMINFO_FLG_COPY)
11005 printf (" COPY");
11006 if (flags & SYMINFO_FLG_LAZYLOAD)
11007 printf (" LAZYLOAD");
11008
11009 puts ("");
11010 }
11011
11012 return 1;
11013}
11014
cf13d699
NC
11015/* Check to see if the given reloc needs to be handled in a target specific
11016 manner. If so then process the reloc and return TRUE otherwise return
11017 FALSE. */
09c11c86 11018
cf13d699
NC
11019static bfd_boolean
11020target_specific_reloc_handling (Elf_Internal_Rela * reloc,
11021 unsigned char * start,
11022 Elf_Internal_Sym * symtab)
252b5132 11023{
cf13d699 11024 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 11025
cf13d699 11026 switch (elf_header.e_machine)
252b5132 11027 {
13761a11
NC
11028 case EM_MSP430:
11029 case EM_MSP430_OLD:
11030 {
11031 static Elf_Internal_Sym * saved_sym = NULL;
11032
11033 switch (reloc_type)
11034 {
11035 case 10: /* R_MSP430_SYM_DIFF */
11036 if (uses_msp430x_relocs ())
11037 break;
11038 case 21: /* R_MSP430X_SYM_DIFF */
11039 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
11040 return TRUE;
11041
11042 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
11043 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
11044 goto handle_sym_diff;
0b4362b0 11045
13761a11
NC
11046 case 5: /* R_MSP430_16_BYTE */
11047 case 9: /* R_MSP430_8 */
11048 if (uses_msp430x_relocs ())
11049 break;
11050 goto handle_sym_diff;
11051
11052 case 2: /* R_MSP430_ABS16 */
11053 case 15: /* R_MSP430X_ABS16 */
11054 if (! uses_msp430x_relocs ())
11055 break;
11056 goto handle_sym_diff;
0b4362b0 11057
13761a11
NC
11058 handle_sym_diff:
11059 if (saved_sym != NULL)
11060 {
11061 bfd_vma value;
11062
11063 value = reloc->r_addend
11064 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
11065 - saved_sym->st_value);
11066
11067 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
11068
11069 saved_sym = NULL;
11070 return TRUE;
11071 }
11072 break;
11073
11074 default:
11075 if (saved_sym != NULL)
071436c6 11076 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
11077 break;
11078 }
11079 break;
11080 }
11081
cf13d699
NC
11082 case EM_MN10300:
11083 case EM_CYGNUS_MN10300:
11084 {
11085 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 11086
cf13d699
NC
11087 switch (reloc_type)
11088 {
11089 case 34: /* R_MN10300_ALIGN */
11090 return TRUE;
11091 case 33: /* R_MN10300_SYM_DIFF */
11092 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
11093 return TRUE;
11094 case 1: /* R_MN10300_32 */
11095 case 2: /* R_MN10300_16 */
11096 if (saved_sym != NULL)
11097 {
11098 bfd_vma value;
252b5132 11099
cf13d699
NC
11100 value = reloc->r_addend
11101 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
11102 - saved_sym->st_value);
252b5132 11103
cf13d699 11104 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 11105
cf13d699
NC
11106 saved_sym = NULL;
11107 return TRUE;
11108 }
11109 break;
11110 default:
11111 if (saved_sym != NULL)
071436c6 11112 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
11113 break;
11114 }
11115 break;
11116 }
252b5132
RH
11117 }
11118
cf13d699 11119 return FALSE;
252b5132
RH
11120}
11121
aca88567
NC
11122/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
11123 DWARF debug sections. This is a target specific test. Note - we do not
11124 go through the whole including-target-headers-multiple-times route, (as
11125 we have already done with <elf/h8.h>) because this would become very
11126 messy and even then this function would have to contain target specific
11127 information (the names of the relocs instead of their numeric values).
11128 FIXME: This is not the correct way to solve this problem. The proper way
11129 is to have target specific reloc sizing and typing functions created by
11130 the reloc-macros.h header, in the same way that it already creates the
11131 reloc naming functions. */
11132
11133static bfd_boolean
11134is_32bit_abs_reloc (unsigned int reloc_type)
11135{
11136 switch (elf_header.e_machine)
11137 {
41e92641
NC
11138 case EM_386:
11139 case EM_486:
11140 return reloc_type == 1; /* R_386_32. */
aca88567
NC
11141 case EM_68K:
11142 return reloc_type == 1; /* R_68K_32. */
11143 case EM_860:
11144 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
11145 case EM_960:
11146 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
11147 case EM_AARCH64:
11148 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 11149 case EM_ALPHA:
137b6b5f 11150 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
11151 case EM_ARC:
11152 return reloc_type == 1; /* R_ARC_32. */
11153 case EM_ARM:
11154 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 11155 case EM_AVR_OLD:
aca88567
NC
11156 case EM_AVR:
11157 return reloc_type == 1;
cfb8c092
NC
11158 case EM_ADAPTEVA_EPIPHANY:
11159 return reloc_type == 3;
aca88567
NC
11160 case EM_BLACKFIN:
11161 return reloc_type == 0x12; /* R_byte4_data. */
11162 case EM_CRIS:
11163 return reloc_type == 3; /* R_CRIS_32. */
11164 case EM_CR16:
11165 return reloc_type == 3; /* R_CR16_NUM32. */
11166 case EM_CRX:
11167 return reloc_type == 15; /* R_CRX_NUM32. */
11168 case EM_CYGNUS_FRV:
11169 return reloc_type == 1;
41e92641
NC
11170 case EM_CYGNUS_D10V:
11171 case EM_D10V:
11172 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
11173 case EM_CYGNUS_D30V:
11174 case EM_D30V:
11175 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
11176 case EM_DLX:
11177 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
11178 case EM_CYGNUS_FR30:
11179 case EM_FR30:
11180 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
11181 case EM_FT32:
11182 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
11183 case EM_H8S:
11184 case EM_H8_300:
11185 case EM_H8_300H:
11186 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
11187 case EM_IA_64:
11188 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
11189 case EM_IP2K_OLD:
11190 case EM_IP2K:
11191 return reloc_type == 2; /* R_IP2K_32. */
11192 case EM_IQ2000:
11193 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
11194 case EM_LATTICEMICO32:
11195 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 11196 case EM_M32C_OLD:
aca88567
NC
11197 case EM_M32C:
11198 return reloc_type == 3; /* R_M32C_32. */
11199 case EM_M32R:
11200 return reloc_type == 34; /* R_M32R_32_RELA. */
11201 case EM_MCORE:
11202 return reloc_type == 1; /* R_MCORE_ADDR32. */
11203 case EM_CYGNUS_MEP:
11204 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
11205 case EM_METAG:
11206 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
11207 case EM_MICROBLAZE:
11208 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
11209 case EM_MIPS:
11210 return reloc_type == 2; /* R_MIPS_32. */
11211 case EM_MMIX:
11212 return reloc_type == 4; /* R_MMIX_32. */
11213 case EM_CYGNUS_MN10200:
11214 case EM_MN10200:
11215 return reloc_type == 1; /* R_MN10200_32. */
11216 case EM_CYGNUS_MN10300:
11217 case EM_MN10300:
11218 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
11219 case EM_MOXIE:
11220 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
11221 case EM_MSP430_OLD:
11222 case EM_MSP430:
13761a11 11223 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
11224 case EM_MT:
11225 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
11226 case EM_NDS32:
11227 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 11228 case EM_ALTERA_NIOS2:
36591ba1 11229 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
11230 case EM_NIOS32:
11231 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
11232 case EM_OR1K:
11233 return reloc_type == 1; /* R_OR1K_32. */
aca88567 11234 case EM_PARISC:
5fda8eca
NC
11235 return (reloc_type == 1 /* R_PARISC_DIR32. */
11236 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
11237 case EM_PJ:
11238 case EM_PJ_OLD:
11239 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
11240 case EM_PPC64:
11241 return reloc_type == 1; /* R_PPC64_ADDR32. */
11242 case EM_PPC:
11243 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
11244 case EM_RL78:
11245 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
11246 case EM_RX:
11247 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
11248 case EM_S370:
11249 return reloc_type == 1; /* R_I370_ADDR31. */
11250 case EM_S390_OLD:
11251 case EM_S390:
11252 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
11253 case EM_SCORE:
11254 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
11255 case EM_SH:
11256 return reloc_type == 1; /* R_SH_DIR32. */
11257 case EM_SPARC32PLUS:
11258 case EM_SPARCV9:
11259 case EM_SPARC:
11260 return reloc_type == 3 /* R_SPARC_32. */
11261 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
11262 case EM_SPU:
11263 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
11264 case EM_TI_C6000:
11265 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
11266 case EM_TILEGX:
11267 return reloc_type == 2; /* R_TILEGX_32. */
11268 case EM_TILEPRO:
11269 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
11270 case EM_CYGNUS_V850:
11271 case EM_V850:
11272 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
11273 case EM_V800:
11274 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
11275 case EM_VAX:
11276 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
11277 case EM_VISIUM:
11278 return reloc_type == 3; /* R_VISIUM_32. */
aca88567 11279 case EM_X86_64:
8a9036a4 11280 case EM_L1OM:
7a9068fe 11281 case EM_K1OM:
aca88567 11282 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
11283 case EM_XC16X:
11284 case EM_C166:
11285 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
11286 case EM_XGATE:
11287 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
11288 case EM_XSTORMY16:
11289 return reloc_type == 1; /* R_XSTROMY16_32. */
11290 case EM_XTENSA_OLD:
11291 case EM_XTENSA:
11292 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 11293 default:
bee0ee85
NC
11294 {
11295 static unsigned int prev_warn = 0;
11296
11297 /* Avoid repeating the same warning multiple times. */
11298 if (prev_warn != elf_header.e_machine)
11299 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
11300 elf_header.e_machine);
11301 prev_warn = elf_header.e_machine;
11302 return FALSE;
11303 }
aca88567
NC
11304 }
11305}
11306
11307/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11308 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
11309
11310static bfd_boolean
11311is_32bit_pcrel_reloc (unsigned int reloc_type)
11312{
11313 switch (elf_header.e_machine)
11314 {
41e92641
NC
11315 case EM_386:
11316 case EM_486:
3e0873ac 11317 return reloc_type == 2; /* R_386_PC32. */
aca88567 11318 case EM_68K:
3e0873ac 11319 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
11320 case EM_AARCH64:
11321 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
11322 case EM_ADAPTEVA_EPIPHANY:
11323 return reloc_type == 6;
aca88567
NC
11324 case EM_ALPHA:
11325 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 11326 case EM_ARM:
3e0873ac 11327 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
11328 case EM_MICROBLAZE:
11329 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
11330 case EM_OR1K:
11331 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 11332 case EM_PARISC:
85acf597 11333 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
11334 case EM_PPC:
11335 return reloc_type == 26; /* R_PPC_REL32. */
11336 case EM_PPC64:
3e0873ac 11337 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
11338 case EM_S390_OLD:
11339 case EM_S390:
3e0873ac 11340 return reloc_type == 5; /* R_390_PC32. */
aca88567 11341 case EM_SH:
3e0873ac 11342 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
11343 case EM_SPARC32PLUS:
11344 case EM_SPARCV9:
11345 case EM_SPARC:
3e0873ac 11346 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
11347 case EM_SPU:
11348 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
11349 case EM_TILEGX:
11350 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
11351 case EM_TILEPRO:
11352 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
11353 case EM_VISIUM:
11354 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 11355 case EM_X86_64:
8a9036a4 11356 case EM_L1OM:
7a9068fe 11357 case EM_K1OM:
3e0873ac 11358 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
11359 case EM_XTENSA_OLD:
11360 case EM_XTENSA:
11361 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
11362 default:
11363 /* Do not abort or issue an error message here. Not all targets use
11364 pc-relative 32-bit relocs in their DWARF debug information and we
11365 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
11366 more helpful warning message will be generated by apply_relocations
11367 anyway, so just return. */
aca88567
NC
11368 return FALSE;
11369 }
11370}
11371
11372/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11373 a 64-bit absolute RELA relocation used in DWARF debug sections. */
11374
11375static bfd_boolean
11376is_64bit_abs_reloc (unsigned int reloc_type)
11377{
11378 switch (elf_header.e_machine)
11379 {
a06ea964
NC
11380 case EM_AARCH64:
11381 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
11382 case EM_ALPHA:
11383 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
11384 case EM_IA_64:
11385 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
11386 case EM_PARISC:
11387 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
11388 case EM_PPC64:
11389 return reloc_type == 38; /* R_PPC64_ADDR64. */
11390 case EM_SPARC32PLUS:
11391 case EM_SPARCV9:
11392 case EM_SPARC:
11393 return reloc_type == 54; /* R_SPARC_UA64. */
11394 case EM_X86_64:
8a9036a4 11395 case EM_L1OM:
7a9068fe 11396 case EM_K1OM:
aca88567 11397 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
11398 case EM_S390_OLD:
11399 case EM_S390:
aa137e4d
NC
11400 return reloc_type == 22; /* R_S390_64. */
11401 case EM_TILEGX:
11402 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 11403 case EM_MIPS:
aa137e4d 11404 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
11405 default:
11406 return FALSE;
11407 }
11408}
11409
85acf597
RH
11410/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
11411 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
11412
11413static bfd_boolean
11414is_64bit_pcrel_reloc (unsigned int reloc_type)
11415{
11416 switch (elf_header.e_machine)
11417 {
a06ea964
NC
11418 case EM_AARCH64:
11419 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 11420 case EM_ALPHA:
aa137e4d 11421 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 11422 case EM_IA_64:
aa137e4d 11423 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 11424 case EM_PARISC:
aa137e4d 11425 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 11426 case EM_PPC64:
aa137e4d 11427 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
11428 case EM_SPARC32PLUS:
11429 case EM_SPARCV9:
11430 case EM_SPARC:
aa137e4d 11431 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 11432 case EM_X86_64:
8a9036a4 11433 case EM_L1OM:
7a9068fe 11434 case EM_K1OM:
aa137e4d 11435 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
11436 case EM_S390_OLD:
11437 case EM_S390:
aa137e4d
NC
11438 return reloc_type == 23; /* R_S390_PC64. */
11439 case EM_TILEGX:
11440 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
11441 default:
11442 return FALSE;
11443 }
11444}
11445
4dc3c23d
AM
11446/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11447 a 24-bit absolute RELA relocation used in DWARF debug sections. */
11448
11449static bfd_boolean
11450is_24bit_abs_reloc (unsigned int reloc_type)
11451{
11452 switch (elf_header.e_machine)
11453 {
11454 case EM_CYGNUS_MN10200:
11455 case EM_MN10200:
11456 return reloc_type == 4; /* R_MN10200_24. */
11457 default:
11458 return FALSE;
11459 }
11460}
11461
aca88567
NC
11462/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11463 a 16-bit absolute RELA relocation used in DWARF debug sections. */
11464
11465static bfd_boolean
11466is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
11467{
11468 switch (elf_header.e_machine)
11469 {
aca88567
NC
11470 case EM_AVR_OLD:
11471 case EM_AVR:
11472 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
11473 case EM_ADAPTEVA_EPIPHANY:
11474 return reloc_type == 5;
41e92641
NC
11475 case EM_CYGNUS_D10V:
11476 case EM_D10V:
11477 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
11478 case EM_H8S:
11479 case EM_H8_300:
11480 case EM_H8_300H:
aca88567
NC
11481 return reloc_type == R_H8_DIR16;
11482 case EM_IP2K_OLD:
11483 case EM_IP2K:
11484 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 11485 case EM_M32C_OLD:
f4236fe4
DD
11486 case EM_M32C:
11487 return reloc_type == 1; /* R_M32C_16 */
aca88567 11488 case EM_MSP430:
13761a11
NC
11489 if (uses_msp430x_relocs ())
11490 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 11491 case EM_MSP430_OLD:
aca88567 11492 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
11493 case EM_NDS32:
11494 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 11495 case EM_ALTERA_NIOS2:
36591ba1 11496 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
11497 case EM_NIOS32:
11498 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
11499 case EM_OR1K:
11500 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
11501 case EM_TI_C6000:
11502 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
11503 case EM_XC16X:
11504 case EM_C166:
11505 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
11506 case EM_CYGNUS_MN10200:
11507 case EM_MN10200:
11508 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
11509 case EM_CYGNUS_MN10300:
11510 case EM_MN10300:
11511 return reloc_type == 2; /* R_MN10300_16. */
619ed720
EB
11512 case EM_VISIUM:
11513 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
11514 case EM_XGATE:
11515 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 11516 default:
aca88567 11517 return FALSE;
4b78141a
NC
11518 }
11519}
11520
2a7b2e88
JK
11521/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
11522 relocation entries (possibly formerly used for SHT_GROUP sections). */
11523
11524static bfd_boolean
11525is_none_reloc (unsigned int reloc_type)
11526{
11527 switch (elf_header.e_machine)
11528 {
cb8f3167
NC
11529 case EM_68K: /* R_68K_NONE. */
11530 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
11531 case EM_SPARC32PLUS:
11532 case EM_SPARCV9:
cb8f3167
NC
11533 case EM_SPARC: /* R_SPARC_NONE. */
11534 case EM_MIPS: /* R_MIPS_NONE. */
11535 case EM_PARISC: /* R_PARISC_NONE. */
11536 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 11537 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
11538 case EM_PPC: /* R_PPC_NONE. */
11539 case EM_PPC64: /* R_PPC64_NONE. */
11540 case EM_ARM: /* R_ARM_NONE. */
11541 case EM_IA_64: /* R_IA64_NONE. */
11542 case EM_SH: /* R_SH_NONE. */
2a7b2e88 11543 case EM_S390_OLD:
cb8f3167
NC
11544 case EM_S390: /* R_390_NONE. */
11545 case EM_CRIS: /* R_CRIS_NONE. */
11546 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 11547 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 11548 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 11549 case EM_MN10300: /* R_MN10300_NONE. */
3f8107ab 11550 case EM_FT32: /* R_FT32_NONE. */
5506d11a 11551 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 11552 case EM_M32R: /* R_M32R_NONE. */
40b36596 11553 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
11554 case EM_TILEGX: /* R_TILEGX_NONE. */
11555 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
11556 case EM_XC16X:
11557 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
11558 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
11559 case EM_NIOS32: /* R_NIOS_NONE. */
73589c9d 11560 case EM_OR1K: /* R_OR1K_NONE. */
cb8f3167 11561 return reloc_type == 0;
a06ea964
NC
11562 case EM_AARCH64:
11563 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
11564 case EM_NDS32:
11565 return (reloc_type == 0 /* R_XTENSA_NONE. */
11566 || reloc_type == 204 /* R_NDS32_DIFF8. */
11567 || reloc_type == 205 /* R_NDS32_DIFF16. */
11568 || reloc_type == 206 /* R_NDS32_DIFF32. */
11569 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
11570 case EM_XTENSA_OLD:
11571 case EM_XTENSA:
4dc3c23d
AM
11572 return (reloc_type == 0 /* R_XTENSA_NONE. */
11573 || reloc_type == 17 /* R_XTENSA_DIFF8. */
11574 || reloc_type == 18 /* R_XTENSA_DIFF16. */
11575 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
11576 case EM_METAG:
11577 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
11578 }
11579 return FALSE;
11580}
11581
cf13d699
NC
11582/* Apply relocations to a section.
11583 Note: So far support has been added only for those relocations
11584 which can be found in debug sections.
11585 FIXME: Add support for more relocations ? */
1b315056 11586
cf13d699
NC
11587static void
11588apply_relocations (void * file,
11589 Elf_Internal_Shdr * section,
11590 unsigned char * start)
1b315056 11591{
cf13d699
NC
11592 Elf_Internal_Shdr * relsec;
11593 unsigned char * end = start + section->sh_size;
cb8f3167 11594
cf13d699
NC
11595 if (elf_header.e_type != ET_REL)
11596 return;
1b315056 11597
cf13d699 11598 /* Find the reloc section associated with the section. */
5b18a4bc
NC
11599 for (relsec = section_headers;
11600 relsec < section_headers + elf_header.e_shnum;
11601 ++relsec)
252b5132 11602 {
41e92641
NC
11603 bfd_boolean is_rela;
11604 unsigned long num_relocs;
2cf0635d
NC
11605 Elf_Internal_Rela * relocs;
11606 Elf_Internal_Rela * rp;
11607 Elf_Internal_Shdr * symsec;
11608 Elf_Internal_Sym * symtab;
ba5cdace 11609 unsigned long num_syms;
2cf0635d 11610 Elf_Internal_Sym * sym;
252b5132 11611
41e92641 11612 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
11613 || relsec->sh_info >= elf_header.e_shnum
11614 || section_headers + relsec->sh_info != section
c256ffe7 11615 || relsec->sh_size == 0
4fbb74a6 11616 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 11617 continue;
428409d5 11618
41e92641
NC
11619 is_rela = relsec->sh_type == SHT_RELA;
11620
11621 if (is_rela)
11622 {
3f5e193b
NC
11623 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
11624 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11625 return;
11626 }
11627 else
11628 {
3f5e193b
NC
11629 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
11630 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11631 return;
11632 }
11633
11634 /* SH uses RELA but uses in place value instead of the addend field. */
11635 if (elf_header.e_machine == EM_SH)
11636 is_rela = FALSE;
428409d5 11637
4fbb74a6 11638 symsec = section_headers + relsec->sh_link;
ba5cdace 11639 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 11640
41e92641 11641 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 11642 {
41e92641
NC
11643 bfd_vma addend;
11644 unsigned int reloc_type;
11645 unsigned int reloc_size;
91d6fa6a 11646 unsigned char * rloc;
ba5cdace 11647 unsigned long sym_index;
4b78141a 11648
aca88567 11649 reloc_type = get_reloc_type (rp->r_info);
41e92641 11650
98fb390a 11651 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 11652 continue;
98fb390a
NC
11653 else if (is_none_reloc (reloc_type))
11654 continue;
11655 else if (is_32bit_abs_reloc (reloc_type)
11656 || is_32bit_pcrel_reloc (reloc_type))
aca88567 11657 reloc_size = 4;
85acf597
RH
11658 else if (is_64bit_abs_reloc (reloc_type)
11659 || is_64bit_pcrel_reloc (reloc_type))
aca88567 11660 reloc_size = 8;
4dc3c23d
AM
11661 else if (is_24bit_abs_reloc (reloc_type))
11662 reloc_size = 3;
aca88567
NC
11663 else if (is_16bit_abs_reloc (reloc_type))
11664 reloc_size = 2;
11665 else
4b78141a 11666 {
bee0ee85
NC
11667 static unsigned int prev_reloc = 0;
11668 if (reloc_type != prev_reloc)
11669 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
11670 reloc_type, printable_section_name (section));
11671 prev_reloc = reloc_type;
4b78141a
NC
11672 continue;
11673 }
103f02d3 11674
91d6fa6a 11675 rloc = start + rp->r_offset;
c8da6823 11676 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
11677 {
11678 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
11679 (unsigned long) rp->r_offset,
74e1a04b 11680 printable_section_name (section));
700dd8b7
L
11681 continue;
11682 }
103f02d3 11683
ba5cdace
NC
11684 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
11685 if (sym_index >= num_syms)
11686 {
11687 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
74e1a04b 11688 sym_index, printable_section_name (section));
ba5cdace
NC
11689 continue;
11690 }
11691 sym = symtab + sym_index;
41e92641
NC
11692
11693 /* If the reloc has a symbol associated with it,
55f25fc3
L
11694 make sure that it is of an appropriate type.
11695
11696 Relocations against symbols without type can happen.
11697 Gcc -feliminate-dwarf2-dups may generate symbols
11698 without type for debug info.
11699
11700 Icc generates relocations against function symbols
11701 instead of local labels.
11702
11703 Relocations against object symbols can happen, eg when
11704 referencing a global array. For an example of this see
11705 the _clz.o binary in libgcc.a. */
aca88567 11706 if (sym != symtab
55f25fc3 11707 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 11708 {
41e92641 11709 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 11710 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 11711 (long int)(rp - relocs),
74e1a04b 11712 printable_section_name (relsec));
aca88567 11713 continue;
5b18a4bc 11714 }
252b5132 11715
4dc3c23d
AM
11716 addend = 0;
11717 if (is_rela)
11718 addend += rp->r_addend;
c47320c3
AM
11719 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
11720 partial_inplace. */
4dc3c23d
AM
11721 if (!is_rela
11722 || (elf_header.e_machine == EM_XTENSA
11723 && reloc_type == 1)
11724 || ((elf_header.e_machine == EM_PJ
11725 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
11726 && reloc_type == 1)
11727 || ((elf_header.e_machine == EM_D30V
11728 || elf_header.e_machine == EM_CYGNUS_D30V)
11729 && reloc_type == 12))
91d6fa6a 11730 addend += byte_get (rloc, reloc_size);
cb8f3167 11731
85acf597
RH
11732 if (is_32bit_pcrel_reloc (reloc_type)
11733 || is_64bit_pcrel_reloc (reloc_type))
11734 {
11735 /* On HPPA, all pc-relative relocations are biased by 8. */
11736 if (elf_header.e_machine == EM_PARISC)
11737 addend -= 8;
91d6fa6a 11738 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
11739 reloc_size);
11740 }
41e92641 11741 else
91d6fa6a 11742 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 11743 }
252b5132 11744
5b18a4bc 11745 free (symtab);
41e92641 11746 free (relocs);
5b18a4bc
NC
11747 break;
11748 }
5b18a4bc 11749}
103f02d3 11750
cf13d699
NC
11751#ifdef SUPPORT_DISASSEMBLY
11752static int
11753disassemble_section (Elf_Internal_Shdr * section, FILE * file)
11754{
74e1a04b 11755 printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
cf13d699 11756
74e1a04b 11757 /* FIXME: XXX -- to be done --- XXX */
cf13d699
NC
11758
11759 return 1;
11760}
11761#endif
11762
11763/* Reads in the contents of SECTION from FILE, returning a pointer
11764 to a malloc'ed buffer or NULL if something went wrong. */
11765
11766static char *
11767get_section_contents (Elf_Internal_Shdr * section, FILE * file)
11768{
11769 bfd_size_type num_bytes;
11770
11771 num_bytes = section->sh_size;
11772
11773 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
11774 {
11775 printf (_("\nSection '%s' has no data to dump.\n"),
74e1a04b 11776 printable_section_name (section));
cf13d699
NC
11777 return NULL;
11778 }
11779
3f5e193b
NC
11780 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
11781 _("section contents"));
cf13d699
NC
11782}
11783
dd24e3da 11784
cf13d699
NC
11785static void
11786dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
11787{
11788 Elf_Internal_Shdr * relsec;
11789 bfd_size_type num_bytes;
cf13d699
NC
11790 char * data;
11791 char * end;
11792 char * start;
cf13d699
NC
11793 bfd_boolean some_strings_shown;
11794
11795 start = get_section_contents (section, file);
11796 if (start == NULL)
11797 return;
11798
74e1a04b 11799 printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11800
11801 /* If the section being dumped has relocations against it the user might
11802 be expecting these relocations to have been applied. Check for this
11803 case and issue a warning message in order to avoid confusion.
11804 FIXME: Maybe we ought to have an option that dumps a section with
11805 relocs applied ? */
11806 for (relsec = section_headers;
11807 relsec < section_headers + elf_header.e_shnum;
11808 ++relsec)
11809 {
11810 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11811 || relsec->sh_info >= elf_header.e_shnum
11812 || section_headers + relsec->sh_info != section
11813 || relsec->sh_size == 0
11814 || relsec->sh_link >= elf_header.e_shnum)
11815 continue;
11816
11817 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11818 break;
11819 }
11820
11821 num_bytes = section->sh_size;
cf13d699
NC
11822 data = start;
11823 end = start + num_bytes;
11824 some_strings_shown = FALSE;
11825
11826 while (data < end)
11827 {
11828 while (!ISPRINT (* data))
11829 if (++ data >= end)
11830 break;
11831
11832 if (data < end)
11833 {
071436c6
NC
11834 size_t maxlen = end - data;
11835
cf13d699 11836#ifndef __MSVCRT__
c975cc98
NC
11837 /* PR 11128: Use two separate invocations in order to work
11838 around bugs in the Solaris 8 implementation of printf. */
11839 printf (" [%6tx] ", data - start);
cf13d699 11840#else
071436c6 11841 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 11842#endif
4082ef84
NC
11843 if (maxlen > 0)
11844 {
11845 print_symbol ((int) maxlen, data);
11846 putchar ('\n');
11847 data += strnlen (data, maxlen);
11848 }
11849 else
11850 {
11851 printf (_("<corrupt>\n"));
11852 data = end;
11853 }
cf13d699
NC
11854 some_strings_shown = TRUE;
11855 }
11856 }
11857
11858 if (! some_strings_shown)
11859 printf (_(" No strings found in this section."));
11860
11861 free (start);
11862
11863 putchar ('\n');
11864}
11865
11866static void
11867dump_section_as_bytes (Elf_Internal_Shdr * section,
11868 FILE * file,
11869 bfd_boolean relocate)
11870{
11871 Elf_Internal_Shdr * relsec;
11872 bfd_size_type bytes;
11873 bfd_vma addr;
11874 unsigned char * data;
11875 unsigned char * start;
11876
11877 start = (unsigned char *) get_section_contents (section, file);
11878 if (start == NULL)
11879 return;
11880
74e1a04b 11881 printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11882
11883 if (relocate)
11884 {
11885 apply_relocations (file, section, start);
11886 }
11887 else
11888 {
11889 /* If the section being dumped has relocations against it the user might
11890 be expecting these relocations to have been applied. Check for this
11891 case and issue a warning message in order to avoid confusion.
11892 FIXME: Maybe we ought to have an option that dumps a section with
11893 relocs applied ? */
11894 for (relsec = section_headers;
11895 relsec < section_headers + elf_header.e_shnum;
11896 ++relsec)
11897 {
11898 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11899 || relsec->sh_info >= elf_header.e_shnum
11900 || section_headers + relsec->sh_info != section
11901 || relsec->sh_size == 0
11902 || relsec->sh_link >= elf_header.e_shnum)
11903 continue;
11904
11905 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11906 break;
11907 }
11908 }
11909
11910 addr = section->sh_addr;
11911 bytes = section->sh_size;
11912 data = start;
11913
11914 while (bytes)
11915 {
11916 int j;
11917 int k;
11918 int lbytes;
11919
11920 lbytes = (bytes > 16 ? 16 : bytes);
11921
11922 printf (" 0x%8.8lx ", (unsigned long) addr);
11923
11924 for (j = 0; j < 16; j++)
11925 {
11926 if (j < lbytes)
11927 printf ("%2.2x", data[j]);
11928 else
11929 printf (" ");
11930
11931 if ((j & 3) == 3)
11932 printf (" ");
11933 }
11934
11935 for (j = 0; j < lbytes; j++)
11936 {
11937 k = data[j];
11938 if (k >= ' ' && k < 0x7f)
11939 printf ("%c", k);
11940 else
11941 printf (".");
11942 }
11943
11944 putchar ('\n');
11945
11946 data += lbytes;
11947 addr += lbytes;
11948 bytes -= lbytes;
11949 }
11950
11951 free (start);
11952
11953 putchar ('\n');
11954}
11955
4a114e3e 11956/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
11957
11958static int
d3dbc530
AM
11959uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
11960 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
11961{
11962#ifndef HAVE_ZLIB_H
cf13d699
NC
11963 return FALSE;
11964#else
11965 dwarf_size_type compressed_size = *size;
11966 unsigned char * compressed_buffer = *buffer;
11967 dwarf_size_type uncompressed_size;
11968 unsigned char * uncompressed_buffer;
11969 z_stream strm;
11970 int rc;
11971 dwarf_size_type header_size = 12;
11972
11973 /* Read the zlib header. In this case, it should be "ZLIB" followed
11974 by the uncompressed section size, 8 bytes in big-endian order. */
11975 if (compressed_size < header_size
11976 || ! streq ((char *) compressed_buffer, "ZLIB"))
11977 return 0;
11978
11979 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
11980 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
11981 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
11982 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
11983 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
11984 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
11985 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
11986 uncompressed_size += compressed_buffer[11];
11987
11988 /* It is possible the section consists of several compressed
11989 buffers concatenated together, so we uncompress in a loop. */
11990 strm.zalloc = NULL;
11991 strm.zfree = NULL;
11992 strm.opaque = NULL;
11993 strm.avail_in = compressed_size - header_size;
11994 strm.next_in = (Bytef *) compressed_buffer + header_size;
11995 strm.avail_out = uncompressed_size;
3f5e193b 11996 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
11997
11998 rc = inflateInit (& strm);
11999 while (strm.avail_in > 0)
12000 {
12001 if (rc != Z_OK)
12002 goto fail;
12003 strm.next_out = ((Bytef *) uncompressed_buffer
12004 + (uncompressed_size - strm.avail_out));
12005 rc = inflate (&strm, Z_FINISH);
12006 if (rc != Z_STREAM_END)
12007 goto fail;
12008 rc = inflateReset (& strm);
12009 }
12010 rc = inflateEnd (& strm);
12011 if (rc != Z_OK
12012 || strm.avail_out != 0)
12013 goto fail;
12014
12015 free (compressed_buffer);
12016 *buffer = uncompressed_buffer;
12017 *size = uncompressed_size;
12018 return 1;
12019
12020 fail:
12021 free (uncompressed_buffer);
4a114e3e
L
12022 /* Indicate decompression failure. */
12023 *buffer = NULL;
cf13d699
NC
12024 return 0;
12025#endif /* HAVE_ZLIB_H */
12026}
12027
d966045b
DJ
12028static int
12029load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 12030 Elf_Internal_Shdr * sec, void * file)
1007acb3 12031{
2cf0635d 12032 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 12033 char buf [64];
1007acb3 12034
19e6b90e
L
12035 /* If it is already loaded, do nothing. */
12036 if (section->start != NULL)
12037 return 1;
1007acb3 12038
19e6b90e
L
12039 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
12040 section->address = sec->sh_addr;
06614111 12041 section->user_data = NULL;
3f5e193b
NC
12042 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
12043 sec->sh_offset, 1,
12044 sec->sh_size, buf);
59245841
NC
12045 if (section->start == NULL)
12046 section->size = 0;
12047 else
12048 {
12049 section->size = sec->sh_size;
12050 if (uncompress_section_contents (&section->start, &section->size))
12051 sec->sh_size = section->size;
12052 }
4a114e3e 12053
1b315056
CS
12054 if (section->start == NULL)
12055 return 0;
12056
19e6b90e 12057 if (debug_displays [debug].relocate)
3f5e193b 12058 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 12059
1b315056 12060 return 1;
1007acb3
L
12061}
12062
657d0d47
CC
12063/* If this is not NULL, load_debug_section will only look for sections
12064 within the list of sections given here. */
12065unsigned int *section_subset = NULL;
12066
d966045b 12067int
2cf0635d 12068load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 12069{
2cf0635d
NC
12070 struct dwarf_section * section = &debug_displays [debug].section;
12071 Elf_Internal_Shdr * sec;
d966045b
DJ
12072
12073 /* Locate the debug section. */
657d0d47 12074 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
12075 if (sec != NULL)
12076 section->name = section->uncompressed_name;
12077 else
12078 {
657d0d47 12079 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
12080 if (sec != NULL)
12081 section->name = section->compressed_name;
12082 }
12083 if (sec == NULL)
12084 return 0;
12085
657d0d47
CC
12086 /* If we're loading from a subset of sections, and we've loaded
12087 a section matching this name before, it's likely that it's a
12088 different one. */
12089 if (section_subset != NULL)
12090 free_debug_section (debug);
12091
3f5e193b 12092 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
12093}
12094
19e6b90e
L
12095void
12096free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 12097{
2cf0635d 12098 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 12099
19e6b90e
L
12100 if (section->start == NULL)
12101 return;
1007acb3 12102
19e6b90e
L
12103 free ((char *) section->start);
12104 section->start = NULL;
12105 section->address = 0;
12106 section->size = 0;
1007acb3
L
12107}
12108
1007acb3 12109static int
657d0d47 12110display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 12111{
2cf0635d 12112 char * name = SECTION_NAME (section);
74e1a04b 12113 const char * print_name = printable_section_name (section);
19e6b90e
L
12114 bfd_size_type length;
12115 int result = 1;
3f5e193b 12116 int i;
1007acb3 12117
19e6b90e
L
12118 length = section->sh_size;
12119 if (length == 0)
1007acb3 12120 {
74e1a04b 12121 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
19e6b90e 12122 return 0;
1007acb3 12123 }
5dff79d8
NC
12124 if (section->sh_type == SHT_NOBITS)
12125 {
12126 /* There is no point in dumping the contents of a debugging section
12127 which has the NOBITS type - the bits in the file will be random.
12128 This can happen when a file containing a .eh_frame section is
12129 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
12130 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
12131 print_name);
5dff79d8
NC
12132 return 0;
12133 }
1007acb3 12134
0112cd26 12135 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 12136 name = ".debug_info";
1007acb3 12137
19e6b90e
L
12138 /* See if we know how to display the contents of this section. */
12139 for (i = 0; i < max; i++)
1b315056 12140 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 12141 || (i == line && const_strneq (name, ".debug_line."))
1b315056 12142 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 12143 {
2cf0635d 12144 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
12145 int secondary = (section != find_section (name));
12146
12147 if (secondary)
3f5e193b 12148 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 12149
b40bf0a2
NC
12150 if (i == line && const_strneq (name, ".debug_line."))
12151 sec->name = name;
12152 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
12153 sec->name = sec->uncompressed_name;
12154 else
12155 sec->name = sec->compressed_name;
3f5e193b
NC
12156 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
12157 section, file))
19e6b90e 12158 {
657d0d47
CC
12159 /* If this debug section is part of a CU/TU set in a .dwp file,
12160 restrict load_debug_section to the sections in that set. */
12161 section_subset = find_cu_tu_set (file, shndx);
12162
19e6b90e 12163 result &= debug_displays[i].display (sec, file);
1007acb3 12164
657d0d47
CC
12165 section_subset = NULL;
12166
d966045b 12167 if (secondary || (i != info && i != abbrev))
3f5e193b 12168 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 12169 }
1007acb3 12170
19e6b90e
L
12171 break;
12172 }
1007acb3 12173
19e6b90e 12174 if (i == max)
1007acb3 12175 {
74e1a04b 12176 printf (_("Unrecognized debug section: %s\n"), print_name);
19e6b90e 12177 result = 0;
1007acb3
L
12178 }
12179
19e6b90e 12180 return result;
5b18a4bc 12181}
103f02d3 12182
aef1f6d0
DJ
12183/* Set DUMP_SECTS for all sections where dumps were requested
12184 based on section name. */
12185
12186static void
12187initialise_dumps_byname (void)
12188{
2cf0635d 12189 struct dump_list_entry * cur;
aef1f6d0
DJ
12190
12191 for (cur = dump_sects_byname; cur; cur = cur->next)
12192 {
12193 unsigned int i;
12194 int any;
12195
12196 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
12197 if (streq (SECTION_NAME (section_headers + i), cur->name))
12198 {
09c11c86 12199 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
12200 any = 1;
12201 }
12202
12203 if (!any)
12204 warn (_("Section '%s' was not dumped because it does not exist!\n"),
12205 cur->name);
12206 }
12207}
12208
5b18a4bc 12209static void
2cf0635d 12210process_section_contents (FILE * file)
5b18a4bc 12211{
2cf0635d 12212 Elf_Internal_Shdr * section;
19e6b90e 12213 unsigned int i;
103f02d3 12214
19e6b90e
L
12215 if (! do_dump)
12216 return;
103f02d3 12217
aef1f6d0
DJ
12218 initialise_dumps_byname ();
12219
19e6b90e
L
12220 for (i = 0, section = section_headers;
12221 i < elf_header.e_shnum && i < num_dump_sects;
12222 i++, section++)
12223 {
12224#ifdef SUPPORT_DISASSEMBLY
12225 if (dump_sects[i] & DISASS_DUMP)
12226 disassemble_section (section, file);
12227#endif
12228 if (dump_sects[i] & HEX_DUMP)
cf13d699 12229 dump_section_as_bytes (section, file, FALSE);
103f02d3 12230
cf13d699
NC
12231 if (dump_sects[i] & RELOC_DUMP)
12232 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
12233
12234 if (dump_sects[i] & STRING_DUMP)
12235 dump_section_as_strings (section, file);
cf13d699
NC
12236
12237 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 12238 display_debug_section (i, section, file);
5b18a4bc 12239 }
103f02d3 12240
19e6b90e
L
12241 /* Check to see if the user requested a
12242 dump of a section that does not exist. */
12243 while (i++ < num_dump_sects)
12244 if (dump_sects[i])
12245 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 12246}
103f02d3 12247
5b18a4bc 12248static void
19e6b90e 12249process_mips_fpe_exception (int mask)
5b18a4bc 12250{
19e6b90e
L
12251 if (mask)
12252 {
12253 int first = 1;
12254 if (mask & OEX_FPU_INEX)
12255 fputs ("INEX", stdout), first = 0;
12256 if (mask & OEX_FPU_UFLO)
12257 printf ("%sUFLO", first ? "" : "|"), first = 0;
12258 if (mask & OEX_FPU_OFLO)
12259 printf ("%sOFLO", first ? "" : "|"), first = 0;
12260 if (mask & OEX_FPU_DIV0)
12261 printf ("%sDIV0", first ? "" : "|"), first = 0;
12262 if (mask & OEX_FPU_INVAL)
12263 printf ("%sINVAL", first ? "" : "|");
12264 }
5b18a4bc 12265 else
19e6b90e 12266 fputs ("0", stdout);
5b18a4bc 12267}
103f02d3 12268
f6f0e17b
NC
12269/* Display's the value of TAG at location P. If TAG is
12270 greater than 0 it is assumed to be an unknown tag, and
12271 a message is printed to this effect. Otherwise it is
12272 assumed that a message has already been printed.
12273
12274 If the bottom bit of TAG is set it assumed to have a
12275 string value, otherwise it is assumed to have an integer
12276 value.
12277
12278 Returns an updated P pointing to the first unread byte
12279 beyond the end of TAG's value.
12280
12281 Reads at or beyond END will not be made. */
12282
12283static unsigned char *
12284display_tag_value (int tag,
12285 unsigned char * p,
12286 const unsigned char * const end)
12287{
12288 unsigned long val;
12289
12290 if (tag > 0)
12291 printf (" Tag_unknown_%d: ", tag);
12292
12293 if (p >= end)
12294 {
4082ef84 12295 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
12296 }
12297 else if (tag & 1)
12298 {
071436c6
NC
12299 /* PR 17531 file: 027-19978-0.004. */
12300 size_t maxlen = (end - p) - 1;
12301
12302 putchar ('"');
4082ef84
NC
12303 if (maxlen > 0)
12304 {
12305 print_symbol ((int) maxlen, (const char *) p);
12306 p += strnlen ((char *) p, maxlen) + 1;
12307 }
12308 else
12309 {
12310 printf (_("<corrupt string tag>"));
12311 p = (unsigned char *) end;
12312 }
071436c6 12313 printf ("\"\n");
f6f0e17b
NC
12314 }
12315 else
12316 {
12317 unsigned int len;
12318
12319 val = read_uleb128 (p, &len, end);
12320 p += len;
12321 printf ("%ld (0x%lx)\n", val, val);
12322 }
12323
4082ef84 12324 assert (p <= end);
f6f0e17b
NC
12325 return p;
12326}
12327
11c1ff18
PB
12328/* ARM EABI attributes section. */
12329typedef struct
12330{
70e99720 12331 unsigned int tag;
2cf0635d 12332 const char * name;
11c1ff18 12333 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 12334 unsigned int type;
2cf0635d 12335 const char ** table;
11c1ff18
PB
12336} arm_attr_public_tag;
12337
2cf0635d 12338static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 12339 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 12340 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
12341static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
12342static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 12343 {"No", "Thumb-1", "Thumb-2"};
75375b3e 12344static const char * arm_attr_tag_FP_arch[] =
bca38921 12345 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 12346 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 12347static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 12348static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 12349 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 12350static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
12351 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
12352 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 12353static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 12354 {"V6", "SB", "TLS", "Unused"};
2cf0635d 12355static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 12356 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 12357static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 12358 {"Absolute", "PC-relative", "None"};
2cf0635d 12359static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 12360 {"None", "direct", "GOT-indirect"};
2cf0635d 12361static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 12362 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
12363static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
12364static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 12365 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
12366static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
12367static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
12368static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 12369 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 12370static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 12371 {"Unused", "small", "int", "forced to int"};
2cf0635d 12372static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 12373 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 12374static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 12375 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 12376static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 12377 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 12378static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
12379 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12380 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 12381static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
12382 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12383 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 12384static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 12385static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 12386 {"Not Allowed", "Allowed"};
2cf0635d 12387static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 12388 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 12389static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
12390 {"Not Allowed", "Allowed"};
12391static const char * arm_attr_tag_DIV_use[] =
dd24e3da 12392 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 12393 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
12394static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
12395static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 12396 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 12397 "TrustZone and Virtualization Extensions"};
dd24e3da 12398static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 12399 {"Not Allowed", "Allowed"};
11c1ff18
PB
12400
12401#define LOOKUP(id, name) \
12402 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 12403static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
12404{
12405 {4, "CPU_raw_name", 1, NULL},
12406 {5, "CPU_name", 1, NULL},
12407 LOOKUP(6, CPU_arch),
12408 {7, "CPU_arch_profile", 0, NULL},
12409 LOOKUP(8, ARM_ISA_use),
12410 LOOKUP(9, THUMB_ISA_use),
75375b3e 12411 LOOKUP(10, FP_arch),
11c1ff18 12412 LOOKUP(11, WMMX_arch),
f5f53991
AS
12413 LOOKUP(12, Advanced_SIMD_arch),
12414 LOOKUP(13, PCS_config),
11c1ff18
PB
12415 LOOKUP(14, ABI_PCS_R9_use),
12416 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 12417 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
12418 LOOKUP(17, ABI_PCS_GOT_use),
12419 LOOKUP(18, ABI_PCS_wchar_t),
12420 LOOKUP(19, ABI_FP_rounding),
12421 LOOKUP(20, ABI_FP_denormal),
12422 LOOKUP(21, ABI_FP_exceptions),
12423 LOOKUP(22, ABI_FP_user_exceptions),
12424 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
12425 {24, "ABI_align_needed", 0, NULL},
12426 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
12427 LOOKUP(26, ABI_enum_size),
12428 LOOKUP(27, ABI_HardFP_use),
12429 LOOKUP(28, ABI_VFP_args),
12430 LOOKUP(29, ABI_WMMX_args),
12431 LOOKUP(30, ABI_optimization_goals),
12432 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 12433 {32, "compatibility", 0, NULL},
f5f53991 12434 LOOKUP(34, CPU_unaligned_access),
75375b3e 12435 LOOKUP(36, FP_HP_extension),
8e79c3df 12436 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
12437 LOOKUP(42, MPextension_use),
12438 LOOKUP(44, DIV_use),
f5f53991
AS
12439 {64, "nodefaults", 0, NULL},
12440 {65, "also_compatible_with", 0, NULL},
12441 LOOKUP(66, T2EE_use),
12442 {67, "conformance", 1, NULL},
12443 LOOKUP(68, Virtualization_use),
cd21e546 12444 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
12445};
12446#undef LOOKUP
12447
11c1ff18 12448static unsigned char *
f6f0e17b
NC
12449display_arm_attribute (unsigned char * p,
12450 const unsigned char * const end)
11c1ff18 12451{
70e99720 12452 unsigned int tag;
11c1ff18 12453 unsigned int len;
70e99720 12454 unsigned int val;
2cf0635d 12455 arm_attr_public_tag * attr;
11c1ff18 12456 unsigned i;
70e99720 12457 unsigned int type;
11c1ff18 12458
f6f0e17b 12459 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
12460 p += len;
12461 attr = NULL;
2cf0635d 12462 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
12463 {
12464 if (arm_attr_public_tags[i].tag == tag)
12465 {
12466 attr = &arm_attr_public_tags[i];
12467 break;
12468 }
12469 }
12470
12471 if (attr)
12472 {
12473 printf (" Tag_%s: ", attr->name);
12474 switch (attr->type)
12475 {
12476 case 0:
12477 switch (tag)
12478 {
12479 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 12480 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12481 p += len;
12482 switch (val)
12483 {
2b692964
NC
12484 case 0: printf (_("None\n")); break;
12485 case 'A': printf (_("Application\n")); break;
12486 case 'R': printf (_("Realtime\n")); break;
12487 case 'M': printf (_("Microcontroller\n")); break;
12488 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
12489 default: printf ("??? (%d)\n", val); break;
12490 }
12491 break;
12492
75375b3e 12493 case 24: /* Tag_align_needed. */
f6f0e17b 12494 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12495 p += len;
12496 switch (val)
12497 {
2b692964
NC
12498 case 0: printf (_("None\n")); break;
12499 case 1: printf (_("8-byte\n")); break;
12500 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
12501 case 3: printf ("??? 3\n"); break;
12502 default:
12503 if (val <= 12)
dd24e3da 12504 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12505 1 << val);
12506 else
12507 printf ("??? (%d)\n", val);
12508 break;
12509 }
12510 break;
12511
12512 case 25: /* Tag_align_preserved. */
f6f0e17b 12513 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12514 p += len;
12515 switch (val)
12516 {
2b692964
NC
12517 case 0: printf (_("None\n")); break;
12518 case 1: printf (_("8-byte, except leaf SP\n")); break;
12519 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
12520 case 3: printf ("??? 3\n"); break;
12521 default:
12522 if (val <= 12)
dd24e3da 12523 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12524 1 << val);
12525 else
12526 printf ("??? (%d)\n", val);
12527 break;
12528 }
12529 break;
12530
11c1ff18 12531 case 32: /* Tag_compatibility. */
071436c6 12532 {
071436c6
NC
12533 val = read_uleb128 (p, &len, end);
12534 p += len;
071436c6 12535 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12536 if (p < end - 1)
12537 {
12538 size_t maxlen = (end - p) - 1;
12539
12540 print_symbol ((int) maxlen, (const char *) p);
12541 p += strnlen ((char *) p, maxlen) + 1;
12542 }
12543 else
12544 {
12545 printf (_("<corrupt>"));
12546 p = (unsigned char *) end;
12547 }
071436c6 12548 putchar ('\n');
071436c6 12549 }
11c1ff18
PB
12550 break;
12551
f5f53991 12552 case 64: /* Tag_nodefaults. */
541a3cbd
NC
12553 /* PR 17531: file: 001-505008-0.01. */
12554 if (p < end)
12555 p++;
2b692964 12556 printf (_("True\n"));
f5f53991
AS
12557 break;
12558
12559 case 65: /* Tag_also_compatible_with. */
f6f0e17b 12560 val = read_uleb128 (p, &len, end);
f5f53991
AS
12561 p += len;
12562 if (val == 6 /* Tag_CPU_arch. */)
12563 {
f6f0e17b 12564 val = read_uleb128 (p, &len, end);
f5f53991 12565 p += len;
071436c6 12566 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
12567 printf ("??? (%d)\n", val);
12568 else
12569 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
12570 }
12571 else
12572 printf ("???\n");
071436c6
NC
12573 while (p < end && *(p++) != '\0' /* NUL terminator. */)
12574 ;
f5f53991
AS
12575 break;
12576
11c1ff18 12577 default:
bee0ee85
NC
12578 printf (_("<unknown: %d>\n"), tag);
12579 break;
11c1ff18
PB
12580 }
12581 return p;
12582
12583 case 1:
f6f0e17b 12584 return display_tag_value (-1, p, end);
11c1ff18 12585 case 2:
f6f0e17b 12586 return display_tag_value (0, p, end);
11c1ff18
PB
12587
12588 default:
12589 assert (attr->type & 0x80);
f6f0e17b 12590 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12591 p += len;
12592 type = attr->type & 0x7f;
12593 if (val >= type)
12594 printf ("??? (%d)\n", val);
12595 else
12596 printf ("%s\n", attr->table[val]);
12597 return p;
12598 }
12599 }
11c1ff18 12600
f6f0e17b 12601 return display_tag_value (tag, p, end);
11c1ff18
PB
12602}
12603
104d59d1 12604static unsigned char *
60bca95a 12605display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
12606 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
12607 const unsigned char * const end)
104d59d1
JM
12608{
12609 int tag;
12610 unsigned int len;
12611 int val;
104d59d1 12612
f6f0e17b 12613 tag = read_uleb128 (p, &len, end);
104d59d1
JM
12614 p += len;
12615
12616 /* Tag_compatibility is the only generic GNU attribute defined at
12617 present. */
12618 if (tag == 32)
12619 {
f6f0e17b 12620 val = read_uleb128 (p, &len, end);
104d59d1 12621 p += len;
071436c6
NC
12622
12623 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
12624 if (p == end)
12625 {
071436c6 12626 printf (_("<corrupt>\n"));
f6f0e17b
NC
12627 warn (_("corrupt vendor attribute\n"));
12628 }
12629 else
12630 {
4082ef84
NC
12631 if (p < end - 1)
12632 {
12633 size_t maxlen = (end - p) - 1;
071436c6 12634
4082ef84
NC
12635 print_symbol ((int) maxlen, (const char *) p);
12636 p += strnlen ((char *) p, maxlen) + 1;
12637 }
12638 else
12639 {
12640 printf (_("<corrupt>"));
12641 p = (unsigned char *) end;
12642 }
071436c6 12643 putchar ('\n');
f6f0e17b 12644 }
104d59d1
JM
12645 return p;
12646 }
12647
12648 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 12649 return display_proc_gnu_attribute (p, tag, end);
104d59d1 12650
f6f0e17b 12651 return display_tag_value (tag, p, end);
104d59d1
JM
12652}
12653
34c8bcba 12654static unsigned char *
f6f0e17b
NC
12655display_power_gnu_attribute (unsigned char * p,
12656 int tag,
12657 const unsigned char * const end)
34c8bcba 12658{
34c8bcba
JM
12659 unsigned int len;
12660 int val;
12661
12662 if (tag == Tag_GNU_Power_ABI_FP)
12663 {
f6f0e17b 12664 val = read_uleb128 (p, &len, end);
34c8bcba
JM
12665 p += len;
12666 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 12667
34c8bcba
JM
12668 switch (val)
12669 {
12670 case 0:
2b692964 12671 printf (_("Hard or soft float\n"));
34c8bcba
JM
12672 break;
12673 case 1:
2b692964 12674 printf (_("Hard float\n"));
34c8bcba
JM
12675 break;
12676 case 2:
2b692964 12677 printf (_("Soft float\n"));
34c8bcba 12678 break;
3c7b9897 12679 case 3:
2b692964 12680 printf (_("Single-precision hard float\n"));
3c7b9897 12681 break;
34c8bcba
JM
12682 default:
12683 printf ("??? (%d)\n", val);
12684 break;
12685 }
12686 return p;
12687 }
12688
c6e65352
DJ
12689 if (tag == Tag_GNU_Power_ABI_Vector)
12690 {
f6f0e17b 12691 val = read_uleb128 (p, &len, end);
c6e65352
DJ
12692 p += len;
12693 printf (" Tag_GNU_Power_ABI_Vector: ");
12694 switch (val)
12695 {
12696 case 0:
2b692964 12697 printf (_("Any\n"));
c6e65352
DJ
12698 break;
12699 case 1:
2b692964 12700 printf (_("Generic\n"));
c6e65352
DJ
12701 break;
12702 case 2:
12703 printf ("AltiVec\n");
12704 break;
12705 case 3:
12706 printf ("SPE\n");
12707 break;
12708 default:
12709 printf ("??? (%d)\n", val);
12710 break;
12711 }
12712 return p;
12713 }
12714
f82e0623
NF
12715 if (tag == Tag_GNU_Power_ABI_Struct_Return)
12716 {
f6f0e17b
NC
12717 if (p == end)
12718 {
071436c6 12719 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return\n"));
f6f0e17b
NC
12720 return p;
12721 }
0b4362b0 12722
f6f0e17b 12723 val = read_uleb128 (p, &len, end);
f82e0623
NF
12724 p += len;
12725 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
12726 switch (val)
12727 {
12728 case 0:
2b692964 12729 printf (_("Any\n"));
f82e0623
NF
12730 break;
12731 case 1:
12732 printf ("r3/r4\n");
12733 break;
12734 case 2:
2b692964 12735 printf (_("Memory\n"));
f82e0623
NF
12736 break;
12737 default:
12738 printf ("??? (%d)\n", val);
12739 break;
12740 }
12741 return p;
12742 }
12743
f6f0e17b 12744 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
12745}
12746
9e8c70f9
DM
12747static void
12748display_sparc_hwcaps (int mask)
12749{
12750 if (mask)
12751 {
12752 int first = 1;
071436c6 12753
9e8c70f9
DM
12754 if (mask & ELF_SPARC_HWCAP_MUL32)
12755 fputs ("mul32", stdout), first = 0;
12756 if (mask & ELF_SPARC_HWCAP_DIV32)
12757 printf ("%sdiv32", first ? "" : "|"), first = 0;
12758 if (mask & ELF_SPARC_HWCAP_FSMULD)
12759 printf ("%sfsmuld", first ? "" : "|"), first = 0;
12760 if (mask & ELF_SPARC_HWCAP_V8PLUS)
12761 printf ("%sv8plus", first ? "" : "|"), first = 0;
12762 if (mask & ELF_SPARC_HWCAP_POPC)
12763 printf ("%spopc", first ? "" : "|"), first = 0;
12764 if (mask & ELF_SPARC_HWCAP_VIS)
12765 printf ("%svis", first ? "" : "|"), first = 0;
12766 if (mask & ELF_SPARC_HWCAP_VIS2)
12767 printf ("%svis2", first ? "" : "|"), first = 0;
12768 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
12769 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
12770 if (mask & ELF_SPARC_HWCAP_FMAF)
12771 printf ("%sfmaf", first ? "" : "|"), first = 0;
12772 if (mask & ELF_SPARC_HWCAP_VIS3)
12773 printf ("%svis3", first ? "" : "|"), first = 0;
12774 if (mask & ELF_SPARC_HWCAP_HPC)
12775 printf ("%shpc", first ? "" : "|"), first = 0;
12776 if (mask & ELF_SPARC_HWCAP_RANDOM)
12777 printf ("%srandom", first ? "" : "|"), first = 0;
12778 if (mask & ELF_SPARC_HWCAP_TRANS)
12779 printf ("%strans", first ? "" : "|"), first = 0;
12780 if (mask & ELF_SPARC_HWCAP_FJFMAU)
12781 printf ("%sfjfmau", first ? "" : "|"), first = 0;
12782 if (mask & ELF_SPARC_HWCAP_IMA)
12783 printf ("%sima", first ? "" : "|"), first = 0;
12784 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
12785 printf ("%scspare", first ? "" : "|"), first = 0;
12786 }
12787 else
071436c6
NC
12788 fputc ('0', stdout);
12789 fputc ('\n', stdout);
9e8c70f9
DM
12790}
12791
3d68f91c
JM
12792static void
12793display_sparc_hwcaps2 (int mask)
12794{
12795 if (mask)
12796 {
12797 int first = 1;
071436c6 12798
3d68f91c
JM
12799 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
12800 fputs ("fjathplus", stdout), first = 0;
12801 if (mask & ELF_SPARC_HWCAP2_VIS3B)
12802 printf ("%svis3b", first ? "" : "|"), first = 0;
12803 if (mask & ELF_SPARC_HWCAP2_ADP)
12804 printf ("%sadp", first ? "" : "|"), first = 0;
12805 if (mask & ELF_SPARC_HWCAP2_SPARC5)
12806 printf ("%ssparc5", first ? "" : "|"), first = 0;
12807 if (mask & ELF_SPARC_HWCAP2_MWAIT)
12808 printf ("%smwait", first ? "" : "|"), first = 0;
12809 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
12810 printf ("%sxmpmul", first ? "" : "|"), first = 0;
12811 if (mask & ELF_SPARC_HWCAP2_XMONT)
12812 printf ("%sxmont2", first ? "" : "|"), first = 0;
12813 if (mask & ELF_SPARC_HWCAP2_NSEC)
12814 printf ("%snsec", first ? "" : "|"), first = 0;
12815 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
12816 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
12817 if (mask & ELF_SPARC_HWCAP2_FJDES)
12818 printf ("%sfjdes", first ? "" : "|"), first = 0;
12819 if (mask & ELF_SPARC_HWCAP2_FJAES)
12820 printf ("%sfjaes", first ? "" : "|"), first = 0;
12821 }
12822 else
071436c6
NC
12823 fputc ('0', stdout);
12824 fputc ('\n', stdout);
3d68f91c
JM
12825}
12826
9e8c70f9 12827static unsigned char *
f6f0e17b
NC
12828display_sparc_gnu_attribute (unsigned char * p,
12829 int tag,
12830 const unsigned char * const end)
9e8c70f9 12831{
3d68f91c
JM
12832 unsigned int len;
12833 int val;
12834
9e8c70f9
DM
12835 if (tag == Tag_GNU_Sparc_HWCAPS)
12836 {
f6f0e17b 12837 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
12838 p += len;
12839 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
12840 display_sparc_hwcaps (val);
12841 return p;
3d68f91c
JM
12842 }
12843 if (tag == Tag_GNU_Sparc_HWCAPS2)
12844 {
12845 val = read_uleb128 (p, &len, end);
12846 p += len;
12847 printf (" Tag_GNU_Sparc_HWCAPS2: ");
12848 display_sparc_hwcaps2 (val);
12849 return p;
12850 }
9e8c70f9 12851
f6f0e17b 12852 return display_tag_value (tag, p, end);
9e8c70f9
DM
12853}
12854
351cdf24
MF
12855static void
12856print_mips_fp_abi_value (int val)
12857{
12858 switch (val)
12859 {
12860 case Val_GNU_MIPS_ABI_FP_ANY:
12861 printf (_("Hard or soft float\n"));
12862 break;
12863 case Val_GNU_MIPS_ABI_FP_DOUBLE:
12864 printf (_("Hard float (double precision)\n"));
12865 break;
12866 case Val_GNU_MIPS_ABI_FP_SINGLE:
12867 printf (_("Hard float (single precision)\n"));
12868 break;
12869 case Val_GNU_MIPS_ABI_FP_SOFT:
12870 printf (_("Soft float\n"));
12871 break;
12872 case Val_GNU_MIPS_ABI_FP_OLD_64:
12873 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
12874 break;
12875 case Val_GNU_MIPS_ABI_FP_XX:
12876 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
12877 break;
12878 case Val_GNU_MIPS_ABI_FP_64:
12879 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
12880 break;
12881 case Val_GNU_MIPS_ABI_FP_64A:
12882 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
12883 break;
12884 default:
12885 printf ("??? (%d)\n", val);
12886 break;
12887 }
12888}
12889
2cf19d5c 12890static unsigned char *
f6f0e17b
NC
12891display_mips_gnu_attribute (unsigned char * p,
12892 int tag,
12893 const unsigned char * const end)
2cf19d5c 12894{
2cf19d5c
JM
12895 if (tag == Tag_GNU_MIPS_ABI_FP)
12896 {
f6f0e17b
NC
12897 unsigned int len;
12898 int val;
12899
12900 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
12901 p += len;
12902 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 12903
351cdf24
MF
12904 print_mips_fp_abi_value (val);
12905
2cf19d5c
JM
12906 return p;
12907 }
12908
a9f58168
CF
12909 if (tag == Tag_GNU_MIPS_ABI_MSA)
12910 {
12911 unsigned int len;
12912 int val;
12913
12914 val = read_uleb128 (p, &len, end);
12915 p += len;
12916 printf (" Tag_GNU_MIPS_ABI_MSA: ");
12917
12918 switch (val)
12919 {
12920 case Val_GNU_MIPS_ABI_MSA_ANY:
12921 printf (_("Any MSA or not\n"));
12922 break;
12923 case Val_GNU_MIPS_ABI_MSA_128:
12924 printf (_("128-bit MSA\n"));
12925 break;
12926 default:
12927 printf ("??? (%d)\n", val);
12928 break;
12929 }
12930 return p;
12931 }
12932
f6f0e17b 12933 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
12934}
12935
59e6276b 12936static unsigned char *
f6f0e17b
NC
12937display_tic6x_attribute (unsigned char * p,
12938 const unsigned char * const end)
59e6276b
JM
12939{
12940 int tag;
12941 unsigned int len;
12942 int val;
12943
f6f0e17b 12944 tag = read_uleb128 (p, &len, end);
59e6276b
JM
12945 p += len;
12946
12947 switch (tag)
12948 {
75fa6dc1 12949 case Tag_ISA:
f6f0e17b 12950 val = read_uleb128 (p, &len, end);
59e6276b 12951 p += len;
75fa6dc1 12952 printf (" Tag_ISA: ");
59e6276b
JM
12953
12954 switch (val)
12955 {
75fa6dc1 12956 case C6XABI_Tag_ISA_none:
59e6276b
JM
12957 printf (_("None\n"));
12958 break;
75fa6dc1 12959 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
12960 printf ("C62x\n");
12961 break;
75fa6dc1 12962 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
12963 printf ("C67x\n");
12964 break;
75fa6dc1 12965 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
12966 printf ("C67x+\n");
12967 break;
75fa6dc1 12968 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
12969 printf ("C64x\n");
12970 break;
75fa6dc1 12971 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
12972 printf ("C64x+\n");
12973 break;
75fa6dc1 12974 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
12975 printf ("C674x\n");
12976 break;
12977 default:
12978 printf ("??? (%d)\n", val);
12979 break;
12980 }
12981 return p;
12982
87779176 12983 case Tag_ABI_wchar_t:
f6f0e17b 12984 val = read_uleb128 (p, &len, end);
87779176
JM
12985 p += len;
12986 printf (" Tag_ABI_wchar_t: ");
12987 switch (val)
12988 {
12989 case 0:
12990 printf (_("Not used\n"));
12991 break;
12992 case 1:
12993 printf (_("2 bytes\n"));
12994 break;
12995 case 2:
12996 printf (_("4 bytes\n"));
12997 break;
12998 default:
12999 printf ("??? (%d)\n", val);
13000 break;
13001 }
13002 return p;
13003
13004 case Tag_ABI_stack_align_needed:
f6f0e17b 13005 val = read_uleb128 (p, &len, end);
87779176
JM
13006 p += len;
13007 printf (" Tag_ABI_stack_align_needed: ");
13008 switch (val)
13009 {
13010 case 0:
13011 printf (_("8-byte\n"));
13012 break;
13013 case 1:
13014 printf (_("16-byte\n"));
13015 break;
13016 default:
13017 printf ("??? (%d)\n", val);
13018 break;
13019 }
13020 return p;
13021
13022 case Tag_ABI_stack_align_preserved:
f6f0e17b 13023 val = read_uleb128 (p, &len, end);
87779176
JM
13024 p += len;
13025 printf (" Tag_ABI_stack_align_preserved: ");
13026 switch (val)
13027 {
13028 case 0:
13029 printf (_("8-byte\n"));
13030 break;
13031 case 1:
13032 printf (_("16-byte\n"));
13033 break;
13034 default:
13035 printf ("??? (%d)\n", val);
13036 break;
13037 }
13038 return p;
13039
b5593623 13040 case Tag_ABI_DSBT:
f6f0e17b 13041 val = read_uleb128 (p, &len, end);
b5593623
JM
13042 p += len;
13043 printf (" Tag_ABI_DSBT: ");
13044 switch (val)
13045 {
13046 case 0:
13047 printf (_("DSBT addressing not used\n"));
13048 break;
13049 case 1:
13050 printf (_("DSBT addressing used\n"));
13051 break;
13052 default:
13053 printf ("??? (%d)\n", val);
13054 break;
13055 }
13056 return p;
13057
87779176 13058 case Tag_ABI_PID:
f6f0e17b 13059 val = read_uleb128 (p, &len, end);
87779176
JM
13060 p += len;
13061 printf (" Tag_ABI_PID: ");
13062 switch (val)
13063 {
13064 case 0:
13065 printf (_("Data addressing position-dependent\n"));
13066 break;
13067 case 1:
13068 printf (_("Data addressing position-independent, GOT near DP\n"));
13069 break;
13070 case 2:
13071 printf (_("Data addressing position-independent, GOT far from DP\n"));
13072 break;
13073 default:
13074 printf ("??? (%d)\n", val);
13075 break;
13076 }
13077 return p;
13078
13079 case Tag_ABI_PIC:
f6f0e17b 13080 val = read_uleb128 (p, &len, end);
87779176
JM
13081 p += len;
13082 printf (" Tag_ABI_PIC: ");
13083 switch (val)
13084 {
13085 case 0:
13086 printf (_("Code addressing position-dependent\n"));
13087 break;
13088 case 1:
13089 printf (_("Code addressing position-independent\n"));
13090 break;
13091 default:
13092 printf ("??? (%d)\n", val);
13093 break;
13094 }
13095 return p;
13096
13097 case Tag_ABI_array_object_alignment:
f6f0e17b 13098 val = read_uleb128 (p, &len, end);
87779176
JM
13099 p += len;
13100 printf (" Tag_ABI_array_object_alignment: ");
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
13118 case Tag_ABI_array_object_align_expected:
f6f0e17b 13119 val = read_uleb128 (p, &len, end);
87779176
JM
13120 p += len;
13121 printf (" Tag_ABI_array_object_align_expected: ");
13122 switch (val)
13123 {
13124 case 0:
13125 printf (_("8-byte\n"));
13126 break;
13127 case 1:
13128 printf (_("4-byte\n"));
13129 break;
13130 case 2:
13131 printf (_("16-byte\n"));
13132 break;
13133 default:
13134 printf ("??? (%d)\n", val);
13135 break;
13136 }
13137 return p;
13138
3cbd1c06 13139 case Tag_ABI_compatibility:
071436c6 13140 {
071436c6
NC
13141 val = read_uleb128 (p, &len, end);
13142 p += len;
13143 printf (" Tag_ABI_compatibility: ");
071436c6 13144 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
13145 if (p < end - 1)
13146 {
13147 size_t maxlen = (end - p) - 1;
13148
13149 print_symbol ((int) maxlen, (const char *) p);
13150 p += strnlen ((char *) p, maxlen) + 1;
13151 }
13152 else
13153 {
13154 printf (_("<corrupt>"));
13155 p = (unsigned char *) end;
13156 }
071436c6 13157 putchar ('\n');
071436c6
NC
13158 return p;
13159 }
87779176
JM
13160
13161 case Tag_ABI_conformance:
071436c6 13162 {
4082ef84
NC
13163 printf (" Tag_ABI_conformance: \"");
13164 if (p < end - 1)
13165 {
13166 size_t maxlen = (end - p) - 1;
071436c6 13167
4082ef84
NC
13168 print_symbol ((int) maxlen, (const char *) p);
13169 p += strnlen ((char *) p, maxlen) + 1;
13170 }
13171 else
13172 {
13173 printf (_("<corrupt>"));
13174 p = (unsigned char *) end;
13175 }
071436c6 13176 printf ("\"\n");
071436c6
NC
13177 return p;
13178 }
59e6276b
JM
13179 }
13180
f6f0e17b
NC
13181 return display_tag_value (tag, p, end);
13182}
59e6276b 13183
f6f0e17b
NC
13184static void
13185display_raw_attribute (unsigned char * p, unsigned char * end)
13186{
13187 unsigned long addr = 0;
13188 size_t bytes = end - p;
13189
e0a31db1 13190 assert (end > p);
f6f0e17b 13191 while (bytes)
87779176 13192 {
f6f0e17b
NC
13193 int j;
13194 int k;
13195 int lbytes = (bytes > 16 ? 16 : bytes);
13196
13197 printf (" 0x%8.8lx ", addr);
13198
13199 for (j = 0; j < 16; j++)
13200 {
13201 if (j < lbytes)
13202 printf ("%2.2x", p[j]);
13203 else
13204 printf (" ");
13205
13206 if ((j & 3) == 3)
13207 printf (" ");
13208 }
13209
13210 for (j = 0; j < lbytes; j++)
13211 {
13212 k = p[j];
13213 if (k >= ' ' && k < 0x7f)
13214 printf ("%c", k);
13215 else
13216 printf (".");
13217 }
13218
13219 putchar ('\n');
13220
13221 p += lbytes;
13222 bytes -= lbytes;
13223 addr += lbytes;
87779176 13224 }
59e6276b 13225
f6f0e17b 13226 putchar ('\n');
59e6276b
JM
13227}
13228
13761a11
NC
13229static unsigned char *
13230display_msp430x_attribute (unsigned char * p,
13231 const unsigned char * const end)
13232{
13233 unsigned int len;
13234 int val;
13235 int tag;
13236
13237 tag = read_uleb128 (p, & len, end);
13238 p += len;
0b4362b0 13239
13761a11
NC
13240 switch (tag)
13241 {
13242 case OFBA_MSPABI_Tag_ISA:
13243 val = read_uleb128 (p, &len, end);
13244 p += len;
13245 printf (" Tag_ISA: ");
13246 switch (val)
13247 {
13248 case 0: printf (_("None\n")); break;
13249 case 1: printf (_("MSP430\n")); break;
13250 case 2: printf (_("MSP430X\n")); break;
13251 default: printf ("??? (%d)\n", val); break;
13252 }
13253 break;
13254
13255 case OFBA_MSPABI_Tag_Code_Model:
13256 val = read_uleb128 (p, &len, end);
13257 p += len;
13258 printf (" Tag_Code_Model: ");
13259 switch (val)
13260 {
13261 case 0: printf (_("None\n")); break;
13262 case 1: printf (_("Small\n")); break;
13263 case 2: printf (_("Large\n")); break;
13264 default: printf ("??? (%d)\n", val); break;
13265 }
13266 break;
13267
13268 case OFBA_MSPABI_Tag_Data_Model:
13269 val = read_uleb128 (p, &len, end);
13270 p += len;
13271 printf (" Tag_Data_Model: ");
13272 switch (val)
13273 {
13274 case 0: printf (_("None\n")); break;
13275 case 1: printf (_("Small\n")); break;
13276 case 2: printf (_("Large\n")); break;
13277 case 3: printf (_("Restricted Large\n")); break;
13278 default: printf ("??? (%d)\n", val); break;
13279 }
13280 break;
13281
13282 default:
13283 printf (_(" <unknown tag %d>: "), tag);
13284
13285 if (tag & 1)
13286 {
071436c6 13287 putchar ('"');
4082ef84
NC
13288 if (p < end - 1)
13289 {
13290 size_t maxlen = (end - p) - 1;
13291
13292 print_symbol ((int) maxlen, (const char *) p);
13293 p += strnlen ((char *) p, maxlen) + 1;
13294 }
13295 else
13296 {
13297 printf (_("<corrupt>"));
13298 p = (unsigned char *) end;
13299 }
071436c6 13300 printf ("\"\n");
13761a11
NC
13301 }
13302 else
13303 {
13304 val = read_uleb128 (p, &len, end);
13305 p += len;
13306 printf ("%d (0x%x)\n", val, val);
13307 }
13308 break;
13309 }
13310
4082ef84 13311 assert (p <= end);
13761a11
NC
13312 return p;
13313}
13314
11c1ff18 13315static int
60bca95a
NC
13316process_attributes (FILE * file,
13317 const char * public_name,
104d59d1 13318 unsigned int proc_type,
f6f0e17b
NC
13319 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
13320 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 13321{
2cf0635d 13322 Elf_Internal_Shdr * sect;
11c1ff18
PB
13323 unsigned i;
13324
13325 /* Find the section header so that we get the size. */
13326 for (i = 0, sect = section_headers;
13327 i < elf_header.e_shnum;
13328 i++, sect++)
13329 {
071436c6
NC
13330 unsigned char * contents;
13331 unsigned char * p;
13332
104d59d1 13333 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
13334 continue;
13335
3f5e193b
NC
13336 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
13337 sect->sh_size, _("attributes"));
60bca95a 13338 if (contents == NULL)
11c1ff18 13339 continue;
60bca95a 13340
11c1ff18
PB
13341 p = contents;
13342 if (*p == 'A')
13343 {
071436c6
NC
13344 bfd_vma section_len;
13345
13346 section_len = sect->sh_size - 1;
11c1ff18 13347 p++;
60bca95a 13348
071436c6 13349 while (section_len > 0)
11c1ff18 13350 {
071436c6 13351 bfd_vma attr_len;
e9847026 13352 unsigned int namelen;
11c1ff18 13353 bfd_boolean public_section;
104d59d1 13354 bfd_boolean gnu_section;
11c1ff18 13355
071436c6 13356 if (section_len <= 4)
e0a31db1
NC
13357 {
13358 error (_("Tag section ends prematurely\n"));
13359 break;
13360 }
071436c6 13361 attr_len = byte_get (p, 4);
11c1ff18 13362 p += 4;
60bca95a 13363
071436c6 13364 if (attr_len > section_len)
11c1ff18 13365 {
071436c6
NC
13366 error (_("Bad attribute length (%u > %u)\n"),
13367 (unsigned) attr_len, (unsigned) section_len);
13368 attr_len = section_len;
11c1ff18 13369 }
74e1a04b 13370 /* PR 17531: file: 001-101425-0.004 */
071436c6 13371 else if (attr_len < 5)
74e1a04b 13372 {
071436c6 13373 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
74e1a04b
NC
13374 break;
13375 }
e9847026 13376
071436c6
NC
13377 section_len -= attr_len;
13378 attr_len -= 4;
13379
13380 namelen = strnlen ((char *) p, attr_len) + 1;
13381 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
13382 {
13383 error (_("Corrupt attribute section name\n"));
13384 break;
13385 }
13386
071436c6
NC
13387 printf (_("Attribute Section: "));
13388 print_symbol (INT_MAX, (const char *) p);
13389 putchar ('\n');
60bca95a
NC
13390
13391 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
13392 public_section = TRUE;
13393 else
13394 public_section = FALSE;
60bca95a
NC
13395
13396 if (streq ((char *) p, "gnu"))
104d59d1
JM
13397 gnu_section = TRUE;
13398 else
13399 gnu_section = FALSE;
60bca95a 13400
11c1ff18 13401 p += namelen;
071436c6 13402 attr_len -= namelen;
e0a31db1 13403
071436c6 13404 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 13405 {
e0a31db1 13406 int tag;
11c1ff18
PB
13407 int val;
13408 bfd_vma size;
071436c6 13409 unsigned char * end;
60bca95a 13410
e0a31db1 13411 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 13412 if (attr_len < 6)
e0a31db1
NC
13413 {
13414 error (_("Unused bytes at end of section\n"));
13415 section_len = 0;
13416 break;
13417 }
13418
13419 tag = *(p++);
11c1ff18 13420 size = byte_get (p, 4);
071436c6 13421 if (size > attr_len)
11c1ff18 13422 {
e9847026 13423 error (_("Bad subsection length (%u > %u)\n"),
071436c6
NC
13424 (unsigned) size, (unsigned) attr_len);
13425 size = attr_len;
11c1ff18 13426 }
e0a31db1
NC
13427 /* PR binutils/17531: Safe handling of corrupt files. */
13428 if (size < 6)
13429 {
13430 error (_("Bad subsection length (%u < 6)\n"),
13431 (unsigned) size);
13432 section_len = 0;
13433 break;
13434 }
60bca95a 13435
071436c6 13436 attr_len -= size;
11c1ff18 13437 end = p + size - 1;
071436c6 13438 assert (end <= contents + sect->sh_size);
11c1ff18 13439 p += 4;
60bca95a 13440
11c1ff18
PB
13441 switch (tag)
13442 {
13443 case 1:
2b692964 13444 printf (_("File Attributes\n"));
11c1ff18
PB
13445 break;
13446 case 2:
2b692964 13447 printf (_("Section Attributes:"));
11c1ff18
PB
13448 goto do_numlist;
13449 case 3:
2b692964 13450 printf (_("Symbol Attributes:"));
11c1ff18
PB
13451 do_numlist:
13452 for (;;)
13453 {
91d6fa6a 13454 unsigned int j;
60bca95a 13455
f6f0e17b 13456 val = read_uleb128 (p, &j, end);
91d6fa6a 13457 p += j;
11c1ff18
PB
13458 if (val == 0)
13459 break;
13460 printf (" %d", val);
13461 }
13462 printf ("\n");
13463 break;
13464 default:
2b692964 13465 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
13466 public_section = FALSE;
13467 break;
13468 }
60bca95a 13469
071436c6 13470 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
13471 {
13472 while (p < end)
f6f0e17b 13473 p = display_pub_attribute (p, end);
071436c6 13474 assert (p <= end);
104d59d1 13475 }
071436c6 13476 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
13477 {
13478 while (p < end)
13479 p = display_gnu_attribute (p,
f6f0e17b
NC
13480 display_proc_gnu_attribute,
13481 end);
071436c6 13482 assert (p <= end);
11c1ff18 13483 }
071436c6 13484 else if (p < end)
11c1ff18 13485 {
071436c6 13486 printf (_(" Unknown attribute:\n"));
f6f0e17b 13487 display_raw_attribute (p, end);
11c1ff18
PB
13488 p = end;
13489 }
071436c6
NC
13490 else
13491 attr_len = 0;
11c1ff18
PB
13492 }
13493 }
13494 }
13495 else
e9847026 13496 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 13497
60bca95a 13498 free (contents);
11c1ff18
PB
13499 }
13500 return 1;
13501}
13502
104d59d1 13503static int
2cf0635d 13504process_arm_specific (FILE * file)
104d59d1
JM
13505{
13506 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
13507 display_arm_attribute, NULL);
13508}
13509
34c8bcba 13510static int
2cf0635d 13511process_power_specific (FILE * file)
34c8bcba
JM
13512{
13513 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13514 display_power_gnu_attribute);
13515}
13516
9e8c70f9
DM
13517static int
13518process_sparc_specific (FILE * file)
13519{
13520 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13521 display_sparc_gnu_attribute);
13522}
13523
59e6276b
JM
13524static int
13525process_tic6x_specific (FILE * file)
13526{
13527 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
13528 display_tic6x_attribute, NULL);
13529}
13530
13761a11
NC
13531static int
13532process_msp430x_specific (FILE * file)
13533{
13534 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
13535 display_msp430x_attribute, NULL);
13536}
13537
ccb4c951
RS
13538/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
13539 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
13540 and return the VMA of the next entry, or -1 if there was a problem.
13541 Does not read from DATA_END or beyond. */
ccb4c951
RS
13542
13543static bfd_vma
82b1b41b
NC
13544print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
13545 unsigned char * data_end)
ccb4c951
RS
13546{
13547 printf (" ");
13548 print_vma (addr, LONG_HEX);
13549 printf (" ");
13550 if (addr < pltgot + 0xfff0)
13551 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
13552 else
13553 printf ("%10s", "");
13554 printf (" ");
13555 if (data == NULL)
2b692964 13556 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
13557 else
13558 {
13559 bfd_vma entry;
82b1b41b 13560 unsigned char * from = data + addr - pltgot;
ccb4c951 13561
82b1b41b
NC
13562 if (from + (is_32bit_elf ? 4 : 8) > data_end)
13563 {
13564 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
13565 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
13566 return (bfd_vma) -1;
13567 }
13568 else
13569 {
13570 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13571 print_vma (entry, LONG_HEX);
13572 }
ccb4c951
RS
13573 }
13574 return addr + (is_32bit_elf ? 4 : 8);
13575}
13576
861fb55a
DJ
13577/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
13578 PLTGOT. Print the Address and Initial fields of an entry at VMA
13579 ADDR and return the VMA of the next entry. */
13580
13581static bfd_vma
2cf0635d 13582print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
13583{
13584 printf (" ");
13585 print_vma (addr, LONG_HEX);
13586 printf (" ");
13587 if (data == NULL)
2b692964 13588 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
13589 else
13590 {
13591 bfd_vma entry;
13592
13593 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13594 print_vma (entry, LONG_HEX);
13595 }
13596 return addr + (is_32bit_elf ? 4 : 8);
13597}
13598
351cdf24
MF
13599static void
13600print_mips_ases (unsigned int mask)
13601{
13602 if (mask & AFL_ASE_DSP)
13603 fputs ("\n\tDSP ASE", stdout);
13604 if (mask & AFL_ASE_DSPR2)
13605 fputs ("\n\tDSP R2 ASE", stdout);
13606 if (mask & AFL_ASE_EVA)
13607 fputs ("\n\tEnhanced VA Scheme", stdout);
13608 if (mask & AFL_ASE_MCU)
13609 fputs ("\n\tMCU (MicroController) ASE", stdout);
13610 if (mask & AFL_ASE_MDMX)
13611 fputs ("\n\tMDMX ASE", stdout);
13612 if (mask & AFL_ASE_MIPS3D)
13613 fputs ("\n\tMIPS-3D ASE", stdout);
13614 if (mask & AFL_ASE_MT)
13615 fputs ("\n\tMT ASE", stdout);
13616 if (mask & AFL_ASE_SMARTMIPS)
13617 fputs ("\n\tSmartMIPS ASE", stdout);
13618 if (mask & AFL_ASE_VIRT)
13619 fputs ("\n\tVZ ASE", stdout);
13620 if (mask & AFL_ASE_MSA)
13621 fputs ("\n\tMSA ASE", stdout);
13622 if (mask & AFL_ASE_MIPS16)
13623 fputs ("\n\tMIPS16 ASE", stdout);
13624 if (mask & AFL_ASE_MICROMIPS)
13625 fputs ("\n\tMICROMIPS ASE", stdout);
13626 if (mask & AFL_ASE_XPA)
13627 fputs ("\n\tXPA ASE", stdout);
13628 if (mask == 0)
13629 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
13630 else if ((mask & ~AFL_ASE_MASK) != 0)
13631 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
13632}
13633
13634static void
13635print_mips_isa_ext (unsigned int isa_ext)
13636{
13637 switch (isa_ext)
13638 {
13639 case 0:
13640 fputs (_("None"), stdout);
13641 break;
13642 case AFL_EXT_XLR:
13643 fputs ("RMI XLR", stdout);
13644 break;
2c629856
N
13645 case AFL_EXT_OCTEON3:
13646 fputs ("Cavium Networks Octeon3", stdout);
13647 break;
351cdf24
MF
13648 case AFL_EXT_OCTEON2:
13649 fputs ("Cavium Networks Octeon2", stdout);
13650 break;
13651 case AFL_EXT_OCTEONP:
13652 fputs ("Cavium Networks OcteonP", stdout);
13653 break;
13654 case AFL_EXT_LOONGSON_3A:
13655 fputs ("Loongson 3A", stdout);
13656 break;
13657 case AFL_EXT_OCTEON:
13658 fputs ("Cavium Networks Octeon", stdout);
13659 break;
13660 case AFL_EXT_5900:
13661 fputs ("Toshiba R5900", stdout);
13662 break;
13663 case AFL_EXT_4650:
13664 fputs ("MIPS R4650", stdout);
13665 break;
13666 case AFL_EXT_4010:
13667 fputs ("LSI R4010", stdout);
13668 break;
13669 case AFL_EXT_4100:
13670 fputs ("NEC VR4100", stdout);
13671 break;
13672 case AFL_EXT_3900:
13673 fputs ("Toshiba R3900", stdout);
13674 break;
13675 case AFL_EXT_10000:
13676 fputs ("MIPS R10000", stdout);
13677 break;
13678 case AFL_EXT_SB1:
13679 fputs ("Broadcom SB-1", stdout);
13680 break;
13681 case AFL_EXT_4111:
13682 fputs ("NEC VR4111/VR4181", stdout);
13683 break;
13684 case AFL_EXT_4120:
13685 fputs ("NEC VR4120", stdout);
13686 break;
13687 case AFL_EXT_5400:
13688 fputs ("NEC VR5400", stdout);
13689 break;
13690 case AFL_EXT_5500:
13691 fputs ("NEC VR5500", stdout);
13692 break;
13693 case AFL_EXT_LOONGSON_2E:
13694 fputs ("ST Microelectronics Loongson 2E", stdout);
13695 break;
13696 case AFL_EXT_LOONGSON_2F:
13697 fputs ("ST Microelectronics Loongson 2F", stdout);
13698 break;
13699 default:
00ac7aa0 13700 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
13701 }
13702}
13703
13704static int
13705get_mips_reg_size (int reg_size)
13706{
13707 return (reg_size == AFL_REG_NONE) ? 0
13708 : (reg_size == AFL_REG_32) ? 32
13709 : (reg_size == AFL_REG_64) ? 64
13710 : (reg_size == AFL_REG_128) ? 128
13711 : -1;
13712}
13713
19e6b90e 13714static int
2cf0635d 13715process_mips_specific (FILE * file)
5b18a4bc 13716{
2cf0635d 13717 Elf_Internal_Dyn * entry;
351cdf24 13718 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
13719 size_t liblist_offset = 0;
13720 size_t liblistno = 0;
13721 size_t conflictsno = 0;
13722 size_t options_offset = 0;
13723 size_t conflicts_offset = 0;
861fb55a
DJ
13724 size_t pltrelsz = 0;
13725 size_t pltrel = 0;
ccb4c951 13726 bfd_vma pltgot = 0;
861fb55a
DJ
13727 bfd_vma mips_pltgot = 0;
13728 bfd_vma jmprel = 0;
ccb4c951
RS
13729 bfd_vma local_gotno = 0;
13730 bfd_vma gotsym = 0;
13731 bfd_vma symtabno = 0;
103f02d3 13732
2cf19d5c
JM
13733 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13734 display_mips_gnu_attribute);
13735
351cdf24
MF
13736 sect = find_section (".MIPS.abiflags");
13737
13738 if (sect != NULL)
13739 {
13740 Elf_External_ABIFlags_v0 *abiflags_ext;
13741 Elf_Internal_ABIFlags_v0 abiflags_in;
13742
13743 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
13744 fputs ("\nCorrupt ABI Flags section.\n", stdout);
13745 else
13746 {
13747 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
13748 sect->sh_size, _("MIPS ABI Flags section"));
13749 if (abiflags_ext)
13750 {
13751 abiflags_in.version = BYTE_GET (abiflags_ext->version);
13752 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
13753 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
13754 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
13755 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
13756 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
13757 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
13758 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
13759 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
13760 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
13761 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
13762
13763 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
13764 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
13765 if (abiflags_in.isa_rev > 1)
13766 printf ("r%d", abiflags_in.isa_rev);
13767 printf ("\nGPR size: %d",
13768 get_mips_reg_size (abiflags_in.gpr_size));
13769 printf ("\nCPR1 size: %d",
13770 get_mips_reg_size (abiflags_in.cpr1_size));
13771 printf ("\nCPR2 size: %d",
13772 get_mips_reg_size (abiflags_in.cpr2_size));
13773 fputs ("\nFP ABI: ", stdout);
13774 print_mips_fp_abi_value (abiflags_in.fp_abi);
13775 fputs ("ISA Extension: ", stdout);
13776 print_mips_isa_ext (abiflags_in.isa_ext);
13777 fputs ("\nASEs:", stdout);
13778 print_mips_ases (abiflags_in.ases);
13779 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
13780 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
13781 fputc ('\n', stdout);
13782 free (abiflags_ext);
13783 }
13784 }
13785 }
13786
19e6b90e
L
13787 /* We have a lot of special sections. Thanks SGI! */
13788 if (dynamic_section == NULL)
13789 /* No information available. */
13790 return 0;
252b5132 13791
071436c6
NC
13792 for (entry = dynamic_section;
13793 /* PR 17531 file: 012-50589-0.004. */
13794 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
13795 ++entry)
252b5132
RH
13796 switch (entry->d_tag)
13797 {
13798 case DT_MIPS_LIBLIST:
d93f0186
NC
13799 liblist_offset
13800 = offset_from_vma (file, entry->d_un.d_val,
13801 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
13802 break;
13803 case DT_MIPS_LIBLISTNO:
13804 liblistno = entry->d_un.d_val;
13805 break;
13806 case DT_MIPS_OPTIONS:
d93f0186 13807 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
13808 break;
13809 case DT_MIPS_CONFLICT:
d93f0186
NC
13810 conflicts_offset
13811 = offset_from_vma (file, entry->d_un.d_val,
13812 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
13813 break;
13814 case DT_MIPS_CONFLICTNO:
13815 conflictsno = entry->d_un.d_val;
13816 break;
ccb4c951 13817 case DT_PLTGOT:
861fb55a
DJ
13818 pltgot = entry->d_un.d_ptr;
13819 break;
ccb4c951
RS
13820 case DT_MIPS_LOCAL_GOTNO:
13821 local_gotno = entry->d_un.d_val;
13822 break;
13823 case DT_MIPS_GOTSYM:
13824 gotsym = entry->d_un.d_val;
13825 break;
13826 case DT_MIPS_SYMTABNO:
13827 symtabno = entry->d_un.d_val;
13828 break;
861fb55a
DJ
13829 case DT_MIPS_PLTGOT:
13830 mips_pltgot = entry->d_un.d_ptr;
13831 break;
13832 case DT_PLTREL:
13833 pltrel = entry->d_un.d_val;
13834 break;
13835 case DT_PLTRELSZ:
13836 pltrelsz = entry->d_un.d_val;
13837 break;
13838 case DT_JMPREL:
13839 jmprel = entry->d_un.d_ptr;
13840 break;
252b5132
RH
13841 default:
13842 break;
13843 }
13844
13845 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
13846 {
2cf0635d 13847 Elf32_External_Lib * elib;
252b5132
RH
13848 size_t cnt;
13849
3f5e193b
NC
13850 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
13851 liblistno,
13852 sizeof (Elf32_External_Lib),
9cf03b7e 13853 _("liblist section data"));
a6e9f9df 13854 if (elib)
252b5132 13855 {
2b692964 13856 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 13857 (unsigned long) liblistno);
2b692964 13858 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
13859 stdout);
13860
13861 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 13862 {
a6e9f9df 13863 Elf32_Lib liblist;
91d6fa6a 13864 time_t atime;
a6e9f9df 13865 char timebuf[20];
2cf0635d 13866 struct tm * tmp;
a6e9f9df
AM
13867
13868 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13869 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
13870 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13871 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13872 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13873
91d6fa6a 13874 tmp = gmtime (&atime);
e9e44622
JJ
13875 snprintf (timebuf, sizeof (timebuf),
13876 "%04u-%02u-%02uT%02u:%02u:%02u",
13877 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13878 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 13879
31104126 13880 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
13881 if (VALID_DYNAMIC_NAME (liblist.l_name))
13882 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
13883 else
2b692964 13884 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
13885 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
13886 liblist.l_version);
a6e9f9df
AM
13887
13888 if (liblist.l_flags == 0)
2b692964 13889 puts (_(" NONE"));
a6e9f9df
AM
13890 else
13891 {
13892 static const struct
252b5132 13893 {
2cf0635d 13894 const char * name;
a6e9f9df 13895 int bit;
252b5132 13896 }
a6e9f9df
AM
13897 l_flags_vals[] =
13898 {
13899 { " EXACT_MATCH", LL_EXACT_MATCH },
13900 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
13901 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
13902 { " EXPORTS", LL_EXPORTS },
13903 { " DELAY_LOAD", LL_DELAY_LOAD },
13904 { " DELTA", LL_DELTA }
13905 };
13906 int flags = liblist.l_flags;
13907 size_t fcnt;
13908
60bca95a 13909 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
13910 if ((flags & l_flags_vals[fcnt].bit) != 0)
13911 {
13912 fputs (l_flags_vals[fcnt].name, stdout);
13913 flags ^= l_flags_vals[fcnt].bit;
13914 }
13915 if (flags != 0)
13916 printf (" %#x", (unsigned int) flags);
252b5132 13917
a6e9f9df
AM
13918 puts ("");
13919 }
252b5132 13920 }
252b5132 13921
a6e9f9df
AM
13922 free (elib);
13923 }
252b5132
RH
13924 }
13925
13926 if (options_offset != 0)
13927 {
2cf0635d 13928 Elf_External_Options * eopt;
2cf0635d
NC
13929 Elf_Internal_Options * iopt;
13930 Elf_Internal_Options * option;
252b5132
RH
13931 size_t offset;
13932 int cnt;
351cdf24 13933 sect = section_headers;
252b5132
RH
13934
13935 /* Find the section header so that we get the size. */
071436c6 13936 sect = find_section_by_type (SHT_MIPS_OPTIONS);
948f632f 13937 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
13938 if (sect == NULL)
13939 {
13940 error (_("No MIPS_OPTIONS header found\n"));
13941 return 0;
13942 }
252b5132 13943
3f5e193b
NC
13944 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
13945 sect->sh_size, _("options"));
a6e9f9df 13946 if (eopt)
252b5132 13947 {
3f5e193b
NC
13948 iopt = (Elf_Internal_Options *)
13949 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
13950 if (iopt == NULL)
13951 {
8b73c356 13952 error (_("Out of memory allocatinf space for MIPS options\n"));
a6e9f9df
AM
13953 return 0;
13954 }
76da6bbe 13955
a6e9f9df
AM
13956 offset = cnt = 0;
13957 option = iopt;
252b5132 13958
82b1b41b 13959 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 13960 {
2cf0635d 13961 Elf_External_Options * eoption;
252b5132 13962
a6e9f9df 13963 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 13964
a6e9f9df
AM
13965 option->kind = BYTE_GET (eoption->kind);
13966 option->size = BYTE_GET (eoption->size);
13967 option->section = BYTE_GET (eoption->section);
13968 option->info = BYTE_GET (eoption->info);
76da6bbe 13969
82b1b41b
NC
13970 /* PR 17531: file: ffa0fa3b. */
13971 if (option->size < sizeof (* eopt)
13972 || offset + option->size > sect->sh_size)
13973 {
55325047
NC
13974 error (_("Invalid size (%u) for MIPS option\n"), option->size);
13975 return 0;
82b1b41b 13976 }
a6e9f9df 13977 offset += option->size;
82b1b41b 13978
a6e9f9df
AM
13979 ++option;
13980 ++cnt;
13981 }
252b5132 13982
a6e9f9df 13983 printf (_("\nSection '%s' contains %d entries:\n"),
74e1a04b 13984 printable_section_name (sect), cnt);
76da6bbe 13985
a6e9f9df 13986 option = iopt;
82b1b41b 13987 offset = 0;
252b5132 13988
a6e9f9df 13989 while (cnt-- > 0)
252b5132 13990 {
a6e9f9df
AM
13991 size_t len;
13992
13993 switch (option->kind)
252b5132 13994 {
a6e9f9df
AM
13995 case ODK_NULL:
13996 /* This shouldn't happen. */
13997 printf (" NULL %d %lx", option->section, option->info);
13998 break;
13999 case ODK_REGINFO:
14000 printf (" REGINFO ");
14001 if (elf_header.e_machine == EM_MIPS)
14002 {
14003 /* 32bit form. */
2cf0635d 14004 Elf32_External_RegInfo * ereg;
b34976b6 14005 Elf32_RegInfo reginfo;
a6e9f9df
AM
14006
14007 ereg = (Elf32_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]);
14013 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
14014
14015 printf ("GPR %08lx GP 0x%lx\n",
14016 reginfo.ri_gprmask,
14017 (unsigned long) reginfo.ri_gp_value);
14018 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
14019 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
14020 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
14021 }
14022 else
14023 {
14024 /* 64 bit form. */
2cf0635d 14025 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
14026 Elf64_Internal_RegInfo reginfo;
14027
14028 ereg = (Elf64_External_RegInfo *) (option + 1);
14029 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
14030 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
14031 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
14032 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
14033 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 14034 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
14035
14036 printf ("GPR %08lx GP 0x",
14037 reginfo.ri_gprmask);
14038 printf_vma (reginfo.ri_gp_value);
14039 printf ("\n");
14040
14041 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
14042 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
14043 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
14044 }
14045 ++option;
14046 continue;
14047 case ODK_EXCEPTIONS:
14048 fputs (" EXCEPTIONS fpe_min(", stdout);
14049 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
14050 fputs (") fpe_max(", stdout);
14051 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
14052 fputs (")", stdout);
14053
14054 if (option->info & OEX_PAGE0)
14055 fputs (" PAGE0", stdout);
14056 if (option->info & OEX_SMM)
14057 fputs (" SMM", stdout);
14058 if (option->info & OEX_FPDBUG)
14059 fputs (" FPDBUG", stdout);
14060 if (option->info & OEX_DISMISS)
14061 fputs (" DISMISS", stdout);
14062 break;
14063 case ODK_PAD:
14064 fputs (" PAD ", stdout);
14065 if (option->info & OPAD_PREFIX)
14066 fputs (" PREFIX", stdout);
14067 if (option->info & OPAD_POSTFIX)
14068 fputs (" POSTFIX", stdout);
14069 if (option->info & OPAD_SYMBOL)
14070 fputs (" SYMBOL", stdout);
14071 break;
14072 case ODK_HWPATCH:
14073 fputs (" HWPATCH ", stdout);
14074 if (option->info & OHW_R4KEOP)
14075 fputs (" R4KEOP", stdout);
14076 if (option->info & OHW_R8KPFETCH)
14077 fputs (" R8KPFETCH", stdout);
14078 if (option->info & OHW_R5KEOP)
14079 fputs (" R5KEOP", stdout);
14080 if (option->info & OHW_R5KCVTL)
14081 fputs (" R5KCVTL", stdout);
14082 break;
14083 case ODK_FILL:
14084 fputs (" FILL ", stdout);
14085 /* XXX Print content of info word? */
14086 break;
14087 case ODK_TAGS:
14088 fputs (" TAGS ", stdout);
14089 /* XXX Print content of info word? */
14090 break;
14091 case ODK_HWAND:
14092 fputs (" HWAND ", stdout);
14093 if (option->info & OHWA0_R4KEOP_CHECKED)
14094 fputs (" R4KEOP_CHECKED", stdout);
14095 if (option->info & OHWA0_R4KEOP_CLEAN)
14096 fputs (" R4KEOP_CLEAN", stdout);
14097 break;
14098 case ODK_HWOR:
14099 fputs (" HWOR ", stdout);
14100 if (option->info & OHWA0_R4KEOP_CHECKED)
14101 fputs (" R4KEOP_CHECKED", stdout);
14102 if (option->info & OHWA0_R4KEOP_CLEAN)
14103 fputs (" R4KEOP_CLEAN", stdout);
14104 break;
14105 case ODK_GP_GROUP:
14106 printf (" GP_GROUP %#06lx self-contained %#06lx",
14107 option->info & OGP_GROUP,
14108 (option->info & OGP_SELF) >> 16);
14109 break;
14110 case ODK_IDENT:
14111 printf (" IDENT %#06lx self-contained %#06lx",
14112 option->info & OGP_GROUP,
14113 (option->info & OGP_SELF) >> 16);
14114 break;
14115 default:
14116 /* This shouldn't happen. */
14117 printf (" %3d ??? %d %lx",
14118 option->kind, option->section, option->info);
14119 break;
252b5132 14120 }
a6e9f9df 14121
2cf0635d 14122 len = sizeof (* eopt);
a6e9f9df 14123 while (len < option->size)
82b1b41b
NC
14124 {
14125 char datum = * ((char *) eopt + offset + len);
a6e9f9df 14126
82b1b41b
NC
14127 if (ISPRINT (datum))
14128 printf ("%c", datum);
14129 else
14130 printf ("\\%03o", datum);
14131 len ++;
14132 }
a6e9f9df 14133 fputs ("\n", stdout);
82b1b41b
NC
14134
14135 offset += option->size;
252b5132 14136 ++option;
252b5132
RH
14137 }
14138
a6e9f9df 14139 free (eopt);
252b5132 14140 }
252b5132
RH
14141 }
14142
14143 if (conflicts_offset != 0 && conflictsno != 0)
14144 {
2cf0635d 14145 Elf32_Conflict * iconf;
252b5132
RH
14146 size_t cnt;
14147
14148 if (dynamic_symbols == NULL)
14149 {
591a748a 14150 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
14151 return 0;
14152 }
14153
3f5e193b 14154 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
14155 if (iconf == NULL)
14156 {
8b73c356 14157 error (_("Out of memory allocating space for dynamic conflicts\n"));
252b5132
RH
14158 return 0;
14159 }
14160
9ea033b2 14161 if (is_32bit_elf)
252b5132 14162 {
2cf0635d 14163 Elf32_External_Conflict * econf32;
a6e9f9df 14164
3f5e193b
NC
14165 econf32 = (Elf32_External_Conflict *)
14166 get_data (NULL, file, conflicts_offset, conflictsno,
14167 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
14168 if (!econf32)
14169 return 0;
252b5132
RH
14170
14171 for (cnt = 0; cnt < conflictsno; ++cnt)
14172 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
14173
14174 free (econf32);
252b5132
RH
14175 }
14176 else
14177 {
2cf0635d 14178 Elf64_External_Conflict * econf64;
a6e9f9df 14179
3f5e193b
NC
14180 econf64 = (Elf64_External_Conflict *)
14181 get_data (NULL, file, conflicts_offset, conflictsno,
14182 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
14183 if (!econf64)
14184 return 0;
252b5132
RH
14185
14186 for (cnt = 0; cnt < conflictsno; ++cnt)
14187 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
14188
14189 free (econf64);
252b5132
RH
14190 }
14191
c7e7ca54
NC
14192 printf (_("\nSection '.conflict' contains %lu entries:\n"),
14193 (unsigned long) conflictsno);
252b5132
RH
14194 puts (_(" Num: Index Value Name"));
14195
14196 for (cnt = 0; cnt < conflictsno; ++cnt)
14197 {
b34976b6 14198 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
14199
14200 if (iconf[cnt] >= num_dynamic_syms)
14201 printf (_("<corrupt symbol index>"));
d79b3d50 14202 else
e0a31db1
NC
14203 {
14204 Elf_Internal_Sym * psym;
14205
14206 psym = & dynamic_symbols[iconf[cnt]];
14207 print_vma (psym->st_value, FULL_HEX);
14208 putchar (' ');
14209 if (VALID_DYNAMIC_NAME (psym->st_name))
14210 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
14211 else
14212 printf (_("<corrupt: %14ld>"), psym->st_name);
14213 }
31104126 14214 putchar ('\n');
252b5132
RH
14215 }
14216
252b5132
RH
14217 free (iconf);
14218 }
14219
ccb4c951
RS
14220 if (pltgot != 0 && local_gotno != 0)
14221 {
91d6fa6a 14222 bfd_vma ent, local_end, global_end;
bbeee7ea 14223 size_t i, offset;
2cf0635d 14224 unsigned char * data;
82b1b41b 14225 unsigned char * data_end;
bbeee7ea 14226 int addr_size;
ccb4c951 14227
91d6fa6a 14228 ent = pltgot;
ccb4c951
RS
14229 addr_size = (is_32bit_elf ? 4 : 8);
14230 local_end = pltgot + local_gotno * addr_size;
ccb4c951 14231
74e1a04b
NC
14232 /* PR binutils/17533 file: 012-111227-0.004 */
14233 if (symtabno < gotsym)
14234 {
14235 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 14236 (unsigned long) gotsym, (unsigned long) symtabno);
74e1a04b
NC
14237 return 0;
14238 }
82b1b41b 14239
74e1a04b 14240 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
14241 /* PR 17531: file: 54c91a34. */
14242 if (global_end < local_end)
14243 {
14244 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
14245 return 0;
14246 }
948f632f 14247
ccb4c951 14248 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 14249 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
14250 global_end - pltgot, 1,
14251 _("Global Offset Table data"));
59245841
NC
14252 if (data == NULL)
14253 return 0;
82b1b41b 14254 data_end = data + (global_end - pltgot);
59245841 14255
ccb4c951
RS
14256 printf (_("\nPrimary GOT:\n"));
14257 printf (_(" Canonical gp value: "));
14258 print_vma (pltgot + 0x7ff0, LONG_HEX);
14259 printf ("\n\n");
14260
14261 printf (_(" Reserved entries:\n"));
14262 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
14263 addr_size * 2, _("Address"), _("Access"),
14264 addr_size * 2, _("Initial"));
82b1b41b 14265 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 14266 printf (_(" Lazy resolver\n"));
82b1b41b
NC
14267 if (ent == (bfd_vma) -1)
14268 goto got_print_fail;
ccb4c951 14269 if (data
91d6fa6a 14270 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
14271 >> (addr_size * 8 - 1)) != 0)
14272 {
82b1b41b 14273 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 14274 printf (_(" Module pointer (GNU extension)\n"));
82b1b41b
NC
14275 if (ent == (bfd_vma) -1)
14276 goto got_print_fail;
ccb4c951
RS
14277 }
14278 printf ("\n");
14279
91d6fa6a 14280 if (ent < local_end)
ccb4c951
RS
14281 {
14282 printf (_(" Local entries:\n"));
cc5914eb 14283 printf (" %*s %10s %*s\n",
2b692964
NC
14284 addr_size * 2, _("Address"), _("Access"),
14285 addr_size * 2, _("Initial"));
91d6fa6a 14286 while (ent < local_end)
ccb4c951 14287 {
82b1b41b 14288 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 14289 printf ("\n");
82b1b41b
NC
14290 if (ent == (bfd_vma) -1)
14291 goto got_print_fail;
ccb4c951
RS
14292 }
14293 printf ("\n");
14294 }
14295
14296 if (gotsym < symtabno)
14297 {
14298 int sym_width;
14299
14300 printf (_(" Global entries:\n"));
cc5914eb 14301 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
14302 addr_size * 2, _("Address"),
14303 _("Access"),
2b692964 14304 addr_size * 2, _("Initial"),
9cf03b7e
NC
14305 addr_size * 2, _("Sym.Val."),
14306 _("Type"),
14307 /* Note for translators: "Ndx" = abbreviated form of "Index". */
14308 _("Ndx"), _("Name"));
0b4362b0 14309
ccb4c951 14310 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 14311
ccb4c951
RS
14312 for (i = gotsym; i < symtabno; i++)
14313 {
82b1b41b 14314 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 14315 printf (" ");
e0a31db1
NC
14316
14317 if (dynamic_symbols == NULL)
14318 printf (_("<no dynamic symbols>"));
14319 else if (i < num_dynamic_syms)
14320 {
14321 Elf_Internal_Sym * psym = dynamic_symbols + i;
14322
14323 print_vma (psym->st_value, LONG_HEX);
14324 printf (" %-7s %3s ",
14325 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14326 get_symbol_index_type (psym->st_shndx));
14327
14328 if (VALID_DYNAMIC_NAME (psym->st_name))
14329 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14330 else
14331 printf (_("<corrupt: %14ld>"), psym->st_name);
14332 }
ccb4c951 14333 else
7fc5ac57
JBG
14334 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
14335 (unsigned long) i);
e0a31db1 14336
ccb4c951 14337 printf ("\n");
82b1b41b
NC
14338 if (ent == (bfd_vma) -1)
14339 break;
ccb4c951
RS
14340 }
14341 printf ("\n");
14342 }
14343
82b1b41b 14344 got_print_fail:
ccb4c951
RS
14345 if (data)
14346 free (data);
14347 }
14348
861fb55a
DJ
14349 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
14350 {
91d6fa6a 14351 bfd_vma ent, end;
861fb55a
DJ
14352 size_t offset, rel_offset;
14353 unsigned long count, i;
2cf0635d 14354 unsigned char * data;
861fb55a 14355 int addr_size, sym_width;
2cf0635d 14356 Elf_Internal_Rela * rels;
861fb55a
DJ
14357
14358 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
14359 if (pltrel == DT_RELA)
14360 {
14361 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
14362 return 0;
14363 }
14364 else
14365 {
14366 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
14367 return 0;
14368 }
14369
91d6fa6a 14370 ent = mips_pltgot;
861fb55a
DJ
14371 addr_size = (is_32bit_elf ? 4 : 8);
14372 end = mips_pltgot + (2 + count) * addr_size;
14373
14374 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 14375 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 14376 1, _("Procedure Linkage Table data"));
59245841
NC
14377 if (data == NULL)
14378 return 0;
14379
9cf03b7e 14380 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
14381 printf (_(" Reserved entries:\n"));
14382 printf (_(" %*s %*s Purpose\n"),
2b692964 14383 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 14384 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14385 printf (_(" PLT lazy resolver\n"));
91d6fa6a 14386 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14387 printf (_(" Module pointer\n"));
861fb55a
DJ
14388 printf ("\n");
14389
14390 printf (_(" Entries:\n"));
cc5914eb 14391 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
14392 addr_size * 2, _("Address"),
14393 addr_size * 2, _("Initial"),
14394 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
14395 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
14396 for (i = 0; i < count; i++)
14397 {
df97ab2a 14398 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 14399
91d6fa6a 14400 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 14401 printf (" ");
e0a31db1 14402
df97ab2a
MF
14403 if (idx >= num_dynamic_syms)
14404 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 14405 else
e0a31db1 14406 {
df97ab2a 14407 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
14408
14409 print_vma (psym->st_value, LONG_HEX);
14410 printf (" %-7s %3s ",
14411 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14412 get_symbol_index_type (psym->st_shndx));
14413 if (VALID_DYNAMIC_NAME (psym->st_name))
14414 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14415 else
14416 printf (_("<corrupt: %14ld>"), psym->st_name);
14417 }
861fb55a
DJ
14418 printf ("\n");
14419 }
14420 printf ("\n");
14421
14422 if (data)
14423 free (data);
14424 free (rels);
14425 }
14426
252b5132
RH
14427 return 1;
14428}
14429
35c08157
KLC
14430static int
14431process_nds32_specific (FILE * file)
14432{
14433 Elf_Internal_Shdr *sect = NULL;
14434
14435 sect = find_section (".nds32_e_flags");
14436 if (sect != NULL)
14437 {
14438 unsigned int *flag;
14439
14440 printf ("\nNDS32 elf flags section:\n");
14441 flag = get_data (NULL, file, sect->sh_offset, 1,
14442 sect->sh_size, _("NDS32 elf flags section"));
14443
14444 switch ((*flag) & 0x3)
14445 {
14446 case 0:
14447 printf ("(VEC_SIZE):\tNo entry.\n");
14448 break;
14449 case 1:
14450 printf ("(VEC_SIZE):\t4 bytes\n");
14451 break;
14452 case 2:
14453 printf ("(VEC_SIZE):\t16 bytes\n");
14454 break;
14455 case 3:
14456 printf ("(VEC_SIZE):\treserved\n");
14457 break;
14458 }
14459 }
14460
14461 return TRUE;
14462}
14463
047b2264 14464static int
2cf0635d 14465process_gnu_liblist (FILE * file)
047b2264 14466{
2cf0635d
NC
14467 Elf_Internal_Shdr * section;
14468 Elf_Internal_Shdr * string_sec;
14469 Elf32_External_Lib * elib;
14470 char * strtab;
c256ffe7 14471 size_t strtab_size;
047b2264
JJ
14472 size_t cnt;
14473 unsigned i;
14474
14475 if (! do_arch)
14476 return 0;
14477
14478 for (i = 0, section = section_headers;
14479 i < elf_header.e_shnum;
b34976b6 14480 i++, section++)
047b2264
JJ
14481 {
14482 switch (section->sh_type)
14483 {
14484 case SHT_GNU_LIBLIST:
4fbb74a6 14485 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
14486 break;
14487
3f5e193b
NC
14488 elib = (Elf32_External_Lib *)
14489 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 14490 _("liblist section data"));
047b2264
JJ
14491
14492 if (elib == NULL)
14493 break;
4fbb74a6 14494 string_sec = section_headers + section->sh_link;
047b2264 14495
3f5e193b
NC
14496 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
14497 string_sec->sh_size,
14498 _("liblist string table"));
047b2264
JJ
14499 if (strtab == NULL
14500 || section->sh_entsize != sizeof (Elf32_External_Lib))
14501 {
14502 free (elib);
2842702f 14503 free (strtab);
047b2264
JJ
14504 break;
14505 }
59245841 14506 strtab_size = string_sec->sh_size;
047b2264
JJ
14507
14508 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
74e1a04b 14509 printable_section_name (section),
0af1713e 14510 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 14511
2b692964 14512 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
14513
14514 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
14515 ++cnt)
14516 {
14517 Elf32_Lib liblist;
91d6fa6a 14518 time_t atime;
047b2264 14519 char timebuf[20];
2cf0635d 14520 struct tm * tmp;
047b2264
JJ
14521
14522 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14523 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
14524 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14525 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14526 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14527
91d6fa6a 14528 tmp = gmtime (&atime);
e9e44622
JJ
14529 snprintf (timebuf, sizeof (timebuf),
14530 "%04u-%02u-%02uT%02u:%02u:%02u",
14531 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14532 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
14533
14534 printf ("%3lu: ", (unsigned long) cnt);
14535 if (do_wide)
c256ffe7 14536 printf ("%-20s", liblist.l_name < strtab_size
2b692964 14537 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 14538 else
c256ffe7 14539 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 14540 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
14541 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
14542 liblist.l_version, liblist.l_flags);
14543 }
14544
14545 free (elib);
2842702f 14546 free (strtab);
047b2264
JJ
14547 }
14548 }
14549
14550 return 1;
14551}
14552
9437c45b 14553static const char *
d3ba0551 14554get_note_type (unsigned e_type)
779fe533
NC
14555{
14556 static char buff[64];
103f02d3 14557
1ec5cd37
NC
14558 if (elf_header.e_type == ET_CORE)
14559 switch (e_type)
14560 {
57346661 14561 case NT_AUXV:
1ec5cd37 14562 return _("NT_AUXV (auxiliary vector)");
57346661 14563 case NT_PRSTATUS:
1ec5cd37 14564 return _("NT_PRSTATUS (prstatus structure)");
57346661 14565 case NT_FPREGSET:
1ec5cd37 14566 return _("NT_FPREGSET (floating point registers)");
57346661 14567 case NT_PRPSINFO:
1ec5cd37 14568 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 14569 case NT_TASKSTRUCT:
1ec5cd37 14570 return _("NT_TASKSTRUCT (task structure)");
57346661 14571 case NT_PRXFPREG:
1ec5cd37 14572 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
14573 case NT_PPC_VMX:
14574 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
14575 case NT_PPC_VSX:
14576 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
14577 case NT_386_TLS:
14578 return _("NT_386_TLS (x86 TLS information)");
14579 case NT_386_IOPERM:
14580 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
14581 case NT_X86_XSTATE:
14582 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
14583 case NT_S390_HIGH_GPRS:
14584 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
14585 case NT_S390_TIMER:
14586 return _("NT_S390_TIMER (s390 timer register)");
14587 case NT_S390_TODCMP:
14588 return _("NT_S390_TODCMP (s390 TOD comparator register)");
14589 case NT_S390_TODPREG:
14590 return _("NT_S390_TODPREG (s390 TOD programmable register)");
14591 case NT_S390_CTRS:
14592 return _("NT_S390_CTRS (s390 control registers)");
14593 case NT_S390_PREFIX:
14594 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
14595 case NT_S390_LAST_BREAK:
14596 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
14597 case NT_S390_SYSTEM_CALL:
14598 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
14599 case NT_S390_TDB:
14600 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
14601 case NT_S390_VXRS_LOW:
14602 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
14603 case NT_S390_VXRS_HIGH:
14604 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
faa9a424
UW
14605 case NT_ARM_VFP:
14606 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
14607 case NT_ARM_TLS:
14608 return _("NT_ARM_TLS (AArch TLS registers)");
14609 case NT_ARM_HW_BREAK:
14610 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
14611 case NT_ARM_HW_WATCH:
14612 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 14613 case NT_PSTATUS:
1ec5cd37 14614 return _("NT_PSTATUS (pstatus structure)");
57346661 14615 case NT_FPREGS:
1ec5cd37 14616 return _("NT_FPREGS (floating point registers)");
57346661 14617 case NT_PSINFO:
1ec5cd37 14618 return _("NT_PSINFO (psinfo structure)");
57346661 14619 case NT_LWPSTATUS:
1ec5cd37 14620 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 14621 case NT_LWPSINFO:
1ec5cd37 14622 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 14623 case NT_WIN32PSTATUS:
1ec5cd37 14624 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
14625 case NT_SIGINFO:
14626 return _("NT_SIGINFO (siginfo_t data)");
14627 case NT_FILE:
14628 return _("NT_FILE (mapped files)");
1ec5cd37
NC
14629 default:
14630 break;
14631 }
14632 else
14633 switch (e_type)
14634 {
14635 case NT_VERSION:
14636 return _("NT_VERSION (version)");
14637 case NT_ARCH:
14638 return _("NT_ARCH (architecture)");
14639 default:
14640 break;
14641 }
14642
e9e44622 14643 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 14644 return buff;
779fe533
NC
14645}
14646
9ece1fa9
TT
14647static int
14648print_core_note (Elf_Internal_Note *pnote)
14649{
14650 unsigned int addr_size = is_32bit_elf ? 4 : 8;
14651 bfd_vma count, page_size;
14652 unsigned char *descdata, *filenames, *descend;
14653
14654 if (pnote->type != NT_FILE)
14655 return 1;
14656
14657#ifndef BFD64
14658 if (!is_32bit_elf)
14659 {
14660 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
14661 /* Still "successful". */
14662 return 1;
14663 }
14664#endif
14665
14666 if (pnote->descsz < 2 * addr_size)
14667 {
14668 printf (_(" Malformed note - too short for header\n"));
14669 return 0;
14670 }
14671
14672 descdata = (unsigned char *) pnote->descdata;
14673 descend = descdata + pnote->descsz;
14674
14675 if (descdata[pnote->descsz - 1] != '\0')
14676 {
14677 printf (_(" Malformed note - does not end with \\0\n"));
14678 return 0;
14679 }
14680
14681 count = byte_get (descdata, addr_size);
14682 descdata += addr_size;
14683
14684 page_size = byte_get (descdata, addr_size);
14685 descdata += addr_size;
14686
14687 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
14688 {
14689 printf (_(" Malformed note - too short for supplied file count\n"));
14690 return 0;
14691 }
14692
14693 printf (_(" Page size: "));
14694 print_vma (page_size, DEC);
14695 printf ("\n");
14696
14697 printf (_(" %*s%*s%*s\n"),
14698 (int) (2 + 2 * addr_size), _("Start"),
14699 (int) (4 + 2 * addr_size), _("End"),
14700 (int) (4 + 2 * addr_size), _("Page Offset"));
14701 filenames = descdata + count * 3 * addr_size;
14702 while (--count > 0)
14703 {
14704 bfd_vma start, end, file_ofs;
14705
14706 if (filenames == descend)
14707 {
14708 printf (_(" Malformed note - filenames end too early\n"));
14709 return 0;
14710 }
14711
14712 start = byte_get (descdata, addr_size);
14713 descdata += addr_size;
14714 end = byte_get (descdata, addr_size);
14715 descdata += addr_size;
14716 file_ofs = byte_get (descdata, addr_size);
14717 descdata += addr_size;
14718
14719 printf (" ");
14720 print_vma (start, FULL_HEX);
14721 printf (" ");
14722 print_vma (end, FULL_HEX);
14723 printf (" ");
14724 print_vma (file_ofs, FULL_HEX);
14725 printf ("\n %s\n", filenames);
14726
14727 filenames += 1 + strlen ((char *) filenames);
14728 }
14729
14730 return 1;
14731}
14732
1118d252
RM
14733static const char *
14734get_gnu_elf_note_type (unsigned e_type)
14735{
14736 static char buff[64];
14737
14738 switch (e_type)
14739 {
14740 case NT_GNU_ABI_TAG:
14741 return _("NT_GNU_ABI_TAG (ABI version tag)");
14742 case NT_GNU_HWCAP:
14743 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
14744 case NT_GNU_BUILD_ID:
14745 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
14746 case NT_GNU_GOLD_VERSION:
14747 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
14748 default:
14749 break;
14750 }
14751
14752 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14753 return buff;
14754}
14755
664f90a3
TT
14756static int
14757print_gnu_note (Elf_Internal_Note *pnote)
14758{
14759 switch (pnote->type)
14760 {
14761 case NT_GNU_BUILD_ID:
14762 {
14763 unsigned long i;
14764
14765 printf (_(" Build ID: "));
14766 for (i = 0; i < pnote->descsz; ++i)
14767 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 14768 printf ("\n");
664f90a3
TT
14769 }
14770 break;
14771
14772 case NT_GNU_ABI_TAG:
14773 {
14774 unsigned long os, major, minor, subminor;
14775 const char *osname;
14776
3102e897
NC
14777 /* PR 17531: file: 030-599401-0.004. */
14778 if (pnote->descsz < 16)
14779 {
14780 printf (_(" <corrupt GNU_ABI_TAG>\n"));
14781 break;
14782 }
14783
664f90a3
TT
14784 os = byte_get ((unsigned char *) pnote->descdata, 4);
14785 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
14786 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
14787 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
14788
14789 switch (os)
14790 {
14791 case GNU_ABI_TAG_LINUX:
14792 osname = "Linux";
14793 break;
14794 case GNU_ABI_TAG_HURD:
14795 osname = "Hurd";
14796 break;
14797 case GNU_ABI_TAG_SOLARIS:
14798 osname = "Solaris";
14799 break;
14800 case GNU_ABI_TAG_FREEBSD:
14801 osname = "FreeBSD";
14802 break;
14803 case GNU_ABI_TAG_NETBSD:
14804 osname = "NetBSD";
14805 break;
14806 default:
14807 osname = "Unknown";
14808 break;
14809 }
14810
14811 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
14812 major, minor, subminor);
14813 }
14814 break;
926c5385
CC
14815
14816 case NT_GNU_GOLD_VERSION:
14817 {
14818 unsigned long i;
14819
14820 printf (_(" Version: "));
14821 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
14822 printf ("%c", pnote->descdata[i]);
14823 printf ("\n");
14824 }
14825 break;
664f90a3
TT
14826 }
14827
14828 return 1;
14829}
14830
685080f2
NC
14831static const char *
14832get_v850_elf_note_type (enum v850_notes n_type)
14833{
14834 static char buff[64];
14835
14836 switch (n_type)
14837 {
14838 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
14839 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
14840 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
14841 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
14842 case V850_NOTE_CACHE_INFO: return _("Use of cache");
14843 case V850_NOTE_MMU_INFO: return _("Use of MMU");
14844 default:
14845 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
14846 return buff;
14847 }
14848}
14849
14850static int
14851print_v850_note (Elf_Internal_Note * pnote)
14852{
14853 unsigned int val;
14854
14855 if (pnote->descsz != 4)
14856 return 0;
14857 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
14858
14859 if (val == 0)
14860 {
14861 printf (_("not set\n"));
14862 return 1;
14863 }
14864
14865 switch (pnote->type)
14866 {
14867 case V850_NOTE_ALIGNMENT:
14868 switch (val)
14869 {
14870 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return 1;
14871 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return 1;
14872 }
14873 break;
14874
14875 case V850_NOTE_DATA_SIZE:
14876 switch (val)
14877 {
14878 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return 1;
14879 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return 1;
14880 }
14881 break;
14882
14883 case V850_NOTE_FPU_INFO:
14884 switch (val)
14885 {
14886 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return 1;
14887 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return 1;
14888 }
14889 break;
14890
14891 case V850_NOTE_MMU_INFO:
14892 case V850_NOTE_CACHE_INFO:
14893 case V850_NOTE_SIMD_INFO:
14894 if (val == EF_RH850_SIMD)
14895 {
14896 printf (_("yes\n"));
14897 return 1;
14898 }
14899 break;
14900
14901 default:
14902 /* An 'unknown note type' message will already have been displayed. */
14903 break;
14904 }
14905
14906 printf (_("unknown value: %x\n"), val);
14907 return 0;
14908}
14909
9437c45b 14910static const char *
d3ba0551 14911get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
14912{
14913 static char buff[64];
14914
b4db1224 14915 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
14916 {
14917 /* NetBSD core "procinfo" structure. */
14918 return _("NetBSD procinfo structure");
14919 }
14920
14921 /* As of Jan 2002 there are no other machine-independent notes
14922 defined for NetBSD core files. If the note type is less
14923 than the start of the machine-dependent note types, we don't
14924 understand it. */
14925
b4db1224 14926 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 14927 {
e9e44622 14928 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
14929 return buff;
14930 }
14931
14932 switch (elf_header.e_machine)
14933 {
14934 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
14935 and PT_GETFPREGS == mach+2. */
14936
14937 case EM_OLD_ALPHA:
14938 case EM_ALPHA:
14939 case EM_SPARC:
14940 case EM_SPARC32PLUS:
14941 case EM_SPARCV9:
14942 switch (e_type)
14943 {
2b692964 14944 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 14945 return _("PT_GETREGS (reg structure)");
2b692964 14946 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 14947 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14948 default:
14949 break;
14950 }
14951 break;
14952
14953 /* On all other arch's, PT_GETREGS == mach+1 and
14954 PT_GETFPREGS == mach+3. */
14955 default:
14956 switch (e_type)
14957 {
2b692964 14958 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 14959 return _("PT_GETREGS (reg structure)");
2b692964 14960 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 14961 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14962 default:
14963 break;
14964 }
14965 }
14966
9cf03b7e 14967 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 14968 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
14969 return buff;
14970}
14971
70616151
TT
14972static const char *
14973get_stapsdt_note_type (unsigned e_type)
14974{
14975 static char buff[64];
14976
14977 switch (e_type)
14978 {
14979 case NT_STAPSDT:
14980 return _("NT_STAPSDT (SystemTap probe descriptors)");
14981
14982 default:
14983 break;
14984 }
14985
14986 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14987 return buff;
14988}
14989
c6a9fc58
TT
14990static int
14991print_stapsdt_note (Elf_Internal_Note *pnote)
14992{
14993 int addr_size = is_32bit_elf ? 4 : 8;
14994 char *data = pnote->descdata;
14995 char *data_end = pnote->descdata + pnote->descsz;
14996 bfd_vma pc, base_addr, semaphore;
14997 char *provider, *probe, *arg_fmt;
14998
14999 pc = byte_get ((unsigned char *) data, addr_size);
15000 data += addr_size;
15001 base_addr = byte_get ((unsigned char *) data, addr_size);
15002 data += addr_size;
15003 semaphore = byte_get ((unsigned char *) data, addr_size);
15004 data += addr_size;
15005
15006 provider = data;
15007 data += strlen (data) + 1;
15008 probe = data;
15009 data += strlen (data) + 1;
15010 arg_fmt = data;
15011 data += strlen (data) + 1;
15012
15013 printf (_(" Provider: %s\n"), provider);
15014 printf (_(" Name: %s\n"), probe);
15015 printf (_(" Location: "));
15016 print_vma (pc, FULL_HEX);
15017 printf (_(", Base: "));
15018 print_vma (base_addr, FULL_HEX);
15019 printf (_(", Semaphore: "));
15020 print_vma (semaphore, FULL_HEX);
9cf03b7e 15021 printf ("\n");
c6a9fc58
TT
15022 printf (_(" Arguments: %s\n"), arg_fmt);
15023
15024 return data == data_end;
15025}
15026
00e98fc7
TG
15027static const char *
15028get_ia64_vms_note_type (unsigned e_type)
15029{
15030 static char buff[64];
15031
15032 switch (e_type)
15033 {
15034 case NT_VMS_MHD:
15035 return _("NT_VMS_MHD (module header)");
15036 case NT_VMS_LNM:
15037 return _("NT_VMS_LNM (language name)");
15038 case NT_VMS_SRC:
15039 return _("NT_VMS_SRC (source files)");
15040 case NT_VMS_TITLE:
9cf03b7e 15041 return "NT_VMS_TITLE";
00e98fc7
TG
15042 case NT_VMS_EIDC:
15043 return _("NT_VMS_EIDC (consistency check)");
15044 case NT_VMS_FPMODE:
15045 return _("NT_VMS_FPMODE (FP mode)");
15046 case NT_VMS_LINKTIME:
9cf03b7e 15047 return "NT_VMS_LINKTIME";
00e98fc7
TG
15048 case NT_VMS_IMGNAM:
15049 return _("NT_VMS_IMGNAM (image name)");
15050 case NT_VMS_IMGID:
15051 return _("NT_VMS_IMGID (image id)");
15052 case NT_VMS_LINKID:
15053 return _("NT_VMS_LINKID (link id)");
15054 case NT_VMS_IMGBID:
15055 return _("NT_VMS_IMGBID (build id)");
15056 case NT_VMS_GSTNAM:
15057 return _("NT_VMS_GSTNAM (sym table name)");
15058 case NT_VMS_ORIG_DYN:
9cf03b7e 15059 return "NT_VMS_ORIG_DYN";
00e98fc7 15060 case NT_VMS_PATCHTIME:
9cf03b7e 15061 return "NT_VMS_PATCHTIME";
00e98fc7
TG
15062 default:
15063 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
15064 return buff;
15065 }
15066}
15067
15068static int
15069print_ia64_vms_note (Elf_Internal_Note * pnote)
15070{
15071 switch (pnote->type)
15072 {
15073 case NT_VMS_MHD:
15074 if (pnote->descsz > 36)
15075 {
15076 size_t l = strlen (pnote->descdata + 34);
15077 printf (_(" Creation date : %.17s\n"), pnote->descdata);
15078 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
15079 printf (_(" Module name : %s\n"), pnote->descdata + 34);
15080 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
15081 }
15082 else
15083 printf (_(" Invalid size\n"));
15084 break;
15085 case NT_VMS_LNM:
15086 printf (_(" Language: %s\n"), pnote->descdata);
15087 break;
15088#ifdef BFD64
15089 case NT_VMS_FPMODE:
9cf03b7e 15090 printf (_(" Floating Point mode: "));
4a5cb34f 15091 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 15092 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
15093 break;
15094 case NT_VMS_LINKTIME:
15095 printf (_(" Link time: "));
15096 print_vms_time
15097 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
15098 printf ("\n");
15099 break;
15100 case NT_VMS_PATCHTIME:
15101 printf (_(" Patch time: "));
15102 print_vms_time
15103 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
15104 printf ("\n");
15105 break;
15106 case NT_VMS_ORIG_DYN:
15107 printf (_(" Major id: %u, minor id: %u\n"),
15108 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
15109 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 15110 printf (_(" Last modified : "));
00e98fc7
TG
15111 print_vms_time
15112 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 15113 printf (_("\n Link flags : "));
4a5cb34f 15114 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 15115 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 15116 printf (_(" Header flags: 0x%08x\n"),
948f632f 15117 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
00e98fc7
TG
15118 printf (_(" Image id : %s\n"), pnote->descdata + 32);
15119 break;
15120#endif
15121 case NT_VMS_IMGNAM:
15122 printf (_(" Image name: %s\n"), pnote->descdata);
15123 break;
15124 case NT_VMS_GSTNAM:
15125 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
15126 break;
15127 case NT_VMS_IMGID:
15128 printf (_(" Image id: %s\n"), pnote->descdata);
15129 break;
15130 case NT_VMS_LINKID:
15131 printf (_(" Linker id: %s\n"), pnote->descdata);
15132 break;
15133 default:
15134 break;
15135 }
15136 return 1;
15137}
15138
6d118b09
NC
15139/* Note that by the ELF standard, the name field is already null byte
15140 terminated, and namesz includes the terminating null byte.
15141 I.E. the value of namesz for the name "FSF" is 4.
15142
e3c8793a 15143 If the value of namesz is zero, there is no name present. */
779fe533 15144static int
2cf0635d 15145process_note (Elf_Internal_Note * pnote)
779fe533 15146{
2cf0635d
NC
15147 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
15148 const char * nt;
9437c45b
JT
15149
15150 if (pnote->namesz == 0)
1ec5cd37
NC
15151 /* If there is no note name, then use the default set of
15152 note type strings. */
15153 nt = get_note_type (pnote->type);
15154
1118d252
RM
15155 else if (const_strneq (pnote->namedata, "GNU"))
15156 /* GNU-specific object file notes. */
15157 nt = get_gnu_elf_note_type (pnote->type);
15158
0112cd26 15159 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
15160 /* NetBSD-specific core file notes. */
15161 nt = get_netbsd_elfcore_note_type (pnote->type);
15162
b15fa79e
AM
15163 else if (strneq (pnote->namedata, "SPU/", 4))
15164 {
15165 /* SPU-specific core file notes. */
15166 nt = pnote->namedata + 4;
15167 name = "SPU";
15168 }
15169
00e98fc7
TG
15170 else if (const_strneq (pnote->namedata, "IPF/VMS"))
15171 /* VMS/ia64-specific file notes. */
15172 nt = get_ia64_vms_note_type (pnote->type);
15173
70616151
TT
15174 else if (const_strneq (pnote->namedata, "stapsdt"))
15175 nt = get_stapsdt_note_type (pnote->type);
15176
9437c45b 15177 else
1ec5cd37
NC
15178 /* Don't recognize this note name; just use the default set of
15179 note type strings. */
00e98fc7 15180 nt = get_note_type (pnote->type);
9437c45b 15181
2aee03ae 15182 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
15183
15184 if (const_strneq (pnote->namedata, "IPF/VMS"))
15185 return print_ia64_vms_note (pnote);
664f90a3
TT
15186 else if (const_strneq (pnote->namedata, "GNU"))
15187 return print_gnu_note (pnote);
c6a9fc58
TT
15188 else if (const_strneq (pnote->namedata, "stapsdt"))
15189 return print_stapsdt_note (pnote);
9ece1fa9
TT
15190 else if (const_strneq (pnote->namedata, "CORE"))
15191 return print_core_note (pnote);
00e98fc7
TG
15192 else
15193 return 1;
779fe533
NC
15194}
15195
6d118b09 15196
779fe533 15197static int
2cf0635d 15198process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 15199{
2cf0635d
NC
15200 Elf_External_Note * pnotes;
15201 Elf_External_Note * external;
c8071705 15202 char * end;
b34976b6 15203 int res = 1;
103f02d3 15204
779fe533
NC
15205 if (length <= 0)
15206 return 0;
103f02d3 15207
3f5e193b 15208 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 15209 _("notes"));
dd24e3da 15210 if (pnotes == NULL)
a6e9f9df 15211 return 0;
779fe533 15212
103f02d3 15213 external = pnotes;
103f02d3 15214
9dd3a467 15215 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 15216 (unsigned long) offset, (unsigned long) length);
2aee03ae 15217 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 15218
c8071705
NC
15219 end = (char *) pnotes + length;
15220 while ((char *) external < end)
779fe533 15221 {
b34976b6 15222 Elf_Internal_Note inote;
15b42fb0
AM
15223 size_t min_notesz;
15224 char *next;
2cf0635d 15225 char * temp = NULL;
c8071705 15226 size_t data_remaining = end - (char *) external;
6d118b09 15227
00e98fc7 15228 if (!is_ia64_vms ())
15b42fb0 15229 {
9dd3a467
NC
15230 /* PR binutils/15191
15231 Make sure that there is enough data to read. */
15b42fb0
AM
15232 min_notesz = offsetof (Elf_External_Note, name);
15233 if (data_remaining < min_notesz)
9dd3a467
NC
15234 {
15235 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
15236 (int) data_remaining);
15237 break;
15238 }
15b42fb0
AM
15239 inote.type = BYTE_GET (external->type);
15240 inote.namesz = BYTE_GET (external->namesz);
15241 inote.namedata = external->name;
15242 inote.descsz = BYTE_GET (external->descsz);
15243 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
834f871c 15244 /* PR 17531: file: 3443835e. */
c8071705 15245 if (inote.descdata < (char *) pnotes || inote.descdata > end)
834f871c
NC
15246 {
15247 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
15248 inote.descdata = inote.namedata;
15249 inote.namesz = 0;
15250 }
c8071705 15251
15b42fb0
AM
15252 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15253 next = inote.descdata + align_power (inote.descsz, 2);
15254 }
00e98fc7 15255 else
15b42fb0
AM
15256 {
15257 Elf64_External_VMS_Note *vms_external;
00e98fc7 15258
9dd3a467
NC
15259 /* PR binutils/15191
15260 Make sure that there is enough data to read. */
15b42fb0
AM
15261 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15262 if (data_remaining < min_notesz)
9dd3a467
NC
15263 {
15264 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
15265 (int) data_remaining);
15266 break;
15267 }
3e55a963 15268
15b42fb0
AM
15269 vms_external = (Elf64_External_VMS_Note *) external;
15270 inote.type = BYTE_GET (vms_external->type);
15271 inote.namesz = BYTE_GET (vms_external->namesz);
15272 inote.namedata = vms_external->name;
15273 inote.descsz = BYTE_GET (vms_external->descsz);
15274 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15275 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15276 next = inote.descdata + align_power (inote.descsz, 3);
15277 }
15278
15279 if (inote.descdata < (char *) external + min_notesz
15280 || next < (char *) external + min_notesz
5d921cbd
NC
15281 /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
15282 || inote.namedata + inote.namesz < inote.namedata
15283 || inote.descdata + inote.descsz < inote.descdata
15b42fb0 15284 || data_remaining < (size_t)(next - (char *) external))
3e55a963 15285 {
15b42fb0 15286 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 15287 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 15288 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
15289 inote.type, inote.namesz, inote.descsz);
15290 break;
15291 }
15292
15b42fb0 15293 external = (Elf_External_Note *) next;
dd24e3da 15294
6d118b09
NC
15295 /* Verify that name is null terminated. It appears that at least
15296 one version of Linux (RedHat 6.0) generates corefiles that don't
15297 comply with the ELF spec by failing to include the null byte in
15298 namesz. */
8b971f9f 15299 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 15300 {
3f5e193b 15301 temp = (char *) malloc (inote.namesz + 1);
6d118b09
NC
15302 if (temp == NULL)
15303 {
8b73c356 15304 error (_("Out of memory allocating space for inote name\n"));
6d118b09
NC
15305 res = 0;
15306 break;
15307 }
76da6bbe 15308
6d118b09
NC
15309 strncpy (temp, inote.namedata, inote.namesz);
15310 temp[inote.namesz] = 0;
76da6bbe 15311
6d118b09
NC
15312 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
15313 inote.namedata = temp;
15314 }
15315
15316 res &= process_note (& inote);
103f02d3 15317
6d118b09
NC
15318 if (temp != NULL)
15319 {
15320 free (temp);
15321 temp = NULL;
15322 }
779fe533
NC
15323 }
15324
15325 free (pnotes);
103f02d3 15326
779fe533
NC
15327 return res;
15328}
15329
15330static int
2cf0635d 15331process_corefile_note_segments (FILE * file)
779fe533 15332{
2cf0635d 15333 Elf_Internal_Phdr * segment;
b34976b6
AM
15334 unsigned int i;
15335 int res = 1;
103f02d3 15336
d93f0186 15337 if (! get_program_headers (file))
779fe533 15338 return 0;
103f02d3 15339
779fe533
NC
15340 for (i = 0, segment = program_headers;
15341 i < elf_header.e_phnum;
b34976b6 15342 i++, segment++)
779fe533
NC
15343 {
15344 if (segment->p_type == PT_NOTE)
103f02d3 15345 res &= process_corefile_note_segment (file,
30800947
NC
15346 (bfd_vma) segment->p_offset,
15347 (bfd_vma) segment->p_filesz);
779fe533 15348 }
103f02d3 15349
779fe533
NC
15350 return res;
15351}
15352
685080f2
NC
15353static int
15354process_v850_notes (FILE * file, bfd_vma offset, bfd_vma length)
15355{
15356 Elf_External_Note * pnotes;
15357 Elf_External_Note * external;
c8071705 15358 char * end;
685080f2
NC
15359 int res = 1;
15360
15361 if (length <= 0)
15362 return 0;
15363
15364 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15365 _("v850 notes"));
15366 if (pnotes == NULL)
15367 return 0;
15368
15369 external = pnotes;
c8071705 15370 end = (char*) pnotes + length;
685080f2
NC
15371
15372 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
15373 (unsigned long) offset, (unsigned long) length);
15374
c8071705 15375 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
15376 {
15377 Elf_External_Note * next;
15378 Elf_Internal_Note inote;
15379
15380 inote.type = BYTE_GET (external->type);
15381 inote.namesz = BYTE_GET (external->namesz);
15382 inote.namedata = external->name;
15383 inote.descsz = BYTE_GET (external->descsz);
15384 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
15385 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15386
c8071705
NC
15387 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
15388 {
15389 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
15390 inote.descdata = inote.namedata;
15391 inote.namesz = 0;
15392 }
15393
685080f2
NC
15394 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
15395
c8071705 15396 if ( ((char *) next > end)
685080f2
NC
15397 || ((char *) next < (char *) pnotes))
15398 {
15399 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
15400 (unsigned long) ((char *) external - (char *) pnotes));
15401 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
15402 inote.type, inote.namesz, inote.descsz);
15403 break;
15404 }
15405
15406 external = next;
15407
15408 /* Prevent out-of-bounds indexing. */
c8071705 15409 if ( inote.namedata + inote.namesz > end
685080f2
NC
15410 || inote.namedata + inote.namesz < inote.namedata)
15411 {
15412 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
15413 (unsigned long) ((char *) external - (char *) pnotes));
15414 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
15415 inote.type, inote.namesz, inote.descsz);
15416 break;
15417 }
15418
15419 printf (" %s: ", get_v850_elf_note_type (inote.type));
15420
15421 if (! print_v850_note (& inote))
15422 {
15423 res = 0;
15424 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
15425 inote.namesz, inote.descsz);
15426 }
15427 }
15428
15429 free (pnotes);
15430
15431 return res;
15432}
15433
779fe533 15434static int
2cf0635d 15435process_note_sections (FILE * file)
1ec5cd37 15436{
2cf0635d 15437 Elf_Internal_Shdr * section;
1ec5cd37 15438 unsigned long i;
df565f32 15439 int n = 0;
1ec5cd37
NC
15440 int res = 1;
15441
15442 for (i = 0, section = section_headers;
fa1908fd 15443 i < elf_header.e_shnum && section != NULL;
1ec5cd37 15444 i++, section++)
685080f2
NC
15445 {
15446 if (section->sh_type == SHT_NOTE)
15447 {
15448 res &= process_corefile_note_segment (file,
15449 (bfd_vma) section->sh_offset,
15450 (bfd_vma) section->sh_size);
15451 n++;
15452 }
15453
15454 if (( elf_header.e_machine == EM_V800
15455 || elf_header.e_machine == EM_V850
15456 || elf_header.e_machine == EM_CYGNUS_V850)
15457 && section->sh_type == SHT_RENESAS_INFO)
15458 {
15459 res &= process_v850_notes (file,
15460 (bfd_vma) section->sh_offset,
15461 (bfd_vma) section->sh_size);
15462 n++;
15463 }
15464 }
df565f32
NC
15465
15466 if (n == 0)
15467 /* Try processing NOTE segments instead. */
15468 return process_corefile_note_segments (file);
1ec5cd37
NC
15469
15470 return res;
15471}
15472
15473static int
2cf0635d 15474process_notes (FILE * file)
779fe533
NC
15475{
15476 /* If we have not been asked to display the notes then do nothing. */
15477 if (! do_notes)
15478 return 1;
103f02d3 15479
779fe533 15480 if (elf_header.e_type != ET_CORE)
1ec5cd37 15481 return process_note_sections (file);
103f02d3 15482
779fe533 15483 /* No program headers means no NOTE segment. */
1ec5cd37
NC
15484 if (elf_header.e_phnum > 0)
15485 return process_corefile_note_segments (file);
779fe533 15486
1ec5cd37
NC
15487 printf (_("No note segments present in the core file.\n"));
15488 return 1;
779fe533
NC
15489}
15490
252b5132 15491static int
2cf0635d 15492process_arch_specific (FILE * file)
252b5132 15493{
a952a375
NC
15494 if (! do_arch)
15495 return 1;
15496
252b5132
RH
15497 switch (elf_header.e_machine)
15498 {
11c1ff18
PB
15499 case EM_ARM:
15500 return process_arm_specific (file);
252b5132 15501 case EM_MIPS:
4fe85591 15502 case EM_MIPS_RS3_LE:
252b5132
RH
15503 return process_mips_specific (file);
15504 break;
35c08157
KLC
15505 case EM_NDS32:
15506 return process_nds32_specific (file);
15507 break;
34c8bcba
JM
15508 case EM_PPC:
15509 return process_power_specific (file);
15510 break;
9e8c70f9
DM
15511 case EM_SPARC:
15512 case EM_SPARC32PLUS:
15513 case EM_SPARCV9:
15514 return process_sparc_specific (file);
15515 break;
59e6276b
JM
15516 case EM_TI_C6000:
15517 return process_tic6x_specific (file);
15518 break;
13761a11
NC
15519 case EM_MSP430:
15520 return process_msp430x_specific (file);
252b5132
RH
15521 default:
15522 break;
15523 }
15524 return 1;
15525}
15526
15527static int
2cf0635d 15528get_file_header (FILE * file)
252b5132 15529{
9ea033b2
NC
15530 /* Read in the identity array. */
15531 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
15532 return 0;
15533
9ea033b2 15534 /* Determine how to read the rest of the header. */
b34976b6 15535 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
15536 {
15537 default: /* fall through */
15538 case ELFDATANONE: /* fall through */
adab8cdc
AO
15539 case ELFDATA2LSB:
15540 byte_get = byte_get_little_endian;
15541 byte_put = byte_put_little_endian;
15542 break;
15543 case ELFDATA2MSB:
15544 byte_get = byte_get_big_endian;
15545 byte_put = byte_put_big_endian;
15546 break;
9ea033b2
NC
15547 }
15548
15549 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 15550 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
15551
15552 /* Read in the rest of the header. */
15553 if (is_32bit_elf)
15554 {
15555 Elf32_External_Ehdr ehdr32;
252b5132 15556
9ea033b2
NC
15557 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
15558 return 0;
103f02d3 15559
9ea033b2
NC
15560 elf_header.e_type = BYTE_GET (ehdr32.e_type);
15561 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
15562 elf_header.e_version = BYTE_GET (ehdr32.e_version);
15563 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
15564 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
15565 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
15566 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
15567 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
15568 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
15569 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
15570 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
15571 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
15572 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
15573 }
252b5132 15574 else
9ea033b2
NC
15575 {
15576 Elf64_External_Ehdr ehdr64;
a952a375
NC
15577
15578 /* If we have been compiled with sizeof (bfd_vma) == 4, then
15579 we will not be able to cope with the 64bit data found in
15580 64 ELF files. Detect this now and abort before we start
50c2245b 15581 overwriting things. */
a952a375
NC
15582 if (sizeof (bfd_vma) < 8)
15583 {
e3c8793a
NC
15584 error (_("This instance of readelf has been built without support for a\n\
1558564 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
15586 return 0;
15587 }
103f02d3 15588
9ea033b2
NC
15589 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
15590 return 0;
103f02d3 15591
9ea033b2
NC
15592 elf_header.e_type = BYTE_GET (ehdr64.e_type);
15593 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
15594 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
15595 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
15596 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
15597 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
15598 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
15599 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
15600 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
15601 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
15602 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
15603 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
15604 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
15605 }
252b5132 15606
7ece0d85
JJ
15607 if (elf_header.e_shoff)
15608 {
15609 /* There may be some extensions in the first section header. Don't
15610 bomb if we can't read it. */
15611 if (is_32bit_elf)
049b0c3a 15612 get_32bit_section_headers (file, TRUE);
7ece0d85 15613 else
049b0c3a 15614 get_64bit_section_headers (file, TRUE);
7ece0d85 15615 }
560f3c1c 15616
252b5132
RH
15617 return 1;
15618}
15619
fb52b2f4
NC
15620/* Process one ELF object file according to the command line options.
15621 This file may actually be stored in an archive. The file is
15622 positioned at the start of the ELF object. */
15623
ff78d6d6 15624static int
2cf0635d 15625process_object (char * file_name, FILE * file)
252b5132 15626{
252b5132
RH
15627 unsigned int i;
15628
252b5132
RH
15629 if (! get_file_header (file))
15630 {
15631 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 15632 return 1;
252b5132
RH
15633 }
15634
15635 /* Initialise per file variables. */
60bca95a 15636 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
15637 version_info[i] = 0;
15638
60bca95a 15639 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 15640 dynamic_info[i] = 0;
5115b233 15641 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
15642
15643 /* Process the file. */
15644 if (show_name)
15645 printf (_("\nFile: %s\n"), file_name);
15646
18bd398b
NC
15647 /* Initialise the dump_sects array from the cmdline_dump_sects array.
15648 Note we do this even if cmdline_dump_sects is empty because we
15649 must make sure that the dump_sets array is zeroed out before each
15650 object file is processed. */
15651 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 15652 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
15653
15654 if (num_cmdline_dump_sects > 0)
15655 {
15656 if (num_dump_sects == 0)
15657 /* A sneaky way of allocating the dump_sects array. */
09c11c86 15658 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
15659
15660 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
15661 memcpy (dump_sects, cmdline_dump_sects,
15662 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 15663 }
d70c5fc7 15664
252b5132 15665 if (! process_file_header ())
fb52b2f4 15666 return 1;
252b5132 15667
d1f5c6e3 15668 if (! process_section_headers (file))
2f62977e 15669 {
d1f5c6e3
L
15670 /* Without loaded section headers we cannot process lots of
15671 things. */
2f62977e 15672 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 15673
2f62977e 15674 if (! do_using_dynamic)
2c610e4b 15675 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 15676 }
252b5132 15677
d1f5c6e3
L
15678 if (! process_section_groups (file))
15679 {
15680 /* Without loaded section groups we cannot process unwind. */
15681 do_unwind = 0;
15682 }
15683
2f62977e 15684 if (process_program_headers (file))
b2d38a17 15685 process_dynamic_section (file);
252b5132
RH
15686
15687 process_relocs (file);
15688
4d6ed7c8
NC
15689 process_unwind (file);
15690
252b5132
RH
15691 process_symbol_table (file);
15692
15693 process_syminfo (file);
15694
15695 process_version_sections (file);
15696
15697 process_section_contents (file);
f5842774 15698
1ec5cd37 15699 process_notes (file);
103f02d3 15700
047b2264
JJ
15701 process_gnu_liblist (file);
15702
252b5132
RH
15703 process_arch_specific (file);
15704
d93f0186
NC
15705 if (program_headers)
15706 {
15707 free (program_headers);
15708 program_headers = NULL;
15709 }
15710
252b5132
RH
15711 if (section_headers)
15712 {
15713 free (section_headers);
15714 section_headers = NULL;
15715 }
15716
15717 if (string_table)
15718 {
15719 free (string_table);
15720 string_table = NULL;
d40ac9bd 15721 string_table_length = 0;
252b5132
RH
15722 }
15723
15724 if (dynamic_strings)
15725 {
15726 free (dynamic_strings);
15727 dynamic_strings = NULL;
d79b3d50 15728 dynamic_strings_length = 0;
252b5132
RH
15729 }
15730
15731 if (dynamic_symbols)
15732 {
15733 free (dynamic_symbols);
15734 dynamic_symbols = NULL;
19936277 15735 num_dynamic_syms = 0;
252b5132
RH
15736 }
15737
15738 if (dynamic_syminfo)
15739 {
15740 free (dynamic_syminfo);
15741 dynamic_syminfo = NULL;
15742 }
ff78d6d6 15743
293c573e
MR
15744 if (dynamic_section)
15745 {
15746 free (dynamic_section);
15747 dynamic_section = NULL;
15748 }
15749
e4b17d5c
L
15750 if (section_headers_groups)
15751 {
15752 free (section_headers_groups);
15753 section_headers_groups = NULL;
15754 }
15755
15756 if (section_groups)
15757 {
2cf0635d
NC
15758 struct group_list * g;
15759 struct group_list * next;
e4b17d5c
L
15760
15761 for (i = 0; i < group_count; i++)
15762 {
15763 for (g = section_groups [i].root; g != NULL; g = next)
15764 {
15765 next = g->next;
15766 free (g);
15767 }
15768 }
15769
15770 free (section_groups);
15771 section_groups = NULL;
15772 }
15773
19e6b90e 15774 free_debug_memory ();
18bd398b 15775
ff78d6d6 15776 return 0;
252b5132
RH
15777}
15778
2cf0635d
NC
15779/* Process an ELF archive.
15780 On entry the file is positioned just after the ARMAG string. */
15781
15782static int
15783process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
15784{
15785 struct archive_info arch;
15786 struct archive_info nested_arch;
15787 size_t got;
2cf0635d
NC
15788 int ret;
15789
15790 show_name = 1;
15791
15792 /* The ARCH structure is used to hold information about this archive. */
15793 arch.file_name = NULL;
15794 arch.file = NULL;
15795 arch.index_array = NULL;
15796 arch.sym_table = NULL;
15797 arch.longnames = NULL;
15798
15799 /* The NESTED_ARCH structure is used as a single-item cache of information
15800 about a nested archive (when members of a thin archive reside within
15801 another regular archive file). */
15802 nested_arch.file_name = NULL;
15803 nested_arch.file = NULL;
15804 nested_arch.index_array = NULL;
15805 nested_arch.sym_table = NULL;
15806 nested_arch.longnames = NULL;
15807
15808 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
15809 {
15810 ret = 1;
15811 goto out;
4145f1d5 15812 }
fb52b2f4 15813
4145f1d5
NC
15814 if (do_archive_index)
15815 {
2cf0635d 15816 if (arch.sym_table == NULL)
4145f1d5
NC
15817 error (_("%s: unable to dump the index as none was found\n"), file_name);
15818 else
15819 {
591f7597 15820 unsigned long i, l;
4145f1d5
NC
15821 unsigned long current_pos;
15822
591f7597
NC
15823 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
15824 file_name, (unsigned long) arch.index_num, arch.sym_size);
4145f1d5
NC
15825 current_pos = ftell (file);
15826
2cf0635d 15827 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 15828 {
2cf0635d
NC
15829 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
15830 {
15831 char * member_name;
4145f1d5 15832
2cf0635d
NC
15833 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
15834
15835 if (member_name != NULL)
15836 {
15837 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
15838
15839 if (qualified_name != NULL)
15840 {
c2a7d3f5
NC
15841 printf (_("Contents of binary %s at offset "), qualified_name);
15842 (void) print_vma (arch.index_array[i], PREFIX_HEX);
15843 putchar ('\n');
2cf0635d
NC
15844 free (qualified_name);
15845 }
4145f1d5
NC
15846 }
15847 }
2cf0635d
NC
15848
15849 if (l >= arch.sym_size)
4145f1d5
NC
15850 {
15851 error (_("%s: end of the symbol table reached before the end of the index\n"),
15852 file_name);
cb8f3167 15853 break;
4145f1d5 15854 }
591f7597
NC
15855 /* PR 17531: file: 0b6630b2. */
15856 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
15857 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
15858 }
15859
c2a7d3f5
NC
15860 if (arch.uses_64bit_indicies)
15861 l = (l + 7) & ~ 7;
15862 else
15863 l += l & 1;
15864
2cf0635d 15865 if (l < arch.sym_size)
c2a7d3f5
NC
15866 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
15867 file_name, arch.sym_size - l);
4145f1d5 15868
4145f1d5
NC
15869 if (fseek (file, current_pos, SEEK_SET) != 0)
15870 {
15871 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
15872 ret = 1;
15873 goto out;
4145f1d5 15874 }
fb52b2f4 15875 }
4145f1d5
NC
15876
15877 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
15878 && !do_segments && !do_header && !do_dump && !do_version
15879 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 15880 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
15881 {
15882 ret = 0; /* Archive index only. */
15883 goto out;
15884 }
fb52b2f4
NC
15885 }
15886
d989285c 15887 ret = 0;
fb52b2f4
NC
15888
15889 while (1)
15890 {
2cf0635d
NC
15891 char * name;
15892 size_t namelen;
15893 char * qualified_name;
15894
15895 /* Read the next archive header. */
15896 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
15897 {
15898 error (_("%s: failed to seek to next archive header\n"), file_name);
15899 return 1;
15900 }
15901 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
15902 if (got != sizeof arch.arhdr)
15903 {
15904 if (got == 0)
15905 break;
15906 error (_("%s: failed to read archive header\n"), file_name);
15907 ret = 1;
15908 break;
15909 }
15910 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
15911 {
15912 error (_("%s: did not find a valid archive header\n"), arch.file_name);
15913 ret = 1;
15914 break;
15915 }
15916
15917 arch.next_arhdr_offset += sizeof arch.arhdr;
15918
15919 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
15920 if (archive_file_size & 01)
15921 ++archive_file_size;
15922
15923 name = get_archive_member_name (&arch, &nested_arch);
15924 if (name == NULL)
fb52b2f4 15925 {
0fd3a477 15926 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15927 ret = 1;
15928 break;
fb52b2f4 15929 }
2cf0635d 15930 namelen = strlen (name);
fb52b2f4 15931
2cf0635d
NC
15932 qualified_name = make_qualified_name (&arch, &nested_arch, name);
15933 if (qualified_name == NULL)
fb52b2f4 15934 {
2cf0635d 15935 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15936 ret = 1;
15937 break;
fb52b2f4
NC
15938 }
15939
2cf0635d
NC
15940 if (is_thin_archive && arch.nested_member_origin == 0)
15941 {
15942 /* This is a proxy for an external member of a thin archive. */
15943 FILE * member_file;
15944 char * member_file_name = adjust_relative_path (file_name, name, namelen);
15945 if (member_file_name == NULL)
15946 {
15947 ret = 1;
15948 break;
15949 }
15950
15951 member_file = fopen (member_file_name, "rb");
15952 if (member_file == NULL)
15953 {
15954 error (_("Input file '%s' is not readable.\n"), member_file_name);
15955 free (member_file_name);
15956 ret = 1;
15957 break;
15958 }
15959
15960 archive_file_offset = arch.nested_member_origin;
15961
15962 ret |= process_object (qualified_name, member_file);
15963
15964 fclose (member_file);
15965 free (member_file_name);
15966 }
15967 else if (is_thin_archive)
15968 {
a043396b
NC
15969 /* PR 15140: Allow for corrupt thin archives. */
15970 if (nested_arch.file == NULL)
15971 {
15972 error (_("%s: contains corrupt thin archive: %s\n"),
15973 file_name, name);
15974 ret = 1;
15975 break;
15976 }
15977
2cf0635d
NC
15978 /* This is a proxy for a member of a nested archive. */
15979 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
15980
15981 /* The nested archive file will have been opened and setup by
15982 get_archive_member_name. */
15983 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
15984 {
15985 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
15986 ret = 1;
15987 break;
15988 }
15989
15990 ret |= process_object (qualified_name, nested_arch.file);
15991 }
15992 else
15993 {
15994 archive_file_offset = arch.next_arhdr_offset;
15995 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 15996
2cf0635d
NC
15997 ret |= process_object (qualified_name, file);
15998 }
fb52b2f4 15999
2b52916e
L
16000 if (dump_sects != NULL)
16001 {
16002 free (dump_sects);
16003 dump_sects = NULL;
16004 num_dump_sects = 0;
16005 }
16006
2cf0635d 16007 free (qualified_name);
fb52b2f4
NC
16008 }
16009
4145f1d5 16010 out:
2cf0635d
NC
16011 if (nested_arch.file != NULL)
16012 fclose (nested_arch.file);
16013 release_archive (&nested_arch);
16014 release_archive (&arch);
fb52b2f4 16015
d989285c 16016 return ret;
fb52b2f4
NC
16017}
16018
16019static int
2cf0635d 16020process_file (char * file_name)
fb52b2f4 16021{
2cf0635d 16022 FILE * file;
fb52b2f4
NC
16023 struct stat statbuf;
16024 char armag[SARMAG];
16025 int ret;
16026
16027 if (stat (file_name, &statbuf) < 0)
16028 {
f24ddbdd
NC
16029 if (errno == ENOENT)
16030 error (_("'%s': No such file\n"), file_name);
16031 else
16032 error (_("Could not locate '%s'. System error message: %s\n"),
16033 file_name, strerror (errno));
16034 return 1;
16035 }
16036
16037 if (! S_ISREG (statbuf.st_mode))
16038 {
16039 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
16040 return 1;
16041 }
16042
16043 file = fopen (file_name, "rb");
16044 if (file == NULL)
16045 {
f24ddbdd 16046 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
16047 return 1;
16048 }
16049
16050 if (fread (armag, SARMAG, 1, file) != 1)
16051 {
4145f1d5 16052 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
16053 fclose (file);
16054 return 1;
16055 }
16056
f54498b4
NC
16057 current_file_size = (bfd_size_type) statbuf.st_size;
16058
fb52b2f4 16059 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
16060 ret = process_archive (file_name, file, FALSE);
16061 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
16062 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
16063 else
16064 {
4145f1d5
NC
16065 if (do_archive_index)
16066 error (_("File %s is not an archive so its index cannot be displayed.\n"),
16067 file_name);
16068
fb52b2f4
NC
16069 rewind (file);
16070 archive_file_size = archive_file_offset = 0;
16071 ret = process_object (file_name, file);
16072 }
16073
16074 fclose (file);
16075
f54498b4 16076 current_file_size = 0;
fb52b2f4
NC
16077 return ret;
16078}
16079
252b5132
RH
16080#ifdef SUPPORT_DISASSEMBLY
16081/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 16082 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 16083 symbols. */
252b5132
RH
16084
16085void
2cf0635d 16086print_address (unsigned int addr, FILE * outfile)
252b5132
RH
16087{
16088 fprintf (outfile,"0x%8.8x", addr);
16089}
16090
e3c8793a 16091/* Needed by the i386 disassembler. */
252b5132
RH
16092void
16093db_task_printsym (unsigned int addr)
16094{
16095 print_address (addr, stderr);
16096}
16097#endif
16098
16099int
2cf0635d 16100main (int argc, char ** argv)
252b5132 16101{
ff78d6d6
L
16102 int err;
16103
252b5132
RH
16104#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
16105 setlocale (LC_MESSAGES, "");
3882b010
L
16106#endif
16107#if defined (HAVE_SETLOCALE)
16108 setlocale (LC_CTYPE, "");
252b5132
RH
16109#endif
16110 bindtextdomain (PACKAGE, LOCALEDIR);
16111 textdomain (PACKAGE);
16112
869b9d07
MM
16113 expandargv (&argc, &argv);
16114
252b5132
RH
16115 parse_args (argc, argv);
16116
18bd398b 16117 if (num_dump_sects > 0)
59f14fc0 16118 {
18bd398b 16119 /* Make a copy of the dump_sects array. */
3f5e193b
NC
16120 cmdline_dump_sects = (dump_type *)
16121 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 16122 if (cmdline_dump_sects == NULL)
591a748a 16123 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
16124 else
16125 {
09c11c86
NC
16126 memcpy (cmdline_dump_sects, dump_sects,
16127 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
16128 num_cmdline_dump_sects = num_dump_sects;
16129 }
16130 }
16131
18bd398b
NC
16132 if (optind < (argc - 1))
16133 show_name = 1;
16134
ff78d6d6 16135 err = 0;
252b5132 16136 while (optind < argc)
18bd398b 16137 err |= process_file (argv[optind++]);
252b5132
RH
16138
16139 if (dump_sects != NULL)
16140 free (dump_sects);
59f14fc0
AS
16141 if (cmdline_dump_sects != NULL)
16142 free (cmdline_dump_sects);
252b5132 16143
ff78d6d6 16144 return err;
252b5132 16145}