Fixes for memory access violations triggered by running readelf on fuzzed binaries.
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
b90efa5b 2 Copyright (C) 1998-2015 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056
CS
46#ifdef HAVE_ZLIB_H
47#include <zlib.h>
48#endif
3bfcb652 49#ifdef HAVE_WCHAR_H
7bfd842d 50#include <wchar.h>
3bfcb652 51#endif
252b5132 52
a952a375 53#if __GNUC__ >= 2
19936277 54/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 55 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 56 Only do this if we believe that the compiler can support a 64 bit
a952a375 57 data type. For now we only rely on GCC being able to do this. */
19936277 58#define BFD64
a952a375
NC
59#endif
60
3db64b00
AM
61#include "bfd.h"
62#include "bucomm.h"
3284fe0c 63#include "elfcomm.h"
19e6b90e 64#include "dwarf.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3f8107ab 109#include "elf/ft32.h"
3b16e843
NC
110#include "elf/h8.h"
111#include "elf/hppa.h"
112#include "elf/i386.h"
35b1837e 113#include "elf/i370.h"
3b16e843
NC
114#include "elf/i860.h"
115#include "elf/i960.h"
116#include "elf/ia64.h"
1e4cf259 117#include "elf/ip2k.h"
84e94c90 118#include "elf/lm32.h"
1c0d3aa6 119#include "elf/iq2000.h"
49f58d10 120#include "elf/m32c.h"
3b16e843
NC
121#include "elf/m32r.h"
122#include "elf/m68k.h"
75751cd9 123#include "elf/m68hc11.h"
252b5132 124#include "elf/mcore.h"
15ab5209 125#include "elf/mep.h"
a3c62988 126#include "elf/metag.h"
7ba29e2a 127#include "elf/microblaze.h"
3b16e843 128#include "elf/mips.h"
3c3bdf30 129#include "elf/mmix.h"
3b16e843
NC
130#include "elf/mn10200.h"
131#include "elf/mn10300.h"
5506d11a 132#include "elf/moxie.h"
4970f871 133#include "elf/mt.h"
2469cfa2 134#include "elf/msp430.h"
35c08157 135#include "elf/nds32.h"
13761a11 136#include "elf/nios2.h"
73589c9d 137#include "elf/or1k.h"
7d466069 138#include "elf/pj.h"
3b16e843 139#include "elf/ppc.h"
c833c019 140#include "elf/ppc64.h"
99c513f6 141#include "elf/rl78.h"
c7927a3c 142#include "elf/rx.h"
a85d7ed0 143#include "elf/s390.h"
1c0d3aa6 144#include "elf/score.h"
3b16e843
NC
145#include "elf/sh.h"
146#include "elf/sparc.h"
e9f53129 147#include "elf/spu.h"
40b36596 148#include "elf/tic6x.h"
aa137e4d
NC
149#include "elf/tilegx.h"
150#include "elf/tilepro.h"
3b16e843 151#include "elf/v850.h"
179d3252 152#include "elf/vax.h"
619ed720 153#include "elf/visium.h"
3b16e843 154#include "elf/x86-64.h"
c29aca4a 155#include "elf/xc16x.h"
f6c1a2d5 156#include "elf/xgate.h"
93fbbb04 157#include "elf/xstormy16.h"
88da6820 158#include "elf/xtensa.h"
252b5132 159
252b5132 160#include "getopt.h"
566b0d53 161#include "libiberty.h"
09c11c86 162#include "safe-ctype.h"
2cf0635d 163#include "filenames.h"
252b5132 164
15b42fb0
AM
165#ifndef offsetof
166#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
167#endif
168
2cf0635d 169char * program_name = "readelf";
c9c1d674 170static unsigned long archive_file_offset;
85b1c36d 171static unsigned long archive_file_size;
f54498b4 172static bfd_size_type current_file_size;
85b1c36d
BE
173static unsigned long dynamic_addr;
174static bfd_size_type dynamic_size;
8b73c356 175static size_t dynamic_nent;
2cf0635d 176static char * dynamic_strings;
85b1c36d 177static unsigned long dynamic_strings_length;
2cf0635d 178static char * string_table;
85b1c36d
BE
179static unsigned long string_table_length;
180static unsigned long num_dynamic_syms;
2cf0635d
NC
181static Elf_Internal_Sym * dynamic_symbols;
182static Elf_Internal_Syminfo * dynamic_syminfo;
85b1c36d
BE
183static unsigned long dynamic_syminfo_offset;
184static unsigned int dynamic_syminfo_nent;
f8eae8b2 185static char program_interpreter[PATH_MAX];
bb8a0291 186static bfd_vma dynamic_info[DT_ENCODING];
fdc90cb4 187static bfd_vma dynamic_info_DT_GNU_HASH;
85b1c36d
BE
188static bfd_vma version_info[16];
189static Elf_Internal_Ehdr elf_header;
2cf0635d
NC
190static Elf_Internal_Shdr * section_headers;
191static Elf_Internal_Phdr * program_headers;
192static Elf_Internal_Dyn * dynamic_section;
193static Elf_Internal_Shdr * symtab_shndx_hdr;
85b1c36d
BE
194static int show_name;
195static int do_dynamic;
196static int do_syms;
2c610e4b 197static int do_dyn_syms;
85b1c36d
BE
198static int do_reloc;
199static int do_sections;
200static int do_section_groups;
5477e8a0 201static int do_section_details;
85b1c36d
BE
202static int do_segments;
203static int do_unwind;
204static int do_using_dynamic;
205static int do_header;
206static int do_dump;
207static int do_version;
85b1c36d
BE
208static int do_histogram;
209static int do_debugging;
85b1c36d
BE
210static int do_arch;
211static int do_notes;
4145f1d5 212static int do_archive_index;
85b1c36d 213static int is_32bit_elf;
252b5132 214
e4b17d5c
L
215struct group_list
216{
2cf0635d 217 struct group_list * next;
e4b17d5c
L
218 unsigned int section_index;
219};
220
221struct group
222{
2cf0635d 223 struct group_list * root;
e4b17d5c
L
224 unsigned int group_index;
225};
226
85b1c36d 227static size_t group_count;
2cf0635d
NC
228static struct group * section_groups;
229static struct group ** section_headers_groups;
e4b17d5c 230
09c11c86
NC
231
232/* Flag bits indicating particular types of dump. */
233#define HEX_DUMP (1 << 0) /* The -x command line switch. */
234#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
235#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
236#define STRING_DUMP (1 << 3) /* The -p command line switch. */
cf13d699 237#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
09c11c86
NC
238
239typedef unsigned char dump_type;
240
241/* A linked list of the section names for which dumps were requested. */
aef1f6d0
DJ
242struct dump_list_entry
243{
2cf0635d 244 char * name;
09c11c86 245 dump_type type;
2cf0635d 246 struct dump_list_entry * next;
aef1f6d0 247};
2cf0635d 248static struct dump_list_entry * dump_sects_byname;
aef1f6d0 249
09c11c86
NC
250/* A dynamic array of flags indicating for which sections a dump
251 has been requested via command line switches. */
252static dump_type * cmdline_dump_sects = NULL;
253static unsigned int num_cmdline_dump_sects = 0;
18bd398b
NC
254
255/* A dynamic array of flags indicating for which sections a dump of
256 some kind has been requested. It is reset on a per-object file
aef1f6d0
DJ
257 basis and then initialised from the cmdline_dump_sects array,
258 the results of interpreting the -w switch, and the
259 dump_sects_byname list. */
09c11c86
NC
260static dump_type * dump_sects = NULL;
261static unsigned int num_dump_sects = 0;
252b5132 262
252b5132 263
c256ffe7 264/* How to print a vma value. */
843dd992
NC
265typedef enum print_mode
266{
267 HEX,
268 DEC,
269 DEC_5,
270 UNSIGNED,
271 PREFIX_HEX,
272 FULL_HEX,
273 LONG_HEX
274}
275print_mode;
276
bb4d2ac2
L
277/* Versioned symbol info. */
278enum versioned_symbol_info
279{
280 symbol_undefined,
281 symbol_hidden,
282 symbol_public
283};
284
285static const char *get_symbol_version_string
286 (FILE *file, int is_dynsym, const char *strtab,
287 unsigned long int strtab_size, unsigned int si,
288 Elf_Internal_Sym *psym, enum versioned_symbol_info *sym_info,
289 unsigned short *vna_other);
290
9c19a809
NC
291#define UNKNOWN -1
292
2b692964
NC
293#define SECTION_NAME(X) \
294 ((X) == NULL ? _("<none>") \
295 : string_table == NULL ? _("<no-name>") \
296 : ((X)->sh_name >= string_table_length ? _("<corrupt>") \
0b49d371 297 : string_table + (X)->sh_name))
252b5132 298
ee42cf8c 299#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 300
ba5cdace
NC
301#define GET_ELF_SYMBOLS(file, section, sym_count) \
302 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
303 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 304
d79b3d50
NC
305#define VALID_DYNAMIC_NAME(offset) ((dynamic_strings != NULL) && (offset < dynamic_strings_length))
306/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
307 already been called and verified that the string exists. */
308#define GET_DYNAMIC_NAME(offset) (dynamic_strings + offset)
18bd398b 309
61865e30
NC
310#define REMOVE_ARCH_BITS(ADDR) \
311 do \
312 { \
313 if (elf_header.e_machine == EM_ARM) \
314 (ADDR) &= ~1; \
315 } \
316 while (0)
d79b3d50 317\f
c9c1d674
EG
318/* Retrieve NMEMB structures, each SIZE bytes long from FILE starting at OFFSET +
319 the offset of the current archive member, if we are examining an archive.
59245841
NC
320 Put the retrieved data into VAR, if it is not NULL. Otherwise allocate a buffer
321 using malloc and fill that. In either case return the pointer to the start of
322 the retrieved data or NULL if something went wrong. If something does go wrong
c9c1d674
EG
323 and REASON is not NULL then emit an error message using REASON as part of the
324 context. */
59245841 325
c256ffe7 326static void *
57028622
NC
327get_data (void * var, FILE * file, unsigned long offset, bfd_size_type size,
328 bfd_size_type nmemb, const char * reason)
a6e9f9df 329{
2cf0635d 330 void * mvar;
57028622 331 bfd_size_type amt = size * nmemb;
a6e9f9df 332
c256ffe7 333 if (size == 0 || nmemb == 0)
a6e9f9df
AM
334 return NULL;
335
57028622
NC
336 /* If the size_t type is smaller than the bfd_size_type, eg because
337 you are building a 32-bit tool on a 64-bit host, then make sure
338 that when the sizes are cast to (size_t) no information is lost. */
339 if (sizeof (size_t) < sizeof (bfd_size_type)
340 && ( (bfd_size_type) ((size_t) size) != size
341 || (bfd_size_type) ((size_t) nmemb) != nmemb))
342 {
343 if (reason)
344 error (_("Size truncation prevents reading 0x%llx elements of size 0x%llx for %s\n"),
345 (unsigned long long) nmemb, (unsigned long long) size, reason);
346 return NULL;
347 }
348
349 /* Check for size overflow. */
350 if (amt < nmemb)
351 {
352 if (reason)
353 error (_("Size overflow prevents reading 0x%llx elements of size 0x%llx for %s\n"),
354 (unsigned long long) nmemb, (unsigned long long) size, reason);
355 return NULL;
356 }
357
c9c1d674
EG
358 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
359 attempting to allocate memory when the read is bound to fail. */
360 if (amt > current_file_size
361 || offset + archive_file_offset + amt > current_file_size)
a6e9f9df 362 {
049b0c3a 363 if (reason)
57028622
NC
364 error (_("Reading 0x%llx bytes extends past end of file for %s\n"),
365 (unsigned long long) amt, reason);
a6e9f9df
AM
366 return NULL;
367 }
368
c9c1d674 369 if (fseek (file, archive_file_offset + offset, SEEK_SET))
071436c6
NC
370 {
371 if (reason)
c9c1d674
EG
372 error (_("Unable to seek to 0x%lx for %s\n"),
373 (unsigned long) archive_file_offset + offset, reason);
071436c6
NC
374 return NULL;
375 }
376
a6e9f9df
AM
377 mvar = var;
378 if (mvar == NULL)
379 {
c256ffe7 380 /* Check for overflow. */
57028622 381 if (nmemb < (~(bfd_size_type) 0 - 1) / size)
c256ffe7 382 /* + 1 so that we can '\0' terminate invalid string table sections. */
57028622 383 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
384
385 if (mvar == NULL)
386 {
049b0c3a 387 if (reason)
57028622
NC
388 error (_("Out of memory allocating 0x%llx bytes for %s\n"),
389 (unsigned long long) amt, reason);
a6e9f9df
AM
390 return NULL;
391 }
c256ffe7 392
c9c1d674 393 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
394 }
395
57028622 396 if (fread (mvar, (size_t) size, (size_t) nmemb, file) != nmemb)
a6e9f9df 397 {
049b0c3a 398 if (reason)
57028622
NC
399 error (_("Unable to read in 0x%llx bytes of %s\n"),
400 (unsigned long long) amt, reason);
a6e9f9df
AM
401 if (mvar != var)
402 free (mvar);
403 return NULL;
404 }
405
406 return mvar;
407}
408
14a91970 409/* Print a VMA value. */
cb8f3167 410
66543521 411static int
14a91970 412print_vma (bfd_vma vma, print_mode mode)
66543521 413{
66543521
AM
414 int nc = 0;
415
14a91970 416 switch (mode)
66543521 417 {
14a91970
AM
418 case FULL_HEX:
419 nc = printf ("0x");
420 /* Drop through. */
66543521 421
14a91970 422 case LONG_HEX:
f7a99963 423#ifdef BFD64
14a91970 424 if (is_32bit_elf)
437c2fb7 425 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 426#endif
14a91970
AM
427 printf_vma (vma);
428 return nc + 16;
b19aac67 429
14a91970
AM
430 case DEC_5:
431 if (vma <= 99999)
432 return printf ("%5" BFD_VMA_FMT "d", vma);
433 /* Drop through. */
66543521 434
14a91970
AM
435 case PREFIX_HEX:
436 nc = printf ("0x");
437 /* Drop through. */
66543521 438
14a91970
AM
439 case HEX:
440 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 441
14a91970
AM
442 case DEC:
443 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 444
14a91970
AM
445 case UNSIGNED:
446 return printf ("%" BFD_VMA_FMT "u", vma);
f7a99963 447 }
66543521 448 return 0;
f7a99963
NC
449}
450
7bfd842d 451/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 452 multibye characters (assuming the host environment supports them).
31104126 453
7bfd842d
NC
454 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
455
456 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
457 padding as necessary.
171191ba
NC
458
459 Returns the number of emitted characters. */
460
461static unsigned int
7a88bc9c 462print_symbol (int width, const char *symbol)
31104126 463{
171191ba 464 bfd_boolean extra_padding = FALSE;
7bfd842d 465 int num_printed = 0;
3bfcb652 466#ifdef HAVE_MBSTATE_T
7bfd842d 467 mbstate_t state;
3bfcb652 468#endif
7bfd842d 469 int width_remaining;
961c521f 470
7bfd842d 471 if (width < 0)
961c521f 472 {
961c521f
NC
473 /* Keep the width positive. This also helps. */
474 width = - width;
171191ba 475 extra_padding = TRUE;
0b4362b0 476 }
74e1a04b 477 assert (width != 0);
961c521f 478
7bfd842d
NC
479 if (do_wide)
480 /* Set the remaining width to a very large value.
481 This simplifies the code below. */
482 width_remaining = INT_MAX;
483 else
484 width_remaining = width;
cb8f3167 485
3bfcb652 486#ifdef HAVE_MBSTATE_T
7bfd842d
NC
487 /* Initialise the multibyte conversion state. */
488 memset (& state, 0, sizeof (state));
3bfcb652 489#endif
961c521f 490
7bfd842d
NC
491 while (width_remaining)
492 {
493 size_t n;
7bfd842d 494 const char c = *symbol++;
961c521f 495
7bfd842d 496 if (c == 0)
961c521f
NC
497 break;
498
7bfd842d
NC
499 /* Do not print control characters directly as they can affect terminal
500 settings. Such characters usually appear in the names generated
501 by the assembler for local labels. */
502 if (ISCNTRL (c))
961c521f 503 {
7bfd842d 504 if (width_remaining < 2)
961c521f
NC
505 break;
506
7bfd842d
NC
507 printf ("^%c", c + 0x40);
508 width_remaining -= 2;
171191ba 509 num_printed += 2;
961c521f 510 }
7bfd842d
NC
511 else if (ISPRINT (c))
512 {
513 putchar (c);
514 width_remaining --;
515 num_printed ++;
516 }
961c521f
NC
517 else
518 {
3bfcb652
NC
519#ifdef HAVE_MBSTATE_T
520 wchar_t w;
521#endif
7bfd842d
NC
522 /* Let printf do the hard work of displaying multibyte characters. */
523 printf ("%.1s", symbol - 1);
524 width_remaining --;
525 num_printed ++;
526
3bfcb652 527#ifdef HAVE_MBSTATE_T
7bfd842d
NC
528 /* Try to find out how many bytes made up the character that was
529 just printed. Advance the symbol pointer past the bytes that
530 were displayed. */
531 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
532#else
533 n = 1;
534#endif
7bfd842d
NC
535 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
536 symbol += (n - 1);
961c521f 537 }
961c521f 538 }
171191ba 539
7bfd842d 540 if (extra_padding && num_printed < width)
171191ba
NC
541 {
542 /* Fill in the remaining spaces. */
7bfd842d
NC
543 printf ("%-*s", width - num_printed, " ");
544 num_printed = width;
171191ba
NC
545 }
546
547 return num_printed;
31104126
NC
548}
549
74e1a04b
NC
550/* Returns a pointer to a static buffer containing a printable version of
551 the given section's name. Like print_symbol, except that it does not try
552 to print multibyte characters, it just interprets them as hex values. */
553
554static const char *
555printable_section_name (Elf_Internal_Shdr * sec)
556{
557#define MAX_PRINT_SEC_NAME_LEN 128
558 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
559 const char * name = SECTION_NAME (sec);
560 char * buf = sec_name_buf;
561 char c;
562 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
563
564 while ((c = * name ++) != 0)
565 {
566 if (ISCNTRL (c))
567 {
568 if (remaining < 2)
569 break;
570
571 * buf ++ = '^';
572 * buf ++ = c + 0x40;
573 remaining -= 2;
574 }
575 else if (ISPRINT (c))
576 {
577 * buf ++ = c;
578 remaining -= 1;
579 }
580 else
581 {
582 static char hex[17] = "0123456789ABCDEF";
583
584 if (remaining < 4)
585 break;
586 * buf ++ = '<';
587 * buf ++ = hex[(c & 0xf0) >> 4];
588 * buf ++ = hex[c & 0x0f];
589 * buf ++ = '>';
590 remaining -= 4;
591 }
592
593 if (remaining == 0)
594 break;
595 }
596
597 * buf = 0;
598 return sec_name_buf;
599}
600
601static const char *
602printable_section_name_from_index (unsigned long ndx)
603{
604 if (ndx >= elf_header.e_shnum)
605 return _("<corrupt>");
606
607 return printable_section_name (section_headers + ndx);
608}
609
89fac5e3
RS
610/* Return a pointer to section NAME, or NULL if no such section exists. */
611
612static Elf_Internal_Shdr *
2cf0635d 613find_section (const char * name)
89fac5e3
RS
614{
615 unsigned int i;
616
617 for (i = 0; i < elf_header.e_shnum; i++)
618 if (streq (SECTION_NAME (section_headers + i), name))
619 return section_headers + i;
620
621 return NULL;
622}
623
0b6ae522
DJ
624/* Return a pointer to a section containing ADDR, or NULL if no such
625 section exists. */
626
627static Elf_Internal_Shdr *
628find_section_by_address (bfd_vma addr)
629{
630 unsigned int i;
631
632 for (i = 0; i < elf_header.e_shnum; i++)
633 {
634 Elf_Internal_Shdr *sec = section_headers + i;
635 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
636 return sec;
637 }
638
639 return NULL;
640}
641
071436c6
NC
642static Elf_Internal_Shdr *
643find_section_by_type (unsigned int type)
644{
645 unsigned int i;
646
647 for (i = 0; i < elf_header.e_shnum; i++)
648 {
649 Elf_Internal_Shdr *sec = section_headers + i;
650 if (sec->sh_type == type)
651 return sec;
652 }
653
654 return NULL;
655}
656
657d0d47
CC
657/* Return a pointer to section NAME, or NULL if no such section exists,
658 restricted to the list of sections given in SET. */
659
660static Elf_Internal_Shdr *
661find_section_in_set (const char * name, unsigned int * set)
662{
663 unsigned int i;
664
665 if (set != NULL)
666 {
667 while ((i = *set++) > 0)
668 if (streq (SECTION_NAME (section_headers + i), name))
669 return section_headers + i;
670 }
671
672 return find_section (name);
673}
674
0b6ae522
DJ
675/* Read an unsigned LEB128 encoded value from p. Set *PLEN to the number of
676 bytes read. */
677
f6f0e17b
NC
678static inline unsigned long
679read_uleb128 (unsigned char *data,
680 unsigned int *length_return,
681 const unsigned char * const end)
0b6ae522 682{
f6f0e17b 683 return read_leb128 (data, length_return, FALSE, end);
0b6ae522
DJ
684}
685
28f997cf
TG
686/* Return true if the current file is for IA-64 machine and OpenVMS ABI.
687 This OS has so many departures from the ELF standard that we test it at
688 many places. */
689
690static inline int
691is_ia64_vms (void)
692{
693 return elf_header.e_machine == EM_IA_64
694 && elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
695}
696
bcedfee6 697/* Guess the relocation size commonly used by the specific machines. */
252b5132 698
252b5132 699static int
2dc4cec1 700guess_is_rela (unsigned int e_machine)
252b5132 701{
9c19a809 702 switch (e_machine)
252b5132
RH
703 {
704 /* Targets that use REL relocations. */
252b5132
RH
705 case EM_386:
706 case EM_486:
63fcb9e9 707 case EM_960:
e9f53129 708 case EM_ARM:
2b0337b0 709 case EM_D10V:
252b5132 710 case EM_CYGNUS_D10V:
e9f53129 711 case EM_DLX:
252b5132 712 case EM_MIPS:
4fe85591 713 case EM_MIPS_RS3_LE:
e9f53129 714 case EM_CYGNUS_M32R:
1c0d3aa6 715 case EM_SCORE:
f6c1a2d5 716 case EM_XGATE:
9c19a809 717 return FALSE;
103f02d3 718
252b5132
RH
719 /* Targets that use RELA relocations. */
720 case EM_68K:
e9f53129 721 case EM_860:
a06ea964 722 case EM_AARCH64:
cfb8c092 723 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
724 case EM_ALPHA:
725 case EM_ALTERA_NIOS2:
726 case EM_AVR:
727 case EM_AVR_OLD:
728 case EM_BLACKFIN:
60bca95a 729 case EM_CR16:
e9f53129
AM
730 case EM_CRIS:
731 case EM_CRX:
2b0337b0 732 case EM_D30V:
252b5132 733 case EM_CYGNUS_D30V:
2b0337b0 734 case EM_FR30:
3f8107ab 735 case EM_FT32:
252b5132 736 case EM_CYGNUS_FR30:
5c70f934 737 case EM_CYGNUS_FRV:
e9f53129
AM
738 case EM_H8S:
739 case EM_H8_300:
740 case EM_H8_300H:
800eeca4 741 case EM_IA_64:
1e4cf259
NC
742 case EM_IP2K:
743 case EM_IP2K_OLD:
3b36097d 744 case EM_IQ2000:
84e94c90 745 case EM_LATTICEMICO32:
ff7eeb89 746 case EM_M32C_OLD:
49f58d10 747 case EM_M32C:
e9f53129
AM
748 case EM_M32R:
749 case EM_MCORE:
15ab5209 750 case EM_CYGNUS_MEP:
a3c62988 751 case EM_METAG:
e9f53129
AM
752 case EM_MMIX:
753 case EM_MN10200:
754 case EM_CYGNUS_MN10200:
755 case EM_MN10300:
756 case EM_CYGNUS_MN10300:
5506d11a 757 case EM_MOXIE:
e9f53129
AM
758 case EM_MSP430:
759 case EM_MSP430_OLD:
d031aafb 760 case EM_MT:
35c08157 761 case EM_NDS32:
64fd6348 762 case EM_NIOS32:
73589c9d 763 case EM_OR1K:
e9f53129
AM
764 case EM_PPC64:
765 case EM_PPC:
99c513f6 766 case EM_RL78:
c7927a3c 767 case EM_RX:
e9f53129
AM
768 case EM_S390:
769 case EM_S390_OLD:
770 case EM_SH:
771 case EM_SPARC:
772 case EM_SPARC32PLUS:
773 case EM_SPARCV9:
774 case EM_SPU:
40b36596 775 case EM_TI_C6000:
aa137e4d
NC
776 case EM_TILEGX:
777 case EM_TILEPRO:
708e2187 778 case EM_V800:
e9f53129
AM
779 case EM_V850:
780 case EM_CYGNUS_V850:
781 case EM_VAX:
619ed720 782 case EM_VISIUM:
e9f53129 783 case EM_X86_64:
8a9036a4 784 case EM_L1OM:
7a9068fe 785 case EM_K1OM:
e9f53129
AM
786 case EM_XSTORMY16:
787 case EM_XTENSA:
788 case EM_XTENSA_OLD:
7ba29e2a
NC
789 case EM_MICROBLAZE:
790 case EM_MICROBLAZE_OLD:
9c19a809 791 return TRUE;
103f02d3 792
e9f53129
AM
793 case EM_68HC05:
794 case EM_68HC08:
795 case EM_68HC11:
796 case EM_68HC16:
797 case EM_FX66:
798 case EM_ME16:
d1133906 799 case EM_MMA:
d1133906
NC
800 case EM_NCPU:
801 case EM_NDR1:
e9f53129 802 case EM_PCP:
d1133906 803 case EM_ST100:
e9f53129 804 case EM_ST19:
d1133906 805 case EM_ST7:
e9f53129
AM
806 case EM_ST9PLUS:
807 case EM_STARCORE:
d1133906 808 case EM_SVX:
e9f53129 809 case EM_TINYJ:
9c19a809
NC
810 default:
811 warn (_("Don't know about relocations on this machine architecture\n"));
812 return FALSE;
813 }
814}
252b5132 815
9c19a809 816static int
2cf0635d 817slurp_rela_relocs (FILE * file,
d3ba0551
AM
818 unsigned long rel_offset,
819 unsigned long rel_size,
2cf0635d
NC
820 Elf_Internal_Rela ** relasp,
821 unsigned long * nrelasp)
9c19a809 822{
2cf0635d 823 Elf_Internal_Rela * relas;
8b73c356 824 size_t nrelas;
4d6ed7c8 825 unsigned int i;
252b5132 826
4d6ed7c8
NC
827 if (is_32bit_elf)
828 {
2cf0635d 829 Elf32_External_Rela * erelas;
103f02d3 830
3f5e193b 831 erelas = (Elf32_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 832 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
833 if (!erelas)
834 return 0;
252b5132 835
4d6ed7c8 836 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 837
3f5e193b
NC
838 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
839 sizeof (Elf_Internal_Rela));
103f02d3 840
4d6ed7c8
NC
841 if (relas == NULL)
842 {
c256ffe7 843 free (erelas);
591a748a 844 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
845 return 0;
846 }
103f02d3 847
4d6ed7c8
NC
848 for (i = 0; i < nrelas; i++)
849 {
850 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
851 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 852 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 853 }
103f02d3 854
4d6ed7c8
NC
855 free (erelas);
856 }
857 else
858 {
2cf0635d 859 Elf64_External_Rela * erelas;
103f02d3 860
3f5e193b 861 erelas = (Elf64_External_Rela *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 862 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
863 if (!erelas)
864 return 0;
4d6ed7c8
NC
865
866 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 867
3f5e193b
NC
868 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
869 sizeof (Elf_Internal_Rela));
103f02d3 870
4d6ed7c8
NC
871 if (relas == NULL)
872 {
c256ffe7 873 free (erelas);
591a748a 874 error (_("out of memory parsing relocs\n"));
4d6ed7c8 875 return 0;
9c19a809 876 }
4d6ed7c8
NC
877
878 for (i = 0; i < nrelas; i++)
9c19a809 879 {
66543521
AM
880 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
881 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 882 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
883
884 /* The #ifdef BFD64 below is to prevent a compile time
885 warning. We know that if we do not have a 64 bit data
886 type that we will never execute this code anyway. */
887#ifdef BFD64
888 if (elf_header.e_machine == EM_MIPS
889 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
890 {
891 /* In little-endian objects, r_info isn't really a
892 64-bit little-endian value: it has a 32-bit
893 little-endian symbol index followed by four
894 individual byte fields. Reorder INFO
895 accordingly. */
91d6fa6a
NC
896 bfd_vma inf = relas[i].r_info;
897 inf = (((inf & 0xffffffff) << 32)
898 | ((inf >> 56) & 0xff)
899 | ((inf >> 40) & 0xff00)
900 | ((inf >> 24) & 0xff0000)
901 | ((inf >> 8) & 0xff000000));
902 relas[i].r_info = inf;
861fb55a
DJ
903 }
904#endif /* BFD64 */
4d6ed7c8 905 }
103f02d3 906
4d6ed7c8
NC
907 free (erelas);
908 }
909 *relasp = relas;
910 *nrelasp = nrelas;
911 return 1;
912}
103f02d3 913
4d6ed7c8 914static int
2cf0635d 915slurp_rel_relocs (FILE * file,
d3ba0551
AM
916 unsigned long rel_offset,
917 unsigned long rel_size,
2cf0635d
NC
918 Elf_Internal_Rela ** relsp,
919 unsigned long * nrelsp)
4d6ed7c8 920{
2cf0635d 921 Elf_Internal_Rela * rels;
8b73c356 922 size_t nrels;
4d6ed7c8 923 unsigned int i;
103f02d3 924
4d6ed7c8
NC
925 if (is_32bit_elf)
926 {
2cf0635d 927 Elf32_External_Rel * erels;
103f02d3 928
3f5e193b 929 erels = (Elf32_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 930 rel_size, _("32-bit relocation data"));
a6e9f9df
AM
931 if (!erels)
932 return 0;
103f02d3 933
4d6ed7c8 934 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 935
3f5e193b 936 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 937
4d6ed7c8
NC
938 if (rels == NULL)
939 {
c256ffe7 940 free (erels);
591a748a 941 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
942 return 0;
943 }
944
945 for (i = 0; i < nrels; i++)
946 {
947 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
948 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 949 rels[i].r_addend = 0;
9ea033b2 950 }
4d6ed7c8
NC
951
952 free (erels);
9c19a809
NC
953 }
954 else
955 {
2cf0635d 956 Elf64_External_Rel * erels;
9ea033b2 957
3f5e193b 958 erels = (Elf64_External_Rel *) get_data (NULL, file, rel_offset, 1,
9cf03b7e 959 rel_size, _("64-bit relocation data"));
a6e9f9df
AM
960 if (!erels)
961 return 0;
103f02d3 962
4d6ed7c8 963 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 964
3f5e193b 965 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 966
4d6ed7c8 967 if (rels == NULL)
9c19a809 968 {
c256ffe7 969 free (erels);
591a748a 970 error (_("out of memory parsing relocs\n"));
4d6ed7c8
NC
971 return 0;
972 }
103f02d3 973
4d6ed7c8
NC
974 for (i = 0; i < nrels; i++)
975 {
66543521
AM
976 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
977 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 978 rels[i].r_addend = 0;
861fb55a
DJ
979
980 /* The #ifdef BFD64 below is to prevent a compile time
981 warning. We know that if we do not have a 64 bit data
982 type that we will never execute this code anyway. */
983#ifdef BFD64
984 if (elf_header.e_machine == EM_MIPS
985 && elf_header.e_ident[EI_DATA] != ELFDATA2MSB)
986 {
987 /* In little-endian objects, r_info isn't really a
988 64-bit little-endian value: it has a 32-bit
989 little-endian symbol index followed by four
990 individual byte fields. Reorder INFO
991 accordingly. */
91d6fa6a
NC
992 bfd_vma inf = rels[i].r_info;
993 inf = (((inf & 0xffffffff) << 32)
994 | ((inf >> 56) & 0xff)
995 | ((inf >> 40) & 0xff00)
996 | ((inf >> 24) & 0xff0000)
997 | ((inf >> 8) & 0xff000000));
998 rels[i].r_info = inf;
861fb55a
DJ
999 }
1000#endif /* BFD64 */
4d6ed7c8 1001 }
103f02d3 1002
4d6ed7c8
NC
1003 free (erels);
1004 }
1005 *relsp = rels;
1006 *nrelsp = nrels;
1007 return 1;
1008}
103f02d3 1009
aca88567
NC
1010/* Returns the reloc type extracted from the reloc info field. */
1011
1012static unsigned int
1013get_reloc_type (bfd_vma reloc_info)
1014{
1015 if (is_32bit_elf)
1016 return ELF32_R_TYPE (reloc_info);
1017
1018 switch (elf_header.e_machine)
1019 {
1020 case EM_MIPS:
1021 /* Note: We assume that reloc_info has already been adjusted for us. */
1022 return ELF64_MIPS_R_TYPE (reloc_info);
1023
1024 case EM_SPARCV9:
1025 return ELF64_R_TYPE_ID (reloc_info);
1026
1027 default:
1028 return ELF64_R_TYPE (reloc_info);
1029 }
1030}
1031
1032/* Return the symbol index extracted from the reloc info field. */
1033
1034static bfd_vma
1035get_reloc_symindex (bfd_vma reloc_info)
1036{
1037 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1038}
1039
13761a11
NC
1040static inline bfd_boolean
1041uses_msp430x_relocs (void)
1042{
1043 return
1044 elf_header.e_machine == EM_MSP430 /* Paranoia. */
1045 /* GCC uses osabi == ELFOSBI_STANDALONE. */
1046 && (((elf_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
1047 /* TI compiler uses ELFOSABI_NONE. */
1048 || (elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
1049}
1050
d3ba0551
AM
1051/* Display the contents of the relocation data found at the specified
1052 offset. */
ee42cf8c 1053
41e92641 1054static void
2cf0635d 1055dump_relocations (FILE * file,
d3ba0551
AM
1056 unsigned long rel_offset,
1057 unsigned long rel_size,
2cf0635d 1058 Elf_Internal_Sym * symtab,
d3ba0551 1059 unsigned long nsyms,
2cf0635d 1060 char * strtab,
d79b3d50 1061 unsigned long strtablen,
bb4d2ac2
L
1062 int is_rela,
1063 int is_dynsym)
4d6ed7c8 1064{
b34976b6 1065 unsigned int i;
2cf0635d 1066 Elf_Internal_Rela * rels;
103f02d3 1067
4d6ed7c8
NC
1068 if (is_rela == UNKNOWN)
1069 is_rela = guess_is_rela (elf_header.e_machine);
103f02d3 1070
4d6ed7c8
NC
1071 if (is_rela)
1072 {
c8286bd1 1073 if (!slurp_rela_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1074 return;
4d6ed7c8
NC
1075 }
1076 else
1077 {
1078 if (!slurp_rel_relocs (file, rel_offset, rel_size, &rels, &rel_size))
41e92641 1079 return;
252b5132
RH
1080 }
1081
410f7a12
L
1082 if (is_32bit_elf)
1083 {
1084 if (is_rela)
2c71103e
NC
1085 {
1086 if (do_wide)
1087 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1088 else
1089 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1090 }
410f7a12 1091 else
2c71103e
NC
1092 {
1093 if (do_wide)
1094 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1095 else
1096 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1097 }
410f7a12 1098 }
252b5132 1099 else
410f7a12
L
1100 {
1101 if (is_rela)
2c71103e
NC
1102 {
1103 if (do_wide)
8beeaeb7 1104 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1105 else
1106 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1107 }
410f7a12 1108 else
2c71103e
NC
1109 {
1110 if (do_wide)
8beeaeb7 1111 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1112 else
1113 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1114 }
410f7a12 1115 }
252b5132
RH
1116
1117 for (i = 0; i < rel_size; i++)
1118 {
2cf0635d 1119 const char * rtype;
b34976b6 1120 bfd_vma offset;
91d6fa6a 1121 bfd_vma inf;
b34976b6
AM
1122 bfd_vma symtab_index;
1123 bfd_vma type;
103f02d3 1124
b34976b6 1125 offset = rels[i].r_offset;
91d6fa6a 1126 inf = rels[i].r_info;
103f02d3 1127
91d6fa6a
NC
1128 type = get_reloc_type (inf);
1129 symtab_index = get_reloc_symindex (inf);
252b5132 1130
410f7a12
L
1131 if (is_32bit_elf)
1132 {
39dbeff8
AM
1133 printf ("%8.8lx %8.8lx ",
1134 (unsigned long) offset & 0xffffffff,
91d6fa6a 1135 (unsigned long) inf & 0xffffffff);
410f7a12
L
1136 }
1137 else
1138 {
39dbeff8
AM
1139#if BFD_HOST_64BIT_LONG
1140 printf (do_wide
1141 ? "%16.16lx %16.16lx "
1142 : "%12.12lx %12.12lx ",
91d6fa6a 1143 offset, inf);
39dbeff8 1144#elif BFD_HOST_64BIT_LONG_LONG
6e3d6dc1 1145#ifndef __MSVCRT__
39dbeff8
AM
1146 printf (do_wide
1147 ? "%16.16llx %16.16llx "
1148 : "%12.12llx %12.12llx ",
91d6fa6a 1149 offset, inf);
6e3d6dc1
NC
1150#else
1151 printf (do_wide
1152 ? "%16.16I64x %16.16I64x "
1153 : "%12.12I64x %12.12I64x ",
91d6fa6a 1154 offset, inf);
6e3d6dc1 1155#endif
39dbeff8 1156#else
2c71103e
NC
1157 printf (do_wide
1158 ? "%8.8lx%8.8lx %8.8lx%8.8lx "
1159 : "%4.4lx%8.8lx %4.4lx%8.8lx ",
410f7a12
L
1160 _bfd_int64_high (offset),
1161 _bfd_int64_low (offset),
91d6fa6a
NC
1162 _bfd_int64_high (inf),
1163 _bfd_int64_low (inf));
9ea033b2 1164#endif
410f7a12 1165 }
103f02d3 1166
252b5132
RH
1167 switch (elf_header.e_machine)
1168 {
1169 default:
1170 rtype = NULL;
1171 break;
1172
a06ea964
NC
1173 case EM_AARCH64:
1174 rtype = elf_aarch64_reloc_type (type);
1175 break;
1176
2b0337b0 1177 case EM_M32R:
252b5132 1178 case EM_CYGNUS_M32R:
9ea033b2 1179 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1180 break;
1181
1182 case EM_386:
1183 case EM_486:
9ea033b2 1184 rtype = elf_i386_reloc_type (type);
252b5132
RH
1185 break;
1186
ba2685cc
AM
1187 case EM_68HC11:
1188 case EM_68HC12:
1189 rtype = elf_m68hc11_reloc_type (type);
1190 break;
75751cd9 1191
252b5132 1192 case EM_68K:
9ea033b2 1193 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1194 break;
1195
63fcb9e9 1196 case EM_960:
9ea033b2 1197 rtype = elf_i960_reloc_type (type);
63fcb9e9
ILT
1198 break;
1199
adde6300 1200 case EM_AVR:
2b0337b0 1201 case EM_AVR_OLD:
adde6300
AM
1202 rtype = elf_avr_reloc_type (type);
1203 break;
1204
9ea033b2
NC
1205 case EM_OLD_SPARCV9:
1206 case EM_SPARC32PLUS:
1207 case EM_SPARCV9:
252b5132 1208 case EM_SPARC:
9ea033b2 1209 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1210 break;
1211
e9f53129
AM
1212 case EM_SPU:
1213 rtype = elf_spu_reloc_type (type);
1214 break;
1215
708e2187
NC
1216 case EM_V800:
1217 rtype = v800_reloc_type (type);
1218 break;
2b0337b0 1219 case EM_V850:
252b5132 1220 case EM_CYGNUS_V850:
9ea033b2 1221 rtype = v850_reloc_type (type);
252b5132
RH
1222 break;
1223
2b0337b0 1224 case EM_D10V:
252b5132 1225 case EM_CYGNUS_D10V:
9ea033b2 1226 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1227 break;
1228
2b0337b0 1229 case EM_D30V:
252b5132 1230 case EM_CYGNUS_D30V:
9ea033b2 1231 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1232 break;
1233
d172d4ba
NC
1234 case EM_DLX:
1235 rtype = elf_dlx_reloc_type (type);
1236 break;
1237
252b5132 1238 case EM_SH:
9ea033b2 1239 rtype = elf_sh_reloc_type (type);
252b5132
RH
1240 break;
1241
2b0337b0 1242 case EM_MN10300:
252b5132 1243 case EM_CYGNUS_MN10300:
9ea033b2 1244 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1245 break;
1246
2b0337b0 1247 case EM_MN10200:
252b5132 1248 case EM_CYGNUS_MN10200:
9ea033b2 1249 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1250 break;
1251
2b0337b0 1252 case EM_FR30:
252b5132 1253 case EM_CYGNUS_FR30:
9ea033b2 1254 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1255 break;
1256
ba2685cc
AM
1257 case EM_CYGNUS_FRV:
1258 rtype = elf_frv_reloc_type (type);
1259 break;
5c70f934 1260
3f8107ab
AM
1261 case EM_FT32:
1262 rtype = elf_ft32_reloc_type (type);
1263 break;
1264
252b5132 1265 case EM_MCORE:
9ea033b2 1266 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1267 break;
1268
3c3bdf30
NC
1269 case EM_MMIX:
1270 rtype = elf_mmix_reloc_type (type);
1271 break;
1272
5506d11a
AM
1273 case EM_MOXIE:
1274 rtype = elf_moxie_reloc_type (type);
1275 break;
1276
2469cfa2 1277 case EM_MSP430:
13761a11
NC
1278 if (uses_msp430x_relocs ())
1279 {
1280 rtype = elf_msp430x_reloc_type (type);
1281 break;
1282 }
2469cfa2
NC
1283 case EM_MSP430_OLD:
1284 rtype = elf_msp430_reloc_type (type);
1285 break;
1286
35c08157
KLC
1287 case EM_NDS32:
1288 rtype = elf_nds32_reloc_type (type);
1289 break;
1290
252b5132 1291 case EM_PPC:
9ea033b2 1292 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1293 break;
1294
c833c019
AM
1295 case EM_PPC64:
1296 rtype = elf_ppc64_reloc_type (type);
1297 break;
1298
252b5132 1299 case EM_MIPS:
4fe85591 1300 case EM_MIPS_RS3_LE:
9ea033b2 1301 rtype = elf_mips_reloc_type (type);
252b5132
RH
1302 break;
1303
1304 case EM_ALPHA:
9ea033b2 1305 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1306 break;
1307
1308 case EM_ARM:
9ea033b2 1309 rtype = elf_arm_reloc_type (type);
252b5132
RH
1310 break;
1311
584da044 1312 case EM_ARC:
9ea033b2 1313 rtype = elf_arc_reloc_type (type);
252b5132
RH
1314 break;
1315
1316 case EM_PARISC:
69e617ca 1317 rtype = elf_hppa_reloc_type (type);
252b5132 1318 break;
7d466069 1319
b8720f9d
JL
1320 case EM_H8_300:
1321 case EM_H8_300H:
1322 case EM_H8S:
1323 rtype = elf_h8_reloc_type (type);
1324 break;
1325
73589c9d
CS
1326 case EM_OR1K:
1327 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1328 break;
1329
7d466069 1330 case EM_PJ:
2b0337b0 1331 case EM_PJ_OLD:
7d466069
ILT
1332 rtype = elf_pj_reloc_type (type);
1333 break;
800eeca4
JW
1334 case EM_IA_64:
1335 rtype = elf_ia64_reloc_type (type);
1336 break;
1b61cf92
HPN
1337
1338 case EM_CRIS:
1339 rtype = elf_cris_reloc_type (type);
1340 break;
535c37ff
JE
1341
1342 case EM_860:
1343 rtype = elf_i860_reloc_type (type);
1344 break;
bcedfee6
NC
1345
1346 case EM_X86_64:
8a9036a4 1347 case EM_L1OM:
7a9068fe 1348 case EM_K1OM:
bcedfee6
NC
1349 rtype = elf_x86_64_reloc_type (type);
1350 break;
a85d7ed0 1351
35b1837e
AM
1352 case EM_S370:
1353 rtype = i370_reloc_type (type);
1354 break;
1355
53c7db4b
KH
1356 case EM_S390_OLD:
1357 case EM_S390:
1358 rtype = elf_s390_reloc_type (type);
1359 break;
93fbbb04 1360
1c0d3aa6
NC
1361 case EM_SCORE:
1362 rtype = elf_score_reloc_type (type);
1363 break;
1364
93fbbb04
GK
1365 case EM_XSTORMY16:
1366 rtype = elf_xstormy16_reloc_type (type);
1367 break;
179d3252 1368
1fe1f39c
NC
1369 case EM_CRX:
1370 rtype = elf_crx_reloc_type (type);
1371 break;
1372
179d3252
JT
1373 case EM_VAX:
1374 rtype = elf_vax_reloc_type (type);
1375 break;
1e4cf259 1376
619ed720
EB
1377 case EM_VISIUM:
1378 rtype = elf_visium_reloc_type (type);
1379 break;
1380
cfb8c092
NC
1381 case EM_ADAPTEVA_EPIPHANY:
1382 rtype = elf_epiphany_reloc_type (type);
1383 break;
1384
1e4cf259
NC
1385 case EM_IP2K:
1386 case EM_IP2K_OLD:
1387 rtype = elf_ip2k_reloc_type (type);
1388 break;
3b36097d
SC
1389
1390 case EM_IQ2000:
1391 rtype = elf_iq2000_reloc_type (type);
1392 break;
88da6820
NC
1393
1394 case EM_XTENSA_OLD:
1395 case EM_XTENSA:
1396 rtype = elf_xtensa_reloc_type (type);
1397 break;
a34e3ecb 1398
84e94c90
NC
1399 case EM_LATTICEMICO32:
1400 rtype = elf_lm32_reloc_type (type);
1401 break;
1402
ff7eeb89 1403 case EM_M32C_OLD:
49f58d10
JB
1404 case EM_M32C:
1405 rtype = elf_m32c_reloc_type (type);
1406 break;
1407
d031aafb
NS
1408 case EM_MT:
1409 rtype = elf_mt_reloc_type (type);
a34e3ecb 1410 break;
1d65ded4
CM
1411
1412 case EM_BLACKFIN:
1413 rtype = elf_bfin_reloc_type (type);
1414 break;
15ab5209
DB
1415
1416 case EM_CYGNUS_MEP:
1417 rtype = elf_mep_reloc_type (type);
1418 break;
60bca95a
NC
1419
1420 case EM_CR16:
1421 rtype = elf_cr16_reloc_type (type);
1422 break;
dd24e3da 1423
7ba29e2a
NC
1424 case EM_MICROBLAZE:
1425 case EM_MICROBLAZE_OLD:
1426 rtype = elf_microblaze_reloc_type (type);
1427 break;
c7927a3c 1428
99c513f6
DD
1429 case EM_RL78:
1430 rtype = elf_rl78_reloc_type (type);
1431 break;
1432
c7927a3c
NC
1433 case EM_RX:
1434 rtype = elf_rx_reloc_type (type);
1435 break;
c29aca4a 1436
a3c62988
NC
1437 case EM_METAG:
1438 rtype = elf_metag_reloc_type (type);
1439 break;
1440
c29aca4a
NC
1441 case EM_XC16X:
1442 case EM_C166:
1443 rtype = elf_xc16x_reloc_type (type);
1444 break;
40b36596
JM
1445
1446 case EM_TI_C6000:
1447 rtype = elf_tic6x_reloc_type (type);
1448 break;
aa137e4d
NC
1449
1450 case EM_TILEGX:
1451 rtype = elf_tilegx_reloc_type (type);
1452 break;
1453
1454 case EM_TILEPRO:
1455 rtype = elf_tilepro_reloc_type (type);
1456 break;
f6c1a2d5
NC
1457
1458 case EM_XGATE:
1459 rtype = elf_xgate_reloc_type (type);
1460 break;
36591ba1
SL
1461
1462 case EM_ALTERA_NIOS2:
1463 rtype = elf_nios2_reloc_type (type);
1464 break;
252b5132
RH
1465 }
1466
1467 if (rtype == NULL)
39dbeff8 1468 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1469 else
8beeaeb7 1470 printf (do_wide ? "%-22.22s" : "%-17.17s", rtype);
252b5132 1471
7ace3541 1472 if (elf_header.e_machine == EM_ALPHA
157c2599 1473 && rtype != NULL
7ace3541
RH
1474 && streq (rtype, "R_ALPHA_LITUSE")
1475 && is_rela)
1476 {
1477 switch (rels[i].r_addend)
1478 {
1479 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1480 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1481 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1482 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1483 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1484 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1485 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1486 default: rtype = NULL;
1487 }
1488 if (rtype)
1489 printf (" (%s)", rtype);
1490 else
1491 {
1492 putchar (' ');
1493 printf (_("<unknown addend: %lx>"),
1494 (unsigned long) rels[i].r_addend);
1495 }
1496 }
1497 else if (symtab_index)
252b5132 1498 {
af3fc3bc 1499 if (symtab == NULL || symtab_index >= nsyms)
2b692964 1500 printf (_(" bad symbol index: %08lx"), (unsigned long) symtab_index);
af3fc3bc 1501 else
19936277 1502 {
2cf0635d 1503 Elf_Internal_Sym * psym;
bb4d2ac2
L
1504 const char * version_string;
1505 enum versioned_symbol_info sym_info;
1506 unsigned short vna_other;
19936277 1507
af3fc3bc 1508 psym = symtab + symtab_index;
103f02d3 1509
bb4d2ac2
L
1510 version_string
1511 = get_symbol_version_string (file, is_dynsym,
1512 strtab, strtablen,
1513 symtab_index,
1514 psym,
1515 &sym_info,
1516 &vna_other);
1517
af3fc3bc 1518 printf (" ");
171191ba 1519
d8045f23
NC
1520 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1521 {
1522 const char * name;
1523 unsigned int len;
1524 unsigned int width = is_32bit_elf ? 8 : 14;
1525
1526 /* Relocations against GNU_IFUNC symbols do not use the value
1527 of the symbol as the address to relocate against. Instead
1528 they invoke the function named by the symbol and use its
1529 result as the address for relocation.
1530
1531 To indicate this to the user, do not display the value of
1532 the symbol in the "Symbols's Value" field. Instead show
1533 its name followed by () as a hint that the symbol is
1534 invoked. */
1535
1536 if (strtab == NULL
1537 || psym->st_name == 0
1538 || psym->st_name >= strtablen)
1539 name = "??";
1540 else
1541 name = strtab + psym->st_name;
1542
1543 len = print_symbol (width, name);
bb4d2ac2
L
1544 if (version_string)
1545 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1546 version_string);
d8045f23
NC
1547 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1548 }
1549 else
1550 {
1551 print_vma (psym->st_value, LONG_HEX);
171191ba 1552
d8045f23
NC
1553 printf (is_32bit_elf ? " " : " ");
1554 }
103f02d3 1555
af3fc3bc 1556 if (psym->st_name == 0)
f1ef08cb 1557 {
2cf0635d 1558 const char * sec_name = "<null>";
f1ef08cb
AM
1559 char name_buf[40];
1560
1561 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1562 {
4fbb74a6 1563 if (psym->st_shndx < elf_header.e_shnum)
74e1a04b 1564 sec_name = SECTION_NAME (section_headers + psym->st_shndx);
f1ef08cb
AM
1565 else if (psym->st_shndx == SHN_ABS)
1566 sec_name = "ABS";
1567 else if (psym->st_shndx == SHN_COMMON)
1568 sec_name = "COMMON";
ac145307
BS
1569 else if ((elf_header.e_machine == EM_MIPS
1570 && psym->st_shndx == SHN_MIPS_SCOMMON)
1571 || (elf_header.e_machine == EM_TI_C6000
1572 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7
TS
1573 sec_name = "SCOMMON";
1574 else if (elf_header.e_machine == EM_MIPS
1575 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1576 sec_name = "SUNDEF";
8a9036a4 1577 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
1578 || elf_header.e_machine == EM_L1OM
1579 || elf_header.e_machine == EM_K1OM)
3b22753a
L
1580 && psym->st_shndx == SHN_X86_64_LCOMMON)
1581 sec_name = "LARGE_COMMON";
9ce701e2
L
1582 else if (elf_header.e_machine == EM_IA_64
1583 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1584 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1585 sec_name = "ANSI_COM";
28f997cf 1586 else if (is_ia64_vms ()
148b93f2
NC
1587 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1588 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1589 else
1590 {
1591 sprintf (name_buf, "<section 0x%x>",
1592 (unsigned int) psym->st_shndx);
1593 sec_name = name_buf;
1594 }
1595 }
1596 print_symbol (22, sec_name);
1597 }
af3fc3bc 1598 else if (strtab == NULL)
d79b3d50 1599 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1600 else if (psym->st_name >= strtablen)
d79b3d50 1601 printf (_("<corrupt string table index: %3ld>"), psym->st_name);
af3fc3bc 1602 else
bb4d2ac2
L
1603 {
1604 print_symbol (22, strtab + psym->st_name);
1605 if (version_string)
1606 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1607 version_string);
1608 }
103f02d3 1609
af3fc3bc 1610 if (is_rela)
171191ba 1611 {
598aaa76 1612 bfd_signed_vma off = rels[i].r_addend;
171191ba 1613
91d6fa6a 1614 if (off < 0)
598aaa76 1615 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1616 else
598aaa76 1617 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1618 }
19936277 1619 }
252b5132 1620 }
1b228002 1621 else if (is_rela)
f7a99963 1622 {
e04d7088
L
1623 bfd_signed_vma off = rels[i].r_addend;
1624
1625 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
1626 if (off < 0)
1627 printf ("-%" BFD_VMA_FMT "x", - off);
1628 else
1629 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1630 }
252b5132 1631
157c2599
NC
1632 if (elf_header.e_machine == EM_SPARCV9
1633 && rtype != NULL
1634 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1635 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1636
252b5132 1637 putchar ('\n');
2c71103e 1638
aca88567 1639#ifdef BFD64
53c7db4b 1640 if (! is_32bit_elf && elf_header.e_machine == EM_MIPS)
2c71103e 1641 {
91d6fa6a
NC
1642 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1643 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1644 const char * rtype2 = elf_mips_reloc_type (type2);
1645 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1646
2c71103e
NC
1647 printf (" Type2: ");
1648
1649 if (rtype2 == NULL)
39dbeff8
AM
1650 printf (_("unrecognized: %-7lx"),
1651 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1652 else
1653 printf ("%-17.17s", rtype2);
1654
18bd398b 1655 printf ("\n Type3: ");
2c71103e
NC
1656
1657 if (rtype3 == NULL)
39dbeff8
AM
1658 printf (_("unrecognized: %-7lx"),
1659 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1660 else
1661 printf ("%-17.17s", rtype3);
1662
53c7db4b 1663 putchar ('\n');
2c71103e 1664 }
aca88567 1665#endif /* BFD64 */
252b5132
RH
1666 }
1667
c8286bd1 1668 free (rels);
252b5132
RH
1669}
1670
1671static const char *
d3ba0551 1672get_mips_dynamic_type (unsigned long type)
252b5132
RH
1673{
1674 switch (type)
1675 {
1676 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1677 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1678 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1679 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1680 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1681 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1682 case DT_MIPS_MSYM: return "MIPS_MSYM";
1683 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1684 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1685 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1686 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1687 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1688 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1689 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1690 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1691 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1692 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
1693 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1694 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1695 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1696 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1697 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1698 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1699 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1700 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1701 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1702 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1703 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1704 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1705 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1706 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1707 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1708 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1709 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1710 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1711 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1712 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1713 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1714 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1715 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1716 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1717 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1718 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1719 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1720 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
252b5132
RH
1721 default:
1722 return NULL;
1723 }
1724}
1725
9a097730 1726static const char *
d3ba0551 1727get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1728{
1729 switch (type)
1730 {
1731 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1732 default:
1733 return NULL;
1734 }
103f02d3
UD
1735}
1736
7490d522
AM
1737static const char *
1738get_ppc_dynamic_type (unsigned long type)
1739{
1740 switch (type)
1741 {
a7f2871e 1742 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1743 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1744 default:
1745 return NULL;
1746 }
1747}
1748
f1cb7e17 1749static const char *
d3ba0551 1750get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1751{
1752 switch (type)
1753 {
a7f2871e
AM
1754 case DT_PPC64_GLINK: return "PPC64_GLINK";
1755 case DT_PPC64_OPD: return "PPC64_OPD";
1756 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1757 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1758 default:
1759 return NULL;
1760 }
1761}
1762
103f02d3 1763static const char *
d3ba0551 1764get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1765{
1766 switch (type)
1767 {
1768 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1769 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1770 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1771 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1772 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1773 case DT_HP_PREINIT: return "HP_PREINIT";
1774 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1775 case DT_HP_NEEDED: return "HP_NEEDED";
1776 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1777 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1778 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1779 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1780 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1781 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1782 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1783 case DT_HP_FILTERED: return "HP_FILTERED";
1784 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1785 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1786 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1787 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1788 case DT_PLT: return "PLT";
1789 case DT_PLT_SIZE: return "PLT_SIZE";
1790 case DT_DLT: return "DLT";
1791 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1792 default:
1793 return NULL;
1794 }
1795}
9a097730 1796
ecc51f48 1797static const char *
d3ba0551 1798get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1799{
1800 switch (type)
1801 {
148b93f2
NC
1802 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1803 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1804 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1805 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1806 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1807 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1808 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1809 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1810 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1811 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
1812 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
1813 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
1814 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
1815 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
1816 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
1817 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
1818 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
1819 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
1820 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
1821 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
1822 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
1823 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
1824 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
1825 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
1826 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
1827 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
1828 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
1829 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
1830 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
1831 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
1832 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
1833 default:
1834 return NULL;
1835 }
1836}
1837
fabcb361
RH
1838static const char *
1839get_alpha_dynamic_type (unsigned long type)
1840{
1841 switch (type)
1842 {
1843 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
1844 default:
1845 return NULL;
1846 }
1847}
1848
1c0d3aa6
NC
1849static const char *
1850get_score_dynamic_type (unsigned long type)
1851{
1852 switch (type)
1853 {
1854 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
1855 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
1856 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
1857 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
1858 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
1859 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
1860 default:
1861 return NULL;
1862 }
1863}
1864
40b36596
JM
1865static const char *
1866get_tic6x_dynamic_type (unsigned long type)
1867{
1868 switch (type)
1869 {
1870 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
1871 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
1872 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
1873 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
1874 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
1875 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
1876 default:
1877 return NULL;
1878 }
1879}
1c0d3aa6 1880
36591ba1
SL
1881static const char *
1882get_nios2_dynamic_type (unsigned long type)
1883{
1884 switch (type)
1885 {
1886 case DT_NIOS2_GP: return "NIOS2_GP";
1887 default:
1888 return NULL;
1889 }
1890}
1891
252b5132 1892static const char *
d3ba0551 1893get_dynamic_type (unsigned long type)
252b5132 1894{
e9e44622 1895 static char buff[64];
252b5132
RH
1896
1897 switch (type)
1898 {
1899 case DT_NULL: return "NULL";
1900 case DT_NEEDED: return "NEEDED";
1901 case DT_PLTRELSZ: return "PLTRELSZ";
1902 case DT_PLTGOT: return "PLTGOT";
1903 case DT_HASH: return "HASH";
1904 case DT_STRTAB: return "STRTAB";
1905 case DT_SYMTAB: return "SYMTAB";
1906 case DT_RELA: return "RELA";
1907 case DT_RELASZ: return "RELASZ";
1908 case DT_RELAENT: return "RELAENT";
1909 case DT_STRSZ: return "STRSZ";
1910 case DT_SYMENT: return "SYMENT";
1911 case DT_INIT: return "INIT";
1912 case DT_FINI: return "FINI";
1913 case DT_SONAME: return "SONAME";
1914 case DT_RPATH: return "RPATH";
1915 case DT_SYMBOLIC: return "SYMBOLIC";
1916 case DT_REL: return "REL";
1917 case DT_RELSZ: return "RELSZ";
1918 case DT_RELENT: return "RELENT";
1919 case DT_PLTREL: return "PLTREL";
1920 case DT_DEBUG: return "DEBUG";
1921 case DT_TEXTREL: return "TEXTREL";
1922 case DT_JMPREL: return "JMPREL";
1923 case DT_BIND_NOW: return "BIND_NOW";
1924 case DT_INIT_ARRAY: return "INIT_ARRAY";
1925 case DT_FINI_ARRAY: return "FINI_ARRAY";
1926 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
1927 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
1928 case DT_RUNPATH: return "RUNPATH";
1929 case DT_FLAGS: return "FLAGS";
2d0e6f43 1930
d1133906
NC
1931 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
1932 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
103f02d3 1933
05107a46 1934 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
1935 case DT_PLTPADSZ: return "PLTPADSZ";
1936 case DT_MOVEENT: return "MOVEENT";
1937 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 1938 case DT_FEATURE: return "FEATURE";
252b5132
RH
1939 case DT_POSFLAG_1: return "POSFLAG_1";
1940 case DT_SYMINSZ: return "SYMINSZ";
1941 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 1942
252b5132 1943 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
1944 case DT_CONFIG: return "CONFIG";
1945 case DT_DEPAUDIT: return "DEPAUDIT";
1946 case DT_AUDIT: return "AUDIT";
1947 case DT_PLTPAD: return "PLTPAD";
1948 case DT_MOVETAB: return "MOVETAB";
252b5132 1949 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 1950
252b5132 1951 case DT_VERSYM: return "VERSYM";
103f02d3 1952
67a4f2b7
AO
1953 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
1954 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
1955 case DT_RELACOUNT: return "RELACOUNT";
1956 case DT_RELCOUNT: return "RELCOUNT";
1957 case DT_FLAGS_1: return "FLAGS_1";
1958 case DT_VERDEF: return "VERDEF";
1959 case DT_VERDEFNUM: return "VERDEFNUM";
1960 case DT_VERNEED: return "VERNEED";
1961 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 1962
019148e4 1963 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
1964 case DT_USED: return "USED";
1965 case DT_FILTER: return "FILTER";
103f02d3 1966
047b2264
JJ
1967 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
1968 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
1969 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
1970 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
1971 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 1972 case DT_GNU_HASH: return "GNU_HASH";
047b2264 1973
252b5132
RH
1974 default:
1975 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
1976 {
2cf0635d 1977 const char * result;
103f02d3 1978
252b5132
RH
1979 switch (elf_header.e_machine)
1980 {
1981 case EM_MIPS:
4fe85591 1982 case EM_MIPS_RS3_LE:
252b5132
RH
1983 result = get_mips_dynamic_type (type);
1984 break;
9a097730
RH
1985 case EM_SPARCV9:
1986 result = get_sparc64_dynamic_type (type);
1987 break;
7490d522
AM
1988 case EM_PPC:
1989 result = get_ppc_dynamic_type (type);
1990 break;
f1cb7e17
AM
1991 case EM_PPC64:
1992 result = get_ppc64_dynamic_type (type);
1993 break;
ecc51f48
NC
1994 case EM_IA_64:
1995 result = get_ia64_dynamic_type (type);
1996 break;
fabcb361
RH
1997 case EM_ALPHA:
1998 result = get_alpha_dynamic_type (type);
1999 break;
1c0d3aa6
NC
2000 case EM_SCORE:
2001 result = get_score_dynamic_type (type);
2002 break;
40b36596
JM
2003 case EM_TI_C6000:
2004 result = get_tic6x_dynamic_type (type);
2005 break;
36591ba1
SL
2006 case EM_ALTERA_NIOS2:
2007 result = get_nios2_dynamic_type (type);
2008 break;
252b5132
RH
2009 default:
2010 result = NULL;
2011 break;
2012 }
2013
2014 if (result != NULL)
2015 return result;
2016
e9e44622 2017 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2018 }
eec8f817
DA
2019 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
2020 || (elf_header.e_machine == EM_PARISC
2021 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2022 {
2cf0635d 2023 const char * result;
103f02d3
UD
2024
2025 switch (elf_header.e_machine)
2026 {
2027 case EM_PARISC:
2028 result = get_parisc_dynamic_type (type);
2029 break;
148b93f2
NC
2030 case EM_IA_64:
2031 result = get_ia64_dynamic_type (type);
2032 break;
103f02d3
UD
2033 default:
2034 result = NULL;
2035 break;
2036 }
2037
2038 if (result != NULL)
2039 return result;
2040
e9e44622
JJ
2041 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2042 type);
103f02d3 2043 }
252b5132 2044 else
e9e44622 2045 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2046
252b5132
RH
2047 return buff;
2048 }
2049}
2050
2051static char *
d3ba0551 2052get_file_type (unsigned e_type)
252b5132 2053{
b34976b6 2054 static char buff[32];
252b5132
RH
2055
2056 switch (e_type)
2057 {
2058 case ET_NONE: return _("NONE (None)");
2059 case ET_REL: return _("REL (Relocatable file)");
ba2685cc
AM
2060 case ET_EXEC: return _("EXEC (Executable file)");
2061 case ET_DYN: return _("DYN (Shared object file)");
2062 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2063
2064 default:
2065 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2066 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2067 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2068 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2069 else
e9e44622 2070 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2071 return buff;
2072 }
2073}
2074
2075static char *
d3ba0551 2076get_machine_name (unsigned e_machine)
252b5132 2077{
b34976b6 2078 static char buff[64]; /* XXX */
252b5132
RH
2079
2080 switch (e_machine)
2081 {
c45021f2 2082 case EM_NONE: return _("None");
a06ea964 2083 case EM_AARCH64: return "AArch64";
c45021f2
NC
2084 case EM_M32: return "WE32100";
2085 case EM_SPARC: return "Sparc";
e9f53129 2086 case EM_SPU: return "SPU";
c45021f2
NC
2087 case EM_386: return "Intel 80386";
2088 case EM_68K: return "MC68000";
2089 case EM_88K: return "MC88000";
2090 case EM_486: return "Intel 80486";
2091 case EM_860: return "Intel 80860";
2092 case EM_MIPS: return "MIPS R3000";
2093 case EM_S370: return "IBM System/370";
7036c0e1 2094 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2095 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2096 case EM_PARISC: return "HPPA";
252b5132 2097 case EM_PPC_OLD: return "Power PC (old)";
7036c0e1 2098 case EM_SPARC32PLUS: return "Sparc v8+" ;
c45021f2
NC
2099 case EM_960: return "Intel 90860";
2100 case EM_PPC: return "PowerPC";
285d1771 2101 case EM_PPC64: return "PowerPC64";
c45021f2 2102 case EM_FR20: return "Fujitsu FR20";
3f8107ab 2103 case EM_FT32: return "FTDI FT32";
c45021f2 2104 case EM_RH32: return "TRW RH32";
b34976b6 2105 case EM_MCORE: return "MCORE";
7036c0e1
AJ
2106 case EM_ARM: return "ARM";
2107 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2108 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2109 case EM_SPARCV9: return "Sparc v9";
2110 case EM_TRICORE: return "Siemens Tricore";
584da044 2111 case EM_ARC: return "ARC";
c2dcd04e
NC
2112 case EM_H8_300: return "Renesas H8/300";
2113 case EM_H8_300H: return "Renesas H8/300H";
2114 case EM_H8S: return "Renesas H8S";
2115 case EM_H8_500: return "Renesas H8/500";
30800947 2116 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2117 case EM_MIPS_X: return "Stanford MIPS-X";
2118 case EM_COLDFIRE: return "Motorola Coldfire";
c45021f2 2119 case EM_ALPHA: return "Alpha";
2b0337b0
AO
2120 case EM_CYGNUS_D10V:
2121 case EM_D10V: return "d10v";
2122 case EM_CYGNUS_D30V:
b34976b6 2123 case EM_D30V: return "d30v";
2b0337b0 2124 case EM_CYGNUS_M32R:
26597c86 2125 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2b0337b0 2126 case EM_CYGNUS_V850:
708e2187 2127 case EM_V800: return "Renesas V850 (using RH850 ABI)";
f6c1a2d5 2128 case EM_V850: return "Renesas V850";
2b0337b0
AO
2129 case EM_CYGNUS_MN10300:
2130 case EM_MN10300: return "mn10300";
2131 case EM_CYGNUS_MN10200:
2132 case EM_MN10200: return "mn10200";
5506d11a 2133 case EM_MOXIE: return "Moxie";
2b0337b0
AO
2134 case EM_CYGNUS_FR30:
2135 case EM_FR30: return "Fujitsu FR30";
b34976b6 2136 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
2b0337b0 2137 case EM_PJ_OLD:
b34976b6 2138 case EM_PJ: return "picoJava";
7036c0e1
AJ
2139 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2140 case EM_PCP: return "Siemens PCP";
2141 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2142 case EM_NDR1: return "Denso NDR1 microprocesspr";
2143 case EM_STARCORE: return "Motorola Star*Core processor";
2144 case EM_ME16: return "Toyota ME16 processor";
2145 case EM_ST100: return "STMicroelectronics ST100 processor";
2146 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
11636f9e
JM
2147 case EM_PDSP: return "Sony DSP processor";
2148 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2149 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2150 case EM_FX66: return "Siemens FX66 microcontroller";
2151 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2152 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2153 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
6927f982 2154 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2155 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2156 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2157 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2158 case EM_SVX: return "Silicon Graphics SVx";
2159 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2160 case EM_VAX: return "Digital VAX";
619ed720 2161 case EM_VISIUM: return "CDS VISIUMcore processor";
2b0337b0 2162 case EM_AVR_OLD:
b34976b6 2163 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
1b61cf92 2164 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2165 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2166 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2167 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
b34976b6 2168 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2169 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2170 case EM_PRISM: return "Vitesse Prism";
bcedfee6 2171 case EM_X86_64: return "Advanced Micro Devices X86-64";
8a9036a4 2172 case EM_L1OM: return "Intel L1OM";
7a9068fe 2173 case EM_K1OM: return "Intel K1OM";
b7498e0e 2174 case EM_S390_OLD:
b34976b6 2175 case EM_S390: return "IBM S/390";
1c0d3aa6 2176 case EM_SCORE: return "SUNPLUS S+Core";
61865e30 2177 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
73589c9d 2178 case EM_OR1K: return "OpenRISC 1000";
11636f9e 2179 case EM_ARC_A5: return "ARC International ARCompact processor";
1fe1f39c 2180 case EM_CRX: return "National Semiconductor CRX microprocessor";
cfb8c092 2181 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
d172d4ba 2182 case EM_DLX: return "OpenDLX";
1e4cf259 2183 case EM_IP2K_OLD:
b34976b6 2184 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
3b36097d 2185 case EM_IQ2000: return "Vitesse IQ2000";
88da6820
NC
2186 case EM_XTENSA_OLD:
2187 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2188 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2189 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2190 case EM_NS32K: return "National Semiconductor 32000 series";
2191 case EM_TPC: return "Tenor Network TPC processor";
2192 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2193 case EM_MAX: return "MAX Processor";
2194 case EM_CR: return "National Semiconductor CompactRISC";
2195 case EM_F2MC16: return "Fujitsu F2MC16";
2196 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
84e94c90 2197 case EM_LATTICEMICO32: return "Lattice Mico32";
ff7eeb89 2198 case EM_M32C_OLD:
49f58d10 2199 case EM_M32C: return "Renesas M32c";
d031aafb 2200 case EM_MT: return "Morpho Techologies MT processor";
7bbe5bc5 2201 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2202 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2203 case EM_SEP: return "Sharp embedded microprocessor";
2204 case EM_ARCA: return "Arca RISC microprocessor";
2205 case EM_UNICORE: return "Unicore";
2206 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2207 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348
NC
2208 case EM_NIOS32: return "Altera Nios";
2209 case EM_ALTERA_NIOS2: return "Altera Nios II";
c29aca4a 2210 case EM_C166:
d70c5fc7 2211 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2212 case EM_M16C: return "Renesas M16C series microprocessors";
2213 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2214 case EM_CE: return "Freescale Communication Engine RISC core";
2215 case EM_TSK3000: return "Altium TSK3000 core";
2216 case EM_RS08: return "Freescale RS08 embedded processor";
2217 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2218 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2219 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2220 case EM_SE_C17: return "Seiko Epson C17 family";
2221 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2222 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2223 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2224 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2225 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2226 case EM_R32C: return "Renesas R32C series microprocessors";
2227 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2228 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2229 case EM_8051: return "Intel 8051 and variants";
2230 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2231 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2232 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2233 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2234 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2235 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2236 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
15ab5209 2237 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
cb8f3167 2238 case EM_CR16:
f6c1a2d5 2239 case EM_MICROBLAZE:
7ba29e2a 2240 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
99c513f6 2241 case EM_RL78: return "Renesas RL78";
c7927a3c 2242 case EM_RX: return "Renesas RX";
a3c62988 2243 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2244 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2245 case EM_ECOG16: return "Cyan Technology eCOG16 family";
2246 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2247 case EM_SLE9X: return "Infineon Technologies SLE9X core";
2248 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor family";
2249 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2250 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2251 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
aa137e4d 2252 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
11636f9e 2253 case EM_CUDA: return "NVIDIA CUDA architecture";
f6c1a2d5 2254 case EM_XGATE: return "Motorola XGATE embedded processor";
252b5132 2255 default:
35d9dd2f 2256 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2257 return buff;
2258 }
2259}
2260
f3485b74 2261static void
d3ba0551 2262decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2263{
2264 unsigned eabi;
2265 int unknown = 0;
2266
2267 eabi = EF_ARM_EABI_VERSION (e_flags);
2268 e_flags &= ~ EF_ARM_EABIMASK;
2269
2270 /* Handle "generic" ARM flags. */
2271 if (e_flags & EF_ARM_RELEXEC)
2272 {
2273 strcat (buf, ", relocatable executable");
2274 e_flags &= ~ EF_ARM_RELEXEC;
2275 }
76da6bbe 2276
f3485b74
NC
2277 if (e_flags & EF_ARM_HASENTRY)
2278 {
2279 strcat (buf, ", has entry point");
2280 e_flags &= ~ EF_ARM_HASENTRY;
2281 }
76da6bbe 2282
f3485b74
NC
2283 /* Now handle EABI specific flags. */
2284 switch (eabi)
2285 {
2286 default:
2c71103e 2287 strcat (buf, ", <unrecognized EABI>");
f3485b74
NC
2288 if (e_flags)
2289 unknown = 1;
2290 break;
2291
2292 case EF_ARM_EABI_VER1:
a5bcd848 2293 strcat (buf, ", Version1 EABI");
f3485b74
NC
2294 while (e_flags)
2295 {
2296 unsigned flag;
76da6bbe 2297
f3485b74
NC
2298 /* Process flags one bit at a time. */
2299 flag = e_flags & - e_flags;
2300 e_flags &= ~ flag;
76da6bbe 2301
f3485b74
NC
2302 switch (flag)
2303 {
a5bcd848 2304 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2305 strcat (buf, ", sorted symbol tables");
2306 break;
76da6bbe 2307
f3485b74
NC
2308 default:
2309 unknown = 1;
2310 break;
2311 }
2312 }
2313 break;
76da6bbe 2314
a5bcd848
PB
2315 case EF_ARM_EABI_VER2:
2316 strcat (buf, ", Version2 EABI");
2317 while (e_flags)
2318 {
2319 unsigned flag;
2320
2321 /* Process flags one bit at a time. */
2322 flag = e_flags & - e_flags;
2323 e_flags &= ~ flag;
2324
2325 switch (flag)
2326 {
2327 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2328 strcat (buf, ", sorted symbol tables");
2329 break;
2330
2331 case EF_ARM_DYNSYMSUSESEGIDX:
2332 strcat (buf, ", dynamic symbols use segment index");
2333 break;
2334
2335 case EF_ARM_MAPSYMSFIRST:
2336 strcat (buf, ", mapping symbols precede others");
2337 break;
2338
2339 default:
2340 unknown = 1;
2341 break;
2342 }
2343 }
2344 break;
2345
d507cf36
PB
2346 case EF_ARM_EABI_VER3:
2347 strcat (buf, ", Version3 EABI");
8cb51566
PB
2348 break;
2349
2350 case EF_ARM_EABI_VER4:
2351 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2352 while (e_flags)
2353 {
2354 unsigned flag;
2355
2356 /* Process flags one bit at a time. */
2357 flag = e_flags & - e_flags;
2358 e_flags &= ~ flag;
2359
2360 switch (flag)
2361 {
2362 case EF_ARM_BE8:
2363 strcat (buf, ", BE8");
2364 break;
2365
2366 case EF_ARM_LE8:
2367 strcat (buf, ", LE8");
2368 break;
2369
2370 default:
2371 unknown = 1;
2372 break;
2373 }
2374 break;
2375 }
2376 break;
3a4a14e9
PB
2377
2378 case EF_ARM_EABI_VER5:
2379 strcat (buf, ", Version5 EABI");
d507cf36
PB
2380 while (e_flags)
2381 {
2382 unsigned flag;
2383
2384 /* Process flags one bit at a time. */
2385 flag = e_flags & - e_flags;
2386 e_flags &= ~ flag;
2387
2388 switch (flag)
2389 {
2390 case EF_ARM_BE8:
2391 strcat (buf, ", BE8");
2392 break;
2393
2394 case EF_ARM_LE8:
2395 strcat (buf, ", LE8");
2396 break;
2397
3bfcb652
NC
2398 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2399 strcat (buf, ", soft-float ABI");
2400 break;
2401
2402 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2403 strcat (buf, ", hard-float ABI");
2404 break;
2405
d507cf36
PB
2406 default:
2407 unknown = 1;
2408 break;
2409 }
2410 }
2411 break;
2412
f3485b74 2413 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2414 strcat (buf, ", GNU EABI");
f3485b74
NC
2415 while (e_flags)
2416 {
2417 unsigned flag;
76da6bbe 2418
f3485b74
NC
2419 /* Process flags one bit at a time. */
2420 flag = e_flags & - e_flags;
2421 e_flags &= ~ flag;
76da6bbe 2422
f3485b74
NC
2423 switch (flag)
2424 {
a5bcd848 2425 case EF_ARM_INTERWORK:
f3485b74
NC
2426 strcat (buf, ", interworking enabled");
2427 break;
76da6bbe 2428
a5bcd848 2429 case EF_ARM_APCS_26:
f3485b74
NC
2430 strcat (buf, ", uses APCS/26");
2431 break;
76da6bbe 2432
a5bcd848 2433 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2434 strcat (buf, ", uses APCS/float");
2435 break;
76da6bbe 2436
a5bcd848 2437 case EF_ARM_PIC:
f3485b74
NC
2438 strcat (buf, ", position independent");
2439 break;
76da6bbe 2440
a5bcd848 2441 case EF_ARM_ALIGN8:
f3485b74
NC
2442 strcat (buf, ", 8 bit structure alignment");
2443 break;
76da6bbe 2444
a5bcd848 2445 case EF_ARM_NEW_ABI:
f3485b74
NC
2446 strcat (buf, ", uses new ABI");
2447 break;
76da6bbe 2448
a5bcd848 2449 case EF_ARM_OLD_ABI:
f3485b74
NC
2450 strcat (buf, ", uses old ABI");
2451 break;
76da6bbe 2452
a5bcd848 2453 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2454 strcat (buf, ", software FP");
2455 break;
76da6bbe 2456
90e01f86
ILT
2457 case EF_ARM_VFP_FLOAT:
2458 strcat (buf, ", VFP");
2459 break;
2460
fde78edd
NC
2461 case EF_ARM_MAVERICK_FLOAT:
2462 strcat (buf, ", Maverick FP");
2463 break;
2464
f3485b74
NC
2465 default:
2466 unknown = 1;
2467 break;
2468 }
2469 }
2470 }
f3485b74
NC
2471
2472 if (unknown)
2b692964 2473 strcat (buf,_(", <unknown>"));
f3485b74
NC
2474}
2475
343433df
AB
2476static void
2477decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2478{
2479 --size; /* Leave space for null terminator. */
2480
2481 switch (e_flags & EF_AVR_MACH)
2482 {
2483 case E_AVR_MACH_AVR1:
2484 strncat (buf, ", avr:1", size);
2485 break;
2486 case E_AVR_MACH_AVR2:
2487 strncat (buf, ", avr:2", size);
2488 break;
2489 case E_AVR_MACH_AVR25:
2490 strncat (buf, ", avr:25", size);
2491 break;
2492 case E_AVR_MACH_AVR3:
2493 strncat (buf, ", avr:3", size);
2494 break;
2495 case E_AVR_MACH_AVR31:
2496 strncat (buf, ", avr:31", size);
2497 break;
2498 case E_AVR_MACH_AVR35:
2499 strncat (buf, ", avr:35", size);
2500 break;
2501 case E_AVR_MACH_AVR4:
2502 strncat (buf, ", avr:4", size);
2503 break;
2504 case E_AVR_MACH_AVR5:
2505 strncat (buf, ", avr:5", size);
2506 break;
2507 case E_AVR_MACH_AVR51:
2508 strncat (buf, ", avr:51", size);
2509 break;
2510 case E_AVR_MACH_AVR6:
2511 strncat (buf, ", avr:6", size);
2512 break;
2513 case E_AVR_MACH_AVRTINY:
2514 strncat (buf, ", avr:100", size);
2515 break;
2516 case E_AVR_MACH_XMEGA1:
2517 strncat (buf, ", avr:101", size);
2518 break;
2519 case E_AVR_MACH_XMEGA2:
2520 strncat (buf, ", avr:102", size);
2521 break;
2522 case E_AVR_MACH_XMEGA3:
2523 strncat (buf, ", avr:103", size);
2524 break;
2525 case E_AVR_MACH_XMEGA4:
2526 strncat (buf, ", avr:104", size);
2527 break;
2528 case E_AVR_MACH_XMEGA5:
2529 strncat (buf, ", avr:105", size);
2530 break;
2531 case E_AVR_MACH_XMEGA6:
2532 strncat (buf, ", avr:106", size);
2533 break;
2534 case E_AVR_MACH_XMEGA7:
2535 strncat (buf, ", avr:107", size);
2536 break;
2537 default:
2538 strncat (buf, ", avr:<unknown>", size);
2539 break;
2540 }
2541
2542 size -= strlen (buf);
2543 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2544 strncat (buf, ", link-relax", size);
2545}
2546
35c08157
KLC
2547static void
2548decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2549{
2550 unsigned abi;
2551 unsigned arch;
2552 unsigned config;
2553 unsigned version;
2554 int has_fpu = 0;
2555 int r = 0;
2556
2557 static const char *ABI_STRINGS[] =
2558 {
2559 "ABI v0", /* use r5 as return register; only used in N1213HC */
2560 "ABI v1", /* use r0 as return register */
2561 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2562 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2563 "AABI",
2564 "ABI2 FP+"
35c08157
KLC
2565 };
2566 static const char *VER_STRINGS[] =
2567 {
2568 "Andes ELF V1.3 or older",
2569 "Andes ELF V1.3.1",
2570 "Andes ELF V1.4"
2571 };
2572 static const char *ARCH_STRINGS[] =
2573 {
2574 "",
2575 "Andes Star v1.0",
2576 "Andes Star v2.0",
2577 "Andes Star v3.0",
2578 "Andes Star v3.0m"
2579 };
2580
2581 abi = EF_NDS_ABI & e_flags;
2582 arch = EF_NDS_ARCH & e_flags;
2583 config = EF_NDS_INST & e_flags;
2584 version = EF_NDS32_ELF_VERSION & e_flags;
2585
2586 memset (buf, 0, size);
2587
2588 switch (abi)
2589 {
2590 case E_NDS_ABI_V0:
2591 case E_NDS_ABI_V1:
2592 case E_NDS_ABI_V2:
2593 case E_NDS_ABI_V2FP:
2594 case E_NDS_ABI_AABI:
40c7a7cb 2595 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2596 /* In case there are holes in the array. */
2597 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2598 break;
2599
2600 default:
2601 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2602 break;
2603 }
2604
2605 switch (version)
2606 {
2607 case E_NDS32_ELF_VER_1_2:
2608 case E_NDS32_ELF_VER_1_3:
2609 case E_NDS32_ELF_VER_1_4:
2610 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2611 break;
2612
2613 default:
2614 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
2615 break;
2616 }
2617
2618 if (E_NDS_ABI_V0 == abi)
2619 {
2620 /* OLD ABI; only used in N1213HC, has performance extension 1. */
2621 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
2622 if (arch == E_NDS_ARCH_STAR_V1_0)
2623 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
2624 return;
2625 }
2626
2627 switch (arch)
2628 {
2629 case E_NDS_ARCH_STAR_V1_0:
2630 case E_NDS_ARCH_STAR_V2_0:
2631 case E_NDS_ARCH_STAR_V3_0:
2632 case E_NDS_ARCH_STAR_V3_M:
2633 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
2634 break;
2635
2636 default:
2637 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
2638 /* ARCH version determines how the e_flags are interpreted.
2639 If it is unknown, we cannot proceed. */
2640 return;
2641 }
2642
2643 /* Newer ABI; Now handle architecture specific flags. */
2644 if (arch == E_NDS_ARCH_STAR_V1_0)
2645 {
2646 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2647 r += snprintf (buf + r, size -r, ", MFUSR_PC");
2648
2649 if (!(config & E_NDS32_HAS_NO_MAC_INST))
2650 r += snprintf (buf + r, size -r, ", MAC");
2651
2652 if (config & E_NDS32_HAS_DIV_INST)
2653 r += snprintf (buf + r, size -r, ", DIV");
2654
2655 if (config & E_NDS32_HAS_16BIT_INST)
2656 r += snprintf (buf + r, size -r, ", 16b");
2657 }
2658 else
2659 {
2660 if (config & E_NDS32_HAS_MFUSR_PC_INST)
2661 {
2662 if (version <= E_NDS32_ELF_VER_1_3)
2663 r += snprintf (buf + r, size -r, ", [B8]");
2664 else
2665 r += snprintf (buf + r, size -r, ", EX9");
2666 }
2667
2668 if (config & E_NDS32_HAS_MAC_DX_INST)
2669 r += snprintf (buf + r, size -r, ", MAC_DX");
2670
2671 if (config & E_NDS32_HAS_DIV_DX_INST)
2672 r += snprintf (buf + r, size -r, ", DIV_DX");
2673
2674 if (config & E_NDS32_HAS_16BIT_INST)
2675 {
2676 if (version <= E_NDS32_ELF_VER_1_3)
2677 r += snprintf (buf + r, size -r, ", 16b");
2678 else
2679 r += snprintf (buf + r, size -r, ", IFC");
2680 }
2681 }
2682
2683 if (config & E_NDS32_HAS_EXT_INST)
2684 r += snprintf (buf + r, size -r, ", PERF1");
2685
2686 if (config & E_NDS32_HAS_EXT2_INST)
2687 r += snprintf (buf + r, size -r, ", PERF2");
2688
2689 if (config & E_NDS32_HAS_FPU_INST)
2690 {
2691 has_fpu = 1;
2692 r += snprintf (buf + r, size -r, ", FPU_SP");
2693 }
2694
2695 if (config & E_NDS32_HAS_FPU_DP_INST)
2696 {
2697 has_fpu = 1;
2698 r += snprintf (buf + r, size -r, ", FPU_DP");
2699 }
2700
2701 if (config & E_NDS32_HAS_FPU_MAC_INST)
2702 {
2703 has_fpu = 1;
2704 r += snprintf (buf + r, size -r, ", FPU_MAC");
2705 }
2706
2707 if (has_fpu)
2708 {
2709 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
2710 {
2711 case E_NDS32_FPU_REG_8SP_4DP:
2712 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
2713 break;
2714 case E_NDS32_FPU_REG_16SP_8DP:
2715 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
2716 break;
2717 case E_NDS32_FPU_REG_32SP_16DP:
2718 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
2719 break;
2720 case E_NDS32_FPU_REG_32SP_32DP:
2721 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
2722 break;
2723 }
2724 }
2725
2726 if (config & E_NDS32_HAS_AUDIO_INST)
2727 r += snprintf (buf + r, size -r, ", AUDIO");
2728
2729 if (config & E_NDS32_HAS_STRING_INST)
2730 r += snprintf (buf + r, size -r, ", STR");
2731
2732 if (config & E_NDS32_HAS_REDUCED_REGS)
2733 r += snprintf (buf + r, size -r, ", 16REG");
2734
2735 if (config & E_NDS32_HAS_VIDEO_INST)
2736 {
2737 if (version <= E_NDS32_ELF_VER_1_3)
2738 r += snprintf (buf + r, size -r, ", VIDEO");
2739 else
2740 r += snprintf (buf + r, size -r, ", SATURATION");
2741 }
2742
2743 if (config & E_NDS32_HAS_ENCRIPT_INST)
2744 r += snprintf (buf + r, size -r, ", ENCRP");
2745
2746 if (config & E_NDS32_HAS_L2C_INST)
2747 r += snprintf (buf + r, size -r, ", L2C");
2748}
2749
252b5132 2750static char *
d3ba0551 2751get_machine_flags (unsigned e_flags, unsigned e_machine)
252b5132 2752{
b34976b6 2753 static char buf[1024];
252b5132
RH
2754
2755 buf[0] = '\0';
76da6bbe 2756
252b5132
RH
2757 if (e_flags)
2758 {
2759 switch (e_machine)
2760 {
2761 default:
2762 break;
2763
f3485b74
NC
2764 case EM_ARM:
2765 decode_ARM_machine_flags (e_flags, buf);
2766 break;
76da6bbe 2767
343433df
AB
2768 case EM_AVR:
2769 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
2770 break;
2771
781303ce
MF
2772 case EM_BLACKFIN:
2773 if (e_flags & EF_BFIN_PIC)
2774 strcat (buf, ", PIC");
2775
2776 if (e_flags & EF_BFIN_FDPIC)
2777 strcat (buf, ", FDPIC");
2778
2779 if (e_flags & EF_BFIN_CODE_IN_L1)
2780 strcat (buf, ", code in L1");
2781
2782 if (e_flags & EF_BFIN_DATA_IN_L1)
2783 strcat (buf, ", data in L1");
2784
2785 break;
2786
ec2dfb42
AO
2787 case EM_CYGNUS_FRV:
2788 switch (e_flags & EF_FRV_CPU_MASK)
2789 {
2790 case EF_FRV_CPU_GENERIC:
2791 break;
2792
2793 default:
2794 strcat (buf, ", fr???");
2795 break;
57346661 2796
ec2dfb42
AO
2797 case EF_FRV_CPU_FR300:
2798 strcat (buf, ", fr300");
2799 break;
2800
2801 case EF_FRV_CPU_FR400:
2802 strcat (buf, ", fr400");
2803 break;
2804 case EF_FRV_CPU_FR405:
2805 strcat (buf, ", fr405");
2806 break;
2807
2808 case EF_FRV_CPU_FR450:
2809 strcat (buf, ", fr450");
2810 break;
2811
2812 case EF_FRV_CPU_FR500:
2813 strcat (buf, ", fr500");
2814 break;
2815 case EF_FRV_CPU_FR550:
2816 strcat (buf, ", fr550");
2817 break;
2818
2819 case EF_FRV_CPU_SIMPLE:
2820 strcat (buf, ", simple");
2821 break;
2822 case EF_FRV_CPU_TOMCAT:
2823 strcat (buf, ", tomcat");
2824 break;
2825 }
1c877e87 2826 break;
ec2dfb42 2827
53c7db4b 2828 case EM_68K:
425c6cb0 2829 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 2830 strcat (buf, ", m68000");
425c6cb0 2831 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
2832 strcat (buf, ", cpu32");
2833 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
2834 strcat (buf, ", fido_a");
425c6cb0 2835 else
266abb8f 2836 {
2cf0635d
NC
2837 char const * isa = _("unknown");
2838 char const * mac = _("unknown mac");
2839 char const * additional = NULL;
0112cd26 2840
c694fd50 2841 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 2842 {
c694fd50 2843 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
2844 isa = "A";
2845 additional = ", nodiv";
2846 break;
c694fd50 2847 case EF_M68K_CF_ISA_A:
266abb8f
NS
2848 isa = "A";
2849 break;
c694fd50 2850 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
2851 isa = "A+";
2852 break;
c694fd50 2853 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
2854 isa = "B";
2855 additional = ", nousp";
2856 break;
c694fd50 2857 case EF_M68K_CF_ISA_B:
266abb8f
NS
2858 isa = "B";
2859 break;
f608cd77
NS
2860 case EF_M68K_CF_ISA_C:
2861 isa = "C";
2862 break;
2863 case EF_M68K_CF_ISA_C_NODIV:
2864 isa = "C";
2865 additional = ", nodiv";
2866 break;
266abb8f
NS
2867 }
2868 strcat (buf, ", cf, isa ");
2869 strcat (buf, isa);
0b2e31dc
NS
2870 if (additional)
2871 strcat (buf, additional);
c694fd50 2872 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 2873 strcat (buf, ", float");
c694fd50 2874 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
2875 {
2876 case 0:
2877 mac = NULL;
2878 break;
c694fd50 2879 case EF_M68K_CF_MAC:
266abb8f
NS
2880 mac = "mac";
2881 break;
c694fd50 2882 case EF_M68K_CF_EMAC:
266abb8f
NS
2883 mac = "emac";
2884 break;
f608cd77
NS
2885 case EF_M68K_CF_EMAC_B:
2886 mac = "emac_b";
2887 break;
266abb8f
NS
2888 }
2889 if (mac)
2890 {
2891 strcat (buf, ", ");
2892 strcat (buf, mac);
2893 }
266abb8f 2894 }
53c7db4b 2895 break;
33c63f9d 2896
252b5132
RH
2897 case EM_PPC:
2898 if (e_flags & EF_PPC_EMB)
2899 strcat (buf, ", emb");
2900
2901 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 2902 strcat (buf, _(", relocatable"));
252b5132
RH
2903
2904 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 2905 strcat (buf, _(", relocatable-lib"));
252b5132
RH
2906 break;
2907
ee67d69a
AM
2908 case EM_PPC64:
2909 if (e_flags & EF_PPC64_ABI)
2910 {
2911 char abi[] = ", abiv0";
2912
2913 abi[6] += e_flags & EF_PPC64_ABI;
2914 strcat (buf, abi);
2915 }
2916 break;
2917
708e2187
NC
2918 case EM_V800:
2919 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
2920 strcat (buf, ", RH850 ABI");
0b4362b0 2921
708e2187
NC
2922 if (e_flags & EF_V800_850E3)
2923 strcat (buf, ", V3 architecture");
2924
2925 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
2926 strcat (buf, ", FPU not used");
2927
2928 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
2929 strcat (buf, ", regmode: COMMON");
2930
2931 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
2932 strcat (buf, ", r4 not used");
2933
2934 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
2935 strcat (buf, ", r30 not used");
2936
2937 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
2938 strcat (buf, ", r5 not used");
2939
2940 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
2941 strcat (buf, ", r2 not used");
2942
2943 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
2944 {
2945 switch (e_flags & - e_flags)
2946 {
2947 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
2948 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
2949 case EF_RH850_SIMD: strcat (buf, ", SIMD"); break;
2950 case EF_RH850_CACHE: strcat (buf, ", CACHE"); break;
2951 case EF_RH850_MMU: strcat (buf, ", MMU"); break;
2952 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
2953 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
2954 case EF_RH850_DATA_ALIGN8: strcat (buf, ", 8-byte alignment"); break;
2955 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
2956 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
2957 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
2958 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
2959 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
2960 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
2961 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
2962 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
2963 default: break;
2964 }
2965 }
2966 break;
2967
2b0337b0 2968 case EM_V850:
252b5132
RH
2969 case EM_CYGNUS_V850:
2970 switch (e_flags & EF_V850_ARCH)
2971 {
78c8d46c
NC
2972 case E_V850E3V5_ARCH:
2973 strcat (buf, ", v850e3v5");
2974 break;
1cd986c5
NC
2975 case E_V850E2V3_ARCH:
2976 strcat (buf, ", v850e2v3");
2977 break;
2978 case E_V850E2_ARCH:
2979 strcat (buf, ", v850e2");
2980 break;
2981 case E_V850E1_ARCH:
2982 strcat (buf, ", v850e1");
8ad30312 2983 break;
252b5132
RH
2984 case E_V850E_ARCH:
2985 strcat (buf, ", v850e");
2986 break;
252b5132
RH
2987 case E_V850_ARCH:
2988 strcat (buf, ", v850");
2989 break;
2990 default:
2b692964 2991 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
2992 break;
2993 }
2994 break;
2995
2b0337b0 2996 case EM_M32R:
252b5132
RH
2997 case EM_CYGNUS_M32R:
2998 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
2999 strcat (buf, ", m32r");
252b5132
RH
3000 break;
3001
3002 case EM_MIPS:
4fe85591 3003 case EM_MIPS_RS3_LE:
252b5132
RH
3004 if (e_flags & EF_MIPS_NOREORDER)
3005 strcat (buf, ", noreorder");
3006
3007 if (e_flags & EF_MIPS_PIC)
3008 strcat (buf, ", pic");
3009
3010 if (e_flags & EF_MIPS_CPIC)
3011 strcat (buf, ", cpic");
3012
d1bdd336
TS
3013 if (e_flags & EF_MIPS_UCODE)
3014 strcat (buf, ", ugen_reserved");
3015
252b5132
RH
3016 if (e_flags & EF_MIPS_ABI2)
3017 strcat (buf, ", abi2");
3018
43521d43
TS
3019 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3020 strcat (buf, ", odk first");
3021
a5d22d2a
TS
3022 if (e_flags & EF_MIPS_32BITMODE)
3023 strcat (buf, ", 32bitmode");
3024
ba92f887
MR
3025 if (e_flags & EF_MIPS_NAN2008)
3026 strcat (buf, ", nan2008");
3027
fef1b0b3
SE
3028 if (e_flags & EF_MIPS_FP64)
3029 strcat (buf, ", fp64");
3030
156c2f8b
NC
3031 switch ((e_flags & EF_MIPS_MACH))
3032 {
3033 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3034 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3035 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3036 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3037 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3038 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3039 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3040 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
c6c98b38 3041 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3042 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3043 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3044 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
fd503541 3045 case E_MIPS_MACH_LS3A: strcat (buf, ", loongson-3a"); break;
05c6f050 3046 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3047 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3048 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3049 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
43521d43
TS
3050 case 0:
3051 /* We simply ignore the field in this case to avoid confusion:
3052 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3053 extension. */
3054 break;
2b692964 3055 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3056 }
43521d43
TS
3057
3058 switch ((e_flags & EF_MIPS_ABI))
3059 {
3060 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3061 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3062 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3063 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3064 case 0:
3065 /* We simply ignore the field in this case to avoid confusion:
3066 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3067 This means it is likely to be an o32 file, but not for
3068 sure. */
3069 break;
2b692964 3070 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3071 }
3072
3073 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3074 strcat (buf, ", mdmx");
3075
3076 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3077 strcat (buf, ", mips16");
3078
df58fc94
RS
3079 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3080 strcat (buf, ", micromips");
3081
43521d43
TS
3082 switch ((e_flags & EF_MIPS_ARCH))
3083 {
3084 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3085 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3086 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3087 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3088 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3089 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3090 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3091 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3092 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3093 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3094 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3095 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3096 }
252b5132 3097 break;
351b4b40 3098
35c08157
KLC
3099 case EM_NDS32:
3100 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3101 break;
3102
ccde1100
AO
3103 case EM_SH:
3104 switch ((e_flags & EF_SH_MACH_MASK))
3105 {
3106 case EF_SH1: strcat (buf, ", sh1"); break;
3107 case EF_SH2: strcat (buf, ", sh2"); break;
3108 case EF_SH3: strcat (buf, ", sh3"); break;
3109 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3110 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3111 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3112 case EF_SH3E: strcat (buf, ", sh3e"); break;
3113 case EF_SH4: strcat (buf, ", sh4"); break;
3114 case EF_SH5: strcat (buf, ", sh5"); break;
3115 case EF_SH2E: strcat (buf, ", sh2e"); break;
3116 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3117 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3118 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3119 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3120 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3121 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3122 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3123 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3124 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3125 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3126 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3127 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3128 }
3129
cec6a5b8
MR
3130 if (e_flags & EF_SH_PIC)
3131 strcat (buf, ", pic");
3132
3133 if (e_flags & EF_SH_FDPIC)
3134 strcat (buf, ", fdpic");
ccde1100 3135 break;
73589c9d
CS
3136
3137 case EM_OR1K:
3138 if (e_flags & EF_OR1K_NODELAY)
3139 strcat (buf, ", no delay");
3140 break;
57346661 3141
351b4b40
RH
3142 case EM_SPARCV9:
3143 if (e_flags & EF_SPARC_32PLUS)
3144 strcat (buf, ", v8+");
3145
3146 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3147 strcat (buf, ", ultrasparcI");
3148
3149 if (e_flags & EF_SPARC_SUN_US3)
3150 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3151
3152 if (e_flags & EF_SPARC_HAL_R1)
3153 strcat (buf, ", halr1");
3154
3155 if (e_flags & EF_SPARC_LEDATA)
3156 strcat (buf, ", ledata");
3157
3158 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3159 strcat (buf, ", tso");
3160
3161 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3162 strcat (buf, ", pso");
3163
3164 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3165 strcat (buf, ", rmo");
3166 break;
7d466069 3167
103f02d3
UD
3168 case EM_PARISC:
3169 switch (e_flags & EF_PARISC_ARCH)
3170 {
3171 case EFA_PARISC_1_0:
3172 strcpy (buf, ", PA-RISC 1.0");
3173 break;
3174 case EFA_PARISC_1_1:
3175 strcpy (buf, ", PA-RISC 1.1");
3176 break;
3177 case EFA_PARISC_2_0:
3178 strcpy (buf, ", PA-RISC 2.0");
3179 break;
3180 default:
3181 break;
3182 }
3183 if (e_flags & EF_PARISC_TRAPNIL)
3184 strcat (buf, ", trapnil");
3185 if (e_flags & EF_PARISC_EXT)
3186 strcat (buf, ", ext");
3187 if (e_flags & EF_PARISC_LSB)
3188 strcat (buf, ", lsb");
3189 if (e_flags & EF_PARISC_WIDE)
3190 strcat (buf, ", wide");
3191 if (e_flags & EF_PARISC_NO_KABP)
3192 strcat (buf, ", no kabp");
3193 if (e_flags & EF_PARISC_LAZYSWAP)
3194 strcat (buf, ", lazyswap");
30800947 3195 break;
76da6bbe 3196
7d466069 3197 case EM_PJ:
2b0337b0 3198 case EM_PJ_OLD:
7d466069
ILT
3199 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3200 strcat (buf, ", new calling convention");
3201
3202 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3203 strcat (buf, ", gnu calling convention");
3204 break;
4d6ed7c8
NC
3205
3206 case EM_IA_64:
3207 if ((e_flags & EF_IA_64_ABI64))
3208 strcat (buf, ", 64-bit");
3209 else
3210 strcat (buf, ", 32-bit");
3211 if ((e_flags & EF_IA_64_REDUCEDFP))
3212 strcat (buf, ", reduced fp model");
3213 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3214 strcat (buf, ", no function descriptors, constant gp");
3215 else if ((e_flags & EF_IA_64_CONS_GP))
3216 strcat (buf, ", constant gp");
3217 if ((e_flags & EF_IA_64_ABSOLUTE))
3218 strcat (buf, ", absolute");
28f997cf
TG
3219 if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3220 {
3221 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3222 strcat (buf, ", vms_linkages");
3223 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3224 {
3225 case EF_IA_64_VMS_COMCOD_SUCCESS:
3226 break;
3227 case EF_IA_64_VMS_COMCOD_WARNING:
3228 strcat (buf, ", warning");
3229 break;
3230 case EF_IA_64_VMS_COMCOD_ERROR:
3231 strcat (buf, ", error");
3232 break;
3233 case EF_IA_64_VMS_COMCOD_ABORT:
3234 strcat (buf, ", abort");
3235 break;
3236 default:
bee0ee85
NC
3237 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3238 e_flags & EF_IA_64_VMS_COMCOD);
3239 strcat (buf, ", <unknown>");
28f997cf
TG
3240 }
3241 }
4d6ed7c8 3242 break;
179d3252
JT
3243
3244 case EM_VAX:
3245 if ((e_flags & EF_VAX_NONPIC))
3246 strcat (buf, ", non-PIC");
3247 if ((e_flags & EF_VAX_DFLOAT))
3248 strcat (buf, ", D-Float");
3249 if ((e_flags & EF_VAX_GFLOAT))
3250 strcat (buf, ", G-Float");
3251 break;
c7927a3c 3252
619ed720
EB
3253 case EM_VISIUM:
3254 if (e_flags & EF_VISIUM_ARCH_MCM)
3255 strcat (buf, ", mcm");
3256 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3257 strcat (buf, ", mcm24");
3258 if (e_flags & EF_VISIUM_ARCH_GR6)
3259 strcat (buf, ", gr6");
3260 break;
3261
4046d87a
NC
3262 case EM_RL78:
3263 if (e_flags & E_FLAG_RL78_G10)
3264 strcat (buf, ", G10");
856ea05c
KP
3265 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3266 strcat (buf, ", 64-bit doubles");
4046d87a 3267 break;
0b4362b0 3268
c7927a3c
NC
3269 case EM_RX:
3270 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3271 strcat (buf, ", 64-bit doubles");
3272 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3273 strcat (buf, ", dsp");
d4cb0ea0 3274 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3275 strcat (buf, ", pid");
708e2187
NC
3276 if (e_flags & E_FLAG_RX_ABI)
3277 strcat (buf, ", RX ABI");
d4cb0ea0 3278 break;
55786da2
AK
3279
3280 case EM_S390:
3281 if (e_flags & EF_S390_HIGH_GPRS)
3282 strcat (buf, ", highgprs");
d4cb0ea0 3283 break;
40b36596
JM
3284
3285 case EM_TI_C6000:
3286 if ((e_flags & EF_C6000_REL))
3287 strcat (buf, ", relocatable module");
d4cb0ea0 3288 break;
13761a11
NC
3289
3290 case EM_MSP430:
3291 strcat (buf, _(": architecture variant: "));
3292 switch (e_flags & EF_MSP430_MACH)
3293 {
3294 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3295 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3296 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3297 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3298 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3299 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3300 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3301 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3302 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3303 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3304 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3305 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3306 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3307 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3308 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3309 default:
3310 strcat (buf, _(": unknown")); break;
3311 }
3312
3313 if (e_flags & ~ EF_MSP430_MACH)
3314 strcat (buf, _(": unknown extra flag bits also present"));
252b5132
RH
3315 }
3316 }
3317
3318 return buf;
3319}
3320
252b5132 3321static const char *
d3ba0551
AM
3322get_osabi_name (unsigned int osabi)
3323{
3324 static char buff[32];
3325
3326 switch (osabi)
3327 {
3328 case ELFOSABI_NONE: return "UNIX - System V";
3329 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3330 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3331 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3332 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3333 case ELFOSABI_AIX: return "UNIX - AIX";
3334 case ELFOSABI_IRIX: return "UNIX - IRIX";
3335 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3336 case ELFOSABI_TRU64: return "UNIX - TRU64";
3337 case ELFOSABI_MODESTO: return "Novell - Modesto";
3338 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3339 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3340 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3341 case ELFOSABI_AROS: return "AROS";
11636f9e 3342 case ELFOSABI_FENIXOS: return "FenixOS";
d3ba0551 3343 default:
40b36596
JM
3344 if (osabi >= 64)
3345 switch (elf_header.e_machine)
3346 {
3347 case EM_ARM:
3348 switch (osabi)
3349 {
3350 case ELFOSABI_ARM: return "ARM";
3351 default:
3352 break;
3353 }
3354 break;
3355
3356 case EM_MSP430:
3357 case EM_MSP430_OLD:
619ed720 3358 case EM_VISIUM:
40b36596
JM
3359 switch (osabi)
3360 {
3361 case ELFOSABI_STANDALONE: return _("Standalone App");
3362 default:
3363 break;
3364 }
3365 break;
3366
3367 case EM_TI_C6000:
3368 switch (osabi)
3369 {
3370 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3371 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3372 default:
3373 break;
3374 }
3375 break;
3376
3377 default:
3378 break;
3379 }
e9e44622 3380 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3381 return buff;
3382 }
3383}
3384
a06ea964
NC
3385static const char *
3386get_aarch64_segment_type (unsigned long type)
3387{
3388 switch (type)
3389 {
3390 case PT_AARCH64_ARCHEXT:
3391 return "AARCH64_ARCHEXT";
3392 default:
3393 break;
3394 }
3395
3396 return NULL;
3397}
3398
b294bdf8
MM
3399static const char *
3400get_arm_segment_type (unsigned long type)
3401{
3402 switch (type)
3403 {
3404 case PT_ARM_EXIDX:
3405 return "EXIDX";
3406 default:
3407 break;
3408 }
3409
3410 return NULL;
3411}
3412
d3ba0551
AM
3413static const char *
3414get_mips_segment_type (unsigned long type)
252b5132
RH
3415{
3416 switch (type)
3417 {
3418 case PT_MIPS_REGINFO:
3419 return "REGINFO";
3420 case PT_MIPS_RTPROC:
3421 return "RTPROC";
3422 case PT_MIPS_OPTIONS:
3423 return "OPTIONS";
351cdf24
MF
3424 case PT_MIPS_ABIFLAGS:
3425 return "ABIFLAGS";
252b5132
RH
3426 default:
3427 break;
3428 }
3429
3430 return NULL;
3431}
3432
103f02d3 3433static const char *
d3ba0551 3434get_parisc_segment_type (unsigned long type)
103f02d3
UD
3435{
3436 switch (type)
3437 {
3438 case PT_HP_TLS: return "HP_TLS";
3439 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3440 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3441 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3442 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3443 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3444 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3445 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3446 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3447 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3448 case PT_HP_PARALLEL: return "HP_PARALLEL";
3449 case PT_HP_FASTBIND: return "HP_FASTBIND";
eec8f817
DA
3450 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3451 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3452 case PT_HP_STACK: return "HP_STACK";
3453 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
103f02d3
UD
3454 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3455 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3456 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
103f02d3
UD
3457 default:
3458 break;
3459 }
3460
3461 return NULL;
3462}
3463
4d6ed7c8 3464static const char *
d3ba0551 3465get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3466{
3467 switch (type)
3468 {
3469 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3470 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
00428cca
AM
3471 case PT_HP_TLS: return "HP_TLS";
3472 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3473 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3474 case PT_IA_64_HP_STACK: return "HP_STACK";
4d6ed7c8
NC
3475 default:
3476 break;
3477 }
3478
3479 return NULL;
3480}
3481
40b36596
JM
3482static const char *
3483get_tic6x_segment_type (unsigned long type)
3484{
3485 switch (type)
3486 {
3487 case PT_C6000_PHATTR: return "C6000_PHATTR";
3488 default:
3489 break;
3490 }
3491
3492 return NULL;
3493}
3494
252b5132 3495static const char *
d3ba0551 3496get_segment_type (unsigned long p_type)
252b5132 3497{
b34976b6 3498 static char buff[32];
252b5132
RH
3499
3500 switch (p_type)
3501 {
b34976b6
AM
3502 case PT_NULL: return "NULL";
3503 case PT_LOAD: return "LOAD";
252b5132 3504 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
3505 case PT_INTERP: return "INTERP";
3506 case PT_NOTE: return "NOTE";
3507 case PT_SHLIB: return "SHLIB";
3508 case PT_PHDR: return "PHDR";
13ae64f3 3509 case PT_TLS: return "TLS";
252b5132 3510
65765700
JJ
3511 case PT_GNU_EH_FRAME:
3512 return "GNU_EH_FRAME";
2b05f1b7 3513 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 3514 case PT_GNU_RELRO: return "GNU_RELRO";
65765700 3515
252b5132
RH
3516 default:
3517 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
3518 {
2cf0635d 3519 const char * result;
103f02d3 3520
252b5132
RH
3521 switch (elf_header.e_machine)
3522 {
a06ea964
NC
3523 case EM_AARCH64:
3524 result = get_aarch64_segment_type (p_type);
3525 break;
b294bdf8
MM
3526 case EM_ARM:
3527 result = get_arm_segment_type (p_type);
3528 break;
252b5132 3529 case EM_MIPS:
4fe85591 3530 case EM_MIPS_RS3_LE:
252b5132
RH
3531 result = get_mips_segment_type (p_type);
3532 break;
103f02d3
UD
3533 case EM_PARISC:
3534 result = get_parisc_segment_type (p_type);
3535 break;
4d6ed7c8
NC
3536 case EM_IA_64:
3537 result = get_ia64_segment_type (p_type);
3538 break;
40b36596
JM
3539 case EM_TI_C6000:
3540 result = get_tic6x_segment_type (p_type);
3541 break;
252b5132
RH
3542 default:
3543 result = NULL;
3544 break;
3545 }
103f02d3 3546
252b5132
RH
3547 if (result != NULL)
3548 return result;
103f02d3 3549
252b5132
RH
3550 sprintf (buff, "LOPROC+%lx", p_type - PT_LOPROC);
3551 }
3552 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 3553 {
2cf0635d 3554 const char * result;
103f02d3
UD
3555
3556 switch (elf_header.e_machine)
3557 {
3558 case EM_PARISC:
3559 result = get_parisc_segment_type (p_type);
3560 break;
00428cca
AM
3561 case EM_IA_64:
3562 result = get_ia64_segment_type (p_type);
3563 break;
103f02d3
UD
3564 default:
3565 result = NULL;
3566 break;
3567 }
3568
3569 if (result != NULL)
3570 return result;
3571
3572 sprintf (buff, "LOOS+%lx", p_type - PT_LOOS);
3573 }
252b5132 3574 else
e9e44622 3575 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
3576
3577 return buff;
3578 }
3579}
3580
3581static const char *
d3ba0551 3582get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
3583{
3584 switch (sh_type)
3585 {
b34976b6
AM
3586 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
3587 case SHT_MIPS_MSYM: return "MIPS_MSYM";
3588 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
3589 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
3590 case SHT_MIPS_UCODE: return "MIPS_UCODE";
3591 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
3592 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
3593 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
3594 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
3595 case SHT_MIPS_RELD: return "MIPS_RELD";
3596 case SHT_MIPS_IFACE: return "MIPS_IFACE";
3597 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
3598 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
3599 case SHT_MIPS_SHDR: return "MIPS_SHDR";
3600 case SHT_MIPS_FDESC: return "MIPS_FDESC";
3601 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
3602 case SHT_MIPS_DENSE: return "MIPS_DENSE";
3603 case SHT_MIPS_PDESC: return "MIPS_PDESC";
3604 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
3605 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
3606 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
3607 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
3608 case SHT_MIPS_LINE: return "MIPS_LINE";
3609 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
3610 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
3611 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
3612 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
3613 case SHT_MIPS_DWARF: return "MIPS_DWARF";
3614 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
3615 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
3616 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
3617 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
3618 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
3619 case SHT_MIPS_XLATE: return "MIPS_XLATE";
3620 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
3621 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
3622 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
3623 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 3624 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 3625 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
252b5132
RH
3626 default:
3627 break;
3628 }
3629 return NULL;
3630}
3631
103f02d3 3632static const char *
d3ba0551 3633get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
3634{
3635 switch (sh_type)
3636 {
3637 case SHT_PARISC_EXT: return "PARISC_EXT";
3638 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
3639 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
3640 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
3641 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
3642 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 3643 case SHT_PARISC_DLKM: return "PARISC_DLKM";
103f02d3
UD
3644 default:
3645 break;
3646 }
3647 return NULL;
3648}
3649
4d6ed7c8 3650static const char *
d3ba0551 3651get_ia64_section_type_name (unsigned int sh_type)
4d6ed7c8 3652{
18bd398b 3653 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48
NC
3654 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
3655 return get_osabi_name ((sh_type & 0x00FF0000) >> 16);
0de14b54 3656
4d6ed7c8
NC
3657 switch (sh_type)
3658 {
148b93f2
NC
3659 case SHT_IA_64_EXT: return "IA_64_EXT";
3660 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
3661 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
3662 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
3663 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
3664 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
3665 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
3666 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
3667 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
3668 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
3669 default:
3670 break;
3671 }
3672 return NULL;
3673}
3674
d2b2c203
DJ
3675static const char *
3676get_x86_64_section_type_name (unsigned int sh_type)
3677{
3678 switch (sh_type)
3679 {
3680 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
3681 default:
3682 break;
3683 }
3684 return NULL;
3685}
3686
a06ea964
NC
3687static const char *
3688get_aarch64_section_type_name (unsigned int sh_type)
3689{
3690 switch (sh_type)
3691 {
3692 case SHT_AARCH64_ATTRIBUTES:
3693 return "AARCH64_ATTRIBUTES";
3694 default:
3695 break;
3696 }
3697 return NULL;
3698}
3699
40a18ebd
NC
3700static const char *
3701get_arm_section_type_name (unsigned int sh_type)
3702{
3703 switch (sh_type)
3704 {
7f6fed87
NC
3705 case SHT_ARM_EXIDX: return "ARM_EXIDX";
3706 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
3707 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
3708 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
3709 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
40a18ebd
NC
3710 default:
3711 break;
3712 }
3713 return NULL;
3714}
3715
40b36596
JM
3716static const char *
3717get_tic6x_section_type_name (unsigned int sh_type)
3718{
3719 switch (sh_type)
3720 {
3721 case SHT_C6000_UNWIND:
3722 return "C6000_UNWIND";
3723 case SHT_C6000_PREEMPTMAP:
3724 return "C6000_PREEMPTMAP";
3725 case SHT_C6000_ATTRIBUTES:
3726 return "C6000_ATTRIBUTES";
3727 case SHT_TI_ICODE:
3728 return "TI_ICODE";
3729 case SHT_TI_XREF:
3730 return "TI_XREF";
3731 case SHT_TI_HANDLER:
3732 return "TI_HANDLER";
3733 case SHT_TI_INITINFO:
3734 return "TI_INITINFO";
3735 case SHT_TI_PHATTRS:
3736 return "TI_PHATTRS";
3737 default:
3738 break;
3739 }
3740 return NULL;
3741}
3742
13761a11
NC
3743static const char *
3744get_msp430x_section_type_name (unsigned int sh_type)
3745{
3746 switch (sh_type)
3747 {
3748 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
3749 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
3750 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
3751 default: return NULL;
3752 }
3753}
3754
252b5132 3755static const char *
d3ba0551 3756get_section_type_name (unsigned int sh_type)
252b5132 3757{
b34976b6 3758 static char buff[32];
252b5132
RH
3759
3760 switch (sh_type)
3761 {
3762 case SHT_NULL: return "NULL";
3763 case SHT_PROGBITS: return "PROGBITS";
3764 case SHT_SYMTAB: return "SYMTAB";
3765 case SHT_STRTAB: return "STRTAB";
3766 case SHT_RELA: return "RELA";
3767 case SHT_HASH: return "HASH";
3768 case SHT_DYNAMIC: return "DYNAMIC";
3769 case SHT_NOTE: return "NOTE";
3770 case SHT_NOBITS: return "NOBITS";
3771 case SHT_REL: return "REL";
3772 case SHT_SHLIB: return "SHLIB";
3773 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
3774 case SHT_INIT_ARRAY: return "INIT_ARRAY";
3775 case SHT_FINI_ARRAY: return "FINI_ARRAY";
3776 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 3777 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586
NC
3778 case SHT_GROUP: return "GROUP";
3779 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICIES";
252b5132
RH
3780 case SHT_GNU_verdef: return "VERDEF";
3781 case SHT_GNU_verneed: return "VERNEED";
3782 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
3783 case 0x6ffffff0: return "VERSYM";
3784 case 0x6ffffffc: return "VERDEF";
252b5132
RH
3785 case 0x7ffffffd: return "AUXILIARY";
3786 case 0x7fffffff: return "FILTER";
047b2264 3787 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
3788
3789 default:
3790 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
3791 {
2cf0635d 3792 const char * result;
252b5132
RH
3793
3794 switch (elf_header.e_machine)
3795 {
3796 case EM_MIPS:
4fe85591 3797 case EM_MIPS_RS3_LE:
252b5132
RH
3798 result = get_mips_section_type_name (sh_type);
3799 break;
103f02d3
UD
3800 case EM_PARISC:
3801 result = get_parisc_section_type_name (sh_type);
3802 break;
4d6ed7c8
NC
3803 case EM_IA_64:
3804 result = get_ia64_section_type_name (sh_type);
3805 break;
d2b2c203 3806 case EM_X86_64:
8a9036a4 3807 case EM_L1OM:
7a9068fe 3808 case EM_K1OM:
d2b2c203
DJ
3809 result = get_x86_64_section_type_name (sh_type);
3810 break;
a06ea964
NC
3811 case EM_AARCH64:
3812 result = get_aarch64_section_type_name (sh_type);
3813 break;
40a18ebd
NC
3814 case EM_ARM:
3815 result = get_arm_section_type_name (sh_type);
3816 break;
40b36596
JM
3817 case EM_TI_C6000:
3818 result = get_tic6x_section_type_name (sh_type);
3819 break;
13761a11
NC
3820 case EM_MSP430:
3821 result = get_msp430x_section_type_name (sh_type);
3822 break;
252b5132
RH
3823 default:
3824 result = NULL;
3825 break;
3826 }
3827
3828 if (result != NULL)
3829 return result;
3830
c91d0dfb 3831 sprintf (buff, "LOPROC+%x", sh_type - SHT_LOPROC);
252b5132
RH
3832 }
3833 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 3834 {
2cf0635d 3835 const char * result;
148b93f2
NC
3836
3837 switch (elf_header.e_machine)
3838 {
3839 case EM_IA_64:
3840 result = get_ia64_section_type_name (sh_type);
3841 break;
3842 default:
3843 result = NULL;
3844 break;
3845 }
3846
3847 if (result != NULL)
3848 return result;
3849
3850 sprintf (buff, "LOOS+%x", sh_type - SHT_LOOS);
3851 }
252b5132 3852 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
c91d0dfb 3853 sprintf (buff, "LOUSER+%x", sh_type - SHT_LOUSER);
252b5132 3854 else
a7dbfd1c
NC
3855 /* This message is probably going to be displayed in a 15
3856 character wide field, so put the hex value first. */
3857 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 3858
252b5132
RH
3859 return buff;
3860 }
3861}
3862
2979dc34 3863#define OPTION_DEBUG_DUMP 512
2c610e4b 3864#define OPTION_DYN_SYMS 513
fd2f0033
TT
3865#define OPTION_DWARF_DEPTH 514
3866#define OPTION_DWARF_START 515
4723351a 3867#define OPTION_DWARF_CHECK 516
2979dc34 3868
85b1c36d 3869static struct option options[] =
252b5132 3870{
b34976b6 3871 {"all", no_argument, 0, 'a'},
252b5132
RH
3872 {"file-header", no_argument, 0, 'h'},
3873 {"program-headers", no_argument, 0, 'l'},
b34976b6
AM
3874 {"headers", no_argument, 0, 'e'},
3875 {"histogram", no_argument, 0, 'I'},
3876 {"segments", no_argument, 0, 'l'},
3877 {"sections", no_argument, 0, 'S'},
252b5132 3878 {"section-headers", no_argument, 0, 'S'},
f5842774 3879 {"section-groups", no_argument, 0, 'g'},
5477e8a0 3880 {"section-details", no_argument, 0, 't'},
595cf52e 3881 {"full-section-name",no_argument, 0, 'N'},
b34976b6
AM
3882 {"symbols", no_argument, 0, 's'},
3883 {"syms", no_argument, 0, 's'},
2c610e4b 3884 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
b34976b6
AM
3885 {"relocs", no_argument, 0, 'r'},
3886 {"notes", no_argument, 0, 'n'},
3887 {"dynamic", no_argument, 0, 'd'},
a952a375 3888 {"arch-specific", no_argument, 0, 'A'},
252b5132
RH
3889 {"version-info", no_argument, 0, 'V'},
3890 {"use-dynamic", no_argument, 0, 'D'},
09c11c86 3891 {"unwind", no_argument, 0, 'u'},
4145f1d5 3892 {"archive-index", no_argument, 0, 'c'},
b34976b6 3893 {"hex-dump", required_argument, 0, 'x'},
cf13d699 3894 {"relocated-dump", required_argument, 0, 'R'},
09c11c86 3895 {"string-dump", required_argument, 0, 'p'},
252b5132
RH
3896#ifdef SUPPORT_DISASSEMBLY
3897 {"instruction-dump", required_argument, 0, 'i'},
3898#endif
cf13d699 3899 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
252b5132 3900
fd2f0033
TT
3901 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
3902 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 3903 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
fd2f0033 3904
b34976b6
AM
3905 {"version", no_argument, 0, 'v'},
3906 {"wide", no_argument, 0, 'W'},
3907 {"help", no_argument, 0, 'H'},
3908 {0, no_argument, 0, 0}
252b5132
RH
3909};
3910
3911static void
2cf0635d 3912usage (FILE * stream)
252b5132 3913{
92f01d61
JM
3914 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
3915 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
3916 fprintf (stream, _(" Options are:\n\
8b53311e
NC
3917 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
3918 -h --file-header Display the ELF file header\n\
3919 -l --program-headers Display the program headers\n\
3920 --segments An alias for --program-headers\n\
3921 -S --section-headers Display the sections' header\n\
3922 --sections An alias for --section-headers\n\
f5842774 3923 -g --section-groups Display the section groups\n\
5477e8a0 3924 -t --section-details Display the section details\n\
8b53311e
NC
3925 -e --headers Equivalent to: -h -l -S\n\
3926 -s --syms Display the symbol table\n\
3f08eb35 3927 --symbols An alias for --syms\n\
2c610e4b 3928 --dyn-syms Display the dynamic symbol table\n\
8b53311e
NC
3929 -n --notes Display the core notes (if present)\n\
3930 -r --relocs Display the relocations (if present)\n\
3931 -u --unwind Display the unwind info (if present)\n\
b2d38a17 3932 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 3933 -V --version-info Display the version sections (if present)\n\
1b31d05e 3934 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 3935 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 3936 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
09c11c86
NC
3937 -x --hex-dump=<number|name>\n\
3938 Dump the contents of section <number|name> as bytes\n\
3939 -p --string-dump=<number|name>\n\
3940 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
3941 -R --relocated-dump=<number|name>\n\
3942 Dump the contents of section <number|name> as relocated bytes\n\
f9f0e732 3943 -w[lLiaprmfFsoRt] or\n\
1ed06042 3944 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
6f875884 3945 =frames-interp,=str,=loc,=Ranges,=pubtypes,\n\
657d0d47
CC
3946 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
3947 =addr,=cu_index]\n\
8b53311e 3948 Display the contents of DWARF2 debug sections\n"));
fd2f0033
TT
3949 fprintf (stream, _("\
3950 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
3951 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
3952 or deeper\n"));
252b5132 3953#ifdef SUPPORT_DISASSEMBLY
92f01d61 3954 fprintf (stream, _("\
09c11c86
NC
3955 -i --instruction-dump=<number|name>\n\
3956 Disassemble the contents of section <number|name>\n"));
252b5132 3957#endif
92f01d61 3958 fprintf (stream, _("\
8b53311e
NC
3959 -I --histogram Display histogram of bucket list lengths\n\
3960 -W --wide Allow output width to exceed 80 characters\n\
07012eee 3961 @<file> Read options from <file>\n\
8b53311e
NC
3962 -H --help Display this information\n\
3963 -v --version Display the version number of readelf\n"));
1118d252 3964
92f01d61
JM
3965 if (REPORT_BUGS_TO[0] && stream == stdout)
3966 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 3967
92f01d61 3968 exit (stream == stdout ? 0 : 1);
252b5132
RH
3969}
3970
18bd398b
NC
3971/* Record the fact that the user wants the contents of section number
3972 SECTION to be displayed using the method(s) encoded as flags bits
3973 in TYPE. Note, TYPE can be zero if we are creating the array for
3974 the first time. */
3975
252b5132 3976static void
09c11c86 3977request_dump_bynumber (unsigned int section, dump_type type)
252b5132
RH
3978{
3979 if (section >= num_dump_sects)
3980 {
2cf0635d 3981 dump_type * new_dump_sects;
252b5132 3982
3f5e193b
NC
3983 new_dump_sects = (dump_type *) calloc (section + 1,
3984 sizeof (* dump_sects));
252b5132
RH
3985
3986 if (new_dump_sects == NULL)
591a748a 3987 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
3988 else
3989 {
3990 /* Copy current flag settings. */
09c11c86 3991 memcpy (new_dump_sects, dump_sects, num_dump_sects * sizeof (* dump_sects));
252b5132
RH
3992
3993 free (dump_sects);
3994
3995 dump_sects = new_dump_sects;
3996 num_dump_sects = section + 1;
3997 }
3998 }
3999
4000 if (dump_sects)
b34976b6 4001 dump_sects[section] |= type;
252b5132
RH
4002
4003 return;
4004}
4005
aef1f6d0
DJ
4006/* Request a dump by section name. */
4007
4008static void
2cf0635d 4009request_dump_byname (const char * section, dump_type type)
aef1f6d0 4010{
2cf0635d 4011 struct dump_list_entry * new_request;
aef1f6d0 4012
3f5e193b
NC
4013 new_request = (struct dump_list_entry *)
4014 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4015 if (!new_request)
591a748a 4016 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4017
4018 new_request->name = strdup (section);
4019 if (!new_request->name)
591a748a 4020 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4021
4022 new_request->type = type;
4023
4024 new_request->next = dump_sects_byname;
4025 dump_sects_byname = new_request;
4026}
4027
cf13d699
NC
4028static inline void
4029request_dump (dump_type type)
4030{
4031 int section;
4032 char * cp;
4033
4034 do_dump++;
4035 section = strtoul (optarg, & cp, 0);
4036
4037 if (! *cp && section >= 0)
4038 request_dump_bynumber (section, type);
4039 else
4040 request_dump_byname (optarg, type);
4041}
4042
4043
252b5132 4044static void
2cf0635d 4045parse_args (int argc, char ** argv)
252b5132
RH
4046{
4047 int c;
4048
4049 if (argc < 2)
92f01d61 4050 usage (stderr);
252b5132
RH
4051
4052 while ((c = getopt_long
cf13d699 4053 (argc, argv, "ADHINR:SVWacdeghi:lnp:rstuvw::x:", options, NULL)) != EOF)
252b5132 4054 {
252b5132
RH
4055 switch (c)
4056 {
4057 case 0:
4058 /* Long options. */
4059 break;
4060 case 'H':
92f01d61 4061 usage (stdout);
252b5132
RH
4062 break;
4063
4064 case 'a':
b34976b6
AM
4065 do_syms++;
4066 do_reloc++;
4067 do_unwind++;
4068 do_dynamic++;
4069 do_header++;
4070 do_sections++;
f5842774 4071 do_section_groups++;
b34976b6
AM
4072 do_segments++;
4073 do_version++;
4074 do_histogram++;
4075 do_arch++;
4076 do_notes++;
252b5132 4077 break;
f5842774
L
4078 case 'g':
4079 do_section_groups++;
4080 break;
5477e8a0 4081 case 't':
595cf52e 4082 case 'N':
5477e8a0
L
4083 do_sections++;
4084 do_section_details++;
595cf52e 4085 break;
252b5132 4086 case 'e':
b34976b6
AM
4087 do_header++;
4088 do_sections++;
4089 do_segments++;
252b5132 4090 break;
a952a375 4091 case 'A':
b34976b6 4092 do_arch++;
a952a375 4093 break;
252b5132 4094 case 'D':
b34976b6 4095 do_using_dynamic++;
252b5132
RH
4096 break;
4097 case 'r':
b34976b6 4098 do_reloc++;
252b5132 4099 break;
4d6ed7c8 4100 case 'u':
b34976b6 4101 do_unwind++;
4d6ed7c8 4102 break;
252b5132 4103 case 'h':
b34976b6 4104 do_header++;
252b5132
RH
4105 break;
4106 case 'l':
b34976b6 4107 do_segments++;
252b5132
RH
4108 break;
4109 case 's':
b34976b6 4110 do_syms++;
252b5132
RH
4111 break;
4112 case 'S':
b34976b6 4113 do_sections++;
252b5132
RH
4114 break;
4115 case 'd':
b34976b6 4116 do_dynamic++;
252b5132 4117 break;
a952a375 4118 case 'I':
b34976b6 4119 do_histogram++;
a952a375 4120 break;
779fe533 4121 case 'n':
b34976b6 4122 do_notes++;
779fe533 4123 break;
4145f1d5
NC
4124 case 'c':
4125 do_archive_index++;
4126 break;
252b5132 4127 case 'x':
cf13d699 4128 request_dump (HEX_DUMP);
aef1f6d0 4129 break;
09c11c86 4130 case 'p':
cf13d699
NC
4131 request_dump (STRING_DUMP);
4132 break;
4133 case 'R':
4134 request_dump (RELOC_DUMP);
09c11c86 4135 break;
252b5132 4136 case 'w':
b34976b6 4137 do_dump++;
252b5132 4138 if (optarg == 0)
613ff48b
CC
4139 {
4140 do_debugging = 1;
4141 dwarf_select_sections_all ();
4142 }
252b5132
RH
4143 else
4144 {
4145 do_debugging = 0;
4cb93e3b 4146 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4147 }
4148 break;
2979dc34 4149 case OPTION_DEBUG_DUMP:
b34976b6 4150 do_dump++;
2979dc34
JJ
4151 if (optarg == 0)
4152 do_debugging = 1;
4153 else
4154 {
2979dc34 4155 do_debugging = 0;
4cb93e3b 4156 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4157 }
4158 break;
fd2f0033
TT
4159 case OPTION_DWARF_DEPTH:
4160 {
4161 char *cp;
4162
4163 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4164 }
4165 break;
4166 case OPTION_DWARF_START:
4167 {
4168 char *cp;
4169
4170 dwarf_start_die = strtoul (optarg, & cp, 0);
4171 }
4172 break;
4723351a
CC
4173 case OPTION_DWARF_CHECK:
4174 dwarf_check = 1;
4175 break;
2c610e4b
L
4176 case OPTION_DYN_SYMS:
4177 do_dyn_syms++;
4178 break;
252b5132
RH
4179#ifdef SUPPORT_DISASSEMBLY
4180 case 'i':
cf13d699
NC
4181 request_dump (DISASS_DUMP);
4182 break;
252b5132
RH
4183#endif
4184 case 'v':
4185 print_version (program_name);
4186 break;
4187 case 'V':
b34976b6 4188 do_version++;
252b5132 4189 break;
d974e256 4190 case 'W':
b34976b6 4191 do_wide++;
d974e256 4192 break;
252b5132 4193 default:
252b5132
RH
4194 /* xgettext:c-format */
4195 error (_("Invalid option '-%c'\n"), c);
4196 /* Drop through. */
4197 case '?':
92f01d61 4198 usage (stderr);
252b5132
RH
4199 }
4200 }
4201
4d6ed7c8 4202 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4203 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4204 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4205 && !do_section_groups && !do_archive_index
4206 && !do_dyn_syms)
92f01d61 4207 usage (stderr);
252b5132
RH
4208 else if (argc < 3)
4209 {
4210 warn (_("Nothing to do.\n"));
92f01d61 4211 usage (stderr);
252b5132
RH
4212 }
4213}
4214
4215static const char *
d3ba0551 4216get_elf_class (unsigned int elf_class)
252b5132 4217{
b34976b6 4218 static char buff[32];
103f02d3 4219
252b5132
RH
4220 switch (elf_class)
4221 {
4222 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4223 case ELFCLASS32: return "ELF32";
4224 case ELFCLASS64: return "ELF64";
ab5e7794 4225 default:
e9e44622 4226 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4227 return buff;
252b5132
RH
4228 }
4229}
4230
4231static const char *
d3ba0551 4232get_data_encoding (unsigned int encoding)
252b5132 4233{
b34976b6 4234 static char buff[32];
103f02d3 4235
252b5132
RH
4236 switch (encoding)
4237 {
4238 case ELFDATANONE: return _("none");
33c63f9d
CM
4239 case ELFDATA2LSB: return _("2's complement, little endian");
4240 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4241 default:
e9e44622 4242 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4243 return buff;
252b5132
RH
4244 }
4245}
4246
252b5132 4247/* Decode the data held in 'elf_header'. */
ee42cf8c 4248
252b5132 4249static int
d3ba0551 4250process_file_header (void)
252b5132 4251{
b34976b6
AM
4252 if ( elf_header.e_ident[EI_MAG0] != ELFMAG0
4253 || elf_header.e_ident[EI_MAG1] != ELFMAG1
4254 || elf_header.e_ident[EI_MAG2] != ELFMAG2
4255 || elf_header.e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4256 {
4257 error
4258 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
4259 return 0;
4260 }
4261
2dc4cec1
L
4262 init_dwarf_regnames (elf_header.e_machine);
4263
252b5132
RH
4264 if (do_header)
4265 {
4266 int i;
4267
4268 printf (_("ELF Header:\n"));
4269 printf (_(" Magic: "));
b34976b6
AM
4270 for (i = 0; i < EI_NIDENT; i++)
4271 printf ("%2.2x ", elf_header.e_ident[i]);
252b5132
RH
4272 printf ("\n");
4273 printf (_(" Class: %s\n"),
b34976b6 4274 get_elf_class (elf_header.e_ident[EI_CLASS]));
252b5132 4275 printf (_(" Data: %s\n"),
b34976b6 4276 get_data_encoding (elf_header.e_ident[EI_DATA]));
252b5132 4277 printf (_(" Version: %d %s\n"),
b34976b6
AM
4278 elf_header.e_ident[EI_VERSION],
4279 (elf_header.e_ident[EI_VERSION] == EV_CURRENT
789be9f7 4280 ? "(current)"
b34976b6 4281 : (elf_header.e_ident[EI_VERSION] != EV_NONE
2b692964 4282 ? _("<unknown: %lx>")
789be9f7 4283 : "")));
252b5132 4284 printf (_(" OS/ABI: %s\n"),
b34976b6 4285 get_osabi_name (elf_header.e_ident[EI_OSABI]));
252b5132 4286 printf (_(" ABI Version: %d\n"),
b34976b6 4287 elf_header.e_ident[EI_ABIVERSION]);
252b5132
RH
4288 printf (_(" Type: %s\n"),
4289 get_file_type (elf_header.e_type));
4290 printf (_(" Machine: %s\n"),
4291 get_machine_name (elf_header.e_machine));
4292 printf (_(" Version: 0x%lx\n"),
4293 (unsigned long) elf_header.e_version);
76da6bbe 4294
f7a99963
NC
4295 printf (_(" Entry point address: "));
4296 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4297 printf (_("\n Start of program headers: "));
4298 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4299 printf (_(" (bytes into file)\n Start of section headers: "));
4300 print_vma ((bfd_vma) elf_header.e_shoff, DEC);
4301 printf (_(" (bytes into file)\n"));
76da6bbe 4302
252b5132
RH
4303 printf (_(" Flags: 0x%lx%s\n"),
4304 (unsigned long) elf_header.e_flags,
4305 get_machine_flags (elf_header.e_flags, elf_header.e_machine));
4306 printf (_(" Size of this header: %ld (bytes)\n"),
4307 (long) elf_header.e_ehsize);
4308 printf (_(" Size of program headers: %ld (bytes)\n"),
4309 (long) elf_header.e_phentsize);
2046a35d 4310 printf (_(" Number of program headers: %ld"),
252b5132 4311 (long) elf_header.e_phnum);
2046a35d
AM
4312 if (section_headers != NULL
4313 && elf_header.e_phnum == PN_XNUM
4314 && section_headers[0].sh_info != 0)
cc5914eb 4315 printf (" (%ld)", (long) section_headers[0].sh_info);
2046a35d 4316 putc ('\n', stdout);
252b5132
RH
4317 printf (_(" Size of section headers: %ld (bytes)\n"),
4318 (long) elf_header.e_shentsize);
560f3c1c 4319 printf (_(" Number of section headers: %ld"),
252b5132 4320 (long) elf_header.e_shnum);
4fbb74a6 4321 if (section_headers != NULL && elf_header.e_shnum == SHN_UNDEF)
560f3c1c
AM
4322 printf (" (%ld)", (long) section_headers[0].sh_size);
4323 putc ('\n', stdout);
4324 printf (_(" Section header string table index: %ld"),
252b5132 4325 (long) elf_header.e_shstrndx);
4fbb74a6
AM
4326 if (section_headers != NULL
4327 && elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
72de5009 4328 printf (" (%u)", section_headers[0].sh_link);
15ba6505
AM
4329 else if (elf_header.e_shstrndx != SHN_UNDEF
4330 && elf_header.e_shstrndx >= elf_header.e_shnum)
2b692964 4331 printf (_(" <corrupt: out of range>"));
560f3c1c
AM
4332 putc ('\n', stdout);
4333 }
4334
4335 if (section_headers != NULL)
4336 {
2046a35d
AM
4337 if (elf_header.e_phnum == PN_XNUM
4338 && section_headers[0].sh_info != 0)
4339 elf_header.e_phnum = section_headers[0].sh_info;
4fbb74a6 4340 if (elf_header.e_shnum == SHN_UNDEF)
560f3c1c 4341 elf_header.e_shnum = section_headers[0].sh_size;
4fbb74a6 4342 if (elf_header.e_shstrndx == (SHN_XINDEX & 0xffff))
560f3c1c 4343 elf_header.e_shstrndx = section_headers[0].sh_link;
4fbb74a6 4344 else if (elf_header.e_shstrndx >= elf_header.e_shnum)
0b49d371 4345 elf_header.e_shstrndx = SHN_UNDEF;
560f3c1c
AM
4346 free (section_headers);
4347 section_headers = NULL;
252b5132 4348 }
103f02d3 4349
9ea033b2
NC
4350 return 1;
4351}
4352
e0a31db1 4353static bfd_boolean
91d6fa6a 4354get_32bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4355{
2cf0635d
NC
4356 Elf32_External_Phdr * phdrs;
4357 Elf32_External_Phdr * external;
4358 Elf_Internal_Phdr * internal;
b34976b6 4359 unsigned int i;
e0a31db1
NC
4360 unsigned int size = elf_header.e_phentsize;
4361 unsigned int num = elf_header.e_phnum;
4362
4363 /* PR binutils/17531: Cope with unexpected section header sizes. */
4364 if (size == 0 || num == 0)
4365 return FALSE;
4366 if (size < sizeof * phdrs)
4367 {
4368 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4369 return FALSE;
4370 }
4371 if (size > sizeof * phdrs)
4372 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4373
3f5e193b 4374 phdrs = (Elf32_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1
NC
4375 size, num, _("program headers"));
4376 if (phdrs == NULL)
4377 return FALSE;
9ea033b2 4378
91d6fa6a 4379 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4380 i < elf_header.e_phnum;
b34976b6 4381 i++, internal++, external++)
252b5132 4382 {
9ea033b2
NC
4383 internal->p_type = BYTE_GET (external->p_type);
4384 internal->p_offset = BYTE_GET (external->p_offset);
4385 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4386 internal->p_paddr = BYTE_GET (external->p_paddr);
4387 internal->p_filesz = BYTE_GET (external->p_filesz);
4388 internal->p_memsz = BYTE_GET (external->p_memsz);
4389 internal->p_flags = BYTE_GET (external->p_flags);
4390 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
4391 }
4392
9ea033b2 4393 free (phdrs);
e0a31db1 4394 return TRUE;
252b5132
RH
4395}
4396
e0a31db1 4397static bfd_boolean
91d6fa6a 4398get_64bit_program_headers (FILE * file, Elf_Internal_Phdr * pheaders)
9ea033b2 4399{
2cf0635d
NC
4400 Elf64_External_Phdr * phdrs;
4401 Elf64_External_Phdr * external;
4402 Elf_Internal_Phdr * internal;
b34976b6 4403 unsigned int i;
e0a31db1
NC
4404 unsigned int size = elf_header.e_phentsize;
4405 unsigned int num = elf_header.e_phnum;
4406
4407 /* PR binutils/17531: Cope with unexpected section header sizes. */
4408 if (size == 0 || num == 0)
4409 return FALSE;
4410 if (size < sizeof * phdrs)
4411 {
4412 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
4413 return FALSE;
4414 }
4415 if (size > sizeof * phdrs)
4416 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 4417
3f5e193b 4418 phdrs = (Elf64_External_Phdr *) get_data (NULL, file, elf_header.e_phoff,
e0a31db1 4419 size, num, _("program headers"));
a6e9f9df 4420 if (!phdrs)
e0a31db1 4421 return FALSE;
9ea033b2 4422
91d6fa6a 4423 for (i = 0, internal = pheaders, external = phdrs;
9ea033b2 4424 i < elf_header.e_phnum;
b34976b6 4425 i++, internal++, external++)
9ea033b2
NC
4426 {
4427 internal->p_type = BYTE_GET (external->p_type);
4428 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
4429 internal->p_offset = BYTE_GET (external->p_offset);
4430 internal->p_vaddr = BYTE_GET (external->p_vaddr);
4431 internal->p_paddr = BYTE_GET (external->p_paddr);
4432 internal->p_filesz = BYTE_GET (external->p_filesz);
4433 internal->p_memsz = BYTE_GET (external->p_memsz);
4434 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
4435 }
4436
4437 free (phdrs);
e0a31db1 4438 return TRUE;
9ea033b2 4439}
252b5132 4440
d93f0186
NC
4441/* Returns 1 if the program headers were read into `program_headers'. */
4442
4443static int
2cf0635d 4444get_program_headers (FILE * file)
d93f0186 4445{
2cf0635d 4446 Elf_Internal_Phdr * phdrs;
d93f0186
NC
4447
4448 /* Check cache of prior read. */
4449 if (program_headers != NULL)
4450 return 1;
4451
3f5e193b
NC
4452 phdrs = (Elf_Internal_Phdr *) cmalloc (elf_header.e_phnum,
4453 sizeof (Elf_Internal_Phdr));
d93f0186
NC
4454
4455 if (phdrs == NULL)
4456 {
8b73c356
NC
4457 error (_("Out of memory reading %u program headers\n"),
4458 elf_header.e_phnum);
d93f0186
NC
4459 return 0;
4460 }
4461
4462 if (is_32bit_elf
4463 ? get_32bit_program_headers (file, phdrs)
4464 : get_64bit_program_headers (file, phdrs))
4465 {
4466 program_headers = phdrs;
4467 return 1;
4468 }
4469
4470 free (phdrs);
4471 return 0;
4472}
4473
2f62977e
NC
4474/* Returns 1 if the program headers were loaded. */
4475
252b5132 4476static int
2cf0635d 4477process_program_headers (FILE * file)
252b5132 4478{
2cf0635d 4479 Elf_Internal_Phdr * segment;
b34976b6 4480 unsigned int i;
252b5132
RH
4481
4482 if (elf_header.e_phnum == 0)
4483 {
82f2dbf7
NC
4484 /* PR binutils/12467. */
4485 if (elf_header.e_phoff != 0)
4486 warn (_("possibly corrupt ELF header - it has a non-zero program"
4487 " header offset, but no program headers"));
4488 else if (do_segments)
252b5132 4489 printf (_("\nThere are no program headers in this file.\n"));
2f62977e 4490 return 0;
252b5132
RH
4491 }
4492
4493 if (do_segments && !do_header)
4494 {
f7a99963
NC
4495 printf (_("\nElf file type is %s\n"), get_file_type (elf_header.e_type));
4496 printf (_("Entry point "));
4497 print_vma ((bfd_vma) elf_header.e_entry, PREFIX_HEX);
4498 printf (_("\nThere are %d program headers, starting at offset "),
4499 elf_header.e_phnum);
4500 print_vma ((bfd_vma) elf_header.e_phoff, DEC);
4501 printf ("\n");
252b5132
RH
4502 }
4503
d93f0186 4504 if (! get_program_headers (file))
252b5132 4505 return 0;
103f02d3 4506
252b5132
RH
4507 if (do_segments)
4508 {
3a1a2036
NC
4509 if (elf_header.e_phnum > 1)
4510 printf (_("\nProgram Headers:\n"));
4511 else
4512 printf (_("\nProgram Headers:\n"));
76da6bbe 4513
f7a99963
NC
4514 if (is_32bit_elf)
4515 printf
4516 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
4517 else if (do_wide)
4518 printf
4519 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
4520 else
4521 {
4522 printf
4523 (_(" Type Offset VirtAddr PhysAddr\n"));
4524 printf
4525 (_(" FileSiz MemSiz Flags Align\n"));
4526 }
252b5132
RH
4527 }
4528
252b5132 4529 dynamic_addr = 0;
1b228002 4530 dynamic_size = 0;
252b5132
RH
4531
4532 for (i = 0, segment = program_headers;
4533 i < elf_header.e_phnum;
b34976b6 4534 i++, segment++)
252b5132
RH
4535 {
4536 if (do_segments)
4537 {
103f02d3 4538 printf (" %-14.14s ", get_segment_type (segment->p_type));
f7a99963
NC
4539
4540 if (is_32bit_elf)
4541 {
4542 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4543 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
4544 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
4545 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
4546 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
4547 printf ("%c%c%c ",
4548 (segment->p_flags & PF_R ? 'R' : ' '),
4549 (segment->p_flags & PF_W ? 'W' : ' '),
4550 (segment->p_flags & PF_X ? 'E' : ' '));
4551 printf ("%#lx", (unsigned long) segment->p_align);
4552 }
d974e256
JJ
4553 else if (do_wide)
4554 {
4555 if ((unsigned long) segment->p_offset == segment->p_offset)
4556 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
4557 else
4558 {
4559 print_vma (segment->p_offset, FULL_HEX);
4560 putchar (' ');
4561 }
4562
4563 print_vma (segment->p_vaddr, FULL_HEX);
4564 putchar (' ');
4565 print_vma (segment->p_paddr, FULL_HEX);
4566 putchar (' ');
4567
4568 if ((unsigned long) segment->p_filesz == segment->p_filesz)
4569 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
4570 else
4571 {
4572 print_vma (segment->p_filesz, FULL_HEX);
4573 putchar (' ');
4574 }
4575
4576 if ((unsigned long) segment->p_memsz == segment->p_memsz)
4577 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
4578 else
4579 {
f48e6c45 4580 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
4581 }
4582
4583 printf (" %c%c%c ",
4584 (segment->p_flags & PF_R ? 'R' : ' '),
4585 (segment->p_flags & PF_W ? 'W' : ' '),
4586 (segment->p_flags & PF_X ? 'E' : ' '));
4587
4588 if ((unsigned long) segment->p_align == segment->p_align)
4589 printf ("%#lx", (unsigned long) segment->p_align);
4590 else
4591 {
4592 print_vma (segment->p_align, PREFIX_HEX);
4593 }
4594 }
f7a99963
NC
4595 else
4596 {
4597 print_vma (segment->p_offset, FULL_HEX);
4598 putchar (' ');
4599 print_vma (segment->p_vaddr, FULL_HEX);
4600 putchar (' ');
4601 print_vma (segment->p_paddr, FULL_HEX);
4602 printf ("\n ");
4603 print_vma (segment->p_filesz, FULL_HEX);
4604 putchar (' ');
4605 print_vma (segment->p_memsz, FULL_HEX);
4606 printf (" %c%c%c ",
4607 (segment->p_flags & PF_R ? 'R' : ' '),
4608 (segment->p_flags & PF_W ? 'W' : ' '),
4609 (segment->p_flags & PF_X ? 'E' : ' '));
4610 print_vma (segment->p_align, HEX);
4611 }
252b5132
RH
4612 }
4613
f54498b4
NC
4614 if (do_segments)
4615 putc ('\n', stdout);
4616
252b5132
RH
4617 switch (segment->p_type)
4618 {
252b5132
RH
4619 case PT_DYNAMIC:
4620 if (dynamic_addr)
4621 error (_("more than one dynamic segment\n"));
4622
20737c13
AM
4623 /* By default, assume that the .dynamic section is the first
4624 section in the DYNAMIC segment. */
4625 dynamic_addr = segment->p_offset;
4626 dynamic_size = segment->p_filesz;
f54498b4
NC
4627 /* PR binutils/17512: Avoid corrupt dynamic section info in the segment. */
4628 if (dynamic_addr + dynamic_size >= current_file_size)
4629 {
4630 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
4631 dynamic_addr = dynamic_size = 0;
4632 }
20737c13 4633
b2d38a17
NC
4634 /* Try to locate the .dynamic section. If there is
4635 a section header table, we can easily locate it. */
4636 if (section_headers != NULL)
4637 {
2cf0635d 4638 Elf_Internal_Shdr * sec;
b2d38a17 4639
89fac5e3
RS
4640 sec = find_section (".dynamic");
4641 if (sec == NULL || sec->sh_size == 0)
b2d38a17 4642 {
28f997cf
TG
4643 /* A corresponding .dynamic section is expected, but on
4644 IA-64/OpenVMS it is OK for it to be missing. */
4645 if (!is_ia64_vms ())
4646 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
4647 break;
4648 }
4649
42bb2e33 4650 if (sec->sh_type == SHT_NOBITS)
20737c13
AM
4651 {
4652 dynamic_size = 0;
4653 break;
4654 }
42bb2e33 4655
b2d38a17
NC
4656 dynamic_addr = sec->sh_offset;
4657 dynamic_size = sec->sh_size;
4658
4659 if (dynamic_addr < segment->p_offset
4660 || dynamic_addr > segment->p_offset + segment->p_filesz)
20737c13
AM
4661 warn (_("the .dynamic section is not contained"
4662 " within the dynamic segment\n"));
b2d38a17 4663 else if (dynamic_addr > segment->p_offset)
20737c13
AM
4664 warn (_("the .dynamic section is not the first section"
4665 " in the dynamic segment.\n"));
b2d38a17 4666 }
252b5132
RH
4667 break;
4668
4669 case PT_INTERP:
fb52b2f4
NC
4670 if (fseek (file, archive_file_offset + (long) segment->p_offset,
4671 SEEK_SET))
252b5132
RH
4672 error (_("Unable to find program interpreter name\n"));
4673 else
4674 {
f8eae8b2 4675 char fmt [32];
9495b2e6 4676 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
4677
4678 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 4679 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 4680
252b5132 4681 program_interpreter[0] = 0;
7bd7b3ef
AM
4682 if (fscanf (file, fmt, program_interpreter) <= 0)
4683 error (_("Unable to read program interpreter name\n"));
252b5132
RH
4684
4685 if (do_segments)
f54498b4 4686 printf (_(" [Requesting program interpreter: %s]\n"),
252b5132
RH
4687 program_interpreter);
4688 }
4689 break;
4690 }
252b5132
RH
4691 }
4692
c256ffe7 4693 if (do_segments && section_headers != NULL && string_table != NULL)
252b5132
RH
4694 {
4695 printf (_("\n Section to Segment mapping:\n"));
4696 printf (_(" Segment Sections...\n"));
4697
252b5132
RH
4698 for (i = 0; i < elf_header.e_phnum; i++)
4699 {
9ad5cbcf 4700 unsigned int j;
2cf0635d 4701 Elf_Internal_Shdr * section;
252b5132
RH
4702
4703 segment = program_headers + i;
b391a3e3 4704 section = section_headers + 1;
252b5132
RH
4705
4706 printf (" %2.2d ", i);
4707
b34976b6 4708 for (j = 1; j < elf_header.e_shnum; j++, section++)
252b5132 4709 {
f4638467
AM
4710 if (!ELF_TBSS_SPECIAL (section, segment)
4711 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
74e1a04b 4712 printf ("%s ", printable_section_name (section));
252b5132
RH
4713 }
4714
4715 putc ('\n',stdout);
4716 }
4717 }
4718
252b5132
RH
4719 return 1;
4720}
4721
4722
d93f0186
NC
4723/* Find the file offset corresponding to VMA by using the program headers. */
4724
4725static long
2cf0635d 4726offset_from_vma (FILE * file, bfd_vma vma, bfd_size_type size)
d93f0186 4727{
2cf0635d 4728 Elf_Internal_Phdr * seg;
d93f0186
NC
4729
4730 if (! get_program_headers (file))
4731 {
4732 warn (_("Cannot interpret virtual addresses without program headers.\n"));
4733 return (long) vma;
4734 }
4735
4736 for (seg = program_headers;
4737 seg < program_headers + elf_header.e_phnum;
4738 ++seg)
4739 {
4740 if (seg->p_type != PT_LOAD)
4741 continue;
4742
4743 if (vma >= (seg->p_vaddr & -seg->p_align)
4744 && vma + size <= seg->p_vaddr + seg->p_filesz)
4745 return vma - seg->p_vaddr + seg->p_offset;
4746 }
4747
4748 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 4749 (unsigned long) vma);
d93f0186
NC
4750 return (long) vma;
4751}
4752
4753
049b0c3a
NC
4754/* Allocate memory and load the sections headers into the global pointer
4755 SECTION_HEADERS. If PROBE is true, this is just a probe and we do not
4756 generate any error messages if the load fails. */
4757
4758static bfd_boolean
4759get_32bit_section_headers (FILE * file, bfd_boolean probe)
252b5132 4760{
2cf0635d
NC
4761 Elf32_External_Shdr * shdrs;
4762 Elf_Internal_Shdr * internal;
b34976b6 4763 unsigned int i;
049b0c3a
NC
4764 unsigned int size = elf_header.e_shentsize;
4765 unsigned int num = probe ? 1 : elf_header.e_shnum;
4766
4767 /* PR binutils/17531: Cope with unexpected section header sizes. */
4768 if (size == 0 || num == 0)
4769 return FALSE;
4770 if (size < sizeof * shdrs)
4771 {
4772 if (! probe)
4773 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4774 return FALSE;
4775 }
4776 if (!probe && size > sizeof * shdrs)
4777 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 4778
3f5e193b 4779 shdrs = (Elf32_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4780 size, num,
4781 probe ? NULL : _("section headers"));
4782 if (shdrs == NULL)
4783 return FALSE;
252b5132 4784
049b0c3a
NC
4785 if (section_headers != NULL)
4786 free (section_headers);
3f5e193b
NC
4787 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4788 sizeof (Elf_Internal_Shdr));
252b5132
RH
4789 if (section_headers == NULL)
4790 {
049b0c3a 4791 if (!probe)
8b73c356 4792 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4793 return FALSE;
252b5132
RH
4794 }
4795
4796 for (i = 0, internal = section_headers;
560f3c1c 4797 i < num;
b34976b6 4798 i++, internal++)
252b5132
RH
4799 {
4800 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4801 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
4802 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4803 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4804 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4805 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4806 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4807 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4808 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4809 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
4810 }
4811
4812 free (shdrs);
049b0c3a 4813 return TRUE;
252b5132
RH
4814}
4815
049b0c3a
NC
4816static bfd_boolean
4817get_64bit_section_headers (FILE * file, bfd_boolean probe)
9ea033b2 4818{
2cf0635d
NC
4819 Elf64_External_Shdr * shdrs;
4820 Elf_Internal_Shdr * internal;
b34976b6 4821 unsigned int i;
049b0c3a
NC
4822 unsigned int size = elf_header.e_shentsize;
4823 unsigned int num = probe ? 1 : elf_header.e_shnum;
4824
4825 /* PR binutils/17531: Cope with unexpected section header sizes. */
4826 if (size == 0 || num == 0)
4827 return FALSE;
4828 if (size < sizeof * shdrs)
4829 {
4830 if (! probe)
4831 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
4832 return FALSE;
4833 }
4834 if (! probe && size > sizeof * shdrs)
4835 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 4836
3f5e193b 4837 shdrs = (Elf64_External_Shdr *) get_data (NULL, file, elf_header.e_shoff,
049b0c3a
NC
4838 size, num,
4839 probe ? NULL : _("section headers"));
4840 if (shdrs == NULL)
4841 return FALSE;
9ea033b2 4842
049b0c3a
NC
4843 if (section_headers != NULL)
4844 free (section_headers);
3f5e193b
NC
4845 section_headers = (Elf_Internal_Shdr *) cmalloc (num,
4846 sizeof (Elf_Internal_Shdr));
9ea033b2
NC
4847 if (section_headers == NULL)
4848 {
049b0c3a 4849 if (! probe)
8b73c356 4850 error (_("Out of memory reading %u section headers\n"), num);
049b0c3a 4851 return FALSE;
9ea033b2
NC
4852 }
4853
4854 for (i = 0, internal = section_headers;
560f3c1c 4855 i < num;
b34976b6 4856 i++, internal++)
9ea033b2
NC
4857 {
4858 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
4859 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
4860 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
4861 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
4862 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
4863 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
4864 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
4865 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
4866 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
4867 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
4868 }
4869
4870 free (shdrs);
049b0c3a 4871 return TRUE;
9ea033b2
NC
4872}
4873
252b5132 4874static Elf_Internal_Sym *
ba5cdace
NC
4875get_32bit_elf_symbols (FILE * file,
4876 Elf_Internal_Shdr * section,
4877 unsigned long * num_syms_return)
252b5132 4878{
ba5cdace 4879 unsigned long number = 0;
dd24e3da 4880 Elf32_External_Sym * esyms = NULL;
ba5cdace 4881 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 4882 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4883 Elf_Internal_Sym * psym;
b34976b6 4884 unsigned int j;
252b5132 4885
c9c1d674
EG
4886 if (section->sh_size == 0)
4887 {
4888 if (num_syms_return != NULL)
4889 * num_syms_return = 0;
4890 return NULL;
4891 }
4892
dd24e3da 4893 /* Run some sanity checks first. */
c9c1d674 4894 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 4895 {
c9c1d674
EG
4896 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
4897 printable_section_name (section), (unsigned long) section->sh_entsize);
ba5cdace 4898 goto exit_point;
dd24e3da
NC
4899 }
4900
f54498b4
NC
4901 if (section->sh_size > current_file_size)
4902 {
4903 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
74e1a04b 4904 printable_section_name (section), (unsigned long) section->sh_size);
f54498b4
NC
4905 goto exit_point;
4906 }
4907
dd24e3da
NC
4908 number = section->sh_size / section->sh_entsize;
4909
4910 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
4911 {
c9c1d674 4912 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
4913 (unsigned long) section->sh_size,
4914 printable_section_name (section),
4915 (unsigned long) section->sh_entsize);
ba5cdace 4916 goto exit_point;
dd24e3da
NC
4917 }
4918
3f5e193b
NC
4919 esyms = (Elf32_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
4920 section->sh_size, _("symbols"));
dd24e3da 4921 if (esyms == NULL)
ba5cdace 4922 goto exit_point;
252b5132 4923
9ad5cbcf
AM
4924 shndx = NULL;
4925 if (symtab_shndx_hdr != NULL
4926 && (symtab_shndx_hdr->sh_link
4fbb74a6 4927 == (unsigned long) (section - section_headers)))
9ad5cbcf 4928 {
3f5e193b
NC
4929 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
4930 symtab_shndx_hdr->sh_offset,
4931 1, symtab_shndx_hdr->sh_size,
9cf03b7e 4932 _("symbol table section indicies"));
dd24e3da
NC
4933 if (shndx == NULL)
4934 goto exit_point;
c9c1d674
EG
4935 /* PR17531: file: heap-buffer-overflow */
4936 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
4937 {
4938 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
4939 printable_section_name (symtab_shndx_hdr),
4940 (unsigned long) symtab_shndx_hdr->sh_size,
4941 (unsigned long) section->sh_size);
4942 goto exit_point;
4943 }
9ad5cbcf
AM
4944 }
4945
3f5e193b 4946 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
4947
4948 if (isyms == NULL)
4949 {
8b73c356
NC
4950 error (_("Out of memory reading %lu symbols\n"),
4951 (unsigned long) number);
dd24e3da 4952 goto exit_point;
252b5132
RH
4953 }
4954
dd24e3da 4955 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
4956 {
4957 psym->st_name = BYTE_GET (esyms[j].st_name);
4958 psym->st_value = BYTE_GET (esyms[j].st_value);
4959 psym->st_size = BYTE_GET (esyms[j].st_size);
4960 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 4961 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
4962 psym->st_shndx
4963 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
4964 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
4965 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
4966 psym->st_info = BYTE_GET (esyms[j].st_info);
4967 psym->st_other = BYTE_GET (esyms[j].st_other);
4968 }
4969
dd24e3da 4970 exit_point:
ba5cdace 4971 if (shndx != NULL)
9ad5cbcf 4972 free (shndx);
ba5cdace 4973 if (esyms != NULL)
dd24e3da 4974 free (esyms);
252b5132 4975
ba5cdace
NC
4976 if (num_syms_return != NULL)
4977 * num_syms_return = isyms == NULL ? 0 : number;
4978
252b5132
RH
4979 return isyms;
4980}
4981
9ea033b2 4982static Elf_Internal_Sym *
ba5cdace
NC
4983get_64bit_elf_symbols (FILE * file,
4984 Elf_Internal_Shdr * section,
4985 unsigned long * num_syms_return)
9ea033b2 4986{
ba5cdace
NC
4987 unsigned long number = 0;
4988 Elf64_External_Sym * esyms = NULL;
4989 Elf_External_Sym_Shndx * shndx = NULL;
4990 Elf_Internal_Sym * isyms = NULL;
2cf0635d 4991 Elf_Internal_Sym * psym;
b34976b6 4992 unsigned int j;
9ea033b2 4993
c9c1d674
EG
4994 if (section->sh_size == 0)
4995 {
4996 if (num_syms_return != NULL)
4997 * num_syms_return = 0;
4998 return NULL;
4999 }
5000
dd24e3da 5001 /* Run some sanity checks first. */
c9c1d674 5002 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5003 {
c9c1d674 5004 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
8066deb1
AM
5005 printable_section_name (section),
5006 (unsigned long) section->sh_entsize);
ba5cdace 5007 goto exit_point;
dd24e3da
NC
5008 }
5009
f54498b4
NC
5010 if (section->sh_size > current_file_size)
5011 {
5012 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
8066deb1
AM
5013 printable_section_name (section),
5014 (unsigned long) section->sh_size);
f54498b4
NC
5015 goto exit_point;
5016 }
5017
dd24e3da
NC
5018 number = section->sh_size / section->sh_entsize;
5019
5020 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5021 {
c9c1d674 5022 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1
AM
5023 (unsigned long) section->sh_size,
5024 printable_section_name (section),
5025 (unsigned long) section->sh_entsize);
ba5cdace 5026 goto exit_point;
dd24e3da
NC
5027 }
5028
3f5e193b
NC
5029 esyms = (Elf64_External_Sym *) get_data (NULL, file, section->sh_offset, 1,
5030 section->sh_size, _("symbols"));
a6e9f9df 5031 if (!esyms)
ba5cdace 5032 goto exit_point;
9ea033b2 5033
9ad5cbcf
AM
5034 if (symtab_shndx_hdr != NULL
5035 && (symtab_shndx_hdr->sh_link
4fbb74a6 5036 == (unsigned long) (section - section_headers)))
9ad5cbcf 5037 {
3f5e193b
NC
5038 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, file,
5039 symtab_shndx_hdr->sh_offset,
5040 1, symtab_shndx_hdr->sh_size,
9cf03b7e 5041 _("symbol table section indicies"));
ba5cdace
NC
5042 if (shndx == NULL)
5043 goto exit_point;
c9c1d674
EG
5044 else if (symtab_shndx_hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5045 {
5046 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5047 printable_section_name (symtab_shndx_hdr),
5048 (unsigned long) symtab_shndx_hdr->sh_size,
5049 (unsigned long) section->sh_size);
5050 goto exit_point;
5051 }
9ad5cbcf
AM
5052 }
5053
3f5e193b 5054 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5055
5056 if (isyms == NULL)
5057 {
8b73c356
NC
5058 error (_("Out of memory reading %lu symbols\n"),
5059 (unsigned long) number);
ba5cdace 5060 goto exit_point;
9ea033b2
NC
5061 }
5062
ba5cdace 5063 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5064 {
5065 psym->st_name = BYTE_GET (esyms[j].st_name);
5066 psym->st_info = BYTE_GET (esyms[j].st_info);
5067 psym->st_other = BYTE_GET (esyms[j].st_other);
5068 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5069
4fbb74a6 5070 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5071 psym->st_shndx
5072 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5073 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5074 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5075
66543521
AM
5076 psym->st_value = BYTE_GET (esyms[j].st_value);
5077 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5078 }
5079
ba5cdace
NC
5080 exit_point:
5081 if (shndx != NULL)
9ad5cbcf 5082 free (shndx);
ba5cdace
NC
5083 if (esyms != NULL)
5084 free (esyms);
5085
5086 if (num_syms_return != NULL)
5087 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5088
5089 return isyms;
5090}
5091
d1133906 5092static const char *
d3ba0551 5093get_elf_section_flags (bfd_vma sh_flags)
d1133906 5094{
5477e8a0 5095 static char buff[1024];
2cf0635d 5096 char * p = buff;
8d5ff12c 5097 int field_size = is_32bit_elf ? 8 : 16;
91d6fa6a
NC
5098 int sindex;
5099 int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5100 bfd_vma os_flags = 0;
5101 bfd_vma proc_flags = 0;
5102 bfd_vma unknown_flags = 0;
148b93f2 5103 static const struct
5477e8a0 5104 {
2cf0635d 5105 const char * str;
5477e8a0
L
5106 int len;
5107 }
5108 flags [] =
5109 {
cfcac11d
NC
5110 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5111 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5112 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5113 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5114 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5115 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5116 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5117 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5118 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5119 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5120 /* IA-64 specific. */
5121 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5122 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5123 /* IA-64 OpenVMS specific. */
5124 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5125 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5126 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5127 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5128 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5129 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5130 /* Generic. */
cfcac11d 5131 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5132 /* SPARC specific. */
cfcac11d 5133 /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
5477e8a0
L
5134 };
5135
5136 if (do_section_details)
5137 {
8d5ff12c
L
5138 sprintf (buff, "[%*.*lx]: ",
5139 field_size, field_size, (unsigned long) sh_flags);
5140 p += field_size + 4;
5477e8a0 5141 }
76da6bbe 5142
d1133906
NC
5143 while (sh_flags)
5144 {
5145 bfd_vma flag;
5146
5147 flag = sh_flags & - sh_flags;
5148 sh_flags &= ~ flag;
76da6bbe 5149
5477e8a0 5150 if (do_section_details)
d1133906 5151 {
5477e8a0
L
5152 switch (flag)
5153 {
91d6fa6a
NC
5154 case SHF_WRITE: sindex = 0; break;
5155 case SHF_ALLOC: sindex = 1; break;
5156 case SHF_EXECINSTR: sindex = 2; break;
5157 case SHF_MERGE: sindex = 3; break;
5158 case SHF_STRINGS: sindex = 4; break;
5159 case SHF_INFO_LINK: sindex = 5; break;
5160 case SHF_LINK_ORDER: sindex = 6; break;
5161 case SHF_OS_NONCONFORMING: sindex = 7; break;
5162 case SHF_GROUP: sindex = 8; break;
5163 case SHF_TLS: sindex = 9; break;
18ae9cc1 5164 case SHF_EXCLUDE: sindex = 18; break;
76da6bbe 5165
5477e8a0 5166 default:
91d6fa6a 5167 sindex = -1;
cfcac11d 5168 switch (elf_header.e_machine)
148b93f2 5169 {
cfcac11d 5170 case EM_IA_64:
148b93f2 5171 if (flag == SHF_IA_64_SHORT)
91d6fa6a 5172 sindex = 10;
148b93f2 5173 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 5174 sindex = 11;
148b93f2
NC
5175#ifdef BFD64
5176 else if (elf_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
5177 switch (flag)
5178 {
91d6fa6a
NC
5179 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
5180 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
5181 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
5182 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
5183 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
5184 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
5185 default: break;
5186 }
5187#endif
cfcac11d
NC
5188 break;
5189
caa83f8b
NC
5190 case EM_386:
5191 case EM_486:
5192 case EM_X86_64:
7f502d6c 5193 case EM_L1OM:
7a9068fe 5194 case EM_K1OM:
cfcac11d
NC
5195 case EM_OLD_SPARCV9:
5196 case EM_SPARC32PLUS:
5197 case EM_SPARCV9:
5198 case EM_SPARC:
18ae9cc1 5199 if (flag == SHF_ORDERED)
91d6fa6a 5200 sindex = 19;
cfcac11d
NC
5201 break;
5202 default:
5203 break;
148b93f2 5204 }
5477e8a0
L
5205 }
5206
91d6fa6a 5207 if (sindex != -1)
5477e8a0 5208 {
8d5ff12c
L
5209 if (p != buff + field_size + 4)
5210 {
5211 if (size < (10 + 2))
bee0ee85
NC
5212 {
5213 warn (_("Internal error: not enough buffer room for section flag info"));
5214 return _("<unknown>");
5215 }
8d5ff12c
L
5216 size -= 2;
5217 *p++ = ',';
5218 *p++ = ' ';
5219 }
5220
91d6fa6a
NC
5221 size -= flags [sindex].len;
5222 p = stpcpy (p, flags [sindex].str);
5477e8a0 5223 }
3b22753a 5224 else if (flag & SHF_MASKOS)
8d5ff12c 5225 os_flags |= flag;
d1133906 5226 else if (flag & SHF_MASKPROC)
8d5ff12c 5227 proc_flags |= flag;
d1133906 5228 else
8d5ff12c 5229 unknown_flags |= flag;
5477e8a0
L
5230 }
5231 else
5232 {
5233 switch (flag)
5234 {
5235 case SHF_WRITE: *p = 'W'; break;
5236 case SHF_ALLOC: *p = 'A'; break;
5237 case SHF_EXECINSTR: *p = 'X'; break;
5238 case SHF_MERGE: *p = 'M'; break;
5239 case SHF_STRINGS: *p = 'S'; break;
5240 case SHF_INFO_LINK: *p = 'I'; break;
5241 case SHF_LINK_ORDER: *p = 'L'; break;
5242 case SHF_OS_NONCONFORMING: *p = 'O'; break;
5243 case SHF_GROUP: *p = 'G'; break;
5244 case SHF_TLS: *p = 'T'; break;
18ae9cc1 5245 case SHF_EXCLUDE: *p = 'E'; break;
5477e8a0
L
5246
5247 default:
8a9036a4 5248 if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
5249 || elf_header.e_machine == EM_L1OM
5250 || elf_header.e_machine == EM_K1OM)
5477e8a0
L
5251 && flag == SHF_X86_64_LARGE)
5252 *p = 'l';
5253 else if (flag & SHF_MASKOS)
5254 {
5255 *p = 'o';
5256 sh_flags &= ~ SHF_MASKOS;
5257 }
5258 else if (flag & SHF_MASKPROC)
5259 {
5260 *p = 'p';
5261 sh_flags &= ~ SHF_MASKPROC;
5262 }
5263 else
5264 *p = 'x';
5265 break;
5266 }
5267 p++;
d1133906
NC
5268 }
5269 }
76da6bbe 5270
8d5ff12c
L
5271 if (do_section_details)
5272 {
5273 if (os_flags)
5274 {
5275 size -= 5 + field_size;
5276 if (p != buff + field_size + 4)
5277 {
5278 if (size < (2 + 1))
bee0ee85
NC
5279 {
5280 warn (_("Internal error: not enough buffer room for section flag info"));
5281 return _("<unknown>");
5282 }
8d5ff12c
L
5283 size -= 2;
5284 *p++ = ',';
5285 *p++ = ' ';
5286 }
5287 sprintf (p, "OS (%*.*lx)", field_size, field_size,
5288 (unsigned long) os_flags);
5289 p += 5 + field_size;
5290 }
5291 if (proc_flags)
5292 {
5293 size -= 7 + field_size;
5294 if (p != buff + field_size + 4)
5295 {
5296 if (size < (2 + 1))
bee0ee85
NC
5297 {
5298 warn (_("Internal error: not enough buffer room for section flag info"));
5299 return _("<unknown>");
5300 }
8d5ff12c
L
5301 size -= 2;
5302 *p++ = ',';
5303 *p++ = ' ';
5304 }
5305 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
5306 (unsigned long) proc_flags);
5307 p += 7 + field_size;
5308 }
5309 if (unknown_flags)
5310 {
5311 size -= 10 + field_size;
5312 if (p != buff + field_size + 4)
5313 {
5314 if (size < (2 + 1))
bee0ee85
NC
5315 {
5316 warn (_("Internal error: not enough buffer room for section flag info"));
5317 return _("<unknown>");
5318 }
8d5ff12c
L
5319 size -= 2;
5320 *p++ = ',';
5321 *p++ = ' ';
5322 }
2b692964 5323 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
5324 (unsigned long) unknown_flags);
5325 p += 10 + field_size;
5326 }
5327 }
5328
e9e44622 5329 *p = '\0';
d1133906
NC
5330 return buff;
5331}
5332
252b5132 5333static int
2cf0635d 5334process_section_headers (FILE * file)
252b5132 5335{
2cf0635d 5336 Elf_Internal_Shdr * section;
b34976b6 5337 unsigned int i;
252b5132
RH
5338
5339 section_headers = NULL;
5340
5341 if (elf_header.e_shnum == 0)
5342 {
82f2dbf7
NC
5343 /* PR binutils/12467. */
5344 if (elf_header.e_shoff != 0)
5345 warn (_("possibly corrupt ELF file header - it has a non-zero"
5346 " section header offset, but no section headers\n"));
5347 else if (do_sections)
252b5132
RH
5348 printf (_("\nThere are no sections in this file.\n"));
5349
5350 return 1;
5351 }
5352
5353 if (do_sections && !do_header)
9ea033b2 5354 printf (_("There are %d section headers, starting at offset 0x%lx:\n"),
252b5132
RH
5355 elf_header.e_shnum, (unsigned long) elf_header.e_shoff);
5356
9ea033b2
NC
5357 if (is_32bit_elf)
5358 {
049b0c3a 5359 if (! get_32bit_section_headers (file, FALSE))
9ea033b2
NC
5360 return 0;
5361 }
049b0c3a 5362 else if (! get_64bit_section_headers (file, FALSE))
252b5132
RH
5363 return 0;
5364
5365 /* Read in the string table, so that we have names to display. */
0b49d371 5366 if (elf_header.e_shstrndx != SHN_UNDEF
4fbb74a6 5367 && elf_header.e_shstrndx < elf_header.e_shnum)
252b5132 5368 {
4fbb74a6 5369 section = section_headers + elf_header.e_shstrndx;
d40ac9bd 5370
c256ffe7
JJ
5371 if (section->sh_size != 0)
5372 {
3f5e193b
NC
5373 string_table = (char *) get_data (NULL, file, section->sh_offset,
5374 1, section->sh_size,
5375 _("string table"));
0de14b54 5376
c256ffe7
JJ
5377 string_table_length = string_table != NULL ? section->sh_size : 0;
5378 }
252b5132
RH
5379 }
5380
5381 /* Scan the sections for the dynamic symbol table
e3c8793a 5382 and dynamic string table and debug sections. */
252b5132
RH
5383 dynamic_symbols = NULL;
5384 dynamic_strings = NULL;
5385 dynamic_syminfo = NULL;
f1ef08cb 5386 symtab_shndx_hdr = NULL;
103f02d3 5387
89fac5e3
RS
5388 eh_addr_size = is_32bit_elf ? 4 : 8;
5389 switch (elf_header.e_machine)
5390 {
5391 case EM_MIPS:
5392 case EM_MIPS_RS3_LE:
5393 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
5394 FDE addresses. However, the ABI also has a semi-official ILP32
5395 variant for which the normal FDE address size rules apply.
5396
5397 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
5398 section, where XX is the size of longs in bits. Unfortunately,
5399 earlier compilers provided no way of distinguishing ILP32 objects
5400 from LP64 objects, so if there's any doubt, we should assume that
5401 the official LP64 form is being used. */
5402 if ((elf_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
5403 && find_section (".gcc_compiled_long32") == NULL)
5404 eh_addr_size = 8;
5405 break;
0f56a26a
DD
5406
5407 case EM_H8_300:
5408 case EM_H8_300H:
5409 switch (elf_header.e_flags & EF_H8_MACH)
5410 {
5411 case E_H8_MACH_H8300:
5412 case E_H8_MACH_H8300HN:
5413 case E_H8_MACH_H8300SN:
5414 case E_H8_MACH_H8300SXN:
5415 eh_addr_size = 2;
5416 break;
5417 case E_H8_MACH_H8300H:
5418 case E_H8_MACH_H8300S:
5419 case E_H8_MACH_H8300SX:
5420 eh_addr_size = 4;
5421 break;
5422 }
f4236fe4
DD
5423 break;
5424
ff7eeb89 5425 case EM_M32C_OLD:
f4236fe4
DD
5426 case EM_M32C:
5427 switch (elf_header.e_flags & EF_M32C_CPU_MASK)
5428 {
5429 case EF_M32C_CPU_M16C:
5430 eh_addr_size = 2;
5431 break;
5432 }
5433 break;
89fac5e3
RS
5434 }
5435
76ca31c0
NC
5436#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
5437 do \
5438 { \
5439 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
5440 if (section->sh_entsize != expected_entsize) \
9dd3a467 5441 { \
76ca31c0
NC
5442 char buf[40]; \
5443 sprintf_vma (buf, section->sh_entsize); \
5444 /* Note: coded this way so that there is a single string for \
5445 translation. */ \
5446 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
5447 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
5448 (unsigned) expected_entsize); \
9dd3a467 5449 section->sh_entsize = expected_entsize; \
76ca31c0
NC
5450 } \
5451 } \
08d8fa11 5452 while (0)
9dd3a467
NC
5453
5454#define CHECK_ENTSIZE(section, i, type) \
08d8fa11
JJ
5455 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
5456 sizeof (Elf64_External_##type))
5457
252b5132
RH
5458 for (i = 0, section = section_headers;
5459 i < elf_header.e_shnum;
b34976b6 5460 i++, section++)
252b5132 5461 {
2cf0635d 5462 char * name = SECTION_NAME (section);
252b5132
RH
5463
5464 if (section->sh_type == SHT_DYNSYM)
5465 {
5466 if (dynamic_symbols != NULL)
5467 {
5468 error (_("File contains multiple dynamic symbol tables\n"));
5469 continue;
5470 }
5471
08d8fa11 5472 CHECK_ENTSIZE (section, i, Sym);
ba5cdace 5473 dynamic_symbols = GET_ELF_SYMBOLS (file, section, & num_dynamic_syms);
252b5132
RH
5474 }
5475 else if (section->sh_type == SHT_STRTAB
18bd398b 5476 && streq (name, ".dynstr"))
252b5132
RH
5477 {
5478 if (dynamic_strings != NULL)
5479 {
5480 error (_("File contains multiple dynamic string tables\n"));
5481 continue;
5482 }
5483
3f5e193b
NC
5484 dynamic_strings = (char *) get_data (NULL, file, section->sh_offset,
5485 1, section->sh_size,
5486 _("dynamic strings"));
59245841 5487 dynamic_strings_length = dynamic_strings == NULL ? 0 : section->sh_size;
252b5132 5488 }
9ad5cbcf
AM
5489 else if (section->sh_type == SHT_SYMTAB_SHNDX)
5490 {
5491 if (symtab_shndx_hdr != NULL)
5492 {
5493 error (_("File contains multiple symtab shndx tables\n"));
5494 continue;
5495 }
5496 symtab_shndx_hdr = section;
5497 }
08d8fa11
JJ
5498 else if (section->sh_type == SHT_SYMTAB)
5499 CHECK_ENTSIZE (section, i, Sym);
5500 else if (section->sh_type == SHT_GROUP)
5501 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
5502 else if (section->sh_type == SHT_REL)
5503 CHECK_ENTSIZE (section, i, Rel);
5504 else if (section->sh_type == SHT_RELA)
5505 CHECK_ENTSIZE (section, i, Rela);
252b5132 5506 else if ((do_debugging || do_debug_info || do_debug_abbrevs
f9f0e732 5507 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
cb8f3167 5508 || do_debug_aranges || do_debug_frames || do_debug_macinfo
657d0d47
CC
5509 || do_debug_str || do_debug_loc || do_debug_ranges
5510 || do_debug_addr || do_debug_cu_index)
1b315056
CS
5511 && (const_strneq (name, ".debug_")
5512 || const_strneq (name, ".zdebug_")))
252b5132 5513 {
1b315056
CS
5514 if (name[1] == 'z')
5515 name += sizeof (".zdebug_") - 1;
5516 else
5517 name += sizeof (".debug_") - 1;
252b5132
RH
5518
5519 if (do_debugging
4723351a
CC
5520 || (do_debug_info && const_strneq (name, "info"))
5521 || (do_debug_info && const_strneq (name, "types"))
5522 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
5523 || (do_debug_lines && strcmp (name, "line") == 0)
5524 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
5525 || (do_debug_pubnames && const_strneq (name, "pubnames"))
5526 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
5527 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
5528 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
5529 || (do_debug_aranges && const_strneq (name, "aranges"))
5530 || (do_debug_ranges && const_strneq (name, "ranges"))
5531 || (do_debug_frames && const_strneq (name, "frame"))
5532 || (do_debug_macinfo && const_strneq (name, "macinfo"))
5533 || (do_debug_macinfo && const_strneq (name, "macro"))
5534 || (do_debug_str && const_strneq (name, "str"))
5535 || (do_debug_loc && const_strneq (name, "loc"))
657d0d47
CC
5536 || (do_debug_addr && const_strneq (name, "addr"))
5537 || (do_debug_cu_index && const_strneq (name, "cu_index"))
5538 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 5539 )
09c11c86 5540 request_dump_bynumber (i, DEBUG_DUMP);
252b5132 5541 }
a262ae96 5542 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 5543 else if ((do_debugging || do_debug_info)
0112cd26 5544 && const_strneq (name, ".gnu.linkonce.wi."))
09c11c86 5545 request_dump_bynumber (i, DEBUG_DUMP);
18bd398b 5546 else if (do_debug_frames && streq (name, ".eh_frame"))
09c11c86 5547 request_dump_bynumber (i, DEBUG_DUMP);
5bbdf3d5
DE
5548 else if (do_gdb_index && streq (name, ".gdb_index"))
5549 request_dump_bynumber (i, DEBUG_DUMP);
6f875884
TG
5550 /* Trace sections for Itanium VMS. */
5551 else if ((do_debugging || do_trace_info || do_trace_abbrevs
5552 || do_trace_aranges)
5553 && const_strneq (name, ".trace_"))
5554 {
5555 name += sizeof (".trace_") - 1;
5556
5557 if (do_debugging
5558 || (do_trace_info && streq (name, "info"))
5559 || (do_trace_abbrevs && streq (name, "abbrev"))
5560 || (do_trace_aranges && streq (name, "aranges"))
5561 )
5562 request_dump_bynumber (i, DEBUG_DUMP);
5563 }
252b5132
RH
5564 }
5565
5566 if (! do_sections)
5567 return 1;
5568
3a1a2036
NC
5569 if (elf_header.e_shnum > 1)
5570 printf (_("\nSection Headers:\n"));
5571 else
5572 printf (_("\nSection Header:\n"));
76da6bbe 5573
f7a99963 5574 if (is_32bit_elf)
595cf52e 5575 {
5477e8a0 5576 if (do_section_details)
595cf52e
L
5577 {
5578 printf (_(" [Nr] Name\n"));
5477e8a0 5579 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
5580 }
5581 else
5582 printf
5583 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
5584 }
d974e256 5585 else if (do_wide)
595cf52e 5586 {
5477e8a0 5587 if (do_section_details)
595cf52e
L
5588 {
5589 printf (_(" [Nr] Name\n"));
5477e8a0 5590 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
5591 }
5592 else
5593 printf
5594 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
5595 }
f7a99963
NC
5596 else
5597 {
5477e8a0 5598 if (do_section_details)
595cf52e
L
5599 {
5600 printf (_(" [Nr] Name\n"));
5477e8a0
L
5601 printf (_(" Type Address Offset Link\n"));
5602 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
5603 }
5604 else
5605 {
5606 printf (_(" [Nr] Name Type Address Offset\n"));
5607 printf (_(" Size EntSize Flags Link Info Align\n"));
5608 }
f7a99963 5609 }
252b5132 5610
5477e8a0
L
5611 if (do_section_details)
5612 printf (_(" Flags\n"));
5613
252b5132
RH
5614 for (i = 0, section = section_headers;
5615 i < elf_header.e_shnum;
b34976b6 5616 i++, section++)
252b5132 5617 {
7bfd842d 5618 printf (" [%2u] ", i);
5477e8a0 5619 if (do_section_details)
74e1a04b 5620 printf ("%s\n ", printable_section_name (section));
595cf52e 5621 else
74e1a04b 5622 print_symbol (-17, SECTION_NAME (section));
0b4362b0 5623
ea52a088
NC
5624 printf (do_wide ? " %-15s " : " %-15.15s ",
5625 get_section_type_name (section->sh_type));
0b4362b0 5626
f7a99963
NC
5627 if (is_32bit_elf)
5628 {
cfcac11d
NC
5629 const char * link_too_big = NULL;
5630
f7a99963 5631 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 5632
f7a99963
NC
5633 printf ( " %6.6lx %6.6lx %2.2lx",
5634 (unsigned long) section->sh_offset,
5635 (unsigned long) section->sh_size,
5636 (unsigned long) section->sh_entsize);
d1133906 5637
5477e8a0
L
5638 if (do_section_details)
5639 fputs (" ", stdout);
5640 else
5641 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5642
cfcac11d
NC
5643 if (section->sh_link >= elf_header.e_shnum)
5644 {
5645 link_too_big = "";
5646 /* The sh_link value is out of range. Normally this indicates
caa83f8b 5647 an error but it can have special values in Solaris binaries. */
cfcac11d
NC
5648 switch (elf_header.e_machine)
5649 {
caa83f8b
NC
5650 case EM_386:
5651 case EM_486:
5652 case EM_X86_64:
7f502d6c 5653 case EM_L1OM:
7a9068fe 5654 case EM_K1OM:
cfcac11d
NC
5655 case EM_OLD_SPARCV9:
5656 case EM_SPARC32PLUS:
5657 case EM_SPARCV9:
5658 case EM_SPARC:
5659 if (section->sh_link == (SHN_BEFORE & 0xffff))
5660 link_too_big = "BEFORE";
5661 else if (section->sh_link == (SHN_AFTER & 0xffff))
5662 link_too_big = "AFTER";
5663 break;
5664 default:
5665 break;
5666 }
5667 }
5668
5669 if (do_section_details)
5670 {
5671 if (link_too_big != NULL && * link_too_big)
5672 printf ("<%s> ", link_too_big);
5673 else
5674 printf ("%2u ", section->sh_link);
5675 printf ("%3u %2lu\n", section->sh_info,
5676 (unsigned long) section->sh_addralign);
5677 }
5678 else
5679 printf ("%2u %3u %2lu\n",
5680 section->sh_link,
5681 section->sh_info,
5682 (unsigned long) section->sh_addralign);
5683
5684 if (link_too_big && ! * link_too_big)
5685 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
5686 i, section->sh_link);
f7a99963 5687 }
d974e256
JJ
5688 else if (do_wide)
5689 {
5690 print_vma (section->sh_addr, LONG_HEX);
5691
5692 if ((long) section->sh_offset == section->sh_offset)
5693 printf (" %6.6lx", (unsigned long) section->sh_offset);
5694 else
5695 {
5696 putchar (' ');
5697 print_vma (section->sh_offset, LONG_HEX);
5698 }
5699
5700 if ((unsigned long) section->sh_size == section->sh_size)
5701 printf (" %6.6lx", (unsigned long) section->sh_size);
5702 else
5703 {
5704 putchar (' ');
5705 print_vma (section->sh_size, LONG_HEX);
5706 }
5707
5708 if ((unsigned long) section->sh_entsize == section->sh_entsize)
5709 printf (" %2.2lx", (unsigned long) section->sh_entsize);
5710 else
5711 {
5712 putchar (' ');
5713 print_vma (section->sh_entsize, LONG_HEX);
5714 }
5715
5477e8a0
L
5716 if (do_section_details)
5717 fputs (" ", stdout);
5718 else
5719 printf (" %3s ", get_elf_section_flags (section->sh_flags));
d974e256 5720
72de5009 5721 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
5722
5723 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 5724 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
5725 else
5726 {
5727 print_vma (section->sh_addralign, DEC);
5728 putchar ('\n');
5729 }
5730 }
5477e8a0 5731 else if (do_section_details)
595cf52e 5732 {
5477e8a0 5733 printf (" %-15.15s ",
595cf52e 5734 get_section_type_name (section->sh_type));
595cf52e
L
5735 print_vma (section->sh_addr, LONG_HEX);
5736 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 5737 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
5738 else
5739 {
5740 printf (" ");
5741 print_vma (section->sh_offset, LONG_HEX);
5742 }
72de5009 5743 printf (" %u\n ", section->sh_link);
595cf52e 5744 print_vma (section->sh_size, LONG_HEX);
5477e8a0 5745 putchar (' ');
595cf52e
L
5746 print_vma (section->sh_entsize, LONG_HEX);
5747
72de5009
AM
5748 printf (" %-16u %lu\n",
5749 section->sh_info,
595cf52e
L
5750 (unsigned long) section->sh_addralign);
5751 }
f7a99963
NC
5752 else
5753 {
5754 putchar (' ');
5755 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
5756 if ((long) section->sh_offset == section->sh_offset)
5757 printf (" %8.8lx", (unsigned long) section->sh_offset);
5758 else
5759 {
5760 printf (" ");
5761 print_vma (section->sh_offset, LONG_HEX);
5762 }
f7a99963
NC
5763 printf ("\n ");
5764 print_vma (section->sh_size, LONG_HEX);
5765 printf (" ");
5766 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 5767
d1133906 5768 printf (" %3s ", get_elf_section_flags (section->sh_flags));
76da6bbe 5769
72de5009
AM
5770 printf (" %2u %3u %lu\n",
5771 section->sh_link,
5772 section->sh_info,
f7a99963
NC
5773 (unsigned long) section->sh_addralign);
5774 }
5477e8a0
L
5775
5776 if (do_section_details)
5777 printf (" %s\n", get_elf_section_flags (section->sh_flags));
252b5132
RH
5778 }
5779
5477e8a0 5780 if (!do_section_details)
3dbcc61d
NC
5781 {
5782 if (elf_header.e_machine == EM_X86_64
7a9068fe
L
5783 || elf_header.e_machine == EM_L1OM
5784 || elf_header.e_machine == EM_K1OM)
3dbcc61d
NC
5785 printf (_("Key to Flags:\n\
5786 W (write), A (alloc), X (execute), M (merge), S (strings), l (large)\n\
5787 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
5788 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
5789 else
5790 printf (_("Key to Flags:\n\
e3c8793a 5791 W (write), A (alloc), X (execute), M (merge), S (strings)\n\
1d0055ea 5792 I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)\n\
e3c8793a 5793 O (extra OS processing required) o (OS specific), p (processor specific)\n"));
0b4362b0 5794 }
d1133906 5795
252b5132
RH
5796 return 1;
5797}
5798
f5842774
L
5799static const char *
5800get_group_flags (unsigned int flags)
5801{
5802 static char buff[32];
5803 switch (flags)
5804 {
220453ec
AM
5805 case 0:
5806 return "";
5807
f5842774 5808 case GRP_COMDAT:
220453ec 5809 return "COMDAT ";
f5842774
L
5810
5811 default:
220453ec 5812 snprintf (buff, sizeof (buff), _("[<unknown>: 0x%x] "), flags);
f5842774
L
5813 break;
5814 }
5815 return buff;
5816}
5817
5818static int
2cf0635d 5819process_section_groups (FILE * file)
f5842774 5820{
2cf0635d 5821 Elf_Internal_Shdr * section;
f5842774 5822 unsigned int i;
2cf0635d
NC
5823 struct group * group;
5824 Elf_Internal_Shdr * symtab_sec;
5825 Elf_Internal_Shdr * strtab_sec;
5826 Elf_Internal_Sym * symtab;
ba5cdace 5827 unsigned long num_syms;
2cf0635d 5828 char * strtab;
c256ffe7 5829 size_t strtab_size;
d1f5c6e3
L
5830
5831 /* Don't process section groups unless needed. */
5832 if (!do_unwind && !do_section_groups)
5833 return 1;
f5842774
L
5834
5835 if (elf_header.e_shnum == 0)
5836 {
5837 if (do_section_groups)
82f2dbf7 5838 printf (_("\nThere are no sections to group in this file.\n"));
f5842774
L
5839
5840 return 1;
5841 }
5842
5843 if (section_headers == NULL)
5844 {
5845 error (_("Section headers are not available!\n"));
fa1908fd
NC
5846 /* PR 13622: This can happen with a corrupt ELF header. */
5847 return 0;
f5842774
L
5848 }
5849
3f5e193b
NC
5850 section_headers_groups = (struct group **) calloc (elf_header.e_shnum,
5851 sizeof (struct group *));
e4b17d5c
L
5852
5853 if (section_headers_groups == NULL)
5854 {
8b73c356
NC
5855 error (_("Out of memory reading %u section group headers\n"),
5856 elf_header.e_shnum);
e4b17d5c
L
5857 return 0;
5858 }
5859
f5842774 5860 /* Scan the sections for the group section. */
d1f5c6e3 5861 group_count = 0;
f5842774
L
5862 for (i = 0, section = section_headers;
5863 i < elf_header.e_shnum;
5864 i++, section++)
e4b17d5c
L
5865 if (section->sh_type == SHT_GROUP)
5866 group_count++;
5867
d1f5c6e3
L
5868 if (group_count == 0)
5869 {
5870 if (do_section_groups)
5871 printf (_("\nThere are no section groups in this file.\n"));
5872
5873 return 1;
5874 }
5875
3f5e193b 5876 section_groups = (struct group *) calloc (group_count, sizeof (struct group));
e4b17d5c
L
5877
5878 if (section_groups == NULL)
5879 {
8b73c356
NC
5880 error (_("Out of memory reading %lu groups\n"),
5881 (unsigned long) group_count);
e4b17d5c
L
5882 return 0;
5883 }
5884
d1f5c6e3
L
5885 symtab_sec = NULL;
5886 strtab_sec = NULL;
5887 symtab = NULL;
ba5cdace 5888 num_syms = 0;
d1f5c6e3 5889 strtab = NULL;
c256ffe7 5890 strtab_size = 0;
e4b17d5c
L
5891 for (i = 0, section = section_headers, group = section_groups;
5892 i < elf_header.e_shnum;
5893 i++, section++)
f5842774
L
5894 {
5895 if (section->sh_type == SHT_GROUP)
5896 {
74e1a04b
NC
5897 const char * name = printable_section_name (section);
5898 const char * group_name;
2cf0635d
NC
5899 unsigned char * start;
5900 unsigned char * indices;
f5842774 5901 unsigned int entry, j, size;
2cf0635d
NC
5902 Elf_Internal_Shdr * sec;
5903 Elf_Internal_Sym * sym;
f5842774
L
5904
5905 /* Get the symbol table. */
4fbb74a6
AM
5906 if (section->sh_link >= elf_header.e_shnum
5907 || ((sec = section_headers + section->sh_link)->sh_type
c256ffe7 5908 != SHT_SYMTAB))
f5842774
L
5909 {
5910 error (_("Bad sh_link in group section `%s'\n"), name);
5911 continue;
5912 }
d1f5c6e3
L
5913
5914 if (symtab_sec != sec)
5915 {
5916 symtab_sec = sec;
5917 if (symtab)
5918 free (symtab);
ba5cdace 5919 symtab = GET_ELF_SYMBOLS (file, symtab_sec, & num_syms);
d1f5c6e3 5920 }
f5842774 5921
dd24e3da
NC
5922 if (symtab == NULL)
5923 {
5924 error (_("Corrupt header in group section `%s'\n"), name);
5925 continue;
5926 }
5927
ba5cdace
NC
5928 if (section->sh_info >= num_syms)
5929 {
5930 error (_("Bad sh_info in group section `%s'\n"), name);
5931 continue;
5932 }
5933
f5842774
L
5934 sym = symtab + section->sh_info;
5935
5936 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
5937 {
4fbb74a6
AM
5938 if (sym->st_shndx == 0
5939 || sym->st_shndx >= elf_header.e_shnum)
f5842774
L
5940 {
5941 error (_("Bad sh_info in group section `%s'\n"), name);
5942 continue;
5943 }
ba2685cc 5944
4fbb74a6 5945 group_name = SECTION_NAME (section_headers + sym->st_shndx);
c256ffe7
JJ
5946 strtab_sec = NULL;
5947 if (strtab)
5948 free (strtab);
f5842774 5949 strtab = NULL;
c256ffe7 5950 strtab_size = 0;
f5842774
L
5951 }
5952 else
5953 {
5954 /* Get the string table. */
4fbb74a6 5955 if (symtab_sec->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
5956 {
5957 strtab_sec = NULL;
5958 if (strtab)
5959 free (strtab);
5960 strtab = NULL;
5961 strtab_size = 0;
5962 }
5963 else if (strtab_sec
4fbb74a6 5964 != (sec = section_headers + symtab_sec->sh_link))
d1f5c6e3
L
5965 {
5966 strtab_sec = sec;
5967 if (strtab)
5968 free (strtab);
071436c6 5969
3f5e193b 5970 strtab = (char *) get_data (NULL, file, strtab_sec->sh_offset,
071436c6
NC
5971 1, strtab_sec->sh_size,
5972 _("string table"));
c256ffe7 5973 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 5974 }
c256ffe7 5975 group_name = sym->st_name < strtab_size
2b692964 5976 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
5977 }
5978
c9c1d674
EG
5979 /* PR 17531: file: loop. */
5980 if (section->sh_entsize > section->sh_size)
5981 {
5982 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
5983 printable_section_name (section),
8066deb1
AM
5984 (unsigned long) section->sh_entsize,
5985 (unsigned long) section->sh_size);
c9c1d674
EG
5986 break;
5987 }
5988
3f5e193b
NC
5989 start = (unsigned char *) get_data (NULL, file, section->sh_offset,
5990 1, section->sh_size,
5991 _("section data"));
59245841
NC
5992 if (start == NULL)
5993 continue;
f5842774
L
5994
5995 indices = start;
5996 size = (section->sh_size / section->sh_entsize) - 1;
5997 entry = byte_get (indices, 4);
5998 indices += 4;
e4b17d5c
L
5999
6000 if (do_section_groups)
6001 {
2b692964 6002 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 6003 get_group_flags (entry), i, name, group_name, size);
ba2685cc 6004
e4b17d5c
L
6005 printf (_(" [Index] Name\n"));
6006 }
6007
6008 group->group_index = i;
6009
f5842774
L
6010 for (j = 0; j < size; j++)
6011 {
2cf0635d 6012 struct group_list * g;
e4b17d5c 6013
f5842774
L
6014 entry = byte_get (indices, 4);
6015 indices += 4;
6016
4fbb74a6 6017 if (entry >= elf_header.e_shnum)
391cb864 6018 {
57028622
NC
6019 static unsigned num_group_errors = 0;
6020
6021 if (num_group_errors ++ < 10)
6022 {
6023 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
6024 entry, i, elf_header.e_shnum - 1);
6025 if (num_group_errors == 10)
6026 warn (_("Futher error messages about overlarge group section indicies suppressed\n"));
6027 }
391cb864
L
6028 continue;
6029 }
391cb864 6030
4fbb74a6 6031 if (section_headers_groups [entry] != NULL)
e4b17d5c 6032 {
d1f5c6e3
L
6033 if (entry)
6034 {
57028622
NC
6035 static unsigned num_errs = 0;
6036
6037 if (num_errs ++ < 10)
6038 {
6039 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
6040 entry, i,
6041 section_headers_groups [entry]->group_index);
6042 if (num_errs == 10)
6043 warn (_("Further error messages about already contained group sections suppressed\n"));
6044 }
d1f5c6e3
L
6045 continue;
6046 }
6047 else
6048 {
6049 /* Intel C/C++ compiler may put section 0 in a
6050 section group. We just warn it the first time
6051 and ignore it afterwards. */
6052 static int warned = 0;
6053 if (!warned)
6054 {
6055 error (_("section 0 in group section [%5u]\n"),
4fbb74a6 6056 section_headers_groups [entry]->group_index);
d1f5c6e3
L
6057 warned++;
6058 }
6059 }
e4b17d5c
L
6060 }
6061
4fbb74a6 6062 section_headers_groups [entry] = group;
e4b17d5c
L
6063
6064 if (do_section_groups)
6065 {
4fbb74a6 6066 sec = section_headers + entry;
74e1a04b 6067 printf (" [%5u] %s\n", entry, printable_section_name (sec));
ba2685cc
AM
6068 }
6069
3f5e193b 6070 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
6071 g->section_index = entry;
6072 g->next = group->root;
6073 group->root = g;
f5842774
L
6074 }
6075
f5842774
L
6076 if (start)
6077 free (start);
e4b17d5c
L
6078
6079 group++;
f5842774
L
6080 }
6081 }
6082
d1f5c6e3
L
6083 if (symtab)
6084 free (symtab);
6085 if (strtab)
6086 free (strtab);
f5842774
L
6087 return 1;
6088}
6089
28f997cf
TG
6090/* Data used to display dynamic fixups. */
6091
6092struct ia64_vms_dynfixup
6093{
6094 bfd_vma needed_ident; /* Library ident number. */
6095 bfd_vma needed; /* Index in the dstrtab of the library name. */
6096 bfd_vma fixup_needed; /* Index of the library. */
6097 bfd_vma fixup_rela_cnt; /* Number of fixups. */
6098 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
6099};
6100
6101/* Data used to display dynamic relocations. */
6102
6103struct ia64_vms_dynimgrela
6104{
6105 bfd_vma img_rela_cnt; /* Number of relocations. */
6106 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
6107};
6108
6109/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
6110 library). */
6111
6112static void
6113dump_ia64_vms_dynamic_fixups (FILE *file, struct ia64_vms_dynfixup *fixup,
6114 const char *strtab, unsigned int strtab_sz)
6115{
6116 Elf64_External_VMS_IMAGE_FIXUP *imfs;
6117 long i;
6118 const char *lib_name;
6119
6120 imfs = get_data (NULL, file, dynamic_addr + fixup->fixup_rela_off,
6121 1, fixup->fixup_rela_cnt * sizeof (*imfs),
6122 _("dynamic section image fixups"));
6123 if (!imfs)
6124 return;
6125
6126 if (fixup->needed < strtab_sz)
6127 lib_name = strtab + fixup->needed;
6128 else
6129 {
6130 warn ("corrupt library name index of 0x%lx found in dynamic entry",
7f01b0c6 6131 (unsigned long) fixup->needed);
28f997cf
TG
6132 lib_name = "???";
6133 }
6134 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
6135 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
6136 printf
6137 (_("Seg Offset Type SymVec DataType\n"));
6138
6139 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
6140 {
6141 unsigned int type;
6142 const char *rtype;
6143
6144 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
6145 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
6146 type = BYTE_GET (imfs [i].type);
6147 rtype = elf_ia64_reloc_type (type);
6148 if (rtype == NULL)
6149 printf (" 0x%08x ", type);
6150 else
6151 printf (" %-32s ", rtype);
6152 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
6153 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
6154 }
6155
6156 free (imfs);
6157}
6158
6159/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
6160
6161static void
6162dump_ia64_vms_dynamic_relocs (FILE *file, struct ia64_vms_dynimgrela *imgrela)
6163{
6164 Elf64_External_VMS_IMAGE_RELA *imrs;
6165 long i;
6166
6167 imrs = get_data (NULL, file, dynamic_addr + imgrela->img_rela_off,
6168 1, imgrela->img_rela_cnt * sizeof (*imrs),
9cf03b7e 6169 _("dynamic section image relocations"));
28f997cf
TG
6170 if (!imrs)
6171 return;
6172
6173 printf (_("\nImage relocs\n"));
6174 printf
6175 (_("Seg Offset Type Addend Seg Sym Off\n"));
6176
6177 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
6178 {
6179 unsigned int type;
6180 const char *rtype;
6181
6182 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
6183 printf ("%08" BFD_VMA_FMT "x ",
6184 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
6185 type = BYTE_GET (imrs [i].type);
6186 rtype = elf_ia64_reloc_type (type);
6187 if (rtype == NULL)
6188 printf ("0x%08x ", type);
6189 else
6190 printf ("%-31s ", rtype);
6191 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
6192 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
6193 printf ("%08" BFD_VMA_FMT "x\n",
6194 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
6195 }
6196
6197 free (imrs);
6198}
6199
6200/* Display IA-64 OpenVMS dynamic relocations and fixups. */
6201
6202static int
6203process_ia64_vms_dynamic_relocs (FILE *file)
6204{
6205 struct ia64_vms_dynfixup fixup;
6206 struct ia64_vms_dynimgrela imgrela;
6207 Elf_Internal_Dyn *entry;
6208 int res = 0;
6209 bfd_vma strtab_off = 0;
6210 bfd_vma strtab_sz = 0;
6211 char *strtab = NULL;
6212
6213 memset (&fixup, 0, sizeof (fixup));
6214 memset (&imgrela, 0, sizeof (imgrela));
6215
6216 /* Note: the order of the entries is specified by the OpenVMS specs. */
6217 for (entry = dynamic_section;
6218 entry < dynamic_section + dynamic_nent;
6219 entry++)
6220 {
6221 switch (entry->d_tag)
6222 {
6223 case DT_IA_64_VMS_STRTAB_OFFSET:
6224 strtab_off = entry->d_un.d_val;
6225 break;
6226 case DT_STRSZ:
6227 strtab_sz = entry->d_un.d_val;
6228 if (strtab == NULL)
6229 strtab = get_data (NULL, file, dynamic_addr + strtab_off,
6230 1, strtab_sz, _("dynamic string section"));
6231 break;
6232
6233 case DT_IA_64_VMS_NEEDED_IDENT:
6234 fixup.needed_ident = entry->d_un.d_val;
6235 break;
6236 case DT_NEEDED:
6237 fixup.needed = entry->d_un.d_val;
6238 break;
6239 case DT_IA_64_VMS_FIXUP_NEEDED:
6240 fixup.fixup_needed = entry->d_un.d_val;
6241 break;
6242 case DT_IA_64_VMS_FIXUP_RELA_CNT:
6243 fixup.fixup_rela_cnt = entry->d_un.d_val;
6244 break;
6245 case DT_IA_64_VMS_FIXUP_RELA_OFF:
6246 fixup.fixup_rela_off = entry->d_un.d_val;
6247 res++;
6248 dump_ia64_vms_dynamic_fixups (file, &fixup, strtab, strtab_sz);
6249 break;
6250
6251 case DT_IA_64_VMS_IMG_RELA_CNT:
6252 imgrela.img_rela_cnt = entry->d_un.d_val;
6253 break;
6254 case DT_IA_64_VMS_IMG_RELA_OFF:
6255 imgrela.img_rela_off = entry->d_un.d_val;
6256 res++;
6257 dump_ia64_vms_dynamic_relocs (file, &imgrela);
6258 break;
6259
6260 default:
6261 break;
6262 }
6263 }
6264
6265 if (strtab != NULL)
6266 free (strtab);
6267
6268 return res;
6269}
6270
85b1c36d 6271static struct
566b0d53 6272{
2cf0635d 6273 const char * name;
566b0d53
L
6274 int reloc;
6275 int size;
6276 int rela;
6277} dynamic_relocations [] =
6278{
6279 { "REL", DT_REL, DT_RELSZ, FALSE },
6280 { "RELA", DT_RELA, DT_RELASZ, TRUE },
6281 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
6282};
6283
252b5132 6284/* Process the reloc section. */
18bd398b 6285
252b5132 6286static int
2cf0635d 6287process_relocs (FILE * file)
252b5132 6288{
b34976b6
AM
6289 unsigned long rel_size;
6290 unsigned long rel_offset;
252b5132
RH
6291
6292
6293 if (!do_reloc)
6294 return 1;
6295
6296 if (do_using_dynamic)
6297 {
566b0d53 6298 int is_rela;
2cf0635d 6299 const char * name;
566b0d53
L
6300 int has_dynamic_reloc;
6301 unsigned int i;
0de14b54 6302
566b0d53 6303 has_dynamic_reloc = 0;
252b5132 6304
566b0d53 6305 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 6306 {
566b0d53
L
6307 is_rela = dynamic_relocations [i].rela;
6308 name = dynamic_relocations [i].name;
6309 rel_size = dynamic_info [dynamic_relocations [i].size];
6310 rel_offset = dynamic_info [dynamic_relocations [i].reloc];
103f02d3 6311
566b0d53
L
6312 has_dynamic_reloc |= rel_size;
6313
6314 if (is_rela == UNKNOWN)
aa903cfb 6315 {
566b0d53
L
6316 if (dynamic_relocations [i].reloc == DT_JMPREL)
6317 switch (dynamic_info[DT_PLTREL])
6318 {
6319 case DT_REL:
6320 is_rela = FALSE;
6321 break;
6322 case DT_RELA:
6323 is_rela = TRUE;
6324 break;
6325 }
aa903cfb 6326 }
252b5132 6327
566b0d53
L
6328 if (rel_size)
6329 {
6330 printf
6331 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
6332 name, rel_offset, rel_size);
252b5132 6333
d93f0186
NC
6334 dump_relocations (file,
6335 offset_from_vma (file, rel_offset, rel_size),
6336 rel_size,
566b0d53 6337 dynamic_symbols, num_dynamic_syms,
bb4d2ac2
L
6338 dynamic_strings, dynamic_strings_length,
6339 is_rela, 1);
566b0d53 6340 }
252b5132 6341 }
566b0d53 6342
28f997cf
TG
6343 if (is_ia64_vms ())
6344 has_dynamic_reloc |= process_ia64_vms_dynamic_relocs (file);
6345
566b0d53 6346 if (! has_dynamic_reloc)
252b5132
RH
6347 printf (_("\nThere are no dynamic relocations in this file.\n"));
6348 }
6349 else
6350 {
2cf0635d 6351 Elf_Internal_Shdr * section;
b34976b6
AM
6352 unsigned long i;
6353 int found = 0;
252b5132
RH
6354
6355 for (i = 0, section = section_headers;
6356 i < elf_header.e_shnum;
b34976b6 6357 i++, section++)
252b5132
RH
6358 {
6359 if ( section->sh_type != SHT_RELA
6360 && section->sh_type != SHT_REL)
6361 continue;
6362
6363 rel_offset = section->sh_offset;
6364 rel_size = section->sh_size;
6365
6366 if (rel_size)
6367 {
2cf0635d 6368 Elf_Internal_Shdr * strsec;
b34976b6 6369 int is_rela;
103f02d3 6370
252b5132
RH
6371 printf (_("\nRelocation section "));
6372
6373 if (string_table == NULL)
19936277 6374 printf ("%d", section->sh_name);
252b5132 6375 else
74e1a04b 6376 printf ("'%s'", printable_section_name (section));
252b5132
RH
6377
6378 printf (_(" at offset 0x%lx contains %lu entries:\n"),
6379 rel_offset, (unsigned long) (rel_size / section->sh_entsize));
6380
d79b3d50
NC
6381 is_rela = section->sh_type == SHT_RELA;
6382
4fbb74a6
AM
6383 if (section->sh_link != 0
6384 && section->sh_link < elf_header.e_shnum)
af3fc3bc 6385 {
2cf0635d
NC
6386 Elf_Internal_Shdr * symsec;
6387 Elf_Internal_Sym * symtab;
d79b3d50 6388 unsigned long nsyms;
c256ffe7 6389 unsigned long strtablen = 0;
2cf0635d 6390 char * strtab = NULL;
57346661 6391
4fbb74a6 6392 symsec = section_headers + section->sh_link;
08d8fa11
JJ
6393 if (symsec->sh_type != SHT_SYMTAB
6394 && symsec->sh_type != SHT_DYNSYM)
6395 continue;
6396
ba5cdace 6397 symtab = GET_ELF_SYMBOLS (file, symsec, & nsyms);
252b5132 6398
af3fc3bc
AM
6399 if (symtab == NULL)
6400 continue;
252b5132 6401
4fbb74a6
AM
6402 if (symsec->sh_link != 0
6403 && symsec->sh_link < elf_header.e_shnum)
c256ffe7 6404 {
4fbb74a6 6405 strsec = section_headers + symsec->sh_link;
103f02d3 6406
3f5e193b 6407 strtab = (char *) get_data (NULL, file, strsec->sh_offset,
071436c6
NC
6408 1, strsec->sh_size,
6409 _("string table"));
c256ffe7
JJ
6410 strtablen = strtab == NULL ? 0 : strsec->sh_size;
6411 }
252b5132 6412
d79b3d50 6413 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2
L
6414 symtab, nsyms, strtab, strtablen,
6415 is_rela,
6416 symsec->sh_type == SHT_DYNSYM);
d79b3d50
NC
6417 if (strtab)
6418 free (strtab);
6419 free (symtab);
6420 }
6421 else
6422 dump_relocations (file, rel_offset, rel_size,
bb4d2ac2 6423 NULL, 0, NULL, 0, is_rela, 0);
252b5132
RH
6424
6425 found = 1;
6426 }
6427 }
6428
6429 if (! found)
6430 printf (_("\nThere are no relocations in this file.\n"));
6431 }
6432
6433 return 1;
6434}
6435
57346661
AM
6436/* Process the unwind section. */
6437
4d6ed7c8
NC
6438#include "unwind-ia64.h"
6439
6440/* An absolute address consists of a section and an offset. If the
6441 section is NULL, the offset itself is the address, otherwise, the
6442 address equals to LOAD_ADDRESS(section) + offset. */
6443
6444struct absaddr
6445 {
6446 unsigned short section;
6447 bfd_vma offset;
6448 };
6449
1949de15
L
6450#define ABSADDR(a) \
6451 ((a).section \
6452 ? section_headers [(a).section].sh_addr + (a).offset \
6453 : (a).offset)
6454
3f5e193b
NC
6455struct ia64_unw_table_entry
6456 {
6457 struct absaddr start;
6458 struct absaddr end;
6459 struct absaddr info;
6460 };
6461
57346661 6462struct ia64_unw_aux_info
4d6ed7c8 6463 {
3f5e193b
NC
6464
6465 struct ia64_unw_table_entry *table; /* Unwind table. */
b34976b6 6466 unsigned long table_len; /* Length of unwind table. */
2cf0635d 6467 unsigned char * info; /* Unwind info. */
b34976b6
AM
6468 unsigned long info_size; /* Size of unwind info. */
6469 bfd_vma info_addr; /* starting address of unwind info. */
6470 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6471 Elf_Internal_Sym * symtab; /* The symbol table. */
b34976b6 6472 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6473 char * strtab; /* The string table. */
b34976b6 6474 unsigned long strtab_size; /* Size of string table. */
4d6ed7c8
NC
6475 };
6476
4d6ed7c8 6477static void
2cf0635d 6478find_symbol_for_address (Elf_Internal_Sym * symtab,
57346661 6479 unsigned long nsyms,
2cf0635d 6480 const char * strtab,
57346661 6481 unsigned long strtab_size,
d3ba0551 6482 struct absaddr addr,
2cf0635d
NC
6483 const char ** symname,
6484 bfd_vma * offset)
4d6ed7c8 6485{
d3ba0551 6486 bfd_vma dist = 0x100000;
2cf0635d
NC
6487 Elf_Internal_Sym * sym;
6488 Elf_Internal_Sym * best = NULL;
4d6ed7c8
NC
6489 unsigned long i;
6490
0b6ae522
DJ
6491 REMOVE_ARCH_BITS (addr.offset);
6492
57346661 6493 for (i = 0, sym = symtab; i < nsyms; ++i, ++sym)
4d6ed7c8 6494 {
0b6ae522
DJ
6495 bfd_vma value = sym->st_value;
6496
6497 REMOVE_ARCH_BITS (value);
6498
4d6ed7c8
NC
6499 if (ELF_ST_TYPE (sym->st_info) == STT_FUNC
6500 && sym->st_name != 0
6501 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
6502 && addr.offset >= value
6503 && addr.offset - value < dist)
4d6ed7c8
NC
6504 {
6505 best = sym;
0b6ae522 6506 dist = addr.offset - value;
4d6ed7c8
NC
6507 if (!dist)
6508 break;
6509 }
6510 }
1b31d05e 6511
4d6ed7c8
NC
6512 if (best)
6513 {
57346661 6514 *symname = (best->st_name >= strtab_size
2b692964 6515 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
6516 *offset = dist;
6517 return;
6518 }
1b31d05e 6519
4d6ed7c8
NC
6520 *symname = NULL;
6521 *offset = addr.offset;
6522}
6523
6524static void
2cf0635d 6525dump_ia64_unwind (struct ia64_unw_aux_info * aux)
4d6ed7c8 6526{
2cf0635d 6527 struct ia64_unw_table_entry * tp;
4d6ed7c8 6528 int in_body;
7036c0e1 6529
4d6ed7c8
NC
6530 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6531 {
6532 bfd_vma stamp;
6533 bfd_vma offset;
2cf0635d
NC
6534 const unsigned char * dp;
6535 const unsigned char * head;
53774b7e 6536 const unsigned char * end;
2cf0635d 6537 const char * procname;
4d6ed7c8 6538
57346661
AM
6539 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6540 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
6541
6542 fputs ("\n<", stdout);
6543
6544 if (procname)
6545 {
6546 fputs (procname, stdout);
6547
6548 if (offset)
6549 printf ("+%lx", (unsigned long) offset);
6550 }
6551
6552 fputs (">: [", stdout);
6553 print_vma (tp->start.offset, PREFIX_HEX);
6554 fputc ('-', stdout);
6555 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 6556 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
6557 (unsigned long) (tp->info.offset - aux->seg_base));
6558
53774b7e
NC
6559 /* PR 17531: file: 86232b32. */
6560 if (aux->info == NULL)
6561 continue;
6562
6563 /* PR 17531: file: 0997b4d1. */
6564 if ((ABSADDR (tp->info) - aux->info_addr) >= aux->info_size)
6565 {
6566 warn (_("Invalid offset %lx in table entry %ld\n"),
6567 (long) tp->info.offset, (long) (tp - aux->table));
6568 continue;
6569 }
6570
1949de15 6571 head = aux->info + (ABSADDR (tp->info) - aux->info_addr);
a4a00738 6572 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 6573
86f55779 6574 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
6575 (unsigned) UNW_VER (stamp),
6576 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
6577 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
6578 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 6579 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
6580
6581 if (UNW_VER (stamp) != 1)
6582 {
2b692964 6583 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
6584 continue;
6585 }
6586
6587 in_body = 0;
53774b7e
NC
6588 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
6589 /* PR 17531: file: 16ceda89. */
6590 if (end > aux->info + aux->info_size)
6591 end = aux->info + aux->info_size;
6592 for (dp = head + 8; dp < end;)
4d6ed7c8
NC
6593 dp = unw_decode (dp, in_body, & in_body);
6594 }
6595}
6596
53774b7e 6597static bfd_boolean
2cf0635d
NC
6598slurp_ia64_unwind_table (FILE * file,
6599 struct ia64_unw_aux_info * aux,
6600 Elf_Internal_Shdr * sec)
4d6ed7c8 6601{
89fac5e3 6602 unsigned long size, nrelas, i;
2cf0635d
NC
6603 Elf_Internal_Phdr * seg;
6604 struct ia64_unw_table_entry * tep;
6605 Elf_Internal_Shdr * relsec;
6606 Elf_Internal_Rela * rela;
6607 Elf_Internal_Rela * rp;
6608 unsigned char * table;
6609 unsigned char * tp;
6610 Elf_Internal_Sym * sym;
6611 const char * relname;
4d6ed7c8 6612
53774b7e
NC
6613 aux->table_len = 0;
6614
4d6ed7c8
NC
6615 /* First, find the starting address of the segment that includes
6616 this section: */
6617
6618 if (elf_header.e_phnum)
6619 {
d93f0186 6620 if (! get_program_headers (file))
53774b7e 6621 return FALSE;
4d6ed7c8 6622
d93f0186
NC
6623 for (seg = program_headers;
6624 seg < program_headers + elf_header.e_phnum;
6625 ++seg)
4d6ed7c8
NC
6626 {
6627 if (seg->p_type != PT_LOAD)
6628 continue;
6629
6630 if (sec->sh_addr >= seg->p_vaddr
6631 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
6632 {
6633 aux->seg_base = seg->p_vaddr;
6634 break;
6635 }
6636 }
4d6ed7c8
NC
6637 }
6638
6639 /* Second, build the unwind table from the contents of the unwind section: */
6640 size = sec->sh_size;
3f5e193b
NC
6641 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
6642 _("unwind table"));
a6e9f9df 6643 if (!table)
53774b7e 6644 return FALSE;
4d6ed7c8 6645
53774b7e 6646 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 6647 aux->table = (struct ia64_unw_table_entry *)
53774b7e 6648 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 6649 tep = aux->table;
53774b7e
NC
6650
6651 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
6652 {
6653 tep->start.section = SHN_UNDEF;
6654 tep->end.section = SHN_UNDEF;
6655 tep->info.section = SHN_UNDEF;
c6a0c689
AM
6656 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6657 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
6658 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
6659 tep->start.offset += aux->seg_base;
6660 tep->end.offset += aux->seg_base;
6661 tep->info.offset += aux->seg_base;
6662 }
6663 free (table);
6664
41e92641 6665 /* Third, apply any relocations to the unwind table: */
4d6ed7c8
NC
6666 for (relsec = section_headers;
6667 relsec < section_headers + elf_header.e_shnum;
6668 ++relsec)
6669 {
6670 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
6671 || relsec->sh_info >= elf_header.e_shnum
6672 || section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
6673 continue;
6674
6675 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
6676 & rela, & nrelas))
53774b7e
NC
6677 {
6678 free (aux->table);
6679 aux->table = NULL;
6680 aux->table_len = 0;
6681 return FALSE;
6682 }
4d6ed7c8
NC
6683
6684 for (rp = rela; rp < rela + nrelas; ++rp)
6685 {
aca88567
NC
6686 relname = elf_ia64_reloc_type (get_reloc_type (rp->r_info));
6687 sym = aux->symtab + get_reloc_symindex (rp->r_info);
4d6ed7c8 6688
82b1b41b
NC
6689 /* PR 17531: file: 9fa67536. */
6690 if (relname == NULL)
6691 {
6692 warn (_("Skipping unknown relocation type: %u\n"), get_reloc_type (rp->r_info));
6693 continue;
6694 }
6695
0112cd26 6696 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 6697 {
82b1b41b 6698 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
6699 continue;
6700 }
6701
89fac5e3 6702 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 6703
53774b7e
NC
6704 /* PR 17531: file: 5bc8d9bf. */
6705 if (i >= aux->table_len)
6706 {
6707 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
6708 continue;
6709 }
6710
6711 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
6712 {
6713 case 0:
6714 aux->table[i].start.section = sym->st_shndx;
e466bc6e 6715 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6716 break;
6717 case 1:
6718 aux->table[i].end.section = sym->st_shndx;
e466bc6e 6719 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6720 break;
6721 case 2:
6722 aux->table[i].info.section = sym->st_shndx;
e466bc6e 6723 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
6724 break;
6725 default:
6726 break;
6727 }
6728 }
6729
6730 free (rela);
6731 }
6732
53774b7e 6733 return TRUE;
4d6ed7c8
NC
6734}
6735
1b31d05e 6736static void
2cf0635d 6737ia64_process_unwind (FILE * file)
4d6ed7c8 6738{
2cf0635d
NC
6739 Elf_Internal_Shdr * sec;
6740 Elf_Internal_Shdr * unwsec = NULL;
6741 Elf_Internal_Shdr * strsec;
89fac5e3 6742 unsigned long i, unwcount = 0, unwstart = 0;
57346661 6743 struct ia64_unw_aux_info aux;
f1467e33 6744
4d6ed7c8
NC
6745 memset (& aux, 0, sizeof (aux));
6746
4d6ed7c8
NC
6747 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
6748 {
c256ffe7 6749 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 6750 && sec->sh_link < elf_header.e_shnum)
4d6ed7c8 6751 {
ba5cdace 6752 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
4d6ed7c8 6753
4fbb74a6 6754 strsec = section_headers + sec->sh_link;
4082ef84
NC
6755 if (aux.strtab != NULL)
6756 {
6757 error (_("Multiple auxillary string tables encountered\n"));
6758 free (aux.strtab);
6759 }
3f5e193b
NC
6760 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
6761 1, strsec->sh_size,
6762 _("string table"));
c256ffe7 6763 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
4d6ed7c8
NC
6764 }
6765 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
6766 unwcount++;
6767 }
6768
6769 if (!unwcount)
6770 printf (_("\nThere are no unwind sections in this file.\n"));
6771
6772 while (unwcount-- > 0)
6773 {
2cf0635d 6774 char * suffix;
579f31ac
JJ
6775 size_t len, len2;
6776
4082ef84 6777 for (i = unwstart, sec = section_headers + unwstart, unwsec = NULL;
579f31ac
JJ
6778 i < elf_header.e_shnum; ++i, ++sec)
6779 if (sec->sh_type == SHT_IA_64_UNWIND)
6780 {
6781 unwsec = sec;
6782 break;
6783 }
4082ef84
NC
6784 /* We have already counted the number of SHT_IA64_UNWIND
6785 sections so the loop above should never fail. */
6786 assert (unwsec != NULL);
579f31ac
JJ
6787
6788 unwstart = i + 1;
6789 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
6790
e4b17d5c
L
6791 if ((unwsec->sh_flags & SHF_GROUP) != 0)
6792 {
6793 /* We need to find which section group it is in. */
4082ef84 6794 struct group_list * g;
e4b17d5c 6795
4082ef84
NC
6796 if (section_headers_groups == NULL
6797 || section_headers_groups [i] == NULL)
6798 i = elf_header.e_shnum;
6799 else
e4b17d5c 6800 {
4082ef84 6801 g = section_headers_groups [i]->root;
18bd398b 6802
4082ef84
NC
6803 for (; g != NULL; g = g->next)
6804 {
6805 sec = section_headers + g->section_index;
e4b17d5c 6806
4082ef84
NC
6807 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
6808 break;
6809 }
6810
6811 if (g == NULL)
6812 i = elf_header.e_shnum;
6813 }
e4b17d5c 6814 }
18bd398b 6815 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 6816 {
18bd398b 6817 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
6818 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
6819 suffix = SECTION_NAME (unwsec) + len;
6820 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6821 ++i, ++sec)
18bd398b
NC
6822 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
6823 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6824 break;
6825 }
6826 else
6827 {
6828 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 6829 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
6830 len = sizeof (ELF_STRING_ia64_unwind) - 1;
6831 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
6832 suffix = "";
18bd398b 6833 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac
JJ
6834 suffix = SECTION_NAME (unwsec) + len;
6835 for (i = 0, sec = section_headers; i < elf_header.e_shnum;
6836 ++i, ++sec)
18bd398b
NC
6837 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
6838 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
6839 break;
6840 }
6841
6842 if (i == elf_header.e_shnum)
6843 {
6844 printf (_("\nCould not find unwind info section for "));
6845
6846 if (string_table == NULL)
6847 printf ("%d", unwsec->sh_name);
6848 else
74e1a04b 6849 printf ("'%s'", printable_section_name (unwsec));
579f31ac
JJ
6850 }
6851 else
4d6ed7c8 6852 {
4d6ed7c8 6853 aux.info_addr = sec->sh_addr;
3f5e193b 6854 aux.info = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1,
4082ef84
NC
6855 sec->sh_size,
6856 _("unwind info"));
59245841 6857 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 6858
579f31ac 6859 printf (_("\nUnwind section "));
4d6ed7c8 6860
579f31ac
JJ
6861 if (string_table == NULL)
6862 printf ("%d", unwsec->sh_name);
6863 else
74e1a04b 6864 printf ("'%s'", printable_section_name (unwsec));
4d6ed7c8 6865
579f31ac 6866 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 6867 (unsigned long) unwsec->sh_offset,
89fac5e3 6868 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 6869
53774b7e
NC
6870 if (slurp_ia64_unwind_table (file, & aux, unwsec)
6871 && aux.table_len > 0)
579f31ac
JJ
6872 dump_ia64_unwind (& aux);
6873
6874 if (aux.table)
6875 free ((char *) aux.table);
6876 if (aux.info)
6877 free ((char *) aux.info);
6878 aux.table = NULL;
6879 aux.info = NULL;
6880 }
4d6ed7c8 6881 }
4d6ed7c8 6882
4d6ed7c8
NC
6883 if (aux.symtab)
6884 free (aux.symtab);
6885 if (aux.strtab)
6886 free ((char *) aux.strtab);
4d6ed7c8
NC
6887}
6888
3f5e193b
NC
6889struct hppa_unw_table_entry
6890 {
6891 struct absaddr start;
6892 struct absaddr end;
6893 unsigned int Cannot_unwind:1; /* 0 */
6894 unsigned int Millicode:1; /* 1 */
6895 unsigned int Millicode_save_sr0:1; /* 2 */
6896 unsigned int Region_description:2; /* 3..4 */
6897 unsigned int reserved1:1; /* 5 */
6898 unsigned int Entry_SR:1; /* 6 */
6899 unsigned int Entry_FR:4; /* number saved */ /* 7..10 */
6900 unsigned int Entry_GR:5; /* number saved */ /* 11..15 */
6901 unsigned int Args_stored:1; /* 16 */
6902 unsigned int Variable_Frame:1; /* 17 */
6903 unsigned int Separate_Package_Body:1; /* 18 */
6904 unsigned int Frame_Extension_Millicode:1; /* 19 */
6905 unsigned int Stack_Overflow_Check:1; /* 20 */
6906 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
6907 unsigned int Ada_Region:1; /* 22 */
6908 unsigned int cxx_info:1; /* 23 */
6909 unsigned int cxx_try_catch:1; /* 24 */
6910 unsigned int sched_entry_seq:1; /* 25 */
6911 unsigned int reserved2:1; /* 26 */
6912 unsigned int Save_SP:1; /* 27 */
6913 unsigned int Save_RP:1; /* 28 */
6914 unsigned int Save_MRP_in_frame:1; /* 29 */
6915 unsigned int extn_ptr_defined:1; /* 30 */
6916 unsigned int Cleanup_defined:1; /* 31 */
6917
6918 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
6919 unsigned int HP_UX_interrupt_marker:1; /* 1 */
6920 unsigned int Large_frame:1; /* 2 */
6921 unsigned int Pseudo_SP_Set:1; /* 3 */
6922 unsigned int reserved4:1; /* 4 */
6923 unsigned int Total_frame_size:27; /* 5..31 */
6924 };
6925
57346661
AM
6926struct hppa_unw_aux_info
6927 {
3f5e193b 6928 struct hppa_unw_table_entry *table; /* Unwind table. */
57346661
AM
6929 unsigned long table_len; /* Length of unwind table. */
6930 bfd_vma seg_base; /* Starting address of segment. */
2cf0635d 6931 Elf_Internal_Sym * symtab; /* The symbol table. */
57346661 6932 unsigned long nsyms; /* Number of symbols. */
2cf0635d 6933 char * strtab; /* The string table. */
57346661
AM
6934 unsigned long strtab_size; /* Size of string table. */
6935 };
6936
6937static void
2cf0635d 6938dump_hppa_unwind (struct hppa_unw_aux_info * aux)
57346661 6939{
2cf0635d 6940 struct hppa_unw_table_entry * tp;
57346661 6941
57346661
AM
6942 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
6943 {
6944 bfd_vma offset;
2cf0635d 6945 const char * procname;
57346661
AM
6946
6947 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
6948 aux->strtab_size, tp->start, &procname,
6949 &offset);
6950
6951 fputs ("\n<", stdout);
6952
6953 if (procname)
6954 {
6955 fputs (procname, stdout);
6956
6957 if (offset)
6958 printf ("+%lx", (unsigned long) offset);
6959 }
6960
6961 fputs (">: [", stdout);
6962 print_vma (tp->start.offset, PREFIX_HEX);
6963 fputc ('-', stdout);
6964 print_vma (tp->end.offset, PREFIX_HEX);
6965 printf ("]\n\t");
6966
18bd398b
NC
6967#define PF(_m) if (tp->_m) printf (#_m " ");
6968#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
6969 PF(Cannot_unwind);
6970 PF(Millicode);
6971 PF(Millicode_save_sr0);
18bd398b 6972 /* PV(Region_description); */
57346661
AM
6973 PF(Entry_SR);
6974 PV(Entry_FR);
6975 PV(Entry_GR);
6976 PF(Args_stored);
6977 PF(Variable_Frame);
6978 PF(Separate_Package_Body);
6979 PF(Frame_Extension_Millicode);
6980 PF(Stack_Overflow_Check);
6981 PF(Two_Instruction_SP_Increment);
6982 PF(Ada_Region);
6983 PF(cxx_info);
6984 PF(cxx_try_catch);
6985 PF(sched_entry_seq);
6986 PF(Save_SP);
6987 PF(Save_RP);
6988 PF(Save_MRP_in_frame);
6989 PF(extn_ptr_defined);
6990 PF(Cleanup_defined);
6991 PF(MPE_XL_interrupt_marker);
6992 PF(HP_UX_interrupt_marker);
6993 PF(Large_frame);
6994 PF(Pseudo_SP_Set);
6995 PV(Total_frame_size);
6996#undef PF
6997#undef PV
6998 }
6999
18bd398b 7000 printf ("\n");
57346661
AM
7001}
7002
7003static int
2cf0635d
NC
7004slurp_hppa_unwind_table (FILE * file,
7005 struct hppa_unw_aux_info * aux,
7006 Elf_Internal_Shdr * sec)
57346661 7007{
1c0751b2 7008 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
7009 Elf_Internal_Phdr * seg;
7010 struct hppa_unw_table_entry * tep;
7011 Elf_Internal_Shdr * relsec;
7012 Elf_Internal_Rela * rela;
7013 Elf_Internal_Rela * rp;
7014 unsigned char * table;
7015 unsigned char * tp;
7016 Elf_Internal_Sym * sym;
7017 const char * relname;
57346661 7018
57346661
AM
7019 /* First, find the starting address of the segment that includes
7020 this section. */
7021
7022 if (elf_header.e_phnum)
7023 {
7024 if (! get_program_headers (file))
7025 return 0;
7026
7027 for (seg = program_headers;
7028 seg < program_headers + elf_header.e_phnum;
7029 ++seg)
7030 {
7031 if (seg->p_type != PT_LOAD)
7032 continue;
7033
7034 if (sec->sh_addr >= seg->p_vaddr
7035 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7036 {
7037 aux->seg_base = seg->p_vaddr;
7038 break;
7039 }
7040 }
7041 }
7042
7043 /* Second, build the unwind table from the contents of the unwind
7044 section. */
7045 size = sec->sh_size;
3f5e193b
NC
7046 table = (unsigned char *) get_data (NULL, file, sec->sh_offset, 1, size,
7047 _("unwind table"));
57346661
AM
7048 if (!table)
7049 return 0;
7050
1c0751b2
DA
7051 unw_ent_size = 16;
7052 nentries = size / unw_ent_size;
7053 size = unw_ent_size * nentries;
57346661 7054
3f5e193b
NC
7055 tep = aux->table = (struct hppa_unw_table_entry *)
7056 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 7057
1c0751b2 7058 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
7059 {
7060 unsigned int tmp1, tmp2;
7061
7062 tep->start.section = SHN_UNDEF;
7063 tep->end.section = SHN_UNDEF;
7064
1c0751b2
DA
7065 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
7066 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
7067 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
7068 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
7069
7070 tep->start.offset += aux->seg_base;
7071 tep->end.offset += aux->seg_base;
57346661
AM
7072
7073 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
7074 tep->Millicode = (tmp1 >> 30) & 0x1;
7075 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
7076 tep->Region_description = (tmp1 >> 27) & 0x3;
7077 tep->reserved1 = (tmp1 >> 26) & 0x1;
7078 tep->Entry_SR = (tmp1 >> 25) & 0x1;
7079 tep->Entry_FR = (tmp1 >> 21) & 0xf;
7080 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
7081 tep->Args_stored = (tmp1 >> 15) & 0x1;
7082 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
7083 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
7084 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
7085 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
7086 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
7087 tep->Ada_Region = (tmp1 >> 9) & 0x1;
7088 tep->cxx_info = (tmp1 >> 8) & 0x1;
7089 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
7090 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
7091 tep->reserved2 = (tmp1 >> 5) & 0x1;
7092 tep->Save_SP = (tmp1 >> 4) & 0x1;
7093 tep->Save_RP = (tmp1 >> 3) & 0x1;
7094 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
7095 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
7096 tep->Cleanup_defined = tmp1 & 0x1;
7097
7098 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
7099 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
7100 tep->Large_frame = (tmp2 >> 29) & 0x1;
7101 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
7102 tep->reserved4 = (tmp2 >> 27) & 0x1;
7103 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
7104 }
7105 free (table);
7106
7107 /* Third, apply any relocations to the unwind table. */
57346661
AM
7108 for (relsec = section_headers;
7109 relsec < section_headers + elf_header.e_shnum;
7110 ++relsec)
7111 {
7112 if (relsec->sh_type != SHT_RELA
4fbb74a6
AM
7113 || relsec->sh_info >= elf_header.e_shnum
7114 || section_headers + relsec->sh_info != sec)
57346661
AM
7115 continue;
7116
7117 if (!slurp_rela_relocs (file, relsec->sh_offset, relsec->sh_size,
7118 & rela, & nrelas))
7119 return 0;
7120
7121 for (rp = rela; rp < rela + nrelas; ++rp)
7122 {
aca88567
NC
7123 relname = elf_hppa_reloc_type (get_reloc_type (rp->r_info));
7124 sym = aux->symtab + get_reloc_symindex (rp->r_info);
57346661
AM
7125
7126 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 7127 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661
AM
7128 {
7129 warn (_("Skipping unexpected relocation type %s\n"), relname);
7130 continue;
7131 }
7132
7133 i = rp->r_offset / unw_ent_size;
7134
89fac5e3 7135 switch ((rp->r_offset % unw_ent_size) / eh_addr_size)
57346661
AM
7136 {
7137 case 0:
7138 aux->table[i].start.section = sym->st_shndx;
1e456d54 7139 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
7140 break;
7141 case 1:
7142 aux->table[i].end.section = sym->st_shndx;
1e456d54 7143 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
7144 break;
7145 default:
7146 break;
7147 }
7148 }
7149
7150 free (rela);
7151 }
7152
1c0751b2 7153 aux->table_len = nentries;
57346661
AM
7154
7155 return 1;
7156}
7157
1b31d05e 7158static void
2cf0635d 7159hppa_process_unwind (FILE * file)
57346661 7160{
57346661 7161 struct hppa_unw_aux_info aux;
2cf0635d
NC
7162 Elf_Internal_Shdr * unwsec = NULL;
7163 Elf_Internal_Shdr * strsec;
7164 Elf_Internal_Shdr * sec;
18bd398b 7165 unsigned long i;
57346661 7166
c256ffe7 7167 if (string_table == NULL)
1b31d05e
NC
7168 return;
7169
7170 memset (& aux, 0, sizeof (aux));
57346661
AM
7171
7172 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7173 {
c256ffe7 7174 if (sec->sh_type == SHT_SYMTAB
4fbb74a6 7175 && sec->sh_link < elf_header.e_shnum)
57346661 7176 {
ba5cdace 7177 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
57346661 7178
4fbb74a6 7179 strsec = section_headers + sec->sh_link;
4082ef84
NC
7180 if (aux.strtab != NULL)
7181 {
7182 error (_("Multiple auxillary string tables encountered\n"));
7183 free (aux.strtab);
7184 }
3f5e193b
NC
7185 aux.strtab = (char *) get_data (NULL, file, strsec->sh_offset,
7186 1, strsec->sh_size,
7187 _("string table"));
c256ffe7 7188 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
57346661 7189 }
18bd398b 7190 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
7191 unwsec = sec;
7192 }
7193
7194 if (!unwsec)
7195 printf (_("\nThere are no unwind sections in this file.\n"));
7196
7197 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
7198 {
18bd398b 7199 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 7200 {
74e1a04b
NC
7201 printf (_("\nUnwind section '%s' at offset 0x%lx contains %lu entries:\n"),
7202 printable_section_name (sec),
57346661 7203 (unsigned long) sec->sh_offset,
89fac5e3 7204 (unsigned long) (sec->sh_size / (2 * eh_addr_size + 8)));
57346661
AM
7205
7206 slurp_hppa_unwind_table (file, &aux, sec);
7207 if (aux.table_len > 0)
7208 dump_hppa_unwind (&aux);
7209
7210 if (aux.table)
7211 free ((char *) aux.table);
7212 aux.table = NULL;
7213 }
7214 }
7215
7216 if (aux.symtab)
7217 free (aux.symtab);
7218 if (aux.strtab)
7219 free ((char *) aux.strtab);
57346661
AM
7220}
7221
0b6ae522
DJ
7222struct arm_section
7223{
a734115a
NC
7224 unsigned char * data; /* The unwind data. */
7225 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
7226 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
7227 unsigned long nrelas; /* The number of relocations. */
7228 unsigned int rel_type; /* REL or RELA ? */
7229 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
7230};
7231
7232struct arm_unw_aux_info
7233{
a734115a
NC
7234 FILE * file; /* The file containing the unwind sections. */
7235 Elf_Internal_Sym * symtab; /* The file's symbol table. */
7236 unsigned long nsyms; /* Number of symbols. */
7237 char * strtab; /* The file's string table. */
7238 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
7239};
7240
7241static const char *
7242arm_print_vma_and_name (struct arm_unw_aux_info *aux,
7243 bfd_vma fn, struct absaddr addr)
7244{
7245 const char *procname;
7246 bfd_vma sym_offset;
7247
7248 if (addr.section == SHN_UNDEF)
7249 addr.offset = fn;
7250
7251 find_symbol_for_address (aux->symtab, aux->nsyms, aux->strtab,
7252 aux->strtab_size, addr, &procname,
7253 &sym_offset);
7254
7255 print_vma (fn, PREFIX_HEX);
7256
7257 if (procname)
7258 {
7259 fputs (" <", stdout);
7260 fputs (procname, stdout);
7261
7262 if (sym_offset)
7263 printf ("+0x%lx", (unsigned long) sym_offset);
7264 fputc ('>', stdout);
7265 }
7266
7267 return procname;
7268}
7269
7270static void
7271arm_free_section (struct arm_section *arm_sec)
7272{
7273 if (arm_sec->data != NULL)
7274 free (arm_sec->data);
7275
7276 if (arm_sec->rela != NULL)
7277 free (arm_sec->rela);
7278}
7279
a734115a
NC
7280/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
7281 cached section and install SEC instead.
7282 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
7283 and return its valued in * WORDP, relocating if necessary.
1b31d05e 7284 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 7285 relocation's offset in ADDR.
1b31d05e
NC
7286 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
7287 into the string table of the symbol associated with the reloc. If no
7288 reloc was applied store -1 there.
7289 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
7290
7291static bfd_boolean
1b31d05e
NC
7292get_unwind_section_word (struct arm_unw_aux_info * aux,
7293 struct arm_section * arm_sec,
7294 Elf_Internal_Shdr * sec,
7295 bfd_vma word_offset,
7296 unsigned int * wordp,
7297 struct absaddr * addr,
7298 bfd_vma * sym_name)
0b6ae522
DJ
7299{
7300 Elf_Internal_Rela *rp;
7301 Elf_Internal_Sym *sym;
7302 const char * relname;
7303 unsigned int word;
7304 bfd_boolean wrapped;
7305
e0a31db1
NC
7306 if (sec == NULL || arm_sec == NULL)
7307 return FALSE;
7308
0b6ae522
DJ
7309 addr->section = SHN_UNDEF;
7310 addr->offset = 0;
7311
1b31d05e
NC
7312 if (sym_name != NULL)
7313 *sym_name = (bfd_vma) -1;
7314
a734115a 7315 /* If necessary, update the section cache. */
0b6ae522
DJ
7316 if (sec != arm_sec->sec)
7317 {
7318 Elf_Internal_Shdr *relsec;
7319
7320 arm_free_section (arm_sec);
7321
7322 arm_sec->sec = sec;
7323 arm_sec->data = get_data (NULL, aux->file, sec->sh_offset, 1,
7324 sec->sh_size, _("unwind data"));
0b6ae522
DJ
7325 arm_sec->rela = NULL;
7326 arm_sec->nrelas = 0;
7327
7328 for (relsec = section_headers;
7329 relsec < section_headers + elf_header.e_shnum;
7330 ++relsec)
7331 {
7332 if (relsec->sh_info >= elf_header.e_shnum
1ae40aa4
NC
7333 || section_headers + relsec->sh_info != sec
7334 /* PR 15745: Check the section type as well. */
7335 || (relsec->sh_type != SHT_REL
7336 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
7337 continue;
7338
a734115a 7339 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
7340 if (relsec->sh_type == SHT_REL)
7341 {
7342 if (!slurp_rel_relocs (aux->file, relsec->sh_offset,
7343 relsec->sh_size,
7344 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7345 return FALSE;
0b6ae522 7346 }
1ae40aa4 7347 else /* relsec->sh_type == SHT_RELA */
0b6ae522
DJ
7348 {
7349 if (!slurp_rela_relocs (aux->file, relsec->sh_offset,
7350 relsec->sh_size,
7351 & arm_sec->rela, & arm_sec->nrelas))
a734115a 7352 return FALSE;
0b6ae522 7353 }
1ae40aa4 7354 break;
0b6ae522
DJ
7355 }
7356
7357 arm_sec->next_rela = arm_sec->rela;
7358 }
7359
a734115a 7360 /* If there is no unwind data we can do nothing. */
0b6ae522 7361 if (arm_sec->data == NULL)
a734115a 7362 return FALSE;
0b6ae522 7363
e0a31db1
NC
7364 /* If the offset is invalid then fail. */
7365 if (word_offset > sec->sh_size - 4)
7366 return FALSE;
7367
a734115a 7368 /* Get the word at the required offset. */
0b6ae522
DJ
7369 word = byte_get (arm_sec->data + word_offset, 4);
7370
0eff7165
NC
7371 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
7372 if (arm_sec->rela == NULL)
7373 {
7374 * wordp = word;
7375 return TRUE;
7376 }
7377
a734115a 7378 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
7379 wrapped = FALSE;
7380 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
7381 {
7382 bfd_vma prelval, offset;
7383
7384 if (rp->r_offset > word_offset && !wrapped)
7385 {
7386 rp = arm_sec->rela;
7387 wrapped = TRUE;
7388 }
7389 if (rp->r_offset > word_offset)
7390 break;
7391
7392 if (rp->r_offset & 3)
7393 {
7394 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
7395 (unsigned long) rp->r_offset);
7396 continue;
7397 }
7398
7399 if (rp->r_offset < word_offset)
7400 continue;
7401
74e1a04b
NC
7402 /* PR 17531: file: 027-161405-0.004 */
7403 if (aux->symtab == NULL)
7404 continue;
7405
0b6ae522
DJ
7406 if (arm_sec->rel_type == SHT_REL)
7407 {
7408 offset = word & 0x7fffffff;
7409 if (offset & 0x40000000)
7410 offset |= ~ (bfd_vma) 0x7fffffff;
7411 }
a734115a 7412 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 7413 offset = rp->r_addend;
a734115a 7414 else
74e1a04b
NC
7415 {
7416 error (_("Unknown section relocation type %d encountered\n"),
7417 arm_sec->rel_type);
7418 break;
7419 }
0b6ae522 7420
071436c6
NC
7421 /* PR 17531 file: 027-1241568-0.004. */
7422 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
7423 {
7424 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
7425 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
7426 break;
7427 }
7428
7429 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
7430 offset += sym->st_value;
7431 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
7432
a734115a
NC
7433 /* Check that we are processing the expected reloc type. */
7434 if (elf_header.e_machine == EM_ARM)
7435 {
7436 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7437 if (relname == NULL)
7438 {
7439 warn (_("Skipping unknown ARM relocation type: %d\n"),
7440 (int) ELF32_R_TYPE (rp->r_info));
7441 continue;
7442 }
a734115a
NC
7443
7444 if (streq (relname, "R_ARM_NONE"))
7445 continue;
0b4362b0 7446
a734115a
NC
7447 if (! streq (relname, "R_ARM_PREL31"))
7448 {
071436c6 7449 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
7450 continue;
7451 }
7452 }
7453 else if (elf_header.e_machine == EM_TI_C6000)
7454 {
7455 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
7456 if (relname == NULL)
7457 {
7458 warn (_("Skipping unknown C6000 relocation type: %d\n"),
7459 (int) ELF32_R_TYPE (rp->r_info));
7460 continue;
7461 }
0b4362b0 7462
a734115a
NC
7463 if (streq (relname, "R_C6000_NONE"))
7464 continue;
7465
7466 if (! streq (relname, "R_C6000_PREL31"))
7467 {
071436c6 7468 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
7469 continue;
7470 }
7471
7472 prelval >>= 1;
7473 }
7474 else
74e1a04b
NC
7475 {
7476 /* This function currently only supports ARM and TI unwinders. */
7477 warn (_("Only TI and ARM unwinders are currently supported\n"));
7478 break;
7479 }
fa197c1c 7480
0b6ae522
DJ
7481 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
7482 addr->section = sym->st_shndx;
7483 addr->offset = offset;
74e1a04b 7484
1b31d05e
NC
7485 if (sym_name)
7486 * sym_name = sym->st_name;
0b6ae522
DJ
7487 break;
7488 }
7489
7490 *wordp = word;
7491 arm_sec->next_rela = rp;
7492
a734115a 7493 return TRUE;
0b6ae522
DJ
7494}
7495
a734115a
NC
7496static const char *tic6x_unwind_regnames[16] =
7497{
0b4362b0
RM
7498 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
7499 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
7500 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
7501};
fa197c1c 7502
0b6ae522 7503static void
fa197c1c 7504decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 7505{
fa197c1c
PB
7506 int i;
7507
7508 for (i = 12; mask; mask >>= 1, i--)
7509 {
7510 if (mask & 1)
7511 {
7512 fputs (tic6x_unwind_regnames[i], stdout);
7513 if (mask > 1)
7514 fputs (", ", stdout);
7515 }
7516 }
7517}
0b6ae522
DJ
7518
7519#define ADVANCE \
7520 if (remaining == 0 && more_words) \
7521 { \
7522 data_offset += 4; \
1b31d05e
NC
7523 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, \
7524 data_offset, & word, & addr, NULL)) \
0b6ae522
DJ
7525 return; \
7526 remaining = 4; \
7527 more_words--; \
7528 } \
7529
7530#define GET_OP(OP) \
7531 ADVANCE; \
7532 if (remaining) \
7533 { \
7534 remaining--; \
7535 (OP) = word >> 24; \
7536 word <<= 8; \
7537 } \
7538 else \
7539 { \
2b692964 7540 printf (_("[Truncated opcode]\n")); \
0b6ae522
DJ
7541 return; \
7542 } \
cc5914eb 7543 printf ("0x%02x ", OP)
0b6ae522 7544
fa197c1c
PB
7545static void
7546decode_arm_unwind_bytecode (struct arm_unw_aux_info *aux,
7547 unsigned int word, unsigned int remaining,
7548 unsigned int more_words,
7549 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7550 struct arm_section *data_arm_sec)
7551{
7552 struct absaddr addr;
0b6ae522
DJ
7553
7554 /* Decode the unwinding instructions. */
7555 while (1)
7556 {
7557 unsigned int op, op2;
7558
7559 ADVANCE;
7560 if (remaining == 0)
7561 break;
7562 remaining--;
7563 op = word >> 24;
7564 word <<= 8;
7565
cc5914eb 7566 printf (" 0x%02x ", op);
0b6ae522
DJ
7567
7568 if ((op & 0xc0) == 0x00)
7569 {
7570 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7571
cc5914eb 7572 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
7573 }
7574 else if ((op & 0xc0) == 0x40)
7575 {
7576 int offset = ((op & 0x3f) << 2) + 4;
61865e30 7577
cc5914eb 7578 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
7579 }
7580 else if ((op & 0xf0) == 0x80)
7581 {
7582 GET_OP (op2);
7583 if (op == 0x80 && op2 == 0)
7584 printf (_("Refuse to unwind"));
7585 else
7586 {
7587 unsigned int mask = ((op & 0x0f) << 8) | op2;
7588 int first = 1;
7589 int i;
2b692964 7590
0b6ae522
DJ
7591 printf ("pop {");
7592 for (i = 0; i < 12; i++)
7593 if (mask & (1 << i))
7594 {
7595 if (first)
7596 first = 0;
7597 else
7598 printf (", ");
7599 printf ("r%d", 4 + i);
7600 }
7601 printf ("}");
7602 }
7603 }
7604 else if ((op & 0xf0) == 0x90)
7605 {
7606 if (op == 0x9d || op == 0x9f)
7607 printf (_(" [Reserved]"));
7608 else
cc5914eb 7609 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
7610 }
7611 else if ((op & 0xf0) == 0xa0)
7612 {
7613 int end = 4 + (op & 0x07);
7614 int first = 1;
7615 int i;
61865e30 7616
0b6ae522
DJ
7617 printf (" pop {");
7618 for (i = 4; i <= end; i++)
7619 {
7620 if (first)
7621 first = 0;
7622 else
7623 printf (", ");
7624 printf ("r%d", i);
7625 }
7626 if (op & 0x08)
7627 {
1b31d05e 7628 if (!first)
0b6ae522
DJ
7629 printf (", ");
7630 printf ("r14");
7631 }
7632 printf ("}");
7633 }
7634 else if (op == 0xb0)
7635 printf (_(" finish"));
7636 else if (op == 0xb1)
7637 {
7638 GET_OP (op2);
7639 if (op2 == 0 || (op2 & 0xf0) != 0)
7640 printf (_("[Spare]"));
7641 else
7642 {
7643 unsigned int mask = op2 & 0x0f;
7644 int first = 1;
7645 int i;
61865e30 7646
0b6ae522
DJ
7647 printf ("pop {");
7648 for (i = 0; i < 12; i++)
7649 if (mask & (1 << i))
7650 {
7651 if (first)
7652 first = 0;
7653 else
7654 printf (", ");
7655 printf ("r%d", i);
7656 }
7657 printf ("}");
7658 }
7659 }
7660 else if (op == 0xb2)
7661 {
b115cf96 7662 unsigned char buf[9];
0b6ae522
DJ
7663 unsigned int i, len;
7664 unsigned long offset;
61865e30 7665
b115cf96 7666 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
7667 {
7668 GET_OP (buf[i]);
7669 if ((buf[i] & 0x80) == 0)
7670 break;
7671 }
4082ef84
NC
7672 if (i == sizeof (buf))
7673 printf (_("corrupt change to vsp"));
7674 else
7675 {
7676 offset = read_uleb128 (buf, &len, buf + i + 1);
7677 assert (len == i + 1);
7678 offset = offset * 4 + 0x204;
7679 printf ("vsp = vsp + %ld", offset);
7680 }
0b6ae522 7681 }
61865e30 7682 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 7683 {
61865e30
NC
7684 unsigned int first, last;
7685
7686 GET_OP (op2);
7687 first = op2 >> 4;
7688 last = op2 & 0x0f;
7689 if (op == 0xc8)
7690 first = first + 16;
7691 printf ("pop {D%d", first);
7692 if (last)
7693 printf ("-D%d", first + last);
7694 printf ("}");
7695 }
7696 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
7697 {
7698 unsigned int count = op & 0x07;
7699
7700 printf ("pop {D8");
7701 if (count)
7702 printf ("-D%d", 8 + count);
7703 printf ("}");
7704 }
7705 else if (op >= 0xc0 && op <= 0xc5)
7706 {
7707 unsigned int count = op & 0x07;
7708
7709 printf (" pop {wR10");
7710 if (count)
7711 printf ("-wR%d", 10 + count);
7712 printf ("}");
7713 }
7714 else if (op == 0xc6)
7715 {
7716 unsigned int first, last;
7717
7718 GET_OP (op2);
7719 first = op2 >> 4;
7720 last = op2 & 0x0f;
7721 printf ("pop {wR%d", first);
7722 if (last)
7723 printf ("-wR%d", first + last);
7724 printf ("}");
7725 }
7726 else if (op == 0xc7)
7727 {
7728 GET_OP (op2);
7729 if (op2 == 0 || (op2 & 0xf0) != 0)
7730 printf (_("[Spare]"));
0b6ae522
DJ
7731 else
7732 {
61865e30
NC
7733 unsigned int mask = op2 & 0x0f;
7734 int first = 1;
7735 int i;
7736
7737 printf ("pop {");
7738 for (i = 0; i < 4; i++)
7739 if (mask & (1 << i))
7740 {
7741 if (first)
7742 first = 0;
7743 else
7744 printf (", ");
7745 printf ("wCGR%d", i);
7746 }
7747 printf ("}");
0b6ae522
DJ
7748 }
7749 }
61865e30
NC
7750 else
7751 printf (_(" [unsupported opcode]"));
0b6ae522
DJ
7752 printf ("\n");
7753 }
fa197c1c
PB
7754}
7755
7756static void
7757decode_tic6x_unwind_bytecode (struct arm_unw_aux_info *aux,
7758 unsigned int word, unsigned int remaining,
7759 unsigned int more_words,
7760 bfd_vma data_offset, Elf_Internal_Shdr *data_sec,
7761 struct arm_section *data_arm_sec)
7762{
7763 struct absaddr addr;
7764
7765 /* Decode the unwinding instructions. */
7766 while (1)
7767 {
7768 unsigned int op, op2;
7769
7770 ADVANCE;
7771 if (remaining == 0)
7772 break;
7773 remaining--;
7774 op = word >> 24;
7775 word <<= 8;
7776
9cf03b7e 7777 printf (" 0x%02x ", op);
fa197c1c
PB
7778
7779 if ((op & 0xc0) == 0x00)
7780 {
7781 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 7782 printf (" sp = sp + %d", offset);
fa197c1c
PB
7783 }
7784 else if ((op & 0xc0) == 0x80)
7785 {
7786 GET_OP (op2);
7787 if (op == 0x80 && op2 == 0)
7788 printf (_("Refuse to unwind"));
7789 else
7790 {
7791 unsigned int mask = ((op & 0x1f) << 8) | op2;
7792 if (op & 0x20)
7793 printf ("pop compact {");
7794 else
7795 printf ("pop {");
7796
7797 decode_tic6x_unwind_regmask (mask);
7798 printf("}");
7799 }
7800 }
7801 else if ((op & 0xf0) == 0xc0)
7802 {
7803 unsigned int reg;
7804 unsigned int nregs;
7805 unsigned int i;
7806 const char *name;
a734115a
NC
7807 struct
7808 {
fa197c1c
PB
7809 unsigned int offset;
7810 unsigned int reg;
7811 } regpos[16];
7812
7813 /* Scan entire instruction first so that GET_OP output is not
7814 interleaved with disassembly. */
7815 nregs = 0;
7816 for (i = 0; nregs < (op & 0xf); i++)
7817 {
7818 GET_OP (op2);
7819 reg = op2 >> 4;
7820 if (reg != 0xf)
7821 {
7822 regpos[nregs].offset = i * 2;
7823 regpos[nregs].reg = reg;
7824 nregs++;
7825 }
7826
7827 reg = op2 & 0xf;
7828 if (reg != 0xf)
7829 {
7830 regpos[nregs].offset = i * 2 + 1;
7831 regpos[nregs].reg = reg;
7832 nregs++;
7833 }
7834 }
7835
7836 printf (_("pop frame {"));
7837 reg = nregs - 1;
7838 for (i = i * 2; i > 0; i--)
7839 {
7840 if (regpos[reg].offset == i - 1)
7841 {
7842 name = tic6x_unwind_regnames[regpos[reg].reg];
7843 if (reg > 0)
7844 reg--;
7845 }
7846 else
7847 name = _("[pad]");
7848
7849 fputs (name, stdout);
7850 if (i > 1)
7851 printf (", ");
7852 }
7853
7854 printf ("}");
7855 }
7856 else if (op == 0xd0)
7857 printf (" MOV FP, SP");
7858 else if (op == 0xd1)
7859 printf (" __c6xabi_pop_rts");
7860 else if (op == 0xd2)
7861 {
7862 unsigned char buf[9];
7863 unsigned int i, len;
7864 unsigned long offset;
a734115a 7865
fa197c1c
PB
7866 for (i = 0; i < sizeof (buf); i++)
7867 {
7868 GET_OP (buf[i]);
7869 if ((buf[i] & 0x80) == 0)
7870 break;
7871 }
0eff7165
NC
7872 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
7873 if (i == sizeof (buf))
7874 {
7875 printf ("<corrupt sp adjust>\n");
7876 warn (_("Corrupt stack pointer adjustment detected\n"));
7877 return;
7878 }
7879
f6f0e17b 7880 offset = read_uleb128 (buf, &len, buf + i + 1);
fa197c1c
PB
7881 assert (len == i + 1);
7882 offset = offset * 8 + 0x408;
7883 printf (_("sp = sp + %ld"), offset);
7884 }
7885 else if ((op & 0xf0) == 0xe0)
7886 {
7887 if ((op & 0x0f) == 7)
7888 printf (" RETURN");
7889 else
7890 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
7891 }
7892 else
7893 {
7894 printf (_(" [unsupported opcode]"));
7895 }
7896 putchar ('\n');
7897 }
7898}
7899
7900static bfd_vma
a734115a 7901arm_expand_prel31 (bfd_vma word, bfd_vma where)
fa197c1c
PB
7902{
7903 bfd_vma offset;
7904
7905 offset = word & 0x7fffffff;
7906 if (offset & 0x40000000)
7907 offset |= ~ (bfd_vma) 0x7fffffff;
7908
7909 if (elf_header.e_machine == EM_TI_C6000)
7910 offset <<= 1;
7911
7912 return offset + where;
7913}
7914
7915static void
1b31d05e
NC
7916decode_arm_unwind (struct arm_unw_aux_info * aux,
7917 unsigned int word,
7918 unsigned int remaining,
7919 bfd_vma data_offset,
7920 Elf_Internal_Shdr * data_sec,
7921 struct arm_section * data_arm_sec)
fa197c1c
PB
7922{
7923 int per_index;
7924 unsigned int more_words = 0;
37e14bc3 7925 struct absaddr addr;
1b31d05e 7926 bfd_vma sym_name = (bfd_vma) -1;
fa197c1c
PB
7927
7928 if (remaining == 0)
7929 {
1b31d05e
NC
7930 /* Fetch the first word.
7931 Note - when decoding an object file the address extracted
7932 here will always be 0. So we also pass in the sym_name
7933 parameter so that we can find the symbol associated with
7934 the personality routine. */
7935 if (! get_unwind_section_word (aux, data_arm_sec, data_sec, data_offset,
7936 & word, & addr, & sym_name))
fa197c1c 7937 return;
1b31d05e 7938
fa197c1c
PB
7939 remaining = 4;
7940 }
7941
7942 if ((word & 0x80000000) == 0)
7943 {
7944 /* Expand prel31 for personality routine. */
7945 bfd_vma fn;
7946 const char *procname;
7947
a734115a 7948 fn = arm_expand_prel31 (word, data_sec->sh_addr + data_offset);
fa197c1c 7949 printf (_(" Personality routine: "));
1b31d05e
NC
7950 if (fn == 0
7951 && addr.section == SHN_UNDEF && addr.offset == 0
7952 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
7953 {
7954 procname = aux->strtab + sym_name;
7955 print_vma (fn, PREFIX_HEX);
7956 if (procname)
7957 {
7958 fputs (" <", stdout);
7959 fputs (procname, stdout);
7960 fputc ('>', stdout);
7961 }
7962 }
7963 else
7964 procname = arm_print_vma_and_name (aux, fn, addr);
fa197c1c
PB
7965 fputc ('\n', stdout);
7966
7967 /* The GCC personality routines use the standard compact
7968 encoding, starting with one byte giving the number of
7969 words. */
7970 if (procname != NULL
7971 && (const_strneq (procname, "__gcc_personality_v0")
7972 || const_strneq (procname, "__gxx_personality_v0")
7973 || const_strneq (procname, "__gcj_personality_v0")
7974 || const_strneq (procname, "__gnu_objc_personality_v0")))
7975 {
7976 remaining = 0;
7977 more_words = 1;
7978 ADVANCE;
7979 if (!remaining)
7980 {
7981 printf (_(" [Truncated data]\n"));
7982 return;
7983 }
7984 more_words = word >> 24;
7985 word <<= 8;
7986 remaining--;
7987 per_index = -1;
7988 }
7989 else
7990 return;
7991 }
7992 else
7993 {
1b31d05e 7994 /* ARM EHABI Section 6.3:
0b4362b0 7995
1b31d05e 7996 An exception-handling table entry for the compact model looks like:
0b4362b0 7997
1b31d05e
NC
7998 31 30-28 27-24 23-0
7999 -- ----- ----- ----
8000 1 0 index Data for personalityRoutine[index] */
8001
8002 if (elf_header.e_machine == EM_ARM
8003 && (word & 0x70000000))
83c257ca 8004 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
1b31d05e 8005
fa197c1c 8006 per_index = (word >> 24) & 0x7f;
1b31d05e 8007 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
8008 if (per_index == 0)
8009 {
8010 more_words = 0;
8011 word <<= 8;
8012 remaining--;
8013 }
8014 else if (per_index < 3)
8015 {
8016 more_words = (word >> 16) & 0xff;
8017 word <<= 16;
8018 remaining -= 2;
8019 }
8020 }
8021
8022 switch (elf_header.e_machine)
8023 {
8024 case EM_ARM:
8025 if (per_index < 3)
8026 {
8027 decode_arm_unwind_bytecode (aux, word, remaining, more_words,
8028 data_offset, data_sec, data_arm_sec);
8029 }
8030 else
1b31d05e
NC
8031 {
8032 warn (_("Unknown ARM compact model index encountered\n"));
8033 printf (_(" [reserved]\n"));
8034 }
fa197c1c
PB
8035 break;
8036
8037 case EM_TI_C6000:
8038 if (per_index < 3)
8039 {
8040 decode_tic6x_unwind_bytecode (aux, word, remaining, more_words,
1b31d05e 8041 data_offset, data_sec, data_arm_sec);
fa197c1c
PB
8042 }
8043 else if (per_index < 5)
8044 {
8045 if (((word >> 17) & 0x7f) == 0x7f)
8046 printf (_(" Restore stack from frame pointer\n"));
8047 else
8048 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
8049 printf (_(" Registers restored: "));
8050 if (per_index == 4)
8051 printf (" (compact) ");
8052 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
8053 putchar ('\n');
8054 printf (_(" Return register: %s\n"),
8055 tic6x_unwind_regnames[word & 0xf]);
8056 }
8057 else
1b31d05e 8058 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
8059 break;
8060
8061 default:
74e1a04b 8062 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
1b31d05e 8063 elf_header.e_machine);
fa197c1c 8064 }
0b6ae522
DJ
8065
8066 /* Decode the descriptors. Not implemented. */
8067}
8068
8069static void
8070dump_arm_unwind (struct arm_unw_aux_info *aux, Elf_Internal_Shdr *exidx_sec)
8071{
8072 struct arm_section exidx_arm_sec, extab_arm_sec;
8073 unsigned int i, exidx_len;
8074
8075 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
8076 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
8077 exidx_len = exidx_sec->sh_size / 8;
8078
8079 for (i = 0; i < exidx_len; i++)
8080 {
8081 unsigned int exidx_fn, exidx_entry;
8082 struct absaddr fn_addr, entry_addr;
8083 bfd_vma fn;
8084
8085 fputc ('\n', stdout);
8086
1b31d05e
NC
8087 if (! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8088 8 * i, & exidx_fn, & fn_addr, NULL)
8089 || ! get_unwind_section_word (aux, & exidx_arm_sec, exidx_sec,
8090 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 8091 {
1b31d05e
NC
8092 arm_free_section (& exidx_arm_sec);
8093 arm_free_section (& extab_arm_sec);
0b6ae522
DJ
8094 return;
8095 }
8096
83c257ca
NC
8097 /* ARM EHABI, Section 5:
8098 An index table entry consists of 2 words.
8099 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
8100 if (exidx_fn & 0x80000000)
8101 warn (_("corrupt index table entry: %x\n"), exidx_fn);
8102
a734115a 8103 fn = arm_expand_prel31 (exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 8104
a734115a 8105 arm_print_vma_and_name (aux, fn, fn_addr);
0b6ae522
DJ
8106 fputs (": ", stdout);
8107
8108 if (exidx_entry == 1)
8109 {
8110 print_vma (exidx_entry, PREFIX_HEX);
8111 fputs (" [cantunwind]\n", stdout);
8112 }
8113 else if (exidx_entry & 0x80000000)
8114 {
8115 print_vma (exidx_entry, PREFIX_HEX);
8116 fputc ('\n', stdout);
8117 decode_arm_unwind (aux, exidx_entry, 4, 0, NULL, NULL);
8118 }
8119 else
8120 {
8f73510c 8121 bfd_vma table, table_offset = 0;
0b6ae522
DJ
8122 Elf_Internal_Shdr *table_sec;
8123
8124 fputs ("@", stdout);
a734115a 8125 table = arm_expand_prel31 (exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
8126 print_vma (table, PREFIX_HEX);
8127 printf ("\n");
8128
8129 /* Locate the matching .ARM.extab. */
8130 if (entry_addr.section != SHN_UNDEF
8131 && entry_addr.section < elf_header.e_shnum)
8132 {
8133 table_sec = section_headers + entry_addr.section;
8134 table_offset = entry_addr.offset;
8135 }
8136 else
8137 {
8138 table_sec = find_section_by_address (table);
8139 if (table_sec != NULL)
8140 table_offset = table - table_sec->sh_addr;
8141 }
8142 if (table_sec == NULL)
8143 {
8144 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
8145 (unsigned long) table);
8146 continue;
8147 }
8148 decode_arm_unwind (aux, 0, 0, table_offset, table_sec,
8149 &extab_arm_sec);
8150 }
8151 }
8152
8153 printf ("\n");
8154
8155 arm_free_section (&exidx_arm_sec);
8156 arm_free_section (&extab_arm_sec);
8157}
8158
fa197c1c 8159/* Used for both ARM and C6X unwinding tables. */
1b31d05e
NC
8160
8161static void
0b6ae522
DJ
8162arm_process_unwind (FILE *file)
8163{
8164 struct arm_unw_aux_info aux;
8165 Elf_Internal_Shdr *unwsec = NULL;
8166 Elf_Internal_Shdr *strsec;
8167 Elf_Internal_Shdr *sec;
8168 unsigned long i;
fa197c1c 8169 unsigned int sec_type;
0b6ae522 8170
fa197c1c
PB
8171 switch (elf_header.e_machine)
8172 {
8173 case EM_ARM:
8174 sec_type = SHT_ARM_EXIDX;
8175 break;
8176
8177 case EM_TI_C6000:
8178 sec_type = SHT_C6000_UNWIND;
8179 break;
8180
0b4362b0 8181 default:
74e1a04b 8182 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
1b31d05e
NC
8183 elf_header.e_machine);
8184 return;
fa197c1c
PB
8185 }
8186
0b6ae522 8187 if (string_table == NULL)
1b31d05e
NC
8188 return;
8189
8190 memset (& aux, 0, sizeof (aux));
8191 aux.file = file;
0b6ae522
DJ
8192
8193 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8194 {
8195 if (sec->sh_type == SHT_SYMTAB && sec->sh_link < elf_header.e_shnum)
8196 {
ba5cdace 8197 aux.symtab = GET_ELF_SYMBOLS (file, sec, & aux.nsyms);
0b6ae522
DJ
8198
8199 strsec = section_headers + sec->sh_link;
74e1a04b
NC
8200
8201 /* PR binutils/17531 file: 011-12666-0.004. */
8202 if (aux.strtab != NULL)
8203 {
4082ef84 8204 error (_("Multiple string tables found in file.\n"));
74e1a04b
NC
8205 free (aux.strtab);
8206 }
0b6ae522
DJ
8207 aux.strtab = get_data (NULL, file, strsec->sh_offset,
8208 1, strsec->sh_size, _("string table"));
8209 aux.strtab_size = aux.strtab != NULL ? strsec->sh_size : 0;
8210 }
fa197c1c 8211 else if (sec->sh_type == sec_type)
0b6ae522
DJ
8212 unwsec = sec;
8213 }
8214
1b31d05e 8215 if (unwsec == NULL)
0b6ae522 8216 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e
NC
8217 else
8218 for (i = 0, sec = section_headers; i < elf_header.e_shnum; ++i, ++sec)
8219 {
8220 if (sec->sh_type == sec_type)
8221 {
8222 printf (_("\nUnwind table index '%s' at offset 0x%lx contains %lu entries:\n"),
74e1a04b 8223 printable_section_name (sec),
1b31d05e
NC
8224 (unsigned long) sec->sh_offset,
8225 (unsigned long) (sec->sh_size / (2 * eh_addr_size)));
0b6ae522 8226
1b31d05e
NC
8227 dump_arm_unwind (&aux, sec);
8228 }
8229 }
0b6ae522
DJ
8230
8231 if (aux.symtab)
8232 free (aux.symtab);
8233 if (aux.strtab)
8234 free ((char *) aux.strtab);
0b6ae522
DJ
8235}
8236
1b31d05e 8237static void
2cf0635d 8238process_unwind (FILE * file)
57346661 8239{
2cf0635d
NC
8240 struct unwind_handler
8241 {
57346661 8242 int machtype;
1b31d05e 8243 void (* handler)(FILE *);
2cf0635d
NC
8244 } handlers[] =
8245 {
0b6ae522 8246 { EM_ARM, arm_process_unwind },
57346661
AM
8247 { EM_IA_64, ia64_process_unwind },
8248 { EM_PARISC, hppa_process_unwind },
fa197c1c 8249 { EM_TI_C6000, arm_process_unwind },
57346661
AM
8250 { 0, 0 }
8251 };
8252 int i;
8253
8254 if (!do_unwind)
1b31d05e 8255 return;
57346661
AM
8256
8257 for (i = 0; handlers[i].handler != NULL; i++)
8258 if (elf_header.e_machine == handlers[i].machtype)
9f758fdc
NC
8259 {
8260 handlers[i].handler (file);
8261 return;
8262 }
57346661 8263
1b31d05e
NC
8264 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
8265 get_machine_name (elf_header.e_machine));
57346661
AM
8266}
8267
252b5132 8268static void
2cf0635d 8269dynamic_section_mips_val (Elf_Internal_Dyn * entry)
252b5132
RH
8270{
8271 switch (entry->d_tag)
8272 {
8273 case DT_MIPS_FLAGS:
8274 if (entry->d_un.d_val == 0)
4b68bca3 8275 printf (_("NONE"));
252b5132
RH
8276 else
8277 {
8278 static const char * opts[] =
8279 {
8280 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
8281 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
8282 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
8283 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
8284 "RLD_ORDER_SAFE"
8285 };
8286 unsigned int cnt;
8287 int first = 1;
2b692964 8288
60bca95a 8289 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
8290 if (entry->d_un.d_val & (1 << cnt))
8291 {
8292 printf ("%s%s", first ? "" : " ", opts[cnt]);
8293 first = 0;
8294 }
252b5132
RH
8295 }
8296 break;
103f02d3 8297
252b5132 8298 case DT_MIPS_IVERSION:
d79b3d50 8299 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
4b68bca3 8300 printf (_("Interface Version: %s"), GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8301 else
76ca31c0
NC
8302 {
8303 char buf[40];
8304 sprintf_vma (buf, entry->d_un.d_ptr);
8305 /* Note: coded this way so that there is a single string for translation. */
8306 printf (_("<corrupt: %s>"), buf);
8307 }
252b5132 8308 break;
103f02d3 8309
252b5132
RH
8310 case DT_MIPS_TIME_STAMP:
8311 {
8312 char timebuf[20];
2cf0635d 8313 struct tm * tmp;
91d6fa6a 8314 time_t atime = entry->d_un.d_val;
82b1b41b 8315
91d6fa6a 8316 tmp = gmtime (&atime);
82b1b41b
NC
8317 /* PR 17531: file: 6accc532. */
8318 if (tmp == NULL)
8319 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
8320 else
8321 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
8322 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
8323 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 8324 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
8325 }
8326 break;
103f02d3 8327
252b5132
RH
8328 case DT_MIPS_RLD_VERSION:
8329 case DT_MIPS_LOCAL_GOTNO:
8330 case DT_MIPS_CONFLICTNO:
8331 case DT_MIPS_LIBLISTNO:
8332 case DT_MIPS_SYMTABNO:
8333 case DT_MIPS_UNREFEXTNO:
8334 case DT_MIPS_HIPAGENO:
8335 case DT_MIPS_DELTA_CLASS_NO:
8336 case DT_MIPS_DELTA_INSTANCE_NO:
8337 case DT_MIPS_DELTA_RELOC_NO:
8338 case DT_MIPS_DELTA_SYM_NO:
8339 case DT_MIPS_DELTA_CLASSSYM_NO:
8340 case DT_MIPS_COMPACT_SIZE:
4b68bca3 8341 print_vma (entry->d_un.d_ptr, DEC);
252b5132 8342 break;
103f02d3
UD
8343
8344 default:
4b68bca3 8345 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 8346 }
4b68bca3 8347 putchar ('\n');
103f02d3
UD
8348}
8349
103f02d3 8350static void
2cf0635d 8351dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
8352{
8353 switch (entry->d_tag)
8354 {
8355 case DT_HP_DLD_FLAGS:
8356 {
8357 static struct
8358 {
8359 long int bit;
2cf0635d 8360 const char * str;
5e220199
NC
8361 }
8362 flags[] =
8363 {
8364 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
8365 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
8366 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
8367 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
8368 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
8369 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
8370 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
8371 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
8372 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
8373 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
8374 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
8375 { DT_HP_GST, "HP_GST" },
8376 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
8377 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
8378 { DT_HP_NODELETE, "HP_NODELETE" },
8379 { DT_HP_GROUP, "HP_GROUP" },
8380 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 8381 };
103f02d3 8382 int first = 1;
5e220199 8383 size_t cnt;
f7a99963 8384 bfd_vma val = entry->d_un.d_val;
103f02d3 8385
60bca95a 8386 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 8387 if (val & flags[cnt].bit)
30800947
NC
8388 {
8389 if (! first)
8390 putchar (' ');
8391 fputs (flags[cnt].str, stdout);
8392 first = 0;
8393 val ^= flags[cnt].bit;
8394 }
76da6bbe 8395
103f02d3 8396 if (val != 0 || first)
f7a99963
NC
8397 {
8398 if (! first)
8399 putchar (' ');
8400 print_vma (val, HEX);
8401 }
103f02d3
UD
8402 }
8403 break;
76da6bbe 8404
252b5132 8405 default:
f7a99963
NC
8406 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8407 break;
252b5132 8408 }
35b1837e 8409 putchar ('\n');
252b5132
RH
8410}
8411
28f997cf
TG
8412#ifdef BFD64
8413
8414/* VMS vs Unix time offset and factor. */
8415
8416#define VMS_EPOCH_OFFSET 35067168000000000LL
8417#define VMS_GRANULARITY_FACTOR 10000000
8418
8419/* Display a VMS time in a human readable format. */
8420
8421static void
8422print_vms_time (bfd_int64_t vmstime)
8423{
8424 struct tm *tm;
8425 time_t unxtime;
8426
8427 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
8428 tm = gmtime (&unxtime);
8429 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
8430 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
8431 tm->tm_hour, tm->tm_min, tm->tm_sec);
8432}
8433#endif /* BFD64 */
8434
ecc51f48 8435static void
2cf0635d 8436dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
8437{
8438 switch (entry->d_tag)
8439 {
0de14b54 8440 case DT_IA_64_PLT_RESERVE:
bdf4d63a 8441 /* First 3 slots reserved. */
ecc51f48
NC
8442 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8443 printf (" -- ");
8444 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
8445 break;
8446
28f997cf
TG
8447 case DT_IA_64_VMS_LINKTIME:
8448#ifdef BFD64
8449 print_vms_time (entry->d_un.d_val);
8450#endif
8451 break;
8452
8453 case DT_IA_64_VMS_LNKFLAGS:
8454 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8455 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
8456 printf (" CALL_DEBUG");
8457 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
8458 printf (" NOP0BUFS");
8459 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
8460 printf (" P0IMAGE");
8461 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
8462 printf (" MKTHREADS");
8463 if (entry->d_un.d_val & VMS_LF_UPCALLS)
8464 printf (" UPCALLS");
8465 if (entry->d_un.d_val & VMS_LF_IMGSTA)
8466 printf (" IMGSTA");
8467 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
8468 printf (" INITIALIZE");
8469 if (entry->d_un.d_val & VMS_LF_MAIN)
8470 printf (" MAIN");
8471 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
8472 printf (" EXE_INIT");
8473 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
8474 printf (" TBK_IN_IMG");
8475 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
8476 printf (" DBG_IN_IMG");
8477 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
8478 printf (" TBK_IN_DSF");
8479 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
8480 printf (" DBG_IN_DSF");
8481 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
8482 printf (" SIGNATURES");
8483 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
8484 printf (" REL_SEG_OFF");
8485 break;
8486
bdf4d63a
JJ
8487 default:
8488 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
8489 break;
ecc51f48 8490 }
bdf4d63a 8491 putchar ('\n');
ecc51f48
NC
8492}
8493
252b5132 8494static int
2cf0635d 8495get_32bit_dynamic_section (FILE * file)
252b5132 8496{
2cf0635d
NC
8497 Elf32_External_Dyn * edyn;
8498 Elf32_External_Dyn * ext;
8499 Elf_Internal_Dyn * entry;
103f02d3 8500
3f5e193b
NC
8501 edyn = (Elf32_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8502 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8503 if (!edyn)
8504 return 0;
103f02d3 8505
071436c6
NC
8506 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8507 might not have the luxury of section headers. Look for the DT_NULL
8508 terminator to determine the number of entries. */
ba2685cc 8509 for (ext = edyn, dynamic_nent = 0;
071436c6 8510 (char *) ext < (char *) edyn + dynamic_size - sizeof (* entry);
ba2685cc
AM
8511 ext++)
8512 {
8513 dynamic_nent++;
8514 if (BYTE_GET (ext->d_tag) == DT_NULL)
8515 break;
8516 }
252b5132 8517
3f5e193b
NC
8518 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8519 sizeof (* entry));
b2d38a17 8520 if (dynamic_section == NULL)
252b5132 8521 {
8b73c356
NC
8522 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8523 (unsigned long) dynamic_nent);
9ea033b2
NC
8524 free (edyn);
8525 return 0;
8526 }
252b5132 8527
fb514b26 8528 for (ext = edyn, entry = dynamic_section;
ba2685cc 8529 entry < dynamic_section + dynamic_nent;
fb514b26 8530 ext++, entry++)
9ea033b2 8531 {
fb514b26
AM
8532 entry->d_tag = BYTE_GET (ext->d_tag);
8533 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8534 }
8535
9ea033b2
NC
8536 free (edyn);
8537
8538 return 1;
8539}
8540
8541static int
2cf0635d 8542get_64bit_dynamic_section (FILE * file)
9ea033b2 8543{
2cf0635d
NC
8544 Elf64_External_Dyn * edyn;
8545 Elf64_External_Dyn * ext;
8546 Elf_Internal_Dyn * entry;
103f02d3 8547
071436c6 8548 /* Read in the data. */
3f5e193b
NC
8549 edyn = (Elf64_External_Dyn *) get_data (NULL, file, dynamic_addr, 1,
8550 dynamic_size, _("dynamic section"));
a6e9f9df
AM
8551 if (!edyn)
8552 return 0;
103f02d3 8553
071436c6
NC
8554 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
8555 might not have the luxury of section headers. Look for the DT_NULL
8556 terminator to determine the number of entries. */
ba2685cc 8557 for (ext = edyn, dynamic_nent = 0;
071436c6
NC
8558 /* PR 17533 file: 033-67080-0.004 - do not read off the end of the buffer. */
8559 (char *) ext < ((char *) edyn) + dynamic_size - sizeof (* ext);
ba2685cc
AM
8560 ext++)
8561 {
8562 dynamic_nent++;
66543521 8563 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
8564 break;
8565 }
252b5132 8566
3f5e193b
NC
8567 dynamic_section = (Elf_Internal_Dyn *) cmalloc (dynamic_nent,
8568 sizeof (* entry));
b2d38a17 8569 if (dynamic_section == NULL)
252b5132 8570 {
8b73c356
NC
8571 error (_("Out of memory allocating space for %lu dynamic entries\n"),
8572 (unsigned long) dynamic_nent);
252b5132
RH
8573 free (edyn);
8574 return 0;
8575 }
8576
071436c6 8577 /* Convert from external to internal formats. */
fb514b26 8578 for (ext = edyn, entry = dynamic_section;
ba2685cc 8579 entry < dynamic_section + dynamic_nent;
fb514b26 8580 ext++, entry++)
252b5132 8581 {
66543521
AM
8582 entry->d_tag = BYTE_GET (ext->d_tag);
8583 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
8584 }
8585
8586 free (edyn);
8587
9ea033b2
NC
8588 return 1;
8589}
8590
e9e44622
JJ
8591static void
8592print_dynamic_flags (bfd_vma flags)
d1133906 8593{
e9e44622 8594 int first = 1;
13ae64f3 8595
d1133906
NC
8596 while (flags)
8597 {
8598 bfd_vma flag;
8599
8600 flag = flags & - flags;
8601 flags &= ~ flag;
8602
e9e44622
JJ
8603 if (first)
8604 first = 0;
8605 else
8606 putc (' ', stdout);
13ae64f3 8607
d1133906
NC
8608 switch (flag)
8609 {
e9e44622
JJ
8610 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
8611 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
8612 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
8613 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
8614 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 8615 default: fputs (_("unknown"), stdout); break;
d1133906
NC
8616 }
8617 }
e9e44622 8618 puts ("");
d1133906
NC
8619}
8620
b2d38a17
NC
8621/* Parse and display the contents of the dynamic section. */
8622
9ea033b2 8623static int
2cf0635d 8624process_dynamic_section (FILE * file)
9ea033b2 8625{
2cf0635d 8626 Elf_Internal_Dyn * entry;
9ea033b2
NC
8627
8628 if (dynamic_size == 0)
8629 {
8630 if (do_dynamic)
b2d38a17 8631 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2
NC
8632
8633 return 1;
8634 }
8635
8636 if (is_32bit_elf)
8637 {
b2d38a17 8638 if (! get_32bit_dynamic_section (file))
9ea033b2
NC
8639 return 0;
8640 }
b2d38a17 8641 else if (! get_64bit_dynamic_section (file))
9ea033b2
NC
8642 return 0;
8643
252b5132
RH
8644 /* Find the appropriate symbol table. */
8645 if (dynamic_symbols == NULL)
8646 {
86dba8ee
AM
8647 for (entry = dynamic_section;
8648 entry < dynamic_section + dynamic_nent;
8649 ++entry)
252b5132 8650 {
c8286bd1 8651 Elf_Internal_Shdr section;
252b5132
RH
8652
8653 if (entry->d_tag != DT_SYMTAB)
8654 continue;
8655
8656 dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
8657
8658 /* Since we do not know how big the symbol table is,
8659 we default to reading in the entire file (!) and
8660 processing that. This is overkill, I know, but it
e3c8793a 8661 should work. */
d93f0186 8662 section.sh_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132 8663
fb52b2f4
NC
8664 if (archive_file_offset != 0)
8665 section.sh_size = archive_file_size - section.sh_offset;
8666 else
8667 {
8668 if (fseek (file, 0, SEEK_END))
591a748a 8669 error (_("Unable to seek to end of file!\n"));
fb52b2f4
NC
8670
8671 section.sh_size = ftell (file) - section.sh_offset;
8672 }
252b5132 8673
9ea033b2 8674 if (is_32bit_elf)
9ad5cbcf 8675 section.sh_entsize = sizeof (Elf32_External_Sym);
9ea033b2 8676 else
9ad5cbcf 8677 section.sh_entsize = sizeof (Elf64_External_Sym);
071436c6 8678 section.sh_name = string_table_length;
252b5132 8679
ba5cdace 8680 dynamic_symbols = GET_ELF_SYMBOLS (file, &section, & num_dynamic_syms);
19936277 8681 if (num_dynamic_syms < 1)
252b5132
RH
8682 {
8683 error (_("Unable to determine the number of symbols to load\n"));
8684 continue;
8685 }
252b5132
RH
8686 }
8687 }
8688
8689 /* Similarly find a string table. */
8690 if (dynamic_strings == NULL)
8691 {
86dba8ee
AM
8692 for (entry = dynamic_section;
8693 entry < dynamic_section + dynamic_nent;
8694 ++entry)
252b5132
RH
8695 {
8696 unsigned long offset;
b34976b6 8697 long str_tab_len;
252b5132
RH
8698
8699 if (entry->d_tag != DT_STRTAB)
8700 continue;
8701
8702 dynamic_info[DT_STRTAB] = entry->d_un.d_val;
8703
8704 /* Since we do not know how big the string table is,
8705 we default to reading in the entire file (!) and
8706 processing that. This is overkill, I know, but it
e3c8793a 8707 should work. */
252b5132 8708
d93f0186 8709 offset = offset_from_vma (file, entry->d_un.d_val, 0);
fb52b2f4
NC
8710
8711 if (archive_file_offset != 0)
8712 str_tab_len = archive_file_size - offset;
8713 else
8714 {
8715 if (fseek (file, 0, SEEK_END))
8716 error (_("Unable to seek to end of file\n"));
8717 str_tab_len = ftell (file) - offset;
8718 }
252b5132
RH
8719
8720 if (str_tab_len < 1)
8721 {
8722 error
8723 (_("Unable to determine the length of the dynamic string table\n"));
8724 continue;
8725 }
8726
3f5e193b
NC
8727 dynamic_strings = (char *) get_data (NULL, file, offset, 1,
8728 str_tab_len,
8729 _("dynamic string table"));
59245841 8730 dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
252b5132
RH
8731 break;
8732 }
8733 }
8734
8735 /* And find the syminfo section if available. */
8736 if (dynamic_syminfo == NULL)
8737 {
3e8bba36 8738 unsigned long syminsz = 0;
252b5132 8739
86dba8ee
AM
8740 for (entry = dynamic_section;
8741 entry < dynamic_section + dynamic_nent;
8742 ++entry)
252b5132
RH
8743 {
8744 if (entry->d_tag == DT_SYMINENT)
8745 {
8746 /* Note: these braces are necessary to avoid a syntax
8747 error from the SunOS4 C compiler. */
049b0c3a
NC
8748 /* PR binutils/17531: A corrupt file can trigger this test.
8749 So do not use an assert, instead generate an error message. */
8750 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 8751 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 8752 (int) entry->d_un.d_val);
252b5132
RH
8753 }
8754 else if (entry->d_tag == DT_SYMINSZ)
8755 syminsz = entry->d_un.d_val;
8756 else if (entry->d_tag == DT_SYMINFO)
d93f0186
NC
8757 dynamic_syminfo_offset = offset_from_vma (file, entry->d_un.d_val,
8758 syminsz);
252b5132
RH
8759 }
8760
8761 if (dynamic_syminfo_offset != 0 && syminsz != 0)
8762 {
2cf0635d
NC
8763 Elf_External_Syminfo * extsyminfo;
8764 Elf_External_Syminfo * extsym;
8765 Elf_Internal_Syminfo * syminfo;
252b5132
RH
8766
8767 /* There is a syminfo section. Read the data. */
3f5e193b
NC
8768 extsyminfo = (Elf_External_Syminfo *)
8769 get_data (NULL, file, dynamic_syminfo_offset, 1, syminsz,
8770 _("symbol information"));
a6e9f9df
AM
8771 if (!extsyminfo)
8772 return 0;
252b5132 8773
3f5e193b 8774 dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
252b5132
RH
8775 if (dynamic_syminfo == NULL)
8776 {
8b73c356
NC
8777 error (_("Out of memory allocating %lu byte for dynamic symbol info\n"),
8778 (unsigned long) syminsz);
252b5132
RH
8779 return 0;
8780 }
8781
8782 dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
86dba8ee
AM
8783 for (syminfo = dynamic_syminfo, extsym = extsyminfo;
8784 syminfo < dynamic_syminfo + dynamic_syminfo_nent;
8785 ++syminfo, ++extsym)
252b5132 8786 {
86dba8ee
AM
8787 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
8788 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
8789 }
8790
8791 free (extsyminfo);
8792 }
8793 }
8794
8795 if (do_dynamic && dynamic_addr)
8b73c356
NC
8796 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
8797 dynamic_addr, (unsigned long) dynamic_nent);
252b5132
RH
8798 if (do_dynamic)
8799 printf (_(" Tag Type Name/Value\n"));
8800
86dba8ee
AM
8801 for (entry = dynamic_section;
8802 entry < dynamic_section + dynamic_nent;
8803 entry++)
252b5132
RH
8804 {
8805 if (do_dynamic)
f7a99963 8806 {
2cf0635d 8807 const char * dtype;
e699b9ff 8808
f7a99963
NC
8809 putchar (' ');
8810 print_vma (entry->d_tag, FULL_HEX);
e699b9ff
ILT
8811 dtype = get_dynamic_type (entry->d_tag);
8812 printf (" (%s)%*s", dtype,
8813 ((is_32bit_elf ? 27 : 19)
8814 - (int) strlen (dtype)),
f7a99963
NC
8815 " ");
8816 }
252b5132
RH
8817
8818 switch (entry->d_tag)
8819 {
d1133906
NC
8820 case DT_FLAGS:
8821 if (do_dynamic)
e9e44622 8822 print_dynamic_flags (entry->d_un.d_val);
d1133906 8823 break;
76da6bbe 8824
252b5132
RH
8825 case DT_AUXILIARY:
8826 case DT_FILTER:
019148e4
L
8827 case DT_CONFIG:
8828 case DT_DEPAUDIT:
8829 case DT_AUDIT:
252b5132
RH
8830 if (do_dynamic)
8831 {
019148e4 8832 switch (entry->d_tag)
b34976b6 8833 {
019148e4
L
8834 case DT_AUXILIARY:
8835 printf (_("Auxiliary library"));
8836 break;
8837
8838 case DT_FILTER:
8839 printf (_("Filter library"));
8840 break;
8841
b34976b6 8842 case DT_CONFIG:
019148e4
L
8843 printf (_("Configuration file"));
8844 break;
8845
8846 case DT_DEPAUDIT:
8847 printf (_("Dependency audit library"));
8848 break;
8849
8850 case DT_AUDIT:
8851 printf (_("Audit library"));
8852 break;
8853 }
252b5132 8854
d79b3d50
NC
8855 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
8856 printf (": [%s]\n", GET_DYNAMIC_NAME (entry->d_un.d_val));
252b5132 8857 else
f7a99963
NC
8858 {
8859 printf (": ");
8860 print_vma (entry->d_un.d_val, PREFIX_HEX);
8861 putchar ('\n');
8862 }
252b5132
RH
8863 }
8864 break;
8865
dcefbbbd 8866 case DT_FEATURE:
252b5132
RH
8867 if (do_dynamic)
8868 {
8869 printf (_("Flags:"));
86f55779 8870
252b5132
RH
8871 if (entry->d_un.d_val == 0)
8872 printf (_(" None\n"));
8873 else
8874 {
8875 unsigned long int val = entry->d_un.d_val;
86f55779 8876
252b5132
RH
8877 if (val & DTF_1_PARINIT)
8878 {
8879 printf (" PARINIT");
8880 val ^= DTF_1_PARINIT;
8881 }
dcefbbbd
L
8882 if (val & DTF_1_CONFEXP)
8883 {
8884 printf (" CONFEXP");
8885 val ^= DTF_1_CONFEXP;
8886 }
252b5132
RH
8887 if (val != 0)
8888 printf (" %lx", val);
8889 puts ("");
8890 }
8891 }
8892 break;
8893
8894 case DT_POSFLAG_1:
8895 if (do_dynamic)
8896 {
8897 printf (_("Flags:"));
86f55779 8898
252b5132
RH
8899 if (entry->d_un.d_val == 0)
8900 printf (_(" None\n"));
8901 else
8902 {
8903 unsigned long int val = entry->d_un.d_val;
86f55779 8904
252b5132
RH
8905 if (val & DF_P1_LAZYLOAD)
8906 {
8907 printf (" LAZYLOAD");
8908 val ^= DF_P1_LAZYLOAD;
8909 }
8910 if (val & DF_P1_GROUPPERM)
8911 {
8912 printf (" GROUPPERM");
8913 val ^= DF_P1_GROUPPERM;
8914 }
8915 if (val != 0)
8916 printf (" %lx", val);
8917 puts ("");
8918 }
8919 }
8920 break;
8921
8922 case DT_FLAGS_1:
8923 if (do_dynamic)
8924 {
8925 printf (_("Flags:"));
8926 if (entry->d_un.d_val == 0)
8927 printf (_(" None\n"));
8928 else
8929 {
8930 unsigned long int val = entry->d_un.d_val;
86f55779 8931
252b5132
RH
8932 if (val & DF_1_NOW)
8933 {
8934 printf (" NOW");
8935 val ^= DF_1_NOW;
8936 }
8937 if (val & DF_1_GLOBAL)
8938 {
8939 printf (" GLOBAL");
8940 val ^= DF_1_GLOBAL;
8941 }
8942 if (val & DF_1_GROUP)
8943 {
8944 printf (" GROUP");
8945 val ^= DF_1_GROUP;
8946 }
8947 if (val & DF_1_NODELETE)
8948 {
8949 printf (" NODELETE");
8950 val ^= DF_1_NODELETE;
8951 }
8952 if (val & DF_1_LOADFLTR)
8953 {
8954 printf (" LOADFLTR");
8955 val ^= DF_1_LOADFLTR;
8956 }
8957 if (val & DF_1_INITFIRST)
8958 {
8959 printf (" INITFIRST");
8960 val ^= DF_1_INITFIRST;
8961 }
8962 if (val & DF_1_NOOPEN)
8963 {
8964 printf (" NOOPEN");
8965 val ^= DF_1_NOOPEN;
8966 }
8967 if (val & DF_1_ORIGIN)
8968 {
8969 printf (" ORIGIN");
8970 val ^= DF_1_ORIGIN;
8971 }
8972 if (val & DF_1_DIRECT)
8973 {
8974 printf (" DIRECT");
8975 val ^= DF_1_DIRECT;
8976 }
8977 if (val & DF_1_TRANS)
8978 {
8979 printf (" TRANS");
8980 val ^= DF_1_TRANS;
8981 }
8982 if (val & DF_1_INTERPOSE)
8983 {
8984 printf (" INTERPOSE");
8985 val ^= DF_1_INTERPOSE;
8986 }
f7db6139 8987 if (val & DF_1_NODEFLIB)
dcefbbbd 8988 {
f7db6139
L
8989 printf (" NODEFLIB");
8990 val ^= DF_1_NODEFLIB;
dcefbbbd
L
8991 }
8992 if (val & DF_1_NODUMP)
8993 {
8994 printf (" NODUMP");
8995 val ^= DF_1_NODUMP;
8996 }
34b60028 8997 if (val & DF_1_CONFALT)
dcefbbbd 8998 {
34b60028
L
8999 printf (" CONFALT");
9000 val ^= DF_1_CONFALT;
9001 }
9002 if (val & DF_1_ENDFILTEE)
9003 {
9004 printf (" ENDFILTEE");
9005 val ^= DF_1_ENDFILTEE;
9006 }
9007 if (val & DF_1_DISPRELDNE)
9008 {
9009 printf (" DISPRELDNE");
9010 val ^= DF_1_DISPRELDNE;
9011 }
9012 if (val & DF_1_DISPRELPND)
9013 {
9014 printf (" DISPRELPND");
9015 val ^= DF_1_DISPRELPND;
9016 }
9017 if (val & DF_1_NODIRECT)
9018 {
9019 printf (" NODIRECT");
9020 val ^= DF_1_NODIRECT;
9021 }
9022 if (val & DF_1_IGNMULDEF)
9023 {
9024 printf (" IGNMULDEF");
9025 val ^= DF_1_IGNMULDEF;
9026 }
9027 if (val & DF_1_NOKSYMS)
9028 {
9029 printf (" NOKSYMS");
9030 val ^= DF_1_NOKSYMS;
9031 }
9032 if (val & DF_1_NOHDR)
9033 {
9034 printf (" NOHDR");
9035 val ^= DF_1_NOHDR;
9036 }
9037 if (val & DF_1_EDITED)
9038 {
9039 printf (" EDITED");
9040 val ^= DF_1_EDITED;
9041 }
9042 if (val & DF_1_NORELOC)
9043 {
9044 printf (" NORELOC");
9045 val ^= DF_1_NORELOC;
9046 }
9047 if (val & DF_1_SYMINTPOSE)
9048 {
9049 printf (" SYMINTPOSE");
9050 val ^= DF_1_SYMINTPOSE;
9051 }
9052 if (val & DF_1_GLOBAUDIT)
9053 {
9054 printf (" GLOBAUDIT");
9055 val ^= DF_1_GLOBAUDIT;
9056 }
9057 if (val & DF_1_SINGLETON)
9058 {
9059 printf (" SINGLETON");
9060 val ^= DF_1_SINGLETON;
dcefbbbd 9061 }
252b5132
RH
9062 if (val != 0)
9063 printf (" %lx", val);
9064 puts ("");
9065 }
9066 }
9067 break;
9068
9069 case DT_PLTREL:
566b0d53 9070 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9071 if (do_dynamic)
9072 puts (get_dynamic_type (entry->d_un.d_val));
9073 break;
9074
9075 case DT_NULL :
9076 case DT_NEEDED :
9077 case DT_PLTGOT :
9078 case DT_HASH :
9079 case DT_STRTAB :
9080 case DT_SYMTAB :
9081 case DT_RELA :
9082 case DT_INIT :
9083 case DT_FINI :
9084 case DT_SONAME :
9085 case DT_RPATH :
9086 case DT_SYMBOLIC:
9087 case DT_REL :
9088 case DT_DEBUG :
9089 case DT_TEXTREL :
9090 case DT_JMPREL :
019148e4 9091 case DT_RUNPATH :
252b5132
RH
9092 dynamic_info[entry->d_tag] = entry->d_un.d_val;
9093
9094 if (do_dynamic)
9095 {
2cf0635d 9096 char * name;
252b5132 9097
d79b3d50
NC
9098 if (VALID_DYNAMIC_NAME (entry->d_un.d_val))
9099 name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9100 else
d79b3d50 9101 name = NULL;
252b5132
RH
9102
9103 if (name)
9104 {
9105 switch (entry->d_tag)
9106 {
9107 case DT_NEEDED:
9108 printf (_("Shared library: [%s]"), name);
9109
18bd398b 9110 if (streq (name, program_interpreter))
f7a99963 9111 printf (_(" program interpreter"));
252b5132
RH
9112 break;
9113
9114 case DT_SONAME:
f7a99963 9115 printf (_("Library soname: [%s]"), name);
252b5132
RH
9116 break;
9117
9118 case DT_RPATH:
f7a99963 9119 printf (_("Library rpath: [%s]"), name);
252b5132
RH
9120 break;
9121
019148e4
L
9122 case DT_RUNPATH:
9123 printf (_("Library runpath: [%s]"), name);
9124 break;
9125
252b5132 9126 default:
f7a99963
NC
9127 print_vma (entry->d_un.d_val, PREFIX_HEX);
9128 break;
252b5132
RH
9129 }
9130 }
9131 else
f7a99963
NC
9132 print_vma (entry->d_un.d_val, PREFIX_HEX);
9133
9134 putchar ('\n');
252b5132
RH
9135 }
9136 break;
9137
9138 case DT_PLTRELSZ:
9139 case DT_RELASZ :
9140 case DT_STRSZ :
9141 case DT_RELSZ :
9142 case DT_RELAENT :
9143 case DT_SYMENT :
9144 case DT_RELENT :
566b0d53 9145 dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
9146 case DT_PLTPADSZ:
9147 case DT_MOVEENT :
9148 case DT_MOVESZ :
9149 case DT_INIT_ARRAYSZ:
9150 case DT_FINI_ARRAYSZ:
047b2264
JJ
9151 case DT_GNU_CONFLICTSZ:
9152 case DT_GNU_LIBLISTSZ:
252b5132 9153 if (do_dynamic)
f7a99963
NC
9154 {
9155 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 9156 printf (_(" (bytes)\n"));
f7a99963 9157 }
252b5132
RH
9158 break;
9159
9160 case DT_VERDEFNUM:
9161 case DT_VERNEEDNUM:
9162 case DT_RELACOUNT:
9163 case DT_RELCOUNT:
9164 if (do_dynamic)
f7a99963
NC
9165 {
9166 print_vma (entry->d_un.d_val, UNSIGNED);
9167 putchar ('\n');
9168 }
252b5132
RH
9169 break;
9170
9171 case DT_SYMINSZ:
9172 case DT_SYMINENT:
9173 case DT_SYMINFO:
9174 case DT_USED:
9175 case DT_INIT_ARRAY:
9176 case DT_FINI_ARRAY:
9177 if (do_dynamic)
9178 {
d79b3d50
NC
9179 if (entry->d_tag == DT_USED
9180 && VALID_DYNAMIC_NAME (entry->d_un.d_val))
252b5132 9181 {
2cf0635d 9182 char * name = GET_DYNAMIC_NAME (entry->d_un.d_val);
252b5132 9183
b34976b6 9184 if (*name)
252b5132
RH
9185 {
9186 printf (_("Not needed object: [%s]\n"), name);
9187 break;
9188 }
9189 }
103f02d3 9190
f7a99963
NC
9191 print_vma (entry->d_un.d_val, PREFIX_HEX);
9192 putchar ('\n');
252b5132
RH
9193 }
9194 break;
9195
9196 case DT_BIND_NOW:
9197 /* The value of this entry is ignored. */
35b1837e
AM
9198 if (do_dynamic)
9199 putchar ('\n');
252b5132 9200 break;
103f02d3 9201
047b2264
JJ
9202 case DT_GNU_PRELINKED:
9203 if (do_dynamic)
9204 {
2cf0635d 9205 struct tm * tmp;
91d6fa6a 9206 time_t atime = entry->d_un.d_val;
047b2264 9207
91d6fa6a 9208 tmp = gmtime (&atime);
071436c6
NC
9209 /* PR 17533 file: 041-1244816-0.004. */
9210 if (tmp == NULL)
5a2cbcf4
L
9211 printf (_("<corrupt time val: %lx"),
9212 (unsigned long) atime);
071436c6
NC
9213 else
9214 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
9215 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9216 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
9217
9218 }
9219 break;
9220
fdc90cb4
JJ
9221 case DT_GNU_HASH:
9222 dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
9223 if (do_dynamic)
9224 {
9225 print_vma (entry->d_un.d_val, PREFIX_HEX);
9226 putchar ('\n');
9227 }
9228 break;
9229
252b5132
RH
9230 default:
9231 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
b34976b6 9232 version_info[DT_VERSIONTAGIDX (entry->d_tag)] =
252b5132
RH
9233 entry->d_un.d_val;
9234
9235 if (do_dynamic)
9236 {
9237 switch (elf_header.e_machine)
9238 {
9239 case EM_MIPS:
4fe85591 9240 case EM_MIPS_RS3_LE:
b2d38a17 9241 dynamic_section_mips_val (entry);
252b5132 9242 break;
103f02d3 9243 case EM_PARISC:
b2d38a17 9244 dynamic_section_parisc_val (entry);
103f02d3 9245 break;
ecc51f48 9246 case EM_IA_64:
b2d38a17 9247 dynamic_section_ia64_val (entry);
ecc51f48 9248 break;
252b5132 9249 default:
f7a99963
NC
9250 print_vma (entry->d_un.d_val, PREFIX_HEX);
9251 putchar ('\n');
252b5132
RH
9252 }
9253 }
9254 break;
9255 }
9256 }
9257
9258 return 1;
9259}
9260
9261static char *
d3ba0551 9262get_ver_flags (unsigned int flags)
252b5132 9263{
b34976b6 9264 static char buff[32];
252b5132
RH
9265
9266 buff[0] = 0;
9267
9268 if (flags == 0)
9269 return _("none");
9270
9271 if (flags & VER_FLG_BASE)
9272 strcat (buff, "BASE ");
9273
9274 if (flags & VER_FLG_WEAK)
9275 {
9276 if (flags & VER_FLG_BASE)
9277 strcat (buff, "| ");
9278
9279 strcat (buff, "WEAK ");
9280 }
9281
44ec90b9
RO
9282 if (flags & VER_FLG_INFO)
9283 {
9284 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
9285 strcat (buff, "| ");
9286
9287 strcat (buff, "INFO ");
9288 }
9289
9290 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
2b692964 9291 strcat (buff, _("| <unknown>"));
252b5132
RH
9292
9293 return buff;
9294}
9295
9296/* Display the contents of the version sections. */
98fb390a 9297
252b5132 9298static int
2cf0635d 9299process_version_sections (FILE * file)
252b5132 9300{
2cf0635d 9301 Elf_Internal_Shdr * section;
b34976b6
AM
9302 unsigned i;
9303 int found = 0;
252b5132
RH
9304
9305 if (! do_version)
9306 return 1;
9307
9308 for (i = 0, section = section_headers;
9309 i < elf_header.e_shnum;
b34976b6 9310 i++, section++)
252b5132
RH
9311 {
9312 switch (section->sh_type)
9313 {
9314 case SHT_GNU_verdef:
9315 {
2cf0635d 9316 Elf_External_Verdef * edefs;
b34976b6
AM
9317 unsigned int idx;
9318 unsigned int cnt;
2cf0635d 9319 char * endbuf;
252b5132
RH
9320
9321 found = 1;
9322
74e1a04b
NC
9323 printf (_("\nVersion definition section '%s' contains %u entries:\n"),
9324 printable_section_name (section),
9325 section->sh_info);
252b5132
RH
9326
9327 printf (_(" Addr: 0x"));
9328 printf_vma (section->sh_addr);
74e1a04b 9329 printf (_(" Offset: %#08lx Link: %u (%s)"),
1b228002 9330 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9331 printable_section_name_from_index (section->sh_link));
252b5132 9332
3f5e193b
NC
9333 edefs = (Elf_External_Verdef *)
9334 get_data (NULL, file, section->sh_offset, 1,section->sh_size,
9335 _("version definition section"));
a6e9f9df
AM
9336 if (!edefs)
9337 break;
59245841 9338 endbuf = (char *) edefs + section->sh_size;
252b5132 9339
b34976b6 9340 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 9341 {
2cf0635d
NC
9342 char * vstart;
9343 Elf_External_Verdef * edef;
b34976b6 9344 Elf_Internal_Verdef ent;
2cf0635d 9345 Elf_External_Verdaux * eaux;
b34976b6
AM
9346 Elf_Internal_Verdaux aux;
9347 int j;
9348 int isum;
103f02d3 9349
7e26601c
NC
9350 /* Check for very large indicies. */
9351 if (idx > (size_t) (endbuf - (char *) edefs))
dd24e3da
NC
9352 break;
9353
252b5132 9354 vstart = ((char *) edefs) + idx;
54806181
AM
9355 if (vstart + sizeof (*edef) > endbuf)
9356 break;
252b5132
RH
9357
9358 edef = (Elf_External_Verdef *) vstart;
9359
9360 ent.vd_version = BYTE_GET (edef->vd_version);
9361 ent.vd_flags = BYTE_GET (edef->vd_flags);
9362 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
9363 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
9364 ent.vd_hash = BYTE_GET (edef->vd_hash);
9365 ent.vd_aux = BYTE_GET (edef->vd_aux);
9366 ent.vd_next = BYTE_GET (edef->vd_next);
9367
9368 printf (_(" %#06x: Rev: %d Flags: %s"),
9369 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
9370
9371 printf (_(" Index: %d Cnt: %d "),
9372 ent.vd_ndx, ent.vd_cnt);
9373
dd24e3da 9374 /* Check for overflow. */
7e26601c 9375 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
9376 break;
9377
252b5132
RH
9378 vstart += ent.vd_aux;
9379
9380 eaux = (Elf_External_Verdaux *) vstart;
9381
9382 aux.vda_name = BYTE_GET (eaux->vda_name);
9383 aux.vda_next = BYTE_GET (eaux->vda_next);
9384
d79b3d50
NC
9385 if (VALID_DYNAMIC_NAME (aux.vda_name))
9386 printf (_("Name: %s\n"), GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9387 else
9388 printf (_("Name index: %ld\n"), aux.vda_name);
9389
9390 isum = idx + ent.vd_aux;
9391
b34976b6 9392 for (j = 1; j < ent.vd_cnt; j++)
252b5132 9393 {
dd24e3da 9394 /* Check for overflow. */
7e26601c 9395 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
9396 break;
9397
252b5132
RH
9398 isum += aux.vda_next;
9399 vstart += aux.vda_next;
9400
9401 eaux = (Elf_External_Verdaux *) vstart;
54806181
AM
9402 if (vstart + sizeof (*eaux) > endbuf)
9403 break;
252b5132
RH
9404
9405 aux.vda_name = BYTE_GET (eaux->vda_name);
9406 aux.vda_next = BYTE_GET (eaux->vda_next);
9407
d79b3d50 9408 if (VALID_DYNAMIC_NAME (aux.vda_name))
252b5132 9409 printf (_(" %#06x: Parent %d: %s\n"),
d79b3d50 9410 isum, j, GET_DYNAMIC_NAME (aux.vda_name));
252b5132
RH
9411 else
9412 printf (_(" %#06x: Parent %d, name index: %ld\n"),
9413 isum, j, aux.vda_name);
9414 }
dd24e3da 9415
54806181
AM
9416 if (j < ent.vd_cnt)
9417 printf (_(" Version def aux past end of section\n"));
252b5132 9418
5d921cbd
NC
9419 /* PR 17531: file: id:000001,src:000172+005151,op:splice,rep:2. */
9420 if (idx + ent.vd_next <= idx)
9421 break;
9422
252b5132
RH
9423 idx += ent.vd_next;
9424 }
dd24e3da 9425
54806181
AM
9426 if (cnt < section->sh_info)
9427 printf (_(" Version definition past end of section\n"));
252b5132
RH
9428
9429 free (edefs);
9430 }
9431 break;
103f02d3 9432
252b5132
RH
9433 case SHT_GNU_verneed:
9434 {
2cf0635d 9435 Elf_External_Verneed * eneed;
b34976b6
AM
9436 unsigned int idx;
9437 unsigned int cnt;
2cf0635d 9438 char * endbuf;
252b5132
RH
9439
9440 found = 1;
9441
72de5009 9442 printf (_("\nVersion needs section '%s' contains %u entries:\n"),
74e1a04b 9443 printable_section_name (section), section->sh_info);
252b5132
RH
9444
9445 printf (_(" Addr: 0x"));
9446 printf_vma (section->sh_addr);
72de5009 9447 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9448 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9449 printable_section_name_from_index (section->sh_link));
252b5132 9450
3f5e193b
NC
9451 eneed = (Elf_External_Verneed *) get_data (NULL, file,
9452 section->sh_offset, 1,
9453 section->sh_size,
9cf03b7e 9454 _("Version Needs section"));
a6e9f9df
AM
9455 if (!eneed)
9456 break;
59245841 9457 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
9458
9459 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
9460 {
2cf0635d 9461 Elf_External_Verneed * entry;
b34976b6
AM
9462 Elf_Internal_Verneed ent;
9463 int j;
9464 int isum;
2cf0635d 9465 char * vstart;
252b5132 9466
7e26601c 9467 if (idx > (size_t) (endbuf - (char *) eneed))
dd24e3da
NC
9468 break;
9469
252b5132 9470 vstart = ((char *) eneed) + idx;
54806181
AM
9471 if (vstart + sizeof (*entry) > endbuf)
9472 break;
252b5132
RH
9473
9474 entry = (Elf_External_Verneed *) vstart;
9475
9476 ent.vn_version = BYTE_GET (entry->vn_version);
9477 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
9478 ent.vn_file = BYTE_GET (entry->vn_file);
9479 ent.vn_aux = BYTE_GET (entry->vn_aux);
9480 ent.vn_next = BYTE_GET (entry->vn_next);
9481
9482 printf (_(" %#06x: Version: %d"), idx, ent.vn_version);
9483
d79b3d50
NC
9484 if (VALID_DYNAMIC_NAME (ent.vn_file))
9485 printf (_(" File: %s"), GET_DYNAMIC_NAME (ent.vn_file));
252b5132
RH
9486 else
9487 printf (_(" File: %lx"), ent.vn_file);
9488
9489 printf (_(" Cnt: %d\n"), ent.vn_cnt);
9490
dd24e3da 9491 /* Check for overflow. */
7e26601c 9492 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 9493 break;
252b5132
RH
9494 vstart += ent.vn_aux;
9495
9496 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
9497 {
2cf0635d 9498 Elf_External_Vernaux * eaux;
b34976b6 9499 Elf_Internal_Vernaux aux;
252b5132 9500
54806181
AM
9501 if (vstart + sizeof (*eaux) > endbuf)
9502 break;
252b5132
RH
9503 eaux = (Elf_External_Vernaux *) vstart;
9504
9505 aux.vna_hash = BYTE_GET (eaux->vna_hash);
9506 aux.vna_flags = BYTE_GET (eaux->vna_flags);
9507 aux.vna_other = BYTE_GET (eaux->vna_other);
9508 aux.vna_name = BYTE_GET (eaux->vna_name);
9509 aux.vna_next = BYTE_GET (eaux->vna_next);
9510
d79b3d50 9511 if (VALID_DYNAMIC_NAME (aux.vna_name))
ecc2063b 9512 printf (_(" %#06x: Name: %s"),
d79b3d50 9513 isum, GET_DYNAMIC_NAME (aux.vna_name));
252b5132 9514 else
ecc2063b 9515 printf (_(" %#06x: Name index: %lx"),
252b5132
RH
9516 isum, aux.vna_name);
9517
9518 printf (_(" Flags: %s Version: %d\n"),
9519 get_ver_flags (aux.vna_flags), aux.vna_other);
9520
dd24e3da 9521 /* Check for overflow. */
53774b7e
NC
9522 if (aux.vna_next > (size_t) (endbuf - vstart)
9523 || (aux.vna_next == 0 && j < ent.vn_cnt - 1))
9524 {
9525 warn (_("Invalid vna_next field of %lx\n"),
9526 aux.vna_next);
9527 j = ent.vn_cnt;
9528 break;
9529 }
252b5132
RH
9530 isum += aux.vna_next;
9531 vstart += aux.vna_next;
9532 }
9cf03b7e 9533
54806181 9534 if (j < ent.vn_cnt)
9cf03b7e 9535 warn (_("Missing Version Needs auxillary information\n"));
252b5132 9536
bcf83b2a 9537 if (ent.vn_next == 0 && cnt < section->sh_info - 1)
c24cf8b6
NC
9538 {
9539 warn (_("Corrupt Version Needs structure - offset to next structure is zero with entries still left to be processed\n"));
9540 cnt = section->sh_info;
9541 break;
9542 }
252b5132
RH
9543 idx += ent.vn_next;
9544 }
9cf03b7e 9545
54806181 9546 if (cnt < section->sh_info)
9cf03b7e 9547 warn (_("Missing Version Needs information\n"));
103f02d3 9548
252b5132
RH
9549 free (eneed);
9550 }
9551 break;
9552
9553 case SHT_GNU_versym:
9554 {
2cf0635d 9555 Elf_Internal_Shdr * link_section;
8b73c356
NC
9556 size_t total;
9557 unsigned int cnt;
2cf0635d
NC
9558 unsigned char * edata;
9559 unsigned short * data;
9560 char * strtab;
9561 Elf_Internal_Sym * symbols;
9562 Elf_Internal_Shdr * string_sec;
ba5cdace 9563 unsigned long num_syms;
d3ba0551 9564 long off;
252b5132 9565
4fbb74a6 9566 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9567 break;
9568
4fbb74a6 9569 link_section = section_headers + section->sh_link;
08d8fa11 9570 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 9571
4fbb74a6 9572 if (link_section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
9573 break;
9574
252b5132
RH
9575 found = 1;
9576
ba5cdace 9577 symbols = GET_ELF_SYMBOLS (file, link_section, & num_syms);
dd24e3da
NC
9578 if (symbols == NULL)
9579 break;
252b5132 9580
4fbb74a6 9581 string_sec = section_headers + link_section->sh_link;
252b5132 9582
3f5e193b
NC
9583 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
9584 string_sec->sh_size,
9585 _("version string table"));
a6e9f9df 9586 if (!strtab)
0429c154
MS
9587 {
9588 free (symbols);
9589 break;
9590 }
252b5132 9591
8b73c356
NC
9592 printf (_("\nVersion symbols section '%s' contains %lu entries:\n"),
9593 printable_section_name (section), (unsigned long) total);
252b5132
RH
9594
9595 printf (_(" Addr: "));
9596 printf_vma (section->sh_addr);
72de5009 9597 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 9598 (unsigned long) section->sh_offset, section->sh_link,
74e1a04b 9599 printable_section_name (link_section));
252b5132 9600
d3ba0551
AM
9601 off = offset_from_vma (file,
9602 version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
9603 total * sizeof (short));
3f5e193b
NC
9604 edata = (unsigned char *) get_data (NULL, file, off, total,
9605 sizeof (short),
9606 _("version symbol data"));
a6e9f9df
AM
9607 if (!edata)
9608 {
9609 free (strtab);
0429c154 9610 free (symbols);
a6e9f9df
AM
9611 break;
9612 }
252b5132 9613
3f5e193b 9614 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
9615
9616 for (cnt = total; cnt --;)
b34976b6
AM
9617 data[cnt] = byte_get (edata + cnt * sizeof (short),
9618 sizeof (short));
252b5132
RH
9619
9620 free (edata);
9621
9622 for (cnt = 0; cnt < total; cnt += 4)
9623 {
9624 int j, nn;
00d93f34 9625 int check_def, check_need;
2cf0635d 9626 char * name;
252b5132
RH
9627
9628 printf (" %03x:", cnt);
9629
9630 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 9631 switch (data[cnt + j])
252b5132
RH
9632 {
9633 case 0:
9634 fputs (_(" 0 (*local*) "), stdout);
9635 break;
9636
9637 case 1:
9638 fputs (_(" 1 (*global*) "), stdout);
9639 break;
9640
9641 default:
c244d050
NC
9642 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
9643 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 9644
dd24e3da 9645 /* If this index value is greater than the size of the symbols
ba5cdace
NC
9646 array, break to avoid an out-of-bounds read. */
9647 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
9648 {
9649 warn (_("invalid index into symbol array\n"));
9650 break;
9651 }
9652
00d93f34
JJ
9653 check_def = 1;
9654 check_need = 1;
4fbb74a6
AM
9655 if (symbols[cnt + j].st_shndx >= elf_header.e_shnum
9656 || section_headers[symbols[cnt + j].st_shndx].sh_type
c256ffe7 9657 != SHT_NOBITS)
252b5132 9658 {
b34976b6 9659 if (symbols[cnt + j].st_shndx == SHN_UNDEF)
00d93f34
JJ
9660 check_def = 0;
9661 else
9662 check_need = 0;
252b5132 9663 }
00d93f34
JJ
9664
9665 if (check_need
b34976b6 9666 && version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 9667 {
b34976b6
AM
9668 Elf_Internal_Verneed ivn;
9669 unsigned long offset;
252b5132 9670
d93f0186
NC
9671 offset = offset_from_vma
9672 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
9673 sizeof (Elf_External_Verneed));
252b5132 9674
b34976b6 9675 do
252b5132 9676 {
b34976b6
AM
9677 Elf_Internal_Vernaux ivna;
9678 Elf_External_Verneed evn;
9679 Elf_External_Vernaux evna;
9680 unsigned long a_off;
252b5132 9681
59245841
NC
9682 if (get_data (&evn, file, offset, sizeof (evn), 1,
9683 _("version need")) == NULL)
9684 break;
0b4362b0 9685
252b5132
RH
9686 ivn.vn_aux = BYTE_GET (evn.vn_aux);
9687 ivn.vn_next = BYTE_GET (evn.vn_next);
9688
9689 a_off = offset + ivn.vn_aux;
9690
9691 do
9692 {
59245841
NC
9693 if (get_data (&evna, file, a_off, sizeof (evna),
9694 1, _("version need aux (2)")) == NULL)
9695 {
9696 ivna.vna_next = 0;
9697 ivna.vna_other = 0;
9698 }
9699 else
9700 {
9701 ivna.vna_next = BYTE_GET (evna.vna_next);
9702 ivna.vna_other = BYTE_GET (evna.vna_other);
9703 }
252b5132
RH
9704
9705 a_off += ivna.vna_next;
9706 }
b34976b6 9707 while (ivna.vna_other != data[cnt + j]
252b5132
RH
9708 && ivna.vna_next != 0);
9709
b34976b6 9710 if (ivna.vna_other == data[cnt + j])
252b5132
RH
9711 {
9712 ivna.vna_name = BYTE_GET (evna.vna_name);
9713
54806181
AM
9714 if (ivna.vna_name >= string_sec->sh_size)
9715 name = _("*invalid*");
9716 else
9717 name = strtab + ivna.vna_name;
252b5132 9718 nn += printf ("(%s%-*s",
16062207
ILT
9719 name,
9720 12 - (int) strlen (name),
252b5132 9721 ")");
00d93f34 9722 check_def = 0;
252b5132
RH
9723 break;
9724 }
9725
9726 offset += ivn.vn_next;
9727 }
9728 while (ivn.vn_next);
9729 }
00d93f34 9730
b34976b6
AM
9731 if (check_def && data[cnt + j] != 0x8001
9732 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 9733 {
b34976b6
AM
9734 Elf_Internal_Verdef ivd;
9735 Elf_External_Verdef evd;
9736 unsigned long offset;
252b5132 9737
d93f0186
NC
9738 offset = offset_from_vma
9739 (file, version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
9740 sizeof evd);
252b5132
RH
9741
9742 do
9743 {
59245841
NC
9744 if (get_data (&evd, file, offset, sizeof (evd), 1,
9745 _("version def")) == NULL)
9746 {
9747 ivd.vd_next = 0;
3102e897
NC
9748 /* PR 17531: file: 046-1082287-0.004. */
9749 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
9750 break;
59245841
NC
9751 }
9752 else
9753 {
9754 ivd.vd_next = BYTE_GET (evd.vd_next);
9755 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
9756 }
252b5132
RH
9757
9758 offset += ivd.vd_next;
9759 }
c244d050 9760 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
9761 && ivd.vd_next != 0);
9762
c244d050 9763 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 9764 {
b34976b6
AM
9765 Elf_External_Verdaux evda;
9766 Elf_Internal_Verdaux ivda;
252b5132
RH
9767
9768 ivd.vd_aux = BYTE_GET (evd.vd_aux);
9769
59245841
NC
9770 if (get_data (&evda, file,
9771 offset - ivd.vd_next + ivd.vd_aux,
9772 sizeof (evda), 1,
9773 _("version def aux")) == NULL)
9774 break;
252b5132
RH
9775
9776 ivda.vda_name = BYTE_GET (evda.vda_name);
9777
54806181
AM
9778 if (ivda.vda_name >= string_sec->sh_size)
9779 name = _("*invalid*");
9780 else
9781 name = strtab + ivda.vda_name;
252b5132 9782 nn += printf ("(%s%-*s",
16062207
ILT
9783 name,
9784 12 - (int) strlen (name),
252b5132
RH
9785 ")");
9786 }
9787 }
9788
9789 if (nn < 18)
9790 printf ("%*c", 18 - nn, ' ');
9791 }
9792
9793 putchar ('\n');
9794 }
9795
9796 free (data);
9797 free (strtab);
9798 free (symbols);
9799 }
9800 break;
103f02d3 9801
252b5132
RH
9802 default:
9803 break;
9804 }
9805 }
9806
9807 if (! found)
9808 printf (_("\nNo version information found in this file.\n"));
9809
9810 return 1;
9811}
9812
d1133906 9813static const char *
d3ba0551 9814get_symbol_binding (unsigned int binding)
252b5132 9815{
b34976b6 9816 static char buff[32];
252b5132
RH
9817
9818 switch (binding)
9819 {
b34976b6
AM
9820 case STB_LOCAL: return "LOCAL";
9821 case STB_GLOBAL: return "GLOBAL";
9822 case STB_WEAK: return "WEAK";
252b5132
RH
9823 default:
9824 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
9825 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
9826 binding);
252b5132 9827 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
9828 {
9829 if (binding == STB_GNU_UNIQUE
9c55345c
TS
9830 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
9831 /* GNU is still using the default value 0. */
3e7a7d11
NC
9832 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9833 return "UNIQUE";
9834 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
9835 }
252b5132 9836 else
e9e44622 9837 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
9838 return buff;
9839 }
9840}
9841
d1133906 9842static const char *
d3ba0551 9843get_symbol_type (unsigned int type)
252b5132 9844{
b34976b6 9845 static char buff[32];
252b5132
RH
9846
9847 switch (type)
9848 {
b34976b6
AM
9849 case STT_NOTYPE: return "NOTYPE";
9850 case STT_OBJECT: return "OBJECT";
9851 case STT_FUNC: return "FUNC";
9852 case STT_SECTION: return "SECTION";
9853 case STT_FILE: return "FILE";
9854 case STT_COMMON: return "COMMON";
9855 case STT_TLS: return "TLS";
15ab5209
DB
9856 case STT_RELC: return "RELC";
9857 case STT_SRELC: return "SRELC";
252b5132
RH
9858 default:
9859 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 9860 {
3510a7b8
NC
9861 if (elf_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
9862 return "THUMB_FUNC";
103f02d3 9863
351b4b40 9864 if (elf_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
9865 return "REGISTER";
9866
9867 if (elf_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
9868 return "PARISC_MILLI";
9869
e9e44622 9870 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 9871 }
252b5132 9872 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3
UD
9873 {
9874 if (elf_header.e_machine == EM_PARISC)
9875 {
9876 if (type == STT_HP_OPAQUE)
9877 return "HP_OPAQUE";
9878 if (type == STT_HP_STUB)
9879 return "HP_STUB";
9880 }
9881
d8045f23 9882 if (type == STT_GNU_IFUNC
9c55345c 9883 && (elf_header.e_ident[EI_OSABI] == ELFOSABI_GNU
83c257ca 9884 || elf_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
9c55345c 9885 /* GNU is still using the default value 0. */
d8045f23
NC
9886 || elf_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
9887 return "IFUNC";
9888
e9e44622 9889 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 9890 }
252b5132 9891 else
e9e44622 9892 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
9893 return buff;
9894 }
9895}
9896
d1133906 9897static const char *
d3ba0551 9898get_symbol_visibility (unsigned int visibility)
d1133906
NC
9899{
9900 switch (visibility)
9901 {
b34976b6
AM
9902 case STV_DEFAULT: return "DEFAULT";
9903 case STV_INTERNAL: return "INTERNAL";
9904 case STV_HIDDEN: return "HIDDEN";
d1133906 9905 case STV_PROTECTED: return "PROTECTED";
bee0ee85
NC
9906 default:
9907 error (_("Unrecognized visibility value: %u"), visibility);
9908 return _("<unknown>");
d1133906
NC
9909 }
9910}
9911
5e2b0d47
NC
9912static const char *
9913get_mips_symbol_other (unsigned int other)
9914{
9915 switch (other)
9916 {
df58fc94
RS
9917 case STO_OPTIONAL:
9918 return "OPTIONAL";
9919 case STO_MIPS_PLT:
9920 return "MIPS PLT";
9921 case STO_MIPS_PIC:
9922 return "MIPS PIC";
9923 case STO_MICROMIPS:
9924 return "MICROMIPS";
9925 case STO_MICROMIPS | STO_MIPS_PIC:
9926 return "MICROMIPS, MIPS PIC";
9927 case STO_MIPS16:
9928 return "MIPS16";
9929 default:
9930 return NULL;
5e2b0d47
NC
9931 }
9932}
9933
28f997cf
TG
9934static const char *
9935get_ia64_symbol_other (unsigned int other)
9936{
9937 if (is_ia64_vms ())
9938 {
9939 static char res[32];
9940
9941 res[0] = 0;
9942
9943 /* Function types is for images and .STB files only. */
9944 switch (elf_header.e_type)
9945 {
9946 case ET_DYN:
9947 case ET_EXEC:
9948 switch (VMS_ST_FUNC_TYPE (other))
9949 {
9950 case VMS_SFT_CODE_ADDR:
9951 strcat (res, " CA");
9952 break;
9953 case VMS_SFT_SYMV_IDX:
9954 strcat (res, " VEC");
9955 break;
9956 case VMS_SFT_FD:
9957 strcat (res, " FD");
9958 break;
9959 case VMS_SFT_RESERVE:
9960 strcat (res, " RSV");
9961 break;
9962 default:
bee0ee85
NC
9963 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
9964 VMS_ST_FUNC_TYPE (other));
9965 strcat (res, " <unknown>");
9966 break;
28f997cf
TG
9967 }
9968 break;
9969 default:
9970 break;
9971 }
9972 switch (VMS_ST_LINKAGE (other))
9973 {
9974 case VMS_STL_IGNORE:
9975 strcat (res, " IGN");
9976 break;
9977 case VMS_STL_RESERVE:
9978 strcat (res, " RSV");
9979 break;
9980 case VMS_STL_STD:
9981 strcat (res, " STD");
9982 break;
9983 case VMS_STL_LNK:
9984 strcat (res, " LNK");
9985 break;
9986 default:
bee0ee85
NC
9987 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
9988 VMS_ST_LINKAGE (other));
9989 strcat (res, " <unknown>");
9990 break;
28f997cf
TG
9991 }
9992
9993 if (res[0] != 0)
9994 return res + 1;
9995 else
9996 return res;
9997 }
9998 return NULL;
9999}
10000
6911b7dc
AM
10001static const char *
10002get_ppc64_symbol_other (unsigned int other)
10003{
10004 if (PPC64_LOCAL_ENTRY_OFFSET (other) != 0)
10005 {
10006 static char buf[32];
10007 snprintf (buf, sizeof buf, _("<localentry>: %d"),
10008 PPC64_LOCAL_ENTRY_OFFSET (other));
10009 return buf;
10010 }
10011 return NULL;
10012}
10013
5e2b0d47
NC
10014static const char *
10015get_symbol_other (unsigned int other)
10016{
10017 const char * result = NULL;
10018 static char buff [32];
10019
10020 if (other == 0)
10021 return "";
10022
10023 switch (elf_header.e_machine)
10024 {
10025 case EM_MIPS:
10026 result = get_mips_symbol_other (other);
28f997cf
TG
10027 break;
10028 case EM_IA_64:
10029 result = get_ia64_symbol_other (other);
10030 break;
6911b7dc
AM
10031 case EM_PPC64:
10032 result = get_ppc64_symbol_other (other);
10033 break;
5e2b0d47
NC
10034 default:
10035 break;
10036 }
10037
10038 if (result)
10039 return result;
10040
10041 snprintf (buff, sizeof buff, _("<other>: %x"), other);
10042 return buff;
10043}
10044
d1133906 10045static const char *
d3ba0551 10046get_symbol_index_type (unsigned int type)
252b5132 10047{
b34976b6 10048 static char buff[32];
5cf1065c 10049
252b5132
RH
10050 switch (type)
10051 {
b34976b6
AM
10052 case SHN_UNDEF: return "UND";
10053 case SHN_ABS: return "ABS";
10054 case SHN_COMMON: return "COM";
252b5132 10055 default:
9ce701e2
L
10056 if (type == SHN_IA_64_ANSI_COMMON
10057 && elf_header.e_machine == EM_IA_64
10058 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
10059 return "ANSI_COM";
8a9036a4 10060 else if ((elf_header.e_machine == EM_X86_64
7a9068fe
L
10061 || elf_header.e_machine == EM_L1OM
10062 || elf_header.e_machine == EM_K1OM)
3b22753a
L
10063 && type == SHN_X86_64_LCOMMON)
10064 return "LARGE_COM";
ac145307
BS
10065 else if ((type == SHN_MIPS_SCOMMON
10066 && elf_header.e_machine == EM_MIPS)
10067 || (type == SHN_TIC6X_SCOMMON
10068 && elf_header.e_machine == EM_TI_C6000))
172553c7
TS
10069 return "SCOM";
10070 else if (type == SHN_MIPS_SUNDEFINED
10071 && elf_header.e_machine == EM_MIPS)
10072 return "SUND";
9ce701e2 10073 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
4fbb74a6 10074 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
252b5132 10075 else if (type >= SHN_LOOS && type <= SHN_HIOS)
4fbb74a6
AM
10076 sprintf (buff, "OS [0x%04x]", type & 0xffff);
10077 else if (type >= SHN_LORESERVE)
10078 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
c6d8cab4 10079 else if (type >= elf_header.e_shnum)
e0a31db1 10080 sprintf (buff, _("bad section index[%3d]"), type);
252b5132 10081 else
232e7cb8 10082 sprintf (buff, "%3d", type);
5cf1065c 10083 break;
252b5132 10084 }
5cf1065c
NC
10085
10086 return buff;
252b5132
RH
10087}
10088
66543521 10089static bfd_vma *
57028622 10090get_dynamic_data (FILE * file, bfd_size_type number, unsigned int ent_size)
252b5132 10091{
2cf0635d
NC
10092 unsigned char * e_data;
10093 bfd_vma * i_data;
252b5132 10094
57028622
NC
10095 /* If the size_t type is smaller than the bfd_size_type, eg because
10096 you are building a 32-bit tool on a 64-bit host, then make sure
10097 that when (number) is cast to (size_t) no information is lost. */
10098 if (sizeof (size_t) < sizeof (bfd_size_type)
10099 && (bfd_size_type) ((size_t) number) != number)
10100 {
10101 error (_("Size truncation prevents reading %llu elements of size %u\n"),
10102 (unsigned long long) number, ent_size);
10103 return NULL;
10104 }
10105
3102e897
NC
10106 /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
10107 attempting to allocate memory when the read is bound to fail. */
10108 if (ent_size * number > current_file_size)
10109 {
57028622
NC
10110 error (_("Invalid number of dynamic entries: %llu\n"),
10111 (unsigned long long) number);
3102e897
NC
10112 return NULL;
10113 }
10114
57028622 10115 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
252b5132
RH
10116 if (e_data == NULL)
10117 {
57028622
NC
10118 error (_("Out of memory reading %llu dynamic entries\n"),
10119 (unsigned long long) number);
252b5132
RH
10120 return NULL;
10121 }
10122
57028622 10123 if (fread (e_data, ent_size, (size_t) number, file) != number)
252b5132 10124 {
57028622
NC
10125 error (_("Unable to read in %llu bytes of dynamic data\n"),
10126 (unsigned long long) (number * ent_size));
3102e897 10127 free (e_data);
252b5132
RH
10128 return NULL;
10129 }
10130
57028622 10131 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
252b5132
RH
10132 if (i_data == NULL)
10133 {
57028622
NC
10134 error (_("Out of memory allocating space for %llu dynamic entries\n"),
10135 (unsigned long long) number);
252b5132
RH
10136 free (e_data);
10137 return NULL;
10138 }
10139
10140 while (number--)
66543521 10141 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
252b5132
RH
10142
10143 free (e_data);
10144
10145 return i_data;
10146}
10147
6bd1a22c
L
10148static void
10149print_dynamic_symbol (bfd_vma si, unsigned long hn)
10150{
2cf0635d 10151 Elf_Internal_Sym * psym;
6bd1a22c
L
10152 int n;
10153
6bd1a22c
L
10154 n = print_vma (si, DEC_5);
10155 if (n < 5)
0b4362b0 10156 fputs (&" "[n], stdout);
6bd1a22c 10157 printf (" %3lu: ", hn);
e0a31db1
NC
10158
10159 if (dynamic_symbols == NULL || si >= num_dynamic_syms)
10160 {
3102e897
NC
10161 printf (_("<No info available for dynamic symbol number %lu>\n"),
10162 (unsigned long) si);
e0a31db1
NC
10163 return;
10164 }
10165
10166 psym = dynamic_symbols + si;
6bd1a22c
L
10167 print_vma (psym->st_value, LONG_HEX);
10168 putchar (' ');
10169 print_vma (psym->st_size, DEC_5);
10170
f4be36b3
AM
10171 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10172 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
10173 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
6bd1a22c
L
10174 /* Check to see if any other bits in the st_other field are set.
10175 Note - displaying this information disrupts the layout of the
10176 table being generated, but for the moment this case is very
10177 rare. */
10178 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10179 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
10180 printf (" %3.3s ", get_symbol_index_type (psym->st_shndx));
10181 if (VALID_DYNAMIC_NAME (psym->st_name))
10182 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
10183 else
2b692964 10184 printf (_(" <corrupt: %14ld>"), psym->st_name);
6bd1a22c
L
10185 putchar ('\n');
10186}
10187
bb4d2ac2
L
10188static const char *
10189get_symbol_version_string (FILE *file, int is_dynsym,
10190 const char *strtab,
10191 unsigned long int strtab_size,
10192 unsigned int si, Elf_Internal_Sym *psym,
10193 enum versioned_symbol_info *sym_info,
10194 unsigned short *vna_other)
10195{
10196 const char *version_string = NULL;
10197
10198 if (is_dynsym
10199 && version_info[DT_VERSIONTAGIDX (DT_VERSYM)] != 0)
10200 {
10201 unsigned char data[2];
10202 unsigned short vers_data;
10203 unsigned long offset;
10204 int is_nobits;
10205 int check_def;
10206
10207 offset = offset_from_vma
10208 (file, version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
10209 sizeof data + si * sizeof (vers_data));
10210
10211 if (get_data (&data, file, offset + si * sizeof (vers_data),
10212 sizeof (data), 1, _("version data")) == NULL)
10213 return NULL;
10214
10215 vers_data = byte_get (data, 2);
10216
53774b7e
NC
10217 is_nobits = (section_headers != NULL
10218 && psym->st_shndx < elf_header.e_shnum
bb4d2ac2
L
10219 && section_headers[psym->st_shndx].sh_type
10220 == SHT_NOBITS);
10221
10222 check_def = (psym->st_shndx != SHN_UNDEF);
10223
10224 if ((vers_data & VERSYM_HIDDEN) || vers_data > 1)
10225 {
10226 if (version_info[DT_VERSIONTAGIDX (DT_VERNEED)]
10227 && (is_nobits || ! check_def))
10228 {
10229 Elf_External_Verneed evn;
10230 Elf_Internal_Verneed ivn;
10231 Elf_Internal_Vernaux ivna;
10232
10233 /* We must test both. */
10234 offset = offset_from_vma
10235 (file, version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
10236 sizeof evn);
10237
10238 do
10239 {
10240 unsigned long vna_off;
10241
10242 if (get_data (&evn, file, offset, sizeof (evn), 1,
10243 _("version need")) == NULL)
10244 {
10245 ivna.vna_next = 0;
10246 ivna.vna_other = 0;
10247 ivna.vna_name = 0;
10248 break;
10249 }
10250
10251 ivn.vn_aux = BYTE_GET (evn.vn_aux);
10252 ivn.vn_next = BYTE_GET (evn.vn_next);
10253
10254 vna_off = offset + ivn.vn_aux;
10255
10256 do
10257 {
10258 Elf_External_Vernaux evna;
10259
10260 if (get_data (&evna, file, vna_off,
10261 sizeof (evna), 1,
10262 _("version need aux (3)")) == NULL)
10263 {
10264 ivna.vna_next = 0;
10265 ivna.vna_other = 0;
10266 ivna.vna_name = 0;
10267 }
10268 else
10269 {
10270 ivna.vna_other = BYTE_GET (evna.vna_other);
10271 ivna.vna_next = BYTE_GET (evna.vna_next);
10272 ivna.vna_name = BYTE_GET (evna.vna_name);
10273 }
10274
10275 vna_off += ivna.vna_next;
10276 }
10277 while (ivna.vna_other != vers_data
10278 && ivna.vna_next != 0);
10279
10280 if (ivna.vna_other == vers_data)
10281 break;
10282
10283 offset += ivn.vn_next;
10284 }
10285 while (ivn.vn_next != 0);
10286
10287 if (ivna.vna_other == vers_data)
10288 {
10289 *sym_info = symbol_undefined;
10290 *vna_other = ivna.vna_other;
10291 version_string = (ivna.vna_name < strtab_size
10292 ? strtab + ivna.vna_name
10293 : _("<corrupt>"));
10294 check_def = 0;
10295 }
10296 else if (! is_nobits)
10297 error (_("bad dynamic symbol\n"));
10298 else
10299 check_def = 1;
10300 }
10301
10302 if (check_def)
10303 {
10304 if (vers_data != 0x8001
10305 && version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
10306 {
10307 Elf_Internal_Verdef ivd;
10308 Elf_Internal_Verdaux ivda;
10309 Elf_External_Verdaux evda;
10310 unsigned long off;
10311
10312 off = offset_from_vma
10313 (file,
10314 version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
10315 sizeof (Elf_External_Verdef));
10316
10317 do
10318 {
10319 Elf_External_Verdef evd;
10320
10321 if (get_data (&evd, file, off, sizeof (evd),
10322 1, _("version def")) == NULL)
10323 {
10324 ivd.vd_ndx = 0;
10325 ivd.vd_aux = 0;
10326 ivd.vd_next = 0;
10327 }
10328 else
10329 {
10330 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
10331 ivd.vd_aux = BYTE_GET (evd.vd_aux);
10332 ivd.vd_next = BYTE_GET (evd.vd_next);
10333 }
10334
10335 off += ivd.vd_next;
10336 }
10337 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION)
10338 && ivd.vd_next != 0);
10339
10340 off -= ivd.vd_next;
10341 off += ivd.vd_aux;
10342
10343 if (get_data (&evda, file, off, sizeof (evda),
10344 1, _("version def aux")) == NULL)
10345 return version_string;
10346
10347 ivda.vda_name = BYTE_GET (evda.vda_name);
10348
10349 if (psym->st_name != ivda.vda_name)
10350 {
10351 *sym_info = ((vers_data & VERSYM_HIDDEN) != 0
10352 ? symbol_hidden : symbol_public);
10353 version_string = (ivda.vda_name < strtab_size
10354 ? strtab + ivda.vda_name
10355 : _("<corrupt>"));
10356 }
10357 }
10358 }
10359 }
10360 }
10361 return version_string;
10362}
10363
e3c8793a 10364/* Dump the symbol table. */
252b5132 10365static int
2cf0635d 10366process_symbol_table (FILE * file)
252b5132 10367{
2cf0635d 10368 Elf_Internal_Shdr * section;
8b73c356
NC
10369 bfd_size_type nbuckets = 0;
10370 bfd_size_type nchains = 0;
2cf0635d
NC
10371 bfd_vma * buckets = NULL;
10372 bfd_vma * chains = NULL;
fdc90cb4 10373 bfd_vma ngnubuckets = 0;
2cf0635d
NC
10374 bfd_vma * gnubuckets = NULL;
10375 bfd_vma * gnuchains = NULL;
6bd1a22c 10376 bfd_vma gnusymidx = 0;
071436c6 10377 bfd_size_type ngnuchains = 0;
252b5132 10378
2c610e4b 10379 if (!do_syms && !do_dyn_syms && !do_histogram)
252b5132
RH
10380 return 1;
10381
6bd1a22c
L
10382 if (dynamic_info[DT_HASH]
10383 && (do_histogram
2c610e4b
L
10384 || (do_using_dynamic
10385 && !do_dyn_syms
10386 && dynamic_strings != NULL)))
252b5132 10387 {
66543521
AM
10388 unsigned char nb[8];
10389 unsigned char nc[8];
8b73c356 10390 unsigned int hash_ent_size = 4;
66543521
AM
10391
10392 if ((elf_header.e_machine == EM_ALPHA
10393 || elf_header.e_machine == EM_S390
10394 || elf_header.e_machine == EM_S390_OLD)
10395 && elf_header.e_ident[EI_CLASS] == ELFCLASS64)
10396 hash_ent_size = 8;
10397
fb52b2f4
NC
10398 if (fseek (file,
10399 (archive_file_offset
10400 + offset_from_vma (file, dynamic_info[DT_HASH],
10401 sizeof nb + sizeof nc)),
d93f0186 10402 SEEK_SET))
252b5132 10403 {
591a748a 10404 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10405 goto no_hash;
252b5132
RH
10406 }
10407
66543521 10408 if (fread (nb, hash_ent_size, 1, file) != 1)
252b5132
RH
10409 {
10410 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10411 goto no_hash;
252b5132
RH
10412 }
10413
66543521 10414 if (fread (nc, hash_ent_size, 1, file) != 1)
252b5132
RH
10415 {
10416 error (_("Failed to read in number of chains\n"));
d3a44ec6 10417 goto no_hash;
252b5132
RH
10418 }
10419
66543521
AM
10420 nbuckets = byte_get (nb, hash_ent_size);
10421 nchains = byte_get (nc, hash_ent_size);
252b5132 10422
66543521
AM
10423 buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
10424 chains = get_dynamic_data (file, nchains, hash_ent_size);
252b5132 10425
d3a44ec6 10426 no_hash:
252b5132 10427 if (buckets == NULL || chains == NULL)
d3a44ec6
JJ
10428 {
10429 if (do_using_dynamic)
10430 return 0;
10431 free (buckets);
10432 free (chains);
10433 buckets = NULL;
10434 chains = NULL;
10435 nbuckets = 0;
10436 nchains = 0;
10437 }
252b5132
RH
10438 }
10439
6bd1a22c
L
10440 if (dynamic_info_DT_GNU_HASH
10441 && (do_histogram
2c610e4b
L
10442 || (do_using_dynamic
10443 && !do_dyn_syms
10444 && dynamic_strings != NULL)))
252b5132 10445 {
6bd1a22c
L
10446 unsigned char nb[16];
10447 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10448 bfd_vma buckets_vma;
10449
10450 if (fseek (file,
10451 (archive_file_offset
10452 + offset_from_vma (file, dynamic_info_DT_GNU_HASH,
10453 sizeof nb)),
10454 SEEK_SET))
10455 {
10456 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10457 goto no_gnu_hash;
6bd1a22c 10458 }
252b5132 10459
6bd1a22c
L
10460 if (fread (nb, 16, 1, file) != 1)
10461 {
10462 error (_("Failed to read in number of buckets\n"));
d3a44ec6 10463 goto no_gnu_hash;
6bd1a22c
L
10464 }
10465
10466 ngnubuckets = byte_get (nb, 4);
10467 gnusymidx = byte_get (nb + 4, 4);
10468 bitmaskwords = byte_get (nb + 8, 4);
10469 buckets_vma = dynamic_info_DT_GNU_HASH + 16;
f7a99963 10470 if (is_32bit_elf)
6bd1a22c 10471 buckets_vma += bitmaskwords * 4;
f7a99963 10472 else
6bd1a22c 10473 buckets_vma += bitmaskwords * 8;
252b5132 10474
6bd1a22c
L
10475 if (fseek (file,
10476 (archive_file_offset
10477 + offset_from_vma (file, buckets_vma, 4)),
10478 SEEK_SET))
252b5132 10479 {
6bd1a22c 10480 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10481 goto no_gnu_hash;
6bd1a22c
L
10482 }
10483
10484 gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
252b5132 10485
6bd1a22c 10486 if (gnubuckets == NULL)
d3a44ec6 10487 goto no_gnu_hash;
6bd1a22c
L
10488
10489 for (i = 0; i < ngnubuckets; i++)
10490 if (gnubuckets[i] != 0)
10491 {
10492 if (gnubuckets[i] < gnusymidx)
10493 return 0;
10494
10495 if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
10496 maxchain = gnubuckets[i];
10497 }
10498
10499 if (maxchain == 0xffffffff)
d3a44ec6 10500 goto no_gnu_hash;
6bd1a22c
L
10501
10502 maxchain -= gnusymidx;
10503
10504 if (fseek (file,
10505 (archive_file_offset
10506 + offset_from_vma (file, buckets_vma
10507 + 4 * (ngnubuckets + maxchain), 4)),
10508 SEEK_SET))
10509 {
10510 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10511 goto no_gnu_hash;
6bd1a22c
L
10512 }
10513
10514 do
10515 {
10516 if (fread (nb, 4, 1, file) != 1)
252b5132 10517 {
6bd1a22c 10518 error (_("Failed to determine last chain length\n"));
d3a44ec6 10519 goto no_gnu_hash;
6bd1a22c 10520 }
252b5132 10521
6bd1a22c 10522 if (maxchain + 1 == 0)
d3a44ec6 10523 goto no_gnu_hash;
252b5132 10524
6bd1a22c
L
10525 ++maxchain;
10526 }
10527 while ((byte_get (nb, 4) & 1) == 0);
76da6bbe 10528
6bd1a22c
L
10529 if (fseek (file,
10530 (archive_file_offset
10531 + offset_from_vma (file, buckets_vma + 4 * ngnubuckets, 4)),
10532 SEEK_SET))
10533 {
10534 error (_("Unable to seek to start of dynamic information\n"));
d3a44ec6 10535 goto no_gnu_hash;
6bd1a22c
L
10536 }
10537
10538 gnuchains = get_dynamic_data (file, maxchain, 4);
071436c6 10539 ngnuchains = maxchain;
6bd1a22c 10540
d3a44ec6 10541 no_gnu_hash:
6bd1a22c 10542 if (gnuchains == NULL)
d3a44ec6
JJ
10543 {
10544 free (gnubuckets);
d3a44ec6
JJ
10545 gnubuckets = NULL;
10546 ngnubuckets = 0;
f64fddf1
NC
10547 if (do_using_dynamic)
10548 return 0;
d3a44ec6 10549 }
6bd1a22c
L
10550 }
10551
10552 if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
10553 && do_syms
10554 && do_using_dynamic
3102e897
NC
10555 && dynamic_strings != NULL
10556 && dynamic_symbols != NULL)
6bd1a22c
L
10557 {
10558 unsigned long hn;
10559
10560 if (dynamic_info[DT_HASH])
10561 {
10562 bfd_vma si;
10563
10564 printf (_("\nSymbol table for image:\n"));
10565 if (is_32bit_elf)
10566 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10567 else
10568 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10569
10570 for (hn = 0; hn < nbuckets; hn++)
10571 {
10572 if (! buckets[hn])
10573 continue;
10574
10575 for (si = buckets[hn]; si < nchains && si > 0; si = chains[si])
10576 print_dynamic_symbol (si, hn);
252b5132
RH
10577 }
10578 }
6bd1a22c
L
10579
10580 if (dynamic_info_DT_GNU_HASH)
10581 {
10582 printf (_("\nSymbol table of `.gnu.hash' for image:\n"));
10583 if (is_32bit_elf)
10584 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10585 else
10586 printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
10587
10588 for (hn = 0; hn < ngnubuckets; ++hn)
10589 if (gnubuckets[hn] != 0)
10590 {
10591 bfd_vma si = gnubuckets[hn];
10592 bfd_vma off = si - gnusymidx;
10593
10594 do
10595 {
10596 print_dynamic_symbol (si, hn);
10597 si++;
10598 }
071436c6 10599 while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
6bd1a22c
L
10600 }
10601 }
252b5132 10602 }
8b73c356
NC
10603 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
10604 && section_headers != NULL)
252b5132 10605 {
b34976b6 10606 unsigned int i;
252b5132
RH
10607
10608 for (i = 0, section = section_headers;
10609 i < elf_header.e_shnum;
10610 i++, section++)
10611 {
b34976b6 10612 unsigned int si;
2cf0635d 10613 char * strtab = NULL;
c256ffe7 10614 unsigned long int strtab_size = 0;
2cf0635d
NC
10615 Elf_Internal_Sym * symtab;
10616 Elf_Internal_Sym * psym;
ba5cdace 10617 unsigned long num_syms;
252b5132 10618
2c610e4b
L
10619 if ((section->sh_type != SHT_SYMTAB
10620 && section->sh_type != SHT_DYNSYM)
10621 || (!do_syms
10622 && section->sh_type == SHT_SYMTAB))
252b5132
RH
10623 continue;
10624
dd24e3da
NC
10625 if (section->sh_entsize == 0)
10626 {
10627 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
74e1a04b 10628 printable_section_name (section));
dd24e3da
NC
10629 continue;
10630 }
10631
252b5132 10632 printf (_("\nSymbol table '%s' contains %lu entries:\n"),
74e1a04b 10633 printable_section_name (section),
252b5132 10634 (unsigned long) (section->sh_size / section->sh_entsize));
dd24e3da 10635
f7a99963 10636 if (is_32bit_elf)
ca47b30c 10637 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 10638 else
ca47b30c 10639 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 10640
ba5cdace 10641 symtab = GET_ELF_SYMBOLS (file, section, & num_syms);
252b5132
RH
10642 if (symtab == NULL)
10643 continue;
10644
10645 if (section->sh_link == elf_header.e_shstrndx)
c256ffe7
JJ
10646 {
10647 strtab = string_table;
10648 strtab_size = string_table_length;
10649 }
4fbb74a6 10650 else if (section->sh_link < elf_header.e_shnum)
252b5132 10651 {
2cf0635d 10652 Elf_Internal_Shdr * string_sec;
252b5132 10653
4fbb74a6 10654 string_sec = section_headers + section->sh_link;
252b5132 10655
3f5e193b
NC
10656 strtab = (char *) get_data (NULL, file, string_sec->sh_offset,
10657 1, string_sec->sh_size,
10658 _("string table"));
c256ffe7 10659 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
10660 }
10661
ba5cdace 10662 for (si = 0, psym = symtab; si < num_syms; si++, psym++)
252b5132 10663 {
bb4d2ac2
L
10664 const char *version_string;
10665 enum versioned_symbol_info sym_info;
10666 unsigned short vna_other;
10667
5e220199 10668 printf ("%6d: ", si);
f7a99963
NC
10669 print_vma (psym->st_value, LONG_HEX);
10670 putchar (' ');
10671 print_vma (psym->st_size, DEC_5);
d1133906
NC
10672 printf (" %-7s", get_symbol_type (ELF_ST_TYPE (psym->st_info)));
10673 printf (" %-6s", get_symbol_binding (ELF_ST_BIND (psym->st_info)));
f4be36b3 10674 printf (" %-7s", get_symbol_visibility (ELF_ST_VISIBILITY (psym->st_other)));
5e2b0d47
NC
10675 /* Check to see if any other bits in the st_other field are set.
10676 Note - displaying this information disrupts the layout of the
10677 table being generated, but for the moment this case is very rare. */
10678 if (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other))
10679 printf (" [%s] ", get_symbol_other (psym->st_other ^ ELF_ST_VISIBILITY (psym->st_other)));
31104126 10680 printf (" %4s ", get_symbol_index_type (psym->st_shndx));
c256ffe7 10681 print_symbol (25, psym->st_name < strtab_size
2b692964 10682 ? strtab + psym->st_name : _("<corrupt>"));
252b5132 10683
bb4d2ac2
L
10684 version_string
10685 = get_symbol_version_string (file,
10686 section->sh_type == SHT_DYNSYM,
10687 strtab, strtab_size, si,
10688 psym, &sym_info, &vna_other);
10689 if (version_string)
252b5132 10690 {
bb4d2ac2
L
10691 if (sym_info == symbol_undefined)
10692 printf ("@%s (%d)", version_string, vna_other);
10693 else
10694 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
10695 version_string);
252b5132
RH
10696 }
10697
10698 putchar ('\n');
10699 }
10700
10701 free (symtab);
10702 if (strtab != string_table)
10703 free (strtab);
10704 }
10705 }
10706 else if (do_syms)
10707 printf
10708 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
10709
10710 if (do_histogram && buckets != NULL)
10711 {
2cf0635d
NC
10712 unsigned long * lengths;
10713 unsigned long * counts;
66543521
AM
10714 unsigned long hn;
10715 bfd_vma si;
10716 unsigned long maxlength = 0;
10717 unsigned long nzero_counts = 0;
10718 unsigned long nsyms = 0;
252b5132 10719
66543521
AM
10720 printf (_("\nHistogram for bucket list length (total of %lu buckets):\n"),
10721 (unsigned long) nbuckets);
252b5132 10722
3f5e193b 10723 lengths = (unsigned long *) calloc (nbuckets, sizeof (*lengths));
252b5132
RH
10724 if (lengths == NULL)
10725 {
8b73c356 10726 error (_("Out of memory allocating space for histogram buckets\n"));
252b5132
RH
10727 return 0;
10728 }
8b73c356
NC
10729
10730 printf (_(" Length Number %% of total Coverage\n"));
252b5132
RH
10731 for (hn = 0; hn < nbuckets; ++hn)
10732 {
57028622 10733 for (si = buckets[hn]; si > 0 && si < nchains && si < nbuckets; si = chains[si])
252b5132 10734 {
b34976b6 10735 ++nsyms;
252b5132 10736 if (maxlength < ++lengths[hn])
b34976b6 10737 ++maxlength;
049b0c3a
NC
10738
10739 /* PR binutils/17531: A corrupt binary could contain broken
10740 histogram data. Do not go into an infinite loop trying
10741 to process it. */
10742 if (chains[si] == si)
10743 {
10744 error (_("histogram chain links to itself\n"));
10745 break;
10746 }
252b5132
RH
10747 }
10748 }
10749
3f5e193b 10750 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
10751 if (counts == NULL)
10752 {
b2e951ec 10753 free (lengths);
8b73c356 10754 error (_("Out of memory allocating space for histogram counts\n"));
252b5132
RH
10755 return 0;
10756 }
10757
10758 for (hn = 0; hn < nbuckets; ++hn)
b34976b6 10759 ++counts[lengths[hn]];
252b5132 10760
103f02d3 10761 if (nbuckets > 0)
252b5132 10762 {
66543521
AM
10763 unsigned long i;
10764 printf (" 0 %-10lu (%5.1f%%)\n",
103f02d3 10765 counts[0], (counts[0] * 100.0) / nbuckets);
66543521 10766 for (i = 1; i <= maxlength; ++i)
103f02d3 10767 {
66543521
AM
10768 nzero_counts += counts[i] * i;
10769 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10770 i, counts[i], (counts[i] * 100.0) / nbuckets,
103f02d3
UD
10771 (nzero_counts * 100.0) / nsyms);
10772 }
252b5132
RH
10773 }
10774
10775 free (counts);
10776 free (lengths);
10777 }
10778
10779 if (buckets != NULL)
10780 {
10781 free (buckets);
10782 free (chains);
10783 }
10784
d3a44ec6 10785 if (do_histogram && gnubuckets != NULL)
fdc90cb4 10786 {
2cf0635d
NC
10787 unsigned long * lengths;
10788 unsigned long * counts;
fdc90cb4
JJ
10789 unsigned long hn;
10790 unsigned long maxlength = 0;
10791 unsigned long nzero_counts = 0;
10792 unsigned long nsyms = 0;
fdc90cb4 10793
8b73c356
NC
10794 printf (_("\nHistogram for `.gnu.hash' bucket list length (total of %lu buckets):\n"),
10795 (unsigned long) ngnubuckets);
10796
3f5e193b 10797 lengths = (unsigned long *) calloc (ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
10798 if (lengths == NULL)
10799 {
8b73c356 10800 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fdc90cb4
JJ
10801 return 0;
10802 }
10803
fdc90cb4
JJ
10804 printf (_(" Length Number %% of total Coverage\n"));
10805
10806 for (hn = 0; hn < ngnubuckets; ++hn)
10807 if (gnubuckets[hn] != 0)
10808 {
10809 bfd_vma off, length = 1;
10810
6bd1a22c 10811 for (off = gnubuckets[hn] - gnusymidx;
071436c6
NC
10812 /* PR 17531 file: 010-77222-0.004. */
10813 off < ngnuchains && (gnuchains[off] & 1) == 0;
10814 ++off)
fdc90cb4
JJ
10815 ++length;
10816 lengths[hn] = length;
10817 if (length > maxlength)
10818 maxlength = length;
10819 nsyms += length;
10820 }
10821
3f5e193b 10822 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
10823 if (counts == NULL)
10824 {
b2e951ec 10825 free (lengths);
8b73c356 10826 error (_("Out of memory allocating space for gnu histogram counts\n"));
fdc90cb4
JJ
10827 return 0;
10828 }
10829
10830 for (hn = 0; hn < ngnubuckets; ++hn)
10831 ++counts[lengths[hn]];
10832
10833 if (ngnubuckets > 0)
10834 {
10835 unsigned long j;
10836 printf (" 0 %-10lu (%5.1f%%)\n",
10837 counts[0], (counts[0] * 100.0) / ngnubuckets);
10838 for (j = 1; j <= maxlength; ++j)
10839 {
10840 nzero_counts += counts[j] * j;
10841 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
10842 j, counts[j], (counts[j] * 100.0) / ngnubuckets,
10843 (nzero_counts * 100.0) / nsyms);
10844 }
10845 }
10846
10847 free (counts);
10848 free (lengths);
10849 free (gnubuckets);
10850 free (gnuchains);
10851 }
10852
252b5132
RH
10853 return 1;
10854}
10855
10856static int
2cf0635d 10857process_syminfo (FILE * file ATTRIBUTE_UNUSED)
252b5132 10858{
b4c96d0d 10859 unsigned int i;
252b5132
RH
10860
10861 if (dynamic_syminfo == NULL
10862 || !do_dynamic)
10863 /* No syminfo, this is ok. */
10864 return 1;
10865
10866 /* There better should be a dynamic symbol section. */
10867 if (dynamic_symbols == NULL || dynamic_strings == NULL)
10868 return 0;
10869
10870 if (dynamic_addr)
10871 printf (_("\nDynamic info segment at offset 0x%lx contains %d entries:\n"),
10872 dynamic_syminfo_offset, dynamic_syminfo_nent);
10873
10874 printf (_(" Num: Name BoundTo Flags\n"));
10875 for (i = 0; i < dynamic_syminfo_nent; ++i)
10876 {
10877 unsigned short int flags = dynamic_syminfo[i].si_flags;
10878
31104126 10879 printf ("%4d: ", i);
4082ef84
NC
10880 if (i >= num_dynamic_syms)
10881 printf (_("<corrupt index>"));
10882 else if (VALID_DYNAMIC_NAME (dynamic_symbols[i].st_name))
d79b3d50
NC
10883 print_symbol (30, GET_DYNAMIC_NAME (dynamic_symbols[i].st_name));
10884 else
2b692964 10885 printf (_("<corrupt: %19ld>"), dynamic_symbols[i].st_name);
31104126 10886 putchar (' ');
252b5132
RH
10887
10888 switch (dynamic_syminfo[i].si_boundto)
10889 {
10890 case SYMINFO_BT_SELF:
10891 fputs ("SELF ", stdout);
10892 break;
10893 case SYMINFO_BT_PARENT:
10894 fputs ("PARENT ", stdout);
10895 break;
10896 default:
10897 if (dynamic_syminfo[i].si_boundto > 0
d79b3d50
NC
10898 && dynamic_syminfo[i].si_boundto < dynamic_nent
10899 && VALID_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 10900 {
d79b3d50 10901 print_symbol (10, GET_DYNAMIC_NAME (dynamic_section[dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
10902 putchar (' ' );
10903 }
252b5132
RH
10904 else
10905 printf ("%-10d ", dynamic_syminfo[i].si_boundto);
10906 break;
10907 }
10908
10909 if (flags & SYMINFO_FLG_DIRECT)
10910 printf (" DIRECT");
10911 if (flags & SYMINFO_FLG_PASSTHRU)
10912 printf (" PASSTHRU");
10913 if (flags & SYMINFO_FLG_COPY)
10914 printf (" COPY");
10915 if (flags & SYMINFO_FLG_LAZYLOAD)
10916 printf (" LAZYLOAD");
10917
10918 puts ("");
10919 }
10920
10921 return 1;
10922}
10923
cf13d699
NC
10924/* Check to see if the given reloc needs to be handled in a target specific
10925 manner. If so then process the reloc and return TRUE otherwise return
10926 FALSE. */
09c11c86 10927
cf13d699
NC
10928static bfd_boolean
10929target_specific_reloc_handling (Elf_Internal_Rela * reloc,
10930 unsigned char * start,
10931 Elf_Internal_Sym * symtab)
252b5132 10932{
cf13d699 10933 unsigned int reloc_type = get_reloc_type (reloc->r_info);
252b5132 10934
cf13d699 10935 switch (elf_header.e_machine)
252b5132 10936 {
13761a11
NC
10937 case EM_MSP430:
10938 case EM_MSP430_OLD:
10939 {
10940 static Elf_Internal_Sym * saved_sym = NULL;
10941
10942 switch (reloc_type)
10943 {
10944 case 10: /* R_MSP430_SYM_DIFF */
10945 if (uses_msp430x_relocs ())
10946 break;
10947 case 21: /* R_MSP430X_SYM_DIFF */
10948 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
10949 return TRUE;
10950
10951 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
10952 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
10953 goto handle_sym_diff;
0b4362b0 10954
13761a11
NC
10955 case 5: /* R_MSP430_16_BYTE */
10956 case 9: /* R_MSP430_8 */
10957 if (uses_msp430x_relocs ())
10958 break;
10959 goto handle_sym_diff;
10960
10961 case 2: /* R_MSP430_ABS16 */
10962 case 15: /* R_MSP430X_ABS16 */
10963 if (! uses_msp430x_relocs ())
10964 break;
10965 goto handle_sym_diff;
0b4362b0 10966
13761a11
NC
10967 handle_sym_diff:
10968 if (saved_sym != NULL)
10969 {
10970 bfd_vma value;
10971
10972 value = reloc->r_addend
10973 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
10974 - saved_sym->st_value);
10975
10976 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
10977
10978 saved_sym = NULL;
10979 return TRUE;
10980 }
10981 break;
10982
10983 default:
10984 if (saved_sym != NULL)
071436c6 10985 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
10986 break;
10987 }
10988 break;
10989 }
10990
cf13d699
NC
10991 case EM_MN10300:
10992 case EM_CYGNUS_MN10300:
10993 {
10994 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 10995
cf13d699
NC
10996 switch (reloc_type)
10997 {
10998 case 34: /* R_MN10300_ALIGN */
10999 return TRUE;
11000 case 33: /* R_MN10300_SYM_DIFF */
11001 saved_sym = symtab + get_reloc_symindex (reloc->r_info);
11002 return TRUE;
11003 case 1: /* R_MN10300_32 */
11004 case 2: /* R_MN10300_16 */
11005 if (saved_sym != NULL)
11006 {
11007 bfd_vma value;
252b5132 11008
cf13d699
NC
11009 value = reloc->r_addend
11010 + (symtab[get_reloc_symindex (reloc->r_info)].st_value
11011 - saved_sym->st_value);
252b5132 11012
cf13d699 11013 byte_put (start + reloc->r_offset, value, reloc_type == 1 ? 4 : 2);
252b5132 11014
cf13d699
NC
11015 saved_sym = NULL;
11016 return TRUE;
11017 }
11018 break;
11019 default:
11020 if (saved_sym != NULL)
071436c6 11021 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
11022 break;
11023 }
11024 break;
11025 }
252b5132
RH
11026 }
11027
cf13d699 11028 return FALSE;
252b5132
RH
11029}
11030
aca88567
NC
11031/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
11032 DWARF debug sections. This is a target specific test. Note - we do not
11033 go through the whole including-target-headers-multiple-times route, (as
11034 we have already done with <elf/h8.h>) because this would become very
11035 messy and even then this function would have to contain target specific
11036 information (the names of the relocs instead of their numeric values).
11037 FIXME: This is not the correct way to solve this problem. The proper way
11038 is to have target specific reloc sizing and typing functions created by
11039 the reloc-macros.h header, in the same way that it already creates the
11040 reloc naming functions. */
11041
11042static bfd_boolean
11043is_32bit_abs_reloc (unsigned int reloc_type)
11044{
11045 switch (elf_header.e_machine)
11046 {
41e92641
NC
11047 case EM_386:
11048 case EM_486:
11049 return reloc_type == 1; /* R_386_32. */
aca88567
NC
11050 case EM_68K:
11051 return reloc_type == 1; /* R_68K_32. */
11052 case EM_860:
11053 return reloc_type == 1; /* R_860_32. */
137b6b5f
AM
11054 case EM_960:
11055 return reloc_type == 2; /* R_960_32. */
a06ea964
NC
11056 case EM_AARCH64:
11057 return reloc_type == 258; /* R_AARCH64_ABS32 */
aca88567 11058 case EM_ALPHA:
137b6b5f 11059 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
11060 case EM_ARC:
11061 return reloc_type == 1; /* R_ARC_32. */
11062 case EM_ARM:
11063 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 11064 case EM_AVR_OLD:
aca88567
NC
11065 case EM_AVR:
11066 return reloc_type == 1;
cfb8c092
NC
11067 case EM_ADAPTEVA_EPIPHANY:
11068 return reloc_type == 3;
aca88567
NC
11069 case EM_BLACKFIN:
11070 return reloc_type == 0x12; /* R_byte4_data. */
11071 case EM_CRIS:
11072 return reloc_type == 3; /* R_CRIS_32. */
11073 case EM_CR16:
11074 return reloc_type == 3; /* R_CR16_NUM32. */
11075 case EM_CRX:
11076 return reloc_type == 15; /* R_CRX_NUM32. */
11077 case EM_CYGNUS_FRV:
11078 return reloc_type == 1;
41e92641
NC
11079 case EM_CYGNUS_D10V:
11080 case EM_D10V:
11081 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
11082 case EM_CYGNUS_D30V:
11083 case EM_D30V:
11084 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
11085 case EM_DLX:
11086 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
11087 case EM_CYGNUS_FR30:
11088 case EM_FR30:
11089 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
11090 case EM_FT32:
11091 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
11092 case EM_H8S:
11093 case EM_H8_300:
11094 case EM_H8_300H:
11095 return reloc_type == 1; /* R_H8_DIR32. */
3730236a
NC
11096 case EM_IA_64:
11097 return reloc_type == 0x65; /* R_IA64_SECREL32LSB. */
aca88567
NC
11098 case EM_IP2K_OLD:
11099 case EM_IP2K:
11100 return reloc_type == 2; /* R_IP2K_32. */
11101 case EM_IQ2000:
11102 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
11103 case EM_LATTICEMICO32:
11104 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 11105 case EM_M32C_OLD:
aca88567
NC
11106 case EM_M32C:
11107 return reloc_type == 3; /* R_M32C_32. */
11108 case EM_M32R:
11109 return reloc_type == 34; /* R_M32R_32_RELA. */
11110 case EM_MCORE:
11111 return reloc_type == 1; /* R_MCORE_ADDR32. */
11112 case EM_CYGNUS_MEP:
11113 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
11114 case EM_METAG:
11115 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
11116 case EM_MICROBLAZE:
11117 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
11118 case EM_MIPS:
11119 return reloc_type == 2; /* R_MIPS_32. */
11120 case EM_MMIX:
11121 return reloc_type == 4; /* R_MMIX_32. */
11122 case EM_CYGNUS_MN10200:
11123 case EM_MN10200:
11124 return reloc_type == 1; /* R_MN10200_32. */
11125 case EM_CYGNUS_MN10300:
11126 case EM_MN10300:
11127 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
11128 case EM_MOXIE:
11129 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
11130 case EM_MSP430_OLD:
11131 case EM_MSP430:
13761a11 11132 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
11133 case EM_MT:
11134 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
11135 case EM_NDS32:
11136 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 11137 case EM_ALTERA_NIOS2:
36591ba1 11138 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
11139 case EM_NIOS32:
11140 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
11141 case EM_OR1K:
11142 return reloc_type == 1; /* R_OR1K_32. */
aca88567 11143 case EM_PARISC:
5fda8eca
NC
11144 return (reloc_type == 1 /* R_PARISC_DIR32. */
11145 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
11146 case EM_PJ:
11147 case EM_PJ_OLD:
11148 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
11149 case EM_PPC64:
11150 return reloc_type == 1; /* R_PPC64_ADDR32. */
11151 case EM_PPC:
11152 return reloc_type == 1; /* R_PPC_ADDR32. */
99c513f6
DD
11153 case EM_RL78:
11154 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
11155 case EM_RX:
11156 return reloc_type == 1; /* R_RX_DIR32. */
aca88567
NC
11157 case EM_S370:
11158 return reloc_type == 1; /* R_I370_ADDR31. */
11159 case EM_S390_OLD:
11160 case EM_S390:
11161 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
11162 case EM_SCORE:
11163 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
11164 case EM_SH:
11165 return reloc_type == 1; /* R_SH_DIR32. */
11166 case EM_SPARC32PLUS:
11167 case EM_SPARCV9:
11168 case EM_SPARC:
11169 return reloc_type == 3 /* R_SPARC_32. */
11170 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
11171 case EM_SPU:
11172 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
11173 case EM_TI_C6000:
11174 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
11175 case EM_TILEGX:
11176 return reloc_type == 2; /* R_TILEGX_32. */
11177 case EM_TILEPRO:
11178 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
11179 case EM_CYGNUS_V850:
11180 case EM_V850:
11181 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
11182 case EM_V800:
11183 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
11184 case EM_VAX:
11185 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
11186 case EM_VISIUM:
11187 return reloc_type == 3; /* R_VISIUM_32. */
aca88567 11188 case EM_X86_64:
8a9036a4 11189 case EM_L1OM:
7a9068fe 11190 case EM_K1OM:
aca88567 11191 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
11192 case EM_XC16X:
11193 case EM_C166:
11194 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
11195 case EM_XGATE:
11196 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
11197 case EM_XSTORMY16:
11198 return reloc_type == 1; /* R_XSTROMY16_32. */
11199 case EM_XTENSA_OLD:
11200 case EM_XTENSA:
11201 return reloc_type == 1; /* R_XTENSA_32. */
aca88567 11202 default:
bee0ee85
NC
11203 {
11204 static unsigned int prev_warn = 0;
11205
11206 /* Avoid repeating the same warning multiple times. */
11207 if (prev_warn != elf_header.e_machine)
11208 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
11209 elf_header.e_machine);
11210 prev_warn = elf_header.e_machine;
11211 return FALSE;
11212 }
aca88567
NC
11213 }
11214}
11215
11216/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11217 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
11218
11219static bfd_boolean
11220is_32bit_pcrel_reloc (unsigned int reloc_type)
11221{
11222 switch (elf_header.e_machine)
11223 {
41e92641
NC
11224 case EM_386:
11225 case EM_486:
3e0873ac 11226 return reloc_type == 2; /* R_386_PC32. */
aca88567 11227 case EM_68K:
3e0873ac 11228 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
11229 case EM_AARCH64:
11230 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
11231 case EM_ADAPTEVA_EPIPHANY:
11232 return reloc_type == 6;
aca88567
NC
11233 case EM_ALPHA:
11234 return reloc_type == 10; /* R_ALPHA_SREL32. */
41e92641 11235 case EM_ARM:
3e0873ac 11236 return reloc_type == 3; /* R_ARM_REL32 */
137b6b5f
AM
11237 case EM_MICROBLAZE:
11238 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
11239 case EM_OR1K:
11240 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 11241 case EM_PARISC:
85acf597 11242 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
11243 case EM_PPC:
11244 return reloc_type == 26; /* R_PPC_REL32. */
11245 case EM_PPC64:
3e0873ac 11246 return reloc_type == 26; /* R_PPC64_REL32. */
aca88567
NC
11247 case EM_S390_OLD:
11248 case EM_S390:
3e0873ac 11249 return reloc_type == 5; /* R_390_PC32. */
aca88567 11250 case EM_SH:
3e0873ac 11251 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
11252 case EM_SPARC32PLUS:
11253 case EM_SPARCV9:
11254 case EM_SPARC:
3e0873ac 11255 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
11256 case EM_SPU:
11257 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
11258 case EM_TILEGX:
11259 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
11260 case EM_TILEPRO:
11261 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
11262 case EM_VISIUM:
11263 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 11264 case EM_X86_64:
8a9036a4 11265 case EM_L1OM:
7a9068fe 11266 case EM_K1OM:
3e0873ac 11267 return reloc_type == 2; /* R_X86_64_PC32. */
2fcb9706
BW
11268 case EM_XTENSA_OLD:
11269 case EM_XTENSA:
11270 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
11271 default:
11272 /* Do not abort or issue an error message here. Not all targets use
11273 pc-relative 32-bit relocs in their DWARF debug information and we
11274 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
11275 more helpful warning message will be generated by apply_relocations
11276 anyway, so just return. */
aca88567
NC
11277 return FALSE;
11278 }
11279}
11280
11281/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11282 a 64-bit absolute RELA relocation used in DWARF debug sections. */
11283
11284static bfd_boolean
11285is_64bit_abs_reloc (unsigned int reloc_type)
11286{
11287 switch (elf_header.e_machine)
11288 {
a06ea964
NC
11289 case EM_AARCH64:
11290 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
11291 case EM_ALPHA:
11292 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a
NC
11293 case EM_IA_64:
11294 return reloc_type == 0x27; /* R_IA64_DIR64LSB. */
3e0873ac
NC
11295 case EM_PARISC:
11296 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
11297 case EM_PPC64:
11298 return reloc_type == 38; /* R_PPC64_ADDR64. */
11299 case EM_SPARC32PLUS:
11300 case EM_SPARCV9:
11301 case EM_SPARC:
11302 return reloc_type == 54; /* R_SPARC_UA64. */
11303 case EM_X86_64:
8a9036a4 11304 case EM_L1OM:
7a9068fe 11305 case EM_K1OM:
aca88567 11306 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
11307 case EM_S390_OLD:
11308 case EM_S390:
aa137e4d
NC
11309 return reloc_type == 22; /* R_S390_64. */
11310 case EM_TILEGX:
11311 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 11312 case EM_MIPS:
aa137e4d 11313 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
11314 default:
11315 return FALSE;
11316 }
11317}
11318
85acf597
RH
11319/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
11320 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
11321
11322static bfd_boolean
11323is_64bit_pcrel_reloc (unsigned int reloc_type)
11324{
11325 switch (elf_header.e_machine)
11326 {
a06ea964
NC
11327 case EM_AARCH64:
11328 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 11329 case EM_ALPHA:
aa137e4d 11330 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 11331 case EM_IA_64:
aa137e4d 11332 return reloc_type == 0x4f; /* R_IA64_PCREL64LSB. */
85acf597 11333 case EM_PARISC:
aa137e4d 11334 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 11335 case EM_PPC64:
aa137e4d 11336 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
11337 case EM_SPARC32PLUS:
11338 case EM_SPARCV9:
11339 case EM_SPARC:
aa137e4d 11340 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 11341 case EM_X86_64:
8a9036a4 11342 case EM_L1OM:
7a9068fe 11343 case EM_K1OM:
aa137e4d 11344 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
11345 case EM_S390_OLD:
11346 case EM_S390:
aa137e4d
NC
11347 return reloc_type == 23; /* R_S390_PC64. */
11348 case EM_TILEGX:
11349 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
11350 default:
11351 return FALSE;
11352 }
11353}
11354
4dc3c23d
AM
11355/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11356 a 24-bit absolute RELA relocation used in DWARF debug sections. */
11357
11358static bfd_boolean
11359is_24bit_abs_reloc (unsigned int reloc_type)
11360{
11361 switch (elf_header.e_machine)
11362 {
11363 case EM_CYGNUS_MN10200:
11364 case EM_MN10200:
11365 return reloc_type == 4; /* R_MN10200_24. */
11366 default:
11367 return FALSE;
11368 }
11369}
11370
aca88567
NC
11371/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
11372 a 16-bit absolute RELA relocation used in DWARF debug sections. */
11373
11374static bfd_boolean
11375is_16bit_abs_reloc (unsigned int reloc_type)
4b78141a
NC
11376{
11377 switch (elf_header.e_machine)
11378 {
aca88567
NC
11379 case EM_AVR_OLD:
11380 case EM_AVR:
11381 return reloc_type == 4; /* R_AVR_16. */
cfb8c092
NC
11382 case EM_ADAPTEVA_EPIPHANY:
11383 return reloc_type == 5;
41e92641
NC
11384 case EM_CYGNUS_D10V:
11385 case EM_D10V:
11386 return reloc_type == 3; /* R_D10V_16. */
4b78141a
NC
11387 case EM_H8S:
11388 case EM_H8_300:
11389 case EM_H8_300H:
aca88567
NC
11390 return reloc_type == R_H8_DIR16;
11391 case EM_IP2K_OLD:
11392 case EM_IP2K:
11393 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 11394 case EM_M32C_OLD:
f4236fe4
DD
11395 case EM_M32C:
11396 return reloc_type == 1; /* R_M32C_16 */
aca88567 11397 case EM_MSP430:
13761a11
NC
11398 if (uses_msp430x_relocs ())
11399 return reloc_type == 2; /* R_MSP430_ABS16. */
78c8d46c 11400 case EM_MSP430_OLD:
aca88567 11401 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
11402 case EM_NDS32:
11403 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 11404 case EM_ALTERA_NIOS2:
36591ba1 11405 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
11406 case EM_NIOS32:
11407 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
11408 case EM_OR1K:
11409 return reloc_type == 2; /* R_OR1K_16. */
40b36596
JM
11410 case EM_TI_C6000:
11411 return reloc_type == 2; /* R_C6000_ABS16. */
c29aca4a
NC
11412 case EM_XC16X:
11413 case EM_C166:
11414 return reloc_type == 2; /* R_XC16C_ABS_16. */
e63734a3
AM
11415 case EM_CYGNUS_MN10200:
11416 case EM_MN10200:
11417 return reloc_type == 2; /* R_MN10200_16. */
0a22ae8e
NC
11418 case EM_CYGNUS_MN10300:
11419 case EM_MN10300:
11420 return reloc_type == 2; /* R_MN10300_16. */
619ed720
EB
11421 case EM_VISIUM:
11422 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
11423 case EM_XGATE:
11424 return reloc_type == 3; /* R_XGATE_16. */
4b78141a 11425 default:
aca88567 11426 return FALSE;
4b78141a
NC
11427 }
11428}
11429
2a7b2e88
JK
11430/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
11431 relocation entries (possibly formerly used for SHT_GROUP sections). */
11432
11433static bfd_boolean
11434is_none_reloc (unsigned int reloc_type)
11435{
11436 switch (elf_header.e_machine)
11437 {
cb8f3167
NC
11438 case EM_68K: /* R_68K_NONE. */
11439 case EM_386: /* R_386_NONE. */
2a7b2e88
JK
11440 case EM_SPARC32PLUS:
11441 case EM_SPARCV9:
cb8f3167
NC
11442 case EM_SPARC: /* R_SPARC_NONE. */
11443 case EM_MIPS: /* R_MIPS_NONE. */
11444 case EM_PARISC: /* R_PARISC_NONE. */
11445 case EM_ALPHA: /* R_ALPHA_NONE. */
cfb8c092 11446 case EM_ADAPTEVA_EPIPHANY:
cb8f3167
NC
11447 case EM_PPC: /* R_PPC_NONE. */
11448 case EM_PPC64: /* R_PPC64_NONE. */
11449 case EM_ARM: /* R_ARM_NONE. */
11450 case EM_IA_64: /* R_IA64_NONE. */
11451 case EM_SH: /* R_SH_NONE. */
2a7b2e88 11452 case EM_S390_OLD:
cb8f3167
NC
11453 case EM_S390: /* R_390_NONE. */
11454 case EM_CRIS: /* R_CRIS_NONE. */
11455 case EM_X86_64: /* R_X86_64_NONE. */
8a9036a4 11456 case EM_L1OM: /* R_X86_64_NONE. */
7a9068fe 11457 case EM_K1OM: /* R_X86_64_NONE. */
cb8f3167 11458 case EM_MN10300: /* R_MN10300_NONE. */
3f8107ab 11459 case EM_FT32: /* R_FT32_NONE. */
5506d11a 11460 case EM_MOXIE: /* R_MOXIE_NONE. */
cb8f3167 11461 case EM_M32R: /* R_M32R_NONE. */
40b36596 11462 case EM_TI_C6000:/* R_C6000_NONE. */
aa137e4d
NC
11463 case EM_TILEGX: /* R_TILEGX_NONE. */
11464 case EM_TILEPRO: /* R_TILEPRO_NONE. */
c29aca4a
NC
11465 case EM_XC16X:
11466 case EM_C166: /* R_XC16X_NONE. */
36591ba1
SL
11467 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
11468 case EM_NIOS32: /* R_NIOS_NONE. */
73589c9d 11469 case EM_OR1K: /* R_OR1K_NONE. */
cb8f3167 11470 return reloc_type == 0;
a06ea964
NC
11471 case EM_AARCH64:
11472 return reloc_type == 0 || reloc_type == 256;
35c08157
KLC
11473 case EM_NDS32:
11474 return (reloc_type == 0 /* R_XTENSA_NONE. */
11475 || reloc_type == 204 /* R_NDS32_DIFF8. */
11476 || reloc_type == 205 /* R_NDS32_DIFF16. */
11477 || reloc_type == 206 /* R_NDS32_DIFF32. */
11478 || reloc_type == 207 /* R_NDS32_ULEB128. */);
58332dda
JK
11479 case EM_XTENSA_OLD:
11480 case EM_XTENSA:
4dc3c23d
AM
11481 return (reloc_type == 0 /* R_XTENSA_NONE. */
11482 || reloc_type == 17 /* R_XTENSA_DIFF8. */
11483 || reloc_type == 18 /* R_XTENSA_DIFF16. */
11484 || reloc_type == 19 /* R_XTENSA_DIFF32. */);
a3c62988
NC
11485 case EM_METAG:
11486 return reloc_type == 3; /* R_METAG_NONE. */
2a7b2e88
JK
11487 }
11488 return FALSE;
11489}
11490
cf13d699
NC
11491/* Apply relocations to a section.
11492 Note: So far support has been added only for those relocations
11493 which can be found in debug sections.
11494 FIXME: Add support for more relocations ? */
1b315056 11495
cf13d699
NC
11496static void
11497apply_relocations (void * file,
11498 Elf_Internal_Shdr * section,
11499 unsigned char * start)
1b315056 11500{
cf13d699
NC
11501 Elf_Internal_Shdr * relsec;
11502 unsigned char * end = start + section->sh_size;
cb8f3167 11503
cf13d699
NC
11504 if (elf_header.e_type != ET_REL)
11505 return;
1b315056 11506
cf13d699 11507 /* Find the reloc section associated with the section. */
5b18a4bc
NC
11508 for (relsec = section_headers;
11509 relsec < section_headers + elf_header.e_shnum;
11510 ++relsec)
252b5132 11511 {
41e92641
NC
11512 bfd_boolean is_rela;
11513 unsigned long num_relocs;
2cf0635d
NC
11514 Elf_Internal_Rela * relocs;
11515 Elf_Internal_Rela * rp;
11516 Elf_Internal_Shdr * symsec;
11517 Elf_Internal_Sym * symtab;
ba5cdace 11518 unsigned long num_syms;
2cf0635d 11519 Elf_Internal_Sym * sym;
252b5132 11520
41e92641 11521 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
4fbb74a6
AM
11522 || relsec->sh_info >= elf_header.e_shnum
11523 || section_headers + relsec->sh_info != section
c256ffe7 11524 || relsec->sh_size == 0
4fbb74a6 11525 || relsec->sh_link >= elf_header.e_shnum)
5b18a4bc 11526 continue;
428409d5 11527
41e92641
NC
11528 is_rela = relsec->sh_type == SHT_RELA;
11529
11530 if (is_rela)
11531 {
3f5e193b
NC
11532 if (!slurp_rela_relocs ((FILE *) file, relsec->sh_offset,
11533 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11534 return;
11535 }
11536 else
11537 {
3f5e193b
NC
11538 if (!slurp_rel_relocs ((FILE *) file, relsec->sh_offset,
11539 relsec->sh_size, & relocs, & num_relocs))
41e92641
NC
11540 return;
11541 }
11542
11543 /* SH uses RELA but uses in place value instead of the addend field. */
11544 if (elf_header.e_machine == EM_SH)
11545 is_rela = FALSE;
428409d5 11546
4fbb74a6 11547 symsec = section_headers + relsec->sh_link;
ba5cdace 11548 symtab = GET_ELF_SYMBOLS ((FILE *) file, symsec, & num_syms);
103f02d3 11549
41e92641 11550 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 11551 {
41e92641
NC
11552 bfd_vma addend;
11553 unsigned int reloc_type;
11554 unsigned int reloc_size;
91d6fa6a 11555 unsigned char * rloc;
ba5cdace 11556 unsigned long sym_index;
4b78141a 11557
aca88567 11558 reloc_type = get_reloc_type (rp->r_info);
41e92641 11559
98fb390a 11560 if (target_specific_reloc_handling (rp, start, symtab))
2a7b2e88 11561 continue;
98fb390a
NC
11562 else if (is_none_reloc (reloc_type))
11563 continue;
11564 else if (is_32bit_abs_reloc (reloc_type)
11565 || is_32bit_pcrel_reloc (reloc_type))
aca88567 11566 reloc_size = 4;
85acf597
RH
11567 else if (is_64bit_abs_reloc (reloc_type)
11568 || is_64bit_pcrel_reloc (reloc_type))
aca88567 11569 reloc_size = 8;
4dc3c23d
AM
11570 else if (is_24bit_abs_reloc (reloc_type))
11571 reloc_size = 3;
aca88567
NC
11572 else if (is_16bit_abs_reloc (reloc_type))
11573 reloc_size = 2;
11574 else
4b78141a 11575 {
bee0ee85
NC
11576 static unsigned int prev_reloc = 0;
11577 if (reloc_type != prev_reloc)
11578 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
11579 reloc_type, printable_section_name (section));
11580 prev_reloc = reloc_type;
4b78141a
NC
11581 continue;
11582 }
103f02d3 11583
91d6fa6a 11584 rloc = start + rp->r_offset;
c8da6823 11585 if ((rloc + reloc_size) > end || (rloc < start))
700dd8b7
L
11586 {
11587 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
11588 (unsigned long) rp->r_offset,
74e1a04b 11589 printable_section_name (section));
700dd8b7
L
11590 continue;
11591 }
103f02d3 11592
ba5cdace
NC
11593 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
11594 if (sym_index >= num_syms)
11595 {
11596 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
74e1a04b 11597 sym_index, printable_section_name (section));
ba5cdace
NC
11598 continue;
11599 }
11600 sym = symtab + sym_index;
41e92641
NC
11601
11602 /* If the reloc has a symbol associated with it,
55f25fc3
L
11603 make sure that it is of an appropriate type.
11604
11605 Relocations against symbols without type can happen.
11606 Gcc -feliminate-dwarf2-dups may generate symbols
11607 without type for debug info.
11608
11609 Icc generates relocations against function symbols
11610 instead of local labels.
11611
11612 Relocations against object symbols can happen, eg when
11613 referencing a global array. For an example of this see
11614 the _clz.o binary in libgcc.a. */
aca88567 11615 if (sym != symtab
55f25fc3 11616 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 11617 {
41e92641 11618 warn (_("skipping unexpected symbol type %s in %ld'th relocation in section %s\n"),
aca88567 11619 get_symbol_type (ELF_ST_TYPE (sym->st_info)),
99dcb0b9 11620 (long int)(rp - relocs),
74e1a04b 11621 printable_section_name (relsec));
aca88567 11622 continue;
5b18a4bc 11623 }
252b5132 11624
4dc3c23d
AM
11625 addend = 0;
11626 if (is_rela)
11627 addend += rp->r_addend;
c47320c3
AM
11628 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
11629 partial_inplace. */
4dc3c23d
AM
11630 if (!is_rela
11631 || (elf_header.e_machine == EM_XTENSA
11632 && reloc_type == 1)
11633 || ((elf_header.e_machine == EM_PJ
11634 || elf_header.e_machine == EM_PJ_OLD)
c47320c3
AM
11635 && reloc_type == 1)
11636 || ((elf_header.e_machine == EM_D30V
11637 || elf_header.e_machine == EM_CYGNUS_D30V)
11638 && reloc_type == 12))
91d6fa6a 11639 addend += byte_get (rloc, reloc_size);
cb8f3167 11640
85acf597
RH
11641 if (is_32bit_pcrel_reloc (reloc_type)
11642 || is_64bit_pcrel_reloc (reloc_type))
11643 {
11644 /* On HPPA, all pc-relative relocations are biased by 8. */
11645 if (elf_header.e_machine == EM_PARISC)
11646 addend -= 8;
91d6fa6a 11647 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
11648 reloc_size);
11649 }
41e92641 11650 else
91d6fa6a 11651 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 11652 }
252b5132 11653
5b18a4bc 11654 free (symtab);
41e92641 11655 free (relocs);
5b18a4bc
NC
11656 break;
11657 }
5b18a4bc 11658}
103f02d3 11659
cf13d699
NC
11660#ifdef SUPPORT_DISASSEMBLY
11661static int
11662disassemble_section (Elf_Internal_Shdr * section, FILE * file)
11663{
74e1a04b 11664 printf (_("\nAssembly dump of section %s\n"), printable_section_name (section));
cf13d699 11665
74e1a04b 11666 /* FIXME: XXX -- to be done --- XXX */
cf13d699
NC
11667
11668 return 1;
11669}
11670#endif
11671
11672/* Reads in the contents of SECTION from FILE, returning a pointer
11673 to a malloc'ed buffer or NULL if something went wrong. */
11674
11675static char *
11676get_section_contents (Elf_Internal_Shdr * section, FILE * file)
11677{
11678 bfd_size_type num_bytes;
11679
11680 num_bytes = section->sh_size;
11681
11682 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
11683 {
11684 printf (_("\nSection '%s' has no data to dump.\n"),
74e1a04b 11685 printable_section_name (section));
cf13d699
NC
11686 return NULL;
11687 }
11688
3f5e193b
NC
11689 return (char *) get_data (NULL, file, section->sh_offset, 1, num_bytes,
11690 _("section contents"));
cf13d699
NC
11691}
11692
dd24e3da 11693
cf13d699
NC
11694static void
11695dump_section_as_strings (Elf_Internal_Shdr * section, FILE * file)
11696{
11697 Elf_Internal_Shdr * relsec;
11698 bfd_size_type num_bytes;
cf13d699
NC
11699 char * data;
11700 char * end;
11701 char * start;
cf13d699
NC
11702 bfd_boolean some_strings_shown;
11703
11704 start = get_section_contents (section, file);
11705 if (start == NULL)
11706 return;
11707
74e1a04b 11708 printf (_("\nString dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11709
11710 /* If the section being dumped has relocations against it the user might
11711 be expecting these relocations to have been applied. Check for this
11712 case and issue a warning message in order to avoid confusion.
11713 FIXME: Maybe we ought to have an option that dumps a section with
11714 relocs applied ? */
11715 for (relsec = section_headers;
11716 relsec < section_headers + elf_header.e_shnum;
11717 ++relsec)
11718 {
11719 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11720 || relsec->sh_info >= elf_header.e_shnum
11721 || section_headers + relsec->sh_info != section
11722 || relsec->sh_size == 0
11723 || relsec->sh_link >= elf_header.e_shnum)
11724 continue;
11725
11726 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11727 break;
11728 }
11729
11730 num_bytes = section->sh_size;
cf13d699
NC
11731 data = start;
11732 end = start + num_bytes;
11733 some_strings_shown = FALSE;
11734
11735 while (data < end)
11736 {
11737 while (!ISPRINT (* data))
11738 if (++ data >= end)
11739 break;
11740
11741 if (data < end)
11742 {
071436c6
NC
11743 size_t maxlen = end - data;
11744
cf13d699 11745#ifndef __MSVCRT__
c975cc98
NC
11746 /* PR 11128: Use two separate invocations in order to work
11747 around bugs in the Solaris 8 implementation of printf. */
11748 printf (" [%6tx] ", data - start);
cf13d699 11749#else
071436c6 11750 printf (" [%6Ix] ", (size_t) (data - start));
cf13d699 11751#endif
4082ef84
NC
11752 if (maxlen > 0)
11753 {
11754 print_symbol ((int) maxlen, data);
11755 putchar ('\n');
11756 data += strnlen (data, maxlen);
11757 }
11758 else
11759 {
11760 printf (_("<corrupt>\n"));
11761 data = end;
11762 }
cf13d699
NC
11763 some_strings_shown = TRUE;
11764 }
11765 }
11766
11767 if (! some_strings_shown)
11768 printf (_(" No strings found in this section."));
11769
11770 free (start);
11771
11772 putchar ('\n');
11773}
11774
11775static void
11776dump_section_as_bytes (Elf_Internal_Shdr * section,
11777 FILE * file,
11778 bfd_boolean relocate)
11779{
11780 Elf_Internal_Shdr * relsec;
11781 bfd_size_type bytes;
11782 bfd_vma addr;
11783 unsigned char * data;
11784 unsigned char * start;
11785
11786 start = (unsigned char *) get_section_contents (section, file);
11787 if (start == NULL)
11788 return;
11789
74e1a04b 11790 printf (_("\nHex dump of section '%s':\n"), printable_section_name (section));
cf13d699
NC
11791
11792 if (relocate)
11793 {
11794 apply_relocations (file, section, start);
11795 }
11796 else
11797 {
11798 /* If the section being dumped has relocations against it the user might
11799 be expecting these relocations to have been applied. Check for this
11800 case and issue a warning message in order to avoid confusion.
11801 FIXME: Maybe we ought to have an option that dumps a section with
11802 relocs applied ? */
11803 for (relsec = section_headers;
11804 relsec < section_headers + elf_header.e_shnum;
11805 ++relsec)
11806 {
11807 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
11808 || relsec->sh_info >= elf_header.e_shnum
11809 || section_headers + relsec->sh_info != section
11810 || relsec->sh_size == 0
11811 || relsec->sh_link >= elf_header.e_shnum)
11812 continue;
11813
11814 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
11815 break;
11816 }
11817 }
11818
11819 addr = section->sh_addr;
11820 bytes = section->sh_size;
11821 data = start;
11822
11823 while (bytes)
11824 {
11825 int j;
11826 int k;
11827 int lbytes;
11828
11829 lbytes = (bytes > 16 ? 16 : bytes);
11830
11831 printf (" 0x%8.8lx ", (unsigned long) addr);
11832
11833 for (j = 0; j < 16; j++)
11834 {
11835 if (j < lbytes)
11836 printf ("%2.2x", data[j]);
11837 else
11838 printf (" ");
11839
11840 if ((j & 3) == 3)
11841 printf (" ");
11842 }
11843
11844 for (j = 0; j < lbytes; j++)
11845 {
11846 k = data[j];
11847 if (k >= ' ' && k < 0x7f)
11848 printf ("%c", k);
11849 else
11850 printf (".");
11851 }
11852
11853 putchar ('\n');
11854
11855 data += lbytes;
11856 addr += lbytes;
11857 bytes -= lbytes;
11858 }
11859
11860 free (start);
11861
11862 putchar ('\n');
11863}
11864
4a114e3e 11865/* Uncompresses a section that was compressed using zlib, in place. */
cf13d699
NC
11866
11867static int
d3dbc530
AM
11868uncompress_section_contents (unsigned char **buffer ATTRIBUTE_UNUSED,
11869 dwarf_size_type *size ATTRIBUTE_UNUSED)
cf13d699
NC
11870{
11871#ifndef HAVE_ZLIB_H
cf13d699
NC
11872 return FALSE;
11873#else
11874 dwarf_size_type compressed_size = *size;
11875 unsigned char * compressed_buffer = *buffer;
11876 dwarf_size_type uncompressed_size;
11877 unsigned char * uncompressed_buffer;
11878 z_stream strm;
11879 int rc;
11880 dwarf_size_type header_size = 12;
11881
11882 /* Read the zlib header. In this case, it should be "ZLIB" followed
11883 by the uncompressed section size, 8 bytes in big-endian order. */
11884 if (compressed_size < header_size
11885 || ! streq ((char *) compressed_buffer, "ZLIB"))
11886 return 0;
11887
11888 uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
11889 uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
11890 uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
11891 uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
11892 uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
11893 uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
11894 uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
11895 uncompressed_size += compressed_buffer[11];
11896
11897 /* It is possible the section consists of several compressed
11898 buffers concatenated together, so we uncompress in a loop. */
11899 strm.zalloc = NULL;
11900 strm.zfree = NULL;
11901 strm.opaque = NULL;
11902 strm.avail_in = compressed_size - header_size;
11903 strm.next_in = (Bytef *) compressed_buffer + header_size;
11904 strm.avail_out = uncompressed_size;
3f5e193b 11905 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
cf13d699
NC
11906
11907 rc = inflateInit (& strm);
11908 while (strm.avail_in > 0)
11909 {
11910 if (rc != Z_OK)
11911 goto fail;
11912 strm.next_out = ((Bytef *) uncompressed_buffer
11913 + (uncompressed_size - strm.avail_out));
11914 rc = inflate (&strm, Z_FINISH);
11915 if (rc != Z_STREAM_END)
11916 goto fail;
11917 rc = inflateReset (& strm);
11918 }
11919 rc = inflateEnd (& strm);
11920 if (rc != Z_OK
11921 || strm.avail_out != 0)
11922 goto fail;
11923
11924 free (compressed_buffer);
11925 *buffer = uncompressed_buffer;
11926 *size = uncompressed_size;
11927 return 1;
11928
11929 fail:
11930 free (uncompressed_buffer);
4a114e3e
L
11931 /* Indicate decompression failure. */
11932 *buffer = NULL;
cf13d699
NC
11933 return 0;
11934#endif /* HAVE_ZLIB_H */
11935}
11936
d966045b
DJ
11937static int
11938load_specific_debug_section (enum dwarf_section_display_enum debug,
2cf0635d 11939 Elf_Internal_Shdr * sec, void * file)
1007acb3 11940{
2cf0635d 11941 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 11942 char buf [64];
1007acb3 11943
19e6b90e
L
11944 /* If it is already loaded, do nothing. */
11945 if (section->start != NULL)
11946 return 1;
1007acb3 11947
19e6b90e
L
11948 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
11949 section->address = sec->sh_addr;
06614111 11950 section->user_data = NULL;
3f5e193b
NC
11951 section->start = (unsigned char *) get_data (NULL, (FILE *) file,
11952 sec->sh_offset, 1,
11953 sec->sh_size, buf);
59245841
NC
11954 if (section->start == NULL)
11955 section->size = 0;
11956 else
11957 {
11958 section->size = sec->sh_size;
11959 if (uncompress_section_contents (&section->start, &section->size))
11960 sec->sh_size = section->size;
11961 }
4a114e3e 11962
1b315056
CS
11963 if (section->start == NULL)
11964 return 0;
11965
19e6b90e 11966 if (debug_displays [debug].relocate)
3f5e193b 11967 apply_relocations ((FILE *) file, sec, section->start);
1007acb3 11968
1b315056 11969 return 1;
1007acb3
L
11970}
11971
657d0d47
CC
11972/* If this is not NULL, load_debug_section will only look for sections
11973 within the list of sections given here. */
11974unsigned int *section_subset = NULL;
11975
d966045b 11976int
2cf0635d 11977load_debug_section (enum dwarf_section_display_enum debug, void * file)
d966045b 11978{
2cf0635d
NC
11979 struct dwarf_section * section = &debug_displays [debug].section;
11980 Elf_Internal_Shdr * sec;
d966045b
DJ
11981
11982 /* Locate the debug section. */
657d0d47 11983 sec = find_section_in_set (section->uncompressed_name, section_subset);
d966045b
DJ
11984 if (sec != NULL)
11985 section->name = section->uncompressed_name;
11986 else
11987 {
657d0d47 11988 sec = find_section_in_set (section->compressed_name, section_subset);
d966045b
DJ
11989 if (sec != NULL)
11990 section->name = section->compressed_name;
11991 }
11992 if (sec == NULL)
11993 return 0;
11994
657d0d47
CC
11995 /* If we're loading from a subset of sections, and we've loaded
11996 a section matching this name before, it's likely that it's a
11997 different one. */
11998 if (section_subset != NULL)
11999 free_debug_section (debug);
12000
3f5e193b 12001 return load_specific_debug_section (debug, sec, (FILE *) file);
d966045b
DJ
12002}
12003
19e6b90e
L
12004void
12005free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 12006{
2cf0635d 12007 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 12008
19e6b90e
L
12009 if (section->start == NULL)
12010 return;
1007acb3 12011
19e6b90e
L
12012 free ((char *) section->start);
12013 section->start = NULL;
12014 section->address = 0;
12015 section->size = 0;
1007acb3
L
12016}
12017
1007acb3 12018static int
657d0d47 12019display_debug_section (int shndx, Elf_Internal_Shdr * section, FILE * file)
1007acb3 12020{
2cf0635d 12021 char * name = SECTION_NAME (section);
74e1a04b 12022 const char * print_name = printable_section_name (section);
19e6b90e
L
12023 bfd_size_type length;
12024 int result = 1;
3f5e193b 12025 int i;
1007acb3 12026
19e6b90e
L
12027 length = section->sh_size;
12028 if (length == 0)
1007acb3 12029 {
74e1a04b 12030 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
19e6b90e 12031 return 0;
1007acb3 12032 }
5dff79d8
NC
12033 if (section->sh_type == SHT_NOBITS)
12034 {
12035 /* There is no point in dumping the contents of a debugging section
12036 which has the NOBITS type - the bits in the file will be random.
12037 This can happen when a file containing a .eh_frame section is
12038 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
12039 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
12040 print_name);
5dff79d8
NC
12041 return 0;
12042 }
1007acb3 12043
0112cd26 12044 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 12045 name = ".debug_info";
1007acb3 12046
19e6b90e
L
12047 /* See if we know how to display the contents of this section. */
12048 for (i = 0; i < max; i++)
1b315056 12049 if (streq (debug_displays[i].section.uncompressed_name, name)
b40bf0a2 12050 || (i == line && const_strneq (name, ".debug_line."))
1b315056 12051 || streq (debug_displays[i].section.compressed_name, name))
19e6b90e 12052 {
2cf0635d 12053 struct dwarf_section * sec = &debug_displays [i].section;
d966045b
DJ
12054 int secondary = (section != find_section (name));
12055
12056 if (secondary)
3f5e193b 12057 free_debug_section ((enum dwarf_section_display_enum) i);
1007acb3 12058
b40bf0a2
NC
12059 if (i == line && const_strneq (name, ".debug_line."))
12060 sec->name = name;
12061 else if (streq (sec->uncompressed_name, name))
d966045b
DJ
12062 sec->name = sec->uncompressed_name;
12063 else
12064 sec->name = sec->compressed_name;
3f5e193b
NC
12065 if (load_specific_debug_section ((enum dwarf_section_display_enum) i,
12066 section, file))
19e6b90e 12067 {
657d0d47
CC
12068 /* If this debug section is part of a CU/TU set in a .dwp file,
12069 restrict load_debug_section to the sections in that set. */
12070 section_subset = find_cu_tu_set (file, shndx);
12071
19e6b90e 12072 result &= debug_displays[i].display (sec, file);
1007acb3 12073
657d0d47
CC
12074 section_subset = NULL;
12075
d966045b 12076 if (secondary || (i != info && i != abbrev))
3f5e193b 12077 free_debug_section ((enum dwarf_section_display_enum) i);
19e6b90e 12078 }
1007acb3 12079
19e6b90e
L
12080 break;
12081 }
1007acb3 12082
19e6b90e 12083 if (i == max)
1007acb3 12084 {
74e1a04b 12085 printf (_("Unrecognized debug section: %s\n"), print_name);
19e6b90e 12086 result = 0;
1007acb3
L
12087 }
12088
19e6b90e 12089 return result;
5b18a4bc 12090}
103f02d3 12091
aef1f6d0
DJ
12092/* Set DUMP_SECTS for all sections where dumps were requested
12093 based on section name. */
12094
12095static void
12096initialise_dumps_byname (void)
12097{
2cf0635d 12098 struct dump_list_entry * cur;
aef1f6d0
DJ
12099
12100 for (cur = dump_sects_byname; cur; cur = cur->next)
12101 {
12102 unsigned int i;
12103 int any;
12104
12105 for (i = 0, any = 0; i < elf_header.e_shnum; i++)
12106 if (streq (SECTION_NAME (section_headers + i), cur->name))
12107 {
09c11c86 12108 request_dump_bynumber (i, cur->type);
aef1f6d0
DJ
12109 any = 1;
12110 }
12111
12112 if (!any)
12113 warn (_("Section '%s' was not dumped because it does not exist!\n"),
12114 cur->name);
12115 }
12116}
12117
5b18a4bc 12118static void
2cf0635d 12119process_section_contents (FILE * file)
5b18a4bc 12120{
2cf0635d 12121 Elf_Internal_Shdr * section;
19e6b90e 12122 unsigned int i;
103f02d3 12123
19e6b90e
L
12124 if (! do_dump)
12125 return;
103f02d3 12126
aef1f6d0
DJ
12127 initialise_dumps_byname ();
12128
19e6b90e
L
12129 for (i = 0, section = section_headers;
12130 i < elf_header.e_shnum && i < num_dump_sects;
12131 i++, section++)
12132 {
12133#ifdef SUPPORT_DISASSEMBLY
12134 if (dump_sects[i] & DISASS_DUMP)
12135 disassemble_section (section, file);
12136#endif
12137 if (dump_sects[i] & HEX_DUMP)
cf13d699 12138 dump_section_as_bytes (section, file, FALSE);
103f02d3 12139
cf13d699
NC
12140 if (dump_sects[i] & RELOC_DUMP)
12141 dump_section_as_bytes (section, file, TRUE);
09c11c86
NC
12142
12143 if (dump_sects[i] & STRING_DUMP)
12144 dump_section_as_strings (section, file);
cf13d699
NC
12145
12146 if (dump_sects[i] & DEBUG_DUMP)
657d0d47 12147 display_debug_section (i, section, file);
5b18a4bc 12148 }
103f02d3 12149
19e6b90e
L
12150 /* Check to see if the user requested a
12151 dump of a section that does not exist. */
12152 while (i++ < num_dump_sects)
12153 if (dump_sects[i])
12154 warn (_("Section %d was not dumped because it does not exist!\n"), i);
5b18a4bc 12155}
103f02d3 12156
5b18a4bc 12157static void
19e6b90e 12158process_mips_fpe_exception (int mask)
5b18a4bc 12159{
19e6b90e
L
12160 if (mask)
12161 {
12162 int first = 1;
12163 if (mask & OEX_FPU_INEX)
12164 fputs ("INEX", stdout), first = 0;
12165 if (mask & OEX_FPU_UFLO)
12166 printf ("%sUFLO", first ? "" : "|"), first = 0;
12167 if (mask & OEX_FPU_OFLO)
12168 printf ("%sOFLO", first ? "" : "|"), first = 0;
12169 if (mask & OEX_FPU_DIV0)
12170 printf ("%sDIV0", first ? "" : "|"), first = 0;
12171 if (mask & OEX_FPU_INVAL)
12172 printf ("%sINVAL", first ? "" : "|");
12173 }
5b18a4bc 12174 else
19e6b90e 12175 fputs ("0", stdout);
5b18a4bc 12176}
103f02d3 12177
f6f0e17b
NC
12178/* Display's the value of TAG at location P. If TAG is
12179 greater than 0 it is assumed to be an unknown tag, and
12180 a message is printed to this effect. Otherwise it is
12181 assumed that a message has already been printed.
12182
12183 If the bottom bit of TAG is set it assumed to have a
12184 string value, otherwise it is assumed to have an integer
12185 value.
12186
12187 Returns an updated P pointing to the first unread byte
12188 beyond the end of TAG's value.
12189
12190 Reads at or beyond END will not be made. */
12191
12192static unsigned char *
12193display_tag_value (int tag,
12194 unsigned char * p,
12195 const unsigned char * const end)
12196{
12197 unsigned long val;
12198
12199 if (tag > 0)
12200 printf (" Tag_unknown_%d: ", tag);
12201
12202 if (p >= end)
12203 {
4082ef84 12204 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
12205 }
12206 else if (tag & 1)
12207 {
071436c6
NC
12208 /* PR 17531 file: 027-19978-0.004. */
12209 size_t maxlen = (end - p) - 1;
12210
12211 putchar ('"');
4082ef84
NC
12212 if (maxlen > 0)
12213 {
12214 print_symbol ((int) maxlen, (const char *) p);
12215 p += strnlen ((char *) p, maxlen) + 1;
12216 }
12217 else
12218 {
12219 printf (_("<corrupt string tag>"));
12220 p = (unsigned char *) end;
12221 }
071436c6 12222 printf ("\"\n");
f6f0e17b
NC
12223 }
12224 else
12225 {
12226 unsigned int len;
12227
12228 val = read_uleb128 (p, &len, end);
12229 p += len;
12230 printf ("%ld (0x%lx)\n", val, val);
12231 }
12232
4082ef84 12233 assert (p <= end);
f6f0e17b
NC
12234 return p;
12235}
12236
11c1ff18
PB
12237/* ARM EABI attributes section. */
12238typedef struct
12239{
70e99720 12240 unsigned int tag;
2cf0635d 12241 const char * name;
11c1ff18 12242 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 12243 unsigned int type;
2cf0635d 12244 const char ** table;
11c1ff18
PB
12245} arm_attr_public_tag;
12246
2cf0635d 12247static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 12248 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
bca38921 12249 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8"};
2cf0635d
NC
12250static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
12251static const char * arm_attr_tag_THUMB_ISA_use[] =
11c1ff18 12252 {"No", "Thumb-1", "Thumb-2"};
75375b3e 12253static const char * arm_attr_tag_FP_arch[] =
bca38921 12254 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 12255 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 12256static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 12257static const char * arm_attr_tag_Advanced_SIMD_arch[] =
bca38921 12258 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8"};
2cf0635d 12259static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
12260 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
12261 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 12262static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 12263 {"V6", "SB", "TLS", "Unused"};
2cf0635d 12264static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 12265 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 12266static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 12267 {"Absolute", "PC-relative", "None"};
2cf0635d 12268static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 12269 {"None", "direct", "GOT-indirect"};
2cf0635d 12270static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 12271 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
12272static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
12273static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 12274 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
12275static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
12276static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
12277static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 12278 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 12279static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 12280 {"Unused", "small", "int", "forced to int"};
2cf0635d 12281static const char * arm_attr_tag_ABI_HardFP_use[] =
75375b3e 12282 {"As Tag_FP_arch", "SP only", "DP only", "SP and DP"};
2cf0635d 12283static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 12284 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 12285static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 12286 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 12287static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
12288 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12289 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 12290static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
12291 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
12292 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 12293static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 12294static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 12295 {"Not Allowed", "Allowed"};
2cf0635d 12296static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 12297 {"None", "IEEE 754", "Alternative Format"};
dd24e3da 12298static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
12299 {"Not Allowed", "Allowed"};
12300static const char * arm_attr_tag_DIV_use[] =
dd24e3da 12301 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 12302 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
12303static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
12304static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 12305 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 12306 "TrustZone and Virtualization Extensions"};
dd24e3da 12307static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 12308 {"Not Allowed", "Allowed"};
11c1ff18
PB
12309
12310#define LOOKUP(id, name) \
12311 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 12312static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
12313{
12314 {4, "CPU_raw_name", 1, NULL},
12315 {5, "CPU_name", 1, NULL},
12316 LOOKUP(6, CPU_arch),
12317 {7, "CPU_arch_profile", 0, NULL},
12318 LOOKUP(8, ARM_ISA_use),
12319 LOOKUP(9, THUMB_ISA_use),
75375b3e 12320 LOOKUP(10, FP_arch),
11c1ff18 12321 LOOKUP(11, WMMX_arch),
f5f53991
AS
12322 LOOKUP(12, Advanced_SIMD_arch),
12323 LOOKUP(13, PCS_config),
11c1ff18
PB
12324 LOOKUP(14, ABI_PCS_R9_use),
12325 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 12326 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
12327 LOOKUP(17, ABI_PCS_GOT_use),
12328 LOOKUP(18, ABI_PCS_wchar_t),
12329 LOOKUP(19, ABI_FP_rounding),
12330 LOOKUP(20, ABI_FP_denormal),
12331 LOOKUP(21, ABI_FP_exceptions),
12332 LOOKUP(22, ABI_FP_user_exceptions),
12333 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
12334 {24, "ABI_align_needed", 0, NULL},
12335 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
12336 LOOKUP(26, ABI_enum_size),
12337 LOOKUP(27, ABI_HardFP_use),
12338 LOOKUP(28, ABI_VFP_args),
12339 LOOKUP(29, ABI_WMMX_args),
12340 LOOKUP(30, ABI_optimization_goals),
12341 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 12342 {32, "compatibility", 0, NULL},
f5f53991 12343 LOOKUP(34, CPU_unaligned_access),
75375b3e 12344 LOOKUP(36, FP_HP_extension),
8e79c3df 12345 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
12346 LOOKUP(42, MPextension_use),
12347 LOOKUP(44, DIV_use),
f5f53991
AS
12348 {64, "nodefaults", 0, NULL},
12349 {65, "also_compatible_with", 0, NULL},
12350 LOOKUP(66, T2EE_use),
12351 {67, "conformance", 1, NULL},
12352 LOOKUP(68, Virtualization_use),
cd21e546 12353 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
12354};
12355#undef LOOKUP
12356
11c1ff18 12357static unsigned char *
f6f0e17b
NC
12358display_arm_attribute (unsigned char * p,
12359 const unsigned char * const end)
11c1ff18 12360{
70e99720 12361 unsigned int tag;
11c1ff18 12362 unsigned int len;
70e99720 12363 unsigned int val;
2cf0635d 12364 arm_attr_public_tag * attr;
11c1ff18 12365 unsigned i;
70e99720 12366 unsigned int type;
11c1ff18 12367
f6f0e17b 12368 tag = read_uleb128 (p, &len, end);
11c1ff18
PB
12369 p += len;
12370 attr = NULL;
2cf0635d 12371 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
12372 {
12373 if (arm_attr_public_tags[i].tag == tag)
12374 {
12375 attr = &arm_attr_public_tags[i];
12376 break;
12377 }
12378 }
12379
12380 if (attr)
12381 {
12382 printf (" Tag_%s: ", attr->name);
12383 switch (attr->type)
12384 {
12385 case 0:
12386 switch (tag)
12387 {
12388 case 7: /* Tag_CPU_arch_profile. */
f6f0e17b 12389 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12390 p += len;
12391 switch (val)
12392 {
2b692964
NC
12393 case 0: printf (_("None\n")); break;
12394 case 'A': printf (_("Application\n")); break;
12395 case 'R': printf (_("Realtime\n")); break;
12396 case 'M': printf (_("Microcontroller\n")); break;
12397 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
12398 default: printf ("??? (%d)\n", val); break;
12399 }
12400 break;
12401
75375b3e 12402 case 24: /* Tag_align_needed. */
f6f0e17b 12403 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12404 p += len;
12405 switch (val)
12406 {
2b692964
NC
12407 case 0: printf (_("None\n")); break;
12408 case 1: printf (_("8-byte\n")); break;
12409 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
12410 case 3: printf ("??? 3\n"); break;
12411 default:
12412 if (val <= 12)
dd24e3da 12413 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12414 1 << val);
12415 else
12416 printf ("??? (%d)\n", val);
12417 break;
12418 }
12419 break;
12420
12421 case 25: /* Tag_align_preserved. */
f6f0e17b 12422 val = read_uleb128 (p, &len, end);
75375b3e
MGD
12423 p += len;
12424 switch (val)
12425 {
2b692964
NC
12426 case 0: printf (_("None\n")); break;
12427 case 1: printf (_("8-byte, except leaf SP\n")); break;
12428 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
12429 case 3: printf ("??? 3\n"); break;
12430 default:
12431 if (val <= 12)
dd24e3da 12432 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
12433 1 << val);
12434 else
12435 printf ("??? (%d)\n", val);
12436 break;
12437 }
12438 break;
12439
11c1ff18 12440 case 32: /* Tag_compatibility. */
071436c6 12441 {
071436c6
NC
12442 val = read_uleb128 (p, &len, end);
12443 p += len;
071436c6 12444 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
12445 if (p < end - 1)
12446 {
12447 size_t maxlen = (end - p) - 1;
12448
12449 print_symbol ((int) maxlen, (const char *) p);
12450 p += strnlen ((char *) p, maxlen) + 1;
12451 }
12452 else
12453 {
12454 printf (_("<corrupt>"));
12455 p = (unsigned char *) end;
12456 }
071436c6 12457 putchar ('\n');
071436c6 12458 }
11c1ff18
PB
12459 break;
12460
f5f53991 12461 case 64: /* Tag_nodefaults. */
541a3cbd
NC
12462 /* PR 17531: file: 001-505008-0.01. */
12463 if (p < end)
12464 p++;
2b692964 12465 printf (_("True\n"));
f5f53991
AS
12466 break;
12467
12468 case 65: /* Tag_also_compatible_with. */
f6f0e17b 12469 val = read_uleb128 (p, &len, end);
f5f53991
AS
12470 p += len;
12471 if (val == 6 /* Tag_CPU_arch. */)
12472 {
f6f0e17b 12473 val = read_uleb128 (p, &len, end);
f5f53991 12474 p += len;
071436c6 12475 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
12476 printf ("??? (%d)\n", val);
12477 else
12478 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
12479 }
12480 else
12481 printf ("???\n");
071436c6
NC
12482 while (p < end && *(p++) != '\0' /* NUL terminator. */)
12483 ;
f5f53991
AS
12484 break;
12485
11c1ff18 12486 default:
bee0ee85
NC
12487 printf (_("<unknown: %d>\n"), tag);
12488 break;
11c1ff18
PB
12489 }
12490 return p;
12491
12492 case 1:
f6f0e17b 12493 return display_tag_value (-1, p, end);
11c1ff18 12494 case 2:
f6f0e17b 12495 return display_tag_value (0, p, end);
11c1ff18
PB
12496
12497 default:
12498 assert (attr->type & 0x80);
f6f0e17b 12499 val = read_uleb128 (p, &len, end);
11c1ff18
PB
12500 p += len;
12501 type = attr->type & 0x7f;
12502 if (val >= type)
12503 printf ("??? (%d)\n", val);
12504 else
12505 printf ("%s\n", attr->table[val]);
12506 return p;
12507 }
12508 }
11c1ff18 12509
f6f0e17b 12510 return display_tag_value (tag, p, end);
11c1ff18
PB
12511}
12512
104d59d1 12513static unsigned char *
60bca95a 12514display_gnu_attribute (unsigned char * p,
f6f0e17b
NC
12515 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const),
12516 const unsigned char * const end)
104d59d1
JM
12517{
12518 int tag;
12519 unsigned int len;
12520 int val;
104d59d1 12521
f6f0e17b 12522 tag = read_uleb128 (p, &len, end);
104d59d1
JM
12523 p += len;
12524
12525 /* Tag_compatibility is the only generic GNU attribute defined at
12526 present. */
12527 if (tag == 32)
12528 {
f6f0e17b 12529 val = read_uleb128 (p, &len, end);
104d59d1 12530 p += len;
071436c6
NC
12531
12532 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
12533 if (p == end)
12534 {
071436c6 12535 printf (_("<corrupt>\n"));
f6f0e17b
NC
12536 warn (_("corrupt vendor attribute\n"));
12537 }
12538 else
12539 {
4082ef84
NC
12540 if (p < end - 1)
12541 {
12542 size_t maxlen = (end - p) - 1;
071436c6 12543
4082ef84
NC
12544 print_symbol ((int) maxlen, (const char *) p);
12545 p += strnlen ((char *) p, maxlen) + 1;
12546 }
12547 else
12548 {
12549 printf (_("<corrupt>"));
12550 p = (unsigned char *) end;
12551 }
071436c6 12552 putchar ('\n');
f6f0e17b 12553 }
104d59d1
JM
12554 return p;
12555 }
12556
12557 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 12558 return display_proc_gnu_attribute (p, tag, end);
104d59d1 12559
f6f0e17b 12560 return display_tag_value (tag, p, end);
104d59d1
JM
12561}
12562
34c8bcba 12563static unsigned char *
f6f0e17b
NC
12564display_power_gnu_attribute (unsigned char * p,
12565 int tag,
12566 const unsigned char * const end)
34c8bcba 12567{
34c8bcba
JM
12568 unsigned int len;
12569 int val;
12570
12571 if (tag == Tag_GNU_Power_ABI_FP)
12572 {
f6f0e17b 12573 val = read_uleb128 (p, &len, end);
34c8bcba
JM
12574 p += len;
12575 printf (" Tag_GNU_Power_ABI_FP: ");
60bca95a 12576
34c8bcba
JM
12577 switch (val)
12578 {
12579 case 0:
2b692964 12580 printf (_("Hard or soft float\n"));
34c8bcba
JM
12581 break;
12582 case 1:
2b692964 12583 printf (_("Hard float\n"));
34c8bcba
JM
12584 break;
12585 case 2:
2b692964 12586 printf (_("Soft float\n"));
34c8bcba 12587 break;
3c7b9897 12588 case 3:
2b692964 12589 printf (_("Single-precision hard float\n"));
3c7b9897 12590 break;
34c8bcba
JM
12591 default:
12592 printf ("??? (%d)\n", val);
12593 break;
12594 }
12595 return p;
12596 }
12597
c6e65352
DJ
12598 if (tag == Tag_GNU_Power_ABI_Vector)
12599 {
f6f0e17b 12600 val = read_uleb128 (p, &len, end);
c6e65352
DJ
12601 p += len;
12602 printf (" Tag_GNU_Power_ABI_Vector: ");
12603 switch (val)
12604 {
12605 case 0:
2b692964 12606 printf (_("Any\n"));
c6e65352
DJ
12607 break;
12608 case 1:
2b692964 12609 printf (_("Generic\n"));
c6e65352
DJ
12610 break;
12611 case 2:
12612 printf ("AltiVec\n");
12613 break;
12614 case 3:
12615 printf ("SPE\n");
12616 break;
12617 default:
12618 printf ("??? (%d)\n", val);
12619 break;
12620 }
12621 return p;
12622 }
12623
f82e0623
NF
12624 if (tag == Tag_GNU_Power_ABI_Struct_Return)
12625 {
f6f0e17b
NC
12626 if (p == end)
12627 {
071436c6 12628 warn (_("corrupt Tag_GNU_Power_ABI_Struct_Return\n"));
f6f0e17b
NC
12629 return p;
12630 }
0b4362b0 12631
f6f0e17b 12632 val = read_uleb128 (p, &len, end);
f82e0623
NF
12633 p += len;
12634 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
12635 switch (val)
12636 {
12637 case 0:
2b692964 12638 printf (_("Any\n"));
f82e0623
NF
12639 break;
12640 case 1:
12641 printf ("r3/r4\n");
12642 break;
12643 case 2:
2b692964 12644 printf (_("Memory\n"));
f82e0623
NF
12645 break;
12646 default:
12647 printf ("??? (%d)\n", val);
12648 break;
12649 }
12650 return p;
12651 }
12652
f6f0e17b 12653 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
12654}
12655
9e8c70f9
DM
12656static void
12657display_sparc_hwcaps (int mask)
12658{
12659 if (mask)
12660 {
12661 int first = 1;
071436c6 12662
9e8c70f9
DM
12663 if (mask & ELF_SPARC_HWCAP_MUL32)
12664 fputs ("mul32", stdout), first = 0;
12665 if (mask & ELF_SPARC_HWCAP_DIV32)
12666 printf ("%sdiv32", first ? "" : "|"), first = 0;
12667 if (mask & ELF_SPARC_HWCAP_FSMULD)
12668 printf ("%sfsmuld", first ? "" : "|"), first = 0;
12669 if (mask & ELF_SPARC_HWCAP_V8PLUS)
12670 printf ("%sv8plus", first ? "" : "|"), first = 0;
12671 if (mask & ELF_SPARC_HWCAP_POPC)
12672 printf ("%spopc", first ? "" : "|"), first = 0;
12673 if (mask & ELF_SPARC_HWCAP_VIS)
12674 printf ("%svis", first ? "" : "|"), first = 0;
12675 if (mask & ELF_SPARC_HWCAP_VIS2)
12676 printf ("%svis2", first ? "" : "|"), first = 0;
12677 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
12678 printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
12679 if (mask & ELF_SPARC_HWCAP_FMAF)
12680 printf ("%sfmaf", first ? "" : "|"), first = 0;
12681 if (mask & ELF_SPARC_HWCAP_VIS3)
12682 printf ("%svis3", first ? "" : "|"), first = 0;
12683 if (mask & ELF_SPARC_HWCAP_HPC)
12684 printf ("%shpc", first ? "" : "|"), first = 0;
12685 if (mask & ELF_SPARC_HWCAP_RANDOM)
12686 printf ("%srandom", first ? "" : "|"), first = 0;
12687 if (mask & ELF_SPARC_HWCAP_TRANS)
12688 printf ("%strans", first ? "" : "|"), first = 0;
12689 if (mask & ELF_SPARC_HWCAP_FJFMAU)
12690 printf ("%sfjfmau", first ? "" : "|"), first = 0;
12691 if (mask & ELF_SPARC_HWCAP_IMA)
12692 printf ("%sima", first ? "" : "|"), first = 0;
12693 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
12694 printf ("%scspare", first ? "" : "|"), first = 0;
12695 }
12696 else
071436c6
NC
12697 fputc ('0', stdout);
12698 fputc ('\n', stdout);
9e8c70f9
DM
12699}
12700
3d68f91c
JM
12701static void
12702display_sparc_hwcaps2 (int mask)
12703{
12704 if (mask)
12705 {
12706 int first = 1;
071436c6 12707
3d68f91c
JM
12708 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
12709 fputs ("fjathplus", stdout), first = 0;
12710 if (mask & ELF_SPARC_HWCAP2_VIS3B)
12711 printf ("%svis3b", first ? "" : "|"), first = 0;
12712 if (mask & ELF_SPARC_HWCAP2_ADP)
12713 printf ("%sadp", first ? "" : "|"), first = 0;
12714 if (mask & ELF_SPARC_HWCAP2_SPARC5)
12715 printf ("%ssparc5", first ? "" : "|"), first = 0;
12716 if (mask & ELF_SPARC_HWCAP2_MWAIT)
12717 printf ("%smwait", first ? "" : "|"), first = 0;
12718 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
12719 printf ("%sxmpmul", first ? "" : "|"), first = 0;
12720 if (mask & ELF_SPARC_HWCAP2_XMONT)
12721 printf ("%sxmont2", first ? "" : "|"), first = 0;
12722 if (mask & ELF_SPARC_HWCAP2_NSEC)
12723 printf ("%snsec", first ? "" : "|"), first = 0;
12724 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
12725 printf ("%sfjathhpc", first ? "" : "|"), first = 0;
12726 if (mask & ELF_SPARC_HWCAP2_FJDES)
12727 printf ("%sfjdes", first ? "" : "|"), first = 0;
12728 if (mask & ELF_SPARC_HWCAP2_FJAES)
12729 printf ("%sfjaes", first ? "" : "|"), first = 0;
12730 }
12731 else
071436c6
NC
12732 fputc ('0', stdout);
12733 fputc ('\n', stdout);
3d68f91c
JM
12734}
12735
9e8c70f9 12736static unsigned char *
f6f0e17b
NC
12737display_sparc_gnu_attribute (unsigned char * p,
12738 int tag,
12739 const unsigned char * const end)
9e8c70f9 12740{
3d68f91c
JM
12741 unsigned int len;
12742 int val;
12743
9e8c70f9
DM
12744 if (tag == Tag_GNU_Sparc_HWCAPS)
12745 {
f6f0e17b 12746 val = read_uleb128 (p, &len, end);
9e8c70f9
DM
12747 p += len;
12748 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
12749 display_sparc_hwcaps (val);
12750 return p;
3d68f91c
JM
12751 }
12752 if (tag == Tag_GNU_Sparc_HWCAPS2)
12753 {
12754 val = read_uleb128 (p, &len, end);
12755 p += len;
12756 printf (" Tag_GNU_Sparc_HWCAPS2: ");
12757 display_sparc_hwcaps2 (val);
12758 return p;
12759 }
9e8c70f9 12760
f6f0e17b 12761 return display_tag_value (tag, p, end);
9e8c70f9
DM
12762}
12763
351cdf24
MF
12764static void
12765print_mips_fp_abi_value (int val)
12766{
12767 switch (val)
12768 {
12769 case Val_GNU_MIPS_ABI_FP_ANY:
12770 printf (_("Hard or soft float\n"));
12771 break;
12772 case Val_GNU_MIPS_ABI_FP_DOUBLE:
12773 printf (_("Hard float (double precision)\n"));
12774 break;
12775 case Val_GNU_MIPS_ABI_FP_SINGLE:
12776 printf (_("Hard float (single precision)\n"));
12777 break;
12778 case Val_GNU_MIPS_ABI_FP_SOFT:
12779 printf (_("Soft float\n"));
12780 break;
12781 case Val_GNU_MIPS_ABI_FP_OLD_64:
12782 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
12783 break;
12784 case Val_GNU_MIPS_ABI_FP_XX:
12785 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
12786 break;
12787 case Val_GNU_MIPS_ABI_FP_64:
12788 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
12789 break;
12790 case Val_GNU_MIPS_ABI_FP_64A:
12791 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
12792 break;
12793 default:
12794 printf ("??? (%d)\n", val);
12795 break;
12796 }
12797}
12798
2cf19d5c 12799static unsigned char *
f6f0e17b
NC
12800display_mips_gnu_attribute (unsigned char * p,
12801 int tag,
12802 const unsigned char * const end)
2cf19d5c 12803{
2cf19d5c
JM
12804 if (tag == Tag_GNU_MIPS_ABI_FP)
12805 {
f6f0e17b
NC
12806 unsigned int len;
12807 int val;
12808
12809 val = read_uleb128 (p, &len, end);
2cf19d5c
JM
12810 p += len;
12811 printf (" Tag_GNU_MIPS_ABI_FP: ");
60bca95a 12812
351cdf24
MF
12813 print_mips_fp_abi_value (val);
12814
2cf19d5c
JM
12815 return p;
12816 }
12817
a9f58168
CF
12818 if (tag == Tag_GNU_MIPS_ABI_MSA)
12819 {
12820 unsigned int len;
12821 int val;
12822
12823 val = read_uleb128 (p, &len, end);
12824 p += len;
12825 printf (" Tag_GNU_MIPS_ABI_MSA: ");
12826
12827 switch (val)
12828 {
12829 case Val_GNU_MIPS_ABI_MSA_ANY:
12830 printf (_("Any MSA or not\n"));
12831 break;
12832 case Val_GNU_MIPS_ABI_MSA_128:
12833 printf (_("128-bit MSA\n"));
12834 break;
12835 default:
12836 printf ("??? (%d)\n", val);
12837 break;
12838 }
12839 return p;
12840 }
12841
f6f0e17b 12842 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
12843}
12844
59e6276b 12845static unsigned char *
f6f0e17b
NC
12846display_tic6x_attribute (unsigned char * p,
12847 const unsigned char * const end)
59e6276b
JM
12848{
12849 int tag;
12850 unsigned int len;
12851 int val;
12852
f6f0e17b 12853 tag = read_uleb128 (p, &len, end);
59e6276b
JM
12854 p += len;
12855
12856 switch (tag)
12857 {
75fa6dc1 12858 case Tag_ISA:
f6f0e17b 12859 val = read_uleb128 (p, &len, end);
59e6276b 12860 p += len;
75fa6dc1 12861 printf (" Tag_ISA: ");
59e6276b
JM
12862
12863 switch (val)
12864 {
75fa6dc1 12865 case C6XABI_Tag_ISA_none:
59e6276b
JM
12866 printf (_("None\n"));
12867 break;
75fa6dc1 12868 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
12869 printf ("C62x\n");
12870 break;
75fa6dc1 12871 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
12872 printf ("C67x\n");
12873 break;
75fa6dc1 12874 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
12875 printf ("C67x+\n");
12876 break;
75fa6dc1 12877 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
12878 printf ("C64x\n");
12879 break;
75fa6dc1 12880 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
12881 printf ("C64x+\n");
12882 break;
75fa6dc1 12883 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
12884 printf ("C674x\n");
12885 break;
12886 default:
12887 printf ("??? (%d)\n", val);
12888 break;
12889 }
12890 return p;
12891
87779176 12892 case Tag_ABI_wchar_t:
f6f0e17b 12893 val = read_uleb128 (p, &len, end);
87779176
JM
12894 p += len;
12895 printf (" Tag_ABI_wchar_t: ");
12896 switch (val)
12897 {
12898 case 0:
12899 printf (_("Not used\n"));
12900 break;
12901 case 1:
12902 printf (_("2 bytes\n"));
12903 break;
12904 case 2:
12905 printf (_("4 bytes\n"));
12906 break;
12907 default:
12908 printf ("??? (%d)\n", val);
12909 break;
12910 }
12911 return p;
12912
12913 case Tag_ABI_stack_align_needed:
f6f0e17b 12914 val = read_uleb128 (p, &len, end);
87779176
JM
12915 p += len;
12916 printf (" Tag_ABI_stack_align_needed: ");
12917 switch (val)
12918 {
12919 case 0:
12920 printf (_("8-byte\n"));
12921 break;
12922 case 1:
12923 printf (_("16-byte\n"));
12924 break;
12925 default:
12926 printf ("??? (%d)\n", val);
12927 break;
12928 }
12929 return p;
12930
12931 case Tag_ABI_stack_align_preserved:
f6f0e17b 12932 val = read_uleb128 (p, &len, end);
87779176
JM
12933 p += len;
12934 printf (" Tag_ABI_stack_align_preserved: ");
12935 switch (val)
12936 {
12937 case 0:
12938 printf (_("8-byte\n"));
12939 break;
12940 case 1:
12941 printf (_("16-byte\n"));
12942 break;
12943 default:
12944 printf ("??? (%d)\n", val);
12945 break;
12946 }
12947 return p;
12948
b5593623 12949 case Tag_ABI_DSBT:
f6f0e17b 12950 val = read_uleb128 (p, &len, end);
b5593623
JM
12951 p += len;
12952 printf (" Tag_ABI_DSBT: ");
12953 switch (val)
12954 {
12955 case 0:
12956 printf (_("DSBT addressing not used\n"));
12957 break;
12958 case 1:
12959 printf (_("DSBT addressing used\n"));
12960 break;
12961 default:
12962 printf ("??? (%d)\n", val);
12963 break;
12964 }
12965 return p;
12966
87779176 12967 case Tag_ABI_PID:
f6f0e17b 12968 val = read_uleb128 (p, &len, end);
87779176
JM
12969 p += len;
12970 printf (" Tag_ABI_PID: ");
12971 switch (val)
12972 {
12973 case 0:
12974 printf (_("Data addressing position-dependent\n"));
12975 break;
12976 case 1:
12977 printf (_("Data addressing position-independent, GOT near DP\n"));
12978 break;
12979 case 2:
12980 printf (_("Data addressing position-independent, GOT far from DP\n"));
12981 break;
12982 default:
12983 printf ("??? (%d)\n", val);
12984 break;
12985 }
12986 return p;
12987
12988 case Tag_ABI_PIC:
f6f0e17b 12989 val = read_uleb128 (p, &len, end);
87779176
JM
12990 p += len;
12991 printf (" Tag_ABI_PIC: ");
12992 switch (val)
12993 {
12994 case 0:
12995 printf (_("Code addressing position-dependent\n"));
12996 break;
12997 case 1:
12998 printf (_("Code addressing position-independent\n"));
12999 break;
13000 default:
13001 printf ("??? (%d)\n", val);
13002 break;
13003 }
13004 return p;
13005
13006 case Tag_ABI_array_object_alignment:
f6f0e17b 13007 val = read_uleb128 (p, &len, end);
87779176
JM
13008 p += len;
13009 printf (" Tag_ABI_array_object_alignment: ");
13010 switch (val)
13011 {
13012 case 0:
13013 printf (_("8-byte\n"));
13014 break;
13015 case 1:
13016 printf (_("4-byte\n"));
13017 break;
13018 case 2:
13019 printf (_("16-byte\n"));
13020 break;
13021 default:
13022 printf ("??? (%d)\n", val);
13023 break;
13024 }
13025 return p;
13026
13027 case Tag_ABI_array_object_align_expected:
f6f0e17b 13028 val = read_uleb128 (p, &len, end);
87779176
JM
13029 p += len;
13030 printf (" Tag_ABI_array_object_align_expected: ");
13031 switch (val)
13032 {
13033 case 0:
13034 printf (_("8-byte\n"));
13035 break;
13036 case 1:
13037 printf (_("4-byte\n"));
13038 break;
13039 case 2:
13040 printf (_("16-byte\n"));
13041 break;
13042 default:
13043 printf ("??? (%d)\n", val);
13044 break;
13045 }
13046 return p;
13047
3cbd1c06 13048 case Tag_ABI_compatibility:
071436c6 13049 {
071436c6
NC
13050 val = read_uleb128 (p, &len, end);
13051 p += len;
13052 printf (" Tag_ABI_compatibility: ");
071436c6 13053 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
13054 if (p < end - 1)
13055 {
13056 size_t maxlen = (end - p) - 1;
13057
13058 print_symbol ((int) maxlen, (const char *) p);
13059 p += strnlen ((char *) p, maxlen) + 1;
13060 }
13061 else
13062 {
13063 printf (_("<corrupt>"));
13064 p = (unsigned char *) end;
13065 }
071436c6 13066 putchar ('\n');
071436c6
NC
13067 return p;
13068 }
87779176
JM
13069
13070 case Tag_ABI_conformance:
071436c6 13071 {
4082ef84
NC
13072 printf (" Tag_ABI_conformance: \"");
13073 if (p < end - 1)
13074 {
13075 size_t maxlen = (end - p) - 1;
071436c6 13076
4082ef84
NC
13077 print_symbol ((int) maxlen, (const char *) p);
13078 p += strnlen ((char *) p, maxlen) + 1;
13079 }
13080 else
13081 {
13082 printf (_("<corrupt>"));
13083 p = (unsigned char *) end;
13084 }
071436c6 13085 printf ("\"\n");
071436c6
NC
13086 return p;
13087 }
59e6276b
JM
13088 }
13089
f6f0e17b
NC
13090 return display_tag_value (tag, p, end);
13091}
59e6276b 13092
f6f0e17b
NC
13093static void
13094display_raw_attribute (unsigned char * p, unsigned char * end)
13095{
13096 unsigned long addr = 0;
13097 size_t bytes = end - p;
13098
e0a31db1 13099 assert (end > p);
f6f0e17b 13100 while (bytes)
87779176 13101 {
f6f0e17b
NC
13102 int j;
13103 int k;
13104 int lbytes = (bytes > 16 ? 16 : bytes);
13105
13106 printf (" 0x%8.8lx ", addr);
13107
13108 for (j = 0; j < 16; j++)
13109 {
13110 if (j < lbytes)
13111 printf ("%2.2x", p[j]);
13112 else
13113 printf (" ");
13114
13115 if ((j & 3) == 3)
13116 printf (" ");
13117 }
13118
13119 for (j = 0; j < lbytes; j++)
13120 {
13121 k = p[j];
13122 if (k >= ' ' && k < 0x7f)
13123 printf ("%c", k);
13124 else
13125 printf (".");
13126 }
13127
13128 putchar ('\n');
13129
13130 p += lbytes;
13131 bytes -= lbytes;
13132 addr += lbytes;
87779176 13133 }
59e6276b 13134
f6f0e17b 13135 putchar ('\n');
59e6276b
JM
13136}
13137
13761a11
NC
13138static unsigned char *
13139display_msp430x_attribute (unsigned char * p,
13140 const unsigned char * const end)
13141{
13142 unsigned int len;
13143 int val;
13144 int tag;
13145
13146 tag = read_uleb128 (p, & len, end);
13147 p += len;
0b4362b0 13148
13761a11
NC
13149 switch (tag)
13150 {
13151 case OFBA_MSPABI_Tag_ISA:
13152 val = read_uleb128 (p, &len, end);
13153 p += len;
13154 printf (" Tag_ISA: ");
13155 switch (val)
13156 {
13157 case 0: printf (_("None\n")); break;
13158 case 1: printf (_("MSP430\n")); break;
13159 case 2: printf (_("MSP430X\n")); break;
13160 default: printf ("??? (%d)\n", val); break;
13161 }
13162 break;
13163
13164 case OFBA_MSPABI_Tag_Code_Model:
13165 val = read_uleb128 (p, &len, end);
13166 p += len;
13167 printf (" Tag_Code_Model: ");
13168 switch (val)
13169 {
13170 case 0: printf (_("None\n")); break;
13171 case 1: printf (_("Small\n")); break;
13172 case 2: printf (_("Large\n")); break;
13173 default: printf ("??? (%d)\n", val); break;
13174 }
13175 break;
13176
13177 case OFBA_MSPABI_Tag_Data_Model:
13178 val = read_uleb128 (p, &len, end);
13179 p += len;
13180 printf (" Tag_Data_Model: ");
13181 switch (val)
13182 {
13183 case 0: printf (_("None\n")); break;
13184 case 1: printf (_("Small\n")); break;
13185 case 2: printf (_("Large\n")); break;
13186 case 3: printf (_("Restricted Large\n")); break;
13187 default: printf ("??? (%d)\n", val); break;
13188 }
13189 break;
13190
13191 default:
13192 printf (_(" <unknown tag %d>: "), tag);
13193
13194 if (tag & 1)
13195 {
071436c6 13196 putchar ('"');
4082ef84
NC
13197 if (p < end - 1)
13198 {
13199 size_t maxlen = (end - p) - 1;
13200
13201 print_symbol ((int) maxlen, (const char *) p);
13202 p += strnlen ((char *) p, maxlen) + 1;
13203 }
13204 else
13205 {
13206 printf (_("<corrupt>"));
13207 p = (unsigned char *) end;
13208 }
071436c6 13209 printf ("\"\n");
13761a11
NC
13210 }
13211 else
13212 {
13213 val = read_uleb128 (p, &len, end);
13214 p += len;
13215 printf ("%d (0x%x)\n", val, val);
13216 }
13217 break;
13218 }
13219
4082ef84 13220 assert (p <= end);
13761a11
NC
13221 return p;
13222}
13223
11c1ff18 13224static int
60bca95a
NC
13225process_attributes (FILE * file,
13226 const char * public_name,
104d59d1 13227 unsigned int proc_type,
f6f0e17b
NC
13228 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
13229 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, int, const unsigned char * const))
11c1ff18 13230{
2cf0635d 13231 Elf_Internal_Shdr * sect;
11c1ff18
PB
13232 unsigned i;
13233
13234 /* Find the section header so that we get the size. */
13235 for (i = 0, sect = section_headers;
13236 i < elf_header.e_shnum;
13237 i++, sect++)
13238 {
071436c6
NC
13239 unsigned char * contents;
13240 unsigned char * p;
13241
104d59d1 13242 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
13243 continue;
13244
3f5e193b
NC
13245 contents = (unsigned char *) get_data (NULL, file, sect->sh_offset, 1,
13246 sect->sh_size, _("attributes"));
60bca95a 13247 if (contents == NULL)
11c1ff18 13248 continue;
60bca95a 13249
11c1ff18
PB
13250 p = contents;
13251 if (*p == 'A')
13252 {
071436c6
NC
13253 bfd_vma section_len;
13254
13255 section_len = sect->sh_size - 1;
11c1ff18 13256 p++;
60bca95a 13257
071436c6 13258 while (section_len > 0)
11c1ff18 13259 {
071436c6 13260 bfd_vma attr_len;
e9847026 13261 unsigned int namelen;
11c1ff18 13262 bfd_boolean public_section;
104d59d1 13263 bfd_boolean gnu_section;
11c1ff18 13264
071436c6 13265 if (section_len <= 4)
e0a31db1
NC
13266 {
13267 error (_("Tag section ends prematurely\n"));
13268 break;
13269 }
071436c6 13270 attr_len = byte_get (p, 4);
11c1ff18 13271 p += 4;
60bca95a 13272
071436c6 13273 if (attr_len > section_len)
11c1ff18 13274 {
071436c6
NC
13275 error (_("Bad attribute length (%u > %u)\n"),
13276 (unsigned) attr_len, (unsigned) section_len);
13277 attr_len = section_len;
11c1ff18 13278 }
74e1a04b 13279 /* PR 17531: file: 001-101425-0.004 */
071436c6 13280 else if (attr_len < 5)
74e1a04b 13281 {
071436c6 13282 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
74e1a04b
NC
13283 break;
13284 }
e9847026 13285
071436c6
NC
13286 section_len -= attr_len;
13287 attr_len -= 4;
13288
13289 namelen = strnlen ((char *) p, attr_len) + 1;
13290 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
13291 {
13292 error (_("Corrupt attribute section name\n"));
13293 break;
13294 }
13295
071436c6
NC
13296 printf (_("Attribute Section: "));
13297 print_symbol (INT_MAX, (const char *) p);
13298 putchar ('\n');
60bca95a
NC
13299
13300 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
13301 public_section = TRUE;
13302 else
13303 public_section = FALSE;
60bca95a
NC
13304
13305 if (streq ((char *) p, "gnu"))
104d59d1
JM
13306 gnu_section = TRUE;
13307 else
13308 gnu_section = FALSE;
60bca95a 13309
11c1ff18 13310 p += namelen;
071436c6 13311 attr_len -= namelen;
e0a31db1 13312
071436c6 13313 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 13314 {
e0a31db1 13315 int tag;
11c1ff18
PB
13316 int val;
13317 bfd_vma size;
071436c6 13318 unsigned char * end;
60bca95a 13319
e0a31db1 13320 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 13321 if (attr_len < 6)
e0a31db1
NC
13322 {
13323 error (_("Unused bytes at end of section\n"));
13324 section_len = 0;
13325 break;
13326 }
13327
13328 tag = *(p++);
11c1ff18 13329 size = byte_get (p, 4);
071436c6 13330 if (size > attr_len)
11c1ff18 13331 {
e9847026 13332 error (_("Bad subsection length (%u > %u)\n"),
071436c6
NC
13333 (unsigned) size, (unsigned) attr_len);
13334 size = attr_len;
11c1ff18 13335 }
e0a31db1
NC
13336 /* PR binutils/17531: Safe handling of corrupt files. */
13337 if (size < 6)
13338 {
13339 error (_("Bad subsection length (%u < 6)\n"),
13340 (unsigned) size);
13341 section_len = 0;
13342 break;
13343 }
60bca95a 13344
071436c6 13345 attr_len -= size;
11c1ff18 13346 end = p + size - 1;
071436c6 13347 assert (end <= contents + sect->sh_size);
11c1ff18 13348 p += 4;
60bca95a 13349
11c1ff18
PB
13350 switch (tag)
13351 {
13352 case 1:
2b692964 13353 printf (_("File Attributes\n"));
11c1ff18
PB
13354 break;
13355 case 2:
2b692964 13356 printf (_("Section Attributes:"));
11c1ff18
PB
13357 goto do_numlist;
13358 case 3:
2b692964 13359 printf (_("Symbol Attributes:"));
11c1ff18
PB
13360 do_numlist:
13361 for (;;)
13362 {
91d6fa6a 13363 unsigned int j;
60bca95a 13364
f6f0e17b 13365 val = read_uleb128 (p, &j, end);
91d6fa6a 13366 p += j;
11c1ff18
PB
13367 if (val == 0)
13368 break;
13369 printf (" %d", val);
13370 }
13371 printf ("\n");
13372 break;
13373 default:
2b692964 13374 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
13375 public_section = FALSE;
13376 break;
13377 }
60bca95a 13378
071436c6 13379 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
13380 {
13381 while (p < end)
f6f0e17b 13382 p = display_pub_attribute (p, end);
071436c6 13383 assert (p <= end);
104d59d1 13384 }
071436c6 13385 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
13386 {
13387 while (p < end)
13388 p = display_gnu_attribute (p,
f6f0e17b
NC
13389 display_proc_gnu_attribute,
13390 end);
071436c6 13391 assert (p <= end);
11c1ff18 13392 }
071436c6 13393 else if (p < end)
11c1ff18 13394 {
071436c6 13395 printf (_(" Unknown attribute:\n"));
f6f0e17b 13396 display_raw_attribute (p, end);
11c1ff18
PB
13397 p = end;
13398 }
071436c6
NC
13399 else
13400 attr_len = 0;
11c1ff18
PB
13401 }
13402 }
13403 }
13404 else
e9847026 13405 printf (_("Unknown format '%c' (%d)\n"), *p, *p);
d70c5fc7 13406
60bca95a 13407 free (contents);
11c1ff18
PB
13408 }
13409 return 1;
13410}
13411
104d59d1 13412static int
2cf0635d 13413process_arm_specific (FILE * file)
104d59d1
JM
13414{
13415 return process_attributes (file, "aeabi", SHT_ARM_ATTRIBUTES,
13416 display_arm_attribute, NULL);
13417}
13418
34c8bcba 13419static int
2cf0635d 13420process_power_specific (FILE * file)
34c8bcba
JM
13421{
13422 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13423 display_power_gnu_attribute);
13424}
13425
9e8c70f9
DM
13426static int
13427process_sparc_specific (FILE * file)
13428{
13429 return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13430 display_sparc_gnu_attribute);
13431}
13432
59e6276b
JM
13433static int
13434process_tic6x_specific (FILE * file)
13435{
13436 return process_attributes (file, "c6xabi", SHT_C6000_ATTRIBUTES,
13437 display_tic6x_attribute, NULL);
13438}
13439
13761a11
NC
13440static int
13441process_msp430x_specific (FILE * file)
13442{
13443 return process_attributes (file, "mspabi", SHT_MSP430_ATTRIBUTES,
13444 display_msp430x_attribute, NULL);
13445}
13446
ccb4c951
RS
13447/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
13448 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
13449 and return the VMA of the next entry, or -1 if there was a problem.
13450 Does not read from DATA_END or beyond. */
ccb4c951
RS
13451
13452static bfd_vma
82b1b41b
NC
13453print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
13454 unsigned char * data_end)
ccb4c951
RS
13455{
13456 printf (" ");
13457 print_vma (addr, LONG_HEX);
13458 printf (" ");
13459 if (addr < pltgot + 0xfff0)
13460 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
13461 else
13462 printf ("%10s", "");
13463 printf (" ");
13464 if (data == NULL)
2b692964 13465 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
13466 else
13467 {
13468 bfd_vma entry;
82b1b41b 13469 unsigned char * from = data + addr - pltgot;
ccb4c951 13470
82b1b41b
NC
13471 if (from + (is_32bit_elf ? 4 : 8) > data_end)
13472 {
13473 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
13474 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
13475 return (bfd_vma) -1;
13476 }
13477 else
13478 {
13479 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13480 print_vma (entry, LONG_HEX);
13481 }
ccb4c951
RS
13482 }
13483 return addr + (is_32bit_elf ? 4 : 8);
13484}
13485
861fb55a
DJ
13486/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
13487 PLTGOT. Print the Address and Initial fields of an entry at VMA
13488 ADDR and return the VMA of the next entry. */
13489
13490static bfd_vma
2cf0635d 13491print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
13492{
13493 printf (" ");
13494 print_vma (addr, LONG_HEX);
13495 printf (" ");
13496 if (data == NULL)
2b692964 13497 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
13498 else
13499 {
13500 bfd_vma entry;
13501
13502 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
13503 print_vma (entry, LONG_HEX);
13504 }
13505 return addr + (is_32bit_elf ? 4 : 8);
13506}
13507
351cdf24
MF
13508static void
13509print_mips_ases (unsigned int mask)
13510{
13511 if (mask & AFL_ASE_DSP)
13512 fputs ("\n\tDSP ASE", stdout);
13513 if (mask & AFL_ASE_DSPR2)
13514 fputs ("\n\tDSP R2 ASE", stdout);
13515 if (mask & AFL_ASE_EVA)
13516 fputs ("\n\tEnhanced VA Scheme", stdout);
13517 if (mask & AFL_ASE_MCU)
13518 fputs ("\n\tMCU (MicroController) ASE", stdout);
13519 if (mask & AFL_ASE_MDMX)
13520 fputs ("\n\tMDMX ASE", stdout);
13521 if (mask & AFL_ASE_MIPS3D)
13522 fputs ("\n\tMIPS-3D ASE", stdout);
13523 if (mask & AFL_ASE_MT)
13524 fputs ("\n\tMT ASE", stdout);
13525 if (mask & AFL_ASE_SMARTMIPS)
13526 fputs ("\n\tSmartMIPS ASE", stdout);
13527 if (mask & AFL_ASE_VIRT)
13528 fputs ("\n\tVZ ASE", stdout);
13529 if (mask & AFL_ASE_MSA)
13530 fputs ("\n\tMSA ASE", stdout);
13531 if (mask & AFL_ASE_MIPS16)
13532 fputs ("\n\tMIPS16 ASE", stdout);
13533 if (mask & AFL_ASE_MICROMIPS)
13534 fputs ("\n\tMICROMIPS ASE", stdout);
13535 if (mask & AFL_ASE_XPA)
13536 fputs ("\n\tXPA ASE", stdout);
13537 if (mask == 0)
13538 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
13539 else if ((mask & ~AFL_ASE_MASK) != 0)
13540 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
13541}
13542
13543static void
13544print_mips_isa_ext (unsigned int isa_ext)
13545{
13546 switch (isa_ext)
13547 {
13548 case 0:
13549 fputs (_("None"), stdout);
13550 break;
13551 case AFL_EXT_XLR:
13552 fputs ("RMI XLR", stdout);
13553 break;
2c629856
N
13554 case AFL_EXT_OCTEON3:
13555 fputs ("Cavium Networks Octeon3", stdout);
13556 break;
351cdf24
MF
13557 case AFL_EXT_OCTEON2:
13558 fputs ("Cavium Networks Octeon2", stdout);
13559 break;
13560 case AFL_EXT_OCTEONP:
13561 fputs ("Cavium Networks OcteonP", stdout);
13562 break;
13563 case AFL_EXT_LOONGSON_3A:
13564 fputs ("Loongson 3A", stdout);
13565 break;
13566 case AFL_EXT_OCTEON:
13567 fputs ("Cavium Networks Octeon", stdout);
13568 break;
13569 case AFL_EXT_5900:
13570 fputs ("Toshiba R5900", stdout);
13571 break;
13572 case AFL_EXT_4650:
13573 fputs ("MIPS R4650", stdout);
13574 break;
13575 case AFL_EXT_4010:
13576 fputs ("LSI R4010", stdout);
13577 break;
13578 case AFL_EXT_4100:
13579 fputs ("NEC VR4100", stdout);
13580 break;
13581 case AFL_EXT_3900:
13582 fputs ("Toshiba R3900", stdout);
13583 break;
13584 case AFL_EXT_10000:
13585 fputs ("MIPS R10000", stdout);
13586 break;
13587 case AFL_EXT_SB1:
13588 fputs ("Broadcom SB-1", stdout);
13589 break;
13590 case AFL_EXT_4111:
13591 fputs ("NEC VR4111/VR4181", stdout);
13592 break;
13593 case AFL_EXT_4120:
13594 fputs ("NEC VR4120", stdout);
13595 break;
13596 case AFL_EXT_5400:
13597 fputs ("NEC VR5400", stdout);
13598 break;
13599 case AFL_EXT_5500:
13600 fputs ("NEC VR5500", stdout);
13601 break;
13602 case AFL_EXT_LOONGSON_2E:
13603 fputs ("ST Microelectronics Loongson 2E", stdout);
13604 break;
13605 case AFL_EXT_LOONGSON_2F:
13606 fputs ("ST Microelectronics Loongson 2F", stdout);
13607 break;
13608 default:
00ac7aa0 13609 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
13610 }
13611}
13612
13613static int
13614get_mips_reg_size (int reg_size)
13615{
13616 return (reg_size == AFL_REG_NONE) ? 0
13617 : (reg_size == AFL_REG_32) ? 32
13618 : (reg_size == AFL_REG_64) ? 64
13619 : (reg_size == AFL_REG_128) ? 128
13620 : -1;
13621}
13622
19e6b90e 13623static int
2cf0635d 13624process_mips_specific (FILE * file)
5b18a4bc 13625{
2cf0635d 13626 Elf_Internal_Dyn * entry;
351cdf24 13627 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
13628 size_t liblist_offset = 0;
13629 size_t liblistno = 0;
13630 size_t conflictsno = 0;
13631 size_t options_offset = 0;
13632 size_t conflicts_offset = 0;
861fb55a
DJ
13633 size_t pltrelsz = 0;
13634 size_t pltrel = 0;
ccb4c951 13635 bfd_vma pltgot = 0;
861fb55a
DJ
13636 bfd_vma mips_pltgot = 0;
13637 bfd_vma jmprel = 0;
ccb4c951
RS
13638 bfd_vma local_gotno = 0;
13639 bfd_vma gotsym = 0;
13640 bfd_vma symtabno = 0;
103f02d3 13641
2cf19d5c
JM
13642 process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
13643 display_mips_gnu_attribute);
13644
351cdf24
MF
13645 sect = find_section (".MIPS.abiflags");
13646
13647 if (sect != NULL)
13648 {
13649 Elf_External_ABIFlags_v0 *abiflags_ext;
13650 Elf_Internal_ABIFlags_v0 abiflags_in;
13651
13652 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
13653 fputs ("\nCorrupt ABI Flags section.\n", stdout);
13654 else
13655 {
13656 abiflags_ext = get_data (NULL, file, sect->sh_offset, 1,
13657 sect->sh_size, _("MIPS ABI Flags section"));
13658 if (abiflags_ext)
13659 {
13660 abiflags_in.version = BYTE_GET (abiflags_ext->version);
13661 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
13662 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
13663 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
13664 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
13665 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
13666 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
13667 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
13668 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
13669 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
13670 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
13671
13672 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
13673 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
13674 if (abiflags_in.isa_rev > 1)
13675 printf ("r%d", abiflags_in.isa_rev);
13676 printf ("\nGPR size: %d",
13677 get_mips_reg_size (abiflags_in.gpr_size));
13678 printf ("\nCPR1 size: %d",
13679 get_mips_reg_size (abiflags_in.cpr1_size));
13680 printf ("\nCPR2 size: %d",
13681 get_mips_reg_size (abiflags_in.cpr2_size));
13682 fputs ("\nFP ABI: ", stdout);
13683 print_mips_fp_abi_value (abiflags_in.fp_abi);
13684 fputs ("ISA Extension: ", stdout);
13685 print_mips_isa_ext (abiflags_in.isa_ext);
13686 fputs ("\nASEs:", stdout);
13687 print_mips_ases (abiflags_in.ases);
13688 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
13689 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
13690 fputc ('\n', stdout);
13691 free (abiflags_ext);
13692 }
13693 }
13694 }
13695
19e6b90e
L
13696 /* We have a lot of special sections. Thanks SGI! */
13697 if (dynamic_section == NULL)
13698 /* No information available. */
13699 return 0;
252b5132 13700
071436c6
NC
13701 for (entry = dynamic_section;
13702 /* PR 17531 file: 012-50589-0.004. */
13703 entry < dynamic_section + dynamic_nent && entry->d_tag != DT_NULL;
13704 ++entry)
252b5132
RH
13705 switch (entry->d_tag)
13706 {
13707 case DT_MIPS_LIBLIST:
d93f0186
NC
13708 liblist_offset
13709 = offset_from_vma (file, entry->d_un.d_val,
13710 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
13711 break;
13712 case DT_MIPS_LIBLISTNO:
13713 liblistno = entry->d_un.d_val;
13714 break;
13715 case DT_MIPS_OPTIONS:
d93f0186 13716 options_offset = offset_from_vma (file, entry->d_un.d_val, 0);
252b5132
RH
13717 break;
13718 case DT_MIPS_CONFLICT:
d93f0186
NC
13719 conflicts_offset
13720 = offset_from_vma (file, entry->d_un.d_val,
13721 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
13722 break;
13723 case DT_MIPS_CONFLICTNO:
13724 conflictsno = entry->d_un.d_val;
13725 break;
ccb4c951 13726 case DT_PLTGOT:
861fb55a
DJ
13727 pltgot = entry->d_un.d_ptr;
13728 break;
ccb4c951
RS
13729 case DT_MIPS_LOCAL_GOTNO:
13730 local_gotno = entry->d_un.d_val;
13731 break;
13732 case DT_MIPS_GOTSYM:
13733 gotsym = entry->d_un.d_val;
13734 break;
13735 case DT_MIPS_SYMTABNO:
13736 symtabno = entry->d_un.d_val;
13737 break;
861fb55a
DJ
13738 case DT_MIPS_PLTGOT:
13739 mips_pltgot = entry->d_un.d_ptr;
13740 break;
13741 case DT_PLTREL:
13742 pltrel = entry->d_un.d_val;
13743 break;
13744 case DT_PLTRELSZ:
13745 pltrelsz = entry->d_un.d_val;
13746 break;
13747 case DT_JMPREL:
13748 jmprel = entry->d_un.d_ptr;
13749 break;
252b5132
RH
13750 default:
13751 break;
13752 }
13753
13754 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
13755 {
2cf0635d 13756 Elf32_External_Lib * elib;
252b5132
RH
13757 size_t cnt;
13758
3f5e193b
NC
13759 elib = (Elf32_External_Lib *) get_data (NULL, file, liblist_offset,
13760 liblistno,
13761 sizeof (Elf32_External_Lib),
9cf03b7e 13762 _("liblist section data"));
a6e9f9df 13763 if (elib)
252b5132 13764 {
2b692964 13765 printf (_("\nSection '.liblist' contains %lu entries:\n"),
a6e9f9df 13766 (unsigned long) liblistno);
2b692964 13767 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
13768 stdout);
13769
13770 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 13771 {
a6e9f9df 13772 Elf32_Lib liblist;
91d6fa6a 13773 time_t atime;
a6e9f9df 13774 char timebuf[20];
2cf0635d 13775 struct tm * tmp;
a6e9f9df
AM
13776
13777 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 13778 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
13779 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
13780 liblist.l_version = BYTE_GET (elib[cnt].l_version);
13781 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
13782
91d6fa6a 13783 tmp = gmtime (&atime);
e9e44622
JJ
13784 snprintf (timebuf, sizeof (timebuf),
13785 "%04u-%02u-%02uT%02u:%02u:%02u",
13786 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
13787 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 13788
31104126 13789 printf ("%3lu: ", (unsigned long) cnt);
d79b3d50
NC
13790 if (VALID_DYNAMIC_NAME (liblist.l_name))
13791 print_symbol (20, GET_DYNAMIC_NAME (liblist.l_name));
13792 else
2b692964 13793 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
13794 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
13795 liblist.l_version);
a6e9f9df
AM
13796
13797 if (liblist.l_flags == 0)
2b692964 13798 puts (_(" NONE"));
a6e9f9df
AM
13799 else
13800 {
13801 static const struct
252b5132 13802 {
2cf0635d 13803 const char * name;
a6e9f9df 13804 int bit;
252b5132 13805 }
a6e9f9df
AM
13806 l_flags_vals[] =
13807 {
13808 { " EXACT_MATCH", LL_EXACT_MATCH },
13809 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
13810 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
13811 { " EXPORTS", LL_EXPORTS },
13812 { " DELAY_LOAD", LL_DELAY_LOAD },
13813 { " DELTA", LL_DELTA }
13814 };
13815 int flags = liblist.l_flags;
13816 size_t fcnt;
13817
60bca95a 13818 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
13819 if ((flags & l_flags_vals[fcnt].bit) != 0)
13820 {
13821 fputs (l_flags_vals[fcnt].name, stdout);
13822 flags ^= l_flags_vals[fcnt].bit;
13823 }
13824 if (flags != 0)
13825 printf (" %#x", (unsigned int) flags);
252b5132 13826
a6e9f9df
AM
13827 puts ("");
13828 }
252b5132 13829 }
252b5132 13830
a6e9f9df
AM
13831 free (elib);
13832 }
252b5132
RH
13833 }
13834
13835 if (options_offset != 0)
13836 {
2cf0635d 13837 Elf_External_Options * eopt;
2cf0635d
NC
13838 Elf_Internal_Options * iopt;
13839 Elf_Internal_Options * option;
252b5132
RH
13840 size_t offset;
13841 int cnt;
351cdf24 13842 sect = section_headers;
252b5132
RH
13843
13844 /* Find the section header so that we get the size. */
071436c6
NC
13845 sect = find_section_by_type (SHT_MIPS_OPTIONS);
13846 /* PR 17533 file: 012-277276-0.004. */
13847 if (sect == NULL)
13848 {
13849 error (_("No MIPS_OPTIONS header found\n"));
13850 return 0;
13851 }
252b5132 13852
3f5e193b
NC
13853 eopt = (Elf_External_Options *) get_data (NULL, file, options_offset, 1,
13854 sect->sh_size, _("options"));
a6e9f9df 13855 if (eopt)
252b5132 13856 {
3f5e193b
NC
13857 iopt = (Elf_Internal_Options *)
13858 cmalloc ((sect->sh_size / sizeof (eopt)), sizeof (* iopt));
a6e9f9df
AM
13859 if (iopt == NULL)
13860 {
8b73c356 13861 error (_("Out of memory allocatinf space for MIPS options\n"));
a6e9f9df
AM
13862 return 0;
13863 }
76da6bbe 13864
a6e9f9df
AM
13865 offset = cnt = 0;
13866 option = iopt;
252b5132 13867
82b1b41b 13868 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 13869 {
2cf0635d 13870 Elf_External_Options * eoption;
252b5132 13871
a6e9f9df 13872 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 13873
a6e9f9df
AM
13874 option->kind = BYTE_GET (eoption->kind);
13875 option->size = BYTE_GET (eoption->size);
13876 option->section = BYTE_GET (eoption->section);
13877 option->info = BYTE_GET (eoption->info);
76da6bbe 13878
82b1b41b
NC
13879 /* PR 17531: file: ffa0fa3b. */
13880 if (option->size < sizeof (* eopt)
13881 || offset + option->size > sect->sh_size)
13882 {
55325047
NC
13883 error (_("Invalid size (%u) for MIPS option\n"), option->size);
13884 return 0;
82b1b41b 13885 }
a6e9f9df 13886 offset += option->size;
82b1b41b 13887
a6e9f9df
AM
13888 ++option;
13889 ++cnt;
13890 }
252b5132 13891
a6e9f9df 13892 printf (_("\nSection '%s' contains %d entries:\n"),
74e1a04b 13893 printable_section_name (sect), cnt);
76da6bbe 13894
a6e9f9df 13895 option = iopt;
82b1b41b 13896 offset = 0;
252b5132 13897
a6e9f9df 13898 while (cnt-- > 0)
252b5132 13899 {
a6e9f9df
AM
13900 size_t len;
13901
13902 switch (option->kind)
252b5132 13903 {
a6e9f9df
AM
13904 case ODK_NULL:
13905 /* This shouldn't happen. */
13906 printf (" NULL %d %lx", option->section, option->info);
13907 break;
13908 case ODK_REGINFO:
13909 printf (" REGINFO ");
13910 if (elf_header.e_machine == EM_MIPS)
13911 {
13912 /* 32bit form. */
2cf0635d 13913 Elf32_External_RegInfo * ereg;
b34976b6 13914 Elf32_RegInfo reginfo;
a6e9f9df
AM
13915
13916 ereg = (Elf32_External_RegInfo *) (option + 1);
13917 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13918 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13919 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13920 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13921 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
13922 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
13923
13924 printf ("GPR %08lx GP 0x%lx\n",
13925 reginfo.ri_gprmask,
13926 (unsigned long) reginfo.ri_gp_value);
13927 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13928 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13929 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13930 }
13931 else
13932 {
13933 /* 64 bit form. */
2cf0635d 13934 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
13935 Elf64_Internal_RegInfo reginfo;
13936
13937 ereg = (Elf64_External_RegInfo *) (option + 1);
13938 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
13939 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
13940 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
13941 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
13942 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 13943 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df
AM
13944
13945 printf ("GPR %08lx GP 0x",
13946 reginfo.ri_gprmask);
13947 printf_vma (reginfo.ri_gp_value);
13948 printf ("\n");
13949
13950 printf (" CPR0 %08lx CPR1 %08lx CPR2 %08lx CPR3 %08lx\n",
13951 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
13952 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
13953 }
13954 ++option;
13955 continue;
13956 case ODK_EXCEPTIONS:
13957 fputs (" EXCEPTIONS fpe_min(", stdout);
13958 process_mips_fpe_exception (option->info & OEX_FPU_MIN);
13959 fputs (") fpe_max(", stdout);
13960 process_mips_fpe_exception ((option->info & OEX_FPU_MAX) >> 8);
13961 fputs (")", stdout);
13962
13963 if (option->info & OEX_PAGE0)
13964 fputs (" PAGE0", stdout);
13965 if (option->info & OEX_SMM)
13966 fputs (" SMM", stdout);
13967 if (option->info & OEX_FPDBUG)
13968 fputs (" FPDBUG", stdout);
13969 if (option->info & OEX_DISMISS)
13970 fputs (" DISMISS", stdout);
13971 break;
13972 case ODK_PAD:
13973 fputs (" PAD ", stdout);
13974 if (option->info & OPAD_PREFIX)
13975 fputs (" PREFIX", stdout);
13976 if (option->info & OPAD_POSTFIX)
13977 fputs (" POSTFIX", stdout);
13978 if (option->info & OPAD_SYMBOL)
13979 fputs (" SYMBOL", stdout);
13980 break;
13981 case ODK_HWPATCH:
13982 fputs (" HWPATCH ", stdout);
13983 if (option->info & OHW_R4KEOP)
13984 fputs (" R4KEOP", stdout);
13985 if (option->info & OHW_R8KPFETCH)
13986 fputs (" R8KPFETCH", stdout);
13987 if (option->info & OHW_R5KEOP)
13988 fputs (" R5KEOP", stdout);
13989 if (option->info & OHW_R5KCVTL)
13990 fputs (" R5KCVTL", stdout);
13991 break;
13992 case ODK_FILL:
13993 fputs (" FILL ", stdout);
13994 /* XXX Print content of info word? */
13995 break;
13996 case ODK_TAGS:
13997 fputs (" TAGS ", stdout);
13998 /* XXX Print content of info word? */
13999 break;
14000 case ODK_HWAND:
14001 fputs (" HWAND ", stdout);
14002 if (option->info & OHWA0_R4KEOP_CHECKED)
14003 fputs (" R4KEOP_CHECKED", stdout);
14004 if (option->info & OHWA0_R4KEOP_CLEAN)
14005 fputs (" R4KEOP_CLEAN", stdout);
14006 break;
14007 case ODK_HWOR:
14008 fputs (" HWOR ", stdout);
14009 if (option->info & OHWA0_R4KEOP_CHECKED)
14010 fputs (" R4KEOP_CHECKED", stdout);
14011 if (option->info & OHWA0_R4KEOP_CLEAN)
14012 fputs (" R4KEOP_CLEAN", stdout);
14013 break;
14014 case ODK_GP_GROUP:
14015 printf (" GP_GROUP %#06lx self-contained %#06lx",
14016 option->info & OGP_GROUP,
14017 (option->info & OGP_SELF) >> 16);
14018 break;
14019 case ODK_IDENT:
14020 printf (" IDENT %#06lx self-contained %#06lx",
14021 option->info & OGP_GROUP,
14022 (option->info & OGP_SELF) >> 16);
14023 break;
14024 default:
14025 /* This shouldn't happen. */
14026 printf (" %3d ??? %d %lx",
14027 option->kind, option->section, option->info);
14028 break;
252b5132 14029 }
a6e9f9df 14030
2cf0635d 14031 len = sizeof (* eopt);
a6e9f9df 14032 while (len < option->size)
82b1b41b
NC
14033 {
14034 char datum = * ((char *) eopt + offset + len);
a6e9f9df 14035
82b1b41b
NC
14036 if (ISPRINT (datum))
14037 printf ("%c", datum);
14038 else
14039 printf ("\\%03o", datum);
14040 len ++;
14041 }
a6e9f9df 14042 fputs ("\n", stdout);
82b1b41b
NC
14043
14044 offset += option->size;
252b5132 14045 ++option;
252b5132
RH
14046 }
14047
a6e9f9df 14048 free (eopt);
252b5132 14049 }
252b5132
RH
14050 }
14051
14052 if (conflicts_offset != 0 && conflictsno != 0)
14053 {
2cf0635d 14054 Elf32_Conflict * iconf;
252b5132
RH
14055 size_t cnt;
14056
14057 if (dynamic_symbols == NULL)
14058 {
591a748a 14059 error (_("conflict list found without a dynamic symbol table\n"));
252b5132
RH
14060 return 0;
14061 }
14062
3f5e193b 14063 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
14064 if (iconf == NULL)
14065 {
8b73c356 14066 error (_("Out of memory allocating space for dynamic conflicts\n"));
252b5132
RH
14067 return 0;
14068 }
14069
9ea033b2 14070 if (is_32bit_elf)
252b5132 14071 {
2cf0635d 14072 Elf32_External_Conflict * econf32;
a6e9f9df 14073
3f5e193b
NC
14074 econf32 = (Elf32_External_Conflict *)
14075 get_data (NULL, file, conflicts_offset, conflictsno,
14076 sizeof (* econf32), _("conflict"));
a6e9f9df
AM
14077 if (!econf32)
14078 return 0;
252b5132
RH
14079
14080 for (cnt = 0; cnt < conflictsno; ++cnt)
14081 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
14082
14083 free (econf32);
252b5132
RH
14084 }
14085 else
14086 {
2cf0635d 14087 Elf64_External_Conflict * econf64;
a6e9f9df 14088
3f5e193b
NC
14089 econf64 = (Elf64_External_Conflict *)
14090 get_data (NULL, file, conflicts_offset, conflictsno,
14091 sizeof (* econf64), _("conflict"));
a6e9f9df
AM
14092 if (!econf64)
14093 return 0;
252b5132
RH
14094
14095 for (cnt = 0; cnt < conflictsno; ++cnt)
14096 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
14097
14098 free (econf64);
252b5132
RH
14099 }
14100
c7e7ca54
NC
14101 printf (_("\nSection '.conflict' contains %lu entries:\n"),
14102 (unsigned long) conflictsno);
252b5132
RH
14103 puts (_(" Num: Index Value Name"));
14104
14105 for (cnt = 0; cnt < conflictsno; ++cnt)
14106 {
b34976b6 14107 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1
NC
14108
14109 if (iconf[cnt] >= num_dynamic_syms)
14110 printf (_("<corrupt symbol index>"));
d79b3d50 14111 else
e0a31db1
NC
14112 {
14113 Elf_Internal_Sym * psym;
14114
14115 psym = & dynamic_symbols[iconf[cnt]];
14116 print_vma (psym->st_value, FULL_HEX);
14117 putchar (' ');
14118 if (VALID_DYNAMIC_NAME (psym->st_name))
14119 print_symbol (25, GET_DYNAMIC_NAME (psym->st_name));
14120 else
14121 printf (_("<corrupt: %14ld>"), psym->st_name);
14122 }
31104126 14123 putchar ('\n');
252b5132
RH
14124 }
14125
252b5132
RH
14126 free (iconf);
14127 }
14128
ccb4c951
RS
14129 if (pltgot != 0 && local_gotno != 0)
14130 {
91d6fa6a 14131 bfd_vma ent, local_end, global_end;
bbeee7ea 14132 size_t i, offset;
2cf0635d 14133 unsigned char * data;
82b1b41b 14134 unsigned char * data_end;
bbeee7ea 14135 int addr_size;
ccb4c951 14136
91d6fa6a 14137 ent = pltgot;
ccb4c951
RS
14138 addr_size = (is_32bit_elf ? 4 : 8);
14139 local_end = pltgot + local_gotno * addr_size;
ccb4c951 14140
74e1a04b
NC
14141 /* PR binutils/17533 file: 012-111227-0.004 */
14142 if (symtabno < gotsym)
14143 {
14144 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 14145 (unsigned long) gotsym, (unsigned long) symtabno);
74e1a04b
NC
14146 return 0;
14147 }
82b1b41b 14148
74e1a04b 14149 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
14150 /* PR 17531: file: 54c91a34. */
14151 if (global_end < local_end)
14152 {
14153 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
14154 return 0;
14155 }
14156
ccb4c951 14157 offset = offset_from_vma (file, pltgot, global_end - pltgot);
3f5e193b 14158 data = (unsigned char *) get_data (NULL, file, offset,
9cf03b7e
NC
14159 global_end - pltgot, 1,
14160 _("Global Offset Table data"));
59245841
NC
14161 if (data == NULL)
14162 return 0;
82b1b41b 14163 data_end = data + (global_end - pltgot);
59245841 14164
ccb4c951
RS
14165 printf (_("\nPrimary GOT:\n"));
14166 printf (_(" Canonical gp value: "));
14167 print_vma (pltgot + 0x7ff0, LONG_HEX);
14168 printf ("\n\n");
14169
14170 printf (_(" Reserved entries:\n"));
14171 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
14172 addr_size * 2, _("Address"), _("Access"),
14173 addr_size * 2, _("Initial"));
82b1b41b 14174 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 14175 printf (_(" Lazy resolver\n"));
82b1b41b
NC
14176 if (ent == (bfd_vma) -1)
14177 goto got_print_fail;
ccb4c951 14178 if (data
91d6fa6a 14179 && (byte_get (data + ent - pltgot, addr_size)
ccb4c951
RS
14180 >> (addr_size * 8 - 1)) != 0)
14181 {
82b1b41b 14182 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 14183 printf (_(" Module pointer (GNU extension)\n"));
82b1b41b
NC
14184 if (ent == (bfd_vma) -1)
14185 goto got_print_fail;
ccb4c951
RS
14186 }
14187 printf ("\n");
14188
91d6fa6a 14189 if (ent < local_end)
ccb4c951
RS
14190 {
14191 printf (_(" Local entries:\n"));
cc5914eb 14192 printf (" %*s %10s %*s\n",
2b692964
NC
14193 addr_size * 2, _("Address"), _("Access"),
14194 addr_size * 2, _("Initial"));
91d6fa6a 14195 while (ent < local_end)
ccb4c951 14196 {
82b1b41b 14197 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 14198 printf ("\n");
82b1b41b
NC
14199 if (ent == (bfd_vma) -1)
14200 goto got_print_fail;
ccb4c951
RS
14201 }
14202 printf ("\n");
14203 }
14204
14205 if (gotsym < symtabno)
14206 {
14207 int sym_width;
14208
14209 printf (_(" Global entries:\n"));
cc5914eb 14210 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
14211 addr_size * 2, _("Address"),
14212 _("Access"),
2b692964 14213 addr_size * 2, _("Initial"),
9cf03b7e
NC
14214 addr_size * 2, _("Sym.Val."),
14215 _("Type"),
14216 /* Note for translators: "Ndx" = abbreviated form of "Index". */
14217 _("Ndx"), _("Name"));
0b4362b0 14218
ccb4c951 14219 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 14220
ccb4c951
RS
14221 for (i = gotsym; i < symtabno; i++)
14222 {
82b1b41b 14223 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 14224 printf (" ");
e0a31db1
NC
14225
14226 if (dynamic_symbols == NULL)
14227 printf (_("<no dynamic symbols>"));
14228 else if (i < num_dynamic_syms)
14229 {
14230 Elf_Internal_Sym * psym = dynamic_symbols + i;
14231
14232 print_vma (psym->st_value, LONG_HEX);
14233 printf (" %-7s %3s ",
14234 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14235 get_symbol_index_type (psym->st_shndx));
14236
14237 if (VALID_DYNAMIC_NAME (psym->st_name))
14238 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14239 else
14240 printf (_("<corrupt: %14ld>"), psym->st_name);
14241 }
ccb4c951 14242 else
7fc5ac57
JBG
14243 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
14244 (unsigned long) i);
e0a31db1 14245
ccb4c951 14246 printf ("\n");
82b1b41b
NC
14247 if (ent == (bfd_vma) -1)
14248 break;
ccb4c951
RS
14249 }
14250 printf ("\n");
14251 }
14252
82b1b41b 14253 got_print_fail:
ccb4c951
RS
14254 if (data)
14255 free (data);
14256 }
14257
861fb55a
DJ
14258 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
14259 {
91d6fa6a 14260 bfd_vma ent, end;
861fb55a
DJ
14261 size_t offset, rel_offset;
14262 unsigned long count, i;
2cf0635d 14263 unsigned char * data;
861fb55a 14264 int addr_size, sym_width;
2cf0635d 14265 Elf_Internal_Rela * rels;
861fb55a
DJ
14266
14267 rel_offset = offset_from_vma (file, jmprel, pltrelsz);
14268 if (pltrel == DT_RELA)
14269 {
14270 if (!slurp_rela_relocs (file, rel_offset, pltrelsz, &rels, &count))
14271 return 0;
14272 }
14273 else
14274 {
14275 if (!slurp_rel_relocs (file, rel_offset, pltrelsz, &rels, &count))
14276 return 0;
14277 }
14278
91d6fa6a 14279 ent = mips_pltgot;
861fb55a
DJ
14280 addr_size = (is_32bit_elf ? 4 : 8);
14281 end = mips_pltgot + (2 + count) * addr_size;
14282
14283 offset = offset_from_vma (file, mips_pltgot, end - mips_pltgot);
3f5e193b 14284 data = (unsigned char *) get_data (NULL, file, offset, end - mips_pltgot,
9cf03b7e 14285 1, _("Procedure Linkage Table data"));
59245841
NC
14286 if (data == NULL)
14287 return 0;
14288
9cf03b7e 14289 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
14290 printf (_(" Reserved entries:\n"));
14291 printf (_(" %*s %*s Purpose\n"),
2b692964 14292 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 14293 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14294 printf (_(" PLT lazy resolver\n"));
91d6fa6a 14295 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 14296 printf (_(" Module pointer\n"));
861fb55a
DJ
14297 printf ("\n");
14298
14299 printf (_(" Entries:\n"));
cc5914eb 14300 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
14301 addr_size * 2, _("Address"),
14302 addr_size * 2, _("Initial"),
14303 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
14304 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
14305 for (i = 0; i < count; i++)
14306 {
df97ab2a 14307 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 14308
91d6fa6a 14309 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 14310 printf (" ");
e0a31db1 14311
df97ab2a
MF
14312 if (idx >= num_dynamic_syms)
14313 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 14314 else
e0a31db1 14315 {
df97ab2a 14316 Elf_Internal_Sym * psym = dynamic_symbols + idx;
e0a31db1
NC
14317
14318 print_vma (psym->st_value, LONG_HEX);
14319 printf (" %-7s %3s ",
14320 get_symbol_type (ELF_ST_TYPE (psym->st_info)),
14321 get_symbol_index_type (psym->st_shndx));
14322 if (VALID_DYNAMIC_NAME (psym->st_name))
14323 print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
14324 else
14325 printf (_("<corrupt: %14ld>"), psym->st_name);
14326 }
861fb55a
DJ
14327 printf ("\n");
14328 }
14329 printf ("\n");
14330
14331 if (data)
14332 free (data);
14333 free (rels);
14334 }
14335
252b5132
RH
14336 return 1;
14337}
14338
35c08157
KLC
14339static int
14340process_nds32_specific (FILE * file)
14341{
14342 Elf_Internal_Shdr *sect = NULL;
14343
14344 sect = find_section (".nds32_e_flags");
14345 if (sect != NULL)
14346 {
14347 unsigned int *flag;
14348
14349 printf ("\nNDS32 elf flags section:\n");
14350 flag = get_data (NULL, file, sect->sh_offset, 1,
14351 sect->sh_size, _("NDS32 elf flags section"));
14352
14353 switch ((*flag) & 0x3)
14354 {
14355 case 0:
14356 printf ("(VEC_SIZE):\tNo entry.\n");
14357 break;
14358 case 1:
14359 printf ("(VEC_SIZE):\t4 bytes\n");
14360 break;
14361 case 2:
14362 printf ("(VEC_SIZE):\t16 bytes\n");
14363 break;
14364 case 3:
14365 printf ("(VEC_SIZE):\treserved\n");
14366 break;
14367 }
14368 }
14369
14370 return TRUE;
14371}
14372
047b2264 14373static int
2cf0635d 14374process_gnu_liblist (FILE * file)
047b2264 14375{
2cf0635d
NC
14376 Elf_Internal_Shdr * section;
14377 Elf_Internal_Shdr * string_sec;
14378 Elf32_External_Lib * elib;
14379 char * strtab;
c256ffe7 14380 size_t strtab_size;
047b2264
JJ
14381 size_t cnt;
14382 unsigned i;
14383
14384 if (! do_arch)
14385 return 0;
14386
14387 for (i = 0, section = section_headers;
14388 i < elf_header.e_shnum;
b34976b6 14389 i++, section++)
047b2264
JJ
14390 {
14391 switch (section->sh_type)
14392 {
14393 case SHT_GNU_LIBLIST:
4fbb74a6 14394 if (section->sh_link >= elf_header.e_shnum)
c256ffe7
JJ
14395 break;
14396
3f5e193b
NC
14397 elib = (Elf32_External_Lib *)
14398 get_data (NULL, file, section->sh_offset, 1, section->sh_size,
9cf03b7e 14399 _("liblist section data"));
047b2264
JJ
14400
14401 if (elib == NULL)
14402 break;
4fbb74a6 14403 string_sec = section_headers + section->sh_link;
047b2264 14404
3f5e193b
NC
14405 strtab = (char *) get_data (NULL, file, string_sec->sh_offset, 1,
14406 string_sec->sh_size,
14407 _("liblist string table"));
047b2264
JJ
14408 if (strtab == NULL
14409 || section->sh_entsize != sizeof (Elf32_External_Lib))
14410 {
14411 free (elib);
2842702f 14412 free (strtab);
047b2264
JJ
14413 break;
14414 }
59245841 14415 strtab_size = string_sec->sh_size;
047b2264
JJ
14416
14417 printf (_("\nLibrary list section '%s' contains %lu entries:\n"),
74e1a04b 14418 printable_section_name (section),
0af1713e 14419 (unsigned long) (section->sh_size / sizeof (Elf32_External_Lib)));
047b2264 14420
2b692964 14421 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
14422
14423 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
14424 ++cnt)
14425 {
14426 Elf32_Lib liblist;
91d6fa6a 14427 time_t atime;
047b2264 14428 char timebuf[20];
2cf0635d 14429 struct tm * tmp;
047b2264
JJ
14430
14431 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 14432 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
14433 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
14434 liblist.l_version = BYTE_GET (elib[cnt].l_version);
14435 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
14436
91d6fa6a 14437 tmp = gmtime (&atime);
e9e44622
JJ
14438 snprintf (timebuf, sizeof (timebuf),
14439 "%04u-%02u-%02uT%02u:%02u:%02u",
14440 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
14441 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
14442
14443 printf ("%3lu: ", (unsigned long) cnt);
14444 if (do_wide)
c256ffe7 14445 printf ("%-20s", liblist.l_name < strtab_size
2b692964 14446 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 14447 else
c256ffe7 14448 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 14449 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
14450 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
14451 liblist.l_version, liblist.l_flags);
14452 }
14453
14454 free (elib);
2842702f 14455 free (strtab);
047b2264
JJ
14456 }
14457 }
14458
14459 return 1;
14460}
14461
9437c45b 14462static const char *
d3ba0551 14463get_note_type (unsigned e_type)
779fe533
NC
14464{
14465 static char buff[64];
103f02d3 14466
1ec5cd37
NC
14467 if (elf_header.e_type == ET_CORE)
14468 switch (e_type)
14469 {
57346661 14470 case NT_AUXV:
1ec5cd37 14471 return _("NT_AUXV (auxiliary vector)");
57346661 14472 case NT_PRSTATUS:
1ec5cd37 14473 return _("NT_PRSTATUS (prstatus structure)");
57346661 14474 case NT_FPREGSET:
1ec5cd37 14475 return _("NT_FPREGSET (floating point registers)");
57346661 14476 case NT_PRPSINFO:
1ec5cd37 14477 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 14478 case NT_TASKSTRUCT:
1ec5cd37 14479 return _("NT_TASKSTRUCT (task structure)");
57346661 14480 case NT_PRXFPREG:
1ec5cd37 14481 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
14482 case NT_PPC_VMX:
14483 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
14484 case NT_PPC_VSX:
14485 return _("NT_PPC_VSX (ppc VSX registers)");
ff826ef3
TT
14486 case NT_386_TLS:
14487 return _("NT_386_TLS (x86 TLS information)");
14488 case NT_386_IOPERM:
14489 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
14490 case NT_X86_XSTATE:
14491 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
14492 case NT_S390_HIGH_GPRS:
14493 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
14494 case NT_S390_TIMER:
14495 return _("NT_S390_TIMER (s390 timer register)");
14496 case NT_S390_TODCMP:
14497 return _("NT_S390_TODCMP (s390 TOD comparator register)");
14498 case NT_S390_TODPREG:
14499 return _("NT_S390_TODPREG (s390 TOD programmable register)");
14500 case NT_S390_CTRS:
14501 return _("NT_S390_CTRS (s390 control registers)");
14502 case NT_S390_PREFIX:
14503 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
14504 case NT_S390_LAST_BREAK:
14505 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
14506 case NT_S390_SYSTEM_CALL:
14507 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
14508 case NT_S390_TDB:
14509 return _("NT_S390_TDB (s390 transaction diagnostic block)");
faa9a424
UW
14510 case NT_ARM_VFP:
14511 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
14512 case NT_ARM_TLS:
14513 return _("NT_ARM_TLS (AArch TLS registers)");
14514 case NT_ARM_HW_BREAK:
14515 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
14516 case NT_ARM_HW_WATCH:
14517 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
57346661 14518 case NT_PSTATUS:
1ec5cd37 14519 return _("NT_PSTATUS (pstatus structure)");
57346661 14520 case NT_FPREGS:
1ec5cd37 14521 return _("NT_FPREGS (floating point registers)");
57346661 14522 case NT_PSINFO:
1ec5cd37 14523 return _("NT_PSINFO (psinfo structure)");
57346661 14524 case NT_LWPSTATUS:
1ec5cd37 14525 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 14526 case NT_LWPSINFO:
1ec5cd37 14527 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 14528 case NT_WIN32PSTATUS:
1ec5cd37 14529 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
14530 case NT_SIGINFO:
14531 return _("NT_SIGINFO (siginfo_t data)");
14532 case NT_FILE:
14533 return _("NT_FILE (mapped files)");
1ec5cd37
NC
14534 default:
14535 break;
14536 }
14537 else
14538 switch (e_type)
14539 {
14540 case NT_VERSION:
14541 return _("NT_VERSION (version)");
14542 case NT_ARCH:
14543 return _("NT_ARCH (architecture)");
14544 default:
14545 break;
14546 }
14547
e9e44622 14548 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 14549 return buff;
779fe533
NC
14550}
14551
9ece1fa9
TT
14552static int
14553print_core_note (Elf_Internal_Note *pnote)
14554{
14555 unsigned int addr_size = is_32bit_elf ? 4 : 8;
14556 bfd_vma count, page_size;
14557 unsigned char *descdata, *filenames, *descend;
14558
14559 if (pnote->type != NT_FILE)
14560 return 1;
14561
14562#ifndef BFD64
14563 if (!is_32bit_elf)
14564 {
14565 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
14566 /* Still "successful". */
14567 return 1;
14568 }
14569#endif
14570
14571 if (pnote->descsz < 2 * addr_size)
14572 {
14573 printf (_(" Malformed note - too short for header\n"));
14574 return 0;
14575 }
14576
14577 descdata = (unsigned char *) pnote->descdata;
14578 descend = descdata + pnote->descsz;
14579
14580 if (descdata[pnote->descsz - 1] != '\0')
14581 {
14582 printf (_(" Malformed note - does not end with \\0\n"));
14583 return 0;
14584 }
14585
14586 count = byte_get (descdata, addr_size);
14587 descdata += addr_size;
14588
14589 page_size = byte_get (descdata, addr_size);
14590 descdata += addr_size;
14591
14592 if (pnote->descsz < 2 * addr_size + count * 3 * addr_size)
14593 {
14594 printf (_(" Malformed note - too short for supplied file count\n"));
14595 return 0;
14596 }
14597
14598 printf (_(" Page size: "));
14599 print_vma (page_size, DEC);
14600 printf ("\n");
14601
14602 printf (_(" %*s%*s%*s\n"),
14603 (int) (2 + 2 * addr_size), _("Start"),
14604 (int) (4 + 2 * addr_size), _("End"),
14605 (int) (4 + 2 * addr_size), _("Page Offset"));
14606 filenames = descdata + count * 3 * addr_size;
14607 while (--count > 0)
14608 {
14609 bfd_vma start, end, file_ofs;
14610
14611 if (filenames == descend)
14612 {
14613 printf (_(" Malformed note - filenames end too early\n"));
14614 return 0;
14615 }
14616
14617 start = byte_get (descdata, addr_size);
14618 descdata += addr_size;
14619 end = byte_get (descdata, addr_size);
14620 descdata += addr_size;
14621 file_ofs = byte_get (descdata, addr_size);
14622 descdata += addr_size;
14623
14624 printf (" ");
14625 print_vma (start, FULL_HEX);
14626 printf (" ");
14627 print_vma (end, FULL_HEX);
14628 printf (" ");
14629 print_vma (file_ofs, FULL_HEX);
14630 printf ("\n %s\n", filenames);
14631
14632 filenames += 1 + strlen ((char *) filenames);
14633 }
14634
14635 return 1;
14636}
14637
1118d252
RM
14638static const char *
14639get_gnu_elf_note_type (unsigned e_type)
14640{
14641 static char buff[64];
14642
14643 switch (e_type)
14644 {
14645 case NT_GNU_ABI_TAG:
14646 return _("NT_GNU_ABI_TAG (ABI version tag)");
14647 case NT_GNU_HWCAP:
14648 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
14649 case NT_GNU_BUILD_ID:
14650 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
14651 case NT_GNU_GOLD_VERSION:
14652 return _("NT_GNU_GOLD_VERSION (gold version)");
1118d252
RM
14653 default:
14654 break;
14655 }
14656
14657 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14658 return buff;
14659}
14660
664f90a3
TT
14661static int
14662print_gnu_note (Elf_Internal_Note *pnote)
14663{
14664 switch (pnote->type)
14665 {
14666 case NT_GNU_BUILD_ID:
14667 {
14668 unsigned long i;
14669
14670 printf (_(" Build ID: "));
14671 for (i = 0; i < pnote->descsz; ++i)
14672 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 14673 printf ("\n");
664f90a3
TT
14674 }
14675 break;
14676
14677 case NT_GNU_ABI_TAG:
14678 {
14679 unsigned long os, major, minor, subminor;
14680 const char *osname;
14681
3102e897
NC
14682 /* PR 17531: file: 030-599401-0.004. */
14683 if (pnote->descsz < 16)
14684 {
14685 printf (_(" <corrupt GNU_ABI_TAG>\n"));
14686 break;
14687 }
14688
664f90a3
TT
14689 os = byte_get ((unsigned char *) pnote->descdata, 4);
14690 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
14691 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
14692 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
14693
14694 switch (os)
14695 {
14696 case GNU_ABI_TAG_LINUX:
14697 osname = "Linux";
14698 break;
14699 case GNU_ABI_TAG_HURD:
14700 osname = "Hurd";
14701 break;
14702 case GNU_ABI_TAG_SOLARIS:
14703 osname = "Solaris";
14704 break;
14705 case GNU_ABI_TAG_FREEBSD:
14706 osname = "FreeBSD";
14707 break;
14708 case GNU_ABI_TAG_NETBSD:
14709 osname = "NetBSD";
14710 break;
14711 default:
14712 osname = "Unknown";
14713 break;
14714 }
14715
14716 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
14717 major, minor, subminor);
14718 }
14719 break;
926c5385
CC
14720
14721 case NT_GNU_GOLD_VERSION:
14722 {
14723 unsigned long i;
14724
14725 printf (_(" Version: "));
14726 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
14727 printf ("%c", pnote->descdata[i]);
14728 printf ("\n");
14729 }
14730 break;
664f90a3
TT
14731 }
14732
14733 return 1;
14734}
14735
9437c45b 14736static const char *
d3ba0551 14737get_netbsd_elfcore_note_type (unsigned e_type)
9437c45b
JT
14738{
14739 static char buff[64];
14740
b4db1224 14741 if (e_type == NT_NETBSDCORE_PROCINFO)
9437c45b
JT
14742 {
14743 /* NetBSD core "procinfo" structure. */
14744 return _("NetBSD procinfo structure");
14745 }
14746
14747 /* As of Jan 2002 there are no other machine-independent notes
14748 defined for NetBSD core files. If the note type is less
14749 than the start of the machine-dependent note types, we don't
14750 understand it. */
14751
b4db1224 14752 if (e_type < NT_NETBSDCORE_FIRSTMACH)
9437c45b 14753 {
e9e44622 14754 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
9437c45b
JT
14755 return buff;
14756 }
14757
14758 switch (elf_header.e_machine)
14759 {
14760 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
14761 and PT_GETFPREGS == mach+2. */
14762
14763 case EM_OLD_ALPHA:
14764 case EM_ALPHA:
14765 case EM_SPARC:
14766 case EM_SPARC32PLUS:
14767 case EM_SPARCV9:
14768 switch (e_type)
14769 {
2b692964 14770 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 14771 return _("PT_GETREGS (reg structure)");
2b692964 14772 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 14773 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14774 default:
14775 break;
14776 }
14777 break;
14778
14779 /* On all other arch's, PT_GETREGS == mach+1 and
14780 PT_GETFPREGS == mach+3. */
14781 default:
14782 switch (e_type)
14783 {
2b692964 14784 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 14785 return _("PT_GETREGS (reg structure)");
2b692964 14786 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 14787 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
14788 default:
14789 break;
14790 }
14791 }
14792
9cf03b7e 14793 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 14794 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
14795 return buff;
14796}
14797
70616151
TT
14798static const char *
14799get_stapsdt_note_type (unsigned e_type)
14800{
14801 static char buff[64];
14802
14803 switch (e_type)
14804 {
14805 case NT_STAPSDT:
14806 return _("NT_STAPSDT (SystemTap probe descriptors)");
14807
14808 default:
14809 break;
14810 }
14811
14812 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14813 return buff;
14814}
14815
c6a9fc58
TT
14816static int
14817print_stapsdt_note (Elf_Internal_Note *pnote)
14818{
14819 int addr_size = is_32bit_elf ? 4 : 8;
14820 char *data = pnote->descdata;
14821 char *data_end = pnote->descdata + pnote->descsz;
14822 bfd_vma pc, base_addr, semaphore;
14823 char *provider, *probe, *arg_fmt;
14824
14825 pc = byte_get ((unsigned char *) data, addr_size);
14826 data += addr_size;
14827 base_addr = byte_get ((unsigned char *) data, addr_size);
14828 data += addr_size;
14829 semaphore = byte_get ((unsigned char *) data, addr_size);
14830 data += addr_size;
14831
14832 provider = data;
14833 data += strlen (data) + 1;
14834 probe = data;
14835 data += strlen (data) + 1;
14836 arg_fmt = data;
14837 data += strlen (data) + 1;
14838
14839 printf (_(" Provider: %s\n"), provider);
14840 printf (_(" Name: %s\n"), probe);
14841 printf (_(" Location: "));
14842 print_vma (pc, FULL_HEX);
14843 printf (_(", Base: "));
14844 print_vma (base_addr, FULL_HEX);
14845 printf (_(", Semaphore: "));
14846 print_vma (semaphore, FULL_HEX);
9cf03b7e 14847 printf ("\n");
c6a9fc58
TT
14848 printf (_(" Arguments: %s\n"), arg_fmt);
14849
14850 return data == data_end;
14851}
14852
00e98fc7
TG
14853static const char *
14854get_ia64_vms_note_type (unsigned e_type)
14855{
14856 static char buff[64];
14857
14858 switch (e_type)
14859 {
14860 case NT_VMS_MHD:
14861 return _("NT_VMS_MHD (module header)");
14862 case NT_VMS_LNM:
14863 return _("NT_VMS_LNM (language name)");
14864 case NT_VMS_SRC:
14865 return _("NT_VMS_SRC (source files)");
14866 case NT_VMS_TITLE:
9cf03b7e 14867 return "NT_VMS_TITLE";
00e98fc7
TG
14868 case NT_VMS_EIDC:
14869 return _("NT_VMS_EIDC (consistency check)");
14870 case NT_VMS_FPMODE:
14871 return _("NT_VMS_FPMODE (FP mode)");
14872 case NT_VMS_LINKTIME:
9cf03b7e 14873 return "NT_VMS_LINKTIME";
00e98fc7
TG
14874 case NT_VMS_IMGNAM:
14875 return _("NT_VMS_IMGNAM (image name)");
14876 case NT_VMS_IMGID:
14877 return _("NT_VMS_IMGID (image id)");
14878 case NT_VMS_LINKID:
14879 return _("NT_VMS_LINKID (link id)");
14880 case NT_VMS_IMGBID:
14881 return _("NT_VMS_IMGBID (build id)");
14882 case NT_VMS_GSTNAM:
14883 return _("NT_VMS_GSTNAM (sym table name)");
14884 case NT_VMS_ORIG_DYN:
9cf03b7e 14885 return "NT_VMS_ORIG_DYN";
00e98fc7 14886 case NT_VMS_PATCHTIME:
9cf03b7e 14887 return "NT_VMS_PATCHTIME";
00e98fc7
TG
14888 default:
14889 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
14890 return buff;
14891 }
14892}
14893
14894static int
14895print_ia64_vms_note (Elf_Internal_Note * pnote)
14896{
14897 switch (pnote->type)
14898 {
14899 case NT_VMS_MHD:
14900 if (pnote->descsz > 36)
14901 {
14902 size_t l = strlen (pnote->descdata + 34);
14903 printf (_(" Creation date : %.17s\n"), pnote->descdata);
14904 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
14905 printf (_(" Module name : %s\n"), pnote->descdata + 34);
14906 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
14907 }
14908 else
14909 printf (_(" Invalid size\n"));
14910 break;
14911 case NT_VMS_LNM:
14912 printf (_(" Language: %s\n"), pnote->descdata);
14913 break;
14914#ifdef BFD64
14915 case NT_VMS_FPMODE:
9cf03b7e 14916 printf (_(" Floating Point mode: "));
4a5cb34f 14917 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14918 (bfd_vma)byte_get ((unsigned char *)pnote->descdata, 8));
14919 break;
14920 case NT_VMS_LINKTIME:
14921 printf (_(" Link time: "));
14922 print_vms_time
14923 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14924 printf ("\n");
14925 break;
14926 case NT_VMS_PATCHTIME:
14927 printf (_(" Patch time: "));
14928 print_vms_time
14929 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
14930 printf ("\n");
14931 break;
14932 case NT_VMS_ORIG_DYN:
14933 printf (_(" Major id: %u, minor id: %u\n"),
14934 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
14935 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 14936 printf (_(" Last modified : "));
00e98fc7
TG
14937 print_vms_time
14938 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 14939 printf (_("\n Link flags : "));
4a5cb34f 14940 printf ("0x%016" BFD_VMA_FMT "x\n",
00e98fc7
TG
14941 (bfd_vma)byte_get ((unsigned char *)pnote->descdata + 16, 8));
14942 printf (_(" Header flags: 0x%08x\n"),
14943 (unsigned)byte_get ((unsigned char *)pnote->descdata + 24, 4));
14944 printf (_(" Image id : %s\n"), pnote->descdata + 32);
14945 break;
14946#endif
14947 case NT_VMS_IMGNAM:
14948 printf (_(" Image name: %s\n"), pnote->descdata);
14949 break;
14950 case NT_VMS_GSTNAM:
14951 printf (_(" Global symbol table name: %s\n"), pnote->descdata);
14952 break;
14953 case NT_VMS_IMGID:
14954 printf (_(" Image id: %s\n"), pnote->descdata);
14955 break;
14956 case NT_VMS_LINKID:
14957 printf (_(" Linker id: %s\n"), pnote->descdata);
14958 break;
14959 default:
14960 break;
14961 }
14962 return 1;
14963}
14964
6d118b09
NC
14965/* Note that by the ELF standard, the name field is already null byte
14966 terminated, and namesz includes the terminating null byte.
14967 I.E. the value of namesz for the name "FSF" is 4.
14968
e3c8793a 14969 If the value of namesz is zero, there is no name present. */
779fe533 14970static int
2cf0635d 14971process_note (Elf_Internal_Note * pnote)
779fe533 14972{
2cf0635d
NC
14973 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
14974 const char * nt;
9437c45b
JT
14975
14976 if (pnote->namesz == 0)
1ec5cd37
NC
14977 /* If there is no note name, then use the default set of
14978 note type strings. */
14979 nt = get_note_type (pnote->type);
14980
1118d252
RM
14981 else if (const_strneq (pnote->namedata, "GNU"))
14982 /* GNU-specific object file notes. */
14983 nt = get_gnu_elf_note_type (pnote->type);
14984
0112cd26 14985 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37
NC
14986 /* NetBSD-specific core file notes. */
14987 nt = get_netbsd_elfcore_note_type (pnote->type);
14988
b15fa79e
AM
14989 else if (strneq (pnote->namedata, "SPU/", 4))
14990 {
14991 /* SPU-specific core file notes. */
14992 nt = pnote->namedata + 4;
14993 name = "SPU";
14994 }
14995
00e98fc7
TG
14996 else if (const_strneq (pnote->namedata, "IPF/VMS"))
14997 /* VMS/ia64-specific file notes. */
14998 nt = get_ia64_vms_note_type (pnote->type);
14999
70616151
TT
15000 else if (const_strneq (pnote->namedata, "stapsdt"))
15001 nt = get_stapsdt_note_type (pnote->type);
15002
9437c45b 15003 else
1ec5cd37
NC
15004 /* Don't recognize this note name; just use the default set of
15005 note type strings. */
00e98fc7 15006 nt = get_note_type (pnote->type);
9437c45b 15007
2aee03ae 15008 printf (" %-20s 0x%08lx\t%s\n", name, pnote->descsz, nt);
00e98fc7
TG
15009
15010 if (const_strneq (pnote->namedata, "IPF/VMS"))
15011 return print_ia64_vms_note (pnote);
664f90a3
TT
15012 else if (const_strneq (pnote->namedata, "GNU"))
15013 return print_gnu_note (pnote);
c6a9fc58
TT
15014 else if (const_strneq (pnote->namedata, "stapsdt"))
15015 return print_stapsdt_note (pnote);
9ece1fa9
TT
15016 else if (const_strneq (pnote->namedata, "CORE"))
15017 return print_core_note (pnote);
00e98fc7
TG
15018 else
15019 return 1;
779fe533
NC
15020}
15021
6d118b09 15022
779fe533 15023static int
2cf0635d 15024process_corefile_note_segment (FILE * file, bfd_vma offset, bfd_vma length)
779fe533 15025{
2cf0635d
NC
15026 Elf_External_Note * pnotes;
15027 Elf_External_Note * external;
b34976b6 15028 int res = 1;
103f02d3 15029
779fe533
NC
15030 if (length <= 0)
15031 return 0;
103f02d3 15032
3f5e193b 15033 pnotes = (Elf_External_Note *) get_data (NULL, file, offset, 1, length,
15b42fb0 15034 _("notes"));
dd24e3da 15035 if (pnotes == NULL)
a6e9f9df 15036 return 0;
779fe533 15037
103f02d3 15038 external = pnotes;
103f02d3 15039
9dd3a467 15040 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
f3485b74 15041 (unsigned long) offset, (unsigned long) length);
2aee03ae 15042 printf (_(" %-20s %10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 15043
15b42fb0 15044 while ((char *) external < (char *) pnotes + length)
779fe533 15045 {
b34976b6 15046 Elf_Internal_Note inote;
15b42fb0
AM
15047 size_t min_notesz;
15048 char *next;
2cf0635d 15049 char * temp = NULL;
15b42fb0 15050 size_t data_remaining = ((char *) pnotes + length) - (char *) external;
6d118b09 15051
00e98fc7 15052 if (!is_ia64_vms ())
15b42fb0 15053 {
9dd3a467
NC
15054 /* PR binutils/15191
15055 Make sure that there is enough data to read. */
15b42fb0
AM
15056 min_notesz = offsetof (Elf_External_Note, name);
15057 if (data_remaining < min_notesz)
9dd3a467
NC
15058 {
15059 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
15060 (int) data_remaining);
15061 break;
15062 }
15b42fb0
AM
15063 inote.type = BYTE_GET (external->type);
15064 inote.namesz = BYTE_GET (external->namesz);
15065 inote.namedata = external->name;
15066 inote.descsz = BYTE_GET (external->descsz);
15067 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
15068 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15069 next = inote.descdata + align_power (inote.descsz, 2);
15070 }
00e98fc7 15071 else
15b42fb0
AM
15072 {
15073 Elf64_External_VMS_Note *vms_external;
00e98fc7 15074
9dd3a467
NC
15075 /* PR binutils/15191
15076 Make sure that there is enough data to read. */
15b42fb0
AM
15077 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15078 if (data_remaining < min_notesz)
9dd3a467
NC
15079 {
15080 warn (_("Corrupt note: only %d bytes remain, not enough for a full note\n"),
15081 (int) data_remaining);
15082 break;
15083 }
3e55a963 15084
15b42fb0
AM
15085 vms_external = (Elf64_External_VMS_Note *) external;
15086 inote.type = BYTE_GET (vms_external->type);
15087 inote.namesz = BYTE_GET (vms_external->namesz);
15088 inote.namedata = vms_external->name;
15089 inote.descsz = BYTE_GET (vms_external->descsz);
15090 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15091 inote.descpos = offset + (inote.descdata - (char *) pnotes);
15092 next = inote.descdata + align_power (inote.descsz, 3);
15093 }
15094
15095 if (inote.descdata < (char *) external + min_notesz
15096 || next < (char *) external + min_notesz
5d921cbd
NC
15097 /* PR binutils/17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
15098 || inote.namedata + inote.namesz < inote.namedata
15099 || inote.descdata + inote.descsz < inote.descdata
15b42fb0 15100 || data_remaining < (size_t)(next - (char *) external))
3e55a963 15101 {
15b42fb0 15102 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 15103 (unsigned long) ((char *) external - (char *) pnotes));
9dd3a467 15104 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx\n"),
3e55a963
NC
15105 inote.type, inote.namesz, inote.descsz);
15106 break;
15107 }
15108
15b42fb0 15109 external = (Elf_External_Note *) next;
dd24e3da 15110
6d118b09
NC
15111 /* Verify that name is null terminated. It appears that at least
15112 one version of Linux (RedHat 6.0) generates corefiles that don't
15113 comply with the ELF spec by failing to include the null byte in
15114 namesz. */
8b971f9f 15115 if (inote.namedata[inote.namesz - 1] != '\0')
6d118b09 15116 {
3f5e193b 15117 temp = (char *) malloc (inote.namesz + 1);
6d118b09
NC
15118 if (temp == NULL)
15119 {
8b73c356 15120 error (_("Out of memory allocating space for inote name\n"));
6d118b09
NC
15121 res = 0;
15122 break;
15123 }
76da6bbe 15124
6d118b09
NC
15125 strncpy (temp, inote.namedata, inote.namesz);
15126 temp[inote.namesz] = 0;
76da6bbe 15127
6d118b09
NC
15128 /* warn (_("'%s' NOTE name not properly null terminated\n"), temp); */
15129 inote.namedata = temp;
15130 }
15131
15132 res &= process_note (& inote);
103f02d3 15133
6d118b09
NC
15134 if (temp != NULL)
15135 {
15136 free (temp);
15137 temp = NULL;
15138 }
779fe533
NC
15139 }
15140
15141 free (pnotes);
103f02d3 15142
779fe533
NC
15143 return res;
15144}
15145
15146static int
2cf0635d 15147process_corefile_note_segments (FILE * file)
779fe533 15148{
2cf0635d 15149 Elf_Internal_Phdr * segment;
b34976b6
AM
15150 unsigned int i;
15151 int res = 1;
103f02d3 15152
d93f0186 15153 if (! get_program_headers (file))
779fe533 15154 return 0;
103f02d3 15155
779fe533
NC
15156 for (i = 0, segment = program_headers;
15157 i < elf_header.e_phnum;
b34976b6 15158 i++, segment++)
779fe533
NC
15159 {
15160 if (segment->p_type == PT_NOTE)
103f02d3 15161 res &= process_corefile_note_segment (file,
30800947
NC
15162 (bfd_vma) segment->p_offset,
15163 (bfd_vma) segment->p_filesz);
779fe533 15164 }
103f02d3 15165
779fe533
NC
15166 return res;
15167}
15168
15169static int
2cf0635d 15170process_note_sections (FILE * file)
1ec5cd37 15171{
2cf0635d 15172 Elf_Internal_Shdr * section;
1ec5cd37 15173 unsigned long i;
df565f32 15174 int n = 0;
1ec5cd37
NC
15175 int res = 1;
15176
15177 for (i = 0, section = section_headers;
fa1908fd 15178 i < elf_header.e_shnum && section != NULL;
1ec5cd37
NC
15179 i++, section++)
15180 if (section->sh_type == SHT_NOTE)
df565f32
NC
15181 {
15182 res &= process_corefile_note_segment (file,
15183 (bfd_vma) section->sh_offset,
15184 (bfd_vma) section->sh_size);
15185 n++;
15186 }
15187
15188 if (n == 0)
15189 /* Try processing NOTE segments instead. */
15190 return process_corefile_note_segments (file);
1ec5cd37
NC
15191
15192 return res;
15193}
15194
15195static int
2cf0635d 15196process_notes (FILE * file)
779fe533
NC
15197{
15198 /* If we have not been asked to display the notes then do nothing. */
15199 if (! do_notes)
15200 return 1;
103f02d3 15201
779fe533 15202 if (elf_header.e_type != ET_CORE)
1ec5cd37 15203 return process_note_sections (file);
103f02d3 15204
779fe533 15205 /* No program headers means no NOTE segment. */
1ec5cd37
NC
15206 if (elf_header.e_phnum > 0)
15207 return process_corefile_note_segments (file);
779fe533 15208
1ec5cd37
NC
15209 printf (_("No note segments present in the core file.\n"));
15210 return 1;
779fe533
NC
15211}
15212
252b5132 15213static int
2cf0635d 15214process_arch_specific (FILE * file)
252b5132 15215{
a952a375
NC
15216 if (! do_arch)
15217 return 1;
15218
252b5132
RH
15219 switch (elf_header.e_machine)
15220 {
11c1ff18
PB
15221 case EM_ARM:
15222 return process_arm_specific (file);
252b5132 15223 case EM_MIPS:
4fe85591 15224 case EM_MIPS_RS3_LE:
252b5132
RH
15225 return process_mips_specific (file);
15226 break;
35c08157
KLC
15227 case EM_NDS32:
15228 return process_nds32_specific (file);
15229 break;
34c8bcba
JM
15230 case EM_PPC:
15231 return process_power_specific (file);
15232 break;
9e8c70f9
DM
15233 case EM_SPARC:
15234 case EM_SPARC32PLUS:
15235 case EM_SPARCV9:
15236 return process_sparc_specific (file);
15237 break;
59e6276b
JM
15238 case EM_TI_C6000:
15239 return process_tic6x_specific (file);
15240 break;
13761a11
NC
15241 case EM_MSP430:
15242 return process_msp430x_specific (file);
252b5132
RH
15243 default:
15244 break;
15245 }
15246 return 1;
15247}
15248
15249static int
2cf0635d 15250get_file_header (FILE * file)
252b5132 15251{
9ea033b2
NC
15252 /* Read in the identity array. */
15253 if (fread (elf_header.e_ident, EI_NIDENT, 1, file) != 1)
252b5132
RH
15254 return 0;
15255
9ea033b2 15256 /* Determine how to read the rest of the header. */
b34976b6 15257 switch (elf_header.e_ident[EI_DATA])
9ea033b2
NC
15258 {
15259 default: /* fall through */
15260 case ELFDATANONE: /* fall through */
adab8cdc
AO
15261 case ELFDATA2LSB:
15262 byte_get = byte_get_little_endian;
15263 byte_put = byte_put_little_endian;
15264 break;
15265 case ELFDATA2MSB:
15266 byte_get = byte_get_big_endian;
15267 byte_put = byte_put_big_endian;
15268 break;
9ea033b2
NC
15269 }
15270
15271 /* For now we only support 32 bit and 64 bit ELF files. */
b34976b6 15272 is_32bit_elf = (elf_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
15273
15274 /* Read in the rest of the header. */
15275 if (is_32bit_elf)
15276 {
15277 Elf32_External_Ehdr ehdr32;
252b5132 15278
9ea033b2
NC
15279 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, file) != 1)
15280 return 0;
103f02d3 15281
9ea033b2
NC
15282 elf_header.e_type = BYTE_GET (ehdr32.e_type);
15283 elf_header.e_machine = BYTE_GET (ehdr32.e_machine);
15284 elf_header.e_version = BYTE_GET (ehdr32.e_version);
15285 elf_header.e_entry = BYTE_GET (ehdr32.e_entry);
15286 elf_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
15287 elf_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
15288 elf_header.e_flags = BYTE_GET (ehdr32.e_flags);
15289 elf_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
15290 elf_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
15291 elf_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
15292 elf_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
15293 elf_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
15294 elf_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
15295 }
252b5132 15296 else
9ea033b2
NC
15297 {
15298 Elf64_External_Ehdr ehdr64;
a952a375
NC
15299
15300 /* If we have been compiled with sizeof (bfd_vma) == 4, then
15301 we will not be able to cope with the 64bit data found in
15302 64 ELF files. Detect this now and abort before we start
50c2245b 15303 overwriting things. */
a952a375
NC
15304 if (sizeof (bfd_vma) < 8)
15305 {
e3c8793a
NC
15306 error (_("This instance of readelf has been built without support for a\n\
1530764 bit data type and so it cannot read 64 bit ELF files.\n"));
a952a375
NC
15308 return 0;
15309 }
103f02d3 15310
9ea033b2
NC
15311 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, file) != 1)
15312 return 0;
103f02d3 15313
9ea033b2
NC
15314 elf_header.e_type = BYTE_GET (ehdr64.e_type);
15315 elf_header.e_machine = BYTE_GET (ehdr64.e_machine);
15316 elf_header.e_version = BYTE_GET (ehdr64.e_version);
66543521
AM
15317 elf_header.e_entry = BYTE_GET (ehdr64.e_entry);
15318 elf_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
15319 elf_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
9ea033b2
NC
15320 elf_header.e_flags = BYTE_GET (ehdr64.e_flags);
15321 elf_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
15322 elf_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
15323 elf_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
15324 elf_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
15325 elf_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
15326 elf_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
15327 }
252b5132 15328
7ece0d85
JJ
15329 if (elf_header.e_shoff)
15330 {
15331 /* There may be some extensions in the first section header. Don't
15332 bomb if we can't read it. */
15333 if (is_32bit_elf)
049b0c3a 15334 get_32bit_section_headers (file, TRUE);
7ece0d85 15335 else
049b0c3a 15336 get_64bit_section_headers (file, TRUE);
7ece0d85 15337 }
560f3c1c 15338
252b5132
RH
15339 return 1;
15340}
15341
fb52b2f4
NC
15342/* Process one ELF object file according to the command line options.
15343 This file may actually be stored in an archive. The file is
15344 positioned at the start of the ELF object. */
15345
ff78d6d6 15346static int
2cf0635d 15347process_object (char * file_name, FILE * file)
252b5132 15348{
252b5132
RH
15349 unsigned int i;
15350
252b5132
RH
15351 if (! get_file_header (file))
15352 {
15353 error (_("%s: Failed to read file header\n"), file_name);
ff78d6d6 15354 return 1;
252b5132
RH
15355 }
15356
15357 /* Initialise per file variables. */
60bca95a 15358 for (i = ARRAY_SIZE (version_info); i--;)
252b5132
RH
15359 version_info[i] = 0;
15360
60bca95a 15361 for (i = ARRAY_SIZE (dynamic_info); i--;)
252b5132 15362 dynamic_info[i] = 0;
5115b233 15363 dynamic_info_DT_GNU_HASH = 0;
252b5132
RH
15364
15365 /* Process the file. */
15366 if (show_name)
15367 printf (_("\nFile: %s\n"), file_name);
15368
18bd398b
NC
15369 /* Initialise the dump_sects array from the cmdline_dump_sects array.
15370 Note we do this even if cmdline_dump_sects is empty because we
15371 must make sure that the dump_sets array is zeroed out before each
15372 object file is processed. */
15373 if (num_dump_sects > num_cmdline_dump_sects)
09c11c86 15374 memset (dump_sects, 0, num_dump_sects * sizeof (* dump_sects));
18bd398b
NC
15375
15376 if (num_cmdline_dump_sects > 0)
15377 {
15378 if (num_dump_sects == 0)
15379 /* A sneaky way of allocating the dump_sects array. */
09c11c86 15380 request_dump_bynumber (num_cmdline_dump_sects, 0);
18bd398b
NC
15381
15382 assert (num_dump_sects >= num_cmdline_dump_sects);
09c11c86
NC
15383 memcpy (dump_sects, cmdline_dump_sects,
15384 num_cmdline_dump_sects * sizeof (* dump_sects));
18bd398b 15385 }
d70c5fc7 15386
252b5132 15387 if (! process_file_header ())
fb52b2f4 15388 return 1;
252b5132 15389
d1f5c6e3 15390 if (! process_section_headers (file))
2f62977e 15391 {
d1f5c6e3
L
15392 /* Without loaded section headers we cannot process lots of
15393 things. */
2f62977e 15394 do_unwind = do_version = do_dump = do_arch = 0;
252b5132 15395
2f62977e 15396 if (! do_using_dynamic)
2c610e4b 15397 do_syms = do_dyn_syms = do_reloc = 0;
2f62977e 15398 }
252b5132 15399
d1f5c6e3
L
15400 if (! process_section_groups (file))
15401 {
15402 /* Without loaded section groups we cannot process unwind. */
15403 do_unwind = 0;
15404 }
15405
2f62977e 15406 if (process_program_headers (file))
b2d38a17 15407 process_dynamic_section (file);
252b5132
RH
15408
15409 process_relocs (file);
15410
4d6ed7c8
NC
15411 process_unwind (file);
15412
252b5132
RH
15413 process_symbol_table (file);
15414
15415 process_syminfo (file);
15416
15417 process_version_sections (file);
15418
15419 process_section_contents (file);
f5842774 15420
1ec5cd37 15421 process_notes (file);
103f02d3 15422
047b2264
JJ
15423 process_gnu_liblist (file);
15424
252b5132
RH
15425 process_arch_specific (file);
15426
d93f0186
NC
15427 if (program_headers)
15428 {
15429 free (program_headers);
15430 program_headers = NULL;
15431 }
15432
252b5132
RH
15433 if (section_headers)
15434 {
15435 free (section_headers);
15436 section_headers = NULL;
15437 }
15438
15439 if (string_table)
15440 {
15441 free (string_table);
15442 string_table = NULL;
d40ac9bd 15443 string_table_length = 0;
252b5132
RH
15444 }
15445
15446 if (dynamic_strings)
15447 {
15448 free (dynamic_strings);
15449 dynamic_strings = NULL;
d79b3d50 15450 dynamic_strings_length = 0;
252b5132
RH
15451 }
15452
15453 if (dynamic_symbols)
15454 {
15455 free (dynamic_symbols);
15456 dynamic_symbols = NULL;
19936277 15457 num_dynamic_syms = 0;
252b5132
RH
15458 }
15459
15460 if (dynamic_syminfo)
15461 {
15462 free (dynamic_syminfo);
15463 dynamic_syminfo = NULL;
15464 }
ff78d6d6 15465
293c573e
MR
15466 if (dynamic_section)
15467 {
15468 free (dynamic_section);
15469 dynamic_section = NULL;
15470 }
15471
e4b17d5c
L
15472 if (section_headers_groups)
15473 {
15474 free (section_headers_groups);
15475 section_headers_groups = NULL;
15476 }
15477
15478 if (section_groups)
15479 {
2cf0635d
NC
15480 struct group_list * g;
15481 struct group_list * next;
e4b17d5c
L
15482
15483 for (i = 0; i < group_count; i++)
15484 {
15485 for (g = section_groups [i].root; g != NULL; g = next)
15486 {
15487 next = g->next;
15488 free (g);
15489 }
15490 }
15491
15492 free (section_groups);
15493 section_groups = NULL;
15494 }
15495
19e6b90e 15496 free_debug_memory ();
18bd398b 15497
ff78d6d6 15498 return 0;
252b5132
RH
15499}
15500
2cf0635d
NC
15501/* Process an ELF archive.
15502 On entry the file is positioned just after the ARMAG string. */
15503
15504static int
15505process_archive (char * file_name, FILE * file, bfd_boolean is_thin_archive)
15506{
15507 struct archive_info arch;
15508 struct archive_info nested_arch;
15509 size_t got;
2cf0635d
NC
15510 int ret;
15511
15512 show_name = 1;
15513
15514 /* The ARCH structure is used to hold information about this archive. */
15515 arch.file_name = NULL;
15516 arch.file = NULL;
15517 arch.index_array = NULL;
15518 arch.sym_table = NULL;
15519 arch.longnames = NULL;
15520
15521 /* The NESTED_ARCH structure is used as a single-item cache of information
15522 about a nested archive (when members of a thin archive reside within
15523 another regular archive file). */
15524 nested_arch.file_name = NULL;
15525 nested_arch.file = NULL;
15526 nested_arch.index_array = NULL;
15527 nested_arch.sym_table = NULL;
15528 nested_arch.longnames = NULL;
15529
15530 if (setup_archive (&arch, file_name, file, is_thin_archive, do_archive_index) != 0)
15531 {
15532 ret = 1;
15533 goto out;
4145f1d5 15534 }
fb52b2f4 15535
4145f1d5
NC
15536 if (do_archive_index)
15537 {
2cf0635d 15538 if (arch.sym_table == NULL)
4145f1d5
NC
15539 error (_("%s: unable to dump the index as none was found\n"), file_name);
15540 else
15541 {
591f7597 15542 unsigned long i, l;
4145f1d5
NC
15543 unsigned long current_pos;
15544
591f7597
NC
15545 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes in the symbol table)\n"),
15546 file_name, (unsigned long) arch.index_num, arch.sym_size);
4145f1d5
NC
15547 current_pos = ftell (file);
15548
2cf0635d 15549 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 15550 {
2cf0635d
NC
15551 if ((i == 0) || ((i > 0) && (arch.index_array[i] != arch.index_array[i - 1])))
15552 {
15553 char * member_name;
4145f1d5 15554
2cf0635d
NC
15555 member_name = get_archive_member_name_at (&arch, arch.index_array[i], &nested_arch);
15556
15557 if (member_name != NULL)
15558 {
15559 char * qualified_name = make_qualified_name (&arch, &nested_arch, member_name);
15560
15561 if (qualified_name != NULL)
15562 {
c2a7d3f5
NC
15563 printf (_("Contents of binary %s at offset "), qualified_name);
15564 (void) print_vma (arch.index_array[i], PREFIX_HEX);
15565 putchar ('\n');
2cf0635d
NC
15566 free (qualified_name);
15567 }
4145f1d5
NC
15568 }
15569 }
2cf0635d
NC
15570
15571 if (l >= arch.sym_size)
4145f1d5
NC
15572 {
15573 error (_("%s: end of the symbol table reached before the end of the index\n"),
15574 file_name);
cb8f3167 15575 break;
4145f1d5 15576 }
591f7597
NC
15577 /* PR 17531: file: 0b6630b2. */
15578 printf ("\t%.*s\n", (int) (arch.sym_size - l), arch.sym_table + l);
15579 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
15580 }
15581
c2a7d3f5
NC
15582 if (arch.uses_64bit_indicies)
15583 l = (l + 7) & ~ 7;
15584 else
15585 l += l & 1;
15586
2cf0635d 15587 if (l < arch.sym_size)
c2a7d3f5
NC
15588 error (_("%s: %ld bytes remain in the symbol table, but without corresponding entries in the index table\n"),
15589 file_name, arch.sym_size - l);
4145f1d5 15590
4145f1d5
NC
15591 if (fseek (file, current_pos, SEEK_SET) != 0)
15592 {
15593 error (_("%s: failed to seek back to start of object files in the archive\n"), file_name);
2cf0635d
NC
15594 ret = 1;
15595 goto out;
4145f1d5 15596 }
fb52b2f4 15597 }
4145f1d5
NC
15598
15599 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
15600 && !do_segments && !do_header && !do_dump && !do_version
15601 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 15602 && !do_section_groups && !do_dyn_syms)
2cf0635d
NC
15603 {
15604 ret = 0; /* Archive index only. */
15605 goto out;
15606 }
fb52b2f4
NC
15607 }
15608
d989285c 15609 ret = 0;
fb52b2f4
NC
15610
15611 while (1)
15612 {
2cf0635d
NC
15613 char * name;
15614 size_t namelen;
15615 char * qualified_name;
15616
15617 /* Read the next archive header. */
15618 if (fseek (file, arch.next_arhdr_offset, SEEK_SET) != 0)
15619 {
15620 error (_("%s: failed to seek to next archive header\n"), file_name);
15621 return 1;
15622 }
15623 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, file);
15624 if (got != sizeof arch.arhdr)
15625 {
15626 if (got == 0)
15627 break;
15628 error (_("%s: failed to read archive header\n"), file_name);
15629 ret = 1;
15630 break;
15631 }
15632 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
15633 {
15634 error (_("%s: did not find a valid archive header\n"), arch.file_name);
15635 ret = 1;
15636 break;
15637 }
15638
15639 arch.next_arhdr_offset += sizeof arch.arhdr;
15640
15641 archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
15642 if (archive_file_size & 01)
15643 ++archive_file_size;
15644
15645 name = get_archive_member_name (&arch, &nested_arch);
15646 if (name == NULL)
fb52b2f4 15647 {
0fd3a477 15648 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15649 ret = 1;
15650 break;
fb52b2f4 15651 }
2cf0635d 15652 namelen = strlen (name);
fb52b2f4 15653
2cf0635d
NC
15654 qualified_name = make_qualified_name (&arch, &nested_arch, name);
15655 if (qualified_name == NULL)
fb52b2f4 15656 {
2cf0635d 15657 error (_("%s: bad archive file name\n"), file_name);
d989285c
ILT
15658 ret = 1;
15659 break;
fb52b2f4
NC
15660 }
15661
2cf0635d
NC
15662 if (is_thin_archive && arch.nested_member_origin == 0)
15663 {
15664 /* This is a proxy for an external member of a thin archive. */
15665 FILE * member_file;
15666 char * member_file_name = adjust_relative_path (file_name, name, namelen);
15667 if (member_file_name == NULL)
15668 {
15669 ret = 1;
15670 break;
15671 }
15672
15673 member_file = fopen (member_file_name, "rb");
15674 if (member_file == NULL)
15675 {
15676 error (_("Input file '%s' is not readable.\n"), member_file_name);
15677 free (member_file_name);
15678 ret = 1;
15679 break;
15680 }
15681
15682 archive_file_offset = arch.nested_member_origin;
15683
15684 ret |= process_object (qualified_name, member_file);
15685
15686 fclose (member_file);
15687 free (member_file_name);
15688 }
15689 else if (is_thin_archive)
15690 {
a043396b
NC
15691 /* PR 15140: Allow for corrupt thin archives. */
15692 if (nested_arch.file == NULL)
15693 {
15694 error (_("%s: contains corrupt thin archive: %s\n"),
15695 file_name, name);
15696 ret = 1;
15697 break;
15698 }
15699
2cf0635d
NC
15700 /* This is a proxy for a member of a nested archive. */
15701 archive_file_offset = arch.nested_member_origin + sizeof arch.arhdr;
15702
15703 /* The nested archive file will have been opened and setup by
15704 get_archive_member_name. */
15705 if (fseek (nested_arch.file, archive_file_offset, SEEK_SET) != 0)
15706 {
15707 error (_("%s: failed to seek to archive member.\n"), nested_arch.file_name);
15708 ret = 1;
15709 break;
15710 }
15711
15712 ret |= process_object (qualified_name, nested_arch.file);
15713 }
15714 else
15715 {
15716 archive_file_offset = arch.next_arhdr_offset;
15717 arch.next_arhdr_offset += archive_file_size;
fb52b2f4 15718
2cf0635d
NC
15719 ret |= process_object (qualified_name, file);
15720 }
fb52b2f4 15721
2b52916e
L
15722 if (dump_sects != NULL)
15723 {
15724 free (dump_sects);
15725 dump_sects = NULL;
15726 num_dump_sects = 0;
15727 }
15728
2cf0635d 15729 free (qualified_name);
fb52b2f4
NC
15730 }
15731
4145f1d5 15732 out:
2cf0635d
NC
15733 if (nested_arch.file != NULL)
15734 fclose (nested_arch.file);
15735 release_archive (&nested_arch);
15736 release_archive (&arch);
fb52b2f4 15737
d989285c 15738 return ret;
fb52b2f4
NC
15739}
15740
15741static int
2cf0635d 15742process_file (char * file_name)
fb52b2f4 15743{
2cf0635d 15744 FILE * file;
fb52b2f4
NC
15745 struct stat statbuf;
15746 char armag[SARMAG];
15747 int ret;
15748
15749 if (stat (file_name, &statbuf) < 0)
15750 {
f24ddbdd
NC
15751 if (errno == ENOENT)
15752 error (_("'%s': No such file\n"), file_name);
15753 else
15754 error (_("Could not locate '%s'. System error message: %s\n"),
15755 file_name, strerror (errno));
15756 return 1;
15757 }
15758
15759 if (! S_ISREG (statbuf.st_mode))
15760 {
15761 error (_("'%s' is not an ordinary file\n"), file_name);
fb52b2f4
NC
15762 return 1;
15763 }
15764
15765 file = fopen (file_name, "rb");
15766 if (file == NULL)
15767 {
f24ddbdd 15768 error (_("Input file '%s' is not readable.\n"), file_name);
fb52b2f4
NC
15769 return 1;
15770 }
15771
15772 if (fread (armag, SARMAG, 1, file) != 1)
15773 {
4145f1d5 15774 error (_("%s: Failed to read file's magic number\n"), file_name);
fb52b2f4
NC
15775 fclose (file);
15776 return 1;
15777 }
15778
f54498b4
NC
15779 current_file_size = (bfd_size_type) statbuf.st_size;
15780
fb52b2f4 15781 if (memcmp (armag, ARMAG, SARMAG) == 0)
2cf0635d
NC
15782 ret = process_archive (file_name, file, FALSE);
15783 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
15784 ret = process_archive (file_name, file, TRUE);
fb52b2f4
NC
15785 else
15786 {
4145f1d5
NC
15787 if (do_archive_index)
15788 error (_("File %s is not an archive so its index cannot be displayed.\n"),
15789 file_name);
15790
fb52b2f4
NC
15791 rewind (file);
15792 archive_file_size = archive_file_offset = 0;
15793 ret = process_object (file_name, file);
15794 }
15795
15796 fclose (file);
15797
f54498b4 15798 current_file_size = 0;
fb52b2f4
NC
15799 return ret;
15800}
15801
252b5132
RH
15802#ifdef SUPPORT_DISASSEMBLY
15803/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 15804 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 15805 symbols. */
252b5132
RH
15806
15807void
2cf0635d 15808print_address (unsigned int addr, FILE * outfile)
252b5132
RH
15809{
15810 fprintf (outfile,"0x%8.8x", addr);
15811}
15812
e3c8793a 15813/* Needed by the i386 disassembler. */
252b5132
RH
15814void
15815db_task_printsym (unsigned int addr)
15816{
15817 print_address (addr, stderr);
15818}
15819#endif
15820
15821int
2cf0635d 15822main (int argc, char ** argv)
252b5132 15823{
ff78d6d6
L
15824 int err;
15825
252b5132
RH
15826#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
15827 setlocale (LC_MESSAGES, "");
3882b010
L
15828#endif
15829#if defined (HAVE_SETLOCALE)
15830 setlocale (LC_CTYPE, "");
252b5132
RH
15831#endif
15832 bindtextdomain (PACKAGE, LOCALEDIR);
15833 textdomain (PACKAGE);
15834
869b9d07
MM
15835 expandargv (&argc, &argv);
15836
252b5132
RH
15837 parse_args (argc, argv);
15838
18bd398b 15839 if (num_dump_sects > 0)
59f14fc0 15840 {
18bd398b 15841 /* Make a copy of the dump_sects array. */
3f5e193b
NC
15842 cmdline_dump_sects = (dump_type *)
15843 malloc (num_dump_sects * sizeof (* dump_sects));
59f14fc0 15844 if (cmdline_dump_sects == NULL)
591a748a 15845 error (_("Out of memory allocating dump request table.\n"));
59f14fc0
AS
15846 else
15847 {
09c11c86
NC
15848 memcpy (cmdline_dump_sects, dump_sects,
15849 num_dump_sects * sizeof (* dump_sects));
59f14fc0
AS
15850 num_cmdline_dump_sects = num_dump_sects;
15851 }
15852 }
15853
18bd398b
NC
15854 if (optind < (argc - 1))
15855 show_name = 1;
15856
ff78d6d6 15857 err = 0;
252b5132 15858 while (optind < argc)
18bd398b 15859 err |= process_file (argv[optind++]);
252b5132
RH
15860
15861 if (dump_sects != NULL)
15862 free (dump_sects);
59f14fc0
AS
15863 if (cmdline_dump_sects != NULL)
15864 free (cmdline_dump_sects);
252b5132 15865
ff78d6d6 15866 return err;
252b5132 15867}
This page took 2.120468 seconds and 4 git commands to generate.