libctf, binutils: initial work towards libctf gettextization
[deliverable/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
b3adc24a 2 Copyright (C) 1998-2020 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
3bfcb652 47#ifdef HAVE_WCHAR_H
7bfd842d 48#include <wchar.h>
3bfcb652 49#endif
252b5132 50
a952a375 51#if __GNUC__ >= 2
19936277 52/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 53 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 54 Only do this if we believe that the compiler can support a 64 bit
a952a375 55 data type. For now we only rely on GCC being able to do this. */
19936277 56#define BFD64
a952a375
NC
57#endif
58
3db64b00
AM
59#include "bfd.h"
60#include "bucomm.h"
3284fe0c 61#include "elfcomm.h"
19e6b90e 62#include "dwarf.h"
7d9813f1 63#include "ctf-api.h"
79bc120c 64#include "demangle.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"
b8891f8d 103#include "elf/csky.h"
252b5132
RH
104#include "elf/d10v.h"
105#include "elf/d30v.h"
d172d4ba 106#include "elf/dlx.h"
aca4efc7 107#include "elf/bpf.h"
cfb8c092 108#include "elf/epiphany.h"
252b5132 109#include "elf/fr30.h"
5c70f934 110#include "elf/frv.h"
3f8107ab 111#include "elf/ft32.h"
3b16e843
NC
112#include "elf/h8.h"
113#include "elf/hppa.h"
114#include "elf/i386.h"
f954747f
AM
115#include "elf/i370.h"
116#include "elf/i860.h"
117#include "elf/i960.h"
3b16e843 118#include "elf/ia64.h"
1e4cf259 119#include "elf/ip2k.h"
84e94c90 120#include "elf/lm32.h"
1c0d3aa6 121#include "elf/iq2000.h"
49f58d10 122#include "elf/m32c.h"
3b16e843
NC
123#include "elf/m32r.h"
124#include "elf/m68k.h"
75751cd9 125#include "elf/m68hc11.h"
7b4ae824 126#include "elf/s12z.h"
252b5132 127#include "elf/mcore.h"
15ab5209 128#include "elf/mep.h"
a3c62988 129#include "elf/metag.h"
7ba29e2a 130#include "elf/microblaze.h"
3b16e843 131#include "elf/mips.h"
3c3bdf30 132#include "elf/mmix.h"
3b16e843
NC
133#include "elf/mn10200.h"
134#include "elf/mn10300.h"
5506d11a 135#include "elf/moxie.h"
4970f871 136#include "elf/mt.h"
2469cfa2 137#include "elf/msp430.h"
35c08157 138#include "elf/nds32.h"
fe944acf 139#include "elf/nfp.h"
13761a11 140#include "elf/nios2.h"
73589c9d 141#include "elf/or1k.h"
7d466069 142#include "elf/pj.h"
3b16e843 143#include "elf/ppc.h"
c833c019 144#include "elf/ppc64.h"
2b100bb5 145#include "elf/pru.h"
03336641 146#include "elf/riscv.h"
99c513f6 147#include "elf/rl78.h"
c7927a3c 148#include "elf/rx.h"
a85d7ed0 149#include "elf/s390.h"
1c0d3aa6 150#include "elf/score.h"
3b16e843
NC
151#include "elf/sh.h"
152#include "elf/sparc.h"
e9f53129 153#include "elf/spu.h"
40b36596 154#include "elf/tic6x.h"
aa137e4d
NC
155#include "elf/tilegx.h"
156#include "elf/tilepro.h"
3b16e843 157#include "elf/v850.h"
179d3252 158#include "elf/vax.h"
619ed720 159#include "elf/visium.h"
f96bd6c2 160#include "elf/wasm32.h"
3b16e843 161#include "elf/x86-64.h"
c29aca4a 162#include "elf/xc16x.h"
f6c1a2d5 163#include "elf/xgate.h"
93fbbb04 164#include "elf/xstormy16.h"
88da6820 165#include "elf/xtensa.h"
6655dba2 166#include "elf/z80.h"
252b5132 167
252b5132 168#include "getopt.h"
566b0d53 169#include "libiberty.h"
09c11c86 170#include "safe-ctype.h"
2cf0635d 171#include "filenames.h"
252b5132 172
15b42fb0
AM
173#ifndef offsetof
174#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
175#endif
176
6a40cf0c
NC
177typedef struct elf_section_list
178{
dda8d76d
NC
179 Elf_Internal_Shdr * hdr;
180 struct elf_section_list * next;
6a40cf0c
NC
181} elf_section_list;
182
dda8d76d
NC
183/* Flag bits indicating particular types of dump. */
184#define HEX_DUMP (1 << 0) /* The -x command line switch. */
185#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
186#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
187#define STRING_DUMP (1 << 3) /* The -p command line switch. */
188#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 189#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
190
191typedef unsigned char dump_type;
192
193/* A linked list of the section names for which dumps were requested. */
194struct dump_list_entry
195{
196 char * name;
197 dump_type type;
198 struct dump_list_entry * next;
199};
200
6431e409
AM
201/* A dynamic array of flags indicating for which sections a dump
202 has been requested via command line switches. */
1b513401
NC
203struct dump_data
204{
6431e409
AM
205 dump_type * dump_sects;
206 unsigned int num_dump_sects;
207};
208
209static struct dump_data cmdline;
210
211static struct dump_list_entry * dump_sects_byname;
212
2cf0635d 213char * program_name = "readelf";
dda8d76d 214
32ec8896
NC
215static bfd_boolean show_name = FALSE;
216static bfd_boolean do_dynamic = FALSE;
217static bfd_boolean do_syms = FALSE;
218static bfd_boolean do_dyn_syms = FALSE;
219static bfd_boolean do_reloc = FALSE;
220static bfd_boolean do_sections = FALSE;
221static bfd_boolean do_section_groups = FALSE;
222static bfd_boolean do_section_details = FALSE;
223static bfd_boolean do_segments = FALSE;
224static bfd_boolean do_unwind = FALSE;
225static bfd_boolean do_using_dynamic = FALSE;
226static bfd_boolean do_header = FALSE;
227static bfd_boolean do_dump = FALSE;
228static bfd_boolean do_version = FALSE;
229static bfd_boolean do_histogram = FALSE;
230static bfd_boolean do_debugging = FALSE;
7d9813f1 231static bfd_boolean do_ctf = FALSE;
32ec8896
NC
232static bfd_boolean do_arch = FALSE;
233static bfd_boolean do_notes = FALSE;
234static bfd_boolean do_archive_index = FALSE;
1b513401 235static bfd_boolean check_all = FALSE;
32ec8896
NC
236static bfd_boolean is_32bit_elf = FALSE;
237static bfd_boolean decompress_dumps = FALSE;
0942c7ab 238static bfd_boolean do_not_show_symbol_truncation = FALSE;
79bc120c
NC
239static bfd_boolean do_demangle = FALSE; /* Pretty print C++ symbol names. */
240static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
252b5132 241
7d9813f1
NA
242static char *dump_ctf_parent_name;
243static char *dump_ctf_symtab_name;
244static char *dump_ctf_strtab_name;
245
e4b17d5c
L
246struct group_list
247{
dda8d76d
NC
248 struct group_list * next;
249 unsigned int section_index;
e4b17d5c
L
250};
251
252struct group
253{
dda8d76d
NC
254 struct group_list * root;
255 unsigned int group_index;
e4b17d5c
L
256};
257
978c4450
AM
258typedef struct filedata
259{
260 const char * file_name;
261 FILE * handle;
262 bfd_size_type file_size;
263 Elf_Internal_Ehdr file_header;
264 Elf_Internal_Shdr * section_headers;
265 Elf_Internal_Phdr * program_headers;
266 char * string_table;
267 unsigned long string_table_length;
268 unsigned long archive_file_offset;
269 unsigned long archive_file_size;
270 unsigned long dynamic_addr;
271 bfd_size_type dynamic_size;
272 size_t dynamic_nent;
273 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 274 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
275 char * dynamic_strings;
276 unsigned long dynamic_strings_length;
8ac10c5b 277 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
278 unsigned long num_dynamic_syms;
279 Elf_Internal_Sym * dynamic_symbols;
280 bfd_vma version_info[16];
281 unsigned int dynamic_syminfo_nent;
282 Elf_Internal_Syminfo * dynamic_syminfo;
283 unsigned long dynamic_syminfo_offset;
284 bfd_size_type nbuckets;
285 bfd_size_type nchains;
286 bfd_vma * buckets;
287 bfd_vma * chains;
288 bfd_size_type ngnubuckets;
289 bfd_size_type ngnuchains;
290 bfd_vma * gnubuckets;
291 bfd_vma * gnuchains;
292 bfd_vma * mipsxlat;
293 bfd_vma gnusymidx;
294 char program_interpreter[PATH_MAX];
295 bfd_vma dynamic_info[DT_ENCODING];
296 bfd_vma dynamic_info_DT_GNU_HASH;
297 bfd_vma dynamic_info_DT_MIPS_XHASH;
298 elf_section_list * symtab_shndx_list;
299 size_t group_count;
300 struct group * section_groups;
301 struct group ** section_headers_groups;
302 /* A dynamic array of flags indicating for which sections a dump of
303 some kind has been requested. It is reset on a per-object file
304 basis and then initialised from the cmdline_dump_sects array,
305 the results of interpreting the -w switch, and the
306 dump_sects_byname list. */
307 struct dump_data dump;
308} Filedata;
aef1f6d0 309
c256ffe7 310/* How to print a vma value. */
843dd992
NC
311typedef enum print_mode
312{
313 HEX,
314 DEC,
315 DEC_5,
316 UNSIGNED,
317 PREFIX_HEX,
318 FULL_HEX,
319 LONG_HEX
320}
321print_mode;
322
bb4d2ac2
L
323/* Versioned symbol info. */
324enum versioned_symbol_info
325{
326 symbol_undefined,
327 symbol_hidden,
328 symbol_public
329};
330
32ec8896 331static const char * get_symbol_version_string
dda8d76d 332 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 333 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 334
9c19a809
NC
335#define UNKNOWN -1
336
2b692964
NC
337#define SECTION_NAME(X) \
338 ((X) == NULL ? _("<none>") \
dda8d76d
NC
339 : filedata->string_table == NULL ? _("<no-strings>") \
340 : ((X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
341 : filedata->string_table + (X)->sh_name))
252b5132 342
ee42cf8c 343#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 344
ba5cdace
NC
345#define GET_ELF_SYMBOLS(file, section, sym_count) \
346 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
347 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 348
10ca4b04
L
349#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
350 (strtab != NULL && offset < strtab_size)
978c4450
AM
351#define VALID_DYNAMIC_NAME(filedata, offset) \
352 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
353 filedata->dynamic_strings_length, offset)
d79b3d50
NC
354/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
355 already been called and verified that the string exists. */
978c4450
AM
356#define GET_DYNAMIC_NAME(filedata, offset) \
357 (filedata->dynamic_strings + offset)
18bd398b 358
61865e30
NC
359#define REMOVE_ARCH_BITS(ADDR) \
360 do \
361 { \
dda8d76d 362 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
363 (ADDR) &= ~1; \
364 } \
365 while (0)
f16a9783
MS
366
367/* Get the correct GNU hash section name. */
978c4450
AM
368#define GNU_HASH_SECTION_NAME(filedata) \
369 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 370\f
66cfc0fd
AM
371/* Print a BFD_VMA to an internal buffer, for use in error messages.
372 BFD_FMA_FMT can't be used in translated strings. */
373
374static const char *
375bfd_vmatoa (char *fmtch, bfd_vma value)
376{
377 /* bfd_vmatoa is used more then once in a printf call for output.
378 Cycle through an array of buffers. */
379 static int buf_pos = 0;
380 static struct bfd_vmatoa_buf
381 {
382 char place[64];
383 } buf[4];
384 char *ret;
385 char fmt[32];
386
387 ret = buf[buf_pos++].place;
388 buf_pos %= ARRAY_SIZE (buf);
389
390 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
391 snprintf (ret, sizeof (buf[0].place), fmt, value);
392 return ret;
393}
394
dda8d76d
NC
395/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
396 OFFSET + the offset of the current archive member, if we are examining an
397 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
398 allocate a buffer using malloc and fill that. In either case return the
399 pointer to the start of the retrieved data or NULL if something went wrong.
400 If something does go wrong and REASON is not NULL then emit an error
401 message using REASON as part of the context. */
59245841 402
c256ffe7 403static void *
dda8d76d
NC
404get_data (void * var,
405 Filedata * filedata,
406 unsigned long offset,
407 bfd_size_type size,
408 bfd_size_type nmemb,
409 const char * reason)
a6e9f9df 410{
2cf0635d 411 void * mvar;
57028622 412 bfd_size_type amt = size * nmemb;
a6e9f9df 413
c256ffe7 414 if (size == 0 || nmemb == 0)
a6e9f9df
AM
415 return NULL;
416
57028622
NC
417 /* If the size_t type is smaller than the bfd_size_type, eg because
418 you are building a 32-bit tool on a 64-bit host, then make sure
419 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
420 if ((size_t) size != size
421 || (size_t) nmemb != nmemb
422 || (size_t) amt != amt)
57028622
NC
423 {
424 if (reason)
66cfc0fd
AM
425 error (_("Size truncation prevents reading %s"
426 " elements of size %s for %s\n"),
427 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
428 return NULL;
429 }
430
431 /* Check for size overflow. */
7c1c1904 432 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
433 {
434 if (reason)
66cfc0fd
AM
435 error (_("Size overflow prevents reading %s"
436 " elements of size %s for %s\n"),
437 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
438 return NULL;
439 }
440
c22b42ce 441 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 442 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
443 if (filedata->archive_file_offset > filedata->file_size
444 || offset > filedata->file_size - filedata->archive_file_offset
445 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 446 {
049b0c3a 447 if (reason)
66cfc0fd
AM
448 error (_("Reading %s bytes extends past end of file for %s\n"),
449 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
450 return NULL;
451 }
452
978c4450
AM
453 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
454 SEEK_SET))
071436c6
NC
455 {
456 if (reason)
c9c1d674 457 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 458 filedata->archive_file_offset + offset, reason);
071436c6
NC
459 return NULL;
460 }
461
a6e9f9df
AM
462 mvar = var;
463 if (mvar == NULL)
464 {
7c1c1904
AM
465 /* + 1 so that we can '\0' terminate invalid string table sections. */
466 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
467
468 if (mvar == NULL)
469 {
049b0c3a 470 if (reason)
66cfc0fd
AM
471 error (_("Out of memory allocating %s bytes for %s\n"),
472 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
473 return NULL;
474 }
c256ffe7 475
c9c1d674 476 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
477 }
478
dda8d76d 479 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 480 {
049b0c3a 481 if (reason)
66cfc0fd
AM
482 error (_("Unable to read in %s bytes of %s\n"),
483 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
484 if (mvar != var)
485 free (mvar);
486 return NULL;
487 }
488
489 return mvar;
490}
491
32ec8896
NC
492/* Print a VMA value in the MODE specified.
493 Returns the number of characters displayed. */
cb8f3167 494
32ec8896 495static unsigned int
14a91970 496print_vma (bfd_vma vma, print_mode mode)
66543521 497{
32ec8896 498 unsigned int nc = 0;
66543521 499
14a91970 500 switch (mode)
66543521 501 {
14a91970
AM
502 case FULL_HEX:
503 nc = printf ("0x");
1a0670f3 504 /* Fall through. */
14a91970 505 case LONG_HEX:
f7a99963 506#ifdef BFD64
14a91970 507 if (is_32bit_elf)
437c2fb7 508 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 509#endif
14a91970
AM
510 printf_vma (vma);
511 return nc + 16;
b19aac67 512
14a91970
AM
513 case DEC_5:
514 if (vma <= 99999)
515 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 516 /* Fall through. */
14a91970
AM
517 case PREFIX_HEX:
518 nc = printf ("0x");
1a0670f3 519 /* Fall through. */
14a91970
AM
520 case HEX:
521 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 522
14a91970
AM
523 case DEC:
524 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 525
14a91970
AM
526 case UNSIGNED:
527 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
528
529 default:
530 /* FIXME: Report unrecognised mode ? */
531 return 0;
f7a99963 532 }
f7a99963
NC
533}
534
7bfd842d 535/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 536 multibye characters (assuming the host environment supports them).
31104126 537
7bfd842d
NC
538 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
539
0942c7ab
NC
540 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
541 abs(WIDTH) - 5 characters followed by "[...]".
542
7bfd842d
NC
543 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
544 padding as necessary.
171191ba
NC
545
546 Returns the number of emitted characters. */
547
548static unsigned int
0942c7ab 549print_symbol (signed int width, const char * symbol)
31104126 550{
171191ba 551 bfd_boolean extra_padding = FALSE;
0942c7ab 552 bfd_boolean do_dots = FALSE;
32ec8896 553 signed int num_printed = 0;
3bfcb652 554#ifdef HAVE_MBSTATE_T
7bfd842d 555 mbstate_t state;
3bfcb652 556#endif
32ec8896 557 unsigned int width_remaining;
79bc120c 558 const void * alloced_symbol = NULL;
961c521f 559
7bfd842d 560 if (width < 0)
961c521f 561 {
88305e1b 562 /* Keep the width positive. This helps the code below. */
961c521f 563 width = - width;
171191ba 564 extra_padding = TRUE;
0b4362b0 565 }
56d8f8a9
NC
566 else if (width == 0)
567 return 0;
961c521f 568
7bfd842d
NC
569 if (do_wide)
570 /* Set the remaining width to a very large value.
571 This simplifies the code below. */
572 width_remaining = INT_MAX;
573 else
0942c7ab
NC
574 {
575 width_remaining = width;
576 if (! do_not_show_symbol_truncation
577 && (int) strlen (symbol) > width)
578 {
579 width_remaining -= 5;
580 if ((int) width_remaining < 0)
581 width_remaining = 0;
582 do_dots = TRUE;
583 }
584 }
cb8f3167 585
3bfcb652 586#ifdef HAVE_MBSTATE_T
7bfd842d
NC
587 /* Initialise the multibyte conversion state. */
588 memset (& state, 0, sizeof (state));
3bfcb652 589#endif
961c521f 590
79bc120c
NC
591 if (do_demangle && *symbol)
592 {
593 const char * res = cplus_demangle (symbol, demangle_flags);
594
595 if (res != NULL)
596 alloced_symbol = symbol = res;
597 }
598
7bfd842d
NC
599 while (width_remaining)
600 {
601 size_t n;
7bfd842d 602 const char c = *symbol++;
961c521f 603
7bfd842d 604 if (c == 0)
961c521f
NC
605 break;
606
7bfd842d
NC
607 /* Do not print control characters directly as they can affect terminal
608 settings. Such characters usually appear in the names generated
609 by the assembler for local labels. */
610 if (ISCNTRL (c))
961c521f 611 {
7bfd842d 612 if (width_remaining < 2)
961c521f
NC
613 break;
614
7bfd842d
NC
615 printf ("^%c", c + 0x40);
616 width_remaining -= 2;
171191ba 617 num_printed += 2;
961c521f 618 }
7bfd842d
NC
619 else if (ISPRINT (c))
620 {
621 putchar (c);
622 width_remaining --;
623 num_printed ++;
624 }
961c521f
NC
625 else
626 {
3bfcb652
NC
627#ifdef HAVE_MBSTATE_T
628 wchar_t w;
629#endif
7bfd842d
NC
630 /* Let printf do the hard work of displaying multibyte characters. */
631 printf ("%.1s", symbol - 1);
632 width_remaining --;
633 num_printed ++;
634
3bfcb652 635#ifdef HAVE_MBSTATE_T
7bfd842d
NC
636 /* Try to find out how many bytes made up the character that was
637 just printed. Advance the symbol pointer past the bytes that
638 were displayed. */
639 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
640#else
641 n = 1;
642#endif
7bfd842d
NC
643 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
644 symbol += (n - 1);
961c521f 645 }
961c521f 646 }
171191ba 647
0942c7ab
NC
648 if (do_dots)
649 num_printed += printf ("[...]");
650
7bfd842d 651 if (extra_padding && num_printed < width)
171191ba
NC
652 {
653 /* Fill in the remaining spaces. */
7bfd842d
NC
654 printf ("%-*s", width - num_printed, " ");
655 num_printed = width;
171191ba
NC
656 }
657
79bc120c 658 free ((void *) alloced_symbol);
171191ba 659 return num_printed;
31104126
NC
660}
661
1449284b 662/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
663 the given section's name. Like print_symbol, except that it does not try
664 to print multibyte characters, it just interprets them as hex values. */
665
666static const char *
dda8d76d 667printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
668{
669#define MAX_PRINT_SEC_NAME_LEN 128
670 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
671 const char * name = SECTION_NAME (sec);
672 char * buf = sec_name_buf;
673 char c;
674 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
675
676 while ((c = * name ++) != 0)
677 {
678 if (ISCNTRL (c))
679 {
680 if (remaining < 2)
681 break;
948f632f 682
74e1a04b
NC
683 * buf ++ = '^';
684 * buf ++ = c + 0x40;
685 remaining -= 2;
686 }
687 else if (ISPRINT (c))
688 {
689 * buf ++ = c;
690 remaining -= 1;
691 }
692 else
693 {
694 static char hex[17] = "0123456789ABCDEF";
695
696 if (remaining < 4)
697 break;
698 * buf ++ = '<';
699 * buf ++ = hex[(c & 0xf0) >> 4];
700 * buf ++ = hex[c & 0x0f];
701 * buf ++ = '>';
702 remaining -= 4;
703 }
704
705 if (remaining == 0)
706 break;
707 }
708
709 * buf = 0;
710 return sec_name_buf;
711}
712
713static const char *
dda8d76d 714printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 715{
dda8d76d 716 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
717 return _("<corrupt>");
718
dda8d76d 719 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
720}
721
89fac5e3
RS
722/* Return a pointer to section NAME, or NULL if no such section exists. */
723
724static Elf_Internal_Shdr *
dda8d76d 725find_section (Filedata * filedata, const char * name)
89fac5e3
RS
726{
727 unsigned int i;
728
68807c3c
NC
729 if (filedata->section_headers == NULL)
730 return NULL;
dda8d76d
NC
731
732 for (i = 0; i < filedata->file_header.e_shnum; i++)
733 if (streq (SECTION_NAME (filedata->section_headers + i), name))
734 return filedata->section_headers + i;
89fac5e3
RS
735
736 return NULL;
737}
738
0b6ae522
DJ
739/* Return a pointer to a section containing ADDR, or NULL if no such
740 section exists. */
741
742static Elf_Internal_Shdr *
dda8d76d 743find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
744{
745 unsigned int i;
746
68807c3c
NC
747 if (filedata->section_headers == NULL)
748 return NULL;
749
dda8d76d 750 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 751 {
dda8d76d
NC
752 Elf_Internal_Shdr *sec = filedata->section_headers + i;
753
0b6ae522
DJ
754 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
755 return sec;
756 }
757
758 return NULL;
759}
760
071436c6 761static Elf_Internal_Shdr *
dda8d76d 762find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
763{
764 unsigned int i;
765
68807c3c
NC
766 if (filedata->section_headers == NULL)
767 return NULL;
768
dda8d76d 769 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 770 {
dda8d76d
NC
771 Elf_Internal_Shdr *sec = filedata->section_headers + i;
772
071436c6
NC
773 if (sec->sh_type == type)
774 return sec;
775 }
776
777 return NULL;
778}
779
657d0d47
CC
780/* Return a pointer to section NAME, or NULL if no such section exists,
781 restricted to the list of sections given in SET. */
782
783static Elf_Internal_Shdr *
dda8d76d 784find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
785{
786 unsigned int i;
787
68807c3c
NC
788 if (filedata->section_headers == NULL)
789 return NULL;
790
657d0d47
CC
791 if (set != NULL)
792 {
793 while ((i = *set++) > 0)
b814a36d
NC
794 {
795 /* See PR 21156 for a reproducer. */
dda8d76d 796 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
797 continue; /* FIXME: Should we issue an error message ? */
798
dda8d76d
NC
799 if (streq (SECTION_NAME (filedata->section_headers + i), name))
800 return filedata->section_headers + i;
b814a36d 801 }
657d0d47
CC
802 }
803
dda8d76d 804 return find_section (filedata, name);
657d0d47
CC
805}
806
32ec8896 807/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
808 This OS has so many departures from the ELF standard that we test it at
809 many places. */
810
32ec8896 811static inline bfd_boolean
dda8d76d 812is_ia64_vms (Filedata * filedata)
28f997cf 813{
dda8d76d
NC
814 return filedata->file_header.e_machine == EM_IA_64
815 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
816}
817
bcedfee6 818/* Guess the relocation size commonly used by the specific machines. */
252b5132 819
32ec8896 820static bfd_boolean
2dc4cec1 821guess_is_rela (unsigned int e_machine)
252b5132 822{
9c19a809 823 switch (e_machine)
252b5132
RH
824 {
825 /* Targets that use REL relocations. */
252b5132 826 case EM_386:
22abe556 827 case EM_IAMCU:
f954747f 828 case EM_960:
e9f53129 829 case EM_ARM:
2b0337b0 830 case EM_D10V:
252b5132 831 case EM_CYGNUS_D10V:
e9f53129 832 case EM_DLX:
252b5132 833 case EM_MIPS:
4fe85591 834 case EM_MIPS_RS3_LE:
e9f53129 835 case EM_CYGNUS_M32R:
1c0d3aa6 836 case EM_SCORE:
f6c1a2d5 837 case EM_XGATE:
fe944acf 838 case EM_NFP:
aca4efc7 839 case EM_BPF:
9c19a809 840 return FALSE;
103f02d3 841
252b5132
RH
842 /* Targets that use RELA relocations. */
843 case EM_68K:
f954747f 844 case EM_860:
a06ea964 845 case EM_AARCH64:
cfb8c092 846 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
847 case EM_ALPHA:
848 case EM_ALTERA_NIOS2:
886a2506
NC
849 case EM_ARC:
850 case EM_ARC_COMPACT:
851 case EM_ARC_COMPACT2:
e9f53129
AM
852 case EM_AVR:
853 case EM_AVR_OLD:
854 case EM_BLACKFIN:
60bca95a 855 case EM_CR16:
e9f53129
AM
856 case EM_CRIS:
857 case EM_CRX:
b8891f8d 858 case EM_CSKY:
2b0337b0 859 case EM_D30V:
252b5132 860 case EM_CYGNUS_D30V:
2b0337b0 861 case EM_FR30:
3f8107ab 862 case EM_FT32:
252b5132 863 case EM_CYGNUS_FR30:
5c70f934 864 case EM_CYGNUS_FRV:
e9f53129
AM
865 case EM_H8S:
866 case EM_H8_300:
867 case EM_H8_300H:
800eeca4 868 case EM_IA_64:
1e4cf259
NC
869 case EM_IP2K:
870 case EM_IP2K_OLD:
3b36097d 871 case EM_IQ2000:
84e94c90 872 case EM_LATTICEMICO32:
ff7eeb89 873 case EM_M32C_OLD:
49f58d10 874 case EM_M32C:
e9f53129
AM
875 case EM_M32R:
876 case EM_MCORE:
15ab5209 877 case EM_CYGNUS_MEP:
a3c62988 878 case EM_METAG:
e9f53129
AM
879 case EM_MMIX:
880 case EM_MN10200:
881 case EM_CYGNUS_MN10200:
882 case EM_MN10300:
883 case EM_CYGNUS_MN10300:
5506d11a 884 case EM_MOXIE:
e9f53129
AM
885 case EM_MSP430:
886 case EM_MSP430_OLD:
d031aafb 887 case EM_MT:
35c08157 888 case EM_NDS32:
64fd6348 889 case EM_NIOS32:
73589c9d 890 case EM_OR1K:
e9f53129
AM
891 case EM_PPC64:
892 case EM_PPC:
2b100bb5 893 case EM_TI_PRU:
e23eba97 894 case EM_RISCV:
99c513f6 895 case EM_RL78:
c7927a3c 896 case EM_RX:
e9f53129
AM
897 case EM_S390:
898 case EM_S390_OLD:
899 case EM_SH:
900 case EM_SPARC:
901 case EM_SPARC32PLUS:
902 case EM_SPARCV9:
903 case EM_SPU:
40b36596 904 case EM_TI_C6000:
aa137e4d
NC
905 case EM_TILEGX:
906 case EM_TILEPRO:
708e2187 907 case EM_V800:
e9f53129
AM
908 case EM_V850:
909 case EM_CYGNUS_V850:
910 case EM_VAX:
619ed720 911 case EM_VISIUM:
e9f53129 912 case EM_X86_64:
8a9036a4 913 case EM_L1OM:
7a9068fe 914 case EM_K1OM:
e9f53129
AM
915 case EM_XSTORMY16:
916 case EM_XTENSA:
917 case EM_XTENSA_OLD:
7ba29e2a
NC
918 case EM_MICROBLAZE:
919 case EM_MICROBLAZE_OLD:
f96bd6c2 920 case EM_WEBASSEMBLY:
9c19a809 921 return TRUE;
103f02d3 922
e9f53129
AM
923 case EM_68HC05:
924 case EM_68HC08:
925 case EM_68HC11:
926 case EM_68HC16:
927 case EM_FX66:
928 case EM_ME16:
d1133906 929 case EM_MMA:
d1133906
NC
930 case EM_NCPU:
931 case EM_NDR1:
e9f53129 932 case EM_PCP:
d1133906 933 case EM_ST100:
e9f53129 934 case EM_ST19:
d1133906 935 case EM_ST7:
e9f53129
AM
936 case EM_ST9PLUS:
937 case EM_STARCORE:
d1133906 938 case EM_SVX:
e9f53129 939 case EM_TINYJ:
9c19a809
NC
940 default:
941 warn (_("Don't know about relocations on this machine architecture\n"));
942 return FALSE;
943 }
944}
252b5132 945
dda8d76d 946/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
947 Returns TRUE upon success, FALSE otherwise. If successful then a
948 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
949 and the number of relocs loaded is placed in *NRELASP. It is the caller's
950 responsibility to free the allocated buffer. */
951
952static bfd_boolean
dda8d76d
NC
953slurp_rela_relocs (Filedata * filedata,
954 unsigned long rel_offset,
955 unsigned long rel_size,
956 Elf_Internal_Rela ** relasp,
957 unsigned long * nrelasp)
9c19a809 958{
2cf0635d 959 Elf_Internal_Rela * relas;
8b73c356 960 size_t nrelas;
4d6ed7c8 961 unsigned int i;
252b5132 962
4d6ed7c8
NC
963 if (is_32bit_elf)
964 {
2cf0635d 965 Elf32_External_Rela * erelas;
103f02d3 966
dda8d76d 967 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 968 rel_size, _("32-bit relocation data"));
a6e9f9df 969 if (!erelas)
32ec8896 970 return FALSE;
252b5132 971
4d6ed7c8 972 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 973
3f5e193b
NC
974 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
975 sizeof (Elf_Internal_Rela));
103f02d3 976
4d6ed7c8
NC
977 if (relas == NULL)
978 {
c256ffe7 979 free (erelas);
591a748a 980 error (_("out of memory parsing relocs\n"));
32ec8896 981 return FALSE;
4d6ed7c8 982 }
103f02d3 983
4d6ed7c8
NC
984 for (i = 0; i < nrelas; i++)
985 {
986 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
987 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 988 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 989 }
103f02d3 990
4d6ed7c8
NC
991 free (erelas);
992 }
993 else
994 {
2cf0635d 995 Elf64_External_Rela * erelas;
103f02d3 996
dda8d76d 997 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 998 rel_size, _("64-bit relocation data"));
a6e9f9df 999 if (!erelas)
32ec8896 1000 return FALSE;
4d6ed7c8
NC
1001
1002 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1003
3f5e193b
NC
1004 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1005 sizeof (Elf_Internal_Rela));
103f02d3 1006
4d6ed7c8
NC
1007 if (relas == NULL)
1008 {
c256ffe7 1009 free (erelas);
591a748a 1010 error (_("out of memory parsing relocs\n"));
32ec8896 1011 return FALSE;
9c19a809 1012 }
4d6ed7c8
NC
1013
1014 for (i = 0; i < nrelas; i++)
9c19a809 1015 {
66543521
AM
1016 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1017 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1018 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1019
1020 /* The #ifdef BFD64 below is to prevent a compile time
1021 warning. We know that if we do not have a 64 bit data
1022 type that we will never execute this code anyway. */
1023#ifdef BFD64
dda8d76d
NC
1024 if (filedata->file_header.e_machine == EM_MIPS
1025 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1026 {
1027 /* In little-endian objects, r_info isn't really a
1028 64-bit little-endian value: it has a 32-bit
1029 little-endian symbol index followed by four
1030 individual byte fields. Reorder INFO
1031 accordingly. */
91d6fa6a
NC
1032 bfd_vma inf = relas[i].r_info;
1033 inf = (((inf & 0xffffffff) << 32)
1034 | ((inf >> 56) & 0xff)
1035 | ((inf >> 40) & 0xff00)
1036 | ((inf >> 24) & 0xff0000)
1037 | ((inf >> 8) & 0xff000000));
1038 relas[i].r_info = inf;
861fb55a
DJ
1039 }
1040#endif /* BFD64 */
4d6ed7c8 1041 }
103f02d3 1042
4d6ed7c8
NC
1043 free (erelas);
1044 }
32ec8896 1045
4d6ed7c8
NC
1046 *relasp = relas;
1047 *nrelasp = nrelas;
32ec8896 1048 return TRUE;
4d6ed7c8 1049}
103f02d3 1050
dda8d76d 1051/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1052 Returns TRUE upon success, FALSE otherwise. If successful then a
1053 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1054 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1055 responsibility to free the allocated buffer. */
1056
1057static bfd_boolean
dda8d76d
NC
1058slurp_rel_relocs (Filedata * filedata,
1059 unsigned long rel_offset,
1060 unsigned long rel_size,
1061 Elf_Internal_Rela ** relsp,
1062 unsigned long * nrelsp)
4d6ed7c8 1063{
2cf0635d 1064 Elf_Internal_Rela * rels;
8b73c356 1065 size_t nrels;
4d6ed7c8 1066 unsigned int i;
103f02d3 1067
4d6ed7c8
NC
1068 if (is_32bit_elf)
1069 {
2cf0635d 1070 Elf32_External_Rel * erels;
103f02d3 1071
dda8d76d 1072 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1073 rel_size, _("32-bit relocation data"));
a6e9f9df 1074 if (!erels)
32ec8896 1075 return FALSE;
103f02d3 1076
4d6ed7c8 1077 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1078
3f5e193b 1079 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1080
4d6ed7c8
NC
1081 if (rels == NULL)
1082 {
c256ffe7 1083 free (erels);
591a748a 1084 error (_("out of memory parsing relocs\n"));
32ec8896 1085 return FALSE;
4d6ed7c8
NC
1086 }
1087
1088 for (i = 0; i < nrels; i++)
1089 {
1090 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1091 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1092 rels[i].r_addend = 0;
9ea033b2 1093 }
4d6ed7c8
NC
1094
1095 free (erels);
9c19a809
NC
1096 }
1097 else
1098 {
2cf0635d 1099 Elf64_External_Rel * erels;
9ea033b2 1100
dda8d76d 1101 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1102 rel_size, _("64-bit relocation data"));
a6e9f9df 1103 if (!erels)
32ec8896 1104 return FALSE;
103f02d3 1105
4d6ed7c8 1106 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1107
3f5e193b 1108 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1109
4d6ed7c8 1110 if (rels == NULL)
9c19a809 1111 {
c256ffe7 1112 free (erels);
591a748a 1113 error (_("out of memory parsing relocs\n"));
32ec8896 1114 return FALSE;
4d6ed7c8 1115 }
103f02d3 1116
4d6ed7c8
NC
1117 for (i = 0; i < nrels; i++)
1118 {
66543521
AM
1119 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1120 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1121 rels[i].r_addend = 0;
861fb55a
DJ
1122
1123 /* The #ifdef BFD64 below is to prevent a compile time
1124 warning. We know that if we do not have a 64 bit data
1125 type that we will never execute this code anyway. */
1126#ifdef BFD64
dda8d76d
NC
1127 if (filedata->file_header.e_machine == EM_MIPS
1128 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1129 {
1130 /* In little-endian objects, r_info isn't really a
1131 64-bit little-endian value: it has a 32-bit
1132 little-endian symbol index followed by four
1133 individual byte fields. Reorder INFO
1134 accordingly. */
91d6fa6a
NC
1135 bfd_vma inf = rels[i].r_info;
1136 inf = (((inf & 0xffffffff) << 32)
1137 | ((inf >> 56) & 0xff)
1138 | ((inf >> 40) & 0xff00)
1139 | ((inf >> 24) & 0xff0000)
1140 | ((inf >> 8) & 0xff000000));
1141 rels[i].r_info = inf;
861fb55a
DJ
1142 }
1143#endif /* BFD64 */
4d6ed7c8 1144 }
103f02d3 1145
4d6ed7c8
NC
1146 free (erels);
1147 }
32ec8896 1148
4d6ed7c8
NC
1149 *relsp = rels;
1150 *nrelsp = nrels;
32ec8896 1151 return TRUE;
4d6ed7c8 1152}
103f02d3 1153
aca88567
NC
1154/* Returns the reloc type extracted from the reloc info field. */
1155
1156static unsigned int
dda8d76d 1157get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1158{
1159 if (is_32bit_elf)
1160 return ELF32_R_TYPE (reloc_info);
1161
dda8d76d 1162 switch (filedata->file_header.e_machine)
aca88567
NC
1163 {
1164 case EM_MIPS:
1165 /* Note: We assume that reloc_info has already been adjusted for us. */
1166 return ELF64_MIPS_R_TYPE (reloc_info);
1167
1168 case EM_SPARCV9:
1169 return ELF64_R_TYPE_ID (reloc_info);
1170
1171 default:
1172 return ELF64_R_TYPE (reloc_info);
1173 }
1174}
1175
1176/* Return the symbol index extracted from the reloc info field. */
1177
1178static bfd_vma
1179get_reloc_symindex (bfd_vma reloc_info)
1180{
1181 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1182}
1183
13761a11 1184static inline bfd_boolean
dda8d76d 1185uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1186{
1187 return
dda8d76d 1188 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1189 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1190 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1191 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1192 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1193}
1194
d3ba0551
AM
1195/* Display the contents of the relocation data found at the specified
1196 offset. */
ee42cf8c 1197
32ec8896 1198static bfd_boolean
dda8d76d
NC
1199dump_relocations (Filedata * filedata,
1200 unsigned long rel_offset,
1201 unsigned long rel_size,
1202 Elf_Internal_Sym * symtab,
1203 unsigned long nsyms,
1204 char * strtab,
1205 unsigned long strtablen,
1206 int is_rela,
1207 bfd_boolean is_dynsym)
4d6ed7c8 1208{
32ec8896 1209 unsigned long i;
2cf0635d 1210 Elf_Internal_Rela * rels;
32ec8896 1211 bfd_boolean res = TRUE;
103f02d3 1212
4d6ed7c8 1213 if (is_rela == UNKNOWN)
dda8d76d 1214 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1215
4d6ed7c8
NC
1216 if (is_rela)
1217 {
dda8d76d 1218 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1219 return FALSE;
4d6ed7c8
NC
1220 }
1221 else
1222 {
dda8d76d 1223 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1224 return FALSE;
252b5132
RH
1225 }
1226
410f7a12
L
1227 if (is_32bit_elf)
1228 {
1229 if (is_rela)
2c71103e
NC
1230 {
1231 if (do_wide)
1232 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1233 else
1234 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1235 }
410f7a12 1236 else
2c71103e
NC
1237 {
1238 if (do_wide)
1239 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1240 else
1241 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1242 }
410f7a12 1243 }
252b5132 1244 else
410f7a12
L
1245 {
1246 if (is_rela)
2c71103e
NC
1247 {
1248 if (do_wide)
8beeaeb7 1249 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1250 else
1251 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1252 }
410f7a12 1253 else
2c71103e
NC
1254 {
1255 if (do_wide)
8beeaeb7 1256 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1257 else
1258 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1259 }
410f7a12 1260 }
252b5132
RH
1261
1262 for (i = 0; i < rel_size; i++)
1263 {
2cf0635d 1264 const char * rtype;
b34976b6 1265 bfd_vma offset;
91d6fa6a 1266 bfd_vma inf;
b34976b6
AM
1267 bfd_vma symtab_index;
1268 bfd_vma type;
103f02d3 1269
b34976b6 1270 offset = rels[i].r_offset;
91d6fa6a 1271 inf = rels[i].r_info;
103f02d3 1272
dda8d76d 1273 type = get_reloc_type (filedata, inf);
91d6fa6a 1274 symtab_index = get_reloc_symindex (inf);
252b5132 1275
410f7a12
L
1276 if (is_32bit_elf)
1277 {
39dbeff8
AM
1278 printf ("%8.8lx %8.8lx ",
1279 (unsigned long) offset & 0xffffffff,
91d6fa6a 1280 (unsigned long) inf & 0xffffffff);
410f7a12
L
1281 }
1282 else
1283 {
39dbeff8 1284 printf (do_wide
d1ce973e
AM
1285 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1286 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1287 offset, inf);
410f7a12 1288 }
103f02d3 1289
dda8d76d 1290 switch (filedata->file_header.e_machine)
252b5132
RH
1291 {
1292 default:
1293 rtype = NULL;
1294 break;
1295
a06ea964
NC
1296 case EM_AARCH64:
1297 rtype = elf_aarch64_reloc_type (type);
1298 break;
1299
2b0337b0 1300 case EM_M32R:
252b5132 1301 case EM_CYGNUS_M32R:
9ea033b2 1302 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1303 break;
1304
1305 case EM_386:
22abe556 1306 case EM_IAMCU:
9ea033b2 1307 rtype = elf_i386_reloc_type (type);
252b5132
RH
1308 break;
1309
ba2685cc
AM
1310 case EM_68HC11:
1311 case EM_68HC12:
1312 rtype = elf_m68hc11_reloc_type (type);
1313 break;
75751cd9 1314
7b4ae824
JD
1315 case EM_S12Z:
1316 rtype = elf_s12z_reloc_type (type);
1317 break;
1318
252b5132 1319 case EM_68K:
9ea033b2 1320 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1321 break;
1322
f954747f
AM
1323 case EM_960:
1324 rtype = elf_i960_reloc_type (type);
1325 break;
1326
adde6300 1327 case EM_AVR:
2b0337b0 1328 case EM_AVR_OLD:
adde6300
AM
1329 rtype = elf_avr_reloc_type (type);
1330 break;
1331
9ea033b2
NC
1332 case EM_OLD_SPARCV9:
1333 case EM_SPARC32PLUS:
1334 case EM_SPARCV9:
252b5132 1335 case EM_SPARC:
9ea033b2 1336 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1337 break;
1338
e9f53129
AM
1339 case EM_SPU:
1340 rtype = elf_spu_reloc_type (type);
1341 break;
1342
708e2187
NC
1343 case EM_V800:
1344 rtype = v800_reloc_type (type);
1345 break;
2b0337b0 1346 case EM_V850:
252b5132 1347 case EM_CYGNUS_V850:
9ea033b2 1348 rtype = v850_reloc_type (type);
252b5132
RH
1349 break;
1350
2b0337b0 1351 case EM_D10V:
252b5132 1352 case EM_CYGNUS_D10V:
9ea033b2 1353 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1354 break;
1355
2b0337b0 1356 case EM_D30V:
252b5132 1357 case EM_CYGNUS_D30V:
9ea033b2 1358 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1359 break;
1360
d172d4ba
NC
1361 case EM_DLX:
1362 rtype = elf_dlx_reloc_type (type);
1363 break;
1364
252b5132 1365 case EM_SH:
9ea033b2 1366 rtype = elf_sh_reloc_type (type);
252b5132
RH
1367 break;
1368
2b0337b0 1369 case EM_MN10300:
252b5132 1370 case EM_CYGNUS_MN10300:
9ea033b2 1371 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1372 break;
1373
2b0337b0 1374 case EM_MN10200:
252b5132 1375 case EM_CYGNUS_MN10200:
9ea033b2 1376 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1377 break;
1378
2b0337b0 1379 case EM_FR30:
252b5132 1380 case EM_CYGNUS_FR30:
9ea033b2 1381 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1382 break;
1383
ba2685cc
AM
1384 case EM_CYGNUS_FRV:
1385 rtype = elf_frv_reloc_type (type);
1386 break;
5c70f934 1387
b8891f8d
AJ
1388 case EM_CSKY:
1389 rtype = elf_csky_reloc_type (type);
1390 break;
1391
3f8107ab
AM
1392 case EM_FT32:
1393 rtype = elf_ft32_reloc_type (type);
1394 break;
1395
252b5132 1396 case EM_MCORE:
9ea033b2 1397 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1398 break;
1399
3c3bdf30
NC
1400 case EM_MMIX:
1401 rtype = elf_mmix_reloc_type (type);
1402 break;
1403
5506d11a
AM
1404 case EM_MOXIE:
1405 rtype = elf_moxie_reloc_type (type);
1406 break;
1407
2469cfa2 1408 case EM_MSP430:
dda8d76d 1409 if (uses_msp430x_relocs (filedata))
13761a11
NC
1410 {
1411 rtype = elf_msp430x_reloc_type (type);
1412 break;
1413 }
1a0670f3 1414 /* Fall through. */
2469cfa2
NC
1415 case EM_MSP430_OLD:
1416 rtype = elf_msp430_reloc_type (type);
1417 break;
1418
35c08157
KLC
1419 case EM_NDS32:
1420 rtype = elf_nds32_reloc_type (type);
1421 break;
1422
252b5132 1423 case EM_PPC:
9ea033b2 1424 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1425 break;
1426
c833c019
AM
1427 case EM_PPC64:
1428 rtype = elf_ppc64_reloc_type (type);
1429 break;
1430
252b5132 1431 case EM_MIPS:
4fe85591 1432 case EM_MIPS_RS3_LE:
9ea033b2 1433 rtype = elf_mips_reloc_type (type);
252b5132
RH
1434 break;
1435
e23eba97
NC
1436 case EM_RISCV:
1437 rtype = elf_riscv_reloc_type (type);
1438 break;
1439
252b5132 1440 case EM_ALPHA:
9ea033b2 1441 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1442 break;
1443
1444 case EM_ARM:
9ea033b2 1445 rtype = elf_arm_reloc_type (type);
252b5132
RH
1446 break;
1447
584da044 1448 case EM_ARC:
886a2506
NC
1449 case EM_ARC_COMPACT:
1450 case EM_ARC_COMPACT2:
9ea033b2 1451 rtype = elf_arc_reloc_type (type);
252b5132
RH
1452 break;
1453
1454 case EM_PARISC:
69e617ca 1455 rtype = elf_hppa_reloc_type (type);
252b5132 1456 break;
7d466069 1457
b8720f9d
JL
1458 case EM_H8_300:
1459 case EM_H8_300H:
1460 case EM_H8S:
1461 rtype = elf_h8_reloc_type (type);
1462 break;
1463
73589c9d
CS
1464 case EM_OR1K:
1465 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1466 break;
1467
7d466069 1468 case EM_PJ:
2b0337b0 1469 case EM_PJ_OLD:
7d466069
ILT
1470 rtype = elf_pj_reloc_type (type);
1471 break;
800eeca4
JW
1472 case EM_IA_64:
1473 rtype = elf_ia64_reloc_type (type);
1474 break;
1b61cf92
HPN
1475
1476 case EM_CRIS:
1477 rtype = elf_cris_reloc_type (type);
1478 break;
535c37ff 1479
f954747f
AM
1480 case EM_860:
1481 rtype = elf_i860_reloc_type (type);
1482 break;
1483
bcedfee6 1484 case EM_X86_64:
8a9036a4 1485 case EM_L1OM:
7a9068fe 1486 case EM_K1OM:
bcedfee6
NC
1487 rtype = elf_x86_64_reloc_type (type);
1488 break;
a85d7ed0 1489
f954747f
AM
1490 case EM_S370:
1491 rtype = i370_reloc_type (type);
1492 break;
1493
53c7db4b
KH
1494 case EM_S390_OLD:
1495 case EM_S390:
1496 rtype = elf_s390_reloc_type (type);
1497 break;
93fbbb04 1498
1c0d3aa6
NC
1499 case EM_SCORE:
1500 rtype = elf_score_reloc_type (type);
1501 break;
1502
93fbbb04
GK
1503 case EM_XSTORMY16:
1504 rtype = elf_xstormy16_reloc_type (type);
1505 break;
179d3252 1506
1fe1f39c
NC
1507 case EM_CRX:
1508 rtype = elf_crx_reloc_type (type);
1509 break;
1510
179d3252
JT
1511 case EM_VAX:
1512 rtype = elf_vax_reloc_type (type);
1513 break;
1e4cf259 1514
619ed720
EB
1515 case EM_VISIUM:
1516 rtype = elf_visium_reloc_type (type);
1517 break;
1518
aca4efc7
JM
1519 case EM_BPF:
1520 rtype = elf_bpf_reloc_type (type);
1521 break;
1522
cfb8c092
NC
1523 case EM_ADAPTEVA_EPIPHANY:
1524 rtype = elf_epiphany_reloc_type (type);
1525 break;
1526
1e4cf259
NC
1527 case EM_IP2K:
1528 case EM_IP2K_OLD:
1529 rtype = elf_ip2k_reloc_type (type);
1530 break;
3b36097d
SC
1531
1532 case EM_IQ2000:
1533 rtype = elf_iq2000_reloc_type (type);
1534 break;
88da6820
NC
1535
1536 case EM_XTENSA_OLD:
1537 case EM_XTENSA:
1538 rtype = elf_xtensa_reloc_type (type);
1539 break;
a34e3ecb 1540
84e94c90
NC
1541 case EM_LATTICEMICO32:
1542 rtype = elf_lm32_reloc_type (type);
1543 break;
1544
ff7eeb89 1545 case EM_M32C_OLD:
49f58d10
JB
1546 case EM_M32C:
1547 rtype = elf_m32c_reloc_type (type);
1548 break;
1549
d031aafb
NS
1550 case EM_MT:
1551 rtype = elf_mt_reloc_type (type);
a34e3ecb 1552 break;
1d65ded4
CM
1553
1554 case EM_BLACKFIN:
1555 rtype = elf_bfin_reloc_type (type);
1556 break;
15ab5209
DB
1557
1558 case EM_CYGNUS_MEP:
1559 rtype = elf_mep_reloc_type (type);
1560 break;
60bca95a
NC
1561
1562 case EM_CR16:
1563 rtype = elf_cr16_reloc_type (type);
1564 break;
dd24e3da 1565
7ba29e2a
NC
1566 case EM_MICROBLAZE:
1567 case EM_MICROBLAZE_OLD:
1568 rtype = elf_microblaze_reloc_type (type);
1569 break;
c7927a3c 1570
99c513f6
DD
1571 case EM_RL78:
1572 rtype = elf_rl78_reloc_type (type);
1573 break;
1574
c7927a3c
NC
1575 case EM_RX:
1576 rtype = elf_rx_reloc_type (type);
1577 break;
c29aca4a 1578
a3c62988
NC
1579 case EM_METAG:
1580 rtype = elf_metag_reloc_type (type);
1581 break;
1582
c29aca4a
NC
1583 case EM_XC16X:
1584 case EM_C166:
1585 rtype = elf_xc16x_reloc_type (type);
1586 break;
40b36596
JM
1587
1588 case EM_TI_C6000:
1589 rtype = elf_tic6x_reloc_type (type);
1590 break;
aa137e4d
NC
1591
1592 case EM_TILEGX:
1593 rtype = elf_tilegx_reloc_type (type);
1594 break;
1595
1596 case EM_TILEPRO:
1597 rtype = elf_tilepro_reloc_type (type);
1598 break;
f6c1a2d5 1599
f96bd6c2
PC
1600 case EM_WEBASSEMBLY:
1601 rtype = elf_wasm32_reloc_type (type);
1602 break;
1603
f6c1a2d5
NC
1604 case EM_XGATE:
1605 rtype = elf_xgate_reloc_type (type);
1606 break;
36591ba1
SL
1607
1608 case EM_ALTERA_NIOS2:
1609 rtype = elf_nios2_reloc_type (type);
1610 break;
2b100bb5
DD
1611
1612 case EM_TI_PRU:
1613 rtype = elf_pru_reloc_type (type);
1614 break;
fe944acf
FT
1615
1616 case EM_NFP:
1617 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1618 rtype = elf_nfp3200_reloc_type (type);
1619 else
1620 rtype = elf_nfp_reloc_type (type);
1621 break;
6655dba2
SB
1622
1623 case EM_Z80:
1624 rtype = elf_z80_reloc_type (type);
1625 break;
252b5132
RH
1626 }
1627
1628 if (rtype == NULL)
39dbeff8 1629 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1630 else
5c144731 1631 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1632
dda8d76d 1633 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1634 && rtype != NULL
7ace3541
RH
1635 && streq (rtype, "R_ALPHA_LITUSE")
1636 && is_rela)
1637 {
1638 switch (rels[i].r_addend)
1639 {
1640 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1641 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1642 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1643 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1644 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1645 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1646 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1647 default: rtype = NULL;
1648 }
32ec8896 1649
7ace3541
RH
1650 if (rtype)
1651 printf (" (%s)", rtype);
1652 else
1653 {
1654 putchar (' ');
1655 printf (_("<unknown addend: %lx>"),
1656 (unsigned long) rels[i].r_addend);
32ec8896 1657 res = FALSE;
7ace3541
RH
1658 }
1659 }
1660 else if (symtab_index)
252b5132 1661 {
af3fc3bc 1662 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1663 {
27a45f42
AS
1664 error (_(" bad symbol index: %08lx in reloc\n"),
1665 (unsigned long) symtab_index);
32ec8896
NC
1666 res = FALSE;
1667 }
af3fc3bc 1668 else
19936277 1669 {
2cf0635d 1670 Elf_Internal_Sym * psym;
bb4d2ac2
L
1671 const char * version_string;
1672 enum versioned_symbol_info sym_info;
1673 unsigned short vna_other;
19936277 1674
af3fc3bc 1675 psym = symtab + symtab_index;
103f02d3 1676
bb4d2ac2 1677 version_string
dda8d76d 1678 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1679 strtab, strtablen,
1680 symtab_index,
1681 psym,
1682 &sym_info,
1683 &vna_other);
1684
af3fc3bc 1685 printf (" ");
171191ba 1686
d8045f23
NC
1687 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1688 {
1689 const char * name;
1690 unsigned int len;
1691 unsigned int width = is_32bit_elf ? 8 : 14;
1692
1693 /* Relocations against GNU_IFUNC symbols do not use the value
1694 of the symbol as the address to relocate against. Instead
1695 they invoke the function named by the symbol and use its
1696 result as the address for relocation.
1697
1698 To indicate this to the user, do not display the value of
1699 the symbol in the "Symbols's Value" field. Instead show
1700 its name followed by () as a hint that the symbol is
1701 invoked. */
1702
1703 if (strtab == NULL
1704 || psym->st_name == 0
1705 || psym->st_name >= strtablen)
1706 name = "??";
1707 else
1708 name = strtab + psym->st_name;
1709
1710 len = print_symbol (width, name);
bb4d2ac2
L
1711 if (version_string)
1712 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1713 version_string);
d8045f23
NC
1714 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1715 }
1716 else
1717 {
1718 print_vma (psym->st_value, LONG_HEX);
171191ba 1719
d8045f23
NC
1720 printf (is_32bit_elf ? " " : " ");
1721 }
103f02d3 1722
af3fc3bc 1723 if (psym->st_name == 0)
f1ef08cb 1724 {
2cf0635d 1725 const char * sec_name = "<null>";
f1ef08cb
AM
1726 char name_buf[40];
1727
1728 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1729 {
dda8d76d
NC
1730 if (psym->st_shndx < filedata->file_header.e_shnum)
1731 sec_name = SECTION_NAME (filedata->section_headers + psym->st_shndx);
f1ef08cb
AM
1732 else if (psym->st_shndx == SHN_ABS)
1733 sec_name = "ABS";
1734 else if (psym->st_shndx == SHN_COMMON)
1735 sec_name = "COMMON";
dda8d76d 1736 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1737 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1738 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1739 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1740 sec_name = "SCOMMON";
dda8d76d 1741 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1742 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1743 sec_name = "SUNDEF";
dda8d76d
NC
1744 else if ((filedata->file_header.e_machine == EM_X86_64
1745 || filedata->file_header.e_machine == EM_L1OM
1746 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1747 && psym->st_shndx == SHN_X86_64_LCOMMON)
1748 sec_name = "LARGE_COMMON";
dda8d76d
NC
1749 else if (filedata->file_header.e_machine == EM_IA_64
1750 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1751 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1752 sec_name = "ANSI_COM";
dda8d76d 1753 else if (is_ia64_vms (filedata)
148b93f2
NC
1754 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1755 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1756 else
1757 {
1758 sprintf (name_buf, "<section 0x%x>",
1759 (unsigned int) psym->st_shndx);
1760 sec_name = name_buf;
1761 }
1762 }
1763 print_symbol (22, sec_name);
1764 }
af3fc3bc 1765 else if (strtab == NULL)
d79b3d50 1766 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1767 else if (psym->st_name >= strtablen)
32ec8896 1768 {
27a45f42
AS
1769 error (_("<corrupt string table index: %3ld>\n"),
1770 psym->st_name);
32ec8896
NC
1771 res = FALSE;
1772 }
af3fc3bc 1773 else
bb4d2ac2
L
1774 {
1775 print_symbol (22, strtab + psym->st_name);
1776 if (version_string)
1777 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1778 version_string);
1779 }
103f02d3 1780
af3fc3bc 1781 if (is_rela)
171191ba 1782 {
7360e63f 1783 bfd_vma off = rels[i].r_addend;
171191ba 1784
7360e63f 1785 if ((bfd_signed_vma) off < 0)
598aaa76 1786 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1787 else
598aaa76 1788 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1789 }
19936277 1790 }
252b5132 1791 }
1b228002 1792 else if (is_rela)
f7a99963 1793 {
7360e63f 1794 bfd_vma off = rels[i].r_addend;
e04d7088
L
1795
1796 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1797 if ((bfd_signed_vma) off < 0)
e04d7088
L
1798 printf ("-%" BFD_VMA_FMT "x", - off);
1799 else
1800 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1801 }
252b5132 1802
dda8d76d 1803 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1804 && rtype != NULL
1805 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1806 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1807
252b5132 1808 putchar ('\n');
2c71103e 1809
aca88567 1810#ifdef BFD64
dda8d76d 1811 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1812 {
91d6fa6a
NC
1813 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1814 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1815 const char * rtype2 = elf_mips_reloc_type (type2);
1816 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1817
2c71103e
NC
1818 printf (" Type2: ");
1819
1820 if (rtype2 == NULL)
39dbeff8
AM
1821 printf (_("unrecognized: %-7lx"),
1822 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1823 else
1824 printf ("%-17.17s", rtype2);
1825
18bd398b 1826 printf ("\n Type3: ");
2c71103e
NC
1827
1828 if (rtype3 == NULL)
39dbeff8
AM
1829 printf (_("unrecognized: %-7lx"),
1830 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1831 else
1832 printf ("%-17.17s", rtype3);
1833
53c7db4b 1834 putchar ('\n');
2c71103e 1835 }
aca88567 1836#endif /* BFD64 */
252b5132
RH
1837 }
1838
c8286bd1 1839 free (rels);
32ec8896
NC
1840
1841 return res;
252b5132
RH
1842}
1843
37c18eed
SD
1844static const char *
1845get_aarch64_dynamic_type (unsigned long type)
1846{
1847 switch (type)
1848 {
1849 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1850 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1851 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1852 default:
1853 return NULL;
1854 }
1855}
1856
252b5132 1857static const char *
d3ba0551 1858get_mips_dynamic_type (unsigned long type)
252b5132
RH
1859{
1860 switch (type)
1861 {
1862 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1863 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1864 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1865 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1866 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1867 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1868 case DT_MIPS_MSYM: return "MIPS_MSYM";
1869 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1870 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1871 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1872 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1873 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1874 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1875 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1876 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1877 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1878 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1879 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1880 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1881 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1882 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1883 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1884 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1885 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1886 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1887 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1888 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1889 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1890 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1891 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1892 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1893 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1894 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1895 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1896 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1897 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1898 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1899 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1900 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1901 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1902 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1903 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1904 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1905 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1906 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1907 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1908 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1909 default:
1910 return NULL;
1911 }
1912}
1913
9a097730 1914static const char *
d3ba0551 1915get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1916{
1917 switch (type)
1918 {
1919 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1920 default:
1921 return NULL;
1922 }
103f02d3
UD
1923}
1924
7490d522
AM
1925static const char *
1926get_ppc_dynamic_type (unsigned long type)
1927{
1928 switch (type)
1929 {
a7f2871e 1930 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1931 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1932 default:
1933 return NULL;
1934 }
1935}
1936
f1cb7e17 1937static const char *
d3ba0551 1938get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1939{
1940 switch (type)
1941 {
a7f2871e
AM
1942 case DT_PPC64_GLINK: return "PPC64_GLINK";
1943 case DT_PPC64_OPD: return "PPC64_OPD";
1944 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1945 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1946 default:
1947 return NULL;
1948 }
1949}
1950
103f02d3 1951static const char *
d3ba0551 1952get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1953{
1954 switch (type)
1955 {
1956 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1957 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1958 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1959 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1960 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1961 case DT_HP_PREINIT: return "HP_PREINIT";
1962 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1963 case DT_HP_NEEDED: return "HP_NEEDED";
1964 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1965 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1966 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1967 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1968 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1969 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1970 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1971 case DT_HP_FILTERED: return "HP_FILTERED";
1972 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1973 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1974 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1975 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1976 case DT_PLT: return "PLT";
1977 case DT_PLT_SIZE: return "PLT_SIZE";
1978 case DT_DLT: return "DLT";
1979 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1980 default:
1981 return NULL;
1982 }
1983}
9a097730 1984
ecc51f48 1985static const char *
d3ba0551 1986get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1987{
1988 switch (type)
1989 {
148b93f2
NC
1990 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
1991 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
1992 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
1993 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
1994 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
1995 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
1996 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
1997 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
1998 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
1999 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2000 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2001 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2002 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2003 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2004 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2005 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2006 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2007 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2008 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2009 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2010 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2011 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2012 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2013 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2014 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2015 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2016 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2017 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2018 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2019 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2020 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2021 default:
2022 return NULL;
2023 }
2024}
2025
fd85a6a1
NC
2026static const char *
2027get_solaris_section_type (unsigned long type)
2028{
2029 switch (type)
2030 {
2031 case 0x6fffffee: return "SUNW_ancillary";
2032 case 0x6fffffef: return "SUNW_capchain";
2033 case 0x6ffffff0: return "SUNW_capinfo";
2034 case 0x6ffffff1: return "SUNW_symsort";
2035 case 0x6ffffff2: return "SUNW_tlssort";
2036 case 0x6ffffff3: return "SUNW_LDYNSYM";
2037 case 0x6ffffff4: return "SUNW_dof";
2038 case 0x6ffffff5: return "SUNW_cap";
2039 case 0x6ffffff6: return "SUNW_SIGNATURE";
2040 case 0x6ffffff7: return "SUNW_ANNOTATE";
2041 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2042 case 0x6ffffff9: return "SUNW_DEBUG";
2043 case 0x6ffffffa: return "SUNW_move";
2044 case 0x6ffffffb: return "SUNW_COMDAT";
2045 case 0x6ffffffc: return "SUNW_syminfo";
2046 case 0x6ffffffd: return "SUNW_verdef";
2047 case 0x6ffffffe: return "SUNW_verneed";
2048 case 0x6fffffff: return "SUNW_versym";
2049 case 0x70000000: return "SPARC_GOTDATA";
2050 default: return NULL;
2051 }
2052}
2053
fabcb361
RH
2054static const char *
2055get_alpha_dynamic_type (unsigned long type)
2056{
2057 switch (type)
2058 {
2059 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2060 default: return NULL;
fabcb361
RH
2061 }
2062}
2063
1c0d3aa6
NC
2064static const char *
2065get_score_dynamic_type (unsigned long type)
2066{
2067 switch (type)
2068 {
2069 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2070 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2071 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2072 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2073 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2074 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2075 default: return NULL;
1c0d3aa6
NC
2076 }
2077}
2078
40b36596
JM
2079static const char *
2080get_tic6x_dynamic_type (unsigned long type)
2081{
2082 switch (type)
2083 {
2084 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2085 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2086 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2087 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2088 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2089 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2090 default: return NULL;
40b36596
JM
2091 }
2092}
1c0d3aa6 2093
36591ba1
SL
2094static const char *
2095get_nios2_dynamic_type (unsigned long type)
2096{
2097 switch (type)
2098 {
2099 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2100 default: return NULL;
36591ba1
SL
2101 }
2102}
2103
fd85a6a1
NC
2104static const char *
2105get_solaris_dynamic_type (unsigned long type)
2106{
2107 switch (type)
2108 {
2109 case 0x6000000d: return "SUNW_AUXILIARY";
2110 case 0x6000000e: return "SUNW_RTLDINF";
2111 case 0x6000000f: return "SUNW_FILTER";
2112 case 0x60000010: return "SUNW_CAP";
2113 case 0x60000011: return "SUNW_SYMTAB";
2114 case 0x60000012: return "SUNW_SYMSZ";
2115 case 0x60000013: return "SUNW_SORTENT";
2116 case 0x60000014: return "SUNW_SYMSORT";
2117 case 0x60000015: return "SUNW_SYMSORTSZ";
2118 case 0x60000016: return "SUNW_TLSSORT";
2119 case 0x60000017: return "SUNW_TLSSORTSZ";
2120 case 0x60000018: return "SUNW_CAPINFO";
2121 case 0x60000019: return "SUNW_STRPAD";
2122 case 0x6000001a: return "SUNW_CAPCHAIN";
2123 case 0x6000001b: return "SUNW_LDMACH";
2124 case 0x6000001d: return "SUNW_CAPCHAINENT";
2125 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2126 case 0x60000021: return "SUNW_PARENT";
2127 case 0x60000023: return "SUNW_ASLR";
2128 case 0x60000025: return "SUNW_RELAX";
2129 case 0x60000029: return "SUNW_NXHEAP";
2130 case 0x6000002b: return "SUNW_NXSTACK";
2131
2132 case 0x70000001: return "SPARC_REGISTER";
2133 case 0x7ffffffd: return "AUXILIARY";
2134 case 0x7ffffffe: return "USED";
2135 case 0x7fffffff: return "FILTER";
2136
15f205b1 2137 default: return NULL;
fd85a6a1
NC
2138 }
2139}
2140
252b5132 2141static const char *
dda8d76d 2142get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2143{
e9e44622 2144 static char buff[64];
252b5132
RH
2145
2146 switch (type)
2147 {
2148 case DT_NULL: return "NULL";
2149 case DT_NEEDED: return "NEEDED";
2150 case DT_PLTRELSZ: return "PLTRELSZ";
2151 case DT_PLTGOT: return "PLTGOT";
2152 case DT_HASH: return "HASH";
2153 case DT_STRTAB: return "STRTAB";
2154 case DT_SYMTAB: return "SYMTAB";
2155 case DT_RELA: return "RELA";
2156 case DT_RELASZ: return "RELASZ";
2157 case DT_RELAENT: return "RELAENT";
2158 case DT_STRSZ: return "STRSZ";
2159 case DT_SYMENT: return "SYMENT";
2160 case DT_INIT: return "INIT";
2161 case DT_FINI: return "FINI";
2162 case DT_SONAME: return "SONAME";
2163 case DT_RPATH: return "RPATH";
2164 case DT_SYMBOLIC: return "SYMBOLIC";
2165 case DT_REL: return "REL";
2166 case DT_RELSZ: return "RELSZ";
2167 case DT_RELENT: return "RELENT";
2168 case DT_PLTREL: return "PLTREL";
2169 case DT_DEBUG: return "DEBUG";
2170 case DT_TEXTREL: return "TEXTREL";
2171 case DT_JMPREL: return "JMPREL";
2172 case DT_BIND_NOW: return "BIND_NOW";
2173 case DT_INIT_ARRAY: return "INIT_ARRAY";
2174 case DT_FINI_ARRAY: return "FINI_ARRAY";
2175 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2176 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2177 case DT_RUNPATH: return "RUNPATH";
2178 case DT_FLAGS: return "FLAGS";
2d0e6f43 2179
d1133906
NC
2180 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2181 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2182 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2183
05107a46 2184 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2185 case DT_PLTPADSZ: return "PLTPADSZ";
2186 case DT_MOVEENT: return "MOVEENT";
2187 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2188 case DT_FEATURE: return "FEATURE";
252b5132
RH
2189 case DT_POSFLAG_1: return "POSFLAG_1";
2190 case DT_SYMINSZ: return "SYMINSZ";
2191 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2192
252b5132 2193 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2194 case DT_CONFIG: return "CONFIG";
2195 case DT_DEPAUDIT: return "DEPAUDIT";
2196 case DT_AUDIT: return "AUDIT";
2197 case DT_PLTPAD: return "PLTPAD";
2198 case DT_MOVETAB: return "MOVETAB";
252b5132 2199 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2200
252b5132 2201 case DT_VERSYM: return "VERSYM";
103f02d3 2202
67a4f2b7
AO
2203 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2204 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2205 case DT_RELACOUNT: return "RELACOUNT";
2206 case DT_RELCOUNT: return "RELCOUNT";
2207 case DT_FLAGS_1: return "FLAGS_1";
2208 case DT_VERDEF: return "VERDEF";
2209 case DT_VERDEFNUM: return "VERDEFNUM";
2210 case DT_VERNEED: return "VERNEED";
2211 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2212
019148e4 2213 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2214 case DT_USED: return "USED";
2215 case DT_FILTER: return "FILTER";
103f02d3 2216
047b2264
JJ
2217 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2218 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2219 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2220 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2221 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2222 case DT_GNU_HASH: return "GNU_HASH";
047b2264 2223
252b5132
RH
2224 default:
2225 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2226 {
2cf0635d 2227 const char * result;
103f02d3 2228
dda8d76d 2229 switch (filedata->file_header.e_machine)
252b5132 2230 {
37c18eed
SD
2231 case EM_AARCH64:
2232 result = get_aarch64_dynamic_type (type);
2233 break;
252b5132 2234 case EM_MIPS:
4fe85591 2235 case EM_MIPS_RS3_LE:
252b5132
RH
2236 result = get_mips_dynamic_type (type);
2237 break;
9a097730
RH
2238 case EM_SPARCV9:
2239 result = get_sparc64_dynamic_type (type);
2240 break;
7490d522
AM
2241 case EM_PPC:
2242 result = get_ppc_dynamic_type (type);
2243 break;
f1cb7e17
AM
2244 case EM_PPC64:
2245 result = get_ppc64_dynamic_type (type);
2246 break;
ecc51f48
NC
2247 case EM_IA_64:
2248 result = get_ia64_dynamic_type (type);
2249 break;
fabcb361
RH
2250 case EM_ALPHA:
2251 result = get_alpha_dynamic_type (type);
2252 break;
1c0d3aa6
NC
2253 case EM_SCORE:
2254 result = get_score_dynamic_type (type);
2255 break;
40b36596
JM
2256 case EM_TI_C6000:
2257 result = get_tic6x_dynamic_type (type);
2258 break;
36591ba1
SL
2259 case EM_ALTERA_NIOS2:
2260 result = get_nios2_dynamic_type (type);
2261 break;
252b5132 2262 default:
dda8d76d 2263 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2264 result = get_solaris_dynamic_type (type);
2265 else
2266 result = NULL;
252b5132
RH
2267 break;
2268 }
2269
2270 if (result != NULL)
2271 return result;
2272
e9e44622 2273 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2274 }
eec8f817 2275 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2276 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2277 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2278 {
2cf0635d 2279 const char * result;
103f02d3 2280
dda8d76d 2281 switch (filedata->file_header.e_machine)
103f02d3
UD
2282 {
2283 case EM_PARISC:
2284 result = get_parisc_dynamic_type (type);
2285 break;
148b93f2
NC
2286 case EM_IA_64:
2287 result = get_ia64_dynamic_type (type);
2288 break;
103f02d3 2289 default:
dda8d76d 2290 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2291 result = get_solaris_dynamic_type (type);
2292 else
2293 result = NULL;
103f02d3
UD
2294 break;
2295 }
2296
2297 if (result != NULL)
2298 return result;
2299
e9e44622
JJ
2300 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2301 type);
103f02d3 2302 }
252b5132 2303 else
e9e44622 2304 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2305
252b5132
RH
2306 return buff;
2307 }
2308}
2309
2310static char *
d3ba0551 2311get_file_type (unsigned e_type)
252b5132 2312{
89246a0e 2313 static char buff[64];
252b5132
RH
2314
2315 switch (e_type)
2316 {
32ec8896
NC
2317 case ET_NONE: return _("NONE (None)");
2318 case ET_REL: return _("REL (Relocatable file)");
2319 case ET_EXEC: return _("EXEC (Executable file)");
2320 case ET_DYN: return _("DYN (Shared object file)");
2321 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2322
2323 default:
2324 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2325 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2326 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2327 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2328 else
e9e44622 2329 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2330 return buff;
2331 }
2332}
2333
2334static char *
d3ba0551 2335get_machine_name (unsigned e_machine)
252b5132 2336{
b34976b6 2337 static char buff[64]; /* XXX */
252b5132
RH
2338
2339 switch (e_machine)
2340 {
55e22ca8
NC
2341 /* Please keep this switch table sorted by increasing EM_ value. */
2342 /* 0 */
c45021f2
NC
2343 case EM_NONE: return _("None");
2344 case EM_M32: return "WE32100";
2345 case EM_SPARC: return "Sparc";
2346 case EM_386: return "Intel 80386";
2347 case EM_68K: return "MC68000";
2348 case EM_88K: return "MC88000";
22abe556 2349 case EM_IAMCU: return "Intel MCU";
fb70ec17 2350 case EM_860: return "Intel 80860";
c45021f2
NC
2351 case EM_MIPS: return "MIPS R3000";
2352 case EM_S370: return "IBM System/370";
55e22ca8 2353 /* 10 */
7036c0e1 2354 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2355 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2356 case EM_PARISC: return "HPPA";
55e22ca8 2357 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2358 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2359 case EM_960: return "Intel 80960";
c45021f2 2360 case EM_PPC: return "PowerPC";
55e22ca8 2361 /* 20 */
285d1771 2362 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2363 case EM_S390_OLD:
2364 case EM_S390: return "IBM S/390";
2365 case EM_SPU: return "SPU";
2366 /* 30 */
2367 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2368 case EM_FR20: return "Fujitsu FR20";
2369 case EM_RH32: return "TRW RH32";
b34976b6 2370 case EM_MCORE: return "MCORE";
55e22ca8 2371 /* 40 */
7036c0e1
AJ
2372 case EM_ARM: return "ARM";
2373 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2374 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2375 case EM_SPARCV9: return "Sparc v9";
2376 case EM_TRICORE: return "Siemens Tricore";
584da044 2377 case EM_ARC: return "ARC";
c2dcd04e
NC
2378 case EM_H8_300: return "Renesas H8/300";
2379 case EM_H8_300H: return "Renesas H8/300H";
2380 case EM_H8S: return "Renesas H8S";
2381 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2382 /* 50 */
30800947 2383 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2384 case EM_MIPS_X: return "Stanford MIPS-X";
2385 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2386 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2387 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2388 case EM_PCP: return "Siemens PCP";
2389 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2390 case EM_NDR1: return "Denso NDR1 microprocesspr";
2391 case EM_STARCORE: return "Motorola Star*Core processor";
2392 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2393 /* 60 */
7036c0e1
AJ
2394 case EM_ST100: return "STMicroelectronics ST100 processor";
2395 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2396 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2397 case EM_PDSP: return "Sony DSP processor";
2398 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2399 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2400 case EM_FX66: return "Siemens FX66 microcontroller";
2401 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2402 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2403 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2404 /* 70 */
7036c0e1
AJ
2405 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2406 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2407 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2408 case EM_SVX: return "Silicon Graphics SVx";
2409 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2410 case EM_VAX: return "Digital VAX";
1b61cf92 2411 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2412 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2413 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2414 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2415 /* 80 */
b34976b6 2416 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2417 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2418 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2419 case EM_AVR_OLD:
2420 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2421 case EM_CYGNUS_FR30:
2422 case EM_FR30: return "Fujitsu FR30";
2423 case EM_CYGNUS_D10V:
2424 case EM_D10V: return "d10v";
2425 case EM_CYGNUS_D30V:
2426 case EM_D30V: return "d30v";
2427 case EM_CYGNUS_V850:
2428 case EM_V850: return "Renesas V850";
2429 case EM_CYGNUS_M32R:
2430 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2431 case EM_CYGNUS_MN10300:
2432 case EM_MN10300: return "mn10300";
2433 /* 90 */
2434 case EM_CYGNUS_MN10200:
2435 case EM_MN10200: return "mn10200";
2436 case EM_PJ: return "picoJava";
73589c9d 2437 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2438 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2439 case EM_XTENSA_OLD:
2440 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2441 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2442 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2443 case EM_NS32K: return "National Semiconductor 32000 series";
2444 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2445 case EM_SNP1K: return "Trebia SNP 1000 processor";
2446 /* 100 */
9abca702 2447 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2448 case EM_IP2K_OLD:
2449 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2450 case EM_MAX: return "MAX Processor";
2451 case EM_CR: return "National Semiconductor CompactRISC";
2452 case EM_F2MC16: return "Fujitsu F2MC16";
2453 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2454 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2455 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2456 case EM_SEP: return "Sharp embedded microprocessor";
2457 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2458 /* 110 */
11636f9e
JM
2459 case EM_UNICORE: return "Unicore";
2460 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2461 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2462 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2463 case EM_CRX: return "National Semiconductor CRX microprocessor";
2464 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2465 case EM_C166:
d70c5fc7 2466 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2467 case EM_M16C: return "Renesas M16C series microprocessors";
2468 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2469 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2470 /* 120 */
2471 case EM_M32C: return "Renesas M32c";
2472 /* 130 */
11636f9e
JM
2473 case EM_TSK3000: return "Altium TSK3000 core";
2474 case EM_RS08: return "Freescale RS08 embedded processor";
2475 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2476 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2477 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2478 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2479 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2480 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2481 /* 140 */
11636f9e
JM
2482 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2483 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2484 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2485 case EM_TI_PRU: return "TI PRU I/O processor";
2486 /* 160 */
11636f9e
JM
2487 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2488 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2489 case EM_R32C: return "Renesas R32C series microprocessors";
2490 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2491 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2492 case EM_8051: return "Intel 8051 and variants";
2493 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2494 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2495 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2496 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2497 /* 170 */
11636f9e
JM
2498 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2499 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2500 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2501 case EM_RX: return "Renesas RX";
a3c62988 2502 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2503 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2504 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2505 case EM_CR16:
2506 case EM_MICROBLAZE:
2507 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2508 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2509 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2510 /* 180 */
2511 case EM_L1OM: return "Intel L1OM";
2512 case EM_K1OM: return "Intel K1OM";
2513 case EM_INTEL182: return "Intel (reserved)";
2514 case EM_AARCH64: return "AArch64";
2515 case EM_ARM184: return "ARM (reserved)";
2516 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2517 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2518 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2519 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2520 /* 190 */
11636f9e 2521 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2522 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2523 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2524 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2525 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2526 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2527 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2528 case EM_RL78: return "Renesas RL78";
6d913794 2529 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2530 case EM_78K0R: return "Renesas 78K0R";
2531 /* 200 */
6d913794 2532 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2533 case EM_BA1: return "Beyond BA1 CPU architecture";
2534 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2535 case EM_XCORE: return "XMOS xCORE processor family";
2536 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2537 /* 210 */
6d913794
NC
2538 case EM_KM32: return "KM211 KM32 32-bit processor";
2539 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2540 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2541 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2542 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2543 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2544 case EM_COGE: return "Cognitive Smart Memory Processor";
2545 case EM_COOL: return "Bluechip Systems CoolEngine";
2546 case EM_NORC: return "Nanoradio Optimized RISC";
2547 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2548 /* 220 */
15f205b1 2549 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2550 case EM_VISIUM: return "CDS VISIUMcore processor";
2551 case EM_FT32: return "FTDI Chip FT32";
2552 case EM_MOXIE: return "Moxie";
2553 case EM_AMDGPU: return "AMD GPU";
2554 case EM_RISCV: return "RISC-V";
2555 case EM_LANAI: return "Lanai 32-bit processor";
2556 case EM_BPF: return "Linux BPF";
fe944acf 2557 case EM_NFP: return "Netronome Flow Processor";
55e22ca8
NC
2558
2559 /* Large numbers... */
2560 case EM_MT: return "Morpho Techologies MT processor";
2561 case EM_ALPHA: return "Alpha";
2562 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2563 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2564 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2565 case EM_IQ2000: return "Vitesse IQ2000";
2566 case EM_M32C_OLD:
2567 case EM_NIOS32: return "Altera Nios";
2568 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2569 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2570 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2571 case EM_S12Z: return "Freescale S12Z";
b8891f8d 2572 case EM_CSKY: return "C-SKY";
55e22ca8 2573
252b5132 2574 default:
35d9dd2f 2575 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2576 return buff;
2577 }
2578}
2579
a9522a21
AB
2580static void
2581decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2582{
2583 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
2584 other compilers don't a specific architecture type in the e_flags, and
2585 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2586 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2587 architectures.
2588
2589 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2590 but also sets a specific architecture type in the e_flags field.
2591
2592 However, when decoding the flags we don't worry if we see an
2593 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2594 ARCEM architecture type. */
2595
2596 switch (e_flags & EF_ARC_MACH_MSK)
2597 {
2598 /* We only expect these to occur for EM_ARC_COMPACT2. */
2599 case EF_ARC_CPU_ARCV2EM:
2600 strcat (buf, ", ARC EM");
2601 break;
2602 case EF_ARC_CPU_ARCV2HS:
2603 strcat (buf, ", ARC HS");
2604 break;
2605
2606 /* We only expect these to occur for EM_ARC_COMPACT. */
2607 case E_ARC_MACH_ARC600:
2608 strcat (buf, ", ARC600");
2609 break;
2610 case E_ARC_MACH_ARC601:
2611 strcat (buf, ", ARC601");
2612 break;
2613 case E_ARC_MACH_ARC700:
2614 strcat (buf, ", ARC700");
2615 break;
2616
2617 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2618 new ELF with new architecture being read by an old version of
2619 readelf, or (c) An ELF built with non-GNU compiler that does not
2620 set the architecture in the e_flags. */
2621 default:
2622 if (e_machine == EM_ARC_COMPACT)
2623 strcat (buf, ", Unknown ARCompact");
2624 else
2625 strcat (buf, ", Unknown ARC");
2626 break;
2627 }
2628
2629 switch (e_flags & EF_ARC_OSABI_MSK)
2630 {
2631 case E_ARC_OSABI_ORIG:
2632 strcat (buf, ", (ABI:legacy)");
2633 break;
2634 case E_ARC_OSABI_V2:
2635 strcat (buf, ", (ABI:v2)");
2636 break;
2637 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2638 case E_ARC_OSABI_V3:
2639 strcat (buf, ", v3 no-legacy-syscalls ABI");
2640 break;
53a346d8
CZ
2641 case E_ARC_OSABI_V4:
2642 strcat (buf, ", v4 ABI");
2643 break;
a9522a21
AB
2644 default:
2645 strcat (buf, ", unrecognised ARC OSABI flag");
2646 break;
2647 }
2648}
2649
f3485b74 2650static void
d3ba0551 2651decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2652{
2653 unsigned eabi;
32ec8896 2654 bfd_boolean unknown = FALSE;
f3485b74
NC
2655
2656 eabi = EF_ARM_EABI_VERSION (e_flags);
2657 e_flags &= ~ EF_ARM_EABIMASK;
2658
2659 /* Handle "generic" ARM flags. */
2660 if (e_flags & EF_ARM_RELEXEC)
2661 {
2662 strcat (buf, ", relocatable executable");
2663 e_flags &= ~ EF_ARM_RELEXEC;
2664 }
76da6bbe 2665
18a20338
CL
2666 if (e_flags & EF_ARM_PIC)
2667 {
2668 strcat (buf, ", position independent");
2669 e_flags &= ~ EF_ARM_PIC;
2670 }
2671
f3485b74
NC
2672 /* Now handle EABI specific flags. */
2673 switch (eabi)
2674 {
2675 default:
2c71103e 2676 strcat (buf, ", <unrecognized EABI>");
f3485b74 2677 if (e_flags)
32ec8896 2678 unknown = TRUE;
f3485b74
NC
2679 break;
2680
2681 case EF_ARM_EABI_VER1:
a5bcd848 2682 strcat (buf, ", Version1 EABI");
f3485b74
NC
2683 while (e_flags)
2684 {
2685 unsigned flag;
76da6bbe 2686
f3485b74
NC
2687 /* Process flags one bit at a time. */
2688 flag = e_flags & - e_flags;
2689 e_flags &= ~ flag;
76da6bbe 2690
f3485b74
NC
2691 switch (flag)
2692 {
a5bcd848 2693 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2694 strcat (buf, ", sorted symbol tables");
2695 break;
76da6bbe 2696
f3485b74 2697 default:
32ec8896 2698 unknown = TRUE;
f3485b74
NC
2699 break;
2700 }
2701 }
2702 break;
76da6bbe 2703
a5bcd848
PB
2704 case EF_ARM_EABI_VER2:
2705 strcat (buf, ", Version2 EABI");
2706 while (e_flags)
2707 {
2708 unsigned flag;
2709
2710 /* Process flags one bit at a time. */
2711 flag = e_flags & - e_flags;
2712 e_flags &= ~ flag;
2713
2714 switch (flag)
2715 {
2716 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2717 strcat (buf, ", sorted symbol tables");
2718 break;
2719
2720 case EF_ARM_DYNSYMSUSESEGIDX:
2721 strcat (buf, ", dynamic symbols use segment index");
2722 break;
2723
2724 case EF_ARM_MAPSYMSFIRST:
2725 strcat (buf, ", mapping symbols precede others");
2726 break;
2727
2728 default:
32ec8896 2729 unknown = TRUE;
a5bcd848
PB
2730 break;
2731 }
2732 }
2733 break;
2734
d507cf36
PB
2735 case EF_ARM_EABI_VER3:
2736 strcat (buf, ", Version3 EABI");
8cb51566
PB
2737 break;
2738
2739 case EF_ARM_EABI_VER4:
2740 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2741 while (e_flags)
2742 {
2743 unsigned flag;
2744
2745 /* Process flags one bit at a time. */
2746 flag = e_flags & - e_flags;
2747 e_flags &= ~ flag;
2748
2749 switch (flag)
2750 {
2751 case EF_ARM_BE8:
2752 strcat (buf, ", BE8");
2753 break;
2754
2755 case EF_ARM_LE8:
2756 strcat (buf, ", LE8");
2757 break;
2758
2759 default:
32ec8896 2760 unknown = TRUE;
3bfcb652
NC
2761 break;
2762 }
3bfcb652
NC
2763 }
2764 break;
3a4a14e9
PB
2765
2766 case EF_ARM_EABI_VER5:
2767 strcat (buf, ", Version5 EABI");
d507cf36
PB
2768 while (e_flags)
2769 {
2770 unsigned flag;
2771
2772 /* Process flags one bit at a time. */
2773 flag = e_flags & - e_flags;
2774 e_flags &= ~ flag;
2775
2776 switch (flag)
2777 {
2778 case EF_ARM_BE8:
2779 strcat (buf, ", BE8");
2780 break;
2781
2782 case EF_ARM_LE8:
2783 strcat (buf, ", LE8");
2784 break;
2785
3bfcb652
NC
2786 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2787 strcat (buf, ", soft-float ABI");
2788 break;
2789
2790 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2791 strcat (buf, ", hard-float ABI");
2792 break;
2793
d507cf36 2794 default:
32ec8896 2795 unknown = TRUE;
d507cf36
PB
2796 break;
2797 }
2798 }
2799 break;
2800
f3485b74 2801 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2802 strcat (buf, ", GNU EABI");
f3485b74
NC
2803 while (e_flags)
2804 {
2805 unsigned flag;
76da6bbe 2806
f3485b74
NC
2807 /* Process flags one bit at a time. */
2808 flag = e_flags & - e_flags;
2809 e_flags &= ~ flag;
76da6bbe 2810
f3485b74
NC
2811 switch (flag)
2812 {
a5bcd848 2813 case EF_ARM_INTERWORK:
f3485b74
NC
2814 strcat (buf, ", interworking enabled");
2815 break;
76da6bbe 2816
a5bcd848 2817 case EF_ARM_APCS_26:
f3485b74
NC
2818 strcat (buf, ", uses APCS/26");
2819 break;
76da6bbe 2820
a5bcd848 2821 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2822 strcat (buf, ", uses APCS/float");
2823 break;
76da6bbe 2824
a5bcd848 2825 case EF_ARM_PIC:
f3485b74
NC
2826 strcat (buf, ", position independent");
2827 break;
76da6bbe 2828
a5bcd848 2829 case EF_ARM_ALIGN8:
f3485b74
NC
2830 strcat (buf, ", 8 bit structure alignment");
2831 break;
76da6bbe 2832
a5bcd848 2833 case EF_ARM_NEW_ABI:
f3485b74
NC
2834 strcat (buf, ", uses new ABI");
2835 break;
76da6bbe 2836
a5bcd848 2837 case EF_ARM_OLD_ABI:
f3485b74
NC
2838 strcat (buf, ", uses old ABI");
2839 break;
76da6bbe 2840
a5bcd848 2841 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2842 strcat (buf, ", software FP");
2843 break;
76da6bbe 2844
90e01f86
ILT
2845 case EF_ARM_VFP_FLOAT:
2846 strcat (buf, ", VFP");
2847 break;
2848
fde78edd
NC
2849 case EF_ARM_MAVERICK_FLOAT:
2850 strcat (buf, ", Maverick FP");
2851 break;
2852
f3485b74 2853 default:
32ec8896 2854 unknown = TRUE;
f3485b74
NC
2855 break;
2856 }
2857 }
2858 }
f3485b74
NC
2859
2860 if (unknown)
2b692964 2861 strcat (buf,_(", <unknown>"));
f3485b74
NC
2862}
2863
343433df
AB
2864static void
2865decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2866{
2867 --size; /* Leave space for null terminator. */
2868
2869 switch (e_flags & EF_AVR_MACH)
2870 {
2871 case E_AVR_MACH_AVR1:
2872 strncat (buf, ", avr:1", size);
2873 break;
2874 case E_AVR_MACH_AVR2:
2875 strncat (buf, ", avr:2", size);
2876 break;
2877 case E_AVR_MACH_AVR25:
2878 strncat (buf, ", avr:25", size);
2879 break;
2880 case E_AVR_MACH_AVR3:
2881 strncat (buf, ", avr:3", size);
2882 break;
2883 case E_AVR_MACH_AVR31:
2884 strncat (buf, ", avr:31", size);
2885 break;
2886 case E_AVR_MACH_AVR35:
2887 strncat (buf, ", avr:35", size);
2888 break;
2889 case E_AVR_MACH_AVR4:
2890 strncat (buf, ", avr:4", size);
2891 break;
2892 case E_AVR_MACH_AVR5:
2893 strncat (buf, ", avr:5", size);
2894 break;
2895 case E_AVR_MACH_AVR51:
2896 strncat (buf, ", avr:51", size);
2897 break;
2898 case E_AVR_MACH_AVR6:
2899 strncat (buf, ", avr:6", size);
2900 break;
2901 case E_AVR_MACH_AVRTINY:
2902 strncat (buf, ", avr:100", size);
2903 break;
2904 case E_AVR_MACH_XMEGA1:
2905 strncat (buf, ", avr:101", size);
2906 break;
2907 case E_AVR_MACH_XMEGA2:
2908 strncat (buf, ", avr:102", size);
2909 break;
2910 case E_AVR_MACH_XMEGA3:
2911 strncat (buf, ", avr:103", size);
2912 break;
2913 case E_AVR_MACH_XMEGA4:
2914 strncat (buf, ", avr:104", size);
2915 break;
2916 case E_AVR_MACH_XMEGA5:
2917 strncat (buf, ", avr:105", size);
2918 break;
2919 case E_AVR_MACH_XMEGA6:
2920 strncat (buf, ", avr:106", size);
2921 break;
2922 case E_AVR_MACH_XMEGA7:
2923 strncat (buf, ", avr:107", size);
2924 break;
2925 default:
2926 strncat (buf, ", avr:<unknown>", size);
2927 break;
2928 }
2929
2930 size -= strlen (buf);
2931 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2932 strncat (buf, ", link-relax", size);
2933}
2934
35c08157
KLC
2935static void
2936decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2937{
2938 unsigned abi;
2939 unsigned arch;
2940 unsigned config;
2941 unsigned version;
32ec8896
NC
2942 bfd_boolean has_fpu = FALSE;
2943 unsigned int r = 0;
35c08157
KLC
2944
2945 static const char *ABI_STRINGS[] =
2946 {
2947 "ABI v0", /* use r5 as return register; only used in N1213HC */
2948 "ABI v1", /* use r0 as return register */
2949 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2950 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2951 "AABI",
2952 "ABI2 FP+"
35c08157
KLC
2953 };
2954 static const char *VER_STRINGS[] =
2955 {
2956 "Andes ELF V1.3 or older",
2957 "Andes ELF V1.3.1",
2958 "Andes ELF V1.4"
2959 };
2960 static const char *ARCH_STRINGS[] =
2961 {
2962 "",
2963 "Andes Star v1.0",
2964 "Andes Star v2.0",
2965 "Andes Star v3.0",
2966 "Andes Star v3.0m"
2967 };
2968
2969 abi = EF_NDS_ABI & e_flags;
2970 arch = EF_NDS_ARCH & e_flags;
2971 config = EF_NDS_INST & e_flags;
2972 version = EF_NDS32_ELF_VERSION & e_flags;
2973
2974 memset (buf, 0, size);
2975
2976 switch (abi)
2977 {
2978 case E_NDS_ABI_V0:
2979 case E_NDS_ABI_V1:
2980 case E_NDS_ABI_V2:
2981 case E_NDS_ABI_V2FP:
2982 case E_NDS_ABI_AABI:
40c7a7cb 2983 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
2984 /* In case there are holes in the array. */
2985 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
2986 break;
2987
2988 default:
2989 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
2990 break;
2991 }
2992
2993 switch (version)
2994 {
2995 case E_NDS32_ELF_VER_1_2:
2996 case E_NDS32_ELF_VER_1_3:
2997 case E_NDS32_ELF_VER_1_4:
2998 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
2999 break;
3000
3001 default:
3002 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3003 break;
3004 }
3005
3006 if (E_NDS_ABI_V0 == abi)
3007 {
3008 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3009 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3010 if (arch == E_NDS_ARCH_STAR_V1_0)
3011 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3012 return;
3013 }
3014
3015 switch (arch)
3016 {
3017 case E_NDS_ARCH_STAR_V1_0:
3018 case E_NDS_ARCH_STAR_V2_0:
3019 case E_NDS_ARCH_STAR_V3_0:
3020 case E_NDS_ARCH_STAR_V3_M:
3021 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3022 break;
3023
3024 default:
3025 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3026 /* ARCH version determines how the e_flags are interpreted.
3027 If it is unknown, we cannot proceed. */
3028 return;
3029 }
3030
3031 /* Newer ABI; Now handle architecture specific flags. */
3032 if (arch == E_NDS_ARCH_STAR_V1_0)
3033 {
3034 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3035 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3036
3037 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3038 r += snprintf (buf + r, size -r, ", MAC");
3039
3040 if (config & E_NDS32_HAS_DIV_INST)
3041 r += snprintf (buf + r, size -r, ", DIV");
3042
3043 if (config & E_NDS32_HAS_16BIT_INST)
3044 r += snprintf (buf + r, size -r, ", 16b");
3045 }
3046 else
3047 {
3048 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3049 {
3050 if (version <= E_NDS32_ELF_VER_1_3)
3051 r += snprintf (buf + r, size -r, ", [B8]");
3052 else
3053 r += snprintf (buf + r, size -r, ", EX9");
3054 }
3055
3056 if (config & E_NDS32_HAS_MAC_DX_INST)
3057 r += snprintf (buf + r, size -r, ", MAC_DX");
3058
3059 if (config & E_NDS32_HAS_DIV_DX_INST)
3060 r += snprintf (buf + r, size -r, ", DIV_DX");
3061
3062 if (config & E_NDS32_HAS_16BIT_INST)
3063 {
3064 if (version <= E_NDS32_ELF_VER_1_3)
3065 r += snprintf (buf + r, size -r, ", 16b");
3066 else
3067 r += snprintf (buf + r, size -r, ", IFC");
3068 }
3069 }
3070
3071 if (config & E_NDS32_HAS_EXT_INST)
3072 r += snprintf (buf + r, size -r, ", PERF1");
3073
3074 if (config & E_NDS32_HAS_EXT2_INST)
3075 r += snprintf (buf + r, size -r, ", PERF2");
3076
3077 if (config & E_NDS32_HAS_FPU_INST)
3078 {
32ec8896 3079 has_fpu = TRUE;
35c08157
KLC
3080 r += snprintf (buf + r, size -r, ", FPU_SP");
3081 }
3082
3083 if (config & E_NDS32_HAS_FPU_DP_INST)
3084 {
32ec8896 3085 has_fpu = TRUE;
35c08157
KLC
3086 r += snprintf (buf + r, size -r, ", FPU_DP");
3087 }
3088
3089 if (config & E_NDS32_HAS_FPU_MAC_INST)
3090 {
32ec8896 3091 has_fpu = TRUE;
35c08157
KLC
3092 r += snprintf (buf + r, size -r, ", FPU_MAC");
3093 }
3094
3095 if (has_fpu)
3096 {
3097 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3098 {
3099 case E_NDS32_FPU_REG_8SP_4DP:
3100 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3101 break;
3102 case E_NDS32_FPU_REG_16SP_8DP:
3103 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3104 break;
3105 case E_NDS32_FPU_REG_32SP_16DP:
3106 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3107 break;
3108 case E_NDS32_FPU_REG_32SP_32DP:
3109 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3110 break;
3111 }
3112 }
3113
3114 if (config & E_NDS32_HAS_AUDIO_INST)
3115 r += snprintf (buf + r, size -r, ", AUDIO");
3116
3117 if (config & E_NDS32_HAS_STRING_INST)
3118 r += snprintf (buf + r, size -r, ", STR");
3119
3120 if (config & E_NDS32_HAS_REDUCED_REGS)
3121 r += snprintf (buf + r, size -r, ", 16REG");
3122
3123 if (config & E_NDS32_HAS_VIDEO_INST)
3124 {
3125 if (version <= E_NDS32_ELF_VER_1_3)
3126 r += snprintf (buf + r, size -r, ", VIDEO");
3127 else
3128 r += snprintf (buf + r, size -r, ", SATURATION");
3129 }
3130
3131 if (config & E_NDS32_HAS_ENCRIPT_INST)
3132 r += snprintf (buf + r, size -r, ", ENCRP");
3133
3134 if (config & E_NDS32_HAS_L2C_INST)
3135 r += snprintf (buf + r, size -r, ", L2C");
3136}
3137
252b5132 3138static char *
dda8d76d 3139get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3140{
b34976b6 3141 static char buf[1024];
252b5132
RH
3142
3143 buf[0] = '\0';
76da6bbe 3144
252b5132
RH
3145 if (e_flags)
3146 {
3147 switch (e_machine)
3148 {
3149 default:
3150 break;
3151
886a2506 3152 case EM_ARC_COMPACT2:
886a2506 3153 case EM_ARC_COMPACT:
a9522a21
AB
3154 decode_ARC_machine_flags (e_flags, e_machine, buf);
3155 break;
886a2506 3156
f3485b74
NC
3157 case EM_ARM:
3158 decode_ARM_machine_flags (e_flags, buf);
3159 break;
76da6bbe 3160
343433df
AB
3161 case EM_AVR:
3162 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3163 break;
3164
781303ce
MF
3165 case EM_BLACKFIN:
3166 if (e_flags & EF_BFIN_PIC)
3167 strcat (buf, ", PIC");
3168
3169 if (e_flags & EF_BFIN_FDPIC)
3170 strcat (buf, ", FDPIC");
3171
3172 if (e_flags & EF_BFIN_CODE_IN_L1)
3173 strcat (buf, ", code in L1");
3174
3175 if (e_flags & EF_BFIN_DATA_IN_L1)
3176 strcat (buf, ", data in L1");
3177
3178 break;
3179
ec2dfb42
AO
3180 case EM_CYGNUS_FRV:
3181 switch (e_flags & EF_FRV_CPU_MASK)
3182 {
3183 case EF_FRV_CPU_GENERIC:
3184 break;
3185
3186 default:
3187 strcat (buf, ", fr???");
3188 break;
57346661 3189
ec2dfb42
AO
3190 case EF_FRV_CPU_FR300:
3191 strcat (buf, ", fr300");
3192 break;
3193
3194 case EF_FRV_CPU_FR400:
3195 strcat (buf, ", fr400");
3196 break;
3197 case EF_FRV_CPU_FR405:
3198 strcat (buf, ", fr405");
3199 break;
3200
3201 case EF_FRV_CPU_FR450:
3202 strcat (buf, ", fr450");
3203 break;
3204
3205 case EF_FRV_CPU_FR500:
3206 strcat (buf, ", fr500");
3207 break;
3208 case EF_FRV_CPU_FR550:
3209 strcat (buf, ", fr550");
3210 break;
3211
3212 case EF_FRV_CPU_SIMPLE:
3213 strcat (buf, ", simple");
3214 break;
3215 case EF_FRV_CPU_TOMCAT:
3216 strcat (buf, ", tomcat");
3217 break;
3218 }
1c877e87 3219 break;
ec2dfb42 3220
53c7db4b 3221 case EM_68K:
425c6cb0 3222 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3223 strcat (buf, ", m68000");
425c6cb0 3224 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3225 strcat (buf, ", cpu32");
3226 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3227 strcat (buf, ", fido_a");
425c6cb0 3228 else
266abb8f 3229 {
2cf0635d
NC
3230 char const * isa = _("unknown");
3231 char const * mac = _("unknown mac");
3232 char const * additional = NULL;
0112cd26 3233
c694fd50 3234 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3235 {
c694fd50 3236 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3237 isa = "A";
3238 additional = ", nodiv";
3239 break;
c694fd50 3240 case EF_M68K_CF_ISA_A:
266abb8f
NS
3241 isa = "A";
3242 break;
c694fd50 3243 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3244 isa = "A+";
3245 break;
c694fd50 3246 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3247 isa = "B";
3248 additional = ", nousp";
3249 break;
c694fd50 3250 case EF_M68K_CF_ISA_B:
266abb8f
NS
3251 isa = "B";
3252 break;
f608cd77
NS
3253 case EF_M68K_CF_ISA_C:
3254 isa = "C";
3255 break;
3256 case EF_M68K_CF_ISA_C_NODIV:
3257 isa = "C";
3258 additional = ", nodiv";
3259 break;
266abb8f
NS
3260 }
3261 strcat (buf, ", cf, isa ");
3262 strcat (buf, isa);
0b2e31dc
NS
3263 if (additional)
3264 strcat (buf, additional);
c694fd50 3265 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3266 strcat (buf, ", float");
c694fd50 3267 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3268 {
3269 case 0:
3270 mac = NULL;
3271 break;
c694fd50 3272 case EF_M68K_CF_MAC:
266abb8f
NS
3273 mac = "mac";
3274 break;
c694fd50 3275 case EF_M68K_CF_EMAC:
266abb8f
NS
3276 mac = "emac";
3277 break;
f608cd77
NS
3278 case EF_M68K_CF_EMAC_B:
3279 mac = "emac_b";
3280 break;
266abb8f
NS
3281 }
3282 if (mac)
3283 {
3284 strcat (buf, ", ");
3285 strcat (buf, mac);
3286 }
266abb8f 3287 }
53c7db4b 3288 break;
33c63f9d 3289
153a2776
NC
3290 case EM_CYGNUS_MEP:
3291 switch (e_flags & EF_MEP_CPU_MASK)
3292 {
3293 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3294 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3295 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3296 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3297 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3298 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3299 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3300 }
3301
3302 switch (e_flags & EF_MEP_COP_MASK)
3303 {
3304 case EF_MEP_COP_NONE: break;
3305 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3306 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3307 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3308 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3309 default: strcat (buf, _("<unknown MeP copro type>")); break;
3310 }
3311
3312 if (e_flags & EF_MEP_LIBRARY)
3313 strcat (buf, ", Built for Library");
3314
3315 if (e_flags & EF_MEP_INDEX_MASK)
3316 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3317 e_flags & EF_MEP_INDEX_MASK);
3318
3319 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3320 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3321 e_flags & ~ EF_MEP_ALL_FLAGS);
3322 break;
3323
252b5132
RH
3324 case EM_PPC:
3325 if (e_flags & EF_PPC_EMB)
3326 strcat (buf, ", emb");
3327
3328 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3329 strcat (buf, _(", relocatable"));
252b5132
RH
3330
3331 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3332 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3333 break;
3334
ee67d69a
AM
3335 case EM_PPC64:
3336 if (e_flags & EF_PPC64_ABI)
3337 {
3338 char abi[] = ", abiv0";
3339
3340 abi[6] += e_flags & EF_PPC64_ABI;
3341 strcat (buf, abi);
3342 }
3343 break;
3344
708e2187
NC
3345 case EM_V800:
3346 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3347 strcat (buf, ", RH850 ABI");
0b4362b0 3348
708e2187
NC
3349 if (e_flags & EF_V800_850E3)
3350 strcat (buf, ", V3 architecture");
3351
3352 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3353 strcat (buf, ", FPU not used");
3354
3355 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3356 strcat (buf, ", regmode: COMMON");
3357
3358 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3359 strcat (buf, ", r4 not used");
3360
3361 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3362 strcat (buf, ", r30 not used");
3363
3364 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3365 strcat (buf, ", r5 not used");
3366
3367 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3368 strcat (buf, ", r2 not used");
3369
3370 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3371 {
3372 switch (e_flags & - e_flags)
3373 {
3374 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3375 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3376 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3377 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3378 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3379 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3380 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3381 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3382 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3383 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3384 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3385 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3386 default: break;
3387 }
3388 }
3389 break;
3390
2b0337b0 3391 case EM_V850:
252b5132
RH
3392 case EM_CYGNUS_V850:
3393 switch (e_flags & EF_V850_ARCH)
3394 {
78c8d46c
NC
3395 case E_V850E3V5_ARCH:
3396 strcat (buf, ", v850e3v5");
3397 break;
1cd986c5
NC
3398 case E_V850E2V3_ARCH:
3399 strcat (buf, ", v850e2v3");
3400 break;
3401 case E_V850E2_ARCH:
3402 strcat (buf, ", v850e2");
3403 break;
3404 case E_V850E1_ARCH:
3405 strcat (buf, ", v850e1");
8ad30312 3406 break;
252b5132
RH
3407 case E_V850E_ARCH:
3408 strcat (buf, ", v850e");
3409 break;
252b5132
RH
3410 case E_V850_ARCH:
3411 strcat (buf, ", v850");
3412 break;
3413 default:
2b692964 3414 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3415 break;
3416 }
3417 break;
3418
2b0337b0 3419 case EM_M32R:
252b5132
RH
3420 case EM_CYGNUS_M32R:
3421 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3422 strcat (buf, ", m32r");
252b5132
RH
3423 break;
3424
3425 case EM_MIPS:
4fe85591 3426 case EM_MIPS_RS3_LE:
252b5132
RH
3427 if (e_flags & EF_MIPS_NOREORDER)
3428 strcat (buf, ", noreorder");
3429
3430 if (e_flags & EF_MIPS_PIC)
3431 strcat (buf, ", pic");
3432
3433 if (e_flags & EF_MIPS_CPIC)
3434 strcat (buf, ", cpic");
3435
d1bdd336
TS
3436 if (e_flags & EF_MIPS_UCODE)
3437 strcat (buf, ", ugen_reserved");
3438
252b5132
RH
3439 if (e_flags & EF_MIPS_ABI2)
3440 strcat (buf, ", abi2");
3441
43521d43
TS
3442 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3443 strcat (buf, ", odk first");
3444
a5d22d2a
TS
3445 if (e_flags & EF_MIPS_32BITMODE)
3446 strcat (buf, ", 32bitmode");
3447
ba92f887
MR
3448 if (e_flags & EF_MIPS_NAN2008)
3449 strcat (buf, ", nan2008");
3450
fef1b0b3
SE
3451 if (e_flags & EF_MIPS_FP64)
3452 strcat (buf, ", fp64");
3453
156c2f8b
NC
3454 switch ((e_flags & EF_MIPS_MACH))
3455 {
3456 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3457 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3458 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3459 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3460 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3461 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3462 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3463 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3464 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3465 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3466 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3467 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3468 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3469 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3470 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3471 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3472 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3473 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3474 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3475 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3476 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3477 case 0:
3478 /* We simply ignore the field in this case to avoid confusion:
3479 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3480 extension. */
3481 break;
2b692964 3482 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3483 }
43521d43
TS
3484
3485 switch ((e_flags & EF_MIPS_ABI))
3486 {
3487 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3488 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3489 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3490 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3491 case 0:
3492 /* We simply ignore the field in this case to avoid confusion:
3493 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3494 This means it is likely to be an o32 file, but not for
3495 sure. */
3496 break;
2b692964 3497 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3498 }
3499
3500 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3501 strcat (buf, ", mdmx");
3502
3503 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3504 strcat (buf, ", mips16");
3505
df58fc94
RS
3506 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3507 strcat (buf, ", micromips");
3508
43521d43
TS
3509 switch ((e_flags & EF_MIPS_ARCH))
3510 {
3511 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3512 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3513 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3514 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3515 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3516 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3517 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3518 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3519 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3520 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3521 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3522 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3523 }
252b5132 3524 break;
351b4b40 3525
35c08157
KLC
3526 case EM_NDS32:
3527 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3528 break;
3529
fe944acf
FT
3530 case EM_NFP:
3531 switch (EF_NFP_MACH (e_flags))
3532 {
3533 case E_NFP_MACH_3200:
3534 strcat (buf, ", NFP-32xx");
3535 break;
3536 case E_NFP_MACH_6000:
3537 strcat (buf, ", NFP-6xxx");
3538 break;
3539 }
3540 break;
3541
e23eba97
NC
3542 case EM_RISCV:
3543 if (e_flags & EF_RISCV_RVC)
3544 strcat (buf, ", RVC");
2922d21d 3545
7f999549
JW
3546 if (e_flags & EF_RISCV_RVE)
3547 strcat (buf, ", RVE");
3548
2922d21d
AW
3549 switch (e_flags & EF_RISCV_FLOAT_ABI)
3550 {
3551 case EF_RISCV_FLOAT_ABI_SOFT:
3552 strcat (buf, ", soft-float ABI");
3553 break;
3554
3555 case EF_RISCV_FLOAT_ABI_SINGLE:
3556 strcat (buf, ", single-float ABI");
3557 break;
3558
3559 case EF_RISCV_FLOAT_ABI_DOUBLE:
3560 strcat (buf, ", double-float ABI");
3561 break;
3562
3563 case EF_RISCV_FLOAT_ABI_QUAD:
3564 strcat (buf, ", quad-float ABI");
3565 break;
3566 }
e23eba97
NC
3567 break;
3568
ccde1100
AO
3569 case EM_SH:
3570 switch ((e_flags & EF_SH_MACH_MASK))
3571 {
3572 case EF_SH1: strcat (buf, ", sh1"); break;
3573 case EF_SH2: strcat (buf, ", sh2"); break;
3574 case EF_SH3: strcat (buf, ", sh3"); break;
3575 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3576 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3577 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3578 case EF_SH3E: strcat (buf, ", sh3e"); break;
3579 case EF_SH4: strcat (buf, ", sh4"); break;
3580 case EF_SH5: strcat (buf, ", sh5"); break;
3581 case EF_SH2E: strcat (buf, ", sh2e"); break;
3582 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3583 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3584 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3585 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3586 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3587 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3588 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3589 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3590 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3591 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3592 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3593 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3594 }
3595
cec6a5b8
MR
3596 if (e_flags & EF_SH_PIC)
3597 strcat (buf, ", pic");
3598
3599 if (e_flags & EF_SH_FDPIC)
3600 strcat (buf, ", fdpic");
ccde1100 3601 break;
948f632f 3602
73589c9d
CS
3603 case EM_OR1K:
3604 if (e_flags & EF_OR1K_NODELAY)
3605 strcat (buf, ", no delay");
3606 break;
57346661 3607
351b4b40
RH
3608 case EM_SPARCV9:
3609 if (e_flags & EF_SPARC_32PLUS)
3610 strcat (buf, ", v8+");
3611
3612 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3613 strcat (buf, ", ultrasparcI");
3614
3615 if (e_flags & EF_SPARC_SUN_US3)
3616 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3617
3618 if (e_flags & EF_SPARC_HAL_R1)
3619 strcat (buf, ", halr1");
3620
3621 if (e_flags & EF_SPARC_LEDATA)
3622 strcat (buf, ", ledata");
3623
3624 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3625 strcat (buf, ", tso");
3626
3627 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3628 strcat (buf, ", pso");
3629
3630 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3631 strcat (buf, ", rmo");
3632 break;
7d466069 3633
103f02d3
UD
3634 case EM_PARISC:
3635 switch (e_flags & EF_PARISC_ARCH)
3636 {
3637 case EFA_PARISC_1_0:
3638 strcpy (buf, ", PA-RISC 1.0");
3639 break;
3640 case EFA_PARISC_1_1:
3641 strcpy (buf, ", PA-RISC 1.1");
3642 break;
3643 case EFA_PARISC_2_0:
3644 strcpy (buf, ", PA-RISC 2.0");
3645 break;
3646 default:
3647 break;
3648 }
3649 if (e_flags & EF_PARISC_TRAPNIL)
3650 strcat (buf, ", trapnil");
3651 if (e_flags & EF_PARISC_EXT)
3652 strcat (buf, ", ext");
3653 if (e_flags & EF_PARISC_LSB)
3654 strcat (buf, ", lsb");
3655 if (e_flags & EF_PARISC_WIDE)
3656 strcat (buf, ", wide");
3657 if (e_flags & EF_PARISC_NO_KABP)
3658 strcat (buf, ", no kabp");
3659 if (e_flags & EF_PARISC_LAZYSWAP)
3660 strcat (buf, ", lazyswap");
30800947 3661 break;
76da6bbe 3662
7d466069 3663 case EM_PJ:
2b0337b0 3664 case EM_PJ_OLD:
7d466069
ILT
3665 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3666 strcat (buf, ", new calling convention");
3667
3668 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3669 strcat (buf, ", gnu calling convention");
3670 break;
4d6ed7c8
NC
3671
3672 case EM_IA_64:
3673 if ((e_flags & EF_IA_64_ABI64))
3674 strcat (buf, ", 64-bit");
3675 else
3676 strcat (buf, ", 32-bit");
3677 if ((e_flags & EF_IA_64_REDUCEDFP))
3678 strcat (buf, ", reduced fp model");
3679 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3680 strcat (buf, ", no function descriptors, constant gp");
3681 else if ((e_flags & EF_IA_64_CONS_GP))
3682 strcat (buf, ", constant gp");
3683 if ((e_flags & EF_IA_64_ABSOLUTE))
3684 strcat (buf, ", absolute");
dda8d76d 3685 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3686 {
3687 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3688 strcat (buf, ", vms_linkages");
3689 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3690 {
3691 case EF_IA_64_VMS_COMCOD_SUCCESS:
3692 break;
3693 case EF_IA_64_VMS_COMCOD_WARNING:
3694 strcat (buf, ", warning");
3695 break;
3696 case EF_IA_64_VMS_COMCOD_ERROR:
3697 strcat (buf, ", error");
3698 break;
3699 case EF_IA_64_VMS_COMCOD_ABORT:
3700 strcat (buf, ", abort");
3701 break;
3702 default:
bee0ee85
NC
3703 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3704 e_flags & EF_IA_64_VMS_COMCOD);
3705 strcat (buf, ", <unknown>");
28f997cf
TG
3706 }
3707 }
4d6ed7c8 3708 break;
179d3252
JT
3709
3710 case EM_VAX:
3711 if ((e_flags & EF_VAX_NONPIC))
3712 strcat (buf, ", non-PIC");
3713 if ((e_flags & EF_VAX_DFLOAT))
3714 strcat (buf, ", D-Float");
3715 if ((e_flags & EF_VAX_GFLOAT))
3716 strcat (buf, ", G-Float");
3717 break;
c7927a3c 3718
619ed720
EB
3719 case EM_VISIUM:
3720 if (e_flags & EF_VISIUM_ARCH_MCM)
3721 strcat (buf, ", mcm");
3722 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3723 strcat (buf, ", mcm24");
3724 if (e_flags & EF_VISIUM_ARCH_GR6)
3725 strcat (buf, ", gr6");
3726 break;
3727
4046d87a 3728 case EM_RL78:
1740ba0c
NC
3729 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3730 {
3731 case E_FLAG_RL78_ANY_CPU: break;
3732 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3733 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3734 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3735 }
856ea05c
KP
3736 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3737 strcat (buf, ", 64-bit doubles");
4046d87a 3738 break;
0b4362b0 3739
c7927a3c
NC
3740 case EM_RX:
3741 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3742 strcat (buf, ", 64-bit doubles");
3743 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3744 strcat (buf, ", dsp");
d4cb0ea0 3745 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3746 strcat (buf, ", pid");
708e2187
NC
3747 if (e_flags & E_FLAG_RX_ABI)
3748 strcat (buf, ", RX ABI");
3525236c
NC
3749 if (e_flags & E_FLAG_RX_SINSNS_SET)
3750 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3751 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3752 if (e_flags & E_FLAG_RX_V2)
3753 strcat (buf, ", V2");
f87673e0
YS
3754 if (e_flags & E_FLAG_RX_V3)
3755 strcat (buf, ", V3");
d4cb0ea0 3756 break;
55786da2
AK
3757
3758 case EM_S390:
3759 if (e_flags & EF_S390_HIGH_GPRS)
3760 strcat (buf, ", highgprs");
d4cb0ea0 3761 break;
40b36596
JM
3762
3763 case EM_TI_C6000:
3764 if ((e_flags & EF_C6000_REL))
3765 strcat (buf, ", relocatable module");
d4cb0ea0 3766 break;
13761a11
NC
3767
3768 case EM_MSP430:
3769 strcat (buf, _(": architecture variant: "));
3770 switch (e_flags & EF_MSP430_MACH)
3771 {
3772 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3773 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3774 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3775 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3776 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3777 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3778 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3779 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3780 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3781 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3782 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3783 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3784 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3785 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3786 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3787 default:
3788 strcat (buf, _(": unknown")); break;
3789 }
3790
3791 if (e_flags & ~ EF_MSP430_MACH)
3792 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3793 break;
3794
3795 case EM_Z80:
3796 switch (e_flags & EF_Z80_MACH_MSK)
3797 {
3798 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3799 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3800 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3801 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3802 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3803 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3804 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3805 default:
3806 strcat (buf, _(", unknown")); break;
3807 }
3808 break;
252b5132
RH
3809 }
3810 }
3811
3812 return buf;
3813}
3814
252b5132 3815static const char *
dda8d76d 3816get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3817{
3818 static char buff[32];
3819
3820 switch (osabi)
3821 {
3822 case ELFOSABI_NONE: return "UNIX - System V";
3823 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3824 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3825 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3826 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3827 case ELFOSABI_AIX: return "UNIX - AIX";
3828 case ELFOSABI_IRIX: return "UNIX - IRIX";
3829 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3830 case ELFOSABI_TRU64: return "UNIX - TRU64";
3831 case ELFOSABI_MODESTO: return "Novell - Modesto";
3832 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3833 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3834 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3835 case ELFOSABI_AROS: return "AROS";
11636f9e 3836 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3837 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3838 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3839 default:
40b36596 3840 if (osabi >= 64)
dda8d76d 3841 switch (filedata->file_header.e_machine)
40b36596
JM
3842 {
3843 case EM_ARM:
3844 switch (osabi)
3845 {
3846 case ELFOSABI_ARM: return "ARM";
18a20338 3847 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3848 default:
3849 break;
3850 }
3851 break;
3852
3853 case EM_MSP430:
3854 case EM_MSP430_OLD:
619ed720 3855 case EM_VISIUM:
40b36596
JM
3856 switch (osabi)
3857 {
3858 case ELFOSABI_STANDALONE: return _("Standalone App");
3859 default:
3860 break;
3861 }
3862 break;
3863
3864 case EM_TI_C6000:
3865 switch (osabi)
3866 {
3867 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3868 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3869 default:
3870 break;
3871 }
3872 break;
3873
3874 default:
3875 break;
3876 }
e9e44622 3877 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3878 return buff;
3879 }
3880}
3881
a06ea964
NC
3882static const char *
3883get_aarch64_segment_type (unsigned long type)
3884{
3885 switch (type)
3886 {
32ec8896
NC
3887 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3888 default: return NULL;
a06ea964 3889 }
a06ea964
NC
3890}
3891
b294bdf8
MM
3892static const char *
3893get_arm_segment_type (unsigned long type)
3894{
3895 switch (type)
3896 {
32ec8896
NC
3897 case PT_ARM_EXIDX: return "EXIDX";
3898 default: return NULL;
b294bdf8 3899 }
b294bdf8
MM
3900}
3901
b4cbbe8f
AK
3902static const char *
3903get_s390_segment_type (unsigned long type)
3904{
3905 switch (type)
3906 {
3907 case PT_S390_PGSTE: return "S390_PGSTE";
3908 default: return NULL;
3909 }
3910}
3911
d3ba0551
AM
3912static const char *
3913get_mips_segment_type (unsigned long type)
252b5132
RH
3914{
3915 switch (type)
3916 {
32ec8896
NC
3917 case PT_MIPS_REGINFO: return "REGINFO";
3918 case PT_MIPS_RTPROC: return "RTPROC";
3919 case PT_MIPS_OPTIONS: return "OPTIONS";
3920 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3921 default: return NULL;
252b5132 3922 }
252b5132
RH
3923}
3924
103f02d3 3925static const char *
d3ba0551 3926get_parisc_segment_type (unsigned long type)
103f02d3
UD
3927{
3928 switch (type)
3929 {
103f02d3
UD
3930 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3931 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3932 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3933 default: return NULL;
103f02d3 3934 }
103f02d3
UD
3935}
3936
4d6ed7c8 3937static const char *
d3ba0551 3938get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3939{
3940 switch (type)
3941 {
3942 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3943 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3944 default: return NULL;
4d6ed7c8 3945 }
4d6ed7c8
NC
3946}
3947
40b36596
JM
3948static const char *
3949get_tic6x_segment_type (unsigned long type)
3950{
3951 switch (type)
3952 {
32ec8896
NC
3953 case PT_C6000_PHATTR: return "C6000_PHATTR";
3954 default: return NULL;
40b36596 3955 }
40b36596
JM
3956}
3957
df3a023b
AM
3958static const char *
3959get_hpux_segment_type (unsigned long type, unsigned e_machine)
3960{
3961 if (e_machine == EM_PARISC)
3962 switch (type)
3963 {
3964 case PT_HP_TLS: return "HP_TLS";
3965 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3966 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3967 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3968 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3969 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3970 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3971 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
3972 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
3973 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
3974 case PT_HP_PARALLEL: return "HP_PARALLEL";
3975 case PT_HP_FASTBIND: return "HP_FASTBIND";
3976 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
3977 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
3978 case PT_HP_STACK: return "HP_STACK";
3979 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
3980 default: return NULL;
3981 }
3982
3983 if (e_machine == EM_IA_64)
3984 switch (type)
3985 {
3986 case PT_HP_TLS: return "HP_TLS";
3987 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
3988 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
3989 case PT_IA_64_HP_STACK: return "HP_STACK";
3990 default: return NULL;
3991 }
3992
3993 return NULL;
3994}
3995
5522f910
NC
3996static const char *
3997get_solaris_segment_type (unsigned long type)
3998{
3999 switch (type)
4000 {
4001 case 0x6464e550: return "PT_SUNW_UNWIND";
4002 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4003 case 0x6ffffff7: return "PT_LOSUNW";
4004 case 0x6ffffffa: return "PT_SUNWBSS";
4005 case 0x6ffffffb: return "PT_SUNWSTACK";
4006 case 0x6ffffffc: return "PT_SUNWDTRACE";
4007 case 0x6ffffffd: return "PT_SUNWCAP";
4008 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4009 default: return NULL;
5522f910
NC
4010 }
4011}
4012
252b5132 4013static const char *
dda8d76d 4014get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4015{
b34976b6 4016 static char buff[32];
252b5132
RH
4017
4018 switch (p_type)
4019 {
b34976b6
AM
4020 case PT_NULL: return "NULL";
4021 case PT_LOAD: return "LOAD";
252b5132 4022 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4023 case PT_INTERP: return "INTERP";
4024 case PT_NOTE: return "NOTE";
4025 case PT_SHLIB: return "SHLIB";
4026 case PT_PHDR: return "PHDR";
13ae64f3 4027 case PT_TLS: return "TLS";
32ec8896 4028 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4029 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4030 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4031 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4032
3eba3ef3
NC
4033 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4034 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4035 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
4036
252b5132 4037 default:
df3a023b 4038 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4039 {
2cf0635d 4040 const char * result;
103f02d3 4041
dda8d76d 4042 switch (filedata->file_header.e_machine)
252b5132 4043 {
a06ea964
NC
4044 case EM_AARCH64:
4045 result = get_aarch64_segment_type (p_type);
4046 break;
b294bdf8
MM
4047 case EM_ARM:
4048 result = get_arm_segment_type (p_type);
4049 break;
252b5132 4050 case EM_MIPS:
4fe85591 4051 case EM_MIPS_RS3_LE:
252b5132
RH
4052 result = get_mips_segment_type (p_type);
4053 break;
103f02d3
UD
4054 case EM_PARISC:
4055 result = get_parisc_segment_type (p_type);
4056 break;
4d6ed7c8
NC
4057 case EM_IA_64:
4058 result = get_ia64_segment_type (p_type);
4059 break;
40b36596
JM
4060 case EM_TI_C6000:
4061 result = get_tic6x_segment_type (p_type);
4062 break;
b4cbbe8f
AK
4063 case EM_S390:
4064 case EM_S390_OLD:
4065 result = get_s390_segment_type (p_type);
4066 break;
252b5132
RH
4067 default:
4068 result = NULL;
4069 break;
4070 }
103f02d3 4071
252b5132
RH
4072 if (result != NULL)
4073 return result;
103f02d3 4074
1a9ccd70 4075 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4076 }
4077 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4078 {
df3a023b 4079 const char * result = NULL;
103f02d3 4080
df3a023b 4081 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4082 {
df3a023b
AM
4083 case ELFOSABI_GNU:
4084 case ELFOSABI_FREEBSD:
4085 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4086 {
4087 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4088 result = buff;
4089 }
103f02d3 4090 break;
df3a023b
AM
4091 case ELFOSABI_HPUX:
4092 result = get_hpux_segment_type (p_type,
4093 filedata->file_header.e_machine);
4094 break;
4095 case ELFOSABI_SOLARIS:
4096 result = get_solaris_segment_type (p_type);
00428cca 4097 break;
103f02d3 4098 default:
103f02d3
UD
4099 break;
4100 }
103f02d3
UD
4101 if (result != NULL)
4102 return result;
4103
1a9ccd70 4104 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4105 }
252b5132 4106 else
e9e44622 4107 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4108
4109 return buff;
4110 }
4111}
4112
53a346d8
CZ
4113static const char *
4114get_arc_section_type_name (unsigned int sh_type)
4115{
4116 switch (sh_type)
4117 {
4118 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4119 default:
4120 break;
4121 }
4122 return NULL;
4123}
4124
252b5132 4125static const char *
d3ba0551 4126get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4127{
4128 switch (sh_type)
4129 {
b34976b6
AM
4130 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4131 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4132 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4133 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4134 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4135 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4136 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4137 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4138 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4139 case SHT_MIPS_RELD: return "MIPS_RELD";
4140 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4141 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4142 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4143 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4144 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4145 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4146 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4147 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4148 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4149 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4150 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4151 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4152 case SHT_MIPS_LINE: return "MIPS_LINE";
4153 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4154 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4155 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4156 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4157 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4158 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4159 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4160 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4161 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4162 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4163 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4164 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4165 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4166 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4167 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4168 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4169 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4170 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4171 default:
4172 break;
4173 }
4174 return NULL;
4175}
4176
103f02d3 4177static const char *
d3ba0551 4178get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4179{
4180 switch (sh_type)
4181 {
4182 case SHT_PARISC_EXT: return "PARISC_EXT";
4183 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4184 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4185 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4186 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4187 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4188 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4189 default: return NULL;
103f02d3 4190 }
103f02d3
UD
4191}
4192
4d6ed7c8 4193static const char *
dda8d76d 4194get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4195{
18bd398b 4196 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4197 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4198 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4199
4d6ed7c8
NC
4200 switch (sh_type)
4201 {
148b93f2
NC
4202 case SHT_IA_64_EXT: return "IA_64_EXT";
4203 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4204 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4205 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4206 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4207 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4208 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4209 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4210 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4211 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4212 default:
4213 break;
4214 }
4215 return NULL;
4216}
4217
d2b2c203
DJ
4218static const char *
4219get_x86_64_section_type_name (unsigned int sh_type)
4220{
4221 switch (sh_type)
4222 {
4223 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4224 default: return NULL;
d2b2c203 4225 }
d2b2c203
DJ
4226}
4227
a06ea964
NC
4228static const char *
4229get_aarch64_section_type_name (unsigned int sh_type)
4230{
4231 switch (sh_type)
4232 {
32ec8896
NC
4233 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4234 default: return NULL;
a06ea964 4235 }
a06ea964
NC
4236}
4237
40a18ebd
NC
4238static const char *
4239get_arm_section_type_name (unsigned int sh_type)
4240{
4241 switch (sh_type)
4242 {
7f6fed87
NC
4243 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4244 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4245 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4246 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4247 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4248 default: return NULL;
40a18ebd 4249 }
40a18ebd
NC
4250}
4251
40b36596
JM
4252static const char *
4253get_tic6x_section_type_name (unsigned int sh_type)
4254{
4255 switch (sh_type)
4256 {
32ec8896
NC
4257 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4258 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4259 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4260 case SHT_TI_ICODE: return "TI_ICODE";
4261 case SHT_TI_XREF: return "TI_XREF";
4262 case SHT_TI_HANDLER: return "TI_HANDLER";
4263 case SHT_TI_INITINFO: return "TI_INITINFO";
4264 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4265 default: return NULL;
40b36596 4266 }
40b36596
JM
4267}
4268
13761a11
NC
4269static const char *
4270get_msp430x_section_type_name (unsigned int sh_type)
4271{
4272 switch (sh_type)
4273 {
32ec8896
NC
4274 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4275 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4276 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4277 default: return NULL;
13761a11
NC
4278 }
4279}
4280
fe944acf
FT
4281static const char *
4282get_nfp_section_type_name (unsigned int sh_type)
4283{
4284 switch (sh_type)
4285 {
4286 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4287 case SHT_NFP_INITREG: return "NFP_INITREG";
4288 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4289 default: return NULL;
4290 }
4291}
4292
685080f2
NC
4293static const char *
4294get_v850_section_type_name (unsigned int sh_type)
4295{
4296 switch (sh_type)
4297 {
32ec8896
NC
4298 case SHT_V850_SCOMMON: return "V850 Small Common";
4299 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4300 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4301 case SHT_RENESAS_IOP: return "RENESAS IOP";
4302 case SHT_RENESAS_INFO: return "RENESAS INFO";
4303 default: return NULL;
685080f2
NC
4304 }
4305}
4306
2dc8dd17
JW
4307static const char *
4308get_riscv_section_type_name (unsigned int sh_type)
4309{
4310 switch (sh_type)
4311 {
4312 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4313 default: return NULL;
4314 }
4315}
4316
252b5132 4317static const char *
dda8d76d 4318get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4319{
b34976b6 4320 static char buff[32];
9fb71ee4 4321 const char * result;
252b5132
RH
4322
4323 switch (sh_type)
4324 {
4325 case SHT_NULL: return "NULL";
4326 case SHT_PROGBITS: return "PROGBITS";
4327 case SHT_SYMTAB: return "SYMTAB";
4328 case SHT_STRTAB: return "STRTAB";
4329 case SHT_RELA: return "RELA";
4330 case SHT_HASH: return "HASH";
4331 case SHT_DYNAMIC: return "DYNAMIC";
4332 case SHT_NOTE: return "NOTE";
4333 case SHT_NOBITS: return "NOBITS";
4334 case SHT_REL: return "REL";
4335 case SHT_SHLIB: return "SHLIB";
4336 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4337 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4338 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4339 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4340 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4341 case SHT_GROUP: return "GROUP";
67ce483b 4342 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4343 case SHT_GNU_verdef: return "VERDEF";
4344 case SHT_GNU_verneed: return "VERNEED";
4345 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4346 case 0x6ffffff0: return "VERSYM";
4347 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4348 case 0x7ffffffd: return "AUXILIARY";
4349 case 0x7fffffff: return "FILTER";
047b2264 4350 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4351
4352 default:
4353 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4354 {
dda8d76d 4355 switch (filedata->file_header.e_machine)
252b5132 4356 {
53a346d8
CZ
4357 case EM_ARC:
4358 case EM_ARC_COMPACT:
4359 case EM_ARC_COMPACT2:
4360 result = get_arc_section_type_name (sh_type);
4361 break;
252b5132 4362 case EM_MIPS:
4fe85591 4363 case EM_MIPS_RS3_LE:
252b5132
RH
4364 result = get_mips_section_type_name (sh_type);
4365 break;
103f02d3
UD
4366 case EM_PARISC:
4367 result = get_parisc_section_type_name (sh_type);
4368 break;
4d6ed7c8 4369 case EM_IA_64:
dda8d76d 4370 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4371 break;
d2b2c203 4372 case EM_X86_64:
8a9036a4 4373 case EM_L1OM:
7a9068fe 4374 case EM_K1OM:
d2b2c203
DJ
4375 result = get_x86_64_section_type_name (sh_type);
4376 break;
a06ea964
NC
4377 case EM_AARCH64:
4378 result = get_aarch64_section_type_name (sh_type);
4379 break;
40a18ebd
NC
4380 case EM_ARM:
4381 result = get_arm_section_type_name (sh_type);
4382 break;
40b36596
JM
4383 case EM_TI_C6000:
4384 result = get_tic6x_section_type_name (sh_type);
4385 break;
13761a11
NC
4386 case EM_MSP430:
4387 result = get_msp430x_section_type_name (sh_type);
4388 break;
fe944acf
FT
4389 case EM_NFP:
4390 result = get_nfp_section_type_name (sh_type);
4391 break;
685080f2
NC
4392 case EM_V800:
4393 case EM_V850:
4394 case EM_CYGNUS_V850:
4395 result = get_v850_section_type_name (sh_type);
4396 break;
2dc8dd17
JW
4397 case EM_RISCV:
4398 result = get_riscv_section_type_name (sh_type);
4399 break;
252b5132
RH
4400 default:
4401 result = NULL;
4402 break;
4403 }
4404
4405 if (result != NULL)
4406 return result;
4407
9fb71ee4 4408 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4409 }
4410 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4411 {
dda8d76d 4412 switch (filedata->file_header.e_machine)
148b93f2
NC
4413 {
4414 case EM_IA_64:
dda8d76d 4415 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4416 break;
4417 default:
dda8d76d 4418 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4419 result = get_solaris_section_type (sh_type);
4420 else
1b4b80bf
NC
4421 {
4422 switch (sh_type)
4423 {
4424 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4425 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4426 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4427 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4428 default:
4429 result = NULL;
4430 break;
4431 }
4432 }
148b93f2
NC
4433 break;
4434 }
4435
4436 if (result != NULL)
4437 return result;
4438
9fb71ee4 4439 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4440 }
252b5132 4441 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4442 {
dda8d76d 4443 switch (filedata->file_header.e_machine)
685080f2
NC
4444 {
4445 case EM_V800:
4446 case EM_V850:
4447 case EM_CYGNUS_V850:
9fb71ee4 4448 result = get_v850_section_type_name (sh_type);
a9fb83be 4449 break;
685080f2 4450 default:
9fb71ee4 4451 result = NULL;
685080f2
NC
4452 break;
4453 }
4454
9fb71ee4
NC
4455 if (result != NULL)
4456 return result;
4457
4458 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4459 }
252b5132 4460 else
a7dbfd1c
NC
4461 /* This message is probably going to be displayed in a 15
4462 character wide field, so put the hex value first. */
4463 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4464
252b5132
RH
4465 return buff;
4466 }
4467}
4468
79bc120c
NC
4469enum long_option_values
4470{
4471 OPTION_DEBUG_DUMP = 512,
4472 OPTION_DYN_SYMS,
4473 OPTION_DWARF_DEPTH,
4474 OPTION_DWARF_START,
4475 OPTION_DWARF_CHECK,
4476 OPTION_CTF_DUMP,
4477 OPTION_CTF_PARENT,
4478 OPTION_CTF_SYMBOLS,
4479 OPTION_CTF_STRINGS,
4480 OPTION_WITH_SYMBOL_VERSIONS,
4481 OPTION_RECURSE_LIMIT,
4482 OPTION_NO_RECURSE_LIMIT,
4483 OPTION_NO_DEMANGLING
4484};
2979dc34 4485
85b1c36d 4486static struct option options[] =
252b5132 4487{
79bc120c
NC
4488 /* Note - This table is alpha-sorted on the 'val'
4489 field in order to make adding new options easier. */
4490 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4491 {"all", no_argument, 0, 'a'},
79bc120c
NC
4492 {"demangle", optional_argument, 0, 'C'},
4493 {"archive-index", no_argument, 0, 'c'},
4494 {"use-dynamic", no_argument, 0, 'D'},
4495 {"dynamic", no_argument, 0, 'd'},
b34976b6 4496 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4497 {"section-groups", no_argument, 0, 'g'},
4498 {"help", no_argument, 0, 'H'},
4499 {"file-header", no_argument, 0, 'h'},
b34976b6 4500 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4501 {"lint", no_argument, 0, 'L'},
4502 {"enable-checks", no_argument, 0, 'L'},
4503 {"program-headers", no_argument, 0, 'l'},
b34976b6 4504 {"segments", no_argument, 0, 'l'},
595cf52e 4505 {"full-section-name",no_argument, 0, 'N'},
79bc120c
NC
4506 {"notes", no_argument, 0, 'n'},
4507 {"string-dump", required_argument, 0, 'p'},
4508 {"relocated-dump", required_argument, 0, 'R'},
4509 {"relocs", no_argument, 0, 'r'},
4510 {"section-headers", no_argument, 0, 'S'},
4511 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4512 {"symbols", no_argument, 0, 's'},
4513 {"syms", no_argument, 0, 's'},
79bc120c
NC
4514 {"silent-truncation",no_argument, 0, 'T'},
4515 {"section-details", no_argument, 0, 't'},
09c11c86 4516 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4517 {"version-info", no_argument, 0, 'V'},
4518 {"version", no_argument, 0, 'v'},
4519 {"wide", no_argument, 0, 'W'},
b34976b6 4520 {"hex-dump", required_argument, 0, 'x'},
0e602686 4521 {"decompress", no_argument, 0, 'z'},
252b5132 4522
79bc120c
NC
4523 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4524 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4525 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4526 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4527 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
4528 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4529 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4530 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4531 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4532#ifdef ENABLE_LIBCTF
d344b407 4533 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4534 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4535 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4536 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4537#endif
7d9813f1 4538
b34976b6 4539 {0, no_argument, 0, 0}
252b5132
RH
4540};
4541
4542static void
2cf0635d 4543usage (FILE * stream)
252b5132 4544{
92f01d61
JM
4545 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4546 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4547 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4548 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4549 -h --file-header Display the ELF file header\n\
4550 -l --program-headers Display the program headers\n\
4551 --segments An alias for --program-headers\n\
4552 -S --section-headers Display the sections' header\n\
4553 --sections An alias for --section-headers\n\
f5842774 4554 -g --section-groups Display the section groups\n\
5477e8a0 4555 -t --section-details Display the section details\n\
8b53311e
NC
4556 -e --headers Equivalent to: -h -l -S\n\
4557 -s --syms Display the symbol table\n\
3f08eb35 4558 --symbols An alias for --syms\n\
1b513401 4559 --dyn-syms Display the dynamic symbol table\n\
79bc120c
NC
4560 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4561 The STYLE, if specified, can be `auto' (the default),\n\
4562 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
4563 or `gnat'\n\
4564 --no-demangle Do not demangle low-level symbol names. (This is the default)\n\
4565 --recurse-limit Enable a demangling recursion limit. (This is the default)\n\
4566 --no-recurse-limit Disable a demangling recursion limit\n\
8b53311e
NC
4567 -n --notes Display the core notes (if present)\n\
4568 -r --relocs Display the relocations (if present)\n\
4569 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4570 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4571 -V --version-info Display the version sections (if present)\n\
1b31d05e 4572 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4573 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4574 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4575 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4576 -x --hex-dump=<number|name>\n\
4577 Dump the contents of section <number|name> as bytes\n\
4578 -p --string-dump=<number|name>\n\
4579 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4580 -R --relocated-dump=<number|name>\n\
4581 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4582 -z --decompress Decompress section before dumping it\n\
e4b7104b 4583 -w[lLiaprmfFsoORtUuTgAckK] or\n\
1ed06042 4584 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
e4b7104b 4585 =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
657d0d47 4586 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4587 =addr,=cu_index,=links,=follow-links]\n\
4588 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4589 fprintf (stream, _("\
4590 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4591 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4592 or deeper\n"));
094e34f2 4593#ifdef ENABLE_LIBCTF
7d9813f1
NA
4594 fprintf (stream, _("\
4595 --ctf=<number|name> Display CTF info from section <number|name>\n\
4596 --ctf-parent=<number|name>\n\
4597 Use section <number|name> as the CTF parent\n\n\
4598 --ctf-symbols=<number|name>\n\
4599 Use section <number|name> as the CTF external symtab\n\n\
4600 --ctf-strings=<number|name>\n\
4601 Use section <number|name> as the CTF external strtab\n\n"));
094e34f2 4602#endif
7d9813f1 4603
252b5132 4604#ifdef SUPPORT_DISASSEMBLY
92f01d61 4605 fprintf (stream, _("\
09c11c86
NC
4606 -i --instruction-dump=<number|name>\n\
4607 Disassemble the contents of section <number|name>\n"));
252b5132 4608#endif
92f01d61 4609 fprintf (stream, _("\
8b53311e
NC
4610 -I --histogram Display histogram of bucket list lengths\n\
4611 -W --wide Allow output width to exceed 80 characters\n\
0942c7ab 4612 -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
07012eee 4613 @<file> Read options from <file>\n\
8b53311e
NC
4614 -H --help Display this information\n\
4615 -v --version Display the version number of readelf\n"));
1118d252 4616
92f01d61
JM
4617 if (REPORT_BUGS_TO[0] && stream == stdout)
4618 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4619
92f01d61 4620 exit (stream == stdout ? 0 : 1);
252b5132
RH
4621}
4622
18bd398b
NC
4623/* Record the fact that the user wants the contents of section number
4624 SECTION to be displayed using the method(s) encoded as flags bits
4625 in TYPE. Note, TYPE can be zero if we are creating the array for
4626 the first time. */
4627
252b5132 4628static void
6431e409
AM
4629request_dump_bynumber (struct dump_data *dumpdata,
4630 unsigned int section, dump_type type)
252b5132 4631{
6431e409 4632 if (section >= dumpdata->num_dump_sects)
252b5132 4633 {
2cf0635d 4634 dump_type * new_dump_sects;
252b5132 4635
3f5e193b 4636 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4637 sizeof (* new_dump_sects));
252b5132
RH
4638
4639 if (new_dump_sects == NULL)
591a748a 4640 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4641 else
4642 {
6431e409 4643 if (dumpdata->dump_sects)
21b65bac
NC
4644 {
4645 /* Copy current flag settings. */
6431e409
AM
4646 memcpy (new_dump_sects, dumpdata->dump_sects,
4647 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4648
6431e409 4649 free (dumpdata->dump_sects);
21b65bac 4650 }
252b5132 4651
6431e409
AM
4652 dumpdata->dump_sects = new_dump_sects;
4653 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4654 }
4655 }
4656
6431e409
AM
4657 if (dumpdata->dump_sects)
4658 dumpdata->dump_sects[section] |= type;
252b5132
RH
4659}
4660
aef1f6d0
DJ
4661/* Request a dump by section name. */
4662
4663static void
2cf0635d 4664request_dump_byname (const char * section, dump_type type)
aef1f6d0 4665{
2cf0635d 4666 struct dump_list_entry * new_request;
aef1f6d0 4667
3f5e193b
NC
4668 new_request = (struct dump_list_entry *)
4669 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4670 if (!new_request)
591a748a 4671 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4672
4673 new_request->name = strdup (section);
4674 if (!new_request->name)
591a748a 4675 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4676
4677 new_request->type = type;
4678
4679 new_request->next = dump_sects_byname;
4680 dump_sects_byname = new_request;
4681}
4682
cf13d699 4683static inline void
6431e409 4684request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4685{
4686 int section;
4687 char * cp;
4688
4689 do_dump++;
4690 section = strtoul (optarg, & cp, 0);
4691
4692 if (! *cp && section >= 0)
6431e409 4693 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4694 else
4695 request_dump_byname (optarg, type);
4696}
4697
252b5132 4698static void
6431e409 4699parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4700{
4701 int c;
4702
4703 if (argc < 2)
92f01d61 4704 usage (stderr);
252b5132
RH
4705
4706 while ((c = getopt_long
79bc120c 4707 (argc, argv, "ACDHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4708 {
252b5132
RH
4709 switch (c)
4710 {
4711 case 0:
4712 /* Long options. */
4713 break;
4714 case 'H':
92f01d61 4715 usage (stdout);
252b5132
RH
4716 break;
4717
4718 case 'a':
32ec8896
NC
4719 do_syms = TRUE;
4720 do_reloc = TRUE;
4721 do_unwind = TRUE;
4722 do_dynamic = TRUE;
4723 do_header = TRUE;
4724 do_sections = TRUE;
4725 do_section_groups = TRUE;
4726 do_segments = TRUE;
4727 do_version = TRUE;
4728 do_histogram = TRUE;
4729 do_arch = TRUE;
4730 do_notes = TRUE;
252b5132 4731 break;
79bc120c 4732
f5842774 4733 case 'g':
32ec8896 4734 do_section_groups = TRUE;
f5842774 4735 break;
5477e8a0 4736 case 't':
595cf52e 4737 case 'N':
32ec8896
NC
4738 do_sections = TRUE;
4739 do_section_details = TRUE;
595cf52e 4740 break;
252b5132 4741 case 'e':
32ec8896
NC
4742 do_header = TRUE;
4743 do_sections = TRUE;
4744 do_segments = TRUE;
252b5132 4745 break;
a952a375 4746 case 'A':
32ec8896 4747 do_arch = TRUE;
a952a375 4748 break;
252b5132 4749 case 'D':
32ec8896 4750 do_using_dynamic = TRUE;
252b5132
RH
4751 break;
4752 case 'r':
32ec8896 4753 do_reloc = TRUE;
252b5132 4754 break;
4d6ed7c8 4755 case 'u':
32ec8896 4756 do_unwind = TRUE;
4d6ed7c8 4757 break;
252b5132 4758 case 'h':
32ec8896 4759 do_header = TRUE;
252b5132
RH
4760 break;
4761 case 'l':
32ec8896 4762 do_segments = TRUE;
252b5132
RH
4763 break;
4764 case 's':
32ec8896 4765 do_syms = TRUE;
252b5132
RH
4766 break;
4767 case 'S':
32ec8896 4768 do_sections = TRUE;
252b5132
RH
4769 break;
4770 case 'd':
32ec8896 4771 do_dynamic = TRUE;
252b5132 4772 break;
a952a375 4773 case 'I':
32ec8896 4774 do_histogram = TRUE;
a952a375 4775 break;
779fe533 4776 case 'n':
32ec8896 4777 do_notes = TRUE;
779fe533 4778 break;
4145f1d5 4779 case 'c':
32ec8896 4780 do_archive_index = TRUE;
4145f1d5 4781 break;
1b513401
NC
4782 case 'L':
4783 do_checks = TRUE;
4784 break;
252b5132 4785 case 'x':
6431e409 4786 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4787 break;
09c11c86 4788 case 'p':
6431e409 4789 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4790 break;
4791 case 'R':
6431e409 4792 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4793 break;
0e602686 4794 case 'z':
32ec8896 4795 decompress_dumps = TRUE;
0e602686 4796 break;
252b5132 4797 case 'w':
32ec8896 4798 do_dump = TRUE;
252b5132 4799 if (optarg == 0)
613ff48b 4800 {
32ec8896 4801 do_debugging = TRUE;
613ff48b
CC
4802 dwarf_select_sections_all ();
4803 }
252b5132
RH
4804 else
4805 {
32ec8896 4806 do_debugging = FALSE;
4cb93e3b 4807 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4808 }
4809 break;
2979dc34 4810 case OPTION_DEBUG_DUMP:
32ec8896 4811 do_dump = TRUE;
2979dc34 4812 if (optarg == 0)
32ec8896 4813 do_debugging = TRUE;
2979dc34
JJ
4814 else
4815 {
32ec8896 4816 do_debugging = FALSE;
4cb93e3b 4817 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4818 }
4819 break;
fd2f0033
TT
4820 case OPTION_DWARF_DEPTH:
4821 {
4822 char *cp;
4823
4824 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4825 }
4826 break;
4827 case OPTION_DWARF_START:
4828 {
4829 char *cp;
4830
4831 dwarf_start_die = strtoul (optarg, & cp, 0);
4832 }
4833 break;
4723351a 4834 case OPTION_DWARF_CHECK:
32ec8896 4835 dwarf_check = TRUE;
4723351a 4836 break;
7d9813f1
NA
4837 case OPTION_CTF_DUMP:
4838 do_ctf = TRUE;
6431e409 4839 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4840 break;
4841 case OPTION_CTF_SYMBOLS:
df16e041 4842 free (dump_ctf_symtab_name);
7d9813f1
NA
4843 dump_ctf_symtab_name = strdup (optarg);
4844 break;
4845 case OPTION_CTF_STRINGS:
df16e041 4846 free (dump_ctf_strtab_name);
7d9813f1
NA
4847 dump_ctf_strtab_name = strdup (optarg);
4848 break;
4849 case OPTION_CTF_PARENT:
df16e041 4850 free (dump_ctf_parent_name);
7d9813f1
NA
4851 dump_ctf_parent_name = strdup (optarg);
4852 break;
2c610e4b 4853 case OPTION_DYN_SYMS:
32ec8896 4854 do_dyn_syms = TRUE;
2c610e4b 4855 break;
252b5132
RH
4856#ifdef SUPPORT_DISASSEMBLY
4857 case 'i':
6431e409 4858 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4859 break;
252b5132
RH
4860#endif
4861 case 'v':
4862 print_version (program_name);
4863 break;
4864 case 'V':
32ec8896 4865 do_version = TRUE;
252b5132 4866 break;
d974e256 4867 case 'W':
32ec8896 4868 do_wide = TRUE;
d974e256 4869 break;
0942c7ab
NC
4870 case 'T':
4871 do_not_show_symbol_truncation = TRUE;
4872 break;
79bc120c
NC
4873 case 'C':
4874 do_demangle = TRUE;
4875 if (optarg != NULL)
4876 {
4877 enum demangling_styles style;
4878
4879 style = cplus_demangle_name_to_style (optarg);
4880 if (style == unknown_demangling)
4881 error (_("unknown demangling style `%s'"), optarg);
4882
4883 cplus_demangle_set_style (style);
4884 }
4885 break;
4886 case OPTION_NO_DEMANGLING:
4887 do_demangle = FALSE;
4888 break;
4889 case OPTION_RECURSE_LIMIT:
4890 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
4891 break;
4892 case OPTION_NO_RECURSE_LIMIT:
4893 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
4894 break;
4895 case OPTION_WITH_SYMBOL_VERSIONS:
4896 /* Ignored for backward compatibility. */
4897 break;
4898
252b5132 4899 default:
252b5132
RH
4900 /* xgettext:c-format */
4901 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4902 /* Fall through. */
252b5132 4903 case '?':
92f01d61 4904 usage (stderr);
252b5132
RH
4905 }
4906 }
4907
4d6ed7c8 4908 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4909 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4910 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4911 && !do_section_groups && !do_archive_index
4912 && !do_dyn_syms)
1b513401
NC
4913 {
4914 if (do_checks)
4915 {
4916 check_all = TRUE;
4917 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = TRUE;
4918 do_segments = do_header = do_dump = do_version = TRUE;
4919 do_histogram = do_debugging = do_arch = do_notes = TRUE;
4920 do_section_groups = do_archive_index = do_dyn_syms = TRUE;
4921 }
4922 else
4923 usage (stderr);
4924 }
252b5132
RH
4925}
4926
4927static const char *
d3ba0551 4928get_elf_class (unsigned int elf_class)
252b5132 4929{
b34976b6 4930 static char buff[32];
103f02d3 4931
252b5132
RH
4932 switch (elf_class)
4933 {
4934 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4935 case ELFCLASS32: return "ELF32";
4936 case ELFCLASS64: return "ELF64";
ab5e7794 4937 default:
e9e44622 4938 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4939 return buff;
252b5132
RH
4940 }
4941}
4942
4943static const char *
d3ba0551 4944get_data_encoding (unsigned int encoding)
252b5132 4945{
b34976b6 4946 static char buff[32];
103f02d3 4947
252b5132
RH
4948 switch (encoding)
4949 {
4950 case ELFDATANONE: return _("none");
33c63f9d
CM
4951 case ELFDATA2LSB: return _("2's complement, little endian");
4952 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4953 default:
e9e44622 4954 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4955 return buff;
252b5132
RH
4956 }
4957}
4958
dda8d76d 4959/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4960
32ec8896 4961static bfd_boolean
dda8d76d 4962process_file_header (Filedata * filedata)
252b5132 4963{
dda8d76d
NC
4964 Elf_Internal_Ehdr * header = & filedata->file_header;
4965
4966 if ( header->e_ident[EI_MAG0] != ELFMAG0
4967 || header->e_ident[EI_MAG1] != ELFMAG1
4968 || header->e_ident[EI_MAG2] != ELFMAG2
4969 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4970 {
4971 error
4972 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4973 return FALSE;
252b5132
RH
4974 }
4975
955ff7fc 4976 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 4977
252b5132
RH
4978 if (do_header)
4979 {
32ec8896 4980 unsigned i;
252b5132
RH
4981
4982 printf (_("ELF Header:\n"));
4983 printf (_(" Magic: "));
b34976b6 4984 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4985 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4986 printf ("\n");
4987 printf (_(" Class: %s\n"),
dda8d76d 4988 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4989 printf (_(" Data: %s\n"),
dda8d76d 4990 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 4991 printf (_(" Version: %d%s\n"),
dda8d76d
NC
4992 header->e_ident[EI_VERSION],
4993 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 4994 ? _(" (current)")
dda8d76d 4995 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 4996 ? _(" <unknown>")
789be9f7 4997 : "")));
252b5132 4998 printf (_(" OS/ABI: %s\n"),
dda8d76d 4999 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5000 printf (_(" ABI Version: %d\n"),
dda8d76d 5001 header->e_ident[EI_ABIVERSION]);
252b5132 5002 printf (_(" Type: %s\n"),
dda8d76d 5003 get_file_type (header->e_type));
252b5132 5004 printf (_(" Machine: %s\n"),
dda8d76d 5005 get_machine_name (header->e_machine));
252b5132 5006 printf (_(" Version: 0x%lx\n"),
e8a64888 5007 header->e_version);
76da6bbe 5008
f7a99963 5009 printf (_(" Entry point address: "));
e8a64888 5010 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5011 printf (_("\n Start of program headers: "));
e8a64888 5012 print_vma (header->e_phoff, DEC);
f7a99963 5013 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5014 print_vma (header->e_shoff, DEC);
f7a99963 5015 printf (_(" (bytes into file)\n"));
76da6bbe 5016
252b5132 5017 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5018 header->e_flags,
dda8d76d 5019 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5020 printf (_(" Size of this header: %u (bytes)\n"),
5021 header->e_ehsize);
5022 printf (_(" Size of program headers: %u (bytes)\n"),
5023 header->e_phentsize);
5024 printf (_(" Number of program headers: %u"),
5025 header->e_phnum);
dda8d76d
NC
5026 if (filedata->section_headers != NULL
5027 && header->e_phnum == PN_XNUM
5028 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5029 {
5030 header->e_phnum = filedata->section_headers[0].sh_info;
5031 printf (" (%u)", header->e_phnum);
5032 }
2046a35d 5033 putc ('\n', stdout);
e8a64888
AM
5034 printf (_(" Size of section headers: %u (bytes)\n"),
5035 header->e_shentsize);
5036 printf (_(" Number of section headers: %u"),
5037 header->e_shnum);
dda8d76d 5038 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5039 {
5040 header->e_shnum = filedata->section_headers[0].sh_size;
5041 printf (" (%u)", header->e_shnum);
5042 }
560f3c1c 5043 putc ('\n', stdout);
e8a64888
AM
5044 printf (_(" Section header string table index: %u"),
5045 header->e_shstrndx);
dda8d76d
NC
5046 if (filedata->section_headers != NULL
5047 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5048 {
5049 header->e_shstrndx = filedata->section_headers[0].sh_link;
5050 printf (" (%u)", header->e_shstrndx);
5051 }
5052 if (header->e_shstrndx != SHN_UNDEF
5053 && header->e_shstrndx >= header->e_shnum)
5054 {
5055 header->e_shstrndx = SHN_UNDEF;
5056 printf (_(" <corrupt: out of range>"));
5057 }
560f3c1c
AM
5058 putc ('\n', stdout);
5059 }
5060
dda8d76d 5061 if (filedata->section_headers != NULL)
560f3c1c 5062 {
dda8d76d
NC
5063 if (header->e_phnum == PN_XNUM
5064 && filedata->section_headers[0].sh_info != 0)
5065 header->e_phnum = filedata->section_headers[0].sh_info;
5066 if (header->e_shnum == SHN_UNDEF)
5067 header->e_shnum = filedata->section_headers[0].sh_size;
5068 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5069 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5070 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5071 header->e_shstrndx = SHN_UNDEF;
5072 free (filedata->section_headers);
5073 filedata->section_headers = NULL;
252b5132 5074 }
103f02d3 5075
32ec8896 5076 return TRUE;
9ea033b2
NC
5077}
5078
dda8d76d
NC
5079/* Read in the program headers from FILEDATA and store them in PHEADERS.
5080 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5081
e0a31db1 5082static bfd_boolean
dda8d76d 5083get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5084{
2cf0635d
NC
5085 Elf32_External_Phdr * phdrs;
5086 Elf32_External_Phdr * external;
5087 Elf_Internal_Phdr * internal;
b34976b6 5088 unsigned int i;
dda8d76d
NC
5089 unsigned int size = filedata->file_header.e_phentsize;
5090 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5091
5092 /* PR binutils/17531: Cope with unexpected section header sizes. */
5093 if (size == 0 || num == 0)
5094 return FALSE;
5095 if (size < sizeof * phdrs)
5096 {
5097 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5098 return FALSE;
5099 }
5100 if (size > sizeof * phdrs)
5101 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5102
dda8d76d 5103 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5104 size, num, _("program headers"));
5105 if (phdrs == NULL)
5106 return FALSE;
9ea033b2 5107
91d6fa6a 5108 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5109 i < filedata->file_header.e_phnum;
b34976b6 5110 i++, internal++, external++)
252b5132 5111 {
9ea033b2
NC
5112 internal->p_type = BYTE_GET (external->p_type);
5113 internal->p_offset = BYTE_GET (external->p_offset);
5114 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5115 internal->p_paddr = BYTE_GET (external->p_paddr);
5116 internal->p_filesz = BYTE_GET (external->p_filesz);
5117 internal->p_memsz = BYTE_GET (external->p_memsz);
5118 internal->p_flags = BYTE_GET (external->p_flags);
5119 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5120 }
5121
9ea033b2 5122 free (phdrs);
e0a31db1 5123 return TRUE;
252b5132
RH
5124}
5125
dda8d76d
NC
5126/* Read in the program headers from FILEDATA and store them in PHEADERS.
5127 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5128
e0a31db1 5129static bfd_boolean
dda8d76d 5130get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5131{
2cf0635d
NC
5132 Elf64_External_Phdr * phdrs;
5133 Elf64_External_Phdr * external;
5134 Elf_Internal_Phdr * internal;
b34976b6 5135 unsigned int i;
dda8d76d
NC
5136 unsigned int size = filedata->file_header.e_phentsize;
5137 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5138
5139 /* PR binutils/17531: Cope with unexpected section header sizes. */
5140 if (size == 0 || num == 0)
5141 return FALSE;
5142 if (size < sizeof * phdrs)
5143 {
5144 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5145 return FALSE;
5146 }
5147 if (size > sizeof * phdrs)
5148 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5149
dda8d76d 5150 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5151 size, num, _("program headers"));
a6e9f9df 5152 if (!phdrs)
e0a31db1 5153 return FALSE;
9ea033b2 5154
91d6fa6a 5155 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5156 i < filedata->file_header.e_phnum;
b34976b6 5157 i++, internal++, external++)
9ea033b2
NC
5158 {
5159 internal->p_type = BYTE_GET (external->p_type);
5160 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5161 internal->p_offset = BYTE_GET (external->p_offset);
5162 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5163 internal->p_paddr = BYTE_GET (external->p_paddr);
5164 internal->p_filesz = BYTE_GET (external->p_filesz);
5165 internal->p_memsz = BYTE_GET (external->p_memsz);
5166 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5167 }
5168
5169 free (phdrs);
e0a31db1 5170 return TRUE;
9ea033b2 5171}
252b5132 5172
32ec8896 5173/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5174
32ec8896 5175static bfd_boolean
dda8d76d 5176get_program_headers (Filedata * filedata)
d93f0186 5177{
2cf0635d 5178 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5179
5180 /* Check cache of prior read. */
dda8d76d 5181 if (filedata->program_headers != NULL)
32ec8896 5182 return TRUE;
d93f0186 5183
82156ab7
NC
5184 /* Be kind to memory checkers by looking for
5185 e_phnum values which we know must be invalid. */
dda8d76d 5186 if (filedata->file_header.e_phnum
82156ab7 5187 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5188 >= filedata->file_size)
82156ab7
NC
5189 {
5190 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5191 filedata->file_header.e_phnum);
82156ab7
NC
5192 return FALSE;
5193 }
d93f0186 5194
dda8d76d 5195 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5196 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5197 if (phdrs == NULL)
5198 {
8b73c356 5199 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5200 filedata->file_header.e_phnum);
32ec8896 5201 return FALSE;
d93f0186
NC
5202 }
5203
5204 if (is_32bit_elf
dda8d76d
NC
5205 ? get_32bit_program_headers (filedata, phdrs)
5206 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5207 {
dda8d76d 5208 filedata->program_headers = phdrs;
32ec8896 5209 return TRUE;
d93f0186
NC
5210 }
5211
5212 free (phdrs);
32ec8896 5213 return FALSE;
d93f0186
NC
5214}
5215
32ec8896 5216/* Returns TRUE if the program headers were loaded. */
2f62977e 5217
32ec8896 5218static bfd_boolean
dda8d76d 5219process_program_headers (Filedata * filedata)
252b5132 5220{
2cf0635d 5221 Elf_Internal_Phdr * segment;
b34976b6 5222 unsigned int i;
1a9ccd70 5223 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5224
978c4450
AM
5225 filedata->dynamic_addr = 0;
5226 filedata->dynamic_size = 0;
663f67df 5227
dda8d76d 5228 if (filedata->file_header.e_phnum == 0)
252b5132 5229 {
82f2dbf7 5230 /* PR binutils/12467. */
dda8d76d 5231 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5232 {
5233 warn (_("possibly corrupt ELF header - it has a non-zero program"
5234 " header offset, but no program headers\n"));
5235 return FALSE;
5236 }
82f2dbf7 5237 else if (do_segments)
252b5132 5238 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5239 return TRUE;
252b5132
RH
5240 }
5241
5242 if (do_segments && !do_header)
5243 {
dda8d76d
NC
5244 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5245 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5246 printf (ngettext ("There is %d program header, starting at offset %s\n",
5247 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5248 filedata->file_header.e_phnum),
5249 filedata->file_header.e_phnum,
5250 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5251 }
5252
dda8d76d 5253 if (! get_program_headers (filedata))
6b4bf3bc 5254 return TRUE;
103f02d3 5255
252b5132
RH
5256 if (do_segments)
5257 {
dda8d76d 5258 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5259 printf (_("\nProgram Headers:\n"));
5260 else
5261 printf (_("\nProgram Headers:\n"));
76da6bbe 5262
f7a99963
NC
5263 if (is_32bit_elf)
5264 printf
5265 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5266 else if (do_wide)
5267 printf
5268 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5269 else
5270 {
5271 printf
5272 (_(" Type Offset VirtAddr PhysAddr\n"));
5273 printf
5274 (_(" FileSiz MemSiz Flags Align\n"));
5275 }
252b5132
RH
5276 }
5277
dda8d76d
NC
5278 for (i = 0, segment = filedata->program_headers;
5279 i < filedata->file_header.e_phnum;
b34976b6 5280 i++, segment++)
252b5132
RH
5281 {
5282 if (do_segments)
5283 {
dda8d76d 5284 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5285
5286 if (is_32bit_elf)
5287 {
5288 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5289 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5290 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5291 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5292 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5293 printf ("%c%c%c ",
5294 (segment->p_flags & PF_R ? 'R' : ' '),
5295 (segment->p_flags & PF_W ? 'W' : ' '),
5296 (segment->p_flags & PF_X ? 'E' : ' '));
5297 printf ("%#lx", (unsigned long) segment->p_align);
5298 }
d974e256
JJ
5299 else if (do_wide)
5300 {
5301 if ((unsigned long) segment->p_offset == segment->p_offset)
5302 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5303 else
5304 {
5305 print_vma (segment->p_offset, FULL_HEX);
5306 putchar (' ');
5307 }
5308
5309 print_vma (segment->p_vaddr, FULL_HEX);
5310 putchar (' ');
5311 print_vma (segment->p_paddr, FULL_HEX);
5312 putchar (' ');
5313
5314 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5315 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5316 else
5317 {
5318 print_vma (segment->p_filesz, FULL_HEX);
5319 putchar (' ');
5320 }
5321
5322 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5323 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5324 else
5325 {
f48e6c45 5326 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5327 }
5328
5329 printf (" %c%c%c ",
5330 (segment->p_flags & PF_R ? 'R' : ' '),
5331 (segment->p_flags & PF_W ? 'W' : ' '),
5332 (segment->p_flags & PF_X ? 'E' : ' '));
5333
5334 if ((unsigned long) segment->p_align == segment->p_align)
5335 printf ("%#lx", (unsigned long) segment->p_align);
5336 else
5337 {
5338 print_vma (segment->p_align, PREFIX_HEX);
5339 }
5340 }
f7a99963
NC
5341 else
5342 {
5343 print_vma (segment->p_offset, FULL_HEX);
5344 putchar (' ');
5345 print_vma (segment->p_vaddr, FULL_HEX);
5346 putchar (' ');
5347 print_vma (segment->p_paddr, FULL_HEX);
5348 printf ("\n ");
5349 print_vma (segment->p_filesz, FULL_HEX);
5350 putchar (' ');
5351 print_vma (segment->p_memsz, FULL_HEX);
5352 printf (" %c%c%c ",
5353 (segment->p_flags & PF_R ? 'R' : ' '),
5354 (segment->p_flags & PF_W ? 'W' : ' '),
5355 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5356 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5357 }
252b5132 5358
1a9ccd70
NC
5359 putc ('\n', stdout);
5360 }
f54498b4 5361
252b5132
RH
5362 switch (segment->p_type)
5363 {
1a9ccd70 5364 case PT_LOAD:
502d895c
NC
5365#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5366 required by the ELF standard, several programs, including the Linux
5367 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5368 if (previous_load
5369 && previous_load->p_vaddr > segment->p_vaddr)
5370 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5371#endif
1a9ccd70
NC
5372 if (segment->p_memsz < segment->p_filesz)
5373 error (_("the segment's file size is larger than its memory size\n"));
5374 previous_load = segment;
5375 break;
5376
5377 case PT_PHDR:
5378 /* PR 20815 - Verify that the program header is loaded into memory. */
5379 if (i > 0 && previous_load != NULL)
5380 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5381 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5382 {
5383 unsigned int j;
5384
dda8d76d 5385 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5386 {
5387 Elf_Internal_Phdr *load = filedata->program_headers + j;
5388 if (load->p_type == PT_LOAD
5389 && load->p_offset <= segment->p_offset
5390 && (load->p_offset + load->p_filesz
5391 >= segment->p_offset + segment->p_filesz)
5392 && load->p_vaddr <= segment->p_vaddr
5393 && (load->p_vaddr + load->p_filesz
5394 >= segment->p_vaddr + segment->p_filesz))
5395 break;
5396 }
dda8d76d 5397 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5398 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5399 }
5400 break;
5401
252b5132 5402 case PT_DYNAMIC:
978c4450 5403 if (filedata->dynamic_addr)
252b5132
RH
5404 error (_("more than one dynamic segment\n"));
5405
20737c13
AM
5406 /* By default, assume that the .dynamic section is the first
5407 section in the DYNAMIC segment. */
978c4450
AM
5408 filedata->dynamic_addr = segment->p_offset;
5409 filedata->dynamic_size = segment->p_filesz;
20737c13 5410
b2d38a17
NC
5411 /* Try to locate the .dynamic section. If there is
5412 a section header table, we can easily locate it. */
dda8d76d 5413 if (filedata->section_headers != NULL)
b2d38a17 5414 {
2cf0635d 5415 Elf_Internal_Shdr * sec;
b2d38a17 5416
dda8d76d 5417 sec = find_section (filedata, ".dynamic");
89fac5e3 5418 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5419 {
28f997cf
TG
5420 /* A corresponding .dynamic section is expected, but on
5421 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5422 if (!is_ia64_vms (filedata))
28f997cf 5423 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5424 break;
5425 }
5426
42bb2e33 5427 if (sec->sh_type == SHT_NOBITS)
20737c13 5428 {
978c4450 5429 filedata->dynamic_size = 0;
20737c13
AM
5430 break;
5431 }
42bb2e33 5432
978c4450
AM
5433 filedata->dynamic_addr = sec->sh_offset;
5434 filedata->dynamic_size = sec->sh_size;
b2d38a17 5435
8ac10c5b
L
5436 /* The PT_DYNAMIC segment, which is used by the run-time
5437 loader, should exactly match the .dynamic section. */
5438 if (do_checks
5439 && (filedata->dynamic_addr != segment->p_offset
5440 || filedata->dynamic_size != segment->p_filesz))
5441 warn (_("\
5442the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5443 }
39e224f6
MW
5444
5445 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5446 segment. Check this after matching against the section headers
5447 so we don't warn on debuginfo file (which have NOBITS .dynamic
5448 sections). */
978c4450
AM
5449 if (filedata->dynamic_addr > filedata->file_size
5450 || (filedata->dynamic_size
5451 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5452 {
5453 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5454 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5455 }
252b5132
RH
5456 break;
5457
5458 case PT_INTERP:
978c4450
AM
5459 if (fseek (filedata->handle,
5460 filedata->archive_file_offset + (long) segment->p_offset,
fb52b2f4 5461 SEEK_SET))
252b5132
RH
5462 error (_("Unable to find program interpreter name\n"));
5463 else
5464 {
f8eae8b2 5465 char fmt [32];
9495b2e6 5466 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5467
5468 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5469 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5470
978c4450
AM
5471 filedata->program_interpreter[0] = 0;
5472 if (fscanf (filedata->handle, fmt,
5473 filedata->program_interpreter) <= 0)
7bd7b3ef 5474 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5475
5476 if (do_segments)
f54498b4 5477 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5478 filedata->program_interpreter);
252b5132
RH
5479 }
5480 break;
5481 }
252b5132
RH
5482 }
5483
dda8d76d
NC
5484 if (do_segments
5485 && filedata->section_headers != NULL
5486 && filedata->string_table != NULL)
252b5132
RH
5487 {
5488 printf (_("\n Section to Segment mapping:\n"));
5489 printf (_(" Segment Sections...\n"));
5490
dda8d76d 5491 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5492 {
9ad5cbcf 5493 unsigned int j;
2cf0635d 5494 Elf_Internal_Shdr * section;
252b5132 5495
dda8d76d
NC
5496 segment = filedata->program_headers + i;
5497 section = filedata->section_headers + 1;
252b5132
RH
5498
5499 printf (" %2.2d ", i);
5500
dda8d76d 5501 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5502 {
f4638467
AM
5503 if (!ELF_TBSS_SPECIAL (section, segment)
5504 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5505 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5506 }
5507
5508 putc ('\n',stdout);
5509 }
5510 }
5511
32ec8896 5512 return TRUE;
252b5132
RH
5513}
5514
5515
d93f0186
NC
5516/* Find the file offset corresponding to VMA by using the program headers. */
5517
5518static long
dda8d76d 5519offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5520{
2cf0635d 5521 Elf_Internal_Phdr * seg;
d93f0186 5522
dda8d76d 5523 if (! get_program_headers (filedata))
d93f0186
NC
5524 {
5525 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5526 return (long) vma;
5527 }
5528
dda8d76d
NC
5529 for (seg = filedata->program_headers;
5530 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5531 ++seg)
5532 {
5533 if (seg->p_type != PT_LOAD)
5534 continue;
5535
5536 if (vma >= (seg->p_vaddr & -seg->p_align)
5537 && vma + size <= seg->p_vaddr + seg->p_filesz)
5538 return vma - seg->p_vaddr + seg->p_offset;
5539 }
5540
5541 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5542 (unsigned long) vma);
d93f0186
NC
5543 return (long) vma;
5544}
5545
5546
dda8d76d
NC
5547/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5548 If PROBE is true, this is just a probe and we do not generate any error
5549 messages if the load fails. */
049b0c3a
NC
5550
5551static bfd_boolean
dda8d76d 5552get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5553{
2cf0635d
NC
5554 Elf32_External_Shdr * shdrs;
5555 Elf_Internal_Shdr * internal;
dda8d76d
NC
5556 unsigned int i;
5557 unsigned int size = filedata->file_header.e_shentsize;
5558 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5559
5560 /* PR binutils/17531: Cope with unexpected section header sizes. */
5561 if (size == 0 || num == 0)
5562 return FALSE;
5563 if (size < sizeof * shdrs)
5564 {
5565 if (! probe)
5566 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5567 return FALSE;
5568 }
5569 if (!probe && size > sizeof * shdrs)
5570 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5571
dda8d76d 5572 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5573 size, num,
5574 probe ? NULL : _("section headers"));
5575 if (shdrs == NULL)
5576 return FALSE;
252b5132 5577
dda8d76d
NC
5578 free (filedata->section_headers);
5579 filedata->section_headers = (Elf_Internal_Shdr *)
5580 cmalloc (num, sizeof (Elf_Internal_Shdr));
5581 if (filedata->section_headers == NULL)
252b5132 5582 {
049b0c3a 5583 if (!probe)
8b73c356 5584 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5585 free (shdrs);
049b0c3a 5586 return FALSE;
252b5132
RH
5587 }
5588
dda8d76d 5589 for (i = 0, internal = filedata->section_headers;
560f3c1c 5590 i < num;
b34976b6 5591 i++, internal++)
252b5132
RH
5592 {
5593 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5594 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5595 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5596 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5597 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5598 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5599 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5600 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5601 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5602 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5603 if (!probe && internal->sh_link > num)
5604 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5605 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5606 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5607 }
5608
5609 free (shdrs);
049b0c3a 5610 return TRUE;
252b5132
RH
5611}
5612
dda8d76d
NC
5613/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5614
049b0c3a 5615static bfd_boolean
dda8d76d 5616get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5617{
dda8d76d
NC
5618 Elf64_External_Shdr * shdrs;
5619 Elf_Internal_Shdr * internal;
5620 unsigned int i;
5621 unsigned int size = filedata->file_header.e_shentsize;
5622 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5623
5624 /* PR binutils/17531: Cope with unexpected section header sizes. */
5625 if (size == 0 || num == 0)
5626 return FALSE;
dda8d76d 5627
049b0c3a
NC
5628 if (size < sizeof * shdrs)
5629 {
5630 if (! probe)
5631 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5632 return FALSE;
5633 }
dda8d76d 5634
049b0c3a
NC
5635 if (! probe && size > sizeof * shdrs)
5636 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5637
dda8d76d
NC
5638 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5639 filedata->file_header.e_shoff,
049b0c3a
NC
5640 size, num,
5641 probe ? NULL : _("section headers"));
5642 if (shdrs == NULL)
5643 return FALSE;
9ea033b2 5644
dda8d76d
NC
5645 free (filedata->section_headers);
5646 filedata->section_headers = (Elf_Internal_Shdr *)
5647 cmalloc (num, sizeof (Elf_Internal_Shdr));
5648 if (filedata->section_headers == NULL)
9ea033b2 5649 {
049b0c3a 5650 if (! probe)
8b73c356 5651 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5652 free (shdrs);
049b0c3a 5653 return FALSE;
9ea033b2
NC
5654 }
5655
dda8d76d 5656 for (i = 0, internal = filedata->section_headers;
560f3c1c 5657 i < num;
b34976b6 5658 i++, internal++)
9ea033b2
NC
5659 {
5660 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5661 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5662 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5663 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5664 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5665 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5666 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5667 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5668 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5669 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5670 if (!probe && internal->sh_link > num)
5671 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5672 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5673 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5674 }
5675
5676 free (shdrs);
049b0c3a 5677 return TRUE;
9ea033b2
NC
5678}
5679
252b5132 5680static Elf_Internal_Sym *
dda8d76d
NC
5681get_32bit_elf_symbols (Filedata * filedata,
5682 Elf_Internal_Shdr * section,
5683 unsigned long * num_syms_return)
252b5132 5684{
ba5cdace 5685 unsigned long number = 0;
dd24e3da 5686 Elf32_External_Sym * esyms = NULL;
ba5cdace 5687 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5688 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5689 Elf_Internal_Sym * psym;
b34976b6 5690 unsigned int j;
e3d39609 5691 elf_section_list * entry;
252b5132 5692
c9c1d674
EG
5693 if (section->sh_size == 0)
5694 {
5695 if (num_syms_return != NULL)
5696 * num_syms_return = 0;
5697 return NULL;
5698 }
5699
dd24e3da 5700 /* Run some sanity checks first. */
c9c1d674 5701 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5702 {
c9c1d674 5703 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5704 printable_section_name (filedata, section),
5705 (unsigned long) section->sh_entsize);
ba5cdace 5706 goto exit_point;
dd24e3da
NC
5707 }
5708
dda8d76d 5709 if (section->sh_size > filedata->file_size)
f54498b4
NC
5710 {
5711 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5712 printable_section_name (filedata, section),
5713 (unsigned long) section->sh_size);
f54498b4
NC
5714 goto exit_point;
5715 }
5716
dd24e3da
NC
5717 number = section->sh_size / section->sh_entsize;
5718
5719 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5720 {
c9c1d674 5721 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5722 (unsigned long) section->sh_size,
dda8d76d 5723 printable_section_name (filedata, section),
8066deb1 5724 (unsigned long) section->sh_entsize);
ba5cdace 5725 goto exit_point;
dd24e3da
NC
5726 }
5727
dda8d76d 5728 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5729 section->sh_size, _("symbols"));
dd24e3da 5730 if (esyms == NULL)
ba5cdace 5731 goto exit_point;
252b5132 5732
e3d39609 5733 shndx = NULL;
978c4450 5734 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5735 {
5736 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5737 continue;
5738
5739 if (shndx != NULL)
5740 {
5741 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5742 free (shndx);
5743 }
5744
5745 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5746 entry->hdr->sh_offset,
5747 1, entry->hdr->sh_size,
5748 _("symbol table section indices"));
5749 if (shndx == NULL)
5750 goto exit_point;
5751
5752 /* PR17531: file: heap-buffer-overflow */
5753 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5754 {
5755 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5756 printable_section_name (filedata, entry->hdr),
5757 (unsigned long) entry->hdr->sh_size,
5758 (unsigned long) section->sh_size);
5759 goto exit_point;
c9c1d674 5760 }
e3d39609 5761 }
9ad5cbcf 5762
3f5e193b 5763 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5764
5765 if (isyms == NULL)
5766 {
8b73c356
NC
5767 error (_("Out of memory reading %lu symbols\n"),
5768 (unsigned long) number);
dd24e3da 5769 goto exit_point;
252b5132
RH
5770 }
5771
dd24e3da 5772 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5773 {
5774 psym->st_name = BYTE_GET (esyms[j].st_name);
5775 psym->st_value = BYTE_GET (esyms[j].st_value);
5776 psym->st_size = BYTE_GET (esyms[j].st_size);
5777 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5778 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5779 psym->st_shndx
5780 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5781 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5782 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5783 psym->st_info = BYTE_GET (esyms[j].st_info);
5784 psym->st_other = BYTE_GET (esyms[j].st_other);
5785 }
5786
dd24e3da 5787 exit_point:
e3d39609
NC
5788 free (shndx);
5789 free (esyms);
252b5132 5790
ba5cdace
NC
5791 if (num_syms_return != NULL)
5792 * num_syms_return = isyms == NULL ? 0 : number;
5793
252b5132
RH
5794 return isyms;
5795}
5796
9ea033b2 5797static Elf_Internal_Sym *
dda8d76d
NC
5798get_64bit_elf_symbols (Filedata * filedata,
5799 Elf_Internal_Shdr * section,
5800 unsigned long * num_syms_return)
9ea033b2 5801{
ba5cdace
NC
5802 unsigned long number = 0;
5803 Elf64_External_Sym * esyms = NULL;
5804 Elf_External_Sym_Shndx * shndx = NULL;
5805 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5806 Elf_Internal_Sym * psym;
b34976b6 5807 unsigned int j;
e3d39609 5808 elf_section_list * entry;
9ea033b2 5809
c9c1d674
EG
5810 if (section->sh_size == 0)
5811 {
5812 if (num_syms_return != NULL)
5813 * num_syms_return = 0;
5814 return NULL;
5815 }
5816
dd24e3da 5817 /* Run some sanity checks first. */
c9c1d674 5818 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5819 {
c9c1d674 5820 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5821 printable_section_name (filedata, section),
8066deb1 5822 (unsigned long) section->sh_entsize);
ba5cdace 5823 goto exit_point;
dd24e3da
NC
5824 }
5825
dda8d76d 5826 if (section->sh_size > filedata->file_size)
f54498b4
NC
5827 {
5828 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5829 printable_section_name (filedata, section),
8066deb1 5830 (unsigned long) section->sh_size);
f54498b4
NC
5831 goto exit_point;
5832 }
5833
dd24e3da
NC
5834 number = section->sh_size / section->sh_entsize;
5835
5836 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5837 {
c9c1d674 5838 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5839 (unsigned long) section->sh_size,
dda8d76d 5840 printable_section_name (filedata, section),
8066deb1 5841 (unsigned long) section->sh_entsize);
ba5cdace 5842 goto exit_point;
dd24e3da
NC
5843 }
5844
dda8d76d 5845 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5846 section->sh_size, _("symbols"));
a6e9f9df 5847 if (!esyms)
ba5cdace 5848 goto exit_point;
9ea033b2 5849
e3d39609 5850 shndx = NULL;
978c4450 5851 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5852 {
5853 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5854 continue;
5855
5856 if (shndx != NULL)
5857 {
5858 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5859 free (shndx);
c9c1d674 5860 }
e3d39609
NC
5861
5862 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5863 entry->hdr->sh_offset,
5864 1, entry->hdr->sh_size,
5865 _("symbol table section indices"));
5866 if (shndx == NULL)
5867 goto exit_point;
5868
5869 /* PR17531: file: heap-buffer-overflow */
5870 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5871 {
5872 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5873 printable_section_name (filedata, entry->hdr),
5874 (unsigned long) entry->hdr->sh_size,
5875 (unsigned long) section->sh_size);
5876 goto exit_point;
5877 }
5878 }
9ad5cbcf 5879
3f5e193b 5880 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5881
5882 if (isyms == NULL)
5883 {
8b73c356
NC
5884 error (_("Out of memory reading %lu symbols\n"),
5885 (unsigned long) number);
ba5cdace 5886 goto exit_point;
9ea033b2
NC
5887 }
5888
ba5cdace 5889 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5890 {
5891 psym->st_name = BYTE_GET (esyms[j].st_name);
5892 psym->st_info = BYTE_GET (esyms[j].st_info);
5893 psym->st_other = BYTE_GET (esyms[j].st_other);
5894 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5895
4fbb74a6 5896 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5897 psym->st_shndx
5898 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5899 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5900 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5901
66543521
AM
5902 psym->st_value = BYTE_GET (esyms[j].st_value);
5903 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5904 }
5905
ba5cdace 5906 exit_point:
e3d39609
NC
5907 free (shndx);
5908 free (esyms);
ba5cdace
NC
5909
5910 if (num_syms_return != NULL)
5911 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5912
5913 return isyms;
5914}
5915
d1133906 5916static const char *
dda8d76d 5917get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5918{
5477e8a0 5919 static char buff[1024];
2cf0635d 5920 char * p = buff;
32ec8896
NC
5921 unsigned int field_size = is_32bit_elf ? 8 : 16;
5922 signed int sindex;
5923 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5924 bfd_vma os_flags = 0;
5925 bfd_vma proc_flags = 0;
5926 bfd_vma unknown_flags = 0;
148b93f2 5927 static const struct
5477e8a0 5928 {
2cf0635d 5929 const char * str;
32ec8896 5930 unsigned int len;
5477e8a0
L
5931 }
5932 flags [] =
5933 {
cfcac11d
NC
5934 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5935 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5936 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5937 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5938 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5939 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5940 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5941 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5942 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5943 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5944 /* IA-64 specific. */
5945 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5946 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5947 /* IA-64 OpenVMS specific. */
5948 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5949 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5950 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5951 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5952 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5953 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5954 /* Generic. */
cfcac11d 5955 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5956 /* SPARC specific. */
77115a4a 5957 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5958 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5959 /* ARM specific. */
5960 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5961 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5962 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5963 /* GNU specific. */
5964 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5965 /* VLE specific. */
5966 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5967 };
5968
5969 if (do_section_details)
5970 {
8d5ff12c
L
5971 sprintf (buff, "[%*.*lx]: ",
5972 field_size, field_size, (unsigned long) sh_flags);
5973 p += field_size + 4;
5477e8a0 5974 }
76da6bbe 5975
d1133906
NC
5976 while (sh_flags)
5977 {
5978 bfd_vma flag;
5979
5980 flag = sh_flags & - sh_flags;
5981 sh_flags &= ~ flag;
76da6bbe 5982
5477e8a0 5983 if (do_section_details)
d1133906 5984 {
5477e8a0
L
5985 switch (flag)
5986 {
91d6fa6a
NC
5987 case SHF_WRITE: sindex = 0; break;
5988 case SHF_ALLOC: sindex = 1; break;
5989 case SHF_EXECINSTR: sindex = 2; break;
5990 case SHF_MERGE: sindex = 3; break;
5991 case SHF_STRINGS: sindex = 4; break;
5992 case SHF_INFO_LINK: sindex = 5; break;
5993 case SHF_LINK_ORDER: sindex = 6; break;
5994 case SHF_OS_NONCONFORMING: sindex = 7; break;
5995 case SHF_GROUP: sindex = 8; break;
5996 case SHF_TLS: sindex = 9; break;
18ae9cc1 5997 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5998 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5999 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 6000
5477e8a0 6001 default:
91d6fa6a 6002 sindex = -1;
dda8d76d 6003 switch (filedata->file_header.e_machine)
148b93f2 6004 {
cfcac11d 6005 case EM_IA_64:
148b93f2 6006 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6007 sindex = 10;
148b93f2 6008 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6009 sindex = 11;
148b93f2 6010#ifdef BFD64
dda8d76d 6011 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6012 switch (flag)
6013 {
91d6fa6a
NC
6014 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6015 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6016 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6017 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6018 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6019 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6020 default: break;
6021 }
6022#endif
cfcac11d
NC
6023 break;
6024
caa83f8b 6025 case EM_386:
22abe556 6026 case EM_IAMCU:
caa83f8b 6027 case EM_X86_64:
7f502d6c 6028 case EM_L1OM:
7a9068fe 6029 case EM_K1OM:
cfcac11d
NC
6030 case EM_OLD_SPARCV9:
6031 case EM_SPARC32PLUS:
6032 case EM_SPARCV9:
6033 case EM_SPARC:
18ae9cc1 6034 if (flag == SHF_ORDERED)
91d6fa6a 6035 sindex = 19;
cfcac11d 6036 break;
ac4c9b04
MG
6037
6038 case EM_ARM:
6039 switch (flag)
6040 {
6041 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6042 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6043 case SHF_COMDEF: sindex = 23; break;
6044 default: break;
6045 }
6046 break;
83eef883
AFB
6047 case EM_PPC:
6048 if (flag == SHF_PPC_VLE)
6049 sindex = 25;
6050 break;
ac4c9b04 6051
cfcac11d
NC
6052 default:
6053 break;
148b93f2 6054 }
5477e8a0
L
6055 }
6056
91d6fa6a 6057 if (sindex != -1)
5477e8a0 6058 {
8d5ff12c
L
6059 if (p != buff + field_size + 4)
6060 {
6061 if (size < (10 + 2))
bee0ee85
NC
6062 {
6063 warn (_("Internal error: not enough buffer room for section flag info"));
6064 return _("<unknown>");
6065 }
8d5ff12c
L
6066 size -= 2;
6067 *p++ = ',';
6068 *p++ = ' ';
6069 }
6070
91d6fa6a
NC
6071 size -= flags [sindex].len;
6072 p = stpcpy (p, flags [sindex].str);
5477e8a0 6073 }
3b22753a 6074 else if (flag & SHF_MASKOS)
8d5ff12c 6075 os_flags |= flag;
d1133906 6076 else if (flag & SHF_MASKPROC)
8d5ff12c 6077 proc_flags |= flag;
d1133906 6078 else
8d5ff12c 6079 unknown_flags |= flag;
5477e8a0
L
6080 }
6081 else
6082 {
6083 switch (flag)
6084 {
6085 case SHF_WRITE: *p = 'W'; break;
6086 case SHF_ALLOC: *p = 'A'; break;
6087 case SHF_EXECINSTR: *p = 'X'; break;
6088 case SHF_MERGE: *p = 'M'; break;
6089 case SHF_STRINGS: *p = 'S'; break;
6090 case SHF_INFO_LINK: *p = 'I'; break;
6091 case SHF_LINK_ORDER: *p = 'L'; break;
6092 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6093 case SHF_GROUP: *p = 'G'; break;
6094 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6095 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6096 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 6097 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
6098
6099 default:
dda8d76d
NC
6100 if ((filedata->file_header.e_machine == EM_X86_64
6101 || filedata->file_header.e_machine == EM_L1OM
6102 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6103 && flag == SHF_X86_64_LARGE)
6104 *p = 'l';
dda8d76d 6105 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6106 && flag == SHF_ARM_PURECODE)
91f68a68 6107 *p = 'y';
dda8d76d 6108 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
6109 && flag == SHF_PPC_VLE)
6110 *p = 'v';
5477e8a0
L
6111 else if (flag & SHF_MASKOS)
6112 {
6113 *p = 'o';
6114 sh_flags &= ~ SHF_MASKOS;
6115 }
6116 else if (flag & SHF_MASKPROC)
6117 {
6118 *p = 'p';
6119 sh_flags &= ~ SHF_MASKPROC;
6120 }
6121 else
6122 *p = 'x';
6123 break;
6124 }
6125 p++;
d1133906
NC
6126 }
6127 }
76da6bbe 6128
8d5ff12c
L
6129 if (do_section_details)
6130 {
6131 if (os_flags)
6132 {
6133 size -= 5 + field_size;
6134 if (p != buff + field_size + 4)
6135 {
6136 if (size < (2 + 1))
bee0ee85
NC
6137 {
6138 warn (_("Internal error: not enough buffer room for section flag info"));
6139 return _("<unknown>");
6140 }
8d5ff12c
L
6141 size -= 2;
6142 *p++ = ',';
6143 *p++ = ' ';
6144 }
6145 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6146 (unsigned long) os_flags);
6147 p += 5 + field_size;
6148 }
6149 if (proc_flags)
6150 {
6151 size -= 7 + field_size;
6152 if (p != buff + field_size + 4)
6153 {
6154 if (size < (2 + 1))
bee0ee85
NC
6155 {
6156 warn (_("Internal error: not enough buffer room for section flag info"));
6157 return _("<unknown>");
6158 }
8d5ff12c
L
6159 size -= 2;
6160 *p++ = ',';
6161 *p++ = ' ';
6162 }
6163 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6164 (unsigned long) proc_flags);
6165 p += 7 + field_size;
6166 }
6167 if (unknown_flags)
6168 {
6169 size -= 10 + field_size;
6170 if (p != buff + field_size + 4)
6171 {
6172 if (size < (2 + 1))
bee0ee85
NC
6173 {
6174 warn (_("Internal error: not enough buffer room for section flag info"));
6175 return _("<unknown>");
6176 }
8d5ff12c
L
6177 size -= 2;
6178 *p++ = ',';
6179 *p++ = ' ';
6180 }
2b692964 6181 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6182 (unsigned long) unknown_flags);
6183 p += 10 + field_size;
6184 }
6185 }
6186
e9e44622 6187 *p = '\0';
d1133906
NC
6188 return buff;
6189}
6190
5844b465 6191static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6192get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6193{
6194 if (is_32bit_elf)
6195 {
6196 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6197
ebdf1ebf
NC
6198 if (size < sizeof (* echdr))
6199 {
6200 error (_("Compressed section is too small even for a compression header\n"));
6201 return 0;
6202 }
6203
77115a4a
L
6204 chdr->ch_type = BYTE_GET (echdr->ch_type);
6205 chdr->ch_size = BYTE_GET (echdr->ch_size);
6206 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6207 return sizeof (*echdr);
6208 }
6209 else
6210 {
6211 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6212
ebdf1ebf
NC
6213 if (size < sizeof (* echdr))
6214 {
6215 error (_("Compressed section is too small even for a compression header\n"));
6216 return 0;
6217 }
6218
77115a4a
L
6219 chdr->ch_type = BYTE_GET (echdr->ch_type);
6220 chdr->ch_size = BYTE_GET (echdr->ch_size);
6221 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6222 return sizeof (*echdr);
6223 }
6224}
6225
32ec8896 6226static bfd_boolean
dda8d76d 6227process_section_headers (Filedata * filedata)
252b5132 6228{
2cf0635d 6229 Elf_Internal_Shdr * section;
b34976b6 6230 unsigned int i;
252b5132 6231
8fb879cd 6232 free (filedata->section_headers);
dda8d76d 6233 filedata->section_headers = NULL;
978c4450
AM
6234 free (filedata->dynamic_symbols);
6235 filedata->dynamic_symbols = NULL;
6236 filedata->num_dynamic_syms = 0;
6237 free (filedata->dynamic_strings);
6238 filedata->dynamic_strings = NULL;
6239 filedata->dynamic_strings_length = 0;
6240 free (filedata->dynamic_syminfo);
6241 filedata->dynamic_syminfo = NULL;
6242 while (filedata->symtab_shndx_list != NULL)
8ff66993 6243 {
978c4450
AM
6244 elf_section_list *next = filedata->symtab_shndx_list->next;
6245 free (filedata->symtab_shndx_list);
6246 filedata->symtab_shndx_list = next;
8ff66993 6247 }
252b5132 6248
dda8d76d 6249 if (filedata->file_header.e_shnum == 0)
252b5132 6250 {
82f2dbf7 6251 /* PR binutils/12467. */
dda8d76d 6252 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6253 {
6254 warn (_("possibly corrupt ELF file header - it has a non-zero"
6255 " section header offset, but no section headers\n"));
6256 return FALSE;
6257 }
82f2dbf7 6258 else if (do_sections)
252b5132
RH
6259 printf (_("\nThere are no sections in this file.\n"));
6260
32ec8896 6261 return TRUE;
252b5132
RH
6262 }
6263
6264 if (do_sections && !do_header)
d3a49aa8
AM
6265 printf (ngettext ("There is %d section header, "
6266 "starting at offset 0x%lx:\n",
6267 "There are %d section headers, "
6268 "starting at offset 0x%lx:\n",
dda8d76d
NC
6269 filedata->file_header.e_shnum),
6270 filedata->file_header.e_shnum,
6271 (unsigned long) filedata->file_header.e_shoff);
252b5132 6272
9ea033b2
NC
6273 if (is_32bit_elf)
6274 {
dda8d76d 6275 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6276 return FALSE;
6277 }
6278 else
6279 {
dda8d76d 6280 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6281 return FALSE;
9ea033b2 6282 }
252b5132
RH
6283
6284 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6285 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6286 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6287 {
dda8d76d 6288 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6289
c256ffe7
JJ
6290 if (section->sh_size != 0)
6291 {
dda8d76d
NC
6292 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6293 1, section->sh_size,
6294 _("string table"));
0de14b54 6295
dda8d76d 6296 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6297 }
252b5132
RH
6298 }
6299
6300 /* Scan the sections for the dynamic symbol table
e3c8793a 6301 and dynamic string table and debug sections. */
89fac5e3 6302 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6303 switch (filedata->file_header.e_machine)
89fac5e3
RS
6304 {
6305 case EM_MIPS:
6306 case EM_MIPS_RS3_LE:
6307 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6308 FDE addresses. However, the ABI also has a semi-official ILP32
6309 variant for which the normal FDE address size rules apply.
6310
6311 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6312 section, where XX is the size of longs in bits. Unfortunately,
6313 earlier compilers provided no way of distinguishing ILP32 objects
6314 from LP64 objects, so if there's any doubt, we should assume that
6315 the official LP64 form is being used. */
dda8d76d
NC
6316 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6317 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6318 eh_addr_size = 8;
6319 break;
0f56a26a
DD
6320
6321 case EM_H8_300:
6322 case EM_H8_300H:
dda8d76d 6323 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6324 {
6325 case E_H8_MACH_H8300:
6326 case E_H8_MACH_H8300HN:
6327 case E_H8_MACH_H8300SN:
6328 case E_H8_MACH_H8300SXN:
6329 eh_addr_size = 2;
6330 break;
6331 case E_H8_MACH_H8300H:
6332 case E_H8_MACH_H8300S:
6333 case E_H8_MACH_H8300SX:
6334 eh_addr_size = 4;
6335 break;
6336 }
f4236fe4
DD
6337 break;
6338
ff7eeb89 6339 case EM_M32C_OLD:
f4236fe4 6340 case EM_M32C:
dda8d76d 6341 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6342 {
6343 case EF_M32C_CPU_M16C:
6344 eh_addr_size = 2;
6345 break;
6346 }
6347 break;
89fac5e3
RS
6348 }
6349
76ca31c0
NC
6350#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6351 do \
6352 { \
6353 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6354 if (section->sh_entsize != expected_entsize) \
9dd3a467 6355 { \
76ca31c0
NC
6356 char buf[40]; \
6357 sprintf_vma (buf, section->sh_entsize); \
6358 /* Note: coded this way so that there is a single string for \
6359 translation. */ \
6360 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6361 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6362 (unsigned) expected_entsize); \
9dd3a467 6363 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6364 } \
6365 } \
08d8fa11 6366 while (0)
9dd3a467
NC
6367
6368#define CHECK_ENTSIZE(section, i, type) \
1b513401 6369 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6370 sizeof (Elf64_External_##type))
6371
dda8d76d
NC
6372 for (i = 0, section = filedata->section_headers;
6373 i < filedata->file_header.e_shnum;
b34976b6 6374 i++, section++)
252b5132 6375 {
2cf0635d 6376 char * name = SECTION_NAME (section);
252b5132 6377
1b513401
NC
6378 /* Run some sanity checks on the headers and
6379 possibly fill in some file data as well. */
6380 switch (section->sh_type)
252b5132 6381 {
1b513401 6382 case SHT_DYNSYM:
978c4450 6383 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6384 {
6385 error (_("File contains multiple dynamic symbol tables\n"));
6386 continue;
6387 }
6388
08d8fa11 6389 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6390 filedata->dynamic_symbols
6391 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6392 filedata->dynamic_symtab_section = section;
1b513401
NC
6393 break;
6394
6395 case SHT_STRTAB:
6396 if (streq (name, ".dynstr"))
252b5132 6397 {
1b513401
NC
6398 if (filedata->dynamic_strings != NULL)
6399 {
6400 error (_("File contains multiple dynamic string tables\n"));
6401 continue;
6402 }
6403
6404 filedata->dynamic_strings
6405 = (char *) get_data (NULL, filedata, section->sh_offset,
6406 1, section->sh_size, _("dynamic strings"));
6407 filedata->dynamic_strings_length
6408 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6409 filedata->dynamic_strtab_section = section;
252b5132 6410 }
1b513401
NC
6411 break;
6412
6413 case SHT_SYMTAB_SHNDX:
6414 {
6415 elf_section_list * entry = xmalloc (sizeof * entry);
6416
6417 entry->hdr = section;
6418 entry->next = filedata->symtab_shndx_list;
6419 filedata->symtab_shndx_list = entry;
6420 }
6421 break;
6422
6423 case SHT_SYMTAB:
6424 CHECK_ENTSIZE (section, i, Sym);
6425 break;
6426
6427 case SHT_GROUP:
6428 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6429 break;
252b5132 6430
1b513401
NC
6431 case SHT_REL:
6432 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6433 if (do_checks && section->sh_size == 0)
1b513401
NC
6434 warn (_("Section '%s': zero-sized relocation section\n"), name);
6435 break;
6436
6437 case SHT_RELA:
6438 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6439 if (do_checks && section->sh_size == 0)
1b513401
NC
6440 warn (_("Section '%s': zero-sized relocation section\n"), name);
6441 break;
6442
6443 case SHT_NOTE:
6444 case SHT_PROGBITS:
546cb2d8
NC
6445 /* Having a zero sized section is not illegal according to the
6446 ELF standard, but it might be an indication that something
6447 is wrong. So issue a warning if we are running in lint mode. */
6448 if (do_checks && section->sh_size == 0)
1b513401
NC
6449 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6450 break;
6451
6452 default:
6453 break;
6454 }
6455
6456 if ((do_debugging || do_debug_info || do_debug_abbrevs
6457 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6458 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e4b7104b 6459 || do_debug_str || do_debug_str_offsets || do_debug_loc || do_debug_ranges
1b513401
NC
6460 || do_debug_addr || do_debug_cu_index || do_debug_links)
6461 && (const_strneq (name, ".debug_")
6462 || const_strneq (name, ".zdebug_")))
252b5132 6463 {
1b315056
CS
6464 if (name[1] == 'z')
6465 name += sizeof (".zdebug_") - 1;
6466 else
6467 name += sizeof (".debug_") - 1;
252b5132
RH
6468
6469 if (do_debugging
4723351a
CC
6470 || (do_debug_info && const_strneq (name, "info"))
6471 || (do_debug_info && const_strneq (name, "types"))
6472 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6473 || (do_debug_lines && strcmp (name, "line") == 0)
6474 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6475 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6476 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6477 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6478 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6479 || (do_debug_aranges && const_strneq (name, "aranges"))
6480 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6481 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6482 || (do_debug_frames && const_strneq (name, "frame"))
6483 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6484 || (do_debug_macinfo && const_strneq (name, "macro"))
6485 || (do_debug_str && const_strneq (name, "str"))
e4b7104b 6486 || (do_debug_str_offsets && const_strneq (name, "str_offsets"))
4723351a 6487 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6488 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6489 || (do_debug_addr && const_strneq (name, "addr"))
6490 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6491 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6492 )
6431e409 6493 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6494 }
a262ae96 6495 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6496 else if ((do_debugging || do_debug_info)
0112cd26 6497 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6498 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6499 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6500 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6501 else if (do_gdb_index && (streq (name, ".gdb_index")
6502 || streq (name, ".debug_names")))
6431e409 6503 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6504 /* Trace sections for Itanium VMS. */
6505 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6506 || do_trace_aranges)
6507 && const_strneq (name, ".trace_"))
6508 {
6509 name += sizeof (".trace_") - 1;
6510
6511 if (do_debugging
6512 || (do_trace_info && streq (name, "info"))
6513 || (do_trace_abbrevs && streq (name, "abbrev"))
6514 || (do_trace_aranges && streq (name, "aranges"))
6515 )
6431e409 6516 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6517 }
dda8d76d
NC
6518 else if ((do_debugging || do_debug_links)
6519 && (const_strneq (name, ".gnu_debuglink")
6520 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6521 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6522 }
6523
6524 if (! do_sections)
32ec8896 6525 return TRUE;
252b5132 6526
dda8d76d 6527 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6528 printf (_("\nSection Headers:\n"));
6529 else
6530 printf (_("\nSection Header:\n"));
76da6bbe 6531
f7a99963 6532 if (is_32bit_elf)
595cf52e 6533 {
5477e8a0 6534 if (do_section_details)
595cf52e
L
6535 {
6536 printf (_(" [Nr] Name\n"));
5477e8a0 6537 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6538 }
6539 else
6540 printf
6541 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6542 }
d974e256 6543 else if (do_wide)
595cf52e 6544 {
5477e8a0 6545 if (do_section_details)
595cf52e
L
6546 {
6547 printf (_(" [Nr] Name\n"));
5477e8a0 6548 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6549 }
6550 else
6551 printf
6552 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6553 }
f7a99963
NC
6554 else
6555 {
5477e8a0 6556 if (do_section_details)
595cf52e
L
6557 {
6558 printf (_(" [Nr] Name\n"));
5477e8a0
L
6559 printf (_(" Type Address Offset Link\n"));
6560 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6561 }
6562 else
6563 {
6564 printf (_(" [Nr] Name Type Address Offset\n"));
6565 printf (_(" Size EntSize Flags Link Info Align\n"));
6566 }
f7a99963 6567 }
252b5132 6568
5477e8a0
L
6569 if (do_section_details)
6570 printf (_(" Flags\n"));
6571
dda8d76d
NC
6572 for (i = 0, section = filedata->section_headers;
6573 i < filedata->file_header.e_shnum;
b34976b6 6574 i++, section++)
252b5132 6575 {
dd905818
NC
6576 /* Run some sanity checks on the section header. */
6577
6578 /* Check the sh_link field. */
6579 switch (section->sh_type)
6580 {
285e3f99
AM
6581 case SHT_REL:
6582 case SHT_RELA:
6583 if (section->sh_link == 0
6584 && (filedata->file_header.e_type == ET_EXEC
6585 || filedata->file_header.e_type == ET_DYN))
6586 /* A dynamic relocation section where all entries use a
6587 zero symbol index need not specify a symtab section. */
6588 break;
6589 /* Fall through. */
dd905818
NC
6590 case SHT_SYMTAB_SHNDX:
6591 case SHT_GROUP:
6592 case SHT_HASH:
6593 case SHT_GNU_HASH:
6594 case SHT_GNU_versym:
285e3f99 6595 if (section->sh_link == 0
dda8d76d
NC
6596 || section->sh_link >= filedata->file_header.e_shnum
6597 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6598 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6599 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6600 i, section->sh_link);
6601 break;
6602
6603 case SHT_DYNAMIC:
6604 case SHT_SYMTAB:
6605 case SHT_DYNSYM:
6606 case SHT_GNU_verneed:
6607 case SHT_GNU_verdef:
6608 case SHT_GNU_LIBLIST:
285e3f99 6609 if (section->sh_link == 0
dda8d76d
NC
6610 || section->sh_link >= filedata->file_header.e_shnum
6611 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6612 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6613 i, section->sh_link);
6614 break;
6615
6616 case SHT_INIT_ARRAY:
6617 case SHT_FINI_ARRAY:
6618 case SHT_PREINIT_ARRAY:
6619 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6620 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6621 i, section->sh_link);
6622 break;
6623
6624 default:
6625 /* FIXME: Add support for target specific section types. */
6626#if 0 /* Currently we do not check other section types as there are too
6627 many special cases. Stab sections for example have a type
6628 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6629 section. */
6630 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6631 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6632 i, section->sh_link);
6633#endif
6634 break;
6635 }
6636
6637 /* Check the sh_info field. */
6638 switch (section->sh_type)
6639 {
6640 case SHT_REL:
6641 case SHT_RELA:
285e3f99
AM
6642 if (section->sh_info == 0
6643 && (filedata->file_header.e_type == ET_EXEC
6644 || filedata->file_header.e_type == ET_DYN))
6645 /* Dynamic relocations apply to segments, so they do not
6646 need to specify the section they relocate. */
6647 break;
6648 if (section->sh_info == 0
dda8d76d
NC
6649 || section->sh_info >= filedata->file_header.e_shnum
6650 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6651 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6652 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6653 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6654 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6655 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6656 /* FIXME: Are other section types valid ? */
dda8d76d 6657 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6658 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6659 i, section->sh_info);
dd905818
NC
6660 break;
6661
6662 case SHT_DYNAMIC:
6663 case SHT_HASH:
6664 case SHT_SYMTAB_SHNDX:
6665 case SHT_INIT_ARRAY:
6666 case SHT_FINI_ARRAY:
6667 case SHT_PREINIT_ARRAY:
6668 if (section->sh_info != 0)
6669 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6670 i, section->sh_info);
6671 break;
6672
6673 case SHT_GROUP:
6674 case SHT_SYMTAB:
6675 case SHT_DYNSYM:
6676 /* A symbol index - we assume that it is valid. */
6677 break;
6678
6679 default:
6680 /* FIXME: Add support for target specific section types. */
6681 if (section->sh_type == SHT_NOBITS)
6682 /* NOBITS section headers with non-zero sh_info fields can be
6683 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6684 information. The stripped sections have their headers
6685 preserved but their types set to SHT_NOBITS. So do not check
6686 this type of section. */
dd905818
NC
6687 ;
6688 else if (section->sh_flags & SHF_INFO_LINK)
6689 {
dda8d76d 6690 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6691 warn (_("[%2u]: Expected link to another section in info field"), i);
6692 }
a91e1603
L
6693 else if (section->sh_type < SHT_LOOS
6694 && (section->sh_flags & SHF_GNU_MBIND) == 0
6695 && section->sh_info != 0)
dd905818
NC
6696 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6697 i, section->sh_info);
6698 break;
6699 }
6700
3e6b6445 6701 /* Check the sh_size field. */
dda8d76d 6702 if (section->sh_size > filedata->file_size
3e6b6445
NC
6703 && section->sh_type != SHT_NOBITS
6704 && section->sh_type != SHT_NULL
6705 && section->sh_type < SHT_LOOS)
6706 warn (_("Size of section %u is larger than the entire file!\n"), i);
6707
7bfd842d 6708 printf (" [%2u] ", i);
5477e8a0 6709 if (do_section_details)
dda8d76d 6710 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6711 else
74e1a04b 6712 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6713
ea52a088 6714 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6715 get_section_type_name (filedata, section->sh_type));
0b4362b0 6716
f7a99963
NC
6717 if (is_32bit_elf)
6718 {
cfcac11d
NC
6719 const char * link_too_big = NULL;
6720
f7a99963 6721 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6722
f7a99963
NC
6723 printf ( " %6.6lx %6.6lx %2.2lx",
6724 (unsigned long) section->sh_offset,
6725 (unsigned long) section->sh_size,
6726 (unsigned long) section->sh_entsize);
d1133906 6727
5477e8a0
L
6728 if (do_section_details)
6729 fputs (" ", stdout);
6730 else
dda8d76d 6731 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6732
dda8d76d 6733 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6734 {
6735 link_too_big = "";
6736 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6737 an error but it can have special values in Solaris binaries. */
dda8d76d 6738 switch (filedata->file_header.e_machine)
cfcac11d 6739 {
caa83f8b 6740 case EM_386:
22abe556 6741 case EM_IAMCU:
caa83f8b 6742 case EM_X86_64:
7f502d6c 6743 case EM_L1OM:
7a9068fe 6744 case EM_K1OM:
cfcac11d
NC
6745 case EM_OLD_SPARCV9:
6746 case EM_SPARC32PLUS:
6747 case EM_SPARCV9:
6748 case EM_SPARC:
6749 if (section->sh_link == (SHN_BEFORE & 0xffff))
6750 link_too_big = "BEFORE";
6751 else if (section->sh_link == (SHN_AFTER & 0xffff))
6752 link_too_big = "AFTER";
6753 break;
6754 default:
6755 break;
6756 }
6757 }
6758
6759 if (do_section_details)
6760 {
6761 if (link_too_big != NULL && * link_too_big)
6762 printf ("<%s> ", link_too_big);
6763 else
6764 printf ("%2u ", section->sh_link);
6765 printf ("%3u %2lu\n", section->sh_info,
6766 (unsigned long) section->sh_addralign);
6767 }
6768 else
6769 printf ("%2u %3u %2lu\n",
6770 section->sh_link,
6771 section->sh_info,
6772 (unsigned long) section->sh_addralign);
6773
6774 if (link_too_big && ! * link_too_big)
6775 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6776 i, section->sh_link);
f7a99963 6777 }
d974e256
JJ
6778 else if (do_wide)
6779 {
6780 print_vma (section->sh_addr, LONG_HEX);
6781
6782 if ((long) section->sh_offset == section->sh_offset)
6783 printf (" %6.6lx", (unsigned long) section->sh_offset);
6784 else
6785 {
6786 putchar (' ');
6787 print_vma (section->sh_offset, LONG_HEX);
6788 }
6789
6790 if ((unsigned long) section->sh_size == section->sh_size)
6791 printf (" %6.6lx", (unsigned long) section->sh_size);
6792 else
6793 {
6794 putchar (' ');
6795 print_vma (section->sh_size, LONG_HEX);
6796 }
6797
6798 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6799 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6800 else
6801 {
6802 putchar (' ');
6803 print_vma (section->sh_entsize, LONG_HEX);
6804 }
6805
5477e8a0
L
6806 if (do_section_details)
6807 fputs (" ", stdout);
6808 else
dda8d76d 6809 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6810
72de5009 6811 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6812
6813 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6814 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6815 else
6816 {
6817 print_vma (section->sh_addralign, DEC);
6818 putchar ('\n');
6819 }
6820 }
5477e8a0 6821 else if (do_section_details)
595cf52e 6822 {
55cc53e9 6823 putchar (' ');
595cf52e
L
6824 print_vma (section->sh_addr, LONG_HEX);
6825 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6826 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6827 else
6828 {
6829 printf (" ");
6830 print_vma (section->sh_offset, LONG_HEX);
6831 }
72de5009 6832 printf (" %u\n ", section->sh_link);
595cf52e 6833 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6834 putchar (' ');
595cf52e
L
6835 print_vma (section->sh_entsize, LONG_HEX);
6836
72de5009
AM
6837 printf (" %-16u %lu\n",
6838 section->sh_info,
595cf52e
L
6839 (unsigned long) section->sh_addralign);
6840 }
f7a99963
NC
6841 else
6842 {
6843 putchar (' ');
6844 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6845 if ((long) section->sh_offset == section->sh_offset)
6846 printf (" %8.8lx", (unsigned long) section->sh_offset);
6847 else
6848 {
6849 printf (" ");
6850 print_vma (section->sh_offset, LONG_HEX);
6851 }
f7a99963
NC
6852 printf ("\n ");
6853 print_vma (section->sh_size, LONG_HEX);
6854 printf (" ");
6855 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6856
dda8d76d 6857 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6858
72de5009
AM
6859 printf (" %2u %3u %lu\n",
6860 section->sh_link,
6861 section->sh_info,
f7a99963
NC
6862 (unsigned long) section->sh_addralign);
6863 }
5477e8a0
L
6864
6865 if (do_section_details)
77115a4a 6866 {
dda8d76d 6867 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6868 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6869 {
6870 /* Minimum section size is 12 bytes for 32-bit compression
6871 header + 12 bytes for compressed data header. */
6872 unsigned char buf[24];
d8024a91 6873
77115a4a 6874 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6875 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6876 sizeof (buf), _("compression header")))
6877 {
6878 Elf_Internal_Chdr chdr;
d8024a91 6879
5844b465
NC
6880 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
6881 printf (_(" [<corrupt>]\n"));
77115a4a 6882 else
5844b465
NC
6883 {
6884 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6885 printf (" ZLIB, ");
6886 else
6887 printf (_(" [<unknown>: 0x%x], "),
6888 chdr.ch_type);
6889 print_vma (chdr.ch_size, LONG_HEX);
6890 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6891 }
77115a4a
L
6892 }
6893 }
6894 }
252b5132
RH
6895 }
6896
5477e8a0 6897 if (!do_section_details)
3dbcc61d 6898 {
9fb71ee4
NC
6899 /* The ordering of the letters shown here matches the ordering of the
6900 corresponding SHF_xxx values, and hence the order in which these
6901 letters will be displayed to the user. */
6902 printf (_("Key to Flags:\n\
6903 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6904 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6905 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6906 if (filedata->file_header.e_machine == EM_X86_64
6907 || filedata->file_header.e_machine == EM_L1OM
6908 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6909 printf (_("l (large), "));
dda8d76d 6910 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6911 printf (_("y (purecode), "));
dda8d76d 6912 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6913 printf (_("v (VLE), "));
9fb71ee4 6914 printf ("p (processor specific)\n");
0b4362b0 6915 }
d1133906 6916
32ec8896 6917 return TRUE;
252b5132
RH
6918}
6919
28d13567
AM
6920static bfd_boolean
6921get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
6922 Elf_Internal_Sym **symtab, unsigned long *nsyms,
6923 char **strtab, unsigned long *strtablen)
6924{
6925 *strtab = NULL;
6926 *strtablen = 0;
6927 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
6928
6929 if (*symtab == NULL)
6930 return FALSE;
6931
6932 if (symsec->sh_link != 0)
6933 {
6934 Elf_Internal_Shdr *strsec;
6935
6936 if (symsec->sh_link >= filedata->file_header.e_shnum)
6937 {
6938 error (_("Bad sh_link in symbol table section\n"));
6939 free (*symtab);
6940 *symtab = NULL;
6941 *nsyms = 0;
6942 return FALSE;
6943 }
6944
6945 strsec = filedata->section_headers + symsec->sh_link;
6946
6947 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
6948 1, strsec->sh_size, _("string table"));
6949 if (*strtab == NULL)
6950 {
6951 free (*symtab);
6952 *symtab = NULL;
6953 *nsyms = 0;
6954 return FALSE;
6955 }
6956 *strtablen = strsec->sh_size;
6957 }
6958 return TRUE;
6959}
6960
f5842774
L
6961static const char *
6962get_group_flags (unsigned int flags)
6963{
1449284b 6964 static char buff[128];
220453ec 6965
6d913794
NC
6966 if (flags == 0)
6967 return "";
6968 else if (flags == GRP_COMDAT)
6969 return "COMDAT ";
f5842774 6970
89246a0e
AM
6971 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
6972 flags,
6973 flags & GRP_MASKOS ? _("<OS specific>") : "",
6974 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
6975 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
6976 ? _("<unknown>") : ""));
6d913794 6977
f5842774
L
6978 return buff;
6979}
6980
32ec8896 6981static bfd_boolean
dda8d76d 6982process_section_groups (Filedata * filedata)
f5842774 6983{
2cf0635d 6984 Elf_Internal_Shdr * section;
f5842774 6985 unsigned int i;
2cf0635d
NC
6986 struct group * group;
6987 Elf_Internal_Shdr * symtab_sec;
6988 Elf_Internal_Shdr * strtab_sec;
6989 Elf_Internal_Sym * symtab;
ba5cdace 6990 unsigned long num_syms;
2cf0635d 6991 char * strtab;
c256ffe7 6992 size_t strtab_size;
d1f5c6e3
L
6993
6994 /* Don't process section groups unless needed. */
6995 if (!do_unwind && !do_section_groups)
32ec8896 6996 return TRUE;
f5842774 6997
dda8d76d 6998 if (filedata->file_header.e_shnum == 0)
f5842774
L
6999 {
7000 if (do_section_groups)
82f2dbf7 7001 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 7002
32ec8896 7003 return TRUE;
f5842774
L
7004 }
7005
dda8d76d 7006 if (filedata->section_headers == NULL)
f5842774
L
7007 {
7008 error (_("Section headers are not available!\n"));
fa1908fd 7009 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 7010 return FALSE;
f5842774
L
7011 }
7012
978c4450
AM
7013 filedata->section_headers_groups
7014 = (struct group **) calloc (filedata->file_header.e_shnum,
7015 sizeof (struct group *));
e4b17d5c 7016
978c4450 7017 if (filedata->section_headers_groups == NULL)
e4b17d5c 7018 {
8b73c356 7019 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7020 filedata->file_header.e_shnum);
32ec8896 7021 return FALSE;
e4b17d5c
L
7022 }
7023
f5842774 7024 /* Scan the sections for the group section. */
978c4450 7025 filedata->group_count = 0;
dda8d76d
NC
7026 for (i = 0, section = filedata->section_headers;
7027 i < filedata->file_header.e_shnum;
f5842774 7028 i++, section++)
e4b17d5c 7029 if (section->sh_type == SHT_GROUP)
978c4450 7030 filedata->group_count++;
e4b17d5c 7031
978c4450 7032 if (filedata->group_count == 0)
d1f5c6e3
L
7033 {
7034 if (do_section_groups)
7035 printf (_("\nThere are no section groups in this file.\n"));
7036
32ec8896 7037 return TRUE;
d1f5c6e3
L
7038 }
7039
978c4450
AM
7040 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7041 sizeof (struct group));
e4b17d5c 7042
978c4450 7043 if (filedata->section_groups == NULL)
e4b17d5c 7044 {
8b73c356 7045 error (_("Out of memory reading %lu groups\n"),
978c4450 7046 (unsigned long) filedata->group_count);
32ec8896 7047 return FALSE;
e4b17d5c
L
7048 }
7049
d1f5c6e3
L
7050 symtab_sec = NULL;
7051 strtab_sec = NULL;
7052 symtab = NULL;
ba5cdace 7053 num_syms = 0;
d1f5c6e3 7054 strtab = NULL;
c256ffe7 7055 strtab_size = 0;
978c4450 7056 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7057 i < filedata->file_header.e_shnum;
e4b17d5c 7058 i++, section++)
f5842774
L
7059 {
7060 if (section->sh_type == SHT_GROUP)
7061 {
dda8d76d 7062 const char * name = printable_section_name (filedata, section);
74e1a04b 7063 const char * group_name;
2cf0635d
NC
7064 unsigned char * start;
7065 unsigned char * indices;
f5842774 7066 unsigned int entry, j, size;
2cf0635d
NC
7067 Elf_Internal_Shdr * sec;
7068 Elf_Internal_Sym * sym;
f5842774
L
7069
7070 /* Get the symbol table. */
dda8d76d
NC
7071 if (section->sh_link >= filedata->file_header.e_shnum
7072 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7073 != SHT_SYMTAB))
f5842774
L
7074 {
7075 error (_("Bad sh_link in group section `%s'\n"), name);
7076 continue;
7077 }
d1f5c6e3
L
7078
7079 if (symtab_sec != sec)
7080 {
7081 symtab_sec = sec;
9db70fc3 7082 free (symtab);
dda8d76d 7083 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7084 }
f5842774 7085
dd24e3da
NC
7086 if (symtab == NULL)
7087 {
7088 error (_("Corrupt header in group section `%s'\n"), name);
7089 continue;
7090 }
7091
ba5cdace
NC
7092 if (section->sh_info >= num_syms)
7093 {
7094 error (_("Bad sh_info in group section `%s'\n"), name);
7095 continue;
7096 }
7097
f5842774
L
7098 sym = symtab + section->sh_info;
7099
7100 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7101 {
4fbb74a6 7102 if (sym->st_shndx == 0
dda8d76d 7103 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7104 {
7105 error (_("Bad sh_info in group section `%s'\n"), name);
7106 continue;
7107 }
ba2685cc 7108
dda8d76d 7109 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7 7110 strtab_sec = NULL;
9db70fc3 7111 free (strtab);
f5842774 7112 strtab = NULL;
c256ffe7 7113 strtab_size = 0;
f5842774
L
7114 }
7115 else
7116 {
7117 /* Get the string table. */
dda8d76d 7118 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7119 {
7120 strtab_sec = NULL;
9db70fc3 7121 free (strtab);
c256ffe7
JJ
7122 strtab = NULL;
7123 strtab_size = 0;
7124 }
7125 else if (strtab_sec
dda8d76d 7126 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7127 {
7128 strtab_sec = sec;
9db70fc3 7129 free (strtab);
071436c6 7130
dda8d76d 7131 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7132 1, strtab_sec->sh_size,
7133 _("string table"));
c256ffe7 7134 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7135 }
c256ffe7 7136 group_name = sym->st_name < strtab_size
2b692964 7137 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7138 }
7139
c9c1d674
EG
7140 /* PR 17531: file: loop. */
7141 if (section->sh_entsize > section->sh_size)
7142 {
7143 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7144 printable_section_name (filedata, section),
8066deb1
AM
7145 (unsigned long) section->sh_entsize,
7146 (unsigned long) section->sh_size);
61dd8e19 7147 continue;
c9c1d674
EG
7148 }
7149
dda8d76d 7150 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7151 1, section->sh_size,
7152 _("section data"));
59245841
NC
7153 if (start == NULL)
7154 continue;
f5842774
L
7155
7156 indices = start;
7157 size = (section->sh_size / section->sh_entsize) - 1;
7158 entry = byte_get (indices, 4);
7159 indices += 4;
e4b17d5c
L
7160
7161 if (do_section_groups)
7162 {
2b692964 7163 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7164 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7165
e4b17d5c
L
7166 printf (_(" [Index] Name\n"));
7167 }
7168
7169 group->group_index = i;
7170
f5842774
L
7171 for (j = 0; j < size; j++)
7172 {
2cf0635d 7173 struct group_list * g;
e4b17d5c 7174
f5842774
L
7175 entry = byte_get (indices, 4);
7176 indices += 4;
7177
dda8d76d 7178 if (entry >= filedata->file_header.e_shnum)
391cb864 7179 {
57028622
NC
7180 static unsigned num_group_errors = 0;
7181
7182 if (num_group_errors ++ < 10)
7183 {
7184 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7185 entry, i, filedata->file_header.e_shnum - 1);
57028622 7186 if (num_group_errors == 10)
67ce483b 7187 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7188 }
391cb864
L
7189 continue;
7190 }
391cb864 7191
978c4450 7192 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7193 {
d1f5c6e3
L
7194 if (entry)
7195 {
57028622
NC
7196 static unsigned num_errs = 0;
7197
7198 if (num_errs ++ < 10)
7199 {
7200 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7201 entry, i,
978c4450 7202 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7203 if (num_errs == 10)
7204 warn (_("Further error messages about already contained group sections suppressed\n"));
7205 }
d1f5c6e3
L
7206 continue;
7207 }
7208 else
7209 {
7210 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7211 section group. We just warn it the first time
d1f5c6e3 7212 and ignore it afterwards. */
32ec8896 7213 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7214 if (!warned)
7215 {
7216 error (_("section 0 in group section [%5u]\n"),
978c4450 7217 filedata->section_headers_groups [entry]->group_index);
32ec8896 7218 warned = TRUE;
d1f5c6e3
L
7219 }
7220 }
e4b17d5c
L
7221 }
7222
978c4450 7223 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7224
7225 if (do_section_groups)
7226 {
dda8d76d
NC
7227 sec = filedata->section_headers + entry;
7228 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7229 }
7230
3f5e193b 7231 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7232 g->section_index = entry;
7233 g->next = group->root;
7234 group->root = g;
f5842774
L
7235 }
7236
9db70fc3 7237 free (start);
e4b17d5c
L
7238
7239 group++;
f5842774
L
7240 }
7241 }
7242
9db70fc3
AM
7243 free (symtab);
7244 free (strtab);
32ec8896 7245 return TRUE;
f5842774
L
7246}
7247
28f997cf
TG
7248/* Data used to display dynamic fixups. */
7249
7250struct ia64_vms_dynfixup
7251{
7252 bfd_vma needed_ident; /* Library ident number. */
7253 bfd_vma needed; /* Index in the dstrtab of the library name. */
7254 bfd_vma fixup_needed; /* Index of the library. */
7255 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7256 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7257};
7258
7259/* Data used to display dynamic relocations. */
7260
7261struct ia64_vms_dynimgrela
7262{
7263 bfd_vma img_rela_cnt; /* Number of relocations. */
7264 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7265};
7266
7267/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7268 library). */
7269
32ec8896 7270static bfd_boolean
dda8d76d
NC
7271dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7272 struct ia64_vms_dynfixup * fixup,
7273 const char * strtab,
7274 unsigned int strtab_sz)
28f997cf 7275{
32ec8896 7276 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7277 long i;
32ec8896 7278 const char * lib_name;
28f997cf 7279
978c4450
AM
7280 imfs = get_data (NULL, filedata,
7281 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7282 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7283 _("dynamic section image fixups"));
7284 if (!imfs)
32ec8896 7285 return FALSE;
28f997cf
TG
7286
7287 if (fixup->needed < strtab_sz)
7288 lib_name = strtab + fixup->needed;
7289 else
7290 {
32ec8896 7291 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7292 (unsigned long) fixup->needed);
28f997cf
TG
7293 lib_name = "???";
7294 }
736990c4 7295
28f997cf
TG
7296 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7297 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7298 printf
7299 (_("Seg Offset Type SymVec DataType\n"));
7300
7301 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7302 {
7303 unsigned int type;
7304 const char *rtype;
7305
7306 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7307 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7308 type = BYTE_GET (imfs [i].type);
7309 rtype = elf_ia64_reloc_type (type);
7310 if (rtype == NULL)
7311 printf (" 0x%08x ", type);
7312 else
7313 printf (" %-32s ", rtype);
7314 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7315 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7316 }
7317
7318 free (imfs);
32ec8896 7319 return TRUE;
28f997cf
TG
7320}
7321
7322/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7323
32ec8896 7324static bfd_boolean
dda8d76d 7325dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7326{
7327 Elf64_External_VMS_IMAGE_RELA *imrs;
7328 long i;
7329
978c4450
AM
7330 imrs = get_data (NULL, filedata,
7331 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7332 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7333 _("dynamic section image relocations"));
28f997cf 7334 if (!imrs)
32ec8896 7335 return FALSE;
28f997cf
TG
7336
7337 printf (_("\nImage relocs\n"));
7338 printf
7339 (_("Seg Offset Type Addend Seg Sym Off\n"));
7340
7341 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7342 {
7343 unsigned int type;
7344 const char *rtype;
7345
7346 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7347 printf ("%08" BFD_VMA_FMT "x ",
7348 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7349 type = BYTE_GET (imrs [i].type);
7350 rtype = elf_ia64_reloc_type (type);
7351 if (rtype == NULL)
7352 printf ("0x%08x ", type);
7353 else
7354 printf ("%-31s ", rtype);
7355 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7356 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7357 printf ("%08" BFD_VMA_FMT "x\n",
7358 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7359 }
7360
7361 free (imrs);
32ec8896 7362 return TRUE;
28f997cf
TG
7363}
7364
7365/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7366
32ec8896 7367static bfd_boolean
dda8d76d 7368process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7369{
7370 struct ia64_vms_dynfixup fixup;
7371 struct ia64_vms_dynimgrela imgrela;
7372 Elf_Internal_Dyn *entry;
28f997cf
TG
7373 bfd_vma strtab_off = 0;
7374 bfd_vma strtab_sz = 0;
7375 char *strtab = NULL;
32ec8896 7376 bfd_boolean res = TRUE;
28f997cf
TG
7377
7378 memset (&fixup, 0, sizeof (fixup));
7379 memset (&imgrela, 0, sizeof (imgrela));
7380
7381 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7382 for (entry = filedata->dynamic_section;
7383 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7384 entry++)
7385 {
7386 switch (entry->d_tag)
7387 {
7388 case DT_IA_64_VMS_STRTAB_OFFSET:
7389 strtab_off = entry->d_un.d_val;
7390 break;
7391 case DT_STRSZ:
7392 strtab_sz = entry->d_un.d_val;
7393 if (strtab == NULL)
978c4450
AM
7394 strtab = get_data (NULL, filedata,
7395 filedata->dynamic_addr + strtab_off,
28f997cf 7396 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7397 if (strtab == NULL)
7398 strtab_sz = 0;
28f997cf
TG
7399 break;
7400
7401 case DT_IA_64_VMS_NEEDED_IDENT:
7402 fixup.needed_ident = entry->d_un.d_val;
7403 break;
7404 case DT_NEEDED:
7405 fixup.needed = entry->d_un.d_val;
7406 break;
7407 case DT_IA_64_VMS_FIXUP_NEEDED:
7408 fixup.fixup_needed = entry->d_un.d_val;
7409 break;
7410 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7411 fixup.fixup_rela_cnt = entry->d_un.d_val;
7412 break;
7413 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7414 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7415 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7416 res = FALSE;
28f997cf 7417 break;
28f997cf
TG
7418 case DT_IA_64_VMS_IMG_RELA_CNT:
7419 imgrela.img_rela_cnt = entry->d_un.d_val;
7420 break;
7421 case DT_IA_64_VMS_IMG_RELA_OFF:
7422 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7423 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7424 res = FALSE;
28f997cf
TG
7425 break;
7426
7427 default:
7428 break;
7429 }
7430 }
7431
9db70fc3 7432 free (strtab);
28f997cf
TG
7433
7434 return res;
7435}
7436
85b1c36d 7437static struct
566b0d53 7438{
2cf0635d 7439 const char * name;
566b0d53
L
7440 int reloc;
7441 int size;
7442 int rela;
32ec8896
NC
7443}
7444 dynamic_relocations [] =
566b0d53 7445{
32ec8896
NC
7446 { "REL", DT_REL, DT_RELSZ, FALSE },
7447 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7448 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7449};
7450
252b5132 7451/* Process the reloc section. */
18bd398b 7452
32ec8896 7453static bfd_boolean
dda8d76d 7454process_relocs (Filedata * filedata)
252b5132 7455{
b34976b6
AM
7456 unsigned long rel_size;
7457 unsigned long rel_offset;
252b5132 7458
252b5132 7459 if (!do_reloc)
32ec8896 7460 return TRUE;
252b5132
RH
7461
7462 if (do_using_dynamic)
7463 {
32ec8896 7464 int is_rela;
2cf0635d 7465 const char * name;
32ec8896 7466 bfd_boolean has_dynamic_reloc;
566b0d53 7467 unsigned int i;
0de14b54 7468
32ec8896 7469 has_dynamic_reloc = FALSE;
252b5132 7470
566b0d53 7471 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7472 {
566b0d53
L
7473 is_rela = dynamic_relocations [i].rela;
7474 name = dynamic_relocations [i].name;
978c4450
AM
7475 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7476 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7477
32ec8896
NC
7478 if (rel_size)
7479 has_dynamic_reloc = TRUE;
566b0d53
L
7480
7481 if (is_rela == UNKNOWN)
aa903cfb 7482 {
566b0d53 7483 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7484 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7485 {
7486 case DT_REL:
7487 is_rela = FALSE;
7488 break;
7489 case DT_RELA:
7490 is_rela = TRUE;
7491 break;
7492 }
aa903cfb 7493 }
252b5132 7494
566b0d53
L
7495 if (rel_size)
7496 {
7497 printf
7498 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7499 name, rel_offset, rel_size);
252b5132 7500
dda8d76d
NC
7501 dump_relocations (filedata,
7502 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7503 rel_size,
978c4450
AM
7504 filedata->dynamic_symbols,
7505 filedata->num_dynamic_syms,
7506 filedata->dynamic_strings,
7507 filedata->dynamic_strings_length,
32ec8896 7508 is_rela, TRUE /* is_dynamic */);
566b0d53 7509 }
252b5132 7510 }
566b0d53 7511
dda8d76d
NC
7512 if (is_ia64_vms (filedata))
7513 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7514 has_dynamic_reloc = TRUE;
28f997cf 7515
566b0d53 7516 if (! has_dynamic_reloc)
252b5132
RH
7517 printf (_("\nThere are no dynamic relocations in this file.\n"));
7518 }
7519 else
7520 {
2cf0635d 7521 Elf_Internal_Shdr * section;
b34976b6 7522 unsigned long i;
32ec8896 7523 bfd_boolean found = FALSE;
252b5132 7524
dda8d76d
NC
7525 for (i = 0, section = filedata->section_headers;
7526 i < filedata->file_header.e_shnum;
b34976b6 7527 i++, section++)
252b5132
RH
7528 {
7529 if ( section->sh_type != SHT_RELA
7530 && section->sh_type != SHT_REL)
7531 continue;
7532
7533 rel_offset = section->sh_offset;
7534 rel_size = section->sh_size;
7535
7536 if (rel_size)
7537 {
b34976b6 7538 int is_rela;
d3a49aa8 7539 unsigned long num_rela;
103f02d3 7540
252b5132
RH
7541 printf (_("\nRelocation section "));
7542
dda8d76d 7543 if (filedata->string_table == NULL)
19936277 7544 printf ("%d", section->sh_name);
252b5132 7545 else
dda8d76d 7546 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7547
d3a49aa8
AM
7548 num_rela = rel_size / section->sh_entsize;
7549 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7550 " at offset 0x%lx contains %lu entries:\n",
7551 num_rela),
7552 rel_offset, num_rela);
252b5132 7553
d79b3d50
NC
7554 is_rela = section->sh_type == SHT_RELA;
7555
4fbb74a6 7556 if (section->sh_link != 0
dda8d76d 7557 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7558 {
2cf0635d
NC
7559 Elf_Internal_Shdr * symsec;
7560 Elf_Internal_Sym * symtab;
d79b3d50 7561 unsigned long nsyms;
c256ffe7 7562 unsigned long strtablen = 0;
2cf0635d 7563 char * strtab = NULL;
57346661 7564
dda8d76d 7565 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7566 if (symsec->sh_type != SHT_SYMTAB
7567 && symsec->sh_type != SHT_DYNSYM)
7568 continue;
7569
28d13567
AM
7570 if (!get_symtab (filedata, symsec,
7571 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7572 continue;
252b5132 7573
dda8d76d 7574 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7575 symtab, nsyms, strtab, strtablen,
7576 is_rela,
7577 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7578 free (strtab);
d79b3d50
NC
7579 free (symtab);
7580 }
7581 else
dda8d76d 7582 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7583 NULL, 0, NULL, 0, is_rela,
7584 FALSE /* is_dynamic */);
252b5132 7585
32ec8896 7586 found = TRUE;
252b5132
RH
7587 }
7588 }
7589
7590 if (! found)
45ac8f4f
NC
7591 {
7592 /* Users sometimes forget the -D option, so try to be helpful. */
7593 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7594 {
978c4450 7595 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f
NC
7596 {
7597 printf (_("\nThere are no static relocations in this file."));
7598 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7599
7600 break;
7601 }
7602 }
7603 if (i == ARRAY_SIZE (dynamic_relocations))
7604 printf (_("\nThere are no relocations in this file.\n"));
7605 }
252b5132
RH
7606 }
7607
32ec8896 7608 return TRUE;
252b5132
RH
7609}
7610
4d6ed7c8
NC
7611/* An absolute address consists of a section and an offset. If the
7612 section is NULL, the offset itself is the address, otherwise, the
7613 address equals to LOAD_ADDRESS(section) + offset. */
7614
7615struct absaddr
948f632f
DA
7616{
7617 unsigned short section;
7618 bfd_vma offset;
7619};
4d6ed7c8 7620
948f632f
DA
7621/* Find the nearest symbol at or below ADDR. Returns the symbol
7622 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7623
4d6ed7c8 7624static void
dda8d76d
NC
7625find_symbol_for_address (Filedata * filedata,
7626 Elf_Internal_Sym * symtab,
7627 unsigned long nsyms,
7628 const char * strtab,
7629 unsigned long strtab_size,
7630 struct absaddr addr,
7631 const char ** symname,
7632 bfd_vma * offset)
4d6ed7c8 7633{
d3ba0551 7634 bfd_vma dist = 0x100000;
2cf0635d 7635 Elf_Internal_Sym * sym;
948f632f
DA
7636 Elf_Internal_Sym * beg;
7637 Elf_Internal_Sym * end;
2cf0635d 7638 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7639
0b6ae522 7640 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7641 beg = symtab;
7642 end = symtab + nsyms;
0b6ae522 7643
948f632f 7644 while (beg < end)
4d6ed7c8 7645 {
948f632f
DA
7646 bfd_vma value;
7647
7648 sym = beg + (end - beg) / 2;
0b6ae522 7649
948f632f 7650 value = sym->st_value;
0b6ae522
DJ
7651 REMOVE_ARCH_BITS (value);
7652
948f632f 7653 if (sym->st_name != 0
4d6ed7c8 7654 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7655 && addr.offset >= value
7656 && addr.offset - value < dist)
4d6ed7c8
NC
7657 {
7658 best = sym;
0b6ae522 7659 dist = addr.offset - value;
4d6ed7c8
NC
7660 if (!dist)
7661 break;
7662 }
948f632f
DA
7663
7664 if (addr.offset < value)
7665 end = sym;
7666 else
7667 beg = sym + 1;
4d6ed7c8 7668 }
1b31d05e 7669
4d6ed7c8
NC
7670 if (best)
7671 {
57346661 7672 *symname = (best->st_name >= strtab_size
2b692964 7673 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7674 *offset = dist;
7675 return;
7676 }
1b31d05e 7677
4d6ed7c8
NC
7678 *symname = NULL;
7679 *offset = addr.offset;
7680}
7681
32ec8896 7682static /* signed */ int
948f632f
DA
7683symcmp (const void *p, const void *q)
7684{
7685 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7686 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7687
7688 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7689}
7690
7691/* Process the unwind section. */
7692
7693#include "unwind-ia64.h"
7694
7695struct ia64_unw_table_entry
7696{
7697 struct absaddr start;
7698 struct absaddr end;
7699 struct absaddr info;
7700};
7701
7702struct ia64_unw_aux_info
7703{
32ec8896
NC
7704 struct ia64_unw_table_entry * table; /* Unwind table. */
7705 unsigned long table_len; /* Length of unwind table. */
7706 unsigned char * info; /* Unwind info. */
7707 unsigned long info_size; /* Size of unwind info. */
7708 bfd_vma info_addr; /* Starting address of unwind info. */
7709 bfd_vma seg_base; /* Starting address of segment. */
7710 Elf_Internal_Sym * symtab; /* The symbol table. */
7711 unsigned long nsyms; /* Number of symbols. */
7712 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7713 unsigned long nfuns; /* Number of entries in funtab. */
7714 char * strtab; /* The string table. */
7715 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7716};
7717
32ec8896 7718static bfd_boolean
dda8d76d 7719dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7720{
2cf0635d 7721 struct ia64_unw_table_entry * tp;
948f632f 7722 unsigned long j, nfuns;
4d6ed7c8 7723 int in_body;
32ec8896 7724 bfd_boolean res = TRUE;
7036c0e1 7725
948f632f
DA
7726 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7727 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7728 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7729 aux->funtab[nfuns++] = aux->symtab[j];
7730 aux->nfuns = nfuns;
7731 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7732
4d6ed7c8
NC
7733 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7734 {
7735 bfd_vma stamp;
7736 bfd_vma offset;
2cf0635d
NC
7737 const unsigned char * dp;
7738 const unsigned char * head;
53774b7e 7739 const unsigned char * end;
2cf0635d 7740 const char * procname;
4d6ed7c8 7741
dda8d76d 7742 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7743 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7744
7745 fputs ("\n<", stdout);
7746
7747 if (procname)
7748 {
7749 fputs (procname, stdout);
7750
7751 if (offset)
7752 printf ("+%lx", (unsigned long) offset);
7753 }
7754
7755 fputs (">: [", stdout);
7756 print_vma (tp->start.offset, PREFIX_HEX);
7757 fputc ('-', stdout);
7758 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7759 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7760 (unsigned long) (tp->info.offset - aux->seg_base));
7761
53774b7e
NC
7762 /* PR 17531: file: 86232b32. */
7763 if (aux->info == NULL)
7764 continue;
7765
97c0a079
AM
7766 offset = tp->info.offset;
7767 if (tp->info.section)
7768 {
7769 if (tp->info.section >= filedata->file_header.e_shnum)
7770 {
7771 warn (_("Invalid section %u in table entry %ld\n"),
7772 tp->info.section, (long) (tp - aux->table));
7773 res = FALSE;
7774 continue;
7775 }
7776 offset += filedata->section_headers[tp->info.section].sh_addr;
7777 }
7778 offset -= aux->info_addr;
53774b7e 7779 /* PR 17531: file: 0997b4d1. */
90679903
AM
7780 if (offset >= aux->info_size
7781 || aux->info_size - offset < 8)
53774b7e
NC
7782 {
7783 warn (_("Invalid offset %lx in table entry %ld\n"),
7784 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7785 res = FALSE;
53774b7e
NC
7786 continue;
7787 }
7788
97c0a079 7789 head = aux->info + offset;
a4a00738 7790 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7791
86f55779 7792 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7793 (unsigned) UNW_VER (stamp),
7794 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7795 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7796 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7797 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7798
7799 if (UNW_VER (stamp) != 1)
7800 {
2b692964 7801 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7802 continue;
7803 }
7804
7805 in_body = 0;
53774b7e
NC
7806 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7807 /* PR 17531: file: 16ceda89. */
7808 if (end > aux->info + aux->info_size)
7809 end = aux->info + aux->info_size;
7810 for (dp = head + 8; dp < end;)
b4477bc8 7811 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7812 }
948f632f
DA
7813
7814 free (aux->funtab);
32ec8896
NC
7815
7816 return res;
4d6ed7c8
NC
7817}
7818
53774b7e 7819static bfd_boolean
dda8d76d
NC
7820slurp_ia64_unwind_table (Filedata * filedata,
7821 struct ia64_unw_aux_info * aux,
7822 Elf_Internal_Shdr * sec)
4d6ed7c8 7823{
89fac5e3 7824 unsigned long size, nrelas, i;
2cf0635d
NC
7825 Elf_Internal_Phdr * seg;
7826 struct ia64_unw_table_entry * tep;
7827 Elf_Internal_Shdr * relsec;
7828 Elf_Internal_Rela * rela;
7829 Elf_Internal_Rela * rp;
7830 unsigned char * table;
7831 unsigned char * tp;
7832 Elf_Internal_Sym * sym;
7833 const char * relname;
4d6ed7c8 7834
53774b7e
NC
7835 aux->table_len = 0;
7836
4d6ed7c8
NC
7837 /* First, find the starting address of the segment that includes
7838 this section: */
7839
dda8d76d 7840 if (filedata->file_header.e_phnum)
4d6ed7c8 7841 {
dda8d76d 7842 if (! get_program_headers (filedata))
53774b7e 7843 return FALSE;
4d6ed7c8 7844
dda8d76d
NC
7845 for (seg = filedata->program_headers;
7846 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7847 ++seg)
4d6ed7c8
NC
7848 {
7849 if (seg->p_type != PT_LOAD)
7850 continue;
7851
7852 if (sec->sh_addr >= seg->p_vaddr
7853 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7854 {
7855 aux->seg_base = seg->p_vaddr;
7856 break;
7857 }
7858 }
4d6ed7c8
NC
7859 }
7860
7861 /* Second, build the unwind table from the contents of the unwind section: */
7862 size = sec->sh_size;
dda8d76d 7863 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7864 _("unwind table"));
a6e9f9df 7865 if (!table)
53774b7e 7866 return FALSE;
4d6ed7c8 7867
53774b7e 7868 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7869 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7870 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7871 tep = aux->table;
53774b7e
NC
7872
7873 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7874 {
7875 tep->start.section = SHN_UNDEF;
7876 tep->end.section = SHN_UNDEF;
7877 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7878 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7879 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7880 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7881 tep->start.offset += aux->seg_base;
7882 tep->end.offset += aux->seg_base;
7883 tep->info.offset += aux->seg_base;
7884 }
7885 free (table);
7886
41e92641 7887 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7888 for (relsec = filedata->section_headers;
7889 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7890 ++relsec)
7891 {
7892 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7893 || relsec->sh_info >= filedata->file_header.e_shnum
7894 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7895 continue;
7896
dda8d76d 7897 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7898 & rela, & nrelas))
53774b7e
NC
7899 {
7900 free (aux->table);
7901 aux->table = NULL;
7902 aux->table_len = 0;
7903 return FALSE;
7904 }
4d6ed7c8
NC
7905
7906 for (rp = rela; rp < rela + nrelas; ++rp)
7907 {
4770fb94 7908 unsigned int sym_ndx;
726bd37d
AM
7909 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
7910 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 7911
82b1b41b
NC
7912 /* PR 17531: file: 9fa67536. */
7913 if (relname == NULL)
7914 {
726bd37d 7915 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
7916 continue;
7917 }
948f632f 7918
0112cd26 7919 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7920 {
82b1b41b 7921 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7922 continue;
7923 }
7924
89fac5e3 7925 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7926
53774b7e
NC
7927 /* PR 17531: file: 5bc8d9bf. */
7928 if (i >= aux->table_len)
7929 {
7930 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7931 continue;
7932 }
7933
4770fb94
AM
7934 sym_ndx = get_reloc_symindex (rp->r_info);
7935 if (sym_ndx >= aux->nsyms)
7936 {
7937 warn (_("Skipping reloc with invalid symbol index: %u\n"),
7938 sym_ndx);
7939 continue;
7940 }
7941 sym = aux->symtab + sym_ndx;
7942
53774b7e 7943 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7944 {
7945 case 0:
7946 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7947 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7948 break;
7949 case 1:
7950 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7951 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7952 break;
7953 case 2:
7954 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7955 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7956 break;
7957 default:
7958 break;
7959 }
7960 }
7961
7962 free (rela);
7963 }
7964
53774b7e 7965 return TRUE;
4d6ed7c8
NC
7966}
7967
32ec8896 7968static bfd_boolean
dda8d76d 7969ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7970{
2cf0635d
NC
7971 Elf_Internal_Shdr * sec;
7972 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 7973 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7974 struct ia64_unw_aux_info aux;
32ec8896 7975 bfd_boolean res = TRUE;
f1467e33 7976
4d6ed7c8
NC
7977 memset (& aux, 0, sizeof (aux));
7978
dda8d76d 7979 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7980 {
28d13567 7981 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 7982 {
28d13567 7983 if (aux.symtab)
4082ef84 7984 {
28d13567
AM
7985 error (_("Multiple symbol tables encountered\n"));
7986 free (aux.symtab);
7987 aux.symtab = NULL;
4082ef84 7988 free (aux.strtab);
28d13567 7989 aux.strtab = NULL;
4082ef84 7990 }
28d13567
AM
7991 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
7992 &aux.strtab, &aux.strtab_size))
7993 return FALSE;
4d6ed7c8
NC
7994 }
7995 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7996 unwcount++;
7997 }
7998
7999 if (!unwcount)
8000 printf (_("\nThere are no unwind sections in this file.\n"));
8001
8002 while (unwcount-- > 0)
8003 {
2cf0635d 8004 char * suffix;
579f31ac
JJ
8005 size_t len, len2;
8006
dda8d76d
NC
8007 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8008 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8009 if (sec->sh_type == SHT_IA_64_UNWIND)
8010 {
8011 unwsec = sec;
8012 break;
8013 }
4082ef84
NC
8014 /* We have already counted the number of SHT_IA64_UNWIND
8015 sections so the loop above should never fail. */
8016 assert (unwsec != NULL);
579f31ac
JJ
8017
8018 unwstart = i + 1;
8019 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8020
e4b17d5c
L
8021 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8022 {
8023 /* We need to find which section group it is in. */
4082ef84 8024 struct group_list * g;
e4b17d5c 8025
978c4450
AM
8026 if (filedata->section_headers_groups == NULL
8027 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8028 i = filedata->file_header.e_shnum;
4082ef84 8029 else
e4b17d5c 8030 {
978c4450 8031 g = filedata->section_headers_groups[i]->root;
18bd398b 8032
4082ef84
NC
8033 for (; g != NULL; g = g->next)
8034 {
dda8d76d 8035 sec = filedata->section_headers + g->section_index;
e4b17d5c 8036
4082ef84
NC
8037 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
8038 break;
8039 }
8040
8041 if (g == NULL)
dda8d76d 8042 i = filedata->file_header.e_shnum;
4082ef84 8043 }
e4b17d5c 8044 }
18bd398b 8045 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 8046 {
18bd398b 8047 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8048 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8049 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8050 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8051 ++i, ++sec)
18bd398b
NC
8052 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
8053 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8054 break;
8055 }
8056 else
8057 {
8058 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8059 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8060 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8061 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8062 suffix = "";
18bd398b 8063 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 8064 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8065 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8066 ++i, ++sec)
18bd398b
NC
8067 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
8068 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8069 break;
8070 }
8071
dda8d76d 8072 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8073 {
8074 printf (_("\nCould not find unwind info section for "));
8075
dda8d76d 8076 if (filedata->string_table == NULL)
579f31ac
JJ
8077 printf ("%d", unwsec->sh_name);
8078 else
dda8d76d 8079 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8080 }
8081 else
4d6ed7c8 8082 {
4d6ed7c8 8083 aux.info_addr = sec->sh_addr;
dda8d76d 8084 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8085 sec->sh_size,
8086 _("unwind info"));
59245841 8087 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8088
579f31ac 8089 printf (_("\nUnwind section "));
4d6ed7c8 8090
dda8d76d 8091 if (filedata->string_table == NULL)
579f31ac
JJ
8092 printf ("%d", unwsec->sh_name);
8093 else
dda8d76d 8094 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8095
579f31ac 8096 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8097 (unsigned long) unwsec->sh_offset,
89fac5e3 8098 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8099
dda8d76d 8100 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8101 && aux.table_len > 0)
dda8d76d 8102 dump_ia64_unwind (filedata, & aux);
579f31ac 8103
9db70fc3
AM
8104 free ((char *) aux.table);
8105 free ((char *) aux.info);
579f31ac
JJ
8106 aux.table = NULL;
8107 aux.info = NULL;
8108 }
4d6ed7c8 8109 }
4d6ed7c8 8110
9db70fc3
AM
8111 free (aux.symtab);
8112 free ((char *) aux.strtab);
32ec8896
NC
8113
8114 return res;
4d6ed7c8
NC
8115}
8116
3f5e193b 8117struct hppa_unw_table_entry
32ec8896
NC
8118{
8119 struct absaddr start;
8120 struct absaddr end;
8121 unsigned int Cannot_unwind:1; /* 0 */
8122 unsigned int Millicode:1; /* 1 */
8123 unsigned int Millicode_save_sr0:1; /* 2 */
8124 unsigned int Region_description:2; /* 3..4 */
8125 unsigned int reserved1:1; /* 5 */
8126 unsigned int Entry_SR:1; /* 6 */
8127 unsigned int Entry_FR:4; /* Number saved 7..10 */
8128 unsigned int Entry_GR:5; /* Number saved 11..15 */
8129 unsigned int Args_stored:1; /* 16 */
8130 unsigned int Variable_Frame:1; /* 17 */
8131 unsigned int Separate_Package_Body:1; /* 18 */
8132 unsigned int Frame_Extension_Millicode:1; /* 19 */
8133 unsigned int Stack_Overflow_Check:1; /* 20 */
8134 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8135 unsigned int Ada_Region:1; /* 22 */
8136 unsigned int cxx_info:1; /* 23 */
8137 unsigned int cxx_try_catch:1; /* 24 */
8138 unsigned int sched_entry_seq:1; /* 25 */
8139 unsigned int reserved2:1; /* 26 */
8140 unsigned int Save_SP:1; /* 27 */
8141 unsigned int Save_RP:1; /* 28 */
8142 unsigned int Save_MRP_in_frame:1; /* 29 */
8143 unsigned int extn_ptr_defined:1; /* 30 */
8144 unsigned int Cleanup_defined:1; /* 31 */
8145
8146 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8147 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8148 unsigned int Large_frame:1; /* 2 */
8149 unsigned int Pseudo_SP_Set:1; /* 3 */
8150 unsigned int reserved4:1; /* 4 */
8151 unsigned int Total_frame_size:27; /* 5..31 */
8152};
3f5e193b 8153
57346661 8154struct hppa_unw_aux_info
948f632f 8155{
32ec8896
NC
8156 struct hppa_unw_table_entry * table; /* Unwind table. */
8157 unsigned long table_len; /* Length of unwind table. */
8158 bfd_vma seg_base; /* Starting address of segment. */
8159 Elf_Internal_Sym * symtab; /* The symbol table. */
8160 unsigned long nsyms; /* Number of symbols. */
8161 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8162 unsigned long nfuns; /* Number of entries in funtab. */
8163 char * strtab; /* The string table. */
8164 unsigned long strtab_size; /* Size of string table. */
948f632f 8165};
57346661 8166
32ec8896 8167static bfd_boolean
dda8d76d 8168dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8169{
2cf0635d 8170 struct hppa_unw_table_entry * tp;
948f632f 8171 unsigned long j, nfuns;
32ec8896 8172 bfd_boolean res = TRUE;
948f632f
DA
8173
8174 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8175 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8176 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8177 aux->funtab[nfuns++] = aux->symtab[j];
8178 aux->nfuns = nfuns;
8179 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8180
57346661
AM
8181 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8182 {
8183 bfd_vma offset;
2cf0635d 8184 const char * procname;
57346661 8185
dda8d76d 8186 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8187 aux->strtab_size, tp->start, &procname,
8188 &offset);
8189
8190 fputs ("\n<", stdout);
8191
8192 if (procname)
8193 {
8194 fputs (procname, stdout);
8195
8196 if (offset)
8197 printf ("+%lx", (unsigned long) offset);
8198 }
8199
8200 fputs (">: [", stdout);
8201 print_vma (tp->start.offset, PREFIX_HEX);
8202 fputc ('-', stdout);
8203 print_vma (tp->end.offset, PREFIX_HEX);
8204 printf ("]\n\t");
8205
18bd398b
NC
8206#define PF(_m) if (tp->_m) printf (#_m " ");
8207#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8208 PF(Cannot_unwind);
8209 PF(Millicode);
8210 PF(Millicode_save_sr0);
18bd398b 8211 /* PV(Region_description); */
57346661
AM
8212 PF(Entry_SR);
8213 PV(Entry_FR);
8214 PV(Entry_GR);
8215 PF(Args_stored);
8216 PF(Variable_Frame);
8217 PF(Separate_Package_Body);
8218 PF(Frame_Extension_Millicode);
8219 PF(Stack_Overflow_Check);
8220 PF(Two_Instruction_SP_Increment);
8221 PF(Ada_Region);
8222 PF(cxx_info);
8223 PF(cxx_try_catch);
8224 PF(sched_entry_seq);
8225 PF(Save_SP);
8226 PF(Save_RP);
8227 PF(Save_MRP_in_frame);
8228 PF(extn_ptr_defined);
8229 PF(Cleanup_defined);
8230 PF(MPE_XL_interrupt_marker);
8231 PF(HP_UX_interrupt_marker);
8232 PF(Large_frame);
8233 PF(Pseudo_SP_Set);
8234 PV(Total_frame_size);
8235#undef PF
8236#undef PV
8237 }
8238
18bd398b 8239 printf ("\n");
948f632f
DA
8240
8241 free (aux->funtab);
32ec8896
NC
8242
8243 return res;
57346661
AM
8244}
8245
32ec8896 8246static bfd_boolean
dda8d76d
NC
8247slurp_hppa_unwind_table (Filedata * filedata,
8248 struct hppa_unw_aux_info * aux,
8249 Elf_Internal_Shdr * sec)
57346661 8250{
1c0751b2 8251 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8252 Elf_Internal_Phdr * seg;
8253 struct hppa_unw_table_entry * tep;
8254 Elf_Internal_Shdr * relsec;
8255 Elf_Internal_Rela * rela;
8256 Elf_Internal_Rela * rp;
8257 unsigned char * table;
8258 unsigned char * tp;
8259 Elf_Internal_Sym * sym;
8260 const char * relname;
57346661 8261
57346661
AM
8262 /* First, find the starting address of the segment that includes
8263 this section. */
dda8d76d 8264 if (filedata->file_header.e_phnum)
57346661 8265 {
dda8d76d 8266 if (! get_program_headers (filedata))
32ec8896 8267 return FALSE;
57346661 8268
dda8d76d
NC
8269 for (seg = filedata->program_headers;
8270 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8271 ++seg)
8272 {
8273 if (seg->p_type != PT_LOAD)
8274 continue;
8275
8276 if (sec->sh_addr >= seg->p_vaddr
8277 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8278 {
8279 aux->seg_base = seg->p_vaddr;
8280 break;
8281 }
8282 }
8283 }
8284
8285 /* Second, build the unwind table from the contents of the unwind
8286 section. */
8287 size = sec->sh_size;
dda8d76d 8288 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8289 _("unwind table"));
57346661 8290 if (!table)
32ec8896 8291 return FALSE;
57346661 8292
1c0751b2
DA
8293 unw_ent_size = 16;
8294 nentries = size / unw_ent_size;
8295 size = unw_ent_size * nentries;
57346661 8296
e3fdc001 8297 aux->table_len = nentries;
3f5e193b
NC
8298 tep = aux->table = (struct hppa_unw_table_entry *)
8299 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8300
1c0751b2 8301 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8302 {
8303 unsigned int tmp1, tmp2;
8304
8305 tep->start.section = SHN_UNDEF;
8306 tep->end.section = SHN_UNDEF;
8307
1c0751b2
DA
8308 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8309 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8310 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8311 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8312
8313 tep->start.offset += aux->seg_base;
8314 tep->end.offset += aux->seg_base;
57346661
AM
8315
8316 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8317 tep->Millicode = (tmp1 >> 30) & 0x1;
8318 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8319 tep->Region_description = (tmp1 >> 27) & 0x3;
8320 tep->reserved1 = (tmp1 >> 26) & 0x1;
8321 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8322 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8323 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8324 tep->Args_stored = (tmp1 >> 15) & 0x1;
8325 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8326 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8327 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8328 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8329 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8330 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8331 tep->cxx_info = (tmp1 >> 8) & 0x1;
8332 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8333 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8334 tep->reserved2 = (tmp1 >> 5) & 0x1;
8335 tep->Save_SP = (tmp1 >> 4) & 0x1;
8336 tep->Save_RP = (tmp1 >> 3) & 0x1;
8337 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8338 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8339 tep->Cleanup_defined = tmp1 & 0x1;
8340
8341 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8342 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8343 tep->Large_frame = (tmp2 >> 29) & 0x1;
8344 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8345 tep->reserved4 = (tmp2 >> 27) & 0x1;
8346 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8347 }
8348 free (table);
8349
8350 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8351 for (relsec = filedata->section_headers;
8352 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8353 ++relsec)
8354 {
8355 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8356 || relsec->sh_info >= filedata->file_header.e_shnum
8357 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8358 continue;
8359
dda8d76d 8360 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8361 & rela, & nrelas))
32ec8896 8362 return FALSE;
57346661
AM
8363
8364 for (rp = rela; rp < rela + nrelas; ++rp)
8365 {
4770fb94 8366 unsigned int sym_ndx;
726bd37d
AM
8367 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8368 relname = elf_hppa_reloc_type (r_type);
57346661 8369
726bd37d
AM
8370 if (relname == NULL)
8371 {
8372 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8373 continue;
8374 }
8375
57346661 8376 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8377 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8378 {
726bd37d 8379 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8380 continue;
8381 }
8382
8383 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8384 if (i >= aux->table_len)
8385 {
8386 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8387 continue;
8388 }
57346661 8389
4770fb94
AM
8390 sym_ndx = get_reloc_symindex (rp->r_info);
8391 if (sym_ndx >= aux->nsyms)
8392 {
8393 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8394 sym_ndx);
8395 continue;
8396 }
8397 sym = aux->symtab + sym_ndx;
8398
43f6cd05 8399 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8400 {
8401 case 0:
8402 aux->table[i].start.section = sym->st_shndx;
1e456d54 8403 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8404 break;
8405 case 1:
8406 aux->table[i].end.section = sym->st_shndx;
1e456d54 8407 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8408 break;
8409 default:
8410 break;
8411 }
8412 }
8413
8414 free (rela);
8415 }
8416
32ec8896 8417 return TRUE;
57346661
AM
8418}
8419
32ec8896 8420static bfd_boolean
dda8d76d 8421hppa_process_unwind (Filedata * filedata)
57346661 8422{
57346661 8423 struct hppa_unw_aux_info aux;
2cf0635d 8424 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8425 Elf_Internal_Shdr * sec;
18bd398b 8426 unsigned long i;
32ec8896 8427 bfd_boolean res = TRUE;
57346661 8428
dda8d76d 8429 if (filedata->string_table == NULL)
32ec8896 8430 return FALSE;
1b31d05e
NC
8431
8432 memset (& aux, 0, sizeof (aux));
57346661 8433
dda8d76d 8434 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8435 {
28d13567 8436 if (sec->sh_type == SHT_SYMTAB)
57346661 8437 {
28d13567 8438 if (aux.symtab)
4082ef84 8439 {
28d13567
AM
8440 error (_("Multiple symbol tables encountered\n"));
8441 free (aux.symtab);
8442 aux.symtab = NULL;
4082ef84 8443 free (aux.strtab);
28d13567 8444 aux.strtab = NULL;
4082ef84 8445 }
28d13567
AM
8446 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8447 &aux.strtab, &aux.strtab_size))
8448 return FALSE;
57346661 8449 }
18bd398b 8450 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8451 unwsec = sec;
8452 }
8453
8454 if (!unwsec)
8455 printf (_("\nThere are no unwind sections in this file.\n"));
8456
dda8d76d 8457 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8458 {
18bd398b 8459 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8460 {
43f6cd05 8461 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8462
d3a49aa8
AM
8463 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8464 "contains %lu entry:\n",
8465 "\nUnwind section '%s' at offset 0x%lx "
8466 "contains %lu entries:\n",
8467 num_unwind),
dda8d76d 8468 printable_section_name (filedata, sec),
57346661 8469 (unsigned long) sec->sh_offset,
d3a49aa8 8470 num_unwind);
57346661 8471
dda8d76d 8472 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8473 res = FALSE;
66b09c7e
S
8474
8475 if (res && aux.table_len > 0)
32ec8896 8476 {
dda8d76d 8477 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8478 res = FALSE;
8479 }
57346661 8480
9db70fc3 8481 free ((char *) aux.table);
57346661
AM
8482 aux.table = NULL;
8483 }
8484 }
8485
9db70fc3
AM
8486 free (aux.symtab);
8487 free ((char *) aux.strtab);
32ec8896
NC
8488
8489 return res;
57346661
AM
8490}
8491
0b6ae522
DJ
8492struct arm_section
8493{
a734115a
NC
8494 unsigned char * data; /* The unwind data. */
8495 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8496 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8497 unsigned long nrelas; /* The number of relocations. */
8498 unsigned int rel_type; /* REL or RELA ? */
8499 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8500};
8501
8502struct arm_unw_aux_info
8503{
dda8d76d 8504 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8505 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8506 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8507 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8508 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8509 char * strtab; /* The file's string table. */
8510 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8511};
8512
8513static const char *
dda8d76d
NC
8514arm_print_vma_and_name (Filedata * filedata,
8515 struct arm_unw_aux_info * aux,
8516 bfd_vma fn,
8517 struct absaddr addr)
0b6ae522
DJ
8518{
8519 const char *procname;
8520 bfd_vma sym_offset;
8521
8522 if (addr.section == SHN_UNDEF)
8523 addr.offset = fn;
8524
dda8d76d 8525 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8526 aux->strtab_size, addr, &procname,
8527 &sym_offset);
8528
8529 print_vma (fn, PREFIX_HEX);
8530
8531 if (procname)
8532 {
8533 fputs (" <", stdout);
8534 fputs (procname, stdout);
8535
8536 if (sym_offset)
8537 printf ("+0x%lx", (unsigned long) sym_offset);
8538 fputc ('>', stdout);
8539 }
8540
8541 return procname;
8542}
8543
8544static void
8545arm_free_section (struct arm_section *arm_sec)
8546{
9db70fc3
AM
8547 free (arm_sec->data);
8548 free (arm_sec->rela);
0b6ae522
DJ
8549}
8550
a734115a
NC
8551/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8552 cached section and install SEC instead.
8553 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8554 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8555 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8556 relocation's offset in ADDR.
1b31d05e
NC
8557 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8558 into the string table of the symbol associated with the reloc. If no
8559 reloc was applied store -1 there.
8560 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8561
8562static bfd_boolean
dda8d76d
NC
8563get_unwind_section_word (Filedata * filedata,
8564 struct arm_unw_aux_info * aux,
1b31d05e
NC
8565 struct arm_section * arm_sec,
8566 Elf_Internal_Shdr * sec,
8567 bfd_vma word_offset,
8568 unsigned int * wordp,
8569 struct absaddr * addr,
8570 bfd_vma * sym_name)
0b6ae522
DJ
8571{
8572 Elf_Internal_Rela *rp;
8573 Elf_Internal_Sym *sym;
8574 const char * relname;
8575 unsigned int word;
8576 bfd_boolean wrapped;
8577
e0a31db1
NC
8578 if (sec == NULL || arm_sec == NULL)
8579 return FALSE;
8580
0b6ae522
DJ
8581 addr->section = SHN_UNDEF;
8582 addr->offset = 0;
8583
1b31d05e
NC
8584 if (sym_name != NULL)
8585 *sym_name = (bfd_vma) -1;
8586
a734115a 8587 /* If necessary, update the section cache. */
0b6ae522
DJ
8588 if (sec != arm_sec->sec)
8589 {
8590 Elf_Internal_Shdr *relsec;
8591
8592 arm_free_section (arm_sec);
8593
8594 arm_sec->sec = sec;
dda8d76d 8595 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8596 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8597 arm_sec->rela = NULL;
8598 arm_sec->nrelas = 0;
8599
dda8d76d
NC
8600 for (relsec = filedata->section_headers;
8601 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8602 ++relsec)
8603 {
dda8d76d
NC
8604 if (relsec->sh_info >= filedata->file_header.e_shnum
8605 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8606 /* PR 15745: Check the section type as well. */
8607 || (relsec->sh_type != SHT_REL
8608 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8609 continue;
8610
a734115a 8611 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8612 if (relsec->sh_type == SHT_REL)
8613 {
dda8d76d 8614 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8615 relsec->sh_size,
8616 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8617 return FALSE;
0b6ae522 8618 }
1ae40aa4 8619 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8620 {
dda8d76d 8621 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8622 relsec->sh_size,
8623 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8624 return FALSE;
0b6ae522 8625 }
1ae40aa4 8626 break;
0b6ae522
DJ
8627 }
8628
8629 arm_sec->next_rela = arm_sec->rela;
8630 }
8631
a734115a 8632 /* If there is no unwind data we can do nothing. */
0b6ae522 8633 if (arm_sec->data == NULL)
a734115a 8634 return FALSE;
0b6ae522 8635
e0a31db1 8636 /* If the offset is invalid then fail. */
f32ba729
NC
8637 if (/* PR 21343 *//* PR 18879 */
8638 sec->sh_size < 4
8639 || word_offset > (sec->sh_size - 4)
1a915552 8640 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8641 return FALSE;
8642
a734115a 8643 /* Get the word at the required offset. */
0b6ae522
DJ
8644 word = byte_get (arm_sec->data + word_offset, 4);
8645
0eff7165
NC
8646 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8647 if (arm_sec->rela == NULL)
8648 {
8649 * wordp = word;
8650 return TRUE;
8651 }
8652
a734115a 8653 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8654 wrapped = FALSE;
8655 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8656 {
8657 bfd_vma prelval, offset;
8658
8659 if (rp->r_offset > word_offset && !wrapped)
8660 {
8661 rp = arm_sec->rela;
8662 wrapped = TRUE;
8663 }
8664 if (rp->r_offset > word_offset)
8665 break;
8666
8667 if (rp->r_offset & 3)
8668 {
8669 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8670 (unsigned long) rp->r_offset);
8671 continue;
8672 }
8673
8674 if (rp->r_offset < word_offset)
8675 continue;
8676
74e1a04b
NC
8677 /* PR 17531: file: 027-161405-0.004 */
8678 if (aux->symtab == NULL)
8679 continue;
8680
0b6ae522
DJ
8681 if (arm_sec->rel_type == SHT_REL)
8682 {
8683 offset = word & 0x7fffffff;
8684 if (offset & 0x40000000)
8685 offset |= ~ (bfd_vma) 0x7fffffff;
8686 }
a734115a 8687 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8688 offset = rp->r_addend;
a734115a 8689 else
74e1a04b
NC
8690 {
8691 error (_("Unknown section relocation type %d encountered\n"),
8692 arm_sec->rel_type);
8693 break;
8694 }
0b6ae522 8695
071436c6
NC
8696 /* PR 17531 file: 027-1241568-0.004. */
8697 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8698 {
8699 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8700 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8701 break;
8702 }
8703
8704 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8705 offset += sym->st_value;
8706 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8707
a734115a 8708 /* Check that we are processing the expected reloc type. */
dda8d76d 8709 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8710 {
8711 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8712 if (relname == NULL)
8713 {
8714 warn (_("Skipping unknown ARM relocation type: %d\n"),
8715 (int) ELF32_R_TYPE (rp->r_info));
8716 continue;
8717 }
a734115a
NC
8718
8719 if (streq (relname, "R_ARM_NONE"))
8720 continue;
0b4362b0 8721
a734115a
NC
8722 if (! streq (relname, "R_ARM_PREL31"))
8723 {
071436c6 8724 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8725 continue;
8726 }
8727 }
dda8d76d 8728 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8729 {
8730 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8731 if (relname == NULL)
8732 {
8733 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8734 (int) ELF32_R_TYPE (rp->r_info));
8735 continue;
8736 }
0b4362b0 8737
a734115a
NC
8738 if (streq (relname, "R_C6000_NONE"))
8739 continue;
8740
8741 if (! streq (relname, "R_C6000_PREL31"))
8742 {
071436c6 8743 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8744 continue;
8745 }
8746
8747 prelval >>= 1;
8748 }
8749 else
74e1a04b
NC
8750 {
8751 /* This function currently only supports ARM and TI unwinders. */
8752 warn (_("Only TI and ARM unwinders are currently supported\n"));
8753 break;
8754 }
fa197c1c 8755
0b6ae522
DJ
8756 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8757 addr->section = sym->st_shndx;
8758 addr->offset = offset;
74e1a04b 8759
1b31d05e
NC
8760 if (sym_name)
8761 * sym_name = sym->st_name;
0b6ae522
DJ
8762 break;
8763 }
8764
8765 *wordp = word;
8766 arm_sec->next_rela = rp;
8767
a734115a 8768 return TRUE;
0b6ae522
DJ
8769}
8770
a734115a
NC
8771static const char *tic6x_unwind_regnames[16] =
8772{
0b4362b0
RM
8773 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8774 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8775 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8776};
fa197c1c 8777
0b6ae522 8778static void
fa197c1c 8779decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8780{
fa197c1c
PB
8781 int i;
8782
8783 for (i = 12; mask; mask >>= 1, i--)
8784 {
8785 if (mask & 1)
8786 {
8787 fputs (tic6x_unwind_regnames[i], stdout);
8788 if (mask > 1)
8789 fputs (", ", stdout);
8790 }
8791 }
8792}
0b6ae522
DJ
8793
8794#define ADVANCE \
8795 if (remaining == 0 && more_words) \
8796 { \
8797 data_offset += 4; \
dda8d76d 8798 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8799 data_offset, & word, & addr, NULL)) \
32ec8896 8800 return FALSE; \
0b6ae522
DJ
8801 remaining = 4; \
8802 more_words--; \
8803 } \
8804
8805#define GET_OP(OP) \
8806 ADVANCE; \
8807 if (remaining) \
8808 { \
8809 remaining--; \
8810 (OP) = word >> 24; \
8811 word <<= 8; \
8812 } \
8813 else \
8814 { \
2b692964 8815 printf (_("[Truncated opcode]\n")); \
32ec8896 8816 return FALSE; \
0b6ae522 8817 } \
cc5914eb 8818 printf ("0x%02x ", OP)
0b6ae522 8819
32ec8896 8820static bfd_boolean
dda8d76d
NC
8821decode_arm_unwind_bytecode (Filedata * filedata,
8822 struct arm_unw_aux_info * aux,
948f632f
DA
8823 unsigned int word,
8824 unsigned int remaining,
8825 unsigned int more_words,
8826 bfd_vma data_offset,
8827 Elf_Internal_Shdr * data_sec,
8828 struct arm_section * data_arm_sec)
fa197c1c
PB
8829{
8830 struct absaddr addr;
32ec8896 8831 bfd_boolean res = TRUE;
0b6ae522
DJ
8832
8833 /* Decode the unwinding instructions. */
8834 while (1)
8835 {
8836 unsigned int op, op2;
8837
8838 ADVANCE;
8839 if (remaining == 0)
8840 break;
8841 remaining--;
8842 op = word >> 24;
8843 word <<= 8;
8844
cc5914eb 8845 printf (" 0x%02x ", op);
0b6ae522
DJ
8846
8847 if ((op & 0xc0) == 0x00)
8848 {
8849 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8850
cc5914eb 8851 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8852 }
8853 else if ((op & 0xc0) == 0x40)
8854 {
8855 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8856
cc5914eb 8857 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8858 }
8859 else if ((op & 0xf0) == 0x80)
8860 {
8861 GET_OP (op2);
8862 if (op == 0x80 && op2 == 0)
8863 printf (_("Refuse to unwind"));
8864 else
8865 {
8866 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8867 bfd_boolean first = TRUE;
0b6ae522 8868 int i;
2b692964 8869
0b6ae522
DJ
8870 printf ("pop {");
8871 for (i = 0; i < 12; i++)
8872 if (mask & (1 << i))
8873 {
8874 if (first)
32ec8896 8875 first = FALSE;
0b6ae522
DJ
8876 else
8877 printf (", ");
8878 printf ("r%d", 4 + i);
8879 }
8880 printf ("}");
8881 }
8882 }
8883 else if ((op & 0xf0) == 0x90)
8884 {
8885 if (op == 0x9d || op == 0x9f)
8886 printf (_(" [Reserved]"));
8887 else
cc5914eb 8888 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8889 }
8890 else if ((op & 0xf0) == 0xa0)
8891 {
8892 int end = 4 + (op & 0x07);
32ec8896 8893 bfd_boolean first = TRUE;
0b6ae522 8894 int i;
61865e30 8895
0b6ae522
DJ
8896 printf (" pop {");
8897 for (i = 4; i <= end; i++)
8898 {
8899 if (first)
32ec8896 8900 first = FALSE;
0b6ae522
DJ
8901 else
8902 printf (", ");
8903 printf ("r%d", i);
8904 }
8905 if (op & 0x08)
8906 {
1b31d05e 8907 if (!first)
0b6ae522
DJ
8908 printf (", ");
8909 printf ("r14");
8910 }
8911 printf ("}");
8912 }
8913 else if (op == 0xb0)
8914 printf (_(" finish"));
8915 else if (op == 0xb1)
8916 {
8917 GET_OP (op2);
8918 if (op2 == 0 || (op2 & 0xf0) != 0)
8919 printf (_("[Spare]"));
8920 else
8921 {
8922 unsigned int mask = op2 & 0x0f;
32ec8896 8923 bfd_boolean first = TRUE;
0b6ae522 8924 int i;
61865e30 8925
0b6ae522
DJ
8926 printf ("pop {");
8927 for (i = 0; i < 12; i++)
8928 if (mask & (1 << i))
8929 {
8930 if (first)
32ec8896 8931 first = FALSE;
0b6ae522
DJ
8932 else
8933 printf (", ");
8934 printf ("r%d", i);
8935 }
8936 printf ("}");
8937 }
8938 }
8939 else if (op == 0xb2)
8940 {
b115cf96 8941 unsigned char buf[9];
0b6ae522
DJ
8942 unsigned int i, len;
8943 unsigned long offset;
61865e30 8944
b115cf96 8945 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8946 {
8947 GET_OP (buf[i]);
8948 if ((buf[i] & 0x80) == 0)
8949 break;
8950 }
4082ef84 8951 if (i == sizeof (buf))
32ec8896 8952 {
27a45f42 8953 error (_("corrupt change to vsp\n"));
32ec8896
NC
8954 res = FALSE;
8955 }
4082ef84
NC
8956 else
8957 {
cd30bcef 8958 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
8959 assert (len == i + 1);
8960 offset = offset * 4 + 0x204;
8961 printf ("vsp = vsp + %ld", offset);
8962 }
0b6ae522 8963 }
61865e30 8964 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8965 {
61865e30
NC
8966 unsigned int first, last;
8967
8968 GET_OP (op2);
8969 first = op2 >> 4;
8970 last = op2 & 0x0f;
8971 if (op == 0xc8)
8972 first = first + 16;
8973 printf ("pop {D%d", first);
8974 if (last)
8975 printf ("-D%d", first + last);
8976 printf ("}");
8977 }
8978 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8979 {
8980 unsigned int count = op & 0x07;
8981
8982 printf ("pop {D8");
8983 if (count)
8984 printf ("-D%d", 8 + count);
8985 printf ("}");
8986 }
8987 else if (op >= 0xc0 && op <= 0xc5)
8988 {
8989 unsigned int count = op & 0x07;
8990
8991 printf (" pop {wR10");
8992 if (count)
8993 printf ("-wR%d", 10 + count);
8994 printf ("}");
8995 }
8996 else if (op == 0xc6)
8997 {
8998 unsigned int first, last;
8999
9000 GET_OP (op2);
9001 first = op2 >> 4;
9002 last = op2 & 0x0f;
9003 printf ("pop {wR%d", first);
9004 if (last)
9005 printf ("-wR%d", first + last);
9006 printf ("}");
9007 }
9008 else if (op == 0xc7)
9009 {
9010 GET_OP (op2);
9011 if (op2 == 0 || (op2 & 0xf0) != 0)
9012 printf (_("[Spare]"));
0b6ae522
DJ
9013 else
9014 {
61865e30 9015 unsigned int mask = op2 & 0x0f;
32ec8896 9016 bfd_boolean first = TRUE;
61865e30
NC
9017 int i;
9018
9019 printf ("pop {");
9020 for (i = 0; i < 4; i++)
9021 if (mask & (1 << i))
9022 {
9023 if (first)
32ec8896 9024 first = FALSE;
61865e30
NC
9025 else
9026 printf (", ");
9027 printf ("wCGR%d", i);
9028 }
9029 printf ("}");
0b6ae522
DJ
9030 }
9031 }
61865e30 9032 else
32ec8896
NC
9033 {
9034 printf (_(" [unsupported opcode]"));
9035 res = FALSE;
9036 }
9037
0b6ae522
DJ
9038 printf ("\n");
9039 }
32ec8896
NC
9040
9041 return res;
fa197c1c
PB
9042}
9043
32ec8896 9044static bfd_boolean
dda8d76d
NC
9045decode_tic6x_unwind_bytecode (Filedata * filedata,
9046 struct arm_unw_aux_info * aux,
948f632f
DA
9047 unsigned int word,
9048 unsigned int remaining,
9049 unsigned int more_words,
9050 bfd_vma data_offset,
9051 Elf_Internal_Shdr * data_sec,
9052 struct arm_section * data_arm_sec)
fa197c1c
PB
9053{
9054 struct absaddr addr;
9055
9056 /* Decode the unwinding instructions. */
9057 while (1)
9058 {
9059 unsigned int op, op2;
9060
9061 ADVANCE;
9062 if (remaining == 0)
9063 break;
9064 remaining--;
9065 op = word >> 24;
9066 word <<= 8;
9067
9cf03b7e 9068 printf (" 0x%02x ", op);
fa197c1c
PB
9069
9070 if ((op & 0xc0) == 0x00)
9071 {
9072 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9073 printf (" sp = sp + %d", offset);
fa197c1c
PB
9074 }
9075 else if ((op & 0xc0) == 0x80)
9076 {
9077 GET_OP (op2);
9078 if (op == 0x80 && op2 == 0)
9079 printf (_("Refuse to unwind"));
9080 else
9081 {
9082 unsigned int mask = ((op & 0x1f) << 8) | op2;
9083 if (op & 0x20)
9084 printf ("pop compact {");
9085 else
9086 printf ("pop {");
9087
9088 decode_tic6x_unwind_regmask (mask);
9089 printf("}");
9090 }
9091 }
9092 else if ((op & 0xf0) == 0xc0)
9093 {
9094 unsigned int reg;
9095 unsigned int nregs;
9096 unsigned int i;
9097 const char *name;
a734115a
NC
9098 struct
9099 {
32ec8896
NC
9100 unsigned int offset;
9101 unsigned int reg;
fa197c1c
PB
9102 } regpos[16];
9103
9104 /* Scan entire instruction first so that GET_OP output is not
9105 interleaved with disassembly. */
9106 nregs = 0;
9107 for (i = 0; nregs < (op & 0xf); i++)
9108 {
9109 GET_OP (op2);
9110 reg = op2 >> 4;
9111 if (reg != 0xf)
9112 {
9113 regpos[nregs].offset = i * 2;
9114 regpos[nregs].reg = reg;
9115 nregs++;
9116 }
9117
9118 reg = op2 & 0xf;
9119 if (reg != 0xf)
9120 {
9121 regpos[nregs].offset = i * 2 + 1;
9122 regpos[nregs].reg = reg;
9123 nregs++;
9124 }
9125 }
9126
9127 printf (_("pop frame {"));
18344509 9128 if (nregs == 0)
fa197c1c 9129 {
18344509
NC
9130 printf (_("*corrupt* - no registers specified"));
9131 }
9132 else
9133 {
9134 reg = nregs - 1;
9135 for (i = i * 2; i > 0; i--)
fa197c1c 9136 {
18344509
NC
9137 if (regpos[reg].offset == i - 1)
9138 {
9139 name = tic6x_unwind_regnames[regpos[reg].reg];
9140 if (reg > 0)
9141 reg--;
9142 }
9143 else
9144 name = _("[pad]");
fa197c1c 9145
18344509
NC
9146 fputs (name, stdout);
9147 if (i > 1)
9148 printf (", ");
9149 }
fa197c1c
PB
9150 }
9151
9152 printf ("}");
9153 }
9154 else if (op == 0xd0)
9155 printf (" MOV FP, SP");
9156 else if (op == 0xd1)
9157 printf (" __c6xabi_pop_rts");
9158 else if (op == 0xd2)
9159 {
9160 unsigned char buf[9];
9161 unsigned int i, len;
9162 unsigned long offset;
a734115a 9163
fa197c1c
PB
9164 for (i = 0; i < sizeof (buf); i++)
9165 {
9166 GET_OP (buf[i]);
9167 if ((buf[i] & 0x80) == 0)
9168 break;
9169 }
0eff7165
NC
9170 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9171 if (i == sizeof (buf))
9172 {
0eff7165 9173 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9174 return FALSE;
0eff7165 9175 }
948f632f 9176
cd30bcef 9177 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9178 assert (len == i + 1);
9179 offset = offset * 8 + 0x408;
9180 printf (_("sp = sp + %ld"), offset);
9181 }
9182 else if ((op & 0xf0) == 0xe0)
9183 {
9184 if ((op & 0x0f) == 7)
9185 printf (" RETURN");
9186 else
9187 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9188 }
9189 else
9190 {
9191 printf (_(" [unsupported opcode]"));
9192 }
9193 putchar ('\n');
9194 }
32ec8896
NC
9195
9196 return TRUE;
fa197c1c
PB
9197}
9198
9199static bfd_vma
dda8d76d 9200arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9201{
9202 bfd_vma offset;
9203
9204 offset = word & 0x7fffffff;
9205 if (offset & 0x40000000)
9206 offset |= ~ (bfd_vma) 0x7fffffff;
9207
dda8d76d 9208 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9209 offset <<= 1;
9210
9211 return offset + where;
9212}
9213
32ec8896 9214static bfd_boolean
dda8d76d
NC
9215decode_arm_unwind (Filedata * filedata,
9216 struct arm_unw_aux_info * aux,
1b31d05e
NC
9217 unsigned int word,
9218 unsigned int remaining,
9219 bfd_vma data_offset,
9220 Elf_Internal_Shdr * data_sec,
9221 struct arm_section * data_arm_sec)
fa197c1c
PB
9222{
9223 int per_index;
9224 unsigned int more_words = 0;
37e14bc3 9225 struct absaddr addr;
1b31d05e 9226 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9227 bfd_boolean res = TRUE;
fa197c1c
PB
9228
9229 if (remaining == 0)
9230 {
1b31d05e
NC
9231 /* Fetch the first word.
9232 Note - when decoding an object file the address extracted
9233 here will always be 0. So we also pass in the sym_name
9234 parameter so that we can find the symbol associated with
9235 the personality routine. */
dda8d76d 9236 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9237 & word, & addr, & sym_name))
32ec8896 9238 return FALSE;
1b31d05e 9239
fa197c1c
PB
9240 remaining = 4;
9241 }
c93dbb25
CZ
9242 else
9243 {
9244 addr.section = SHN_UNDEF;
9245 addr.offset = 0;
9246 }
fa197c1c
PB
9247
9248 if ((word & 0x80000000) == 0)
9249 {
9250 /* Expand prel31 for personality routine. */
9251 bfd_vma fn;
9252 const char *procname;
9253
dda8d76d 9254 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9255 printf (_(" Personality routine: "));
1b31d05e
NC
9256 if (fn == 0
9257 && addr.section == SHN_UNDEF && addr.offset == 0
9258 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9259 {
9260 procname = aux->strtab + sym_name;
9261 print_vma (fn, PREFIX_HEX);
9262 if (procname)
9263 {
9264 fputs (" <", stdout);
9265 fputs (procname, stdout);
9266 fputc ('>', stdout);
9267 }
9268 }
9269 else
dda8d76d 9270 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9271 fputc ('\n', stdout);
9272
9273 /* The GCC personality routines use the standard compact
9274 encoding, starting with one byte giving the number of
9275 words. */
9276 if (procname != NULL
9277 && (const_strneq (procname, "__gcc_personality_v0")
9278 || const_strneq (procname, "__gxx_personality_v0")
9279 || const_strneq (procname, "__gcj_personality_v0")
9280 || const_strneq (procname, "__gnu_objc_personality_v0")))
9281 {
9282 remaining = 0;
9283 more_words = 1;
9284 ADVANCE;
9285 if (!remaining)
9286 {
9287 printf (_(" [Truncated data]\n"));
32ec8896 9288 return FALSE;
fa197c1c
PB
9289 }
9290 more_words = word >> 24;
9291 word <<= 8;
9292 remaining--;
9293 per_index = -1;
9294 }
9295 else
32ec8896 9296 return TRUE;
fa197c1c
PB
9297 }
9298 else
9299 {
1b31d05e 9300 /* ARM EHABI Section 6.3:
0b4362b0 9301
1b31d05e 9302 An exception-handling table entry for the compact model looks like:
0b4362b0 9303
1b31d05e
NC
9304 31 30-28 27-24 23-0
9305 -- ----- ----- ----
9306 1 0 index Data for personalityRoutine[index] */
9307
dda8d76d 9308 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9309 && (word & 0x70000000))
32ec8896
NC
9310 {
9311 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9312 res = FALSE;
9313 }
1b31d05e 9314
fa197c1c 9315 per_index = (word >> 24) & 0x7f;
1b31d05e 9316 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9317 if (per_index == 0)
9318 {
9319 more_words = 0;
9320 word <<= 8;
9321 remaining--;
9322 }
9323 else if (per_index < 3)
9324 {
9325 more_words = (word >> 16) & 0xff;
9326 word <<= 16;
9327 remaining -= 2;
9328 }
9329 }
9330
dda8d76d 9331 switch (filedata->file_header.e_machine)
fa197c1c
PB
9332 {
9333 case EM_ARM:
9334 if (per_index < 3)
9335 {
dda8d76d 9336 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9337 data_offset, data_sec, data_arm_sec))
9338 res = FALSE;
fa197c1c
PB
9339 }
9340 else
1b31d05e
NC
9341 {
9342 warn (_("Unknown ARM compact model index encountered\n"));
9343 printf (_(" [reserved]\n"));
32ec8896 9344 res = FALSE;
1b31d05e 9345 }
fa197c1c
PB
9346 break;
9347
9348 case EM_TI_C6000:
9349 if (per_index < 3)
9350 {
dda8d76d 9351 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9352 data_offset, data_sec, data_arm_sec))
9353 res = FALSE;
fa197c1c
PB
9354 }
9355 else if (per_index < 5)
9356 {
9357 if (((word >> 17) & 0x7f) == 0x7f)
9358 printf (_(" Restore stack from frame pointer\n"));
9359 else
9360 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9361 printf (_(" Registers restored: "));
9362 if (per_index == 4)
9363 printf (" (compact) ");
9364 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9365 putchar ('\n');
9366 printf (_(" Return register: %s\n"),
9367 tic6x_unwind_regnames[word & 0xf]);
9368 }
9369 else
1b31d05e 9370 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9371 break;
9372
9373 default:
74e1a04b 9374 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9375 filedata->file_header.e_machine);
32ec8896 9376 res = FALSE;
fa197c1c 9377 }
0b6ae522
DJ
9378
9379 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9380
9381 return res;
0b6ae522
DJ
9382}
9383
32ec8896 9384static bfd_boolean
dda8d76d
NC
9385dump_arm_unwind (Filedata * filedata,
9386 struct arm_unw_aux_info * aux,
9387 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9388{
9389 struct arm_section exidx_arm_sec, extab_arm_sec;
9390 unsigned int i, exidx_len;
948f632f 9391 unsigned long j, nfuns;
32ec8896 9392 bfd_boolean res = TRUE;
0b6ae522
DJ
9393
9394 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9395 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9396 exidx_len = exidx_sec->sh_size / 8;
9397
948f632f
DA
9398 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9399 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9400 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9401 aux->funtab[nfuns++] = aux->symtab[j];
9402 aux->nfuns = nfuns;
9403 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9404
0b6ae522
DJ
9405 for (i = 0; i < exidx_len; i++)
9406 {
9407 unsigned int exidx_fn, exidx_entry;
9408 struct absaddr fn_addr, entry_addr;
9409 bfd_vma fn;
9410
9411 fputc ('\n', stdout);
9412
dda8d76d 9413 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9414 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9415 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9416 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9417 {
948f632f 9418 free (aux->funtab);
1b31d05e
NC
9419 arm_free_section (& exidx_arm_sec);
9420 arm_free_section (& extab_arm_sec);
32ec8896 9421 return FALSE;
0b6ae522
DJ
9422 }
9423
83c257ca
NC
9424 /* ARM EHABI, Section 5:
9425 An index table entry consists of 2 words.
9426 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9427 if (exidx_fn & 0x80000000)
32ec8896
NC
9428 {
9429 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9430 res = FALSE;
9431 }
83c257ca 9432
dda8d76d 9433 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9434
dda8d76d 9435 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9436 fputs (": ", stdout);
9437
9438 if (exidx_entry == 1)
9439 {
9440 print_vma (exidx_entry, PREFIX_HEX);
9441 fputs (" [cantunwind]\n", stdout);
9442 }
9443 else if (exidx_entry & 0x80000000)
9444 {
9445 print_vma (exidx_entry, PREFIX_HEX);
9446 fputc ('\n', stdout);
dda8d76d 9447 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9448 }
9449 else
9450 {
8f73510c 9451 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9452 Elf_Internal_Shdr *table_sec;
9453
9454 fputs ("@", stdout);
dda8d76d 9455 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9456 print_vma (table, PREFIX_HEX);
9457 printf ("\n");
9458
9459 /* Locate the matching .ARM.extab. */
9460 if (entry_addr.section != SHN_UNDEF
dda8d76d 9461 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9462 {
dda8d76d 9463 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9464 table_offset = entry_addr.offset;
1a915552
NC
9465 /* PR 18879 */
9466 if (table_offset > table_sec->sh_size
9467 || ((bfd_signed_vma) table_offset) < 0)
9468 {
9469 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9470 (unsigned long) table_offset,
dda8d76d 9471 printable_section_name (filedata, table_sec));
32ec8896 9472 res = FALSE;
1a915552
NC
9473 continue;
9474 }
0b6ae522
DJ
9475 }
9476 else
9477 {
dda8d76d 9478 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9479 if (table_sec != NULL)
9480 table_offset = table - table_sec->sh_addr;
9481 }
32ec8896 9482
0b6ae522
DJ
9483 if (table_sec == NULL)
9484 {
9485 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9486 (unsigned long) table);
32ec8896 9487 res = FALSE;
0b6ae522
DJ
9488 continue;
9489 }
32ec8896 9490
dda8d76d 9491 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9492 &extab_arm_sec))
9493 res = FALSE;
0b6ae522
DJ
9494 }
9495 }
9496
9497 printf ("\n");
9498
948f632f 9499 free (aux->funtab);
0b6ae522
DJ
9500 arm_free_section (&exidx_arm_sec);
9501 arm_free_section (&extab_arm_sec);
32ec8896
NC
9502
9503 return res;
0b6ae522
DJ
9504}
9505
fa197c1c 9506/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9507
32ec8896 9508static bfd_boolean
dda8d76d 9509arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9510{
9511 struct arm_unw_aux_info aux;
9512 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9513 Elf_Internal_Shdr *sec;
9514 unsigned long i;
fa197c1c 9515 unsigned int sec_type;
32ec8896 9516 bfd_boolean res = TRUE;
0b6ae522 9517
dda8d76d 9518 switch (filedata->file_header.e_machine)
fa197c1c
PB
9519 {
9520 case EM_ARM:
9521 sec_type = SHT_ARM_EXIDX;
9522 break;
9523
9524 case EM_TI_C6000:
9525 sec_type = SHT_C6000_UNWIND;
9526 break;
9527
0b4362b0 9528 default:
74e1a04b 9529 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9530 filedata->file_header.e_machine);
32ec8896 9531 return FALSE;
fa197c1c
PB
9532 }
9533
dda8d76d 9534 if (filedata->string_table == NULL)
32ec8896 9535 return FALSE;
1b31d05e
NC
9536
9537 memset (& aux, 0, sizeof (aux));
dda8d76d 9538 aux.filedata = filedata;
0b6ae522 9539
dda8d76d 9540 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9541 {
28d13567 9542 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9543 {
28d13567 9544 if (aux.symtab)
74e1a04b 9545 {
28d13567
AM
9546 error (_("Multiple symbol tables encountered\n"));
9547 free (aux.symtab);
9548 aux.symtab = NULL;
74e1a04b 9549 free (aux.strtab);
28d13567 9550 aux.strtab = NULL;
74e1a04b 9551 }
28d13567
AM
9552 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9553 &aux.strtab, &aux.strtab_size))
9554 return FALSE;
0b6ae522 9555 }
fa197c1c 9556 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9557 unwsec = sec;
9558 }
9559
1b31d05e 9560 if (unwsec == NULL)
0b6ae522 9561 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9562 else
dda8d76d 9563 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9564 {
9565 if (sec->sh_type == sec_type)
9566 {
d3a49aa8
AM
9567 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9568 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9569 "contains %lu entry:\n",
9570 "\nUnwind section '%s' at offset 0x%lx "
9571 "contains %lu entries:\n",
9572 num_unwind),
dda8d76d 9573 printable_section_name (filedata, sec),
1b31d05e 9574 (unsigned long) sec->sh_offset,
d3a49aa8 9575 num_unwind);
0b6ae522 9576
dda8d76d 9577 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9578 res = FALSE;
1b31d05e
NC
9579 }
9580 }
0b6ae522 9581
9db70fc3
AM
9582 free (aux.symtab);
9583 free ((char *) aux.strtab);
32ec8896
NC
9584
9585 return res;
0b6ae522
DJ
9586}
9587
32ec8896 9588static bfd_boolean
dda8d76d 9589process_unwind (Filedata * filedata)
57346661 9590{
2cf0635d
NC
9591 struct unwind_handler
9592 {
32ec8896 9593 unsigned int machtype;
dda8d76d 9594 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9595 } handlers[] =
9596 {
0b6ae522 9597 { EM_ARM, arm_process_unwind },
57346661
AM
9598 { EM_IA_64, ia64_process_unwind },
9599 { EM_PARISC, hppa_process_unwind },
fa197c1c 9600 { EM_TI_C6000, arm_process_unwind },
32ec8896 9601 { 0, NULL }
57346661
AM
9602 };
9603 int i;
9604
9605 if (!do_unwind)
32ec8896 9606 return TRUE;
57346661
AM
9607
9608 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9609 if (filedata->file_header.e_machine == handlers[i].machtype)
9610 return handlers[i].handler (filedata);
57346661 9611
1b31d05e 9612 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9613 get_machine_name (filedata->file_header.e_machine));
32ec8896 9614 return TRUE;
57346661
AM
9615}
9616
37c18eed
SD
9617static void
9618dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9619{
9620 switch (entry->d_tag)
9621 {
9622 case DT_AARCH64_BTI_PLT:
1dbade74 9623 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9624 break;
9625 default:
9626 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9627 break;
9628 }
9629 putchar ('\n');
9630}
9631
252b5132 9632static void
978c4450 9633dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9634{
9635 switch (entry->d_tag)
9636 {
9637 case DT_MIPS_FLAGS:
9638 if (entry->d_un.d_val == 0)
4b68bca3 9639 printf (_("NONE"));
252b5132
RH
9640 else
9641 {
9642 static const char * opts[] =
9643 {
9644 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9645 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9646 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9647 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9648 "RLD_ORDER_SAFE"
9649 };
9650 unsigned int cnt;
32ec8896 9651 bfd_boolean first = TRUE;
2b692964 9652
60bca95a 9653 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9654 if (entry->d_un.d_val & (1 << cnt))
9655 {
9656 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9657 first = FALSE;
252b5132 9658 }
252b5132
RH
9659 }
9660 break;
103f02d3 9661
252b5132 9662 case DT_MIPS_IVERSION:
978c4450
AM
9663 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9664 printf (_("Interface Version: %s"),
9665 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9666 else
76ca31c0
NC
9667 {
9668 char buf[40];
9669 sprintf_vma (buf, entry->d_un.d_ptr);
9670 /* Note: coded this way so that there is a single string for translation. */
9671 printf (_("<corrupt: %s>"), buf);
9672 }
252b5132 9673 break;
103f02d3 9674
252b5132
RH
9675 case DT_MIPS_TIME_STAMP:
9676 {
d5b07ef4 9677 char timebuf[128];
2cf0635d 9678 struct tm * tmp;
91d6fa6a 9679 time_t atime = entry->d_un.d_val;
82b1b41b 9680
91d6fa6a 9681 tmp = gmtime (&atime);
82b1b41b
NC
9682 /* PR 17531: file: 6accc532. */
9683 if (tmp == NULL)
9684 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9685 else
9686 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9687 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9688 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9689 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9690 }
9691 break;
103f02d3 9692
252b5132
RH
9693 case DT_MIPS_RLD_VERSION:
9694 case DT_MIPS_LOCAL_GOTNO:
9695 case DT_MIPS_CONFLICTNO:
9696 case DT_MIPS_LIBLISTNO:
9697 case DT_MIPS_SYMTABNO:
9698 case DT_MIPS_UNREFEXTNO:
9699 case DT_MIPS_HIPAGENO:
9700 case DT_MIPS_DELTA_CLASS_NO:
9701 case DT_MIPS_DELTA_INSTANCE_NO:
9702 case DT_MIPS_DELTA_RELOC_NO:
9703 case DT_MIPS_DELTA_SYM_NO:
9704 case DT_MIPS_DELTA_CLASSSYM_NO:
9705 case DT_MIPS_COMPACT_SIZE:
c69075ac 9706 print_vma (entry->d_un.d_val, DEC);
252b5132 9707 break;
103f02d3 9708
f16a9783 9709 case DT_MIPS_XHASH:
978c4450
AM
9710 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9711 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9712 /* Falls through. */
9713
103f02d3 9714 default:
4b68bca3 9715 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9716 }
4b68bca3 9717 putchar ('\n');
103f02d3
UD
9718}
9719
103f02d3 9720static void
2cf0635d 9721dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9722{
9723 switch (entry->d_tag)
9724 {
9725 case DT_HP_DLD_FLAGS:
9726 {
9727 static struct
9728 {
9729 long int bit;
2cf0635d 9730 const char * str;
5e220199
NC
9731 }
9732 flags[] =
9733 {
9734 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9735 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9736 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9737 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9738 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9739 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9740 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9741 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9742 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9743 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9744 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9745 { DT_HP_GST, "HP_GST" },
9746 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9747 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9748 { DT_HP_NODELETE, "HP_NODELETE" },
9749 { DT_HP_GROUP, "HP_GROUP" },
9750 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9751 };
32ec8896 9752 bfd_boolean first = TRUE;
5e220199 9753 size_t cnt;
f7a99963 9754 bfd_vma val = entry->d_un.d_val;
103f02d3 9755
60bca95a 9756 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9757 if (val & flags[cnt].bit)
30800947
NC
9758 {
9759 if (! first)
9760 putchar (' ');
9761 fputs (flags[cnt].str, stdout);
32ec8896 9762 first = FALSE;
30800947
NC
9763 val ^= flags[cnt].bit;
9764 }
76da6bbe 9765
103f02d3 9766 if (val != 0 || first)
f7a99963
NC
9767 {
9768 if (! first)
9769 putchar (' ');
9770 print_vma (val, HEX);
9771 }
103f02d3
UD
9772 }
9773 break;
76da6bbe 9774
252b5132 9775 default:
f7a99963
NC
9776 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9777 break;
252b5132 9778 }
35b1837e 9779 putchar ('\n');
252b5132
RH
9780}
9781
28f997cf
TG
9782#ifdef BFD64
9783
9784/* VMS vs Unix time offset and factor. */
9785
9786#define VMS_EPOCH_OFFSET 35067168000000000LL
9787#define VMS_GRANULARITY_FACTOR 10000000
9788
9789/* Display a VMS time in a human readable format. */
9790
9791static void
9792print_vms_time (bfd_int64_t vmstime)
9793{
9794 struct tm *tm;
9795 time_t unxtime;
9796
9797 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9798 tm = gmtime (&unxtime);
9799 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9800 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9801 tm->tm_hour, tm->tm_min, tm->tm_sec);
9802}
9803#endif /* BFD64 */
9804
ecc51f48 9805static void
2cf0635d 9806dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9807{
9808 switch (entry->d_tag)
9809 {
0de14b54 9810 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9811 /* First 3 slots reserved. */
ecc51f48
NC
9812 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9813 printf (" -- ");
9814 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9815 break;
9816
28f997cf
TG
9817 case DT_IA_64_VMS_LINKTIME:
9818#ifdef BFD64
9819 print_vms_time (entry->d_un.d_val);
9820#endif
9821 break;
9822
9823 case DT_IA_64_VMS_LNKFLAGS:
9824 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9825 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9826 printf (" CALL_DEBUG");
9827 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9828 printf (" NOP0BUFS");
9829 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9830 printf (" P0IMAGE");
9831 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9832 printf (" MKTHREADS");
9833 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9834 printf (" UPCALLS");
9835 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9836 printf (" IMGSTA");
9837 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9838 printf (" INITIALIZE");
9839 if (entry->d_un.d_val & VMS_LF_MAIN)
9840 printf (" MAIN");
9841 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9842 printf (" EXE_INIT");
9843 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9844 printf (" TBK_IN_IMG");
9845 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9846 printf (" DBG_IN_IMG");
9847 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9848 printf (" TBK_IN_DSF");
9849 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9850 printf (" DBG_IN_DSF");
9851 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9852 printf (" SIGNATURES");
9853 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9854 printf (" REL_SEG_OFF");
9855 break;
9856
bdf4d63a
JJ
9857 default:
9858 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9859 break;
ecc51f48 9860 }
bdf4d63a 9861 putchar ('\n');
ecc51f48
NC
9862}
9863
32ec8896 9864static bfd_boolean
dda8d76d 9865get_32bit_dynamic_section (Filedata * filedata)
252b5132 9866{
2cf0635d
NC
9867 Elf32_External_Dyn * edyn;
9868 Elf32_External_Dyn * ext;
9869 Elf_Internal_Dyn * entry;
103f02d3 9870
978c4450
AM
9871 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
9872 filedata->dynamic_addr, 1,
9873 filedata->dynamic_size,
9874 _("dynamic section"));
a6e9f9df 9875 if (!edyn)
32ec8896 9876 return FALSE;
103f02d3 9877
071436c6
NC
9878 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9879 might not have the luxury of section headers. Look for the DT_NULL
9880 terminator to determine the number of entries. */
978c4450
AM
9881 for (ext = edyn, filedata->dynamic_nent = 0;
9882 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9883 ext++)
9884 {
978c4450 9885 filedata->dynamic_nent++;
ba2685cc
AM
9886 if (BYTE_GET (ext->d_tag) == DT_NULL)
9887 break;
9888 }
252b5132 9889
978c4450
AM
9890 filedata->dynamic_section
9891 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9892 if (filedata->dynamic_section == NULL)
252b5132 9893 {
8b73c356 9894 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9895 (unsigned long) filedata->dynamic_nent);
9ea033b2 9896 free (edyn);
32ec8896 9897 return FALSE;
9ea033b2 9898 }
252b5132 9899
978c4450
AM
9900 for (ext = edyn, entry = filedata->dynamic_section;
9901 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9902 ext++, entry++)
9ea033b2 9903 {
fb514b26
AM
9904 entry->d_tag = BYTE_GET (ext->d_tag);
9905 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9906 }
9907
9ea033b2
NC
9908 free (edyn);
9909
32ec8896 9910 return TRUE;
9ea033b2
NC
9911}
9912
32ec8896 9913static bfd_boolean
dda8d76d 9914get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9915{
2cf0635d
NC
9916 Elf64_External_Dyn * edyn;
9917 Elf64_External_Dyn * ext;
9918 Elf_Internal_Dyn * entry;
103f02d3 9919
071436c6 9920 /* Read in the data. */
978c4450
AM
9921 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
9922 filedata->dynamic_addr, 1,
9923 filedata->dynamic_size,
9924 _("dynamic section"));
a6e9f9df 9925 if (!edyn)
32ec8896 9926 return FALSE;
103f02d3 9927
071436c6
NC
9928 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9929 might not have the luxury of section headers. Look for the DT_NULL
9930 terminator to determine the number of entries. */
978c4450 9931 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 9932 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 9933 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9934 ext++)
9935 {
978c4450 9936 filedata->dynamic_nent++;
66543521 9937 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9938 break;
9939 }
252b5132 9940
978c4450
AM
9941 filedata->dynamic_section
9942 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9943 if (filedata->dynamic_section == NULL)
252b5132 9944 {
8b73c356 9945 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9946 (unsigned long) filedata->dynamic_nent);
252b5132 9947 free (edyn);
32ec8896 9948 return FALSE;
252b5132
RH
9949 }
9950
071436c6 9951 /* Convert from external to internal formats. */
978c4450
AM
9952 for (ext = edyn, entry = filedata->dynamic_section;
9953 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9954 ext++, entry++)
252b5132 9955 {
66543521
AM
9956 entry->d_tag = BYTE_GET (ext->d_tag);
9957 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9958 }
9959
9960 free (edyn);
9961
32ec8896 9962 return TRUE;
9ea033b2
NC
9963}
9964
e9e44622
JJ
9965static void
9966print_dynamic_flags (bfd_vma flags)
d1133906 9967{
32ec8896 9968 bfd_boolean first = TRUE;
13ae64f3 9969
d1133906
NC
9970 while (flags)
9971 {
9972 bfd_vma flag;
9973
9974 flag = flags & - flags;
9975 flags &= ~ flag;
9976
e9e44622 9977 if (first)
32ec8896 9978 first = FALSE;
e9e44622
JJ
9979 else
9980 putc (' ', stdout);
13ae64f3 9981
d1133906
NC
9982 switch (flag)
9983 {
e9e44622
JJ
9984 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9985 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9986 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9987 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9988 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9989 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9990 }
9991 }
e9e44622 9992 puts ("");
d1133906
NC
9993}
9994
10ca4b04
L
9995static bfd_vma *
9996get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
9997{
9998 unsigned char * e_data;
9999 bfd_vma * i_data;
10000
10001 /* If the size_t type is smaller than the bfd_size_type, eg because
10002 you are building a 32-bit tool on a 64-bit host, then make sure
10003 that when (number) is cast to (size_t) no information is lost. */
10004 if (sizeof (size_t) < sizeof (bfd_size_type)
10005 && (bfd_size_type) ((size_t) number) != number)
10006 {
10007 error (_("Size truncation prevents reading %s elements of size %u\n"),
10008 bfd_vmatoa ("u", number), ent_size);
10009 return NULL;
10010 }
10011
10012 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10013 attempting to allocate memory when the read is bound to fail. */
10014 if (ent_size * number > filedata->file_size)
10015 {
10016 error (_("Invalid number of dynamic entries: %s\n"),
10017 bfd_vmatoa ("u", number));
10018 return NULL;
10019 }
10020
10021 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10022 if (e_data == NULL)
10023 {
10024 error (_("Out of memory reading %s dynamic entries\n"),
10025 bfd_vmatoa ("u", number));
10026 return NULL;
10027 }
10028
10029 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10030 {
10031 error (_("Unable to read in %s bytes of dynamic data\n"),
10032 bfd_vmatoa ("u", number * ent_size));
10033 free (e_data);
10034 return NULL;
10035 }
10036
10037 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10038 if (i_data == NULL)
10039 {
10040 error (_("Out of memory allocating space for %s dynamic entries\n"),
10041 bfd_vmatoa ("u", number));
10042 free (e_data);
10043 return NULL;
10044 }
10045
10046 while (number--)
10047 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10048
10049 free (e_data);
10050
10051 return i_data;
10052}
10053
10054static unsigned long
10055get_num_dynamic_syms (Filedata * filedata)
10056{
10057 unsigned long num_of_syms = 0;
10058
10059 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10060 return num_of_syms;
10061
978c4450 10062 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10063 {
10064 unsigned char nb[8];
10065 unsigned char nc[8];
10066 unsigned int hash_ent_size = 4;
10067
10068 if ((filedata->file_header.e_machine == EM_ALPHA
10069 || filedata->file_header.e_machine == EM_S390
10070 || filedata->file_header.e_machine == EM_S390_OLD)
10071 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10072 hash_ent_size = 8;
10073
10074 if (fseek (filedata->handle,
978c4450
AM
10075 (filedata->archive_file_offset
10076 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10077 sizeof nb + sizeof nc)),
10078 SEEK_SET))
10079 {
10080 error (_("Unable to seek to start of dynamic information\n"));
10081 goto no_hash;
10082 }
10083
10084 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10085 {
10086 error (_("Failed to read in number of buckets\n"));
10087 goto no_hash;
10088 }
10089
10090 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10091 {
10092 error (_("Failed to read in number of chains\n"));
10093 goto no_hash;
10094 }
10095
978c4450
AM
10096 filedata->nbuckets = byte_get (nb, hash_ent_size);
10097 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10098
2482f306
AM
10099 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10100 {
10101 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10102 hash_ent_size);
10103 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10104 hash_ent_size);
001890e1 10105
2482f306
AM
10106 if (filedata->buckets != NULL && filedata->chains != NULL)
10107 num_of_syms = filedata->nchains;
10108 }
ceb9bf11 10109 no_hash:
10ca4b04
L
10110 if (num_of_syms == 0)
10111 {
9db70fc3
AM
10112 free (filedata->buckets);
10113 filedata->buckets = NULL;
10114 free (filedata->chains);
10115 filedata->chains = NULL;
978c4450 10116 filedata->nbuckets = 0;
10ca4b04
L
10117 }
10118 }
10119
978c4450 10120 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10121 {
10122 unsigned char nb[16];
10123 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10124 bfd_vma buckets_vma;
10125 unsigned long hn;
10ca4b04
L
10126
10127 if (fseek (filedata->handle,
978c4450
AM
10128 (filedata->archive_file_offset
10129 + offset_from_vma (filedata,
10130 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10131 sizeof nb)),
10132 SEEK_SET))
10133 {
10134 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10135 goto no_gnu_hash;
10136 }
10137
10138 if (fread (nb, 16, 1, filedata->handle) != 1)
10139 {
10140 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10141 goto no_gnu_hash;
10142 }
10143
978c4450
AM
10144 filedata->ngnubuckets = byte_get (nb, 4);
10145 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10146 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10147 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10148 if (is_32bit_elf)
10149 buckets_vma += bitmaskwords * 4;
10150 else
10151 buckets_vma += bitmaskwords * 8;
10152
10153 if (fseek (filedata->handle,
978c4450 10154 (filedata->archive_file_offset
10ca4b04
L
10155 + offset_from_vma (filedata, buckets_vma, 4)),
10156 SEEK_SET))
10157 {
10158 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10159 goto no_gnu_hash;
10160 }
10161
978c4450
AM
10162 filedata->gnubuckets
10163 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10164
978c4450 10165 if (filedata->gnubuckets == NULL)
90837ea7 10166 goto no_gnu_hash;
10ca4b04 10167
978c4450
AM
10168 for (i = 0; i < filedata->ngnubuckets; i++)
10169 if (filedata->gnubuckets[i] != 0)
10ca4b04 10170 {
978c4450 10171 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10172 goto no_gnu_hash;
10ca4b04 10173
978c4450
AM
10174 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10175 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10176 }
10177
10178 if (maxchain == 0xffffffff)
90837ea7 10179 goto no_gnu_hash;
10ca4b04 10180
978c4450 10181 maxchain -= filedata->gnusymidx;
10ca4b04
L
10182
10183 if (fseek (filedata->handle,
978c4450
AM
10184 (filedata->archive_file_offset
10185 + offset_from_vma (filedata,
10186 buckets_vma + 4 * (filedata->ngnubuckets
10187 + maxchain),
10188 4)),
10ca4b04
L
10189 SEEK_SET))
10190 {
10191 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10192 goto no_gnu_hash;
10193 }
10194
10195 do
10196 {
10197 if (fread (nb, 4, 1, filedata->handle) != 1)
10198 {
10199 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10200 goto no_gnu_hash;
10201 }
10202
10203 if (maxchain + 1 == 0)
90837ea7 10204 goto no_gnu_hash;
10ca4b04
L
10205
10206 ++maxchain;
10207 }
10208 while ((byte_get (nb, 4) & 1) == 0);
10209
10210 if (fseek (filedata->handle,
978c4450
AM
10211 (filedata->archive_file_offset
10212 + offset_from_vma (filedata, (buckets_vma
10213 + 4 * filedata->ngnubuckets),
10214 4)),
10ca4b04
L
10215 SEEK_SET))
10216 {
10217 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10218 goto no_gnu_hash;
10219 }
10220
978c4450
AM
10221 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10222 filedata->ngnuchains = maxchain;
10ca4b04 10223
978c4450 10224 if (filedata->gnuchains == NULL)
90837ea7 10225 goto no_gnu_hash;
10ca4b04 10226
978c4450 10227 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10228 {
10229 if (fseek (filedata->handle,
978c4450 10230 (filedata->archive_file_offset
10ca4b04 10231 + offset_from_vma (filedata, (buckets_vma
978c4450 10232 + 4 * (filedata->ngnubuckets
10ca4b04
L
10233 + maxchain)), 4)),
10234 SEEK_SET))
10235 {
10236 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10237 goto no_gnu_hash;
10238 }
10239
978c4450 10240 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10241 if (filedata->mipsxlat == NULL)
10242 goto no_gnu_hash;
10ca4b04
L
10243 }
10244
978c4450
AM
10245 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10246 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10247 {
978c4450
AM
10248 bfd_vma si = filedata->gnubuckets[hn];
10249 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10250
10251 do
10252 {
978c4450 10253 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10254 {
c31ab5a0
AM
10255 if (off < filedata->ngnuchains
10256 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10257 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10258 }
10259 else
10260 {
10261 if (si >= num_of_syms)
10262 num_of_syms = si + 1;
10263 }
10264 si++;
10265 }
978c4450
AM
10266 while (off < filedata->ngnuchains
10267 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10268 }
10269
90837ea7 10270 if (num_of_syms == 0)
10ca4b04 10271 {
90837ea7 10272 no_gnu_hash:
9db70fc3
AM
10273 free (filedata->mipsxlat);
10274 filedata->mipsxlat = NULL;
10275 free (filedata->gnuchains);
10276 filedata->gnuchains = NULL;
10277 free (filedata->gnubuckets);
10278 filedata->gnubuckets = NULL;
978c4450
AM
10279 filedata->ngnubuckets = 0;
10280 filedata->ngnuchains = 0;
10ca4b04
L
10281 }
10282 }
10283
10284 return num_of_syms;
10285}
10286
b2d38a17
NC
10287/* Parse and display the contents of the dynamic section. */
10288
32ec8896 10289static bfd_boolean
dda8d76d 10290process_dynamic_section (Filedata * filedata)
9ea033b2 10291{
2cf0635d 10292 Elf_Internal_Dyn * entry;
9ea033b2 10293
978c4450 10294 if (filedata->dynamic_size == 0)
9ea033b2
NC
10295 {
10296 if (do_dynamic)
b2d38a17 10297 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 10298
32ec8896 10299 return TRUE;
9ea033b2
NC
10300 }
10301
10302 if (is_32bit_elf)
10303 {
dda8d76d 10304 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10305 return FALSE;
10306 }
10307 else
10308 {
dda8d76d 10309 if (! get_64bit_dynamic_section (filedata))
32ec8896 10310 return FALSE;
9ea033b2 10311 }
9ea033b2 10312
252b5132 10313 /* Find the appropriate symbol table. */
978c4450 10314 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10315 {
2482f306
AM
10316 unsigned long num_of_syms;
10317
978c4450
AM
10318 for (entry = filedata->dynamic_section;
10319 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10320 ++entry)
10ca4b04 10321 if (entry->d_tag == DT_SYMTAB)
978c4450 10322 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10323 else if (entry->d_tag == DT_SYMENT)
978c4450 10324 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10325 else if (entry->d_tag == DT_HASH)
978c4450 10326 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10327 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10328 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10329 else if ((filedata->file_header.e_machine == EM_MIPS
10330 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10331 && entry->d_tag == DT_MIPS_XHASH)
10332 {
978c4450
AM
10333 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10334 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10335 }
252b5132 10336
2482f306
AM
10337 num_of_syms = get_num_dynamic_syms (filedata);
10338
10339 if (num_of_syms != 0
10340 && filedata->dynamic_symbols == NULL
10341 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10342 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10343 {
10344 Elf_Internal_Phdr *seg;
2482f306 10345 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10346
2482f306
AM
10347 if (! get_program_headers (filedata))
10348 {
10349 error (_("Cannot interpret virtual addresses "
10350 "without program headers.\n"));
10351 return FALSE;
10352 }
252b5132 10353
2482f306
AM
10354 for (seg = filedata->program_headers;
10355 seg < filedata->program_headers + filedata->file_header.e_phnum;
10356 ++seg)
10357 {
10358 if (seg->p_type != PT_LOAD)
10359 continue;
252b5132 10360
2482f306
AM
10361 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10362 {
10363 /* See PR 21379 for a reproducer. */
10364 error (_("Invalid PT_LOAD entry\n"));
10365 return FALSE;
10366 }
252b5132 10367
2482f306
AM
10368 if (vma >= (seg->p_vaddr & -seg->p_align)
10369 && vma < seg->p_vaddr + seg->p_filesz)
10370 {
10371 /* Since we do not know how big the symbol table is,
10372 we default to reading in up to the end of PT_LOAD
10373 segment and processing that. This is overkill, I
10374 know, but it should work. */
10375 Elf_Internal_Shdr section;
10376 section.sh_offset = (vma - seg->p_vaddr
10377 + seg->p_offset);
10378 section.sh_size = (num_of_syms
10379 * filedata->dynamic_info[DT_SYMENT]);
10380 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10381
10382 if (do_checks
10383 && filedata->dynamic_symtab_section != NULL
10384 && ((filedata->dynamic_symtab_section->sh_offset
10385 != section.sh_offset)
10386 || (filedata->dynamic_symtab_section->sh_size
10387 != section.sh_size)
10388 || (filedata->dynamic_symtab_section->sh_entsize
10389 != section.sh_entsize)))
10390 warn (_("\
10391the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10392
2482f306
AM
10393 section.sh_name = filedata->string_table_length;
10394 filedata->dynamic_symbols
10395 = GET_ELF_SYMBOLS (filedata, &section,
10396 &filedata->num_dynamic_syms);
10397 if (filedata->dynamic_symbols == NULL
10398 || filedata->num_dynamic_syms != num_of_syms)
10399 {
10400 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10401 return FALSE;
10402 }
10403 break;
10404 }
10405 }
10406 }
10407 }
252b5132
RH
10408
10409 /* Similarly find a string table. */
978c4450
AM
10410 if (filedata->dynamic_strings == NULL)
10411 for (entry = filedata->dynamic_section;
10412 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10413 ++entry)
10414 {
10415 if (entry->d_tag == DT_STRTAB)
978c4450 10416 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10417
10ca4b04 10418 if (entry->d_tag == DT_STRSZ)
978c4450 10419 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10420
978c4450
AM
10421 if (filedata->dynamic_info[DT_STRTAB]
10422 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10423 {
10424 unsigned long offset;
978c4450 10425 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10426
10427 offset = offset_from_vma (filedata,
978c4450 10428 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10429 str_tab_len);
8ac10c5b
L
10430 if (do_checks
10431 && filedata->dynamic_strtab_section
10432 && ((filedata->dynamic_strtab_section->sh_offset
10433 != (file_ptr) offset)
10434 || (filedata->dynamic_strtab_section->sh_size
10435 != str_tab_len)))
10436 warn (_("\
10437the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10438
978c4450
AM
10439 filedata->dynamic_strings
10440 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10441 _("dynamic string table"));
10442 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10443 {
10444 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10445 break;
10446 }
e3d39609 10447
978c4450 10448 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10449 break;
10450 }
10451 }
252b5132
RH
10452
10453 /* And find the syminfo section if available. */
978c4450 10454 if (filedata->dynamic_syminfo == NULL)
252b5132 10455 {
3e8bba36 10456 unsigned long syminsz = 0;
252b5132 10457
978c4450
AM
10458 for (entry = filedata->dynamic_section;
10459 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10460 ++entry)
252b5132
RH
10461 {
10462 if (entry->d_tag == DT_SYMINENT)
10463 {
10464 /* Note: these braces are necessary to avoid a syntax
10465 error from the SunOS4 C compiler. */
049b0c3a
NC
10466 /* PR binutils/17531: A corrupt file can trigger this test.
10467 So do not use an assert, instead generate an error message. */
10468 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10469 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10470 (int) entry->d_un.d_val);
252b5132
RH
10471 }
10472 else if (entry->d_tag == DT_SYMINSZ)
10473 syminsz = entry->d_un.d_val;
10474 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10475 filedata->dynamic_syminfo_offset
10476 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10477 }
10478
978c4450 10479 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10480 {
2cf0635d
NC
10481 Elf_External_Syminfo * extsyminfo;
10482 Elf_External_Syminfo * extsym;
10483 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10484
10485 /* There is a syminfo section. Read the data. */
3f5e193b 10486 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10487 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10488 1, syminsz, _("symbol information"));
a6e9f9df 10489 if (!extsyminfo)
32ec8896 10490 return FALSE;
252b5132 10491
978c4450 10492 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10493 {
10494 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10495 free (filedata->dynamic_syminfo);
e3d39609 10496 }
978c4450
AM
10497 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10498 if (filedata->dynamic_syminfo == NULL)
252b5132 10499 {
2482f306
AM
10500 error (_("Out of memory allocating %lu bytes "
10501 "for dynamic symbol info\n"),
8b73c356 10502 (unsigned long) syminsz);
32ec8896 10503 return FALSE;
252b5132
RH
10504 }
10505
2482f306
AM
10506 filedata->dynamic_syminfo_nent
10507 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10508 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10509 syminfo < (filedata->dynamic_syminfo
10510 + filedata->dynamic_syminfo_nent);
86dba8ee 10511 ++syminfo, ++extsym)
252b5132 10512 {
86dba8ee
AM
10513 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10514 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10515 }
10516
10517 free (extsyminfo);
10518 }
10519 }
10520
978c4450 10521 if (do_dynamic && filedata->dynamic_addr)
d3a49aa8
AM
10522 printf (ngettext ("\nDynamic section at offset 0x%lx "
10523 "contains %lu entry:\n",
10524 "\nDynamic section at offset 0x%lx "
10525 "contains %lu entries:\n",
978c4450
AM
10526 filedata->dynamic_nent),
10527 filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent);
252b5132
RH
10528 if (do_dynamic)
10529 printf (_(" Tag Type Name/Value\n"));
10530
978c4450
AM
10531 for (entry = filedata->dynamic_section;
10532 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10533 entry++)
252b5132
RH
10534 {
10535 if (do_dynamic)
f7a99963 10536 {
2cf0635d 10537 const char * dtype;
e699b9ff 10538
f7a99963
NC
10539 putchar (' ');
10540 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10541 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10542 printf (" (%s)%*s", dtype,
32ec8896 10543 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10544 }
252b5132
RH
10545
10546 switch (entry->d_tag)
10547 {
d1133906
NC
10548 case DT_FLAGS:
10549 if (do_dynamic)
e9e44622 10550 print_dynamic_flags (entry->d_un.d_val);
d1133906 10551 break;
76da6bbe 10552
252b5132
RH
10553 case DT_AUXILIARY:
10554 case DT_FILTER:
019148e4
L
10555 case DT_CONFIG:
10556 case DT_DEPAUDIT:
10557 case DT_AUDIT:
252b5132
RH
10558 if (do_dynamic)
10559 {
019148e4 10560 switch (entry->d_tag)
b34976b6 10561 {
019148e4
L
10562 case DT_AUXILIARY:
10563 printf (_("Auxiliary library"));
10564 break;
10565
10566 case DT_FILTER:
10567 printf (_("Filter library"));
10568 break;
10569
b34976b6 10570 case DT_CONFIG:
019148e4
L
10571 printf (_("Configuration file"));
10572 break;
10573
10574 case DT_DEPAUDIT:
10575 printf (_("Dependency audit library"));
10576 break;
10577
10578 case DT_AUDIT:
10579 printf (_("Audit library"));
10580 break;
10581 }
252b5132 10582
978c4450
AM
10583 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10584 printf (": [%s]\n",
10585 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10586 else
f7a99963
NC
10587 {
10588 printf (": ");
10589 print_vma (entry->d_un.d_val, PREFIX_HEX);
10590 putchar ('\n');
10591 }
252b5132
RH
10592 }
10593 break;
10594
dcefbbbd 10595 case DT_FEATURE:
252b5132
RH
10596 if (do_dynamic)
10597 {
10598 printf (_("Flags:"));
86f55779 10599
252b5132
RH
10600 if (entry->d_un.d_val == 0)
10601 printf (_(" None\n"));
10602 else
10603 {
10604 unsigned long int val = entry->d_un.d_val;
86f55779 10605
252b5132
RH
10606 if (val & DTF_1_PARINIT)
10607 {
10608 printf (" PARINIT");
10609 val ^= DTF_1_PARINIT;
10610 }
dcefbbbd
L
10611 if (val & DTF_1_CONFEXP)
10612 {
10613 printf (" CONFEXP");
10614 val ^= DTF_1_CONFEXP;
10615 }
252b5132
RH
10616 if (val != 0)
10617 printf (" %lx", val);
10618 puts ("");
10619 }
10620 }
10621 break;
10622
10623 case DT_POSFLAG_1:
10624 if (do_dynamic)
10625 {
10626 printf (_("Flags:"));
86f55779 10627
252b5132
RH
10628 if (entry->d_un.d_val == 0)
10629 printf (_(" None\n"));
10630 else
10631 {
10632 unsigned long int val = entry->d_un.d_val;
86f55779 10633
252b5132
RH
10634 if (val & DF_P1_LAZYLOAD)
10635 {
10636 printf (" LAZYLOAD");
10637 val ^= DF_P1_LAZYLOAD;
10638 }
10639 if (val & DF_P1_GROUPPERM)
10640 {
10641 printf (" GROUPPERM");
10642 val ^= DF_P1_GROUPPERM;
10643 }
10644 if (val != 0)
10645 printf (" %lx", val);
10646 puts ("");
10647 }
10648 }
10649 break;
10650
10651 case DT_FLAGS_1:
10652 if (do_dynamic)
10653 {
10654 printf (_("Flags:"));
10655 if (entry->d_un.d_val == 0)
10656 printf (_(" None\n"));
10657 else
10658 {
10659 unsigned long int val = entry->d_un.d_val;
86f55779 10660
252b5132
RH
10661 if (val & DF_1_NOW)
10662 {
10663 printf (" NOW");
10664 val ^= DF_1_NOW;
10665 }
10666 if (val & DF_1_GLOBAL)
10667 {
10668 printf (" GLOBAL");
10669 val ^= DF_1_GLOBAL;
10670 }
10671 if (val & DF_1_GROUP)
10672 {
10673 printf (" GROUP");
10674 val ^= DF_1_GROUP;
10675 }
10676 if (val & DF_1_NODELETE)
10677 {
10678 printf (" NODELETE");
10679 val ^= DF_1_NODELETE;
10680 }
10681 if (val & DF_1_LOADFLTR)
10682 {
10683 printf (" LOADFLTR");
10684 val ^= DF_1_LOADFLTR;
10685 }
10686 if (val & DF_1_INITFIRST)
10687 {
10688 printf (" INITFIRST");
10689 val ^= DF_1_INITFIRST;
10690 }
10691 if (val & DF_1_NOOPEN)
10692 {
10693 printf (" NOOPEN");
10694 val ^= DF_1_NOOPEN;
10695 }
10696 if (val & DF_1_ORIGIN)
10697 {
10698 printf (" ORIGIN");
10699 val ^= DF_1_ORIGIN;
10700 }
10701 if (val & DF_1_DIRECT)
10702 {
10703 printf (" DIRECT");
10704 val ^= DF_1_DIRECT;
10705 }
10706 if (val & DF_1_TRANS)
10707 {
10708 printf (" TRANS");
10709 val ^= DF_1_TRANS;
10710 }
10711 if (val & DF_1_INTERPOSE)
10712 {
10713 printf (" INTERPOSE");
10714 val ^= DF_1_INTERPOSE;
10715 }
f7db6139 10716 if (val & DF_1_NODEFLIB)
dcefbbbd 10717 {
f7db6139
L
10718 printf (" NODEFLIB");
10719 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10720 }
10721 if (val & DF_1_NODUMP)
10722 {
10723 printf (" NODUMP");
10724 val ^= DF_1_NODUMP;
10725 }
34b60028 10726 if (val & DF_1_CONFALT)
dcefbbbd 10727 {
34b60028
L
10728 printf (" CONFALT");
10729 val ^= DF_1_CONFALT;
10730 }
10731 if (val & DF_1_ENDFILTEE)
10732 {
10733 printf (" ENDFILTEE");
10734 val ^= DF_1_ENDFILTEE;
10735 }
10736 if (val & DF_1_DISPRELDNE)
10737 {
10738 printf (" DISPRELDNE");
10739 val ^= DF_1_DISPRELDNE;
10740 }
10741 if (val & DF_1_DISPRELPND)
10742 {
10743 printf (" DISPRELPND");
10744 val ^= DF_1_DISPRELPND;
10745 }
10746 if (val & DF_1_NODIRECT)
10747 {
10748 printf (" NODIRECT");
10749 val ^= DF_1_NODIRECT;
10750 }
10751 if (val & DF_1_IGNMULDEF)
10752 {
10753 printf (" IGNMULDEF");
10754 val ^= DF_1_IGNMULDEF;
10755 }
10756 if (val & DF_1_NOKSYMS)
10757 {
10758 printf (" NOKSYMS");
10759 val ^= DF_1_NOKSYMS;
10760 }
10761 if (val & DF_1_NOHDR)
10762 {
10763 printf (" NOHDR");
10764 val ^= DF_1_NOHDR;
10765 }
10766 if (val & DF_1_EDITED)
10767 {
10768 printf (" EDITED");
10769 val ^= DF_1_EDITED;
10770 }
10771 if (val & DF_1_NORELOC)
10772 {
10773 printf (" NORELOC");
10774 val ^= DF_1_NORELOC;
10775 }
10776 if (val & DF_1_SYMINTPOSE)
10777 {
10778 printf (" SYMINTPOSE");
10779 val ^= DF_1_SYMINTPOSE;
10780 }
10781 if (val & DF_1_GLOBAUDIT)
10782 {
10783 printf (" GLOBAUDIT");
10784 val ^= DF_1_GLOBAUDIT;
10785 }
10786 if (val & DF_1_SINGLETON)
10787 {
10788 printf (" SINGLETON");
10789 val ^= DF_1_SINGLETON;
dcefbbbd 10790 }
5c383f02
RO
10791 if (val & DF_1_STUB)
10792 {
10793 printf (" STUB");
10794 val ^= DF_1_STUB;
10795 }
10796 if (val & DF_1_PIE)
10797 {
10798 printf (" PIE");
10799 val ^= DF_1_PIE;
10800 }
b1202ffa
L
10801 if (val & DF_1_KMOD)
10802 {
10803 printf (" KMOD");
10804 val ^= DF_1_KMOD;
10805 }
10806 if (val & DF_1_WEAKFILTER)
10807 {
10808 printf (" WEAKFILTER");
10809 val ^= DF_1_WEAKFILTER;
10810 }
10811 if (val & DF_1_NOCOMMON)
10812 {
10813 printf (" NOCOMMON");
10814 val ^= DF_1_NOCOMMON;
10815 }
252b5132
RH
10816 if (val != 0)
10817 printf (" %lx", val);
10818 puts ("");
10819 }
10820 }
10821 break;
10822
10823 case DT_PLTREL:
978c4450 10824 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10825 if (do_dynamic)
dda8d76d 10826 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10827 break;
10828
10829 case DT_NULL :
10830 case DT_NEEDED :
10831 case DT_PLTGOT :
10832 case DT_HASH :
10833 case DT_STRTAB :
10834 case DT_SYMTAB :
10835 case DT_RELA :
10836 case DT_INIT :
10837 case DT_FINI :
10838 case DT_SONAME :
10839 case DT_RPATH :
10840 case DT_SYMBOLIC:
10841 case DT_REL :
10842 case DT_DEBUG :
10843 case DT_TEXTREL :
10844 case DT_JMPREL :
019148e4 10845 case DT_RUNPATH :
978c4450 10846 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
10847
10848 if (do_dynamic)
10849 {
2cf0635d 10850 char * name;
252b5132 10851
978c4450
AM
10852 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10853 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10854 else
d79b3d50 10855 name = NULL;
252b5132
RH
10856
10857 if (name)
10858 {
10859 switch (entry->d_tag)
10860 {
10861 case DT_NEEDED:
10862 printf (_("Shared library: [%s]"), name);
10863
978c4450 10864 if (streq (name, filedata->program_interpreter))
f7a99963 10865 printf (_(" program interpreter"));
252b5132
RH
10866 break;
10867
10868 case DT_SONAME:
f7a99963 10869 printf (_("Library soname: [%s]"), name);
252b5132
RH
10870 break;
10871
10872 case DT_RPATH:
f7a99963 10873 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10874 break;
10875
019148e4
L
10876 case DT_RUNPATH:
10877 printf (_("Library runpath: [%s]"), name);
10878 break;
10879
252b5132 10880 default:
f7a99963
NC
10881 print_vma (entry->d_un.d_val, PREFIX_HEX);
10882 break;
252b5132
RH
10883 }
10884 }
10885 else
f7a99963
NC
10886 print_vma (entry->d_un.d_val, PREFIX_HEX);
10887
10888 putchar ('\n');
252b5132
RH
10889 }
10890 break;
10891
10892 case DT_PLTRELSZ:
10893 case DT_RELASZ :
10894 case DT_STRSZ :
10895 case DT_RELSZ :
10896 case DT_RELAENT :
10897 case DT_SYMENT :
10898 case DT_RELENT :
978c4450 10899 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10900 /* Fall through. */
252b5132
RH
10901 case DT_PLTPADSZ:
10902 case DT_MOVEENT :
10903 case DT_MOVESZ :
10904 case DT_INIT_ARRAYSZ:
10905 case DT_FINI_ARRAYSZ:
047b2264
JJ
10906 case DT_GNU_CONFLICTSZ:
10907 case DT_GNU_LIBLISTSZ:
252b5132 10908 if (do_dynamic)
f7a99963
NC
10909 {
10910 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10911 printf (_(" (bytes)\n"));
f7a99963 10912 }
252b5132
RH
10913 break;
10914
10915 case DT_VERDEFNUM:
10916 case DT_VERNEEDNUM:
10917 case DT_RELACOUNT:
10918 case DT_RELCOUNT:
10919 if (do_dynamic)
f7a99963
NC
10920 {
10921 print_vma (entry->d_un.d_val, UNSIGNED);
10922 putchar ('\n');
10923 }
252b5132
RH
10924 break;
10925
10926 case DT_SYMINSZ:
10927 case DT_SYMINENT:
10928 case DT_SYMINFO:
10929 case DT_USED:
10930 case DT_INIT_ARRAY:
10931 case DT_FINI_ARRAY:
10932 if (do_dynamic)
10933 {
d79b3d50 10934 if (entry->d_tag == DT_USED
978c4450 10935 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 10936 {
978c4450 10937 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10938
b34976b6 10939 if (*name)
252b5132
RH
10940 {
10941 printf (_("Not needed object: [%s]\n"), name);
10942 break;
10943 }
10944 }
103f02d3 10945
f7a99963
NC
10946 print_vma (entry->d_un.d_val, PREFIX_HEX);
10947 putchar ('\n');
252b5132
RH
10948 }
10949 break;
10950
10951 case DT_BIND_NOW:
10952 /* The value of this entry is ignored. */
35b1837e
AM
10953 if (do_dynamic)
10954 putchar ('\n');
252b5132 10955 break;
103f02d3 10956
047b2264
JJ
10957 case DT_GNU_PRELINKED:
10958 if (do_dynamic)
10959 {
2cf0635d 10960 struct tm * tmp;
91d6fa6a 10961 time_t atime = entry->d_un.d_val;
047b2264 10962
91d6fa6a 10963 tmp = gmtime (&atime);
071436c6
NC
10964 /* PR 17533 file: 041-1244816-0.004. */
10965 if (tmp == NULL)
5a2cbcf4
L
10966 printf (_("<corrupt time val: %lx"),
10967 (unsigned long) atime);
071436c6
NC
10968 else
10969 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10970 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10971 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10972
10973 }
10974 break;
10975
fdc90cb4 10976 case DT_GNU_HASH:
978c4450 10977 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
10978 if (do_dynamic)
10979 {
10980 print_vma (entry->d_un.d_val, PREFIX_HEX);
10981 putchar ('\n');
10982 }
10983 break;
10984
252b5132
RH
10985 default:
10986 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
10987 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
10988 = entry->d_un.d_val;
252b5132
RH
10989
10990 if (do_dynamic)
10991 {
dda8d76d 10992 switch (filedata->file_header.e_machine)
252b5132 10993 {
37c18eed
SD
10994 case EM_AARCH64:
10995 dynamic_section_aarch64_val (entry);
10996 break;
252b5132 10997 case EM_MIPS:
4fe85591 10998 case EM_MIPS_RS3_LE:
978c4450 10999 dynamic_section_mips_val (filedata, entry);
252b5132 11000 break;
103f02d3 11001 case EM_PARISC:
b2d38a17 11002 dynamic_section_parisc_val (entry);
103f02d3 11003 break;
ecc51f48 11004 case EM_IA_64:
b2d38a17 11005 dynamic_section_ia64_val (entry);
ecc51f48 11006 break;
252b5132 11007 default:
f7a99963
NC
11008 print_vma (entry->d_un.d_val, PREFIX_HEX);
11009 putchar ('\n');
252b5132
RH
11010 }
11011 }
11012 break;
11013 }
11014 }
11015
32ec8896 11016 return TRUE;
252b5132
RH
11017}
11018
11019static char *
d3ba0551 11020get_ver_flags (unsigned int flags)
252b5132 11021{
6d4f21f6 11022 static char buff[128];
252b5132
RH
11023
11024 buff[0] = 0;
11025
11026 if (flags == 0)
11027 return _("none");
11028
11029 if (flags & VER_FLG_BASE)
7bb1ad17 11030 strcat (buff, "BASE");
252b5132
RH
11031
11032 if (flags & VER_FLG_WEAK)
11033 {
11034 if (flags & VER_FLG_BASE)
7bb1ad17 11035 strcat (buff, " | ");
252b5132 11036
7bb1ad17 11037 strcat (buff, "WEAK");
252b5132
RH
11038 }
11039
44ec90b9
RO
11040 if (flags & VER_FLG_INFO)
11041 {
11042 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11043 strcat (buff, " | ");
44ec90b9 11044
7bb1ad17 11045 strcat (buff, "INFO");
44ec90b9
RO
11046 }
11047
11048 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11049 {
11050 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11051 strcat (buff, " | ");
11052
11053 strcat (buff, _("<unknown>"));
11054 }
252b5132
RH
11055
11056 return buff;
11057}
11058
11059/* Display the contents of the version sections. */
98fb390a 11060
32ec8896 11061static bfd_boolean
dda8d76d 11062process_version_sections (Filedata * filedata)
252b5132 11063{
2cf0635d 11064 Elf_Internal_Shdr * section;
b34976b6 11065 unsigned i;
32ec8896 11066 bfd_boolean found = FALSE;
252b5132
RH
11067
11068 if (! do_version)
32ec8896 11069 return TRUE;
252b5132 11070
dda8d76d
NC
11071 for (i = 0, section = filedata->section_headers;
11072 i < filedata->file_header.e_shnum;
b34976b6 11073 i++, section++)
252b5132
RH
11074 {
11075 switch (section->sh_type)
11076 {
11077 case SHT_GNU_verdef:
11078 {
2cf0635d 11079 Elf_External_Verdef * edefs;
452bf675
AM
11080 unsigned long idx;
11081 unsigned long cnt;
2cf0635d 11082 char * endbuf;
252b5132 11083
32ec8896 11084 found = TRUE;
252b5132 11085
d3a49aa8
AM
11086 printf (ngettext ("\nVersion definition section '%s' "
11087 "contains %u entry:\n",
11088 "\nVersion definition section '%s' "
11089 "contains %u entries:\n",
11090 section->sh_info),
dda8d76d 11091 printable_section_name (filedata, section),
74e1a04b 11092 section->sh_info);
252b5132 11093
ae9ac79e 11094 printf (_(" Addr: 0x"));
252b5132 11095 printf_vma (section->sh_addr);
233f82cf 11096 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11097 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11098 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11099
3f5e193b 11100 edefs = (Elf_External_Verdef *)
dda8d76d 11101 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11102 _("version definition section"));
a6e9f9df
AM
11103 if (!edefs)
11104 break;
59245841 11105 endbuf = (char *) edefs + section->sh_size;
252b5132 11106
1445030f 11107 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11108 {
2cf0635d
NC
11109 char * vstart;
11110 Elf_External_Verdef * edef;
b34976b6 11111 Elf_Internal_Verdef ent;
2cf0635d 11112 Elf_External_Verdaux * eaux;
b34976b6 11113 Elf_Internal_Verdaux aux;
452bf675 11114 unsigned long isum;
b34976b6 11115 int j;
103f02d3 11116
252b5132 11117 vstart = ((char *) edefs) + idx;
54806181
AM
11118 if (vstart + sizeof (*edef) > endbuf)
11119 break;
252b5132
RH
11120
11121 edef = (Elf_External_Verdef *) vstart;
11122
11123 ent.vd_version = BYTE_GET (edef->vd_version);
11124 ent.vd_flags = BYTE_GET (edef->vd_flags);
11125 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11126 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11127 ent.vd_hash = BYTE_GET (edef->vd_hash);
11128 ent.vd_aux = BYTE_GET (edef->vd_aux);
11129 ent.vd_next = BYTE_GET (edef->vd_next);
11130
452bf675 11131 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11132 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11133
11134 printf (_(" Index: %d Cnt: %d "),
11135 ent.vd_ndx, ent.vd_cnt);
11136
452bf675 11137 /* Check for overflow. */
1445030f 11138 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11139 break;
11140
252b5132
RH
11141 vstart += ent.vd_aux;
11142
1445030f
AM
11143 if (vstart + sizeof (*eaux) > endbuf)
11144 break;
252b5132
RH
11145 eaux = (Elf_External_Verdaux *) vstart;
11146
11147 aux.vda_name = BYTE_GET (eaux->vda_name);
11148 aux.vda_next = BYTE_GET (eaux->vda_next);
11149
978c4450
AM
11150 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11151 printf (_("Name: %s\n"),
11152 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11153 else
11154 printf (_("Name index: %ld\n"), aux.vda_name);
11155
11156 isum = idx + ent.vd_aux;
11157
b34976b6 11158 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11159 {
1445030f
AM
11160 if (aux.vda_next < sizeof (*eaux)
11161 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11162 {
11163 warn (_("Invalid vda_next field of %lx\n"),
11164 aux.vda_next);
11165 j = ent.vd_cnt;
11166 break;
11167 }
dd24e3da 11168 /* Check for overflow. */
7e26601c 11169 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11170 break;
11171
252b5132
RH
11172 isum += aux.vda_next;
11173 vstart += aux.vda_next;
11174
54806181
AM
11175 if (vstart + sizeof (*eaux) > endbuf)
11176 break;
1445030f 11177 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11178
11179 aux.vda_name = BYTE_GET (eaux->vda_name);
11180 aux.vda_next = BYTE_GET (eaux->vda_next);
11181
978c4450 11182 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11183 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11184 isum, j,
11185 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11186 else
452bf675 11187 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11188 isum, j, aux.vda_name);
11189 }
dd24e3da 11190
54806181
AM
11191 if (j < ent.vd_cnt)
11192 printf (_(" Version def aux past end of section\n"));
252b5132 11193
c9f02c3e
MR
11194 /* PR 17531:
11195 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11196 if (ent.vd_next < sizeof (*edef)
11197 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11198 {
11199 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11200 cnt = section->sh_info;
11201 break;
11202 }
452bf675 11203 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11204 break;
11205
252b5132
RH
11206 idx += ent.vd_next;
11207 }
dd24e3da 11208
54806181
AM
11209 if (cnt < section->sh_info)
11210 printf (_(" Version definition past end of section\n"));
252b5132
RH
11211
11212 free (edefs);
11213 }
11214 break;
103f02d3 11215
252b5132
RH
11216 case SHT_GNU_verneed:
11217 {
2cf0635d 11218 Elf_External_Verneed * eneed;
452bf675
AM
11219 unsigned long idx;
11220 unsigned long cnt;
2cf0635d 11221 char * endbuf;
252b5132 11222
32ec8896 11223 found = TRUE;
252b5132 11224
d3a49aa8
AM
11225 printf (ngettext ("\nVersion needs section '%s' "
11226 "contains %u entry:\n",
11227 "\nVersion needs section '%s' "
11228 "contains %u entries:\n",
11229 section->sh_info),
dda8d76d 11230 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11231
11232 printf (_(" Addr: 0x"));
11233 printf_vma (section->sh_addr);
72de5009 11234 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11235 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11236 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11237
dda8d76d 11238 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11239 section->sh_offset, 1,
11240 section->sh_size,
9cf03b7e 11241 _("Version Needs section"));
a6e9f9df
AM
11242 if (!eneed)
11243 break;
59245841 11244 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11245
11246 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11247 {
2cf0635d 11248 Elf_External_Verneed * entry;
b34976b6 11249 Elf_Internal_Verneed ent;
452bf675 11250 unsigned long isum;
b34976b6 11251 int j;
2cf0635d 11252 char * vstart;
252b5132
RH
11253
11254 vstart = ((char *) eneed) + idx;
54806181
AM
11255 if (vstart + sizeof (*entry) > endbuf)
11256 break;
252b5132
RH
11257
11258 entry = (Elf_External_Verneed *) vstart;
11259
11260 ent.vn_version = BYTE_GET (entry->vn_version);
11261 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11262 ent.vn_file = BYTE_GET (entry->vn_file);
11263 ent.vn_aux = BYTE_GET (entry->vn_aux);
11264 ent.vn_next = BYTE_GET (entry->vn_next);
11265
452bf675 11266 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11267
978c4450
AM
11268 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11269 printf (_(" File: %s"),
11270 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11271 else
11272 printf (_(" File: %lx"), ent.vn_file);
11273
11274 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11275
dd24e3da 11276 /* Check for overflow. */
7e26601c 11277 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11278 break;
252b5132
RH
11279 vstart += ent.vn_aux;
11280
11281 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11282 {
2cf0635d 11283 Elf_External_Vernaux * eaux;
b34976b6 11284 Elf_Internal_Vernaux aux;
252b5132 11285
54806181
AM
11286 if (vstart + sizeof (*eaux) > endbuf)
11287 break;
252b5132
RH
11288 eaux = (Elf_External_Vernaux *) vstart;
11289
11290 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11291 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11292 aux.vna_other = BYTE_GET (eaux->vna_other);
11293 aux.vna_name = BYTE_GET (eaux->vna_name);
11294 aux.vna_next = BYTE_GET (eaux->vna_next);
11295
978c4450 11296 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11297 printf (_(" %#06lx: Name: %s"),
978c4450 11298 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11299 else
452bf675 11300 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11301 isum, aux.vna_name);
11302
11303 printf (_(" Flags: %s Version: %d\n"),
11304 get_ver_flags (aux.vna_flags), aux.vna_other);
11305
1445030f
AM
11306 if (aux.vna_next < sizeof (*eaux)
11307 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11308 {
11309 warn (_("Invalid vna_next field of %lx\n"),
11310 aux.vna_next);
11311 j = ent.vn_cnt;
11312 break;
11313 }
1445030f
AM
11314 /* Check for overflow. */
11315 if (aux.vna_next > (size_t) (endbuf - vstart))
11316 break;
252b5132
RH
11317 isum += aux.vna_next;
11318 vstart += aux.vna_next;
11319 }
9cf03b7e 11320
54806181 11321 if (j < ent.vn_cnt)
9cf03b7e 11322 warn (_("Missing Version Needs auxillary information\n"));
252b5132 11323
1445030f
AM
11324 if (ent.vn_next < sizeof (*entry)
11325 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11326 {
452bf675 11327 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11328 cnt = section->sh_info;
11329 break;
11330 }
1445030f
AM
11331 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11332 break;
252b5132
RH
11333 idx += ent.vn_next;
11334 }
9cf03b7e 11335
54806181 11336 if (cnt < section->sh_info)
9cf03b7e 11337 warn (_("Missing Version Needs information\n"));
103f02d3 11338
252b5132
RH
11339 free (eneed);
11340 }
11341 break;
11342
11343 case SHT_GNU_versym:
11344 {
2cf0635d 11345 Elf_Internal_Shdr * link_section;
8b73c356
NC
11346 size_t total;
11347 unsigned int cnt;
2cf0635d
NC
11348 unsigned char * edata;
11349 unsigned short * data;
11350 char * strtab;
11351 Elf_Internal_Sym * symbols;
11352 Elf_Internal_Shdr * string_sec;
ba5cdace 11353 unsigned long num_syms;
d3ba0551 11354 long off;
252b5132 11355
dda8d76d 11356 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11357 break;
11358
dda8d76d 11359 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11360 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11361
dda8d76d 11362 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11363 break;
11364
32ec8896 11365 found = TRUE;
252b5132 11366
dda8d76d 11367 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11368 if (symbols == NULL)
11369 break;
252b5132 11370
dda8d76d 11371 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11372
dda8d76d 11373 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11374 string_sec->sh_size,
11375 _("version string table"));
a6e9f9df 11376 if (!strtab)
0429c154
MS
11377 {
11378 free (symbols);
11379 break;
11380 }
252b5132 11381
d3a49aa8
AM
11382 printf (ngettext ("\nVersion symbols section '%s' "
11383 "contains %lu entry:\n",
11384 "\nVersion symbols section '%s' "
11385 "contains %lu entries:\n",
11386 total),
dda8d76d 11387 printable_section_name (filedata, section), (unsigned long) total);
252b5132 11388
ae9ac79e 11389 printf (_(" Addr: 0x"));
252b5132 11390 printf_vma (section->sh_addr);
72de5009 11391 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11392 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11393 printable_section_name (filedata, link_section));
252b5132 11394
dda8d76d 11395 off = offset_from_vma (filedata,
978c4450 11396 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11397 total * sizeof (short));
95099889
AM
11398 edata = (unsigned char *) get_data (NULL, filedata, off,
11399 sizeof (short), total,
11400 _("version symbol data"));
a6e9f9df
AM
11401 if (!edata)
11402 {
11403 free (strtab);
0429c154 11404 free (symbols);
a6e9f9df
AM
11405 break;
11406 }
252b5132 11407
3f5e193b 11408 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11409
11410 for (cnt = total; cnt --;)
b34976b6
AM
11411 data[cnt] = byte_get (edata + cnt * sizeof (short),
11412 sizeof (short));
252b5132
RH
11413
11414 free (edata);
11415
11416 for (cnt = 0; cnt < total; cnt += 4)
11417 {
11418 int j, nn;
ab273396
AM
11419 char *name;
11420 char *invalid = _("*invalid*");
252b5132
RH
11421
11422 printf (" %03x:", cnt);
11423
11424 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11425 switch (data[cnt + j])
252b5132
RH
11426 {
11427 case 0:
11428 fputs (_(" 0 (*local*) "), stdout);
11429 break;
11430
11431 case 1:
11432 fputs (_(" 1 (*global*) "), stdout);
11433 break;
11434
11435 default:
c244d050
NC
11436 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11437 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11438
dd24e3da 11439 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11440 array, break to avoid an out-of-bounds read. */
11441 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11442 {
11443 warn (_("invalid index into symbol array\n"));
11444 break;
11445 }
11446
ab273396 11447 name = NULL;
978c4450 11448 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11449 {
b34976b6
AM
11450 Elf_Internal_Verneed ivn;
11451 unsigned long offset;
252b5132 11452
d93f0186 11453 offset = offset_from_vma
978c4450
AM
11454 (filedata,
11455 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11456 sizeof (Elf_External_Verneed));
252b5132 11457
b34976b6 11458 do
252b5132 11459 {
b34976b6
AM
11460 Elf_Internal_Vernaux ivna;
11461 Elf_External_Verneed evn;
11462 Elf_External_Vernaux evna;
11463 unsigned long a_off;
252b5132 11464
dda8d76d 11465 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11466 _("version need")) == NULL)
11467 break;
0b4362b0 11468
252b5132
RH
11469 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11470 ivn.vn_next = BYTE_GET (evn.vn_next);
11471
11472 a_off = offset + ivn.vn_aux;
11473
11474 do
11475 {
dda8d76d 11476 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11477 1, _("version need aux (2)")) == NULL)
11478 {
11479 ivna.vna_next = 0;
11480 ivna.vna_other = 0;
11481 }
11482 else
11483 {
11484 ivna.vna_next = BYTE_GET (evna.vna_next);
11485 ivna.vna_other = BYTE_GET (evna.vna_other);
11486 }
252b5132
RH
11487
11488 a_off += ivna.vna_next;
11489 }
b34976b6 11490 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11491 && ivna.vna_next != 0);
11492
b34976b6 11493 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11494 {
11495 ivna.vna_name = BYTE_GET (evna.vna_name);
11496
54806181 11497 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11498 name = invalid;
54806181
AM
11499 else
11500 name = strtab + ivna.vna_name;
252b5132
RH
11501 break;
11502 }
11503
11504 offset += ivn.vn_next;
11505 }
11506 while (ivn.vn_next);
11507 }
00d93f34 11508
ab273396 11509 if (data[cnt + j] != 0x8001
978c4450 11510 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11511 {
b34976b6
AM
11512 Elf_Internal_Verdef ivd;
11513 Elf_External_Verdef evd;
11514 unsigned long offset;
252b5132 11515
d93f0186 11516 offset = offset_from_vma
978c4450
AM
11517 (filedata,
11518 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11519 sizeof evd);
252b5132
RH
11520
11521 do
11522 {
dda8d76d 11523 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11524 _("version def")) == NULL)
11525 {
11526 ivd.vd_next = 0;
948f632f 11527 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11528 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11529 break;
59245841
NC
11530 }
11531 else
11532 {
11533 ivd.vd_next = BYTE_GET (evd.vd_next);
11534 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11535 }
252b5132
RH
11536
11537 offset += ivd.vd_next;
11538 }
c244d050 11539 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11540 && ivd.vd_next != 0);
11541
c244d050 11542 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11543 {
b34976b6
AM
11544 Elf_External_Verdaux evda;
11545 Elf_Internal_Verdaux ivda;
252b5132
RH
11546
11547 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11548
dda8d76d 11549 if (get_data (&evda, filedata,
59245841
NC
11550 offset - ivd.vd_next + ivd.vd_aux,
11551 sizeof (evda), 1,
11552 _("version def aux")) == NULL)
11553 break;
252b5132
RH
11554
11555 ivda.vda_name = BYTE_GET (evda.vda_name);
11556
54806181 11557 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11558 name = invalid;
11559 else if (name != NULL && name != invalid)
11560 name = _("*both*");
54806181
AM
11561 else
11562 name = strtab + ivda.vda_name;
252b5132
RH
11563 }
11564 }
ab273396
AM
11565 if (name != NULL)
11566 nn += printf ("(%s%-*s",
11567 name,
11568 12 - (int) strlen (name),
11569 ")");
252b5132
RH
11570
11571 if (nn < 18)
11572 printf ("%*c", 18 - nn, ' ');
11573 }
11574
11575 putchar ('\n');
11576 }
11577
11578 free (data);
11579 free (strtab);
11580 free (symbols);
11581 }
11582 break;
103f02d3 11583
252b5132
RH
11584 default:
11585 break;
11586 }
11587 }
11588
11589 if (! found)
11590 printf (_("\nNo version information found in this file.\n"));
11591
32ec8896 11592 return TRUE;
252b5132
RH
11593}
11594
d1133906 11595static const char *
dda8d76d 11596get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11597{
89246a0e 11598 static char buff[64];
252b5132
RH
11599
11600 switch (binding)
11601 {
b34976b6
AM
11602 case STB_LOCAL: return "LOCAL";
11603 case STB_GLOBAL: return "GLOBAL";
11604 case STB_WEAK: return "WEAK";
252b5132
RH
11605 default:
11606 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11607 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11608 binding);
252b5132 11609 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11610 {
11611 if (binding == STB_GNU_UNIQUE
df3a023b 11612 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11613 return "UNIQUE";
11614 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11615 }
252b5132 11616 else
e9e44622 11617 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11618 return buff;
11619 }
11620}
11621
d1133906 11622static const char *
dda8d76d 11623get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11624{
89246a0e 11625 static char buff[64];
252b5132
RH
11626
11627 switch (type)
11628 {
b34976b6
AM
11629 case STT_NOTYPE: return "NOTYPE";
11630 case STT_OBJECT: return "OBJECT";
11631 case STT_FUNC: return "FUNC";
11632 case STT_SECTION: return "SECTION";
11633 case STT_FILE: return "FILE";
11634 case STT_COMMON: return "COMMON";
11635 case STT_TLS: return "TLS";
15ab5209
DB
11636 case STT_RELC: return "RELC";
11637 case STT_SRELC: return "SRELC";
252b5132
RH
11638 default:
11639 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11640 {
dda8d76d 11641 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11642 return "THUMB_FUNC";
103f02d3 11643
dda8d76d 11644 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11645 return "REGISTER";
11646
dda8d76d 11647 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11648 return "PARISC_MILLI";
11649
e9e44622 11650 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11651 }
252b5132 11652 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11653 {
dda8d76d 11654 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11655 {
11656 if (type == STT_HP_OPAQUE)
11657 return "HP_OPAQUE";
11658 if (type == STT_HP_STUB)
11659 return "HP_STUB";
11660 }
11661
d8045f23 11662 if (type == STT_GNU_IFUNC
dda8d76d 11663 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11664 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11665 return "IFUNC";
11666
e9e44622 11667 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11668 }
252b5132 11669 else
e9e44622 11670 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11671 return buff;
11672 }
11673}
11674
d1133906 11675static const char *
d3ba0551 11676get_symbol_visibility (unsigned int visibility)
d1133906
NC
11677{
11678 switch (visibility)
11679 {
b34976b6
AM
11680 case STV_DEFAULT: return "DEFAULT";
11681 case STV_INTERNAL: return "INTERNAL";
11682 case STV_HIDDEN: return "HIDDEN";
d1133906 11683 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11684 default:
27a45f42 11685 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11686 return _("<unknown>");
d1133906
NC
11687 }
11688}
11689
2057d69d
CZ
11690static const char *
11691get_alpha_symbol_other (unsigned int other)
9abca702 11692{
2057d69d
CZ
11693 switch (other)
11694 {
11695 case STO_ALPHA_NOPV: return "NOPV";
11696 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11697 default:
27a45f42 11698 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11699 return _("<unknown>");
9abca702 11700 }
2057d69d
CZ
11701}
11702
fd85a6a1
NC
11703static const char *
11704get_solaris_symbol_visibility (unsigned int visibility)
11705{
11706 switch (visibility)
11707 {
11708 case 4: return "EXPORTED";
11709 case 5: return "SINGLETON";
11710 case 6: return "ELIMINATE";
11711 default: return get_symbol_visibility (visibility);
11712 }
11713}
11714
2301ed1c
SN
11715static const char *
11716get_aarch64_symbol_other (unsigned int other)
11717{
11718 static char buf[32];
11719
11720 if (other & STO_AARCH64_VARIANT_PCS)
11721 {
11722 other &= ~STO_AARCH64_VARIANT_PCS;
11723 if (other == 0)
11724 return "VARIANT_PCS";
11725 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
11726 return buf;
11727 }
11728 return NULL;
11729}
11730
5e2b0d47
NC
11731static const char *
11732get_mips_symbol_other (unsigned int other)
11733{
11734 switch (other)
11735 {
32ec8896
NC
11736 case STO_OPTIONAL: return "OPTIONAL";
11737 case STO_MIPS_PLT: return "MIPS PLT";
11738 case STO_MIPS_PIC: return "MIPS PIC";
11739 case STO_MICROMIPS: return "MICROMIPS";
11740 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11741 case STO_MIPS16: return "MIPS16";
11742 default: return NULL;
5e2b0d47
NC
11743 }
11744}
11745
28f997cf 11746static const char *
dda8d76d 11747get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11748{
dda8d76d 11749 if (is_ia64_vms (filedata))
28f997cf
TG
11750 {
11751 static char res[32];
11752
11753 res[0] = 0;
11754
11755 /* Function types is for images and .STB files only. */
dda8d76d 11756 switch (filedata->file_header.e_type)
28f997cf
TG
11757 {
11758 case ET_DYN:
11759 case ET_EXEC:
11760 switch (VMS_ST_FUNC_TYPE (other))
11761 {
11762 case VMS_SFT_CODE_ADDR:
11763 strcat (res, " CA");
11764 break;
11765 case VMS_SFT_SYMV_IDX:
11766 strcat (res, " VEC");
11767 break;
11768 case VMS_SFT_FD:
11769 strcat (res, " FD");
11770 break;
11771 case VMS_SFT_RESERVE:
11772 strcat (res, " RSV");
11773 break;
11774 default:
bee0ee85
NC
11775 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11776 VMS_ST_FUNC_TYPE (other));
11777 strcat (res, " <unknown>");
11778 break;
28f997cf
TG
11779 }
11780 break;
11781 default:
11782 break;
11783 }
11784 switch (VMS_ST_LINKAGE (other))
11785 {
11786 case VMS_STL_IGNORE:
11787 strcat (res, " IGN");
11788 break;
11789 case VMS_STL_RESERVE:
11790 strcat (res, " RSV");
11791 break;
11792 case VMS_STL_STD:
11793 strcat (res, " STD");
11794 break;
11795 case VMS_STL_LNK:
11796 strcat (res, " LNK");
11797 break;
11798 default:
bee0ee85
NC
11799 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11800 VMS_ST_LINKAGE (other));
11801 strcat (res, " <unknown>");
11802 break;
28f997cf
TG
11803 }
11804
11805 if (res[0] != 0)
11806 return res + 1;
11807 else
11808 return res;
11809 }
11810 return NULL;
11811}
11812
6911b7dc
AM
11813static const char *
11814get_ppc64_symbol_other (unsigned int other)
11815{
14732552
AM
11816 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11817 return NULL;
11818
11819 other >>= STO_PPC64_LOCAL_BIT;
11820 if (other <= 6)
6911b7dc 11821 {
89246a0e 11822 static char buf[64];
14732552
AM
11823 if (other >= 2)
11824 other = ppc64_decode_local_entry (other);
11825 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11826 return buf;
11827 }
11828 return NULL;
11829}
11830
5e2b0d47 11831static const char *
dda8d76d 11832get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11833{
11834 const char * result = NULL;
89246a0e 11835 static char buff [64];
5e2b0d47
NC
11836
11837 if (other == 0)
11838 return "";
11839
dda8d76d 11840 switch (filedata->file_header.e_machine)
5e2b0d47 11841 {
2057d69d
CZ
11842 case EM_ALPHA:
11843 result = get_alpha_symbol_other (other);
11844 break;
2301ed1c
SN
11845 case EM_AARCH64:
11846 result = get_aarch64_symbol_other (other);
11847 break;
5e2b0d47
NC
11848 case EM_MIPS:
11849 result = get_mips_symbol_other (other);
28f997cf
TG
11850 break;
11851 case EM_IA_64:
dda8d76d 11852 result = get_ia64_symbol_other (filedata, other);
28f997cf 11853 break;
6911b7dc
AM
11854 case EM_PPC64:
11855 result = get_ppc64_symbol_other (other);
11856 break;
5e2b0d47 11857 default:
fd85a6a1 11858 result = NULL;
5e2b0d47
NC
11859 break;
11860 }
11861
11862 if (result)
11863 return result;
11864
11865 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11866 return buff;
11867}
11868
d1133906 11869static const char *
dda8d76d 11870get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11871{
b34976b6 11872 static char buff[32];
5cf1065c 11873
252b5132
RH
11874 switch (type)
11875 {
b34976b6
AM
11876 case SHN_UNDEF: return "UND";
11877 case SHN_ABS: return "ABS";
11878 case SHN_COMMON: return "COM";
252b5132 11879 default:
9ce701e2 11880 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
11881 && filedata->file_header.e_machine == EM_IA_64
11882 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
11883 return "ANSI_COM";
11884 else if ((filedata->file_header.e_machine == EM_X86_64
11885 || filedata->file_header.e_machine == EM_L1OM
11886 || filedata->file_header.e_machine == EM_K1OM)
11887 && type == SHN_X86_64_LCOMMON)
11888 return "LARGE_COM";
11889 else if ((type == SHN_MIPS_SCOMMON
11890 && filedata->file_header.e_machine == EM_MIPS)
11891 || (type == SHN_TIC6X_SCOMMON
11892 && filedata->file_header.e_machine == EM_TI_C6000))
11893 return "SCOM";
11894 else if (type == SHN_MIPS_SUNDEFINED
11895 && filedata->file_header.e_machine == EM_MIPS)
11896 return "SUND";
11897 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
11898 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
11899 else if (type >= SHN_LOOS && type <= SHN_HIOS)
11900 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11901 else if (type >= SHN_LORESERVE)
11902 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
11903 else if (filedata->file_header.e_shnum != 0
11904 && type >= filedata->file_header.e_shnum)
11905 sprintf (buff, _("bad section index[%3d]"), type);
11906 else
11907 sprintf (buff, "%3d", type);
11908 break;
fd85a6a1
NC
11909 }
11910
10ca4b04 11911 return buff;
6bd1a22c
L
11912}
11913
bb4d2ac2 11914static const char *
dda8d76d 11915get_symbol_version_string (Filedata * filedata,
1449284b
NC
11916 bfd_boolean is_dynsym,
11917 const char * strtab,
11918 unsigned long int strtab_size,
11919 unsigned int si,
11920 Elf_Internal_Sym * psym,
11921 enum versioned_symbol_info * sym_info,
11922 unsigned short * vna_other)
bb4d2ac2 11923{
ab273396
AM
11924 unsigned char data[2];
11925 unsigned short vers_data;
11926 unsigned long offset;
7a815dd5 11927 unsigned short max_vd_ndx;
bb4d2ac2 11928
ab273396 11929 if (!is_dynsym
978c4450 11930 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 11931 return NULL;
bb4d2ac2 11932
978c4450
AM
11933 offset = offset_from_vma (filedata,
11934 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11935 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11936
dda8d76d 11937 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11938 sizeof (data), 1, _("version data")) == NULL)
11939 return NULL;
11940
11941 vers_data = byte_get (data, 2);
bb4d2ac2 11942
1f6f5dba 11943 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11944 return NULL;
bb4d2ac2 11945
0b8b7609 11946 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
11947 max_vd_ndx = 0;
11948
ab273396
AM
11949 /* Usually we'd only see verdef for defined symbols, and verneed for
11950 undefined symbols. However, symbols defined by the linker in
11951 .dynbss for variables copied from a shared library in order to
11952 avoid text relocations are defined yet have verneed. We could
11953 use a heuristic to detect the special case, for example, check
11954 for verneed first on symbols defined in SHT_NOBITS sections, but
11955 it is simpler and more reliable to just look for both verdef and
11956 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11957
ab273396
AM
11958 if (psym->st_shndx != SHN_UNDEF
11959 && vers_data != 0x8001
978c4450 11960 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
11961 {
11962 Elf_Internal_Verdef ivd;
11963 Elf_Internal_Verdaux ivda;
11964 Elf_External_Verdaux evda;
11965 unsigned long off;
bb4d2ac2 11966
dda8d76d 11967 off = offset_from_vma (filedata,
978c4450 11968 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
11969 sizeof (Elf_External_Verdef));
11970
11971 do
bb4d2ac2 11972 {
ab273396
AM
11973 Elf_External_Verdef evd;
11974
dda8d76d 11975 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11976 _("version def")) == NULL)
11977 {
11978 ivd.vd_ndx = 0;
11979 ivd.vd_aux = 0;
11980 ivd.vd_next = 0;
1f6f5dba 11981 ivd.vd_flags = 0;
ab273396
AM
11982 }
11983 else
bb4d2ac2 11984 {
ab273396
AM
11985 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11986 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11987 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 11988 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 11989 }
bb4d2ac2 11990
7a815dd5
L
11991 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
11992 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
11993
ab273396
AM
11994 off += ivd.vd_next;
11995 }
11996 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11997
ab273396
AM
11998 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11999 {
9abca702 12000 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12001 return NULL;
12002
ab273396
AM
12003 off -= ivd.vd_next;
12004 off += ivd.vd_aux;
bb4d2ac2 12005
dda8d76d 12006 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12007 _("version def aux")) != NULL)
12008 {
12009 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12010
ab273396 12011 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12012 return (ivda.vda_name < strtab_size
12013 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12014 }
12015 }
12016 }
bb4d2ac2 12017
978c4450 12018 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12019 {
12020 Elf_External_Verneed evn;
12021 Elf_Internal_Verneed ivn;
12022 Elf_Internal_Vernaux ivna;
bb4d2ac2 12023
dda8d76d 12024 offset = offset_from_vma (filedata,
978c4450 12025 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12026 sizeof evn);
12027 do
12028 {
12029 unsigned long vna_off;
bb4d2ac2 12030
dda8d76d 12031 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12032 _("version need")) == NULL)
12033 {
12034 ivna.vna_next = 0;
12035 ivna.vna_other = 0;
12036 ivna.vna_name = 0;
12037 break;
12038 }
bb4d2ac2 12039
ab273396
AM
12040 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12041 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12042
ab273396 12043 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12044
ab273396
AM
12045 do
12046 {
12047 Elf_External_Vernaux evna;
bb4d2ac2 12048
dda8d76d 12049 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12050 _("version need aux (3)")) == NULL)
bb4d2ac2 12051 {
ab273396
AM
12052 ivna.vna_next = 0;
12053 ivna.vna_other = 0;
12054 ivna.vna_name = 0;
bb4d2ac2 12055 }
bb4d2ac2 12056 else
bb4d2ac2 12057 {
ab273396
AM
12058 ivna.vna_other = BYTE_GET (evna.vna_other);
12059 ivna.vna_next = BYTE_GET (evna.vna_next);
12060 ivna.vna_name = BYTE_GET (evna.vna_name);
12061 }
bb4d2ac2 12062
ab273396
AM
12063 vna_off += ivna.vna_next;
12064 }
12065 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12066
ab273396
AM
12067 if (ivna.vna_other == vers_data)
12068 break;
bb4d2ac2 12069
ab273396
AM
12070 offset += ivn.vn_next;
12071 }
12072 while (ivn.vn_next != 0);
bb4d2ac2 12073
ab273396
AM
12074 if (ivna.vna_other == vers_data)
12075 {
12076 *sym_info = symbol_undefined;
12077 *vna_other = ivna.vna_other;
12078 return (ivna.vna_name < strtab_size
12079 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12080 }
7a815dd5
L
12081 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12082 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12083 return _("<corrupt>");
bb4d2ac2 12084 }
ab273396 12085 return NULL;
bb4d2ac2
L
12086}
12087
10ca4b04
L
12088static void
12089print_dynamic_symbol (Filedata *filedata, unsigned long si,
12090 Elf_Internal_Sym *symtab,
12091 Elf_Internal_Shdr *section,
12092 char *strtab, size_t strtab_size)
252b5132 12093{
10ca4b04
L
12094 const char *version_string;
12095 enum versioned_symbol_info sym_info;
12096 unsigned short vna_other;
12097 Elf_Internal_Sym *psym = symtab + si;
0942c7ab 12098
10ca4b04
L
12099 printf ("%6ld: ", si);
12100 print_vma (psym->st_value, LONG_HEX);
12101 putchar (' ');
12102 print_vma (psym->st_size, DEC_5);
12103 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12104 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12105 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12106 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12107 else
252b5132 12108 {
10ca4b04 12109 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12110
10ca4b04
L
12111 printf (" %-7s", get_symbol_visibility (vis));
12112 /* Check to see if any other bits in the st_other field are set.
12113 Note - displaying this information disrupts the layout of the
12114 table being generated, but for the moment this case is very rare. */
12115 if (psym->st_other ^ vis)
12116 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12117 }
10ca4b04 12118 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab
NC
12119
12120 bfd_boolean is_valid = VALID_SYMBOL_NAME (strtab, strtab_size,
12121 psym->st_name);
12122 const char * sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
10ca4b04
L
12123
12124 version_string
12125 = get_symbol_version_string (filedata,
12126 (section == NULL
12127 || section->sh_type == SHT_DYNSYM),
12128 strtab, strtab_size, si,
12129 psym, &sym_info, &vna_other);
0942c7ab
NC
12130
12131 int len_avail = 21;
12132 if (! do_wide && version_string != NULL)
12133 {
ddb43bab 12134 char buffer[16];
0942c7ab 12135
ddb43bab 12136 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12137
12138 if (sym_info == symbol_undefined)
12139 len_avail -= sprintf (buffer," (%d)", vna_other);
12140 else if (sym_info != symbol_hidden)
12141 len_avail -= 1;
12142 }
12143
12144 print_symbol (len_avail, sstr);
12145
10ca4b04
L
12146 if (version_string)
12147 {
12148 if (sym_info == symbol_undefined)
12149 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12150 else
10ca4b04
L
12151 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12152 version_string);
12153 }
6bd1a22c 12154
10ca4b04 12155 putchar ('\n');
6bd1a22c 12156
10ca4b04
L
12157 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12158 && section != NULL
12159 && si >= section->sh_info
12160 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12161 && filedata->file_header.e_machine != EM_MIPS
12162 /* Solaris binaries have been found to violate this requirement as
12163 well. Not sure if this is a bug or an ABI requirement. */
12164 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12165 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12166 si, printable_section_name (filedata, section), section->sh_info);
12167}
f16a9783 12168
10ca4b04
L
12169/* Dump the symbol table. */
12170static bfd_boolean
12171process_symbol_table (Filedata * filedata)
12172{
12173 Elf_Internal_Shdr * section;
f16a9783 12174
10ca4b04
L
12175 if (!do_syms && !do_dyn_syms && !do_histogram)
12176 return TRUE;
6bd1a22c 12177
978c4450 12178 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12179 && do_syms
12180 && do_using_dynamic
978c4450
AM
12181 && filedata->dynamic_strings != NULL
12182 && filedata->dynamic_symbols != NULL)
6bd1a22c 12183 {
10ca4b04 12184 unsigned long si;
6bd1a22c 12185
10ca4b04
L
12186 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12187 "\nSymbol table for image contains %lu entries:\n",
978c4450
AM
12188 filedata->num_dynamic_syms),
12189 filedata->num_dynamic_syms);
10ca4b04
L
12190 if (is_32bit_elf)
12191 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12192 else
12193 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12194
978c4450
AM
12195 for (si = 0; si < filedata->num_dynamic_syms; si++)
12196 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12197 filedata->dynamic_strings,
12198 filedata->dynamic_strings_length);
252b5132 12199 }
8b73c356 12200 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12201 && filedata->section_headers != NULL)
252b5132 12202 {
b34976b6 12203 unsigned int i;
252b5132 12204
dda8d76d
NC
12205 for (i = 0, section = filedata->section_headers;
12206 i < filedata->file_header.e_shnum;
252b5132
RH
12207 i++, section++)
12208 {
2cf0635d 12209 char * strtab = NULL;
c256ffe7 12210 unsigned long int strtab_size = 0;
2cf0635d 12211 Elf_Internal_Sym * symtab;
ef3df110 12212 unsigned long si, num_syms;
252b5132 12213
2c610e4b
L
12214 if ((section->sh_type != SHT_SYMTAB
12215 && section->sh_type != SHT_DYNSYM)
12216 || (!do_syms
12217 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12218 continue;
12219
dd24e3da
NC
12220 if (section->sh_entsize == 0)
12221 {
12222 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12223 printable_section_name (filedata, section));
dd24e3da
NC
12224 continue;
12225 }
12226
d3a49aa8
AM
12227 num_syms = section->sh_size / section->sh_entsize;
12228 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12229 "\nSymbol table '%s' contains %lu entries:\n",
12230 num_syms),
dda8d76d 12231 printable_section_name (filedata, section),
d3a49aa8 12232 num_syms);
dd24e3da 12233
f7a99963 12234 if (is_32bit_elf)
ca47b30c 12235 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12236 else
ca47b30c 12237 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12238
dda8d76d 12239 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12240 if (symtab == NULL)
12241 continue;
12242
dda8d76d 12243 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12244 {
dda8d76d
NC
12245 strtab = filedata->string_table;
12246 strtab_size = filedata->string_table_length;
c256ffe7 12247 }
dda8d76d 12248 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12249 {
2cf0635d 12250 Elf_Internal_Shdr * string_sec;
252b5132 12251
dda8d76d 12252 string_sec = filedata->section_headers + section->sh_link;
252b5132 12253
dda8d76d 12254 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12255 1, string_sec->sh_size,
12256 _("string table"));
c256ffe7 12257 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12258 }
12259
10ca4b04
L
12260 for (si = 0; si < num_syms; si++)
12261 print_dynamic_symbol (filedata, si, symtab, section,
12262 strtab, strtab_size);
252b5132
RH
12263
12264 free (symtab);
dda8d76d 12265 if (strtab != filedata->string_table)
252b5132
RH
12266 free (strtab);
12267 }
12268 }
12269 else if (do_syms)
12270 printf
12271 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12272
978c4450 12273 if (do_histogram && filedata->buckets != NULL)
252b5132 12274 {
2cf0635d
NC
12275 unsigned long * lengths;
12276 unsigned long * counts;
66543521
AM
12277 unsigned long hn;
12278 bfd_vma si;
12279 unsigned long maxlength = 0;
12280 unsigned long nzero_counts = 0;
12281 unsigned long nsyms = 0;
6bd6a03d 12282 char *visited;
252b5132 12283
d3a49aa8
AM
12284 printf (ngettext ("\nHistogram for bucket list length "
12285 "(total of %lu bucket):\n",
12286 "\nHistogram for bucket list length "
12287 "(total of %lu buckets):\n",
978c4450
AM
12288 (unsigned long) filedata->nbuckets),
12289 (unsigned long) filedata->nbuckets);
252b5132 12290
978c4450
AM
12291 lengths = (unsigned long *) calloc (filedata->nbuckets,
12292 sizeof (*lengths));
252b5132
RH
12293 if (lengths == NULL)
12294 {
8b73c356 12295 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12296 goto err_out;
252b5132 12297 }
978c4450
AM
12298 visited = xcmalloc (filedata->nchains, 1);
12299 memset (visited, 0, filedata->nchains);
8b73c356
NC
12300
12301 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12302 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12303 {
978c4450 12304 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12305 {
b34976b6 12306 ++nsyms;
252b5132 12307 if (maxlength < ++lengths[hn])
b34976b6 12308 ++maxlength;
978c4450 12309 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12310 {
12311 error (_("histogram chain is corrupt\n"));
12312 break;
12313 }
12314 visited[si] = 1;
252b5132
RH
12315 }
12316 }
6bd6a03d 12317 free (visited);
252b5132 12318
3f5e193b 12319 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12320 if (counts == NULL)
12321 {
b2e951ec 12322 free (lengths);
8b73c356 12323 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12324 goto err_out;
252b5132
RH
12325 }
12326
978c4450 12327 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12328 ++counts[lengths[hn]];
252b5132 12329
978c4450 12330 if (filedata->nbuckets > 0)
252b5132 12331 {
66543521
AM
12332 unsigned long i;
12333 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12334 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12335 for (i = 1; i <= maxlength; ++i)
103f02d3 12336 {
66543521
AM
12337 nzero_counts += counts[i] * i;
12338 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12339 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12340 (nzero_counts * 100.0) / nsyms);
12341 }
252b5132
RH
12342 }
12343
12344 free (counts);
12345 free (lengths);
12346 }
12347
978c4450
AM
12348 free (filedata->buckets);
12349 filedata->buckets = NULL;
12350 filedata->nbuckets = 0;
12351 free (filedata->chains);
12352 filedata->chains = NULL;
252b5132 12353
978c4450 12354 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 12355 {
2cf0635d
NC
12356 unsigned long * lengths;
12357 unsigned long * counts;
fdc90cb4
JJ
12358 unsigned long hn;
12359 unsigned long maxlength = 0;
12360 unsigned long nzero_counts = 0;
12361 unsigned long nsyms = 0;
fdc90cb4 12362
f16a9783 12363 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12364 "(total of %lu bucket):\n",
f16a9783 12365 "\nHistogram for `%s' bucket list length "
d3a49aa8 12366 "(total of %lu buckets):\n",
978c4450
AM
12367 (unsigned long) filedata->ngnubuckets),
12368 GNU_HASH_SECTION_NAME (filedata),
12369 (unsigned long) filedata->ngnubuckets);
8b73c356 12370
978c4450
AM
12371 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
12372 sizeof (*lengths));
fdc90cb4
JJ
12373 if (lengths == NULL)
12374 {
8b73c356 12375 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12376 goto err_out;
fdc90cb4
JJ
12377 }
12378
fdc90cb4
JJ
12379 printf (_(" Length Number %% of total Coverage\n"));
12380
978c4450
AM
12381 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12382 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
12383 {
12384 bfd_vma off, length = 1;
12385
978c4450 12386 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 12387 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
12388 off < filedata->ngnuchains
12389 && (filedata->gnuchains[off] & 1) == 0;
071436c6 12390 ++off)
fdc90cb4
JJ
12391 ++length;
12392 lengths[hn] = length;
12393 if (length > maxlength)
12394 maxlength = length;
12395 nsyms += length;
12396 }
12397
3f5e193b 12398 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12399 if (counts == NULL)
12400 {
b2e951ec 12401 free (lengths);
8b73c356 12402 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12403 goto err_out;
fdc90cb4
JJ
12404 }
12405
978c4450 12406 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
12407 ++counts[lengths[hn]];
12408
978c4450 12409 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
12410 {
12411 unsigned long j;
12412 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12413 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
12414 for (j = 1; j <= maxlength; ++j)
12415 {
12416 nzero_counts += counts[j] * j;
12417 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12418 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
12419 (nzero_counts * 100.0) / nsyms);
12420 }
12421 }
12422
12423 free (counts);
12424 free (lengths);
fdc90cb4 12425 }
978c4450
AM
12426 free (filedata->gnubuckets);
12427 filedata->gnubuckets = NULL;
12428 filedata->ngnubuckets = 0;
12429 free (filedata->gnuchains);
12430 filedata->gnuchains = NULL;
12431 filedata->ngnuchains = 0;
12432 free (filedata->mipsxlat);
12433 filedata->mipsxlat = NULL;
32ec8896 12434 return TRUE;
fd486f32
AM
12435
12436 err_out:
978c4450
AM
12437 free (filedata->gnubuckets);
12438 filedata->gnubuckets = NULL;
12439 filedata->ngnubuckets = 0;
12440 free (filedata->gnuchains);
12441 filedata->gnuchains = NULL;
12442 filedata->ngnuchains = 0;
12443 free (filedata->mipsxlat);
12444 filedata->mipsxlat = NULL;
12445 free (filedata->buckets);
12446 filedata->buckets = NULL;
12447 filedata->nbuckets = 0;
12448 free (filedata->chains);
12449 filedata->chains = NULL;
fd486f32 12450 return FALSE;
252b5132
RH
12451}
12452
32ec8896 12453static bfd_boolean
dda8d76d 12454process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12455{
b4c96d0d 12456 unsigned int i;
252b5132 12457
978c4450 12458 if (filedata->dynamic_syminfo == NULL
252b5132
RH
12459 || !do_dynamic)
12460 /* No syminfo, this is ok. */
32ec8896 12461 return TRUE;
252b5132
RH
12462
12463 /* There better should be a dynamic symbol section. */
978c4450 12464 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
32ec8896 12465 return FALSE;
252b5132 12466
978c4450 12467 if (filedata->dynamic_addr)
d3a49aa8
AM
12468 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12469 "contains %d entry:\n",
12470 "\nDynamic info segment at offset 0x%lx "
12471 "contains %d entries:\n",
978c4450
AM
12472 filedata->dynamic_syminfo_nent),
12473 filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent);
252b5132
RH
12474
12475 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 12476 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 12477 {
978c4450 12478 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 12479
31104126 12480 printf ("%4d: ", i);
978c4450 12481 if (i >= filedata->num_dynamic_syms)
4082ef84 12482 printf (_("<corrupt index>"));
978c4450
AM
12483 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
12484 print_symbol (30, GET_DYNAMIC_NAME (filedata,
12485 filedata->dynamic_symbols[i].st_name));
d79b3d50 12486 else
978c4450 12487 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 12488 putchar (' ');
252b5132 12489
978c4450 12490 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
12491 {
12492 case SYMINFO_BT_SELF:
12493 fputs ("SELF ", stdout);
12494 break;
12495 case SYMINFO_BT_PARENT:
12496 fputs ("PARENT ", stdout);
12497 break;
12498 default:
978c4450
AM
12499 if (filedata->dynamic_syminfo[i].si_boundto > 0
12500 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
12501 && VALID_DYNAMIC_NAME (filedata,
12502 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12503 {
978c4450
AM
12504 print_symbol (10, GET_DYNAMIC_NAME (filedata,
12505 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12506 putchar (' ' );
12507 }
252b5132 12508 else
978c4450 12509 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
12510 break;
12511 }
12512
12513 if (flags & SYMINFO_FLG_DIRECT)
12514 printf (" DIRECT");
12515 if (flags & SYMINFO_FLG_PASSTHRU)
12516 printf (" PASSTHRU");
12517 if (flags & SYMINFO_FLG_COPY)
12518 printf (" COPY");
12519 if (flags & SYMINFO_FLG_LAZYLOAD)
12520 printf (" LAZYLOAD");
12521
12522 puts ("");
12523 }
12524
32ec8896 12525 return TRUE;
252b5132
RH
12526}
12527
75802ccb
CE
12528/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
12529 is contained by the region START .. END. The types of ADDR, START
12530 and END should all be the same. Note both ADDR + NELEM and END
12531 point to just beyond the end of the regions that are being tested. */
12532#define IN_RANGE(START,END,ADDR,NELEM) \
12533 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 12534
cf13d699
NC
12535/* Check to see if the given reloc needs to be handled in a target specific
12536 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12537 FALSE.
12538
12539 If called with reloc == NULL, then this is a signal that reloc processing
12540 for the current section has finished, and any saved state should be
12541 discarded. */
09c11c86 12542
cf13d699 12543static bfd_boolean
dda8d76d
NC
12544target_specific_reloc_handling (Filedata * filedata,
12545 Elf_Internal_Rela * reloc,
12546 unsigned char * start,
12547 unsigned char * end,
12548 Elf_Internal_Sym * symtab,
12549 unsigned long num_syms)
252b5132 12550{
f84ce13b
NC
12551 unsigned int reloc_type = 0;
12552 unsigned long sym_index = 0;
12553
12554 if (reloc)
12555 {
dda8d76d 12556 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12557 sym_index = get_reloc_symindex (reloc->r_info);
12558 }
252b5132 12559
dda8d76d 12560 switch (filedata->file_header.e_machine)
252b5132 12561 {
13761a11
NC
12562 case EM_MSP430:
12563 case EM_MSP430_OLD:
12564 {
12565 static Elf_Internal_Sym * saved_sym = NULL;
12566
f84ce13b
NC
12567 if (reloc == NULL)
12568 {
12569 saved_sym = NULL;
12570 return TRUE;
12571 }
12572
13761a11
NC
12573 switch (reloc_type)
12574 {
12575 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12576 if (uses_msp430x_relocs (filedata))
13761a11 12577 break;
1a0670f3 12578 /* Fall through. */
13761a11 12579 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12580 /* PR 21139. */
12581 if (sym_index >= num_syms)
12582 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12583 sym_index);
12584 else
12585 saved_sym = symtab + sym_index;
13761a11
NC
12586 return TRUE;
12587
12588 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12589 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12590 goto handle_sym_diff;
0b4362b0 12591
13761a11
NC
12592 case 5: /* R_MSP430_16_BYTE */
12593 case 9: /* R_MSP430_8 */
dda8d76d 12594 if (uses_msp430x_relocs (filedata))
13761a11
NC
12595 break;
12596 goto handle_sym_diff;
12597
12598 case 2: /* R_MSP430_ABS16 */
12599 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12600 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12601 break;
12602 goto handle_sym_diff;
0b4362b0 12603
13761a11
NC
12604 handle_sym_diff:
12605 if (saved_sym != NULL)
12606 {
03f7786e 12607 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12608 bfd_vma value;
12609
f84ce13b
NC
12610 if (sym_index >= num_syms)
12611 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12612 sym_index);
03f7786e 12613 else
f84ce13b
NC
12614 {
12615 value = reloc->r_addend + (symtab[sym_index].st_value
12616 - saved_sym->st_value);
12617
b32e566b 12618 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12619 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12620 else
12621 /* PR 21137 */
12622 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12623 (long) reloc->r_offset);
f84ce13b 12624 }
13761a11
NC
12625
12626 saved_sym = NULL;
12627 return TRUE;
12628 }
12629 break;
12630
12631 default:
12632 if (saved_sym != NULL)
071436c6 12633 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12634 break;
12635 }
12636 break;
12637 }
12638
cf13d699
NC
12639 case EM_MN10300:
12640 case EM_CYGNUS_MN10300:
12641 {
12642 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12643
f84ce13b
NC
12644 if (reloc == NULL)
12645 {
12646 saved_sym = NULL;
12647 return TRUE;
12648 }
12649
cf13d699
NC
12650 switch (reloc_type)
12651 {
12652 case 34: /* R_MN10300_ALIGN */
12653 return TRUE;
12654 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12655 if (sym_index >= num_syms)
12656 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12657 sym_index);
12658 else
12659 saved_sym = symtab + sym_index;
cf13d699 12660 return TRUE;
f84ce13b 12661
cf13d699
NC
12662 case 1: /* R_MN10300_32 */
12663 case 2: /* R_MN10300_16 */
12664 if (saved_sym != NULL)
12665 {
03f7786e 12666 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12667 bfd_vma value;
252b5132 12668
f84ce13b
NC
12669 if (sym_index >= num_syms)
12670 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12671 sym_index);
03f7786e 12672 else
f84ce13b
NC
12673 {
12674 value = reloc->r_addend + (symtab[sym_index].st_value
12675 - saved_sym->st_value);
12676
b32e566b 12677 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12678 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12679 else
12680 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12681 (long) reloc->r_offset);
f84ce13b 12682 }
252b5132 12683
cf13d699
NC
12684 saved_sym = NULL;
12685 return TRUE;
12686 }
12687 break;
12688 default:
12689 if (saved_sym != NULL)
071436c6 12690 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12691 break;
12692 }
12693 break;
12694 }
6ff71e76
NC
12695
12696 case EM_RL78:
12697 {
12698 static bfd_vma saved_sym1 = 0;
12699 static bfd_vma saved_sym2 = 0;
12700 static bfd_vma value;
12701
f84ce13b
NC
12702 if (reloc == NULL)
12703 {
12704 saved_sym1 = saved_sym2 = 0;
12705 return TRUE;
12706 }
12707
6ff71e76
NC
12708 switch (reloc_type)
12709 {
12710 case 0x80: /* R_RL78_SYM. */
12711 saved_sym1 = saved_sym2;
f84ce13b
NC
12712 if (sym_index >= num_syms)
12713 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12714 sym_index);
12715 else
12716 {
12717 saved_sym2 = symtab[sym_index].st_value;
12718 saved_sym2 += reloc->r_addend;
12719 }
6ff71e76
NC
12720 return TRUE;
12721
12722 case 0x83: /* R_RL78_OPsub. */
12723 value = saved_sym1 - saved_sym2;
12724 saved_sym2 = saved_sym1 = 0;
12725 return TRUE;
12726 break;
12727
12728 case 0x41: /* R_RL78_ABS32. */
b32e566b 12729 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12730 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12731 else
12732 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12733 (long) reloc->r_offset);
6ff71e76
NC
12734 value = 0;
12735 return TRUE;
12736
12737 case 0x43: /* R_RL78_ABS16. */
b32e566b 12738 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12739 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12740 else
12741 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12742 (long) reloc->r_offset);
6ff71e76
NC
12743 value = 0;
12744 return TRUE;
12745
12746 default:
12747 break;
12748 }
12749 break;
12750 }
252b5132
RH
12751 }
12752
cf13d699 12753 return FALSE;
252b5132
RH
12754}
12755
aca88567
NC
12756/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12757 DWARF debug sections. This is a target specific test. Note - we do not
12758 go through the whole including-target-headers-multiple-times route, (as
12759 we have already done with <elf/h8.h>) because this would become very
12760 messy and even then this function would have to contain target specific
12761 information (the names of the relocs instead of their numeric values).
12762 FIXME: This is not the correct way to solve this problem. The proper way
12763 is to have target specific reloc sizing and typing functions created by
12764 the reloc-macros.h header, in the same way that it already creates the
12765 reloc naming functions. */
12766
12767static bfd_boolean
dda8d76d 12768is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12769{
d347c9df 12770 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12771 switch (filedata->file_header.e_machine)
aca88567 12772 {
41e92641 12773 case EM_386:
22abe556 12774 case EM_IAMCU:
41e92641 12775 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12776 case EM_68K:
12777 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12778 case EM_860:
12779 return reloc_type == 1; /* R_860_32. */
12780 case EM_960:
12781 return reloc_type == 2; /* R_960_32. */
a06ea964 12782 case EM_AARCH64:
9282b95a
JW
12783 return (reloc_type == 258
12784 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
12785 case EM_BPF:
12786 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
12787 case EM_ADAPTEVA_EPIPHANY:
12788 return reloc_type == 3;
aca88567 12789 case EM_ALPHA:
137b6b5f 12790 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12791 case EM_ARC:
12792 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12793 case EM_ARC_COMPACT:
12794 case EM_ARC_COMPACT2:
12795 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12796 case EM_ARM:
12797 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12798 case EM_AVR_OLD:
aca88567
NC
12799 case EM_AVR:
12800 return reloc_type == 1;
12801 case EM_BLACKFIN:
12802 return reloc_type == 0x12; /* R_byte4_data. */
12803 case EM_CRIS:
12804 return reloc_type == 3; /* R_CRIS_32. */
12805 case EM_CR16:
12806 return reloc_type == 3; /* R_CR16_NUM32. */
12807 case EM_CRX:
12808 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
12809 case EM_CSKY:
12810 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
12811 case EM_CYGNUS_FRV:
12812 return reloc_type == 1;
41e92641
NC
12813 case EM_CYGNUS_D10V:
12814 case EM_D10V:
12815 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12816 case EM_CYGNUS_D30V:
12817 case EM_D30V:
12818 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12819 case EM_DLX:
12820 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12821 case EM_CYGNUS_FR30:
12822 case EM_FR30:
12823 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12824 case EM_FT32:
12825 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12826 case EM_H8S:
12827 case EM_H8_300:
12828 case EM_H8_300H:
12829 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12830 case EM_IA_64:
262cdac7
AM
12831 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12832 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12833 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12834 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12835 case EM_IP2K_OLD:
12836 case EM_IP2K:
12837 return reloc_type == 2; /* R_IP2K_32. */
12838 case EM_IQ2000:
12839 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12840 case EM_LATTICEMICO32:
12841 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12842 case EM_M32C_OLD:
aca88567
NC
12843 case EM_M32C:
12844 return reloc_type == 3; /* R_M32C_32. */
12845 case EM_M32R:
12846 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12847 case EM_68HC11:
12848 case EM_68HC12:
12849 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 12850 case EM_S12Z:
2849d19f
JD
12851 return reloc_type == 7 || /* R_S12Z_EXT32 */
12852 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
12853 case EM_MCORE:
12854 return reloc_type == 1; /* R_MCORE_ADDR32. */
12855 case EM_CYGNUS_MEP:
12856 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12857 case EM_METAG:
12858 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12859 case EM_MICROBLAZE:
12860 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12861 case EM_MIPS:
12862 return reloc_type == 2; /* R_MIPS_32. */
12863 case EM_MMIX:
12864 return reloc_type == 4; /* R_MMIX_32. */
12865 case EM_CYGNUS_MN10200:
12866 case EM_MN10200:
12867 return reloc_type == 1; /* R_MN10200_32. */
12868 case EM_CYGNUS_MN10300:
12869 case EM_MN10300:
12870 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12871 case EM_MOXIE:
12872 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12873 case EM_MSP430_OLD:
12874 case EM_MSP430:
13761a11 12875 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12876 case EM_MT:
12877 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12878 case EM_NDS32:
12879 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12880 case EM_ALTERA_NIOS2:
36591ba1 12881 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12882 case EM_NIOS32:
12883 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12884 case EM_OR1K:
12885 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12886 case EM_PARISC:
9abca702 12887 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 12888 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12889 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12890 case EM_PJ:
12891 case EM_PJ_OLD:
12892 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12893 case EM_PPC64:
12894 return reloc_type == 1; /* R_PPC64_ADDR32. */
12895 case EM_PPC:
12896 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12897 case EM_TI_PRU:
12898 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12899 case EM_RISCV:
12900 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12901 case EM_RL78:
12902 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12903 case EM_RX:
12904 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12905 case EM_S370:
12906 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12907 case EM_S390_OLD:
12908 case EM_S390:
12909 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12910 case EM_SCORE:
12911 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12912 case EM_SH:
12913 return reloc_type == 1; /* R_SH_DIR32. */
12914 case EM_SPARC32PLUS:
12915 case EM_SPARCV9:
12916 case EM_SPARC:
12917 return reloc_type == 3 /* R_SPARC_32. */
12918 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12919 case EM_SPU:
12920 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12921 case EM_TI_C6000:
12922 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12923 case EM_TILEGX:
12924 return reloc_type == 2; /* R_TILEGX_32. */
12925 case EM_TILEPRO:
12926 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12927 case EM_CYGNUS_V850:
12928 case EM_V850:
12929 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12930 case EM_V800:
12931 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12932 case EM_VAX:
12933 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12934 case EM_VISIUM:
12935 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12936 case EM_WEBASSEMBLY:
12937 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12938 case EM_X86_64:
8a9036a4 12939 case EM_L1OM:
7a9068fe 12940 case EM_K1OM:
aca88567 12941 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12942 case EM_XC16X:
12943 case EM_C166:
12944 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12945 case EM_XGATE:
12946 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12947 case EM_XSTORMY16:
12948 return reloc_type == 1; /* R_XSTROMY16_32. */
12949 case EM_XTENSA_OLD:
12950 case EM_XTENSA:
12951 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
12952 case EM_Z80:
12953 return reloc_type == 6; /* R_Z80_32. */
aca88567 12954 default:
bee0ee85
NC
12955 {
12956 static unsigned int prev_warn = 0;
12957
12958 /* Avoid repeating the same warning multiple times. */
dda8d76d 12959 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12960 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12961 filedata->file_header.e_machine);
12962 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12963 return FALSE;
12964 }
aca88567
NC
12965 }
12966}
12967
12968/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12969 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12970
12971static bfd_boolean
dda8d76d 12972is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12973{
dda8d76d 12974 switch (filedata->file_header.e_machine)
d347c9df 12975 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12976 {
41e92641 12977 case EM_386:
22abe556 12978 case EM_IAMCU:
3e0873ac 12979 return reloc_type == 2; /* R_386_PC32. */
aca88567 12980 case EM_68K:
3e0873ac 12981 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12982 case EM_AARCH64:
12983 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12984 case EM_ADAPTEVA_EPIPHANY:
12985 return reloc_type == 6;
aca88567
NC
12986 case EM_ALPHA:
12987 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12988 case EM_ARC_COMPACT:
12989 case EM_ARC_COMPACT2:
12990 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12991 case EM_ARM:
3e0873ac 12992 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12993 case EM_AVR_OLD:
12994 case EM_AVR:
12995 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12996 case EM_MICROBLAZE:
12997 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12998 case EM_OR1K:
12999 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13000 case EM_PARISC:
85acf597 13001 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13002 case EM_PPC:
13003 return reloc_type == 26; /* R_PPC_REL32. */
13004 case EM_PPC64:
3e0873ac 13005 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13006 case EM_RISCV:
13007 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13008 case EM_S390_OLD:
13009 case EM_S390:
3e0873ac 13010 return reloc_type == 5; /* R_390_PC32. */
aca88567 13011 case EM_SH:
3e0873ac 13012 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13013 case EM_SPARC32PLUS:
13014 case EM_SPARCV9:
13015 case EM_SPARC:
3e0873ac 13016 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13017 case EM_SPU:
13018 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13019 case EM_TILEGX:
13020 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13021 case EM_TILEPRO:
13022 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13023 case EM_VISIUM:
13024 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13025 case EM_X86_64:
8a9036a4 13026 case EM_L1OM:
7a9068fe 13027 case EM_K1OM:
3e0873ac 13028 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13029 case EM_VAX:
13030 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13031 case EM_XTENSA_OLD:
13032 case EM_XTENSA:
13033 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13034 default:
13035 /* Do not abort or issue an error message here. Not all targets use
13036 pc-relative 32-bit relocs in their DWARF debug information and we
13037 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13038 more helpful warning message will be generated by apply_relocations
13039 anyway, so just return. */
aca88567
NC
13040 return FALSE;
13041 }
13042}
13043
13044/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13045 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13046
13047static bfd_boolean
dda8d76d 13048is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13049{
dda8d76d 13050 switch (filedata->file_header.e_machine)
aca88567 13051 {
a06ea964
NC
13052 case EM_AARCH64:
13053 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13054 case EM_ALPHA:
13055 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13056 case EM_IA_64:
262cdac7
AM
13057 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13058 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13059 case EM_PARISC:
13060 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13061 case EM_PPC64:
13062 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13063 case EM_RISCV:
13064 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13065 case EM_SPARC32PLUS:
13066 case EM_SPARCV9:
13067 case EM_SPARC:
714da62f
NC
13068 return reloc_type == 32 /* R_SPARC_64. */
13069 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13070 case EM_X86_64:
8a9036a4 13071 case EM_L1OM:
7a9068fe 13072 case EM_K1OM:
aca88567 13073 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13074 case EM_S390_OLD:
13075 case EM_S390:
aa137e4d
NC
13076 return reloc_type == 22; /* R_S390_64. */
13077 case EM_TILEGX:
13078 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13079 case EM_MIPS:
aa137e4d 13080 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
13081 default:
13082 return FALSE;
13083 }
13084}
13085
85acf597
RH
13086/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13087 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13088
13089static bfd_boolean
dda8d76d 13090is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13091{
dda8d76d 13092 switch (filedata->file_header.e_machine)
85acf597 13093 {
a06ea964
NC
13094 case EM_AARCH64:
13095 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13096 case EM_ALPHA:
aa137e4d 13097 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13098 case EM_IA_64:
262cdac7
AM
13099 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13100 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13101 case EM_PARISC:
aa137e4d 13102 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13103 case EM_PPC64:
aa137e4d 13104 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13105 case EM_SPARC32PLUS:
13106 case EM_SPARCV9:
13107 case EM_SPARC:
aa137e4d 13108 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13109 case EM_X86_64:
8a9036a4 13110 case EM_L1OM:
7a9068fe 13111 case EM_K1OM:
aa137e4d 13112 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13113 case EM_S390_OLD:
13114 case EM_S390:
aa137e4d
NC
13115 return reloc_type == 23; /* R_S390_PC64. */
13116 case EM_TILEGX:
13117 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
13118 default:
13119 return FALSE;
13120 }
13121}
13122
4dc3c23d
AM
13123/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13124 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13125
13126static bfd_boolean
dda8d76d 13127is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13128{
dda8d76d 13129 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13130 {
13131 case EM_CYGNUS_MN10200:
13132 case EM_MN10200:
13133 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13134 case EM_FT32:
13135 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13136 case EM_Z80:
13137 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
13138 default:
13139 return FALSE;
13140 }
13141}
13142
aca88567
NC
13143/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13144 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13145
13146static bfd_boolean
dda8d76d 13147is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13148{
d347c9df 13149 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13150 switch (filedata->file_header.e_machine)
4b78141a 13151 {
886a2506
NC
13152 case EM_ARC:
13153 case EM_ARC_COMPACT:
13154 case EM_ARC_COMPACT2:
13155 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13156 case EM_ADAPTEVA_EPIPHANY:
13157 return reloc_type == 5;
aca88567
NC
13158 case EM_AVR_OLD:
13159 case EM_AVR:
13160 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13161 case EM_CYGNUS_D10V:
13162 case EM_D10V:
13163 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13164 case EM_FT32:
13165 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13166 case EM_H8S:
13167 case EM_H8_300:
13168 case EM_H8_300H:
aca88567
NC
13169 return reloc_type == R_H8_DIR16;
13170 case EM_IP2K_OLD:
13171 case EM_IP2K:
13172 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13173 case EM_M32C_OLD:
f4236fe4
DD
13174 case EM_M32C:
13175 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13176 case EM_CYGNUS_MN10200:
13177 case EM_MN10200:
13178 return reloc_type == 2; /* R_MN10200_16. */
13179 case EM_CYGNUS_MN10300:
13180 case EM_MN10300:
13181 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13182 case EM_MSP430:
dda8d76d 13183 if (uses_msp430x_relocs (filedata))
13761a11 13184 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13185 /* Fall through. */
78c8d46c 13186 case EM_MSP430_OLD:
aca88567 13187 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13188 case EM_NDS32:
13189 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13190 case EM_ALTERA_NIOS2:
36591ba1 13191 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13192 case EM_NIOS32:
13193 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13194 case EM_OR1K:
13195 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13196 case EM_RISCV:
13197 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13198 case EM_TI_PRU:
13199 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13200 case EM_TI_C6000:
13201 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13202 case EM_VISIUM:
13203 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13204 case EM_XC16X:
13205 case EM_C166:
13206 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13207 case EM_XGATE:
13208 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13209 case EM_Z80:
13210 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13211 default:
aca88567 13212 return FALSE;
4b78141a
NC
13213 }
13214}
13215
39e07931
AS
13216/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13217 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13218
13219static bfd_boolean
13220is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13221{
13222 switch (filedata->file_header.e_machine)
13223 {
13224 case EM_RISCV:
13225 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13226 case EM_Z80:
13227 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13228 default:
13229 return FALSE;
13230 }
13231}
13232
13233/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13234 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13235
13236static bfd_boolean
13237is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13238{
13239 switch (filedata->file_header.e_machine)
13240 {
13241 case EM_RISCV:
13242 return reloc_type == 53; /* R_RISCV_SET6. */
13243 default:
13244 return FALSE;
13245 }
13246}
13247
03336641
JW
13248/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13249 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13250
13251static bfd_boolean
13252is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13253{
13254 /* Please keep this table alpha-sorted for ease of visual lookup. */
13255 switch (filedata->file_header.e_machine)
13256 {
13257 case EM_RISCV:
13258 return reloc_type == 35; /* R_RISCV_ADD32. */
13259 default:
13260 return FALSE;
13261 }
13262}
13263
13264/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13265 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13266
13267static bfd_boolean
13268is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13269{
13270 /* Please keep this table alpha-sorted for ease of visual lookup. */
13271 switch (filedata->file_header.e_machine)
13272 {
13273 case EM_RISCV:
13274 return reloc_type == 39; /* R_RISCV_SUB32. */
13275 default:
13276 return FALSE;
13277 }
13278}
13279
13280/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13281 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13282
13283static bfd_boolean
13284is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13285{
13286 /* Please keep this table alpha-sorted for ease of visual lookup. */
13287 switch (filedata->file_header.e_machine)
13288 {
13289 case EM_RISCV:
13290 return reloc_type == 36; /* R_RISCV_ADD64. */
13291 default:
13292 return FALSE;
13293 }
13294}
13295
13296/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13297 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13298
13299static bfd_boolean
13300is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13301{
13302 /* Please keep this table alpha-sorted for ease of visual lookup. */
13303 switch (filedata->file_header.e_machine)
13304 {
13305 case EM_RISCV:
13306 return reloc_type == 40; /* R_RISCV_SUB64. */
13307 default:
13308 return FALSE;
13309 }
13310}
13311
13312/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13313 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13314
13315static bfd_boolean
13316is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13317{
13318 /* Please keep this table alpha-sorted for ease of visual lookup. */
13319 switch (filedata->file_header.e_machine)
13320 {
13321 case EM_RISCV:
13322 return reloc_type == 34; /* R_RISCV_ADD16. */
13323 default:
13324 return FALSE;
13325 }
13326}
13327
13328/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13329 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13330
13331static bfd_boolean
13332is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13333{
13334 /* Please keep this table alpha-sorted for ease of visual lookup. */
13335 switch (filedata->file_header.e_machine)
13336 {
13337 case EM_RISCV:
13338 return reloc_type == 38; /* R_RISCV_SUB16. */
13339 default:
13340 return FALSE;
13341 }
13342}
13343
13344/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13345 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13346
13347static bfd_boolean
13348is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13349{
13350 /* Please keep this table alpha-sorted for ease of visual lookup. */
13351 switch (filedata->file_header.e_machine)
13352 {
13353 case EM_RISCV:
13354 return reloc_type == 33; /* R_RISCV_ADD8. */
13355 default:
13356 return FALSE;
13357 }
13358}
13359
13360/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13361 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13362
13363static bfd_boolean
13364is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13365{
13366 /* Please keep this table alpha-sorted for ease of visual lookup. */
13367 switch (filedata->file_header.e_machine)
13368 {
13369 case EM_RISCV:
13370 return reloc_type == 37; /* R_RISCV_SUB8. */
13371 default:
13372 return FALSE;
13373 }
13374}
13375
39e07931
AS
13376/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13377 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13378
13379static bfd_boolean
13380is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13381{
13382 switch (filedata->file_header.e_machine)
13383 {
13384 case EM_RISCV:
13385 return reloc_type == 52; /* R_RISCV_SUB6. */
13386 default:
13387 return FALSE;
13388 }
13389}
13390
2a7b2e88
JK
13391/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13392 relocation entries (possibly formerly used for SHT_GROUP sections). */
13393
13394static bfd_boolean
dda8d76d 13395is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13396{
dda8d76d 13397 switch (filedata->file_header.e_machine)
2a7b2e88 13398 {
cb8f3167 13399 case EM_386: /* R_386_NONE. */
d347c9df 13400 case EM_68K: /* R_68K_NONE. */
cfb8c092 13401 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13402 case EM_ALPHA: /* R_ALPHA_NONE. */
13403 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13404 case EM_ARC: /* R_ARC_NONE. */
886a2506 13405 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13406 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13407 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13408 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13409 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13410 case EM_FT32: /* R_FT32_NONE. */
13411 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13412 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13413 case EM_L1OM: /* R_X86_64_NONE. */
13414 case EM_M32R: /* R_M32R_NONE. */
13415 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13416 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13417 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13418 case EM_NIOS32: /* R_NIOS_NONE. */
13419 case EM_OR1K: /* R_OR1K_NONE. */
13420 case EM_PARISC: /* R_PARISC_NONE. */
13421 case EM_PPC64: /* R_PPC64_NONE. */
13422 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13423 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13424 case EM_S390: /* R_390_NONE. */
13425 case EM_S390_OLD:
13426 case EM_SH: /* R_SH_NONE. */
13427 case EM_SPARC32PLUS:
13428 case EM_SPARC: /* R_SPARC_NONE. */
13429 case EM_SPARCV9:
aa137e4d
NC
13430 case EM_TILEGX: /* R_TILEGX_NONE. */
13431 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13432 case EM_TI_C6000:/* R_C6000_NONE. */
13433 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13434 case EM_XC16X:
6655dba2 13435 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 13436 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13437 return reloc_type == 0;
d347c9df 13438
a06ea964
NC
13439 case EM_AARCH64:
13440 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13441 case EM_AVR_OLD:
13442 case EM_AVR:
13443 return (reloc_type == 0 /* R_AVR_NONE. */
13444 || reloc_type == 30 /* R_AVR_DIFF8. */
13445 || reloc_type == 31 /* R_AVR_DIFF16. */
13446 || reloc_type == 32 /* R_AVR_DIFF32. */);
13447 case EM_METAG:
13448 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13449 case EM_NDS32:
13450 return (reloc_type == 0 /* R_XTENSA_NONE. */
13451 || reloc_type == 204 /* R_NDS32_DIFF8. */
13452 || reloc_type == 205 /* R_NDS32_DIFF16. */
13453 || reloc_type == 206 /* R_NDS32_DIFF32. */
13454 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13455 case EM_TI_PRU:
13456 return (reloc_type == 0 /* R_PRU_NONE. */
13457 || reloc_type == 65 /* R_PRU_DIFF8. */
13458 || reloc_type == 66 /* R_PRU_DIFF16. */
13459 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13460 case EM_XTENSA_OLD:
13461 case EM_XTENSA:
4dc3c23d
AM
13462 return (reloc_type == 0 /* R_XTENSA_NONE. */
13463 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13464 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
13465 || reloc_type == 19 /* R_XTENSA_DIFF32. */
13466 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
13467 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
13468 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
13469 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
13470 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
13471 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88
JK
13472 }
13473 return FALSE;
13474}
13475
d1c4b12b
NC
13476/* Returns TRUE if there is a relocation against
13477 section NAME at OFFSET bytes. */
13478
13479bfd_boolean
13480reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13481{
13482 Elf_Internal_Rela * relocs;
13483 Elf_Internal_Rela * rp;
13484
13485 if (dsec == NULL || dsec->reloc_info == NULL)
13486 return FALSE;
13487
13488 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13489
13490 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13491 if (rp->r_offset == offset)
13492 return TRUE;
13493
13494 return FALSE;
13495}
13496
cf13d699 13497/* Apply relocations to a section.
32ec8896
NC
13498 Returns TRUE upon success, FALSE otherwise.
13499 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13500 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13501 will be set to the number of relocs loaded.
13502
cf13d699 13503 Note: So far support has been added only for those relocations
32ec8896
NC
13504 which can be found in debug sections. FIXME: Add support for
13505 more relocations ? */
1b315056 13506
32ec8896 13507static bfd_boolean
dda8d76d 13508apply_relocations (Filedata * filedata,
d1c4b12b
NC
13509 const Elf_Internal_Shdr * section,
13510 unsigned char * start,
13511 bfd_size_type size,
1449284b 13512 void ** relocs_return,
d1c4b12b 13513 unsigned long * num_relocs_return)
1b315056 13514{
cf13d699 13515 Elf_Internal_Shdr * relsec;
0d2a7a93 13516 unsigned char * end = start + size;
cb8f3167 13517
d1c4b12b
NC
13518 if (relocs_return != NULL)
13519 {
13520 * (Elf_Internal_Rela **) relocs_return = NULL;
13521 * num_relocs_return = 0;
13522 }
13523
dda8d76d 13524 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13525 /* No relocs to apply. */
13526 return TRUE;
1b315056 13527
cf13d699 13528 /* Find the reloc section associated with the section. */
dda8d76d
NC
13529 for (relsec = filedata->section_headers;
13530 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13531 ++relsec)
252b5132 13532 {
41e92641
NC
13533 bfd_boolean is_rela;
13534 unsigned long num_relocs;
2cf0635d
NC
13535 Elf_Internal_Rela * relocs;
13536 Elf_Internal_Rela * rp;
13537 Elf_Internal_Shdr * symsec;
13538 Elf_Internal_Sym * symtab;
ba5cdace 13539 unsigned long num_syms;
2cf0635d 13540 Elf_Internal_Sym * sym;
252b5132 13541
41e92641 13542 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13543 || relsec->sh_info >= filedata->file_header.e_shnum
13544 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13545 || relsec->sh_size == 0
dda8d76d 13546 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13547 continue;
428409d5 13548
a788aedd
AM
13549 symsec = filedata->section_headers + relsec->sh_link;
13550 if (symsec->sh_type != SHT_SYMTAB
13551 && symsec->sh_type != SHT_DYNSYM)
13552 return FALSE;
13553
41e92641
NC
13554 is_rela = relsec->sh_type == SHT_RELA;
13555
13556 if (is_rela)
13557 {
dda8d76d 13558 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13559 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13560 return FALSE;
41e92641
NC
13561 }
13562 else
13563 {
dda8d76d 13564 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13565 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13566 return FALSE;
41e92641
NC
13567 }
13568
13569 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13570 if (filedata->file_header.e_machine == EM_SH)
41e92641 13571 is_rela = FALSE;
428409d5 13572
dda8d76d 13573 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13574
41e92641 13575 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13576 {
41e92641
NC
13577 bfd_vma addend;
13578 unsigned int reloc_type;
13579 unsigned int reloc_size;
03336641
JW
13580 bfd_boolean reloc_inplace = FALSE;
13581 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13582 unsigned char * rloc;
ba5cdace 13583 unsigned long sym_index;
4b78141a 13584
dda8d76d 13585 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13586
dda8d76d 13587 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13588 continue;
dda8d76d 13589 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13590 continue;
dda8d76d
NC
13591 else if (is_32bit_abs_reloc (filedata, reloc_type)
13592 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13593 reloc_size = 4;
dda8d76d
NC
13594 else if (is_64bit_abs_reloc (filedata, reloc_type)
13595 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13596 reloc_size = 8;
dda8d76d 13597 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13598 reloc_size = 3;
dda8d76d 13599 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13600 reloc_size = 2;
39e07931
AS
13601 else if (is_8bit_abs_reloc (filedata, reloc_type)
13602 || is_6bit_abs_reloc (filedata, reloc_type))
13603 reloc_size = 1;
03336641
JW
13604 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13605 reloc_type))
13606 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13607 {
13608 reloc_size = 4;
13609 reloc_inplace = TRUE;
13610 }
13611 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13612 reloc_type))
13613 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13614 {
13615 reloc_size = 8;
13616 reloc_inplace = TRUE;
13617 }
13618 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13619 reloc_type))
13620 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13621 {
13622 reloc_size = 2;
13623 reloc_inplace = TRUE;
13624 }
13625 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13626 reloc_type))
13627 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13628 {
13629 reloc_size = 1;
13630 reloc_inplace = TRUE;
13631 }
39e07931
AS
13632 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13633 reloc_type)))
13634 {
13635 reloc_size = 1;
13636 reloc_inplace = TRUE;
13637 }
aca88567 13638 else
4b78141a 13639 {
bee0ee85 13640 static unsigned int prev_reloc = 0;
dda8d76d 13641
bee0ee85
NC
13642 if (reloc_type != prev_reloc)
13643 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13644 reloc_type, printable_section_name (filedata, section));
bee0ee85 13645 prev_reloc = reloc_type;
4b78141a
NC
13646 continue;
13647 }
103f02d3 13648
91d6fa6a 13649 rloc = start + rp->r_offset;
75802ccb 13650 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
13651 {
13652 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13653 (unsigned long) rp->r_offset,
dda8d76d 13654 printable_section_name (filedata, section));
700dd8b7
L
13655 continue;
13656 }
103f02d3 13657
ba5cdace
NC
13658 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13659 if (sym_index >= num_syms)
13660 {
13661 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13662 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
13663 continue;
13664 }
13665 sym = symtab + sym_index;
41e92641
NC
13666
13667 /* If the reloc has a symbol associated with it,
55f25fc3
L
13668 make sure that it is of an appropriate type.
13669
13670 Relocations against symbols without type can happen.
13671 Gcc -feliminate-dwarf2-dups may generate symbols
13672 without type for debug info.
13673
13674 Icc generates relocations against function symbols
13675 instead of local labels.
13676
13677 Relocations against object symbols can happen, eg when
13678 referencing a global array. For an example of this see
13679 the _clz.o binary in libgcc.a. */
aca88567 13680 if (sym != symtab
b8871f35 13681 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13682 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13683 {
d3a49aa8 13684 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13685 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13686 printable_section_name (filedata, relsec),
d3a49aa8 13687 (long int)(rp - relocs));
aca88567 13688 continue;
5b18a4bc 13689 }
252b5132 13690
4dc3c23d
AM
13691 addend = 0;
13692 if (is_rela)
13693 addend += rp->r_addend;
c47320c3
AM
13694 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13695 partial_inplace. */
4dc3c23d 13696 if (!is_rela
dda8d76d 13697 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13698 && reloc_type == 1)
dda8d76d
NC
13699 || ((filedata->file_header.e_machine == EM_PJ
13700 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13701 && reloc_type == 1)
dda8d76d
NC
13702 || ((filedata->file_header.e_machine == EM_D30V
13703 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13704 && reloc_type == 12)
13705 || reloc_inplace)
39e07931
AS
13706 {
13707 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
13708 addend += byte_get (rloc, reloc_size) & 0x3f;
13709 else
13710 addend += byte_get (rloc, reloc_size);
13711 }
cb8f3167 13712
dda8d76d
NC
13713 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13714 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13715 {
13716 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13717 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13718 addend -= 8;
91d6fa6a 13719 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13720 reloc_size);
13721 }
39e07931
AS
13722 else if (is_6bit_abs_reloc (filedata, reloc_type)
13723 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
13724 {
13725 if (reloc_subtract)
13726 addend -= sym->st_value;
13727 else
13728 addend += sym->st_value;
13729 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
13730 byte_put (rloc, addend, reloc_size);
13731 }
03336641
JW
13732 else if (reloc_subtract)
13733 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13734 else
91d6fa6a 13735 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13736 }
252b5132 13737
5b18a4bc 13738 free (symtab);
f84ce13b
NC
13739 /* Let the target specific reloc processing code know that
13740 we have finished with these relocs. */
dda8d76d 13741 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13742
13743 if (relocs_return)
13744 {
13745 * (Elf_Internal_Rela **) relocs_return = relocs;
13746 * num_relocs_return = num_relocs;
13747 }
13748 else
13749 free (relocs);
13750
5b18a4bc
NC
13751 break;
13752 }
32ec8896 13753
dfc616fa 13754 return TRUE;
5b18a4bc 13755}
103f02d3 13756
cf13d699 13757#ifdef SUPPORT_DISASSEMBLY
32ec8896 13758static bfd_boolean
dda8d76d 13759disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13760{
dda8d76d 13761 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13762
74e1a04b 13763 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13764
32ec8896 13765 return TRUE;
cf13d699
NC
13766}
13767#endif
13768
13769/* Reads in the contents of SECTION from FILE, returning a pointer
13770 to a malloc'ed buffer or NULL if something went wrong. */
13771
13772static char *
dda8d76d 13773get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13774{
dda8d76d 13775 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13776
13777 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13778 {
c6b78c96 13779 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13780 printable_section_name (filedata, section));
cf13d699
NC
13781 return NULL;
13782 }
13783
dda8d76d 13784 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13785 _("section contents"));
cf13d699
NC
13786}
13787
0e602686
NC
13788/* Uncompresses a section that was compressed using zlib, in place. */
13789
13790static bfd_boolean
dda8d76d
NC
13791uncompress_section_contents (unsigned char ** buffer,
13792 dwarf_size_type uncompressed_size,
13793 dwarf_size_type * size)
0e602686
NC
13794{
13795 dwarf_size_type compressed_size = *size;
13796 unsigned char * compressed_buffer = *buffer;
13797 unsigned char * uncompressed_buffer;
13798 z_stream strm;
13799 int rc;
13800
13801 /* It is possible the section consists of several compressed
13802 buffers concatenated together, so we uncompress in a loop. */
13803 /* PR 18313: The state field in the z_stream structure is supposed
13804 to be invisible to the user (ie us), but some compilers will
13805 still complain about it being used without initialisation. So
13806 we first zero the entire z_stream structure and then set the fields
13807 that we need. */
13808 memset (& strm, 0, sizeof strm);
13809 strm.avail_in = compressed_size;
13810 strm.next_in = (Bytef *) compressed_buffer;
13811 strm.avail_out = uncompressed_size;
13812 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13813
13814 rc = inflateInit (& strm);
13815 while (strm.avail_in > 0)
13816 {
13817 if (rc != Z_OK)
13818 goto fail;
13819 strm.next_out = ((Bytef *) uncompressed_buffer
13820 + (uncompressed_size - strm.avail_out));
13821 rc = inflate (&strm, Z_FINISH);
13822 if (rc != Z_STREAM_END)
13823 goto fail;
13824 rc = inflateReset (& strm);
13825 }
13826 rc = inflateEnd (& strm);
13827 if (rc != Z_OK
13828 || strm.avail_out != 0)
13829 goto fail;
13830
13831 *buffer = uncompressed_buffer;
13832 *size = uncompressed_size;
13833 return TRUE;
13834
13835 fail:
13836 free (uncompressed_buffer);
13837 /* Indicate decompression failure. */
13838 *buffer = NULL;
13839 return FALSE;
13840}
dd24e3da 13841
32ec8896 13842static bfd_boolean
dda8d76d 13843dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13844{
0e602686
NC
13845 Elf_Internal_Shdr * relsec;
13846 bfd_size_type num_bytes;
fd8008d8
L
13847 unsigned char * data;
13848 unsigned char * end;
13849 unsigned char * real_start;
13850 unsigned char * start;
0e602686 13851 bfd_boolean some_strings_shown;
cf13d699 13852
dda8d76d 13853 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13854 if (start == NULL)
c6b78c96
NC
13855 /* PR 21820: Do not fail if the section was empty. */
13856 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13857
0e602686 13858 num_bytes = section->sh_size;
cf13d699 13859
dda8d76d 13860 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13861
0e602686
NC
13862 if (decompress_dumps)
13863 {
13864 dwarf_size_type new_size = num_bytes;
13865 dwarf_size_type uncompressed_size = 0;
13866
13867 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13868 {
13869 Elf_Internal_Chdr chdr;
13870 unsigned int compression_header_size
ebdf1ebf
NC
13871 = get_compression_header (& chdr, (unsigned char *) start,
13872 num_bytes);
5844b465
NC
13873 if (compression_header_size == 0)
13874 /* An error message will have already been generated
13875 by get_compression_header. */
13876 goto error_out;
0e602686 13877
813dabb9 13878 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13879 {
813dabb9 13880 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13881 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 13882 goto error_out;
813dabb9 13883 }
813dabb9
L
13884 uncompressed_size = chdr.ch_size;
13885 start += compression_header_size;
13886 new_size -= compression_header_size;
0e602686
NC
13887 }
13888 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13889 {
13890 /* Read the zlib header. In this case, it should be "ZLIB"
13891 followed by the uncompressed section size, 8 bytes in
13892 big-endian order. */
13893 uncompressed_size = start[4]; uncompressed_size <<= 8;
13894 uncompressed_size += start[5]; uncompressed_size <<= 8;
13895 uncompressed_size += start[6]; uncompressed_size <<= 8;
13896 uncompressed_size += start[7]; uncompressed_size <<= 8;
13897 uncompressed_size += start[8]; uncompressed_size <<= 8;
13898 uncompressed_size += start[9]; uncompressed_size <<= 8;
13899 uncompressed_size += start[10]; uncompressed_size <<= 8;
13900 uncompressed_size += start[11];
13901 start += 12;
13902 new_size -= 12;
13903 }
13904
1835f746
NC
13905 if (uncompressed_size)
13906 {
13907 if (uncompress_section_contents (& start,
13908 uncompressed_size, & new_size))
13909 num_bytes = new_size;
13910 else
13911 {
13912 error (_("Unable to decompress section %s\n"),
dda8d76d 13913 printable_section_name (filedata, section));
f761cb13 13914 goto error_out;
1835f746
NC
13915 }
13916 }
bc303e5d
NC
13917 else
13918 start = real_start;
0e602686 13919 }
fd8008d8 13920
cf13d699
NC
13921 /* If the section being dumped has relocations against it the user might
13922 be expecting these relocations to have been applied. Check for this
13923 case and issue a warning message in order to avoid confusion.
13924 FIXME: Maybe we ought to have an option that dumps a section with
13925 relocs applied ? */
dda8d76d
NC
13926 for (relsec = filedata->section_headers;
13927 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13928 ++relsec)
13929 {
13930 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13931 || relsec->sh_info >= filedata->file_header.e_shnum
13932 || filedata->section_headers + relsec->sh_info != section
cf13d699 13933 || relsec->sh_size == 0
dda8d76d 13934 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13935 continue;
13936
13937 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13938 break;
13939 }
13940
cf13d699
NC
13941 data = start;
13942 end = start + num_bytes;
13943 some_strings_shown = FALSE;
13944
ba3265d0
NC
13945#ifdef HAVE_MBSTATE_T
13946 mbstate_t state;
13947 /* Initialise the multibyte conversion state. */
13948 memset (& state, 0, sizeof (state));
13949#endif
13950
13951 bfd_boolean continuing = FALSE;
13952
cf13d699
NC
13953 while (data < end)
13954 {
13955 while (!ISPRINT (* data))
13956 if (++ data >= end)
13957 break;
13958
13959 if (data < end)
13960 {
071436c6
NC
13961 size_t maxlen = end - data;
13962
ba3265d0
NC
13963 if (continuing)
13964 {
13965 printf (" ");
13966 continuing = FALSE;
13967 }
13968 else
13969 {
d1ce973e 13970 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
13971 }
13972
4082ef84
NC
13973 if (maxlen > 0)
13974 {
f3da8a96 13975 char c = 0;
ba3265d0
NC
13976
13977 while (maxlen)
13978 {
13979 c = *data++;
13980
13981 if (c == 0)
13982 break;
13983
13984 /* PR 25543: Treat new-lines as string-ending characters. */
13985 if (c == '\n')
13986 {
13987 printf ("\\n\n");
13988 if (*data != 0)
13989 continuing = TRUE;
13990 break;
13991 }
13992
13993 /* Do not print control characters directly as they can affect terminal
13994 settings. Such characters usually appear in the names generated
13995 by the assembler for local labels. */
13996 if (ISCNTRL (c))
13997 {
13998 printf ("^%c", c + 0x40);
13999 }
14000 else if (ISPRINT (c))
14001 {
14002 putchar (c);
14003 }
14004 else
14005 {
14006 size_t n;
14007#ifdef HAVE_MBSTATE_T
14008 wchar_t w;
14009#endif
14010 /* Let printf do the hard work of displaying multibyte characters. */
14011 printf ("%.1s", data - 1);
14012#ifdef HAVE_MBSTATE_T
14013 /* Try to find out how many bytes made up the character that was
14014 just printed. Advance the symbol pointer past the bytes that
14015 were displayed. */
14016 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14017#else
14018 n = 1;
14019#endif
14020 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14021 data += (n - 1);
14022 }
14023 }
14024
14025 if (c != '\n')
14026 putchar ('\n');
4082ef84
NC
14027 }
14028 else
14029 {
14030 printf (_("<corrupt>\n"));
14031 data = end;
14032 }
cf13d699
NC
14033 some_strings_shown = TRUE;
14034 }
14035 }
14036
14037 if (! some_strings_shown)
14038 printf (_(" No strings found in this section."));
14039
0e602686 14040 free (real_start);
cf13d699
NC
14041
14042 putchar ('\n');
32ec8896 14043 return TRUE;
f761cb13
AM
14044
14045error_out:
14046 free (real_start);
14047 return FALSE;
cf13d699
NC
14048}
14049
32ec8896 14050static bfd_boolean
dda8d76d
NC
14051dump_section_as_bytes (Elf_Internal_Shdr * section,
14052 Filedata * filedata,
14053 bfd_boolean relocate)
cf13d699
NC
14054{
14055 Elf_Internal_Shdr * relsec;
0e602686
NC
14056 bfd_size_type bytes;
14057 bfd_size_type section_size;
14058 bfd_vma addr;
14059 unsigned char * data;
14060 unsigned char * real_start;
14061 unsigned char * start;
14062
dda8d76d 14063 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14064 if (start == NULL)
c6b78c96
NC
14065 /* PR 21820: Do not fail if the section was empty. */
14066 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 14067
0e602686 14068 section_size = section->sh_size;
cf13d699 14069
dda8d76d 14070 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14071
0e602686
NC
14072 if (decompress_dumps)
14073 {
14074 dwarf_size_type new_size = section_size;
14075 dwarf_size_type uncompressed_size = 0;
14076
14077 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14078 {
14079 Elf_Internal_Chdr chdr;
14080 unsigned int compression_header_size
ebdf1ebf 14081 = get_compression_header (& chdr, start, section_size);
0e602686 14082
5844b465
NC
14083 if (compression_header_size == 0)
14084 /* An error message will have already been generated
14085 by get_compression_header. */
14086 goto error_out;
14087
813dabb9 14088 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14089 {
813dabb9 14090 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14091 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14092 goto error_out;
0e602686 14093 }
813dabb9
L
14094 uncompressed_size = chdr.ch_size;
14095 start += compression_header_size;
14096 new_size -= compression_header_size;
0e602686
NC
14097 }
14098 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14099 {
14100 /* Read the zlib header. In this case, it should be "ZLIB"
14101 followed by the uncompressed section size, 8 bytes in
14102 big-endian order. */
14103 uncompressed_size = start[4]; uncompressed_size <<= 8;
14104 uncompressed_size += start[5]; uncompressed_size <<= 8;
14105 uncompressed_size += start[6]; uncompressed_size <<= 8;
14106 uncompressed_size += start[7]; uncompressed_size <<= 8;
14107 uncompressed_size += start[8]; uncompressed_size <<= 8;
14108 uncompressed_size += start[9]; uncompressed_size <<= 8;
14109 uncompressed_size += start[10]; uncompressed_size <<= 8;
14110 uncompressed_size += start[11];
14111 start += 12;
14112 new_size -= 12;
14113 }
14114
f055032e
NC
14115 if (uncompressed_size)
14116 {
14117 if (uncompress_section_contents (& start, uncompressed_size,
14118 & new_size))
bc303e5d
NC
14119 {
14120 section_size = new_size;
14121 }
f055032e
NC
14122 else
14123 {
14124 error (_("Unable to decompress section %s\n"),
dda8d76d 14125 printable_section_name (filedata, section));
bc303e5d 14126 /* FIXME: Print the section anyway ? */
f761cb13 14127 goto error_out;
f055032e
NC
14128 }
14129 }
bc303e5d
NC
14130 else
14131 start = real_start;
0e602686 14132 }
14ae95f2 14133
cf13d699
NC
14134 if (relocate)
14135 {
dda8d76d 14136 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14137 goto error_out;
cf13d699
NC
14138 }
14139 else
14140 {
14141 /* If the section being dumped has relocations against it the user might
14142 be expecting these relocations to have been applied. Check for this
14143 case and issue a warning message in order to avoid confusion.
14144 FIXME: Maybe we ought to have an option that dumps a section with
14145 relocs applied ? */
dda8d76d
NC
14146 for (relsec = filedata->section_headers;
14147 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14148 ++relsec)
14149 {
14150 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14151 || relsec->sh_info >= filedata->file_header.e_shnum
14152 || filedata->section_headers + relsec->sh_info != section
cf13d699 14153 || relsec->sh_size == 0
dda8d76d 14154 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14155 continue;
14156
14157 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14158 break;
14159 }
14160 }
14161
14162 addr = section->sh_addr;
0e602686 14163 bytes = section_size;
cf13d699
NC
14164 data = start;
14165
14166 while (bytes)
14167 {
14168 int j;
14169 int k;
14170 int lbytes;
14171
14172 lbytes = (bytes > 16 ? 16 : bytes);
14173
14174 printf (" 0x%8.8lx ", (unsigned long) addr);
14175
14176 for (j = 0; j < 16; j++)
14177 {
14178 if (j < lbytes)
14179 printf ("%2.2x", data[j]);
14180 else
14181 printf (" ");
14182
14183 if ((j & 3) == 3)
14184 printf (" ");
14185 }
14186
14187 for (j = 0; j < lbytes; j++)
14188 {
14189 k = data[j];
14190 if (k >= ' ' && k < 0x7f)
14191 printf ("%c", k);
14192 else
14193 printf (".");
14194 }
14195
14196 putchar ('\n');
14197
14198 data += lbytes;
14199 addr += lbytes;
14200 bytes -= lbytes;
14201 }
14202
0e602686 14203 free (real_start);
cf13d699
NC
14204
14205 putchar ('\n');
32ec8896 14206 return TRUE;
f761cb13
AM
14207
14208 error_out:
14209 free (real_start);
14210 return FALSE;
cf13d699
NC
14211}
14212
094e34f2 14213#ifdef ENABLE_LIBCTF
7d9813f1
NA
14214static ctf_sect_t *
14215shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14216{
90bd5423 14217 buf->cts_name = SECTION_NAME (shdr);
7d9813f1
NA
14218 buf->cts_size = shdr->sh_size;
14219 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14220
14221 return buf;
14222}
14223
14224/* Formatting callback function passed to ctf_dump. Returns either the pointer
14225 it is passed, or a pointer to newly-allocated storage, in which case
14226 dump_ctf() will free it when it no longer needs it. */
14227
2f6ecaed
NA
14228static char *
14229dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14230 char *s, void *arg)
7d9813f1 14231{
3e50a591 14232 const char *blanks = arg;
7d9813f1
NA
14233 char *new_s;
14234
3e50a591 14235 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14236 return s;
14237 return new_s;
14238}
14239
2f6ecaed
NA
14240/* Dump one CTF archive member. */
14241
14242static int
14243dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
14244{
14245 ctf_file_t *parent = (ctf_file_t *) arg;
14246 const char *things[] = {"Header", "Labels", "Data objects",
14247 "Function objects", "Variables", "Types", "Strings",
14248 ""};
14249 const char **thing;
8b37e7b6
NA
14250 ctf_next_t *it = NULL;
14251 char *errtext;
14252 int is_warning;
2f6ecaed 14253 size_t i;
8b37e7b6 14254 int err = 0;
2f6ecaed
NA
14255
14256 /* Only print out the name of non-default-named archive members.
14257 The name .ctf appears everywhere, even for things that aren't
14258 really archives, so printing it out is liable to be confusing.
14259
14260 The parent, if there is one, is the default-owned archive member:
14261 avoid importing it into itself. (This does no harm, but looks
14262 confusing.) */
14263
14264 if (strcmp (name, ".ctf") != 0)
14265 {
14266 printf (_("\nCTF archive member: %s:\n"), name);
14267 ctf_import (ctf, parent);
14268 }
14269
14270 for (i = 0, thing = things; *thing[0]; thing++, i++)
14271 {
14272 ctf_dump_state_t *s = NULL;
14273 char *item;
14274
14275 printf ("\n %s:\n", *thing);
14276 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14277 (void *) " ")) != NULL)
14278 {
14279 printf ("%s\n", item);
14280 free (item);
14281 }
14282
14283 if (ctf_errno (ctf))
14284 {
14285 error (_("Iteration failed: %s, %s\n"), *thing,
14286 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
14287 err = 1;
14288 goto out;
2f6ecaed
NA
14289 }
14290 }
8b37e7b6
NA
14291
14292 out:
14293 /* Dump accumulated errors and warnings. */
14294 while ((errtext = ctf_errwarning_next (ctf, &it, &is_warning)) != NULL)
14295 {
14296 error (_("%s: `%s'\n"), is_warning ? _("warning"): _("error"),
14297 errtext);
14298 free (errtext);
14299 }
14300 if (ctf_errno (ctf) != ECTF_NEXT_END)
14301 {
14302 error (_("CTF error: cannot get CTF errors: `%s'\n"),
14303 ctf_errmsg (ctf_errno (ctf)));
14304 }
14305 return err;
2f6ecaed
NA
14306}
14307
7d9813f1
NA
14308static bfd_boolean
14309dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14310{
14311 Elf_Internal_Shdr * parent_sec = NULL;
14312 Elf_Internal_Shdr * symtab_sec = NULL;
14313 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14314 void * data = NULL;
14315 void * symdata = NULL;
14316 void * strdata = NULL;
14317 void * parentdata = NULL;
14318 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14319 ctf_sect_t * symsectp = NULL;
14320 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
14321 ctf_archive_t * ctfa = NULL;
14322 ctf_archive_t * parenta = NULL, *lookparent;
14323 ctf_file_t * parent = NULL;
7d9813f1 14324
7d9813f1
NA
14325 int err;
14326 bfd_boolean ret = FALSE;
7d9813f1
NA
14327
14328 shdr_to_ctf_sect (&ctfsect, section, filedata);
14329 data = get_section_contents (section, filedata);
14330 ctfsect.cts_data = data;
14331
616febde
NA
14332 if (!dump_ctf_symtab_name)
14333 dump_ctf_symtab_name = strdup (".symtab");
14334
14335 if (!dump_ctf_strtab_name)
14336 dump_ctf_strtab_name = strdup (".strtab");
14337
14338 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14339 {
14340 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14341 {
14342 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14343 goto fail;
14344 }
14345 if ((symdata = (void *) get_data (NULL, filedata,
14346 symtab_sec->sh_offset, 1,
14347 symtab_sec->sh_size,
14348 _("symbols"))) == NULL)
14349 goto fail;
14350 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14351 symsect.cts_data = symdata;
14352 }
df16e041 14353 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
14354 {
14355 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14356 {
14357 error (_("No string table section named %s\n"),
14358 dump_ctf_strtab_name);
14359 goto fail;
14360 }
14361 if ((strdata = (void *) get_data (NULL, filedata,
14362 strtab_sec->sh_offset, 1,
14363 strtab_sec->sh_size,
14364 _("strings"))) == NULL)
14365 goto fail;
14366 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14367 strsect.cts_data = strdata;
14368 }
14369 if (dump_ctf_parent_name)
14370 {
14371 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14372 {
14373 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14374 goto fail;
14375 }
14376 if ((parentdata = (void *) get_data (NULL, filedata,
14377 parent_sec->sh_offset, 1,
14378 parent_sec->sh_size,
14379 _("CTF parent"))) == NULL)
14380 goto fail;
14381 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14382 parentsect.cts_data = parentdata;
14383 }
14384
2f6ecaed
NA
14385 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
14386 libctf papers over the difference, so we can pretend it is always an
14387 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 14388
2f6ecaed 14389 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1
NA
14390 {
14391 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14392 goto fail;
14393 }
14394
14395 if (parentdata)
14396 {
2f6ecaed
NA
14397 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
14398 &err)) == NULL)
7d9813f1
NA
14399 {
14400 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14401 goto fail;
14402 }
2f6ecaed
NA
14403 lookparent = parenta;
14404 }
14405 else
14406 lookparent = ctfa;
7d9813f1 14407
2f6ecaed
NA
14408 /* Assume that the applicable parent archive member is the default one.
14409 (This is what all known implementations are expected to do, if they
14410 put CTFs and their parents in archives together.) */
14411 if ((parent = ctf_arc_open_by_name (lookparent, NULL, &err)) == NULL)
14412 {
14413 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14414 goto fail;
7d9813f1
NA
14415 }
14416
14417 ret = TRUE;
14418
14419 printf (_("\nDump of CTF section '%s':\n"),
14420 printable_section_name (filedata, section));
14421
2f6ecaed
NA
14422 if (ctf_archive_iter (ctfa, dump_ctf_archive_member, parent) != 0)
14423 ret = FALSE;
7d9813f1
NA
14424
14425 fail:
7d9813f1 14426 ctf_file_close (parent);
2f6ecaed
NA
14427 ctf_close (ctfa);
14428 ctf_close (parenta);
7d9813f1
NA
14429 free (parentdata);
14430 free (data);
14431 free (symdata);
14432 free (strdata);
14433 return ret;
14434}
094e34f2 14435#endif
7d9813f1 14436
32ec8896 14437static bfd_boolean
dda8d76d
NC
14438load_specific_debug_section (enum dwarf_section_display_enum debug,
14439 const Elf_Internal_Shdr * sec,
14440 void * data)
1007acb3 14441{
2cf0635d 14442 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 14443 char buf [64];
dda8d76d 14444 Filedata * filedata = (Filedata *) data;
9abca702 14445
19e6b90e 14446 if (section->start != NULL)
dda8d76d
NC
14447 {
14448 /* If it is already loaded, do nothing. */
14449 if (streq (section->filename, filedata->file_name))
14450 return TRUE;
14451 free (section->start);
14452 }
1007acb3 14453
19e6b90e
L
14454 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
14455 section->address = sec->sh_addr;
06614111 14456 section->user_data = NULL;
dda8d76d
NC
14457 section->filename = filedata->file_name;
14458 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
14459 sec->sh_offset, 1,
14460 sec->sh_size, buf);
59245841
NC
14461 if (section->start == NULL)
14462 section->size = 0;
14463 else
14464 {
77115a4a
L
14465 unsigned char *start = section->start;
14466 dwarf_size_type size = sec->sh_size;
dab394de 14467 dwarf_size_type uncompressed_size = 0;
77115a4a
L
14468
14469 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
14470 {
14471 Elf_Internal_Chdr chdr;
d8024a91
NC
14472 unsigned int compression_header_size;
14473
f53be977
L
14474 if (size < (is_32bit_elf
14475 ? sizeof (Elf32_External_Chdr)
14476 : sizeof (Elf64_External_Chdr)))
d8024a91 14477 {
55be8fd0 14478 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 14479 section->name);
32ec8896 14480 return FALSE;
d8024a91
NC
14481 }
14482
ebdf1ebf 14483 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
14484 if (compression_header_size == 0)
14485 /* An error message will have already been generated
14486 by get_compression_header. */
14487 return FALSE;
d8024a91 14488
813dabb9
L
14489 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
14490 {
14491 warn (_("section '%s' has unsupported compress type: %d\n"),
14492 section->name, chdr.ch_type);
32ec8896 14493 return FALSE;
813dabb9 14494 }
dab394de 14495 uncompressed_size = chdr.ch_size;
77115a4a
L
14496 start += compression_header_size;
14497 size -= compression_header_size;
14498 }
dab394de
L
14499 else if (size > 12 && streq ((char *) start, "ZLIB"))
14500 {
14501 /* Read the zlib header. In this case, it should be "ZLIB"
14502 followed by the uncompressed section size, 8 bytes in
14503 big-endian order. */
14504 uncompressed_size = start[4]; uncompressed_size <<= 8;
14505 uncompressed_size += start[5]; uncompressed_size <<= 8;
14506 uncompressed_size += start[6]; uncompressed_size <<= 8;
14507 uncompressed_size += start[7]; uncompressed_size <<= 8;
14508 uncompressed_size += start[8]; uncompressed_size <<= 8;
14509 uncompressed_size += start[9]; uncompressed_size <<= 8;
14510 uncompressed_size += start[10]; uncompressed_size <<= 8;
14511 uncompressed_size += start[11];
14512 start += 12;
14513 size -= 12;
14514 }
14515
1835f746 14516 if (uncompressed_size)
77115a4a 14517 {
1835f746
NC
14518 if (uncompress_section_contents (&start, uncompressed_size,
14519 &size))
14520 {
14521 /* Free the compressed buffer, update the section buffer
14522 and the section size if uncompress is successful. */
14523 free (section->start);
14524 section->start = start;
14525 }
14526 else
14527 {
14528 error (_("Unable to decompress section %s\n"),
dda8d76d 14529 printable_section_name (filedata, sec));
32ec8896 14530 return FALSE;
1835f746 14531 }
77115a4a 14532 }
bc303e5d 14533
77115a4a 14534 section->size = size;
59245841 14535 }
4a114e3e 14536
1b315056 14537 if (section->start == NULL)
32ec8896 14538 return FALSE;
1b315056 14539
19e6b90e 14540 if (debug_displays [debug].relocate)
32ec8896 14541 {
dda8d76d 14542 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
14543 & section->reloc_info, & section->num_relocs))
14544 return FALSE;
14545 }
d1c4b12b
NC
14546 else
14547 {
14548 section->reloc_info = NULL;
14549 section->num_relocs = 0;
14550 }
1007acb3 14551
32ec8896 14552 return TRUE;
1007acb3
L
14553}
14554
301a9420
AM
14555#if HAVE_LIBDEBUGINFOD
14556/* Return a hex string representation of the build-id. */
14557unsigned char *
14558get_build_id (void * data)
14559{
14560 Filedata * filedata = (Filedata *)data;
14561 Elf_Internal_Shdr * shdr;
14562 unsigned long i;
14563
55be8fd0
NC
14564 /* Iterate through notes to find note.gnu.build-id.
14565 FIXME: Only the first note in any note section is examined. */
301a9420
AM
14566 for (i = 0, shdr = filedata->section_headers;
14567 i < filedata->file_header.e_shnum && shdr != NULL;
14568 i++, shdr++)
14569 {
14570 if (shdr->sh_type != SHT_NOTE)
14571 continue;
14572
14573 char * next;
14574 char * end;
14575 size_t data_remaining;
14576 size_t min_notesz;
14577 Elf_External_Note * enote;
14578 Elf_Internal_Note inote;
14579
14580 bfd_vma offset = shdr->sh_offset;
14581 bfd_vma align = shdr->sh_addralign;
14582 bfd_vma length = shdr->sh_size;
14583
14584 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
14585 if (enote == NULL)
14586 continue;
14587
14588 if (align < 4)
14589 align = 4;
14590 else if (align != 4 && align != 8)
f761cb13
AM
14591 {
14592 free (enote);
14593 continue;
14594 }
301a9420
AM
14595
14596 end = (char *) enote + length;
14597 data_remaining = end - (char *) enote;
14598
14599 if (!is_ia64_vms (filedata))
14600 {
14601 min_notesz = offsetof (Elf_External_Note, name);
14602 if (data_remaining < min_notesz)
14603 {
55be8fd0
NC
14604 warn (_("\
14605malformed note encountered in section %s whilst scanning for build-id note\n"),
14606 printable_section_name (filedata, shdr));
f761cb13 14607 free (enote);
55be8fd0 14608 continue;
301a9420
AM
14609 }
14610 data_remaining -= min_notesz;
14611
14612 inote.type = BYTE_GET (enote->type);
14613 inote.namesz = BYTE_GET (enote->namesz);
14614 inote.namedata = enote->name;
14615 inote.descsz = BYTE_GET (enote->descsz);
14616 inote.descdata = ((char *) enote
14617 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
14618 inote.descpos = offset + (inote.descdata - (char *) enote);
14619 next = ((char *) enote
14620 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
14621 }
14622 else
14623 {
14624 Elf64_External_VMS_Note *vms_enote;
14625
14626 /* PR binutils/15191
14627 Make sure that there is enough data to read. */
14628 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14629 if (data_remaining < min_notesz)
14630 {
55be8fd0
NC
14631 warn (_("\
14632malformed note encountered in section %s whilst scanning for build-id note\n"),
14633 printable_section_name (filedata, shdr));
f761cb13 14634 free (enote);
55be8fd0 14635 continue;
301a9420
AM
14636 }
14637 data_remaining -= min_notesz;
14638
14639 vms_enote = (Elf64_External_VMS_Note *) enote;
14640 inote.type = BYTE_GET (vms_enote->type);
14641 inote.namesz = BYTE_GET (vms_enote->namesz);
14642 inote.namedata = vms_enote->name;
14643 inote.descsz = BYTE_GET (vms_enote->descsz);
14644 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14645 inote.descpos = offset + (inote.descdata - (char *) enote);
14646 next = inote.descdata + align_power (inote.descsz, 3);
14647 }
14648
14649 /* Skip malformed notes. */
14650 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
14651 || (size_t) (inote.descdata - inote.namedata) > data_remaining
14652 || (size_t) (next - inote.descdata) < inote.descsz
14653 || ((size_t) (next - inote.descdata)
14654 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
14655 {
55be8fd0
NC
14656 warn (_("\
14657malformed note encountered in section %s whilst scanning for build-id note\n"),
14658 printable_section_name (filedata, shdr));
f761cb13 14659 free (enote);
301a9420
AM
14660 continue;
14661 }
14662
14663 /* Check if this is the build-id note. If so then convert the build-id
14664 bytes to a hex string. */
14665 if (inote.namesz > 0
14666 && const_strneq (inote.namedata, "GNU")
14667 && inote.type == NT_GNU_BUILD_ID)
14668 {
14669 unsigned long j;
14670 char * build_id;
14671
14672 build_id = malloc (inote.descsz * 2 + 1);
14673 if (build_id == NULL)
f761cb13
AM
14674 {
14675 free (enote);
14676 return NULL;
14677 }
301a9420
AM
14678
14679 for (j = 0; j < inote.descsz; ++j)
14680 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
14681 build_id[inote.descsz * 2] = '\0';
f761cb13 14682 free (enote);
301a9420 14683
55be8fd0 14684 return (unsigned char *) build_id;
301a9420 14685 }
f761cb13 14686 free (enote);
301a9420
AM
14687 }
14688
14689 return NULL;
14690}
14691#endif /* HAVE_LIBDEBUGINFOD */
14692
657d0d47
CC
14693/* If this is not NULL, load_debug_section will only look for sections
14694 within the list of sections given here. */
32ec8896 14695static unsigned int * section_subset = NULL;
657d0d47 14696
32ec8896 14697bfd_boolean
dda8d76d 14698load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 14699{
2cf0635d
NC
14700 struct dwarf_section * section = &debug_displays [debug].section;
14701 Elf_Internal_Shdr * sec;
dda8d76d
NC
14702 Filedata * filedata = (Filedata *) data;
14703
f425ec66
NC
14704 /* Without section headers we cannot find any sections. */
14705 if (filedata->section_headers == NULL)
14706 return FALSE;
14707
9c1ce108
AM
14708 if (filedata->string_table == NULL
14709 && filedata->file_header.e_shstrndx != SHN_UNDEF
14710 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
14711 {
14712 Elf_Internal_Shdr * strs;
14713
14714 /* Read in the string table, so that we have section names to scan. */
14715 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
14716
4dff97b2 14717 if (strs != NULL && strs->sh_size != 0)
dda8d76d 14718 {
9c1ce108
AM
14719 filedata->string_table
14720 = (char *) get_data (NULL, filedata, strs->sh_offset,
14721 1, strs->sh_size, _("string table"));
dda8d76d 14722
9c1ce108
AM
14723 filedata->string_table_length
14724 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
14725 }
14726 }
d966045b
DJ
14727
14728 /* Locate the debug section. */
dda8d76d 14729 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
14730 if (sec != NULL)
14731 section->name = section->uncompressed_name;
14732 else
14733 {
dda8d76d 14734 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
14735 if (sec != NULL)
14736 section->name = section->compressed_name;
14737 }
14738 if (sec == NULL)
32ec8896 14739 return FALSE;
d966045b 14740
657d0d47
CC
14741 /* If we're loading from a subset of sections, and we've loaded
14742 a section matching this name before, it's likely that it's a
14743 different one. */
14744 if (section_subset != NULL)
14745 free_debug_section (debug);
14746
dda8d76d 14747 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
14748}
14749
19e6b90e
L
14750void
14751free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 14752{
2cf0635d 14753 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 14754
19e6b90e
L
14755 if (section->start == NULL)
14756 return;
1007acb3 14757
19e6b90e
L
14758 free ((char *) section->start);
14759 section->start = NULL;
14760 section->address = 0;
14761 section->size = 0;
a788aedd 14762
9db70fc3
AM
14763 free (section->reloc_info);
14764 section->reloc_info = NULL;
14765 section->num_relocs = 0;
1007acb3
L
14766}
14767
32ec8896 14768static bfd_boolean
dda8d76d 14769display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 14770{
2cf0635d 14771 char * name = SECTION_NAME (section);
dda8d76d 14772 const char * print_name = printable_section_name (filedata, section);
19e6b90e 14773 bfd_size_type length;
32ec8896 14774 bfd_boolean result = TRUE;
3f5e193b 14775 int i;
1007acb3 14776
19e6b90e
L
14777 length = section->sh_size;
14778 if (length == 0)
1007acb3 14779 {
74e1a04b 14780 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 14781 return TRUE;
1007acb3 14782 }
5dff79d8
NC
14783 if (section->sh_type == SHT_NOBITS)
14784 {
14785 /* There is no point in dumping the contents of a debugging section
14786 which has the NOBITS type - the bits in the file will be random.
14787 This can happen when a file containing a .eh_frame section is
14788 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
14789 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
14790 print_name);
32ec8896 14791 return FALSE;
5dff79d8 14792 }
1007acb3 14793
0112cd26 14794 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 14795 name = ".debug_info";
1007acb3 14796
19e6b90e
L
14797 /* See if we know how to display the contents of this section. */
14798 for (i = 0; i < max; i++)
d85bf2ba
NC
14799 {
14800 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
14801 struct dwarf_section_display * display = debug_displays + i;
14802 struct dwarf_section * sec = & display->section;
d966045b 14803
d85bf2ba
NC
14804 if (streq (sec->uncompressed_name, name)
14805 || (id == line && const_strneq (name, ".debug_line."))
14806 || streq (sec->compressed_name, name))
14807 {
14808 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 14809
d85bf2ba
NC
14810 if (secondary)
14811 free_debug_section (id);
dda8d76d 14812
d85bf2ba
NC
14813 if (i == line && const_strneq (name, ".debug_line."))
14814 sec->name = name;
14815 else if (streq (sec->uncompressed_name, name))
14816 sec->name = sec->uncompressed_name;
14817 else
14818 sec->name = sec->compressed_name;
657d0d47 14819
d85bf2ba
NC
14820 if (load_specific_debug_section (id, section, filedata))
14821 {
14822 /* If this debug section is part of a CU/TU set in a .dwp file,
14823 restrict load_debug_section to the sections in that set. */
14824 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 14825
d85bf2ba 14826 result &= display->display (sec, filedata);
657d0d47 14827
d85bf2ba 14828 section_subset = NULL;
1007acb3 14829
d85bf2ba
NC
14830 if (secondary || (id != info && id != abbrev))
14831 free_debug_section (id);
14832 }
14833 break;
14834 }
14835 }
1007acb3 14836
19e6b90e 14837 if (i == max)
1007acb3 14838 {
74e1a04b 14839 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 14840 result = FALSE;
1007acb3
L
14841 }
14842
19e6b90e 14843 return result;
5b18a4bc 14844}
103f02d3 14845
aef1f6d0
DJ
14846/* Set DUMP_SECTS for all sections where dumps were requested
14847 based on section name. */
14848
14849static void
dda8d76d 14850initialise_dumps_byname (Filedata * filedata)
aef1f6d0 14851{
2cf0635d 14852 struct dump_list_entry * cur;
aef1f6d0
DJ
14853
14854 for (cur = dump_sects_byname; cur; cur = cur->next)
14855 {
14856 unsigned int i;
32ec8896 14857 bfd_boolean any = FALSE;
aef1f6d0 14858
dda8d76d
NC
14859 for (i = 0; i < filedata->file_header.e_shnum; i++)
14860 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 14861 {
6431e409 14862 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 14863 any = TRUE;
aef1f6d0
DJ
14864 }
14865
14866 if (!any)
14867 warn (_("Section '%s' was not dumped because it does not exist!\n"),
14868 cur->name);
14869 }
14870}
14871
32ec8896 14872static bfd_boolean
dda8d76d 14873process_section_contents (Filedata * filedata)
5b18a4bc 14874{
2cf0635d 14875 Elf_Internal_Shdr * section;
19e6b90e 14876 unsigned int i;
32ec8896 14877 bfd_boolean res = TRUE;
103f02d3 14878
19e6b90e 14879 if (! do_dump)
32ec8896 14880 return TRUE;
103f02d3 14881
dda8d76d 14882 initialise_dumps_byname (filedata);
aef1f6d0 14883
dda8d76d 14884 for (i = 0, section = filedata->section_headers;
6431e409 14885 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
14886 i++, section++)
14887 {
6431e409 14888 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 14889
19e6b90e 14890#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
14891 if (dump & DISASS_DUMP)
14892 {
14893 if (! disassemble_section (section, filedata))
14894 res = FALSE;
14895 }
19e6b90e 14896#endif
dda8d76d 14897 if (dump & HEX_DUMP)
32ec8896 14898 {
dda8d76d 14899 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
14900 res = FALSE;
14901 }
103f02d3 14902
dda8d76d 14903 if (dump & RELOC_DUMP)
32ec8896 14904 {
dda8d76d 14905 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
14906 res = FALSE;
14907 }
09c11c86 14908
dda8d76d 14909 if (dump & STRING_DUMP)
32ec8896 14910 {
dda8d76d 14911 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
14912 res = FALSE;
14913 }
cf13d699 14914
dda8d76d 14915 if (dump & DEBUG_DUMP)
32ec8896 14916 {
dda8d76d 14917 if (! display_debug_section (i, section, filedata))
32ec8896
NC
14918 res = FALSE;
14919 }
7d9813f1 14920
094e34f2 14921#ifdef ENABLE_LIBCTF
7d9813f1
NA
14922 if (dump & CTF_DUMP)
14923 {
14924 if (! dump_section_as_ctf (section, filedata))
14925 res = FALSE;
14926 }
094e34f2 14927#endif
5b18a4bc 14928 }
103f02d3 14929
19e6b90e
L
14930 /* Check to see if the user requested a
14931 dump of a section that does not exist. */
6431e409 14932 while (i < filedata->dump.num_dump_sects)
0ee3043f 14933 {
6431e409 14934 if (filedata->dump.dump_sects[i])
32ec8896
NC
14935 {
14936 warn (_("Section %d was not dumped because it does not exist!\n"), i);
14937 res = FALSE;
14938 }
0ee3043f
NC
14939 i++;
14940 }
32ec8896
NC
14941
14942 return res;
5b18a4bc 14943}
103f02d3 14944
5b18a4bc 14945static void
19e6b90e 14946process_mips_fpe_exception (int mask)
5b18a4bc 14947{
19e6b90e
L
14948 if (mask)
14949 {
32ec8896
NC
14950 bfd_boolean first = TRUE;
14951
19e6b90e 14952 if (mask & OEX_FPU_INEX)
32ec8896 14953 fputs ("INEX", stdout), first = FALSE;
19e6b90e 14954 if (mask & OEX_FPU_UFLO)
32ec8896 14955 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14956 if (mask & OEX_FPU_OFLO)
32ec8896 14957 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14958 if (mask & OEX_FPU_DIV0)
32ec8896 14959 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
14960 if (mask & OEX_FPU_INVAL)
14961 printf ("%sINVAL", first ? "" : "|");
14962 }
5b18a4bc 14963 else
19e6b90e 14964 fputs ("0", stdout);
5b18a4bc 14965}
103f02d3 14966
f6f0e17b
NC
14967/* Display's the value of TAG at location P. If TAG is
14968 greater than 0 it is assumed to be an unknown tag, and
14969 a message is printed to this effect. Otherwise it is
14970 assumed that a message has already been printed.
14971
14972 If the bottom bit of TAG is set it assumed to have a
14973 string value, otherwise it is assumed to have an integer
14974 value.
14975
14976 Returns an updated P pointing to the first unread byte
14977 beyond the end of TAG's value.
14978
14979 Reads at or beyond END will not be made. */
14980
14981static unsigned char *
60abdbed 14982display_tag_value (signed int tag,
f6f0e17b
NC
14983 unsigned char * p,
14984 const unsigned char * const end)
14985{
14986 unsigned long val;
14987
14988 if (tag > 0)
14989 printf (" Tag_unknown_%d: ", tag);
14990
14991 if (p >= end)
14992 {
4082ef84 14993 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
14994 }
14995 else if (tag & 1)
14996 {
071436c6
NC
14997 /* PR 17531 file: 027-19978-0.004. */
14998 size_t maxlen = (end - p) - 1;
14999
15000 putchar ('"');
4082ef84
NC
15001 if (maxlen > 0)
15002 {
15003 print_symbol ((int) maxlen, (const char *) p);
15004 p += strnlen ((char *) p, maxlen) + 1;
15005 }
15006 else
15007 {
15008 printf (_("<corrupt string tag>"));
15009 p = (unsigned char *) end;
15010 }
071436c6 15011 printf ("\"\n");
f6f0e17b
NC
15012 }
15013 else
15014 {
cd30bcef 15015 READ_ULEB (val, p, end);
f6f0e17b
NC
15016 printf ("%ld (0x%lx)\n", val, val);
15017 }
15018
4082ef84 15019 assert (p <= end);
f6f0e17b
NC
15020 return p;
15021}
15022
53a346d8
CZ
15023/* ARC ABI attributes section. */
15024
15025static unsigned char *
15026display_arc_attribute (unsigned char * p,
15027 const unsigned char * const end)
15028{
15029 unsigned int tag;
53a346d8
CZ
15030 unsigned int val;
15031
cd30bcef 15032 READ_ULEB (tag, p, end);
53a346d8
CZ
15033
15034 switch (tag)
15035 {
15036 case Tag_ARC_PCS_config:
cd30bcef 15037 READ_ULEB (val, p, end);
53a346d8
CZ
15038 printf (" Tag_ARC_PCS_config: ");
15039 switch (val)
15040 {
15041 case 0:
15042 printf (_("Absent/Non standard\n"));
15043 break;
15044 case 1:
15045 printf (_("Bare metal/mwdt\n"));
15046 break;
15047 case 2:
15048 printf (_("Bare metal/newlib\n"));
15049 break;
15050 case 3:
15051 printf (_("Linux/uclibc\n"));
15052 break;
15053 case 4:
15054 printf (_("Linux/glibc\n"));
15055 break;
15056 default:
15057 printf (_("Unknown\n"));
15058 break;
15059 }
15060 break;
15061
15062 case Tag_ARC_CPU_base:
cd30bcef 15063 READ_ULEB (val, p, end);
53a346d8
CZ
15064 printf (" Tag_ARC_CPU_base: ");
15065 switch (val)
15066 {
15067 default:
15068 case TAG_CPU_NONE:
15069 printf (_("Absent\n"));
15070 break;
15071 case TAG_CPU_ARC6xx:
15072 printf ("ARC6xx\n");
15073 break;
15074 case TAG_CPU_ARC7xx:
15075 printf ("ARC7xx\n");
15076 break;
15077 case TAG_CPU_ARCEM:
15078 printf ("ARCEM\n");
15079 break;
15080 case TAG_CPU_ARCHS:
15081 printf ("ARCHS\n");
15082 break;
15083 }
15084 break;
15085
15086 case Tag_ARC_CPU_variation:
cd30bcef 15087 READ_ULEB (val, p, end);
53a346d8
CZ
15088 printf (" Tag_ARC_CPU_variation: ");
15089 switch (val)
15090 {
15091 default:
15092 if (val > 0 && val < 16)
53a346d8 15093 printf ("Core%d\n", val);
d8cbc93b
JL
15094 else
15095 printf ("Unknown\n");
15096 break;
15097
53a346d8
CZ
15098 case 0:
15099 printf (_("Absent\n"));
15100 break;
15101 }
15102 break;
15103
15104 case Tag_ARC_CPU_name:
15105 printf (" Tag_ARC_CPU_name: ");
15106 p = display_tag_value (-1, p, end);
15107 break;
15108
15109 case Tag_ARC_ABI_rf16:
cd30bcef 15110 READ_ULEB (val, p, end);
53a346d8
CZ
15111 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15112 break;
15113
15114 case Tag_ARC_ABI_osver:
cd30bcef 15115 READ_ULEB (val, p, end);
53a346d8
CZ
15116 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15117 break;
15118
15119 case Tag_ARC_ABI_pic:
15120 case Tag_ARC_ABI_sda:
cd30bcef 15121 READ_ULEB (val, p, end);
53a346d8
CZ
15122 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15123 : " Tag_ARC_ABI_pic: ");
15124 switch (val)
15125 {
15126 case 0:
15127 printf (_("Absent\n"));
15128 break;
15129 case 1:
15130 printf ("MWDT\n");
15131 break;
15132 case 2:
15133 printf ("GNU\n");
15134 break;
15135 default:
15136 printf (_("Unknown\n"));
15137 break;
15138 }
15139 break;
15140
15141 case Tag_ARC_ABI_tls:
cd30bcef 15142 READ_ULEB (val, p, end);
53a346d8
CZ
15143 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15144 break;
15145
15146 case Tag_ARC_ABI_enumsize:
cd30bcef 15147 READ_ULEB (val, p, end);
53a346d8
CZ
15148 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15149 _("smallest"));
15150 break;
15151
15152 case Tag_ARC_ABI_exceptions:
cd30bcef 15153 READ_ULEB (val, p, end);
53a346d8
CZ
15154 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15155 : _("default"));
15156 break;
15157
15158 case Tag_ARC_ABI_double_size:
cd30bcef 15159 READ_ULEB (val, p, end);
53a346d8
CZ
15160 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15161 break;
15162
15163 case Tag_ARC_ISA_config:
15164 printf (" Tag_ARC_ISA_config: ");
15165 p = display_tag_value (-1, p, end);
15166 break;
15167
15168 case Tag_ARC_ISA_apex:
15169 printf (" Tag_ARC_ISA_apex: ");
15170 p = display_tag_value (-1, p, end);
15171 break;
15172
15173 case Tag_ARC_ISA_mpy_option:
cd30bcef 15174 READ_ULEB (val, p, end);
53a346d8
CZ
15175 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15176 break;
15177
db1e1b45 15178 case Tag_ARC_ATR_version:
cd30bcef 15179 READ_ULEB (val, p, end);
db1e1b45 15180 printf (" Tag_ARC_ATR_version: %d\n", val);
15181 break;
15182
53a346d8
CZ
15183 default:
15184 return display_tag_value (tag & 1, p, end);
15185 }
15186
15187 return p;
15188}
15189
11c1ff18
PB
15190/* ARM EABI attributes section. */
15191typedef struct
15192{
70e99720 15193 unsigned int tag;
2cf0635d 15194 const char * name;
11c1ff18 15195 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15196 unsigned int type;
2cf0635d 15197 const char ** table;
11c1ff18
PB
15198} arm_attr_public_tag;
15199
2cf0635d 15200static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 15201 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15202 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15203 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
2cf0635d
NC
15204static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15205static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15206 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 15207static const char * arm_attr_tag_FP_arch[] =
bca38921 15208 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15209 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 15210static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 15211static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15212 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15213 "NEON for ARMv8.1"};
2cf0635d 15214static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
15215 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15216 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 15217static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15218 {"V6", "SB", "TLS", "Unused"};
2cf0635d 15219static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15220 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 15221static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15222 {"Absolute", "PC-relative", "None"};
2cf0635d 15223static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15224 {"None", "direct", "GOT-indirect"};
2cf0635d 15225static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15226 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
15227static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15228static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15229 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
15230static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15231static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15232static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15233 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 15234static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 15235 {"Unused", "small", "int", "forced to int"};
2cf0635d 15236static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15237 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 15238static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 15239 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 15240static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15241 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 15242static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15243 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15244 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 15245static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15246 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15247 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 15248static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 15249static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 15250 {"Not Allowed", "Allowed"};
2cf0635d 15251static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15252 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
15253static const char * arm_attr_tag_DSP_extension[] =
15254 {"Follow architecture", "Allowed"};
dd24e3da 15255static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
15256 {"Not Allowed", "Allowed"};
15257static const char * arm_attr_tag_DIV_use[] =
dd24e3da 15258 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15259 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
15260static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15261static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 15262 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15263 "TrustZone and Virtualization Extensions"};
dd24e3da 15264static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15265 {"Not Allowed", "Allowed"};
11c1ff18 15266
a7ad558c
AV
15267static const char * arm_attr_tag_MVE_arch[] =
15268 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15269
11c1ff18
PB
15270#define LOOKUP(id, name) \
15271 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15272static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15273{
15274 {4, "CPU_raw_name", 1, NULL},
15275 {5, "CPU_name", 1, NULL},
15276 LOOKUP(6, CPU_arch),
15277 {7, "CPU_arch_profile", 0, NULL},
15278 LOOKUP(8, ARM_ISA_use),
15279 LOOKUP(9, THUMB_ISA_use),
75375b3e 15280 LOOKUP(10, FP_arch),
11c1ff18 15281 LOOKUP(11, WMMX_arch),
f5f53991
AS
15282 LOOKUP(12, Advanced_SIMD_arch),
15283 LOOKUP(13, PCS_config),
11c1ff18
PB
15284 LOOKUP(14, ABI_PCS_R9_use),
15285 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15286 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15287 LOOKUP(17, ABI_PCS_GOT_use),
15288 LOOKUP(18, ABI_PCS_wchar_t),
15289 LOOKUP(19, ABI_FP_rounding),
15290 LOOKUP(20, ABI_FP_denormal),
15291 LOOKUP(21, ABI_FP_exceptions),
15292 LOOKUP(22, ABI_FP_user_exceptions),
15293 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15294 {24, "ABI_align_needed", 0, NULL},
15295 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15296 LOOKUP(26, ABI_enum_size),
15297 LOOKUP(27, ABI_HardFP_use),
15298 LOOKUP(28, ABI_VFP_args),
15299 LOOKUP(29, ABI_WMMX_args),
15300 LOOKUP(30, ABI_optimization_goals),
15301 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15302 {32, "compatibility", 0, NULL},
f5f53991 15303 LOOKUP(34, CPU_unaligned_access),
75375b3e 15304 LOOKUP(36, FP_HP_extension),
8e79c3df 15305 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15306 LOOKUP(42, MPextension_use),
15307 LOOKUP(44, DIV_use),
15afaa63 15308 LOOKUP(46, DSP_extension),
a7ad558c 15309 LOOKUP(48, MVE_arch),
f5f53991
AS
15310 {64, "nodefaults", 0, NULL},
15311 {65, "also_compatible_with", 0, NULL},
15312 LOOKUP(66, T2EE_use),
15313 {67, "conformance", 1, NULL},
15314 LOOKUP(68, Virtualization_use),
cd21e546 15315 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15316};
15317#undef LOOKUP
15318
11c1ff18 15319static unsigned char *
f6f0e17b
NC
15320display_arm_attribute (unsigned char * p,
15321 const unsigned char * const end)
11c1ff18 15322{
70e99720 15323 unsigned int tag;
70e99720 15324 unsigned int val;
2cf0635d 15325 arm_attr_public_tag * attr;
11c1ff18 15326 unsigned i;
70e99720 15327 unsigned int type;
11c1ff18 15328
cd30bcef 15329 READ_ULEB (tag, p, end);
11c1ff18 15330 attr = NULL;
2cf0635d 15331 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15332 {
15333 if (arm_attr_public_tags[i].tag == tag)
15334 {
15335 attr = &arm_attr_public_tags[i];
15336 break;
15337 }
15338 }
15339
15340 if (attr)
15341 {
15342 printf (" Tag_%s: ", attr->name);
15343 switch (attr->type)
15344 {
15345 case 0:
15346 switch (tag)
15347 {
15348 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15349 READ_ULEB (val, p, end);
11c1ff18
PB
15350 switch (val)
15351 {
2b692964
NC
15352 case 0: printf (_("None\n")); break;
15353 case 'A': printf (_("Application\n")); break;
15354 case 'R': printf (_("Realtime\n")); break;
15355 case 'M': printf (_("Microcontroller\n")); break;
15356 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15357 default: printf ("??? (%d)\n", val); break;
15358 }
15359 break;
15360
75375b3e 15361 case 24: /* Tag_align_needed. */
cd30bcef 15362 READ_ULEB (val, p, end);
75375b3e
MGD
15363 switch (val)
15364 {
2b692964
NC
15365 case 0: printf (_("None\n")); break;
15366 case 1: printf (_("8-byte\n")); break;
15367 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15368 case 3: printf ("??? 3\n"); break;
15369 default:
15370 if (val <= 12)
dd24e3da 15371 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15372 1 << val);
15373 else
15374 printf ("??? (%d)\n", val);
15375 break;
15376 }
15377 break;
15378
15379 case 25: /* Tag_align_preserved. */
cd30bcef 15380 READ_ULEB (val, p, end);
75375b3e
MGD
15381 switch (val)
15382 {
2b692964
NC
15383 case 0: printf (_("None\n")); break;
15384 case 1: printf (_("8-byte, except leaf SP\n")); break;
15385 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
15386 case 3: printf ("??? 3\n"); break;
15387 default:
15388 if (val <= 12)
dd24e3da 15389 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15390 1 << val);
15391 else
15392 printf ("??? (%d)\n", val);
15393 break;
15394 }
15395 break;
15396
11c1ff18 15397 case 32: /* Tag_compatibility. */
071436c6 15398 {
cd30bcef 15399 READ_ULEB (val, p, end);
071436c6 15400 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15401 if (p < end - 1)
15402 {
15403 size_t maxlen = (end - p) - 1;
15404
15405 print_symbol ((int) maxlen, (const char *) p);
15406 p += strnlen ((char *) p, maxlen) + 1;
15407 }
15408 else
15409 {
15410 printf (_("<corrupt>"));
15411 p = (unsigned char *) end;
15412 }
071436c6 15413 putchar ('\n');
071436c6 15414 }
11c1ff18
PB
15415 break;
15416
f5f53991 15417 case 64: /* Tag_nodefaults. */
541a3cbd
NC
15418 /* PR 17531: file: 001-505008-0.01. */
15419 if (p < end)
15420 p++;
2b692964 15421 printf (_("True\n"));
f5f53991
AS
15422 break;
15423
15424 case 65: /* Tag_also_compatible_with. */
cd30bcef 15425 READ_ULEB (val, p, end);
f5f53991
AS
15426 if (val == 6 /* Tag_CPU_arch. */)
15427 {
cd30bcef 15428 READ_ULEB (val, p, end);
071436c6 15429 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
15430 printf ("??? (%d)\n", val);
15431 else
15432 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
15433 }
15434 else
15435 printf ("???\n");
071436c6
NC
15436 while (p < end && *(p++) != '\0' /* NUL terminator. */)
15437 ;
f5f53991
AS
15438 break;
15439
11c1ff18 15440 default:
bee0ee85
NC
15441 printf (_("<unknown: %d>\n"), tag);
15442 break;
11c1ff18
PB
15443 }
15444 return p;
15445
15446 case 1:
f6f0e17b 15447 return display_tag_value (-1, p, end);
11c1ff18 15448 case 2:
f6f0e17b 15449 return display_tag_value (0, p, end);
11c1ff18
PB
15450
15451 default:
15452 assert (attr->type & 0x80);
cd30bcef 15453 READ_ULEB (val, p, end);
11c1ff18
PB
15454 type = attr->type & 0x7f;
15455 if (val >= type)
15456 printf ("??? (%d)\n", val);
15457 else
15458 printf ("%s\n", attr->table[val]);
15459 return p;
15460 }
15461 }
11c1ff18 15462
f6f0e17b 15463 return display_tag_value (tag, p, end);
11c1ff18
PB
15464}
15465
104d59d1 15466static unsigned char *
60bca95a 15467display_gnu_attribute (unsigned char * p,
60abdbed 15468 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 15469 const unsigned char * const end)
104d59d1 15470{
cd30bcef 15471 unsigned int tag;
60abdbed 15472 unsigned int val;
104d59d1 15473
cd30bcef 15474 READ_ULEB (tag, p, end);
104d59d1
JM
15475
15476 /* Tag_compatibility is the only generic GNU attribute defined at
15477 present. */
15478 if (tag == 32)
15479 {
cd30bcef 15480 READ_ULEB (val, p, end);
071436c6
NC
15481
15482 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
15483 if (p == end)
15484 {
071436c6 15485 printf (_("<corrupt>\n"));
f6f0e17b
NC
15486 warn (_("corrupt vendor attribute\n"));
15487 }
15488 else
15489 {
4082ef84
NC
15490 if (p < end - 1)
15491 {
15492 size_t maxlen = (end - p) - 1;
071436c6 15493
4082ef84
NC
15494 print_symbol ((int) maxlen, (const char *) p);
15495 p += strnlen ((char *) p, maxlen) + 1;
15496 }
15497 else
15498 {
15499 printf (_("<corrupt>"));
15500 p = (unsigned char *) end;
15501 }
071436c6 15502 putchar ('\n');
f6f0e17b 15503 }
104d59d1
JM
15504 return p;
15505 }
15506
15507 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 15508 return display_proc_gnu_attribute (p, tag, end);
104d59d1 15509
f6f0e17b 15510 return display_tag_value (tag, p, end);
104d59d1
JM
15511}
15512
85f7484a
PB
15513static unsigned char *
15514display_m68k_gnu_attribute (unsigned char * p,
15515 unsigned int tag,
15516 const unsigned char * const end)
15517{
15518 unsigned int val;
15519
15520 if (tag == Tag_GNU_M68K_ABI_FP)
15521 {
15522 printf (" Tag_GNU_M68K_ABI_FP: ");
15523 if (p == end)
15524 {
15525 printf (_("<corrupt>\n"));
15526 return p;
15527 }
15528 READ_ULEB (val, p, end);
15529
15530 if (val > 3)
15531 printf ("(%#x), ", val);
15532
15533 switch (val & 3)
15534 {
15535 case 0:
15536 printf (_("unspecified hard/soft float\n"));
15537 break;
15538 case 1:
15539 printf (_("hard float\n"));
15540 break;
15541 case 2:
15542 printf (_("soft float\n"));
15543 break;
15544 }
15545 return p;
15546 }
15547
15548 return display_tag_value (tag & 1, p, end);
15549}
15550
34c8bcba 15551static unsigned char *
f6f0e17b 15552display_power_gnu_attribute (unsigned char * p,
60abdbed 15553 unsigned int tag,
f6f0e17b 15554 const unsigned char * const end)
34c8bcba 15555{
005d79fd 15556 unsigned int val;
34c8bcba
JM
15557
15558 if (tag == Tag_GNU_Power_ABI_FP)
15559 {
34c8bcba 15560 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 15561 if (p == end)
005d79fd
AM
15562 {
15563 printf (_("<corrupt>\n"));
15564 return p;
15565 }
cd30bcef 15566 READ_ULEB (val, p, end);
60bca95a 15567
005d79fd
AM
15568 if (val > 15)
15569 printf ("(%#x), ", val);
15570
15571 switch (val & 3)
34c8bcba
JM
15572 {
15573 case 0:
005d79fd 15574 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
15575 break;
15576 case 1:
005d79fd 15577 printf (_("hard float, "));
34c8bcba
JM
15578 break;
15579 case 2:
005d79fd 15580 printf (_("soft float, "));
34c8bcba 15581 break;
3c7b9897 15582 case 3:
005d79fd 15583 printf (_("single-precision hard float, "));
3c7b9897 15584 break;
005d79fd
AM
15585 }
15586
15587 switch (val & 0xC)
15588 {
15589 case 0:
15590 printf (_("unspecified long double\n"));
15591 break;
15592 case 4:
15593 printf (_("128-bit IBM long double\n"));
15594 break;
15595 case 8:
15596 printf (_("64-bit long double\n"));
15597 break;
15598 case 12:
15599 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
15600 break;
15601 }
15602 return p;
005d79fd 15603 }
34c8bcba 15604
c6e65352
DJ
15605 if (tag == Tag_GNU_Power_ABI_Vector)
15606 {
c6e65352 15607 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 15608 if (p == end)
005d79fd
AM
15609 {
15610 printf (_("<corrupt>\n"));
15611 return p;
15612 }
cd30bcef 15613 READ_ULEB (val, p, end);
005d79fd
AM
15614
15615 if (val > 3)
15616 printf ("(%#x), ", val);
15617
15618 switch (val & 3)
c6e65352
DJ
15619 {
15620 case 0:
005d79fd 15621 printf (_("unspecified\n"));
c6e65352
DJ
15622 break;
15623 case 1:
005d79fd 15624 printf (_("generic\n"));
c6e65352
DJ
15625 break;
15626 case 2:
15627 printf ("AltiVec\n");
15628 break;
15629 case 3:
15630 printf ("SPE\n");
15631 break;
c6e65352
DJ
15632 }
15633 return p;
005d79fd 15634 }
c6e65352 15635
f82e0623
NF
15636 if (tag == Tag_GNU_Power_ABI_Struct_Return)
15637 {
005d79fd 15638 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 15639 if (p == end)
f6f0e17b 15640 {
005d79fd 15641 printf (_("<corrupt>\n"));
f6f0e17b
NC
15642 return p;
15643 }
cd30bcef 15644 READ_ULEB (val, p, end);
0b4362b0 15645
005d79fd
AM
15646 if (val > 2)
15647 printf ("(%#x), ", val);
15648
15649 switch (val & 3)
15650 {
15651 case 0:
15652 printf (_("unspecified\n"));
15653 break;
15654 case 1:
15655 printf ("r3/r4\n");
15656 break;
15657 case 2:
15658 printf (_("memory\n"));
15659 break;
15660 case 3:
15661 printf ("???\n");
15662 break;
15663 }
f82e0623
NF
15664 return p;
15665 }
15666
f6f0e17b 15667 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
15668}
15669
643f7afb
AK
15670static unsigned char *
15671display_s390_gnu_attribute (unsigned char * p,
60abdbed 15672 unsigned int tag,
643f7afb
AK
15673 const unsigned char * const end)
15674{
cd30bcef 15675 unsigned int val;
643f7afb
AK
15676
15677 if (tag == Tag_GNU_S390_ABI_Vector)
15678 {
643f7afb 15679 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 15680 READ_ULEB (val, p, end);
643f7afb
AK
15681
15682 switch (val)
15683 {
15684 case 0:
15685 printf (_("any\n"));
15686 break;
15687 case 1:
15688 printf (_("software\n"));
15689 break;
15690 case 2:
15691 printf (_("hardware\n"));
15692 break;
15693 default:
15694 printf ("??? (%d)\n", val);
15695 break;
15696 }
15697 return p;
15698 }
15699
15700 return display_tag_value (tag & 1, p, end);
15701}
15702
9e8c70f9 15703static void
60abdbed 15704display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
15705{
15706 if (mask)
15707 {
32ec8896 15708 bfd_boolean first = TRUE;
071436c6 15709
9e8c70f9 15710 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 15711 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 15712 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 15713 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 15714 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 15715 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 15716 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 15717 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 15718 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 15719 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 15720 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 15721 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 15722 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 15723 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 15724 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 15725 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 15726 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 15727 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 15728 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 15729 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 15730 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 15731 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 15732 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 15733 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 15734 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 15735 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 15736 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 15737 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 15738 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 15739 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 15740 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 15741 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
15742 }
15743 else
071436c6
NC
15744 fputc ('0', stdout);
15745 fputc ('\n', stdout);
9e8c70f9
DM
15746}
15747
3d68f91c 15748static void
60abdbed 15749display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
15750{
15751 if (mask)
15752 {
32ec8896 15753 bfd_boolean first = TRUE;
071436c6 15754
3d68f91c 15755 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 15756 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 15757 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 15758 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 15759 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 15760 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 15761 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 15762 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 15763 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 15764 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 15765 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 15766 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 15767 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 15768 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 15769 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 15770 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 15771 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 15772 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 15773 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 15774 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 15775 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 15776 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
15777 }
15778 else
071436c6
NC
15779 fputc ('0', stdout);
15780 fputc ('\n', stdout);
3d68f91c
JM
15781}
15782
9e8c70f9 15783static unsigned char *
f6f0e17b 15784display_sparc_gnu_attribute (unsigned char * p,
60abdbed 15785 unsigned int tag,
f6f0e17b 15786 const unsigned char * const end)
9e8c70f9 15787{
cd30bcef 15788 unsigned int val;
3d68f91c 15789
9e8c70f9
DM
15790 if (tag == Tag_GNU_Sparc_HWCAPS)
15791 {
cd30bcef 15792 READ_ULEB (val, p, end);
9e8c70f9 15793 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
15794 display_sparc_hwcaps (val);
15795 return p;
3d68f91c
JM
15796 }
15797 if (tag == Tag_GNU_Sparc_HWCAPS2)
15798 {
cd30bcef 15799 READ_ULEB (val, p, end);
3d68f91c
JM
15800 printf (" Tag_GNU_Sparc_HWCAPS2: ");
15801 display_sparc_hwcaps2 (val);
15802 return p;
15803 }
9e8c70f9 15804
f6f0e17b 15805 return display_tag_value (tag, p, end);
9e8c70f9
DM
15806}
15807
351cdf24 15808static void
32ec8896 15809print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
15810{
15811 switch (val)
15812 {
15813 case Val_GNU_MIPS_ABI_FP_ANY:
15814 printf (_("Hard or soft float\n"));
15815 break;
15816 case Val_GNU_MIPS_ABI_FP_DOUBLE:
15817 printf (_("Hard float (double precision)\n"));
15818 break;
15819 case Val_GNU_MIPS_ABI_FP_SINGLE:
15820 printf (_("Hard float (single precision)\n"));
15821 break;
15822 case Val_GNU_MIPS_ABI_FP_SOFT:
15823 printf (_("Soft float\n"));
15824 break;
15825 case Val_GNU_MIPS_ABI_FP_OLD_64:
15826 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
15827 break;
15828 case Val_GNU_MIPS_ABI_FP_XX:
15829 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
15830 break;
15831 case Val_GNU_MIPS_ABI_FP_64:
15832 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
15833 break;
15834 case Val_GNU_MIPS_ABI_FP_64A:
15835 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
15836 break;
3350cc01
CM
15837 case Val_GNU_MIPS_ABI_FP_NAN2008:
15838 printf (_("NaN 2008 compatibility\n"));
15839 break;
351cdf24
MF
15840 default:
15841 printf ("??? (%d)\n", val);
15842 break;
15843 }
15844}
15845
2cf19d5c 15846static unsigned char *
f6f0e17b 15847display_mips_gnu_attribute (unsigned char * p,
60abdbed 15848 unsigned int tag,
f6f0e17b 15849 const unsigned char * const end)
2cf19d5c 15850{
2cf19d5c
JM
15851 if (tag == Tag_GNU_MIPS_ABI_FP)
15852 {
32ec8896 15853 unsigned int val;
f6f0e17b 15854
2cf19d5c 15855 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 15856 READ_ULEB (val, p, end);
351cdf24 15857 print_mips_fp_abi_value (val);
2cf19d5c
JM
15858 return p;
15859 }
15860
a9f58168
CF
15861 if (tag == Tag_GNU_MIPS_ABI_MSA)
15862 {
32ec8896 15863 unsigned int val;
a9f58168 15864
a9f58168 15865 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 15866 READ_ULEB (val, p, end);
a9f58168
CF
15867
15868 switch (val)
15869 {
15870 case Val_GNU_MIPS_ABI_MSA_ANY:
15871 printf (_("Any MSA or not\n"));
15872 break;
15873 case Val_GNU_MIPS_ABI_MSA_128:
15874 printf (_("128-bit MSA\n"));
15875 break;
15876 default:
15877 printf ("??? (%d)\n", val);
15878 break;
15879 }
15880 return p;
15881 }
15882
f6f0e17b 15883 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
15884}
15885
59e6276b 15886static unsigned char *
f6f0e17b
NC
15887display_tic6x_attribute (unsigned char * p,
15888 const unsigned char * const end)
59e6276b 15889{
60abdbed 15890 unsigned int tag;
cd30bcef 15891 unsigned int val;
59e6276b 15892
cd30bcef 15893 READ_ULEB (tag, p, end);
59e6276b
JM
15894
15895 switch (tag)
15896 {
75fa6dc1 15897 case Tag_ISA:
75fa6dc1 15898 printf (" Tag_ISA: ");
cd30bcef 15899 READ_ULEB (val, p, end);
59e6276b
JM
15900
15901 switch (val)
15902 {
75fa6dc1 15903 case C6XABI_Tag_ISA_none:
59e6276b
JM
15904 printf (_("None\n"));
15905 break;
75fa6dc1 15906 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
15907 printf ("C62x\n");
15908 break;
75fa6dc1 15909 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
15910 printf ("C67x\n");
15911 break;
75fa6dc1 15912 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
15913 printf ("C67x+\n");
15914 break;
75fa6dc1 15915 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
15916 printf ("C64x\n");
15917 break;
75fa6dc1 15918 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
15919 printf ("C64x+\n");
15920 break;
75fa6dc1 15921 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
15922 printf ("C674x\n");
15923 break;
15924 default:
15925 printf ("??? (%d)\n", val);
15926 break;
15927 }
15928 return p;
15929
87779176 15930 case Tag_ABI_wchar_t:
87779176 15931 printf (" Tag_ABI_wchar_t: ");
cd30bcef 15932 READ_ULEB (val, p, end);
87779176
JM
15933 switch (val)
15934 {
15935 case 0:
15936 printf (_("Not used\n"));
15937 break;
15938 case 1:
15939 printf (_("2 bytes\n"));
15940 break;
15941 case 2:
15942 printf (_("4 bytes\n"));
15943 break;
15944 default:
15945 printf ("??? (%d)\n", val);
15946 break;
15947 }
15948 return p;
15949
15950 case Tag_ABI_stack_align_needed:
87779176 15951 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 15952 READ_ULEB (val, p, end);
87779176
JM
15953 switch (val)
15954 {
15955 case 0:
15956 printf (_("8-byte\n"));
15957 break;
15958 case 1:
15959 printf (_("16-byte\n"));
15960 break;
15961 default:
15962 printf ("??? (%d)\n", val);
15963 break;
15964 }
15965 return p;
15966
15967 case Tag_ABI_stack_align_preserved:
cd30bcef 15968 READ_ULEB (val, p, end);
87779176
JM
15969 printf (" Tag_ABI_stack_align_preserved: ");
15970 switch (val)
15971 {
15972 case 0:
15973 printf (_("8-byte\n"));
15974 break;
15975 case 1:
15976 printf (_("16-byte\n"));
15977 break;
15978 default:
15979 printf ("??? (%d)\n", val);
15980 break;
15981 }
15982 return p;
15983
b5593623 15984 case Tag_ABI_DSBT:
cd30bcef 15985 READ_ULEB (val, p, end);
b5593623
JM
15986 printf (" Tag_ABI_DSBT: ");
15987 switch (val)
15988 {
15989 case 0:
15990 printf (_("DSBT addressing not used\n"));
15991 break;
15992 case 1:
15993 printf (_("DSBT addressing used\n"));
15994 break;
15995 default:
15996 printf ("??? (%d)\n", val);
15997 break;
15998 }
15999 return p;
16000
87779176 16001 case Tag_ABI_PID:
cd30bcef 16002 READ_ULEB (val, p, end);
87779176
JM
16003 printf (" Tag_ABI_PID: ");
16004 switch (val)
16005 {
16006 case 0:
16007 printf (_("Data addressing position-dependent\n"));
16008 break;
16009 case 1:
16010 printf (_("Data addressing position-independent, GOT near DP\n"));
16011 break;
16012 case 2:
16013 printf (_("Data addressing position-independent, GOT far from DP\n"));
16014 break;
16015 default:
16016 printf ("??? (%d)\n", val);
16017 break;
16018 }
16019 return p;
16020
16021 case Tag_ABI_PIC:
cd30bcef 16022 READ_ULEB (val, p, end);
87779176
JM
16023 printf (" Tag_ABI_PIC: ");
16024 switch (val)
16025 {
16026 case 0:
16027 printf (_("Code addressing position-dependent\n"));
16028 break;
16029 case 1:
16030 printf (_("Code addressing position-independent\n"));
16031 break;
16032 default:
16033 printf ("??? (%d)\n", val);
16034 break;
16035 }
16036 return p;
16037
16038 case Tag_ABI_array_object_alignment:
cd30bcef 16039 READ_ULEB (val, p, end);
87779176
JM
16040 printf (" Tag_ABI_array_object_alignment: ");
16041 switch (val)
16042 {
16043 case 0:
16044 printf (_("8-byte\n"));
16045 break;
16046 case 1:
16047 printf (_("4-byte\n"));
16048 break;
16049 case 2:
16050 printf (_("16-byte\n"));
16051 break;
16052 default:
16053 printf ("??? (%d)\n", val);
16054 break;
16055 }
16056 return p;
16057
16058 case Tag_ABI_array_object_align_expected:
cd30bcef 16059 READ_ULEB (val, p, end);
87779176
JM
16060 printf (" Tag_ABI_array_object_align_expected: ");
16061 switch (val)
16062 {
16063 case 0:
16064 printf (_("8-byte\n"));
16065 break;
16066 case 1:
16067 printf (_("4-byte\n"));
16068 break;
16069 case 2:
16070 printf (_("16-byte\n"));
16071 break;
16072 default:
16073 printf ("??? (%d)\n", val);
16074 break;
16075 }
16076 return p;
16077
3cbd1c06 16078 case Tag_ABI_compatibility:
071436c6 16079 {
cd30bcef 16080 READ_ULEB (val, p, end);
071436c6 16081 printf (" Tag_ABI_compatibility: ");
071436c6 16082 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16083 if (p < end - 1)
16084 {
16085 size_t maxlen = (end - p) - 1;
16086
16087 print_symbol ((int) maxlen, (const char *) p);
16088 p += strnlen ((char *) p, maxlen) + 1;
16089 }
16090 else
16091 {
16092 printf (_("<corrupt>"));
16093 p = (unsigned char *) end;
16094 }
071436c6 16095 putchar ('\n');
071436c6
NC
16096 return p;
16097 }
87779176
JM
16098
16099 case Tag_ABI_conformance:
071436c6 16100 {
4082ef84
NC
16101 printf (" Tag_ABI_conformance: \"");
16102 if (p < end - 1)
16103 {
16104 size_t maxlen = (end - p) - 1;
071436c6 16105
4082ef84
NC
16106 print_symbol ((int) maxlen, (const char *) p);
16107 p += strnlen ((char *) p, maxlen) + 1;
16108 }
16109 else
16110 {
16111 printf (_("<corrupt>"));
16112 p = (unsigned char *) end;
16113 }
071436c6 16114 printf ("\"\n");
071436c6
NC
16115 return p;
16116 }
59e6276b
JM
16117 }
16118
f6f0e17b
NC
16119 return display_tag_value (tag, p, end);
16120}
59e6276b 16121
f6f0e17b 16122static void
60abdbed 16123display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16124{
16125 unsigned long addr = 0;
16126 size_t bytes = end - p;
16127
feceaa59 16128 assert (end >= p);
f6f0e17b 16129 while (bytes)
87779176 16130 {
f6f0e17b
NC
16131 int j;
16132 int k;
16133 int lbytes = (bytes > 16 ? 16 : bytes);
16134
16135 printf (" 0x%8.8lx ", addr);
16136
16137 for (j = 0; j < 16; j++)
16138 {
16139 if (j < lbytes)
16140 printf ("%2.2x", p[j]);
16141 else
16142 printf (" ");
16143
16144 if ((j & 3) == 3)
16145 printf (" ");
16146 }
16147
16148 for (j = 0; j < lbytes; j++)
16149 {
16150 k = p[j];
16151 if (k >= ' ' && k < 0x7f)
16152 printf ("%c", k);
16153 else
16154 printf (".");
16155 }
16156
16157 putchar ('\n');
16158
16159 p += lbytes;
16160 bytes -= lbytes;
16161 addr += lbytes;
87779176 16162 }
59e6276b 16163
f6f0e17b 16164 putchar ('\n');
59e6276b
JM
16165}
16166
13761a11
NC
16167static unsigned char *
16168display_msp430x_attribute (unsigned char * p,
16169 const unsigned char * const end)
16170{
60abdbed
NC
16171 unsigned int val;
16172 unsigned int tag;
13761a11 16173
cd30bcef 16174 READ_ULEB (tag, p, end);
0b4362b0 16175
13761a11
NC
16176 switch (tag)
16177 {
16178 case OFBA_MSPABI_Tag_ISA:
13761a11 16179 printf (" Tag_ISA: ");
cd30bcef 16180 READ_ULEB (val, p, end);
13761a11
NC
16181 switch (val)
16182 {
16183 case 0: printf (_("None\n")); break;
16184 case 1: printf (_("MSP430\n")); break;
16185 case 2: printf (_("MSP430X\n")); break;
16186 default: printf ("??? (%d)\n", val); break;
16187 }
16188 break;
16189
16190 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16191 printf (" Tag_Code_Model: ");
cd30bcef 16192 READ_ULEB (val, p, end);
13761a11
NC
16193 switch (val)
16194 {
16195 case 0: printf (_("None\n")); break;
16196 case 1: printf (_("Small\n")); break;
16197 case 2: printf (_("Large\n")); break;
16198 default: printf ("??? (%d)\n", val); break;
16199 }
16200 break;
16201
16202 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16203 printf (" Tag_Data_Model: ");
cd30bcef 16204 READ_ULEB (val, p, end);
13761a11
NC
16205 switch (val)
16206 {
16207 case 0: printf (_("None\n")); break;
16208 case 1: printf (_("Small\n")); break;
16209 case 2: printf (_("Large\n")); break;
16210 case 3: printf (_("Restricted Large\n")); break;
16211 default: printf ("??? (%d)\n", val); break;
16212 }
16213 break;
16214
16215 default:
16216 printf (_(" <unknown tag %d>: "), tag);
16217
16218 if (tag & 1)
16219 {
071436c6 16220 putchar ('"');
4082ef84
NC
16221 if (p < end - 1)
16222 {
16223 size_t maxlen = (end - p) - 1;
16224
16225 print_symbol ((int) maxlen, (const char *) p);
16226 p += strnlen ((char *) p, maxlen) + 1;
16227 }
16228 else
16229 {
16230 printf (_("<corrupt>"));
16231 p = (unsigned char *) end;
16232 }
071436c6 16233 printf ("\"\n");
13761a11
NC
16234 }
16235 else
16236 {
cd30bcef 16237 READ_ULEB (val, p, end);
13761a11
NC
16238 printf ("%d (0x%x)\n", val, val);
16239 }
16240 break;
16241 }
16242
4082ef84 16243 assert (p <= end);
13761a11
NC
16244 return p;
16245}
16246
c0ea7c52
JL
16247static unsigned char *
16248display_msp430_gnu_attribute (unsigned char * p,
16249 unsigned int tag,
16250 const unsigned char * const end)
16251{
16252 if (tag == Tag_GNU_MSP430_Data_Region)
16253 {
cd30bcef 16254 unsigned int val;
c0ea7c52 16255
c0ea7c52 16256 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16257 READ_ULEB (val, p, end);
c0ea7c52
JL
16258
16259 switch (val)
16260 {
16261 case Val_GNU_MSP430_Data_Region_Any:
16262 printf (_("Any Region\n"));
16263 break;
16264 case Val_GNU_MSP430_Data_Region_Lower:
16265 printf (_("Lower Region Only\n"));
16266 break;
16267 default:
cd30bcef 16268 printf ("??? (%u)\n", val);
c0ea7c52
JL
16269 }
16270 return p;
16271 }
16272 return display_tag_value (tag & 1, p, end);
16273}
16274
2dc8dd17
JW
16275struct riscv_attr_tag_t {
16276 const char *name;
cd30bcef 16277 unsigned int tag;
2dc8dd17
JW
16278};
16279
16280static struct riscv_attr_tag_t riscv_attr_tag[] =
16281{
16282#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16283 T(arch),
16284 T(priv_spec),
16285 T(priv_spec_minor),
16286 T(priv_spec_revision),
16287 T(unaligned_access),
16288 T(stack_align),
16289#undef T
16290};
16291
16292static unsigned char *
16293display_riscv_attribute (unsigned char *p,
16294 const unsigned char * const end)
16295{
cd30bcef
AM
16296 unsigned int val;
16297 unsigned int tag;
2dc8dd17
JW
16298 struct riscv_attr_tag_t *attr = NULL;
16299 unsigned i;
16300
cd30bcef 16301 READ_ULEB (tag, p, end);
2dc8dd17
JW
16302
16303 /* Find the name of attribute. */
16304 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16305 {
16306 if (riscv_attr_tag[i].tag == tag)
16307 {
16308 attr = &riscv_attr_tag[i];
16309 break;
16310 }
16311 }
16312
16313 if (attr)
16314 printf (" %s: ", attr->name);
16315 else
16316 return display_tag_value (tag, p, end);
16317
16318 switch (tag)
16319 {
16320 case Tag_RISCV_priv_spec:
16321 case Tag_RISCV_priv_spec_minor:
16322 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16323 READ_ULEB (val, p, end);
16324 printf (_("%u\n"), val);
2dc8dd17
JW
16325 break;
16326 case Tag_RISCV_unaligned_access:
cd30bcef 16327 READ_ULEB (val, p, end);
2dc8dd17
JW
16328 switch (val)
16329 {
16330 case 0:
16331 printf (_("No unaligned access\n"));
16332 break;
16333 case 1:
16334 printf (_("Unaligned access\n"));
16335 break;
16336 }
16337 break;
16338 case Tag_RISCV_stack_align:
cd30bcef
AM
16339 READ_ULEB (val, p, end);
16340 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16341 break;
16342 case Tag_RISCV_arch:
16343 p = display_tag_value (-1, p, end);
16344 break;
16345 default:
16346 return display_tag_value (tag, p, end);
16347 }
16348
16349 return p;
16350}
16351
32ec8896 16352static bfd_boolean
dda8d76d 16353process_attributes (Filedata * filedata,
60bca95a 16354 const char * public_name,
104d59d1 16355 unsigned int proc_type,
f6f0e17b 16356 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 16357 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 16358{
2cf0635d 16359 Elf_Internal_Shdr * sect;
11c1ff18 16360 unsigned i;
32ec8896 16361 bfd_boolean res = TRUE;
11c1ff18
PB
16362
16363 /* Find the section header so that we get the size. */
dda8d76d
NC
16364 for (i = 0, sect = filedata->section_headers;
16365 i < filedata->file_header.e_shnum;
11c1ff18
PB
16366 i++, sect++)
16367 {
071436c6
NC
16368 unsigned char * contents;
16369 unsigned char * p;
16370
104d59d1 16371 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
16372 continue;
16373
dda8d76d 16374 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 16375 sect->sh_size, _("attributes"));
60bca95a 16376 if (contents == NULL)
32ec8896
NC
16377 {
16378 res = FALSE;
16379 continue;
16380 }
60bca95a 16381
11c1ff18 16382 p = contents;
60abdbed
NC
16383 /* The first character is the version of the attributes.
16384 Currently only version 1, (aka 'A') is recognised here. */
16385 if (*p != 'A')
32ec8896
NC
16386 {
16387 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
16388 res = FALSE;
16389 }
60abdbed 16390 else
11c1ff18 16391 {
071436c6
NC
16392 bfd_vma section_len;
16393
16394 section_len = sect->sh_size - 1;
11c1ff18 16395 p++;
60bca95a 16396
071436c6 16397 while (section_len > 0)
11c1ff18 16398 {
071436c6 16399 bfd_vma attr_len;
e9847026 16400 unsigned int namelen;
11c1ff18 16401 bfd_boolean public_section;
104d59d1 16402 bfd_boolean gnu_section;
11c1ff18 16403
071436c6 16404 if (section_len <= 4)
e0a31db1
NC
16405 {
16406 error (_("Tag section ends prematurely\n"));
32ec8896 16407 res = FALSE;
e0a31db1
NC
16408 break;
16409 }
071436c6 16410 attr_len = byte_get (p, 4);
11c1ff18 16411 p += 4;
60bca95a 16412
071436c6 16413 if (attr_len > section_len)
11c1ff18 16414 {
071436c6
NC
16415 error (_("Bad attribute length (%u > %u)\n"),
16416 (unsigned) attr_len, (unsigned) section_len);
16417 attr_len = section_len;
32ec8896 16418 res = FALSE;
11c1ff18 16419 }
74e1a04b 16420 /* PR 17531: file: 001-101425-0.004 */
071436c6 16421 else if (attr_len < 5)
74e1a04b 16422 {
071436c6 16423 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 16424 res = FALSE;
74e1a04b
NC
16425 break;
16426 }
e9847026 16427
071436c6
NC
16428 section_len -= attr_len;
16429 attr_len -= 4;
16430
16431 namelen = strnlen ((char *) p, attr_len) + 1;
16432 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
16433 {
16434 error (_("Corrupt attribute section name\n"));
32ec8896 16435 res = FALSE;
e9847026
NC
16436 break;
16437 }
16438
071436c6
NC
16439 printf (_("Attribute Section: "));
16440 print_symbol (INT_MAX, (const char *) p);
16441 putchar ('\n');
60bca95a
NC
16442
16443 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
16444 public_section = TRUE;
16445 else
16446 public_section = FALSE;
60bca95a
NC
16447
16448 if (streq ((char *) p, "gnu"))
104d59d1
JM
16449 gnu_section = TRUE;
16450 else
16451 gnu_section = FALSE;
60bca95a 16452
11c1ff18 16453 p += namelen;
071436c6 16454 attr_len -= namelen;
e0a31db1 16455
071436c6 16456 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 16457 {
e0a31db1 16458 int tag;
cd30bcef 16459 unsigned int val;
11c1ff18 16460 bfd_vma size;
071436c6 16461 unsigned char * end;
60bca95a 16462
e0a31db1 16463 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 16464 if (attr_len < 6)
e0a31db1
NC
16465 {
16466 error (_("Unused bytes at end of section\n"));
32ec8896 16467 res = FALSE;
e0a31db1
NC
16468 section_len = 0;
16469 break;
16470 }
16471
16472 tag = *(p++);
11c1ff18 16473 size = byte_get (p, 4);
071436c6 16474 if (size > attr_len)
11c1ff18 16475 {
e9847026 16476 error (_("Bad subsection length (%u > %u)\n"),
071436c6 16477 (unsigned) size, (unsigned) attr_len);
32ec8896 16478 res = FALSE;
071436c6 16479 size = attr_len;
11c1ff18 16480 }
e0a31db1
NC
16481 /* PR binutils/17531: Safe handling of corrupt files. */
16482 if (size < 6)
16483 {
16484 error (_("Bad subsection length (%u < 6)\n"),
16485 (unsigned) size);
32ec8896 16486 res = FALSE;
e0a31db1
NC
16487 section_len = 0;
16488 break;
16489 }
60bca95a 16490
071436c6 16491 attr_len -= size;
11c1ff18 16492 end = p + size - 1;
071436c6 16493 assert (end <= contents + sect->sh_size);
11c1ff18 16494 p += 4;
60bca95a 16495
11c1ff18
PB
16496 switch (tag)
16497 {
16498 case 1:
2b692964 16499 printf (_("File Attributes\n"));
11c1ff18
PB
16500 break;
16501 case 2:
2b692964 16502 printf (_("Section Attributes:"));
11c1ff18
PB
16503 goto do_numlist;
16504 case 3:
2b692964 16505 printf (_("Symbol Attributes:"));
1a0670f3 16506 /* Fall through. */
11c1ff18
PB
16507 do_numlist:
16508 for (;;)
16509 {
cd30bcef 16510 READ_ULEB (val, p, end);
11c1ff18
PB
16511 if (val == 0)
16512 break;
16513 printf (" %d", val);
16514 }
16515 printf ("\n");
16516 break;
16517 default:
2b692964 16518 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
16519 public_section = FALSE;
16520 break;
16521 }
60bca95a 16522
071436c6 16523 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
16524 {
16525 while (p < end)
f6f0e17b 16526 p = display_pub_attribute (p, end);
60abdbed 16527 assert (p == end);
104d59d1 16528 }
071436c6 16529 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
16530 {
16531 while (p < end)
16532 p = display_gnu_attribute (p,
f6f0e17b
NC
16533 display_proc_gnu_attribute,
16534 end);
60abdbed 16535 assert (p == end);
11c1ff18 16536 }
071436c6 16537 else if (p < end)
11c1ff18 16538 {
071436c6 16539 printf (_(" Unknown attribute:\n"));
f6f0e17b 16540 display_raw_attribute (p, end);
11c1ff18
PB
16541 p = end;
16542 }
071436c6
NC
16543 else
16544 attr_len = 0;
11c1ff18
PB
16545 }
16546 }
16547 }
d70c5fc7 16548
60bca95a 16549 free (contents);
11c1ff18 16550 }
32ec8896
NC
16551
16552 return res;
11c1ff18
PB
16553}
16554
ccb4c951
RS
16555/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
16556 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
16557 and return the VMA of the next entry, or -1 if there was a problem.
16558 Does not read from DATA_END or beyond. */
ccb4c951
RS
16559
16560static bfd_vma
82b1b41b
NC
16561print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
16562 unsigned char * data_end)
ccb4c951
RS
16563{
16564 printf (" ");
16565 print_vma (addr, LONG_HEX);
16566 printf (" ");
16567 if (addr < pltgot + 0xfff0)
16568 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
16569 else
16570 printf ("%10s", "");
16571 printf (" ");
16572 if (data == NULL)
2b692964 16573 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
16574 else
16575 {
16576 bfd_vma entry;
82b1b41b 16577 unsigned char * from = data + addr - pltgot;
ccb4c951 16578
82b1b41b
NC
16579 if (from + (is_32bit_elf ? 4 : 8) > data_end)
16580 {
16581 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
16582 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
16583 return (bfd_vma) -1;
16584 }
16585 else
16586 {
16587 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16588 print_vma (entry, LONG_HEX);
16589 }
ccb4c951
RS
16590 }
16591 return addr + (is_32bit_elf ? 4 : 8);
16592}
16593
861fb55a
DJ
16594/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
16595 PLTGOT. Print the Address and Initial fields of an entry at VMA
16596 ADDR and return the VMA of the next entry. */
16597
16598static bfd_vma
2cf0635d 16599print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
16600{
16601 printf (" ");
16602 print_vma (addr, LONG_HEX);
16603 printf (" ");
16604 if (data == NULL)
2b692964 16605 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
16606 else
16607 {
16608 bfd_vma entry;
16609
16610 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16611 print_vma (entry, LONG_HEX);
16612 }
16613 return addr + (is_32bit_elf ? 4 : 8);
16614}
16615
351cdf24
MF
16616static void
16617print_mips_ases (unsigned int mask)
16618{
16619 if (mask & AFL_ASE_DSP)
16620 fputs ("\n\tDSP ASE", stdout);
16621 if (mask & AFL_ASE_DSPR2)
16622 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
16623 if (mask & AFL_ASE_DSPR3)
16624 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
16625 if (mask & AFL_ASE_EVA)
16626 fputs ("\n\tEnhanced VA Scheme", stdout);
16627 if (mask & AFL_ASE_MCU)
16628 fputs ("\n\tMCU (MicroController) ASE", stdout);
16629 if (mask & AFL_ASE_MDMX)
16630 fputs ("\n\tMDMX ASE", stdout);
16631 if (mask & AFL_ASE_MIPS3D)
16632 fputs ("\n\tMIPS-3D ASE", stdout);
16633 if (mask & AFL_ASE_MT)
16634 fputs ("\n\tMT ASE", stdout);
16635 if (mask & AFL_ASE_SMARTMIPS)
16636 fputs ("\n\tSmartMIPS ASE", stdout);
16637 if (mask & AFL_ASE_VIRT)
16638 fputs ("\n\tVZ ASE", stdout);
16639 if (mask & AFL_ASE_MSA)
16640 fputs ("\n\tMSA ASE", stdout);
16641 if (mask & AFL_ASE_MIPS16)
16642 fputs ("\n\tMIPS16 ASE", stdout);
16643 if (mask & AFL_ASE_MICROMIPS)
16644 fputs ("\n\tMICROMIPS ASE", stdout);
16645 if (mask & AFL_ASE_XPA)
16646 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
16647 if (mask & AFL_ASE_MIPS16E2)
16648 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
16649 if (mask & AFL_ASE_CRC)
16650 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
16651 if (mask & AFL_ASE_GINV)
16652 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
16653 if (mask & AFL_ASE_LOONGSON_MMI)
16654 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
16655 if (mask & AFL_ASE_LOONGSON_CAM)
16656 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
16657 if (mask & AFL_ASE_LOONGSON_EXT)
16658 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
16659 if (mask & AFL_ASE_LOONGSON_EXT2)
16660 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
16661 if (mask == 0)
16662 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
16663 else if ((mask & ~AFL_ASE_MASK) != 0)
16664 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
16665}
16666
16667static void
16668print_mips_isa_ext (unsigned int isa_ext)
16669{
16670 switch (isa_ext)
16671 {
16672 case 0:
16673 fputs (_("None"), stdout);
16674 break;
16675 case AFL_EXT_XLR:
16676 fputs ("RMI XLR", stdout);
16677 break;
2c629856
N
16678 case AFL_EXT_OCTEON3:
16679 fputs ("Cavium Networks Octeon3", stdout);
16680 break;
351cdf24
MF
16681 case AFL_EXT_OCTEON2:
16682 fputs ("Cavium Networks Octeon2", stdout);
16683 break;
16684 case AFL_EXT_OCTEONP:
16685 fputs ("Cavium Networks OcteonP", stdout);
16686 break;
351cdf24
MF
16687 case AFL_EXT_OCTEON:
16688 fputs ("Cavium Networks Octeon", stdout);
16689 break;
16690 case AFL_EXT_5900:
16691 fputs ("Toshiba R5900", stdout);
16692 break;
16693 case AFL_EXT_4650:
16694 fputs ("MIPS R4650", stdout);
16695 break;
16696 case AFL_EXT_4010:
16697 fputs ("LSI R4010", stdout);
16698 break;
16699 case AFL_EXT_4100:
16700 fputs ("NEC VR4100", stdout);
16701 break;
16702 case AFL_EXT_3900:
16703 fputs ("Toshiba R3900", stdout);
16704 break;
16705 case AFL_EXT_10000:
16706 fputs ("MIPS R10000", stdout);
16707 break;
16708 case AFL_EXT_SB1:
16709 fputs ("Broadcom SB-1", stdout);
16710 break;
16711 case AFL_EXT_4111:
16712 fputs ("NEC VR4111/VR4181", stdout);
16713 break;
16714 case AFL_EXT_4120:
16715 fputs ("NEC VR4120", stdout);
16716 break;
16717 case AFL_EXT_5400:
16718 fputs ("NEC VR5400", stdout);
16719 break;
16720 case AFL_EXT_5500:
16721 fputs ("NEC VR5500", stdout);
16722 break;
16723 case AFL_EXT_LOONGSON_2E:
16724 fputs ("ST Microelectronics Loongson 2E", stdout);
16725 break;
16726 case AFL_EXT_LOONGSON_2F:
16727 fputs ("ST Microelectronics Loongson 2F", stdout);
16728 break;
38bf472a
MR
16729 case AFL_EXT_INTERAPTIV_MR2:
16730 fputs ("Imagination interAptiv MR2", stdout);
16731 break;
351cdf24 16732 default:
00ac7aa0 16733 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
16734 }
16735}
16736
32ec8896 16737static signed int
351cdf24
MF
16738get_mips_reg_size (int reg_size)
16739{
16740 return (reg_size == AFL_REG_NONE) ? 0
16741 : (reg_size == AFL_REG_32) ? 32
16742 : (reg_size == AFL_REG_64) ? 64
16743 : (reg_size == AFL_REG_128) ? 128
16744 : -1;
16745}
16746
32ec8896 16747static bfd_boolean
dda8d76d 16748process_mips_specific (Filedata * filedata)
5b18a4bc 16749{
2cf0635d 16750 Elf_Internal_Dyn * entry;
351cdf24 16751 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
16752 size_t liblist_offset = 0;
16753 size_t liblistno = 0;
16754 size_t conflictsno = 0;
16755 size_t options_offset = 0;
16756 size_t conflicts_offset = 0;
861fb55a
DJ
16757 size_t pltrelsz = 0;
16758 size_t pltrel = 0;
ccb4c951 16759 bfd_vma pltgot = 0;
861fb55a
DJ
16760 bfd_vma mips_pltgot = 0;
16761 bfd_vma jmprel = 0;
ccb4c951
RS
16762 bfd_vma local_gotno = 0;
16763 bfd_vma gotsym = 0;
16764 bfd_vma symtabno = 0;
32ec8896 16765 bfd_boolean res = TRUE;
103f02d3 16766
dda8d76d 16767 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
16768 display_mips_gnu_attribute))
16769 res = FALSE;
2cf19d5c 16770
dda8d76d 16771 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
16772
16773 if (sect != NULL)
16774 {
16775 Elf_External_ABIFlags_v0 *abiflags_ext;
16776 Elf_Internal_ABIFlags_v0 abiflags_in;
16777
16778 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
16779 {
16780 error (_("Corrupt MIPS ABI Flags section.\n"));
16781 res = FALSE;
16782 }
351cdf24
MF
16783 else
16784 {
dda8d76d 16785 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
16786 sect->sh_size, _("MIPS ABI Flags section"));
16787 if (abiflags_ext)
16788 {
16789 abiflags_in.version = BYTE_GET (abiflags_ext->version);
16790 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
16791 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
16792 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
16793 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
16794 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
16795 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
16796 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
16797 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
16798 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
16799 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
16800
16801 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
16802 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
16803 if (abiflags_in.isa_rev > 1)
16804 printf ("r%d", abiflags_in.isa_rev);
16805 printf ("\nGPR size: %d",
16806 get_mips_reg_size (abiflags_in.gpr_size));
16807 printf ("\nCPR1 size: %d",
16808 get_mips_reg_size (abiflags_in.cpr1_size));
16809 printf ("\nCPR2 size: %d",
16810 get_mips_reg_size (abiflags_in.cpr2_size));
16811 fputs ("\nFP ABI: ", stdout);
16812 print_mips_fp_abi_value (abiflags_in.fp_abi);
16813 fputs ("ISA Extension: ", stdout);
16814 print_mips_isa_ext (abiflags_in.isa_ext);
16815 fputs ("\nASEs:", stdout);
16816 print_mips_ases (abiflags_in.ases);
16817 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
16818 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
16819 fputc ('\n', stdout);
16820 free (abiflags_ext);
16821 }
16822 }
16823 }
16824
19e6b90e 16825 /* We have a lot of special sections. Thanks SGI! */
978c4450 16826 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
16827 {
16828 /* No dynamic information available. See if there is static GOT. */
dda8d76d 16829 sect = find_section (filedata, ".got");
bbdd9a68
MR
16830 if (sect != NULL)
16831 {
16832 unsigned char *data_end;
16833 unsigned char *data;
16834 bfd_vma ent, end;
16835 int addr_size;
16836
16837 pltgot = sect->sh_addr;
16838
16839 ent = pltgot;
16840 addr_size = (is_32bit_elf ? 4 : 8);
16841 end = pltgot + sect->sh_size;
16842
dda8d76d 16843 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
16844 end - pltgot, 1,
16845 _("Global Offset Table data"));
16846 /* PR 12855: Null data is handled gracefully throughout. */
16847 data_end = data + (end - pltgot);
16848
16849 printf (_("\nStatic GOT:\n"));
16850 printf (_(" Canonical gp value: "));
16851 print_vma (ent + 0x7ff0, LONG_HEX);
16852 printf ("\n\n");
16853
16854 /* In a dynamic binary GOT[0] is reserved for the dynamic
16855 loader to store the lazy resolver pointer, however in
16856 a static binary it may well have been omitted and GOT
16857 reduced to a table of addresses.
16858 PR 21344: Check for the entry being fully available
16859 before fetching it. */
16860 if (data
16861 && data + ent - pltgot + addr_size <= data_end
16862 && byte_get (data + ent - pltgot, addr_size) == 0)
16863 {
16864 printf (_(" Reserved entries:\n"));
16865 printf (_(" %*s %10s %*s\n"),
16866 addr_size * 2, _("Address"), _("Access"),
16867 addr_size * 2, _("Value"));
16868 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16869 printf ("\n");
16870 if (ent == (bfd_vma) -1)
16871 goto sgot_print_fail;
16872
16873 /* Check for the MSB of GOT[1] being set, identifying a
16874 GNU object. This entry will be used by some runtime
16875 loaders, to store the module pointer. Otherwise this
16876 is an ordinary local entry.
16877 PR 21344: Check for the entry being fully available
16878 before fetching it. */
16879 if (data
16880 && data + ent - pltgot + addr_size <= data_end
16881 && (byte_get (data + ent - pltgot, addr_size)
16882 >> (addr_size * 8 - 1)) != 0)
16883 {
16884 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16885 printf ("\n");
16886 if (ent == (bfd_vma) -1)
16887 goto sgot_print_fail;
16888 }
16889 printf ("\n");
16890 }
16891
f17e9d8a 16892 if (data != NULL && ent < end)
bbdd9a68
MR
16893 {
16894 printf (_(" Local entries:\n"));
16895 printf (" %*s %10s %*s\n",
16896 addr_size * 2, _("Address"), _("Access"),
16897 addr_size * 2, _("Value"));
16898 while (ent < end)
16899 {
16900 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16901 printf ("\n");
16902 if (ent == (bfd_vma) -1)
16903 goto sgot_print_fail;
16904 }
16905 printf ("\n");
16906 }
16907
16908 sgot_print_fail:
9db70fc3 16909 free (data);
bbdd9a68
MR
16910 }
16911 return res;
16912 }
252b5132 16913
978c4450 16914 for (entry = filedata->dynamic_section;
071436c6 16915 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
16916 (entry < filedata->dynamic_section + filedata->dynamic_nent
16917 && entry->d_tag != DT_NULL);
071436c6 16918 ++entry)
252b5132
RH
16919 switch (entry->d_tag)
16920 {
16921 case DT_MIPS_LIBLIST:
d93f0186 16922 liblist_offset
dda8d76d 16923 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16924 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
16925 break;
16926 case DT_MIPS_LIBLISTNO:
16927 liblistno = entry->d_un.d_val;
16928 break;
16929 case DT_MIPS_OPTIONS:
dda8d76d 16930 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
16931 break;
16932 case DT_MIPS_CONFLICT:
d93f0186 16933 conflicts_offset
dda8d76d 16934 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16935 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
16936 break;
16937 case DT_MIPS_CONFLICTNO:
16938 conflictsno = entry->d_un.d_val;
16939 break;
ccb4c951 16940 case DT_PLTGOT:
861fb55a
DJ
16941 pltgot = entry->d_un.d_ptr;
16942 break;
ccb4c951
RS
16943 case DT_MIPS_LOCAL_GOTNO:
16944 local_gotno = entry->d_un.d_val;
16945 break;
16946 case DT_MIPS_GOTSYM:
16947 gotsym = entry->d_un.d_val;
16948 break;
16949 case DT_MIPS_SYMTABNO:
16950 symtabno = entry->d_un.d_val;
16951 break;
861fb55a
DJ
16952 case DT_MIPS_PLTGOT:
16953 mips_pltgot = entry->d_un.d_ptr;
16954 break;
16955 case DT_PLTREL:
16956 pltrel = entry->d_un.d_val;
16957 break;
16958 case DT_PLTRELSZ:
16959 pltrelsz = entry->d_un.d_val;
16960 break;
16961 case DT_JMPREL:
16962 jmprel = entry->d_un.d_ptr;
16963 break;
252b5132
RH
16964 default:
16965 break;
16966 }
16967
16968 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
16969 {
2cf0635d 16970 Elf32_External_Lib * elib;
252b5132
RH
16971 size_t cnt;
16972
dda8d76d 16973 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
16974 sizeof (Elf32_External_Lib),
16975 liblistno,
16976 _("liblist section data"));
a6e9f9df 16977 if (elib)
252b5132 16978 {
d3a49aa8
AM
16979 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
16980 "\nSection '.liblist' contains %lu entries:\n",
16981 (unsigned long) liblistno),
a6e9f9df 16982 (unsigned long) liblistno);
2b692964 16983 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
16984 stdout);
16985
16986 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 16987 {
a6e9f9df 16988 Elf32_Lib liblist;
91d6fa6a 16989 time_t atime;
d5b07ef4 16990 char timebuf[128];
2cf0635d 16991 struct tm * tmp;
a6e9f9df
AM
16992
16993 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16994 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
16995 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16996 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16997 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16998
91d6fa6a 16999 tmp = gmtime (&atime);
e9e44622
JJ
17000 snprintf (timebuf, sizeof (timebuf),
17001 "%04u-%02u-%02uT%02u:%02u:%02u",
17002 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17003 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17004
31104126 17005 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17006 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17007 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17008 else
2b692964 17009 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17010 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17011 liblist.l_version);
a6e9f9df
AM
17012
17013 if (liblist.l_flags == 0)
2b692964 17014 puts (_(" NONE"));
a6e9f9df
AM
17015 else
17016 {
17017 static const struct
252b5132 17018 {
2cf0635d 17019 const char * name;
a6e9f9df 17020 int bit;
252b5132 17021 }
a6e9f9df
AM
17022 l_flags_vals[] =
17023 {
17024 { " EXACT_MATCH", LL_EXACT_MATCH },
17025 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17026 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17027 { " EXPORTS", LL_EXPORTS },
17028 { " DELAY_LOAD", LL_DELAY_LOAD },
17029 { " DELTA", LL_DELTA }
17030 };
17031 int flags = liblist.l_flags;
17032 size_t fcnt;
17033
60bca95a 17034 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17035 if ((flags & l_flags_vals[fcnt].bit) != 0)
17036 {
17037 fputs (l_flags_vals[fcnt].name, stdout);
17038 flags ^= l_flags_vals[fcnt].bit;
17039 }
17040 if (flags != 0)
17041 printf (" %#x", (unsigned int) flags);
252b5132 17042
a6e9f9df
AM
17043 puts ("");
17044 }
252b5132 17045 }
252b5132 17046
a6e9f9df
AM
17047 free (elib);
17048 }
32ec8896
NC
17049 else
17050 res = FALSE;
252b5132
RH
17051 }
17052
17053 if (options_offset != 0)
17054 {
2cf0635d 17055 Elf_External_Options * eopt;
252b5132
RH
17056 size_t offset;
17057 int cnt;
dda8d76d 17058 sect = filedata->section_headers;
252b5132
RH
17059
17060 /* Find the section header so that we get the size. */
dda8d76d 17061 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17062 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17063 if (sect == NULL)
17064 {
17065 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 17066 return FALSE;
071436c6 17067 }
7fc0c668
NC
17068 /* PR 24243 */
17069 if (sect->sh_size < sizeof (* eopt))
17070 {
17071 error (_("The MIPS options section is too small.\n"));
17072 return FALSE;
17073 }
252b5132 17074
dda8d76d 17075 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17076 sect->sh_size, _("options"));
a6e9f9df 17077 if (eopt)
252b5132 17078 {
fd17d1e6 17079 Elf_Internal_Options option;
76da6bbe 17080
a6e9f9df 17081 offset = cnt = 0;
82b1b41b 17082 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17083 {
2cf0635d 17084 Elf_External_Options * eoption;
fd17d1e6 17085 unsigned int optsize;
252b5132 17086
a6e9f9df 17087 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17088
fd17d1e6 17089 optsize = BYTE_GET (eoption->size);
76da6bbe 17090
82b1b41b 17091 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17092 if (optsize < sizeof (* eopt)
17093 || optsize > sect->sh_size - offset)
82b1b41b 17094 {
645f43a8 17095 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17096 optsize);
645f43a8 17097 free (eopt);
32ec8896 17098 return FALSE;
82b1b41b 17099 }
fd17d1e6 17100 offset += optsize;
a6e9f9df
AM
17101 ++cnt;
17102 }
252b5132 17103
d3a49aa8
AM
17104 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17105 "\nSection '%s' contains %d entries:\n",
17106 cnt),
dda8d76d 17107 printable_section_name (filedata, sect), cnt);
76da6bbe 17108
82b1b41b 17109 offset = 0;
a6e9f9df 17110 while (cnt-- > 0)
252b5132 17111 {
a6e9f9df 17112 size_t len;
fd17d1e6
AM
17113 Elf_External_Options * eoption;
17114
17115 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17116
17117 option.kind = BYTE_GET (eoption->kind);
17118 option.size = BYTE_GET (eoption->size);
17119 option.section = BYTE_GET (eoption->section);
17120 option.info = BYTE_GET (eoption->info);
a6e9f9df 17121
fd17d1e6 17122 switch (option.kind)
252b5132 17123 {
a6e9f9df
AM
17124 case ODK_NULL:
17125 /* This shouldn't happen. */
d0c4e780 17126 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 17127 option.section, option.info);
a6e9f9df 17128 break;
2e6be59c 17129
a6e9f9df
AM
17130 case ODK_REGINFO:
17131 printf (" REGINFO ");
dda8d76d 17132 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17133 {
2cf0635d 17134 Elf32_External_RegInfo * ereg;
b34976b6 17135 Elf32_RegInfo reginfo;
a6e9f9df 17136
2e6be59c 17137 /* 32bit form. */
fd17d1e6
AM
17138 if (option.size < (sizeof (Elf_External_Options)
17139 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
17140 {
17141 printf (_("<corrupt>\n"));
17142 error (_("Truncated MIPS REGINFO option\n"));
17143 cnt = 0;
17144 break;
17145 }
17146
fd17d1e6 17147 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 17148
a6e9f9df
AM
17149 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17150 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17151 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17152 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17153 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17154 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17155
d0c4e780
AM
17156 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
17157 reginfo.ri_gprmask, reginfo.ri_gp_value);
17158 printf (" "
17159 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17160 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17161 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17162 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17163 }
17164 else
17165 {
17166 /* 64 bit form. */
2cf0635d 17167 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17168 Elf64_Internal_RegInfo reginfo;
17169
fd17d1e6
AM
17170 if (option.size < (sizeof (Elf_External_Options)
17171 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
17172 {
17173 printf (_("<corrupt>\n"));
17174 error (_("Truncated MIPS REGINFO option\n"));
17175 cnt = 0;
17176 break;
17177 }
17178
fd17d1e6 17179 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
17180 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17181 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17182 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17183 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17184 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 17185 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 17186
d0c4e780
AM
17187 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
17188 reginfo.ri_gprmask, reginfo.ri_gp_value);
17189 printf (" "
17190 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17191 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17192 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17193 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17194 }
fd17d1e6 17195 offset += option.size;
a6e9f9df 17196 continue;
2e6be59c 17197
a6e9f9df
AM
17198 case ODK_EXCEPTIONS:
17199 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 17200 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 17201 fputs (") fpe_max(", stdout);
fd17d1e6 17202 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
17203 fputs (")", stdout);
17204
fd17d1e6 17205 if (option.info & OEX_PAGE0)
a6e9f9df 17206 fputs (" PAGE0", stdout);
fd17d1e6 17207 if (option.info & OEX_SMM)
a6e9f9df 17208 fputs (" SMM", stdout);
fd17d1e6 17209 if (option.info & OEX_FPDBUG)
a6e9f9df 17210 fputs (" FPDBUG", stdout);
fd17d1e6 17211 if (option.info & OEX_DISMISS)
a6e9f9df
AM
17212 fputs (" DISMISS", stdout);
17213 break;
2e6be59c 17214
a6e9f9df
AM
17215 case ODK_PAD:
17216 fputs (" PAD ", stdout);
fd17d1e6 17217 if (option.info & OPAD_PREFIX)
a6e9f9df 17218 fputs (" PREFIX", stdout);
fd17d1e6 17219 if (option.info & OPAD_POSTFIX)
a6e9f9df 17220 fputs (" POSTFIX", stdout);
fd17d1e6 17221 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
17222 fputs (" SYMBOL", stdout);
17223 break;
2e6be59c 17224
a6e9f9df
AM
17225 case ODK_HWPATCH:
17226 fputs (" HWPATCH ", stdout);
fd17d1e6 17227 if (option.info & OHW_R4KEOP)
a6e9f9df 17228 fputs (" R4KEOP", stdout);
fd17d1e6 17229 if (option.info & OHW_R8KPFETCH)
a6e9f9df 17230 fputs (" R8KPFETCH", stdout);
fd17d1e6 17231 if (option.info & OHW_R5KEOP)
a6e9f9df 17232 fputs (" R5KEOP", stdout);
fd17d1e6 17233 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
17234 fputs (" R5KCVTL", stdout);
17235 break;
2e6be59c 17236
a6e9f9df
AM
17237 case ODK_FILL:
17238 fputs (" FILL ", stdout);
17239 /* XXX Print content of info word? */
17240 break;
2e6be59c 17241
a6e9f9df
AM
17242 case ODK_TAGS:
17243 fputs (" TAGS ", stdout);
17244 /* XXX Print content of info word? */
17245 break;
2e6be59c 17246
a6e9f9df
AM
17247 case ODK_HWAND:
17248 fputs (" HWAND ", stdout);
fd17d1e6 17249 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17250 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17251 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17252 fputs (" R4KEOP_CLEAN", stdout);
17253 break;
2e6be59c 17254
a6e9f9df
AM
17255 case ODK_HWOR:
17256 fputs (" HWOR ", stdout);
fd17d1e6 17257 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17258 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17259 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17260 fputs (" R4KEOP_CLEAN", stdout);
17261 break;
2e6be59c 17262
a6e9f9df 17263 case ODK_GP_GROUP:
d0c4e780 17264 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
17265 option.info & OGP_GROUP,
17266 (option.info & OGP_SELF) >> 16);
a6e9f9df 17267 break;
2e6be59c 17268
a6e9f9df 17269 case ODK_IDENT:
d0c4e780 17270 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
17271 option.info & OGP_GROUP,
17272 (option.info & OGP_SELF) >> 16);
a6e9f9df 17273 break;
2e6be59c 17274
a6e9f9df
AM
17275 default:
17276 /* This shouldn't happen. */
d0c4e780 17277 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 17278 option.kind, option.section, option.info);
a6e9f9df 17279 break;
252b5132 17280 }
a6e9f9df 17281
2cf0635d 17282 len = sizeof (* eopt);
fd17d1e6 17283 while (len < option.size)
82b1b41b 17284 {
fd17d1e6 17285 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 17286
82b1b41b
NC
17287 if (ISPRINT (datum))
17288 printf ("%c", datum);
17289 else
17290 printf ("\\%03o", datum);
17291 len ++;
17292 }
a6e9f9df 17293 fputs ("\n", stdout);
82b1b41b 17294
fd17d1e6 17295 offset += option.size;
252b5132 17296 }
a6e9f9df 17297 free (eopt);
252b5132 17298 }
32ec8896
NC
17299 else
17300 res = FALSE;
252b5132
RH
17301 }
17302
17303 if (conflicts_offset != 0 && conflictsno != 0)
17304 {
2cf0635d 17305 Elf32_Conflict * iconf;
252b5132
RH
17306 size_t cnt;
17307
978c4450 17308 if (filedata->dynamic_symbols == NULL)
252b5132 17309 {
591a748a 17310 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 17311 return FALSE;
252b5132
RH
17312 }
17313
7296a62a
NC
17314 /* PR 21345 - print a slightly more helpful error message
17315 if we are sure that the cmalloc will fail. */
645f43a8 17316 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
17317 {
17318 error (_("Overlarge number of conflicts detected: %lx\n"),
17319 (long) conflictsno);
17320 return FALSE;
17321 }
17322
3f5e193b 17323 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
17324 if (iconf == NULL)
17325 {
8b73c356 17326 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 17327 return FALSE;
252b5132
RH
17328 }
17329
9ea033b2 17330 if (is_32bit_elf)
252b5132 17331 {
2cf0635d 17332 Elf32_External_Conflict * econf32;
a6e9f9df 17333
3f5e193b 17334 econf32 = (Elf32_External_Conflict *)
95099889
AM
17335 get_data (NULL, filedata, conflicts_offset,
17336 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 17337 if (!econf32)
5a814d6d
AM
17338 {
17339 free (iconf);
17340 return FALSE;
17341 }
252b5132
RH
17342
17343 for (cnt = 0; cnt < conflictsno; ++cnt)
17344 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
17345
17346 free (econf32);
252b5132
RH
17347 }
17348 else
17349 {
2cf0635d 17350 Elf64_External_Conflict * econf64;
a6e9f9df 17351
3f5e193b 17352 econf64 = (Elf64_External_Conflict *)
95099889
AM
17353 get_data (NULL, filedata, conflicts_offset,
17354 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 17355 if (!econf64)
5a814d6d
AM
17356 {
17357 free (iconf);
17358 return FALSE;
17359 }
252b5132
RH
17360
17361 for (cnt = 0; cnt < conflictsno; ++cnt)
17362 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
17363
17364 free (econf64);
252b5132
RH
17365 }
17366
d3a49aa8
AM
17367 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
17368 "\nSection '.conflict' contains %lu entries:\n",
17369 (unsigned long) conflictsno),
c7e7ca54 17370 (unsigned long) conflictsno);
252b5132
RH
17371 puts (_(" Num: Index Value Name"));
17372
17373 for (cnt = 0; cnt < conflictsno; ++cnt)
17374 {
b34976b6 17375 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 17376
978c4450 17377 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 17378 printf (_("<corrupt symbol index>"));
d79b3d50 17379 else
e0a31db1
NC
17380 {
17381 Elf_Internal_Sym * psym;
17382
978c4450 17383 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
17384 print_vma (psym->st_value, FULL_HEX);
17385 putchar (' ');
978c4450
AM
17386 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17387 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17388 else
17389 printf (_("<corrupt: %14ld>"), psym->st_name);
17390 }
31104126 17391 putchar ('\n');
252b5132
RH
17392 }
17393
252b5132
RH
17394 free (iconf);
17395 }
17396
ccb4c951
RS
17397 if (pltgot != 0 && local_gotno != 0)
17398 {
91d6fa6a 17399 bfd_vma ent, local_end, global_end;
bbeee7ea 17400 size_t i, offset;
2cf0635d 17401 unsigned char * data;
82b1b41b 17402 unsigned char * data_end;
bbeee7ea 17403 int addr_size;
ccb4c951 17404
91d6fa6a 17405 ent = pltgot;
ccb4c951
RS
17406 addr_size = (is_32bit_elf ? 4 : 8);
17407 local_end = pltgot + local_gotno * addr_size;
ccb4c951 17408
74e1a04b
NC
17409 /* PR binutils/17533 file: 012-111227-0.004 */
17410 if (symtabno < gotsym)
17411 {
17412 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 17413 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 17414 return FALSE;
74e1a04b 17415 }
82b1b41b 17416
74e1a04b 17417 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
17418 /* PR 17531: file: 54c91a34. */
17419 if (global_end < local_end)
17420 {
17421 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 17422 return FALSE;
82b1b41b 17423 }
948f632f 17424
dda8d76d
NC
17425 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
17426 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
17427 global_end - pltgot, 1,
17428 _("Global Offset Table data"));
919383ac 17429 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 17430 data_end = data + (global_end - pltgot);
59245841 17431
ccb4c951
RS
17432 printf (_("\nPrimary GOT:\n"));
17433 printf (_(" Canonical gp value: "));
17434 print_vma (pltgot + 0x7ff0, LONG_HEX);
17435 printf ("\n\n");
17436
17437 printf (_(" Reserved entries:\n"));
17438 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
17439 addr_size * 2, _("Address"), _("Access"),
17440 addr_size * 2, _("Initial"));
82b1b41b 17441 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 17442 printf (_(" Lazy resolver\n"));
82b1b41b
NC
17443 if (ent == (bfd_vma) -1)
17444 goto got_print_fail;
75ec1fdb 17445
c4ab9505
MR
17446 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
17447 This entry will be used by some runtime loaders, to store the
17448 module pointer. Otherwise this is an ordinary local entry.
17449 PR 21344: Check for the entry being fully available before
17450 fetching it. */
17451 if (data
17452 && data + ent - pltgot + addr_size <= data_end
17453 && (byte_get (data + ent - pltgot, addr_size)
17454 >> (addr_size * 8 - 1)) != 0)
17455 {
17456 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17457 printf (_(" Module pointer (GNU extension)\n"));
17458 if (ent == (bfd_vma) -1)
17459 goto got_print_fail;
ccb4c951
RS
17460 }
17461 printf ("\n");
17462
f17e9d8a 17463 if (data != NULL && ent < local_end)
ccb4c951
RS
17464 {
17465 printf (_(" Local entries:\n"));
cc5914eb 17466 printf (" %*s %10s %*s\n",
2b692964
NC
17467 addr_size * 2, _("Address"), _("Access"),
17468 addr_size * 2, _("Initial"));
91d6fa6a 17469 while (ent < local_end)
ccb4c951 17470 {
82b1b41b 17471 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17472 printf ("\n");
82b1b41b
NC
17473 if (ent == (bfd_vma) -1)
17474 goto got_print_fail;
ccb4c951
RS
17475 }
17476 printf ("\n");
17477 }
17478
f17e9d8a 17479 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
17480 {
17481 int sym_width;
17482
17483 printf (_(" Global entries:\n"));
cc5914eb 17484 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
17485 addr_size * 2, _("Address"),
17486 _("Access"),
2b692964 17487 addr_size * 2, _("Initial"),
9cf03b7e
NC
17488 addr_size * 2, _("Sym.Val."),
17489 _("Type"),
17490 /* Note for translators: "Ndx" = abbreviated form of "Index". */
17491 _("Ndx"), _("Name"));
0b4362b0 17492
ccb4c951 17493 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 17494
ccb4c951
RS
17495 for (i = gotsym; i < symtabno; i++)
17496 {
82b1b41b 17497 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17498 printf (" ");
e0a31db1 17499
978c4450 17500 if (filedata->dynamic_symbols == NULL)
e0a31db1 17501 printf (_("<no dynamic symbols>"));
978c4450 17502 else if (i < filedata->num_dynamic_syms)
e0a31db1 17503 {
978c4450 17504 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
17505
17506 print_vma (psym->st_value, LONG_HEX);
17507 printf (" %-7s %3s ",
dda8d76d
NC
17508 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17509 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 17510
978c4450
AM
17511 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17512 print_symbol (sym_width,
17513 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17514 else
17515 printf (_("<corrupt: %14ld>"), psym->st_name);
17516 }
ccb4c951 17517 else
7fc5ac57
JBG
17518 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
17519 (unsigned long) i);
e0a31db1 17520
ccb4c951 17521 printf ("\n");
82b1b41b
NC
17522 if (ent == (bfd_vma) -1)
17523 break;
ccb4c951
RS
17524 }
17525 printf ("\n");
17526 }
17527
82b1b41b 17528 got_print_fail:
9db70fc3 17529 free (data);
ccb4c951
RS
17530 }
17531
861fb55a
DJ
17532 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
17533 {
91d6fa6a 17534 bfd_vma ent, end;
861fb55a
DJ
17535 size_t offset, rel_offset;
17536 unsigned long count, i;
2cf0635d 17537 unsigned char * data;
861fb55a 17538 int addr_size, sym_width;
2cf0635d 17539 Elf_Internal_Rela * rels;
861fb55a 17540
dda8d76d 17541 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
17542 if (pltrel == DT_RELA)
17543 {
dda8d76d 17544 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17545 return FALSE;
861fb55a
DJ
17546 }
17547 else
17548 {
dda8d76d 17549 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17550 return FALSE;
861fb55a
DJ
17551 }
17552
91d6fa6a 17553 ent = mips_pltgot;
861fb55a
DJ
17554 addr_size = (is_32bit_elf ? 4 : 8);
17555 end = mips_pltgot + (2 + count) * addr_size;
17556
dda8d76d
NC
17557 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
17558 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 17559 1, _("Procedure Linkage Table data"));
59245841 17560 if (data == NULL)
32ec8896 17561 return FALSE;
59245841 17562
9cf03b7e 17563 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
17564 printf (_(" Reserved entries:\n"));
17565 printf (_(" %*s %*s Purpose\n"),
2b692964 17566 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 17567 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17568 printf (_(" PLT lazy resolver\n"));
91d6fa6a 17569 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17570 printf (_(" Module pointer\n"));
861fb55a
DJ
17571 printf ("\n");
17572
17573 printf (_(" Entries:\n"));
cc5914eb 17574 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
17575 addr_size * 2, _("Address"),
17576 addr_size * 2, _("Initial"),
17577 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
17578 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
17579 for (i = 0; i < count; i++)
17580 {
df97ab2a 17581 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 17582
91d6fa6a 17583 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 17584 printf (" ");
e0a31db1 17585
978c4450 17586 if (idx >= filedata->num_dynamic_syms)
df97ab2a 17587 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 17588 else
e0a31db1 17589 {
978c4450 17590 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
17591
17592 print_vma (psym->st_value, LONG_HEX);
17593 printf (" %-7s %3s ",
dda8d76d
NC
17594 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17595 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
17596 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17597 print_symbol (sym_width,
17598 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17599 else
17600 printf (_("<corrupt: %14ld>"), psym->st_name);
17601 }
861fb55a
DJ
17602 printf ("\n");
17603 }
17604 printf ("\n");
17605
9db70fc3 17606 free (data);
861fb55a
DJ
17607 free (rels);
17608 }
17609
32ec8896 17610 return res;
252b5132
RH
17611}
17612
32ec8896 17613static bfd_boolean
dda8d76d 17614process_nds32_specific (Filedata * filedata)
35c08157
KLC
17615{
17616 Elf_Internal_Shdr *sect = NULL;
17617
dda8d76d 17618 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 17619 if (sect != NULL && sect->sh_size >= 4)
35c08157 17620 {
9c7b8e9b
AM
17621 unsigned char *buf;
17622 unsigned int flag;
35c08157
KLC
17623
17624 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
17625 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
17626 _("NDS32 elf flags section"));
35c08157 17627
9c7b8e9b 17628 if (buf == NULL)
32ec8896
NC
17629 return FALSE;
17630
9c7b8e9b
AM
17631 flag = byte_get (buf, 4);
17632 free (buf);
17633 switch (flag & 0x3)
35c08157
KLC
17634 {
17635 case 0:
17636 printf ("(VEC_SIZE):\tNo entry.\n");
17637 break;
17638 case 1:
17639 printf ("(VEC_SIZE):\t4 bytes\n");
17640 break;
17641 case 2:
17642 printf ("(VEC_SIZE):\t16 bytes\n");
17643 break;
17644 case 3:
17645 printf ("(VEC_SIZE):\treserved\n");
17646 break;
17647 }
17648 }
17649
17650 return TRUE;
17651}
17652
32ec8896 17653static bfd_boolean
dda8d76d 17654process_gnu_liblist (Filedata * filedata)
047b2264 17655{
2cf0635d
NC
17656 Elf_Internal_Shdr * section;
17657 Elf_Internal_Shdr * string_sec;
17658 Elf32_External_Lib * elib;
17659 char * strtab;
c256ffe7 17660 size_t strtab_size;
047b2264 17661 size_t cnt;
d3a49aa8 17662 unsigned long num_liblist;
047b2264 17663 unsigned i;
32ec8896 17664 bfd_boolean res = TRUE;
047b2264
JJ
17665
17666 if (! do_arch)
32ec8896 17667 return TRUE;
047b2264 17668
dda8d76d
NC
17669 for (i = 0, section = filedata->section_headers;
17670 i < filedata->file_header.e_shnum;
b34976b6 17671 i++, section++)
047b2264
JJ
17672 {
17673 switch (section->sh_type)
17674 {
17675 case SHT_GNU_LIBLIST:
dda8d76d 17676 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
17677 break;
17678
3f5e193b 17679 elib = (Elf32_External_Lib *)
dda8d76d 17680 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 17681 _("liblist section data"));
047b2264
JJ
17682
17683 if (elib == NULL)
32ec8896
NC
17684 {
17685 res = FALSE;
17686 break;
17687 }
047b2264 17688
dda8d76d
NC
17689 string_sec = filedata->section_headers + section->sh_link;
17690 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
17691 string_sec->sh_size,
17692 _("liblist string table"));
047b2264
JJ
17693 if (strtab == NULL
17694 || section->sh_entsize != sizeof (Elf32_External_Lib))
17695 {
17696 free (elib);
2842702f 17697 free (strtab);
32ec8896 17698 res = FALSE;
047b2264
JJ
17699 break;
17700 }
59245841 17701 strtab_size = string_sec->sh_size;
047b2264 17702
d3a49aa8
AM
17703 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
17704 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
17705 "\nLibrary list section '%s' contains %lu entries:\n",
17706 num_liblist),
dda8d76d 17707 printable_section_name (filedata, section),
d3a49aa8 17708 num_liblist);
047b2264 17709
2b692964 17710 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
17711
17712 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
17713 ++cnt)
17714 {
17715 Elf32_Lib liblist;
91d6fa6a 17716 time_t atime;
d5b07ef4 17717 char timebuf[128];
2cf0635d 17718 struct tm * tmp;
047b2264
JJ
17719
17720 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17721 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
17722 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17723 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17724 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17725
91d6fa6a 17726 tmp = gmtime (&atime);
e9e44622
JJ
17727 snprintf (timebuf, sizeof (timebuf),
17728 "%04u-%02u-%02uT%02u:%02u:%02u",
17729 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17730 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
17731
17732 printf ("%3lu: ", (unsigned long) cnt);
17733 if (do_wide)
c256ffe7 17734 printf ("%-20s", liblist.l_name < strtab_size
2b692964 17735 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 17736 else
c256ffe7 17737 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 17738 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
17739 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
17740 liblist.l_version, liblist.l_flags);
17741 }
17742
17743 free (elib);
2842702f 17744 free (strtab);
047b2264
JJ
17745 }
17746 }
17747
32ec8896 17748 return res;
047b2264
JJ
17749}
17750
9437c45b 17751static const char *
dda8d76d 17752get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
17753{
17754 static char buff[64];
103f02d3 17755
dda8d76d 17756 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
17757 switch (e_type)
17758 {
57346661 17759 case NT_AUXV:
1ec5cd37 17760 return _("NT_AUXV (auxiliary vector)");
57346661 17761 case NT_PRSTATUS:
1ec5cd37 17762 return _("NT_PRSTATUS (prstatus structure)");
57346661 17763 case NT_FPREGSET:
1ec5cd37 17764 return _("NT_FPREGSET (floating point registers)");
57346661 17765 case NT_PRPSINFO:
1ec5cd37 17766 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 17767 case NT_TASKSTRUCT:
1ec5cd37 17768 return _("NT_TASKSTRUCT (task structure)");
57346661 17769 case NT_PRXFPREG:
1ec5cd37 17770 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
17771 case NT_PPC_VMX:
17772 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
17773 case NT_PPC_VSX:
17774 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
17775 case NT_PPC_TAR:
17776 return _("NT_PPC_TAR (ppc TAR register)");
17777 case NT_PPC_PPR:
17778 return _("NT_PPC_PPR (ppc PPR register)");
17779 case NT_PPC_DSCR:
17780 return _("NT_PPC_DSCR (ppc DSCR register)");
17781 case NT_PPC_EBB:
17782 return _("NT_PPC_EBB (ppc EBB registers)");
17783 case NT_PPC_PMU:
17784 return _("NT_PPC_PMU (ppc PMU registers)");
17785 case NT_PPC_TM_CGPR:
17786 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
17787 case NT_PPC_TM_CFPR:
17788 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
17789 case NT_PPC_TM_CVMX:
17790 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
17791 case NT_PPC_TM_CVSX:
3fd21718 17792 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
17793 case NT_PPC_TM_SPR:
17794 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
17795 case NT_PPC_TM_CTAR:
17796 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
17797 case NT_PPC_TM_CPPR:
17798 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
17799 case NT_PPC_TM_CDSCR:
17800 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
17801 case NT_386_TLS:
17802 return _("NT_386_TLS (x86 TLS information)");
17803 case NT_386_IOPERM:
17804 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
17805 case NT_X86_XSTATE:
17806 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
17807 case NT_S390_HIGH_GPRS:
17808 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
17809 case NT_S390_TIMER:
17810 return _("NT_S390_TIMER (s390 timer register)");
17811 case NT_S390_TODCMP:
17812 return _("NT_S390_TODCMP (s390 TOD comparator register)");
17813 case NT_S390_TODPREG:
17814 return _("NT_S390_TODPREG (s390 TOD programmable register)");
17815 case NT_S390_CTRS:
17816 return _("NT_S390_CTRS (s390 control registers)");
17817 case NT_S390_PREFIX:
17818 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
17819 case NT_S390_LAST_BREAK:
17820 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
17821 case NT_S390_SYSTEM_CALL:
17822 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
17823 case NT_S390_TDB:
17824 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
17825 case NT_S390_VXRS_LOW:
17826 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
17827 case NT_S390_VXRS_HIGH:
17828 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
17829 case NT_S390_GS_CB:
17830 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
17831 case NT_S390_GS_BC:
17832 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
17833 case NT_ARM_VFP:
17834 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
17835 case NT_ARM_TLS:
17836 return _("NT_ARM_TLS (AArch TLS registers)");
17837 case NT_ARM_HW_BREAK:
17838 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
17839 case NT_ARM_HW_WATCH:
17840 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
17841 case NT_ARC_V2:
17842 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
57346661 17843 case NT_PSTATUS:
1ec5cd37 17844 return _("NT_PSTATUS (pstatus structure)");
57346661 17845 case NT_FPREGS:
1ec5cd37 17846 return _("NT_FPREGS (floating point registers)");
57346661 17847 case NT_PSINFO:
1ec5cd37 17848 return _("NT_PSINFO (psinfo structure)");
57346661 17849 case NT_LWPSTATUS:
1ec5cd37 17850 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 17851 case NT_LWPSINFO:
1ec5cd37 17852 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 17853 case NT_WIN32PSTATUS:
1ec5cd37 17854 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
17855 case NT_SIGINFO:
17856 return _("NT_SIGINFO (siginfo_t data)");
17857 case NT_FILE:
17858 return _("NT_FILE (mapped files)");
1ec5cd37
NC
17859 default:
17860 break;
17861 }
17862 else
17863 switch (e_type)
17864 {
17865 case NT_VERSION:
17866 return _("NT_VERSION (version)");
17867 case NT_ARCH:
17868 return _("NT_ARCH (architecture)");
9ef920e9 17869 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 17870 return _("OPEN");
9ef920e9 17871 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 17872 return _("func");
1ec5cd37
NC
17873 default:
17874 break;
17875 }
17876
e9e44622 17877 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 17878 return buff;
779fe533
NC
17879}
17880
32ec8896 17881static bfd_boolean
9ece1fa9
TT
17882print_core_note (Elf_Internal_Note *pnote)
17883{
17884 unsigned int addr_size = is_32bit_elf ? 4 : 8;
17885 bfd_vma count, page_size;
17886 unsigned char *descdata, *filenames, *descend;
17887
17888 if (pnote->type != NT_FILE)
04ac15ab
AS
17889 {
17890 if (do_wide)
17891 printf ("\n");
17892 return TRUE;
17893 }
9ece1fa9
TT
17894
17895#ifndef BFD64
17896 if (!is_32bit_elf)
17897 {
17898 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
17899 /* Still "successful". */
32ec8896 17900 return TRUE;
9ece1fa9
TT
17901 }
17902#endif
17903
17904 if (pnote->descsz < 2 * addr_size)
17905 {
32ec8896
NC
17906 error (_(" Malformed note - too short for header\n"));
17907 return FALSE;
9ece1fa9
TT
17908 }
17909
17910 descdata = (unsigned char *) pnote->descdata;
17911 descend = descdata + pnote->descsz;
17912
17913 if (descdata[pnote->descsz - 1] != '\0')
17914 {
32ec8896
NC
17915 error (_(" Malformed note - does not end with \\0\n"));
17916 return FALSE;
9ece1fa9
TT
17917 }
17918
17919 count = byte_get (descdata, addr_size);
17920 descdata += addr_size;
17921
17922 page_size = byte_get (descdata, addr_size);
17923 descdata += addr_size;
17924
5396a86e
AM
17925 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
17926 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 17927 {
32ec8896
NC
17928 error (_(" Malformed note - too short for supplied file count\n"));
17929 return FALSE;
9ece1fa9
TT
17930 }
17931
17932 printf (_(" Page size: "));
17933 print_vma (page_size, DEC);
17934 printf ("\n");
17935
17936 printf (_(" %*s%*s%*s\n"),
17937 (int) (2 + 2 * addr_size), _("Start"),
17938 (int) (4 + 2 * addr_size), _("End"),
17939 (int) (4 + 2 * addr_size), _("Page Offset"));
17940 filenames = descdata + count * 3 * addr_size;
595712bb 17941 while (count-- > 0)
9ece1fa9
TT
17942 {
17943 bfd_vma start, end, file_ofs;
17944
17945 if (filenames == descend)
17946 {
32ec8896
NC
17947 error (_(" Malformed note - filenames end too early\n"));
17948 return FALSE;
9ece1fa9
TT
17949 }
17950
17951 start = byte_get (descdata, addr_size);
17952 descdata += addr_size;
17953 end = byte_get (descdata, addr_size);
17954 descdata += addr_size;
17955 file_ofs = byte_get (descdata, addr_size);
17956 descdata += addr_size;
17957
17958 printf (" ");
17959 print_vma (start, FULL_HEX);
17960 printf (" ");
17961 print_vma (end, FULL_HEX);
17962 printf (" ");
17963 print_vma (file_ofs, FULL_HEX);
17964 printf ("\n %s\n", filenames);
17965
17966 filenames += 1 + strlen ((char *) filenames);
17967 }
17968
32ec8896 17969 return TRUE;
9ece1fa9
TT
17970}
17971
1118d252
RM
17972static const char *
17973get_gnu_elf_note_type (unsigned e_type)
17974{
1449284b 17975 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
17976 switch (e_type)
17977 {
17978 case NT_GNU_ABI_TAG:
17979 return _("NT_GNU_ABI_TAG (ABI version tag)");
17980 case NT_GNU_HWCAP:
17981 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
17982 case NT_GNU_BUILD_ID:
17983 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
17984 case NT_GNU_GOLD_VERSION:
17985 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
17986 case NT_GNU_PROPERTY_TYPE_0:
17987 return _("NT_GNU_PROPERTY_TYPE_0");
17988 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
17989 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
17990 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
17991 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 17992 default:
1449284b
NC
17993 {
17994 static char buff[64];
1118d252 17995
1449284b
NC
17996 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17997 return buff;
17998 }
17999 }
1118d252
RM
18000}
18001
a9eafb08
L
18002static void
18003decode_x86_compat_isa (unsigned int bitmask)
18004{
18005 while (bitmask)
18006 {
18007 unsigned int bit = bitmask & (- bitmask);
18008
18009 bitmask &= ~ bit;
18010 switch (bit)
18011 {
18012 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18013 printf ("i486");
18014 break;
18015 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18016 printf ("586");
18017 break;
18018 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18019 printf ("686");
18020 break;
18021 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18022 printf ("SSE");
18023 break;
18024 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18025 printf ("SSE2");
18026 break;
18027 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18028 printf ("SSE3");
18029 break;
18030 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18031 printf ("SSSE3");
18032 break;
18033 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18034 printf ("SSE4_1");
18035 break;
18036 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18037 printf ("SSE4_2");
18038 break;
18039 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18040 printf ("AVX");
18041 break;
18042 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18043 printf ("AVX2");
18044 break;
18045 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18046 printf ("AVX512F");
18047 break;
18048 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18049 printf ("AVX512CD");
18050 break;
18051 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18052 printf ("AVX512ER");
18053 break;
18054 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18055 printf ("AVX512PF");
18056 break;
18057 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18058 printf ("AVX512VL");
18059 break;
18060 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18061 printf ("AVX512DQ");
18062 break;
18063 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18064 printf ("AVX512BW");
18065 break;
65b3d26e
L
18066 default:
18067 printf (_("<unknown: %x>"), bit);
18068 break;
a9eafb08
L
18069 }
18070 if (bitmask)
18071 printf (", ");
18072 }
18073}
18074
9ef920e9 18075static void
1fc87489 18076decode_x86_isa (unsigned int bitmask)
9ef920e9 18077{
0a59decb 18078 if (!bitmask)
90c745dc
L
18079 {
18080 printf (_("<None>"));
18081 return;
18082 }
90c745dc 18083
9ef920e9
NC
18084 while (bitmask)
18085 {
1fc87489 18086 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18087
18088 bitmask &= ~ bit;
18089 switch (bit)
18090 {
a9eafb08
L
18091 case GNU_PROPERTY_X86_ISA_1_CMOV:
18092 printf ("CMOV");
18093 break;
18094 case GNU_PROPERTY_X86_ISA_1_SSE:
18095 printf ("SSE");
18096 break;
18097 case GNU_PROPERTY_X86_ISA_1_SSE2:
18098 printf ("SSE2");
18099 break;
18100 case GNU_PROPERTY_X86_ISA_1_SSE3:
18101 printf ("SSE3");
18102 break;
18103 case GNU_PROPERTY_X86_ISA_1_SSSE3:
18104 printf ("SSSE3");
18105 break;
18106 case GNU_PROPERTY_X86_ISA_1_SSE4_1:
18107 printf ("SSE4_1");
18108 break;
18109 case GNU_PROPERTY_X86_ISA_1_SSE4_2:
18110 printf ("SSE4_2");
18111 break;
18112 case GNU_PROPERTY_X86_ISA_1_AVX:
18113 printf ("AVX");
18114 break;
18115 case GNU_PROPERTY_X86_ISA_1_AVX2:
18116 printf ("AVX2");
18117 break;
18118 case GNU_PROPERTY_X86_ISA_1_FMA:
18119 printf ("FMA");
18120 break;
18121 case GNU_PROPERTY_X86_ISA_1_AVX512F:
18122 printf ("AVX512F");
18123 break;
18124 case GNU_PROPERTY_X86_ISA_1_AVX512CD:
18125 printf ("AVX512CD");
18126 break;
18127 case GNU_PROPERTY_X86_ISA_1_AVX512ER:
18128 printf ("AVX512ER");
18129 break;
18130 case GNU_PROPERTY_X86_ISA_1_AVX512PF:
18131 printf ("AVX512PF");
18132 break;
18133 case GNU_PROPERTY_X86_ISA_1_AVX512VL:
18134 printf ("AVX512VL");
18135 break;
18136 case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
18137 printf ("AVX512DQ");
18138 break;
18139 case GNU_PROPERTY_X86_ISA_1_AVX512BW:
18140 printf ("AVX512BW");
18141 break;
18142 case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
18143 printf ("AVX512_4FMAPS");
18144 break;
18145 case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
18146 printf ("AVX512_4VNNIW");
18147 break;
18148 case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
18149 printf ("AVX512_BITALG");
18150 break;
18151 case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
18152 printf ("AVX512_IFMA");
18153 break;
18154 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
18155 printf ("AVX512_VBMI");
18156 break;
18157 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
18158 printf ("AVX512_VBMI2");
18159 break;
18160 case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
18161 printf ("AVX512_VNNI");
18162 break;
462cac58
L
18163 case GNU_PROPERTY_X86_ISA_1_AVX512_BF16:
18164 printf ("AVX512_BF16");
18165 break;
65b3d26e
L
18166 default:
18167 printf (_("<unknown: %x>"), bit);
18168 break;
9ef920e9
NC
18169 }
18170 if (bitmask)
18171 printf (", ");
18172 }
18173}
18174
ee2fdd6f 18175static void
a9eafb08 18176decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 18177{
0a59decb 18178 if (!bitmask)
90c745dc
L
18179 {
18180 printf (_("<None>"));
18181 return;
18182 }
90c745dc 18183
ee2fdd6f
L
18184 while (bitmask)
18185 {
18186 unsigned int bit = bitmask & (- bitmask);
18187
18188 bitmask &= ~ bit;
18189 switch (bit)
18190 {
18191 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 18192 printf ("IBT");
ee2fdd6f 18193 break;
48580982 18194 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 18195 printf ("SHSTK");
48580982 18196 break;
ee2fdd6f
L
18197 default:
18198 printf (_("<unknown: %x>"), bit);
18199 break;
18200 }
18201 if (bitmask)
18202 printf (", ");
18203 }
18204}
18205
a9eafb08
L
18206static void
18207decode_x86_feature_2 (unsigned int bitmask)
18208{
0a59decb 18209 if (!bitmask)
90c745dc
L
18210 {
18211 printf (_("<None>"));
18212 return;
18213 }
90c745dc 18214
a9eafb08
L
18215 while (bitmask)
18216 {
18217 unsigned int bit = bitmask & (- bitmask);
18218
18219 bitmask &= ~ bit;
18220 switch (bit)
18221 {
18222 case GNU_PROPERTY_X86_FEATURE_2_X86:
18223 printf ("x86");
18224 break;
18225 case GNU_PROPERTY_X86_FEATURE_2_X87:
18226 printf ("x87");
18227 break;
18228 case GNU_PROPERTY_X86_FEATURE_2_MMX:
18229 printf ("MMX");
18230 break;
18231 case GNU_PROPERTY_X86_FEATURE_2_XMM:
18232 printf ("XMM");
18233 break;
18234 case GNU_PROPERTY_X86_FEATURE_2_YMM:
18235 printf ("YMM");
18236 break;
18237 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
18238 printf ("ZMM");
18239 break;
a308b89d
L
18240 case GNU_PROPERTY_X86_FEATURE_2_TMM:
18241 printf ("TMM");
18242 break;
a9eafb08
L
18243 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
18244 printf ("FXSR");
18245 break;
18246 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
18247 printf ("XSAVE");
18248 break;
18249 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
18250 printf ("XSAVEOPT");
18251 break;
18252 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
18253 printf ("XSAVEC");
18254 break;
65b3d26e
L
18255 default:
18256 printf (_("<unknown: %x>"), bit);
18257 break;
a9eafb08
L
18258 }
18259 if (bitmask)
18260 printf (", ");
18261 }
18262}
18263
cd702818
SD
18264static void
18265decode_aarch64_feature_1_and (unsigned int bitmask)
18266{
18267 while (bitmask)
18268 {
18269 unsigned int bit = bitmask & (- bitmask);
18270
18271 bitmask &= ~ bit;
18272 switch (bit)
18273 {
18274 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
18275 printf ("BTI");
18276 break;
18277
18278 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
18279 printf ("PAC");
18280 break;
18281
18282 default:
18283 printf (_("<unknown: %x>"), bit);
18284 break;
18285 }
18286 if (bitmask)
18287 printf (", ");
18288 }
18289}
18290
9ef920e9 18291static void
dda8d76d 18292print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
18293{
18294 unsigned char * ptr = (unsigned char *) pnote->descdata;
18295 unsigned char * ptr_end = ptr + pnote->descsz;
18296 unsigned int size = is_32bit_elf ? 4 : 8;
18297
18298 printf (_(" Properties: "));
18299
1fc87489 18300 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
18301 {
18302 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
18303 return;
18304 }
18305
6ab2c4ed 18306 while (ptr < ptr_end)
9ef920e9 18307 {
1fc87489 18308 unsigned int j;
6ab2c4ed
MC
18309 unsigned int type;
18310 unsigned int datasz;
18311
18312 if ((size_t) (ptr_end - ptr) < 8)
18313 {
18314 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
18315 break;
18316 }
18317
18318 type = byte_get (ptr, 4);
18319 datasz = byte_get (ptr + 4, 4);
9ef920e9 18320
1fc87489 18321 ptr += 8;
9ef920e9 18322
6ab2c4ed 18323 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 18324 {
1fc87489
L
18325 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
18326 type, datasz);
9ef920e9 18327 break;
1fc87489 18328 }
9ef920e9 18329
1fc87489
L
18330 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
18331 {
dda8d76d
NC
18332 if (filedata->file_header.e_machine == EM_X86_64
18333 || filedata->file_header.e_machine == EM_IAMCU
18334 || filedata->file_header.e_machine == EM_386)
1fc87489 18335 {
aa7bca9b
L
18336 unsigned int bitmask;
18337
18338 if (datasz == 4)
0a59decb 18339 bitmask = byte_get (ptr, 4);
aa7bca9b
L
18340 else
18341 bitmask = 0;
18342
1fc87489
L
18343 switch (type)
18344 {
18345 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 18346 if (datasz != 4)
aa7bca9b
L
18347 printf (_("x86 ISA used: <corrupt length: %#x> "),
18348 datasz);
1fc87489 18349 else
aa7bca9b
L
18350 {
18351 printf ("x86 ISA used: ");
18352 decode_x86_isa (bitmask);
18353 }
1fc87489 18354 goto next;
9ef920e9 18355
1fc87489 18356 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 18357 if (datasz != 4)
aa7bca9b
L
18358 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18359 datasz);
1fc87489 18360 else
aa7bca9b
L
18361 {
18362 printf ("x86 ISA needed: ");
18363 decode_x86_isa (bitmask);
18364 }
1fc87489 18365 goto next;
9ef920e9 18366
ee2fdd6f 18367 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 18368 if (datasz != 4)
aa7bca9b
L
18369 printf (_("x86 feature: <corrupt length: %#x> "),
18370 datasz);
ee2fdd6f 18371 else
aa7bca9b
L
18372 {
18373 printf ("x86 feature: ");
a9eafb08
L
18374 decode_x86_feature_1 (bitmask);
18375 }
18376 goto next;
18377
18378 case GNU_PROPERTY_X86_FEATURE_2_USED:
18379 if (datasz != 4)
18380 printf (_("x86 feature used: <corrupt length: %#x> "),
18381 datasz);
18382 else
18383 {
18384 printf ("x86 feature used: ");
18385 decode_x86_feature_2 (bitmask);
18386 }
18387 goto next;
18388
18389 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
18390 if (datasz != 4)
18391 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
18392 else
18393 {
18394 printf ("x86 feature needed: ");
18395 decode_x86_feature_2 (bitmask);
18396 }
18397 goto next;
18398
18399 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
18400 if (datasz != 4)
18401 printf (_("x86 ISA used: <corrupt length: %#x> "),
18402 datasz);
18403 else
18404 {
18405 printf ("x86 ISA used: ");
18406 decode_x86_compat_isa (bitmask);
18407 }
18408 goto next;
18409
18410 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
18411 if (datasz != 4)
18412 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18413 datasz);
18414 else
18415 {
18416 printf ("x86 ISA needed: ");
18417 decode_x86_compat_isa (bitmask);
aa7bca9b 18418 }
ee2fdd6f
L
18419 goto next;
18420
1fc87489
L
18421 default:
18422 break;
18423 }
18424 }
cd702818
SD
18425 else if (filedata->file_header.e_machine == EM_AARCH64)
18426 {
18427 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
18428 {
18429 printf ("AArch64 feature: ");
18430 if (datasz != 4)
18431 printf (_("<corrupt length: %#x> "), datasz);
18432 else
18433 decode_aarch64_feature_1_and (byte_get (ptr, 4));
18434 goto next;
18435 }
18436 }
1fc87489
L
18437 }
18438 else
18439 {
18440 switch (type)
9ef920e9 18441 {
1fc87489
L
18442 case GNU_PROPERTY_STACK_SIZE:
18443 printf (_("stack size: "));
18444 if (datasz != size)
18445 printf (_("<corrupt length: %#x> "), datasz);
18446 else
18447 printf ("%#lx", (unsigned long) byte_get (ptr, size));
18448 goto next;
18449
18450 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
18451 printf ("no copy on protected ");
18452 if (datasz)
18453 printf (_("<corrupt length: %#x> "), datasz);
18454 goto next;
18455
18456 default:
9ef920e9
NC
18457 break;
18458 }
9ef920e9
NC
18459 }
18460
1fc87489
L
18461 if (type < GNU_PROPERTY_LOPROC)
18462 printf (_("<unknown type %#x data: "), type);
18463 else if (type < GNU_PROPERTY_LOUSER)
18464 printf (_("<procesor-specific type %#x data: "), type);
18465 else
18466 printf (_("<application-specific type %#x data: "), type);
18467 for (j = 0; j < datasz; ++j)
18468 printf ("%02x ", ptr[j] & 0xff);
18469 printf (">");
18470
dc1e8a47 18471 next:
9ef920e9 18472 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
18473 if (ptr == ptr_end)
18474 break;
1fc87489 18475
6ab2c4ed
MC
18476 if (do_wide)
18477 printf (", ");
18478 else
18479 printf ("\n\t");
9ef920e9
NC
18480 }
18481
18482 printf ("\n");
18483}
18484
32ec8896 18485static bfd_boolean
dda8d76d 18486print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 18487{
1449284b 18488 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
18489 switch (pnote->type)
18490 {
18491 case NT_GNU_BUILD_ID:
18492 {
18493 unsigned long i;
18494
18495 printf (_(" Build ID: "));
18496 for (i = 0; i < pnote->descsz; ++i)
18497 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 18498 printf ("\n");
664f90a3
TT
18499 }
18500 break;
18501
18502 case NT_GNU_ABI_TAG:
18503 {
18504 unsigned long os, major, minor, subminor;
18505 const char *osname;
18506
3102e897
NC
18507 /* PR 17531: file: 030-599401-0.004. */
18508 if (pnote->descsz < 16)
18509 {
18510 printf (_(" <corrupt GNU_ABI_TAG>\n"));
18511 break;
18512 }
18513
664f90a3
TT
18514 os = byte_get ((unsigned char *) pnote->descdata, 4);
18515 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18516 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
18517 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
18518
18519 switch (os)
18520 {
18521 case GNU_ABI_TAG_LINUX:
18522 osname = "Linux";
18523 break;
18524 case GNU_ABI_TAG_HURD:
18525 osname = "Hurd";
18526 break;
18527 case GNU_ABI_TAG_SOLARIS:
18528 osname = "Solaris";
18529 break;
18530 case GNU_ABI_TAG_FREEBSD:
18531 osname = "FreeBSD";
18532 break;
18533 case GNU_ABI_TAG_NETBSD:
18534 osname = "NetBSD";
18535 break;
14ae95f2
RM
18536 case GNU_ABI_TAG_SYLLABLE:
18537 osname = "Syllable";
18538 break;
18539 case GNU_ABI_TAG_NACL:
18540 osname = "NaCl";
18541 break;
664f90a3
TT
18542 default:
18543 osname = "Unknown";
18544 break;
18545 }
18546
18547 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
18548 major, minor, subminor);
18549 }
18550 break;
926c5385
CC
18551
18552 case NT_GNU_GOLD_VERSION:
18553 {
18554 unsigned long i;
18555
18556 printf (_(" Version: "));
18557 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
18558 printf ("%c", pnote->descdata[i]);
18559 printf ("\n");
18560 }
18561 break;
1449284b
NC
18562
18563 case NT_GNU_HWCAP:
18564 {
18565 unsigned long num_entries, mask;
18566
18567 /* Hardware capabilities information. Word 0 is the number of entries.
18568 Word 1 is a bitmask of enabled entries. The rest of the descriptor
18569 is a series of entries, where each entry is a single byte followed
18570 by a nul terminated string. The byte gives the bit number to test
18571 if enabled in the bitmask. */
18572 printf (_(" Hardware Capabilities: "));
18573 if (pnote->descsz < 8)
18574 {
32ec8896
NC
18575 error (_("<corrupt GNU_HWCAP>\n"));
18576 return FALSE;
1449284b
NC
18577 }
18578 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
18579 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18580 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
18581 /* FIXME: Add code to display the entries... */
18582 }
18583 break;
18584
9ef920e9 18585 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 18586 print_gnu_property_note (filedata, pnote);
9ef920e9 18587 break;
9abca702 18588
1449284b
NC
18589 default:
18590 /* Handle unrecognised types. An error message should have already been
18591 created by get_gnu_elf_note_type(), so all that we need to do is to
18592 display the data. */
18593 {
18594 unsigned long i;
18595
18596 printf (_(" Description data: "));
18597 for (i = 0; i < pnote->descsz; ++i)
18598 printf ("%02x ", pnote->descdata[i] & 0xff);
18599 printf ("\n");
18600 }
18601 break;
664f90a3
TT
18602 }
18603
32ec8896 18604 return TRUE;
664f90a3
TT
18605}
18606
685080f2
NC
18607static const char *
18608get_v850_elf_note_type (enum v850_notes n_type)
18609{
18610 static char buff[64];
18611
18612 switch (n_type)
18613 {
18614 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
18615 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
18616 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
18617 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
18618 case V850_NOTE_CACHE_INFO: return _("Use of cache");
18619 case V850_NOTE_MMU_INFO: return _("Use of MMU");
18620 default:
18621 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
18622 return buff;
18623 }
18624}
18625
32ec8896 18626static bfd_boolean
685080f2
NC
18627print_v850_note (Elf_Internal_Note * pnote)
18628{
18629 unsigned int val;
18630
18631 if (pnote->descsz != 4)
32ec8896
NC
18632 return FALSE;
18633
685080f2
NC
18634 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
18635
18636 if (val == 0)
18637 {
18638 printf (_("not set\n"));
32ec8896 18639 return TRUE;
685080f2
NC
18640 }
18641
18642 switch (pnote->type)
18643 {
18644 case V850_NOTE_ALIGNMENT:
18645 switch (val)
18646 {
32ec8896
NC
18647 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
18648 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
18649 }
18650 break;
14ae95f2 18651
685080f2
NC
18652 case V850_NOTE_DATA_SIZE:
18653 switch (val)
18654 {
32ec8896
NC
18655 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
18656 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
18657 }
18658 break;
14ae95f2 18659
685080f2
NC
18660 case V850_NOTE_FPU_INFO:
18661 switch (val)
18662 {
32ec8896
NC
18663 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
18664 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
18665 }
18666 break;
14ae95f2 18667
685080f2
NC
18668 case V850_NOTE_MMU_INFO:
18669 case V850_NOTE_CACHE_INFO:
18670 case V850_NOTE_SIMD_INFO:
18671 if (val == EF_RH850_SIMD)
18672 {
18673 printf (_("yes\n"));
32ec8896 18674 return TRUE;
685080f2
NC
18675 }
18676 break;
18677
18678 default:
18679 /* An 'unknown note type' message will already have been displayed. */
18680 break;
18681 }
18682
18683 printf (_("unknown value: %x\n"), val);
32ec8896 18684 return FALSE;
685080f2
NC
18685}
18686
32ec8896 18687static bfd_boolean
c6056a74
SF
18688process_netbsd_elf_note (Elf_Internal_Note * pnote)
18689{
18690 unsigned int version;
18691
18692 switch (pnote->type)
18693 {
18694 case NT_NETBSD_IDENT:
b966f55f
AM
18695 if (pnote->descsz < 1)
18696 break;
c6056a74
SF
18697 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18698 if ((version / 10000) % 100)
b966f55f 18699 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
18700 version, version / 100000000, (version / 1000000) % 100,
18701 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 18702 'A' + (version / 10000) % 26);
c6056a74
SF
18703 else
18704 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 18705 version, version / 100000000, (version / 1000000) % 100,
15f205b1 18706 (version / 100) % 100);
32ec8896 18707 return TRUE;
c6056a74
SF
18708
18709 case NT_NETBSD_MARCH:
9abca702 18710 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 18711 pnote->descdata);
32ec8896 18712 return TRUE;
c6056a74 18713
9abca702
CZ
18714#ifdef NT_NETBSD_PAX
18715 case NT_NETBSD_PAX:
b966f55f
AM
18716 if (pnote->descsz < 1)
18717 break;
9abca702
CZ
18718 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18719 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
18720 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
18721 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
18722 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
18723 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
18724 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
18725 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
18726 return TRUE;
18727#endif
c6056a74 18728 }
b966f55f
AM
18729
18730 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
18731 pnote->descsz, pnote->type);
18732 return FALSE;
c6056a74
SF
18733}
18734
f4ddf30f 18735static const char *
dda8d76d 18736get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 18737{
f4ddf30f
JB
18738 switch (e_type)
18739 {
18740 case NT_FREEBSD_THRMISC:
18741 return _("NT_THRMISC (thrmisc structure)");
18742 case NT_FREEBSD_PROCSTAT_PROC:
18743 return _("NT_PROCSTAT_PROC (proc data)");
18744 case NT_FREEBSD_PROCSTAT_FILES:
18745 return _("NT_PROCSTAT_FILES (files data)");
18746 case NT_FREEBSD_PROCSTAT_VMMAP:
18747 return _("NT_PROCSTAT_VMMAP (vmmap data)");
18748 case NT_FREEBSD_PROCSTAT_GROUPS:
18749 return _("NT_PROCSTAT_GROUPS (groups data)");
18750 case NT_FREEBSD_PROCSTAT_UMASK:
18751 return _("NT_PROCSTAT_UMASK (umask data)");
18752 case NT_FREEBSD_PROCSTAT_RLIMIT:
18753 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
18754 case NT_FREEBSD_PROCSTAT_OSREL:
18755 return _("NT_PROCSTAT_OSREL (osreldate data)");
18756 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
18757 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
18758 case NT_FREEBSD_PROCSTAT_AUXV:
18759 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
18760 case NT_FREEBSD_PTLWPINFO:
18761 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 18762 }
dda8d76d 18763 return get_note_type (filedata, e_type);
f4ddf30f
JB
18764}
18765
9437c45b 18766static const char *
dda8d76d 18767get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
18768{
18769 static char buff[64];
18770
540e6170
CZ
18771 switch (e_type)
18772 {
18773 case NT_NETBSDCORE_PROCINFO:
18774 /* NetBSD core "procinfo" structure. */
18775 return _("NetBSD procinfo structure");
9437c45b 18776
540e6170
CZ
18777#ifdef NT_NETBSDCORE_AUXV
18778 case NT_NETBSDCORE_AUXV:
18779 return _("NetBSD ELF auxiliary vector data");
18780#endif
9437c45b 18781
06d949ec
KR
18782#ifdef NT_NETBSDCORE_LWPSTATUS
18783 case NT_NETBSDCORE_LWPSTATUS:
18784 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
18785#endif
18786
540e6170 18787 default:
06d949ec 18788 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
18789 defined for NetBSD core files. If the note type is less
18790 than the start of the machine-dependent note types, we don't
18791 understand it. */
18792
18793 if (e_type < NT_NETBSDCORE_FIRSTMACH)
18794 {
18795 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18796 return buff;
18797 }
18798 break;
9437c45b
JT
18799 }
18800
dda8d76d 18801 switch (filedata->file_header.e_machine)
9437c45b
JT
18802 {
18803 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
18804 and PT_GETFPREGS == mach+2. */
18805
18806 case EM_OLD_ALPHA:
18807 case EM_ALPHA:
18808 case EM_SPARC:
18809 case EM_SPARC32PLUS:
18810 case EM_SPARCV9:
18811 switch (e_type)
18812 {
2b692964 18813 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 18814 return _("PT_GETREGS (reg structure)");
2b692964 18815 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 18816 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18817 default:
18818 break;
18819 }
18820 break;
18821
c0d38b0e
CZ
18822 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
18823 There's also old PT___GETREGS40 == mach + 1 for old reg
18824 structure which lacks GBR. */
18825 case EM_SH:
18826 switch (e_type)
18827 {
18828 case NT_NETBSDCORE_FIRSTMACH + 1:
18829 return _("PT___GETREGS40 (old reg structure)");
18830 case NT_NETBSDCORE_FIRSTMACH + 3:
18831 return _("PT_GETREGS (reg structure)");
18832 case NT_NETBSDCORE_FIRSTMACH + 5:
18833 return _("PT_GETFPREGS (fpreg structure)");
18834 default:
18835 break;
18836 }
18837 break;
18838
9437c45b
JT
18839 /* On all other arch's, PT_GETREGS == mach+1 and
18840 PT_GETFPREGS == mach+3. */
18841 default:
18842 switch (e_type)
18843 {
2b692964 18844 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 18845 return _("PT_GETREGS (reg structure)");
2b692964 18846 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 18847 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18848 default:
18849 break;
18850 }
18851 }
18852
9cf03b7e 18853 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 18854 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
18855 return buff;
18856}
18857
70616151
TT
18858static const char *
18859get_stapsdt_note_type (unsigned e_type)
18860{
18861 static char buff[64];
18862
18863 switch (e_type)
18864 {
18865 case NT_STAPSDT:
18866 return _("NT_STAPSDT (SystemTap probe descriptors)");
18867
18868 default:
18869 break;
18870 }
18871
18872 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18873 return buff;
18874}
18875
32ec8896 18876static bfd_boolean
c6a9fc58
TT
18877print_stapsdt_note (Elf_Internal_Note *pnote)
18878{
3ca60c57
NC
18879 size_t len, maxlen;
18880 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
18881 char *data = pnote->descdata;
18882 char *data_end = pnote->descdata + pnote->descsz;
18883 bfd_vma pc, base_addr, semaphore;
18884 char *provider, *probe, *arg_fmt;
18885
3ca60c57
NC
18886 if (pnote->descsz < (addr_size * 3))
18887 goto stapdt_note_too_small;
18888
c6a9fc58
TT
18889 pc = byte_get ((unsigned char *) data, addr_size);
18890 data += addr_size;
3ca60c57 18891
c6a9fc58
TT
18892 base_addr = byte_get ((unsigned char *) data, addr_size);
18893 data += addr_size;
3ca60c57 18894
c6a9fc58
TT
18895 semaphore = byte_get ((unsigned char *) data, addr_size);
18896 data += addr_size;
18897
3ca60c57
NC
18898 if (data >= data_end)
18899 goto stapdt_note_too_small;
18900 maxlen = data_end - data;
18901 len = strnlen (data, maxlen);
18902 if (len < maxlen)
18903 {
18904 provider = data;
18905 data += len + 1;
18906 }
18907 else
18908 goto stapdt_note_too_small;
18909
18910 if (data >= data_end)
18911 goto stapdt_note_too_small;
18912 maxlen = data_end - data;
18913 len = strnlen (data, maxlen);
18914 if (len < maxlen)
18915 {
18916 probe = data;
18917 data += len + 1;
18918 }
18919 else
18920 goto stapdt_note_too_small;
9abca702 18921
3ca60c57
NC
18922 if (data >= data_end)
18923 goto stapdt_note_too_small;
18924 maxlen = data_end - data;
18925 len = strnlen (data, maxlen);
18926 if (len < maxlen)
18927 {
18928 arg_fmt = data;
18929 data += len + 1;
18930 }
18931 else
18932 goto stapdt_note_too_small;
c6a9fc58
TT
18933
18934 printf (_(" Provider: %s\n"), provider);
18935 printf (_(" Name: %s\n"), probe);
18936 printf (_(" Location: "));
18937 print_vma (pc, FULL_HEX);
18938 printf (_(", Base: "));
18939 print_vma (base_addr, FULL_HEX);
18940 printf (_(", Semaphore: "));
18941 print_vma (semaphore, FULL_HEX);
9cf03b7e 18942 printf ("\n");
c6a9fc58
TT
18943 printf (_(" Arguments: %s\n"), arg_fmt);
18944
18945 return data == data_end;
3ca60c57
NC
18946
18947 stapdt_note_too_small:
18948 printf (_(" <corrupt - note is too small>\n"));
18949 error (_("corrupt stapdt note - the data size is too small\n"));
18950 return FALSE;
c6a9fc58
TT
18951}
18952
00e98fc7
TG
18953static const char *
18954get_ia64_vms_note_type (unsigned e_type)
18955{
18956 static char buff[64];
18957
18958 switch (e_type)
18959 {
18960 case NT_VMS_MHD:
18961 return _("NT_VMS_MHD (module header)");
18962 case NT_VMS_LNM:
18963 return _("NT_VMS_LNM (language name)");
18964 case NT_VMS_SRC:
18965 return _("NT_VMS_SRC (source files)");
18966 case NT_VMS_TITLE:
9cf03b7e 18967 return "NT_VMS_TITLE";
00e98fc7
TG
18968 case NT_VMS_EIDC:
18969 return _("NT_VMS_EIDC (consistency check)");
18970 case NT_VMS_FPMODE:
18971 return _("NT_VMS_FPMODE (FP mode)");
18972 case NT_VMS_LINKTIME:
9cf03b7e 18973 return "NT_VMS_LINKTIME";
00e98fc7
TG
18974 case NT_VMS_IMGNAM:
18975 return _("NT_VMS_IMGNAM (image name)");
18976 case NT_VMS_IMGID:
18977 return _("NT_VMS_IMGID (image id)");
18978 case NT_VMS_LINKID:
18979 return _("NT_VMS_LINKID (link id)");
18980 case NT_VMS_IMGBID:
18981 return _("NT_VMS_IMGBID (build id)");
18982 case NT_VMS_GSTNAM:
18983 return _("NT_VMS_GSTNAM (sym table name)");
18984 case NT_VMS_ORIG_DYN:
9cf03b7e 18985 return "NT_VMS_ORIG_DYN";
00e98fc7 18986 case NT_VMS_PATCHTIME:
9cf03b7e 18987 return "NT_VMS_PATCHTIME";
00e98fc7
TG
18988 default:
18989 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18990 return buff;
18991 }
18992}
18993
32ec8896 18994static bfd_boolean
00e98fc7
TG
18995print_ia64_vms_note (Elf_Internal_Note * pnote)
18996{
8d18bf79
NC
18997 int maxlen = pnote->descsz;
18998
18999 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19000 goto desc_size_fail;
19001
00e98fc7
TG
19002 switch (pnote->type)
19003 {
19004 case NT_VMS_MHD:
8d18bf79
NC
19005 if (maxlen <= 36)
19006 goto desc_size_fail;
19007
19008 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19009
19010 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19011 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19012 if (l + 34 < maxlen)
19013 {
19014 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19015 if (l + 35 < maxlen)
19016 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19017 else
19018 printf (_(" Module version : <missing>\n"));
19019 }
00e98fc7 19020 else
8d18bf79
NC
19021 {
19022 printf (_(" Module name : <missing>\n"));
19023 printf (_(" Module version : <missing>\n"));
19024 }
00e98fc7 19025 break;
8d18bf79 19026
00e98fc7 19027 case NT_VMS_LNM:
8d18bf79 19028 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19029 break;
8d18bf79 19030
00e98fc7
TG
19031#ifdef BFD64
19032 case NT_VMS_FPMODE:
9cf03b7e 19033 printf (_(" Floating Point mode: "));
8d18bf79
NC
19034 if (maxlen < 8)
19035 goto desc_size_fail;
19036 /* FIXME: Generate an error if descsz > 8 ? */
19037
4a5cb34f 19038 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19039 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19040 break;
8d18bf79 19041
00e98fc7
TG
19042 case NT_VMS_LINKTIME:
19043 printf (_(" Link time: "));
8d18bf79
NC
19044 if (maxlen < 8)
19045 goto desc_size_fail;
19046 /* FIXME: Generate an error if descsz > 8 ? */
19047
00e98fc7 19048 print_vms_time
8d18bf79 19049 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19050 printf ("\n");
19051 break;
8d18bf79 19052
00e98fc7
TG
19053 case NT_VMS_PATCHTIME:
19054 printf (_(" Patch time: "));
8d18bf79
NC
19055 if (maxlen < 8)
19056 goto desc_size_fail;
19057 /* FIXME: Generate an error if descsz > 8 ? */
19058
00e98fc7 19059 print_vms_time
8d18bf79 19060 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19061 printf ("\n");
19062 break;
8d18bf79 19063
00e98fc7 19064 case NT_VMS_ORIG_DYN:
8d18bf79
NC
19065 if (maxlen < 34)
19066 goto desc_size_fail;
19067
00e98fc7
TG
19068 printf (_(" Major id: %u, minor id: %u\n"),
19069 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
19070 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 19071 printf (_(" Last modified : "));
00e98fc7
TG
19072 print_vms_time
19073 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 19074 printf (_("\n Link flags : "));
4a5cb34f 19075 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 19076 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 19077 printf (_(" Header flags: 0x%08x\n"),
948f632f 19078 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 19079 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
19080 break;
19081#endif
8d18bf79 19082
00e98fc7 19083 case NT_VMS_IMGNAM:
8d18bf79 19084 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19085 break;
8d18bf79 19086
00e98fc7 19087 case NT_VMS_GSTNAM:
8d18bf79 19088 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19089 break;
8d18bf79 19090
00e98fc7 19091 case NT_VMS_IMGID:
8d18bf79 19092 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19093 break;
8d18bf79 19094
00e98fc7 19095 case NT_VMS_LINKID:
8d18bf79 19096 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19097 break;
8d18bf79 19098
00e98fc7 19099 default:
32ec8896 19100 return FALSE;
00e98fc7 19101 }
8d18bf79 19102
32ec8896 19103 return TRUE;
8d18bf79
NC
19104
19105 desc_size_fail:
19106 printf (_(" <corrupt - data size is too small>\n"));
19107 error (_("corrupt IA64 note: data size is too small\n"));
19108 return FALSE;
00e98fc7
TG
19109}
19110
fd486f32
AM
19111struct build_attr_cache {
19112 Filedata *filedata;
19113 char *strtab;
19114 unsigned long strtablen;
19115 Elf_Internal_Sym *symtab;
19116 unsigned long nsyms;
19117} ba_cache;
19118
6f156d7a
NC
19119/* Find the symbol associated with a build attribute that is attached
19120 to address OFFSET. If PNAME is non-NULL then store the name of
19121 the symbol (if found) in the provided pointer, Returns NULL if a
19122 symbol could not be found. */
c799a79d 19123
6f156d7a
NC
19124static Elf_Internal_Sym *
19125get_symbol_for_build_attribute (Filedata * filedata,
19126 unsigned long offset,
19127 bfd_boolean is_open_attr,
19128 const char ** pname)
9ef920e9 19129{
fd486f32
AM
19130 Elf_Internal_Sym *saved_sym = NULL;
19131 Elf_Internal_Sym *sym;
9ef920e9 19132
dda8d76d 19133 if (filedata->section_headers != NULL
fd486f32 19134 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 19135 {
c799a79d 19136 Elf_Internal_Shdr * symsec;
9ef920e9 19137
fd486f32
AM
19138 free (ba_cache.strtab);
19139 ba_cache.strtab = NULL;
19140 free (ba_cache.symtab);
19141 ba_cache.symtab = NULL;
19142
c799a79d 19143 /* Load the symbol and string sections. */
dda8d76d
NC
19144 for (symsec = filedata->section_headers;
19145 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 19146 symsec ++)
9ef920e9 19147 {
28d13567
AM
19148 if (symsec->sh_type == SHT_SYMTAB
19149 && get_symtab (filedata, symsec,
19150 &ba_cache.symtab, &ba_cache.nsyms,
19151 &ba_cache.strtab, &ba_cache.strtablen))
19152 break;
9ef920e9 19153 }
fd486f32 19154 ba_cache.filedata = filedata;
9ef920e9
NC
19155 }
19156
fd486f32 19157 if (ba_cache.symtab == NULL)
6f156d7a 19158 return NULL;
9ef920e9 19159
c799a79d 19160 /* Find a symbol whose value matches offset. */
fd486f32 19161 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
19162 if (sym->st_value == offset)
19163 {
fd486f32 19164 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
19165 /* Huh ? This should not happen. */
19166 continue;
9ef920e9 19167
fd486f32 19168 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 19169 continue;
9ef920e9 19170
8fd75781
NC
19171 /* The AArch64 and ARM architectures define mapping symbols
19172 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
19173 if (ba_cache.strtab[sym->st_name] == '$'
19174 && ba_cache.strtab[sym->st_name + 1] != 0
19175 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
19176 continue;
19177
c799a79d
NC
19178 if (is_open_attr)
19179 {
19180 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
19181 and FILE or OBJECT symbols over NOTYPE symbols. We skip
19182 FUNC symbols entirely. */
19183 switch (ELF_ST_TYPE (sym->st_info))
19184 {
c799a79d 19185 case STT_OBJECT:
6f156d7a 19186 case STT_FILE:
c799a79d 19187 saved_sym = sym;
6f156d7a
NC
19188 if (sym->st_size)
19189 {
19190 /* If the symbol has a size associated
19191 with it then we can stop searching. */
fd486f32 19192 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 19193 }
c799a79d 19194 continue;
9ef920e9 19195
c799a79d
NC
19196 case STT_FUNC:
19197 /* Ignore function symbols. */
19198 continue;
19199
19200 default:
19201 break;
19202 }
19203
19204 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 19205 {
c799a79d
NC
19206 case STB_GLOBAL:
19207 if (saved_sym == NULL
19208 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
19209 saved_sym = sym;
19210 break;
c871dade 19211
c799a79d
NC
19212 case STB_LOCAL:
19213 if (saved_sym == NULL)
19214 saved_sym = sym;
19215 break;
19216
19217 default:
9ef920e9
NC
19218 break;
19219 }
19220 }
c799a79d
NC
19221 else
19222 {
19223 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
19224 continue;
19225
19226 saved_sym = sym;
19227 break;
19228 }
19229 }
19230
6f156d7a 19231 if (saved_sym && pname)
fd486f32 19232 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
19233
19234 return saved_sym;
c799a79d
NC
19235}
19236
d20e98ab
NC
19237/* Returns true iff addr1 and addr2 are in the same section. */
19238
19239static bfd_boolean
19240same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
19241{
19242 Elf_Internal_Shdr * a1;
19243 Elf_Internal_Shdr * a2;
19244
19245 a1 = find_section_by_address (filedata, addr1);
19246 a2 = find_section_by_address (filedata, addr2);
9abca702 19247
d20e98ab
NC
19248 return a1 == a2 && a1 != NULL;
19249}
19250
c799a79d 19251static bfd_boolean
dda8d76d
NC
19252print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
19253 Filedata * filedata)
c799a79d 19254{
6f156d7a
NC
19255 static unsigned long global_offset = 0;
19256 static unsigned long global_end = 0;
19257 static unsigned long func_offset = 0;
19258 static unsigned long func_end = 0;
c871dade 19259
6f156d7a
NC
19260 Elf_Internal_Sym * sym;
19261 const char * name;
19262 unsigned long start;
19263 unsigned long end;
19264 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
19265
19266 switch (pnote->descsz)
c799a79d 19267 {
6f156d7a
NC
19268 case 0:
19269 /* A zero-length description means that the range of
19270 the previous note of the same type should be used. */
c799a79d 19271 if (is_open_attr)
c871dade 19272 {
6f156d7a
NC
19273 if (global_end > global_offset)
19274 printf (_(" Applies to region from %#lx to %#lx\n"),
19275 global_offset, global_end);
19276 else
19277 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
19278 }
19279 else
19280 {
6f156d7a
NC
19281 if (func_end > func_offset)
19282 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
19283 else
19284 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 19285 }
6f156d7a 19286 return TRUE;
9ef920e9 19287
6f156d7a
NC
19288 case 4:
19289 start = byte_get ((unsigned char *) pnote->descdata, 4);
19290 end = 0;
19291 break;
19292
19293 case 8:
19294 if (is_32bit_elf)
19295 {
19296 /* FIXME: We should check that version 3+ notes are being used here... */
19297 start = byte_get ((unsigned char *) pnote->descdata, 4);
19298 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19299 }
19300 else
19301 {
19302 start = byte_get ((unsigned char *) pnote->descdata, 8);
19303 end = 0;
19304 }
19305 break;
19306
19307 case 16:
19308 start = byte_get ((unsigned char *) pnote->descdata, 8);
19309 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
19310 break;
9abca702 19311
6f156d7a 19312 default:
c799a79d
NC
19313 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
19314 printf (_(" <invalid descsz>"));
19315 return FALSE;
19316 }
19317
6f156d7a
NC
19318 name = NULL;
19319 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
19320 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
19321 in order to avoid them being confused with the start address of the
19322 first function in the file... */
19323 if (sym == NULL && is_open_attr)
19324 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
19325 & name);
6f156d7a
NC
19326
19327 if (end == 0 && sym != NULL && sym->st_size > 0)
19328 end = start + sym->st_size;
c799a79d
NC
19329
19330 if (is_open_attr)
19331 {
d20e98ab
NC
19332 /* FIXME: Need to properly allow for section alignment.
19333 16 is just the alignment used on x86_64. */
19334 if (global_end > 0
19335 && start > BFD_ALIGN (global_end, 16)
19336 /* Build notes are not guaranteed to be organised in order of
19337 increasing address, but we should find the all of the notes
19338 for one section in the same place. */
19339 && same_section (filedata, start, global_end))
6f156d7a
NC
19340 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
19341 global_end + 1, start - 1);
19342
19343 printf (_(" Applies to region from %#lx"), start);
19344 global_offset = start;
19345
19346 if (end)
19347 {
19348 printf (_(" to %#lx"), end);
19349 global_end = end;
19350 }
c799a79d
NC
19351 }
19352 else
19353 {
6f156d7a
NC
19354 printf (_(" Applies to region from %#lx"), start);
19355 func_offset = start;
19356
19357 if (end)
19358 {
19359 printf (_(" to %#lx"), end);
19360 func_end = end;
19361 }
c799a79d
NC
19362 }
19363
6f156d7a
NC
19364 if (sym && name)
19365 printf (_(" (%s)"), name);
19366
19367 printf ("\n");
19368 return TRUE;
9ef920e9
NC
19369}
19370
19371static bfd_boolean
19372print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
19373{
1d15e434
NC
19374 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
19375 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
19376 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
19377 char name_type;
19378 char name_attribute;
1d15e434 19379 const char * expected_types;
9ef920e9
NC
19380 const char * name = pnote->namedata;
19381 const char * text;
88305e1b 19382 signed int left;
9ef920e9
NC
19383
19384 if (name == NULL || pnote->namesz < 2)
19385 {
19386 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 19387 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
19388 return FALSE;
19389 }
19390
6f156d7a
NC
19391 if (do_wide)
19392 left = 28;
19393 else
19394 left = 20;
88305e1b
NC
19395
19396 /* Version 2 of the spec adds a "GA" prefix to the name field. */
19397 if (name[0] == 'G' && name[1] == 'A')
19398 {
6f156d7a
NC
19399 if (pnote->namesz < 4)
19400 {
19401 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
19402 print_symbol (-20, _(" <corrupt name>"));
19403 return FALSE;
19404 }
19405
88305e1b
NC
19406 printf ("GA");
19407 name += 2;
19408 left -= 2;
19409 }
19410
9ef920e9
NC
19411 switch ((name_type = * name))
19412 {
19413 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19414 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19415 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19416 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19417 printf ("%c", * name);
88305e1b 19418 left --;
9ef920e9
NC
19419 break;
19420 default:
19421 error (_("unrecognised attribute type in name field: %d\n"), name_type);
19422 print_symbol (-20, _("<unknown name type>"));
19423 return FALSE;
19424 }
19425
9ef920e9
NC
19426 ++ name;
19427 text = NULL;
19428
19429 switch ((name_attribute = * name))
19430 {
19431 case GNU_BUILD_ATTRIBUTE_VERSION:
19432 text = _("<version>");
1d15e434 19433 expected_types = string_expected;
9ef920e9
NC
19434 ++ name;
19435 break;
19436 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19437 text = _("<stack prot>");
75d7d298 19438 expected_types = "!+*";
9ef920e9
NC
19439 ++ name;
19440 break;
19441 case GNU_BUILD_ATTRIBUTE_RELRO:
19442 text = _("<relro>");
1d15e434 19443 expected_types = bool_expected;
9ef920e9
NC
19444 ++ name;
19445 break;
19446 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
19447 text = _("<stack size>");
1d15e434 19448 expected_types = number_expected;
9ef920e9
NC
19449 ++ name;
19450 break;
19451 case GNU_BUILD_ATTRIBUTE_TOOL:
19452 text = _("<tool>");
1d15e434 19453 expected_types = string_expected;
9ef920e9
NC
19454 ++ name;
19455 break;
19456 case GNU_BUILD_ATTRIBUTE_ABI:
19457 text = _("<ABI>");
19458 expected_types = "$*";
19459 ++ name;
19460 break;
19461 case GNU_BUILD_ATTRIBUTE_PIC:
19462 text = _("<PIC>");
1d15e434 19463 expected_types = number_expected;
9ef920e9
NC
19464 ++ name;
19465 break;
a8be5506
NC
19466 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
19467 text = _("<short enum>");
1d15e434 19468 expected_types = bool_expected;
a8be5506
NC
19469 ++ name;
19470 break;
9ef920e9
NC
19471 default:
19472 if (ISPRINT (* name))
19473 {
19474 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
19475
19476 if (len > left && ! do_wide)
19477 len = left;
75d7d298 19478 printf ("%.*s:", len, name);
9ef920e9 19479 left -= len;
0dd6ae21 19480 name += len;
9ef920e9
NC
19481 }
19482 else
19483 {
3e6b6445 19484 static char tmpbuf [128];
88305e1b 19485
3e6b6445
NC
19486 error (_("unrecognised byte in name field: %d\n"), * name);
19487 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
19488 text = tmpbuf;
19489 name ++;
9ef920e9
NC
19490 }
19491 expected_types = "*$!+";
19492 break;
19493 }
19494
19495 if (text)
88305e1b 19496 left -= printf ("%s", text);
9ef920e9
NC
19497
19498 if (strchr (expected_types, name_type) == NULL)
75d7d298 19499 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
19500
19501 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
19502 {
19503 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
19504 (unsigned long) pnote->namesz,
19505 (long) (name - pnote->namedata));
19506 return FALSE;
19507 }
19508
19509 if (left < 1 && ! do_wide)
19510 return TRUE;
19511
19512 switch (name_type)
19513 {
19514 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19515 {
b06b2c92 19516 unsigned int bytes;
ddef72cd
NC
19517 unsigned long long val = 0;
19518 unsigned int shift = 0;
19519 char * decoded = NULL;
19520
b06b2c92
NC
19521 bytes = pnote->namesz - (name - pnote->namedata);
19522 if (bytes > 0)
19523 /* The -1 is because the name field is always 0 terminated, and we
19524 want to be able to ensure that the shift in the while loop below
19525 will not overflow. */
19526 -- bytes;
19527
ddef72cd
NC
19528 if (bytes > sizeof (val))
19529 {
3e6b6445
NC
19530 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
19531 bytes);
19532 bytes = sizeof (val);
ddef72cd 19533 }
3e6b6445
NC
19534 /* We do not bother to warn if bytes == 0 as this can
19535 happen with some early versions of the gcc plugin. */
9ef920e9
NC
19536
19537 while (bytes --)
19538 {
79a964dc
NC
19539 unsigned long byte = (* name ++) & 0xff;
19540
19541 val |= byte << shift;
9ef920e9
NC
19542 shift += 8;
19543 }
19544
75d7d298 19545 switch (name_attribute)
9ef920e9 19546 {
75d7d298 19547 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
19548 switch (val)
19549 {
75d7d298
NC
19550 case 0: decoded = "static"; break;
19551 case 1: decoded = "pic"; break;
19552 case 2: decoded = "PIC"; break;
19553 case 3: decoded = "pie"; break;
19554 case 4: decoded = "PIE"; break;
19555 default: break;
9ef920e9 19556 }
75d7d298
NC
19557 break;
19558 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19559 switch (val)
9ef920e9 19560 {
75d7d298
NC
19561 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
19562 case 0: decoded = "off"; break;
19563 case 1: decoded = "on"; break;
19564 case 2: decoded = "all"; break;
19565 case 3: decoded = "strong"; break;
19566 case 4: decoded = "explicit"; break;
19567 default: break;
9ef920e9 19568 }
75d7d298
NC
19569 break;
19570 default:
19571 break;
9ef920e9
NC
19572 }
19573
75d7d298 19574 if (decoded != NULL)
3e6b6445
NC
19575 {
19576 print_symbol (-left, decoded);
19577 left = 0;
19578 }
19579 else if (val == 0)
19580 {
19581 printf ("0x0");
19582 left -= 3;
19583 }
9ef920e9 19584 else
75d7d298
NC
19585 {
19586 if (do_wide)
ddef72cd 19587 left -= printf ("0x%llx", val);
75d7d298 19588 else
ddef72cd 19589 left -= printf ("0x%-.*llx", left, val);
75d7d298 19590 }
9ef920e9
NC
19591 }
19592 break;
19593 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19594 left -= print_symbol (- left, name);
19595 break;
19596 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19597 left -= print_symbol (- left, "true");
19598 break;
19599 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19600 left -= print_symbol (- left, "false");
19601 break;
19602 }
19603
19604 if (do_wide && left > 0)
19605 printf ("%-*s", left, " ");
9abca702 19606
9ef920e9
NC
19607 return TRUE;
19608}
19609
6d118b09
NC
19610/* Note that by the ELF standard, the name field is already null byte
19611 terminated, and namesz includes the terminating null byte.
19612 I.E. the value of namesz for the name "FSF" is 4.
19613
e3c8793a 19614 If the value of namesz is zero, there is no name present. */
9ef920e9 19615
32ec8896 19616static bfd_boolean
9ef920e9 19617process_note (Elf_Internal_Note * pnote,
dda8d76d 19618 Filedata * filedata)
779fe533 19619{
2cf0635d
NC
19620 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
19621 const char * nt;
9437c45b
JT
19622
19623 if (pnote->namesz == 0)
1ec5cd37
NC
19624 /* If there is no note name, then use the default set of
19625 note type strings. */
dda8d76d 19626 nt = get_note_type (filedata, pnote->type);
1ec5cd37 19627
1118d252
RM
19628 else if (const_strneq (pnote->namedata, "GNU"))
19629 /* GNU-specific object file notes. */
19630 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
19631
19632 else if (const_strneq (pnote->namedata, "FreeBSD"))
19633 /* FreeBSD-specific core file notes. */
dda8d76d 19634 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 19635
0112cd26 19636 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 19637 /* NetBSD-specific core file notes. */
dda8d76d 19638 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 19639
c6056a74
SF
19640 else if (const_strneq (pnote->namedata, "NetBSD"))
19641 /* NetBSD-specific core file notes. */
19642 return process_netbsd_elf_note (pnote);
19643
9abca702
CZ
19644 else if (const_strneq (pnote->namedata, "PaX"))
19645 /* NetBSD-specific core file notes. */
19646 return process_netbsd_elf_note (pnote);
19647
b15fa79e
AM
19648 else if (strneq (pnote->namedata, "SPU/", 4))
19649 {
19650 /* SPU-specific core file notes. */
19651 nt = pnote->namedata + 4;
19652 name = "SPU";
19653 }
19654
00e98fc7
TG
19655 else if (const_strneq (pnote->namedata, "IPF/VMS"))
19656 /* VMS/ia64-specific file notes. */
19657 nt = get_ia64_vms_note_type (pnote->type);
19658
70616151
TT
19659 else if (const_strneq (pnote->namedata, "stapsdt"))
19660 nt = get_stapsdt_note_type (pnote->type);
19661
9437c45b 19662 else
1ec5cd37
NC
19663 /* Don't recognize this note name; just use the default set of
19664 note type strings. */
dda8d76d 19665 nt = get_note_type (filedata, pnote->type);
9437c45b 19666
1449284b 19667 printf (" ");
9ef920e9 19668
483767a3
AM
19669 if (((const_strneq (pnote->namedata, "GA")
19670 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19671 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19672 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19673 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
19674 print_gnu_build_attribute_name (pnote);
19675 else
19676 print_symbol (-20, name);
19677
19678 if (do_wide)
19679 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
19680 else
19681 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
19682
19683 if (const_strneq (pnote->namedata, "IPF/VMS"))
19684 return print_ia64_vms_note (pnote);
664f90a3 19685 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 19686 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
19687 else if (const_strneq (pnote->namedata, "stapsdt"))
19688 return print_stapsdt_note (pnote);
9ece1fa9
TT
19689 else if (const_strneq (pnote->namedata, "CORE"))
19690 return print_core_note (pnote);
483767a3
AM
19691 else if (((const_strneq (pnote->namedata, "GA")
19692 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19693 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19694 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19695 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 19696 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 19697
9ef920e9 19698 if (pnote->descsz)
1449284b
NC
19699 {
19700 unsigned long i;
19701
19702 printf (_(" description data: "));
19703 for (i = 0; i < pnote->descsz; i++)
178d8719 19704 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
19705 if (!do_wide)
19706 printf ("\n");
1449284b
NC
19707 }
19708
9ef920e9
NC
19709 if (do_wide)
19710 printf ("\n");
19711
32ec8896 19712 return TRUE;
1449284b 19713}
6d118b09 19714
32ec8896 19715static bfd_boolean
dda8d76d
NC
19716process_notes_at (Filedata * filedata,
19717 Elf_Internal_Shdr * section,
19718 bfd_vma offset,
82ed9683
L
19719 bfd_vma length,
19720 bfd_vma align)
779fe533 19721{
2cf0635d
NC
19722 Elf_External_Note * pnotes;
19723 Elf_External_Note * external;
4dff97b2
NC
19724 char * end;
19725 bfd_boolean res = TRUE;
103f02d3 19726
779fe533 19727 if (length <= 0)
32ec8896 19728 return FALSE;
103f02d3 19729
1449284b
NC
19730 if (section)
19731 {
dda8d76d 19732 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 19733 if (pnotes)
32ec8896 19734 {
dda8d76d 19735 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
19736 {
19737 free (pnotes);
19738 return FALSE;
19739 }
32ec8896 19740 }
1449284b
NC
19741 }
19742 else
82ed9683 19743 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 19744 _("notes"));
4dff97b2 19745
dd24e3da 19746 if (pnotes == NULL)
32ec8896 19747 return FALSE;
779fe533 19748
103f02d3 19749 external = pnotes;
103f02d3 19750
1449284b 19751 if (section)
dda8d76d 19752 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
19753 else
19754 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
19755 (unsigned long) offset, (unsigned long) length);
19756
82ed9683
L
19757 /* NB: Some note sections may have alignment value of 0 or 1. gABI
19758 specifies that notes should be aligned to 4 bytes in 32-bit
19759 objects and to 8 bytes in 64-bit objects. As a Linux extension,
19760 we also support 4 byte alignment in 64-bit objects. If section
19761 alignment is less than 4, we treate alignment as 4 bytes. */
19762 if (align < 4)
19763 align = 4;
19764 else if (align != 4 && align != 8)
19765 {
19766 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
19767 (long) align);
a788aedd 19768 free (pnotes);
82ed9683
L
19769 return FALSE;
19770 }
19771
dbe15e4e 19772 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 19773
c8071705
NC
19774 end = (char *) pnotes + length;
19775 while ((char *) external < end)
779fe533 19776 {
b34976b6 19777 Elf_Internal_Note inote;
15b42fb0 19778 size_t min_notesz;
4dff97b2 19779 char * next;
2cf0635d 19780 char * temp = NULL;
c8071705 19781 size_t data_remaining = end - (char *) external;
6d118b09 19782
dda8d76d 19783 if (!is_ia64_vms (filedata))
15b42fb0 19784 {
9dd3a467
NC
19785 /* PR binutils/15191
19786 Make sure that there is enough data to read. */
15b42fb0
AM
19787 min_notesz = offsetof (Elf_External_Note, name);
19788 if (data_remaining < min_notesz)
9dd3a467 19789 {
d3a49aa8
AM
19790 warn (ngettext ("Corrupt note: only %ld byte remains, "
19791 "not enough for a full note\n",
19792 "Corrupt note: only %ld bytes remain, "
19793 "not enough for a full note\n",
19794 data_remaining),
19795 (long) data_remaining);
9dd3a467
NC
19796 break;
19797 }
5396a86e
AM
19798 data_remaining -= min_notesz;
19799
15b42fb0
AM
19800 inote.type = BYTE_GET (external->type);
19801 inote.namesz = BYTE_GET (external->namesz);
19802 inote.namedata = external->name;
19803 inote.descsz = BYTE_GET (external->descsz);
276da9b3 19804 inote.descdata = ((char *) external
4dff97b2 19805 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 19806 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 19807 next = ((char *) external
4dff97b2 19808 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 19809 }
00e98fc7 19810 else
15b42fb0
AM
19811 {
19812 Elf64_External_VMS_Note *vms_external;
00e98fc7 19813
9dd3a467
NC
19814 /* PR binutils/15191
19815 Make sure that there is enough data to read. */
15b42fb0
AM
19816 min_notesz = offsetof (Elf64_External_VMS_Note, name);
19817 if (data_remaining < min_notesz)
9dd3a467 19818 {
d3a49aa8
AM
19819 warn (ngettext ("Corrupt note: only %ld byte remains, "
19820 "not enough for a full note\n",
19821 "Corrupt note: only %ld bytes remain, "
19822 "not enough for a full note\n",
19823 data_remaining),
19824 (long) data_remaining);
9dd3a467
NC
19825 break;
19826 }
5396a86e 19827 data_remaining -= min_notesz;
3e55a963 19828
15b42fb0
AM
19829 vms_external = (Elf64_External_VMS_Note *) external;
19830 inote.type = BYTE_GET (vms_external->type);
19831 inote.namesz = BYTE_GET (vms_external->namesz);
19832 inote.namedata = vms_external->name;
19833 inote.descsz = BYTE_GET (vms_external->descsz);
19834 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
19835 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19836 next = inote.descdata + align_power (inote.descsz, 3);
19837 }
19838
5396a86e
AM
19839 /* PR 17531: file: 3443835e. */
19840 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
19841 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
19842 || (size_t) (inote.descdata - inote.namedata) > data_remaining
19843 || (size_t) (next - inote.descdata) < inote.descsz
19844 || ((size_t) (next - inote.descdata)
19845 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 19846 {
15b42fb0 19847 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 19848 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
19849 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
19850 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
19851 break;
19852 }
19853
15b42fb0 19854 external = (Elf_External_Note *) next;
dd24e3da 19855
6d118b09
NC
19856 /* Verify that name is null terminated. It appears that at least
19857 one version of Linux (RedHat 6.0) generates corefiles that don't
19858 comply with the ELF spec by failing to include the null byte in
19859 namesz. */
18344509 19860 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 19861 {
5396a86e 19862 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 19863 {
5396a86e
AM
19864 temp = (char *) malloc (inote.namesz + 1);
19865 if (temp == NULL)
19866 {
19867 error (_("Out of memory allocating space for inote name\n"));
19868 res = FALSE;
19869 break;
19870 }
76da6bbe 19871
5396a86e
AM
19872 memcpy (temp, inote.namedata, inote.namesz);
19873 inote.namedata = temp;
19874 }
19875 inote.namedata[inote.namesz] = 0;
6d118b09
NC
19876 }
19877
dda8d76d 19878 if (! process_note (& inote, filedata))
6b4bf3bc 19879 res = FALSE;
103f02d3 19880
9db70fc3
AM
19881 free (temp);
19882 temp = NULL;
779fe533
NC
19883 }
19884
19885 free (pnotes);
103f02d3 19886
779fe533
NC
19887 return res;
19888}
19889
32ec8896 19890static bfd_boolean
dda8d76d 19891process_corefile_note_segments (Filedata * filedata)
779fe533 19892{
2cf0635d 19893 Elf_Internal_Phdr * segment;
b34976b6 19894 unsigned int i;
32ec8896 19895 bfd_boolean res = TRUE;
103f02d3 19896
dda8d76d 19897 if (! get_program_headers (filedata))
6b4bf3bc 19898 return TRUE;
103f02d3 19899
dda8d76d
NC
19900 for (i = 0, segment = filedata->program_headers;
19901 i < filedata->file_header.e_phnum;
b34976b6 19902 i++, segment++)
779fe533
NC
19903 {
19904 if (segment->p_type == PT_NOTE)
dda8d76d 19905 if (! process_notes_at (filedata, NULL,
32ec8896 19906 (bfd_vma) segment->p_offset,
82ed9683
L
19907 (bfd_vma) segment->p_filesz,
19908 (bfd_vma) segment->p_align))
32ec8896 19909 res = FALSE;
779fe533 19910 }
103f02d3 19911
779fe533
NC
19912 return res;
19913}
19914
32ec8896 19915static bfd_boolean
dda8d76d 19916process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
19917{
19918 Elf_External_Note * pnotes;
19919 Elf_External_Note * external;
c8071705 19920 char * end;
32ec8896 19921 bfd_boolean res = TRUE;
685080f2
NC
19922
19923 if (length <= 0)
32ec8896 19924 return FALSE;
685080f2 19925
dda8d76d 19926 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
19927 _("v850 notes"));
19928 if (pnotes == NULL)
32ec8896 19929 return FALSE;
685080f2
NC
19930
19931 external = pnotes;
c8071705 19932 end = (char*) pnotes + length;
685080f2
NC
19933
19934 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
19935 (unsigned long) offset, (unsigned long) length);
19936
c8071705 19937 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
19938 {
19939 Elf_External_Note * next;
19940 Elf_Internal_Note inote;
19941
19942 inote.type = BYTE_GET (external->type);
19943 inote.namesz = BYTE_GET (external->namesz);
19944 inote.namedata = external->name;
19945 inote.descsz = BYTE_GET (external->descsz);
19946 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
19947 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19948
c8071705
NC
19949 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
19950 {
19951 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
19952 inote.descdata = inote.namedata;
19953 inote.namesz = 0;
19954 }
19955
685080f2
NC
19956 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
19957
c8071705 19958 if ( ((char *) next > end)
685080f2
NC
19959 || ((char *) next < (char *) pnotes))
19960 {
19961 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
19962 (unsigned long) ((char *) external - (char *) pnotes));
19963 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19964 inote.type, inote.namesz, inote.descsz);
19965 break;
19966 }
19967
19968 external = next;
19969
19970 /* Prevent out-of-bounds indexing. */
c8071705 19971 if ( inote.namedata + inote.namesz > end
685080f2
NC
19972 || inote.namedata + inote.namesz < inote.namedata)
19973 {
19974 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
19975 (unsigned long) ((char *) external - (char *) pnotes));
19976 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19977 inote.type, inote.namesz, inote.descsz);
19978 break;
19979 }
19980
19981 printf (" %s: ", get_v850_elf_note_type (inote.type));
19982
19983 if (! print_v850_note (& inote))
19984 {
32ec8896 19985 res = FALSE;
685080f2
NC
19986 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
19987 inote.namesz, inote.descsz);
19988 }
19989 }
19990
19991 free (pnotes);
19992
19993 return res;
19994}
19995
32ec8896 19996static bfd_boolean
dda8d76d 19997process_note_sections (Filedata * filedata)
1ec5cd37 19998{
2cf0635d 19999 Elf_Internal_Shdr * section;
1ec5cd37 20000 unsigned long i;
32ec8896
NC
20001 unsigned int n = 0;
20002 bfd_boolean res = TRUE;
1ec5cd37 20003
dda8d76d
NC
20004 for (i = 0, section = filedata->section_headers;
20005 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20006 i++, section++)
685080f2
NC
20007 {
20008 if (section->sh_type == SHT_NOTE)
20009 {
dda8d76d 20010 if (! process_notes_at (filedata, section,
32ec8896 20011 (bfd_vma) section->sh_offset,
82ed9683
L
20012 (bfd_vma) section->sh_size,
20013 (bfd_vma) section->sh_addralign))
32ec8896 20014 res = FALSE;
685080f2
NC
20015 n++;
20016 }
20017
dda8d76d
NC
20018 if (( filedata->file_header.e_machine == EM_V800
20019 || filedata->file_header.e_machine == EM_V850
20020 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20021 && section->sh_type == SHT_RENESAS_INFO)
20022 {
dda8d76d 20023 if (! process_v850_notes (filedata,
32ec8896
NC
20024 (bfd_vma) section->sh_offset,
20025 (bfd_vma) section->sh_size))
20026 res = FALSE;
685080f2
NC
20027 n++;
20028 }
20029 }
df565f32
NC
20030
20031 if (n == 0)
20032 /* Try processing NOTE segments instead. */
dda8d76d 20033 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20034
20035 return res;
20036}
20037
32ec8896 20038static bfd_boolean
dda8d76d 20039process_notes (Filedata * filedata)
779fe533
NC
20040{
20041 /* If we have not been asked to display the notes then do nothing. */
20042 if (! do_notes)
32ec8896 20043 return TRUE;
103f02d3 20044
dda8d76d
NC
20045 if (filedata->file_header.e_type != ET_CORE)
20046 return process_note_sections (filedata);
103f02d3 20047
779fe533 20048 /* No program headers means no NOTE segment. */
dda8d76d
NC
20049 if (filedata->file_header.e_phnum > 0)
20050 return process_corefile_note_segments (filedata);
779fe533 20051
1ec5cd37 20052 printf (_("No note segments present in the core file.\n"));
32ec8896 20053 return TRUE;
779fe533
NC
20054}
20055
60abdbed
NC
20056static unsigned char *
20057display_public_gnu_attributes (unsigned char * start,
20058 const unsigned char * const end)
20059{
20060 printf (_(" Unknown GNU attribute: %s\n"), start);
20061
20062 start += strnlen ((char *) start, end - start);
20063 display_raw_attribute (start, end);
20064
20065 return (unsigned char *) end;
20066}
20067
20068static unsigned char *
20069display_generic_attribute (unsigned char * start,
20070 unsigned int tag,
20071 const unsigned char * const end)
20072{
20073 if (tag == 0)
20074 return (unsigned char *) end;
20075
20076 return display_tag_value (tag, start, end);
20077}
20078
32ec8896 20079static bfd_boolean
dda8d76d 20080process_arch_specific (Filedata * filedata)
252b5132 20081{
a952a375 20082 if (! do_arch)
32ec8896 20083 return TRUE;
a952a375 20084
dda8d76d 20085 switch (filedata->file_header.e_machine)
252b5132 20086 {
53a346d8
CZ
20087 case EM_ARC:
20088 case EM_ARC_COMPACT:
20089 case EM_ARC_COMPACT2:
dda8d76d 20090 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
20091 display_arc_attribute,
20092 display_generic_attribute);
11c1ff18 20093 case EM_ARM:
dda8d76d 20094 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
20095 display_arm_attribute,
20096 display_generic_attribute);
20097
252b5132 20098 case EM_MIPS:
4fe85591 20099 case EM_MIPS_RS3_LE:
dda8d76d 20100 return process_mips_specific (filedata);
60abdbed
NC
20101
20102 case EM_MSP430:
dda8d76d
NC
20103 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
20104 display_msp430x_attribute,
c0ea7c52 20105 display_msp430_gnu_attribute);
60abdbed 20106
2dc8dd17
JW
20107 case EM_RISCV:
20108 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
20109 display_riscv_attribute,
20110 display_generic_attribute);
20111
35c08157 20112 case EM_NDS32:
dda8d76d 20113 return process_nds32_specific (filedata);
60abdbed 20114
85f7484a
PB
20115 case EM_68K:
20116 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
20117 display_m68k_gnu_attribute);
20118
34c8bcba 20119 case EM_PPC:
b82317dd 20120 case EM_PPC64:
dda8d76d 20121 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20122 display_power_gnu_attribute);
20123
643f7afb
AK
20124 case EM_S390:
20125 case EM_S390_OLD:
dda8d76d 20126 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20127 display_s390_gnu_attribute);
20128
9e8c70f9
DM
20129 case EM_SPARC:
20130 case EM_SPARC32PLUS:
20131 case EM_SPARCV9:
dda8d76d 20132 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20133 display_sparc_gnu_attribute);
20134
59e6276b 20135 case EM_TI_C6000:
dda8d76d 20136 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
20137 display_tic6x_attribute,
20138 display_generic_attribute);
20139
252b5132 20140 default:
dda8d76d 20141 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
20142 display_public_gnu_attributes,
20143 display_generic_attribute);
252b5132 20144 }
252b5132
RH
20145}
20146
32ec8896 20147static bfd_boolean
dda8d76d 20148get_file_header (Filedata * filedata)
252b5132 20149{
9ea033b2 20150 /* Read in the identity array. */
dda8d76d 20151 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20152 return FALSE;
252b5132 20153
9ea033b2 20154 /* Determine how to read the rest of the header. */
dda8d76d 20155 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 20156 {
1a0670f3
AM
20157 default:
20158 case ELFDATANONE:
adab8cdc
AO
20159 case ELFDATA2LSB:
20160 byte_get = byte_get_little_endian;
20161 byte_put = byte_put_little_endian;
20162 break;
20163 case ELFDATA2MSB:
20164 byte_get = byte_get_big_endian;
20165 byte_put = byte_put_big_endian;
20166 break;
9ea033b2
NC
20167 }
20168
20169 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 20170 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
20171
20172 /* Read in the rest of the header. */
20173 if (is_32bit_elf)
20174 {
20175 Elf32_External_Ehdr ehdr32;
252b5132 20176
dda8d76d 20177 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20178 return FALSE;
103f02d3 20179
dda8d76d
NC
20180 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
20181 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
20182 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
20183 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
20184 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
20185 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
20186 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
20187 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
20188 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
20189 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
20190 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
20191 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
20192 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 20193 }
252b5132 20194 else
9ea033b2
NC
20195 {
20196 Elf64_External_Ehdr ehdr64;
a952a375
NC
20197
20198 /* If we have been compiled with sizeof (bfd_vma) == 4, then
20199 we will not be able to cope with the 64bit data found in
20200 64 ELF files. Detect this now and abort before we start
50c2245b 20201 overwriting things. */
a952a375
NC
20202 if (sizeof (bfd_vma) < 8)
20203 {
e3c8793a
NC
20204 error (_("This instance of readelf has been built without support for a\n\
2020564 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 20206 return FALSE;
a952a375 20207 }
103f02d3 20208
dda8d76d 20209 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20210 return FALSE;
103f02d3 20211
dda8d76d
NC
20212 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
20213 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
20214 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
20215 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
20216 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
20217 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
20218 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
20219 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
20220 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
20221 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
20222 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
20223 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
20224 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 20225 }
252b5132 20226
dda8d76d 20227 if (filedata->file_header.e_shoff)
7ece0d85
JJ
20228 {
20229 /* There may be some extensions in the first section header. Don't
20230 bomb if we can't read it. */
20231 if (is_32bit_elf)
dda8d76d 20232 get_32bit_section_headers (filedata, TRUE);
7ece0d85 20233 else
dda8d76d 20234 get_64bit_section_headers (filedata, TRUE);
7ece0d85 20235 }
560f3c1c 20236
32ec8896 20237 return TRUE;
252b5132
RH
20238}
20239
dda8d76d
NC
20240static void
20241close_file (Filedata * filedata)
20242{
20243 if (filedata)
20244 {
20245 if (filedata->handle)
20246 fclose (filedata->handle);
20247 free (filedata);
20248 }
20249}
20250
20251void
20252close_debug_file (void * data)
20253{
20254 close_file ((Filedata *) data);
20255}
20256
20257static Filedata *
20258open_file (const char * pathname)
20259{
20260 struct stat statbuf;
20261 Filedata * filedata = NULL;
20262
20263 if (stat (pathname, & statbuf) < 0
20264 || ! S_ISREG (statbuf.st_mode))
20265 goto fail;
20266
20267 filedata = calloc (1, sizeof * filedata);
20268 if (filedata == NULL)
20269 goto fail;
20270
20271 filedata->handle = fopen (pathname, "rb");
20272 if (filedata->handle == NULL)
20273 goto fail;
20274
20275 filedata->file_size = (bfd_size_type) statbuf.st_size;
20276 filedata->file_name = pathname;
20277
20278 if (! get_file_header (filedata))
20279 goto fail;
20280
20281 if (filedata->file_header.e_shoff)
20282 {
20283 bfd_boolean res;
20284
20285 /* Read the section headers again, this time for real. */
20286 if (is_32bit_elf)
20287 res = get_32bit_section_headers (filedata, FALSE);
20288 else
20289 res = get_64bit_section_headers (filedata, FALSE);
20290
20291 if (!res)
20292 goto fail;
20293 }
20294
20295 return filedata;
20296
20297 fail:
20298 if (filedata)
20299 {
20300 if (filedata->handle)
20301 fclose (filedata->handle);
20302 free (filedata);
20303 }
20304 return NULL;
20305}
20306
20307void *
20308open_debug_file (const char * pathname)
20309{
20310 return open_file (pathname);
20311}
20312
fb52b2f4
NC
20313/* Process one ELF object file according to the command line options.
20314 This file may actually be stored in an archive. The file is
32ec8896
NC
20315 positioned at the start of the ELF object. Returns TRUE if no
20316 problems were encountered, FALSE otherwise. */
fb52b2f4 20317
32ec8896 20318static bfd_boolean
dda8d76d 20319process_object (Filedata * filedata)
252b5132 20320{
24841daa 20321 bfd_boolean have_separate_files;
252b5132 20322 unsigned int i;
2482f306 20323 bfd_boolean res;
252b5132 20324
dda8d76d 20325 if (! get_file_header (filedata))
252b5132 20326 {
dda8d76d 20327 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 20328 return FALSE;
252b5132
RH
20329 }
20330
20331 /* Initialise per file variables. */
978c4450
AM
20332 for (i = ARRAY_SIZE (filedata->version_info); i--;)
20333 filedata->version_info[i] = 0;
252b5132 20334
978c4450
AM
20335 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
20336 filedata->dynamic_info[i] = 0;
20337 filedata->dynamic_info_DT_GNU_HASH = 0;
20338 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
20339
20340 /* Process the file. */
20341 if (show_name)
dda8d76d 20342 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 20343
18bd398b
NC
20344 /* Initialise the dump_sects array from the cmdline_dump_sects array.
20345 Note we do this even if cmdline_dump_sects is empty because we
20346 must make sure that the dump_sets array is zeroed out before each
20347 object file is processed. */
6431e409
AM
20348 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
20349 memset (filedata->dump.dump_sects, 0,
20350 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20351
dda8d76d 20352 if (cmdline.num_dump_sects > 0)
18bd398b 20353 {
6431e409 20354 if (filedata->dump.num_dump_sects == 0)
18bd398b 20355 /* A sneaky way of allocating the dump_sects array. */
6431e409 20356 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 20357
6431e409
AM
20358 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
20359 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
20360 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20361 }
d70c5fc7 20362
dda8d76d 20363 if (! process_file_header (filedata))
32ec8896 20364 return FALSE;
252b5132 20365
dda8d76d 20366 if (! process_section_headers (filedata))
2f62977e 20367 {
32ec8896
NC
20368 /* Without loaded section headers we cannot process lots of things. */
20369 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 20370
2f62977e 20371 if (! do_using_dynamic)
32ec8896 20372 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 20373 }
252b5132 20374
dda8d76d 20375 if (! process_section_groups (filedata))
32ec8896
NC
20376 /* Without loaded section groups we cannot process unwind. */
20377 do_unwind = FALSE;
d1f5c6e3 20378
2482f306
AM
20379 res = process_program_headers (filedata);
20380 if (res)
20381 res = process_dynamic_section (filedata);
252b5132 20382
dda8d76d 20383 if (! process_relocs (filedata))
32ec8896 20384 res = FALSE;
252b5132 20385
dda8d76d 20386 if (! process_unwind (filedata))
32ec8896 20387 res = FALSE;
4d6ed7c8 20388
dda8d76d 20389 if (! process_symbol_table (filedata))
32ec8896 20390 res = FALSE;
252b5132 20391
dda8d76d 20392 if (! process_syminfo (filedata))
32ec8896 20393 res = FALSE;
252b5132 20394
dda8d76d 20395 if (! process_version_sections (filedata))
32ec8896 20396 res = FALSE;
252b5132 20397
82ed9683 20398 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 20399 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 20400 else
24841daa 20401 have_separate_files = FALSE;
dda8d76d
NC
20402
20403 if (! process_section_contents (filedata))
32ec8896 20404 res = FALSE;
f5842774 20405
24841daa 20406 if (have_separate_files)
dda8d76d 20407 {
24841daa
NC
20408 separate_info * d;
20409
20410 for (d = first_separate_info; d != NULL; d = d->next)
20411 {
20412 if (! process_section_headers (d->handle))
20413 res = FALSE;
20414 else if (! process_section_contents (d->handle))
20415 res = FALSE;
20416 }
20417
20418 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
20419 }
20420
20421 if (! process_notes (filedata))
32ec8896 20422 res = FALSE;
103f02d3 20423
dda8d76d 20424 if (! process_gnu_liblist (filedata))
32ec8896 20425 res = FALSE;
047b2264 20426
dda8d76d 20427 if (! process_arch_specific (filedata))
32ec8896 20428 res = FALSE;
252b5132 20429
dda8d76d
NC
20430 free (filedata->program_headers);
20431 filedata->program_headers = NULL;
d93f0186 20432
dda8d76d
NC
20433 free (filedata->section_headers);
20434 filedata->section_headers = NULL;
252b5132 20435
dda8d76d
NC
20436 free (filedata->string_table);
20437 filedata->string_table = NULL;
20438 filedata->string_table_length = 0;
252b5132 20439
9db70fc3
AM
20440 free (filedata->dump.dump_sects);
20441 filedata->dump.dump_sects = NULL;
20442 filedata->dump.num_dump_sects = 0;
a788aedd 20443
9db70fc3
AM
20444 free (filedata->dynamic_strings);
20445 filedata->dynamic_strings = NULL;
20446 filedata->dynamic_strings_length = 0;
252b5132 20447
9db70fc3
AM
20448 free (filedata->dynamic_symbols);
20449 filedata->dynamic_symbols = NULL;
20450 filedata->num_dynamic_syms = 0;
252b5132 20451
9db70fc3
AM
20452 free (filedata->dynamic_syminfo);
20453 filedata->dynamic_syminfo = NULL;
ff78d6d6 20454
9db70fc3
AM
20455 free (filedata->dynamic_section);
20456 filedata->dynamic_section = NULL;
293c573e 20457
978c4450 20458 while (filedata->symtab_shndx_list != NULL)
8fb879cd 20459 {
978c4450
AM
20460 elf_section_list *next = filedata->symtab_shndx_list->next;
20461 free (filedata->symtab_shndx_list);
20462 filedata->symtab_shndx_list = next;
8fb879cd
AM
20463 }
20464
9db70fc3
AM
20465 free (filedata->section_headers_groups);
20466 filedata->section_headers_groups = NULL;
e4b17d5c 20467
978c4450 20468 if (filedata->section_groups)
e4b17d5c 20469 {
2cf0635d
NC
20470 struct group_list * g;
20471 struct group_list * next;
e4b17d5c 20472
978c4450 20473 for (i = 0; i < filedata->group_count; i++)
e4b17d5c 20474 {
978c4450 20475 for (g = filedata->section_groups [i].root; g != NULL; g = next)
e4b17d5c
L
20476 {
20477 next = g->next;
20478 free (g);
20479 }
20480 }
20481
978c4450
AM
20482 free (filedata->section_groups);
20483 filedata->section_groups = NULL;
e4b17d5c
L
20484 }
20485
19e6b90e 20486 free_debug_memory ();
18bd398b 20487
32ec8896 20488 return res;
252b5132
RH
20489}
20490
2cf0635d 20491/* Process an ELF archive.
32ec8896
NC
20492 On entry the file is positioned just after the ARMAG string.
20493 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 20494
32ec8896 20495static bfd_boolean
dda8d76d 20496process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
20497{
20498 struct archive_info arch;
20499 struct archive_info nested_arch;
20500 size_t got;
32ec8896 20501 bfd_boolean ret = TRUE;
2cf0635d 20502
32ec8896 20503 show_name = TRUE;
2cf0635d
NC
20504
20505 /* The ARCH structure is used to hold information about this archive. */
20506 arch.file_name = NULL;
20507 arch.file = NULL;
20508 arch.index_array = NULL;
20509 arch.sym_table = NULL;
20510 arch.longnames = NULL;
20511
20512 /* The NESTED_ARCH structure is used as a single-item cache of information
20513 about a nested archive (when members of a thin archive reside within
20514 another regular archive file). */
20515 nested_arch.file_name = NULL;
20516 nested_arch.file = NULL;
20517 nested_arch.index_array = NULL;
20518 nested_arch.sym_table = NULL;
20519 nested_arch.longnames = NULL;
20520
dda8d76d 20521 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
20522 filedata->file_size, is_thin_archive,
20523 do_archive_index) != 0)
2cf0635d 20524 {
32ec8896 20525 ret = FALSE;
2cf0635d 20526 goto out;
4145f1d5 20527 }
fb52b2f4 20528
4145f1d5
NC
20529 if (do_archive_index)
20530 {
2cf0635d 20531 if (arch.sym_table == NULL)
1cb7d8b1
AM
20532 error (_("%s: unable to dump the index as none was found\n"),
20533 filedata->file_name);
4145f1d5
NC
20534 else
20535 {
591f7597 20536 unsigned long i, l;
4145f1d5
NC
20537 unsigned long current_pos;
20538
1cb7d8b1
AM
20539 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
20540 "in the symbol table)\n"),
20541 filedata->file_name, (unsigned long) arch.index_num,
20542 arch.sym_size);
dda8d76d
NC
20543
20544 current_pos = ftell (filedata->handle);
4145f1d5 20545
2cf0635d 20546 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 20547 {
1cb7d8b1
AM
20548 if (i == 0
20549 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
20550 {
20551 char * member_name
20552 = get_archive_member_name_at (&arch, arch.index_array[i],
20553 &nested_arch);
2cf0635d 20554
1cb7d8b1
AM
20555 if (member_name != NULL)
20556 {
20557 char * qualified_name
20558 = make_qualified_name (&arch, &nested_arch,
20559 member_name);
2cf0635d 20560
1cb7d8b1
AM
20561 if (qualified_name != NULL)
20562 {
20563 printf (_("Contents of binary %s at offset "),
20564 qualified_name);
c2a7d3f5
NC
20565 (void) print_vma (arch.index_array[i], PREFIX_HEX);
20566 putchar ('\n');
1cb7d8b1
AM
20567 free (qualified_name);
20568 }
fd486f32 20569 free (member_name);
4145f1d5
NC
20570 }
20571 }
2cf0635d
NC
20572
20573 if (l >= arch.sym_size)
4145f1d5 20574 {
1cb7d8b1
AM
20575 error (_("%s: end of the symbol table reached "
20576 "before the end of the index\n"),
dda8d76d 20577 filedata->file_name);
32ec8896 20578 ret = FALSE;
cb8f3167 20579 break;
4145f1d5 20580 }
591f7597 20581 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
20582 printf ("\t%.*s\n",
20583 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 20584 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
20585 }
20586
67ce483b 20587 if (arch.uses_64bit_indices)
c2a7d3f5
NC
20588 l = (l + 7) & ~ 7;
20589 else
20590 l += l & 1;
20591
2cf0635d 20592 if (l < arch.sym_size)
32ec8896 20593 {
d3a49aa8
AM
20594 error (ngettext ("%s: %ld byte remains in the symbol table, "
20595 "but without corresponding entries in "
20596 "the index table\n",
20597 "%s: %ld bytes remain in the symbol table, "
20598 "but without corresponding entries in "
20599 "the index table\n",
20600 arch.sym_size - l),
dda8d76d 20601 filedata->file_name, arch.sym_size - l);
32ec8896
NC
20602 ret = FALSE;
20603 }
4145f1d5 20604
dda8d76d 20605 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 20606 {
1cb7d8b1
AM
20607 error (_("%s: failed to seek back to start of object files "
20608 "in the archive\n"),
dda8d76d 20609 filedata->file_name);
32ec8896 20610 ret = FALSE;
2cf0635d 20611 goto out;
4145f1d5 20612 }
fb52b2f4 20613 }
4145f1d5
NC
20614
20615 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
20616 && !do_segments && !do_header && !do_dump && !do_version
20617 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 20618 && !do_section_groups && !do_dyn_syms)
2cf0635d 20619 {
32ec8896 20620 ret = TRUE; /* Archive index only. */
2cf0635d
NC
20621 goto out;
20622 }
fb52b2f4
NC
20623 }
20624
fb52b2f4
NC
20625 while (1)
20626 {
2cf0635d
NC
20627 char * name;
20628 size_t namelen;
20629 char * qualified_name;
20630
20631 /* Read the next archive header. */
dda8d76d 20632 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
20633 {
20634 error (_("%s: failed to seek to next archive header\n"),
20635 arch.file_name);
20636 ret = FALSE;
20637 break;
20638 }
dda8d76d 20639 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 20640 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
20641 {
20642 if (got == 0)
2cf0635d 20643 break;
28e817cc
NC
20644 /* PR 24049 - we cannot use filedata->file_name as this will
20645 have already been freed. */
20646 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 20647
1cb7d8b1
AM
20648 ret = FALSE;
20649 break;
20650 }
2cf0635d 20651 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
20652 {
20653 error (_("%s: did not find a valid archive header\n"),
20654 arch.file_name);
20655 ret = FALSE;
20656 break;
20657 }
2cf0635d
NC
20658
20659 arch.next_arhdr_offset += sizeof arch.arhdr;
20660
978c4450
AM
20661 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
20662 if (filedata->archive_file_size & 01)
20663 ++filedata->archive_file_size;
2cf0635d
NC
20664
20665 name = get_archive_member_name (&arch, &nested_arch);
20666 if (name == NULL)
fb52b2f4 20667 {
28e817cc 20668 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 20669 ret = FALSE;
d989285c 20670 break;
fb52b2f4 20671 }
2cf0635d 20672 namelen = strlen (name);
fb52b2f4 20673
2cf0635d
NC
20674 qualified_name = make_qualified_name (&arch, &nested_arch, name);
20675 if (qualified_name == NULL)
fb52b2f4 20676 {
28e817cc 20677 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 20678 free (name);
32ec8896 20679 ret = FALSE;
d989285c 20680 break;
fb52b2f4
NC
20681 }
20682
2cf0635d 20683 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
20684 {
20685 /* This is a proxy for an external member of a thin archive. */
20686 Filedata * member_filedata;
20687 char * member_file_name = adjust_relative_path
dda8d76d 20688 (filedata->file_name, name, namelen);
32ec8896 20689
fd486f32 20690 free (name);
1cb7d8b1
AM
20691 if (member_file_name == NULL)
20692 {
fd486f32 20693 free (qualified_name);
1cb7d8b1
AM
20694 ret = FALSE;
20695 break;
20696 }
2cf0635d 20697
1cb7d8b1
AM
20698 member_filedata = open_file (member_file_name);
20699 if (member_filedata == NULL)
20700 {
20701 error (_("Input file '%s' is not readable.\n"), member_file_name);
20702 free (member_file_name);
fd486f32 20703 free (qualified_name);
1cb7d8b1
AM
20704 ret = FALSE;
20705 break;
20706 }
2cf0635d 20707
978c4450 20708 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 20709 member_filedata->file_name = qualified_name;
2cf0635d 20710
1cb7d8b1 20711 if (! process_object (member_filedata))
32ec8896 20712 ret = FALSE;
2cf0635d 20713
1cb7d8b1
AM
20714 close_file (member_filedata);
20715 free (member_file_name);
1cb7d8b1 20716 }
2cf0635d 20717 else if (is_thin_archive)
1cb7d8b1
AM
20718 {
20719 Filedata thin_filedata;
eb02c04d 20720
1cb7d8b1 20721 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 20722
a043396b
NC
20723 /* PR 15140: Allow for corrupt thin archives. */
20724 if (nested_arch.file == NULL)
20725 {
20726 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 20727 qualified_name, name);
fd486f32
AM
20728 free (qualified_name);
20729 free (name);
32ec8896 20730 ret = FALSE;
a043396b
NC
20731 break;
20732 }
fd486f32 20733 free (name);
a043396b 20734
1cb7d8b1 20735 /* This is a proxy for a member of a nested archive. */
978c4450
AM
20736 filedata->archive_file_offset
20737 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 20738
1cb7d8b1
AM
20739 /* The nested archive file will have been opened and setup by
20740 get_archive_member_name. */
978c4450
AM
20741 if (fseek (nested_arch.file, filedata->archive_file_offset,
20742 SEEK_SET) != 0)
1cb7d8b1
AM
20743 {
20744 error (_("%s: failed to seek to archive member.\n"),
20745 nested_arch.file_name);
fd486f32 20746 free (qualified_name);
1cb7d8b1
AM
20747 ret = FALSE;
20748 break;
20749 }
2cf0635d 20750
dda8d76d
NC
20751 thin_filedata.handle = nested_arch.file;
20752 thin_filedata.file_name = qualified_name;
9abca702 20753
1cb7d8b1 20754 if (! process_object (& thin_filedata))
32ec8896 20755 ret = FALSE;
1cb7d8b1 20756 }
2cf0635d 20757 else
1cb7d8b1 20758 {
fd486f32 20759 free (name);
978c4450 20760 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 20761 filedata->file_name = qualified_name;
1cb7d8b1 20762 if (! process_object (filedata))
32ec8896 20763 ret = FALSE;
978c4450 20764 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 20765 /* Stop looping with "negative" archive_file_size. */
978c4450 20766 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 20767 arch.next_arhdr_offset = -1ul;
1cb7d8b1 20768 }
fb52b2f4 20769
2cf0635d 20770 free (qualified_name);
fb52b2f4
NC
20771 }
20772
4145f1d5 20773 out:
2cf0635d
NC
20774 if (nested_arch.file != NULL)
20775 fclose (nested_arch.file);
20776 release_archive (&nested_arch);
20777 release_archive (&arch);
fb52b2f4 20778
d989285c 20779 return ret;
fb52b2f4
NC
20780}
20781
32ec8896 20782static bfd_boolean
2cf0635d 20783process_file (char * file_name)
fb52b2f4 20784{
dda8d76d 20785 Filedata * filedata = NULL;
fb52b2f4
NC
20786 struct stat statbuf;
20787 char armag[SARMAG];
32ec8896 20788 bfd_boolean ret = TRUE;
fb52b2f4
NC
20789
20790 if (stat (file_name, &statbuf) < 0)
20791 {
f24ddbdd
NC
20792 if (errno == ENOENT)
20793 error (_("'%s': No such file\n"), file_name);
20794 else
20795 error (_("Could not locate '%s'. System error message: %s\n"),
20796 file_name, strerror (errno));
32ec8896 20797 return FALSE;
f24ddbdd
NC
20798 }
20799
20800 if (! S_ISREG (statbuf.st_mode))
20801 {
20802 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 20803 return FALSE;
fb52b2f4
NC
20804 }
20805
dda8d76d
NC
20806 filedata = calloc (1, sizeof * filedata);
20807 if (filedata == NULL)
20808 {
20809 error (_("Out of memory allocating file data structure\n"));
20810 return FALSE;
20811 }
20812
20813 filedata->file_name = file_name;
20814 filedata->handle = fopen (file_name, "rb");
20815 if (filedata->handle == NULL)
fb52b2f4 20816 {
f24ddbdd 20817 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 20818 free (filedata);
32ec8896 20819 return FALSE;
fb52b2f4
NC
20820 }
20821
dda8d76d 20822 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 20823 {
4145f1d5 20824 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
20825 fclose (filedata->handle);
20826 free (filedata);
32ec8896 20827 return FALSE;
fb52b2f4
NC
20828 }
20829
dda8d76d 20830 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 20831
fb52b2f4 20832 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 20833 {
dda8d76d 20834 if (! process_archive (filedata, FALSE))
32ec8896
NC
20835 ret = FALSE;
20836 }
2cf0635d 20837 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 20838 {
dda8d76d 20839 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
20840 ret = FALSE;
20841 }
fb52b2f4
NC
20842 else
20843 {
1b513401 20844 if (do_archive_index && !check_all)
4145f1d5
NC
20845 error (_("File %s is not an archive so its index cannot be displayed.\n"),
20846 file_name);
20847
dda8d76d 20848 rewind (filedata->handle);
978c4450 20849 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 20850
dda8d76d 20851 if (! process_object (filedata))
32ec8896 20852 ret = FALSE;
fb52b2f4
NC
20853 }
20854
dda8d76d 20855 fclose (filedata->handle);
8fb879cd
AM
20856 free (filedata->section_headers);
20857 free (filedata->program_headers);
20858 free (filedata->string_table);
6431e409 20859 free (filedata->dump.dump_sects);
dda8d76d 20860 free (filedata);
32ec8896 20861
fd486f32 20862 free (ba_cache.strtab);
1bd6175a 20863 ba_cache.strtab = NULL;
fd486f32 20864 free (ba_cache.symtab);
1bd6175a 20865 ba_cache.symtab = NULL;
fd486f32
AM
20866 ba_cache.filedata = NULL;
20867
fb52b2f4
NC
20868 return ret;
20869}
20870
252b5132
RH
20871#ifdef SUPPORT_DISASSEMBLY
20872/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 20873 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 20874 symbols. */
252b5132
RH
20875
20876void
2cf0635d 20877print_address (unsigned int addr, FILE * outfile)
252b5132
RH
20878{
20879 fprintf (outfile,"0x%8.8x", addr);
20880}
20881
e3c8793a 20882/* Needed by the i386 disassembler. */
dda8d76d 20883
252b5132
RH
20884void
20885db_task_printsym (unsigned int addr)
20886{
20887 print_address (addr, stderr);
20888}
20889#endif
20890
20891int
2cf0635d 20892main (int argc, char ** argv)
252b5132 20893{
ff78d6d6
L
20894 int err;
20895
252b5132
RH
20896#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
20897 setlocale (LC_MESSAGES, "");
3882b010
L
20898#endif
20899#if defined (HAVE_SETLOCALE)
20900 setlocale (LC_CTYPE, "");
252b5132
RH
20901#endif
20902 bindtextdomain (PACKAGE, LOCALEDIR);
20903 textdomain (PACKAGE);
20904
869b9d07
MM
20905 expandargv (&argc, &argv);
20906
dda8d76d 20907 parse_args (& cmdline, argc, argv);
59f14fc0 20908
18bd398b 20909 if (optind < (argc - 1))
1b513401
NC
20910 /* When displaying information for more than one file,
20911 prefix the information with the file name. */
32ec8896 20912 show_name = TRUE;
5656ba2c
L
20913 else if (optind >= argc)
20914 {
1b513401
NC
20915 /* Ensure that the warning is always displayed. */
20916 do_checks = TRUE;
20917
5656ba2c
L
20918 warn (_("Nothing to do.\n"));
20919 usage (stderr);
20920 }
18bd398b 20921
32ec8896 20922 err = FALSE;
252b5132 20923 while (optind < argc)
32ec8896
NC
20924 if (! process_file (argv[optind++]))
20925 err = TRUE;
252b5132 20926
9db70fc3 20927 free (cmdline.dump_sects);
252b5132 20928
7d9813f1
NA
20929 free (dump_ctf_symtab_name);
20930 free (dump_ctf_strtab_name);
20931 free (dump_ctf_parent_name);
20932
32ec8896 20933 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 20934}
This page took 3.423246 seconds and 4 git commands to generate.