]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
minor reformatting in printcmd.c::print_scalar_formatted
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
6f2750fe 2 Copyright (C) 1998-2016 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 46#include <zlib.h>
3bfcb652 47#ifdef HAVE_WCHAR_H
7bfd842d 48#include <wchar.h>
3bfcb652 49#endif
252b5132 50
a952a375 51#if __GNUC__ >= 2
19936277 52/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 53 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 54 Only do this if we believe that the compiler can support a 64 bit
a952a375 55 data type. For now we only rely on GCC being able to do this. */
19936277 56#define BFD64
a952a375
NC
57#endif
58
3db64b00
AM
59#include "bfd.h"
60#include "bucomm.h"
3284fe0c 61#include "elfcomm.h"
19e6b90e 62#include "dwarf.h"
252b5132
RH
63
64#include "elf/common.h"
65#include "elf/external.h"
66#include "elf/internal.h"
252b5132 67
4b78141a
NC
68
69/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
70 we can obtain the H8 reloc numbers. We need these for the
71 get_reloc_size() function. We include h8.h again after defining
72 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
73
74#include "elf/h8.h"
75#undef _ELF_H8_H
76
77/* Undo the effects of #including reloc-macros.h. */
78
79#undef START_RELOC_NUMBERS
80#undef RELOC_NUMBER
81#undef FAKE_RELOC
82#undef EMPTY_RELOC
83#undef END_RELOC_NUMBERS
84#undef _RELOC_MACROS_H
85
252b5132
RH
86/* The following headers use the elf/reloc-macros.h file to
87 automatically generate relocation recognition functions
88 such as elf_mips_reloc_type() */
89
90#define RELOC_MACROS_GEN_FUNC
91
a06ea964 92#include "elf/aarch64.h"
252b5132 93#include "elf/alpha.h"
3b16e843 94#include "elf/arc.h"
252b5132 95#include "elf/arm.h"
3b16e843 96#include "elf/avr.h"
1d65ded4 97#include "elf/bfin.h"
60bca95a 98#include "elf/cr16.h"
3b16e843 99#include "elf/cris.h"
1c0d3aa6 100#include "elf/crx.h"
252b5132
RH
101#include "elf/d10v.h"
102#include "elf/d30v.h"
d172d4ba 103#include "elf/dlx.h"
cfb8c092 104#include "elf/epiphany.h"
252b5132 105#include "elf/fr30.h"
5c70f934 106#include "elf/frv.h"
3f8107ab 107#include "elf/ft32.h"
3b16e843
NC
108#include "elf/h8.h"
109#include "elf/hppa.h"
110#include "elf/i386.h"
35b1837e 111#include "elf/i370.h"
3b16e843
NC
112#include "elf/i860.h"
113#include "elf/i960.h"
114#include "elf/ia64.h"
1e4cf259 115#include "elf/ip2k.h"
84e94c90 116#include "elf/lm32.h"
1c0d3aa6 117#include "elf/iq2000.h"
49f58d10 118#include "elf/m32c.h"
3b16e843
NC
119#include "elf/m32r.h"
120#include "elf/m68k.h"
75751cd9 121#include "elf/m68hc11.h"
252b5132 122#include "elf/mcore.h"
15ab5209 123#include "elf/mep.h"
a3c62988 124#include "elf/metag.h"
7ba29e2a 125#include "elf/microblaze.h"
3b16e843 126#include "elf/mips.h"
3c3bdf30 127#include "elf/mmix.h"
3b16e843
NC
128#include "elf/mn10200.h"
129#include "elf/mn10300.h"
5506d11a 130#include "elf/moxie.h"
4970f871 131#include "elf/mt.h"
2469cfa2 132#include "elf/msp430.h"
35c08157 133#include "elf/nds32.h"
13761a11 134#include "elf/nios2.h"
73589c9d 135#include "elf/or1k.h"
7d466069 136#include "elf/pj.h"
3b16e843 137#include "elf/ppc.h"
c833c019 138#include "elf/ppc64.h"
99c513f6 139#include "elf/rl78.h"
c7927a3c 140#include "elf/rx.h"
a85d7ed0 141#include "elf/s390.h"
1c0d3aa6 142#include "elf/score.h"
3b16e843
NC
143#include "elf/sh.h"
144#include "elf/sparc.h"
e9f53129 145#include "elf/spu.h"
40b36596 146#include "elf/tic6x.h"
aa137e4d
NC
147#include "elf/tilegx.h"
148#include "elf/tilepro.h"
3b16e843 149#include "elf/v850.h"
179d3252 150#include "elf/vax.h"
619ed720 151#include "elf/visium.h"
3b16e843 152#include "elf/x86-64.h"
c29aca4a 153#include "elf/xc16x.h"
f6c1a2d5 154#include "elf/xgate.h"
93fbbb04 155#include "elf/xstormy16.h"
88da6820 156#include "elf/xtensa.h"
252b5132 157
252b5132 158#include "getopt.h"
566b0d53 159#include "libiberty.h"
09c11c86 160#include "safe-ctype.h"
2cf0635d 161#include "filenames.h"
252b5132 162
15b42fb0
AM
163#ifndef offsetof
164#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
165#endif
166
6a40cf0c
NC
167typedef struct elf_section_list
168{
169 Elf_Internal_Shdr * hdr;
170 struct elf_section_list * next;
171} elf_section_list;
172
2cf0635d 173char * program_name = "readelf";
c9c1d674 174static unsigned long archive_file_offset;
85b1c36d 175static unsigned long archive_file_size;
f54498b4 176static bfd_size_type current_file_size;
85b1c36d
BE
177static unsigned long dynamic_addr;
178static bfd_size_type dynamic_size;
8b73c356 179static size_t dynamic_nent;
2cf0635d 180static char * dynamic_strings;
85b1c36d 181static unsigned long dynamic_strings_length;
2cf0635d 182static char * string_table;
85b1c36d
BE
183static unsigned long string_table_length;
184static unsigned long num_dynamic_syms;
2cf0635d
NC
185static Elf_Internal_Sym * dynamic_symbols;
186static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
187static unsigned long dynamic_syminfo_offset;
188static unsigned int dynamic_syminfo_nent;
f8eae8b2 189static char program_interpreter[PATH_MAX];
bb8a0291 190static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 191static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
192static bfd_vma version_info[16];
193static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
194static Elf_Internal_Shdr * section_headers;
195static Elf_Internal_Phdr * program_headers;
196static Elf_Internal_Dyn * dynamic_section;
6a40cf0c 197static elf_section_list * symtab_shndx_list;
85b1c36d
BE
198static int show_name;
199static int do_dynamic;
200static int do_syms;
2c610e4b 201static int do_dyn_syms;
85b1c36d
BE
202static int do_reloc;
203static int do_sections;
204static int do_section_groups;
5477e8a0 205static int do_section_details;
85b1c36d
BE
206static int do_segments;
207static int do_unwind;
208static int do_using_dynamic;
209static int do_header;
210static int do_dump;
211static int do_version;
85b1c36d
BE
212static int do_histogram;
213static int do_debugging;
85b1c36d
BE
214static int do_arch;
215static int do_notes;
4145f1d5 216static int do_archive_index;
85b1c36d 217static int is_32bit_elf;
0e602686 218static int decompress_dumps;
252b5132 219
e4b17d5c
L
220struct group_list
221{
2cf0635d 222 struct group_list * next;
e4b17d5c
L
223 unsigned int section_index;
224};
225
226struct group
227{
2cf0635d 228 struct group_list * root;
e4b17d5c
L
229 unsigned int group_index;
230};
231
85b1c36d 232static size_t group_count;
2cf0635d
NC
233static struct group * section_groups;
234static struct group ** section_headers_groups;
e4b17d5c 235
09c11c86
NC
236
237/* Flag bits indicating particular types of dump. */
238#define HEX_DUMP (1 << 0) /* The -x command line switch. */
239#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
240#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
241#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 242#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
243
244typedef unsigned char dump_type;
245
246/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
247struct dump_list_entry
248{
2cf0635d 249 char * name;
09c11c86 250 dump_type type;
2cf0635d 251 struct dump_list_entry * next;
aef1f6d0 252};
2cf0635d 253static struct dump_list_entry * dump_sects_byname;
aef1f6d0 254
09c11c86
NC
255/* A dynamic array of flags indicating for which sections a dump
256 has been requested via command line switches. */
257static dump_type * cmdline_dump_sects = NULL;
258static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
259
260/* A dynamic array of flags indicating for which sections a dump of
261 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
262 basis and then initialised from the cmdline_dump_sects array,
263 the results of interpreting the -w switch, and the
264 dump_sects_byname list. */
09c11c86
NC
265static dump_type * dump_sects = NULL;
266static unsigned int num_dump_sects = 0;
252b5132 267
252b5132 268
c256ffe7 269/* How to print a vma value. */
843dd992
NC
270typedef enum print_mode
271{
272 HEX,
273 DEC,
274 DEC_5,
275 UNSIGNED,
276 PREFIX_HEX,
277 FULL_HEX,
278 LONG_HEX
279}
280print_mode;
281
bb4d2ac2
L
282/* Versioned symbol info. */
283enum versioned_symbol_info
284{
285 symbol_undefined,
286 symbol_hidden,
287 symbol_public
288};
289
290static const char *get_symbol_version_string
291 (FILE *file, int is_dynsym, const char *strtab,
292 unsigned long int strtab_size, unsigned int si,
293 Elf_Internal_Sym *psym, enum versioned_symbol_info *sym_info,
294 unsigned short *vna_other);
295
9c19a809
NC
296#define UNKNOWN -1
297
2b692964
NC
298#define SECTION_NAME(X) \
299 ((X) == NULL ? _("<none>") \
300 : string_table == NULL ? _("<no-name>") \
301 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 302 : string_table + (X)->sh_name))
252b5132 303
ee42cf8c 304#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 305
ba5cdace
NC
306#define GET_ELF_SYMBOLS(file, section, sym_count) \
307 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
308 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 309
d79b3d50
NC
310#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
311/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
312 already been called and verified that the string exists. */
313#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 314
61865e30
NC
315#define REMOVE_ARCH_BITS(ADDR) \
316 do \
317 { \
318 if (elf_header.e_machine == EM_ARM) \
319 (ADDR) &= ~1; \
320 } \
321 while (0)
d79b3d50 322\f
c9c1d674
EG
323/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET +
324 the offset of the current archive member, if we are examining an archive.
59245841
NC
325 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
326 using malloc and fill that. In either case return the pointer to the start of
327 the retrieved data or NULL if something went wrong. If something does go wrong
c9c1d674
EG
328 and REASON is not NULL then emit an error message using REASON as part of the
329 context. */
59245841 330
c256ffe7 331static void *
57028622
NC
332get_data (void * var, FILE * file, unsigned long offset, bfd_size_type size,
333 bfd_size_type nmemb, const char * reason)
a6e9f9df 334{
2cf0635d 335 void * mvar;
57028622 336 bfd_size_type amt = size * nmemb;
a6e9f9df 337
c256ffe7 338 if (size == 0 || nmemb == 0)
a6e9f9df
AM
339 return NULL;
340
57028622
NC
341 /* If the size_t type is smaller than the bfd_size_type, eg because
342 you are building a 32-bit tool on a 64-bit host, then make sure
343 that when the sizes are cast to (size_t) no information is lost. */
344 if (sizeof (size_t) < sizeof (bfd_size_type)
345 && ( (bfd_size_type) ((size_t) size) != size
346 || (bfd_size_type) ((size_t) nmemb) != nmemb))
347 {
348 if (reason)
349 error (_("Size truncation prevents reading 0x%llx elements of size 0x%llx for %s\n"),
350 (unsigned long long) nmemb, (unsigned long long) size, reason);
351 return NULL;
352 }
353
354 /* Check for size overflow. */
355 if (amt < nmemb)
356 {
357 if (reason)
358 error (_("Size overflow prevents reading 0x%llx elements of size 0x%llx for %s\n"),
359 (unsigned long long) nmemb, (unsigned long long) size, reason);
360 return NULL;
361 }
362
c9c1d674
EG
363 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
364 attempting to allocate memory when the read is bound to fail. */
365 if (amt > current_file_size
366 || offset + archive_file_offset + amt > current_file_size)
a6e9f9df 367 {
049b0c3a 368 if (reason)
57028622
NC
369 error (_("Reading 0x%llx bytes extends past end of file for %s\n"),
370 (unsigned long long) amt, reason);
a6e9f9df
AM
371 return NULL;
372 }
373
c9c1d674 374 if (fseek (file, archive_file_offset + offset, SEEK_SET))
071436c6
NC
375 {
376 if (reason)
c9c1d674
EG
377 error (_("Unable to seek to 0x%lx for %s\n"),
378 (unsigned long) archive_file_offset + offset, reason);
071436c6
NC
379 return NULL;
380 }
381
a6e9f9df
AM
382 mvar = var;
383 if (mvar == NULL)
384 {
c256ffe7 385 /* Check for overflow. */
57028622 386 if (nmemb < (~(bfd_size_type) 0 - 1) / size)
c256ffe7 387 /* + 1 so that we can '\0' terminate invalid string table sections. */
57028622 388 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
389
390 if (mvar == NULL)
391 {
049b0c3a 392 if (reason)
57028622
NC
393 error (_("Out of memory allocating 0x%llx bytes for %s\n"),
394 (unsigned long long) amt, reason);
a6e9f9df
AM
395 return NULL;
396 }
c256ffe7 397
c9c1d674 398 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
399 }
400
57028622 401 if (fread (mvar, (size_t) size, (size_t) nmemb, file) != nmemb)
a6e9f9df 402 {
049b0c3a 403 if (reason)
57028622
NC
404 error (_("Unable to read in 0x%llx bytes of %s\n"),
405 (unsigned long long) amt, reason);
a6e9f9df
AM
406 if (mvar != var)
407 free (mvar);
408 return NULL;
409 }
410
411 return mvar;
412}
413
14a91970 414/* Print a VMA value. */
cb8f3167 415
66543521 416static int
14a91970 417print_vma (bfd_vma vma, print_mode mode)
66543521 418{
66543521
AM
419 int nc = 0;
420
14a91970 421 switch (mode)
66543521 422 {
14a91970
AM
423 case FULL_HEX:
424 nc = printf ("0x");
425 /* Drop through. */
66543521 426
14a91970 427 case LONG_HEX:
f7a99963 428#ifdef BFD64
14a91970 429 if (is_32bit_elf)
437c2fb7 430 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 431#endif
14a91970
AM
432 printf_vma (vma);
433 return nc + 16;
b19aac67 434
14a91970
AM
435 case DEC_5:
436 if (vma <= 99999)
437 return printf ("%5" BFD_VMA_FMT "d", vma);
438 /* Drop through. */
66543521 439
14a91970
AM
440 case PREFIX_HEX:
441 nc = printf ("0x");
442 /* Drop through. */
66543521 443
14a91970
AM
444 case HEX:
445 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 446
14a91970
AM
447 case DEC:
448 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 449
14a91970
AM
450 case UNSIGNED:
451 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 452 }
66543521 453 return 0;
f7a99963
NC
454}
455
7bfd842d 456/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 457 multibye characters (assuming the host environment supports them).
31104126 458
7bfd842d
NC
459 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
460
461 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
462 padding as necessary.
171191ba
NC
463
464 Returns the number of emitted characters. */
465
466static unsigned int
7a88bc9c 467print_symbol (int width, const char *symbol)
31104126 468{
171191ba 469 bfd_boolean extra_padding = FALSE;
7bfd842d 470 int num_printed = 0;
3bfcb652 471#ifdef HAVE_MBSTATE_T
7bfd842d 472 mbstate_t state;
3bfcb652 473#endif
7bfd842d 474 int width_remaining;
961c521f 475
7bfd842d 476 if (width < 0)
961c521f 477 {
961c521f
NC
478 /* Keep the width positive. This also helps. */
479 width = - width;
171191ba 480 extra_padding = TRUE;
0b4362b0 481 }
74e1a04b 482 assert (width != 0);
961c521f 483
7bfd842d
NC
484 if (do_wide)
485 /* Set the remaining width to a very large value.
486 This simplifies the code below. */
487 width_remaining = INT_MAX;
488 else
489 width_remaining = width;
cb8f3167 490
3bfcb652 491#ifdef HAVE_MBSTATE_T
7bfd842d
NC
492 /* Initialise the multibyte conversion state. */
493 memset (& state, 0, sizeof (state));
3bfcb652 494#endif
961c521f 495
7bfd842d
NC
496 while (width_remaining)
497 {
498 size_t n;
7bfd842d 499 const char c = *symbol++;
961c521f 500
7bfd842d 501 if (c == 0)
961c521f
NC
502 break;
503
7bfd842d
NC
504 /* Do not print control characters directly as they can affect terminal
505 settings. Such characters usually appear in the names generated
506 by the assembler for local labels. */
507 if (ISCNTRL (c))
961c521f 508 {
7bfd842d 509 if (width_remaining < 2)
961c521f
NC
510 break;
511
7bfd842d
NC
512 printf ("^%c", c + 0x40);
513 width_remaining -= 2;
171191ba 514 num_printed += 2;
961c521f 515 }
7bfd842d
NC
516 else if (ISPRINT (c))
517 {
518 putchar (c);
519 width_remaining --;
520 num_printed ++;
521 }
961c521f
NC
522 else
523 {
3bfcb652
NC
524#ifdef HAVE_MBSTATE_T
525 wchar_t w;
526#endif
7bfd842d
NC
527 /* Let printf do the hard work of displaying multibyte characters. */
528 printf ("%.1s", symbol - 1);
529 width_remaining --;
530 num_printed ++;
531
3bfcb652 532#ifdef HAVE_MBSTATE_T
7bfd842d
NC
533 /* Try to find out how many bytes made up the character that was
534 just printed. Advance the symbol pointer past the bytes that
535 were displayed. */
536 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
537#else
538 n = 1;
539#endif
7bfd842d
NC
540 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
541 symbol += (n - 1);
961c521f 542 }
961c521f 543 }
171191ba 544
7bfd842d 545 if (extra_padding && num_printed < width)
171191ba
NC
546 {
547 /* Fill in the remaining spaces. */
7bfd842d
NC
548 printf ("%-*s", width - num_printed, " ");
549 num_printed = width;
171191ba
NC
550 }
551
552 return num_printed;
31104126
NC
553}
554
74e1a04b
NC
555/* Returns a pointer to a static buffer containing a printable version of
556 the given section's name. Like print_symbol, except that it does not try
557 to print multibyte characters, it just interprets them as hex values. */
558
559static const char *
0d2a7a93 560printable_section_name (const Elf_Internal_Shdr * sec)
74e1a04b
NC
561{
562#define MAX_PRINT_SEC_NAME_LEN 128
563 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
564 const char * name = SECTION_NAME (sec);
565 char * buf = sec_name_buf;
566 char c;
567 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
568
569 while ((c = * name ++) != 0)
570 {
571 if (ISCNTRL (c))
572 {
573 if (remaining < 2)
574 break;
948f632f 575
74e1a04b
NC
576 * buf ++ = '^';
577 * buf ++ = c + 0x40;
578 remaining -= 2;
579 }
580 else if (ISPRINT (c))
581 {
582 * buf ++ = c;
583 remaining -= 1;
584 }
585 else
586 {
587 static char hex[17] = "0123456789ABCDEF";
588
589 if (remaining < 4)
590 break;
591 * buf ++ = '<';
592 * buf ++ = hex[(c & 0xf0) >> 4];
593 * buf ++ = hex[c & 0x0f];
594 * buf ++ = '>';
595 remaining -= 4;
596 }
597
598 if (remaining == 0)
599 break;
600 }
601
602 * buf = 0;
603 return sec_name_buf;
604}
605
606static const char *
607printable_section_name_from_index (unsigned long ndx)
608{
609 if (ndx >= elf_header.e_shnum)
610 return _("<corrupt>");
611
612 return printable_section_name (section_headers + ndx);
613}
614
89fac5e3
RS
615/* Return a pointer to section NAME, or NULL if no such section exists. */
616
617static Elf_Internal_Shdr *
2cf0635d 618find_section (const char * name)
89fac5e3
RS
619{
620 unsigned int i;
621
622 for (i = 0; i < elf_header.e_shnum; i++)
623 if (streq (SECTION_NAME (section_headers + i), name))
624 return section_headers + i;
625
626 return NULL;
627}
628
0b6ae522
DJ
629/* Return a pointer to a section containing ADDR, or NULL if no such
630 section exists. */
631
632static Elf_Internal_Shdr *
633find_section_by_address (bfd_vma addr)
634{
635 unsigned int i;
636
637 for (i = 0; i < elf_header.e_shnum; i++)
638 {
639 Elf_Internal_Shdr *sec = section_headers + i;
640 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
641 return sec;
642 }
643
644 return NULL;
645}
646
071436c6
NC
647static Elf_Internal_Shdr *
648find_section_by_type (unsigned int type)
649{
650 unsigned int i;
651
652 for (i = 0; i < elf_header.e_shnum; i++)
653 {
654 Elf_Internal_Shdr *sec = section_headers + i;
655 if (sec->sh_type == type)
656 return sec;
657 }
658
659 return NULL;
660}
661
657d0d47
CC
662/* Return a pointer to section NAME, or NULL if no such section exists,
663 restricted to the list of sections given in SET. */
664
665static Elf_Internal_Shdr *
666find_section_in_set (const char * name, unsigned int * set)
667{
668 unsigned int i;
669
670 if (set != NULL)
671 {
672 while ((i = *set++) > 0)
673 if (streq (SECTION_NAME (section_headers + i), name))
674 return section_headers + i;
675 }
676
677 return find_section (name);
678}
679
0b6ae522
DJ
680/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
681 bytes read. */
682
f6f0e17b
NC
683static inline unsigned long
684read_uleb128 (unsigned char *data,
685 unsigned int *length_return,
686 const unsigned char * const end)
0b6ae522 687{
f6f0e17b 688 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
689}
690
28f997cf
TG
691/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
692 This OS has so many departures from the ELF standard that we test it at
693 many places. */
694
695static inline int
696is_ia64_vms (void)
697{
698 return elf_header.e_machine == EM_IA_64
699 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
700}
701
bcedfee6 702/* Guess the relocation size commonly used by the specific machines. */
252b5132 703
252b5132 704static int
2dc4cec1 705guess_is_rela (unsigned int e_machine)
252b5132 706{
9c19a809 707 switch (e_machine)
252b5132
RH
708 {
709 /* Targets that use REL relocations. */
252b5132 710 case EM_386:
22abe556 711 case EM_IAMCU:
63fcb9e9 712 case EM_960:
e9f53129 713 case EM_ARM:
2b0337b0 714 case EM_D10V:
252b5132 715 case EM_CYGNUS_D10V:
e9f53129 716 case EM_DLX:
252b5132 717 case EM_MIPS:
4fe85591 718 case EM_MIPS_RS3_LE:
e9f53129 719 case EM_CYGNUS_M32R:
1c0d3aa6 720 case EM_SCORE:
f6c1a2d5 721 case EM_XGATE:
9c19a809 722 return FALSE;
103f02d3 723
252b5132
RH
724 /* Targets that use RELA relocations. */
725 case EM_68K:
e9f53129 726 case EM_860:
a06ea964 727 case EM_AARCH64:
cfb8c092 728 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
729 case EM_ALPHA:
730 case EM_ALTERA_NIOS2:
886a2506
NC
731 case EM_ARC:
732 case EM_ARC_COMPACT:
733 case EM_ARC_COMPACT2:
e9f53129
AM
734 case EM_AVR:
735 case EM_AVR_OLD:
736 case EM_BLACKFIN:
60bca95a 737 case EM_CR16:
e9f53129
AM
738 case EM_CRIS:
739 case EM_CRX:
2b0337b0 740 case EM_D30V:
252b5132 741 case EM_CYGNUS_D30V:
2b0337b0 742 case EM_FR30:
3f8107ab 743 case EM_FT32:
252b5132 744 case EM_CYGNUS_FR30:
5c70f934 745 case EM_CYGNUS_FRV:
e9f53129
AM
746 case EM_H8S:
747 case EM_H8_300:
748 case EM_H8_300H:
800eeca4 749 case EM_IA_64:
1e4cf259
NC
750 case EM_IP2K:
751 case EM_IP2K_OLD:
3b36097d 752 case EM_IQ2000:
84e94c90 753 case EM_LATTICEMICO32:
ff7eeb89 754 case EM_M32C_OLD:
49f58d10 755 case EM_M32C:
e9f53129
AM
756 case EM_M32R:
757 case EM_MCORE:
15ab5209 758 case EM_CYGNUS_MEP:
a3c62988 759 case EM_METAG:
e9f53129
AM
760 case EM_MMIX:
761 case EM_MN10200:
762 case EM_CYGNUS_MN10200:
763 case EM_MN10300:
764 case EM_CYGNUS_MN10300:
5506d11a 765 case EM_MOXIE:
e9f53129
AM
766 case EM_MSP430:
767 case EM_MSP430_OLD:
d031aafb 768 case EM_MT:
35c08157 769 case EM_NDS32:
64fd6348 770 case EM_NIOS32:
73589c9d 771 case EM_OR1K:
e9f53129
AM
772 case EM_PPC64:
773 case EM_PPC:
99c513f6 774 case EM_RL78:
c7927a3c 775 case EM_RX:
e9f53129
AM
776 case EM_S390:
777 case EM_S390_OLD:
778 case EM_SH:
779 case EM_SPARC:
780 case EM_SPARC32PLUS:
781 case EM_SPARCV9:
782 case EM_SPU:
40b36596 783 case EM_TI_C6000:
aa137e4d
NC
784 case EM_TILEGX:
785 case EM_TILEPRO:
708e2187 786 case EM_V800:
e9f53129
AM
787 case EM_V850:
788 case EM_CYGNUS_V850:
789 case EM_VAX:
619ed720 790 case EM_VISIUM:
e9f53129 791 case EM_X86_64:
8a9036a4 792 case EM_L1OM:
7a9068fe 793 case EM_K1OM:
e9f53129
AM
794 case EM_XSTORMY16:
795 case EM_XTENSA:
796 case EM_XTENSA_OLD:
7ba29e2a
NC
797 case EM_MICROBLAZE:
798 case EM_MICROBLAZE_OLD:
9c19a809 799 return TRUE;
103f02d3 800
e9f53129
AM
801 case EM_68HC05:
802 case EM_68HC08:
803 case EM_68HC11:
804 case EM_68HC16:
805 case EM_FX66:
806 case EM_ME16:
d1133906 807 case EM_MMA:
d1133906
NC
808 case EM_NCPU:
809 case EM_NDR1:
e9f53129 810 case EM_PCP:
d1133906 811 case EM_ST100:
e9f53129 812 case EM_ST19:
d1133906 813 case EM_ST7:
e9f53129
AM
814 case EM_ST9PLUS:
815 case EM_STARCORE:
d1133906 816 case EM_SVX:
e9f53129 817 case EM_TINYJ:
9c19a809
NC
818 default:
819 warn (_("Don't know about relocations on this machine architecture\n"));
820 return FALSE;
821 }
822}
252b5132 823
9c19a809 824static int
2cf0635d 825slurp_rela_relocs (FILE * file,
d3ba0551
AM
826 unsigned long rel_offset,
827 unsigned long rel_size,
2cf0635d
NC
828 Elf_Internal_Rela ** relasp,
829 unsigned long * nrelasp)
9c19a809 830{
2cf0635d 831 Elf_Internal_Rela * relas;
8b73c356 832 size_t nrelas;
4d6ed7c8 833 unsigned int i;
252b5132 834
4d6ed7c8
NC
835 if (is_32bit_elf)
836 {
2cf0635d 837 Elf32_External_Rela * erelas;
103f02d3 838
3f5e193b 839 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 840 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
841 if (!erelas)
842 return 0;
252b5132 843
4d6ed7c8 844 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 845
3f5e193b
NC
846 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
847 sizeof (Elf_Internal_Rela));
103f02d3 848
4d6ed7c8
NC
849 if (relas == NULL)
850 {
c256ffe7 851 free (erelas);
591a748a 852 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
853 return 0;
854 }
103f02d3 855
4d6ed7c8
NC
856 for (i = 0; i < nrelas; i++)
857 {
858 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
859 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 860 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 861 }
103f02d3 862
4d6ed7c8
NC
863 free (erelas);
864 }
865 else
866 {
2cf0635d 867 Elf64_External_Rela * erelas;
103f02d3 868
3f5e193b 869 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 870 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
871 if (!erelas)
872 return 0;
4d6ed7c8
NC
873
874 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 875
3f5e193b
NC
876 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
877 sizeof (Elf_Internal_Rela));
103f02d3 878
4d6ed7c8
NC
879 if (relas == NULL)
880 {
c256ffe7 881 free (erelas);
591a748a 882 error (_("out of memory parsing relocs\n"));
4d6ed7c8 883 return 0;
9c19a809 884 }
4d6ed7c8
NC
885
886 for (i = 0; i < nrelas; i++)
9c19a809 887 {
66543521
AM
888 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
889 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 890 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
891
892 /* The #ifdef BFD64 below is to prevent a compile time
893 warning. We know that if we do not have a 64 bit data
894 type that we will never execute this code anyway. */
895#ifdef BFD64
896 if (elf_header.e_machine == EM_MIPS
897 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
898 {
899 /* In little-endian objects, r_info isn't really a
900 64-bit little-endian value: it has a 32-bit
901 little-endian symbol index followed by four
902 individual byte fields. Reorder INFO
903 accordingly. */
91d6fa6a
NC
904 bfd_vma inf = relas[i].r_info;
905 inf = (((inf & 0xffffffff) << 32)
906 | ((inf >> 56) & 0xff)
907 | ((inf >> 40) & 0xff00)
908 | ((inf >> 24) & 0xff0000)
909 | ((inf >> 8) & 0xff000000));
910 relas[i].r_info = inf;
861fb55a
DJ
911 }
912#endif /* BFD64 */
4d6ed7c8 913 }
103f02d3 914
4d6ed7c8
NC
915 free (erelas);
916 }
917 *relasp = relas;
918 *nrelasp = nrelas;
919 return 1;
920}
103f02d3 921
4d6ed7c8 922static int
2cf0635d 923slurp_rel_relocs (FILE * file,
d3ba0551
AM
924 unsigned long rel_offset,
925 unsigned long rel_size,
2cf0635d
NC
926 Elf_Internal_Rela ** relsp,
927 unsigned long * nrelsp)
4d6ed7c8 928{
2cf0635d 929 Elf_Internal_Rela * rels;
8b73c356 930 size_t nrels;
4d6ed7c8 931 unsigned int i;
103f02d3 932
4d6ed7c8
NC
933 if (is_32bit_elf)
934 {
2cf0635d 935 Elf32_External_Rel * erels;
103f02d3 936
3f5e193b 937 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 938 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
939 if (!erels)
940 return 0;
103f02d3 941
4d6ed7c8 942 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 943
3f5e193b 944 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 945
4d6ed7c8
NC
946 if (rels == NULL)
947 {
c256ffe7 948 free (erels);
591a748a 949 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
950 return 0;
951 }
952
953 for (i = 0; i < nrels; i++)
954 {
955 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
956 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 957 rels[i].r_addend = 0;
9ea033b2 958 }
4d6ed7c8
NC
959
960 free (erels);
9c19a809
NC
961 }
962 else
963 {
2cf0635d 964 Elf64_External_Rel * erels;
9ea033b2 965
3f5e193b 966 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 967 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
968 if (!erels)
969 return 0;
103f02d3 970
4d6ed7c8 971 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 972
3f5e193b 973 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 974
4d6ed7c8 975 if (rels == NULL)
9c19a809 976 {
c256ffe7 977 free (erels);
591a748a 978 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
979 return 0;
980 }
103f02d3 981
4d6ed7c8
NC
982 for (i = 0; i < nrels; i++)
983 {
66543521
AM
984 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
985 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 986 rels[i].r_addend = 0;
861fb55a
DJ
987
988 /* The #ifdef BFD64 below is to prevent a compile time
989 warning. We know that if we do not have a 64 bit data
990 type that we will never execute this code anyway. */
991#ifdef BFD64
992 if (elf_header.e_machine == EM_MIPS
993 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
994 {
995 /* In little-endian objects, r_info isn't really a
996 64-bit little-endian value: it has a 32-bit
997 little-endian symbol index followed by four
998 individual byte fields. Reorder INFO
999 accordingly. */
91d6fa6a
NC
1000 bfd_vma inf = rels[i].r_info;
1001 inf = (((inf & 0xffffffff) << 32)
1002 | ((inf >> 56) & 0xff)
1003 | ((inf >> 40) & 0xff00)
1004 | ((inf >> 24) & 0xff0000)
1005 | ((inf >> 8) & 0xff000000));
1006 rels[i].r_info = inf;
861fb55a
DJ
1007 }
1008#endif /* BFD64 */
4d6ed7c8 1009 }
103f02d3 1010
4d6ed7c8
NC
1011 free (erels);
1012 }
1013 *relsp = rels;
1014 *nrelsp = nrels;
1015 return 1;
1016}
103f02d3 1017
aca88567
NC
1018/* Returns the reloc type extracted from the reloc info field. */
1019
1020static unsigned int
1021get_reloc_type (bfd_vma reloc_info)
1022{
1023 if (is_32bit_elf)
1024 return ELF32_R_TYPE (reloc_info);
1025
1026 switch (elf_header.e_machine)
1027 {
1028 case EM_MIPS:
1029 /* Note: We assume that reloc_info has already been adjusted for us. */
1030 return ELF64_MIPS_R_TYPE (reloc_info);
1031
1032 case EM_SPARCV9:
1033 return ELF64_R_TYPE_ID (reloc_info);
1034
1035 default:
1036 return ELF64_R_TYPE (reloc_info);
1037 }
1038}
1039
1040/* Return the symbol index extracted from the reloc info field. */
1041
1042static bfd_vma
1043get_reloc_symindex (bfd_vma reloc_info)
1044{
1045 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1046}
1047
13761a11
NC
1048static inline bfd_boolean
1049uses_msp430x_relocs (void)
1050{
1051 return
1052 elf_header.e_machine == EM_MSP430 /* Paranoia. */
1053 /* GCC uses osabi == ELFOSBI_STANDALONE. */
1054 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
1055 /* TI compiler uses ELFOSABI_NONE. */
1056 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
1057}
1058
d3ba0551
AM
1059/* Display the contents of the relocation data found at the specified
1060 offset. */
ee42cf8c 1061
41e92641 1062static void
2cf0635d 1063dump_relocations (FILE * file,
d3ba0551
AM
1064 unsigned long rel_offset,
1065 unsigned long rel_size,
2cf0635d 1066 Elf_Internal_Sym * symtab,
d3ba0551 1067 unsigned long nsyms,
2cf0635d 1068 char * strtab,
d79b3d50 1069 unsigned long strtablen,
bb4d2ac2
L
1070 int is_rela,
1071 int is_dynsym)
4d6ed7c8 1072{
b34976b6 1073 unsigned int i;
2cf0635d 1074 Elf_Internal_Rela * rels;
103f02d3 1075
4d6ed7c8
NC
1076 if (is_rela == UNKNOWN)
1077 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 1078
4d6ed7c8
NC
1079 if (is_rela)
1080 {
c8286bd1 1081 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1082 return;
4d6ed7c8
NC
1083 }
1084 else
1085 {
1086 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1087 return;
252b5132
RH
1088 }
1089
410f7a12
L
1090 if (is_32bit_elf)
1091 {
1092 if (is_rela)
2c71103e
NC
1093 {
1094 if (do_wide)
1095 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1096 else
1097 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1098 }
410f7a12 1099 else
2c71103e
NC
1100 {
1101 if (do_wide)
1102 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1103 else
1104 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1105 }
410f7a12 1106 }
252b5132 1107 else
410f7a12
L
1108 {
1109 if (is_rela)
2c71103e
NC
1110 {
1111 if (do_wide)
8beeaeb7 1112 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1113 else
1114 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1115 }
410f7a12 1116 else
2c71103e
NC
1117 {
1118 if (do_wide)
8beeaeb7 1119 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1120 else
1121 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1122 }
410f7a12 1123 }
252b5132
RH
1124
1125 for (i = 0; i < rel_size; i++)
1126 {
2cf0635d 1127 const char * rtype;
b34976b6 1128 bfd_vma offset;
91d6fa6a 1129 bfd_vma inf;
b34976b6
AM
1130 bfd_vma symtab_index;
1131 bfd_vma type;
103f02d3 1132
b34976b6 1133 offset = rels[i].r_offset;
91d6fa6a 1134 inf = rels[i].r_info;
103f02d3 1135
91d6fa6a
NC
1136 type = get_reloc_type (inf);
1137 symtab_index = get_reloc_symindex (inf);
252b5132 1138
410f7a12
L
1139 if (is_32bit_elf)
1140 {
39dbeff8
AM
1141 printf ("%8.8lx %8.8lx ",
1142 (unsigned long) offset & 0xffffffff,
91d6fa6a 1143 (unsigned long) inf & 0xffffffff);
410f7a12
L
1144 }
1145 else
1146 {
39dbeff8
AM
1147#if BFD_HOST_64BIT_LONG
1148 printf (do_wide
1149 ? "%16.16lx %16.16lx "
1150 : "%12.12lx %12.12lx ",
91d6fa6a 1151 offset, inf);
39dbeff8 1152#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1153#ifndef __MSVCRT__
39dbeff8
AM
1154 printf (do_wide
1155 ? "%16.16llx %16.16llx "
1156 : "%12.12llx %12.12llx ",
91d6fa6a 1157 offset, inf);
6e3d6dc1
NC
1158#else
1159 printf (do_wide
1160 ? "%16.16I64x %16.16I64x "
1161 : "%12.12I64x %12.12I64x ",
91d6fa6a 1162 offset, inf);
6e3d6dc1 1163#endif
39dbeff8 1164#else
2c71103e
NC
1165 printf (do_wide
1166 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1167 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1168 _bfd_int64_high (offset),
1169 _bfd_int64_low (offset),
91d6fa6a
NC
1170 _bfd_int64_high (inf),
1171 _bfd_int64_low (inf));
9ea033b2 1172#endif
410f7a12 1173 }
103f02d3 1174
252b5132
RH
1175 switch (elf_header.e_machine)
1176 {
1177 default:
1178 rtype = NULL;
1179 break;
1180
a06ea964
NC
1181 case EM_AARCH64:
1182 rtype = elf_aarch64_reloc_type (type);
1183 break;
1184
2b0337b0 1185 case EM_M32R:
252b5132 1186 case EM_CYGNUS_M32R:
9ea033b2 1187 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1188 break;
1189
1190 case EM_386:
22abe556 1191 case EM_IAMCU:
9ea033b2 1192 rtype = elf_i386_reloc_type (type);
252b5132
RH
1193 break;
1194
ba2685cc
AM
1195 case EM_68HC11:
1196 case EM_68HC12:
1197 rtype = elf_m68hc11_reloc_type (type);
1198 break;
75751cd9 1199
252b5132 1200 case EM_68K:
9ea033b2 1201 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1202 break;
1203
63fcb9e9 1204 case EM_960:
9ea033b2 1205 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1206 break;
1207
adde6300 1208 case EM_AVR:
2b0337b0 1209 case EM_AVR_OLD:
adde6300
AM
1210 rtype = elf_avr_reloc_type (type);
1211 break;
1212
9ea033b2
NC
1213 case EM_OLD_SPARCV9:
1214 case EM_SPARC32PLUS:
1215 case EM_SPARCV9:
252b5132 1216 case EM_SPARC:
9ea033b2 1217 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1218 break;
1219
e9f53129
AM
1220 case EM_SPU:
1221 rtype = elf_spu_reloc_type (type);
1222 break;
1223
708e2187
NC
1224 case EM_V800:
1225 rtype = v800_reloc_type (type);
1226 break;
2b0337b0 1227 case EM_V850:
252b5132 1228 case EM_CYGNUS_V850:
9ea033b2 1229 rtype = v850_reloc_type (type);
252b5132
RH
1230 break;
1231
2b0337b0 1232 case EM_D10V:
252b5132 1233 case EM_CYGNUS_D10V:
9ea033b2 1234 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1235 break;
1236
2b0337b0 1237 case EM_D30V:
252b5132 1238 case EM_CYGNUS_D30V:
9ea033b2 1239 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1240 break;
1241
d172d4ba
NC
1242 case EM_DLX:
1243 rtype = elf_dlx_reloc_type (type);
1244 break;
1245
252b5132 1246 case EM_SH:
9ea033b2 1247 rtype = elf_sh_reloc_type (type);
252b5132
RH
1248 break;
1249
2b0337b0 1250 case EM_MN10300:
252b5132 1251 case EM_CYGNUS_MN10300:
9ea033b2 1252 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1253 break;
1254
2b0337b0 1255 case EM_MN10200:
252b5132 1256 case EM_CYGNUS_MN10200:
9ea033b2 1257 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1258 break;
1259
2b0337b0 1260 case EM_FR30:
252b5132 1261 case EM_CYGNUS_FR30:
9ea033b2 1262 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1263 break;
1264
ba2685cc
AM
1265 case EM_CYGNUS_FRV:
1266 rtype = elf_frv_reloc_type (type);
1267 break;
5c70f934 1268
3f8107ab
AM
1269 case EM_FT32:
1270 rtype = elf_ft32_reloc_type (type);
1271 break;
1272
252b5132 1273 case EM_MCORE:
9ea033b2 1274 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1275 break;
1276
3c3bdf30
NC
1277 case EM_MMIX:
1278 rtype = elf_mmix_reloc_type (type);
1279 break;
1280
5506d11a
AM
1281 case EM_MOXIE:
1282 rtype = elf_moxie_reloc_type (type);
1283 break;
1284
2469cfa2 1285 case EM_MSP430:
13761a11
NC
1286 if (uses_msp430x_relocs ())
1287 {
1288 rtype = elf_msp430x_reloc_type (type);
1289 break;
1290 }
2469cfa2
NC
1291 case EM_MSP430_OLD:
1292 rtype = elf_msp430_reloc_type (type);
1293 break;
1294
35c08157
KLC
1295 case EM_NDS32:
1296 rtype = elf_nds32_reloc_type (type);
1297 break;
1298
252b5132 1299 case EM_PPC:
9ea033b2 1300 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1301 break;
1302
c833c019
AM
1303 case EM_PPC64:
1304 rtype = elf_ppc64_reloc_type (type);
1305 break;
1306
252b5132 1307 case EM_MIPS:
4fe85591 1308 case EM_MIPS_RS3_LE:
9ea033b2 1309 rtype = elf_mips_reloc_type (type);
252b5132
RH
1310 break;
1311
1312 case EM_ALPHA:
9ea033b2 1313 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1314 break;
1315
1316 case EM_ARM:
9ea033b2 1317 rtype = elf_arm_reloc_type (type);
252b5132
RH
1318 break;
1319
584da044 1320 case EM_ARC:
886a2506
NC
1321 case EM_ARC_COMPACT:
1322 case EM_ARC_COMPACT2:
9ea033b2 1323 rtype = elf_arc_reloc_type (type);
252b5132
RH
1324 break;
1325
1326 case EM_PARISC:
69e617ca 1327 rtype = elf_hppa_reloc_type (type);
252b5132 1328 break;
7d466069 1329
b8720f9d
JL
1330 case EM_H8_300:
1331 case EM_H8_300H:
1332 case EM_H8S:
1333 rtype = elf_h8_reloc_type (type);
1334 break;
1335
73589c9d
CS
1336 case EM_OR1K:
1337 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1338 break;
1339
7d466069 1340 case EM_PJ:
2b0337b0 1341 case EM_PJ_OLD:
7d466069
ILT
1342 rtype = elf_pj_reloc_type (type);
1343 break;
800eeca4
JW
1344 case EM_IA_64:
1345 rtype = elf_ia64_reloc_type (type);
1346 break;
1b61cf92
HPN
1347
1348 case EM_CRIS:
1349 rtype = elf_cris_reloc_type (type);
1350 break;
535c37ff
JE
1351
1352 case EM_860:
1353 rtype = elf_i860_reloc_type (type);
1354 break;
bcedfee6
NC
1355
1356 case EM_X86_64:
8a9036a4 1357 case EM_L1OM:
7a9068fe 1358 case EM_K1OM:
bcedfee6
NC
1359 rtype = elf_x86_64_reloc_type (type);
1360 break;
a85d7ed0 1361
35b1837e
AM
1362 case EM_S370:
1363 rtype = i370_reloc_type (type);
1364 break;
1365
53c7db4b
KH
1366 case EM_S390_OLD:
1367 case EM_S390:
1368 rtype = elf_s390_reloc_type (type);
1369 break;
93fbbb04 1370
1c0d3aa6
NC
1371 case EM_SCORE:
1372 rtype = elf_score_reloc_type (type);
1373 break;
1374
93fbbb04
GK
1375 case EM_XSTORMY16:
1376 rtype = elf_xstormy16_reloc_type (type);
1377 break;
179d3252 1378
1fe1f39c
NC
1379 case EM_CRX:
1380 rtype = elf_crx_reloc_type (type);
1381 break;
1382
179d3252
JT
1383 case EM_VAX:
1384 rtype = elf_vax_reloc_type (type);
1385 break;
1e4cf259 1386
619ed720
EB
1387 case EM_VISIUM:
1388 rtype = elf_visium_reloc_type (type);
1389 break;
1390
cfb8c092
NC
1391 case EM_ADAPTEVA_EPIPHANY:
1392 rtype = elf_epiphany_reloc_type (type);
1393 break;
1394
1e4cf259
NC
1395 case EM_IP2K:
1396 case EM_IP2K_OLD:
1397 rtype = elf_ip2k_reloc_type (type);
1398 break;
3b36097d
SC
1399
1400 case EM_IQ2000:
1401 rtype = elf_iq2000_reloc_type (type);
1402 break;
88da6820
NC
1403
1404 case EM_XTENSA_OLD:
1405 case EM_XTENSA:
1406 rtype = elf_xtensa_reloc_type (type);
1407 break;
a34e3ecb 1408
84e94c90
NC
1409 case EM_LATTICEMICO32:
1410 rtype = elf_lm32_reloc_type (type);
1411 break;
1412
ff7eeb89 1413 case EM_M32C_OLD:
49f58d10
JB
1414 case EM_M32C:
1415 rtype = elf_m32c_reloc_type (type);
1416 break;
1417
d031aafb
NS
1418 case EM_MT:
1419 rtype = elf_mt_reloc_type (type);
a34e3ecb 1420 break;
1d65ded4
CM
1421
1422 case EM_BLACKFIN:
1423 rtype = elf_bfin_reloc_type (type);
1424 break;
15ab5209
DB
1425
1426 case EM_CYGNUS_MEP:
1427 rtype = elf_mep_reloc_type (type);
1428 break;
60bca95a
NC
1429
1430 case EM_CR16:
1431 rtype = elf_cr16_reloc_type (type);
1432 break;
dd24e3da 1433
7ba29e2a
NC
1434 case EM_MICROBLAZE:
1435 case EM_MICROBLAZE_OLD:
1436 rtype = elf_microblaze_reloc_type (type);
1437 break;
c7927a3c 1438
99c513f6
DD
1439 case EM_RL78:
1440 rtype = elf_rl78_reloc_type (type);
1441 break;
1442
c7927a3c
NC
1443 case EM_RX:
1444 rtype = elf_rx_reloc_type (type);
1445 break;
c29aca4a 1446
a3c62988
NC
1447 case EM_METAG:
1448 rtype = elf_metag_reloc_type (type);
1449 break;
1450
c29aca4a
NC
1451 case EM_XC16X:
1452 case EM_C166:
1453 rtype = elf_xc16x_reloc_type (type);
1454 break;
40b36596
JM
1455
1456 case EM_TI_C6000:
1457 rtype = elf_tic6x_reloc_type (type);
1458 break;
aa137e4d
NC
1459
1460 case EM_TILEGX:
1461 rtype = elf_tilegx_reloc_type (type);
1462 break;
1463
1464 case EM_TILEPRO:
1465 rtype = elf_tilepro_reloc_type (type);
1466 break;
f6c1a2d5
NC
1467
1468 case EM_XGATE:
1469 rtype = elf_xgate_reloc_type (type);
1470 break;
36591ba1
SL
1471
1472 case EM_ALTERA_NIOS2:
1473 rtype = elf_nios2_reloc_type (type);
1474 break;
252b5132
RH
1475 }
1476
1477 if (rtype == NULL)
39dbeff8 1478 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1479 else
8beeaeb7 1480 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1481
7ace3541 1482 if (elf_header.e_machine == EM_ALPHA
157c2599 1483 && rtype != NULL
7ace3541
RH
1484 && streq (rtype, "R_ALPHA_LITUSE")
1485 && is_rela)
1486 {
1487 switch (rels[i].r_addend)
1488 {
1489 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1490 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1491 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1492 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1493 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1494 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1495 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1496 default: rtype = NULL;
1497 }
1498 if (rtype)
1499 printf (" (%s)", rtype);
1500 else
1501 {
1502 putchar (' ');
1503 printf (_("<unknown addend: %lx>"),
1504 (unsigned long) rels[i].r_addend);
1505 }
1506 }
1507 else if (symtab_index)
252b5132 1508 {
af3fc3bc 1509 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1510 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1511 else
19936277 1512 {
2cf0635d 1513 Elf_Internal_Sym * psym;
bb4d2ac2
L
1514 const char * version_string;
1515 enum versioned_symbol_info sym_info;
1516 unsigned short vna_other;
19936277 1517
af3fc3bc 1518 psym = symtab + symtab_index;
103f02d3 1519
bb4d2ac2
L
1520 version_string
1521 = get_symbol_version_string (file, is_dynsym,
1522 strtab, strtablen,
1523 symtab_index,
1524 psym,
1525 &sym_info,
1526 &vna_other);
1527
af3fc3bc 1528 printf (" ");
171191ba 1529
d8045f23
NC
1530 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1531 {
1532 const char * name;
1533 unsigned int len;
1534 unsigned int width = is_32bit_elf ? 8 : 14;
1535
1536 /* Relocations against GNU_IFUNC symbols do not use the value
1537 of the symbol as the address to relocate against. Instead
1538 they invoke the function named by the symbol and use its
1539 result as the address for relocation.
1540
1541 To indicate this to the user, do not display the value of
1542 the symbol in the "Symbols's Value" field. Instead show
1543 its name followed by () as a hint that the symbol is
1544 invoked. */
1545
1546 if (strtab == NULL
1547 || psym->st_name == 0
1548 || psym->st_name >= strtablen)
1549 name = "??";
1550 else
1551 name = strtab + psym->st_name;
1552
1553 len = print_symbol (width, name);
bb4d2ac2
L
1554 if (version_string)
1555 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1556 version_string);
d8045f23
NC
1557 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1558 }
1559 else
1560 {
1561 print_vma (psym->st_value, LONG_HEX);
171191ba 1562
d8045f23
NC
1563 printf (is_32bit_elf ? " " : " ");
1564 }
103f02d3 1565
af3fc3bc 1566 if (psym->st_name == 0)
f1ef08cb 1567 {
2cf0635d 1568 const char * sec_name = "<null>";
f1ef08cb
AM
1569 char name_buf[40];
1570
1571 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1572 {
4fbb74a6 1573 if (psym->st_shndx < elf_header.e_shnum)
74e1a04b 1574 sec_name = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1575 else if (psym->st_shndx == SHN_ABS)
1576 sec_name = "ABS";
1577 else if (psym->st_shndx == SHN_COMMON)
1578 sec_name = "COMMON";
ac145307
BS
1579 else if ((elf_header.e_machine == EM_MIPS
1580 && psym->st_shndx == SHN_MIPS_SCOMMON)
1581 || (elf_header.e_machine == EM_TI_C6000
1582 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1583 sec_name = "SCOMMON";
1584 else if (elf_header.e_machine == EM_MIPS
1585 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1586 sec_name = "SUNDEF";
8a9036a4 1587 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1588 || elf_header.e_machine == EM_L1OM
1589 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1590 && psym->st_shndx == SHN_X86_64_LCOMMON)
1591 sec_name = "LARGE_COMMON";
9ce701e2
L
1592 else if (elf_header.e_machine == EM_IA_64
1593 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1594 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1595 sec_name = "ANSI_COM";
28f997cf 1596 else if (is_ia64_vms ()
148b93f2
NC
1597 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1598 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1599 else
1600 {
1601 sprintf (name_buf, "<section 0x%x>",
1602 (unsigned int) psym->st_shndx);
1603 sec_name = name_buf;
1604 }
1605 }
1606 print_symbol (22, sec_name);
1607 }
af3fc3bc 1608 else if (strtab == NULL)
d79b3d50 1609 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1610 else if (psym->st_name >= strtablen)
d79b3d50 1611 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1612 else
bb4d2ac2
L
1613 {
1614 print_symbol (22, strtab + psym->st_name);
1615 if (version_string)
1616 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1617 version_string);
1618 }
103f02d3 1619
af3fc3bc 1620 if (is_rela)
171191ba 1621 {
7360e63f 1622 bfd_vma off = rels[i].r_addend;
171191ba 1623
7360e63f 1624 if ((bfd_signed_vma) off < 0)
598aaa76 1625 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1626 else
598aaa76 1627 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1628 }
19936277 1629 }
252b5132 1630 }
1b228002 1631 else if (is_rela)
f7a99963 1632 {
7360e63f 1633 bfd_vma off = rels[i].r_addend;
e04d7088
L
1634
1635 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1636 if ((bfd_signed_vma) off < 0)
e04d7088
L
1637 printf ("-%" BFD_VMA_FMT "x", - off);
1638 else
1639 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1640 }
252b5132 1641
157c2599
NC
1642 if (elf_header.e_machine == EM_SPARCV9
1643 && rtype != NULL
1644 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1645 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1646
252b5132 1647 putchar ('\n');
2c71103e 1648
aca88567 1649#ifdef BFD64
53c7db4b 1650 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1651 {
91d6fa6a
NC
1652 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1653 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1654 const char * rtype2 = elf_mips_reloc_type (type2);
1655 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1656
2c71103e
NC
1657 printf (" Type2: ");
1658
1659 if (rtype2 == NULL)
39dbeff8
AM
1660 printf (_("unrecognized: %-7lx"),
1661 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1662 else
1663 printf ("%-17.17s", rtype2);
1664
18bd398b 1665 printf ("\n Type3: ");
2c71103e
NC
1666
1667 if (rtype3 == NULL)
39dbeff8
AM
1668 printf (_("unrecognized: %-7lx"),
1669 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1670 else
1671 printf ("%-17.17s", rtype3);
1672
53c7db4b 1673 putchar ('\n');
2c71103e 1674 }
aca88567 1675#endif /* BFD64 */
252b5132
RH
1676 }
1677
c8286bd1 1678 free (rels);
252b5132
RH
1679}
1680
1681static const char *
d3ba0551 1682get_mips_dynamic_type (unsigned long type)
252b5132
RH
1683{
1684 switch (type)
1685 {
1686 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1687 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1688 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1689 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1690 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1691 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1692 case DT_MIPS_MSYM: return "MIPS_MSYM";
1693 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1694 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1695 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1696 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1697 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1698 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1699 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1700 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1701 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1702 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1703 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1704 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1705 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1706 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1707 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1708 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1709 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1710 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1711 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1712 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1713 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1714 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1715 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1716 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1717 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1718 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1719 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1720 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1721 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1722 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1723 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1724 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1725 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1726 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1727 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1728 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1729 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1730 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1731 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1732 default:
1733 return NULL;
1734 }
1735}
1736
9a097730 1737static const char *
d3ba0551 1738get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1739{
1740 switch (type)
1741 {
1742 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1743 default:
1744 return NULL;
1745 }
103f02d3
UD
1746}
1747
7490d522
AM
1748static const char *
1749get_ppc_dynamic_type (unsigned long type)
1750{
1751 switch (type)
1752 {
a7f2871e 1753 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1754 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1755 default:
1756 return NULL;
1757 }
1758}
1759
f1cb7e17 1760static const char *
d3ba0551 1761get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1762{
1763 switch (type)
1764 {
a7f2871e
AM
1765 case DT_PPC64_GLINK: return "PPC64_GLINK";
1766 case DT_PPC64_OPD: return "PPC64_OPD";
1767 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1768 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1769 default:
1770 return NULL;
1771 }
1772}
1773
103f02d3 1774static const char *
d3ba0551 1775get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1776{
1777 switch (type)
1778 {
1779 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1780 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1781 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1782 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1783 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1784 case DT_HP_PREINIT: return "HP_PREINIT";
1785 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1786 case DT_HP_NEEDED: return "HP_NEEDED";
1787 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1788 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1789 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1790 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1791 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1792 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1793 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1794 case DT_HP_FILTERED: return "HP_FILTERED";
1795 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1796 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1797 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1798 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1799 case DT_PLT: return "PLT";
1800 case DT_PLT_SIZE: return "PLT_SIZE";
1801 case DT_DLT: return "DLT";
1802 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1803 default:
1804 return NULL;
1805 }
1806}
9a097730 1807
ecc51f48 1808static const char *
d3ba0551 1809get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1810{
1811 switch (type)
1812 {
148b93f2
NC
1813 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1814 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1815 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1816 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1817 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1818 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1819 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1820 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1821 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1822 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1823 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1824 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1825 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1826 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1827 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1828 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1829 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1830 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1831 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1832 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1833 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1834 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1835 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1836 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1837 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1838 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1839 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1840 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1841 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1842 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1843 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1844 default:
1845 return NULL;
1846 }
1847}
1848
fabcb361
RH
1849static const char *
1850get_alpha_dynamic_type (unsigned long type)
1851{
1852 switch (type)
1853 {
1854 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1855 default:
1856 return NULL;
1857 }
1858}
1859
1c0d3aa6
NC
1860static const char *
1861get_score_dynamic_type (unsigned long type)
1862{
1863 switch (type)
1864 {
1865 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1866 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1867 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1868 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1869 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1870 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1871 default:
1872 return NULL;
1873 }
1874}
1875
40b36596
JM
1876static const char *
1877get_tic6x_dynamic_type (unsigned long type)
1878{
1879 switch (type)
1880 {
1881 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1882 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1883 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1884 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1885 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1886 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1887 default:
1888 return NULL;
1889 }
1890}
1c0d3aa6 1891
36591ba1
SL
1892static const char *
1893get_nios2_dynamic_type (unsigned long type)
1894{
1895 switch (type)
1896 {
1897 case DT_NIOS2_GP: return "NIOS2_GP";
1898 default:
1899 return NULL;
1900 }
1901}
1902
252b5132 1903static const char *
d3ba0551 1904get_dynamic_type (unsigned long type)
252b5132 1905{
e9e44622 1906 static char buff[64];
252b5132
RH
1907
1908 switch (type)
1909 {
1910 case DT_NULL: return "NULL";
1911 case DT_NEEDED: return "NEEDED";
1912 case DT_PLTRELSZ: return "PLTRELSZ";
1913 case DT_PLTGOT: return "PLTGOT";
1914 case DT_HASH: return "HASH";
1915 case DT_STRTAB: return "STRTAB";
1916 case DT_SYMTAB: return "SYMTAB";
1917 case DT_RELA: return "RELA";
1918 case DT_RELASZ: return "RELASZ";
1919 case DT_RELAENT: return "RELAENT";
1920 case DT_STRSZ: return "STRSZ";
1921 case DT_SYMENT: return "SYMENT";
1922 case DT_INIT: return "INIT";
1923 case DT_FINI: return "FINI";
1924 case DT_SONAME: return "SONAME";
1925 case DT_RPATH: return "RPATH";
1926 case DT_SYMBOLIC: return "SYMBOLIC";
1927 case DT_REL: return "REL";
1928 case DT_RELSZ: return "RELSZ";
1929 case DT_RELENT: return "RELENT";
1930 case DT_PLTREL: return "PLTREL";
1931 case DT_DEBUG: return "DEBUG";
1932 case DT_TEXTREL: return "TEXTREL";
1933 case DT_JMPREL: return "JMPREL";
1934 case DT_BIND_NOW: return "BIND_NOW";
1935 case DT_INIT_ARRAY: return "INIT_ARRAY";
1936 case DT_FINI_ARRAY: return "FINI_ARRAY";
1937 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1938 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1939 case DT_RUNPATH: return "RUNPATH";
1940 case DT_FLAGS: return "FLAGS";
2d0e6f43 1941
d1133906
NC
1942 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1943 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1944
05107a46 1945 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1946 case DT_PLTPADSZ: return "PLTPADSZ";
1947 case DT_MOVEENT: return "MOVEENT";
1948 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1949 case DT_FEATURE: return "FEATURE";
252b5132
RH
1950 case DT_POSFLAG_1: return "POSFLAG_1";
1951 case DT_SYMINSZ: return "SYMINSZ";
1952 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1953
252b5132 1954 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1955 case DT_CONFIG: return "CONFIG";
1956 case DT_DEPAUDIT: return "DEPAUDIT";
1957 case DT_AUDIT: return "AUDIT";
1958 case DT_PLTPAD: return "PLTPAD";
1959 case DT_MOVETAB: return "MOVETAB";
252b5132 1960 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1961
252b5132 1962 case DT_VERSYM: return "VERSYM";
103f02d3 1963
67a4f2b7
AO
1964 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1965 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1966 case DT_RELACOUNT: return "RELACOUNT";
1967 case DT_RELCOUNT: return "RELCOUNT";
1968 case DT_FLAGS_1: return "FLAGS_1";
1969 case DT_VERDEF: return "VERDEF";
1970 case DT_VERDEFNUM: return "VERDEFNUM";
1971 case DT_VERNEED: return "VERNEED";
1972 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1973
019148e4 1974 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1975 case DT_USED: return "USED";
1976 case DT_FILTER: return "FILTER";
103f02d3 1977
047b2264
JJ
1978 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1979 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1980 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1981 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1982 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1983 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1984
252b5132
RH
1985 default:
1986 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1987 {
2cf0635d 1988 const char * result;
103f02d3 1989
252b5132
RH
1990 switch (elf_header.e_machine)
1991 {
1992 case EM_MIPS:
4fe85591 1993 case EM_MIPS_RS3_LE:
252b5132
RH
1994 result = get_mips_dynamic_type (type);
1995 break;
9a097730
RH
1996 case EM_SPARCV9:
1997 result = get_sparc64_dynamic_type (type);
1998 break;
7490d522
AM
1999 case EM_PPC:
2000 result = get_ppc_dynamic_type (type);
2001 break;
f1cb7e17
AM
2002 case EM_PPC64:
2003 result = get_ppc64_dynamic_type (type);
2004 break;
ecc51f48
NC
2005 case EM_IA_64:
2006 result = get_ia64_dynamic_type (type);
2007 break;
fabcb361
RH
2008 case EM_ALPHA:
2009 result = get_alpha_dynamic_type (type);
2010 break;
1c0d3aa6
NC
2011 case EM_SCORE:
2012 result = get_score_dynamic_type (type);
2013 break;
40b36596
JM
2014 case EM_TI_C6000:
2015 result = get_tic6x_dynamic_type (type);
2016 break;
36591ba1
SL
2017 case EM_ALTERA_NIOS2:
2018 result = get_nios2_dynamic_type (type);
2019 break;
252b5132
RH
2020 default:
2021 result = NULL;
2022 break;
2023 }
2024
2025 if (result != NULL)
2026 return result;
2027
e9e44622 2028 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2029 }
eec8f817
DA
2030 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
2031 || (elf_header.e_machine == EM_PARISC
2032 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2033 {
2cf0635d 2034 const char * result;
103f02d3
UD
2035
2036 switch (elf_header.e_machine)
2037 {
2038 case EM_PARISC:
2039 result = get_parisc_dynamic_type (type);
2040 break;
148b93f2
NC
2041 case EM_IA_64:
2042 result = get_ia64_dynamic_type (type);
2043 break;
103f02d3
UD
2044 default:
2045 result = NULL;
2046 break;
2047 }
2048
2049 if (result != NULL)
2050 return result;
2051
e9e44622
JJ
2052 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2053 type);
103f02d3 2054 }
252b5132 2055 else
e9e44622 2056 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2057
252b5132
RH
2058 return buff;
2059 }
2060}
2061
2062static char *
d3ba0551 2063get_file_type (unsigned e_type)
252b5132 2064{
b34976b6 2065 static char buff[32];
252b5132
RH
2066
2067 switch (e_type)
2068 {
2069 case ET_NONE: return _("NONE (None)");
2070 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
2071 case ET_EXEC: return _("EXEC (Executable file)");
2072 case ET_DYN: return _("DYN (Shared object file)");
2073 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2074
2075 default:
2076 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2077 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2078 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2079 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2080 else
e9e44622 2081 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2082 return buff;
2083 }
2084}
2085
2086static char *
d3ba0551 2087get_machine_name (unsigned e_machine)
252b5132 2088{
b34976b6 2089 static char buff[64]; /* XXX */
252b5132
RH
2090
2091 switch (e_machine)
2092 {
c45021f2 2093 case EM_NONE: return _("None");
a06ea964 2094 case EM_AARCH64: return "AArch64";
c45021f2
NC
2095 case EM_M32: return "WE32100";
2096 case EM_SPARC: return "Sparc";
e9f53129 2097 case EM_SPU: return "SPU";
c45021f2
NC
2098 case EM_386: return "Intel 80386";
2099 case EM_68K: return "MC68000";
2100 case EM_88K: return "MC88000";
22abe556 2101 case EM_IAMCU: return "Intel MCU";
c45021f2
NC
2102 case EM_860: return "Intel 80860";
2103 case EM_MIPS: return "MIPS R3000";
2104 case EM_S370: return "IBM System/370";
7036c0e1 2105 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2106 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2107 case EM_PARISC: return "HPPA";
252b5132 2108 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 2109 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
2110 case EM_960: return "Intel 90860";
2111 case EM_PPC: return "PowerPC";
285d1771 2112 case EM_PPC64: return "PowerPC64";
c45021f2 2113 case EM_FR20: return "Fujitsu FR20";
3f8107ab 2114 case EM_FT32: return "FTDI FT32";
c45021f2 2115 case EM_RH32: return "TRW RH32";
b34976b6 2116 case EM_MCORE: return "MCORE";
7036c0e1
AJ
2117 case EM_ARM: return "ARM";
2118 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2119 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2120 case EM_SPARCV9: return "Sparc v9";
2121 case EM_TRICORE: return "Siemens Tricore";
584da044 2122 case EM_ARC: return "ARC";
886a2506
NC
2123 case EM_ARC_COMPACT: return "ARCompact";
2124 case EM_ARC_COMPACT2: return "ARCv2";
c2dcd04e
NC
2125 case EM_H8_300: return "Renesas H8/300";
2126 case EM_H8_300H: return "Renesas H8/300H";
2127 case EM_H8S: return "Renesas H8S";
2128 case EM_H8_500: return "Renesas H8/500";
30800947 2129 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2130 case EM_MIPS_X: return "Stanford MIPS-X";
2131 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 2132 case EM_ALPHA: return "Alpha";
2b0337b0
AO
2133 case EM_CYGNUS_D10V:
2134 case EM_D10V: return "d10v";
2135 case EM_CYGNUS_D30V:
b34976b6 2136 case EM_D30V: return "d30v";
2b0337b0 2137 case EM_CYGNUS_M32R:
26597c86 2138 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 2139 case EM_CYGNUS_V850:
708e2187 2140 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 2141 case EM_V850: return "Renesas V850";
2b0337b0
AO
2142 case EM_CYGNUS_MN10300:
2143 case EM_MN10300: return "mn10300";
2144 case EM_CYGNUS_MN10200:
2145 case EM_MN10200: return "mn10200";
5506d11a 2146 case EM_MOXIE: return "Moxie";
2b0337b0
AO
2147 case EM_CYGNUS_FR30:
2148 case EM_FR30: return "Fujitsu FR30";
b34976b6 2149 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 2150 case EM_PJ_OLD:
b34976b6 2151 case EM_PJ: return "picoJava";
7036c0e1
AJ
2152 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2153 case EM_PCP: return "Siemens PCP";
2154 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2155 case EM_NDR1: return "Denso NDR1 microprocesspr";
2156 case EM_STARCORE: return "Motorola Star*Core processor";
2157 case EM_ME16: return "Toyota ME16 processor";
2158 case EM_ST100: return "STMicroelectronics ST100 processor";
2159 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
2160 case EM_PDSP: return "Sony DSP processor";
2161 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2162 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2163 case EM_FX66: return "Siemens FX66 microcontroller";
2164 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2165 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2166 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 2167 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2168 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2169 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2170 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2171 case EM_SVX: return "Silicon Graphics SVx";
2172 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2173 case EM_VAX: return "Digital VAX";
619ed720 2174 case EM_VISIUM: return "CDS VISIUMcore processor";
2b0337b0 2175 case EM_AVR_OLD:
b34976b6 2176 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 2177 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2178 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2179 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2180 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2181 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2182 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2183 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2184 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2185 case EM_L1OM: return "Intel L1OM";
7a9068fe 2186 case EM_K1OM: return "Intel K1OM";
b7498e0e 2187 case EM_S390_OLD:
b34976b6 2188 case EM_S390: return "IBM S/390";
1c0d3aa6 2189 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2190 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
73589c9d 2191 case EM_OR1K: return "OpenRISC 1000";
1fe1f39c 2192 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2193 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2194 case EM_DLX: return "OpenDLX";
1e4cf259 2195 case EM_IP2K_OLD:
b34976b6 2196 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2197 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2198 case EM_XTENSA_OLD:
2199 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2200 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2201 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2202 case EM_NS32K: return "National Semiconductor 32000 series";
2203 case EM_TPC: return "Tenor Network TPC processor";
2204 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2205 case EM_MAX: return "MAX Processor";
2206 case EM_CR: return "National Semiconductor CompactRISC";
2207 case EM_F2MC16: return "Fujitsu F2MC16";
2208 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2209 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2210 case EM_M32C_OLD:
49f58d10 2211 case EM_M32C: return "Renesas M32c";
d031aafb 2212 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2213 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2214 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2215 case EM_SEP: return "Sharp embedded microprocessor";
2216 case EM_ARCA: return "Arca RISC microprocessor";
2217 case EM_UNICORE: return "Unicore";
2218 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2219 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2220 case EM_NIOS32: return "Altera Nios";
2221 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2222 case EM_C166:
d70c5fc7 2223 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2224 case EM_M16C: return "Renesas M16C series microprocessors";
2225 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2226 case EM_CE: return "Freescale Communication Engine RISC core";
2227 case EM_TSK3000: return "Altium TSK3000 core";
2228 case EM_RS08: return "Freescale RS08 embedded processor";
2229 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2230 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2231 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2232 case EM_SE_C17: return "Seiko Epson C17 family";
2233 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2234 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2235 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2236 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2237 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2238 case EM_R32C: return "Renesas R32C series microprocessors";
2239 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2240 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2241 case EM_8051: return "Intel 8051 and variants";
2242 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2243 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2244 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2245 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2246 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2247 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2248 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2249 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2250 case EM_CR16:
f6c1a2d5 2251 case EM_MICROBLAZE:
7ba29e2a 2252 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2253 case EM_RL78: return "Renesas RL78";
c7927a3c 2254 case EM_RX: return "Renesas RX";
a3c62988 2255 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2256 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2257 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2258 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2259 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2260 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2261 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2262 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2263 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2264 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2265 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2266 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2267 default:
35d9dd2f 2268 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2269 return buff;
2270 }
2271}
2272
f3485b74 2273static void
d3ba0551 2274decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2275{
2276 unsigned eabi;
2277 int unknown = 0;
2278
2279 eabi = EF_ARM_EABI_VERSION (e_flags);
2280 e_flags &= ~ EF_ARM_EABIMASK;
2281
2282 /* Handle "generic" ARM flags. */
2283 if (e_flags & EF_ARM_RELEXEC)
2284 {
2285 strcat (buf, ", relocatable executable");
2286 e_flags &= ~ EF_ARM_RELEXEC;
2287 }
76da6bbe 2288
f3485b74
NC
2289 /* Now handle EABI specific flags. */
2290 switch (eabi)
2291 {
2292 default:
2c71103e 2293 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2294 if (e_flags)
2295 unknown = 1;
2296 break;
2297
2298 case EF_ARM_EABI_VER1:
a5bcd848 2299 strcat (buf, ", Version1 EABI");
f3485b74
NC
2300 while (e_flags)
2301 {
2302 unsigned flag;
76da6bbe 2303
f3485b74
NC
2304 /* Process flags one bit at a time. */
2305 flag = e_flags & - e_flags;
2306 e_flags &= ~ flag;
76da6bbe 2307
f3485b74
NC
2308 switch (flag)
2309 {
a5bcd848 2310 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2311 strcat (buf, ", sorted symbol tables");
2312 break;
76da6bbe 2313
f3485b74
NC
2314 default:
2315 unknown = 1;
2316 break;
2317 }
2318 }
2319 break;
76da6bbe 2320
a5bcd848
PB
2321 case EF_ARM_EABI_VER2:
2322 strcat (buf, ", Version2 EABI");
2323 while (e_flags)
2324 {
2325 unsigned flag;
2326
2327 /* Process flags one bit at a time. */
2328 flag = e_flags & - e_flags;
2329 e_flags &= ~ flag;
2330
2331 switch (flag)
2332 {
2333 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2334 strcat (buf, ", sorted symbol tables");
2335 break;
2336
2337 case EF_ARM_DYNSYMSUSESEGIDX:
2338 strcat (buf, ", dynamic symbols use segment index");
2339 break;
2340
2341 case EF_ARM_MAPSYMSFIRST:
2342 strcat (buf, ", mapping symbols precede others");
2343 break;
2344
2345 default:
2346 unknown = 1;
2347 break;
2348 }
2349 }
2350 break;
2351
d507cf36
PB
2352 case EF_ARM_EABI_VER3:
2353 strcat (buf, ", Version3 EABI");
8cb51566
PB
2354 break;
2355
2356 case EF_ARM_EABI_VER4:
2357 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2358 while (e_flags)
2359 {
2360 unsigned flag;
2361
2362 /* Process flags one bit at a time. */
2363 flag = e_flags & - e_flags;
2364 e_flags &= ~ flag;
2365
2366 switch (flag)
2367 {
2368 case EF_ARM_BE8:
2369 strcat (buf, ", BE8");
2370 break;
2371
2372 case EF_ARM_LE8:
2373 strcat (buf, ", LE8");
2374 break;
2375
2376 default:
2377 unknown = 1;
2378 break;
2379 }
2380 break;
2381 }
2382 break;
3a4a14e9
PB
2383
2384 case EF_ARM_EABI_VER5:
2385 strcat (buf, ", Version5 EABI");
d507cf36
PB
2386 while (e_flags)
2387 {
2388 unsigned flag;
2389
2390 /* Process flags one bit at a time. */
2391 flag = e_flags & - e_flags;
2392 e_flags &= ~ flag;
2393
2394 switch (flag)
2395 {
2396 case EF_ARM_BE8:
2397 strcat (buf, ", BE8");
2398 break;
2399
2400 case EF_ARM_LE8:
2401 strcat (buf, ", LE8");
2402 break;
2403
3bfcb652
NC
2404 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2405 strcat (buf, ", soft-float ABI");
2406 break;
2407
2408 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2409 strcat (buf, ", hard-float ABI");
2410 break;
2411
d507cf36
PB
2412 default:
2413 unknown = 1;
2414 break;
2415 }
2416 }
2417 break;
2418
f3485b74 2419 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2420 strcat (buf, ", GNU EABI");
f3485b74
NC
2421 while (e_flags)
2422 {
2423 unsigned flag;
76da6bbe 2424
f3485b74
NC
2425 /* Process flags one bit at a time. */
2426 flag = e_flags & - e_flags;
2427 e_flags &= ~ flag;
76da6bbe 2428
f3485b74
NC
2429 switch (flag)
2430 {
a5bcd848 2431 case EF_ARM_INTERWORK:
f3485b74
NC
2432 strcat (buf, ", interworking enabled");
2433 break;
76da6bbe 2434
a5bcd848 2435 case EF_ARM_APCS_26:
f3485b74
NC
2436 strcat (buf, ", uses APCS/26");
2437 break;
76da6bbe 2438
a5bcd848 2439 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2440 strcat (buf, ", uses APCS/float");
2441 break;
76da6bbe 2442
a5bcd848 2443 case EF_ARM_PIC:
f3485b74
NC
2444 strcat (buf, ", position independent");
2445 break;
76da6bbe 2446
a5bcd848 2447 case EF_ARM_ALIGN8:
f3485b74
NC
2448 strcat (buf, ", 8 bit structure alignment");
2449 break;
76da6bbe 2450
a5bcd848 2451 case EF_ARM_NEW_ABI:
f3485b74
NC
2452 strcat (buf, ", uses new ABI");
2453 break;
76da6bbe 2454
a5bcd848 2455 case EF_ARM_OLD_ABI:
f3485b74
NC
2456 strcat (buf, ", uses old ABI");
2457 break;
76da6bbe 2458
a5bcd848 2459 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2460 strcat (buf, ", software FP");
2461 break;
76da6bbe 2462
90e01f86
ILT
2463 case EF_ARM_VFP_FLOAT:
2464 strcat (buf, ", VFP");
2465 break;
2466
fde78edd
NC
2467 case EF_ARM_MAVERICK_FLOAT:
2468 strcat (buf, ", Maverick FP");
2469 break;
2470
f3485b74
NC
2471 default:
2472 unknown = 1;
2473 break;
2474 }
2475 }
2476 }
f3485b74
NC
2477
2478 if (unknown)
2b692964 2479 strcat (buf,_(", <unknown>"));
f3485b74
NC
2480}
2481
343433df
AB
2482static void
2483decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2484{
2485 --size; /* Leave space for null terminator. */
2486
2487 switch (e_flags & EF_AVR_MACH)
2488 {
2489 case E_AVR_MACH_AVR1:
2490 strncat (buf, ", avr:1", size);
2491 break;
2492 case E_AVR_MACH_AVR2:
2493 strncat (buf, ", avr:2", size);
2494 break;
2495 case E_AVR_MACH_AVR25:
2496 strncat (buf, ", avr:25", size);
2497 break;
2498 case E_AVR_MACH_AVR3:
2499 strncat (buf, ", avr:3", size);
2500 break;
2501 case E_AVR_MACH_AVR31:
2502 strncat (buf, ", avr:31", size);
2503 break;
2504 case E_AVR_MACH_AVR35:
2505 strncat (buf, ", avr:35", size);
2506 break;
2507 case E_AVR_MACH_AVR4:
2508 strncat (buf, ", avr:4", size);
2509 break;
2510 case E_AVR_MACH_AVR5:
2511 strncat (buf, ", avr:5", size);
2512 break;
2513 case E_AVR_MACH_AVR51:
2514 strncat (buf, ", avr:51", size);
2515 break;
2516 case E_AVR_MACH_AVR6:
2517 strncat (buf, ", avr:6", size);
2518 break;
2519 case E_AVR_MACH_AVRTINY:
2520 strncat (buf, ", avr:100", size);
2521 break;
2522 case E_AVR_MACH_XMEGA1:
2523 strncat (buf, ", avr:101", size);
2524 break;
2525 case E_AVR_MACH_XMEGA2:
2526 strncat (buf, ", avr:102", size);
2527 break;
2528 case E_AVR_MACH_XMEGA3:
2529 strncat (buf, ", avr:103", size);
2530 break;
2531 case E_AVR_MACH_XMEGA4:
2532 strncat (buf, ", avr:104", size);
2533 break;
2534 case E_AVR_MACH_XMEGA5:
2535 strncat (buf, ", avr:105", size);
2536 break;
2537 case E_AVR_MACH_XMEGA6:
2538 strncat (buf, ", avr:106", size);
2539 break;
2540 case E_AVR_MACH_XMEGA7:
2541 strncat (buf, ", avr:107", size);
2542 break;
2543 default:
2544 strncat (buf, ", avr:<unknown>", size);
2545 break;
2546 }
2547
2548 size -= strlen (buf);
2549 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2550 strncat (buf, ", link-relax", size);
2551}
2552
35c08157
KLC
2553static void
2554decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2555{
2556 unsigned abi;
2557 unsigned arch;
2558 unsigned config;
2559 unsigned version;
2560 int has_fpu = 0;
2561 int r = 0;
2562
2563 static const char *ABI_STRINGS[] =
2564 {
2565 "ABI v0", /* use r5 as return register; only used in N1213HC */
2566 "ABI v1", /* use r0 as return register */
2567 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2568 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2569 "AABI",
2570 "ABI2 FP+"
35c08157
KLC
2571 };
2572 static const char *VER_STRINGS[] =
2573 {
2574 "Andes ELF V1.3 or older",
2575 "Andes ELF V1.3.1",
2576 "Andes ELF V1.4"
2577 };
2578 static const char *ARCH_STRINGS[] =
2579 {
2580 "",
2581 "Andes Star v1.0",
2582 "Andes Star v2.0",
2583 "Andes Star v3.0",
2584 "Andes Star v3.0m"
2585 };
2586
2587 abi = EF_NDS_ABI & e_flags;
2588 arch = EF_NDS_ARCH & e_flags;
2589 config = EF_NDS_INST & e_flags;
2590 version = EF_NDS32_ELF_VERSION & e_flags;
2591
2592 memset (buf, 0, size);
2593
2594 switch (abi)
2595 {
2596 case E_NDS_ABI_V0:
2597 case E_NDS_ABI_V1:
2598 case E_NDS_ABI_V2:
2599 case E_NDS_ABI_V2FP:
2600 case E_NDS_ABI_AABI:
40c7a7cb 2601 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2602 /* In case there are holes in the array. */
2603 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2604 break;
2605
2606 default:
2607 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2608 break;
2609 }
2610
2611 switch (version)
2612 {
2613 case E_NDS32_ELF_VER_1_2:
2614 case E_NDS32_ELF_VER_1_3:
2615 case E_NDS32_ELF_VER_1_4:
2616 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2617 break;
2618
2619 default:
2620 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2621 break;
2622 }
2623
2624 if (E_NDS_ABI_V0 == abi)
2625 {
2626 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2627 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2628 if (arch == E_NDS_ARCH_STAR_V1_0)
2629 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2630 return;
2631 }
2632
2633 switch (arch)
2634 {
2635 case E_NDS_ARCH_STAR_V1_0:
2636 case E_NDS_ARCH_STAR_V2_0:
2637 case E_NDS_ARCH_STAR_V3_0:
2638 case E_NDS_ARCH_STAR_V3_M:
2639 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2640 break;
2641
2642 default:
2643 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2644 /* ARCH version determines how the e_flags are interpreted.
2645 If it is unknown, we cannot proceed. */
2646 return;
2647 }
2648
2649 /* Newer ABI; Now handle architecture specific flags. */
2650 if (arch == E_NDS_ARCH_STAR_V1_0)
2651 {
2652 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2653 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2654
2655 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2656 r += snprintf (buf + r, size -r, ", MAC");
2657
2658 if (config & E_NDS32_HAS_DIV_INST)
2659 r += snprintf (buf + r, size -r, ", DIV");
2660
2661 if (config & E_NDS32_HAS_16BIT_INST)
2662 r += snprintf (buf + r, size -r, ", 16b");
2663 }
2664 else
2665 {
2666 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2667 {
2668 if (version <= E_NDS32_ELF_VER_1_3)
2669 r += snprintf (buf + r, size -r, ", [B8]");
2670 else
2671 r += snprintf (buf + r, size -r, ", EX9");
2672 }
2673
2674 if (config & E_NDS32_HAS_MAC_DX_INST)
2675 r += snprintf (buf + r, size -r, ", MAC_DX");
2676
2677 if (config & E_NDS32_HAS_DIV_DX_INST)
2678 r += snprintf (buf + r, size -r, ", DIV_DX");
2679
2680 if (config & E_NDS32_HAS_16BIT_INST)
2681 {
2682 if (version <= E_NDS32_ELF_VER_1_3)
2683 r += snprintf (buf + r, size -r, ", 16b");
2684 else
2685 r += snprintf (buf + r, size -r, ", IFC");
2686 }
2687 }
2688
2689 if (config & E_NDS32_HAS_EXT_INST)
2690 r += snprintf (buf + r, size -r, ", PERF1");
2691
2692 if (config & E_NDS32_HAS_EXT2_INST)
2693 r += snprintf (buf + r, size -r, ", PERF2");
2694
2695 if (config & E_NDS32_HAS_FPU_INST)
2696 {
2697 has_fpu = 1;
2698 r += snprintf (buf + r, size -r, ", FPU_SP");
2699 }
2700
2701 if (config & E_NDS32_HAS_FPU_DP_INST)
2702 {
2703 has_fpu = 1;
2704 r += snprintf (buf + r, size -r, ", FPU_DP");
2705 }
2706
2707 if (config & E_NDS32_HAS_FPU_MAC_INST)
2708 {
2709 has_fpu = 1;
2710 r += snprintf (buf + r, size -r, ", FPU_MAC");
2711 }
2712
2713 if (has_fpu)
2714 {
2715 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2716 {
2717 case E_NDS32_FPU_REG_8SP_4DP:
2718 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2719 break;
2720 case E_NDS32_FPU_REG_16SP_8DP:
2721 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2722 break;
2723 case E_NDS32_FPU_REG_32SP_16DP:
2724 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2725 break;
2726 case E_NDS32_FPU_REG_32SP_32DP:
2727 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
2728 break;
2729 }
2730 }
2731
2732 if (config & E_NDS32_HAS_AUDIO_INST)
2733 r += snprintf (buf + r, size -r, ", AUDIO");
2734
2735 if (config & E_NDS32_HAS_STRING_INST)
2736 r += snprintf (buf + r, size -r, ", STR");
2737
2738 if (config & E_NDS32_HAS_REDUCED_REGS)
2739 r += snprintf (buf + r, size -r, ", 16REG");
2740
2741 if (config & E_NDS32_HAS_VIDEO_INST)
2742 {
2743 if (version <= E_NDS32_ELF_VER_1_3)
2744 r += snprintf (buf + r, size -r, ", VIDEO");
2745 else
2746 r += snprintf (buf + r, size -r, ", SATURATION");
2747 }
2748
2749 if (config & E_NDS32_HAS_ENCRIPT_INST)
2750 r += snprintf (buf + r, size -r, ", ENCRP");
2751
2752 if (config & E_NDS32_HAS_L2C_INST)
2753 r += snprintf (buf + r, size -r, ", L2C");
2754}
2755
252b5132 2756static char *
d3ba0551 2757get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2758{
b34976b6 2759 static char buf[1024];
252b5132
RH
2760
2761 buf[0] = '\0';
76da6bbe 2762
252b5132
RH
2763 if (e_flags)
2764 {
2765 switch (e_machine)
2766 {
2767 default:
2768 break;
2769
886a2506
NC
2770 case EM_ARC_COMPACT2:
2771 switch (e_flags & EF_ARC_MACH_MSK)
2772 {
2773 case EF_ARC_CPU_ARCV2EM:
2774 strcat (buf, ", ARC EM");
2775 break;
2776 case EF_ARC_CPU_ARCV2HS:
2777 strcat (buf, ", ARC HS");
2778 break;
34e967a5
MC
2779 case EF_ARC_CPU_GENERIC:
2780 strcat (buf, ", ARC generic");
2781 break;
2782 case E_ARC_MACH_ARC600:
2783 strcat (buf, ", ARC600");
2784 break;
2785 case E_ARC_MACH_ARC601:
2786 strcat (buf, ", ARC601");
2787 break;
2788 case E_ARC_MACH_ARC700:
2789 strcat (buf, ", ARC700");
2790 break;
886a2506 2791 default:
34e967a5 2792 strcat (buf, ", unrecognized cpu flag for ARCv2");
886a2506
NC
2793 break;
2794 }
2795 switch (e_flags & EF_ARC_OSABI_MSK)
2796 {
34e967a5
MC
2797 case E_ARC_OSABI_ORIG:
2798 strcat (buf, ", (ABI:legacy)");
2799 break;
2800 case E_ARC_OSABI_V2:
2801 strcat (buf, ", (ABI:v2)");
2802 break;
2803 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
886a2506
NC
2804 case E_ARC_OSABI_V3:
2805 strcat (buf, ", v3 no-legacy-syscalls ABI");
2806 break;
34e967a5
MC
2807 default:
2808 strcat (buf, ", unrecognised ARC OSABI flag");
2809 break;
886a2506
NC
2810 }
2811 break;
2812
2813 case EM_ARC_COMPACT:
2814 switch (e_flags & EF_ARC_MACH_MSK)
2815 {
2816 case E_ARC_MACH_ARC600:
2817 strcat (buf, ", ARC 600");
2818 break;
2819 case E_ARC_MACH_ARC601:
2820 strcat (buf, ", ARC 601");
2821 break;
2822 case E_ARC_MACH_ARC700:
2823 strcat (buf, ", ARC 700");
2824 break;
2825 default:
2826 strcat (buf, ", Generic ARCompact");
2827 break;
2828 }
2829 switch (e_flags & EF_ARC_OSABI_MSK)
2830 {
2831 case E_ARC_OSABI_ORIG:
2832 strcat (buf, ", legacy syscall ABI");
2833 break;
2834 case E_ARC_OSABI_V2:
2835 /* For 3.2+ Linux kernels which use asm-generic
2836 hdrs. */
2837 strcat (buf, ", v2 syscall ABI");
2838 break;
2839 case E_ARC_OSABI_V3:
2840 /* Upstream 3.9+ kernels which don't use any legacy
2841 syscalls. */
2842 strcat (buf, ", v3 no-legacy-syscalls ABI");
2843 break;
2844 }
2845 break;
2846
f3485b74
NC
2847 case EM_ARM:
2848 decode_ARM_machine_flags (e_flags, buf);
2849 break;
76da6bbe 2850
343433df
AB
2851 case EM_AVR:
2852 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
2853 break;
2854
781303ce
MF
2855 case EM_BLACKFIN:
2856 if (e_flags & EF_BFIN_PIC)
2857 strcat (buf, ", PIC");
2858
2859 if (e_flags & EF_BFIN_FDPIC)
2860 strcat (buf, ", FDPIC");
2861
2862 if (e_flags & EF_BFIN_CODE_IN_L1)
2863 strcat (buf, ", code in L1");
2864
2865 if (e_flags & EF_BFIN_DATA_IN_L1)
2866 strcat (buf, ", data in L1");
2867
2868 break;
2869
ec2dfb42
AO
2870 case EM_CYGNUS_FRV:
2871 switch (e_flags & EF_FRV_CPU_MASK)
2872 {
2873 case EF_FRV_CPU_GENERIC:
2874 break;
2875
2876 default:
2877 strcat (buf, ", fr???");
2878 break;
57346661 2879
ec2dfb42
AO
2880 case EF_FRV_CPU_FR300:
2881 strcat (buf, ", fr300");
2882 break;
2883
2884 case EF_FRV_CPU_FR400:
2885 strcat (buf, ", fr400");
2886 break;
2887 case EF_FRV_CPU_FR405:
2888 strcat (buf, ", fr405");
2889 break;
2890
2891 case EF_FRV_CPU_FR450:
2892 strcat (buf, ", fr450");
2893 break;
2894
2895 case EF_FRV_CPU_FR500:
2896 strcat (buf, ", fr500");
2897 break;
2898 case EF_FRV_CPU_FR550:
2899 strcat (buf, ", fr550");
2900 break;
2901
2902 case EF_FRV_CPU_SIMPLE:
2903 strcat (buf, ", simple");
2904 break;
2905 case EF_FRV_CPU_TOMCAT:
2906 strcat (buf, ", tomcat");
2907 break;
2908 }
1c877e87 2909 break;
ec2dfb42 2910
53c7db4b 2911 case EM_68K:
425c6cb0 2912 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2913 strcat (buf, ", m68000");
425c6cb0 2914 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2915 strcat (buf, ", cpu32");
2916 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2917 strcat (buf, ", fido_a");
425c6cb0 2918 else
266abb8f 2919 {
2cf0635d
NC
2920 char const * isa = _("unknown");
2921 char const * mac = _("unknown mac");
2922 char const * additional = NULL;
0112cd26 2923
c694fd50 2924 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2925 {
c694fd50 2926 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2927 isa = "A";
2928 additional = ", nodiv";
2929 break;
c694fd50 2930 case EF_M68K_CF_ISA_A:
266abb8f
NS
2931 isa = "A";
2932 break;
c694fd50 2933 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2934 isa = "A+";
2935 break;
c694fd50 2936 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2937 isa = "B";
2938 additional = ", nousp";
2939 break;
c694fd50 2940 case EF_M68K_CF_ISA_B:
266abb8f
NS
2941 isa = "B";
2942 break;
f608cd77
NS
2943 case EF_M68K_CF_ISA_C:
2944 isa = "C";
2945 break;
2946 case EF_M68K_CF_ISA_C_NODIV:
2947 isa = "C";
2948 additional = ", nodiv";
2949 break;
266abb8f
NS
2950 }
2951 strcat (buf, ", cf, isa ");
2952 strcat (buf, isa);
0b2e31dc
NS
2953 if (additional)
2954 strcat (buf, additional);
c694fd50 2955 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2956 strcat (buf, ", float");
c694fd50 2957 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2958 {
2959 case 0:
2960 mac = NULL;
2961 break;
c694fd50 2962 case EF_M68K_CF_MAC:
266abb8f
NS
2963 mac = "mac";
2964 break;
c694fd50 2965 case EF_M68K_CF_EMAC:
266abb8f
NS
2966 mac = "emac";
2967 break;
f608cd77
NS
2968 case EF_M68K_CF_EMAC_B:
2969 mac = "emac_b";
2970 break;
266abb8f
NS
2971 }
2972 if (mac)
2973 {
2974 strcat (buf, ", ");
2975 strcat (buf, mac);
2976 }
266abb8f 2977 }
53c7db4b 2978 break;
33c63f9d 2979
153a2776
NC
2980 case EM_CYGNUS_MEP:
2981 switch (e_flags & EF_MEP_CPU_MASK)
2982 {
2983 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
2984 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
2985 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
2986 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
2987 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
2988 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
2989 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
2990 }
2991
2992 switch (e_flags & EF_MEP_COP_MASK)
2993 {
2994 case EF_MEP_COP_NONE: break;
2995 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
2996 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
2997 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
2998 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
2999 default: strcat (buf, _("<unknown MeP copro type>")); break;
3000 }
3001
3002 if (e_flags & EF_MEP_LIBRARY)
3003 strcat (buf, ", Built for Library");
3004
3005 if (e_flags & EF_MEP_INDEX_MASK)
3006 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3007 e_flags & EF_MEP_INDEX_MASK);
3008
3009 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3010 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3011 e_flags & ~ EF_MEP_ALL_FLAGS);
3012 break;
3013
252b5132
RH
3014 case EM_PPC:
3015 if (e_flags & EF_PPC_EMB)
3016 strcat (buf, ", emb");
3017
3018 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3019 strcat (buf, _(", relocatable"));
252b5132
RH
3020
3021 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3022 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3023 break;
3024
ee67d69a
AM
3025 case EM_PPC64:
3026 if (e_flags & EF_PPC64_ABI)
3027 {
3028 char abi[] = ", abiv0";
3029
3030 abi[6] += e_flags & EF_PPC64_ABI;
3031 strcat (buf, abi);
3032 }
3033 break;
3034
708e2187
NC
3035 case EM_V800:
3036 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3037 strcat (buf, ", RH850 ABI");
0b4362b0 3038
708e2187
NC
3039 if (e_flags & EF_V800_850E3)
3040 strcat (buf, ", V3 architecture");
3041
3042 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3043 strcat (buf, ", FPU not used");
3044
3045 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3046 strcat (buf, ", regmode: COMMON");
3047
3048 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3049 strcat (buf, ", r4 not used");
3050
3051 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3052 strcat (buf, ", r30 not used");
3053
3054 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3055 strcat (buf, ", r5 not used");
3056
3057 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3058 strcat (buf, ", r2 not used");
3059
3060 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3061 {
3062 switch (e_flags & - e_flags)
3063 {
3064 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3065 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3066 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3067 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3068 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3069 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3070 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3071 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3072 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3073 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3074 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3075 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3076 default: break;
3077 }
3078 }
3079 break;
3080
2b0337b0 3081 case EM_V850:
252b5132
RH
3082 case EM_CYGNUS_V850:
3083 switch (e_flags & EF_V850_ARCH)
3084 {
78c8d46c
NC
3085 case E_V850E3V5_ARCH:
3086 strcat (buf, ", v850e3v5");
3087 break;
1cd986c5
NC
3088 case E_V850E2V3_ARCH:
3089 strcat (buf, ", v850e2v3");
3090 break;
3091 case E_V850E2_ARCH:
3092 strcat (buf, ", v850e2");
3093 break;
3094 case E_V850E1_ARCH:
3095 strcat (buf, ", v850e1");
8ad30312 3096 break;
252b5132
RH
3097 case E_V850E_ARCH:
3098 strcat (buf, ", v850e");
3099 break;
252b5132
RH
3100 case E_V850_ARCH:
3101 strcat (buf, ", v850");
3102 break;
3103 default:
2b692964 3104 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3105 break;
3106 }
3107 break;
3108
2b0337b0 3109 case EM_M32R:
252b5132
RH
3110 case EM_CYGNUS_M32R:
3111 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3112 strcat (buf, ", m32r");
252b5132
RH
3113 break;
3114
3115 case EM_MIPS:
4fe85591 3116 case EM_MIPS_RS3_LE:
252b5132
RH
3117 if (e_flags & EF_MIPS_NOREORDER)
3118 strcat (buf, ", noreorder");
3119
3120 if (e_flags & EF_MIPS_PIC)
3121 strcat (buf, ", pic");
3122
3123 if (e_flags & EF_MIPS_CPIC)
3124 strcat (buf, ", cpic");
3125
d1bdd336
TS
3126 if (e_flags & EF_MIPS_UCODE)
3127 strcat (buf, ", ugen_reserved");
3128
252b5132
RH
3129 if (e_flags & EF_MIPS_ABI2)
3130 strcat (buf, ", abi2");
3131
43521d43
TS
3132 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3133 strcat (buf, ", odk first");
3134
a5d22d2a
TS
3135 if (e_flags & EF_MIPS_32BITMODE)
3136 strcat (buf, ", 32bitmode");
3137
ba92f887
MR
3138 if (e_flags & EF_MIPS_NAN2008)
3139 strcat (buf, ", nan2008");
3140
fef1b0b3
SE
3141 if (e_flags & EF_MIPS_FP64)
3142 strcat (buf, ", fp64");
3143
156c2f8b
NC
3144 switch ((e_flags & EF_MIPS_MACH))
3145 {
3146 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3147 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3148 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3149 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3150 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3151 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3152 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3153 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 3154 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3155 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3156 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3157 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 3158 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 3159 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3160 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3161 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3162 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
3163 case 0:
3164 /* We simply ignore the field in this case to avoid confusion:
3165 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3166 extension. */
3167 break;
2b692964 3168 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3169 }
43521d43
TS
3170
3171 switch ((e_flags & EF_MIPS_ABI))
3172 {
3173 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3174 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3175 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3176 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3177 case 0:
3178 /* We simply ignore the field in this case to avoid confusion:
3179 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3180 This means it is likely to be an o32 file, but not for
3181 sure. */
3182 break;
2b692964 3183 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3184 }
3185
3186 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3187 strcat (buf, ", mdmx");
3188
3189 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3190 strcat (buf, ", mips16");
3191
df58fc94
RS
3192 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3193 strcat (buf, ", micromips");
3194
43521d43
TS
3195 switch ((e_flags & EF_MIPS_ARCH))
3196 {
3197 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3198 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3199 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3200 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3201 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3202 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3203 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3204 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3205 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3206 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3207 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3208 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3209 }
252b5132 3210 break;
351b4b40 3211
35c08157
KLC
3212 case EM_NDS32:
3213 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3214 break;
3215
ccde1100
AO
3216 case EM_SH:
3217 switch ((e_flags & EF_SH_MACH_MASK))
3218 {
3219 case EF_SH1: strcat (buf, ", sh1"); break;
3220 case EF_SH2: strcat (buf, ", sh2"); break;
3221 case EF_SH3: strcat (buf, ", sh3"); break;
3222 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3223 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3224 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3225 case EF_SH3E: strcat (buf, ", sh3e"); break;
3226 case EF_SH4: strcat (buf, ", sh4"); break;
3227 case EF_SH5: strcat (buf, ", sh5"); break;
3228 case EF_SH2E: strcat (buf, ", sh2e"); break;
3229 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3230 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3231 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3232 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3233 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3234 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3235 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3236 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3237 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3238 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3239 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3240 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3241 }
3242
cec6a5b8
MR
3243 if (e_flags & EF_SH_PIC)
3244 strcat (buf, ", pic");
3245
3246 if (e_flags & EF_SH_FDPIC)
3247 strcat (buf, ", fdpic");
ccde1100 3248 break;
948f632f 3249
73589c9d
CS
3250 case EM_OR1K:
3251 if (e_flags & EF_OR1K_NODELAY)
3252 strcat (buf, ", no delay");
3253 break;
57346661 3254
351b4b40
RH
3255 case EM_SPARCV9:
3256 if (e_flags & EF_SPARC_32PLUS)
3257 strcat (buf, ", v8+");
3258
3259 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3260 strcat (buf, ", ultrasparcI");
3261
3262 if (e_flags & EF_SPARC_SUN_US3)
3263 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3264
3265 if (e_flags & EF_SPARC_HAL_R1)
3266 strcat (buf, ", halr1");
3267
3268 if (e_flags & EF_SPARC_LEDATA)
3269 strcat (buf, ", ledata");
3270
3271 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3272 strcat (buf, ", tso");
3273
3274 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3275 strcat (buf, ", pso");
3276
3277 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3278 strcat (buf, ", rmo");
3279 break;
7d466069 3280
103f02d3
UD
3281 case EM_PARISC:
3282 switch (e_flags & EF_PARISC_ARCH)
3283 {
3284 case EFA_PARISC_1_0:
3285 strcpy (buf, ", PA-RISC 1.0");
3286 break;
3287 case EFA_PARISC_1_1:
3288 strcpy (buf, ", PA-RISC 1.1");
3289 break;
3290 case EFA_PARISC_2_0:
3291 strcpy (buf, ", PA-RISC 2.0");
3292 break;
3293 default:
3294 break;
3295 }
3296 if (e_flags & EF_PARISC_TRAPNIL)
3297 strcat (buf, ", trapnil");
3298 if (e_flags & EF_PARISC_EXT)
3299 strcat (buf, ", ext");
3300 if (e_flags & EF_PARISC_LSB)
3301 strcat (buf, ", lsb");
3302 if (e_flags & EF_PARISC_WIDE)
3303 strcat (buf, ", wide");
3304 if (e_flags & EF_PARISC_NO_KABP)
3305 strcat (buf, ", no kabp");
3306 if (e_flags & EF_PARISC_LAZYSWAP)
3307 strcat (buf, ", lazyswap");
30800947 3308 break;
76da6bbe 3309
7d466069 3310 case EM_PJ:
2b0337b0 3311 case EM_PJ_OLD:
7d466069
ILT
3312 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3313 strcat (buf, ", new calling convention");
3314
3315 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3316 strcat (buf, ", gnu calling convention");
3317 break;
4d6ed7c8
NC
3318
3319 case EM_IA_64:
3320 if ((e_flags & EF_IA_64_ABI64))
3321 strcat (buf, ", 64-bit");
3322 else
3323 strcat (buf, ", 32-bit");
3324 if ((e_flags & EF_IA_64_REDUCEDFP))
3325 strcat (buf, ", reduced fp model");
3326 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3327 strcat (buf, ", no function descriptors, constant gp");
3328 else if ((e_flags & EF_IA_64_CONS_GP))
3329 strcat (buf, ", constant gp");
3330 if ((e_flags & EF_IA_64_ABSOLUTE))
3331 strcat (buf, ", absolute");
28f997cf
TG
3332 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3333 {
3334 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3335 strcat (buf, ", vms_linkages");
3336 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3337 {
3338 case EF_IA_64_VMS_COMCOD_SUCCESS:
3339 break;
3340 case EF_IA_64_VMS_COMCOD_WARNING:
3341 strcat (buf, ", warning");
3342 break;
3343 case EF_IA_64_VMS_COMCOD_ERROR:
3344 strcat (buf, ", error");
3345 break;
3346 case EF_IA_64_VMS_COMCOD_ABORT:
3347 strcat (buf, ", abort");
3348 break;
3349 default:
bee0ee85
NC
3350 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3351 e_flags & EF_IA_64_VMS_COMCOD);
3352 strcat (buf, ", <unknown>");
28f997cf
TG
3353 }
3354 }
4d6ed7c8 3355 break;
179d3252
JT
3356
3357 case EM_VAX:
3358 if ((e_flags & EF_VAX_NONPIC))
3359 strcat (buf, ", non-PIC");
3360 if ((e_flags & EF_VAX_DFLOAT))
3361 strcat (buf, ", D-Float");
3362 if ((e_flags & EF_VAX_GFLOAT))
3363 strcat (buf, ", G-Float");
3364 break;
c7927a3c 3365
619ed720
EB
3366 case EM_VISIUM:
3367 if (e_flags & EF_VISIUM_ARCH_MCM)
3368 strcat (buf, ", mcm");
3369 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3370 strcat (buf, ", mcm24");
3371 if (e_flags & EF_VISIUM_ARCH_GR6)
3372 strcat (buf, ", gr6");
3373 break;
3374
4046d87a 3375 case EM_RL78:
1740ba0c
NC
3376 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3377 {
3378 case E_FLAG_RL78_ANY_CPU: break;
3379 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3380 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3381 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3382 }
856ea05c
KP
3383 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3384 strcat (buf, ", 64-bit doubles");
4046d87a 3385 break;
0b4362b0 3386
c7927a3c
NC
3387 case EM_RX:
3388 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3389 strcat (buf, ", 64-bit doubles");
3390 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3391 strcat (buf, ", dsp");
d4cb0ea0 3392 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3393 strcat (buf, ", pid");
708e2187
NC
3394 if (e_flags & E_FLAG_RX_ABI)
3395 strcat (buf, ", RX ABI");
3525236c
NC
3396 if (e_flags & E_FLAG_RX_SINSNS_SET)
3397 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3398 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3399 if (e_flags & E_FLAG_RX_V2)
3400 strcat (buf, ", V2");
d4cb0ea0 3401 break;
55786da2
AK
3402
3403 case EM_S390:
3404 if (e_flags & EF_S390_HIGH_GPRS)
3405 strcat (buf, ", highgprs");
d4cb0ea0 3406 break;
40b36596
JM
3407
3408 case EM_TI_C6000:
3409 if ((e_flags & EF_C6000_REL))
3410 strcat (buf, ", relocatable module");
d4cb0ea0 3411 break;
13761a11
NC
3412
3413 case EM_MSP430:
3414 strcat (buf, _(": architecture variant: "));
3415 switch (e_flags & EF_MSP430_MACH)
3416 {
3417 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3418 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3419 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3420 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3421 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3422 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3423 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3424 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3425 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3426 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3427 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3428 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3429 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3430 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3431 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3432 default:
3433 strcat (buf, _(": unknown")); break;
3434 }
3435
3436 if (e_flags & ~ EF_MSP430_MACH)
3437 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3438 }
3439 }
3440
3441 return buf;
3442}
3443
252b5132 3444static const char *
d3ba0551
AM
3445get_osabi_name (unsigned int osabi)
3446{
3447 static char buff[32];
3448
3449 switch (osabi)
3450 {
3451 case ELFOSABI_NONE: return "UNIX - System V";
3452 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3453 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3454 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3455 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3456 case ELFOSABI_AIX: return "UNIX - AIX";
3457 case ELFOSABI_IRIX: return "UNIX - IRIX";
3458 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3459 case ELFOSABI_TRU64: return "UNIX - TRU64";
3460 case ELFOSABI_MODESTO: return "Novell - Modesto";
3461 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3462 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3463 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3464 case ELFOSABI_AROS: return "AROS";
11636f9e 3465 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 3466 default:
40b36596
JM
3467 if (osabi >= 64)
3468 switch (elf_header.e_machine)
3469 {
3470 case EM_ARM:
3471 switch (osabi)
3472 {
3473 case ELFOSABI_ARM: return "ARM";
3474 default:
3475 break;
3476 }
3477 break;
3478
3479 case EM_MSP430:
3480 case EM_MSP430_OLD:
619ed720 3481 case EM_VISIUM:
40b36596
JM
3482 switch (osabi)
3483 {
3484 case ELFOSABI_STANDALONE: return _("Standalone App");
3485 default:
3486 break;
3487 }
3488 break;
3489
3490 case EM_TI_C6000:
3491 switch (osabi)
3492 {
3493 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3494 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3495 default:
3496 break;
3497 }
3498 break;
3499
3500 default:
3501 break;
3502 }
e9e44622 3503 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3504 return buff;
3505 }
3506}
3507
a06ea964
NC
3508static const char *
3509get_aarch64_segment_type (unsigned long type)
3510{
3511 switch (type)
3512 {
3513 case PT_AARCH64_ARCHEXT:
3514 return "AARCH64_ARCHEXT";
3515 default:
3516 break;
3517 }
3518
3519 return NULL;
3520}
3521
b294bdf8
MM
3522static const char *
3523get_arm_segment_type (unsigned long type)
3524{
3525 switch (type)
3526 {
3527 case PT_ARM_EXIDX:
3528 return "EXIDX";
3529 default:
3530 break;
3531 }
3532
3533 return NULL;
3534}
3535
d3ba0551
AM
3536static const char *
3537get_mips_segment_type (unsigned long type)
252b5132
RH
3538{
3539 switch (type)
3540 {
3541 case PT_MIPS_REGINFO:
3542 return "REGINFO";
3543 case PT_MIPS_RTPROC:
3544 return "RTPROC";
3545 case PT_MIPS_OPTIONS:
3546 return "OPTIONS";
351cdf24
MF
3547 case PT_MIPS_ABIFLAGS:
3548 return "ABIFLAGS";
252b5132
RH
3549 default:
3550 break;
3551 }
3552
3553 return NULL;
3554}
3555
103f02d3 3556static const char *
d3ba0551 3557get_parisc_segment_type (unsigned long type)
103f02d3
UD
3558{
3559 switch (type)
3560 {
3561 case PT_HP_TLS: return "HP_TLS";
3562 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3563 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3564 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3565 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3566 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3567 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3568 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3569 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3570 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3571 case PT_HP_PARALLEL: return "HP_PARALLEL";
3572 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3573 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3574 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3575 case PT_HP_STACK: return "HP_STACK";
3576 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3577 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3578 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3579 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
3580 default:
3581 break;
3582 }
3583
3584 return NULL;
3585}
3586
4d6ed7c8 3587static const char *
d3ba0551 3588get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3589{
3590 switch (type)
3591 {
3592 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3593 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3594 case PT_HP_TLS: return "HP_TLS";
3595 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3596 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3597 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3598 default:
3599 break;
3600 }
3601
3602 return NULL;
3603}
3604
40b36596
JM
3605static const char *
3606get_tic6x_segment_type (unsigned long type)
3607{
3608 switch (type)
3609 {
3610 case PT_C6000_PHATTR: return "C6000_PHATTR";
3611 default:
3612 break;
3613 }
3614
3615 return NULL;
3616}
3617
252b5132 3618static const char *
d3ba0551 3619get_segment_type (unsigned long p_type)
252b5132 3620{
b34976b6 3621 static char buff[32];
252b5132
RH
3622
3623 switch (p_type)
3624 {
b34976b6
AM
3625 case PT_NULL: return "NULL";
3626 case PT_LOAD: return "LOAD";
252b5132 3627 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3628 case PT_INTERP: return "INTERP";
3629 case PT_NOTE: return "NOTE";
3630 case PT_SHLIB: return "SHLIB";
3631 case PT_PHDR: return "PHDR";
13ae64f3 3632 case PT_TLS: return "TLS";
252b5132 3633
65765700
JJ
3634 case PT_GNU_EH_FRAME:
3635 return "GNU_EH_FRAME";
2b05f1b7 3636 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3637 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3638
252b5132
RH
3639 default:
3640 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3641 {
2cf0635d 3642 const char * result;
103f02d3 3643
252b5132
RH
3644 switch (elf_header.e_machine)
3645 {
a06ea964
NC
3646 case EM_AARCH64:
3647 result = get_aarch64_segment_type (p_type);
3648 break;
b294bdf8
MM
3649 case EM_ARM:
3650 result = get_arm_segment_type (p_type);
3651 break;
252b5132 3652 case EM_MIPS:
4fe85591 3653 case EM_MIPS_RS3_LE:
252b5132
RH
3654 result = get_mips_segment_type (p_type);
3655 break;
103f02d3
UD
3656 case EM_PARISC:
3657 result = get_parisc_segment_type (p_type);
3658 break;
4d6ed7c8
NC
3659 case EM_IA_64:
3660 result = get_ia64_segment_type (p_type);
3661 break;
40b36596
JM
3662 case EM_TI_C6000:
3663 result = get_tic6x_segment_type (p_type);
3664 break;
252b5132
RH
3665 default:
3666 result = NULL;
3667 break;
3668 }
103f02d3 3669
252b5132
RH
3670 if (result != NULL)
3671 return result;
103f02d3 3672
252b5132
RH
3673 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3674 }
3675 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3676 {
2cf0635d 3677 const char * result;
103f02d3
UD
3678
3679 switch (elf_header.e_machine)
3680 {
3681 case EM_PARISC:
3682 result = get_parisc_segment_type (p_type);
3683 break;
00428cca
AM
3684 case EM_IA_64:
3685 result = get_ia64_segment_type (p_type);
3686 break;
103f02d3
UD
3687 default:
3688 result = NULL;
3689 break;
3690 }
3691
3692 if (result != NULL)
3693 return result;
3694
3695 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3696 }
252b5132 3697 else
e9e44622 3698 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3699
3700 return buff;
3701 }
3702}
3703
3704static const char *
d3ba0551 3705get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3706{
3707 switch (sh_type)
3708 {
b34976b6
AM
3709 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3710 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3711 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3712 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3713 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3714 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3715 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3716 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3717 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3718 case SHT_MIPS_RELD: return "MIPS_RELD";
3719 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3720 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3721 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3722 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3723 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3724 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3725 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3726 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3727 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3728 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3729 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3730 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3731 case SHT_MIPS_LINE: return "MIPS_LINE";
3732 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3733 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3734 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3735 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3736 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3737 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3738 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3739 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3740 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3741 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3742 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3743 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3744 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3745 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3746 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 3747 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 3748 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
3749 default:
3750 break;
3751 }
3752 return NULL;
3753}
3754
103f02d3 3755static const char *
d3ba0551 3756get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3757{
3758 switch (sh_type)
3759 {
3760 case SHT_PARISC_EXT: return "PARISC_EXT";
3761 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3762 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3763 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3764 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3765 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3766 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3767 default:
3768 break;
3769 }
3770 return NULL;
3771}
3772
4d6ed7c8 3773static const char *
d3ba0551 3774get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3775{
18bd398b 3776 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3777 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3778 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3779
4d6ed7c8
NC
3780 switch (sh_type)
3781 {
148b93f2
NC
3782 case SHT_IA_64_EXT: return "IA_64_EXT";
3783 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3784 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3785 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3786 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3787 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3788 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3789 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3790 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3791 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3792 default:
3793 break;
3794 }
3795 return NULL;
3796}
3797
d2b2c203
DJ
3798static const char *
3799get_x86_64_section_type_name (unsigned int sh_type)
3800{
3801 switch (sh_type)
3802 {
3803 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3804 default:
3805 break;
3806 }
3807 return NULL;
3808}
3809
a06ea964
NC
3810static const char *
3811get_aarch64_section_type_name (unsigned int sh_type)
3812{
3813 switch (sh_type)
3814 {
3815 case SHT_AARCH64_ATTRIBUTES:
3816 return "AARCH64_ATTRIBUTES";
3817 default:
3818 break;
3819 }
3820 return NULL;
3821}
3822
40a18ebd
NC
3823static const char *
3824get_arm_section_type_name (unsigned int sh_type)
3825{
3826 switch (sh_type)
3827 {
7f6fed87
NC
3828 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3829 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3830 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3831 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3832 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3833 default:
3834 break;
3835 }
3836 return NULL;
3837}
3838
40b36596
JM
3839static const char *
3840get_tic6x_section_type_name (unsigned int sh_type)
3841{
3842 switch (sh_type)
3843 {
3844 case SHT_C6000_UNWIND:
3845 return "C6000_UNWIND";
3846 case SHT_C6000_PREEMPTMAP:
3847 return "C6000_PREEMPTMAP";
3848 case SHT_C6000_ATTRIBUTES:
3849 return "C6000_ATTRIBUTES";
3850 case SHT_TI_ICODE:
3851 return "TI_ICODE";
3852 case SHT_TI_XREF:
3853 return "TI_XREF";
3854 case SHT_TI_HANDLER:
3855 return "TI_HANDLER";
3856 case SHT_TI_INITINFO:
3857 return "TI_INITINFO";
3858 case SHT_TI_PHATTRS:
3859 return "TI_PHATTRS";
3860 default:
3861 break;
3862 }
3863 return NULL;
3864}
3865
13761a11
NC
3866static const char *
3867get_msp430x_section_type_name (unsigned int sh_type)
3868{
3869 switch (sh_type)
3870 {
3871 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3872 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3873 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3874 default: return NULL;
3875 }
3876}
3877
685080f2
NC
3878static const char *
3879get_v850_section_type_name (unsigned int sh_type)
3880{
3881 switch (sh_type)
3882 {
3883 case SHT_V850_SCOMMON: return "V850 Small Common";
3884 case SHT_V850_TCOMMON: return "V850 Tiny Common";
3885 case SHT_V850_ZCOMMON: return "V850 Zero Common";
3886 case SHT_RENESAS_IOP: return "RENESAS IOP";
3887 case SHT_RENESAS_INFO: return "RENESAS INFO";
3888 default: return NULL;
3889 }
3890}
3891
252b5132 3892static const char *
d3ba0551 3893get_section_type_name (unsigned int sh_type)
252b5132 3894{
b34976b6 3895 static char buff[32];
252b5132
RH
3896
3897 switch (sh_type)
3898 {
3899 case SHT_NULL: return "NULL";
3900 case SHT_PROGBITS: return "PROGBITS";
3901 case SHT_SYMTAB: return "SYMTAB";
3902 case SHT_STRTAB: return "STRTAB";
3903 case SHT_RELA: return "RELA";
3904 case SHT_HASH: return "HASH";
3905 case SHT_DYNAMIC: return "DYNAMIC";
3906 case SHT_NOTE: return "NOTE";
3907 case SHT_NOBITS: return "NOBITS";
3908 case SHT_REL: return "REL";
3909 case SHT_SHLIB: return "SHLIB";
3910 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3911 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3912 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3913 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3914 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3915 case SHT_GROUP: return "GROUP";
3916 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3917 case SHT_GNU_verdef: return "VERDEF";
3918 case SHT_GNU_verneed: return "VERNEED";
3919 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3920 case 0x6ffffff0: return "VERSYM";
3921 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3922 case 0x7ffffffd: return "AUXILIARY";
3923 case 0x7fffffff: return "FILTER";
047b2264 3924 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3925
3926 default:
3927 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3928 {
2cf0635d 3929 const char * result;
252b5132
RH
3930
3931 switch (elf_header.e_machine)
3932 {
3933 case EM_MIPS:
4fe85591 3934 case EM_MIPS_RS3_LE:
252b5132
RH
3935 result = get_mips_section_type_name (sh_type);
3936 break;
103f02d3
UD
3937 case EM_PARISC:
3938 result = get_parisc_section_type_name (sh_type);
3939 break;
4d6ed7c8
NC
3940 case EM_IA_64:
3941 result = get_ia64_section_type_name (sh_type);
3942 break;
d2b2c203 3943 case EM_X86_64:
8a9036a4 3944 case EM_L1OM:
7a9068fe 3945 case EM_K1OM:
d2b2c203
DJ
3946 result = get_x86_64_section_type_name (sh_type);
3947 break;
a06ea964
NC
3948 case EM_AARCH64:
3949 result = get_aarch64_section_type_name (sh_type);
3950 break;
40a18ebd
NC
3951 case EM_ARM:
3952 result = get_arm_section_type_name (sh_type);
3953 break;
40b36596
JM
3954 case EM_TI_C6000:
3955 result = get_tic6x_section_type_name (sh_type);
3956 break;
13761a11
NC
3957 case EM_MSP430:
3958 result = get_msp430x_section_type_name (sh_type);
3959 break;
685080f2
NC
3960 case EM_V800:
3961 case EM_V850:
3962 case EM_CYGNUS_V850:
3963 result = get_v850_section_type_name (sh_type);
3964 break;
252b5132
RH
3965 default:
3966 result = NULL;
3967 break;
3968 }
3969
3970 if (result != NULL)
3971 return result;
3972
c91d0dfb 3973 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3974 }
3975 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3976 {
2cf0635d 3977 const char * result;
148b93f2
NC
3978
3979 switch (elf_header.e_machine)
3980 {
3981 case EM_IA_64:
3982 result = get_ia64_section_type_name (sh_type);
3983 break;
3984 default:
3985 result = NULL;
3986 break;
3987 }
3988
3989 if (result != NULL)
3990 return result;
3991
3992 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3993 }
252b5132 3994 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2
NC
3995 {
3996 switch (elf_header.e_machine)
3997 {
3998 case EM_V800:
3999 case EM_V850:
4000 case EM_CYGNUS_V850:
4001 return get_v850_section_type_name (sh_type);
4002 default:
4003 break;
4004 }
4005
4006 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
4007 }
252b5132 4008 else
a7dbfd1c
NC
4009 /* This message is probably going to be displayed in a 15
4010 character wide field, so put the hex value first. */
4011 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4012
252b5132
RH
4013 return buff;
4014 }
4015}
4016
2979dc34 4017#define OPTION_DEBUG_DUMP 512
2c610e4b 4018#define OPTION_DYN_SYMS 513
fd2f0033
TT
4019#define OPTION_DWARF_DEPTH 514
4020#define OPTION_DWARF_START 515
4723351a 4021#define OPTION_DWARF_CHECK 516
2979dc34 4022
85b1c36d 4023static struct option options[] =
252b5132 4024{
b34976b6 4025 {"all", no_argument, 0, 'a'},
252b5132
RH
4026 {"file-header", no_argument, 0, 'h'},
4027 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
4028 {"headers", no_argument, 0, 'e'},
4029 {"histogram", no_argument, 0, 'I'},
4030 {"segments", no_argument, 0, 'l'},
4031 {"sections", no_argument, 0, 'S'},
252b5132 4032 {"section-headers", no_argument, 0, 'S'},
f5842774 4033 {"section-groups", no_argument, 0, 'g'},
5477e8a0 4034 {"section-details", no_argument, 0, 't'},
595cf52e 4035 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
4036 {"symbols", no_argument, 0, 's'},
4037 {"syms", no_argument, 0, 's'},
2c610e4b 4038 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
4039 {"relocs", no_argument, 0, 'r'},
4040 {"notes", no_argument, 0, 'n'},
4041 {"dynamic", no_argument, 0, 'd'},
a952a375 4042 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
4043 {"version-info", no_argument, 0, 'V'},
4044 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 4045 {"unwind", no_argument, 0, 'u'},
4145f1d5 4046 {"archive-index", no_argument, 0, 'c'},
b34976b6 4047 {"hex-dump", required_argument, 0, 'x'},
cf13d699 4048 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 4049 {"string-dump", required_argument, 0, 'p'},
0e602686 4050 {"decompress", no_argument, 0, 'z'},
252b5132
RH
4051#ifdef SUPPORT_DISASSEMBLY
4052 {"instruction-dump", required_argument, 0, 'i'},
4053#endif
cf13d699 4054 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 4055
fd2f0033
TT
4056 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4057 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4058 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 4059
b34976b6
AM
4060 {"version", no_argument, 0, 'v'},
4061 {"wide", no_argument, 0, 'W'},
4062 {"help", no_argument, 0, 'H'},
4063 {0, no_argument, 0, 0}
252b5132
RH
4064};
4065
4066static void
2cf0635d 4067usage (FILE * stream)
252b5132 4068{
92f01d61
JM
4069 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4070 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4071 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4072 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4073 -h --file-header Display the ELF file header\n\
4074 -l --program-headers Display the program headers\n\
4075 --segments An alias for --program-headers\n\
4076 -S --section-headers Display the sections' header\n\
4077 --sections An alias for --section-headers\n\
f5842774 4078 -g --section-groups Display the section groups\n\
5477e8a0 4079 -t --section-details Display the section details\n\
8b53311e
NC
4080 -e --headers Equivalent to: -h -l -S\n\
4081 -s --syms Display the symbol table\n\
3f08eb35 4082 --symbols An alias for --syms\n\
2c610e4b 4083 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
4084 -n --notes Display the core notes (if present)\n\
4085 -r --relocs Display the relocations (if present)\n\
4086 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4087 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4088 -V --version-info Display the version sections (if present)\n\
1b31d05e 4089 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4090 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4091 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
4092 -x --hex-dump=<number|name>\n\
4093 Dump the contents of section <number|name> as bytes\n\
4094 -p --string-dump=<number|name>\n\
4095 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4096 -R --relocated-dump=<number|name>\n\
4097 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4098 -z --decompress Decompress section before dumping it\n\
f9f0e732 4099 -w[lLiaprmfFsoRt] or\n\
1ed06042 4100 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 4101 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
4102 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
4103 =addr,=cu_index]\n\
8b53311e 4104 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
4105 fprintf (stream, _("\
4106 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4107 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4108 or deeper\n"));
252b5132 4109#ifdef SUPPORT_DISASSEMBLY
92f01d61 4110 fprintf (stream, _("\
09c11c86
NC
4111 -i --instruction-dump=<number|name>\n\
4112 Disassemble the contents of section <number|name>\n"));
252b5132 4113#endif
92f01d61 4114 fprintf (stream, _("\
8b53311e
NC
4115 -I --histogram Display histogram of bucket list lengths\n\
4116 -W --wide Allow output width to exceed 80 characters\n\
07012eee 4117 @<file> Read options from <file>\n\
8b53311e
NC
4118 -H --help Display this information\n\
4119 -v --version Display the version number of readelf\n"));
1118d252 4120
92f01d61
JM
4121 if (REPORT_BUGS_TO[0] && stream == stdout)
4122 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4123
92f01d61 4124 exit (stream == stdout ? 0 : 1);
252b5132
RH
4125}
4126
18bd398b
NC
4127/* Record the fact that the user wants the contents of section number
4128 SECTION to be displayed using the method(s) encoded as flags bits
4129 in TYPE. Note, TYPE can be zero if we are creating the array for
4130 the first time. */
4131
252b5132 4132static void
09c11c86 4133request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
4134{
4135 if (section >= num_dump_sects)
4136 {
2cf0635d 4137 dump_type * new_dump_sects;
252b5132 4138
3f5e193b
NC
4139 new_dump_sects = (dump_type *) calloc (section + 1,
4140 sizeof (* dump_sects));
252b5132
RH
4141
4142 if (new_dump_sects == NULL)
591a748a 4143 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4144 else
4145 {
4146 /* Copy current flag settings. */
09c11c86 4147 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
4148
4149 free (dump_sects);
4150
4151 dump_sects = new_dump_sects;
4152 num_dump_sects = section + 1;
4153 }
4154 }
4155
4156 if (dump_sects)
b34976b6 4157 dump_sects[section] |= type;
252b5132
RH
4158
4159 return;
4160}
4161
aef1f6d0
DJ
4162/* Request a dump by section name. */
4163
4164static void
2cf0635d 4165request_dump_byname (const char * section, dump_type type)
aef1f6d0 4166{
2cf0635d 4167 struct dump_list_entry * new_request;
aef1f6d0 4168
3f5e193b
NC
4169 new_request = (struct dump_list_entry *)
4170 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4171 if (!new_request)
591a748a 4172 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4173
4174 new_request->name = strdup (section);
4175 if (!new_request->name)
591a748a 4176 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4177
4178 new_request->type = type;
4179
4180 new_request->next = dump_sects_byname;
4181 dump_sects_byname = new_request;
4182}
4183
cf13d699
NC
4184static inline void
4185request_dump (dump_type type)
4186{
4187 int section;
4188 char * cp;
4189
4190 do_dump++;
4191 section = strtoul (optarg, & cp, 0);
4192
4193 if (! *cp && section >= 0)
4194 request_dump_bynumber (section, type);
4195 else
4196 request_dump_byname (optarg, type);
4197}
4198
4199
252b5132 4200static void
2cf0635d 4201parse_args (int argc, char ** argv)
252b5132
RH
4202{
4203 int c;
4204
4205 if (argc < 2)
92f01d61 4206 usage (stderr);
252b5132
RH
4207
4208 while ((c = getopt_long
0e602686 4209 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4210 {
252b5132
RH
4211 switch (c)
4212 {
4213 case 0:
4214 /* Long options. */
4215 break;
4216 case 'H':
92f01d61 4217 usage (stdout);
252b5132
RH
4218 break;
4219
4220 case 'a':
b34976b6
AM
4221 do_syms++;
4222 do_reloc++;
4223 do_unwind++;
4224 do_dynamic++;
4225 do_header++;
4226 do_sections++;
f5842774 4227 do_section_groups++;
b34976b6
AM
4228 do_segments++;
4229 do_version++;
4230 do_histogram++;
4231 do_arch++;
4232 do_notes++;
252b5132 4233 break;
f5842774
L
4234 case 'g':
4235 do_section_groups++;
4236 break;
5477e8a0 4237 case 't':
595cf52e 4238 case 'N':
5477e8a0
L
4239 do_sections++;
4240 do_section_details++;
595cf52e 4241 break;
252b5132 4242 case 'e':
b34976b6
AM
4243 do_header++;
4244 do_sections++;
4245 do_segments++;
252b5132 4246 break;
a952a375 4247 case 'A':
b34976b6 4248 do_arch++;
a952a375 4249 break;
252b5132 4250 case 'D':
b34976b6 4251 do_using_dynamic++;
252b5132
RH
4252 break;
4253 case 'r':
b34976b6 4254 do_reloc++;
252b5132 4255 break;
4d6ed7c8 4256 case 'u':
b34976b6 4257 do_unwind++;
4d6ed7c8 4258 break;
252b5132 4259 case 'h':
b34976b6 4260 do_header++;
252b5132
RH
4261 break;
4262 case 'l':
b34976b6 4263 do_segments++;
252b5132
RH
4264 break;
4265 case 's':
b34976b6 4266 do_syms++;
252b5132
RH
4267 break;
4268 case 'S':
b34976b6 4269 do_sections++;
252b5132
RH
4270 break;
4271 case 'd':
b34976b6 4272 do_dynamic++;
252b5132 4273 break;
a952a375 4274 case 'I':
b34976b6 4275 do_histogram++;
a952a375 4276 break;
779fe533 4277 case 'n':
b34976b6 4278 do_notes++;
779fe533 4279 break;
4145f1d5
NC
4280 case 'c':
4281 do_archive_index++;
4282 break;
252b5132 4283 case 'x':
cf13d699 4284 request_dump (HEX_DUMP);
aef1f6d0 4285 break;
09c11c86 4286 case 'p':
cf13d699
NC
4287 request_dump (STRING_DUMP);
4288 break;
4289 case 'R':
4290 request_dump (RELOC_DUMP);
09c11c86 4291 break;
0e602686
NC
4292 case 'z':
4293 decompress_dumps++;
4294 break;
252b5132 4295 case 'w':
b34976b6 4296 do_dump++;
252b5132 4297 if (optarg == 0)
613ff48b
CC
4298 {
4299 do_debugging = 1;
4300 dwarf_select_sections_all ();
4301 }
252b5132
RH
4302 else
4303 {
4304 do_debugging = 0;
4cb93e3b 4305 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4306 }
4307 break;
2979dc34 4308 case OPTION_DEBUG_DUMP:
b34976b6 4309 do_dump++;
2979dc34
JJ
4310 if (optarg == 0)
4311 do_debugging = 1;
4312 else
4313 {
2979dc34 4314 do_debugging = 0;
4cb93e3b 4315 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4316 }
4317 break;
fd2f0033
TT
4318 case OPTION_DWARF_DEPTH:
4319 {
4320 char *cp;
4321
4322 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4323 }
4324 break;
4325 case OPTION_DWARF_START:
4326 {
4327 char *cp;
4328
4329 dwarf_start_die = strtoul (optarg, & cp, 0);
4330 }
4331 break;
4723351a
CC
4332 case OPTION_DWARF_CHECK:
4333 dwarf_check = 1;
4334 break;
2c610e4b
L
4335 case OPTION_DYN_SYMS:
4336 do_dyn_syms++;
4337 break;
252b5132
RH
4338#ifdef SUPPORT_DISASSEMBLY
4339 case 'i':
cf13d699
NC
4340 request_dump (DISASS_DUMP);
4341 break;
252b5132
RH
4342#endif
4343 case 'v':
4344 print_version (program_name);
4345 break;
4346 case 'V':
b34976b6 4347 do_version++;
252b5132 4348 break;
d974e256 4349 case 'W':
b34976b6 4350 do_wide++;
d974e256 4351 break;
252b5132 4352 default:
252b5132
RH
4353 /* xgettext:c-format */
4354 error (_("Invalid option '-%c'\n"), c);
4355 /* Drop through. */
4356 case '?':
92f01d61 4357 usage (stderr);
252b5132
RH
4358 }
4359 }
4360
4d6ed7c8 4361 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4362 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4363 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4364 && !do_section_groups && !do_archive_index
4365 && !do_dyn_syms)
92f01d61 4366 usage (stderr);
252b5132
RH
4367}
4368
4369static const char *
d3ba0551 4370get_elf_class (unsigned int elf_class)
252b5132 4371{
b34976b6 4372 static char buff[32];
103f02d3 4373
252b5132
RH
4374 switch (elf_class)
4375 {
4376 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4377 case ELFCLASS32: return "ELF32";
4378 case ELFCLASS64: return "ELF64";
ab5e7794 4379 default:
e9e44622 4380 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4381 return buff;
252b5132
RH
4382 }
4383}
4384
4385static const char *
d3ba0551 4386get_data_encoding (unsigned int encoding)
252b5132 4387{
b34976b6 4388 static char buff[32];
103f02d3 4389
252b5132
RH
4390 switch (encoding)
4391 {
4392 case ELFDATANONE: return _("none");
33c63f9d
CM
4393 case ELFDATA2LSB: return _("2's complement, little endian");
4394 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4395 default:
e9e44622 4396 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4397 return buff;
252b5132
RH
4398 }
4399}
4400
252b5132 4401/* Decode the data held in 'elf_header'. */
ee42cf8c 4402
252b5132 4403static int
d3ba0551 4404process_file_header (void)
252b5132 4405{
b34976b6
AM
4406 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
4407 || elf_header.e_ident[EI_MAG1] != ELFMAG1
4408 || elf_header.e_ident[EI_MAG2] != ELFMAG2
4409 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4410 {
4411 error
4412 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
4413 return 0;
4414 }
4415
2dc4cec1
L
4416 init_dwarf_regnames (elf_header.e_machine);
4417
252b5132
RH
4418 if (do_header)
4419 {
4420 int i;
4421
4422 printf (_("ELF Header:\n"));
4423 printf (_(" Magic: "));
b34976b6
AM
4424 for (i = 0; i < EI_NIDENT; i++)
4425 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
4426 printf ("\n");
4427 printf (_(" Class: %s\n"),
b34976b6 4428 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 4429 printf (_(" Data: %s\n"),
b34976b6 4430 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 4431 printf (_(" Version: %d %s\n"),
b34976b6
AM
4432 elf_header.e_ident[EI_VERSION],
4433 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4434 ? "(current)"
b34976b6 4435 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 4436 ? _("<unknown: %lx>")
789be9f7 4437 : "")));
252b5132 4438 printf (_(" OS/ABI: %s\n"),
b34976b6 4439 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 4440 printf (_(" ABI Version: %d\n"),
b34976b6 4441 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
4442 printf (_(" Type: %s\n"),
4443 get_file_type (elf_header.e_type));
4444 printf (_(" Machine: %s\n"),
4445 get_machine_name (elf_header.e_machine));
4446 printf (_(" Version: 0x%lx\n"),
4447 (unsigned long) elf_header.e_version);
76da6bbe 4448
f7a99963
NC
4449 printf (_(" Entry point address: "));
4450 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4451 printf (_("\n Start of program headers: "));
4452 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4453 printf (_(" (bytes into file)\n Start of section headers: "));
4454 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
4455 printf (_(" (bytes into file)\n"));
76da6bbe 4456
252b5132
RH
4457 printf (_(" Flags: 0x%lx%s\n"),
4458 (unsigned long) elf_header.e_flags,
4459 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
4460 printf (_(" Size of this header: %ld (bytes)\n"),
4461 (long) elf_header.e_ehsize);
4462 printf (_(" Size of program headers: %ld (bytes)\n"),
4463 (long) elf_header.e_phentsize);
2046a35d 4464 printf (_(" Number of program headers: %ld"),
252b5132 4465 (long) elf_header.e_phnum);
2046a35d
AM
4466 if (section_headers != NULL
4467 && elf_header.e_phnum == PN_XNUM
4468 && section_headers[0].sh_info != 0)
cc5914eb 4469 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 4470 putc ('\n', stdout);
252b5132
RH
4471 printf (_(" Size of section headers: %ld (bytes)\n"),
4472 (long) elf_header.e_shentsize);
560f3c1c 4473 printf (_(" Number of section headers: %ld"),
252b5132 4474 (long) elf_header.e_shnum);
4fbb74a6 4475 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
4476 printf (" (%ld)", (long) section_headers[0].sh_size);
4477 putc ('\n', stdout);
4478 printf (_(" Section header string table index: %ld"),
252b5132 4479 (long) elf_header.e_shstrndx);
4fbb74a6
AM
4480 if (section_headers != NULL
4481 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 4482 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
4483 else if (elf_header.e_shstrndx != SHN_UNDEF
4484 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 4485 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4486 putc ('\n', stdout);
4487 }
4488
4489 if (section_headers != NULL)
4490 {
2046a35d
AM
4491 if (elf_header.e_phnum == PN_XNUM
4492 && section_headers[0].sh_info != 0)
4493 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 4494 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 4495 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 4496 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 4497 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 4498 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 4499 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
4500 free (section_headers);
4501 section_headers = NULL;
252b5132 4502 }
103f02d3 4503
9ea033b2
NC
4504 return 1;
4505}
4506
e0a31db1 4507static bfd_boolean
91d6fa6a 4508get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4509{
2cf0635d
NC
4510 Elf32_External_Phdr * phdrs;
4511 Elf32_External_Phdr * external;
4512 Elf_Internal_Phdr * internal;
b34976b6 4513 unsigned int i;
e0a31db1
NC
4514 unsigned int size = elf_header.e_phentsize;
4515 unsigned int num = elf_header.e_phnum;
4516
4517 /* PR binutils/17531: Cope with unexpected section header sizes. */
4518 if (size == 0 || num == 0)
4519 return FALSE;
4520 if (size < sizeof * phdrs)
4521 {
4522 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4523 return FALSE;
4524 }
4525 if (size > sizeof * phdrs)
4526 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4527
3f5e193b 4528 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1
NC
4529 size, num, _("program headers"));
4530 if (phdrs == NULL)
4531 return FALSE;
9ea033b2 4532
91d6fa6a 4533 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4534 i < elf_header.e_phnum;
b34976b6 4535 i++, internal++, external++)
252b5132 4536 {
9ea033b2
NC
4537 internal->p_type = BYTE_GET (external->p_type);
4538 internal->p_offset = BYTE_GET (external->p_offset);
4539 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4540 internal->p_paddr = BYTE_GET (external->p_paddr);
4541 internal->p_filesz = BYTE_GET (external->p_filesz);
4542 internal->p_memsz = BYTE_GET (external->p_memsz);
4543 internal->p_flags = BYTE_GET (external->p_flags);
4544 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4545 }
4546
9ea033b2 4547 free (phdrs);
e0a31db1 4548 return TRUE;
252b5132
RH
4549}
4550
e0a31db1 4551static bfd_boolean
91d6fa6a 4552get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4553{
2cf0635d
NC
4554 Elf64_External_Phdr * phdrs;
4555 Elf64_External_Phdr * external;
4556 Elf_Internal_Phdr * internal;
b34976b6 4557 unsigned int i;
e0a31db1
NC
4558 unsigned int size = elf_header.e_phentsize;
4559 unsigned int num = elf_header.e_phnum;
4560
4561 /* PR binutils/17531: Cope with unexpected section header sizes. */
4562 if (size == 0 || num == 0)
4563 return FALSE;
4564 if (size < sizeof * phdrs)
4565 {
4566 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4567 return FALSE;
4568 }
4569 if (size > sizeof * phdrs)
4570 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4571
3f5e193b 4572 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1 4573 size, num, _("program headers"));
a6e9f9df 4574 if (!phdrs)
e0a31db1 4575 return FALSE;
9ea033b2 4576
91d6fa6a 4577 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4578 i < elf_header.e_phnum;
b34976b6 4579 i++, internal++, external++)
9ea033b2
NC
4580 {
4581 internal->p_type = BYTE_GET (external->p_type);
4582 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4583 internal->p_offset = BYTE_GET (external->p_offset);
4584 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4585 internal->p_paddr = BYTE_GET (external->p_paddr);
4586 internal->p_filesz = BYTE_GET (external->p_filesz);
4587 internal->p_memsz = BYTE_GET (external->p_memsz);
4588 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4589 }
4590
4591 free (phdrs);
e0a31db1 4592 return TRUE;
9ea033b2 4593}
252b5132 4594
d93f0186
NC
4595/* Returns 1 if the program headers were read into `program_headers'. */
4596
4597static int
2cf0635d 4598get_program_headers (FILE * file)
d93f0186 4599{
2cf0635d 4600 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4601
4602 /* Check cache of prior read. */
4603 if (program_headers != NULL)
4604 return 1;
4605
3f5e193b
NC
4606 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
4607 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4608
4609 if (phdrs == NULL)
4610 {
8b73c356
NC
4611 error (_("Out of memory reading %u program headers\n"),
4612 elf_header.e_phnum);
d93f0186
NC
4613 return 0;
4614 }
4615
4616 if (is_32bit_elf
4617 ? get_32bit_program_headers (file, phdrs)
4618 : get_64bit_program_headers (file, phdrs))
4619 {
4620 program_headers = phdrs;
4621 return 1;
4622 }
4623
4624 free (phdrs);
4625 return 0;
4626}
4627
2f62977e
NC
4628/* Returns 1 if the program headers were loaded. */
4629
252b5132 4630static int
2cf0635d 4631process_program_headers (FILE * file)
252b5132 4632{
2cf0635d 4633 Elf_Internal_Phdr * segment;
b34976b6 4634 unsigned int i;
252b5132
RH
4635
4636 if (elf_header.e_phnum == 0)
4637 {
82f2dbf7
NC
4638 /* PR binutils/12467. */
4639 if (elf_header.e_phoff != 0)
4640 warn (_("possibly corrupt ELF header - it has a non-zero program"
9035ed51 4641 " header offset, but no program headers\n"));
82f2dbf7 4642 else if (do_segments)
252b5132 4643 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4644 return 0;
252b5132
RH
4645 }
4646
4647 if (do_segments && !do_header)
4648 {
f7a99963
NC
4649 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4650 printf (_("Entry point "));
4651 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4652 printf (_("\nThere are %d program headers, starting at offset "),
4653 elf_header.e_phnum);
4654 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4655 printf ("\n");
252b5132
RH
4656 }
4657
d93f0186 4658 if (! get_program_headers (file))
252b5132 4659 return 0;
103f02d3 4660
252b5132
RH
4661 if (do_segments)
4662 {
3a1a2036
NC
4663 if (elf_header.e_phnum > 1)
4664 printf (_("\nProgram Headers:\n"));
4665 else
4666 printf (_("\nProgram Headers:\n"));
76da6bbe 4667
f7a99963
NC
4668 if (is_32bit_elf)
4669 printf
4670 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4671 else if (do_wide)
4672 printf
4673 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4674 else
4675 {
4676 printf
4677 (_(" Type Offset VirtAddr PhysAddr\n"));
4678 printf
4679 (_(" FileSiz MemSiz Flags Align\n"));
4680 }
252b5132
RH
4681 }
4682
252b5132 4683 dynamic_addr = 0;
1b228002 4684 dynamic_size = 0;
252b5132
RH
4685
4686 for (i = 0, segment = program_headers;
4687 i < elf_header.e_phnum;
b34976b6 4688 i++, segment++)
252b5132
RH
4689 {
4690 if (do_segments)
4691 {
103f02d3 4692 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4693
4694 if (is_32bit_elf)
4695 {
4696 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4697 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4698 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4699 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4700 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4701 printf ("%c%c%c ",
4702 (segment->p_flags & PF_R ? 'R' : ' '),
4703 (segment->p_flags & PF_W ? 'W' : ' '),
4704 (segment->p_flags & PF_X ? 'E' : ' '));
4705 printf ("%#lx", (unsigned long) segment->p_align);
4706 }
d974e256
JJ
4707 else if (do_wide)
4708 {
4709 if ((unsigned long) segment->p_offset == segment->p_offset)
4710 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4711 else
4712 {
4713 print_vma (segment->p_offset, FULL_HEX);
4714 putchar (' ');
4715 }
4716
4717 print_vma (segment->p_vaddr, FULL_HEX);
4718 putchar (' ');
4719 print_vma (segment->p_paddr, FULL_HEX);
4720 putchar (' ');
4721
4722 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4723 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4724 else
4725 {
4726 print_vma (segment->p_filesz, FULL_HEX);
4727 putchar (' ');
4728 }
4729
4730 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4731 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4732 else
4733 {
f48e6c45 4734 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4735 }
4736
4737 printf (" %c%c%c ",
4738 (segment->p_flags & PF_R ? 'R' : ' '),
4739 (segment->p_flags & PF_W ? 'W' : ' '),
4740 (segment->p_flags & PF_X ? 'E' : ' '));
4741
4742 if ((unsigned long) segment->p_align == segment->p_align)
4743 printf ("%#lx", (unsigned long) segment->p_align);
4744 else
4745 {
4746 print_vma (segment->p_align, PREFIX_HEX);
4747 }
4748 }
f7a99963
NC
4749 else
4750 {
4751 print_vma (segment->p_offset, FULL_HEX);
4752 putchar (' ');
4753 print_vma (segment->p_vaddr, FULL_HEX);
4754 putchar (' ');
4755 print_vma (segment->p_paddr, FULL_HEX);
4756 printf ("\n ");
4757 print_vma (segment->p_filesz, FULL_HEX);
4758 putchar (' ');
4759 print_vma (segment->p_memsz, FULL_HEX);
4760 printf (" %c%c%c ",
4761 (segment->p_flags & PF_R ? 'R' : ' '),
4762 (segment->p_flags & PF_W ? 'W' : ' '),
4763 (segment->p_flags & PF_X ? 'E' : ' '));
4764 print_vma (segment->p_align, HEX);
4765 }
252b5132
RH
4766 }
4767
f54498b4
NC
4768 if (do_segments)
4769 putc ('\n', stdout);
4770
252b5132
RH
4771 switch (segment->p_type)
4772 {
252b5132
RH
4773 case PT_DYNAMIC:
4774 if (dynamic_addr)
4775 error (_("more than one dynamic segment\n"));
4776
20737c13
AM
4777 /* By default, assume that the .dynamic section is the first
4778 section in the DYNAMIC segment. */
4779 dynamic_addr = segment->p_offset;
4780 dynamic_size = segment->p_filesz;
f54498b4
NC
4781 /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
4782 if (dynamic_addr + dynamic_size >= current_file_size)
4783 {
4784 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
4785 dynamic_addr = dynamic_size = 0;
4786 }
20737c13 4787
b2d38a17
NC
4788 /* Try to locate the .dynamic section. If there is
4789 a section header table, we can easily locate it. */
4790 if (section_headers != NULL)
4791 {
2cf0635d 4792 Elf_Internal_Shdr * sec;
b2d38a17 4793
89fac5e3
RS
4794 sec = find_section (".dynamic");
4795 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4796 {
28f997cf
TG
4797 /* A corresponding .dynamic section is expected, but on
4798 IA-64/OpenVMS it is OK for it to be missing. */
4799 if (!is_ia64_vms ())
4800 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4801 break;
4802 }
4803
42bb2e33 4804 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4805 {
4806 dynamic_size = 0;
4807 break;
4808 }
42bb2e33 4809
b2d38a17
NC
4810 dynamic_addr = sec->sh_offset;
4811 dynamic_size = sec->sh_size;
4812
4813 if (dynamic_addr < segment->p_offset
4814 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4815 warn (_("the .dynamic section is not contained"
4816 " within the dynamic segment\n"));
b2d38a17 4817 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4818 warn (_("the .dynamic section is not the first section"
4819 " in the dynamic segment.\n"));
b2d38a17 4820 }
252b5132
RH
4821 break;
4822
4823 case PT_INTERP:
fb52b2f4
NC
4824 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4825 SEEK_SET))
252b5132
RH
4826 error (_("Unable to find program interpreter name\n"));
4827 else
4828 {
f8eae8b2 4829 char fmt [32];
9495b2e6 4830 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
4831
4832 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4833 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4834
252b5132 4835 program_interpreter[0] = 0;
7bd7b3ef
AM
4836 if (fscanf (file, fmt, program_interpreter) <= 0)
4837 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4838
4839 if (do_segments)
f54498b4 4840 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
4841 program_interpreter);
4842 }
4843 break;
4844 }
252b5132
RH
4845 }
4846
c256ffe7 4847 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4848 {
4849 printf (_("\n Section to Segment mapping:\n"));
4850 printf (_(" Segment Sections...\n"));
4851
252b5132
RH
4852 for (i = 0; i < elf_header.e_phnum; i++)
4853 {
9ad5cbcf 4854 unsigned int j;
2cf0635d 4855 Elf_Internal_Shdr * section;
252b5132
RH
4856
4857 segment = program_headers + i;
b391a3e3 4858 section = section_headers + 1;
252b5132
RH
4859
4860 printf (" %2.2d ", i);
4861
b34976b6 4862 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4863 {
f4638467
AM
4864 if (!ELF_TBSS_SPECIAL (section, segment)
4865 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
74e1a04b 4866 printf ("%s ", printable_section_name (section));
252b5132
RH
4867 }
4868
4869 putc ('\n',stdout);
4870 }
4871 }
4872
252b5132
RH
4873 return 1;
4874}
4875
4876
d93f0186
NC
4877/* Find the file offset corresponding to VMA by using the program headers. */
4878
4879static long
2cf0635d 4880offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4881{
2cf0635d 4882 Elf_Internal_Phdr * seg;
d93f0186
NC
4883
4884 if (! get_program_headers (file))
4885 {
4886 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4887 return (long) vma;
4888 }
4889
4890 for (seg = program_headers;
4891 seg < program_headers + elf_header.e_phnum;
4892 ++seg)
4893 {
4894 if (seg->p_type != PT_LOAD)
4895 continue;
4896
4897 if (vma >= (seg->p_vaddr & -seg->p_align)
4898 && vma + size <= seg->p_vaddr + seg->p_filesz)
4899 return vma - seg->p_vaddr + seg->p_offset;
4900 }
4901
4902 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4903 (unsigned long) vma);
d93f0186
NC
4904 return (long) vma;
4905}
4906
4907
049b0c3a
NC
4908/* Allocate memory and load the sections headers into the global pointer
4909 SECTION_HEADERS. If PROBE is true, this is just a probe and we do not
4910 generate any error messages if the load fails. */
4911
4912static bfd_boolean
4913get_32bit_section_headers (FILE * file, bfd_boolean probe)
252b5132 4914{
2cf0635d
NC
4915 Elf32_External_Shdr * shdrs;
4916 Elf_Internal_Shdr * internal;
b34976b6 4917 unsigned int i;
049b0c3a
NC
4918 unsigned int size = elf_header.e_shentsize;
4919 unsigned int num = probe ? 1 : elf_header.e_shnum;
4920
4921 /* PR binutils/17531: Cope with unexpected section header sizes. */
4922 if (size == 0 || num == 0)
4923 return FALSE;
4924 if (size < sizeof * shdrs)
4925 {
4926 if (! probe)
4927 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4928 return FALSE;
4929 }
4930 if (!probe && size > sizeof * shdrs)
4931 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 4932
3f5e193b 4933 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4934 size, num,
4935 probe ? NULL : _("section headers"));
4936 if (shdrs == NULL)
4937 return FALSE;
252b5132 4938
049b0c3a
NC
4939 if (section_headers != NULL)
4940 free (section_headers);
3f5e193b
NC
4941 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4942 sizeof (Elf_Internal_Shdr));
252b5132
RH
4943 if (section_headers == NULL)
4944 {
049b0c3a 4945 if (!probe)
8b73c356 4946 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4947 return FALSE;
252b5132
RH
4948 }
4949
4950 for (i = 0, internal = section_headers;
560f3c1c 4951 i < num;
b34976b6 4952 i++, internal++)
252b5132
RH
4953 {
4954 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4955 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4956 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4957 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4958 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4959 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4960 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4961 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4962 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4963 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4964 }
4965
4966 free (shdrs);
049b0c3a 4967 return TRUE;
252b5132
RH
4968}
4969
049b0c3a
NC
4970static bfd_boolean
4971get_64bit_section_headers (FILE * file, bfd_boolean probe)
9ea033b2 4972{
2cf0635d
NC
4973 Elf64_External_Shdr * shdrs;
4974 Elf_Internal_Shdr * internal;
b34976b6 4975 unsigned int i;
049b0c3a
NC
4976 unsigned int size = elf_header.e_shentsize;
4977 unsigned int num = probe ? 1 : elf_header.e_shnum;
4978
4979 /* PR binutils/17531: Cope with unexpected section header sizes. */
4980 if (size == 0 || num == 0)
4981 return FALSE;
4982 if (size < sizeof * shdrs)
4983 {
4984 if (! probe)
4985 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4986 return FALSE;
4987 }
4988 if (! probe && size > sizeof * shdrs)
4989 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 4990
3f5e193b 4991 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4992 size, num,
4993 probe ? NULL : _("section headers"));
4994 if (shdrs == NULL)
4995 return FALSE;
9ea033b2 4996
049b0c3a
NC
4997 if (section_headers != NULL)
4998 free (section_headers);
3f5e193b
NC
4999 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
5000 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
5001 if (section_headers == NULL)
5002 {
049b0c3a 5003 if (! probe)
8b73c356 5004 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 5005 return FALSE;
9ea033b2
NC
5006 }
5007
5008 for (i = 0, internal = section_headers;
560f3c1c 5009 i < num;
b34976b6 5010 i++, internal++)
9ea033b2
NC
5011 {
5012 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5013 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5014 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5015 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5016 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5017 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5018 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5019 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5020 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5021 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5022 }
5023
5024 free (shdrs);
049b0c3a 5025 return TRUE;
9ea033b2
NC
5026}
5027
252b5132 5028static Elf_Internal_Sym *
ba5cdace
NC
5029get_32bit_elf_symbols (FILE * file,
5030 Elf_Internal_Shdr * section,
5031 unsigned long * num_syms_return)
252b5132 5032{
ba5cdace 5033 unsigned long number = 0;
dd24e3da 5034 Elf32_External_Sym * esyms = NULL;
ba5cdace 5035 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5036 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5037 Elf_Internal_Sym * psym;
b34976b6 5038 unsigned int j;
252b5132 5039
c9c1d674
EG
5040 if (section->sh_size == 0)
5041 {
5042 if (num_syms_return != NULL)
5043 * num_syms_return = 0;
5044 return NULL;
5045 }
5046
dd24e3da 5047 /* Run some sanity checks first. */
c9c1d674 5048 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5049 {
c9c1d674
EG
5050 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
5051 printable_section_name (section), (unsigned long) section->sh_entsize);
ba5cdace 5052 goto exit_point;
dd24e3da
NC
5053 }
5054
f54498b4
NC
5055 if (section->sh_size > current_file_size)
5056 {
5057 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
74e1a04b 5058 printable_section_name (section), (unsigned long) section->sh_size);
f54498b4
NC
5059 goto exit_point;
5060 }
5061
dd24e3da
NC
5062 number = section->sh_size / section->sh_entsize;
5063
5064 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5065 {
c9c1d674 5066 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
5067 (unsigned long) section->sh_size,
5068 printable_section_name (section),
5069 (unsigned long) section->sh_entsize);
ba5cdace 5070 goto exit_point;
dd24e3da
NC
5071 }
5072
3f5e193b
NC
5073 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
5074 section->sh_size, _("symbols"));
dd24e3da 5075 if (esyms == NULL)
ba5cdace 5076 goto exit_point;
252b5132 5077
6a40cf0c
NC
5078 {
5079 elf_section_list * entry;
5080
5081 shndx = NULL;
5082 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5083 if (entry->hdr->sh_link == (unsigned long) (section - section_headers))
c9c1d674 5084 {
6a40cf0c
NC
5085 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
5086 entry->hdr->sh_offset,
5087 1, entry->hdr->sh_size,
5088 _("symbol table section indicies"));
5089 if (shndx == NULL)
5090 goto exit_point;
5091 /* PR17531: file: heap-buffer-overflow */
5092 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5093 {
5094 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5095 printable_section_name (entry->hdr),
5096 (unsigned long) entry->hdr->sh_size,
5097 (unsigned long) section->sh_size);
5098 goto exit_point;
5099 }
c9c1d674 5100 }
6a40cf0c 5101 }
9ad5cbcf 5102
3f5e193b 5103 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5104
5105 if (isyms == NULL)
5106 {
8b73c356
NC
5107 error (_("Out of memory reading %lu symbols\n"),
5108 (unsigned long) number);
dd24e3da 5109 goto exit_point;
252b5132
RH
5110 }
5111
dd24e3da 5112 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5113 {
5114 psym->st_name = BYTE_GET (esyms[j].st_name);
5115 psym->st_value = BYTE_GET (esyms[j].st_value);
5116 psym->st_size = BYTE_GET (esyms[j].st_size);
5117 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5118 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5119 psym->st_shndx
5120 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5121 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5122 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5123 psym->st_info = BYTE_GET (esyms[j].st_info);
5124 psym->st_other = BYTE_GET (esyms[j].st_other);
5125 }
5126
dd24e3da 5127 exit_point:
ba5cdace 5128 if (shndx != NULL)
9ad5cbcf 5129 free (shndx);
ba5cdace 5130 if (esyms != NULL)
dd24e3da 5131 free (esyms);
252b5132 5132
ba5cdace
NC
5133 if (num_syms_return != NULL)
5134 * num_syms_return = isyms == NULL ? 0 : number;
5135
252b5132
RH
5136 return isyms;
5137}
5138
9ea033b2 5139static Elf_Internal_Sym *
ba5cdace
NC
5140get_64bit_elf_symbols (FILE * file,
5141 Elf_Internal_Shdr * section,
5142 unsigned long * num_syms_return)
9ea033b2 5143{
ba5cdace
NC
5144 unsigned long number = 0;
5145 Elf64_External_Sym * esyms = NULL;
5146 Elf_External_Sym_Shndx * shndx = NULL;
5147 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5148 Elf_Internal_Sym * psym;
b34976b6 5149 unsigned int j;
9ea033b2 5150
c9c1d674
EG
5151 if (section->sh_size == 0)
5152 {
5153 if (num_syms_return != NULL)
5154 * num_syms_return = 0;
5155 return NULL;
5156 }
5157
dd24e3da 5158 /* Run some sanity checks first. */
c9c1d674 5159 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5160 {
c9c1d674 5161 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
8066deb1
AM
5162 printable_section_name (section),
5163 (unsigned long) section->sh_entsize);
ba5cdace 5164 goto exit_point;
dd24e3da
NC
5165 }
5166
f54498b4
NC
5167 if (section->sh_size > current_file_size)
5168 {
5169 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
8066deb1
AM
5170 printable_section_name (section),
5171 (unsigned long) section->sh_size);
f54498b4
NC
5172 goto exit_point;
5173 }
5174
dd24e3da
NC
5175 number = section->sh_size / section->sh_entsize;
5176
5177 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5178 {
c9c1d674 5179 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
5180 (unsigned long) section->sh_size,
5181 printable_section_name (section),
5182 (unsigned long) section->sh_entsize);
ba5cdace 5183 goto exit_point;
dd24e3da
NC
5184 }
5185
3f5e193b
NC
5186 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
5187 section->sh_size, _("symbols"));
a6e9f9df 5188 if (!esyms)
ba5cdace 5189 goto exit_point;
9ea033b2 5190
6a40cf0c
NC
5191 {
5192 elf_section_list * entry;
5193
5194 shndx = NULL;
5195 for (entry = symtab_shndx_list; entry != NULL; entry = entry->next)
5196 if (entry->hdr->sh_link == (unsigned long) (section - section_headers))
c9c1d674 5197 {
6a40cf0c
NC
5198 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
5199 entry->hdr->sh_offset,
5200 1, entry->hdr->sh_size,
5201 _("symbol table section indicies"));
5202 if (shndx == NULL)
5203 goto exit_point;
5204 /* PR17531: file: heap-buffer-overflow */
5205 else if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5206 {
5207 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5208 printable_section_name (entry->hdr),
5209 (unsigned long) entry->hdr->sh_size,
5210 (unsigned long) section->sh_size);
5211 goto exit_point;
5212 }
c9c1d674 5213 }
6a40cf0c 5214 }
9ad5cbcf 5215
3f5e193b 5216 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5217
5218 if (isyms == NULL)
5219 {
8b73c356
NC
5220 error (_("Out of memory reading %lu symbols\n"),
5221 (unsigned long) number);
ba5cdace 5222 goto exit_point;
9ea033b2
NC
5223 }
5224
ba5cdace 5225 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5226 {
5227 psym->st_name = BYTE_GET (esyms[j].st_name);
5228 psym->st_info = BYTE_GET (esyms[j].st_info);
5229 psym->st_other = BYTE_GET (esyms[j].st_other);
5230 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5231
4fbb74a6 5232 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5233 psym->st_shndx
5234 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5235 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5236 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5237
66543521
AM
5238 psym->st_value = BYTE_GET (esyms[j].st_value);
5239 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5240 }
5241
ba5cdace
NC
5242 exit_point:
5243 if (shndx != NULL)
9ad5cbcf 5244 free (shndx);
ba5cdace
NC
5245 if (esyms != NULL)
5246 free (esyms);
5247
5248 if (num_syms_return != NULL)
5249 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5250
5251 return isyms;
5252}
5253
d1133906 5254static const char *
d3ba0551 5255get_elf_section_flags (bfd_vma sh_flags)
d1133906 5256{
5477e8a0 5257 static char buff[1024];
2cf0635d 5258 char * p = buff;
8d5ff12c 5259 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
5260 int sindex;
5261 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5262 bfd_vma os_flags = 0;
5263 bfd_vma proc_flags = 0;
5264 bfd_vma unknown_flags = 0;
148b93f2 5265 static const struct
5477e8a0 5266 {
2cf0635d 5267 const char * str;
5477e8a0
L
5268 int len;
5269 }
5270 flags [] =
5271 {
cfcac11d
NC
5272 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5273 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5274 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5275 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5276 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5277 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5278 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5279 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5280 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5281 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5282 /* IA-64 specific. */
5283 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5284 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5285 /* IA-64 OpenVMS specific. */
5286 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5287 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5288 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5289 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5290 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5291 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5292 /* Generic. */
cfcac11d 5293 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5294 /* SPARC specific. */
77115a4a 5295 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5296 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5297 /* ARM specific. */
5298 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
5299 /* 22 */ { STRING_COMMA_LEN ("ARM_NOREAD") },
5300 /* 23 */ { STRING_COMMA_LEN ("COMDEF") }
5477e8a0
L
5301 };
5302
5303 if (do_section_details)
5304 {
8d5ff12c
L
5305 sprintf (buff, "[%*.*lx]: ",
5306 field_size, field_size, (unsigned long) sh_flags);
5307 p += field_size + 4;
5477e8a0 5308 }
76da6bbe 5309
d1133906
NC
5310 while (sh_flags)
5311 {
5312 bfd_vma flag;
5313
5314 flag = sh_flags & - sh_flags;
5315 sh_flags &= ~ flag;
76da6bbe 5316
5477e8a0 5317 if (do_section_details)
d1133906 5318 {
5477e8a0
L
5319 switch (flag)
5320 {
91d6fa6a
NC
5321 case SHF_WRITE: sindex = 0; break;
5322 case SHF_ALLOC: sindex = 1; break;
5323 case SHF_EXECINSTR: sindex = 2; break;
5324 case SHF_MERGE: sindex = 3; break;
5325 case SHF_STRINGS: sindex = 4; break;
5326 case SHF_INFO_LINK: sindex = 5; break;
5327 case SHF_LINK_ORDER: sindex = 6; break;
5328 case SHF_OS_NONCONFORMING: sindex = 7; break;
5329 case SHF_GROUP: sindex = 8; break;
5330 case SHF_TLS: sindex = 9; break;
18ae9cc1 5331 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5332 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 5333
5477e8a0 5334 default:
91d6fa6a 5335 sindex = -1;
cfcac11d 5336 switch (elf_header.e_machine)
148b93f2 5337 {
cfcac11d 5338 case EM_IA_64:
148b93f2 5339 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5340 sindex = 10;
148b93f2 5341 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5342 sindex = 11;
148b93f2
NC
5343#ifdef BFD64
5344 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
5345 switch (flag)
5346 {
91d6fa6a
NC
5347 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5348 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5349 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5350 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5351 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5352 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5353 default: break;
5354 }
5355#endif
cfcac11d
NC
5356 break;
5357
caa83f8b 5358 case EM_386:
22abe556 5359 case EM_IAMCU:
caa83f8b 5360 case EM_X86_64:
7f502d6c 5361 case EM_L1OM:
7a9068fe 5362 case EM_K1OM:
cfcac11d
NC
5363 case EM_OLD_SPARCV9:
5364 case EM_SPARC32PLUS:
5365 case EM_SPARCV9:
5366 case EM_SPARC:
18ae9cc1 5367 if (flag == SHF_ORDERED)
91d6fa6a 5368 sindex = 19;
cfcac11d 5369 break;
ac4c9b04
MG
5370
5371 case EM_ARM:
5372 switch (flag)
5373 {
5374 case SHF_ENTRYSECT: sindex = 21; break;
5375 case SHF_ARM_NOREAD: sindex = 22; break;
5376 case SHF_COMDEF: sindex = 23; break;
5377 default: break;
5378 }
5379 break;
5380
cfcac11d
NC
5381 default:
5382 break;
148b93f2 5383 }
5477e8a0
L
5384 }
5385
91d6fa6a 5386 if (sindex != -1)
5477e8a0 5387 {
8d5ff12c
L
5388 if (p != buff + field_size + 4)
5389 {
5390 if (size < (10 + 2))
bee0ee85
NC
5391 {
5392 warn (_("Internal error: not enough buffer room for section flag info"));
5393 return _("<unknown>");
5394 }
8d5ff12c
L
5395 size -= 2;
5396 *p++ = ',';
5397 *p++ = ' ';
5398 }
5399
91d6fa6a
NC
5400 size -= flags [sindex].len;
5401 p = stpcpy (p, flags [sindex].str);
5477e8a0 5402 }
3b22753a 5403 else if (flag & SHF_MASKOS)
8d5ff12c 5404 os_flags |= flag;
d1133906 5405 else if (flag & SHF_MASKPROC)
8d5ff12c 5406 proc_flags |= flag;
d1133906 5407 else
8d5ff12c 5408 unknown_flags |= flag;
5477e8a0
L
5409 }
5410 else
5411 {
5412 switch (flag)
5413 {
5414 case SHF_WRITE: *p = 'W'; break;
5415 case SHF_ALLOC: *p = 'A'; break;
5416 case SHF_EXECINSTR: *p = 'X'; break;
5417 case SHF_MERGE: *p = 'M'; break;
5418 case SHF_STRINGS: *p = 'S'; break;
5419 case SHF_INFO_LINK: *p = 'I'; break;
5420 case SHF_LINK_ORDER: *p = 'L'; break;
5421 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5422 case SHF_GROUP: *p = 'G'; break;
5423 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5424 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 5425 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
5426
5427 default:
8a9036a4 5428 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
5429 || elf_header.e_machine == EM_L1OM
5430 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
5431 && flag == SHF_X86_64_LARGE)
5432 *p = 'l';
5433 else if (flag & SHF_MASKOS)
5434 {
5435 *p = 'o';
5436 sh_flags &= ~ SHF_MASKOS;
5437 }
5438 else if (flag & SHF_MASKPROC)
5439 {
5440 *p = 'p';
5441 sh_flags &= ~ SHF_MASKPROC;
5442 }
5443 else
5444 *p = 'x';
5445 break;
5446 }
5447 p++;
d1133906
NC
5448 }
5449 }
76da6bbe 5450
8d5ff12c
L
5451 if (do_section_details)
5452 {
5453 if (os_flags)
5454 {
5455 size -= 5 + field_size;
5456 if (p != buff + field_size + 4)
5457 {
5458 if (size < (2 + 1))
bee0ee85
NC
5459 {
5460 warn (_("Internal error: not enough buffer room for section flag info"));
5461 return _("<unknown>");
5462 }
8d5ff12c
L
5463 size -= 2;
5464 *p++ = ',';
5465 *p++ = ' ';
5466 }
5467 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5468 (unsigned long) os_flags);
5469 p += 5 + field_size;
5470 }
5471 if (proc_flags)
5472 {
5473 size -= 7 + field_size;
5474 if (p != buff + field_size + 4)
5475 {
5476 if (size < (2 + 1))
bee0ee85
NC
5477 {
5478 warn (_("Internal error: not enough buffer room for section flag info"));
5479 return _("<unknown>");
5480 }
8d5ff12c
L
5481 size -= 2;
5482 *p++ = ',';
5483 *p++ = ' ';
5484 }
5485 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5486 (unsigned long) proc_flags);
5487 p += 7 + field_size;
5488 }
5489 if (unknown_flags)
5490 {
5491 size -= 10 + field_size;
5492 if (p != buff + field_size + 4)
5493 {
5494 if (size < (2 + 1))
bee0ee85
NC
5495 {
5496 warn (_("Internal error: not enough buffer room for section flag info"));
5497 return _("<unknown>");
5498 }
8d5ff12c
L
5499 size -= 2;
5500 *p++ = ',';
5501 *p++ = ' ';
5502 }
2b692964 5503 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5504 (unsigned long) unknown_flags);
5505 p += 10 + field_size;
5506 }
5507 }
5508
e9e44622 5509 *p = '\0';
d1133906
NC
5510 return buff;
5511}
5512
77115a4a
L
5513static unsigned int
5514get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf)
5515{
5516 if (is_32bit_elf)
5517 {
5518 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
5519 chdr->ch_type = BYTE_GET (echdr->ch_type);
5520 chdr->ch_size = BYTE_GET (echdr->ch_size);
5521 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5522 return sizeof (*echdr);
5523 }
5524 else
5525 {
5526 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
5527 chdr->ch_type = BYTE_GET (echdr->ch_type);
5528 chdr->ch_size = BYTE_GET (echdr->ch_size);
5529 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
5530 return sizeof (*echdr);
5531 }
5532}
5533
252b5132 5534static int
2cf0635d 5535process_section_headers (FILE * file)
252b5132 5536{
2cf0635d 5537 Elf_Internal_Shdr * section;
b34976b6 5538 unsigned int i;
252b5132
RH
5539
5540 section_headers = NULL;
5541
5542 if (elf_header.e_shnum == 0)
5543 {
82f2dbf7
NC
5544 /* PR binutils/12467. */
5545 if (elf_header.e_shoff != 0)
5546 warn (_("possibly corrupt ELF file header - it has a non-zero"
5547 " section header offset, but no section headers\n"));
5548 else if (do_sections)
252b5132
RH
5549 printf (_("\nThere are no sections in this file.\n"));
5550
5551 return 1;
5552 }
5553
5554 if (do_sections && !do_header)
9ea033b2 5555 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
5556 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
5557
9ea033b2
NC
5558 if (is_32bit_elf)
5559 {
049b0c3a 5560 if (! get_32bit_section_headers (file, FALSE))
9ea033b2
NC
5561 return 0;
5562 }
049b0c3a 5563 else if (! get_64bit_section_headers (file, FALSE))
252b5132
RH
5564 return 0;
5565
5566 /* Read in the string table, so that we have names to display. */
0b49d371 5567 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 5568 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 5569 {
4fbb74a6 5570 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 5571
c256ffe7
JJ
5572 if (section->sh_size != 0)
5573 {
3f5e193b
NC
5574 string_table = (char *) get_data (NULL, file, section->sh_offset,
5575 1, section->sh_size,
5576 _("string table"));
0de14b54 5577
c256ffe7
JJ
5578 string_table_length = string_table != NULL ? section->sh_size : 0;
5579 }
252b5132
RH
5580 }
5581
5582 /* Scan the sections for the dynamic symbol table
e3c8793a 5583 and dynamic string table and debug sections. */
252b5132
RH
5584 dynamic_symbols = NULL;
5585 dynamic_strings = NULL;
5586 dynamic_syminfo = NULL;
6a40cf0c 5587 symtab_shndx_list = NULL;
103f02d3 5588
89fac5e3
RS
5589 eh_addr_size = is_32bit_elf ? 4 : 8;
5590 switch (elf_header.e_machine)
5591 {
5592 case EM_MIPS:
5593 case EM_MIPS_RS3_LE:
5594 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5595 FDE addresses. However, the ABI also has a semi-official ILP32
5596 variant for which the normal FDE address size rules apply.
5597
5598 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5599 section, where XX is the size of longs in bits. Unfortunately,
5600 earlier compilers provided no way of distinguishing ILP32 objects
5601 from LP64 objects, so if there's any doubt, we should assume that
5602 the official LP64 form is being used. */
5603 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5604 && find_section (".gcc_compiled_long32") == NULL)
5605 eh_addr_size = 8;
5606 break;
0f56a26a
DD
5607
5608 case EM_H8_300:
5609 case EM_H8_300H:
5610 switch (elf_header.e_flags & EF_H8_MACH)
5611 {
5612 case E_H8_MACH_H8300:
5613 case E_H8_MACH_H8300HN:
5614 case E_H8_MACH_H8300SN:
5615 case E_H8_MACH_H8300SXN:
5616 eh_addr_size = 2;
5617 break;
5618 case E_H8_MACH_H8300H:
5619 case E_H8_MACH_H8300S:
5620 case E_H8_MACH_H8300SX:
5621 eh_addr_size = 4;
5622 break;
5623 }
f4236fe4
DD
5624 break;
5625
ff7eeb89 5626 case EM_M32C_OLD:
f4236fe4
DD
5627 case EM_M32C:
5628 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5629 {
5630 case EF_M32C_CPU_M16C:
5631 eh_addr_size = 2;
5632 break;
5633 }
5634 break;
89fac5e3
RS
5635 }
5636
76ca31c0
NC
5637#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5638 do \
5639 { \
5640 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
5641 if (section->sh_entsize != expected_entsize) \
9dd3a467 5642 { \
76ca31c0
NC
5643 char buf[40]; \
5644 sprintf_vma (buf, section->sh_entsize); \
5645 /* Note: coded this way so that there is a single string for \
5646 translation. */ \
5647 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
5648 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
5649 (unsigned) expected_entsize); \
9dd3a467 5650 section->sh_entsize = expected_entsize; \
76ca31c0
NC
5651 } \
5652 } \
08d8fa11 5653 while (0)
9dd3a467
NC
5654
5655#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5656 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5657 sizeof (Elf64_External_##type))
5658
252b5132
RH
5659 for (i = 0, section = section_headers;
5660 i < elf_header.e_shnum;
b34976b6 5661 i++, section++)
252b5132 5662 {
2cf0635d 5663 char * name = SECTION_NAME (section);
252b5132
RH
5664
5665 if (section->sh_type == SHT_DYNSYM)
5666 {
5667 if (dynamic_symbols != NULL)
5668 {
5669 error (_("File contains multiple dynamic symbol tables\n"));
5670 continue;
5671 }
5672
08d8fa11 5673 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5674 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5675 }
5676 else if (section->sh_type == SHT_STRTAB
18bd398b 5677 && streq (name, ".dynstr"))
252b5132
RH
5678 {
5679 if (dynamic_strings != NULL)
5680 {
5681 error (_("File contains multiple dynamic string tables\n"));
5682 continue;
5683 }
5684
3f5e193b
NC
5685 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5686 1, section->sh_size,
5687 _("dynamic strings"));
59245841 5688 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5689 }
9ad5cbcf
AM
5690 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5691 {
6a40cf0c
NC
5692 elf_section_list * entry = xmalloc (sizeof * entry);
5693 entry->hdr = section;
5694 entry->next = symtab_shndx_list;
5695 symtab_shndx_list = entry;
9ad5cbcf 5696 }
08d8fa11
JJ
5697 else if (section->sh_type == SHT_SYMTAB)
5698 CHECK_ENTSIZE (section, i, Sym);
5699 else if (section->sh_type == SHT_GROUP)
5700 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5701 else if (section->sh_type == SHT_REL)
5702 CHECK_ENTSIZE (section, i, Rel);
5703 else if (section->sh_type == SHT_RELA)
5704 CHECK_ENTSIZE (section, i, Rela);
252b5132 5705 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5706 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5707 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5708 || do_debug_str || do_debug_loc || do_debug_ranges
5709 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5710 && (const_strneq (name, ".debug_")
5711 || const_strneq (name, ".zdebug_")))
252b5132 5712 {
1b315056
CS
5713 if (name[1] == 'z')
5714 name += sizeof (".zdebug_") - 1;
5715 else
5716 name += sizeof (".debug_") - 1;
252b5132
RH
5717
5718 if (do_debugging
4723351a
CC
5719 || (do_debug_info && const_strneq (name, "info"))
5720 || (do_debug_info && const_strneq (name, "types"))
5721 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5722 || (do_debug_lines && strcmp (name, "line") == 0)
5723 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5724 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5725 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5726 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5727 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5728 || (do_debug_aranges && const_strneq (name, "aranges"))
5729 || (do_debug_ranges && const_strneq (name, "ranges"))
5730 || (do_debug_frames && const_strneq (name, "frame"))
5731 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5732 || (do_debug_macinfo && const_strneq (name, "macro"))
5733 || (do_debug_str && const_strneq (name, "str"))
5734 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5735 || (do_debug_addr && const_strneq (name, "addr"))
5736 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5737 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5738 )
09c11c86 5739 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5740 }
a262ae96 5741 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5742 else if ((do_debugging || do_debug_info)
0112cd26 5743 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5744 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5745 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5746 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5747 else if (do_gdb_index && streq (name, ".gdb_index"))
5748 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5749 /* Trace sections for Itanium VMS. */
5750 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5751 || do_trace_aranges)
5752 && const_strneq (name, ".trace_"))
5753 {
5754 name += sizeof (".trace_") - 1;
5755
5756 if (do_debugging
5757 || (do_trace_info && streq (name, "info"))
5758 || (do_trace_abbrevs && streq (name, "abbrev"))
5759 || (do_trace_aranges && streq (name, "aranges"))
5760 )
5761 request_dump_bynumber (i, DEBUG_DUMP);
5762 }
252b5132
RH
5763 }
5764
5765 if (! do_sections)
5766 return 1;
5767
3a1a2036
NC
5768 if (elf_header.e_shnum > 1)
5769 printf (_("\nSection Headers:\n"));
5770 else
5771 printf (_("\nSection Header:\n"));
76da6bbe 5772
f7a99963 5773 if (is_32bit_elf)
595cf52e 5774 {
5477e8a0 5775 if (do_section_details)
595cf52e
L
5776 {
5777 printf (_(" [Nr] Name\n"));
5477e8a0 5778 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5779 }
5780 else
5781 printf
5782 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5783 }
d974e256 5784 else if (do_wide)
595cf52e 5785 {
5477e8a0 5786 if (do_section_details)
595cf52e
L
5787 {
5788 printf (_(" [Nr] Name\n"));
5477e8a0 5789 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5790 }
5791 else
5792 printf
5793 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5794 }
f7a99963
NC
5795 else
5796 {
5477e8a0 5797 if (do_section_details)
595cf52e
L
5798 {
5799 printf (_(" [Nr] Name\n"));
5477e8a0
L
5800 printf (_(" Type Address Offset Link\n"));
5801 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5802 }
5803 else
5804 {
5805 printf (_(" [Nr] Name Type Address Offset\n"));
5806 printf (_(" Size EntSize Flags Link Info Align\n"));
5807 }
f7a99963 5808 }
252b5132 5809
5477e8a0
L
5810 if (do_section_details)
5811 printf (_(" Flags\n"));
5812
252b5132
RH
5813 for (i = 0, section = section_headers;
5814 i < elf_header.e_shnum;
b34976b6 5815 i++, section++)
252b5132 5816 {
7bfd842d 5817 printf (" [%2u] ", i);
5477e8a0 5818 if (do_section_details)
74e1a04b 5819 printf ("%s\n ", printable_section_name (section));
595cf52e 5820 else
74e1a04b 5821 print_symbol (-17, SECTION_NAME (section));
0b4362b0 5822
ea52a088
NC
5823 printf (do_wide ? " %-15s " : " %-15.15s ",
5824 get_section_type_name (section->sh_type));
0b4362b0 5825
f7a99963
NC
5826 if (is_32bit_elf)
5827 {
cfcac11d
NC
5828 const char * link_too_big = NULL;
5829
f7a99963 5830 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5831
f7a99963
NC
5832 printf ( " %6.6lx %6.6lx %2.2lx",
5833 (unsigned long) section->sh_offset,
5834 (unsigned long) section->sh_size,
5835 (unsigned long) section->sh_entsize);
d1133906 5836
5477e8a0
L
5837 if (do_section_details)
5838 fputs (" ", stdout);
5839 else
5840 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5841
cfcac11d
NC
5842 if (section->sh_link >= elf_header.e_shnum)
5843 {
5844 link_too_big = "";
5845 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5846 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5847 switch (elf_header.e_machine)
5848 {
caa83f8b 5849 case EM_386:
22abe556 5850 case EM_IAMCU:
caa83f8b 5851 case EM_X86_64:
7f502d6c 5852 case EM_L1OM:
7a9068fe 5853 case EM_K1OM:
cfcac11d
NC
5854 case EM_OLD_SPARCV9:
5855 case EM_SPARC32PLUS:
5856 case EM_SPARCV9:
5857 case EM_SPARC:
5858 if (section->sh_link == (SHN_BEFORE & 0xffff))
5859 link_too_big = "BEFORE";
5860 else if (section->sh_link == (SHN_AFTER & 0xffff))
5861 link_too_big = "AFTER";
5862 break;
5863 default:
5864 break;
5865 }
5866 }
5867
5868 if (do_section_details)
5869 {
5870 if (link_too_big != NULL && * link_too_big)
5871 printf ("<%s> ", link_too_big);
5872 else
5873 printf ("%2u ", section->sh_link);
5874 printf ("%3u %2lu\n", section->sh_info,
5875 (unsigned long) section->sh_addralign);
5876 }
5877 else
5878 printf ("%2u %3u %2lu\n",
5879 section->sh_link,
5880 section->sh_info,
5881 (unsigned long) section->sh_addralign);
5882
5883 if (link_too_big && ! * link_too_big)
5884 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5885 i, section->sh_link);
f7a99963 5886 }
d974e256
JJ
5887 else if (do_wide)
5888 {
5889 print_vma (section->sh_addr, LONG_HEX);
5890
5891 if ((long) section->sh_offset == section->sh_offset)
5892 printf (" %6.6lx", (unsigned long) section->sh_offset);
5893 else
5894 {
5895 putchar (' ');
5896 print_vma (section->sh_offset, LONG_HEX);
5897 }
5898
5899 if ((unsigned long) section->sh_size == section->sh_size)
5900 printf (" %6.6lx", (unsigned long) section->sh_size);
5901 else
5902 {
5903 putchar (' ');
5904 print_vma (section->sh_size, LONG_HEX);
5905 }
5906
5907 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5908 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5909 else
5910 {
5911 putchar (' ');
5912 print_vma (section->sh_entsize, LONG_HEX);
5913 }
5914
5477e8a0
L
5915 if (do_section_details)
5916 fputs (" ", stdout);
5917 else
5918 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5919
72de5009 5920 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5921
5922 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5923 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5924 else
5925 {
5926 print_vma (section->sh_addralign, DEC);
5927 putchar ('\n');
5928 }
5929 }
5477e8a0 5930 else if (do_section_details)
595cf52e 5931 {
5477e8a0 5932 printf (" %-15.15s ",
595cf52e 5933 get_section_type_name (section->sh_type));
595cf52e
L
5934 print_vma (section->sh_addr, LONG_HEX);
5935 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5936 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5937 else
5938 {
5939 printf (" ");
5940 print_vma (section->sh_offset, LONG_HEX);
5941 }
72de5009 5942 printf (" %u\n ", section->sh_link);
595cf52e 5943 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5944 putchar (' ');
595cf52e
L
5945 print_vma (section->sh_entsize, LONG_HEX);
5946
72de5009
AM
5947 printf (" %-16u %lu\n",
5948 section->sh_info,
595cf52e
L
5949 (unsigned long) section->sh_addralign);
5950 }
f7a99963
NC
5951 else
5952 {
5953 putchar (' ');
5954 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5955 if ((long) section->sh_offset == section->sh_offset)
5956 printf (" %8.8lx", (unsigned long) section->sh_offset);
5957 else
5958 {
5959 printf (" ");
5960 print_vma (section->sh_offset, LONG_HEX);
5961 }
f7a99963
NC
5962 printf ("\n ");
5963 print_vma (section->sh_size, LONG_HEX);
5964 printf (" ");
5965 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5966
d1133906 5967 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5968
72de5009
AM
5969 printf (" %2u %3u %lu\n",
5970 section->sh_link,
5971 section->sh_info,
f7a99963
NC
5972 (unsigned long) section->sh_addralign);
5973 }
5477e8a0
L
5974
5975 if (do_section_details)
77115a4a
L
5976 {
5977 printf (" %s\n", get_elf_section_flags (section->sh_flags));
5978 if ((section->sh_flags & SHF_COMPRESSED) != 0)
5979 {
5980 /* Minimum section size is 12 bytes for 32-bit compression
5981 header + 12 bytes for compressed data header. */
5982 unsigned char buf[24];
5983 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
5984 if (get_data (&buf, (FILE *) file, section->sh_offset, 1,
5985 sizeof (buf), _("compression header")))
5986 {
5987 Elf_Internal_Chdr chdr;
5988 get_compression_header (&chdr, buf);
5989 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
5990 printf (" ZLIB, ");
5991 else
5992 printf (_(" [<unknown>: 0x%x], "),
5993 chdr.ch_type);
5994 print_vma (chdr.ch_size, LONG_HEX);
5995 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
5996 }
5997 }
5998 }
252b5132
RH
5999 }
6000
5477e8a0 6001 if (!do_section_details)
3dbcc61d
NC
6002 {
6003 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
6004 || elf_header.e_machine == EM_L1OM
6005 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
6006 printf (_("Key to Flags:\n\
6007 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
6008 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
6009 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
6010 else
6011 printf (_("Key to Flags:\n\
e3c8793a 6012 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 6013 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 6014 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 6015 }
d1133906 6016
252b5132
RH
6017 return 1;
6018}
6019
f5842774
L
6020static const char *
6021get_group_flags (unsigned int flags)
6022{
6023 static char buff[32];
6024 switch (flags)
6025 {
220453ec
AM
6026 case 0:
6027 return "";
6028
f5842774 6029 case GRP_COMDAT:
220453ec 6030 return "COMDAT ";
f5842774
L
6031
6032 default:
220453ec 6033 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
6034 break;
6035 }
6036 return buff;
6037}
6038
6039static int
2cf0635d 6040process_section_groups (FILE * file)
f5842774 6041{
2cf0635d 6042 Elf_Internal_Shdr * section;
f5842774 6043 unsigned int i;
2cf0635d
NC
6044 struct group * group;
6045 Elf_Internal_Shdr * symtab_sec;
6046 Elf_Internal_Shdr * strtab_sec;
6047 Elf_Internal_Sym * symtab;
ba5cdace 6048 unsigned long num_syms;
2cf0635d 6049 char * strtab;
c256ffe7 6050 size_t strtab_size;
d1f5c6e3
L
6051
6052 /* Don't process section groups unless needed. */
6053 if (!do_unwind && !do_section_groups)
6054 return 1;
f5842774
L
6055
6056 if (elf_header.e_shnum == 0)
6057 {
6058 if (do_section_groups)
82f2dbf7 6059 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
6060
6061 return 1;
6062 }
6063
6064 if (section_headers == NULL)
6065 {
6066 error (_("Section headers are not available!\n"));
fa1908fd
NC
6067 /* PR 13622: This can happen with a corrupt ELF header. */
6068 return 0;
f5842774
L
6069 }
6070
3f5e193b
NC
6071 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
6072 sizeof (struct group *));
e4b17d5c
L
6073
6074 if (section_headers_groups == NULL)
6075 {
8b73c356
NC
6076 error (_("Out of memory reading %u section group headers\n"),
6077 elf_header.e_shnum);
e4b17d5c
L
6078 return 0;
6079 }
6080
f5842774 6081 /* Scan the sections for the group section. */
d1f5c6e3 6082 group_count = 0;
f5842774
L
6083 for (i = 0, section = section_headers;
6084 i < elf_header.e_shnum;
6085 i++, section++)
e4b17d5c
L
6086 if (section->sh_type == SHT_GROUP)
6087 group_count++;
6088
d1f5c6e3
L
6089 if (group_count == 0)
6090 {
6091 if (do_section_groups)
6092 printf (_("\nThere are no section groups in this file.\n"));
6093
6094 return 1;
6095 }
6096
3f5e193b 6097 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
6098
6099 if (section_groups == NULL)
6100 {
8b73c356
NC
6101 error (_("Out of memory reading %lu groups\n"),
6102 (unsigned long) group_count);
e4b17d5c
L
6103 return 0;
6104 }
6105
d1f5c6e3
L
6106 symtab_sec = NULL;
6107 strtab_sec = NULL;
6108 symtab = NULL;
ba5cdace 6109 num_syms = 0;
d1f5c6e3 6110 strtab = NULL;
c256ffe7 6111 strtab_size = 0;
e4b17d5c
L
6112 for (i = 0, section = section_headers, group = section_groups;
6113 i < elf_header.e_shnum;
6114 i++, section++)
f5842774
L
6115 {
6116 if (section->sh_type == SHT_GROUP)
6117 {
74e1a04b
NC
6118 const char * name = printable_section_name (section);
6119 const char * group_name;
2cf0635d
NC
6120 unsigned char * start;
6121 unsigned char * indices;
f5842774 6122 unsigned int entry, j, size;
2cf0635d
NC
6123 Elf_Internal_Shdr * sec;
6124 Elf_Internal_Sym * sym;
f5842774
L
6125
6126 /* Get the symbol table. */
4fbb74a6
AM
6127 if (section->sh_link >= elf_header.e_shnum
6128 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 6129 != SHT_SYMTAB))
f5842774
L
6130 {
6131 error (_("Bad sh_link in group section `%s'\n"), name);
6132 continue;
6133 }
d1f5c6e3
L
6134
6135 if (symtab_sec != sec)
6136 {
6137 symtab_sec = sec;
6138 if (symtab)
6139 free (symtab);
ba5cdace 6140 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 6141 }
f5842774 6142
dd24e3da
NC
6143 if (symtab == NULL)
6144 {
6145 error (_("Corrupt header in group section `%s'\n"), name);
6146 continue;
6147 }
6148
ba5cdace
NC
6149 if (section->sh_info >= num_syms)
6150 {
6151 error (_("Bad sh_info in group section `%s'\n"), name);
6152 continue;
6153 }
6154
f5842774
L
6155 sym = symtab + section->sh_info;
6156
6157 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
6158 {
4fbb74a6
AM
6159 if (sym->st_shndx == 0
6160 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
6161 {
6162 error (_("Bad sh_info in group section `%s'\n"), name);
6163 continue;
6164 }
ba2685cc 6165
4fbb74a6 6166 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
6167 strtab_sec = NULL;
6168 if (strtab)
6169 free (strtab);
f5842774 6170 strtab = NULL;
c256ffe7 6171 strtab_size = 0;
f5842774
L
6172 }
6173 else
6174 {
6175 /* Get the string table. */
4fbb74a6 6176 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
6177 {
6178 strtab_sec = NULL;
6179 if (strtab)
6180 free (strtab);
6181 strtab = NULL;
6182 strtab_size = 0;
6183 }
6184 else if (strtab_sec
4fbb74a6 6185 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
6186 {
6187 strtab_sec = sec;
6188 if (strtab)
6189 free (strtab);
071436c6 6190
3f5e193b 6191 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
071436c6
NC
6192 1, strtab_sec->sh_size,
6193 _("string table"));
c256ffe7 6194 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 6195 }
c256ffe7 6196 group_name = sym->st_name < strtab_size
2b692964 6197 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
6198 }
6199
c9c1d674
EG
6200 /* PR 17531: file: loop. */
6201 if (section->sh_entsize > section->sh_size)
6202 {
6203 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
6204 printable_section_name (section),
8066deb1
AM
6205 (unsigned long) section->sh_entsize,
6206 (unsigned long) section->sh_size);
c9c1d674
EG
6207 break;
6208 }
6209
3f5e193b
NC
6210 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
6211 1, section->sh_size,
6212 _("section data"));
59245841
NC
6213 if (start == NULL)
6214 continue;
f5842774
L
6215
6216 indices = start;
6217 size = (section->sh_size / section->sh_entsize) - 1;
6218 entry = byte_get (indices, 4);
6219 indices += 4;
e4b17d5c
L
6220
6221 if (do_section_groups)
6222 {
2b692964 6223 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6224 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6225
e4b17d5c
L
6226 printf (_(" [Index] Name\n"));
6227 }
6228
6229 group->group_index = i;
6230
f5842774
L
6231 for (j = 0; j < size; j++)
6232 {
2cf0635d 6233 struct group_list * g;
e4b17d5c 6234
f5842774
L
6235 entry = byte_get (indices, 4);
6236 indices += 4;
6237
4fbb74a6 6238 if (entry >= elf_header.e_shnum)
391cb864 6239 {
57028622
NC
6240 static unsigned num_group_errors = 0;
6241
6242 if (num_group_errors ++ < 10)
6243 {
6244 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
6245 entry, i, elf_header.e_shnum - 1);
6246 if (num_group_errors == 10)
6247 warn (_("Futher error messages about overlarge group section indicies suppressed\n"));
6248 }
391cb864
L
6249 continue;
6250 }
391cb864 6251
4fbb74a6 6252 if (section_headers_groups [entry] != NULL)
e4b17d5c 6253 {
d1f5c6e3
L
6254 if (entry)
6255 {
57028622
NC
6256 static unsigned num_errs = 0;
6257
6258 if (num_errs ++ < 10)
6259 {
6260 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6261 entry, i,
6262 section_headers_groups [entry]->group_index);
6263 if (num_errs == 10)
6264 warn (_("Further error messages about already contained group sections suppressed\n"));
6265 }
d1f5c6e3
L
6266 continue;
6267 }
6268 else
6269 {
6270 /* Intel C/C++ compiler may put section 0 in a
6271 section group. We just warn it the first time
6272 and ignore it afterwards. */
6273 static int warned = 0;
6274 if (!warned)
6275 {
6276 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6277 section_headers_groups [entry]->group_index);
d1f5c6e3
L
6278 warned++;
6279 }
6280 }
e4b17d5c
L
6281 }
6282
4fbb74a6 6283 section_headers_groups [entry] = group;
e4b17d5c
L
6284
6285 if (do_section_groups)
6286 {
4fbb74a6 6287 sec = section_headers + entry;
74e1a04b 6288 printf (" [%5u] %s\n", entry, printable_section_name (sec));
ba2685cc
AM
6289 }
6290
3f5e193b 6291 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6292 g->section_index = entry;
6293 g->next = group->root;
6294 group->root = g;
f5842774
L
6295 }
6296
f5842774
L
6297 if (start)
6298 free (start);
e4b17d5c
L
6299
6300 group++;
f5842774
L
6301 }
6302 }
6303
d1f5c6e3
L
6304 if (symtab)
6305 free (symtab);
6306 if (strtab)
6307 free (strtab);
f5842774
L
6308 return 1;
6309}
6310
28f997cf
TG
6311/* Data used to display dynamic fixups. */
6312
6313struct ia64_vms_dynfixup
6314{
6315 bfd_vma needed_ident; /* Library ident number. */
6316 bfd_vma needed; /* Index in the dstrtab of the library name. */
6317 bfd_vma fixup_needed; /* Index of the library. */
6318 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6319 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6320};
6321
6322/* Data used to display dynamic relocations. */
6323
6324struct ia64_vms_dynimgrela
6325{
6326 bfd_vma img_rela_cnt; /* Number of relocations. */
6327 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6328};
6329
6330/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6331 library). */
6332
6333static void
6334dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
6335 const char *strtab, unsigned int strtab_sz)
6336{
6337 Elf64_External_VMS_IMAGE_FIXUP *imfs;
6338 long i;
6339 const char *lib_name;
6340
6341 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
6342 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6343 _("dynamic section image fixups"));
6344 if (!imfs)
6345 return;
6346
6347 if (fixup->needed < strtab_sz)
6348 lib_name = strtab + fixup->needed;
6349 else
6350 {
6351 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 6352 (unsigned long) fixup->needed);
28f997cf
TG
6353 lib_name = "???";
6354 }
6355 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6356 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6357 printf
6358 (_("Seg Offset Type SymVec DataType\n"));
6359
6360 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6361 {
6362 unsigned int type;
6363 const char *rtype;
6364
6365 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6366 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6367 type = BYTE_GET (imfs [i].type);
6368 rtype = elf_ia64_reloc_type (type);
6369 if (rtype == NULL)
6370 printf (" 0x%08x ", type);
6371 else
6372 printf (" %-32s ", rtype);
6373 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6374 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6375 }
6376
6377 free (imfs);
6378}
6379
6380/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6381
6382static void
6383dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
6384{
6385 Elf64_External_VMS_IMAGE_RELA *imrs;
6386 long i;
6387
6388 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
6389 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6390 _("dynamic section image relocations"));
28f997cf
TG
6391 if (!imrs)
6392 return;
6393
6394 printf (_("\nImage relocs\n"));
6395 printf
6396 (_("Seg Offset Type Addend Seg Sym Off\n"));
6397
6398 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6399 {
6400 unsigned int type;
6401 const char *rtype;
6402
6403 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6404 printf ("%08" BFD_VMA_FMT "x ",
6405 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6406 type = BYTE_GET (imrs [i].type);
6407 rtype = elf_ia64_reloc_type (type);
6408 if (rtype == NULL)
6409 printf ("0x%08x ", type);
6410 else
6411 printf ("%-31s ", rtype);
6412 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6413 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6414 printf ("%08" BFD_VMA_FMT "x\n",
6415 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6416 }
6417
6418 free (imrs);
6419}
6420
6421/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6422
6423static int
6424process_ia64_vms_dynamic_relocs (FILE *file)
6425{
6426 struct ia64_vms_dynfixup fixup;
6427 struct ia64_vms_dynimgrela imgrela;
6428 Elf_Internal_Dyn *entry;
6429 int res = 0;
6430 bfd_vma strtab_off = 0;
6431 bfd_vma strtab_sz = 0;
6432 char *strtab = NULL;
6433
6434 memset (&fixup, 0, sizeof (fixup));
6435 memset (&imgrela, 0, sizeof (imgrela));
6436
6437 /* Note: the order of the entries is specified by the OpenVMS specs. */
6438 for (entry = dynamic_section;
6439 entry < dynamic_section + dynamic_nent;
6440 entry++)
6441 {
6442 switch (entry->d_tag)
6443 {
6444 case DT_IA_64_VMS_STRTAB_OFFSET:
6445 strtab_off = entry->d_un.d_val;
6446 break;
6447 case DT_STRSZ:
6448 strtab_sz = entry->d_un.d_val;
6449 if (strtab == NULL)
6450 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
6451 1, strtab_sz, _("dynamic string section"));
6452 break;
6453
6454 case DT_IA_64_VMS_NEEDED_IDENT:
6455 fixup.needed_ident = entry->d_un.d_val;
6456 break;
6457 case DT_NEEDED:
6458 fixup.needed = entry->d_un.d_val;
6459 break;
6460 case DT_IA_64_VMS_FIXUP_NEEDED:
6461 fixup.fixup_needed = entry->d_un.d_val;
6462 break;
6463 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6464 fixup.fixup_rela_cnt = entry->d_un.d_val;
6465 break;
6466 case DT_IA_64_VMS_FIXUP_RELA_OFF:
6467 fixup.fixup_rela_off = entry->d_un.d_val;
6468 res++;
6469 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
6470 break;
6471
6472 case DT_IA_64_VMS_IMG_RELA_CNT:
6473 imgrela.img_rela_cnt = entry->d_un.d_val;
6474 break;
6475 case DT_IA_64_VMS_IMG_RELA_OFF:
6476 imgrela.img_rela_off = entry->d_un.d_val;
6477 res++;
6478 dump_ia64_vms_dynamic_relocs (file, &imgrela);
6479 break;
6480
6481 default:
6482 break;
6483 }
6484 }
6485
6486 if (strtab != NULL)
6487 free (strtab);
6488
6489 return res;
6490}
6491
85b1c36d 6492static struct
566b0d53 6493{
2cf0635d 6494 const char * name;
566b0d53
L
6495 int reloc;
6496 int size;
6497 int rela;
6498} dynamic_relocations [] =
6499{
6500 { "REL", DT_REL, DT_RELSZ, FALSE },
6501 { "RELA", DT_RELA, DT_RELASZ, TRUE },
6502 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
6503};
6504
252b5132 6505/* Process the reloc section. */
18bd398b 6506
252b5132 6507static int
2cf0635d 6508process_relocs (FILE * file)
252b5132 6509{
b34976b6
AM
6510 unsigned long rel_size;
6511 unsigned long rel_offset;
252b5132
RH
6512
6513
6514 if (!do_reloc)
6515 return 1;
6516
6517 if (do_using_dynamic)
6518 {
566b0d53 6519 int is_rela;
2cf0635d 6520 const char * name;
566b0d53
L
6521 int has_dynamic_reloc;
6522 unsigned int i;
0de14b54 6523
566b0d53 6524 has_dynamic_reloc = 0;
252b5132 6525
566b0d53 6526 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 6527 {
566b0d53
L
6528 is_rela = dynamic_relocations [i].rela;
6529 name = dynamic_relocations [i].name;
6530 rel_size = dynamic_info [dynamic_relocations [i].size];
6531 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 6532
566b0d53
L
6533 has_dynamic_reloc |= rel_size;
6534
6535 if (is_rela == UNKNOWN)
aa903cfb 6536 {
566b0d53
L
6537 if (dynamic_relocations [i].reloc == DT_JMPREL)
6538 switch (dynamic_info[DT_PLTREL])
6539 {
6540 case DT_REL:
6541 is_rela = FALSE;
6542 break;
6543 case DT_RELA:
6544 is_rela = TRUE;
6545 break;
6546 }
aa903cfb 6547 }
252b5132 6548
566b0d53
L
6549 if (rel_size)
6550 {
6551 printf
6552 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
6553 name, rel_offset, rel_size);
252b5132 6554
d93f0186
NC
6555 dump_relocations (file,
6556 offset_from_vma (file, rel_offset, rel_size),
6557 rel_size,
566b0d53 6558 dynamic_symbols, num_dynamic_syms,
bb4d2ac2
L
6559 dynamic_strings, dynamic_strings_length,
6560 is_rela, 1);
566b0d53 6561 }
252b5132 6562 }
566b0d53 6563
28f997cf
TG
6564 if (is_ia64_vms ())
6565 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
6566
566b0d53 6567 if (! has_dynamic_reloc)
252b5132
RH
6568 printf (_("\nThere are no dynamic relocations in this file.\n"));
6569 }
6570 else
6571 {
2cf0635d 6572 Elf_Internal_Shdr * section;
b34976b6
AM
6573 unsigned long i;
6574 int found = 0;
252b5132
RH
6575
6576 for (i = 0, section = section_headers;
6577 i < elf_header.e_shnum;
b34976b6 6578 i++, section++)
252b5132
RH
6579 {
6580 if ( section->sh_type != SHT_RELA
6581 && section->sh_type != SHT_REL)
6582 continue;
6583
6584 rel_offset = section->sh_offset;
6585 rel_size = section->sh_size;
6586
6587 if (rel_size)
6588 {
2cf0635d 6589 Elf_Internal_Shdr * strsec;
b34976b6 6590 int is_rela;
103f02d3 6591
252b5132
RH
6592 printf (_("\nRelocation section "));
6593
6594 if (string_table == NULL)
19936277 6595 printf ("%d", section->sh_name);
252b5132 6596 else
74e1a04b 6597 printf ("'%s'", printable_section_name (section));
252b5132
RH
6598
6599 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6600 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
6601
d79b3d50
NC
6602 is_rela = section->sh_type == SHT_RELA;
6603
4fbb74a6
AM
6604 if (section->sh_link != 0
6605 && section->sh_link < elf_header.e_shnum)
af3fc3bc 6606 {
2cf0635d
NC
6607 Elf_Internal_Shdr * symsec;
6608 Elf_Internal_Sym * symtab;
d79b3d50 6609 unsigned long nsyms;
c256ffe7 6610 unsigned long strtablen = 0;
2cf0635d 6611 char * strtab = NULL;
57346661 6612
4fbb74a6 6613 symsec = section_headers + section->sh_link;
08d8fa11
JJ
6614 if (symsec->sh_type != SHT_SYMTAB
6615 && symsec->sh_type != SHT_DYNSYM)
6616 continue;
6617
ba5cdace 6618 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 6619
af3fc3bc
AM
6620 if (symtab == NULL)
6621 continue;
252b5132 6622
4fbb74a6
AM
6623 if (symsec->sh_link != 0
6624 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 6625 {
4fbb74a6 6626 strsec = section_headers + symsec->sh_link;
103f02d3 6627
3f5e193b 6628 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
071436c6
NC
6629 1, strsec->sh_size,
6630 _("string table"));
c256ffe7
JJ
6631 strtablen = strtab == NULL ? 0 : strsec->sh_size;
6632 }
252b5132 6633
d79b3d50 6634 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2
L
6635 symtab, nsyms, strtab, strtablen,
6636 is_rela,
6637 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
6638 if (strtab)
6639 free (strtab);
6640 free (symtab);
6641 }
6642 else
6643 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2 6644 NULL, 0, NULL, 0, is_rela, 0);
252b5132
RH
6645
6646 found = 1;
6647 }
6648 }
6649
6650 if (! found)
6651 printf (_("\nThere are no relocations in this file.\n"));
6652 }
6653
6654 return 1;
6655}
6656
4d6ed7c8
NC
6657/* An absolute address consists of a section and an offset. If the
6658 section is NULL, the offset itself is the address, otherwise, the
6659 address equals to LOAD_ADDRESS(section) + offset. */
6660
6661struct absaddr
948f632f
DA
6662{
6663 unsigned short section;
6664 bfd_vma offset;
6665};
4d6ed7c8 6666
1949de15
L
6667#define ABSADDR(a) \
6668 ((a).section \
6669 ? section_headers [(a).section].sh_addr + (a).offset \
6670 : (a).offset)
6671
948f632f
DA
6672/* Find the nearest symbol at or below ADDR. Returns the symbol
6673 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 6674
4d6ed7c8 6675static void
2cf0635d 6676find_symbol_for_address (Elf_Internal_Sym * symtab,
948f632f
DA
6677 unsigned long nsyms,
6678 const char * strtab,
6679 unsigned long strtab_size,
6680 struct absaddr addr,
6681 const char ** symname,
6682 bfd_vma * offset)
4d6ed7c8 6683{
d3ba0551 6684 bfd_vma dist = 0x100000;
2cf0635d 6685 Elf_Internal_Sym * sym;
948f632f
DA
6686 Elf_Internal_Sym * beg;
6687 Elf_Internal_Sym * end;
2cf0635d 6688 Elf_Internal_Sym * best = NULL;
4d6ed7c8 6689
0b6ae522 6690 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
6691 beg = symtab;
6692 end = symtab + nsyms;
0b6ae522 6693
948f632f 6694 while (beg < end)
4d6ed7c8 6695 {
948f632f
DA
6696 bfd_vma value;
6697
6698 sym = beg + (end - beg) / 2;
0b6ae522 6699
948f632f 6700 value = sym->st_value;
0b6ae522
DJ
6701 REMOVE_ARCH_BITS (value);
6702
948f632f 6703 if (sym->st_name != 0
4d6ed7c8 6704 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
6705 && addr.offset >= value
6706 && addr.offset - value < dist)
4d6ed7c8
NC
6707 {
6708 best = sym;
0b6ae522 6709 dist = addr.offset - value;
4d6ed7c8
NC
6710 if (!dist)
6711 break;
6712 }
948f632f
DA
6713
6714 if (addr.offset < value)
6715 end = sym;
6716 else
6717 beg = sym + 1;
4d6ed7c8 6718 }
1b31d05e 6719
4d6ed7c8
NC
6720 if (best)
6721 {
57346661 6722 *symname = (best->st_name >= strtab_size
2b692964 6723 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
6724 *offset = dist;
6725 return;
6726 }
1b31d05e 6727
4d6ed7c8
NC
6728 *symname = NULL;
6729 *offset = addr.offset;
6730}
6731
948f632f
DA
6732static int
6733symcmp (const void *p, const void *q)
6734{
6735 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
6736 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
6737
6738 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
6739}
6740
6741/* Process the unwind section. */
6742
6743#include "unwind-ia64.h"
6744
6745struct ia64_unw_table_entry
6746{
6747 struct absaddr start;
6748 struct absaddr end;
6749 struct absaddr info;
6750};
6751
6752struct ia64_unw_aux_info
6753{
6754 struct ia64_unw_table_entry *table; /* Unwind table. */
6755 unsigned long table_len; /* Length of unwind table. */
6756 unsigned char * info; /* Unwind info. */
6757 unsigned long info_size; /* Size of unwind info. */
6758 bfd_vma info_addr; /* Starting address of unwind info. */
6759 bfd_vma seg_base; /* Starting address of segment. */
6760 Elf_Internal_Sym * symtab; /* The symbol table. */
6761 unsigned long nsyms; /* Number of symbols. */
6762 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
6763 unsigned long nfuns; /* Number of entries in funtab. */
6764 char * strtab; /* The string table. */
6765 unsigned long strtab_size; /* Size of string table. */
6766};
6767
4d6ed7c8 6768static void
2cf0635d 6769dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 6770{
2cf0635d 6771 struct ia64_unw_table_entry * tp;
948f632f 6772 unsigned long j, nfuns;
4d6ed7c8 6773 int in_body;
7036c0e1 6774
948f632f
DA
6775 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
6776 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
6777 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
6778 aux->funtab[nfuns++] = aux->symtab[j];
6779 aux->nfuns = nfuns;
6780 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
6781
4d6ed7c8
NC
6782 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6783 {
6784 bfd_vma stamp;
6785 bfd_vma offset;
2cf0635d
NC
6786 const unsigned char * dp;
6787 const unsigned char * head;
53774b7e 6788 const unsigned char * end;
2cf0635d 6789 const char * procname;
4d6ed7c8 6790
948f632f 6791 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
57346661 6792 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
6793
6794 fputs ("\n<", stdout);
6795
6796 if (procname)
6797 {
6798 fputs (procname, stdout);
6799
6800 if (offset)
6801 printf ("+%lx", (unsigned long) offset);
6802 }
6803
6804 fputs (">: [", stdout);
6805 print_vma (tp->start.offset, PREFIX_HEX);
6806 fputc ('-', stdout);
6807 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 6808 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
6809 (unsigned long) (tp->info.offset - aux->seg_base));
6810
53774b7e
NC
6811 /* PR 17531: file: 86232b32. */
6812 if (aux->info == NULL)
6813 continue;
6814
6815 /* PR 17531: file: 0997b4d1. */
6816 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
6817 {
6818 warn (_("Invalid offset %lx in table entry %ld\n"),
6819 (long) tp->info.offset, (long) (tp - aux->table));
6820 continue;
6821 }
6822
1949de15 6823 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 6824 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 6825
86f55779 6826 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
6827 (unsigned) UNW_VER (stamp),
6828 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
6829 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
6830 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 6831 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
6832
6833 if (UNW_VER (stamp) != 1)
6834 {
2b692964 6835 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
6836 continue;
6837 }
6838
6839 in_body = 0;
53774b7e
NC
6840 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
6841 /* PR 17531: file: 16ceda89. */
6842 if (end > aux->info + aux->info_size)
6843 end = aux->info + aux->info_size;
6844 for (dp = head + 8; dp < end;)
b4477bc8 6845 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 6846 }
948f632f
DA
6847
6848 free (aux->funtab);
4d6ed7c8
NC
6849}
6850
53774b7e 6851static bfd_boolean
2cf0635d
NC
6852slurp_ia64_unwind_table (FILE * file,
6853 struct ia64_unw_aux_info * aux,
6854 Elf_Internal_Shdr * sec)
4d6ed7c8 6855{
89fac5e3 6856 unsigned long size, nrelas, i;
2cf0635d
NC
6857 Elf_Internal_Phdr * seg;
6858 struct ia64_unw_table_entry * tep;
6859 Elf_Internal_Shdr * relsec;
6860 Elf_Internal_Rela * rela;
6861 Elf_Internal_Rela * rp;
6862 unsigned char * table;
6863 unsigned char * tp;
6864 Elf_Internal_Sym * sym;
6865 const char * relname;
4d6ed7c8 6866
53774b7e
NC
6867 aux->table_len = 0;
6868
4d6ed7c8
NC
6869 /* First, find the starting address of the segment that includes
6870 this section: */
6871
6872 if (elf_header.e_phnum)
6873 {
d93f0186 6874 if (! get_program_headers (file))
53774b7e 6875 return FALSE;
4d6ed7c8 6876
d93f0186
NC
6877 for (seg = program_headers;
6878 seg < program_headers + elf_header.e_phnum;
6879 ++seg)
4d6ed7c8
NC
6880 {
6881 if (seg->p_type != PT_LOAD)
6882 continue;
6883
6884 if (sec->sh_addr >= seg->p_vaddr
6885 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6886 {
6887 aux->seg_base = seg->p_vaddr;
6888 break;
6889 }
6890 }
4d6ed7c8
NC
6891 }
6892
6893 /* Second, build the unwind table from the contents of the unwind section: */
6894 size = sec->sh_size;
3f5e193b
NC
6895 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6896 _("unwind table"));
a6e9f9df 6897 if (!table)
53774b7e 6898 return FALSE;
4d6ed7c8 6899
53774b7e 6900 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 6901 aux->table = (struct ia64_unw_table_entry *)
53774b7e 6902 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 6903 tep = aux->table;
53774b7e
NC
6904
6905 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
6906 {
6907 tep->start.section = SHN_UNDEF;
6908 tep->end.section = SHN_UNDEF;
6909 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6910 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6911 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6912 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6913 tep->start.offset += aux->seg_base;
6914 tep->end.offset += aux->seg_base;
6915 tep->info.offset += aux->seg_base;
6916 }
6917 free (table);
6918
41e92641 6919 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6920 for (relsec = section_headers;
6921 relsec < section_headers + elf_header.e_shnum;
6922 ++relsec)
6923 {
6924 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6925 || relsec->sh_info >= elf_header.e_shnum
6926 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6927 continue;
6928
6929 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6930 & rela, & nrelas))
53774b7e
NC
6931 {
6932 free (aux->table);
6933 aux->table = NULL;
6934 aux->table_len = 0;
6935 return FALSE;
6936 }
4d6ed7c8
NC
6937
6938 for (rp = rela; rp < rela + nrelas; ++rp)
6939 {
aca88567
NC
6940 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6941 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6942
82b1b41b
NC
6943 /* PR 17531: file: 9fa67536. */
6944 if (relname == NULL)
6945 {
6946 warn (_("Skipping unknown relocation type: %u\n"), get_reloc_type (rp->r_info));
6947 continue;
6948 }
948f632f 6949
0112cd26 6950 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6951 {
82b1b41b 6952 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
6953 continue;
6954 }
6955
89fac5e3 6956 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6957
53774b7e
NC
6958 /* PR 17531: file: 5bc8d9bf. */
6959 if (i >= aux->table_len)
6960 {
6961 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
6962 continue;
6963 }
6964
6965 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
6966 {
6967 case 0:
6968 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6969 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6970 break;
6971 case 1:
6972 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6973 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6974 break;
6975 case 2:
6976 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6977 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6978 break;
6979 default:
6980 break;
6981 }
6982 }
6983
6984 free (rela);
6985 }
6986
53774b7e 6987 return TRUE;
4d6ed7c8
NC
6988}
6989
1b31d05e 6990static void
2cf0635d 6991ia64_process_unwind (FILE * file)
4d6ed7c8 6992{
2cf0635d
NC
6993 Elf_Internal_Shdr * sec;
6994 Elf_Internal_Shdr * unwsec = NULL;
6995 Elf_Internal_Shdr * strsec;
89fac5e3 6996 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6997 struct ia64_unw_aux_info aux;
f1467e33 6998
4d6ed7c8
NC
6999 memset (& aux, 0, sizeof (aux));
7000
4d6ed7c8
NC
7001 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7002 {
c256ffe7 7003 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7004 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 7005 {
ba5cdace 7006 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 7007
4fbb74a6 7008 strsec = section_headers + sec->sh_link;
4082ef84
NC
7009 if (aux.strtab != NULL)
7010 {
7011 error (_("Multiple auxillary string tables encountered\n"));
7012 free (aux.strtab);
7013 }
3f5e193b
NC
7014 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7015 1, strsec->sh_size,
7016 _("string table"));
c256ffe7 7017 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
7018 }
7019 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7020 unwcount++;
7021 }
7022
7023 if (!unwcount)
7024 printf (_("\nThere are no unwind sections in this file.\n"));
7025
7026 while (unwcount-- > 0)
7027 {
2cf0635d 7028 char * suffix;
579f31ac
JJ
7029 size_t len, len2;
7030
4082ef84 7031 for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
579f31ac
JJ
7032 i < elf_header.e_shnum; ++i, ++sec)
7033 if (sec->sh_type == SHT_IA_64_UNWIND)
7034 {
7035 unwsec = sec;
7036 break;
7037 }
4082ef84
NC
7038 /* We have already counted the number of SHT_IA64_UNWIND
7039 sections so the loop above should never fail. */
7040 assert (unwsec != NULL);
579f31ac
JJ
7041
7042 unwstart = i + 1;
7043 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
7044
e4b17d5c
L
7045 if ((unwsec->sh_flags & SHF_GROUP) != 0)
7046 {
7047 /* We need to find which section group it is in. */
4082ef84 7048 struct group_list * g;
e4b17d5c 7049
4082ef84
NC
7050 if (section_headers_groups == NULL
7051 || section_headers_groups [i] == NULL)
7052 i = elf_header.e_shnum;
7053 else
e4b17d5c 7054 {
4082ef84 7055 g = section_headers_groups [i]->root;
18bd398b 7056
4082ef84
NC
7057 for (; g != NULL; g = g->next)
7058 {
7059 sec = section_headers + g->section_index;
e4b17d5c 7060
4082ef84
NC
7061 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
7062 break;
7063 }
7064
7065 if (g == NULL)
7066 i = elf_header.e_shnum;
7067 }
e4b17d5c 7068 }
18bd398b 7069 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 7070 {
18bd398b 7071 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
7072 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
7073 suffix = SECTION_NAME (unwsec) + len;
7074 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
7075 ++i, ++sec)
18bd398b
NC
7076 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
7077 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7078 break;
7079 }
7080 else
7081 {
7082 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 7083 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
7084 len = sizeof (ELF_STRING_ia64_unwind) - 1;
7085 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
7086 suffix = "";
18bd398b 7087 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
7088 suffix = SECTION_NAME (unwsec) + len;
7089 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
7090 ++i, ++sec)
18bd398b
NC
7091 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
7092 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
7093 break;
7094 }
7095
7096 if (i == elf_header.e_shnum)
7097 {
7098 printf (_("\nCould not find unwind info section for "));
7099
7100 if (string_table == NULL)
7101 printf ("%d", unwsec->sh_name);
7102 else
74e1a04b 7103 printf ("'%s'", printable_section_name (unwsec));
579f31ac
JJ
7104 }
7105 else
4d6ed7c8 7106 {
4d6ed7c8 7107 aux.info_addr = sec->sh_addr;
3f5e193b 7108 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
4082ef84
NC
7109 sec->sh_size,
7110 _("unwind info"));
59245841 7111 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 7112
579f31ac 7113 printf (_("\nUnwind section "));
4d6ed7c8 7114
579f31ac
JJ
7115 if (string_table == NULL)
7116 printf ("%d", unwsec->sh_name);
7117 else
74e1a04b 7118 printf ("'%s'", printable_section_name (unwsec));
4d6ed7c8 7119
579f31ac 7120 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 7121 (unsigned long) unwsec->sh_offset,
89fac5e3 7122 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 7123
53774b7e
NC
7124 if (slurp_ia64_unwind_table (file, & aux, unwsec)
7125 && aux.table_len > 0)
579f31ac
JJ
7126 dump_ia64_unwind (& aux);
7127
7128 if (aux.table)
7129 free ((char *) aux.table);
7130 if (aux.info)
7131 free ((char *) aux.info);
7132 aux.table = NULL;
7133 aux.info = NULL;
7134 }
4d6ed7c8 7135 }
4d6ed7c8 7136
4d6ed7c8
NC
7137 if (aux.symtab)
7138 free (aux.symtab);
7139 if (aux.strtab)
7140 free ((char *) aux.strtab);
4d6ed7c8
NC
7141}
7142
3f5e193b
NC
7143struct hppa_unw_table_entry
7144 {
7145 struct absaddr start;
7146 struct absaddr end;
948f632f 7147 unsigned int Cannot_unwind:1; /* 0 */
3f5e193b
NC
7148 unsigned int Millicode:1; /* 1 */
7149 unsigned int Millicode_save_sr0:1; /* 2 */
7150 unsigned int Region_description:2; /* 3..4 */
7151 unsigned int reserved1:1; /* 5 */
7152 unsigned int Entry_SR:1; /* 6 */
7153 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
7154 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
7155 unsigned int Args_stored:1; /* 16 */
948f632f
DA
7156 unsigned int Variable_Frame:1; /* 17 */
7157 unsigned int Separate_Package_Body:1; /* 18 */
3f5e193b 7158 unsigned int Frame_Extension_Millicode:1; /* 19 */
948f632f
DA
7159 unsigned int Stack_Overflow_Check:1; /* 20 */
7160 unsigned int Two_Instruction_SP_Increment:1;/* 21 */
3f5e193b
NC
7161 unsigned int Ada_Region:1; /* 22 */
7162 unsigned int cxx_info:1; /* 23 */
948f632f
DA
7163 unsigned int cxx_try_catch:1; /* 24 */
7164 unsigned int sched_entry_seq:1; /* 25 */
3f5e193b 7165 unsigned int reserved2:1; /* 26 */
948f632f
DA
7166 unsigned int Save_SP:1; /* 27 */
7167 unsigned int Save_RP:1; /* 28 */
3f5e193b
NC
7168 unsigned int Save_MRP_in_frame:1; /* 29 */
7169 unsigned int extn_ptr_defined:1; /* 30 */
948f632f 7170 unsigned int Cleanup_defined:1; /* 31 */
3f5e193b 7171
948f632f
DA
7172 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
7173 unsigned int HP_UX_interrupt_marker:1; /* 1 */
3f5e193b 7174 unsigned int Large_frame:1; /* 2 */
948f632f 7175 unsigned int Pseudo_SP_Set:1; /* 3 */
3f5e193b
NC
7176 unsigned int reserved4:1; /* 4 */
7177 unsigned int Total_frame_size:27; /* 5..31 */
7178 };
7179
57346661 7180struct hppa_unw_aux_info
948f632f
DA
7181{
7182 struct hppa_unw_table_entry * table; /* Unwind table. */
7183 unsigned long table_len; /* Length of unwind table. */
7184 bfd_vma seg_base; /* Starting address of segment. */
7185 Elf_Internal_Sym * symtab; /* The symbol table. */
7186 unsigned long nsyms; /* Number of symbols. */
7187 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7188 unsigned long nfuns; /* Number of entries in funtab. */
7189 char * strtab; /* The string table. */
7190 unsigned long strtab_size; /* Size of string table. */
7191};
57346661
AM
7192
7193static void
2cf0635d 7194dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 7195{
2cf0635d 7196 struct hppa_unw_table_entry * tp;
948f632f
DA
7197 unsigned long j, nfuns;
7198
7199 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7200 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7201 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7202 aux->funtab[nfuns++] = aux->symtab[j];
7203 aux->nfuns = nfuns;
7204 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 7205
57346661
AM
7206 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7207 {
7208 bfd_vma offset;
2cf0635d 7209 const char * procname;
57346661 7210
948f632f 7211 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
7212 aux->strtab_size, tp->start, &procname,
7213 &offset);
7214
7215 fputs ("\n<", stdout);
7216
7217 if (procname)
7218 {
7219 fputs (procname, stdout);
7220
7221 if (offset)
7222 printf ("+%lx", (unsigned long) offset);
7223 }
7224
7225 fputs (">: [", stdout);
7226 print_vma (tp->start.offset, PREFIX_HEX);
7227 fputc ('-', stdout);
7228 print_vma (tp->end.offset, PREFIX_HEX);
7229 printf ("]\n\t");
7230
18bd398b
NC
7231#define PF(_m) if (tp->_m) printf (#_m " ");
7232#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
7233 PF(Cannot_unwind);
7234 PF(Millicode);
7235 PF(Millicode_save_sr0);
18bd398b 7236 /* PV(Region_description); */
57346661
AM
7237 PF(Entry_SR);
7238 PV(Entry_FR);
7239 PV(Entry_GR);
7240 PF(Args_stored);
7241 PF(Variable_Frame);
7242 PF(Separate_Package_Body);
7243 PF(Frame_Extension_Millicode);
7244 PF(Stack_Overflow_Check);
7245 PF(Two_Instruction_SP_Increment);
7246 PF(Ada_Region);
7247 PF(cxx_info);
7248 PF(cxx_try_catch);
7249 PF(sched_entry_seq);
7250 PF(Save_SP);
7251 PF(Save_RP);
7252 PF(Save_MRP_in_frame);
7253 PF(extn_ptr_defined);
7254 PF(Cleanup_defined);
7255 PF(MPE_XL_interrupt_marker);
7256 PF(HP_UX_interrupt_marker);
7257 PF(Large_frame);
7258 PF(Pseudo_SP_Set);
7259 PV(Total_frame_size);
7260#undef PF
7261#undef PV
7262 }
7263
18bd398b 7264 printf ("\n");
948f632f
DA
7265
7266 free (aux->funtab);
57346661
AM
7267}
7268
7269static int
2cf0635d
NC
7270slurp_hppa_unwind_table (FILE * file,
7271 struct hppa_unw_aux_info * aux,
7272 Elf_Internal_Shdr * sec)
57346661 7273{
1c0751b2 7274 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7275 Elf_Internal_Phdr * seg;
7276 struct hppa_unw_table_entry * tep;
7277 Elf_Internal_Shdr * relsec;
7278 Elf_Internal_Rela * rela;
7279 Elf_Internal_Rela * rp;
7280 unsigned char * table;
7281 unsigned char * tp;
7282 Elf_Internal_Sym * sym;
7283 const char * relname;
57346661 7284
57346661
AM
7285 /* First, find the starting address of the segment that includes
7286 this section. */
7287
7288 if (elf_header.e_phnum)
7289 {
7290 if (! get_program_headers (file))
7291 return 0;
7292
7293 for (seg = program_headers;
7294 seg < program_headers + elf_header.e_phnum;
7295 ++seg)
7296 {
7297 if (seg->p_type != PT_LOAD)
7298 continue;
7299
7300 if (sec->sh_addr >= seg->p_vaddr
7301 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7302 {
7303 aux->seg_base = seg->p_vaddr;
7304 break;
7305 }
7306 }
7307 }
7308
7309 /* Second, build the unwind table from the contents of the unwind
7310 section. */
7311 size = sec->sh_size;
3f5e193b
NC
7312 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
7313 _("unwind table"));
57346661
AM
7314 if (!table)
7315 return 0;
7316
1c0751b2
DA
7317 unw_ent_size = 16;
7318 nentries = size / unw_ent_size;
7319 size = unw_ent_size * nentries;
57346661 7320
3f5e193b
NC
7321 tep = aux->table = (struct hppa_unw_table_entry *)
7322 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7323
1c0751b2 7324 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7325 {
7326 unsigned int tmp1, tmp2;
7327
7328 tep->start.section = SHN_UNDEF;
7329 tep->end.section = SHN_UNDEF;
7330
1c0751b2
DA
7331 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7332 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7333 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7334 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7335
7336 tep->start.offset += aux->seg_base;
7337 tep->end.offset += aux->seg_base;
57346661
AM
7338
7339 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
7340 tep->Millicode = (tmp1 >> 30) & 0x1;
7341 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
7342 tep->Region_description = (tmp1 >> 27) & 0x3;
7343 tep->reserved1 = (tmp1 >> 26) & 0x1;
7344 tep->Entry_SR = (tmp1 >> 25) & 0x1;
7345 tep->Entry_FR = (tmp1 >> 21) & 0xf;
7346 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7347 tep->Args_stored = (tmp1 >> 15) & 0x1;
7348 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7349 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7350 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7351 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7352 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7353 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7354 tep->cxx_info = (tmp1 >> 8) & 0x1;
7355 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7356 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7357 tep->reserved2 = (tmp1 >> 5) & 0x1;
7358 tep->Save_SP = (tmp1 >> 4) & 0x1;
7359 tep->Save_RP = (tmp1 >> 3) & 0x1;
7360 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7361 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7362 tep->Cleanup_defined = tmp1 & 0x1;
7363
7364 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7365 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7366 tep->Large_frame = (tmp2 >> 29) & 0x1;
7367 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7368 tep->reserved4 = (tmp2 >> 27) & 0x1;
7369 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7370 }
7371 free (table);
7372
7373 /* Third, apply any relocations to the unwind table. */
57346661
AM
7374 for (relsec = section_headers;
7375 relsec < section_headers + elf_header.e_shnum;
7376 ++relsec)
7377 {
7378 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
7379 || relsec->sh_info >= elf_header.e_shnum
7380 || section_headers + relsec->sh_info != sec)
57346661
AM
7381 continue;
7382
7383 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7384 & rela, & nrelas))
7385 return 0;
7386
7387 for (rp = rela; rp < rela + nrelas; ++rp)
7388 {
aca88567
NC
7389 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
7390 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
7391
7392 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 7393 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
7394 {
7395 warn (_("Skipping unexpected relocation type %s\n"), relname);
7396 continue;
7397 }
7398
7399 i = rp->r_offset / unw_ent_size;
7400
89fac5e3 7401 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
7402 {
7403 case 0:
7404 aux->table[i].start.section = sym->st_shndx;
1e456d54 7405 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
7406 break;
7407 case 1:
7408 aux->table[i].end.section = sym->st_shndx;
1e456d54 7409 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
7410 break;
7411 default:
7412 break;
7413 }
7414 }
7415
7416 free (rela);
7417 }
7418
1c0751b2 7419 aux->table_len = nentries;
57346661
AM
7420
7421 return 1;
7422}
7423
1b31d05e 7424static void
2cf0635d 7425hppa_process_unwind (FILE * file)
57346661 7426{
57346661 7427 struct hppa_unw_aux_info aux;
2cf0635d
NC
7428 Elf_Internal_Shdr * unwsec = NULL;
7429 Elf_Internal_Shdr * strsec;
7430 Elf_Internal_Shdr * sec;
18bd398b 7431 unsigned long i;
57346661 7432
c256ffe7 7433 if (string_table == NULL)
1b31d05e
NC
7434 return;
7435
7436 memset (& aux, 0, sizeof (aux));
57346661
AM
7437
7438 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7439 {
c256ffe7 7440 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7441 && sec->sh_link < elf_header.e_shnum)
57346661 7442 {
ba5cdace 7443 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 7444
4fbb74a6 7445 strsec = section_headers + sec->sh_link;
4082ef84
NC
7446 if (aux.strtab != NULL)
7447 {
7448 error (_("Multiple auxillary string tables encountered\n"));
7449 free (aux.strtab);
7450 }
3f5e193b
NC
7451 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7452 1, strsec->sh_size,
7453 _("string table"));
c256ffe7 7454 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 7455 }
18bd398b 7456 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
7457 unwsec = sec;
7458 }
7459
7460 if (!unwsec)
7461 printf (_("\nThere are no unwind sections in this file.\n"));
7462
7463 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7464 {
18bd398b 7465 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 7466 {
74e1a04b
NC
7467 printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
7468 printable_section_name (sec),
57346661 7469 (unsigned long) sec->sh_offset,
89fac5e3 7470 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
7471
7472 slurp_hppa_unwind_table (file, &aux, sec);
7473 if (aux.table_len > 0)
7474 dump_hppa_unwind (&aux);
7475
7476 if (aux.table)
7477 free ((char *) aux.table);
7478 aux.table = NULL;
7479 }
7480 }
7481
7482 if (aux.symtab)
7483 free (aux.symtab);
7484 if (aux.strtab)
7485 free ((char *) aux.strtab);
57346661
AM
7486}
7487
0b6ae522
DJ
7488struct arm_section
7489{
a734115a
NC
7490 unsigned char * data; /* The unwind data. */
7491 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
7492 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
7493 unsigned long nrelas; /* The number of relocations. */
7494 unsigned int rel_type; /* REL or RELA ? */
7495 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
7496};
7497
7498struct arm_unw_aux_info
7499{
a734115a
NC
7500 FILE * file; /* The file containing the unwind sections. */
7501 Elf_Internal_Sym * symtab; /* The file's symbol table. */
7502 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
7503 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7504 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
7505 char * strtab; /* The file's string table. */
7506 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
7507};
7508
7509static const char *
7510arm_print_vma_and_name (struct arm_unw_aux_info *aux,
7511 bfd_vma fn, struct absaddr addr)
7512{
7513 const char *procname;
7514 bfd_vma sym_offset;
7515
7516 if (addr.section == SHN_UNDEF)
7517 addr.offset = fn;
7518
948f632f 7519 find_symbol_for_address (aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
7520 aux->strtab_size, addr, &procname,
7521 &sym_offset);
7522
7523 print_vma (fn, PREFIX_HEX);
7524
7525 if (procname)
7526 {
7527 fputs (" <", stdout);
7528 fputs (procname, stdout);
7529
7530 if (sym_offset)
7531 printf ("+0x%lx", (unsigned long) sym_offset);
7532 fputc ('>', stdout);
7533 }
7534
7535 return procname;
7536}
7537
7538static void
7539arm_free_section (struct arm_section *arm_sec)
7540{
7541 if (arm_sec->data != NULL)
7542 free (arm_sec->data);
7543
7544 if (arm_sec->rela != NULL)
7545 free (arm_sec->rela);
7546}
7547
a734115a
NC
7548/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
7549 cached section and install SEC instead.
7550 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
7551 and return its valued in * WORDP, relocating if necessary.
1b31d05e 7552 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 7553 relocation's offset in ADDR.
1b31d05e
NC
7554 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
7555 into the string table of the symbol associated with the reloc. If no
7556 reloc was applied store -1 there.
7557 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
7558
7559static bfd_boolean
1b31d05e
NC
7560get_unwind_section_word (struct arm_unw_aux_info * aux,
7561 struct arm_section * arm_sec,
7562 Elf_Internal_Shdr * sec,
7563 bfd_vma word_offset,
7564 unsigned int * wordp,
7565 struct absaddr * addr,
7566 bfd_vma * sym_name)
0b6ae522
DJ
7567{
7568 Elf_Internal_Rela *rp;
7569 Elf_Internal_Sym *sym;
7570 const char * relname;
7571 unsigned int word;
7572 bfd_boolean wrapped;
7573
e0a31db1
NC
7574 if (sec == NULL || arm_sec == NULL)
7575 return FALSE;
7576
0b6ae522
DJ
7577 addr->section = SHN_UNDEF;
7578 addr->offset = 0;
7579
1b31d05e
NC
7580 if (sym_name != NULL)
7581 *sym_name = (bfd_vma) -1;
7582
a734115a 7583 /* If necessary, update the section cache. */
0b6ae522
DJ
7584 if (sec != arm_sec->sec)
7585 {
7586 Elf_Internal_Shdr *relsec;
7587
7588 arm_free_section (arm_sec);
7589
7590 arm_sec->sec = sec;
7591 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
7592 sec->sh_size, _("unwind data"));
0b6ae522
DJ
7593 arm_sec->rela = NULL;
7594 arm_sec->nrelas = 0;
7595
7596 for (relsec = section_headers;
7597 relsec < section_headers + elf_header.e_shnum;
7598 ++relsec)
7599 {
7600 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
7601 || section_headers + relsec->sh_info != sec
7602 /* PR 15745: Check the section type as well. */
7603 || (relsec->sh_type != SHT_REL
7604 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
7605 continue;
7606
a734115a 7607 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
7608 if (relsec->sh_type == SHT_REL)
7609 {
7610 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
7611 relsec->sh_size,
7612 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7613 return FALSE;
0b6ae522 7614 }
1ae40aa4 7615 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
7616 {
7617 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
7618 relsec->sh_size,
7619 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7620 return FALSE;
0b6ae522 7621 }
1ae40aa4 7622 break;
0b6ae522
DJ
7623 }
7624
7625 arm_sec->next_rela = arm_sec->rela;
7626 }
7627
a734115a 7628 /* If there is no unwind data we can do nothing. */
0b6ae522 7629 if (arm_sec->data == NULL)
a734115a 7630 return FALSE;
0b6ae522 7631
e0a31db1 7632 /* If the offset is invalid then fail. */
1a915552
NC
7633 if (word_offset > (sec->sh_size - 4)
7634 /* PR 18879 */
7635 || (sec->sh_size < 5 && word_offset >= sec->sh_size)
7636 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
7637 return FALSE;
7638
a734115a 7639 /* Get the word at the required offset. */
0b6ae522
DJ
7640 word = byte_get (arm_sec->data + word_offset, 4);
7641
0eff7165
NC
7642 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
7643 if (arm_sec->rela == NULL)
7644 {
7645 * wordp = word;
7646 return TRUE;
7647 }
7648
a734115a 7649 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
7650 wrapped = FALSE;
7651 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
7652 {
7653 bfd_vma prelval, offset;
7654
7655 if (rp->r_offset > word_offset && !wrapped)
7656 {
7657 rp = arm_sec->rela;
7658 wrapped = TRUE;
7659 }
7660 if (rp->r_offset > word_offset)
7661 break;
7662
7663 if (rp->r_offset & 3)
7664 {
7665 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
7666 (unsigned long) rp->r_offset);
7667 continue;
7668 }
7669
7670 if (rp->r_offset < word_offset)
7671 continue;
7672
74e1a04b
NC
7673 /* PR 17531: file: 027-161405-0.004 */
7674 if (aux->symtab == NULL)
7675 continue;
7676
0b6ae522
DJ
7677 if (arm_sec->rel_type == SHT_REL)
7678 {
7679 offset = word & 0x7fffffff;
7680 if (offset & 0x40000000)
7681 offset |= ~ (bfd_vma) 0x7fffffff;
7682 }
a734115a 7683 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 7684 offset = rp->r_addend;
a734115a 7685 else
74e1a04b
NC
7686 {
7687 error (_("Unknown section relocation type %d encountered\n"),
7688 arm_sec->rel_type);
7689 break;
7690 }
0b6ae522 7691
071436c6
NC
7692 /* PR 17531 file: 027-1241568-0.004. */
7693 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
7694 {
7695 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
7696 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
7697 break;
7698 }
7699
7700 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
7701 offset += sym->st_value;
7702 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
7703
a734115a
NC
7704 /* Check that we are processing the expected reloc type. */
7705 if (elf_header.e_machine == EM_ARM)
7706 {
7707 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7708 if (relname == NULL)
7709 {
7710 warn (_("Skipping unknown ARM relocation type: %d\n"),
7711 (int) ELF32_R_TYPE (rp->r_info));
7712 continue;
7713 }
a734115a
NC
7714
7715 if (streq (relname, "R_ARM_NONE"))
7716 continue;
0b4362b0 7717
a734115a
NC
7718 if (! streq (relname, "R_ARM_PREL31"))
7719 {
071436c6 7720 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
7721 continue;
7722 }
7723 }
7724 else if (elf_header.e_machine == EM_TI_C6000)
7725 {
7726 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7727 if (relname == NULL)
7728 {
7729 warn (_("Skipping unknown C6000 relocation type: %d\n"),
7730 (int) ELF32_R_TYPE (rp->r_info));
7731 continue;
7732 }
0b4362b0 7733
a734115a
NC
7734 if (streq (relname, "R_C6000_NONE"))
7735 continue;
7736
7737 if (! streq (relname, "R_C6000_PREL31"))
7738 {
071436c6 7739 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
7740 continue;
7741 }
7742
7743 prelval >>= 1;
7744 }
7745 else
74e1a04b
NC
7746 {
7747 /* This function currently only supports ARM and TI unwinders. */
7748 warn (_("Only TI and ARM unwinders are currently supported\n"));
7749 break;
7750 }
fa197c1c 7751
0b6ae522
DJ
7752 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
7753 addr->section = sym->st_shndx;
7754 addr->offset = offset;
74e1a04b 7755
1b31d05e
NC
7756 if (sym_name)
7757 * sym_name = sym->st_name;
0b6ae522
DJ
7758 break;
7759 }
7760
7761 *wordp = word;
7762 arm_sec->next_rela = rp;
7763
a734115a 7764 return TRUE;
0b6ae522
DJ
7765}
7766
a734115a
NC
7767static const char *tic6x_unwind_regnames[16] =
7768{
0b4362b0
RM
7769 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
7770 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
7771 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
7772};
fa197c1c 7773
0b6ae522 7774static void
fa197c1c 7775decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 7776{
fa197c1c
PB
7777 int i;
7778
7779 for (i = 12; mask; mask >>= 1, i--)
7780 {
7781 if (mask & 1)
7782 {
7783 fputs (tic6x_unwind_regnames[i], stdout);
7784 if (mask > 1)
7785 fputs (", ", stdout);
7786 }
7787 }
7788}
0b6ae522
DJ
7789
7790#define ADVANCE \
7791 if (remaining == 0 && more_words) \
7792 { \
7793 data_offset += 4; \
1b31d05e
NC
7794 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
7795 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
7796 return; \
7797 remaining = 4; \
7798 more_words--; \
7799 } \
7800
7801#define GET_OP(OP) \
7802 ADVANCE; \
7803 if (remaining) \
7804 { \
7805 remaining--; \
7806 (OP) = word >> 24; \
7807 word <<= 8; \
7808 } \
7809 else \
7810 { \
2b692964 7811 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
7812 return; \
7813 } \
cc5914eb 7814 printf ("0x%02x ", OP)
0b6ae522 7815
fa197c1c 7816static void
948f632f
DA
7817decode_arm_unwind_bytecode (struct arm_unw_aux_info * aux,
7818 unsigned int word,
7819 unsigned int remaining,
7820 unsigned int more_words,
7821 bfd_vma data_offset,
7822 Elf_Internal_Shdr * data_sec,
7823 struct arm_section * data_arm_sec)
fa197c1c
PB
7824{
7825 struct absaddr addr;
0b6ae522
DJ
7826
7827 /* Decode the unwinding instructions. */
7828 while (1)
7829 {
7830 unsigned int op, op2;
7831
7832 ADVANCE;
7833 if (remaining == 0)
7834 break;
7835 remaining--;
7836 op = word >> 24;
7837 word <<= 8;
7838
cc5914eb 7839 printf (" 0x%02x ", op);
0b6ae522
DJ
7840
7841 if ((op & 0xc0) == 0x00)
7842 {
7843 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7844
cc5914eb 7845 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
7846 }
7847 else if ((op & 0xc0) == 0x40)
7848 {
7849 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7850
cc5914eb 7851 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
7852 }
7853 else if ((op & 0xf0) == 0x80)
7854 {
7855 GET_OP (op2);
7856 if (op == 0x80 && op2 == 0)
7857 printf (_("Refuse to unwind"));
7858 else
7859 {
7860 unsigned int mask = ((op & 0x0f) << 8) | op2;
7861 int first = 1;
7862 int i;
2b692964 7863
0b6ae522
DJ
7864 printf ("pop {");
7865 for (i = 0; i < 12; i++)
7866 if (mask & (1 << i))
7867 {
7868 if (first)
7869 first = 0;
7870 else
7871 printf (", ");
7872 printf ("r%d", 4 + i);
7873 }
7874 printf ("}");
7875 }
7876 }
7877 else if ((op & 0xf0) == 0x90)
7878 {
7879 if (op == 0x9d || op == 0x9f)
7880 printf (_(" [Reserved]"));
7881 else
cc5914eb 7882 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
7883 }
7884 else if ((op & 0xf0) == 0xa0)
7885 {
7886 int end = 4 + (op & 0x07);
7887 int first = 1;
7888 int i;
61865e30 7889
0b6ae522
DJ
7890 printf (" pop {");
7891 for (i = 4; i <= end; i++)
7892 {
7893 if (first)
7894 first = 0;
7895 else
7896 printf (", ");
7897 printf ("r%d", i);
7898 }
7899 if (op & 0x08)
7900 {
1b31d05e 7901 if (!first)
0b6ae522
DJ
7902 printf (", ");
7903 printf ("r14");
7904 }
7905 printf ("}");
7906 }
7907 else if (op == 0xb0)
7908 printf (_(" finish"));
7909 else if (op == 0xb1)
7910 {
7911 GET_OP (op2);
7912 if (op2 == 0 || (op2 & 0xf0) != 0)
7913 printf (_("[Spare]"));
7914 else
7915 {
7916 unsigned int mask = op2 & 0x0f;
7917 int first = 1;
7918 int i;
61865e30 7919
0b6ae522
DJ
7920 printf ("pop {");
7921 for (i = 0; i < 12; i++)
7922 if (mask & (1 << i))
7923 {
7924 if (first)
7925 first = 0;
7926 else
7927 printf (", ");
7928 printf ("r%d", i);
7929 }
7930 printf ("}");
7931 }
7932 }
7933 else if (op == 0xb2)
7934 {
b115cf96 7935 unsigned char buf[9];
0b6ae522
DJ
7936 unsigned int i, len;
7937 unsigned long offset;
61865e30 7938
b115cf96 7939 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
7940 {
7941 GET_OP (buf[i]);
7942 if ((buf[i] & 0x80) == 0)
7943 break;
7944 }
4082ef84
NC
7945 if (i == sizeof (buf))
7946 printf (_("corrupt change to vsp"));
7947 else
7948 {
7949 offset = read_uleb128 (buf, &len, buf + i + 1);
7950 assert (len == i + 1);
7951 offset = offset * 4 + 0x204;
7952 printf ("vsp = vsp + %ld", offset);
7953 }
0b6ae522 7954 }
61865e30 7955 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 7956 {
61865e30
NC
7957 unsigned int first, last;
7958
7959 GET_OP (op2);
7960 first = op2 >> 4;
7961 last = op2 & 0x0f;
7962 if (op == 0xc8)
7963 first = first + 16;
7964 printf ("pop {D%d", first);
7965 if (last)
7966 printf ("-D%d", first + last);
7967 printf ("}");
7968 }
7969 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
7970 {
7971 unsigned int count = op & 0x07;
7972
7973 printf ("pop {D8");
7974 if (count)
7975 printf ("-D%d", 8 + count);
7976 printf ("}");
7977 }
7978 else if (op >= 0xc0 && op <= 0xc5)
7979 {
7980 unsigned int count = op & 0x07;
7981
7982 printf (" pop {wR10");
7983 if (count)
7984 printf ("-wR%d", 10 + count);
7985 printf ("}");
7986 }
7987 else if (op == 0xc6)
7988 {
7989 unsigned int first, last;
7990
7991 GET_OP (op2);
7992 first = op2 >> 4;
7993 last = op2 & 0x0f;
7994 printf ("pop {wR%d", first);
7995 if (last)
7996 printf ("-wR%d", first + last);
7997 printf ("}");
7998 }
7999 else if (op == 0xc7)
8000 {
8001 GET_OP (op2);
8002 if (op2 == 0 || (op2 & 0xf0) != 0)
8003 printf (_("[Spare]"));
0b6ae522
DJ
8004 else
8005 {
61865e30
NC
8006 unsigned int mask = op2 & 0x0f;
8007 int first = 1;
8008 int i;
8009
8010 printf ("pop {");
8011 for (i = 0; i < 4; i++)
8012 if (mask & (1 << i))
8013 {
8014 if (first)
8015 first = 0;
8016 else
8017 printf (", ");
8018 printf ("wCGR%d", i);
8019 }
8020 printf ("}");
0b6ae522
DJ
8021 }
8022 }
61865e30
NC
8023 else
8024 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
8025 printf ("\n");
8026 }
fa197c1c
PB
8027}
8028
8029static void
948f632f
DA
8030decode_tic6x_unwind_bytecode (struct arm_unw_aux_info * aux,
8031 unsigned int word,
8032 unsigned int remaining,
8033 unsigned int more_words,
8034 bfd_vma data_offset,
8035 Elf_Internal_Shdr * data_sec,
8036 struct arm_section * data_arm_sec)
fa197c1c
PB
8037{
8038 struct absaddr addr;
8039
8040 /* Decode the unwinding instructions. */
8041 while (1)
8042 {
8043 unsigned int op, op2;
8044
8045 ADVANCE;
8046 if (remaining == 0)
8047 break;
8048 remaining--;
8049 op = word >> 24;
8050 word <<= 8;
8051
9cf03b7e 8052 printf (" 0x%02x ", op);
fa197c1c
PB
8053
8054 if ((op & 0xc0) == 0x00)
8055 {
8056 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 8057 printf (" sp = sp + %d", offset);
fa197c1c
PB
8058 }
8059 else if ((op & 0xc0) == 0x80)
8060 {
8061 GET_OP (op2);
8062 if (op == 0x80 && op2 == 0)
8063 printf (_("Refuse to unwind"));
8064 else
8065 {
8066 unsigned int mask = ((op & 0x1f) << 8) | op2;
8067 if (op & 0x20)
8068 printf ("pop compact {");
8069 else
8070 printf ("pop {");
8071
8072 decode_tic6x_unwind_regmask (mask);
8073 printf("}");
8074 }
8075 }
8076 else if ((op & 0xf0) == 0xc0)
8077 {
8078 unsigned int reg;
8079 unsigned int nregs;
8080 unsigned int i;
8081 const char *name;
a734115a
NC
8082 struct
8083 {
fa197c1c
PB
8084 unsigned int offset;
8085 unsigned int reg;
8086 } regpos[16];
8087
8088 /* Scan entire instruction first so that GET_OP output is not
8089 interleaved with disassembly. */
8090 nregs = 0;
8091 for (i = 0; nregs < (op & 0xf); i++)
8092 {
8093 GET_OP (op2);
8094 reg = op2 >> 4;
8095 if (reg != 0xf)
8096 {
8097 regpos[nregs].offset = i * 2;
8098 regpos[nregs].reg = reg;
8099 nregs++;
8100 }
8101
8102 reg = op2 & 0xf;
8103 if (reg != 0xf)
8104 {
8105 regpos[nregs].offset = i * 2 + 1;
8106 regpos[nregs].reg = reg;
8107 nregs++;
8108 }
8109 }
8110
8111 printf (_("pop frame {"));
8112 reg = nregs - 1;
8113 for (i = i * 2; i > 0; i--)
8114 {
8115 if (regpos[reg].offset == i - 1)
8116 {
8117 name = tic6x_unwind_regnames[regpos[reg].reg];
8118 if (reg > 0)
8119 reg--;
8120 }
8121 else
8122 name = _("[pad]");
8123
8124 fputs (name, stdout);
8125 if (i > 1)
8126 printf (", ");
8127 }
8128
8129 printf ("}");
8130 }
8131 else if (op == 0xd0)
8132 printf (" MOV FP, SP");
8133 else if (op == 0xd1)
8134 printf (" __c6xabi_pop_rts");
8135 else if (op == 0xd2)
8136 {
8137 unsigned char buf[9];
8138 unsigned int i, len;
8139 unsigned long offset;
a734115a 8140
fa197c1c
PB
8141 for (i = 0; i < sizeof (buf); i++)
8142 {
8143 GET_OP (buf[i]);
8144 if ((buf[i] & 0x80) == 0)
8145 break;
8146 }
0eff7165
NC
8147 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
8148 if (i == sizeof (buf))
8149 {
8150 printf ("<corrupt sp adjust>\n");
8151 warn (_("Corrupt stack pointer adjustment detected\n"));
8152 return;
8153 }
948f632f 8154
f6f0e17b 8155 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
8156 assert (len == i + 1);
8157 offset = offset * 8 + 0x408;
8158 printf (_("sp = sp + %ld"), offset);
8159 }
8160 else if ((op & 0xf0) == 0xe0)
8161 {
8162 if ((op & 0x0f) == 7)
8163 printf (" RETURN");
8164 else
8165 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
8166 }
8167 else
8168 {
8169 printf (_(" [unsupported opcode]"));
8170 }
8171 putchar ('\n');
8172 }
8173}
8174
8175static bfd_vma
a734115a 8176arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
8177{
8178 bfd_vma offset;
8179
8180 offset = word & 0x7fffffff;
8181 if (offset & 0x40000000)
8182 offset |= ~ (bfd_vma) 0x7fffffff;
8183
8184 if (elf_header.e_machine == EM_TI_C6000)
8185 offset <<= 1;
8186
8187 return offset + where;
8188}
8189
8190static void
1b31d05e
NC
8191decode_arm_unwind (struct arm_unw_aux_info * aux,
8192 unsigned int word,
8193 unsigned int remaining,
8194 bfd_vma data_offset,
8195 Elf_Internal_Shdr * data_sec,
8196 struct arm_section * data_arm_sec)
fa197c1c
PB
8197{
8198 int per_index;
8199 unsigned int more_words = 0;
37e14bc3 8200 struct absaddr addr;
1b31d05e 8201 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
8202
8203 if (remaining == 0)
8204 {
1b31d05e
NC
8205 /* Fetch the first word.
8206 Note - when decoding an object file the address extracted
8207 here will always be 0. So we also pass in the sym_name
8208 parameter so that we can find the symbol associated with
8209 the personality routine. */
8210 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
8211 & word, & addr, & sym_name))
fa197c1c 8212 return;
1b31d05e 8213
fa197c1c
PB
8214 remaining = 4;
8215 }
8216
8217 if ((word & 0x80000000) == 0)
8218 {
8219 /* Expand prel31 for personality routine. */
8220 bfd_vma fn;
8221 const char *procname;
8222
a734115a 8223 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 8224 printf (_(" Personality routine: "));
1b31d05e
NC
8225 if (fn == 0
8226 && addr.section == SHN_UNDEF && addr.offset == 0
8227 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
8228 {
8229 procname = aux->strtab + sym_name;
8230 print_vma (fn, PREFIX_HEX);
8231 if (procname)
8232 {
8233 fputs (" <", stdout);
8234 fputs (procname, stdout);
8235 fputc ('>', stdout);
8236 }
8237 }
8238 else
8239 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
8240 fputc ('\n', stdout);
8241
8242 /* The GCC personality routines use the standard compact
8243 encoding, starting with one byte giving the number of
8244 words. */
8245 if (procname != NULL
8246 && (const_strneq (procname, "__gcc_personality_v0")
8247 || const_strneq (procname, "__gxx_personality_v0")
8248 || const_strneq (procname, "__gcj_personality_v0")
8249 || const_strneq (procname, "__gnu_objc_personality_v0")))
8250 {
8251 remaining = 0;
8252 more_words = 1;
8253 ADVANCE;
8254 if (!remaining)
8255 {
8256 printf (_(" [Truncated data]\n"));
8257 return;
8258 }
8259 more_words = word >> 24;
8260 word <<= 8;
8261 remaining--;
8262 per_index = -1;
8263 }
8264 else
8265 return;
8266 }
8267 else
8268 {
1b31d05e 8269 /* ARM EHABI Section 6.3:
0b4362b0 8270
1b31d05e 8271 An exception-handling table entry for the compact model looks like:
0b4362b0 8272
1b31d05e
NC
8273 31 30-28 27-24 23-0
8274 -- ----- ----- ----
8275 1 0 index Data for personalityRoutine[index] */
8276
8277 if (elf_header.e_machine == EM_ARM
8278 && (word & 0x70000000))
83c257ca 8279 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 8280
fa197c1c 8281 per_index = (word >> 24) & 0x7f;
1b31d05e 8282 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
8283 if (per_index == 0)
8284 {
8285 more_words = 0;
8286 word <<= 8;
8287 remaining--;
8288 }
8289 else if (per_index < 3)
8290 {
8291 more_words = (word >> 16) & 0xff;
8292 word <<= 16;
8293 remaining -= 2;
8294 }
8295 }
8296
8297 switch (elf_header.e_machine)
8298 {
8299 case EM_ARM:
8300 if (per_index < 3)
8301 {
8302 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
8303 data_offset, data_sec, data_arm_sec);
8304 }
8305 else
1b31d05e
NC
8306 {
8307 warn (_("Unknown ARM compact model index encountered\n"));
8308 printf (_(" [reserved]\n"));
8309 }
fa197c1c
PB
8310 break;
8311
8312 case EM_TI_C6000:
8313 if (per_index < 3)
8314 {
8315 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 8316 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
8317 }
8318 else if (per_index < 5)
8319 {
8320 if (((word >> 17) & 0x7f) == 0x7f)
8321 printf (_(" Restore stack from frame pointer\n"));
8322 else
8323 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
8324 printf (_(" Registers restored: "));
8325 if (per_index == 4)
8326 printf (" (compact) ");
8327 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
8328 putchar ('\n');
8329 printf (_(" Return register: %s\n"),
8330 tic6x_unwind_regnames[word & 0xf]);
8331 }
8332 else
1b31d05e 8333 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
8334 break;
8335
8336 default:
74e1a04b 8337 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
1b31d05e 8338 elf_header.e_machine);
fa197c1c 8339 }
0b6ae522
DJ
8340
8341 /* Decode the descriptors. Not implemented. */
8342}
8343
8344static void
8345dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
8346{
8347 struct arm_section exidx_arm_sec, extab_arm_sec;
8348 unsigned int i, exidx_len;
948f632f 8349 unsigned long j, nfuns;
0b6ae522
DJ
8350
8351 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
8352 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
8353 exidx_len = exidx_sec->sh_size / 8;
8354
948f632f
DA
8355 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8356 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8357 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8358 aux->funtab[nfuns++] = aux->symtab[j];
8359 aux->nfuns = nfuns;
8360 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8361
0b6ae522
DJ
8362 for (i = 0; i < exidx_len; i++)
8363 {
8364 unsigned int exidx_fn, exidx_entry;
8365 struct absaddr fn_addr, entry_addr;
8366 bfd_vma fn;
8367
8368 fputc ('\n', stdout);
8369
1b31d05e
NC
8370 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8371 8 * i, & exidx_fn, & fn_addr, NULL)
8372 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8373 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 8374 {
948f632f 8375 free (aux->funtab);
1b31d05e
NC
8376 arm_free_section (& exidx_arm_sec);
8377 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
8378 return;
8379 }
8380
83c257ca
NC
8381 /* ARM EHABI, Section 5:
8382 An index table entry consists of 2 words.
8383 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
8384 if (exidx_fn & 0x80000000)
8385 warn (_("corrupt index table entry: %x\n"), exidx_fn);
8386
a734115a 8387 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 8388
a734115a 8389 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
8390 fputs (": ", stdout);
8391
8392 if (exidx_entry == 1)
8393 {
8394 print_vma (exidx_entry, PREFIX_HEX);
8395 fputs (" [cantunwind]\n", stdout);
8396 }
8397 else if (exidx_entry & 0x80000000)
8398 {
8399 print_vma (exidx_entry, PREFIX_HEX);
8400 fputc ('\n', stdout);
8401 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
8402 }
8403 else
8404 {
8f73510c 8405 bfd_vma table, table_offset = 0;
0b6ae522
DJ
8406 Elf_Internal_Shdr *table_sec;
8407
8408 fputs ("@", stdout);
a734115a 8409 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
8410 print_vma (table, PREFIX_HEX);
8411 printf ("\n");
8412
8413 /* Locate the matching .ARM.extab. */
8414 if (entry_addr.section != SHN_UNDEF
8415 && entry_addr.section < elf_header.e_shnum)
8416 {
8417 table_sec = section_headers + entry_addr.section;
8418 table_offset = entry_addr.offset;
1a915552
NC
8419 /* PR 18879 */
8420 if (table_offset > table_sec->sh_size
8421 || ((bfd_signed_vma) table_offset) < 0)
8422 {
8423 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
8424 (unsigned long) table_offset,
8425 printable_section_name (table_sec));
8426 continue;
8427 }
0b6ae522
DJ
8428 }
8429 else
8430 {
8431 table_sec = find_section_by_address (table);
8432 if (table_sec != NULL)
8433 table_offset = table - table_sec->sh_addr;
8434 }
8435 if (table_sec == NULL)
8436 {
8437 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
8438 (unsigned long) table);
8439 continue;
8440 }
8441 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
8442 &extab_arm_sec);
8443 }
8444 }
8445
8446 printf ("\n");
8447
948f632f 8448 free (aux->funtab);
0b6ae522
DJ
8449 arm_free_section (&exidx_arm_sec);
8450 arm_free_section (&extab_arm_sec);
8451}
8452
fa197c1c 8453/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
8454
8455static void
0b6ae522
DJ
8456arm_process_unwind (FILE *file)
8457{
8458 struct arm_unw_aux_info aux;
8459 Elf_Internal_Shdr *unwsec = NULL;
8460 Elf_Internal_Shdr *strsec;
8461 Elf_Internal_Shdr *sec;
8462 unsigned long i;
fa197c1c 8463 unsigned int sec_type;
0b6ae522 8464
fa197c1c
PB
8465 switch (elf_header.e_machine)
8466 {
8467 case EM_ARM:
8468 sec_type = SHT_ARM_EXIDX;
8469 break;
8470
8471 case EM_TI_C6000:
8472 sec_type = SHT_C6000_UNWIND;
8473 break;
8474
0b4362b0 8475 default:
74e1a04b 8476 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
1b31d05e
NC
8477 elf_header.e_machine);
8478 return;
fa197c1c
PB
8479 }
8480
0b6ae522 8481 if (string_table == NULL)
1b31d05e
NC
8482 return;
8483
8484 memset (& aux, 0, sizeof (aux));
8485 aux.file = file;
0b6ae522
DJ
8486
8487 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8488 {
8489 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
8490 {
ba5cdace 8491 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
8492
8493 strsec = section_headers + sec->sh_link;
74e1a04b
NC
8494
8495 /* PR binutils/17531 file: 011-12666-0.004. */
8496 if (aux.strtab != NULL)
8497 {
4082ef84 8498 error (_("Multiple string tables found in file.\n"));
74e1a04b
NC
8499 free (aux.strtab);
8500 }
0b6ae522
DJ
8501 aux.strtab = get_data (NULL, file, strsec->sh_offset,
8502 1, strsec->sh_size, _("string table"));
8503 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
8504 }
fa197c1c 8505 else if (sec->sh_type == sec_type)
0b6ae522
DJ
8506 unwsec = sec;
8507 }
8508
1b31d05e 8509 if (unwsec == NULL)
0b6ae522 8510 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
8511 else
8512 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8513 {
8514 if (sec->sh_type == sec_type)
8515 {
8516 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
74e1a04b 8517 printable_section_name (sec),
1b31d05e
NC
8518 (unsigned long) sec->sh_offset,
8519 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 8520
1b31d05e
NC
8521 dump_arm_unwind (&aux, sec);
8522 }
8523 }
0b6ae522
DJ
8524
8525 if (aux.symtab)
8526 free (aux.symtab);
8527 if (aux.strtab)
8528 free ((char *) aux.strtab);
0b6ae522
DJ
8529}
8530
1b31d05e 8531static void
2cf0635d 8532process_unwind (FILE * file)
57346661 8533{
2cf0635d
NC
8534 struct unwind_handler
8535 {
57346661 8536 int machtype;
1b31d05e 8537 void (* handler)(FILE *);
2cf0635d
NC
8538 } handlers[] =
8539 {
0b6ae522 8540 { EM_ARM, arm_process_unwind },
57346661
AM
8541 { EM_IA_64, ia64_process_unwind },
8542 { EM_PARISC, hppa_process_unwind },
fa197c1c 8543 { EM_TI_C6000, arm_process_unwind },
57346661
AM
8544 { 0, 0 }
8545 };
8546 int i;
8547
8548 if (!do_unwind)
1b31d05e 8549 return;
57346661
AM
8550
8551 for (i = 0; handlers[i].handler != NULL; i++)
8552 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
8553 {
8554 handlers[i].handler (file);
8555 return;
8556 }
57346661 8557
1b31d05e
NC
8558 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
8559 get_machine_name (elf_header.e_machine));
57346661
AM
8560}
8561
252b5132 8562static void
2cf0635d 8563dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
8564{
8565 switch (entry->d_tag)
8566 {
8567 case DT_MIPS_FLAGS:
8568 if (entry->d_un.d_val == 0)
4b68bca3 8569 printf (_("NONE"));
252b5132
RH
8570 else
8571 {
8572 static const char * opts[] =
8573 {
8574 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
8575 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
8576 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
8577 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
8578 "RLD_ORDER_SAFE"
8579 };
8580 unsigned int cnt;
8581 int first = 1;
2b692964 8582
60bca95a 8583 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
8584 if (entry->d_un.d_val & (1 << cnt))
8585 {
8586 printf ("%s%s", first ? "" : " ", opts[cnt]);
8587 first = 0;
8588 }
252b5132
RH
8589 }
8590 break;
103f02d3 8591
252b5132 8592 case DT_MIPS_IVERSION:
d79b3d50 8593 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 8594 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8595 else
76ca31c0
NC
8596 {
8597 char buf[40];
8598 sprintf_vma (buf, entry->d_un.d_ptr);
8599 /* Note: coded this way so that there is a single string for translation. */
8600 printf (_("<corrupt: %s>"), buf);
8601 }
252b5132 8602 break;
103f02d3 8603
252b5132
RH
8604 case DT_MIPS_TIME_STAMP:
8605 {
8606 char timebuf[20];
2cf0635d 8607 struct tm * tmp;
91d6fa6a 8608 time_t atime = entry->d_un.d_val;
82b1b41b 8609
91d6fa6a 8610 tmp = gmtime (&atime);
82b1b41b
NC
8611 /* PR 17531: file: 6accc532. */
8612 if (tmp == NULL)
8613 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
8614 else
8615 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
8616 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8617 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 8618 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
8619 }
8620 break;
103f02d3 8621
252b5132
RH
8622 case DT_MIPS_RLD_VERSION:
8623 case DT_MIPS_LOCAL_GOTNO:
8624 case DT_MIPS_CONFLICTNO:
8625 case DT_MIPS_LIBLISTNO:
8626 case DT_MIPS_SYMTABNO:
8627 case DT_MIPS_UNREFEXTNO:
8628 case DT_MIPS_HIPAGENO:
8629 case DT_MIPS_DELTA_CLASS_NO:
8630 case DT_MIPS_DELTA_INSTANCE_NO:
8631 case DT_MIPS_DELTA_RELOC_NO:
8632 case DT_MIPS_DELTA_SYM_NO:
8633 case DT_MIPS_DELTA_CLASSSYM_NO:
8634 case DT_MIPS_COMPACT_SIZE:
4b68bca3 8635 print_vma (entry->d_un.d_ptr, DEC);
252b5132 8636 break;
103f02d3
UD
8637
8638 default:
4b68bca3 8639 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 8640 }
4b68bca3 8641 putchar ('\n');
103f02d3
UD
8642}
8643
103f02d3 8644static void
2cf0635d 8645dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
8646{
8647 switch (entry->d_tag)
8648 {
8649 case DT_HP_DLD_FLAGS:
8650 {
8651 static struct
8652 {
8653 long int bit;
2cf0635d 8654 const char * str;
5e220199
NC
8655 }
8656 flags[] =
8657 {
8658 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
8659 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
8660 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
8661 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
8662 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
8663 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
8664 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
8665 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
8666 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
8667 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
8668 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
8669 { DT_HP_GST, "HP_GST" },
8670 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
8671 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
8672 { DT_HP_NODELETE, "HP_NODELETE" },
8673 { DT_HP_GROUP, "HP_GROUP" },
8674 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 8675 };
103f02d3 8676 int first = 1;
5e220199 8677 size_t cnt;
f7a99963 8678 bfd_vma val = entry->d_un.d_val;
103f02d3 8679
60bca95a 8680 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 8681 if (val & flags[cnt].bit)
30800947
NC
8682 {
8683 if (! first)
8684 putchar (' ');
8685 fputs (flags[cnt].str, stdout);
8686 first = 0;
8687 val ^= flags[cnt].bit;
8688 }
76da6bbe 8689
103f02d3 8690 if (val != 0 || first)
f7a99963
NC
8691 {
8692 if (! first)
8693 putchar (' ');
8694 print_vma (val, HEX);
8695 }
103f02d3
UD
8696 }
8697 break;
76da6bbe 8698
252b5132 8699 default:
f7a99963
NC
8700 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8701 break;
252b5132 8702 }
35b1837e 8703 putchar ('\n');
252b5132
RH
8704}
8705
28f997cf
TG
8706#ifdef BFD64
8707
8708/* VMS vs Unix time offset and factor. */
8709
8710#define VMS_EPOCH_OFFSET 35067168000000000LL
8711#define VMS_GRANULARITY_FACTOR 10000000
8712
8713/* Display a VMS time in a human readable format. */
8714
8715static void
8716print_vms_time (bfd_int64_t vmstime)
8717{
8718 struct tm *tm;
8719 time_t unxtime;
8720
8721 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
8722 tm = gmtime (&unxtime);
8723 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
8724 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
8725 tm->tm_hour, tm->tm_min, tm->tm_sec);
8726}
8727#endif /* BFD64 */
8728
ecc51f48 8729static void
2cf0635d 8730dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
8731{
8732 switch (entry->d_tag)
8733 {
0de14b54 8734 case DT_IA_64_PLT_RESERVE:
bdf4d63a 8735 /* First 3 slots reserved. */
ecc51f48
NC
8736 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8737 printf (" -- ");
8738 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
8739 break;
8740
28f997cf
TG
8741 case DT_IA_64_VMS_LINKTIME:
8742#ifdef BFD64
8743 print_vms_time (entry->d_un.d_val);
8744#endif
8745 break;
8746
8747 case DT_IA_64_VMS_LNKFLAGS:
8748 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8749 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
8750 printf (" CALL_DEBUG");
8751 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
8752 printf (" NOP0BUFS");
8753 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
8754 printf (" P0IMAGE");
8755 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
8756 printf (" MKTHREADS");
8757 if (entry->d_un.d_val & VMS_LF_UPCALLS)
8758 printf (" UPCALLS");
8759 if (entry->d_un.d_val & VMS_LF_IMGSTA)
8760 printf (" IMGSTA");
8761 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
8762 printf (" INITIALIZE");
8763 if (entry->d_un.d_val & VMS_LF_MAIN)
8764 printf (" MAIN");
8765 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
8766 printf (" EXE_INIT");
8767 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
8768 printf (" TBK_IN_IMG");
8769 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
8770 printf (" DBG_IN_IMG");
8771 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
8772 printf (" TBK_IN_DSF");
8773 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
8774 printf (" DBG_IN_DSF");
8775 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
8776 printf (" SIGNATURES");
8777 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
8778 printf (" REL_SEG_OFF");
8779 break;
8780
bdf4d63a
JJ
8781 default:
8782 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8783 break;
ecc51f48 8784 }
bdf4d63a 8785 putchar ('\n');
ecc51f48
NC
8786}
8787
252b5132 8788static int
2cf0635d 8789get_32bit_dynamic_section (FILE * file)
252b5132 8790{
2cf0635d
NC
8791 Elf32_External_Dyn * edyn;
8792 Elf32_External_Dyn * ext;
8793 Elf_Internal_Dyn * entry;
103f02d3 8794
3f5e193b
NC
8795 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8796 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8797 if (!edyn)
8798 return 0;
103f02d3 8799
071436c6
NC
8800 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8801 might not have the luxury of section headers. Look for the DT_NULL
8802 terminator to determine the number of entries. */
ba2685cc 8803 for (ext = edyn, dynamic_nent = 0;
53c3012c 8804 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
8805 ext++)
8806 {
8807 dynamic_nent++;
8808 if (BYTE_GET (ext->d_tag) == DT_NULL)
8809 break;
8810 }
252b5132 8811
3f5e193b
NC
8812 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8813 sizeof (* entry));
b2d38a17 8814 if (dynamic_section == NULL)
252b5132 8815 {
8b73c356
NC
8816 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8817 (unsigned long) dynamic_nent);
9ea033b2
NC
8818 free (edyn);
8819 return 0;
8820 }
252b5132 8821
fb514b26 8822 for (ext = edyn, entry = dynamic_section;
ba2685cc 8823 entry < dynamic_section + dynamic_nent;
fb514b26 8824 ext++, entry++)
9ea033b2 8825 {
fb514b26
AM
8826 entry->d_tag = BYTE_GET (ext->d_tag);
8827 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8828 }
8829
9ea033b2
NC
8830 free (edyn);
8831
8832 return 1;
8833}
8834
8835static int
2cf0635d 8836get_64bit_dynamic_section (FILE * file)
9ea033b2 8837{
2cf0635d
NC
8838 Elf64_External_Dyn * edyn;
8839 Elf64_External_Dyn * ext;
8840 Elf_Internal_Dyn * entry;
103f02d3 8841
071436c6 8842 /* Read in the data. */
3f5e193b
NC
8843 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8844 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8845 if (!edyn)
8846 return 0;
103f02d3 8847
071436c6
NC
8848 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8849 might not have the luxury of section headers. Look for the DT_NULL
8850 terminator to determine the number of entries. */
ba2685cc 8851 for (ext = edyn, dynamic_nent = 0;
53c3012c
AM
8852 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
8853 (char *) (ext + 1) <= (char *) edyn + dynamic_size;
ba2685cc
AM
8854 ext++)
8855 {
8856 dynamic_nent++;
66543521 8857 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
8858 break;
8859 }
252b5132 8860
3f5e193b
NC
8861 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8862 sizeof (* entry));
b2d38a17 8863 if (dynamic_section == NULL)
252b5132 8864 {
8b73c356
NC
8865 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8866 (unsigned long) dynamic_nent);
252b5132
RH
8867 free (edyn);
8868 return 0;
8869 }
8870
071436c6 8871 /* Convert from external to internal formats. */
fb514b26 8872 for (ext = edyn, entry = dynamic_section;
ba2685cc 8873 entry < dynamic_section + dynamic_nent;
fb514b26 8874 ext++, entry++)
252b5132 8875 {
66543521
AM
8876 entry->d_tag = BYTE_GET (ext->d_tag);
8877 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8878 }
8879
8880 free (edyn);
8881
9ea033b2
NC
8882 return 1;
8883}
8884
e9e44622
JJ
8885static void
8886print_dynamic_flags (bfd_vma flags)
d1133906 8887{
e9e44622 8888 int first = 1;
13ae64f3 8889
d1133906
NC
8890 while (flags)
8891 {
8892 bfd_vma flag;
8893
8894 flag = flags & - flags;
8895 flags &= ~ flag;
8896
e9e44622
JJ
8897 if (first)
8898 first = 0;
8899 else
8900 putc (' ', stdout);
13ae64f3 8901
d1133906
NC
8902 switch (flag)
8903 {
e9e44622
JJ
8904 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
8905 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
8906 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
8907 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
8908 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 8909 default: fputs (_("unknown"), stdout); break;
d1133906
NC
8910 }
8911 }
e9e44622 8912 puts ("");
d1133906
NC
8913}
8914
b2d38a17
NC
8915/* Parse and display the contents of the dynamic section. */
8916
9ea033b2 8917static int
2cf0635d 8918process_dynamic_section (FILE * file)
9ea033b2 8919{
2cf0635d 8920 Elf_Internal_Dyn * entry;
9ea033b2
NC
8921
8922 if (dynamic_size == 0)
8923 {
8924 if (do_dynamic)
b2d38a17 8925 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
8926
8927 return 1;
8928 }
8929
8930 if (is_32bit_elf)
8931 {
b2d38a17 8932 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
8933 return 0;
8934 }
b2d38a17 8935 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
8936 return 0;
8937
252b5132
RH
8938 /* Find the appropriate symbol table. */
8939 if (dynamic_symbols == NULL)
8940 {
86dba8ee
AM
8941 for (entry = dynamic_section;
8942 entry < dynamic_section + dynamic_nent;
8943 ++entry)
252b5132 8944 {
c8286bd1 8945 Elf_Internal_Shdr section;
252b5132
RH
8946
8947 if (entry->d_tag != DT_SYMTAB)
8948 continue;
8949
8950 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
8951
8952 /* Since we do not know how big the symbol table is,
8953 we default to reading in the entire file (!) and
8954 processing that. This is overkill, I know, but it
e3c8793a 8955 should work. */
d93f0186 8956 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 8957
fb52b2f4
NC
8958 if (archive_file_offset != 0)
8959 section.sh_size = archive_file_size - section.sh_offset;
8960 else
8961 {
8962 if (fseek (file, 0, SEEK_END))
591a748a 8963 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
8964
8965 section.sh_size = ftell (file) - section.sh_offset;
8966 }
252b5132 8967
9ea033b2 8968 if (is_32bit_elf)
9ad5cbcf 8969 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 8970 else
9ad5cbcf 8971 section.sh_entsize = sizeof (Elf64_External_Sym);
071436c6 8972 section.sh_name = string_table_length;
252b5132 8973
ba5cdace 8974 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 8975 if (num_dynamic_syms < 1)
252b5132
RH
8976 {
8977 error (_("Unable to determine the number of symbols to load\n"));
8978 continue;
8979 }
252b5132
RH
8980 }
8981 }
8982
8983 /* Similarly find a string table. */
8984 if (dynamic_strings == NULL)
8985 {
86dba8ee
AM
8986 for (entry = dynamic_section;
8987 entry < dynamic_section + dynamic_nent;
8988 ++entry)
252b5132
RH
8989 {
8990 unsigned long offset;
b34976b6 8991 long str_tab_len;
252b5132
RH
8992
8993 if (entry->d_tag != DT_STRTAB)
8994 continue;
8995
8996 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
8997
8998 /* Since we do not know how big the string table is,
8999 we default to reading in the entire file (!) and
9000 processing that. This is overkill, I know, but it
e3c8793a 9001 should work. */
252b5132 9002
d93f0186 9003 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
9004
9005 if (archive_file_offset != 0)
9006 str_tab_len = archive_file_size - offset;
9007 else
9008 {
9009 if (fseek (file, 0, SEEK_END))
9010 error (_("Unable to seek to end of file\n"));
9011 str_tab_len = ftell (file) - offset;
9012 }
252b5132
RH
9013
9014 if (str_tab_len < 1)
9015 {
9016 error
9017 (_("Unable to determine the length of the dynamic string table\n"));
9018 continue;
9019 }
9020
3f5e193b
NC
9021 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
9022 str_tab_len,
9023 _("dynamic string table"));
59245841 9024 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
9025 break;
9026 }
9027 }
9028
9029 /* And find the syminfo section if available. */
9030 if (dynamic_syminfo == NULL)
9031 {
3e8bba36 9032 unsigned long syminsz = 0;
252b5132 9033
86dba8ee
AM
9034 for (entry = dynamic_section;
9035 entry < dynamic_section + dynamic_nent;
9036 ++entry)
252b5132
RH
9037 {
9038 if (entry->d_tag == DT_SYMINENT)
9039 {
9040 /* Note: these braces are necessary to avoid a syntax
9041 error from the SunOS4 C compiler. */
049b0c3a
NC
9042 /* PR binutils/17531: A corrupt file can trigger this test.
9043 So do not use an assert, instead generate an error message. */
9044 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 9045 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 9046 (int) entry->d_un.d_val);
252b5132
RH
9047 }
9048 else if (entry->d_tag == DT_SYMINSZ)
9049 syminsz = entry->d_un.d_val;
9050 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
9051 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
9052 syminsz);
252b5132
RH
9053 }
9054
9055 if (dynamic_syminfo_offset != 0 && syminsz != 0)
9056 {
2cf0635d
NC
9057 Elf_External_Syminfo * extsyminfo;
9058 Elf_External_Syminfo * extsym;
9059 Elf_Internal_Syminfo * syminfo;
252b5132
RH
9060
9061 /* There is a syminfo section. Read the data. */
3f5e193b
NC
9062 extsyminfo = (Elf_External_Syminfo *)
9063 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
9064 _("symbol information"));
a6e9f9df
AM
9065 if (!extsyminfo)
9066 return 0;
252b5132 9067
3f5e193b 9068 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
9069 if (dynamic_syminfo == NULL)
9070 {
8b73c356
NC
9071 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
9072 (unsigned long) syminsz);
252b5132
RH
9073 return 0;
9074 }
9075
9076 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
9077 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
9078 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
9079 ++syminfo, ++extsym)
252b5132 9080 {
86dba8ee
AM
9081 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
9082 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
9083 }
9084
9085 free (extsyminfo);
9086 }
9087 }
9088
9089 if (do_dynamic && dynamic_addr)
8b73c356
NC
9090 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
9091 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
9092 if (do_dynamic)
9093 printf (_(" Tag Type Name/Value\n"));
9094
86dba8ee
AM
9095 for (entry = dynamic_section;
9096 entry < dynamic_section + dynamic_nent;
9097 entry++)
252b5132
RH
9098 {
9099 if (do_dynamic)
f7a99963 9100 {
2cf0635d 9101 const char * dtype;
e699b9ff 9102
f7a99963
NC
9103 putchar (' ');
9104 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
9105 dtype = get_dynamic_type (entry->d_tag);
9106 printf (" (%s)%*s", dtype,
9107 ((is_32bit_elf ? 27 : 19)
9108 - (int) strlen (dtype)),
f7a99963
NC
9109 " ");
9110 }
252b5132
RH
9111
9112 switch (entry->d_tag)
9113 {
d1133906
NC
9114 case DT_FLAGS:
9115 if (do_dynamic)
e9e44622 9116 print_dynamic_flags (entry->d_un.d_val);
d1133906 9117 break;
76da6bbe 9118
252b5132
RH
9119 case DT_AUXILIARY:
9120 case DT_FILTER:
019148e4
L
9121 case DT_CONFIG:
9122 case DT_DEPAUDIT:
9123 case DT_AUDIT:
252b5132
RH
9124 if (do_dynamic)
9125 {
019148e4 9126 switch (entry->d_tag)
b34976b6 9127 {
019148e4
L
9128 case DT_AUXILIARY:
9129 printf (_("Auxiliary library"));
9130 break;
9131
9132 case DT_FILTER:
9133 printf (_("Filter library"));
9134 break;
9135
b34976b6 9136 case DT_CONFIG:
019148e4
L
9137 printf (_("Configuration file"));
9138 break;
9139
9140 case DT_DEPAUDIT:
9141 printf (_("Dependency audit library"));
9142 break;
9143
9144 case DT_AUDIT:
9145 printf (_("Audit library"));
9146 break;
9147 }
252b5132 9148
d79b3d50
NC
9149 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9150 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 9151 else
f7a99963
NC
9152 {
9153 printf (": ");
9154 print_vma (entry->d_un.d_val, PREFIX_HEX);
9155 putchar ('\n');
9156 }
252b5132
RH
9157 }
9158 break;
9159
dcefbbbd 9160 case DT_FEATURE:
252b5132
RH
9161 if (do_dynamic)
9162 {
9163 printf (_("Flags:"));
86f55779 9164
252b5132
RH
9165 if (entry->d_un.d_val == 0)
9166 printf (_(" None\n"));
9167 else
9168 {
9169 unsigned long int val = entry->d_un.d_val;
86f55779 9170
252b5132
RH
9171 if (val & DTF_1_PARINIT)
9172 {
9173 printf (" PARINIT");
9174 val ^= DTF_1_PARINIT;
9175 }
dcefbbbd
L
9176 if (val & DTF_1_CONFEXP)
9177 {
9178 printf (" CONFEXP");
9179 val ^= DTF_1_CONFEXP;
9180 }
252b5132
RH
9181 if (val != 0)
9182 printf (" %lx", val);
9183 puts ("");
9184 }
9185 }
9186 break;
9187
9188 case DT_POSFLAG_1:
9189 if (do_dynamic)
9190 {
9191 printf (_("Flags:"));
86f55779 9192
252b5132
RH
9193 if (entry->d_un.d_val == 0)
9194 printf (_(" None\n"));
9195 else
9196 {
9197 unsigned long int val = entry->d_un.d_val;
86f55779 9198
252b5132
RH
9199 if (val & DF_P1_LAZYLOAD)
9200 {
9201 printf (" LAZYLOAD");
9202 val ^= DF_P1_LAZYLOAD;
9203 }
9204 if (val & DF_P1_GROUPPERM)
9205 {
9206 printf (" GROUPPERM");
9207 val ^= DF_P1_GROUPPERM;
9208 }
9209 if (val != 0)
9210 printf (" %lx", val);
9211 puts ("");
9212 }
9213 }
9214 break;
9215
9216 case DT_FLAGS_1:
9217 if (do_dynamic)
9218 {
9219 printf (_("Flags:"));
9220 if (entry->d_un.d_val == 0)
9221 printf (_(" None\n"));
9222 else
9223 {
9224 unsigned long int val = entry->d_un.d_val;
86f55779 9225
252b5132
RH
9226 if (val & DF_1_NOW)
9227 {
9228 printf (" NOW");
9229 val ^= DF_1_NOW;
9230 }
9231 if (val & DF_1_GLOBAL)
9232 {
9233 printf (" GLOBAL");
9234 val ^= DF_1_GLOBAL;
9235 }
9236 if (val & DF_1_GROUP)
9237 {
9238 printf (" GROUP");
9239 val ^= DF_1_GROUP;
9240 }
9241 if (val & DF_1_NODELETE)
9242 {
9243 printf (" NODELETE");
9244 val ^= DF_1_NODELETE;
9245 }
9246 if (val & DF_1_LOADFLTR)
9247 {
9248 printf (" LOADFLTR");
9249 val ^= DF_1_LOADFLTR;
9250 }
9251 if (val & DF_1_INITFIRST)
9252 {
9253 printf (" INITFIRST");
9254 val ^= DF_1_INITFIRST;
9255 }
9256 if (val & DF_1_NOOPEN)
9257 {
9258 printf (" NOOPEN");
9259 val ^= DF_1_NOOPEN;
9260 }
9261 if (val & DF_1_ORIGIN)
9262 {
9263 printf (" ORIGIN");
9264 val ^= DF_1_ORIGIN;
9265 }
9266 if (val & DF_1_DIRECT)
9267 {
9268 printf (" DIRECT");
9269 val ^= DF_1_DIRECT;
9270 }
9271 if (val & DF_1_TRANS)
9272 {
9273 printf (" TRANS");
9274 val ^= DF_1_TRANS;
9275 }
9276 if (val & DF_1_INTERPOSE)
9277 {
9278 printf (" INTERPOSE");
9279 val ^= DF_1_INTERPOSE;
9280 }
f7db6139 9281 if (val & DF_1_NODEFLIB)
dcefbbbd 9282 {
f7db6139
L
9283 printf (" NODEFLIB");
9284 val ^= DF_1_NODEFLIB;
dcefbbbd
L
9285 }
9286 if (val & DF_1_NODUMP)
9287 {
9288 printf (" NODUMP");
9289 val ^= DF_1_NODUMP;
9290 }
34b60028 9291 if (val & DF_1_CONFALT)
dcefbbbd 9292 {
34b60028
L
9293 printf (" CONFALT");
9294 val ^= DF_1_CONFALT;
9295 }
9296 if (val & DF_1_ENDFILTEE)
9297 {
9298 printf (" ENDFILTEE");
9299 val ^= DF_1_ENDFILTEE;
9300 }
9301 if (val & DF_1_DISPRELDNE)
9302 {
9303 printf (" DISPRELDNE");
9304 val ^= DF_1_DISPRELDNE;
9305 }
9306 if (val & DF_1_DISPRELPND)
9307 {
9308 printf (" DISPRELPND");
9309 val ^= DF_1_DISPRELPND;
9310 }
9311 if (val & DF_1_NODIRECT)
9312 {
9313 printf (" NODIRECT");
9314 val ^= DF_1_NODIRECT;
9315 }
9316 if (val & DF_1_IGNMULDEF)
9317 {
9318 printf (" IGNMULDEF");
9319 val ^= DF_1_IGNMULDEF;
9320 }
9321 if (val & DF_1_NOKSYMS)
9322 {
9323 printf (" NOKSYMS");
9324 val ^= DF_1_NOKSYMS;
9325 }
9326 if (val & DF_1_NOHDR)
9327 {
9328 printf (" NOHDR");
9329 val ^= DF_1_NOHDR;
9330 }
9331 if (val & DF_1_EDITED)
9332 {
9333 printf (" EDITED");
9334 val ^= DF_1_EDITED;
9335 }
9336 if (val & DF_1_NORELOC)
9337 {
9338 printf (" NORELOC");
9339 val ^= DF_1_NORELOC;
9340 }
9341 if (val & DF_1_SYMINTPOSE)
9342 {
9343 printf (" SYMINTPOSE");
9344 val ^= DF_1_SYMINTPOSE;
9345 }
9346 if (val & DF_1_GLOBAUDIT)
9347 {
9348 printf (" GLOBAUDIT");
9349 val ^= DF_1_GLOBAUDIT;
9350 }
9351 if (val & DF_1_SINGLETON)
9352 {
9353 printf (" SINGLETON");
9354 val ^= DF_1_SINGLETON;
dcefbbbd 9355 }
5c383f02
RO
9356 if (val & DF_1_STUB)
9357 {
9358 printf (" STUB");
9359 val ^= DF_1_STUB;
9360 }
9361 if (val & DF_1_PIE)
9362 {
9363 printf (" PIE");
9364 val ^= DF_1_PIE;
9365 }
252b5132
RH
9366 if (val != 0)
9367 printf (" %lx", val);
9368 puts ("");
9369 }
9370 }
9371 break;
9372
9373 case DT_PLTREL:
566b0d53 9374 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9375 if (do_dynamic)
9376 puts (get_dynamic_type (entry->d_un.d_val));
9377 break;
9378
9379 case DT_NULL :
9380 case DT_NEEDED :
9381 case DT_PLTGOT :
9382 case DT_HASH :
9383 case DT_STRTAB :
9384 case DT_SYMTAB :
9385 case DT_RELA :
9386 case DT_INIT :
9387 case DT_FINI :
9388 case DT_SONAME :
9389 case DT_RPATH :
9390 case DT_SYMBOLIC:
9391 case DT_REL :
9392 case DT_DEBUG :
9393 case DT_TEXTREL :
9394 case DT_JMPREL :
019148e4 9395 case DT_RUNPATH :
252b5132
RH
9396 dynamic_info[entry->d_tag] = entry->d_un.d_val;
9397
9398 if (do_dynamic)
9399 {
2cf0635d 9400 char * name;
252b5132 9401
d79b3d50
NC
9402 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9403 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9404 else
d79b3d50 9405 name = NULL;
252b5132
RH
9406
9407 if (name)
9408 {
9409 switch (entry->d_tag)
9410 {
9411 case DT_NEEDED:
9412 printf (_("Shared library: [%s]"), name);
9413
18bd398b 9414 if (streq (name, program_interpreter))
f7a99963 9415 printf (_(" program interpreter"));
252b5132
RH
9416 break;
9417
9418 case DT_SONAME:
f7a99963 9419 printf (_("Library soname: [%s]"), name);
252b5132
RH
9420 break;
9421
9422 case DT_RPATH:
f7a99963 9423 printf (_("Library rpath: [%s]"), name);
252b5132
RH
9424 break;
9425
019148e4
L
9426 case DT_RUNPATH:
9427 printf (_("Library runpath: [%s]"), name);
9428 break;
9429
252b5132 9430 default:
f7a99963
NC
9431 print_vma (entry->d_un.d_val, PREFIX_HEX);
9432 break;
252b5132
RH
9433 }
9434 }
9435 else
f7a99963
NC
9436 print_vma (entry->d_un.d_val, PREFIX_HEX);
9437
9438 putchar ('\n');
252b5132
RH
9439 }
9440 break;
9441
9442 case DT_PLTRELSZ:
9443 case DT_RELASZ :
9444 case DT_STRSZ :
9445 case DT_RELSZ :
9446 case DT_RELAENT :
9447 case DT_SYMENT :
9448 case DT_RELENT :
566b0d53 9449 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9450 case DT_PLTPADSZ:
9451 case DT_MOVEENT :
9452 case DT_MOVESZ :
9453 case DT_INIT_ARRAYSZ:
9454 case DT_FINI_ARRAYSZ:
047b2264
JJ
9455 case DT_GNU_CONFLICTSZ:
9456 case DT_GNU_LIBLISTSZ:
252b5132 9457 if (do_dynamic)
f7a99963
NC
9458 {
9459 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 9460 printf (_(" (bytes)\n"));
f7a99963 9461 }
252b5132
RH
9462 break;
9463
9464 case DT_VERDEFNUM:
9465 case DT_VERNEEDNUM:
9466 case DT_RELACOUNT:
9467 case DT_RELCOUNT:
9468 if (do_dynamic)
f7a99963
NC
9469 {
9470 print_vma (entry->d_un.d_val, UNSIGNED);
9471 putchar ('\n');
9472 }
252b5132
RH
9473 break;
9474
9475 case DT_SYMINSZ:
9476 case DT_SYMINENT:
9477 case DT_SYMINFO:
9478 case DT_USED:
9479 case DT_INIT_ARRAY:
9480 case DT_FINI_ARRAY:
9481 if (do_dynamic)
9482 {
d79b3d50
NC
9483 if (entry->d_tag == DT_USED
9484 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 9485 {
2cf0635d 9486 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9487
b34976b6 9488 if (*name)
252b5132
RH
9489 {
9490 printf (_("Not needed object: [%s]\n"), name);
9491 break;
9492 }
9493 }
103f02d3 9494
f7a99963
NC
9495 print_vma (entry->d_un.d_val, PREFIX_HEX);
9496 putchar ('\n');
252b5132
RH
9497 }
9498 break;
9499
9500 case DT_BIND_NOW:
9501 /* The value of this entry is ignored. */
35b1837e
AM
9502 if (do_dynamic)
9503 putchar ('\n');
252b5132 9504 break;
103f02d3 9505
047b2264
JJ
9506 case DT_GNU_PRELINKED:
9507 if (do_dynamic)
9508 {
2cf0635d 9509 struct tm * tmp;
91d6fa6a 9510 time_t atime = entry->d_un.d_val;
047b2264 9511
91d6fa6a 9512 tmp = gmtime (&atime);
071436c6
NC
9513 /* PR 17533 file: 041-1244816-0.004. */
9514 if (tmp == NULL)
5a2cbcf4
L
9515 printf (_("<corrupt time val: %lx"),
9516 (unsigned long) atime);
071436c6
NC
9517 else
9518 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
9519 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9520 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9521
9522 }
9523 break;
9524
fdc90cb4
JJ
9525 case DT_GNU_HASH:
9526 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9527 if (do_dynamic)
9528 {
9529 print_vma (entry->d_un.d_val, PREFIX_HEX);
9530 putchar ('\n');
9531 }
9532 break;
9533
252b5132
RH
9534 default:
9535 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 9536 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
9537 entry->d_un.d_val;
9538
9539 if (do_dynamic)
9540 {
9541 switch (elf_header.e_machine)
9542 {
9543 case EM_MIPS:
4fe85591 9544 case EM_MIPS_RS3_LE:
b2d38a17 9545 dynamic_section_mips_val (entry);
252b5132 9546 break;
103f02d3 9547 case EM_PARISC:
b2d38a17 9548 dynamic_section_parisc_val (entry);
103f02d3 9549 break;
ecc51f48 9550 case EM_IA_64:
b2d38a17 9551 dynamic_section_ia64_val (entry);
ecc51f48 9552 break;
252b5132 9553 default:
f7a99963
NC
9554 print_vma (entry->d_un.d_val, PREFIX_HEX);
9555 putchar ('\n');
252b5132
RH
9556 }
9557 }
9558 break;
9559 }
9560 }
9561
9562 return 1;
9563}
9564
9565static char *
d3ba0551 9566get_ver_flags (unsigned int flags)
252b5132 9567{
b34976b6 9568 static char buff[32];
252b5132
RH
9569
9570 buff[0] = 0;
9571
9572 if (flags == 0)
9573 return _("none");
9574
9575 if (flags & VER_FLG_BASE)
9576 strcat (buff, "BASE ");
9577
9578 if (flags & VER_FLG_WEAK)
9579 {
9580 if (flags & VER_FLG_BASE)
9581 strcat (buff, "| ");
9582
9583 strcat (buff, "WEAK ");
9584 }
9585
44ec90b9
RO
9586 if (flags & VER_FLG_INFO)
9587 {
9588 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
9589 strcat (buff, "| ");
9590
9591 strcat (buff, "INFO ");
9592 }
9593
9594 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 9595 strcat (buff, _("| <unknown>"));
252b5132
RH
9596
9597 return buff;
9598}
9599
9600/* Display the contents of the version sections. */
98fb390a 9601
252b5132 9602static int
2cf0635d 9603process_version_sections (FILE * file)
252b5132 9604{
2cf0635d 9605 Elf_Internal_Shdr * section;
b34976b6
AM
9606 unsigned i;
9607 int found = 0;
252b5132
RH
9608
9609 if (! do_version)
9610 return 1;
9611
9612 for (i = 0, section = section_headers;
9613 i < elf_header.e_shnum;
b34976b6 9614 i++, section++)
252b5132
RH
9615 {
9616 switch (section->sh_type)
9617 {
9618 case SHT_GNU_verdef:
9619 {
2cf0635d 9620 Elf_External_Verdef * edefs;
b34976b6
AM
9621 unsigned int idx;
9622 unsigned int cnt;
2cf0635d 9623 char * endbuf;
252b5132
RH
9624
9625 found = 1;
9626
74e1a04b
NC
9627 printf (_("\nVersion definition section '%s' contains %u entries:\n"),
9628 printable_section_name (section),
9629 section->sh_info);
252b5132
RH
9630
9631 printf (_(" Addr: 0x"));
9632 printf_vma (section->sh_addr);
74e1a04b 9633 printf (_(" Offset: %#08lx Link: %u (%s)"),
1b228002 9634 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9635 printable_section_name_from_index (section->sh_link));
252b5132 9636
3f5e193b
NC
9637 edefs = (Elf_External_Verdef *)
9638 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
9639 _("version definition section"));
a6e9f9df
AM
9640 if (!edefs)
9641 break;
59245841 9642 endbuf = (char *) edefs + section->sh_size;
252b5132 9643
b34976b6 9644 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 9645 {
2cf0635d
NC
9646 char * vstart;
9647 Elf_External_Verdef * edef;
b34976b6 9648 Elf_Internal_Verdef ent;
2cf0635d 9649 Elf_External_Verdaux * eaux;
b34976b6
AM
9650 Elf_Internal_Verdaux aux;
9651 int j;
9652 int isum;
103f02d3 9653
7e26601c
NC
9654 /* Check for very large indicies. */
9655 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
9656 break;
9657
252b5132 9658 vstart = ((char *) edefs) + idx;
54806181
AM
9659 if (vstart + sizeof (*edef) > endbuf)
9660 break;
252b5132
RH
9661
9662 edef = (Elf_External_Verdef *) vstart;
9663
9664 ent.vd_version = BYTE_GET (edef->vd_version);
9665 ent.vd_flags = BYTE_GET (edef->vd_flags);
9666 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
9667 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
9668 ent.vd_hash = BYTE_GET (edef->vd_hash);
9669 ent.vd_aux = BYTE_GET (edef->vd_aux);
9670 ent.vd_next = BYTE_GET (edef->vd_next);
9671
9672 printf (_(" %#06x: Rev: %d Flags: %s"),
9673 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
9674
9675 printf (_(" Index: %d Cnt: %d "),
9676 ent.vd_ndx, ent.vd_cnt);
9677
dd24e3da 9678 /* Check for overflow. */
7e26601c 9679 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9680 break;
9681
252b5132
RH
9682 vstart += ent.vd_aux;
9683
9684 eaux = (Elf_External_Verdaux *) vstart;
9685
9686 aux.vda_name = BYTE_GET (eaux->vda_name);
9687 aux.vda_next = BYTE_GET (eaux->vda_next);
9688
d79b3d50
NC
9689 if (VALID_DYNAMIC_NAME (aux.vda_name))
9690 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9691 else
9692 printf (_("Name index: %ld\n"), aux.vda_name);
9693
9694 isum = idx + ent.vd_aux;
9695
b34976b6 9696 for (j = 1; j < ent.vd_cnt; j++)
252b5132 9697 {
dd24e3da 9698 /* Check for overflow. */
7e26601c 9699 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9700 break;
9701
252b5132
RH
9702 isum += aux.vda_next;
9703 vstart += aux.vda_next;
9704
9705 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
9706 if (vstart + sizeof (*eaux) > endbuf)
9707 break;
252b5132
RH
9708
9709 aux.vda_name = BYTE_GET (eaux->vda_name);
9710 aux.vda_next = BYTE_GET (eaux->vda_next);
9711
d79b3d50 9712 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 9713 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 9714 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9715 else
9716 printf (_(" %#06x: Parent %d, name index: %ld\n"),
9717 isum, j, aux.vda_name);
9718 }
dd24e3da 9719
54806181
AM
9720 if (j < ent.vd_cnt)
9721 printf (_(" Version def aux past end of section\n"));
252b5132 9722
5d921cbd
NC
9723 /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
9724 if (idx + ent.vd_next <= idx)
9725 break;
9726
252b5132
RH
9727 idx += ent.vd_next;
9728 }
dd24e3da 9729
54806181
AM
9730 if (cnt < section->sh_info)
9731 printf (_(" Version definition past end of section\n"));
252b5132
RH
9732
9733 free (edefs);
9734 }
9735 break;
103f02d3 9736
252b5132
RH
9737 case SHT_GNU_verneed:
9738 {
2cf0635d 9739 Elf_External_Verneed * eneed;
b34976b6
AM
9740 unsigned int idx;
9741 unsigned int cnt;
2cf0635d 9742 char * endbuf;
252b5132
RH
9743
9744 found = 1;
9745
72de5009 9746 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
74e1a04b 9747 printable_section_name (section), section->sh_info);
252b5132
RH
9748
9749 printf (_(" Addr: 0x"));
9750 printf_vma (section->sh_addr);
72de5009 9751 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9752 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9753 printable_section_name_from_index (section->sh_link));
252b5132 9754
3f5e193b
NC
9755 eneed = (Elf_External_Verneed *) get_data (NULL, file,
9756 section->sh_offset, 1,
9757 section->sh_size,
9cf03b7e 9758 _("Version Needs section"));
a6e9f9df
AM
9759 if (!eneed)
9760 break;
59245841 9761 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
9762
9763 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
9764 {
2cf0635d 9765 Elf_External_Verneed * entry;
b34976b6
AM
9766 Elf_Internal_Verneed ent;
9767 int j;
9768 int isum;
2cf0635d 9769 char * vstart;
252b5132 9770
7e26601c 9771 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
9772 break;
9773
252b5132 9774 vstart = ((char *) eneed) + idx;
54806181
AM
9775 if (vstart + sizeof (*entry) > endbuf)
9776 break;
252b5132
RH
9777
9778 entry = (Elf_External_Verneed *) vstart;
9779
9780 ent.vn_version = BYTE_GET (entry->vn_version);
9781 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
9782 ent.vn_file = BYTE_GET (entry->vn_file);
9783 ent.vn_aux = BYTE_GET (entry->vn_aux);
9784 ent.vn_next = BYTE_GET (entry->vn_next);
9785
9786 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
9787
d79b3d50
NC
9788 if (VALID_DYNAMIC_NAME (ent.vn_file))
9789 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
9790 else
9791 printf (_(" File: %lx"), ent.vn_file);
9792
9793 printf (_(" Cnt: %d\n"), ent.vn_cnt);
9794
dd24e3da 9795 /* Check for overflow. */
7e26601c 9796 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 9797 break;
252b5132
RH
9798 vstart += ent.vn_aux;
9799
9800 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
9801 {
2cf0635d 9802 Elf_External_Vernaux * eaux;
b34976b6 9803 Elf_Internal_Vernaux aux;
252b5132 9804
54806181
AM
9805 if (vstart + sizeof (*eaux) > endbuf)
9806 break;
252b5132
RH
9807 eaux = (Elf_External_Vernaux *) vstart;
9808
9809 aux.vna_hash = BYTE_GET (eaux->vna_hash);
9810 aux.vna_flags = BYTE_GET (eaux->vna_flags);
9811 aux.vna_other = BYTE_GET (eaux->vna_other);
9812 aux.vna_name = BYTE_GET (eaux->vna_name);
9813 aux.vna_next = BYTE_GET (eaux->vna_next);
9814
d79b3d50 9815 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 9816 printf (_(" %#06x: Name: %s"),
d79b3d50 9817 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 9818 else
ecc2063b 9819 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
9820 isum, aux.vna_name);
9821
9822 printf (_(" Flags: %s Version: %d\n"),
9823 get_ver_flags (aux.vna_flags), aux.vna_other);
9824
dd24e3da 9825 /* Check for overflow. */
53774b7e
NC
9826 if (aux.vna_next > (size_t) (endbuf - vstart)
9827 || (aux.vna_next == 0 && j < ent.vn_cnt - 1))
9828 {
9829 warn (_("Invalid vna_next field of %lx\n"),
9830 aux.vna_next);
9831 j = ent.vn_cnt;
9832 break;
9833 }
252b5132
RH
9834 isum += aux.vna_next;
9835 vstart += aux.vna_next;
9836 }
9cf03b7e 9837
54806181 9838 if (j < ent.vn_cnt)
9cf03b7e 9839 warn (_("Missing Version Needs auxillary information\n"));
252b5132 9840
bcf83b2a 9841 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
9842 {
9843 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
9844 cnt = section->sh_info;
9845 break;
9846 }
252b5132
RH
9847 idx += ent.vn_next;
9848 }
9cf03b7e 9849
54806181 9850 if (cnt < section->sh_info)
9cf03b7e 9851 warn (_("Missing Version Needs information\n"));
103f02d3 9852
252b5132
RH
9853 free (eneed);
9854 }
9855 break;
9856
9857 case SHT_GNU_versym:
9858 {
2cf0635d 9859 Elf_Internal_Shdr * link_section;
8b73c356
NC
9860 size_t total;
9861 unsigned int cnt;
2cf0635d
NC
9862 unsigned char * edata;
9863 unsigned short * data;
9864 char * strtab;
9865 Elf_Internal_Sym * symbols;
9866 Elf_Internal_Shdr * string_sec;
ba5cdace 9867 unsigned long num_syms;
d3ba0551 9868 long off;
252b5132 9869
4fbb74a6 9870 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9871 break;
9872
4fbb74a6 9873 link_section = section_headers + section->sh_link;
08d8fa11 9874 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9875
4fbb74a6 9876 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9877 break;
9878
252b5132
RH
9879 found = 1;
9880
ba5cdace 9881 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9882 if (symbols == NULL)
9883 break;
252b5132 9884
4fbb74a6 9885 string_sec = section_headers + link_section->sh_link;
252b5132 9886
3f5e193b
NC
9887 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9888 string_sec->sh_size,
9889 _("version string table"));
a6e9f9df 9890 if (!strtab)
0429c154
MS
9891 {
9892 free (symbols);
9893 break;
9894 }
252b5132 9895
8b73c356
NC
9896 printf (_("\nVersion symbols section '%s' contains %lu entries:\n"),
9897 printable_section_name (section), (unsigned long) total);
252b5132
RH
9898
9899 printf (_(" Addr: "));
9900 printf_vma (section->sh_addr);
72de5009 9901 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9902 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9903 printable_section_name (link_section));
252b5132 9904
d3ba0551
AM
9905 off = offset_from_vma (file,
9906 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9907 total * sizeof (short));
3f5e193b
NC
9908 edata = (unsigned char *) get_data (NULL, file, off, total,
9909 sizeof (short),
9910 _("version symbol data"));
a6e9f9df
AM
9911 if (!edata)
9912 {
9913 free (strtab);
0429c154 9914 free (symbols);
a6e9f9df
AM
9915 break;
9916 }
252b5132 9917
3f5e193b 9918 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9919
9920 for (cnt = total; cnt --;)
b34976b6
AM
9921 data[cnt] = byte_get (edata + cnt * sizeof (short),
9922 sizeof (short));
252b5132
RH
9923
9924 free (edata);
9925
9926 for (cnt = 0; cnt < total; cnt += 4)
9927 {
9928 int j, nn;
ab273396
AM
9929 char *name;
9930 char *invalid = _("*invalid*");
252b5132
RH
9931
9932 printf (" %03x:", cnt);
9933
9934 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9935 switch (data[cnt + j])
252b5132
RH
9936 {
9937 case 0:
9938 fputs (_(" 0 (*local*) "), stdout);
9939 break;
9940
9941 case 1:
9942 fputs (_(" 1 (*global*) "), stdout);
9943 break;
9944
9945 default:
c244d050
NC
9946 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9947 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9948
dd24e3da 9949 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9950 array, break to avoid an out-of-bounds read. */
9951 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9952 {
9953 warn (_("invalid index into symbol array\n"));
9954 break;
9955 }
9956
ab273396
AM
9957 name = NULL;
9958 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9959 {
b34976b6
AM
9960 Elf_Internal_Verneed ivn;
9961 unsigned long offset;
252b5132 9962
d93f0186
NC
9963 offset = offset_from_vma
9964 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9965 sizeof (Elf_External_Verneed));
252b5132 9966
b34976b6 9967 do
252b5132 9968 {
b34976b6
AM
9969 Elf_Internal_Vernaux ivna;
9970 Elf_External_Verneed evn;
9971 Elf_External_Vernaux evna;
9972 unsigned long a_off;
252b5132 9973
59245841
NC
9974 if (get_data (&evn, file, offset, sizeof (evn), 1,
9975 _("version need")) == NULL)
9976 break;
0b4362b0 9977
252b5132
RH
9978 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9979 ivn.vn_next = BYTE_GET (evn.vn_next);
9980
9981 a_off = offset + ivn.vn_aux;
9982
9983 do
9984 {
59245841
NC
9985 if (get_data (&evna, file, a_off, sizeof (evna),
9986 1, _("version need aux (2)")) == NULL)
9987 {
9988 ivna.vna_next = 0;
9989 ivna.vna_other = 0;
9990 }
9991 else
9992 {
9993 ivna.vna_next = BYTE_GET (evna.vna_next);
9994 ivna.vna_other = BYTE_GET (evna.vna_other);
9995 }
252b5132
RH
9996
9997 a_off += ivna.vna_next;
9998 }
b34976b6 9999 while (ivna.vna_other != data[cnt + j]
252b5132
RH
10000 && ivna.vna_next != 0);
10001
b34976b6 10002 if (ivna.vna_other == data[cnt + j])
252b5132
RH
10003 {
10004 ivna.vna_name = BYTE_GET (evna.vna_name);
10005
54806181 10006 if (ivna.vna_name >= string_sec->sh_size)
ab273396 10007 name = invalid;
54806181
AM
10008 else
10009 name = strtab + ivna.vna_name;
252b5132
RH
10010 break;
10011 }
10012
10013 offset += ivn.vn_next;
10014 }
10015 while (ivn.vn_next);
10016 }
00d93f34 10017
ab273396 10018 if (data[cnt + j] != 0x8001
b34976b6 10019 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 10020 {
b34976b6
AM
10021 Elf_Internal_Verdef ivd;
10022 Elf_External_Verdef evd;
10023 unsigned long offset;
252b5132 10024
d93f0186
NC
10025 offset = offset_from_vma
10026 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10027 sizeof evd);
252b5132
RH
10028
10029 do
10030 {
59245841
NC
10031 if (get_data (&evd, file, offset, sizeof (evd), 1,
10032 _("version def")) == NULL)
10033 {
10034 ivd.vd_next = 0;
948f632f 10035 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
10036 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
10037 break;
59245841
NC
10038 }
10039 else
10040 {
10041 ivd.vd_next = BYTE_GET (evd.vd_next);
10042 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10043 }
252b5132
RH
10044
10045 offset += ivd.vd_next;
10046 }
c244d050 10047 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
10048 && ivd.vd_next != 0);
10049
c244d050 10050 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 10051 {
b34976b6
AM
10052 Elf_External_Verdaux evda;
10053 Elf_Internal_Verdaux ivda;
252b5132
RH
10054
10055 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10056
59245841
NC
10057 if (get_data (&evda, file,
10058 offset - ivd.vd_next + ivd.vd_aux,
10059 sizeof (evda), 1,
10060 _("version def aux")) == NULL)
10061 break;
252b5132
RH
10062
10063 ivda.vda_name = BYTE_GET (evda.vda_name);
10064
54806181 10065 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
10066 name = invalid;
10067 else if (name != NULL && name != invalid)
10068 name = _("*both*");
54806181
AM
10069 else
10070 name = strtab + ivda.vda_name;
252b5132
RH
10071 }
10072 }
ab273396
AM
10073 if (name != NULL)
10074 nn += printf ("(%s%-*s",
10075 name,
10076 12 - (int) strlen (name),
10077 ")");
252b5132
RH
10078
10079 if (nn < 18)
10080 printf ("%*c", 18 - nn, ' ');
10081 }
10082
10083 putchar ('\n');
10084 }
10085
10086 free (data);
10087 free (strtab);
10088 free (symbols);
10089 }
10090 break;
103f02d3 10091
252b5132
RH
10092 default:
10093 break;
10094 }
10095 }
10096
10097 if (! found)
10098 printf (_("\nNo version information found in this file.\n"));
10099
10100 return 1;
10101}
10102
d1133906 10103static const char *
d3ba0551 10104get_symbol_binding (unsigned int binding)
252b5132 10105{
b34976b6 10106 static char buff[32];
252b5132
RH
10107
10108 switch (binding)
10109 {
b34976b6
AM
10110 case STB_LOCAL: return "LOCAL";
10111 case STB_GLOBAL: return "GLOBAL";
10112 case STB_WEAK: return "WEAK";
252b5132
RH
10113 default:
10114 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
10115 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
10116 binding);
252b5132 10117 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
10118 {
10119 if (binding == STB_GNU_UNIQUE
9c55345c
TS
10120 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
10121 /* GNU is still using the default value 0. */
3e7a7d11
NC
10122 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
10123 return "UNIQUE";
10124 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
10125 }
252b5132 10126 else
e9e44622 10127 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
10128 return buff;
10129 }
10130}
10131
d1133906 10132static const char *
d3ba0551 10133get_symbol_type (unsigned int type)
252b5132 10134{
b34976b6 10135 static char buff[32];
252b5132
RH
10136
10137 switch (type)
10138 {
b34976b6
AM
10139 case STT_NOTYPE: return "NOTYPE";
10140 case STT_OBJECT: return "OBJECT";
10141 case STT_FUNC: return "FUNC";
10142 case STT_SECTION: return "SECTION";
10143 case STT_FILE: return "FILE";
10144 case STT_COMMON: return "COMMON";
10145 case STT_TLS: return "TLS";
15ab5209
DB
10146 case STT_RELC: return "RELC";
10147 case STT_SRELC: return "SRELC";
252b5132
RH
10148 default:
10149 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 10150 {
3510a7b8
NC
10151 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
10152 return "THUMB_FUNC";
103f02d3 10153
351b4b40 10154 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
10155 return "REGISTER";
10156
10157 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
10158 return "PARISC_MILLI";
10159
e9e44622 10160 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 10161 }
252b5132 10162 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
10163 {
10164 if (elf_header.e_machine == EM_PARISC)
10165 {
10166 if (type == STT_HP_OPAQUE)
10167 return "HP_OPAQUE";
10168 if (type == STT_HP_STUB)
10169 return "HP_STUB";
10170 }
10171
d8045f23 10172 if (type == STT_GNU_IFUNC
9c55345c 10173 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 10174 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 10175 /* GNU is still using the default value 0. */
d8045f23
NC
10176 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
10177 return "IFUNC";
10178
e9e44622 10179 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 10180 }
252b5132 10181 else
e9e44622 10182 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
10183 return buff;
10184 }
10185}
10186
d1133906 10187static const char *
d3ba0551 10188get_symbol_visibility (unsigned int visibility)
d1133906
NC
10189{
10190 switch (visibility)
10191 {
b34976b6
AM
10192 case STV_DEFAULT: return "DEFAULT";
10193 case STV_INTERNAL: return "INTERNAL";
10194 case STV_HIDDEN: return "HIDDEN";
d1133906 10195 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
10196 default:
10197 error (_("Unrecognized visibility value: %u"), visibility);
10198 return _("<unknown>");
d1133906
NC
10199 }
10200}
10201
5e2b0d47
NC
10202static const char *
10203get_mips_symbol_other (unsigned int other)
10204{
10205 switch (other)
10206 {
df58fc94
RS
10207 case STO_OPTIONAL:
10208 return "OPTIONAL";
10209 case STO_MIPS_PLT:
10210 return "MIPS PLT";
10211 case STO_MIPS_PIC:
10212 return "MIPS PIC";
10213 case STO_MICROMIPS:
10214 return "MICROMIPS";
10215 case STO_MICROMIPS | STO_MIPS_PIC:
10216 return "MICROMIPS, MIPS PIC";
10217 case STO_MIPS16:
10218 return "MIPS16";
10219 default:
10220 return NULL;
5e2b0d47
NC
10221 }
10222}
10223
28f997cf
TG
10224static const char *
10225get_ia64_symbol_other (unsigned int other)
10226{
10227 if (is_ia64_vms ())
10228 {
10229 static char res[32];
10230
10231 res[0] = 0;
10232
10233 /* Function types is for images and .STB files only. */
10234 switch (elf_header.e_type)
10235 {
10236 case ET_DYN:
10237 case ET_EXEC:
10238 switch (VMS_ST_FUNC_TYPE (other))
10239 {
10240 case VMS_SFT_CODE_ADDR:
10241 strcat (res, " CA");
10242 break;
10243 case VMS_SFT_SYMV_IDX:
10244 strcat (res, " VEC");
10245 break;
10246 case VMS_SFT_FD:
10247 strcat (res, " FD");
10248 break;
10249 case VMS_SFT_RESERVE:
10250 strcat (res, " RSV");
10251 break;
10252 default:
bee0ee85
NC
10253 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
10254 VMS_ST_FUNC_TYPE (other));
10255 strcat (res, " <unknown>");
10256 break;
28f997cf
TG
10257 }
10258 break;
10259 default:
10260 break;
10261 }
10262 switch (VMS_ST_LINKAGE (other))
10263 {
10264 case VMS_STL_IGNORE:
10265 strcat (res, " IGN");
10266 break;
10267 case VMS_STL_RESERVE:
10268 strcat (res, " RSV");
10269 break;
10270 case VMS_STL_STD:
10271 strcat (res, " STD");
10272 break;
10273 case VMS_STL_LNK:
10274 strcat (res, " LNK");
10275 break;
10276 default:
bee0ee85
NC
10277 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
10278 VMS_ST_LINKAGE (other));
10279 strcat (res, " <unknown>");
10280 break;
28f997cf
TG
10281 }
10282
10283 if (res[0] != 0)
10284 return res + 1;
10285 else
10286 return res;
10287 }
10288 return NULL;
10289}
10290
6911b7dc
AM
10291static const char *
10292get_ppc64_symbol_other (unsigned int other)
10293{
10294 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
10295 {
10296 static char buf[32];
10297 snprintf (buf, sizeof buf, _("<localentry>: %d"),
10298 PPC64_LOCAL_ENTRY_OFFSET (other));
10299 return buf;
10300 }
10301 return NULL;
10302}
10303
5e2b0d47
NC
10304static const char *
10305get_symbol_other (unsigned int other)
10306{
10307 const char * result = NULL;
10308 static char buff [32];
10309
10310 if (other == 0)
10311 return "";
10312
10313 switch (elf_header.e_machine)
10314 {
10315 case EM_MIPS:
10316 result = get_mips_symbol_other (other);
28f997cf
TG
10317 break;
10318 case EM_IA_64:
10319 result = get_ia64_symbol_other (other);
10320 break;
6911b7dc
AM
10321 case EM_PPC64:
10322 result = get_ppc64_symbol_other (other);
10323 break;
5e2b0d47
NC
10324 default:
10325 break;
10326 }
10327
10328 if (result)
10329 return result;
10330
10331 snprintf (buff, sizeof buff, _("<other>: %x"), other);
10332 return buff;
10333}
10334
d1133906 10335static const char *
d3ba0551 10336get_symbol_index_type (unsigned int type)
252b5132 10337{
b34976b6 10338 static char buff[32];
5cf1065c 10339
252b5132
RH
10340 switch (type)
10341 {
b34976b6
AM
10342 case SHN_UNDEF: return "UND";
10343 case SHN_ABS: return "ABS";
10344 case SHN_COMMON: return "COM";
252b5132 10345 default:
9ce701e2
L
10346 if (type == SHN_IA_64_ANSI_COMMON
10347 && elf_header.e_machine == EM_IA_64
10348 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
10349 return "ANSI_COM";
8a9036a4 10350 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
10351 || elf_header.e_machine == EM_L1OM
10352 || elf_header.e_machine == EM_K1OM)
3b22753a
L
10353 && type == SHN_X86_64_LCOMMON)
10354 return "LARGE_COM";
ac145307
BS
10355 else if ((type == SHN_MIPS_SCOMMON
10356 && elf_header.e_machine == EM_MIPS)
10357 || (type == SHN_TIC6X_SCOMMON
10358 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
10359 return "SCOM";
10360 else if (type == SHN_MIPS_SUNDEFINED
10361 && elf_header.e_machine == EM_MIPS)
10362 return "SUND";
9ce701e2 10363 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 10364 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 10365 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
10366 sprintf (buff, "OS [0x%04x]", type & 0xffff);
10367 else if (type >= SHN_LORESERVE)
10368 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4 10369 else if (type >= elf_header.e_shnum)
e0a31db1 10370 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 10371 else
232e7cb8 10372 sprintf (buff, "%3d", type);
5cf1065c 10373 break;
252b5132 10374 }
5cf1065c
NC
10375
10376 return buff;
252b5132
RH
10377}
10378
66543521 10379static bfd_vma *
57028622 10380get_dynamic_data (FILE * file, bfd_size_type number, unsigned int ent_size)
252b5132 10381{
2cf0635d
NC
10382 unsigned char * e_data;
10383 bfd_vma * i_data;
252b5132 10384
57028622
NC
10385 /* If the size_t type is smaller than the bfd_size_type, eg because
10386 you are building a 32-bit tool on a 64-bit host, then make sure
10387 that when (number) is cast to (size_t) no information is lost. */
10388 if (sizeof (size_t) < sizeof (bfd_size_type)
10389 && (bfd_size_type) ((size_t) number) != number)
10390 {
10391 error (_("Size truncation prevents reading %llu elements of size %u\n"),
10392 (unsigned long long) number, ent_size);
10393 return NULL;
10394 }
948f632f 10395
3102e897
NC
10396 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
10397 attempting to allocate memory when the read is bound to fail. */
10398 if (ent_size * number > current_file_size)
10399 {
57028622
NC
10400 error (_("Invalid number of dynamic entries: %llu\n"),
10401 (unsigned long long) number);
3102e897
NC
10402 return NULL;
10403 }
10404
57028622 10405 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
10406 if (e_data == NULL)
10407 {
57028622
NC
10408 error (_("Out of memory reading %llu dynamic entries\n"),
10409 (unsigned long long) number);
252b5132
RH
10410 return NULL;
10411 }
10412
57028622 10413 if (fread (e_data, ent_size, (size_t) number, file) != number)
252b5132 10414 {
57028622
NC
10415 error (_("Unable to read in %llu bytes of dynamic data\n"),
10416 (unsigned long long) (number * ent_size));
3102e897 10417 free (e_data);
252b5132
RH
10418 return NULL;
10419 }
10420
57028622 10421 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
10422 if (i_data == NULL)
10423 {
57028622
NC
10424 error (_("Out of memory allocating space for %llu dynamic entries\n"),
10425 (unsigned long long) number);
252b5132
RH
10426 free (e_data);
10427 return NULL;
10428 }
10429
10430 while (number--)
66543521 10431 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
10432
10433 free (e_data);
10434
10435 return i_data;
10436}
10437
6bd1a22c
L
10438static void
10439print_dynamic_symbol (bfd_vma si, unsigned long hn)
10440{
2cf0635d 10441 Elf_Internal_Sym * psym;
6bd1a22c
L
10442 int n;
10443
6bd1a22c
L
10444 n = print_vma (si, DEC_5);
10445 if (n < 5)
0b4362b0 10446 fputs (&" "[n], stdout);
6bd1a22c 10447 printf (" %3lu: ", hn);
e0a31db1
NC
10448
10449 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
10450 {
3102e897
NC
10451 printf (_("<No info available for dynamic symbol number %lu>\n"),
10452 (unsigned long) si);
e0a31db1
NC
10453 return;
10454 }
10455
10456 psym = dynamic_symbols + si;
6bd1a22c
L
10457 print_vma (psym->st_value, LONG_HEX);
10458 putchar (' ');
10459 print_vma (psym->st_size, DEC_5);
10460
f4be36b3
AM
10461 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10462 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
10463 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
10464 /* Check to see if any other bits in the st_other field are set.
10465 Note - displaying this information disrupts the layout of the
10466 table being generated, but for the moment this case is very
10467 rare. */
10468 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10469 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
10470 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
10471 if (VALID_DYNAMIC_NAME (psym->st_name))
10472 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10473 else
2b692964 10474 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
10475 putchar ('\n');
10476}
10477
bb4d2ac2
L
10478static const char *
10479get_symbol_version_string (FILE *file, int is_dynsym,
10480 const char *strtab,
10481 unsigned long int strtab_size,
10482 unsigned int si, Elf_Internal_Sym *psym,
10483 enum versioned_symbol_info *sym_info,
10484 unsigned short *vna_other)
10485{
ab273396
AM
10486 unsigned char data[2];
10487 unsigned short vers_data;
10488 unsigned long offset;
bb4d2ac2 10489
ab273396
AM
10490 if (!is_dynsym
10491 || version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
10492 return NULL;
bb4d2ac2 10493
ab273396
AM
10494 offset = offset_from_vma (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10495 sizeof data + si * sizeof (vers_data));
bb4d2ac2 10496
ab273396
AM
10497 if (get_data (&data, file, offset + si * sizeof (vers_data),
10498 sizeof (data), 1, _("version data")) == NULL)
10499 return NULL;
10500
10501 vers_data = byte_get (data, 2);
bb4d2ac2 10502
ab273396
AM
10503 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data <= 1)
10504 return NULL;
bb4d2ac2 10505
ab273396
AM
10506 /* Usually we'd only see verdef for defined symbols, and verneed for
10507 undefined symbols. However, symbols defined by the linker in
10508 .dynbss for variables copied from a shared library in order to
10509 avoid text relocations are defined yet have verneed. We could
10510 use a heuristic to detect the special case, for example, check
10511 for verneed first on symbols defined in SHT_NOBITS sections, but
10512 it is simpler and more reliable to just look for both verdef and
10513 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 10514
ab273396
AM
10515 if (psym->st_shndx != SHN_UNDEF
10516 && vers_data != 0x8001
10517 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
10518 {
10519 Elf_Internal_Verdef ivd;
10520 Elf_Internal_Verdaux ivda;
10521 Elf_External_Verdaux evda;
10522 unsigned long off;
bb4d2ac2 10523
ab273396
AM
10524 off = offset_from_vma (file,
10525 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10526 sizeof (Elf_External_Verdef));
10527
10528 do
bb4d2ac2 10529 {
ab273396
AM
10530 Elf_External_Verdef evd;
10531
10532 if (get_data (&evd, file, off, sizeof (evd), 1,
10533 _("version def")) == NULL)
10534 {
10535 ivd.vd_ndx = 0;
10536 ivd.vd_aux = 0;
10537 ivd.vd_next = 0;
10538 }
10539 else
bb4d2ac2 10540 {
ab273396
AM
10541 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10542 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10543 ivd.vd_next = BYTE_GET (evd.vd_next);
10544 }
bb4d2ac2 10545
ab273396
AM
10546 off += ivd.vd_next;
10547 }
10548 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 10549
ab273396
AM
10550 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
10551 {
10552 off -= ivd.vd_next;
10553 off += ivd.vd_aux;
bb4d2ac2 10554
ab273396
AM
10555 if (get_data (&evda, file, off, sizeof (evda), 1,
10556 _("version def aux")) != NULL)
10557 {
10558 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 10559
ab273396
AM
10560 if (psym->st_name != ivda.vda_name)
10561 {
10562 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
10563 ? symbol_hidden : symbol_public);
10564 return (ivda.vda_name < strtab_size
10565 ? strtab + ivda.vda_name : _("<corrupt>"));
10566 }
10567 }
10568 }
10569 }
bb4d2ac2 10570
ab273396
AM
10571 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
10572 {
10573 Elf_External_Verneed evn;
10574 Elf_Internal_Verneed ivn;
10575 Elf_Internal_Vernaux ivna;
bb4d2ac2 10576
ab273396
AM
10577 offset = offset_from_vma (file,
10578 version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10579 sizeof evn);
10580 do
10581 {
10582 unsigned long vna_off;
bb4d2ac2 10583
ab273396
AM
10584 if (get_data (&evn, file, offset, sizeof (evn), 1,
10585 _("version need")) == NULL)
10586 {
10587 ivna.vna_next = 0;
10588 ivna.vna_other = 0;
10589 ivna.vna_name = 0;
10590 break;
10591 }
bb4d2ac2 10592
ab273396
AM
10593 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10594 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 10595
ab273396 10596 vna_off = offset + ivn.vn_aux;
bb4d2ac2 10597
ab273396
AM
10598 do
10599 {
10600 Elf_External_Vernaux evna;
bb4d2ac2 10601
ab273396
AM
10602 if (get_data (&evna, file, vna_off, sizeof (evna), 1,
10603 _("version need aux (3)")) == NULL)
bb4d2ac2 10604 {
ab273396
AM
10605 ivna.vna_next = 0;
10606 ivna.vna_other = 0;
10607 ivna.vna_name = 0;
bb4d2ac2 10608 }
bb4d2ac2 10609 else
bb4d2ac2 10610 {
ab273396
AM
10611 ivna.vna_other = BYTE_GET (evna.vna_other);
10612 ivna.vna_next = BYTE_GET (evna.vna_next);
10613 ivna.vna_name = BYTE_GET (evna.vna_name);
10614 }
bb4d2ac2 10615
ab273396
AM
10616 vna_off += ivna.vna_next;
10617 }
10618 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 10619
ab273396
AM
10620 if (ivna.vna_other == vers_data)
10621 break;
bb4d2ac2 10622
ab273396
AM
10623 offset += ivn.vn_next;
10624 }
10625 while (ivn.vn_next != 0);
bb4d2ac2 10626
ab273396
AM
10627 if (ivna.vna_other == vers_data)
10628 {
10629 *sym_info = symbol_undefined;
10630 *vna_other = ivna.vna_other;
10631 return (ivna.vna_name < strtab_size
10632 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2
L
10633 }
10634 }
ab273396 10635 return NULL;
bb4d2ac2
L
10636}
10637
e3c8793a 10638/* Dump the symbol table. */
252b5132 10639static int
2cf0635d 10640process_symbol_table (FILE * file)
252b5132 10641{
2cf0635d 10642 Elf_Internal_Shdr * section;
8b73c356
NC
10643 bfd_size_type nbuckets = 0;
10644 bfd_size_type nchains = 0;
2cf0635d
NC
10645 bfd_vma * buckets = NULL;
10646 bfd_vma * chains = NULL;
fdc90cb4 10647 bfd_vma ngnubuckets = 0;
2cf0635d
NC
10648 bfd_vma * gnubuckets = NULL;
10649 bfd_vma * gnuchains = NULL;
6bd1a22c 10650 bfd_vma gnusymidx = 0;
071436c6 10651 bfd_size_type ngnuchains = 0;
252b5132 10652
2c610e4b 10653 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
10654 return 1;
10655
6bd1a22c
L
10656 if (dynamic_info[DT_HASH]
10657 && (do_histogram
2c610e4b
L
10658 || (do_using_dynamic
10659 && !do_dyn_syms
10660 && dynamic_strings != NULL)))
252b5132 10661 {
66543521
AM
10662 unsigned char nb[8];
10663 unsigned char nc[8];
8b73c356 10664 unsigned int hash_ent_size = 4;
66543521
AM
10665
10666 if ((elf_header.e_machine == EM_ALPHA
10667 || elf_header.e_machine == EM_S390
10668 || elf_header.e_machine == EM_S390_OLD)
10669 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
10670 hash_ent_size = 8;
10671
fb52b2f4
NC
10672 if (fseek (file,
10673 (archive_file_offset
10674 + offset_from_vma (file, dynamic_info[DT_HASH],
10675 sizeof nb + sizeof nc)),
d93f0186 10676 SEEK_SET))
252b5132 10677 {
591a748a 10678 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10679 goto no_hash;
252b5132
RH
10680 }
10681
66543521 10682 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
10683 {
10684 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10685 goto no_hash;
252b5132
RH
10686 }
10687
66543521 10688 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
10689 {
10690 error (_("Failed to read in number of chains\n"));
d3a44ec6 10691 goto no_hash;
252b5132
RH
10692 }
10693
66543521
AM
10694 nbuckets = byte_get (nb, hash_ent_size);
10695 nchains = byte_get (nc, hash_ent_size);
252b5132 10696
66543521
AM
10697 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
10698 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 10699
d3a44ec6 10700 no_hash:
252b5132 10701 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
10702 {
10703 if (do_using_dynamic)
10704 return 0;
10705 free (buckets);
10706 free (chains);
10707 buckets = NULL;
10708 chains = NULL;
10709 nbuckets = 0;
10710 nchains = 0;
10711 }
252b5132
RH
10712 }
10713
6bd1a22c
L
10714 if (dynamic_info_DT_GNU_HASH
10715 && (do_histogram
2c610e4b
L
10716 || (do_using_dynamic
10717 && !do_dyn_syms
10718 && dynamic_strings != NULL)))
252b5132 10719 {
6bd1a22c
L
10720 unsigned char nb[16];
10721 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10722 bfd_vma buckets_vma;
10723
10724 if (fseek (file,
10725 (archive_file_offset
10726 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
10727 sizeof nb)),
10728 SEEK_SET))
10729 {
10730 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10731 goto no_gnu_hash;
6bd1a22c 10732 }
252b5132 10733
6bd1a22c
L
10734 if (fread (nb, 16, 1, file) != 1)
10735 {
10736 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10737 goto no_gnu_hash;
6bd1a22c
L
10738 }
10739
10740 ngnubuckets = byte_get (nb, 4);
10741 gnusymidx = byte_get (nb + 4, 4);
10742 bitmaskwords = byte_get (nb + 8, 4);
10743 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 10744 if (is_32bit_elf)
6bd1a22c 10745 buckets_vma += bitmaskwords * 4;
f7a99963 10746 else
6bd1a22c 10747 buckets_vma += bitmaskwords * 8;
252b5132 10748
6bd1a22c
L
10749 if (fseek (file,
10750 (archive_file_offset
10751 + offset_from_vma (file, buckets_vma, 4)),
10752 SEEK_SET))
252b5132 10753 {
6bd1a22c 10754 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10755 goto no_gnu_hash;
6bd1a22c
L
10756 }
10757
10758 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 10759
6bd1a22c 10760 if (gnubuckets == NULL)
d3a44ec6 10761 goto no_gnu_hash;
6bd1a22c
L
10762
10763 for (i = 0; i < ngnubuckets; i++)
10764 if (gnubuckets[i] != 0)
10765 {
10766 if (gnubuckets[i] < gnusymidx)
10767 return 0;
10768
10769 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
10770 maxchain = gnubuckets[i];
10771 }
10772
10773 if (maxchain == 0xffffffff)
d3a44ec6 10774 goto no_gnu_hash;
6bd1a22c
L
10775
10776 maxchain -= gnusymidx;
10777
10778 if (fseek (file,
10779 (archive_file_offset
10780 + offset_from_vma (file, buckets_vma
10781 + 4 * (ngnubuckets + maxchain), 4)),
10782 SEEK_SET))
10783 {
10784 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10785 goto no_gnu_hash;
6bd1a22c
L
10786 }
10787
10788 do
10789 {
10790 if (fread (nb, 4, 1, file) != 1)
252b5132 10791 {
6bd1a22c 10792 error (_("Failed to determine last chain length\n"));
d3a44ec6 10793 goto no_gnu_hash;
6bd1a22c 10794 }
252b5132 10795
6bd1a22c 10796 if (maxchain + 1 == 0)
d3a44ec6 10797 goto no_gnu_hash;
252b5132 10798
6bd1a22c
L
10799 ++maxchain;
10800 }
10801 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 10802
6bd1a22c
L
10803 if (fseek (file,
10804 (archive_file_offset
10805 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
10806 SEEK_SET))
10807 {
10808 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10809 goto no_gnu_hash;
6bd1a22c
L
10810 }
10811
10812 gnuchains = get_dynamic_data (file, maxchain, 4);
071436c6 10813 ngnuchains = maxchain;
6bd1a22c 10814
d3a44ec6 10815 no_gnu_hash:
6bd1a22c 10816 if (gnuchains == NULL)
d3a44ec6
JJ
10817 {
10818 free (gnubuckets);
d3a44ec6
JJ
10819 gnubuckets = NULL;
10820 ngnubuckets = 0;
f64fddf1
NC
10821 if (do_using_dynamic)
10822 return 0;
d3a44ec6 10823 }
6bd1a22c
L
10824 }
10825
10826 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
10827 && do_syms
10828 && do_using_dynamic
3102e897
NC
10829 && dynamic_strings != NULL
10830 && dynamic_symbols != NULL)
6bd1a22c
L
10831 {
10832 unsigned long hn;
10833
10834 if (dynamic_info[DT_HASH])
10835 {
10836 bfd_vma si;
10837
10838 printf (_("\nSymbol table for image:\n"));
10839 if (is_32bit_elf)
10840 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10841 else
10842 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10843
10844 for (hn = 0; hn < nbuckets; hn++)
10845 {
10846 if (! buckets[hn])
10847 continue;
10848
10849 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
10850 print_dynamic_symbol (si, hn);
252b5132
RH
10851 }
10852 }
6bd1a22c
L
10853
10854 if (dynamic_info_DT_GNU_HASH)
10855 {
10856 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
10857 if (is_32bit_elf)
10858 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10859 else
10860 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10861
10862 for (hn = 0; hn < ngnubuckets; ++hn)
10863 if (gnubuckets[hn] != 0)
10864 {
10865 bfd_vma si = gnubuckets[hn];
10866 bfd_vma off = si - gnusymidx;
10867
10868 do
10869 {
10870 print_dynamic_symbol (si, hn);
10871 si++;
10872 }
071436c6 10873 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
10874 }
10875 }
252b5132 10876 }
8b73c356
NC
10877 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
10878 && section_headers != NULL)
252b5132 10879 {
b34976b6 10880 unsigned int i;
252b5132
RH
10881
10882 for (i = 0, section = section_headers;
10883 i < elf_header.e_shnum;
10884 i++, section++)
10885 {
b34976b6 10886 unsigned int si;
2cf0635d 10887 char * strtab = NULL;
c256ffe7 10888 unsigned long int strtab_size = 0;
2cf0635d
NC
10889 Elf_Internal_Sym * symtab;
10890 Elf_Internal_Sym * psym;
ba5cdace 10891 unsigned long num_syms;
252b5132 10892
2c610e4b
L
10893 if ((section->sh_type != SHT_SYMTAB
10894 && section->sh_type != SHT_DYNSYM)
10895 || (!do_syms
10896 && section->sh_type == SHT_SYMTAB))
252b5132
RH
10897 continue;
10898
dd24e3da
NC
10899 if (section->sh_entsize == 0)
10900 {
10901 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
74e1a04b 10902 printable_section_name (section));
dd24e3da
NC
10903 continue;
10904 }
10905
252b5132 10906 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
74e1a04b 10907 printable_section_name (section),
252b5132 10908 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 10909
f7a99963 10910 if (is_32bit_elf)
ca47b30c 10911 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 10912 else
ca47b30c 10913 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 10914
ba5cdace 10915 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
10916 if (symtab == NULL)
10917 continue;
10918
10919 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
10920 {
10921 strtab = string_table;
10922 strtab_size = string_table_length;
10923 }
4fbb74a6 10924 else if (section->sh_link < elf_header.e_shnum)
252b5132 10925 {
2cf0635d 10926 Elf_Internal_Shdr * string_sec;
252b5132 10927
4fbb74a6 10928 string_sec = section_headers + section->sh_link;
252b5132 10929
3f5e193b
NC
10930 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
10931 1, string_sec->sh_size,
10932 _("string table"));
c256ffe7 10933 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
10934 }
10935
ba5cdace 10936 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 10937 {
bb4d2ac2
L
10938 const char *version_string;
10939 enum versioned_symbol_info sym_info;
10940 unsigned short vna_other;
10941
5e220199 10942 printf ("%6d: ", si);
f7a99963
NC
10943 print_vma (psym->st_value, LONG_HEX);
10944 putchar (' ');
10945 print_vma (psym->st_size, DEC_5);
d1133906
NC
10946 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10947 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 10948 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
10949 /* Check to see if any other bits in the st_other field are set.
10950 Note - displaying this information disrupts the layout of the
10951 table being generated, but for the moment this case is very rare. */
10952 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10953 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 10954 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 10955 print_symbol (25, psym->st_name < strtab_size
2b692964 10956 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 10957
bb4d2ac2
L
10958 version_string
10959 = get_symbol_version_string (file,
10960 section->sh_type == SHT_DYNSYM,
10961 strtab, strtab_size, si,
10962 psym, &sym_info, &vna_other);
10963 if (version_string)
252b5132 10964 {
bb4d2ac2
L
10965 if (sym_info == symbol_undefined)
10966 printf ("@%s (%d)", version_string, vna_other);
10967 else
10968 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
10969 version_string);
252b5132
RH
10970 }
10971
10972 putchar ('\n');
10973 }
10974
10975 free (symtab);
10976 if (strtab != string_table)
10977 free (strtab);
10978 }
10979 }
10980 else if (do_syms)
10981 printf
10982 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10983
10984 if (do_histogram && buckets != NULL)
10985 {
2cf0635d
NC
10986 unsigned long * lengths;
10987 unsigned long * counts;
66543521
AM
10988 unsigned long hn;
10989 bfd_vma si;
10990 unsigned long maxlength = 0;
10991 unsigned long nzero_counts = 0;
10992 unsigned long nsyms = 0;
94d15024 10993 unsigned long chained;
252b5132 10994
66543521
AM
10995 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10996 (unsigned long) nbuckets);
252b5132 10997
3f5e193b 10998 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10999 if (lengths == NULL)
11000 {
8b73c356 11001 error (_("Out of memory allocating space for histogram buckets\n"));
252b5132
RH
11002 return 0;
11003 }
8b73c356
NC
11004
11005 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
11006 for (hn = 0; hn < nbuckets; ++hn)
11007 {
94d15024
MF
11008 for (si = buckets[hn], chained = 0;
11009 si > 0 && si < nchains && si < nbuckets && chained <= nchains;
11010 si = chains[si], ++chained)
252b5132 11011 {
b34976b6 11012 ++nsyms;
252b5132 11013 if (maxlength < ++lengths[hn])
b34976b6 11014 ++maxlength;
252b5132 11015 }
94d15024
MF
11016
11017 /* PR binutils/17531: A corrupt binary could contain broken
11018 histogram data. Do not go into an infinite loop trying
11019 to process it. */
11020 if (chained > nchains)
11021 {
11022 error (_("histogram chain is corrupt\n"));
11023 break;
11024 }
252b5132
RH
11025 }
11026
3f5e193b 11027 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
11028 if (counts == NULL)
11029 {
b2e951ec 11030 free (lengths);
8b73c356 11031 error (_("Out of memory allocating space for histogram counts\n"));
252b5132
RH
11032 return 0;
11033 }
11034
11035 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 11036 ++counts[lengths[hn]];
252b5132 11037
103f02d3 11038 if (nbuckets > 0)
252b5132 11039 {
66543521
AM
11040 unsigned long i;
11041 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 11042 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 11043 for (i = 1; i <= maxlength; ++i)
103f02d3 11044 {
66543521
AM
11045 nzero_counts += counts[i] * i;
11046 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11047 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
11048 (nzero_counts * 100.0) / nsyms);
11049 }
252b5132
RH
11050 }
11051
11052 free (counts);
11053 free (lengths);
11054 }
11055
11056 if (buckets != NULL)
11057 {
11058 free (buckets);
11059 free (chains);
11060 }
11061
d3a44ec6 11062 if (do_histogram && gnubuckets != NULL)
fdc90cb4 11063 {
2cf0635d
NC
11064 unsigned long * lengths;
11065 unsigned long * counts;
fdc90cb4
JJ
11066 unsigned long hn;
11067 unsigned long maxlength = 0;
11068 unsigned long nzero_counts = 0;
11069 unsigned long nsyms = 0;
fdc90cb4 11070
8b73c356
NC
11071 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
11072 (unsigned long) ngnubuckets);
11073
3f5e193b 11074 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
11075 if (lengths == NULL)
11076 {
8b73c356 11077 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fdc90cb4
JJ
11078 return 0;
11079 }
11080
fdc90cb4
JJ
11081 printf (_(" Length Number %% of total Coverage\n"));
11082
11083 for (hn = 0; hn < ngnubuckets; ++hn)
11084 if (gnubuckets[hn] != 0)
11085 {
11086 bfd_vma off, length = 1;
11087
6bd1a22c 11088 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
11089 /* PR 17531 file: 010-77222-0.004. */
11090 off < ngnuchains && (gnuchains[off] & 1) == 0;
11091 ++off)
fdc90cb4
JJ
11092 ++length;
11093 lengths[hn] = length;
11094 if (length > maxlength)
11095 maxlength = length;
11096 nsyms += length;
11097 }
11098
3f5e193b 11099 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
11100 if (counts == NULL)
11101 {
b2e951ec 11102 free (lengths);
8b73c356 11103 error (_("Out of memory allocating space for gnu histogram counts\n"));
fdc90cb4
JJ
11104 return 0;
11105 }
11106
11107 for (hn = 0; hn < ngnubuckets; ++hn)
11108 ++counts[lengths[hn]];
11109
11110 if (ngnubuckets > 0)
11111 {
11112 unsigned long j;
11113 printf (" 0 %-10lu (%5.1f%%)\n",
11114 counts[0], (counts[0] * 100.0) / ngnubuckets);
11115 for (j = 1; j <= maxlength; ++j)
11116 {
11117 nzero_counts += counts[j] * j;
11118 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
11119 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
11120 (nzero_counts * 100.0) / nsyms);
11121 }
11122 }
11123
11124 free (counts);
11125 free (lengths);
11126 free (gnubuckets);
11127 free (gnuchains);
11128 }
11129
252b5132
RH
11130 return 1;
11131}
11132
11133static int
2cf0635d 11134process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 11135{
b4c96d0d 11136 unsigned int i;
252b5132
RH
11137
11138 if (dynamic_syminfo == NULL
11139 || !do_dynamic)
11140 /* No syminfo, this is ok. */
11141 return 1;
11142
11143 /* There better should be a dynamic symbol section. */
11144 if (dynamic_symbols == NULL || dynamic_strings == NULL)
11145 return 0;
11146
11147 if (dynamic_addr)
11148 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
11149 dynamic_syminfo_offset, dynamic_syminfo_nent);
11150
11151 printf (_(" Num: Name BoundTo Flags\n"));
11152 for (i = 0; i < dynamic_syminfo_nent; ++i)
11153 {
11154 unsigned short int flags = dynamic_syminfo[i].si_flags;
11155
31104126 11156 printf ("%4d: ", i);
4082ef84
NC
11157 if (i >= num_dynamic_syms)
11158 printf (_("<corrupt index>"));
11159 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
11160 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
11161 else
2b692964 11162 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 11163 putchar (' ');
252b5132
RH
11164
11165 switch (dynamic_syminfo[i].si_boundto)
11166 {
11167 case SYMINFO_BT_SELF:
11168 fputs ("SELF ", stdout);
11169 break;
11170 case SYMINFO_BT_PARENT:
11171 fputs ("PARENT ", stdout);
11172 break;
11173 default:
11174 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
11175 && dynamic_syminfo[i].si_boundto < dynamic_nent
11176 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 11177 {
d79b3d50 11178 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
11179 putchar (' ' );
11180 }
252b5132
RH
11181 else
11182 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
11183 break;
11184 }
11185
11186 if (flags & SYMINFO_FLG_DIRECT)
11187 printf (" DIRECT");
11188 if (flags & SYMINFO_FLG_PASSTHRU)
11189 printf (" PASSTHRU");
11190 if (flags & SYMINFO_FLG_COPY)
11191 printf (" COPY");
11192 if (flags & SYMINFO_FLG_LAZYLOAD)
11193 printf (" LAZYLOAD");
11194
11195 puts ("");
11196 }
11197
11198 return 1;
11199}
11200
cf13d699
NC
11201/* Check to see if the given reloc needs to be handled in a target specific
11202 manner. If so then process the reloc and return TRUE otherwise return
11203 FALSE. */
09c11c86 11204
cf13d699
NC
11205static bfd_boolean
11206target_specific_reloc_handling (Elf_Internal_Rela * reloc,
11207 unsigned char * start,
11208 Elf_Internal_Sym * symtab)
252b5132 11209{
cf13d699 11210 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 11211
cf13d699 11212 switch (elf_header.e_machine)
252b5132 11213 {
13761a11
NC
11214 case EM_MSP430:
11215 case EM_MSP430_OLD:
11216 {
11217 static Elf_Internal_Sym * saved_sym = NULL;
11218
11219 switch (reloc_type)
11220 {
11221 case 10: /* R_MSP430_SYM_DIFF */
11222 if (uses_msp430x_relocs ())
11223 break;
11224 case 21: /* R_MSP430X_SYM_DIFF */
11225 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
11226 return TRUE;
11227
11228 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
11229 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
11230 goto handle_sym_diff;
0b4362b0 11231
13761a11
NC
11232 case 5: /* R_MSP430_16_BYTE */
11233 case 9: /* R_MSP430_8 */
11234 if (uses_msp430x_relocs ())
11235 break;
11236 goto handle_sym_diff;
11237
11238 case 2: /* R_MSP430_ABS16 */
11239 case 15: /* R_MSP430X_ABS16 */
11240 if (! uses_msp430x_relocs ())
11241 break;
11242 goto handle_sym_diff;
0b4362b0 11243
13761a11
NC
11244 handle_sym_diff:
11245 if (saved_sym != NULL)
11246 {
11247 bfd_vma value;
11248
11249 value = reloc->r_addend
11250 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
11251 - saved_sym->st_value);
11252
11253 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
11254
11255 saved_sym = NULL;
11256 return TRUE;
11257 }
11258 break;
11259
11260 default:
11261 if (saved_sym != NULL)
071436c6 11262 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
11263 break;
11264 }
11265 break;
11266 }
11267
cf13d699
NC
11268 case EM_MN10300:
11269 case EM_CYGNUS_MN10300:
11270 {
11271 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 11272
cf13d699
NC
11273 switch (reloc_type)
11274 {
11275 case 34: /* R_MN10300_ALIGN */
11276 return TRUE;
11277 case 33: /* R_MN10300_SYM_DIFF */
11278 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
11279 return TRUE;
11280 case 1: /* R_MN10300_32 */
11281 case 2: /* R_MN10300_16 */
11282 if (saved_sym != NULL)
11283 {
11284 bfd_vma value;
252b5132 11285
cf13d699
NC
11286 value = reloc->r_addend
11287 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
11288 - saved_sym->st_value);
252b5132 11289
cf13d699 11290 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 11291
cf13d699
NC
11292 saved_sym = NULL;
11293 return TRUE;
11294 }
11295 break;
11296 default:
11297 if (saved_sym != NULL)
071436c6 11298 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
11299 break;
11300 }
11301 break;
11302 }
6ff71e76
NC
11303
11304 case EM_RL78:
11305 {
11306 static bfd_vma saved_sym1 = 0;
11307 static bfd_vma saved_sym2 = 0;
11308 static bfd_vma value;
11309
11310 switch (reloc_type)
11311 {
11312 case 0x80: /* R_RL78_SYM. */
11313 saved_sym1 = saved_sym2;
11314 saved_sym2 = symtab[get_reloc_symindex (reloc->r_info)].st_value;
11315 saved_sym2 += reloc->r_addend;
11316 return TRUE;
11317
11318 case 0x83: /* R_RL78_OPsub. */
11319 value = saved_sym1 - saved_sym2;
11320 saved_sym2 = saved_sym1 = 0;
11321 return TRUE;
11322 break;
11323
11324 case 0x41: /* R_RL78_ABS32. */
11325 byte_put (start + reloc->r_offset, value, 4);
11326 value = 0;
11327 return TRUE;
11328
11329 case 0x43: /* R_RL78_ABS16. */
11330 byte_put (start + reloc->r_offset, value, 2);
11331 value = 0;
11332 return TRUE;
11333
11334 default:
11335 break;
11336 }
11337 break;
11338 }
252b5132
RH
11339 }
11340
cf13d699 11341 return FALSE;
252b5132
RH
11342}
11343
aca88567
NC
11344/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
11345 DWARF debug sections. This is a target specific test. Note - we do not
11346 go through the whole including-target-headers-multiple-times route, (as
11347 we have already done with <elf/h8.h>) because this would become very
11348 messy and even then this function would have to contain target specific
11349 information (the names of the relocs instead of their numeric values).
11350 FIXME: This is not the correct way to solve this problem. The proper way
11351 is to have target specific reloc sizing and typing functions created by
11352 the reloc-macros.h header, in the same way that it already creates the
11353 reloc naming functions. */
11354
11355static bfd_boolean
11356is_32bit_abs_reloc (unsigned int reloc_type)
11357{
11358 switch (elf_header.e_machine)
11359 {
41e92641 11360 case EM_386:
22abe556 11361 case EM_IAMCU:
41e92641 11362 return reloc_type == 1; /* R_386_32. */
aca88567
NC
11363 case EM_68K:
11364 return reloc_type == 1; /* R_68K_32. */
11365 case EM_860:
11366 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
11367 case EM_960:
11368 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
11369 case EM_AARCH64:
11370 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 11371 case EM_ALPHA:
137b6b5f 11372 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
11373 case EM_ARC:
11374 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
11375 case EM_ARC_COMPACT:
11376 case EM_ARC_COMPACT2:
11377 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
11378 case EM_ARM:
11379 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 11380 case EM_AVR_OLD:
aca88567
NC
11381 case EM_AVR:
11382 return reloc_type == 1;
cfb8c092
NC
11383 case EM_ADAPTEVA_EPIPHANY:
11384 return reloc_type == 3;
aca88567
NC
11385 case EM_BLACKFIN:
11386 return reloc_type == 0x12; /* R_byte4_data. */
11387 case EM_CRIS:
11388 return reloc_type == 3; /* R_CRIS_32. */
11389 case EM_CR16:
11390 return reloc_type == 3; /* R_CR16_NUM32. */
11391 case EM_CRX:
11392 return reloc_type == 15; /* R_CRX_NUM32. */
11393 case EM_CYGNUS_FRV:
11394 return reloc_type == 1;
41e92641
NC
11395 case EM_CYGNUS_D10V:
11396 case EM_D10V:
11397 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
11398 case EM_CYGNUS_D30V:
11399 case EM_D30V:
11400 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
11401 case EM_DLX:
11402 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
11403 case EM_CYGNUS_FR30:
11404 case EM_FR30:
11405 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
11406 case EM_FT32:
11407 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
11408 case EM_H8S:
11409 case EM_H8_300:
11410 case EM_H8_300H:
11411 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 11412 case EM_IA_64:
d1c4b12b
NC
11413 return reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
11414 || reloc_type == 0x25; /* R_IA64_DIR32LSB. */
aca88567
NC
11415 case EM_IP2K_OLD:
11416 case EM_IP2K:
11417 return reloc_type == 2; /* R_IP2K_32. */
11418 case EM_IQ2000:
11419 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
11420 case EM_LATTICEMICO32:
11421 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 11422 case EM_M32C_OLD:
aca88567
NC
11423 case EM_M32C:
11424 return reloc_type == 3; /* R_M32C_32. */
11425 case EM_M32R:
11426 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
11427 case EM_68HC11:
11428 case EM_68HC12:
11429 return reloc_type == 6; /* R_M68HC11_32. */
aca88567
NC
11430 case EM_MCORE:
11431 return reloc_type == 1; /* R_MCORE_ADDR32. */
11432 case EM_CYGNUS_MEP:
11433 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
11434 case EM_METAG:
11435 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
11436 case EM_MICROBLAZE:
11437 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
11438 case EM_MIPS:
11439 return reloc_type == 2; /* R_MIPS_32. */
11440 case EM_MMIX:
11441 return reloc_type == 4; /* R_MMIX_32. */
11442 case EM_CYGNUS_MN10200:
11443 case EM_MN10200:
11444 return reloc_type == 1; /* R_MN10200_32. */
11445 case EM_CYGNUS_MN10300:
11446 case EM_MN10300:
11447 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
11448 case EM_MOXIE:
11449 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
11450 case EM_MSP430_OLD:
11451 case EM_MSP430:
13761a11 11452 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
11453 case EM_MT:
11454 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
11455 case EM_NDS32:
11456 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 11457 case EM_ALTERA_NIOS2:
36591ba1 11458 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
11459 case EM_NIOS32:
11460 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
11461 case EM_OR1K:
11462 return reloc_type == 1; /* R_OR1K_32. */
aca88567 11463 case EM_PARISC:
5fda8eca
NC
11464 return (reloc_type == 1 /* R_PARISC_DIR32. */
11465 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
11466 case EM_PJ:
11467 case EM_PJ_OLD:
11468 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
11469 case EM_PPC64:
11470 return reloc_type == 1; /* R_PPC64_ADDR32. */
11471 case EM_PPC:
11472 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
11473 case EM_RL78:
11474 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
11475 case EM_RX:
11476 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
11477 case EM_S370:
11478 return reloc_type == 1; /* R_I370_ADDR31. */
11479 case EM_S390_OLD:
11480 case EM_S390:
11481 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
11482 case EM_SCORE:
11483 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
11484 case EM_SH:
11485 return reloc_type == 1; /* R_SH_DIR32. */
11486 case EM_SPARC32PLUS:
11487 case EM_SPARCV9:
11488 case EM_SPARC:
11489 return reloc_type == 3 /* R_SPARC_32. */
11490 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
11491 case EM_SPU:
11492 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
11493 case EM_TI_C6000:
11494 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
11495 case EM_TILEGX:
11496 return reloc_type == 2; /* R_TILEGX_32. */
11497 case EM_TILEPRO:
11498 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
11499 case EM_CYGNUS_V850:
11500 case EM_V850:
11501 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
11502 case EM_V800:
11503 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
11504 case EM_VAX:
11505 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
11506 case EM_VISIUM:
11507 return reloc_type == 3; /* R_VISIUM_32. */
aca88567 11508 case EM_X86_64:
8a9036a4 11509 case EM_L1OM:
7a9068fe 11510 case EM_K1OM:
aca88567 11511 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
11512 case EM_XC16X:
11513 case EM_C166:
11514 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
11515 case EM_XGATE:
11516 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
11517 case EM_XSTORMY16:
11518 return reloc_type == 1; /* R_XSTROMY16_32. */
11519 case EM_XTENSA_OLD:
11520 case EM_XTENSA:
11521 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 11522 default:
bee0ee85
NC
11523 {
11524 static unsigned int prev_warn = 0;
11525
11526 /* Avoid repeating the same warning multiple times. */
11527 if (prev_warn != elf_header.e_machine)
11528 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
11529 elf_header.e_machine);
11530 prev_warn = elf_header.e_machine;
11531 return FALSE;
11532 }
aca88567
NC
11533 }
11534}
11535
11536/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11537 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
11538
11539static bfd_boolean
11540is_32bit_pcrel_reloc (unsigned int reloc_type)
11541{
11542 switch (elf_header.e_machine)
11543 {
41e92641 11544 case EM_386:
22abe556 11545 case EM_IAMCU:
3e0873ac 11546 return reloc_type == 2; /* R_386_PC32. */
aca88567 11547 case EM_68K:
3e0873ac 11548 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
11549 case EM_AARCH64:
11550 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
11551 case EM_ADAPTEVA_EPIPHANY:
11552 return reloc_type == 6;
aca88567
NC
11553 case EM_ALPHA:
11554 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 11555 case EM_ARM:
3e0873ac 11556 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
11557 case EM_MICROBLAZE:
11558 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
11559 case EM_OR1K:
11560 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 11561 case EM_PARISC:
85acf597 11562 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
11563 case EM_PPC:
11564 return reloc_type == 26; /* R_PPC_REL32. */
11565 case EM_PPC64:
3e0873ac 11566 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
11567 case EM_S390_OLD:
11568 case EM_S390:
3e0873ac 11569 return reloc_type == 5; /* R_390_PC32. */
aca88567 11570 case EM_SH:
3e0873ac 11571 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
11572 case EM_SPARC32PLUS:
11573 case EM_SPARCV9:
11574 case EM_SPARC:
3e0873ac 11575 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
11576 case EM_SPU:
11577 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
11578 case EM_TILEGX:
11579 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
11580 case EM_TILEPRO:
11581 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
11582 case EM_VISIUM:
11583 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 11584 case EM_X86_64:
8a9036a4 11585 case EM_L1OM:
7a9068fe 11586 case EM_K1OM:
3e0873ac 11587 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
11588 case EM_XTENSA_OLD:
11589 case EM_XTENSA:
11590 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
11591 default:
11592 /* Do not abort or issue an error message here. Not all targets use
11593 pc-relative 32-bit relocs in their DWARF debug information and we
11594 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
11595 more helpful warning message will be generated by apply_relocations
11596 anyway, so just return. */
aca88567
NC
11597 return FALSE;
11598 }
11599}
11600
11601/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11602 a 64-bit absolute RELA relocation used in DWARF debug sections. */
11603
11604static bfd_boolean
11605is_64bit_abs_reloc (unsigned int reloc_type)
11606{
11607 switch (elf_header.e_machine)
11608 {
a06ea964
NC
11609 case EM_AARCH64:
11610 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
11611 case EM_ALPHA:
11612 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
11613 case EM_IA_64:
11614 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
11615 case EM_PARISC:
11616 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
11617 case EM_PPC64:
11618 return reloc_type == 38; /* R_PPC64_ADDR64. */
11619 case EM_SPARC32PLUS:
11620 case EM_SPARCV9:
11621 case EM_SPARC:
11622 return reloc_type == 54; /* R_SPARC_UA64. */
11623 case EM_X86_64:
8a9036a4 11624 case EM_L1OM:
7a9068fe 11625 case EM_K1OM:
aca88567 11626 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
11627 case EM_S390_OLD:
11628 case EM_S390:
aa137e4d
NC
11629 return reloc_type == 22; /* R_S390_64. */
11630 case EM_TILEGX:
11631 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 11632 case EM_MIPS:
aa137e4d 11633 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
11634 default:
11635 return FALSE;
11636 }
11637}
11638
85acf597
RH
11639/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
11640 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
11641
11642static bfd_boolean
11643is_64bit_pcrel_reloc (unsigned int reloc_type)
11644{
11645 switch (elf_header.e_machine)
11646 {
a06ea964
NC
11647 case EM_AARCH64:
11648 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 11649 case EM_ALPHA:
aa137e4d 11650 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 11651 case EM_IA_64:
aa137e4d 11652 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 11653 case EM_PARISC:
aa137e4d 11654 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 11655 case EM_PPC64:
aa137e4d 11656 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
11657 case EM_SPARC32PLUS:
11658 case EM_SPARCV9:
11659 case EM_SPARC:
aa137e4d 11660 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 11661 case EM_X86_64:
8a9036a4 11662 case EM_L1OM:
7a9068fe 11663 case EM_K1OM:
aa137e4d 11664 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
11665 case EM_S390_OLD:
11666 case EM_S390:
aa137e4d
NC
11667 return reloc_type == 23; /* R_S390_PC64. */
11668 case EM_TILEGX:
11669 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
11670 default:
11671 return FALSE;
11672 }
11673}
11674
4dc3c23d
AM
11675/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11676 a 24-bit absolute RELA relocation used in DWARF debug sections. */
11677
11678static bfd_boolean
11679is_24bit_abs_reloc (unsigned int reloc_type)
11680{
11681 switch (elf_header.e_machine)
11682 {
11683 case EM_CYGNUS_MN10200:
11684 case EM_MN10200:
11685 return reloc_type == 4; /* R_MN10200_24. */
11686 default:
11687 return FALSE;
11688 }
11689}
11690
aca88567
NC
11691/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11692 a 16-bit absolute RELA relocation used in DWARF debug sections. */
11693
11694static bfd_boolean
11695is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
11696{
11697 switch (elf_header.e_machine)
11698 {
886a2506
NC
11699 case EM_ARC:
11700 case EM_ARC_COMPACT:
11701 case EM_ARC_COMPACT2:
11702 return reloc_type == 2; /* R_ARC_16. */
aca88567
NC
11703 case EM_AVR_OLD:
11704 case EM_AVR:
11705 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
11706 case EM_ADAPTEVA_EPIPHANY:
11707 return reloc_type == 5;
41e92641
NC
11708 case EM_CYGNUS_D10V:
11709 case EM_D10V:
11710 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
11711 case EM_H8S:
11712 case EM_H8_300:
11713 case EM_H8_300H:
aca88567
NC
11714 return reloc_type == R_H8_DIR16;
11715 case EM_IP2K_OLD:
11716 case EM_IP2K:
11717 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 11718 case EM_M32C_OLD:
f4236fe4
DD
11719 case EM_M32C:
11720 return reloc_type == 1; /* R_M32C_16 */
aca88567 11721 case EM_MSP430:
13761a11
NC
11722 if (uses_msp430x_relocs ())
11723 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 11724 case EM_MSP430_OLD:
aca88567 11725 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
11726 case EM_NDS32:
11727 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 11728 case EM_ALTERA_NIOS2:
36591ba1 11729 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
11730 case EM_NIOS32:
11731 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
11732 case EM_OR1K:
11733 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
11734 case EM_TI_C6000:
11735 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
11736 case EM_XC16X:
11737 case EM_C166:
11738 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
11739 case EM_CYGNUS_MN10200:
11740 case EM_MN10200:
11741 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
11742 case EM_CYGNUS_MN10300:
11743 case EM_MN10300:
11744 return reloc_type == 2; /* R_MN10300_16. */
619ed720
EB
11745 case EM_VISIUM:
11746 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
11747 case EM_XGATE:
11748 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 11749 default:
aca88567 11750 return FALSE;
4b78141a
NC
11751 }
11752}
11753
2a7b2e88
JK
11754/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
11755 relocation entries (possibly formerly used for SHT_GROUP sections). */
11756
11757static bfd_boolean
11758is_none_reloc (unsigned int reloc_type)
11759{
11760 switch (elf_header.e_machine)
11761 {
cb8f3167
NC
11762 case EM_68K: /* R_68K_NONE. */
11763 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
11764 case EM_SPARC32PLUS:
11765 case EM_SPARCV9:
cb8f3167
NC
11766 case EM_SPARC: /* R_SPARC_NONE. */
11767 case EM_MIPS: /* R_MIPS_NONE. */
11768 case EM_PARISC: /* R_PARISC_NONE. */
11769 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 11770 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
11771 case EM_PPC: /* R_PPC_NONE. */
11772 case EM_PPC64: /* R_PPC64_NONE. */
886a2506
NC
11773 case EM_ARC: /* R_ARC_NONE. */
11774 case EM_ARC_COMPACT: /* R_ARC_NONE. */
11775 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
cb8f3167
NC
11776 case EM_ARM: /* R_ARM_NONE. */
11777 case EM_IA_64: /* R_IA64_NONE. */
11778 case EM_SH: /* R_SH_NONE. */
2a7b2e88 11779 case EM_S390_OLD:
cb8f3167
NC
11780 case EM_S390: /* R_390_NONE. */
11781 case EM_CRIS: /* R_CRIS_NONE. */
11782 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 11783 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 11784 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 11785 case EM_MN10300: /* R_MN10300_NONE. */
3f8107ab 11786 case EM_FT32: /* R_FT32_NONE. */
5506d11a 11787 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 11788 case EM_M32R: /* R_M32R_NONE. */
40b36596 11789 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
11790 case EM_TILEGX: /* R_TILEGX_NONE. */
11791 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
11792 case EM_XC16X:
11793 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
11794 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
11795 case EM_NIOS32: /* R_NIOS_NONE. */
73589c9d 11796 case EM_OR1K: /* R_OR1K_NONE. */
cb8f3167 11797 return reloc_type == 0;
a06ea964
NC
11798 case EM_AARCH64:
11799 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
11800 case EM_NDS32:
11801 return (reloc_type == 0 /* R_XTENSA_NONE. */
11802 || reloc_type == 204 /* R_NDS32_DIFF8. */
11803 || reloc_type == 205 /* R_NDS32_DIFF16. */
11804 || reloc_type == 206 /* R_NDS32_DIFF32. */
11805 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
11806 case EM_XTENSA_OLD:
11807 case EM_XTENSA:
4dc3c23d
AM
11808 return (reloc_type == 0 /* R_XTENSA_NONE. */
11809 || reloc_type == 17 /* R_XTENSA_DIFF8. */
11810 || reloc_type == 18 /* R_XTENSA_DIFF16. */
11811 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
11812 case EM_METAG:
11813 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
11814 }
11815 return FALSE;
11816}
11817
d1c4b12b
NC
11818/* Returns TRUE if there is a relocation against
11819 section NAME at OFFSET bytes. */
11820
11821bfd_boolean
11822reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
11823{
11824 Elf_Internal_Rela * relocs;
11825 Elf_Internal_Rela * rp;
11826
11827 if (dsec == NULL || dsec->reloc_info == NULL)
11828 return FALSE;
11829
11830 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
11831
11832 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
11833 if (rp->r_offset == offset)
11834 return TRUE;
11835
11836 return FALSE;
11837}
11838
cf13d699
NC
11839/* Apply relocations to a section.
11840 Note: So far support has been added only for those relocations
11841 which can be found in debug sections.
d1c4b12b
NC
11842 If RELOCS_RETURN is non-NULL then returns in it a pointer to the
11843 loaded relocs. It is then the caller's responsibility to free them.
cf13d699 11844 FIXME: Add support for more relocations ? */
1b315056 11845
cf13d699 11846static void
d1c4b12b
NC
11847apply_relocations (void * file,
11848 const Elf_Internal_Shdr * section,
11849 unsigned char * start,
11850 bfd_size_type size,
11851 void ** relocs_return,
11852 unsigned long * num_relocs_return)
1b315056 11853{
cf13d699 11854 Elf_Internal_Shdr * relsec;
0d2a7a93 11855 unsigned char * end = start + size;
cb8f3167 11856
d1c4b12b
NC
11857 if (relocs_return != NULL)
11858 {
11859 * (Elf_Internal_Rela **) relocs_return = NULL;
11860 * num_relocs_return = 0;
11861 }
11862
cf13d699
NC
11863 if (elf_header.e_type != ET_REL)
11864 return;
1b315056 11865
cf13d699 11866 /* Find the reloc section associated with the section. */
5b18a4bc
NC
11867 for (relsec = section_headers;
11868 relsec < section_headers + elf_header.e_shnum;
11869 ++relsec)
252b5132 11870 {
41e92641
NC
11871 bfd_boolean is_rela;
11872 unsigned long num_relocs;
2cf0635d
NC
11873 Elf_Internal_Rela * relocs;
11874 Elf_Internal_Rela * rp;
11875 Elf_Internal_Shdr * symsec;
11876 Elf_Internal_Sym * symtab;
ba5cdace 11877 unsigned long num_syms;
2cf0635d 11878 Elf_Internal_Sym * sym;
252b5132 11879
41e92641 11880 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
11881 || relsec->sh_info >= elf_header.e_shnum
11882 || section_headers + relsec->sh_info != section
c256ffe7 11883 || relsec->sh_size == 0
4fbb74a6 11884 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 11885 continue;
428409d5 11886
41e92641
NC
11887 is_rela = relsec->sh_type == SHT_RELA;
11888
11889 if (is_rela)
11890 {
3f5e193b
NC
11891 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
11892 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11893 return;
11894 }
11895 else
11896 {
3f5e193b
NC
11897 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
11898 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11899 return;
11900 }
11901
11902 /* SH uses RELA but uses in place value instead of the addend field. */
11903 if (elf_header.e_machine == EM_SH)
11904 is_rela = FALSE;
428409d5 11905
4fbb74a6 11906 symsec = section_headers + relsec->sh_link;
ba5cdace 11907 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 11908
41e92641 11909 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 11910 {
41e92641
NC
11911 bfd_vma addend;
11912 unsigned int reloc_type;
11913 unsigned int reloc_size;
91d6fa6a 11914 unsigned char * rloc;
ba5cdace 11915 unsigned long sym_index;
4b78141a 11916
aca88567 11917 reloc_type = get_reloc_type (rp->r_info);
41e92641 11918
98fb390a 11919 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 11920 continue;
98fb390a
NC
11921 else if (is_none_reloc (reloc_type))
11922 continue;
11923 else if (is_32bit_abs_reloc (reloc_type)
11924 || is_32bit_pcrel_reloc (reloc_type))
aca88567 11925 reloc_size = 4;
85acf597
RH
11926 else if (is_64bit_abs_reloc (reloc_type)
11927 || is_64bit_pcrel_reloc (reloc_type))
aca88567 11928 reloc_size = 8;
4dc3c23d
AM
11929 else if (is_24bit_abs_reloc (reloc_type))
11930 reloc_size = 3;
aca88567
NC
11931 else if (is_16bit_abs_reloc (reloc_type))
11932 reloc_size = 2;
11933 else
4b78141a 11934 {
bee0ee85
NC
11935 static unsigned int prev_reloc = 0;
11936 if (reloc_type != prev_reloc)
11937 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
11938 reloc_type, printable_section_name (section));
11939 prev_reloc = reloc_type;
4b78141a
NC
11940 continue;
11941 }
103f02d3 11942
91d6fa6a 11943 rloc = start + rp->r_offset;
c8da6823 11944 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
11945 {
11946 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
11947 (unsigned long) rp->r_offset,
74e1a04b 11948 printable_section_name (section));
700dd8b7
L
11949 continue;
11950 }
103f02d3 11951
ba5cdace
NC
11952 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
11953 if (sym_index >= num_syms)
11954 {
11955 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
74e1a04b 11956 sym_index, printable_section_name (section));
ba5cdace
NC
11957 continue;
11958 }
11959 sym = symtab + sym_index;
41e92641
NC
11960
11961 /* If the reloc has a symbol associated with it,
55f25fc3
L
11962 make sure that it is of an appropriate type.
11963
11964 Relocations against symbols without type can happen.
11965 Gcc -feliminate-dwarf2-dups may generate symbols
11966 without type for debug info.
11967
11968 Icc generates relocations against function symbols
11969 instead of local labels.
11970
11971 Relocations against object symbols can happen, eg when
11972 referencing a global array. For an example of this see
11973 the _clz.o binary in libgcc.a. */
aca88567 11974 if (sym != symtab
55f25fc3 11975 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 11976 {
41e92641 11977 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 11978 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 11979 (long int)(rp - relocs),
74e1a04b 11980 printable_section_name (relsec));
aca88567 11981 continue;
5b18a4bc 11982 }
252b5132 11983
4dc3c23d
AM
11984 addend = 0;
11985 if (is_rela)
11986 addend += rp->r_addend;
c47320c3
AM
11987 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
11988 partial_inplace. */
4dc3c23d
AM
11989 if (!is_rela
11990 || (elf_header.e_machine == EM_XTENSA
11991 && reloc_type == 1)
11992 || ((elf_header.e_machine == EM_PJ
11993 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
11994 && reloc_type == 1)
11995 || ((elf_header.e_machine == EM_D30V
11996 || elf_header.e_machine == EM_CYGNUS_D30V)
11997 && reloc_type == 12))
91d6fa6a 11998 addend += byte_get (rloc, reloc_size);
cb8f3167 11999
85acf597
RH
12000 if (is_32bit_pcrel_reloc (reloc_type)
12001 || is_64bit_pcrel_reloc (reloc_type))
12002 {
12003 /* On HPPA, all pc-relative relocations are biased by 8. */
12004 if (elf_header.e_machine == EM_PARISC)
12005 addend -= 8;
91d6fa6a 12006 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
12007 reloc_size);
12008 }
41e92641 12009 else
91d6fa6a 12010 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 12011 }
252b5132 12012
5b18a4bc 12013 free (symtab);
d1c4b12b
NC
12014
12015 if (relocs_return)
12016 {
12017 * (Elf_Internal_Rela **) relocs_return = relocs;
12018 * num_relocs_return = num_relocs;
12019 }
12020 else
12021 free (relocs);
12022
5b18a4bc
NC
12023 break;
12024 }
5b18a4bc 12025}
103f02d3 12026
cf13d699
NC
12027#ifdef SUPPORT_DISASSEMBLY
12028static int
12029disassemble_section (Elf_Internal_Shdr * section, FILE * file)
12030{
74e1a04b 12031 printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
cf13d699 12032
74e1a04b 12033 /* FIXME: XXX -- to be done --- XXX */
cf13d699
NC
12034
12035 return 1;
12036}
12037#endif
12038
12039/* Reads in the contents of SECTION from FILE, returning a pointer
12040 to a malloc'ed buffer or NULL if something went wrong. */
12041
12042static char *
12043get_section_contents (Elf_Internal_Shdr * section, FILE * file)
12044{
12045 bfd_size_type num_bytes;
12046
12047 num_bytes = section->sh_size;
12048
12049 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
12050 {
12051 printf (_("\nSection '%s' has no data to dump.\n"),
74e1a04b 12052 printable_section_name (section));
cf13d699
NC
12053 return NULL;
12054 }
12055
3f5e193b
NC
12056 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
12057 _("section contents"));
cf13d699
NC
12058}
12059
0e602686
NC
12060/* Uncompresses a section that was compressed using zlib, in place. */
12061
12062static bfd_boolean
12063uncompress_section_contents (unsigned char **buffer,
12064 dwarf_size_type uncompressed_size,
12065 dwarf_size_type *size)
12066{
12067 dwarf_size_type compressed_size = *size;
12068 unsigned char * compressed_buffer = *buffer;
12069 unsigned char * uncompressed_buffer;
12070 z_stream strm;
12071 int rc;
12072
12073 /* It is possible the section consists of several compressed
12074 buffers concatenated together, so we uncompress in a loop. */
12075 /* PR 18313: The state field in the z_stream structure is supposed
12076 to be invisible to the user (ie us), but some compilers will
12077 still complain about it being used without initialisation. So
12078 we first zero the entire z_stream structure and then set the fields
12079 that we need. */
12080 memset (& strm, 0, sizeof strm);
12081 strm.avail_in = compressed_size;
12082 strm.next_in = (Bytef *) compressed_buffer;
12083 strm.avail_out = uncompressed_size;
12084 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
12085
12086 rc = inflateInit (& strm);
12087 while (strm.avail_in > 0)
12088 {
12089 if (rc != Z_OK)
12090 goto fail;
12091 strm.next_out = ((Bytef *) uncompressed_buffer
12092 + (uncompressed_size - strm.avail_out));
12093 rc = inflate (&strm, Z_FINISH);
12094 if (rc != Z_STREAM_END)
12095 goto fail;
12096 rc = inflateReset (& strm);
12097 }
12098 rc = inflateEnd (& strm);
12099 if (rc != Z_OK
12100 || strm.avail_out != 0)
12101 goto fail;
12102
12103 *buffer = uncompressed_buffer;
12104 *size = uncompressed_size;
12105 return TRUE;
12106
12107 fail:
12108 free (uncompressed_buffer);
12109 /* Indicate decompression failure. */
12110 *buffer = NULL;
12111 return FALSE;
12112}
dd24e3da 12113
cf13d699
NC
12114static void
12115dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
12116{
0e602686
NC
12117 Elf_Internal_Shdr * relsec;
12118 bfd_size_type num_bytes;
fd8008d8
L
12119 unsigned char * data;
12120 unsigned char * end;
12121 unsigned char * real_start;
12122 unsigned char * start;
0e602686 12123 bfd_boolean some_strings_shown;
cf13d699 12124
fd8008d8
L
12125 real_start = start = (unsigned char *) get_section_contents (section,
12126 file);
cf13d699
NC
12127 if (start == NULL)
12128 return;
0e602686 12129 num_bytes = section->sh_size;
cf13d699 12130
74e1a04b 12131 printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
cf13d699 12132
0e602686
NC
12133 if (decompress_dumps)
12134 {
12135 dwarf_size_type new_size = num_bytes;
12136 dwarf_size_type uncompressed_size = 0;
12137
12138 if ((section->sh_flags & SHF_COMPRESSED) != 0)
12139 {
12140 Elf_Internal_Chdr chdr;
12141 unsigned int compression_header_size
12142 = get_compression_header (& chdr, (unsigned char *) start);
12143
813dabb9 12144 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 12145 {
813dabb9
L
12146 warn (_("section '%s' has unsupported compress type: %d\n"),
12147 printable_section_name (section), chdr.ch_type);
12148 return;
12149 }
12150 else if (chdr.ch_addralign != section->sh_addralign)
12151 {
12152 warn (_("compressed section '%s' is corrupted\n"),
12153 printable_section_name (section));
12154 return;
0e602686 12155 }
813dabb9
L
12156 uncompressed_size = chdr.ch_size;
12157 start += compression_header_size;
12158 new_size -= compression_header_size;
0e602686
NC
12159 }
12160 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
12161 {
12162 /* Read the zlib header. In this case, it should be "ZLIB"
12163 followed by the uncompressed section size, 8 bytes in
12164 big-endian order. */
12165 uncompressed_size = start[4]; uncompressed_size <<= 8;
12166 uncompressed_size += start[5]; uncompressed_size <<= 8;
12167 uncompressed_size += start[6]; uncompressed_size <<= 8;
12168 uncompressed_size += start[7]; uncompressed_size <<= 8;
12169 uncompressed_size += start[8]; uncompressed_size <<= 8;
12170 uncompressed_size += start[9]; uncompressed_size <<= 8;
12171 uncompressed_size += start[10]; uncompressed_size <<= 8;
12172 uncompressed_size += start[11];
12173 start += 12;
12174 new_size -= 12;
12175 }
12176
12177 if (uncompressed_size
fd8008d8 12178 && uncompress_section_contents (& start,
0e602686
NC
12179 uncompressed_size, & new_size))
12180 num_bytes = new_size;
12181 }
fd8008d8 12182
cf13d699
NC
12183 /* If the section being dumped has relocations against it the user might
12184 be expecting these relocations to have been applied. Check for this
12185 case and issue a warning message in order to avoid confusion.
12186 FIXME: Maybe we ought to have an option that dumps a section with
12187 relocs applied ? */
12188 for (relsec = section_headers;
12189 relsec < section_headers + elf_header.e_shnum;
12190 ++relsec)
12191 {
12192 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
12193 || relsec->sh_info >= elf_header.e_shnum
12194 || section_headers + relsec->sh_info != section
12195 || relsec->sh_size == 0
12196 || relsec->sh_link >= elf_header.e_shnum)
12197 continue;
12198
12199 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
12200 break;
12201 }
12202
cf13d699
NC
12203 data = start;
12204 end = start + num_bytes;
12205 some_strings_shown = FALSE;
12206
12207 while (data < end)
12208 {
12209 while (!ISPRINT (* data))
12210 if (++ data >= end)
12211 break;
12212
12213 if (data < end)
12214 {
071436c6
NC
12215 size_t maxlen = end - data;
12216
cf13d699 12217#ifndef __MSVCRT__
c975cc98
NC
12218 /* PR 11128: Use two separate invocations in order to work
12219 around bugs in the Solaris 8 implementation of printf. */
12220 printf (" [%6tx] ", data - start);
cf13d699 12221#else
071436c6 12222 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 12223#endif
4082ef84
NC
12224 if (maxlen > 0)
12225 {
fd8008d8 12226 print_symbol ((int) maxlen, (const char *) data);
4082ef84 12227 putchar ('\n');
fd8008d8 12228 data += strnlen ((const char *) data, maxlen);
4082ef84
NC
12229 }
12230 else
12231 {
12232 printf (_("<corrupt>\n"));
12233 data = end;
12234 }
cf13d699
NC
12235 some_strings_shown = TRUE;
12236 }
12237 }
12238
12239 if (! some_strings_shown)
12240 printf (_(" No strings found in this section."));
12241
0e602686 12242 free (real_start);
cf13d699
NC
12243
12244 putchar ('\n');
12245}
12246
12247static void
12248dump_section_as_bytes (Elf_Internal_Shdr * section,
12249 FILE * file,
12250 bfd_boolean relocate)
12251{
12252 Elf_Internal_Shdr * relsec;
0e602686
NC
12253 bfd_size_type bytes;
12254 bfd_size_type section_size;
12255 bfd_vma addr;
12256 unsigned char * data;
12257 unsigned char * real_start;
12258 unsigned char * start;
12259
12260 real_start = start = (unsigned char *) get_section_contents (section, file);
cf13d699
NC
12261 if (start == NULL)
12262 return;
0e602686 12263 section_size = section->sh_size;
cf13d699 12264
74e1a04b 12265 printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
cf13d699 12266
0e602686
NC
12267 if (decompress_dumps)
12268 {
12269 dwarf_size_type new_size = section_size;
12270 dwarf_size_type uncompressed_size = 0;
12271
12272 if ((section->sh_flags & SHF_COMPRESSED) != 0)
12273 {
12274 Elf_Internal_Chdr chdr;
12275 unsigned int compression_header_size
12276 = get_compression_header (& chdr, start);
12277
813dabb9 12278 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 12279 {
813dabb9
L
12280 warn (_("section '%s' has unsupported compress type: %d\n"),
12281 printable_section_name (section), chdr.ch_type);
12282 return;
0e602686 12283 }
813dabb9
L
12284 else if (chdr.ch_addralign != section->sh_addralign)
12285 {
12286 warn (_("compressed section '%s' is corrupted\n"),
12287 printable_section_name (section));
12288 return;
12289 }
12290 uncompressed_size = chdr.ch_size;
12291 start += compression_header_size;
12292 new_size -= compression_header_size;
0e602686
NC
12293 }
12294 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
12295 {
12296 /* Read the zlib header. In this case, it should be "ZLIB"
12297 followed by the uncompressed section size, 8 bytes in
12298 big-endian order. */
12299 uncompressed_size = start[4]; uncompressed_size <<= 8;
12300 uncompressed_size += start[5]; uncompressed_size <<= 8;
12301 uncompressed_size += start[6]; uncompressed_size <<= 8;
12302 uncompressed_size += start[7]; uncompressed_size <<= 8;
12303 uncompressed_size += start[8]; uncompressed_size <<= 8;
12304 uncompressed_size += start[9]; uncompressed_size <<= 8;
12305 uncompressed_size += start[10]; uncompressed_size <<= 8;
12306 uncompressed_size += start[11];
12307 start += 12;
12308 new_size -= 12;
12309 }
12310
12311 if (uncompressed_size
12312 && uncompress_section_contents (& start, uncompressed_size,
12313 & new_size))
12314 section_size = new_size;
12315 }
14ae95f2 12316
cf13d699
NC
12317 if (relocate)
12318 {
0e602686 12319 apply_relocations (file, section, start, section_size, NULL, NULL);
cf13d699
NC
12320 }
12321 else
12322 {
12323 /* If the section being dumped has relocations against it the user might
12324 be expecting these relocations to have been applied. Check for this
12325 case and issue a warning message in order to avoid confusion.
12326 FIXME: Maybe we ought to have an option that dumps a section with
12327 relocs applied ? */
12328 for (relsec = section_headers;
12329 relsec < section_headers + elf_header.e_shnum;
12330 ++relsec)
12331 {
12332 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
12333 || relsec->sh_info >= elf_header.e_shnum
12334 || section_headers + relsec->sh_info != section
12335 || relsec->sh_size == 0
12336 || relsec->sh_link >= elf_header.e_shnum)
12337 continue;
12338
12339 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
12340 break;
12341 }
12342 }
12343
12344 addr = section->sh_addr;
0e602686 12345 bytes = section_size;
cf13d699
NC
12346 data = start;
12347
12348 while (bytes)
12349 {
12350 int j;
12351 int k;
12352 int lbytes;
12353
12354 lbytes = (bytes > 16 ? 16 : bytes);
12355
12356 printf (" 0x%8.8lx ", (unsigned long) addr);
12357
12358 for (j = 0; j < 16; j++)
12359 {
12360 if (j < lbytes)
12361 printf ("%2.2x", data[j]);
12362 else
12363 printf (" ");
12364
12365 if ((j & 3) == 3)
12366 printf (" ");
12367 }
12368
12369 for (j = 0; j < lbytes; j++)
12370 {
12371 k = data[j];
12372 if (k >= ' ' && k < 0x7f)
12373 printf ("%c", k);
12374 else
12375 printf (".");
12376 }
12377
12378 putchar ('\n');
12379
12380 data += lbytes;
12381 addr += lbytes;
12382 bytes -= lbytes;
12383 }
12384
0e602686 12385 free (real_start);
cf13d699
NC
12386
12387 putchar ('\n');
12388}
12389
d966045b
DJ
12390static int
12391load_specific_debug_section (enum dwarf_section_display_enum debug,
0d2a7a93 12392 const Elf_Internal_Shdr * sec, void * file)
1007acb3 12393{
2cf0635d 12394 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 12395 char buf [64];
1007acb3 12396
19e6b90e
L
12397 /* If it is already loaded, do nothing. */
12398 if (section->start != NULL)
12399 return 1;
1007acb3 12400
19e6b90e
L
12401 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
12402 section->address = sec->sh_addr;
06614111 12403 section->user_data = NULL;
3f5e193b
NC
12404 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
12405 sec->sh_offset, 1,
12406 sec->sh_size, buf);
59245841
NC
12407 if (section->start == NULL)
12408 section->size = 0;
12409 else
12410 {
77115a4a
L
12411 unsigned char *start = section->start;
12412 dwarf_size_type size = sec->sh_size;
dab394de 12413 dwarf_size_type uncompressed_size = 0;
77115a4a
L
12414
12415 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
12416 {
12417 Elf_Internal_Chdr chdr;
12418 unsigned int compression_header_size
12419 = get_compression_header (&chdr, start);
813dabb9
L
12420 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
12421 {
12422 warn (_("section '%s' has unsupported compress type: %d\n"),
12423 section->name, chdr.ch_type);
12424 return 0;
12425 }
12426 else if (chdr.ch_addralign != sec->sh_addralign)
12427 {
12428 warn (_("compressed section '%s' is corrupted\n"),
12429 section->name);
12430 return 0;
12431 }
dab394de 12432 uncompressed_size = chdr.ch_size;
77115a4a
L
12433 start += compression_header_size;
12434 size -= compression_header_size;
12435 }
dab394de
L
12436 else if (size > 12 && streq ((char *) start, "ZLIB"))
12437 {
12438 /* Read the zlib header. In this case, it should be "ZLIB"
12439 followed by the uncompressed section size, 8 bytes in
12440 big-endian order. */
12441 uncompressed_size = start[4]; uncompressed_size <<= 8;
12442 uncompressed_size += start[5]; uncompressed_size <<= 8;
12443 uncompressed_size += start[6]; uncompressed_size <<= 8;
12444 uncompressed_size += start[7]; uncompressed_size <<= 8;
12445 uncompressed_size += start[8]; uncompressed_size <<= 8;
12446 uncompressed_size += start[9]; uncompressed_size <<= 8;
12447 uncompressed_size += start[10]; uncompressed_size <<= 8;
12448 uncompressed_size += start[11];
12449 start += 12;
12450 size -= 12;
12451 }
12452
12453 if (uncompressed_size
12454 && uncompress_section_contents (&start, uncompressed_size,
12455 &size))
77115a4a
L
12456 {
12457 /* Free the compressed buffer, update the section buffer
12458 and the section size if uncompress is successful. */
12459 free (section->start);
12460 section->start = start;
77115a4a
L
12461 }
12462 section->size = size;
59245841 12463 }
4a114e3e 12464
1b315056
CS
12465 if (section->start == NULL)
12466 return 0;
12467
19e6b90e 12468 if (debug_displays [debug].relocate)
d1c4b12b
NC
12469 apply_relocations ((FILE *) file, sec, section->start, section->size,
12470 & section->reloc_info, & section->num_relocs);
12471 else
12472 {
12473 section->reloc_info = NULL;
12474 section->num_relocs = 0;
12475 }
1007acb3 12476
1b315056 12477 return 1;
1007acb3
L
12478}
12479
657d0d47
CC
12480/* If this is not NULL, load_debug_section will only look for sections
12481 within the list of sections given here. */
12482unsigned int *section_subset = NULL;
12483
d966045b 12484int
2cf0635d 12485load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 12486{
2cf0635d
NC
12487 struct dwarf_section * section = &debug_displays [debug].section;
12488 Elf_Internal_Shdr * sec;
d966045b
DJ
12489
12490 /* Locate the debug section. */
657d0d47 12491 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
12492 if (sec != NULL)
12493 section->name = section->uncompressed_name;
12494 else
12495 {
657d0d47 12496 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
12497 if (sec != NULL)
12498 section->name = section->compressed_name;
12499 }
12500 if (sec == NULL)
12501 return 0;
12502
657d0d47
CC
12503 /* If we're loading from a subset of sections, and we've loaded
12504 a section matching this name before, it's likely that it's a
12505 different one. */
12506 if (section_subset != NULL)
12507 free_debug_section (debug);
12508
3f5e193b 12509 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
12510}
12511
19e6b90e
L
12512void
12513free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 12514{
2cf0635d 12515 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 12516
19e6b90e
L
12517 if (section->start == NULL)
12518 return;
1007acb3 12519
19e6b90e
L
12520 free ((char *) section->start);
12521 section->start = NULL;
12522 section->address = 0;
12523 section->size = 0;
1007acb3
L
12524}
12525
1007acb3 12526static int
657d0d47 12527display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 12528{
2cf0635d 12529 char * name = SECTION_NAME (section);
74e1a04b 12530 const char * print_name = printable_section_name (section);
19e6b90e
L
12531 bfd_size_type length;
12532 int result = 1;
3f5e193b 12533 int i;
1007acb3 12534
19e6b90e
L
12535 length = section->sh_size;
12536 if (length == 0)
1007acb3 12537 {
74e1a04b 12538 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
19e6b90e 12539 return 0;
1007acb3 12540 }
5dff79d8
NC
12541 if (section->sh_type == SHT_NOBITS)
12542 {
12543 /* There is no point in dumping the contents of a debugging section
12544 which has the NOBITS type - the bits in the file will be random.
12545 This can happen when a file containing a .eh_frame section is
12546 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
12547 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
12548 print_name);
5dff79d8
NC
12549 return 0;
12550 }
1007acb3 12551
0112cd26 12552 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 12553 name = ".debug_info";
1007acb3 12554
19e6b90e
L
12555 /* See if we know how to display the contents of this section. */
12556 for (i = 0; i < max; i++)
1b315056 12557 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 12558 || (i == line && const_strneq (name, ".debug_line."))
1b315056 12559 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 12560 {
2cf0635d 12561 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
12562 int secondary = (section != find_section (name));
12563
12564 if (secondary)
3f5e193b 12565 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 12566
b40bf0a2
NC
12567 if (i == line && const_strneq (name, ".debug_line."))
12568 sec->name = name;
12569 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
12570 sec->name = sec->uncompressed_name;
12571 else
12572 sec->name = sec->compressed_name;
3f5e193b
NC
12573 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
12574 section, file))
19e6b90e 12575 {
657d0d47
CC
12576 /* If this debug section is part of a CU/TU set in a .dwp file,
12577 restrict load_debug_section to the sections in that set. */
12578 section_subset = find_cu_tu_set (file, shndx);
12579
19e6b90e 12580 result &= debug_displays[i].display (sec, file);
1007acb3 12581
657d0d47
CC
12582 section_subset = NULL;
12583
d966045b 12584 if (secondary || (i != info && i != abbrev))
3f5e193b 12585 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 12586 }
1007acb3 12587
19e6b90e
L
12588 break;
12589 }
1007acb3 12590
19e6b90e 12591 if (i == max)
1007acb3 12592 {
74e1a04b 12593 printf (_("Unrecognized debug section: %s\n"), print_name);
19e6b90e 12594 result = 0;
1007acb3
L
12595 }
12596
19e6b90e 12597 return result;
5b18a4bc 12598}
103f02d3 12599
aef1f6d0
DJ
12600/* Set DUMP_SECTS for all sections where dumps were requested
12601 based on section name. */
12602
12603static void
12604initialise_dumps_byname (void)
12605{
2cf0635d 12606 struct dump_list_entry * cur;
aef1f6d0
DJ
12607
12608 for (cur = dump_sects_byname; cur; cur = cur->next)
12609 {
12610 unsigned int i;
12611 int any;
12612
12613 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
12614 if (streq (SECTION_NAME (section_headers + i), cur->name))
12615 {
09c11c86 12616 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
12617 any = 1;
12618 }
12619
12620 if (!any)
12621 warn (_("Section '%s' was not dumped because it does not exist!\n"),
12622 cur->name);
12623 }
12624}
12625
5b18a4bc 12626static void
2cf0635d 12627process_section_contents (FILE * file)
5b18a4bc 12628{
2cf0635d 12629 Elf_Internal_Shdr * section;
19e6b90e 12630 unsigned int i;
103f02d3 12631
19e6b90e
L
12632 if (! do_dump)
12633 return;
103f02d3 12634
aef1f6d0
DJ
12635 initialise_dumps_byname ();
12636
19e6b90e
L
12637 for (i = 0, section = section_headers;
12638 i < elf_header.e_shnum && i < num_dump_sects;
12639 i++, section++)
12640 {
12641#ifdef SUPPORT_DISASSEMBLY
12642 if (dump_sects[i] & DISASS_DUMP)
12643 disassemble_section (section, file);
12644#endif
12645 if (dump_sects[i] & HEX_DUMP)
cf13d699 12646 dump_section_as_bytes (section, file, FALSE);
103f02d3 12647
cf13d699
NC
12648 if (dump_sects[i] & RELOC_DUMP)
12649 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
12650
12651 if (dump_sects[i] & STRING_DUMP)
12652 dump_section_as_strings (section, file);
cf13d699
NC
12653
12654 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 12655 display_debug_section (i, section, file);
5b18a4bc 12656 }
103f02d3 12657
19e6b90e
L
12658 /* Check to see if the user requested a
12659 dump of a section that does not exist. */
12660 while (i++ < num_dump_sects)
12661 if (dump_sects[i])
12662 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 12663}
103f02d3 12664
5b18a4bc 12665static void
19e6b90e 12666process_mips_fpe_exception (int mask)
5b18a4bc 12667{
19e6b90e
L
12668 if (mask)
12669 {
12670 int first = 1;
12671 if (mask & OEX_FPU_INEX)
12672 fputs ("INEX", stdout), first = 0;
12673 if (mask & OEX_FPU_UFLO)
12674 printf ("%sUFLO", first ? "" : "|"), first = 0;
12675 if (mask & OEX_FPU_OFLO)
12676 printf ("%sOFLO", first ? "" : "|"), first = 0;
12677 if (mask & OEX_FPU_DIV0)
12678 printf ("%sDIV0", first ? "" : "|"), first = 0;
12679 if (mask & OEX_FPU_INVAL)
12680 printf ("%sINVAL", first ? "" : "|");
12681 }
5b18a4bc 12682 else
19e6b90e 12683 fputs ("0", stdout);
5b18a4bc 12684}
103f02d3 12685
f6f0e17b
NC
12686/* Display's the value of TAG at location P. If TAG is
12687 greater than 0 it is assumed to be an unknown tag, and
12688 a message is printed to this effect. Otherwise it is
12689 assumed that a message has already been printed.
12690
12691 If the bottom bit of TAG is set it assumed to have a
12692 string value, otherwise it is assumed to have an integer
12693 value.
12694
12695 Returns an updated P pointing to the first unread byte
12696 beyond the end of TAG's value.
12697
12698 Reads at or beyond END will not be made. */
12699
12700static unsigned char *
12701display_tag_value (int tag,
12702 unsigned char * p,
12703 const unsigned char * const end)
12704{
12705 unsigned long val;
12706
12707 if (tag > 0)
12708 printf (" Tag_unknown_%d: ", tag);
12709
12710 if (p >= end)
12711 {
4082ef84 12712 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
12713 }
12714 else if (tag & 1)
12715 {
071436c6
NC
12716 /* PR 17531 file: 027-19978-0.004. */
12717 size_t maxlen = (end - p) - 1;
12718
12719 putchar ('"');
4082ef84
NC
12720 if (maxlen > 0)
12721 {
12722 print_symbol ((int) maxlen, (const char *) p);
12723 p += strnlen ((char *) p, maxlen) + 1;
12724 }
12725 else
12726 {
12727 printf (_("<corrupt string tag>"));
12728 p = (unsigned char *) end;
12729 }
071436c6 12730 printf ("\"\n");
f6f0e17b
NC
12731 }
12732 else
12733 {
12734 unsigned int len;
12735
12736 val = read_uleb128 (p, &len, end);
12737 p += len;
12738 printf ("%ld (0x%lx)\n", val, val);
12739 }
12740
4082ef84 12741 assert (p <= end);
f6f0e17b
NC
12742 return p;
12743}
12744
11c1ff18
PB
12745/* ARM EABI attributes section. */
12746typedef struct
12747{
70e99720 12748 unsigned int tag;
2cf0635d 12749 const char * name;
11c1ff18 12750 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 12751 unsigned int type;
2cf0635d 12752 const char ** table;
11c1ff18
PB
12753} arm_attr_public_tag;
12754
2cf0635d 12755static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 12756 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ff8646ee
TP
12757 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "", "v8-M.baseline",
12758 "v8-M.mainline"};
2cf0635d
NC
12759static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
12760static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 12761 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 12762static const char * arm_attr_tag_FP_arch[] =
bca38921 12763 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 12764 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 12765static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 12766static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 12767 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 12768static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
12769 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
12770 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 12771static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 12772 {"V6", "SB", "TLS", "Unused"};
2cf0635d 12773static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 12774 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 12775static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 12776 {"Absolute", "PC-relative", "None"};
2cf0635d 12777static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 12778 {"None", "direct", "GOT-indirect"};
2cf0635d 12779static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 12780 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
12781static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
12782static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 12783 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
12784static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
12785static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
12786static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 12787 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 12788static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 12789 {"Unused", "small", "int", "forced to int"};
2cf0635d 12790static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 12791 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 12792static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 12793 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 12794static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 12795 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 12796static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
12797 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12798 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 12799static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
12800 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12801 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 12802static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 12803static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 12804 {"Not Allowed", "Allowed"};
2cf0635d 12805static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 12806 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 12807static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
12808 {"Not Allowed", "Allowed"};
12809static const char * arm_attr_tag_DIV_use[] =
dd24e3da 12810 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 12811 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
12812static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
12813static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 12814 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 12815 "TrustZone and Virtualization Extensions"};
dd24e3da 12816static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 12817 {"Not Allowed", "Allowed"};
11c1ff18
PB
12818
12819#define LOOKUP(id, name) \
12820 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 12821static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
12822{
12823 {4, "CPU_raw_name", 1, NULL},
12824 {5, "CPU_name", 1, NULL},
12825 LOOKUP(6, CPU_arch),
12826 {7, "CPU_arch_profile", 0, NULL},
12827 LOOKUP(8, ARM_ISA_use),
12828 LOOKUP(9, THUMB_ISA_use),
75375b3e 12829 LOOKUP(10, FP_arch),
11c1ff18 12830 LOOKUP(11, WMMX_arch),
f5f53991
AS
12831 LOOKUP(12, Advanced_SIMD_arch),
12832 LOOKUP(13, PCS_config),
11c1ff18
PB
12833 LOOKUP(14, ABI_PCS_R9_use),
12834 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 12835 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
12836 LOOKUP(17, ABI_PCS_GOT_use),
12837 LOOKUP(18, ABI_PCS_wchar_t),
12838 LOOKUP(19, ABI_FP_rounding),
12839 LOOKUP(20, ABI_FP_denormal),
12840 LOOKUP(21, ABI_FP_exceptions),
12841 LOOKUP(22, ABI_FP_user_exceptions),
12842 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
12843 {24, "ABI_align_needed", 0, NULL},
12844 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
12845 LOOKUP(26, ABI_enum_size),
12846 LOOKUP(27, ABI_HardFP_use),
12847 LOOKUP(28, ABI_VFP_args),
12848 LOOKUP(29, ABI_WMMX_args),
12849 LOOKUP(30, ABI_optimization_goals),
12850 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 12851 {32, "compatibility", 0, NULL},
f5f53991 12852 LOOKUP(34, CPU_unaligned_access),
75375b3e 12853 LOOKUP(36, FP_HP_extension),
8e79c3df 12854 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
12855 LOOKUP(42, MPextension_use),
12856 LOOKUP(44, DIV_use),
f5f53991
AS
12857 {64, "nodefaults", 0, NULL},
12858 {65, "also_compatible_with", 0, NULL},
12859 LOOKUP(66, T2EE_use),
12860 {67, "conformance", 1, NULL},
12861 LOOKUP(68, Virtualization_use),
cd21e546 12862 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
12863};
12864#undef LOOKUP
12865
11c1ff18 12866static unsigned char *
f6f0e17b
NC
12867display_arm_attribute (unsigned char * p,
12868 const unsigned char * const end)
11c1ff18 12869{
70e99720 12870 unsigned int tag;
11c1ff18 12871 unsigned int len;
70e99720 12872 unsigned int val;
2cf0635d 12873 arm_attr_public_tag * attr;
11c1ff18 12874 unsigned i;
70e99720 12875 unsigned int type;
11c1ff18 12876
f6f0e17b 12877 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
12878 p += len;
12879 attr = NULL;
2cf0635d 12880 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
12881 {
12882 if (arm_attr_public_tags[i].tag == tag)
12883 {
12884 attr = &arm_attr_public_tags[i];
12885 break;
12886 }
12887 }
12888
12889 if (attr)
12890 {
12891 printf (" Tag_%s: ", attr->name);
12892 switch (attr->type)
12893 {
12894 case 0:
12895 switch (tag)
12896 {
12897 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 12898 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12899 p += len;
12900 switch (val)
12901 {
2b692964
NC
12902 case 0: printf (_("None\n")); break;
12903 case 'A': printf (_("Application\n")); break;
12904 case 'R': printf (_("Realtime\n")); break;
12905 case 'M': printf (_("Microcontroller\n")); break;
12906 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
12907 default: printf ("??? (%d)\n", val); break;
12908 }
12909 break;
12910
75375b3e 12911 case 24: /* Tag_align_needed. */
f6f0e17b 12912 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12913 p += len;
12914 switch (val)
12915 {
2b692964
NC
12916 case 0: printf (_("None\n")); break;
12917 case 1: printf (_("8-byte\n")); break;
12918 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
12919 case 3: printf ("??? 3\n"); break;
12920 default:
12921 if (val <= 12)
dd24e3da 12922 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12923 1 << val);
12924 else
12925 printf ("??? (%d)\n", val);
12926 break;
12927 }
12928 break;
12929
12930 case 25: /* Tag_align_preserved. */
f6f0e17b 12931 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12932 p += len;
12933 switch (val)
12934 {
2b692964
NC
12935 case 0: printf (_("None\n")); break;
12936 case 1: printf (_("8-byte, except leaf SP\n")); break;
12937 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
12938 case 3: printf ("??? 3\n"); break;
12939 default:
12940 if (val <= 12)
dd24e3da 12941 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12942 1 << val);
12943 else
12944 printf ("??? (%d)\n", val);
12945 break;
12946 }
12947 break;
12948
11c1ff18 12949 case 32: /* Tag_compatibility. */
071436c6 12950 {
071436c6
NC
12951 val = read_uleb128 (p, &len, end);
12952 p += len;
071436c6 12953 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12954 if (p < end - 1)
12955 {
12956 size_t maxlen = (end - p) - 1;
12957
12958 print_symbol ((int) maxlen, (const char *) p);
12959 p += strnlen ((char *) p, maxlen) + 1;
12960 }
12961 else
12962 {
12963 printf (_("<corrupt>"));
12964 p = (unsigned char *) end;
12965 }
071436c6 12966 putchar ('\n');
071436c6 12967 }
11c1ff18
PB
12968 break;
12969
f5f53991 12970 case 64: /* Tag_nodefaults. */
541a3cbd
NC
12971 /* PR 17531: file: 001-505008-0.01. */
12972 if (p < end)
12973 p++;
2b692964 12974 printf (_("True\n"));
f5f53991
AS
12975 break;
12976
12977 case 65: /* Tag_also_compatible_with. */
f6f0e17b 12978 val = read_uleb128 (p, &len, end);
f5f53991
AS
12979 p += len;
12980 if (val == 6 /* Tag_CPU_arch. */)
12981 {
f6f0e17b 12982 val = read_uleb128 (p, &len, end);
f5f53991 12983 p += len;
071436c6 12984 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
12985 printf ("??? (%d)\n", val);
12986 else
12987 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
12988 }
12989 else
12990 printf ("???\n");
071436c6
NC
12991 while (p < end && *(p++) != '\0' /* NUL terminator. */)
12992 ;
f5f53991
AS
12993 break;
12994
11c1ff18 12995 default:
bee0ee85
NC
12996 printf (_("<unknown: %d>\n"), tag);
12997 break;
11c1ff18
PB
12998 }
12999 return p;
13000
13001 case 1:
f6f0e17b 13002 return display_tag_value (-1, p, end);
11c1ff18 13003 case 2:
f6f0e17b 13004 return display_tag_value (0, p, end);
11c1ff18
PB
13005
13006 default:
13007 assert (attr->type & 0x80);
f6f0e17b 13008 val = read_uleb128 (p, &len, end);
11c1ff18
PB
13009 p += len;
13010 type = attr->type & 0x7f;
13011 if (val >= type)
13012 printf ("??? (%d)\n", val);
13013 else
13014 printf ("%s\n", attr->table[val]);
13015 return p;
13016 }
13017 }
11c1ff18 13018
f6f0e17b 13019 return display_tag_value (tag, p, end);
11c1ff18
PB
13020}
13021
104d59d1 13022static unsigned char *
60bca95a 13023display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
13024 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
13025 const unsigned char * const end)
104d59d1
JM
13026{
13027 int tag;
13028 unsigned int len;
13029 int val;
104d59d1 13030
f6f0e17b 13031 tag = read_uleb128 (p, &len, end);
104d59d1
JM
13032 p += len;
13033
13034 /* Tag_compatibility is the only generic GNU attribute defined at
13035 present. */
13036 if (tag == 32)
13037 {
f6f0e17b 13038 val = read_uleb128 (p, &len, end);
104d59d1 13039 p += len;
071436c6
NC
13040
13041 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
13042 if (p == end)
13043 {
071436c6 13044 printf (_("<corrupt>\n"));
f6f0e17b
NC
13045 warn (_("corrupt vendor attribute\n"));
13046 }
13047 else
13048 {
4082ef84
NC
13049 if (p < end - 1)
13050 {
13051 size_t maxlen = (end - p) - 1;
071436c6 13052
4082ef84
NC
13053 print_symbol ((int) maxlen, (const char *) p);
13054 p += strnlen ((char *) p, maxlen) + 1;
13055 }
13056 else
13057 {
13058 printf (_("<corrupt>"));
13059 p = (unsigned char *) end;
13060 }
071436c6 13061 putchar ('\n');
f6f0e17b 13062 }
104d59d1
JM
13063 return p;
13064 }
13065
13066 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 13067 return display_proc_gnu_attribute (p, tag, end);
104d59d1 13068
f6f0e17b 13069 return display_tag_value (tag, p, end);
104d59d1
JM
13070}
13071
34c8bcba 13072static unsigned char *
f6f0e17b
NC
13073display_power_gnu_attribute (unsigned char * p,
13074 int tag,
13075 const unsigned char * const end)
34c8bcba 13076{
34c8bcba
JM
13077 unsigned int len;
13078 int val;
13079
13080 if (tag == Tag_GNU_Power_ABI_FP)
13081 {
f6f0e17b 13082 val = read_uleb128 (p, &len, end);
34c8bcba
JM
13083 p += len;
13084 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 13085
34c8bcba
JM
13086 switch (val)
13087 {
13088 case 0:
2b692964 13089 printf (_("Hard or soft float\n"));
34c8bcba
JM
13090 break;
13091 case 1:
2b692964 13092 printf (_("Hard float\n"));
34c8bcba
JM
13093 break;
13094 case 2:
2b692964 13095 printf (_("Soft float\n"));
34c8bcba 13096 break;
3c7b9897 13097 case 3:
2b692964 13098 printf (_("Single-precision hard float\n"));
3c7b9897 13099 break;
34c8bcba
JM
13100 default:
13101 printf ("??? (%d)\n", val);
13102 break;
13103 }
13104 return p;
13105 }
13106
c6e65352
DJ
13107 if (tag == Tag_GNU_Power_ABI_Vector)
13108 {
f6f0e17b 13109 val = read_uleb128 (p, &len, end);
c6e65352
DJ
13110 p += len;
13111 printf (" Tag_GNU_Power_ABI_Vector: ");
13112 switch (val)
13113 {
13114 case 0:
2b692964 13115 printf (_("Any\n"));
c6e65352
DJ
13116 break;
13117 case 1:
2b692964 13118 printf (_("Generic\n"));
c6e65352
DJ
13119 break;
13120 case 2:
13121 printf ("AltiVec\n");
13122 break;
13123 case 3:
13124 printf ("SPE\n");
13125 break;
13126 default:
13127 printf ("??? (%d)\n", val);
13128 break;
13129 }
13130 return p;
13131 }
13132
f82e0623
NF
13133 if (tag == Tag_GNU_Power_ABI_Struct_Return)
13134 {
f6f0e17b
NC
13135 if (p == end)
13136 {
071436c6 13137 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return\n"));
f6f0e17b
NC
13138 return p;
13139 }
0b4362b0 13140
f6f0e17b 13141 val = read_uleb128 (p, &len, end);
f82e0623
NF
13142 p += len;
13143 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
13144 switch (val)
13145 {
13146 case 0:
2b692964 13147 printf (_("Any\n"));
f82e0623
NF
13148 break;
13149 case 1:
13150 printf ("r3/r4\n");
13151 break;
13152 case 2:
2b692964 13153 printf (_("Memory\n"));
f82e0623
NF
13154 break;
13155 default:
13156 printf ("??? (%d)\n", val);
13157 break;
13158 }
13159 return p;
13160 }
13161
f6f0e17b 13162 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
13163}
13164
643f7afb
AK
13165static unsigned char *
13166display_s390_gnu_attribute (unsigned char * p,
13167 int tag,
13168 const unsigned char * const end)
13169{
13170 unsigned int len;
13171 int val;
13172
13173 if (tag == Tag_GNU_S390_ABI_Vector)
13174 {
13175 val = read_uleb128 (p, &len, end);
13176 p += len;
13177 printf (" Tag_GNU_S390_ABI_Vector: ");
13178
13179 switch (val)
13180 {
13181 case 0:
13182 printf (_("any\n"));
13183 break;
13184 case 1:
13185 printf (_("software\n"));
13186 break;
13187 case 2:
13188 printf (_("hardware\n"));
13189 break;
13190 default:
13191 printf ("??? (%d)\n", val);
13192 break;
13193 }
13194 return p;
13195 }
13196
13197 return display_tag_value (tag & 1, p, end);
13198}
13199
9e8c70f9
DM
13200static void
13201display_sparc_hwcaps (int mask)
13202{
13203 if (mask)
13204 {
13205 int first = 1;
071436c6 13206
9e8c70f9
DM
13207 if (mask & ELF_SPARC_HWCAP_MUL32)
13208 fputs ("mul32", stdout), first = 0;
13209 if (mask & ELF_SPARC_HWCAP_DIV32)
13210 printf ("%sdiv32", first ? "" : "|"), first = 0;
13211 if (mask & ELF_SPARC_HWCAP_FSMULD)
13212 printf ("%sfsmuld", first ? "" : "|"), first = 0;
13213 if (mask & ELF_SPARC_HWCAP_V8PLUS)
13214 printf ("%sv8plus", first ? "" : "|"), first = 0;
13215 if (mask & ELF_SPARC_HWCAP_POPC)
13216 printf ("%spopc", first ? "" : "|"), first = 0;
13217 if (mask & ELF_SPARC_HWCAP_VIS)
13218 printf ("%svis", first ? "" : "|"), first = 0;
13219 if (mask & ELF_SPARC_HWCAP_VIS2)
13220 printf ("%svis2", first ? "" : "|"), first = 0;
13221 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
13222 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
13223 if (mask & ELF_SPARC_HWCAP_FMAF)
13224 printf ("%sfmaf", first ? "" : "|"), first = 0;
13225 if (mask & ELF_SPARC_HWCAP_VIS3)
13226 printf ("%svis3", first ? "" : "|"), first = 0;
13227 if (mask & ELF_SPARC_HWCAP_HPC)
13228 printf ("%shpc", first ? "" : "|"), first = 0;
13229 if (mask & ELF_SPARC_HWCAP_RANDOM)
13230 printf ("%srandom", first ? "" : "|"), first = 0;
13231 if (mask & ELF_SPARC_HWCAP_TRANS)
13232 printf ("%strans", first ? "" : "|"), first = 0;
13233 if (mask & ELF_SPARC_HWCAP_FJFMAU)
13234 printf ("%sfjfmau", first ? "" : "|"), first = 0;
13235 if (mask & ELF_SPARC_HWCAP_IMA)
13236 printf ("%sima", first ? "" : "|"), first = 0;
13237 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
13238 printf ("%scspare", first ? "" : "|"), first = 0;
13239 }
13240 else
071436c6
NC
13241 fputc ('0', stdout);
13242 fputc ('\n', stdout);
9e8c70f9
DM
13243}
13244
3d68f91c
JM
13245static void
13246display_sparc_hwcaps2 (int mask)
13247{
13248 if (mask)
13249 {
13250 int first = 1;
071436c6 13251
3d68f91c
JM
13252 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
13253 fputs ("fjathplus", stdout), first = 0;
13254 if (mask & ELF_SPARC_HWCAP2_VIS3B)
13255 printf ("%svis3b", first ? "" : "|"), first = 0;
13256 if (mask & ELF_SPARC_HWCAP2_ADP)
13257 printf ("%sadp", first ? "" : "|"), first = 0;
13258 if (mask & ELF_SPARC_HWCAP2_SPARC5)
13259 printf ("%ssparc5", first ? "" : "|"), first = 0;
13260 if (mask & ELF_SPARC_HWCAP2_MWAIT)
13261 printf ("%smwait", first ? "" : "|"), first = 0;
13262 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
13263 printf ("%sxmpmul", first ? "" : "|"), first = 0;
13264 if (mask & ELF_SPARC_HWCAP2_XMONT)
13265 printf ("%sxmont2", first ? "" : "|"), first = 0;
13266 if (mask & ELF_SPARC_HWCAP2_NSEC)
13267 printf ("%snsec", first ? "" : "|"), first = 0;
13268 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
13269 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
13270 if (mask & ELF_SPARC_HWCAP2_FJDES)
13271 printf ("%sfjdes", first ? "" : "|"), first = 0;
13272 if (mask & ELF_SPARC_HWCAP2_FJAES)
13273 printf ("%sfjaes", first ? "" : "|"), first = 0;
13274 }
13275 else
071436c6
NC
13276 fputc ('0', stdout);
13277 fputc ('\n', stdout);
3d68f91c
JM
13278}
13279
9e8c70f9 13280static unsigned char *
f6f0e17b
NC
13281display_sparc_gnu_attribute (unsigned char * p,
13282 int tag,
13283 const unsigned char * const end)
9e8c70f9 13284{
3d68f91c
JM
13285 unsigned int len;
13286 int val;
13287
9e8c70f9
DM
13288 if (tag == Tag_GNU_Sparc_HWCAPS)
13289 {
f6f0e17b 13290 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
13291 p += len;
13292 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
13293 display_sparc_hwcaps (val);
13294 return p;
3d68f91c
JM
13295 }
13296 if (tag == Tag_GNU_Sparc_HWCAPS2)
13297 {
13298 val = read_uleb128 (p, &len, end);
13299 p += len;
13300 printf (" Tag_GNU_Sparc_HWCAPS2: ");
13301 display_sparc_hwcaps2 (val);
13302 return p;
13303 }
9e8c70f9 13304
f6f0e17b 13305 return display_tag_value (tag, p, end);
9e8c70f9
DM
13306}
13307
351cdf24
MF
13308static void
13309print_mips_fp_abi_value (int val)
13310{
13311 switch (val)
13312 {
13313 case Val_GNU_MIPS_ABI_FP_ANY:
13314 printf (_("Hard or soft float\n"));
13315 break;
13316 case Val_GNU_MIPS_ABI_FP_DOUBLE:
13317 printf (_("Hard float (double precision)\n"));
13318 break;
13319 case Val_GNU_MIPS_ABI_FP_SINGLE:
13320 printf (_("Hard float (single precision)\n"));
13321 break;
13322 case Val_GNU_MIPS_ABI_FP_SOFT:
13323 printf (_("Soft float\n"));
13324 break;
13325 case Val_GNU_MIPS_ABI_FP_OLD_64:
13326 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
13327 break;
13328 case Val_GNU_MIPS_ABI_FP_XX:
13329 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
13330 break;
13331 case Val_GNU_MIPS_ABI_FP_64:
13332 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
13333 break;
13334 case Val_GNU_MIPS_ABI_FP_64A:
13335 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
13336 break;
3350cc01
CM
13337 case Val_GNU_MIPS_ABI_FP_NAN2008:
13338 printf (_("NaN 2008 compatibility\n"));
13339 break;
351cdf24
MF
13340 default:
13341 printf ("??? (%d)\n", val);
13342 break;
13343 }
13344}
13345
2cf19d5c 13346static unsigned char *
f6f0e17b
NC
13347display_mips_gnu_attribute (unsigned char * p,
13348 int tag,
13349 const unsigned char * const end)
2cf19d5c 13350{
2cf19d5c
JM
13351 if (tag == Tag_GNU_MIPS_ABI_FP)
13352 {
f6f0e17b
NC
13353 unsigned int len;
13354 int val;
13355
13356 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
13357 p += len;
13358 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 13359
351cdf24
MF
13360 print_mips_fp_abi_value (val);
13361
2cf19d5c
JM
13362 return p;
13363 }
13364
a9f58168
CF
13365 if (tag == Tag_GNU_MIPS_ABI_MSA)
13366 {
13367 unsigned int len;
13368 int val;
13369
13370 val = read_uleb128 (p, &len, end);
13371 p += len;
13372 printf (" Tag_GNU_MIPS_ABI_MSA: ");
13373
13374 switch (val)
13375 {
13376 case Val_GNU_MIPS_ABI_MSA_ANY:
13377 printf (_("Any MSA or not\n"));
13378 break;
13379 case Val_GNU_MIPS_ABI_MSA_128:
13380 printf (_("128-bit MSA\n"));
13381 break;
13382 default:
13383 printf ("??? (%d)\n", val);
13384 break;
13385 }
13386 return p;
13387 }
13388
f6f0e17b 13389 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
13390}
13391
59e6276b 13392static unsigned char *
f6f0e17b
NC
13393display_tic6x_attribute (unsigned char * p,
13394 const unsigned char * const end)
59e6276b
JM
13395{
13396 int tag;
13397 unsigned int len;
13398 int val;
13399
f6f0e17b 13400 tag = read_uleb128 (p, &len, end);
59e6276b
JM
13401 p += len;
13402
13403 switch (tag)
13404 {
75fa6dc1 13405 case Tag_ISA:
f6f0e17b 13406 val = read_uleb128 (p, &len, end);
59e6276b 13407 p += len;
75fa6dc1 13408 printf (" Tag_ISA: ");
59e6276b
JM
13409
13410 switch (val)
13411 {
75fa6dc1 13412 case C6XABI_Tag_ISA_none:
59e6276b
JM
13413 printf (_("None\n"));
13414 break;
75fa6dc1 13415 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
13416 printf ("C62x\n");
13417 break;
75fa6dc1 13418 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
13419 printf ("C67x\n");
13420 break;
75fa6dc1 13421 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
13422 printf ("C67x+\n");
13423 break;
75fa6dc1 13424 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
13425 printf ("C64x\n");
13426 break;
75fa6dc1 13427 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
13428 printf ("C64x+\n");
13429 break;
75fa6dc1 13430 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
13431 printf ("C674x\n");
13432 break;
13433 default:
13434 printf ("??? (%d)\n", val);
13435 break;
13436 }
13437 return p;
13438
87779176 13439 case Tag_ABI_wchar_t:
f6f0e17b 13440 val = read_uleb128 (p, &len, end);
87779176
JM
13441 p += len;
13442 printf (" Tag_ABI_wchar_t: ");
13443 switch (val)
13444 {
13445 case 0:
13446 printf (_("Not used\n"));
13447 break;
13448 case 1:
13449 printf (_("2 bytes\n"));
13450 break;
13451 case 2:
13452 printf (_("4 bytes\n"));
13453 break;
13454 default:
13455 printf ("??? (%d)\n", val);
13456 break;
13457 }
13458 return p;
13459
13460 case Tag_ABI_stack_align_needed:
f6f0e17b 13461 val = read_uleb128 (p, &len, end);
87779176
JM
13462 p += len;
13463 printf (" Tag_ABI_stack_align_needed: ");
13464 switch (val)
13465 {
13466 case 0:
13467 printf (_("8-byte\n"));
13468 break;
13469 case 1:
13470 printf (_("16-byte\n"));
13471 break;
13472 default:
13473 printf ("??? (%d)\n", val);
13474 break;
13475 }
13476 return p;
13477
13478 case Tag_ABI_stack_align_preserved:
f6f0e17b 13479 val = read_uleb128 (p, &len, end);
87779176
JM
13480 p += len;
13481 printf (" Tag_ABI_stack_align_preserved: ");
13482 switch (val)
13483 {
13484 case 0:
13485 printf (_("8-byte\n"));
13486 break;
13487 case 1:
13488 printf (_("16-byte\n"));
13489 break;
13490 default:
13491 printf ("??? (%d)\n", val);
13492 break;
13493 }
13494 return p;
13495
b5593623 13496 case Tag_ABI_DSBT:
f6f0e17b 13497 val = read_uleb128 (p, &len, end);
b5593623
JM
13498 p += len;
13499 printf (" Tag_ABI_DSBT: ");
13500 switch (val)
13501 {
13502 case 0:
13503 printf (_("DSBT addressing not used\n"));
13504 break;
13505 case 1:
13506 printf (_("DSBT addressing used\n"));
13507 break;
13508 default:
13509 printf ("??? (%d)\n", val);
13510 break;
13511 }
13512 return p;
13513
87779176 13514 case Tag_ABI_PID:
f6f0e17b 13515 val = read_uleb128 (p, &len, end);
87779176
JM
13516 p += len;
13517 printf (" Tag_ABI_PID: ");
13518 switch (val)
13519 {
13520 case 0:
13521 printf (_("Data addressing position-dependent\n"));
13522 break;
13523 case 1:
13524 printf (_("Data addressing position-independent, GOT near DP\n"));
13525 break;
13526 case 2:
13527 printf (_("Data addressing position-independent, GOT far from DP\n"));
13528 break;
13529 default:
13530 printf ("??? (%d)\n", val);
13531 break;
13532 }
13533 return p;
13534
13535 case Tag_ABI_PIC:
f6f0e17b 13536 val = read_uleb128 (p, &len, end);
87779176
JM
13537 p += len;
13538 printf (" Tag_ABI_PIC: ");
13539 switch (val)
13540 {
13541 case 0:
13542 printf (_("Code addressing position-dependent\n"));
13543 break;
13544 case 1:
13545 printf (_("Code addressing position-independent\n"));
13546 break;
13547 default:
13548 printf ("??? (%d)\n", val);
13549 break;
13550 }
13551 return p;
13552
13553 case Tag_ABI_array_object_alignment:
f6f0e17b 13554 val = read_uleb128 (p, &len, end);
87779176
JM
13555 p += len;
13556 printf (" Tag_ABI_array_object_alignment: ");
13557 switch (val)
13558 {
13559 case 0:
13560 printf (_("8-byte\n"));
13561 break;
13562 case 1:
13563 printf (_("4-byte\n"));
13564 break;
13565 case 2:
13566 printf (_("16-byte\n"));
13567 break;
13568 default:
13569 printf ("??? (%d)\n", val);
13570 break;
13571 }
13572 return p;
13573
13574 case Tag_ABI_array_object_align_expected:
f6f0e17b 13575 val = read_uleb128 (p, &len, end);
87779176
JM
13576 p += len;
13577 printf (" Tag_ABI_array_object_align_expected: ");
13578 switch (val)
13579 {
13580 case 0:
13581 printf (_("8-byte\n"));
13582 break;
13583 case 1:
13584 printf (_("4-byte\n"));
13585 break;
13586 case 2:
13587 printf (_("16-byte\n"));
13588 break;
13589 default:
13590 printf ("??? (%d)\n", val);
13591 break;
13592 }
13593 return p;
13594
3cbd1c06 13595 case Tag_ABI_compatibility:
071436c6 13596 {
071436c6
NC
13597 val = read_uleb128 (p, &len, end);
13598 p += len;
13599 printf (" Tag_ABI_compatibility: ");
071436c6 13600 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
13601 if (p < end - 1)
13602 {
13603 size_t maxlen = (end - p) - 1;
13604
13605 print_symbol ((int) maxlen, (const char *) p);
13606 p += strnlen ((char *) p, maxlen) + 1;
13607 }
13608 else
13609 {
13610 printf (_("<corrupt>"));
13611 p = (unsigned char *) end;
13612 }
071436c6 13613 putchar ('\n');
071436c6
NC
13614 return p;
13615 }
87779176
JM
13616
13617 case Tag_ABI_conformance:
071436c6 13618 {
4082ef84
NC
13619 printf (" Tag_ABI_conformance: \"");
13620 if (p < end - 1)
13621 {
13622 size_t maxlen = (end - p) - 1;
071436c6 13623
4082ef84
NC
13624 print_symbol ((int) maxlen, (const char *) p);
13625 p += strnlen ((char *) p, maxlen) + 1;
13626 }
13627 else
13628 {
13629 printf (_("<corrupt>"));
13630 p = (unsigned char *) end;
13631 }
071436c6 13632 printf ("\"\n");
071436c6
NC
13633 return p;
13634 }
59e6276b
JM
13635 }
13636
f6f0e17b
NC
13637 return display_tag_value (tag, p, end);
13638}
59e6276b 13639
f6f0e17b
NC
13640static void
13641display_raw_attribute (unsigned char * p, unsigned char * end)
13642{
13643 unsigned long addr = 0;
13644 size_t bytes = end - p;
13645
e0a31db1 13646 assert (end > p);
f6f0e17b 13647 while (bytes)
87779176 13648 {
f6f0e17b
NC
13649 int j;
13650 int k;
13651 int lbytes = (bytes > 16 ? 16 : bytes);
13652
13653 printf (" 0x%8.8lx ", addr);
13654
13655 for (j = 0; j < 16; j++)
13656 {
13657 if (j < lbytes)
13658 printf ("%2.2x", p[j]);
13659 else
13660 printf (" ");
13661
13662 if ((j & 3) == 3)
13663 printf (" ");
13664 }
13665
13666 for (j = 0; j < lbytes; j++)
13667 {
13668 k = p[j];
13669 if (k >= ' ' && k < 0x7f)
13670 printf ("%c", k);
13671 else
13672 printf (".");
13673 }
13674
13675 putchar ('\n');
13676
13677 p += lbytes;
13678 bytes -= lbytes;
13679 addr += lbytes;
87779176 13680 }
59e6276b 13681
f6f0e17b 13682 putchar ('\n');
59e6276b
JM
13683}
13684
13761a11
NC
13685static unsigned char *
13686display_msp430x_attribute (unsigned char * p,
13687 const unsigned char * const end)
13688{
13689 unsigned int len;
13690 int val;
13691 int tag;
13692
13693 tag = read_uleb128 (p, & len, end);
13694 p += len;
0b4362b0 13695
13761a11
NC
13696 switch (tag)
13697 {
13698 case OFBA_MSPABI_Tag_ISA:
13699 val = read_uleb128 (p, &len, end);
13700 p += len;
13701 printf (" Tag_ISA: ");
13702 switch (val)
13703 {
13704 case 0: printf (_("None\n")); break;
13705 case 1: printf (_("MSP430\n")); break;
13706 case 2: printf (_("MSP430X\n")); break;
13707 default: printf ("??? (%d)\n", val); break;
13708 }
13709 break;
13710
13711 case OFBA_MSPABI_Tag_Code_Model:
13712 val = read_uleb128 (p, &len, end);
13713 p += len;
13714 printf (" Tag_Code_Model: ");
13715 switch (val)
13716 {
13717 case 0: printf (_("None\n")); break;
13718 case 1: printf (_("Small\n")); break;
13719 case 2: printf (_("Large\n")); break;
13720 default: printf ("??? (%d)\n", val); break;
13721 }
13722 break;
13723
13724 case OFBA_MSPABI_Tag_Data_Model:
13725 val = read_uleb128 (p, &len, end);
13726 p += len;
13727 printf (" Tag_Data_Model: ");
13728 switch (val)
13729 {
13730 case 0: printf (_("None\n")); break;
13731 case 1: printf (_("Small\n")); break;
13732 case 2: printf (_("Large\n")); break;
13733 case 3: printf (_("Restricted Large\n")); break;
13734 default: printf ("??? (%d)\n", val); break;
13735 }
13736 break;
13737
13738 default:
13739 printf (_(" <unknown tag %d>: "), tag);
13740
13741 if (tag & 1)
13742 {
071436c6 13743 putchar ('"');
4082ef84
NC
13744 if (p < end - 1)
13745 {
13746 size_t maxlen = (end - p) - 1;
13747
13748 print_symbol ((int) maxlen, (const char *) p);
13749 p += strnlen ((char *) p, maxlen) + 1;
13750 }
13751 else
13752 {
13753 printf (_("<corrupt>"));
13754 p = (unsigned char *) end;
13755 }
071436c6 13756 printf ("\"\n");
13761a11
NC
13757 }
13758 else
13759 {
13760 val = read_uleb128 (p, &len, end);
13761 p += len;
13762 printf ("%d (0x%x)\n", val, val);
13763 }
13764 break;
13765 }
13766
4082ef84 13767 assert (p <= end);
13761a11
NC
13768 return p;
13769}
13770
11c1ff18 13771static int
60bca95a
NC
13772process_attributes (FILE * file,
13773 const char * public_name,
104d59d1 13774 unsigned int proc_type,
f6f0e17b
NC
13775 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
13776 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 13777{
2cf0635d 13778 Elf_Internal_Shdr * sect;
11c1ff18
PB
13779 unsigned i;
13780
13781 /* Find the section header so that we get the size. */
13782 for (i = 0, sect = section_headers;
13783 i < elf_header.e_shnum;
13784 i++, sect++)
13785 {
071436c6
NC
13786 unsigned char * contents;
13787 unsigned char * p;
13788
104d59d1 13789 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
13790 continue;
13791
3f5e193b
NC
13792 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
13793 sect->sh_size, _("attributes"));
60bca95a 13794 if (contents == NULL)
11c1ff18 13795 continue;
60bca95a 13796
11c1ff18
PB
13797 p = contents;
13798 if (*p == 'A')
13799 {
071436c6
NC
13800 bfd_vma section_len;
13801
13802 section_len = sect->sh_size - 1;
11c1ff18 13803 p++;
60bca95a 13804
071436c6 13805 while (section_len > 0)
11c1ff18 13806 {
071436c6 13807 bfd_vma attr_len;
e9847026 13808 unsigned int namelen;
11c1ff18 13809 bfd_boolean public_section;
104d59d1 13810 bfd_boolean gnu_section;
11c1ff18 13811
071436c6 13812 if (section_len <= 4)
e0a31db1
NC
13813 {
13814 error (_("Tag section ends prematurely\n"));
13815 break;
13816 }
071436c6 13817 attr_len = byte_get (p, 4);
11c1ff18 13818 p += 4;
60bca95a 13819
071436c6 13820 if (attr_len > section_len)
11c1ff18 13821 {
071436c6
NC
13822 error (_("Bad attribute length (%u > %u)\n"),
13823 (unsigned) attr_len, (unsigned) section_len);
13824 attr_len = section_len;
11c1ff18 13825 }
74e1a04b 13826 /* PR 17531: file: 001-101425-0.004 */
071436c6 13827 else if (attr_len < 5)
74e1a04b 13828 {
071436c6 13829 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
74e1a04b
NC
13830 break;
13831 }
e9847026 13832
071436c6
NC
13833 section_len -= attr_len;
13834 attr_len -= 4;
13835
13836 namelen = strnlen ((char *) p, attr_len) + 1;
13837 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
13838 {
13839 error (_("Corrupt attribute section name\n"));
13840 break;
13841 }
13842
071436c6
NC
13843 printf (_("Attribute Section: "));
13844 print_symbol (INT_MAX, (const char *) p);
13845 putchar ('\n');
60bca95a
NC
13846
13847 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
13848 public_section = TRUE;
13849 else
13850 public_section = FALSE;
60bca95a
NC
13851
13852 if (streq ((char *) p, "gnu"))
104d59d1
JM
13853 gnu_section = TRUE;
13854 else
13855 gnu_section = FALSE;
60bca95a 13856
11c1ff18 13857 p += namelen;
071436c6 13858 attr_len -= namelen;
e0a31db1 13859
071436c6 13860 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 13861 {
e0a31db1 13862 int tag;
11c1ff18
PB
13863 int val;
13864 bfd_vma size;
071436c6 13865 unsigned char * end;
60bca95a 13866
e0a31db1 13867 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 13868 if (attr_len < 6)
e0a31db1
NC
13869 {
13870 error (_("Unused bytes at end of section\n"));
13871 section_len = 0;
13872 break;
13873 }
13874
13875 tag = *(p++);
11c1ff18 13876 size = byte_get (p, 4);
071436c6 13877 if (size > attr_len)
11c1ff18 13878 {
e9847026 13879 error (_("Bad subsection length (%u > %u)\n"),
071436c6
NC
13880 (unsigned) size, (unsigned) attr_len);
13881 size = attr_len;
11c1ff18 13882 }
e0a31db1
NC
13883 /* PR binutils/17531: Safe handling of corrupt files. */
13884 if (size < 6)
13885 {
13886 error (_("Bad subsection length (%u < 6)\n"),
13887 (unsigned) size);
13888 section_len = 0;
13889 break;
13890 }
60bca95a 13891
071436c6 13892 attr_len -= size;
11c1ff18 13893 end = p + size - 1;
071436c6 13894 assert (end <= contents + sect->sh_size);
11c1ff18 13895 p += 4;
60bca95a 13896
11c1ff18
PB
13897 switch (tag)
13898 {
13899 case 1:
2b692964 13900 printf (_("File Attributes\n"));
11c1ff18
PB
13901 break;
13902 case 2:
2b692964 13903 printf (_("Section Attributes:"));
11c1ff18
PB
13904 goto do_numlist;
13905 case 3:
2b692964 13906 printf (_("Symbol Attributes:"));
11c1ff18
PB
13907 do_numlist:
13908 for (;;)
13909 {
91d6fa6a 13910 unsigned int j;
60bca95a 13911
f6f0e17b 13912 val = read_uleb128 (p, &j, end);
91d6fa6a 13913 p += j;
11c1ff18
PB
13914 if (val == 0)
13915 break;
13916 printf (" %d", val);
13917 }
13918 printf ("\n");
13919 break;
13920 default:
2b692964 13921 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
13922 public_section = FALSE;
13923 break;
13924 }
60bca95a 13925
071436c6 13926 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
13927 {
13928 while (p < end)
f6f0e17b 13929 p = display_pub_attribute (p, end);
071436c6 13930 assert (p <= end);
104d59d1 13931 }
071436c6 13932 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
13933 {
13934 while (p < end)
13935 p = display_gnu_attribute (p,
f6f0e17b
NC
13936 display_proc_gnu_attribute,
13937 end);
071436c6 13938 assert (p <= end);
11c1ff18 13939 }
071436c6 13940 else if (p < end)
11c1ff18 13941 {
071436c6 13942 printf (_(" Unknown attribute:\n"));
f6f0e17b 13943 display_raw_attribute (p, end);
11c1ff18
PB
13944 p = end;
13945 }
071436c6
NC
13946 else
13947 attr_len = 0;
11c1ff18
PB
13948 }
13949 }
13950 }
13951 else
e9847026 13952 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 13953
60bca95a 13954 free (contents);
11c1ff18
PB
13955 }
13956 return 1;
13957}
13958
104d59d1 13959static int
2cf0635d 13960process_arm_specific (FILE * file)
104d59d1
JM
13961{
13962 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
13963 display_arm_attribute, NULL);
13964}
13965
34c8bcba 13966static int
2cf0635d 13967process_power_specific (FILE * file)
34c8bcba
JM
13968{
13969 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13970 display_power_gnu_attribute);
13971}
13972
643f7afb
AK
13973static int
13974process_s390_specific (FILE * file)
13975{
13976 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13977 display_s390_gnu_attribute);
13978}
13979
9e8c70f9
DM
13980static int
13981process_sparc_specific (FILE * file)
13982{
13983 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13984 display_sparc_gnu_attribute);
13985}
13986
59e6276b
JM
13987static int
13988process_tic6x_specific (FILE * file)
13989{
13990 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
13991 display_tic6x_attribute, NULL);
13992}
13993
13761a11
NC
13994static int
13995process_msp430x_specific (FILE * file)
13996{
13997 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
13998 display_msp430x_attribute, NULL);
13999}
14000
ccb4c951
RS
14001/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
14002 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
14003 and return the VMA of the next entry, or -1 if there was a problem.
14004 Does not read from DATA_END or beyond. */
ccb4c951
RS
14005
14006static bfd_vma
82b1b41b
NC
14007print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
14008 unsigned char * data_end)
ccb4c951
RS
14009{
14010 printf (" ");
14011 print_vma (addr, LONG_HEX);
14012 printf (" ");
14013 if (addr < pltgot + 0xfff0)
14014 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
14015 else
14016 printf ("%10s", "");
14017 printf (" ");
14018 if (data == NULL)
2b692964 14019 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
14020 else
14021 {
14022 bfd_vma entry;
82b1b41b 14023 unsigned char * from = data + addr - pltgot;
ccb4c951 14024
82b1b41b
NC
14025 if (from + (is_32bit_elf ? 4 : 8) > data_end)
14026 {
14027 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
14028 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
14029 return (bfd_vma) -1;
14030 }
14031 else
14032 {
14033 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
14034 print_vma (entry, LONG_HEX);
14035 }
ccb4c951
RS
14036 }
14037 return addr + (is_32bit_elf ? 4 : 8);
14038}
14039
861fb55a
DJ
14040/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
14041 PLTGOT. Print the Address and Initial fields of an entry at VMA
14042 ADDR and return the VMA of the next entry. */
14043
14044static bfd_vma
2cf0635d 14045print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
14046{
14047 printf (" ");
14048 print_vma (addr, LONG_HEX);
14049 printf (" ");
14050 if (data == NULL)
2b692964 14051 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
14052 else
14053 {
14054 bfd_vma entry;
14055
14056 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
14057 print_vma (entry, LONG_HEX);
14058 }
14059 return addr + (is_32bit_elf ? 4 : 8);
14060}
14061
351cdf24
MF
14062static void
14063print_mips_ases (unsigned int mask)
14064{
14065 if (mask & AFL_ASE_DSP)
14066 fputs ("\n\tDSP ASE", stdout);
14067 if (mask & AFL_ASE_DSPR2)
14068 fputs ("\n\tDSP R2 ASE", stdout);
14069 if (mask & AFL_ASE_EVA)
14070 fputs ("\n\tEnhanced VA Scheme", stdout);
14071 if (mask & AFL_ASE_MCU)
14072 fputs ("\n\tMCU (MicroController) ASE", stdout);
14073 if (mask & AFL_ASE_MDMX)
14074 fputs ("\n\tMDMX ASE", stdout);
14075 if (mask & AFL_ASE_MIPS3D)
14076 fputs ("\n\tMIPS-3D ASE", stdout);
14077 if (mask & AFL_ASE_MT)
14078 fputs ("\n\tMT ASE", stdout);
14079 if (mask & AFL_ASE_SMARTMIPS)
14080 fputs ("\n\tSmartMIPS ASE", stdout);
14081 if (mask & AFL_ASE_VIRT)
14082 fputs ("\n\tVZ ASE", stdout);
14083 if (mask & AFL_ASE_MSA)
14084 fputs ("\n\tMSA ASE", stdout);
14085 if (mask & AFL_ASE_MIPS16)
14086 fputs ("\n\tMIPS16 ASE", stdout);
14087 if (mask & AFL_ASE_MICROMIPS)
14088 fputs ("\n\tMICROMIPS ASE", stdout);
14089 if (mask & AFL_ASE_XPA)
14090 fputs ("\n\tXPA ASE", stdout);
14091 if (mask == 0)
14092 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
14093 else if ((mask & ~AFL_ASE_MASK) != 0)
14094 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
14095}
14096
14097static void
14098print_mips_isa_ext (unsigned int isa_ext)
14099{
14100 switch (isa_ext)
14101 {
14102 case 0:
14103 fputs (_("None"), stdout);
14104 break;
14105 case AFL_EXT_XLR:
14106 fputs ("RMI XLR", stdout);
14107 break;
2c629856
N
14108 case AFL_EXT_OCTEON3:
14109 fputs ("Cavium Networks Octeon3", stdout);
14110 break;
351cdf24
MF
14111 case AFL_EXT_OCTEON2:
14112 fputs ("Cavium Networks Octeon2", stdout);
14113 break;
14114 case AFL_EXT_OCTEONP:
14115 fputs ("Cavium Networks OcteonP", stdout);
14116 break;
14117 case AFL_EXT_LOONGSON_3A:
14118 fputs ("Loongson 3A", stdout);
14119 break;
14120 case AFL_EXT_OCTEON:
14121 fputs ("Cavium Networks Octeon", stdout);
14122 break;
14123 case AFL_EXT_5900:
14124 fputs ("Toshiba R5900", stdout);
14125 break;
14126 case AFL_EXT_4650:
14127 fputs ("MIPS R4650", stdout);
14128 break;
14129 case AFL_EXT_4010:
14130 fputs ("LSI R4010", stdout);
14131 break;
14132 case AFL_EXT_4100:
14133 fputs ("NEC VR4100", stdout);
14134 break;
14135 case AFL_EXT_3900:
14136 fputs ("Toshiba R3900", stdout);
14137 break;
14138 case AFL_EXT_10000:
14139 fputs ("MIPS R10000", stdout);
14140 break;
14141 case AFL_EXT_SB1:
14142 fputs ("Broadcom SB-1", stdout);
14143 break;
14144 case AFL_EXT_4111:
14145 fputs ("NEC VR4111/VR4181", stdout);
14146 break;
14147 case AFL_EXT_4120:
14148 fputs ("NEC VR4120", stdout);
14149 break;
14150 case AFL_EXT_5400:
14151 fputs ("NEC VR5400", stdout);
14152 break;
14153 case AFL_EXT_5500:
14154 fputs ("NEC VR5500", stdout);
14155 break;
14156 case AFL_EXT_LOONGSON_2E:
14157 fputs ("ST Microelectronics Loongson 2E", stdout);
14158 break;
14159 case AFL_EXT_LOONGSON_2F:
14160 fputs ("ST Microelectronics Loongson 2F", stdout);
14161 break;
14162 default:
00ac7aa0 14163 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
14164 }
14165}
14166
14167static int
14168get_mips_reg_size (int reg_size)
14169{
14170 return (reg_size == AFL_REG_NONE) ? 0
14171 : (reg_size == AFL_REG_32) ? 32
14172 : (reg_size == AFL_REG_64) ? 64
14173 : (reg_size == AFL_REG_128) ? 128
14174 : -1;
14175}
14176
19e6b90e 14177static int
2cf0635d 14178process_mips_specific (FILE * file)
5b18a4bc 14179{
2cf0635d 14180 Elf_Internal_Dyn * entry;
351cdf24 14181 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
14182 size_t liblist_offset = 0;
14183 size_t liblistno = 0;
14184 size_t conflictsno = 0;
14185 size_t options_offset = 0;
14186 size_t conflicts_offset = 0;
861fb55a
DJ
14187 size_t pltrelsz = 0;
14188 size_t pltrel = 0;
ccb4c951 14189 bfd_vma pltgot = 0;
861fb55a
DJ
14190 bfd_vma mips_pltgot = 0;
14191 bfd_vma jmprel = 0;
ccb4c951
RS
14192 bfd_vma local_gotno = 0;
14193 bfd_vma gotsym = 0;
14194 bfd_vma symtabno = 0;
103f02d3 14195
2cf19d5c
JM
14196 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
14197 display_mips_gnu_attribute);
14198
351cdf24
MF
14199 sect = find_section (".MIPS.abiflags");
14200
14201 if (sect != NULL)
14202 {
14203 Elf_External_ABIFlags_v0 *abiflags_ext;
14204 Elf_Internal_ABIFlags_v0 abiflags_in;
14205
14206 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
14207 fputs ("\nCorrupt ABI Flags section.\n", stdout);
14208 else
14209 {
14210 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
14211 sect->sh_size, _("MIPS ABI Flags section"));
14212 if (abiflags_ext)
14213 {
14214 abiflags_in.version = BYTE_GET (abiflags_ext->version);
14215 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
14216 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
14217 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
14218 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
14219 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
14220 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
14221 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
14222 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
14223 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
14224 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
14225
14226 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
14227 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
14228 if (abiflags_in.isa_rev > 1)
14229 printf ("r%d", abiflags_in.isa_rev);
14230 printf ("\nGPR size: %d",
14231 get_mips_reg_size (abiflags_in.gpr_size));
14232 printf ("\nCPR1 size: %d",
14233 get_mips_reg_size (abiflags_in.cpr1_size));
14234 printf ("\nCPR2 size: %d",
14235 get_mips_reg_size (abiflags_in.cpr2_size));
14236 fputs ("\nFP ABI: ", stdout);
14237 print_mips_fp_abi_value (abiflags_in.fp_abi);
14238 fputs ("ISA Extension: ", stdout);
14239 print_mips_isa_ext (abiflags_in.isa_ext);
14240 fputs ("\nASEs:", stdout);
14241 print_mips_ases (abiflags_in.ases);
14242 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
14243 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
14244 fputc ('\n', stdout);
14245 free (abiflags_ext);
14246 }
14247 }
14248 }
14249
19e6b90e
L
14250 /* We have a lot of special sections. Thanks SGI! */
14251 if (dynamic_section == NULL)
14252 /* No information available. */
14253 return 0;
252b5132 14254
071436c6
NC
14255 for (entry = dynamic_section;
14256 /* PR 17531 file: 012-50589-0.004. */
14257 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
14258 ++entry)
252b5132
RH
14259 switch (entry->d_tag)
14260 {
14261 case DT_MIPS_LIBLIST:
d93f0186
NC
14262 liblist_offset
14263 = offset_from_vma (file, entry->d_un.d_val,
14264 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
14265 break;
14266 case DT_MIPS_LIBLISTNO:
14267 liblistno = entry->d_un.d_val;
14268 break;
14269 case DT_MIPS_OPTIONS:
d93f0186 14270 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
14271 break;
14272 case DT_MIPS_CONFLICT:
d93f0186
NC
14273 conflicts_offset
14274 = offset_from_vma (file, entry->d_un.d_val,
14275 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
14276 break;
14277 case DT_MIPS_CONFLICTNO:
14278 conflictsno = entry->d_un.d_val;
14279 break;
ccb4c951 14280 case DT_PLTGOT:
861fb55a
DJ
14281 pltgot = entry->d_un.d_ptr;
14282 break;
ccb4c951
RS
14283 case DT_MIPS_LOCAL_GOTNO:
14284 local_gotno = entry->d_un.d_val;
14285 break;
14286 case DT_MIPS_GOTSYM:
14287 gotsym = entry->d_un.d_val;
14288 break;
14289 case DT_MIPS_SYMTABNO:
14290 symtabno = entry->d_un.d_val;
14291 break;
861fb55a
DJ
14292 case DT_MIPS_PLTGOT:
14293 mips_pltgot = entry->d_un.d_ptr;
14294 break;
14295 case DT_PLTREL:
14296 pltrel = entry->d_un.d_val;
14297 break;
14298 case DT_PLTRELSZ:
14299 pltrelsz = entry->d_un.d_val;
14300 break;
14301 case DT_JMPREL:
14302 jmprel = entry->d_un.d_ptr;
14303 break;
252b5132
RH
14304 default:
14305 break;
14306 }
14307
14308 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
14309 {
2cf0635d 14310 Elf32_External_Lib * elib;
252b5132
RH
14311 size_t cnt;
14312
3f5e193b
NC
14313 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
14314 liblistno,
14315 sizeof (Elf32_External_Lib),
9cf03b7e 14316 _("liblist section data"));
a6e9f9df 14317 if (elib)
252b5132 14318 {
2b692964 14319 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 14320 (unsigned long) liblistno);
2b692964 14321 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
14322 stdout);
14323
14324 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 14325 {
a6e9f9df 14326 Elf32_Lib liblist;
91d6fa6a 14327 time_t atime;
a6e9f9df 14328 char timebuf[20];
2cf0635d 14329 struct tm * tmp;
a6e9f9df
AM
14330
14331 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14332 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
14333 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14334 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14335 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14336
91d6fa6a 14337 tmp = gmtime (&atime);
e9e44622
JJ
14338 snprintf (timebuf, sizeof (timebuf),
14339 "%04u-%02u-%02uT%02u:%02u:%02u",
14340 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14341 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 14342
31104126 14343 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
14344 if (VALID_DYNAMIC_NAME (liblist.l_name))
14345 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
14346 else
2b692964 14347 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
14348 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
14349 liblist.l_version);
a6e9f9df
AM
14350
14351 if (liblist.l_flags == 0)
2b692964 14352 puts (_(" NONE"));
a6e9f9df
AM
14353 else
14354 {
14355 static const struct
252b5132 14356 {
2cf0635d 14357 const char * name;
a6e9f9df 14358 int bit;
252b5132 14359 }
a6e9f9df
AM
14360 l_flags_vals[] =
14361 {
14362 { " EXACT_MATCH", LL_EXACT_MATCH },
14363 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
14364 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
14365 { " EXPORTS", LL_EXPORTS },
14366 { " DELAY_LOAD", LL_DELAY_LOAD },
14367 { " DELTA", LL_DELTA }
14368 };
14369 int flags = liblist.l_flags;
14370 size_t fcnt;
14371
60bca95a 14372 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
14373 if ((flags & l_flags_vals[fcnt].bit) != 0)
14374 {
14375 fputs (l_flags_vals[fcnt].name, stdout);
14376 flags ^= l_flags_vals[fcnt].bit;
14377 }
14378 if (flags != 0)
14379 printf (" %#x", (unsigned int) flags);
252b5132 14380
a6e9f9df
AM
14381 puts ("");
14382 }
252b5132 14383 }
252b5132 14384
a6e9f9df
AM
14385 free (elib);
14386 }
252b5132
RH
14387 }
14388
14389 if (options_offset != 0)
14390 {
2cf0635d 14391 Elf_External_Options * eopt;
2cf0635d
NC
14392 Elf_Internal_Options * iopt;
14393 Elf_Internal_Options * option;
252b5132
RH
14394 size_t offset;
14395 int cnt;
351cdf24 14396 sect = section_headers;
252b5132
RH
14397
14398 /* Find the section header so that we get the size. */
071436c6 14399 sect = find_section_by_type (SHT_MIPS_OPTIONS);
948f632f 14400 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
14401 if (sect == NULL)
14402 {
14403 error (_("No MIPS_OPTIONS header found\n"));
14404 return 0;
14405 }
252b5132 14406
3f5e193b
NC
14407 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
14408 sect->sh_size, _("options"));
a6e9f9df 14409 if (eopt)
252b5132 14410 {
3f5e193b
NC
14411 iopt = (Elf_Internal_Options *)
14412 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
14413 if (iopt == NULL)
14414 {
8b73c356 14415 error (_("Out of memory allocatinf space for MIPS options\n"));
a6e9f9df
AM
14416 return 0;
14417 }
76da6bbe 14418
a6e9f9df
AM
14419 offset = cnt = 0;
14420 option = iopt;
252b5132 14421
82b1b41b 14422 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 14423 {
2cf0635d 14424 Elf_External_Options * eoption;
252b5132 14425
a6e9f9df 14426 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 14427
a6e9f9df
AM
14428 option->kind = BYTE_GET (eoption->kind);
14429 option->size = BYTE_GET (eoption->size);
14430 option->section = BYTE_GET (eoption->section);
14431 option->info = BYTE_GET (eoption->info);
76da6bbe 14432
82b1b41b
NC
14433 /* PR 17531: file: ffa0fa3b. */
14434 if (option->size < sizeof (* eopt)
14435 || offset + option->size > sect->sh_size)
14436 {
55325047
NC
14437 error (_("Invalid size (%u) for MIPS option\n"), option->size);
14438 return 0;
82b1b41b 14439 }
a6e9f9df 14440 offset += option->size;
14ae95f2 14441
a6e9f9df
AM
14442 ++option;
14443 ++cnt;
14444 }
252b5132 14445
a6e9f9df 14446 printf (_("\nSection '%s' contains %d entries:\n"),
74e1a04b 14447 printable_section_name (sect), cnt);
76da6bbe 14448
a6e9f9df 14449 option = iopt;
82b1b41b 14450 offset = 0;
252b5132 14451
a6e9f9df 14452 while (cnt-- > 0)
252b5132 14453 {
a6e9f9df
AM
14454 size_t len;
14455
14456 switch (option->kind)
252b5132 14457 {
a6e9f9df
AM
14458 case ODK_NULL:
14459 /* This shouldn't happen. */
14460 printf (" NULL %d %lx", option->section, option->info);
14461 break;
14462 case ODK_REGINFO:
14463 printf (" REGINFO ");
14464 if (elf_header.e_machine == EM_MIPS)
14465 {
14466 /* 32bit form. */
2cf0635d 14467 Elf32_External_RegInfo * ereg;
b34976b6 14468 Elf32_RegInfo reginfo;
a6e9f9df
AM
14469
14470 ereg = (Elf32_External_RegInfo *) (option + 1);
14471 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
14472 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
14473 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
14474 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
14475 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
14476 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
14477
14478 printf ("GPR %08lx GP 0x%lx\n",
14479 reginfo.ri_gprmask,
14480 (unsigned long) reginfo.ri_gp_value);
14481 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
14482 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
14483 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
14484 }
14485 else
14486 {
14487 /* 64 bit form. */
2cf0635d 14488 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
14489 Elf64_Internal_RegInfo reginfo;
14490
14491 ereg = (Elf64_External_RegInfo *) (option + 1);
14492 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
14493 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
14494 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
14495 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
14496 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 14497 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
14498
14499 printf ("GPR %08lx GP 0x",
14500 reginfo.ri_gprmask);
14501 printf_vma (reginfo.ri_gp_value);
14502 printf ("\n");
14503
14504 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
14505 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
14506 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
14507 }
14508 ++option;
14509 continue;
14510 case ODK_EXCEPTIONS:
14511 fputs (" EXCEPTIONS fpe_min(", stdout);
14512 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
14513 fputs (") fpe_max(", stdout);
14514 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
14515 fputs (")", stdout);
14516
14517 if (option->info & OEX_PAGE0)
14518 fputs (" PAGE0", stdout);
14519 if (option->info & OEX_SMM)
14520 fputs (" SMM", stdout);
14521 if (option->info & OEX_FPDBUG)
14522 fputs (" FPDBUG", stdout);
14523 if (option->info & OEX_DISMISS)
14524 fputs (" DISMISS", stdout);
14525 break;
14526 case ODK_PAD:
14527 fputs (" PAD ", stdout);
14528 if (option->info & OPAD_PREFIX)
14529 fputs (" PREFIX", stdout);
14530 if (option->info & OPAD_POSTFIX)
14531 fputs (" POSTFIX", stdout);
14532 if (option->info & OPAD_SYMBOL)
14533 fputs (" SYMBOL", stdout);
14534 break;
14535 case ODK_HWPATCH:
14536 fputs (" HWPATCH ", stdout);
14537 if (option->info & OHW_R4KEOP)
14538 fputs (" R4KEOP", stdout);
14539 if (option->info & OHW_R8KPFETCH)
14540 fputs (" R8KPFETCH", stdout);
14541 if (option->info & OHW_R5KEOP)
14542 fputs (" R5KEOP", stdout);
14543 if (option->info & OHW_R5KCVTL)
14544 fputs (" R5KCVTL", stdout);
14545 break;
14546 case ODK_FILL:
14547 fputs (" FILL ", stdout);
14548 /* XXX Print content of info word? */
14549 break;
14550 case ODK_TAGS:
14551 fputs (" TAGS ", stdout);
14552 /* XXX Print content of info word? */
14553 break;
14554 case ODK_HWAND:
14555 fputs (" HWAND ", stdout);
14556 if (option->info & OHWA0_R4KEOP_CHECKED)
14557 fputs (" R4KEOP_CHECKED", stdout);
14558 if (option->info & OHWA0_R4KEOP_CLEAN)
14559 fputs (" R4KEOP_CLEAN", stdout);
14560 break;
14561 case ODK_HWOR:
14562 fputs (" HWOR ", stdout);
14563 if (option->info & OHWA0_R4KEOP_CHECKED)
14564 fputs (" R4KEOP_CHECKED", stdout);
14565 if (option->info & OHWA0_R4KEOP_CLEAN)
14566 fputs (" R4KEOP_CLEAN", stdout);
14567 break;
14568 case ODK_GP_GROUP:
14569 printf (" GP_GROUP %#06lx self-contained %#06lx",
14570 option->info & OGP_GROUP,
14571 (option->info & OGP_SELF) >> 16);
14572 break;
14573 case ODK_IDENT:
14574 printf (" IDENT %#06lx self-contained %#06lx",
14575 option->info & OGP_GROUP,
14576 (option->info & OGP_SELF) >> 16);
14577 break;
14578 default:
14579 /* This shouldn't happen. */
14580 printf (" %3d ??? %d %lx",
14581 option->kind, option->section, option->info);
14582 break;
252b5132 14583 }
a6e9f9df 14584
2cf0635d 14585 len = sizeof (* eopt);
a6e9f9df 14586 while (len < option->size)
82b1b41b 14587 {
7e27a9d5 14588 unsigned char datum = * ((unsigned char *) eopt + offset + len);
a6e9f9df 14589
82b1b41b
NC
14590 if (ISPRINT (datum))
14591 printf ("%c", datum);
14592 else
14593 printf ("\\%03o", datum);
14594 len ++;
14595 }
a6e9f9df 14596 fputs ("\n", stdout);
82b1b41b
NC
14597
14598 offset += option->size;
252b5132 14599 ++option;
252b5132
RH
14600 }
14601
a6e9f9df 14602 free (eopt);
252b5132 14603 }
252b5132
RH
14604 }
14605
14606 if (conflicts_offset != 0 && conflictsno != 0)
14607 {
2cf0635d 14608 Elf32_Conflict * iconf;
252b5132
RH
14609 size_t cnt;
14610
14611 if (dynamic_symbols == NULL)
14612 {
591a748a 14613 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
14614 return 0;
14615 }
14616
3f5e193b 14617 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
14618 if (iconf == NULL)
14619 {
8b73c356 14620 error (_("Out of memory allocating space for dynamic conflicts\n"));
252b5132
RH
14621 return 0;
14622 }
14623
9ea033b2 14624 if (is_32bit_elf)
252b5132 14625 {
2cf0635d 14626 Elf32_External_Conflict * econf32;
a6e9f9df 14627
3f5e193b
NC
14628 econf32 = (Elf32_External_Conflict *)
14629 get_data (NULL, file, conflicts_offset, conflictsno,
14630 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
14631 if (!econf32)
14632 return 0;
252b5132
RH
14633
14634 for (cnt = 0; cnt < conflictsno; ++cnt)
14635 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
14636
14637 free (econf32);
252b5132
RH
14638 }
14639 else
14640 {
2cf0635d 14641 Elf64_External_Conflict * econf64;
a6e9f9df 14642
3f5e193b
NC
14643 econf64 = (Elf64_External_Conflict *)
14644 get_data (NULL, file, conflicts_offset, conflictsno,
14645 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
14646 if (!econf64)
14647 return 0;
252b5132
RH
14648
14649 for (cnt = 0; cnt < conflictsno; ++cnt)
14650 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
14651
14652 free (econf64);
252b5132
RH
14653 }
14654
c7e7ca54
NC
14655 printf (_("\nSection '.conflict' contains %lu entries:\n"),
14656 (unsigned long) conflictsno);
252b5132
RH
14657 puts (_(" Num: Index Value Name"));
14658
14659 for (cnt = 0; cnt < conflictsno; ++cnt)
14660 {
b34976b6 14661 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
14662
14663 if (iconf[cnt] >= num_dynamic_syms)
14664 printf (_("<corrupt symbol index>"));
d79b3d50 14665 else
e0a31db1
NC
14666 {
14667 Elf_Internal_Sym * psym;
14668
14669 psym = & dynamic_symbols[iconf[cnt]];
14670 print_vma (psym->st_value, FULL_HEX);
14671 putchar (' ');
14672 if (VALID_DYNAMIC_NAME (psym->st_name))
14673 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
14674 else
14675 printf (_("<corrupt: %14ld>"), psym->st_name);
14676 }
31104126 14677 putchar ('\n');
252b5132
RH
14678 }
14679
252b5132
RH
14680 free (iconf);
14681 }
14682
ccb4c951
RS
14683 if (pltgot != 0 && local_gotno != 0)
14684 {
91d6fa6a 14685 bfd_vma ent, local_end, global_end;
bbeee7ea 14686 size_t i, offset;
2cf0635d 14687 unsigned char * data;
82b1b41b 14688 unsigned char * data_end;
bbeee7ea 14689 int addr_size;
ccb4c951 14690
91d6fa6a 14691 ent = pltgot;
ccb4c951
RS
14692 addr_size = (is_32bit_elf ? 4 : 8);
14693 local_end = pltgot + local_gotno * addr_size;
ccb4c951 14694
74e1a04b
NC
14695 /* PR binutils/17533 file: 012-111227-0.004 */
14696 if (symtabno < gotsym)
14697 {
14698 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 14699 (unsigned long) gotsym, (unsigned long) symtabno);
74e1a04b
NC
14700 return 0;
14701 }
82b1b41b 14702
74e1a04b 14703 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
14704 /* PR 17531: file: 54c91a34. */
14705 if (global_end < local_end)
14706 {
14707 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
14708 return 0;
14709 }
948f632f 14710
ccb4c951 14711 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 14712 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
14713 global_end - pltgot, 1,
14714 _("Global Offset Table data"));
59245841
NC
14715 if (data == NULL)
14716 return 0;
82b1b41b 14717 data_end = data + (global_end - pltgot);
59245841 14718
ccb4c951
RS
14719 printf (_("\nPrimary GOT:\n"));
14720 printf (_(" Canonical gp value: "));
14721 print_vma (pltgot + 0x7ff0, LONG_HEX);
14722 printf ("\n\n");
14723
14724 printf (_(" Reserved entries:\n"));
14725 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
14726 addr_size * 2, _("Address"), _("Access"),
14727 addr_size * 2, _("Initial"));
82b1b41b 14728 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 14729 printf (_(" Lazy resolver\n"));
82b1b41b
NC
14730 if (ent == (bfd_vma) -1)
14731 goto got_print_fail;
ccb4c951 14732 if (data
91d6fa6a 14733 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
14734 >> (addr_size * 8 - 1)) != 0)
14735 {
82b1b41b 14736 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 14737 printf (_(" Module pointer (GNU extension)\n"));
82b1b41b
NC
14738 if (ent == (bfd_vma) -1)
14739 goto got_print_fail;
ccb4c951
RS
14740 }
14741 printf ("\n");
14742
91d6fa6a 14743 if (ent < local_end)
ccb4c951
RS
14744 {
14745 printf (_(" Local entries:\n"));
cc5914eb 14746 printf (" %*s %10s %*s\n",
2b692964
NC
14747 addr_size * 2, _("Address"), _("Access"),
14748 addr_size * 2, _("Initial"));
91d6fa6a 14749 while (ent < local_end)
ccb4c951 14750 {
82b1b41b 14751 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 14752 printf ("\n");
82b1b41b
NC
14753 if (ent == (bfd_vma) -1)
14754 goto got_print_fail;
ccb4c951
RS
14755 }
14756 printf ("\n");
14757 }
14758
14759 if (gotsym < symtabno)
14760 {
14761 int sym_width;
14762
14763 printf (_(" Global entries:\n"));
cc5914eb 14764 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
14765 addr_size * 2, _("Address"),
14766 _("Access"),
2b692964 14767 addr_size * 2, _("Initial"),
9cf03b7e
NC
14768 addr_size * 2, _("Sym.Val."),
14769 _("Type"),
14770 /* Note for translators: "Ndx" = abbreviated form of "Index". */
14771 _("Ndx"), _("Name"));
0b4362b0 14772
ccb4c951 14773 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 14774
ccb4c951
RS
14775 for (i = gotsym; i < symtabno; i++)
14776 {
82b1b41b 14777 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 14778 printf (" ");
e0a31db1
NC
14779
14780 if (dynamic_symbols == NULL)
14781 printf (_("<no dynamic symbols>"));
14782 else if (i < num_dynamic_syms)
14783 {
14784 Elf_Internal_Sym * psym = dynamic_symbols + i;
14785
14786 print_vma (psym->st_value, LONG_HEX);
14787 printf (" %-7s %3s ",
14788 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14789 get_symbol_index_type (psym->st_shndx));
14790
14791 if (VALID_DYNAMIC_NAME (psym->st_name))
14792 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14793 else
14794 printf (_("<corrupt: %14ld>"), psym->st_name);
14795 }
ccb4c951 14796 else
7fc5ac57
JBG
14797 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
14798 (unsigned long) i);
e0a31db1 14799
ccb4c951 14800 printf ("\n");
82b1b41b
NC
14801 if (ent == (bfd_vma) -1)
14802 break;
ccb4c951
RS
14803 }
14804 printf ("\n");
14805 }
14806
82b1b41b 14807 got_print_fail:
ccb4c951
RS
14808 if (data)
14809 free (data);
14810 }
14811
861fb55a
DJ
14812 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
14813 {
91d6fa6a 14814 bfd_vma ent, end;
861fb55a
DJ
14815 size_t offset, rel_offset;
14816 unsigned long count, i;
2cf0635d 14817 unsigned char * data;
861fb55a 14818 int addr_size, sym_width;
2cf0635d 14819 Elf_Internal_Rela * rels;
861fb55a
DJ
14820
14821 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
14822 if (pltrel == DT_RELA)
14823 {
14824 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
14825 return 0;
14826 }
14827 else
14828 {
14829 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
14830 return 0;
14831 }
14832
91d6fa6a 14833 ent = mips_pltgot;
861fb55a
DJ
14834 addr_size = (is_32bit_elf ? 4 : 8);
14835 end = mips_pltgot + (2 + count) * addr_size;
14836
14837 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 14838 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 14839 1, _("Procedure Linkage Table data"));
59245841
NC
14840 if (data == NULL)
14841 return 0;
14842
9cf03b7e 14843 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
14844 printf (_(" Reserved entries:\n"));
14845 printf (_(" %*s %*s Purpose\n"),
2b692964 14846 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 14847 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14848 printf (_(" PLT lazy resolver\n"));
91d6fa6a 14849 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14850 printf (_(" Module pointer\n"));
861fb55a
DJ
14851 printf ("\n");
14852
14853 printf (_(" Entries:\n"));
cc5914eb 14854 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
14855 addr_size * 2, _("Address"),
14856 addr_size * 2, _("Initial"),
14857 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
14858 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
14859 for (i = 0; i < count; i++)
14860 {
df97ab2a 14861 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 14862
91d6fa6a 14863 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 14864 printf (" ");
e0a31db1 14865
df97ab2a
MF
14866 if (idx >= num_dynamic_syms)
14867 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 14868 else
e0a31db1 14869 {
df97ab2a 14870 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
14871
14872 print_vma (psym->st_value, LONG_HEX);
14873 printf (" %-7s %3s ",
14874 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14875 get_symbol_index_type (psym->st_shndx));
14876 if (VALID_DYNAMIC_NAME (psym->st_name))
14877 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14878 else
14879 printf (_("<corrupt: %14ld>"), psym->st_name);
14880 }
861fb55a
DJ
14881 printf ("\n");
14882 }
14883 printf ("\n");
14884
14885 if (data)
14886 free (data);
14887 free (rels);
14888 }
14889
252b5132
RH
14890 return 1;
14891}
14892
35c08157
KLC
14893static int
14894process_nds32_specific (FILE * file)
14895{
14896 Elf_Internal_Shdr *sect = NULL;
14897
14898 sect = find_section (".nds32_e_flags");
14899 if (sect != NULL)
14900 {
14901 unsigned int *flag;
14902
14903 printf ("\nNDS32 elf flags section:\n");
14904 flag = get_data (NULL, file, sect->sh_offset, 1,
14905 sect->sh_size, _("NDS32 elf flags section"));
14906
14907 switch ((*flag) & 0x3)
14908 {
14909 case 0:
14910 printf ("(VEC_SIZE):\tNo entry.\n");
14911 break;
14912 case 1:
14913 printf ("(VEC_SIZE):\t4 bytes\n");
14914 break;
14915 case 2:
14916 printf ("(VEC_SIZE):\t16 bytes\n");
14917 break;
14918 case 3:
14919 printf ("(VEC_SIZE):\treserved\n");
14920 break;
14921 }
14922 }
14923
14924 return TRUE;
14925}
14926
047b2264 14927static int
2cf0635d 14928process_gnu_liblist (FILE * file)
047b2264 14929{
2cf0635d
NC
14930 Elf_Internal_Shdr * section;
14931 Elf_Internal_Shdr * string_sec;
14932 Elf32_External_Lib * elib;
14933 char * strtab;
c256ffe7 14934 size_t strtab_size;
047b2264
JJ
14935 size_t cnt;
14936 unsigned i;
14937
14938 if (! do_arch)
14939 return 0;
14940
14941 for (i = 0, section = section_headers;
14942 i < elf_header.e_shnum;
b34976b6 14943 i++, section++)
047b2264
JJ
14944 {
14945 switch (section->sh_type)
14946 {
14947 case SHT_GNU_LIBLIST:
4fbb74a6 14948 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
14949 break;
14950
3f5e193b
NC
14951 elib = (Elf32_External_Lib *)
14952 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 14953 _("liblist section data"));
047b2264
JJ
14954
14955 if (elib == NULL)
14956 break;
4fbb74a6 14957 string_sec = section_headers + section->sh_link;
047b2264 14958
3f5e193b
NC
14959 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
14960 string_sec->sh_size,
14961 _("liblist string table"));
047b2264
JJ
14962 if (strtab == NULL
14963 || section->sh_entsize != sizeof (Elf32_External_Lib))
14964 {
14965 free (elib);
2842702f 14966 free (strtab);
047b2264
JJ
14967 break;
14968 }
59245841 14969 strtab_size = string_sec->sh_size;
047b2264
JJ
14970
14971 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
74e1a04b 14972 printable_section_name (section),
0af1713e 14973 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 14974
2b692964 14975 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
14976
14977 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
14978 ++cnt)
14979 {
14980 Elf32_Lib liblist;
91d6fa6a 14981 time_t atime;
047b2264 14982 char timebuf[20];
2cf0635d 14983 struct tm * tmp;
047b2264
JJ
14984
14985 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14986 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
14987 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14988 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14989 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14990
91d6fa6a 14991 tmp = gmtime (&atime);
e9e44622
JJ
14992 snprintf (timebuf, sizeof (timebuf),
14993 "%04u-%02u-%02uT%02u:%02u:%02u",
14994 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14995 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
14996
14997 printf ("%3lu: ", (unsigned long) cnt);
14998 if (do_wide)
c256ffe7 14999 printf ("%-20s", liblist.l_name < strtab_size
2b692964 15000 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 15001 else
c256ffe7 15002 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 15003 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
15004 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
15005 liblist.l_version, liblist.l_flags);
15006 }
15007
15008 free (elib);
2842702f 15009 free (strtab);
047b2264
JJ
15010 }
15011 }
15012
15013 return 1;
15014}
15015
9437c45b 15016static const char *
d3ba0551 15017get_note_type (unsigned e_type)
779fe533
NC
15018{
15019 static char buff[64];
103f02d3 15020
1ec5cd37
NC
15021 if (elf_header.e_type == ET_CORE)
15022 switch (e_type)
15023 {
57346661 15024 case NT_AUXV:
1ec5cd37 15025 return _("NT_AUXV (auxiliary vector)");
57346661 15026 case NT_PRSTATUS:
1ec5cd37 15027 return _("NT_PRSTATUS (prstatus structure)");
57346661 15028 case NT_FPREGSET:
1ec5cd37 15029 return _("NT_FPREGSET (floating point registers)");
57346661 15030 case NT_PRPSINFO:
1ec5cd37 15031 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 15032 case NT_TASKSTRUCT:
1ec5cd37 15033 return _("NT_TASKSTRUCT (task structure)");
57346661 15034 case NT_PRXFPREG:
1ec5cd37 15035 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
15036 case NT_PPC_VMX:
15037 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
15038 case NT_PPC_VSX:
15039 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
15040 case NT_386_TLS:
15041 return _("NT_386_TLS (x86 TLS information)");
15042 case NT_386_IOPERM:
15043 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
15044 case NT_X86_XSTATE:
15045 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
15046 case NT_S390_HIGH_GPRS:
15047 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
15048 case NT_S390_TIMER:
15049 return _("NT_S390_TIMER (s390 timer register)");
15050 case NT_S390_TODCMP:
15051 return _("NT_S390_TODCMP (s390 TOD comparator register)");
15052 case NT_S390_TODPREG:
15053 return _("NT_S390_TODPREG (s390 TOD programmable register)");
15054 case NT_S390_CTRS:
15055 return _("NT_S390_CTRS (s390 control registers)");
15056 case NT_S390_PREFIX:
15057 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
15058 case NT_S390_LAST_BREAK:
15059 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
15060 case NT_S390_SYSTEM_CALL:
15061 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
15062 case NT_S390_TDB:
15063 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
15064 case NT_S390_VXRS_LOW:
15065 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
15066 case NT_S390_VXRS_HIGH:
15067 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
faa9a424
UW
15068 case NT_ARM_VFP:
15069 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
15070 case NT_ARM_TLS:
15071 return _("NT_ARM_TLS (AArch TLS registers)");
15072 case NT_ARM_HW_BREAK:
15073 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
15074 case NT_ARM_HW_WATCH:
15075 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 15076 case NT_PSTATUS:
1ec5cd37 15077 return _("NT_PSTATUS (pstatus structure)");
57346661 15078 case NT_FPREGS:
1ec5cd37 15079 return _("NT_FPREGS (floating point registers)");
57346661 15080 case NT_PSINFO:
1ec5cd37 15081 return _("NT_PSINFO (psinfo structure)");
57346661 15082 case NT_LWPSTATUS:
1ec5cd37 15083 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 15084 case NT_LWPSINFO:
1ec5cd37 15085 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 15086 case NT_WIN32PSTATUS:
1ec5cd37 15087 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
15088 case NT_SIGINFO:
15089 return _("NT_SIGINFO (siginfo_t data)");
15090 case NT_FILE:
15091 return _("NT_FILE (mapped files)");
1ec5cd37
NC
15092 default:
15093 break;
15094 }
15095 else
15096 switch (e_type)
15097 {
15098 case NT_VERSION:
15099 return _("NT_VERSION (version)");
15100 case NT_ARCH:
15101 return _("NT_ARCH (architecture)");
15102 default:
15103 break;
15104 }
15105
e9e44622 15106 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 15107 return buff;
779fe533
NC
15108}
15109
9ece1fa9
TT
15110static int
15111print_core_note (Elf_Internal_Note *pnote)
15112{
15113 unsigned int addr_size = is_32bit_elf ? 4 : 8;
15114 bfd_vma count, page_size;
15115 unsigned char *descdata, *filenames, *descend;
15116
15117 if (pnote->type != NT_FILE)
15118 return 1;
15119
15120#ifndef BFD64
15121 if (!is_32bit_elf)
15122 {
15123 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
15124 /* Still "successful". */
15125 return 1;
15126 }
15127#endif
15128
15129 if (pnote->descsz < 2 * addr_size)
15130 {
15131 printf (_(" Malformed note - too short for header\n"));
15132 return 0;
15133 }
15134
15135 descdata = (unsigned char *) pnote->descdata;
15136 descend = descdata + pnote->descsz;
15137
15138 if (descdata[pnote->descsz - 1] != '\0')
15139 {
15140 printf (_(" Malformed note - does not end with \\0\n"));
15141 return 0;
15142 }
15143
15144 count = byte_get (descdata, addr_size);
15145 descdata += addr_size;
15146
15147 page_size = byte_get (descdata, addr_size);
15148 descdata += addr_size;
15149
15150 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
15151 {
15152 printf (_(" Malformed note - too short for supplied file count\n"));
15153 return 0;
15154 }
15155
15156 printf (_(" Page size: "));
15157 print_vma (page_size, DEC);
15158 printf ("\n");
15159
15160 printf (_(" %*s%*s%*s\n"),
15161 (int) (2 + 2 * addr_size), _("Start"),
15162 (int) (4 + 2 * addr_size), _("End"),
15163 (int) (4 + 2 * addr_size), _("Page Offset"));
15164 filenames = descdata + count * 3 * addr_size;
595712bb 15165 while (count-- > 0)
9ece1fa9
TT
15166 {
15167 bfd_vma start, end, file_ofs;
15168
15169 if (filenames == descend)
15170 {
15171 printf (_(" Malformed note - filenames end too early\n"));
15172 return 0;
15173 }
15174
15175 start = byte_get (descdata, addr_size);
15176 descdata += addr_size;
15177 end = byte_get (descdata, addr_size);
15178 descdata += addr_size;
15179 file_ofs = byte_get (descdata, addr_size);
15180 descdata += addr_size;
15181
15182 printf (" ");
15183 print_vma (start, FULL_HEX);
15184 printf (" ");
15185 print_vma (end, FULL_HEX);
15186 printf (" ");
15187 print_vma (file_ofs, FULL_HEX);
15188 printf ("\n %s\n", filenames);
15189
15190 filenames += 1 + strlen ((char *) filenames);
15191 }
15192
15193 return 1;
15194}
15195
1118d252
RM
15196static const char *
15197get_gnu_elf_note_type (unsigned e_type)
15198{
15199 static char buff[64];
15200
15201 switch (e_type)
15202 {
15203 case NT_GNU_ABI_TAG:
15204 return _("NT_GNU_ABI_TAG (ABI version tag)");
15205 case NT_GNU_HWCAP:
15206 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
15207 case NT_GNU_BUILD_ID:
15208 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
15209 case NT_GNU_GOLD_VERSION:
15210 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
15211 default:
15212 break;
15213 }
15214
15215 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
15216 return buff;
15217}
15218
664f90a3
TT
15219static int
15220print_gnu_note (Elf_Internal_Note *pnote)
15221{
15222 switch (pnote->type)
15223 {
15224 case NT_GNU_BUILD_ID:
15225 {
15226 unsigned long i;
15227
15228 printf (_(" Build ID: "));
15229 for (i = 0; i < pnote->descsz; ++i)
15230 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 15231 printf ("\n");
664f90a3
TT
15232 }
15233 break;
15234
15235 case NT_GNU_ABI_TAG:
15236 {
15237 unsigned long os, major, minor, subminor;
15238 const char *osname;
15239
3102e897
NC
15240 /* PR 17531: file: 030-599401-0.004. */
15241 if (pnote->descsz < 16)
15242 {
15243 printf (_(" <corrupt GNU_ABI_TAG>\n"));
15244 break;
15245 }
15246
664f90a3
TT
15247 os = byte_get ((unsigned char *) pnote->descdata, 4);
15248 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
15249 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
15250 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
15251
15252 switch (os)
15253 {
15254 case GNU_ABI_TAG_LINUX:
15255 osname = "Linux";
15256 break;
15257 case GNU_ABI_TAG_HURD:
15258 osname = "Hurd";
15259 break;
15260 case GNU_ABI_TAG_SOLARIS:
15261 osname = "Solaris";
15262 break;
15263 case GNU_ABI_TAG_FREEBSD:
15264 osname = "FreeBSD";
15265 break;
15266 case GNU_ABI_TAG_NETBSD:
15267 osname = "NetBSD";
15268 break;
14ae95f2
RM
15269 case GNU_ABI_TAG_SYLLABLE:
15270 osname = "Syllable";
15271 break;
15272 case GNU_ABI_TAG_NACL:
15273 osname = "NaCl";
15274 break;
664f90a3
TT
15275 default:
15276 osname = "Unknown";
15277 break;
15278 }
15279
15280 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
15281 major, minor, subminor);
15282 }
15283 break;
926c5385
CC
15284
15285 case NT_GNU_GOLD_VERSION:
15286 {
15287 unsigned long i;
15288
15289 printf (_(" Version: "));
15290 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
15291 printf ("%c", pnote->descdata[i]);
15292 printf ("\n");
15293 }
15294 break;
664f90a3
TT
15295 }
15296
15297 return 1;
15298}
15299
685080f2
NC
15300static const char *
15301get_v850_elf_note_type (enum v850_notes n_type)
15302{
15303 static char buff[64];
15304
15305 switch (n_type)
15306 {
15307 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
15308 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
15309 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
15310 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
15311 case V850_NOTE_CACHE_INFO: return _("Use of cache");
15312 case V850_NOTE_MMU_INFO: return _("Use of MMU");
15313 default:
15314 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
15315 return buff;
15316 }
15317}
15318
15319static int
15320print_v850_note (Elf_Internal_Note * pnote)
15321{
15322 unsigned int val;
15323
15324 if (pnote->descsz != 4)
15325 return 0;
15326 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
15327
15328 if (val == 0)
15329 {
15330 printf (_("not set\n"));
15331 return 1;
15332 }
15333
15334 switch (pnote->type)
15335 {
15336 case V850_NOTE_ALIGNMENT:
15337 switch (val)
15338 {
15339 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return 1;
15340 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return 1;
15341 }
15342 break;
14ae95f2 15343
685080f2
NC
15344 case V850_NOTE_DATA_SIZE:
15345 switch (val)
15346 {
15347 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return 1;
15348 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return 1;
15349 }
15350 break;
14ae95f2 15351
685080f2
NC
15352 case V850_NOTE_FPU_INFO:
15353 switch (val)
15354 {
15355 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return 1;
15356 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return 1;
15357 }
15358 break;
14ae95f2 15359
685080f2
NC
15360 case V850_NOTE_MMU_INFO:
15361 case V850_NOTE_CACHE_INFO:
15362 case V850_NOTE_SIMD_INFO:
15363 if (val == EF_RH850_SIMD)
15364 {
15365 printf (_("yes\n"));
15366 return 1;
15367 }
15368 break;
15369
15370 default:
15371 /* An 'unknown note type' message will already have been displayed. */
15372 break;
15373 }
15374
15375 printf (_("unknown value: %x\n"), val);
15376 return 0;
15377}
15378
c6056a74
SF
15379static int
15380process_netbsd_elf_note (Elf_Internal_Note * pnote)
15381{
15382 unsigned int version;
15383
15384 switch (pnote->type)
15385 {
15386 case NT_NETBSD_IDENT:
15387 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
15388 if ((version / 10000) % 100)
15389 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
15390 version, version / 100000000, (version / 1000000) % 100,
15391 (version / 10000) % 100 > 26 ? "Z" : "",
15392 'A' + (version / 10000) % 26);
15393 else
15394 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
15395 version, version / 100000000, (version / 1000000) % 100,
15396 (version / 100) % 100);
15397 return 1;
15398
15399 case NT_NETBSD_MARCH:
15400 printf (" NetBSD\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
15401 pnote->descdata);
15402 return 1;
15403
15404 default:
15405 break;
15406 }
15407
15408 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n", pnote->descsz,
15409 pnote->type);
15410 return 1;
15411}
15412
f4ddf30f
JB
15413static const char *
15414get_freebsd_elfcore_note_type (unsigned e_type)
15415{
f4ddf30f
JB
15416 switch (e_type)
15417 {
15418 case NT_FREEBSD_THRMISC:
15419 return _("NT_THRMISC (thrmisc structure)");
15420 case NT_FREEBSD_PROCSTAT_PROC:
15421 return _("NT_PROCSTAT_PROC (proc data)");
15422 case NT_FREEBSD_PROCSTAT_FILES:
15423 return _("NT_PROCSTAT_FILES (files data)");
15424 case NT_FREEBSD_PROCSTAT_VMMAP:
15425 return _("NT_PROCSTAT_VMMAP (vmmap data)");
15426 case NT_FREEBSD_PROCSTAT_GROUPS:
15427 return _("NT_PROCSTAT_GROUPS (groups data)");
15428 case NT_FREEBSD_PROCSTAT_UMASK:
15429 return _("NT_PROCSTAT_UMASK (umask data)");
15430 case NT_FREEBSD_PROCSTAT_RLIMIT:
15431 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
15432 case NT_FREEBSD_PROCSTAT_OSREL:
15433 return _("NT_PROCSTAT_OSREL (osreldate data)");
15434 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
15435 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
15436 case NT_FREEBSD_PROCSTAT_AUXV:
15437 return _("NT_PROCSTAT_AUXV (auxv data)");
15438 }
15439 return get_note_type (e_type);
15440}
15441
9437c45b 15442static const char *
d3ba0551 15443get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
15444{
15445 static char buff[64];
15446
b4db1224 15447 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
15448 {
15449 /* NetBSD core "procinfo" structure. */
15450 return _("NetBSD procinfo structure");
15451 }
15452
15453 /* As of Jan 2002 there are no other machine-independent notes
15454 defined for NetBSD core files. If the note type is less
15455 than the start of the machine-dependent note types, we don't
15456 understand it. */
15457
b4db1224 15458 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 15459 {
e9e44622 15460 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
15461 return buff;
15462 }
15463
15464 switch (elf_header.e_machine)
15465 {
15466 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
15467 and PT_GETFPREGS == mach+2. */
15468
15469 case EM_OLD_ALPHA:
15470 case EM_ALPHA:
15471 case EM_SPARC:
15472 case EM_SPARC32PLUS:
15473 case EM_SPARCV9:
15474 switch (e_type)
15475 {
2b692964 15476 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 15477 return _("PT_GETREGS (reg structure)");
2b692964 15478 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 15479 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
15480 default:
15481 break;
15482 }
15483 break;
15484
15485 /* On all other arch's, PT_GETREGS == mach+1 and
15486 PT_GETFPREGS == mach+3. */
15487 default:
15488 switch (e_type)
15489 {
2b692964 15490 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 15491 return _("PT_GETREGS (reg structure)");
2b692964 15492 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 15493 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
15494 default:
15495 break;
15496 }
15497 }
15498
9cf03b7e 15499 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 15500 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
15501 return buff;
15502}
15503
70616151
TT
15504static const char *
15505get_stapsdt_note_type (unsigned e_type)
15506{
15507 static char buff[64];
15508
15509 switch (e_type)
15510 {
15511 case NT_STAPSDT:
15512 return _("NT_STAPSDT (SystemTap probe descriptors)");
15513
15514 default:
15515 break;
15516 }
15517
15518 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
15519 return buff;
15520}
15521
c6a9fc58
TT
15522static int
15523print_stapsdt_note (Elf_Internal_Note *pnote)
15524{
15525 int addr_size = is_32bit_elf ? 4 : 8;
15526 char *data = pnote->descdata;
15527 char *data_end = pnote->descdata + pnote->descsz;
15528 bfd_vma pc, base_addr, semaphore;
15529 char *provider, *probe, *arg_fmt;
15530
15531 pc = byte_get ((unsigned char *) data, addr_size);
15532 data += addr_size;
15533 base_addr = byte_get ((unsigned char *) data, addr_size);
15534 data += addr_size;
15535 semaphore = byte_get ((unsigned char *) data, addr_size);
15536 data += addr_size;
15537
15538 provider = data;
15539 data += strlen (data) + 1;
15540 probe = data;
15541 data += strlen (data) + 1;
15542 arg_fmt = data;
15543 data += strlen (data) + 1;
15544
15545 printf (_(" Provider: %s\n"), provider);
15546 printf (_(" Name: %s\n"), probe);
15547 printf (_(" Location: "));
15548 print_vma (pc, FULL_HEX);
15549 printf (_(", Base: "));
15550 print_vma (base_addr, FULL_HEX);
15551 printf (_(", Semaphore: "));
15552 print_vma (semaphore, FULL_HEX);
9cf03b7e 15553 printf ("\n");
c6a9fc58
TT
15554 printf (_(" Arguments: %s\n"), arg_fmt);
15555
15556 return data == data_end;
15557}
15558
00e98fc7
TG
15559static const char *
15560get_ia64_vms_note_type (unsigned e_type)
15561{
15562 static char buff[64];
15563
15564 switch (e_type)
15565 {
15566 case NT_VMS_MHD:
15567 return _("NT_VMS_MHD (module header)");
15568 case NT_VMS_LNM:
15569 return _("NT_VMS_LNM (language name)");
15570 case NT_VMS_SRC:
15571 return _("NT_VMS_SRC (source files)");
15572 case NT_VMS_TITLE:
9cf03b7e 15573 return "NT_VMS_TITLE";
00e98fc7
TG
15574 case NT_VMS_EIDC:
15575 return _("NT_VMS_EIDC (consistency check)");
15576 case NT_VMS_FPMODE:
15577 return _("NT_VMS_FPMODE (FP mode)");
15578 case NT_VMS_LINKTIME:
9cf03b7e 15579 return "NT_VMS_LINKTIME";
00e98fc7
TG
15580 case NT_VMS_IMGNAM:
15581 return _("NT_VMS_IMGNAM (image name)");
15582 case NT_VMS_IMGID:
15583 return _("NT_VMS_IMGID (image id)");
15584 case NT_VMS_LINKID:
15585 return _("NT_VMS_LINKID (link id)");
15586 case NT_VMS_IMGBID:
15587 return _("NT_VMS_IMGBID (build id)");
15588 case NT_VMS_GSTNAM:
15589 return _("NT_VMS_GSTNAM (sym table name)");
15590 case NT_VMS_ORIG_DYN:
9cf03b7e 15591 return "NT_VMS_ORIG_DYN";
00e98fc7 15592 case NT_VMS_PATCHTIME:
9cf03b7e 15593 return "NT_VMS_PATCHTIME";
00e98fc7
TG
15594 default:
15595 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
15596 return buff;
15597 }
15598}
15599
15600static int
15601print_ia64_vms_note (Elf_Internal_Note * pnote)
15602{
15603 switch (pnote->type)
15604 {
15605 case NT_VMS_MHD:
15606 if (pnote->descsz > 36)
15607 {
15608 size_t l = strlen (pnote->descdata + 34);
15609 printf (_(" Creation date : %.17s\n"), pnote->descdata);
15610 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
15611 printf (_(" Module name : %s\n"), pnote->descdata + 34);
15612 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
15613 }
15614 else
15615 printf (_(" Invalid size\n"));
15616 break;
15617 case NT_VMS_LNM:
15618 printf (_(" Language: %s\n"), pnote->descdata);
15619 break;
15620#ifdef BFD64
15621 case NT_VMS_FPMODE:
9cf03b7e 15622 printf (_(" Floating Point mode: "));
4a5cb34f 15623 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 15624 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
15625 break;
15626 case NT_VMS_LINKTIME:
15627 printf (_(" Link time: "));
15628 print_vms_time
15629 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
15630 printf ("\n");
15631 break;
15632 case NT_VMS_PATCHTIME:
15633 printf (_(" Patch time: "));
15634 print_vms_time
15635 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
15636 printf ("\n");
15637 break;
15638 case NT_VMS_ORIG_DYN:
15639 printf (_(" Major id: %u, minor id: %u\n"),
15640 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
15641 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 15642 printf (_(" Last modified : "));
00e98fc7
TG
15643 print_vms_time
15644 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 15645 printf (_("\n Link flags : "));
4a5cb34f 15646 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 15647 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 15648 printf (_(" Header flags: 0x%08x\n"),
948f632f 15649 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
00e98fc7
TG
15650 printf (_(" Image id : %s\n"), pnote->descdata + 32);
15651 break;
15652#endif
15653 case NT_VMS_IMGNAM:
15654 printf (_(" Image name: %s\n"), pnote->descdata);
15655 break;
15656 case NT_VMS_GSTNAM:
15657 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
15658 break;
15659 case NT_VMS_IMGID:
15660 printf (_(" Image id: %s\n"), pnote->descdata);
15661 break;
15662 case NT_VMS_LINKID:
15663 printf (_(" Linker id: %s\n"), pnote->descdata);
15664 break;
15665 default:
15666 break;
15667 }
15668 return 1;
15669}
15670
6d118b09
NC
15671/* Note that by the ELF standard, the name field is already null byte
15672 terminated, and namesz includes the terminating null byte.
15673 I.E. the value of namesz for the name "FSF" is 4.
15674
e3c8793a 15675 If the value of namesz is zero, there is no name present. */
779fe533 15676static int
2cf0635d 15677process_note (Elf_Internal_Note * pnote)
779fe533 15678{
2cf0635d
NC
15679 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
15680 const char * nt;
9437c45b
JT
15681
15682 if (pnote->namesz == 0)
1ec5cd37
NC
15683 /* If there is no note name, then use the default set of
15684 note type strings. */
15685 nt = get_note_type (pnote->type);
15686
1118d252
RM
15687 else if (const_strneq (pnote->namedata, "GNU"))
15688 /* GNU-specific object file notes. */
15689 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
15690
15691 else if (const_strneq (pnote->namedata, "FreeBSD"))
15692 /* FreeBSD-specific core file notes. */
15693 nt = get_freebsd_elfcore_note_type (pnote->type);
1118d252 15694
0112cd26 15695 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
15696 /* NetBSD-specific core file notes. */
15697 nt = get_netbsd_elfcore_note_type (pnote->type);
15698
c6056a74
SF
15699 else if (const_strneq (pnote->namedata, "NetBSD"))
15700 /* NetBSD-specific core file notes. */
15701 return process_netbsd_elf_note (pnote);
15702
b15fa79e
AM
15703 else if (strneq (pnote->namedata, "SPU/", 4))
15704 {
15705 /* SPU-specific core file notes. */
15706 nt = pnote->namedata + 4;
15707 name = "SPU";
15708 }
15709
00e98fc7
TG
15710 else if (const_strneq (pnote->namedata, "IPF/VMS"))
15711 /* VMS/ia64-specific file notes. */
15712 nt = get_ia64_vms_note_type (pnote->type);
15713
70616151
TT
15714 else if (const_strneq (pnote->namedata, "stapsdt"))
15715 nt = get_stapsdt_note_type (pnote->type);
15716
9437c45b 15717 else
1ec5cd37
NC
15718 /* Don't recognize this note name; just use the default set of
15719 note type strings. */
00e98fc7 15720 nt = get_note_type (pnote->type);
9437c45b 15721
2aee03ae 15722 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
15723
15724 if (const_strneq (pnote->namedata, "IPF/VMS"))
15725 return print_ia64_vms_note (pnote);
664f90a3
TT
15726 else if (const_strneq (pnote->namedata, "GNU"))
15727 return print_gnu_note (pnote);
c6a9fc58
TT
15728 else if (const_strneq (pnote->namedata, "stapsdt"))
15729 return print_stapsdt_note (pnote);
9ece1fa9
TT
15730 else if (const_strneq (pnote->namedata, "CORE"))
15731 return print_core_note (pnote);
00e98fc7
TG
15732 else
15733 return 1;
779fe533
NC
15734}
15735
6d118b09 15736
779fe533 15737static int
2cf0635d 15738process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 15739{
2cf0635d
NC
15740 Elf_External_Note * pnotes;
15741 Elf_External_Note * external;
c8071705 15742 char * end;
b34976b6 15743 int res = 1;
103f02d3 15744
779fe533
NC
15745 if (length <= 0)
15746 return 0;
103f02d3 15747
3f5e193b 15748 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 15749 _("notes"));
dd24e3da 15750 if (pnotes == NULL)
a6e9f9df 15751 return 0;
779fe533 15752
103f02d3 15753 external = pnotes;
103f02d3 15754
9dd3a467 15755 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 15756 (unsigned long) offset, (unsigned long) length);
2aee03ae 15757 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 15758
c8071705
NC
15759 end = (char *) pnotes + length;
15760 while ((char *) external < end)
779fe533 15761 {
b34976b6 15762 Elf_Internal_Note inote;
15b42fb0
AM
15763 size_t min_notesz;
15764 char *next;
2cf0635d 15765 char * temp = NULL;
c8071705 15766 size_t data_remaining = end - (char *) external;
6d118b09 15767
00e98fc7 15768 if (!is_ia64_vms ())
15b42fb0 15769 {
9dd3a467
NC
15770 /* PR binutils/15191
15771 Make sure that there is enough data to read. */
15b42fb0
AM
15772 min_notesz = offsetof (Elf_External_Note, name);
15773 if (data_remaining < min_notesz)
9dd3a467
NC
15774 {
15775 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
15776 (int) data_remaining);
15777 break;
15778 }
15b42fb0
AM
15779 inote.type = BYTE_GET (external->type);
15780 inote.namesz = BYTE_GET (external->namesz);
15781 inote.namedata = external->name;
15782 inote.descsz = BYTE_GET (external->descsz);
15783 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
834f871c 15784 /* PR 17531: file: 3443835e. */
c8071705 15785 if (inote.descdata < (char *) pnotes || inote.descdata > end)
834f871c
NC
15786 {
15787 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
15788 inote.descdata = inote.namedata;
15789 inote.namesz = 0;
15790 }
14ae95f2 15791
15b42fb0
AM
15792 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15793 next = inote.descdata + align_power (inote.descsz, 2);
15794 }
00e98fc7 15795 else
15b42fb0
AM
15796 {
15797 Elf64_External_VMS_Note *vms_external;
00e98fc7 15798
9dd3a467
NC
15799 /* PR binutils/15191
15800 Make sure that there is enough data to read. */
15b42fb0
AM
15801 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15802 if (data_remaining < min_notesz)
9dd3a467
NC
15803 {
15804 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
15805 (int) data_remaining);
15806 break;
15807 }
3e55a963 15808
15b42fb0
AM
15809 vms_external = (Elf64_External_VMS_Note *) external;
15810 inote.type = BYTE_GET (vms_external->type);
15811 inote.namesz = BYTE_GET (vms_external->namesz);
15812 inote.namedata = vms_external->name;
15813 inote.descsz = BYTE_GET (vms_external->descsz);
15814 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15815 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15816 next = inote.descdata + align_power (inote.descsz, 3);
15817 }
15818
15819 if (inote.descdata < (char *) external + min_notesz
15820 || next < (char *) external + min_notesz
5d921cbd
NC
15821 /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
15822 || inote.namedata + inote.namesz < inote.namedata
15823 || inote.descdata + inote.descsz < inote.descdata
15b42fb0 15824 || data_remaining < (size_t)(next - (char *) external))
3e55a963 15825 {
15b42fb0 15826 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 15827 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 15828 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
15829 inote.type, inote.namesz, inote.descsz);
15830 break;
15831 }
15832
15b42fb0 15833 external = (Elf_External_Note *) next;
dd24e3da 15834
6d118b09
NC
15835 /* Verify that name is null terminated. It appears that at least
15836 one version of Linux (RedHat 6.0) generates corefiles that don't
15837 comply with the ELF spec by failing to include the null byte in
15838 namesz. */
8b971f9f 15839 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 15840 {
3f5e193b 15841 temp = (char *) malloc (inote.namesz + 1);
6d118b09
NC
15842 if (temp == NULL)
15843 {
8b73c356 15844 error (_("Out of memory allocating space for inote name\n"));
6d118b09
NC
15845 res = 0;
15846 break;
15847 }
76da6bbe 15848
6d118b09
NC
15849 strncpy (temp, inote.namedata, inote.namesz);
15850 temp[inote.namesz] = 0;
76da6bbe 15851
6d118b09
NC
15852 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
15853 inote.namedata = temp;
15854 }
15855
15856 res &= process_note (& inote);
103f02d3 15857
6d118b09
NC
15858 if (temp != NULL)
15859 {
15860 free (temp);
15861 temp = NULL;
15862 }
779fe533
NC
15863 }
15864
15865 free (pnotes);
103f02d3 15866
779fe533
NC
15867 return res;
15868}
15869
15870static int
2cf0635d 15871process_corefile_note_segments (FILE * file)
779fe533 15872{
2cf0635d 15873 Elf_Internal_Phdr * segment;
b34976b6
AM
15874 unsigned int i;
15875 int res = 1;
103f02d3 15876
d93f0186 15877 if (! get_program_headers (file))
779fe533 15878 return 0;
103f02d3 15879
779fe533
NC
15880 for (i = 0, segment = program_headers;
15881 i < elf_header.e_phnum;
b34976b6 15882 i++, segment++)
779fe533
NC
15883 {
15884 if (segment->p_type == PT_NOTE)
103f02d3 15885 res &= process_corefile_note_segment (file,
30800947
NC
15886 (bfd_vma) segment->p_offset,
15887 (bfd_vma) segment->p_filesz);
779fe533 15888 }
103f02d3 15889
779fe533
NC
15890 return res;
15891}
15892
685080f2
NC
15893static int
15894process_v850_notes (FILE * file, bfd_vma offset, bfd_vma length)
15895{
15896 Elf_External_Note * pnotes;
15897 Elf_External_Note * external;
c8071705 15898 char * end;
685080f2
NC
15899 int res = 1;
15900
15901 if (length <= 0)
15902 return 0;
15903
15904 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15905 _("v850 notes"));
15906 if (pnotes == NULL)
15907 return 0;
15908
15909 external = pnotes;
c8071705 15910 end = (char*) pnotes + length;
685080f2
NC
15911
15912 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
15913 (unsigned long) offset, (unsigned long) length);
15914
c8071705 15915 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
15916 {
15917 Elf_External_Note * next;
15918 Elf_Internal_Note inote;
15919
15920 inote.type = BYTE_GET (external->type);
15921 inote.namesz = BYTE_GET (external->namesz);
15922 inote.namedata = external->name;
15923 inote.descsz = BYTE_GET (external->descsz);
15924 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
15925 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15926
c8071705
NC
15927 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
15928 {
15929 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
15930 inote.descdata = inote.namedata;
15931 inote.namesz = 0;
15932 }
15933
685080f2
NC
15934 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
15935
c8071705 15936 if ( ((char *) next > end)
685080f2
NC
15937 || ((char *) next < (char *) pnotes))
15938 {
15939 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
15940 (unsigned long) ((char *) external - (char *) pnotes));
15941 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
15942 inote.type, inote.namesz, inote.descsz);
15943 break;
15944 }
15945
15946 external = next;
15947
15948 /* Prevent out-of-bounds indexing. */
c8071705 15949 if ( inote.namedata + inote.namesz > end
685080f2
NC
15950 || inote.namedata + inote.namesz < inote.namedata)
15951 {
15952 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
15953 (unsigned long) ((char *) external - (char *) pnotes));
15954 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
15955 inote.type, inote.namesz, inote.descsz);
15956 break;
15957 }
15958
15959 printf (" %s: ", get_v850_elf_note_type (inote.type));
15960
15961 if (! print_v850_note (& inote))
15962 {
15963 res = 0;
15964 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
15965 inote.namesz, inote.descsz);
15966 }
15967 }
15968
15969 free (pnotes);
15970
15971 return res;
15972}
15973
779fe533 15974static int
2cf0635d 15975process_note_sections (FILE * file)
1ec5cd37 15976{
2cf0635d 15977 Elf_Internal_Shdr * section;
1ec5cd37 15978 unsigned long i;
df565f32 15979 int n = 0;
1ec5cd37
NC
15980 int res = 1;
15981
15982 for (i = 0, section = section_headers;
fa1908fd 15983 i < elf_header.e_shnum && section != NULL;
1ec5cd37 15984 i++, section++)
685080f2
NC
15985 {
15986 if (section->sh_type == SHT_NOTE)
15987 {
15988 res &= process_corefile_note_segment (file,
15989 (bfd_vma) section->sh_offset,
15990 (bfd_vma) section->sh_size);
15991 n++;
15992 }
15993
15994 if (( elf_header.e_machine == EM_V800
15995 || elf_header.e_machine == EM_V850
15996 || elf_header.e_machine == EM_CYGNUS_V850)
15997 && section->sh_type == SHT_RENESAS_INFO)
15998 {
15999 res &= process_v850_notes (file,
16000 (bfd_vma) section->sh_offset,
16001 (bfd_vma) section->sh_size);
16002 n++;
16003 }
16004 }
df565f32
NC
16005
16006 if (n == 0)
16007 /* Try processing NOTE segments instead. */
16008 return process_corefile_note_segments (file);
1ec5cd37
NC
16009
16010 return res;
16011}
16012
16013static int
2cf0635d 16014process_notes (FILE * file)
779fe533
NC
16015{
16016 /* If we have not been asked to display the notes then do nothing. */
16017 if (! do_notes)
16018 return 1;
103f02d3 16019
779fe533 16020 if (elf_header.e_type != ET_CORE)
1ec5cd37 16021 return process_note_sections (file);
103f02d3 16022
779fe533 16023 /* No program headers means no NOTE segment. */
1ec5cd37
NC
16024 if (elf_header.e_phnum > 0)
16025 return process_corefile_note_segments (file);
779fe533 16026
1ec5cd37
NC
16027 printf (_("No note segments present in the core file.\n"));
16028 return 1;
779fe533
NC
16029}
16030
252b5132 16031static int
2cf0635d 16032process_arch_specific (FILE * file)
252b5132 16033{
a952a375
NC
16034 if (! do_arch)
16035 return 1;
16036
252b5132
RH
16037 switch (elf_header.e_machine)
16038 {
11c1ff18
PB
16039 case EM_ARM:
16040 return process_arm_specific (file);
252b5132 16041 case EM_MIPS:
4fe85591 16042 case EM_MIPS_RS3_LE:
252b5132
RH
16043 return process_mips_specific (file);
16044 break;
35c08157
KLC
16045 case EM_NDS32:
16046 return process_nds32_specific (file);
16047 break;
34c8bcba
JM
16048 case EM_PPC:
16049 return process_power_specific (file);
16050 break;
643f7afb
AK
16051 case EM_S390:
16052 case EM_S390_OLD:
16053 return process_s390_specific (file);
16054 break;
9e8c70f9
DM
16055 case EM_SPARC:
16056 case EM_SPARC32PLUS:
16057 case EM_SPARCV9:
16058 return process_sparc_specific (file);
16059 break;
59e6276b
JM
16060 case EM_TI_C6000:
16061 return process_tic6x_specific (file);
16062 break;
13761a11
NC
16063 case EM_MSP430:
16064 return process_msp430x_specific (file);
252b5132
RH
16065 default:
16066 break;
16067 }
16068 return 1;
16069}
16070
16071static int
2cf0635d 16072get_file_header (FILE * file)
252b5132 16073{
9ea033b2
NC
16074 /* Read in the identity array. */
16075 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
16076 return 0;
16077
9ea033b2 16078 /* Determine how to read the rest of the header. */
b34976b6 16079 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
16080 {
16081 default: /* fall through */
16082 case ELFDATANONE: /* fall through */
adab8cdc
AO
16083 case ELFDATA2LSB:
16084 byte_get = byte_get_little_endian;
16085 byte_put = byte_put_little_endian;
16086 break;
16087 case ELFDATA2MSB:
16088 byte_get = byte_get_big_endian;
16089 byte_put = byte_put_big_endian;
16090 break;
9ea033b2
NC
16091 }
16092
16093 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 16094 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
16095
16096 /* Read in the rest of the header. */
16097 if (is_32bit_elf)
16098 {
16099 Elf32_External_Ehdr ehdr32;
252b5132 16100
9ea033b2
NC
16101 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
16102 return 0;
103f02d3 16103
9ea033b2
NC
16104 elf_header.e_type = BYTE_GET (ehdr32.e_type);
16105 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
16106 elf_header.e_version = BYTE_GET (ehdr32.e_version);
16107 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
16108 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
16109 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
16110 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
16111 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
16112 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
16113 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
16114 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
16115 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
16116 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
16117 }
252b5132 16118 else
9ea033b2
NC
16119 {
16120 Elf64_External_Ehdr ehdr64;
a952a375
NC
16121
16122 /* If we have been compiled with sizeof (bfd_vma) == 4, then
16123 we will not be able to cope with the 64bit data found in
16124 64 ELF files. Detect this now and abort before we start
50c2245b 16125 overwriting things. */
a952a375
NC
16126 if (sizeof (bfd_vma) < 8)
16127 {
e3c8793a
NC
16128 error (_("This instance of readelf has been built without support for a\n\
1612964 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
16130 return 0;
16131 }
103f02d3 16132
9ea033b2
NC
16133 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
16134 return 0;
103f02d3 16135
9ea033b2
NC
16136 elf_header.e_type = BYTE_GET (ehdr64.e_type);
16137 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
16138 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
16139 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
16140 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
16141 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
16142 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
16143 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
16144 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
16145 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
16146 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
16147 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
16148 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
16149 }
252b5132 16150
7ece0d85
JJ
16151 if (elf_header.e_shoff)
16152 {
16153 /* There may be some extensions in the first section header. Don't
16154 bomb if we can't read it. */
16155 if (is_32bit_elf)
049b0c3a 16156 get_32bit_section_headers (file, TRUE);
7ece0d85 16157 else
049b0c3a 16158 get_64bit_section_headers (file, TRUE);
7ece0d85 16159 }
560f3c1c 16160
252b5132
RH
16161 return 1;
16162}
16163
fb52b2f4
NC
16164/* Process one ELF object file according to the command line options.
16165 This file may actually be stored in an archive. The file is
16166 positioned at the start of the ELF object. */
16167
ff78d6d6 16168static int
2cf0635d 16169process_object (char * file_name, FILE * file)
252b5132 16170{
252b5132
RH
16171 unsigned int i;
16172
252b5132
RH
16173 if (! get_file_header (file))
16174 {
16175 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 16176 return 1;
252b5132
RH
16177 }
16178
16179 /* Initialise per file variables. */
60bca95a 16180 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
16181 version_info[i] = 0;
16182
60bca95a 16183 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 16184 dynamic_info[i] = 0;
5115b233 16185 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
16186
16187 /* Process the file. */
16188 if (show_name)
16189 printf (_("\nFile: %s\n"), file_name);
16190
18bd398b
NC
16191 /* Initialise the dump_sects array from the cmdline_dump_sects array.
16192 Note we do this even if cmdline_dump_sects is empty because we
16193 must make sure that the dump_sets array is zeroed out before each
16194 object file is processed. */
16195 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 16196 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
16197
16198 if (num_cmdline_dump_sects > 0)
16199 {
16200 if (num_dump_sects == 0)
16201 /* A sneaky way of allocating the dump_sects array. */
09c11c86 16202 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
16203
16204 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
16205 memcpy (dump_sects, cmdline_dump_sects,
16206 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 16207 }
d70c5fc7 16208
252b5132 16209 if (! process_file_header ())
fb52b2f4 16210 return 1;
252b5132 16211
d1f5c6e3 16212 if (! process_section_headers (file))
2f62977e 16213 {
d1f5c6e3
L
16214 /* Without loaded section headers we cannot process lots of
16215 things. */
2f62977e 16216 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 16217
2f62977e 16218 if (! do_using_dynamic)
2c610e4b 16219 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 16220 }
252b5132 16221
d1f5c6e3
L
16222 if (! process_section_groups (file))
16223 {
16224 /* Without loaded section groups we cannot process unwind. */
16225 do_unwind = 0;
16226 }
16227
2f62977e 16228 if (process_program_headers (file))
b2d38a17 16229 process_dynamic_section (file);
252b5132
RH
16230
16231 process_relocs (file);
16232
4d6ed7c8
NC
16233 process_unwind (file);
16234
252b5132
RH
16235 process_symbol_table (file);
16236
16237 process_syminfo (file);
16238
16239 process_version_sections (file);
16240
16241 process_section_contents (file);
f5842774 16242
1ec5cd37 16243 process_notes (file);
103f02d3 16244
047b2264
JJ
16245 process_gnu_liblist (file);
16246
252b5132
RH
16247 process_arch_specific (file);
16248
d93f0186
NC
16249 if (program_headers)
16250 {
16251 free (program_headers);
16252 program_headers = NULL;
16253 }
16254
252b5132
RH
16255 if (section_headers)
16256 {
16257 free (section_headers);
16258 section_headers = NULL;
16259 }
16260
16261 if (string_table)
16262 {
16263 free (string_table);
16264 string_table = NULL;
d40ac9bd 16265 string_table_length = 0;
252b5132
RH
16266 }
16267
16268 if (dynamic_strings)
16269 {
16270 free (dynamic_strings);
16271 dynamic_strings = NULL;
d79b3d50 16272 dynamic_strings_length = 0;
252b5132
RH
16273 }
16274
16275 if (dynamic_symbols)
16276 {
16277 free (dynamic_symbols);
16278 dynamic_symbols = NULL;
19936277 16279 num_dynamic_syms = 0;
252b5132
RH
16280 }
16281
16282 if (dynamic_syminfo)
16283 {
16284 free (dynamic_syminfo);
16285 dynamic_syminfo = NULL;
16286 }
ff78d6d6 16287
293c573e
MR
16288 if (dynamic_section)
16289 {
16290 free (dynamic_section);
16291 dynamic_section = NULL;
16292 }
16293
e4b17d5c
L
16294 if (section_headers_groups)
16295 {
16296 free (section_headers_groups);
16297 section_headers_groups = NULL;
16298 }
16299
16300 if (section_groups)
16301 {
2cf0635d
NC
16302 struct group_list * g;
16303 struct group_list * next;
e4b17d5c
L
16304
16305 for (i = 0; i < group_count; i++)
16306 {
16307 for (g = section_groups [i].root; g != NULL; g = next)
16308 {
16309 next = g->next;
16310 free (g);
16311 }
16312 }
16313
16314 free (section_groups);
16315 section_groups = NULL;
16316 }
16317
19e6b90e 16318 free_debug_memory ();
18bd398b 16319
ff78d6d6 16320 return 0;
252b5132
RH
16321}
16322
2cf0635d
NC
16323/* Process an ELF archive.
16324 On entry the file is positioned just after the ARMAG string. */
16325
16326static int
16327process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
16328{
16329 struct archive_info arch;
16330 struct archive_info nested_arch;
16331 size_t got;
2cf0635d
NC
16332 int ret;
16333
16334 show_name = 1;
16335
16336 /* The ARCH structure is used to hold information about this archive. */
16337 arch.file_name = NULL;
16338 arch.file = NULL;
16339 arch.index_array = NULL;
16340 arch.sym_table = NULL;
16341 arch.longnames = NULL;
16342
16343 /* The NESTED_ARCH structure is used as a single-item cache of information
16344 about a nested archive (when members of a thin archive reside within
16345 another regular archive file). */
16346 nested_arch.file_name = NULL;
16347 nested_arch.file = NULL;
16348 nested_arch.index_array = NULL;
16349 nested_arch.sym_table = NULL;
16350 nested_arch.longnames = NULL;
16351
16352 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
16353 {
16354 ret = 1;
16355 goto out;
4145f1d5 16356 }
fb52b2f4 16357
4145f1d5
NC
16358 if (do_archive_index)
16359 {
2cf0635d 16360 if (arch.sym_table == NULL)
4145f1d5
NC
16361 error (_("%s: unable to dump the index as none was found\n"), file_name);
16362 else
16363 {
591f7597 16364 unsigned long i, l;
4145f1d5
NC
16365 unsigned long current_pos;
16366
591f7597
NC
16367 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
16368 file_name, (unsigned long) arch.index_num, arch.sym_size);
4145f1d5
NC
16369 current_pos = ftell (file);
16370
2cf0635d 16371 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 16372 {
2cf0635d
NC
16373 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
16374 {
16375 char * member_name;
4145f1d5 16376
2cf0635d
NC
16377 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
16378
16379 if (member_name != NULL)
16380 {
16381 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
16382
16383 if (qualified_name != NULL)
16384 {
c2a7d3f5
NC
16385 printf (_("Contents of binary %s at offset "), qualified_name);
16386 (void) print_vma (arch.index_array[i], PREFIX_HEX);
16387 putchar ('\n');
2cf0635d
NC
16388 free (qualified_name);
16389 }
4145f1d5
NC
16390 }
16391 }
2cf0635d
NC
16392
16393 if (l >= arch.sym_size)
4145f1d5
NC
16394 {
16395 error (_("%s: end of the symbol table reached before the end of the index\n"),
16396 file_name);
cb8f3167 16397 break;
4145f1d5 16398 }
591f7597
NC
16399 /* PR 17531: file: 0b6630b2. */
16400 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
16401 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
16402 }
16403
c2a7d3f5
NC
16404 if (arch.uses_64bit_indicies)
16405 l = (l + 7) & ~ 7;
16406 else
16407 l += l & 1;
16408
2cf0635d 16409 if (l < arch.sym_size)
c2a7d3f5
NC
16410 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
16411 file_name, arch.sym_size - l);
4145f1d5 16412
4145f1d5
NC
16413 if (fseek (file, current_pos, SEEK_SET) != 0)
16414 {
16415 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
16416 ret = 1;
16417 goto out;
4145f1d5 16418 }
fb52b2f4 16419 }
4145f1d5
NC
16420
16421 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
16422 && !do_segments && !do_header && !do_dump && !do_version
16423 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 16424 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
16425 {
16426 ret = 0; /* Archive index only. */
16427 goto out;
16428 }
fb52b2f4
NC
16429 }
16430
d989285c 16431 ret = 0;
fb52b2f4
NC
16432
16433 while (1)
16434 {
2cf0635d
NC
16435 char * name;
16436 size_t namelen;
16437 char * qualified_name;
16438
16439 /* Read the next archive header. */
16440 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
16441 {
16442 error (_("%s: failed to seek to next archive header\n"), file_name);
16443 return 1;
16444 }
16445 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
16446 if (got != sizeof arch.arhdr)
16447 {
16448 if (got == 0)
16449 break;
16450 error (_("%s: failed to read archive header\n"), file_name);
16451 ret = 1;
16452 break;
16453 }
16454 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
16455 {
16456 error (_("%s: did not find a valid archive header\n"), arch.file_name);
16457 ret = 1;
16458 break;
16459 }
16460
16461 arch.next_arhdr_offset += sizeof arch.arhdr;
16462
16463 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
16464 if (archive_file_size & 01)
16465 ++archive_file_size;
16466
16467 name = get_archive_member_name (&arch, &nested_arch);
16468 if (name == NULL)
fb52b2f4 16469 {
0fd3a477 16470 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
16471 ret = 1;
16472 break;
fb52b2f4 16473 }
2cf0635d 16474 namelen = strlen (name);
fb52b2f4 16475
2cf0635d
NC
16476 qualified_name = make_qualified_name (&arch, &nested_arch, name);
16477 if (qualified_name == NULL)
fb52b2f4 16478 {
2cf0635d 16479 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
16480 ret = 1;
16481 break;
fb52b2f4
NC
16482 }
16483
2cf0635d
NC
16484 if (is_thin_archive && arch.nested_member_origin == 0)
16485 {
16486 /* This is a proxy for an external member of a thin archive. */
16487 FILE * member_file;
16488 char * member_file_name = adjust_relative_path (file_name, name, namelen);
16489 if (member_file_name == NULL)
16490 {
16491 ret = 1;
16492 break;
16493 }
16494
16495 member_file = fopen (member_file_name, "rb");
16496 if (member_file == NULL)
16497 {
16498 error (_("Input file '%s' is not readable.\n"), member_file_name);
16499 free (member_file_name);
16500 ret = 1;
16501 break;
16502 }
16503
16504 archive_file_offset = arch.nested_member_origin;
16505
16506 ret |= process_object (qualified_name, member_file);
16507
16508 fclose (member_file);
16509 free (member_file_name);
16510 }
16511 else if (is_thin_archive)
16512 {
a043396b
NC
16513 /* PR 15140: Allow for corrupt thin archives. */
16514 if (nested_arch.file == NULL)
16515 {
16516 error (_("%s: contains corrupt thin archive: %s\n"),
16517 file_name, name);
16518 ret = 1;
16519 break;
16520 }
16521
2cf0635d
NC
16522 /* This is a proxy for a member of a nested archive. */
16523 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
16524
16525 /* The nested archive file will have been opened and setup by
16526 get_archive_member_name. */
16527 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
16528 {
16529 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
16530 ret = 1;
16531 break;
16532 }
16533
16534 ret |= process_object (qualified_name, nested_arch.file);
16535 }
16536 else
16537 {
16538 archive_file_offset = arch.next_arhdr_offset;
16539 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 16540
2cf0635d
NC
16541 ret |= process_object (qualified_name, file);
16542 }
fb52b2f4 16543
2b52916e
L
16544 if (dump_sects != NULL)
16545 {
16546 free (dump_sects);
16547 dump_sects = NULL;
16548 num_dump_sects = 0;
16549 }
16550
2cf0635d 16551 free (qualified_name);
fb52b2f4
NC
16552 }
16553
4145f1d5 16554 out:
2cf0635d
NC
16555 if (nested_arch.file != NULL)
16556 fclose (nested_arch.file);
16557 release_archive (&nested_arch);
16558 release_archive (&arch);
fb52b2f4 16559
d989285c 16560 return ret;
fb52b2f4
NC
16561}
16562
16563static int
2cf0635d 16564process_file (char * file_name)
fb52b2f4 16565{
2cf0635d 16566 FILE * file;
fb52b2f4
NC
16567 struct stat statbuf;
16568 char armag[SARMAG];
16569 int ret;
16570
16571 if (stat (file_name, &statbuf) < 0)
16572 {
f24ddbdd
NC
16573 if (errno == ENOENT)
16574 error (_("'%s': No such file\n"), file_name);
16575 else
16576 error (_("Could not locate '%s'. System error message: %s\n"),
16577 file_name, strerror (errno));
16578 return 1;
16579 }
16580
16581 if (! S_ISREG (statbuf.st_mode))
16582 {
16583 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
16584 return 1;
16585 }
16586
16587 file = fopen (file_name, "rb");
16588 if (file == NULL)
16589 {
f24ddbdd 16590 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
16591 return 1;
16592 }
16593
16594 if (fread (armag, SARMAG, 1, file) != 1)
16595 {
4145f1d5 16596 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
16597 fclose (file);
16598 return 1;
16599 }
16600
f54498b4
NC
16601 current_file_size = (bfd_size_type) statbuf.st_size;
16602
fb52b2f4 16603 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
16604 ret = process_archive (file_name, file, FALSE);
16605 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
16606 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
16607 else
16608 {
4145f1d5
NC
16609 if (do_archive_index)
16610 error (_("File %s is not an archive so its index cannot be displayed.\n"),
16611 file_name);
16612
fb52b2f4
NC
16613 rewind (file);
16614 archive_file_size = archive_file_offset = 0;
16615 ret = process_object (file_name, file);
16616 }
16617
16618 fclose (file);
16619
f54498b4 16620 current_file_size = 0;
fb52b2f4
NC
16621 return ret;
16622}
16623
252b5132
RH
16624#ifdef SUPPORT_DISASSEMBLY
16625/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 16626 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 16627 symbols. */
252b5132
RH
16628
16629void
2cf0635d 16630print_address (unsigned int addr, FILE * outfile)
252b5132
RH
16631{
16632 fprintf (outfile,"0x%8.8x", addr);
16633}
16634
e3c8793a 16635/* Needed by the i386 disassembler. */
252b5132
RH
16636void
16637db_task_printsym (unsigned int addr)
16638{
16639 print_address (addr, stderr);
16640}
16641#endif
16642
16643int
2cf0635d 16644main (int argc, char ** argv)
252b5132 16645{
ff78d6d6
L
16646 int err;
16647
252b5132
RH
16648#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
16649 setlocale (LC_MESSAGES, "");
3882b010
L
16650#endif
16651#if defined (HAVE_SETLOCALE)
16652 setlocale (LC_CTYPE, "");
252b5132
RH
16653#endif
16654 bindtextdomain (PACKAGE, LOCALEDIR);
16655 textdomain (PACKAGE);
16656
869b9d07
MM
16657 expandargv (&argc, &argv);
16658
252b5132
RH
16659 parse_args (argc, argv);
16660
18bd398b 16661 if (num_dump_sects > 0)
59f14fc0 16662 {
18bd398b 16663 /* Make a copy of the dump_sects array. */
3f5e193b
NC
16664 cmdline_dump_sects = (dump_type *)
16665 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 16666 if (cmdline_dump_sects == NULL)
591a748a 16667 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
16668 else
16669 {
09c11c86
NC
16670 memcpy (cmdline_dump_sects, dump_sects,
16671 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
16672 num_cmdline_dump_sects = num_dump_sects;
16673 }
16674 }
16675
18bd398b
NC
16676 if (optind < (argc - 1))
16677 show_name = 1;
5656ba2c
L
16678 else if (optind >= argc)
16679 {
16680 warn (_("Nothing to do.\n"));
16681 usage (stderr);
16682 }
18bd398b 16683
ff78d6d6 16684 err = 0;
252b5132 16685 while (optind < argc)
18bd398b 16686 err |= process_file (argv[optind++]);
252b5132
RH
16687
16688 if (dump_sects != NULL)
16689 free (dump_sects);
59f14fc0
AS
16690 if (cmdline_dump_sects != NULL)
16691 free (cmdline_dump_sects);
252b5132 16692
ff78d6d6 16693 return err;
252b5132 16694}