PR26508 UBSAN: tc-xtensa.c:7764 null pointer bsearch
[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
252b5132 4033 default:
df3a023b 4034 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4035 {
2cf0635d 4036 const char * result;
103f02d3 4037
dda8d76d 4038 switch (filedata->file_header.e_machine)
252b5132 4039 {
a06ea964
NC
4040 case EM_AARCH64:
4041 result = get_aarch64_segment_type (p_type);
4042 break;
b294bdf8
MM
4043 case EM_ARM:
4044 result = get_arm_segment_type (p_type);
4045 break;
252b5132 4046 case EM_MIPS:
4fe85591 4047 case EM_MIPS_RS3_LE:
252b5132
RH
4048 result = get_mips_segment_type (p_type);
4049 break;
103f02d3
UD
4050 case EM_PARISC:
4051 result = get_parisc_segment_type (p_type);
4052 break;
4d6ed7c8
NC
4053 case EM_IA_64:
4054 result = get_ia64_segment_type (p_type);
4055 break;
40b36596
JM
4056 case EM_TI_C6000:
4057 result = get_tic6x_segment_type (p_type);
4058 break;
b4cbbe8f
AK
4059 case EM_S390:
4060 case EM_S390_OLD:
4061 result = get_s390_segment_type (p_type);
4062 break;
252b5132
RH
4063 default:
4064 result = NULL;
4065 break;
4066 }
103f02d3 4067
252b5132
RH
4068 if (result != NULL)
4069 return result;
103f02d3 4070
1a9ccd70 4071 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4072 }
4073 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4074 {
df3a023b 4075 const char * result = NULL;
103f02d3 4076
df3a023b 4077 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4078 {
df3a023b
AM
4079 case ELFOSABI_GNU:
4080 case ELFOSABI_FREEBSD:
4081 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4082 {
4083 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4084 result = buff;
4085 }
103f02d3 4086 break;
df3a023b
AM
4087 case ELFOSABI_HPUX:
4088 result = get_hpux_segment_type (p_type,
4089 filedata->file_header.e_machine);
4090 break;
4091 case ELFOSABI_SOLARIS:
4092 result = get_solaris_segment_type (p_type);
00428cca 4093 break;
103f02d3 4094 default:
103f02d3
UD
4095 break;
4096 }
103f02d3
UD
4097 if (result != NULL)
4098 return result;
4099
1a9ccd70 4100 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4101 }
252b5132 4102 else
e9e44622 4103 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4104
4105 return buff;
4106 }
4107}
4108
53a346d8
CZ
4109static const char *
4110get_arc_section_type_name (unsigned int sh_type)
4111{
4112 switch (sh_type)
4113 {
4114 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4115 default:
4116 break;
4117 }
4118 return NULL;
4119}
4120
252b5132 4121static const char *
d3ba0551 4122get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4123{
4124 switch (sh_type)
4125 {
b34976b6
AM
4126 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4127 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4128 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4129 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4130 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4131 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4132 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4133 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4134 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4135 case SHT_MIPS_RELD: return "MIPS_RELD";
4136 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4137 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4138 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4139 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4140 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4141 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4142 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4143 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4144 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4145 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4146 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4147 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4148 case SHT_MIPS_LINE: return "MIPS_LINE";
4149 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4150 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4151 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4152 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4153 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4154 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4155 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4156 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4157 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4158 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4159 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4160 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4161 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4162 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4163 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4164 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4165 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4166 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4167 default:
4168 break;
4169 }
4170 return NULL;
4171}
4172
103f02d3 4173static const char *
d3ba0551 4174get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4175{
4176 switch (sh_type)
4177 {
4178 case SHT_PARISC_EXT: return "PARISC_EXT";
4179 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4180 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4181 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4182 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4183 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4184 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4185 default: return NULL;
103f02d3 4186 }
103f02d3
UD
4187}
4188
4d6ed7c8 4189static const char *
dda8d76d 4190get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4191{
18bd398b 4192 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4193 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4194 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4195
4d6ed7c8
NC
4196 switch (sh_type)
4197 {
148b93f2
NC
4198 case SHT_IA_64_EXT: return "IA_64_EXT";
4199 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4200 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4201 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4202 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4203 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4204 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4205 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4206 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4207 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4208 default:
4209 break;
4210 }
4211 return NULL;
4212}
4213
d2b2c203
DJ
4214static const char *
4215get_x86_64_section_type_name (unsigned int sh_type)
4216{
4217 switch (sh_type)
4218 {
4219 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4220 default: return NULL;
d2b2c203 4221 }
d2b2c203
DJ
4222}
4223
a06ea964
NC
4224static const char *
4225get_aarch64_section_type_name (unsigned int sh_type)
4226{
4227 switch (sh_type)
4228 {
32ec8896
NC
4229 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4230 default: return NULL;
a06ea964 4231 }
a06ea964
NC
4232}
4233
40a18ebd
NC
4234static const char *
4235get_arm_section_type_name (unsigned int sh_type)
4236{
4237 switch (sh_type)
4238 {
7f6fed87
NC
4239 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4240 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4241 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4242 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4243 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4244 default: return NULL;
40a18ebd 4245 }
40a18ebd
NC
4246}
4247
40b36596
JM
4248static const char *
4249get_tic6x_section_type_name (unsigned int sh_type)
4250{
4251 switch (sh_type)
4252 {
32ec8896
NC
4253 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4254 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4255 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4256 case SHT_TI_ICODE: return "TI_ICODE";
4257 case SHT_TI_XREF: return "TI_XREF";
4258 case SHT_TI_HANDLER: return "TI_HANDLER";
4259 case SHT_TI_INITINFO: return "TI_INITINFO";
4260 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4261 default: return NULL;
40b36596 4262 }
40b36596
JM
4263}
4264
13761a11
NC
4265static const char *
4266get_msp430x_section_type_name (unsigned int sh_type)
4267{
4268 switch (sh_type)
4269 {
32ec8896
NC
4270 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4271 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4272 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4273 default: return NULL;
13761a11
NC
4274 }
4275}
4276
fe944acf
FT
4277static const char *
4278get_nfp_section_type_name (unsigned int sh_type)
4279{
4280 switch (sh_type)
4281 {
4282 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4283 case SHT_NFP_INITREG: return "NFP_INITREG";
4284 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4285 default: return NULL;
4286 }
4287}
4288
685080f2
NC
4289static const char *
4290get_v850_section_type_name (unsigned int sh_type)
4291{
4292 switch (sh_type)
4293 {
32ec8896
NC
4294 case SHT_V850_SCOMMON: return "V850 Small Common";
4295 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4296 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4297 case SHT_RENESAS_IOP: return "RENESAS IOP";
4298 case SHT_RENESAS_INFO: return "RENESAS INFO";
4299 default: return NULL;
685080f2
NC
4300 }
4301}
4302
2dc8dd17
JW
4303static const char *
4304get_riscv_section_type_name (unsigned int sh_type)
4305{
4306 switch (sh_type)
4307 {
4308 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4309 default: return NULL;
4310 }
4311}
4312
252b5132 4313static const char *
dda8d76d 4314get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4315{
b34976b6 4316 static char buff[32];
9fb71ee4 4317 const char * result;
252b5132
RH
4318
4319 switch (sh_type)
4320 {
4321 case SHT_NULL: return "NULL";
4322 case SHT_PROGBITS: return "PROGBITS";
4323 case SHT_SYMTAB: return "SYMTAB";
4324 case SHT_STRTAB: return "STRTAB";
4325 case SHT_RELA: return "RELA";
4326 case SHT_HASH: return "HASH";
4327 case SHT_DYNAMIC: return "DYNAMIC";
4328 case SHT_NOTE: return "NOTE";
4329 case SHT_NOBITS: return "NOBITS";
4330 case SHT_REL: return "REL";
4331 case SHT_SHLIB: return "SHLIB";
4332 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4333 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4334 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4335 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4336 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4337 case SHT_GROUP: return "GROUP";
67ce483b 4338 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4339 case SHT_GNU_verdef: return "VERDEF";
4340 case SHT_GNU_verneed: return "VERNEED";
4341 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4342 case 0x6ffffff0: return "VERSYM";
4343 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4344 case 0x7ffffffd: return "AUXILIARY";
4345 case 0x7fffffff: return "FILTER";
047b2264 4346 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4347
4348 default:
4349 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4350 {
dda8d76d 4351 switch (filedata->file_header.e_machine)
252b5132 4352 {
53a346d8
CZ
4353 case EM_ARC:
4354 case EM_ARC_COMPACT:
4355 case EM_ARC_COMPACT2:
4356 result = get_arc_section_type_name (sh_type);
4357 break;
252b5132 4358 case EM_MIPS:
4fe85591 4359 case EM_MIPS_RS3_LE:
252b5132
RH
4360 result = get_mips_section_type_name (sh_type);
4361 break;
103f02d3
UD
4362 case EM_PARISC:
4363 result = get_parisc_section_type_name (sh_type);
4364 break;
4d6ed7c8 4365 case EM_IA_64:
dda8d76d 4366 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4367 break;
d2b2c203 4368 case EM_X86_64:
8a9036a4 4369 case EM_L1OM:
7a9068fe 4370 case EM_K1OM:
d2b2c203
DJ
4371 result = get_x86_64_section_type_name (sh_type);
4372 break;
a06ea964
NC
4373 case EM_AARCH64:
4374 result = get_aarch64_section_type_name (sh_type);
4375 break;
40a18ebd
NC
4376 case EM_ARM:
4377 result = get_arm_section_type_name (sh_type);
4378 break;
40b36596
JM
4379 case EM_TI_C6000:
4380 result = get_tic6x_section_type_name (sh_type);
4381 break;
13761a11
NC
4382 case EM_MSP430:
4383 result = get_msp430x_section_type_name (sh_type);
4384 break;
fe944acf
FT
4385 case EM_NFP:
4386 result = get_nfp_section_type_name (sh_type);
4387 break;
685080f2
NC
4388 case EM_V800:
4389 case EM_V850:
4390 case EM_CYGNUS_V850:
4391 result = get_v850_section_type_name (sh_type);
4392 break;
2dc8dd17
JW
4393 case EM_RISCV:
4394 result = get_riscv_section_type_name (sh_type);
4395 break;
252b5132
RH
4396 default:
4397 result = NULL;
4398 break;
4399 }
4400
4401 if (result != NULL)
4402 return result;
4403
9fb71ee4 4404 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4405 }
4406 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4407 {
dda8d76d 4408 switch (filedata->file_header.e_machine)
148b93f2
NC
4409 {
4410 case EM_IA_64:
dda8d76d 4411 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4412 break;
4413 default:
dda8d76d 4414 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4415 result = get_solaris_section_type (sh_type);
4416 else
1b4b80bf
NC
4417 {
4418 switch (sh_type)
4419 {
4420 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4421 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4422 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4423 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4424 default:
4425 result = NULL;
4426 break;
4427 }
4428 }
148b93f2
NC
4429 break;
4430 }
4431
4432 if (result != NULL)
4433 return result;
4434
9fb71ee4 4435 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4436 }
252b5132 4437 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4438 {
dda8d76d 4439 switch (filedata->file_header.e_machine)
685080f2
NC
4440 {
4441 case EM_V800:
4442 case EM_V850:
4443 case EM_CYGNUS_V850:
9fb71ee4 4444 result = get_v850_section_type_name (sh_type);
a9fb83be 4445 break;
685080f2 4446 default:
9fb71ee4 4447 result = NULL;
685080f2
NC
4448 break;
4449 }
4450
9fb71ee4
NC
4451 if (result != NULL)
4452 return result;
4453
4454 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4455 }
252b5132 4456 else
a7dbfd1c
NC
4457 /* This message is probably going to be displayed in a 15
4458 character wide field, so put the hex value first. */
4459 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4460
252b5132
RH
4461 return buff;
4462 }
4463}
4464
79bc120c
NC
4465enum long_option_values
4466{
4467 OPTION_DEBUG_DUMP = 512,
4468 OPTION_DYN_SYMS,
4469 OPTION_DWARF_DEPTH,
4470 OPTION_DWARF_START,
4471 OPTION_DWARF_CHECK,
4472 OPTION_CTF_DUMP,
4473 OPTION_CTF_PARENT,
4474 OPTION_CTF_SYMBOLS,
4475 OPTION_CTF_STRINGS,
4476 OPTION_WITH_SYMBOL_VERSIONS,
4477 OPTION_RECURSE_LIMIT,
4478 OPTION_NO_RECURSE_LIMIT,
4479 OPTION_NO_DEMANGLING
4480};
2979dc34 4481
85b1c36d 4482static struct option options[] =
252b5132 4483{
79bc120c
NC
4484 /* Note - This table is alpha-sorted on the 'val'
4485 field in order to make adding new options easier. */
4486 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4487 {"all", no_argument, 0, 'a'},
79bc120c
NC
4488 {"demangle", optional_argument, 0, 'C'},
4489 {"archive-index", no_argument, 0, 'c'},
4490 {"use-dynamic", no_argument, 0, 'D'},
4491 {"dynamic", no_argument, 0, 'd'},
b34976b6 4492 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4493 {"section-groups", no_argument, 0, 'g'},
4494 {"help", no_argument, 0, 'H'},
4495 {"file-header", no_argument, 0, 'h'},
b34976b6 4496 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4497 {"lint", no_argument, 0, 'L'},
4498 {"enable-checks", no_argument, 0, 'L'},
4499 {"program-headers", no_argument, 0, 'l'},
b34976b6 4500 {"segments", no_argument, 0, 'l'},
595cf52e 4501 {"full-section-name",no_argument, 0, 'N'},
79bc120c
NC
4502 {"notes", no_argument, 0, 'n'},
4503 {"string-dump", required_argument, 0, 'p'},
4504 {"relocated-dump", required_argument, 0, 'R'},
4505 {"relocs", no_argument, 0, 'r'},
4506 {"section-headers", no_argument, 0, 'S'},
4507 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4508 {"symbols", no_argument, 0, 's'},
4509 {"syms", no_argument, 0, 's'},
79bc120c
NC
4510 {"silent-truncation",no_argument, 0, 'T'},
4511 {"section-details", no_argument, 0, 't'},
09c11c86 4512 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4513 {"version-info", no_argument, 0, 'V'},
4514 {"version", no_argument, 0, 'v'},
4515 {"wide", no_argument, 0, 'W'},
b34976b6 4516 {"hex-dump", required_argument, 0, 'x'},
0e602686 4517 {"decompress", no_argument, 0, 'z'},
252b5132 4518
79bc120c
NC
4519 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4520 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4521 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4522 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4523 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
4524 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4525 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4526 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4527 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4528#ifdef ENABLE_LIBCTF
d344b407 4529 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4530 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4531 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4532 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4533#endif
7d9813f1 4534
b34976b6 4535 {0, no_argument, 0, 0}
252b5132
RH
4536};
4537
4538static void
2cf0635d 4539usage (FILE * stream)
252b5132 4540{
92f01d61
JM
4541 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4542 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4543 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4544 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4545 -h --file-header Display the ELF file header\n\
4546 -l --program-headers Display the program headers\n\
4547 --segments An alias for --program-headers\n\
4548 -S --section-headers Display the sections' header\n\
4549 --sections An alias for --section-headers\n\
f5842774 4550 -g --section-groups Display the section groups\n\
5477e8a0 4551 -t --section-details Display the section details\n\
8b53311e
NC
4552 -e --headers Equivalent to: -h -l -S\n\
4553 -s --syms Display the symbol table\n\
3f08eb35 4554 --symbols An alias for --syms\n\
1b513401 4555 --dyn-syms Display the dynamic symbol table\n\
79bc120c
NC
4556 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4557 The STYLE, if specified, can be `auto' (the default),\n\
4558 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
4559 or `gnat'\n\
4560 --no-demangle Do not demangle low-level symbol names. (This is the default)\n\
4561 --recurse-limit Enable a demangling recursion limit. (This is the default)\n\
4562 --no-recurse-limit Disable a demangling recursion limit\n\
8b53311e
NC
4563 -n --notes Display the core notes (if present)\n\
4564 -r --relocs Display the relocations (if present)\n\
4565 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4566 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4567 -V --version-info Display the version sections (if present)\n\
1b31d05e 4568 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4569 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4570 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4571 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4572 -x --hex-dump=<number|name>\n\
4573 Dump the contents of section <number|name> as bytes\n\
4574 -p --string-dump=<number|name>\n\
4575 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4576 -R --relocated-dump=<number|name>\n\
4577 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4578 -z --decompress Decompress section before dumping it\n\
e4b7104b 4579 -w[lLiaprmfFsoORtUuTgAckK] or\n\
1ed06042 4580 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
e4b7104b 4581 =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
657d0d47 4582 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4583 =addr,=cu_index,=links,=follow-links]\n\
4584 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4585 fprintf (stream, _("\
4586 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4587 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4588 or deeper\n"));
094e34f2 4589#ifdef ENABLE_LIBCTF
7d9813f1
NA
4590 fprintf (stream, _("\
4591 --ctf=<number|name> Display CTF info from section <number|name>\n\
4592 --ctf-parent=<number|name>\n\
4593 Use section <number|name> as the CTF parent\n\n\
4594 --ctf-symbols=<number|name>\n\
4595 Use section <number|name> as the CTF external symtab\n\n\
4596 --ctf-strings=<number|name>\n\
4597 Use section <number|name> as the CTF external strtab\n\n"));
094e34f2 4598#endif
7d9813f1 4599
252b5132 4600#ifdef SUPPORT_DISASSEMBLY
92f01d61 4601 fprintf (stream, _("\
09c11c86
NC
4602 -i --instruction-dump=<number|name>\n\
4603 Disassemble the contents of section <number|name>\n"));
252b5132 4604#endif
92f01d61 4605 fprintf (stream, _("\
8b53311e
NC
4606 -I --histogram Display histogram of bucket list lengths\n\
4607 -W --wide Allow output width to exceed 80 characters\n\
0942c7ab 4608 -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
07012eee 4609 @<file> Read options from <file>\n\
8b53311e
NC
4610 -H --help Display this information\n\
4611 -v --version Display the version number of readelf\n"));
1118d252 4612
92f01d61
JM
4613 if (REPORT_BUGS_TO[0] && stream == stdout)
4614 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4615
92f01d61 4616 exit (stream == stdout ? 0 : 1);
252b5132
RH
4617}
4618
18bd398b
NC
4619/* Record the fact that the user wants the contents of section number
4620 SECTION to be displayed using the method(s) encoded as flags bits
4621 in TYPE. Note, TYPE can be zero if we are creating the array for
4622 the first time. */
4623
252b5132 4624static void
6431e409
AM
4625request_dump_bynumber (struct dump_data *dumpdata,
4626 unsigned int section, dump_type type)
252b5132 4627{
6431e409 4628 if (section >= dumpdata->num_dump_sects)
252b5132 4629 {
2cf0635d 4630 dump_type * new_dump_sects;
252b5132 4631
3f5e193b 4632 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4633 sizeof (* new_dump_sects));
252b5132
RH
4634
4635 if (new_dump_sects == NULL)
591a748a 4636 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4637 else
4638 {
6431e409 4639 if (dumpdata->dump_sects)
21b65bac
NC
4640 {
4641 /* Copy current flag settings. */
6431e409
AM
4642 memcpy (new_dump_sects, dumpdata->dump_sects,
4643 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4644
6431e409 4645 free (dumpdata->dump_sects);
21b65bac 4646 }
252b5132 4647
6431e409
AM
4648 dumpdata->dump_sects = new_dump_sects;
4649 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4650 }
4651 }
4652
6431e409
AM
4653 if (dumpdata->dump_sects)
4654 dumpdata->dump_sects[section] |= type;
252b5132
RH
4655}
4656
aef1f6d0
DJ
4657/* Request a dump by section name. */
4658
4659static void
2cf0635d 4660request_dump_byname (const char * section, dump_type type)
aef1f6d0 4661{
2cf0635d 4662 struct dump_list_entry * new_request;
aef1f6d0 4663
3f5e193b
NC
4664 new_request = (struct dump_list_entry *)
4665 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4666 if (!new_request)
591a748a 4667 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4668
4669 new_request->name = strdup (section);
4670 if (!new_request->name)
591a748a 4671 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4672
4673 new_request->type = type;
4674
4675 new_request->next = dump_sects_byname;
4676 dump_sects_byname = new_request;
4677}
4678
cf13d699 4679static inline void
6431e409 4680request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4681{
4682 int section;
4683 char * cp;
4684
4685 do_dump++;
4686 section = strtoul (optarg, & cp, 0);
4687
4688 if (! *cp && section >= 0)
6431e409 4689 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4690 else
4691 request_dump_byname (optarg, type);
4692}
4693
252b5132 4694static void
6431e409 4695parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4696{
4697 int c;
4698
4699 if (argc < 2)
92f01d61 4700 usage (stderr);
252b5132
RH
4701
4702 while ((c = getopt_long
79bc120c 4703 (argc, argv, "ACDHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4704 {
252b5132
RH
4705 switch (c)
4706 {
4707 case 0:
4708 /* Long options. */
4709 break;
4710 case 'H':
92f01d61 4711 usage (stdout);
252b5132
RH
4712 break;
4713
4714 case 'a':
32ec8896
NC
4715 do_syms = TRUE;
4716 do_reloc = TRUE;
4717 do_unwind = TRUE;
4718 do_dynamic = TRUE;
4719 do_header = TRUE;
4720 do_sections = TRUE;
4721 do_section_groups = TRUE;
4722 do_segments = TRUE;
4723 do_version = TRUE;
4724 do_histogram = TRUE;
4725 do_arch = TRUE;
4726 do_notes = TRUE;
252b5132 4727 break;
79bc120c 4728
f5842774 4729 case 'g':
32ec8896 4730 do_section_groups = TRUE;
f5842774 4731 break;
5477e8a0 4732 case 't':
595cf52e 4733 case 'N':
32ec8896
NC
4734 do_sections = TRUE;
4735 do_section_details = TRUE;
595cf52e 4736 break;
252b5132 4737 case 'e':
32ec8896
NC
4738 do_header = TRUE;
4739 do_sections = TRUE;
4740 do_segments = TRUE;
252b5132 4741 break;
a952a375 4742 case 'A':
32ec8896 4743 do_arch = TRUE;
a952a375 4744 break;
252b5132 4745 case 'D':
32ec8896 4746 do_using_dynamic = TRUE;
252b5132
RH
4747 break;
4748 case 'r':
32ec8896 4749 do_reloc = TRUE;
252b5132 4750 break;
4d6ed7c8 4751 case 'u':
32ec8896 4752 do_unwind = TRUE;
4d6ed7c8 4753 break;
252b5132 4754 case 'h':
32ec8896 4755 do_header = TRUE;
252b5132
RH
4756 break;
4757 case 'l':
32ec8896 4758 do_segments = TRUE;
252b5132
RH
4759 break;
4760 case 's':
32ec8896 4761 do_syms = TRUE;
252b5132
RH
4762 break;
4763 case 'S':
32ec8896 4764 do_sections = TRUE;
252b5132
RH
4765 break;
4766 case 'd':
32ec8896 4767 do_dynamic = TRUE;
252b5132 4768 break;
a952a375 4769 case 'I':
32ec8896 4770 do_histogram = TRUE;
a952a375 4771 break;
779fe533 4772 case 'n':
32ec8896 4773 do_notes = TRUE;
779fe533 4774 break;
4145f1d5 4775 case 'c':
32ec8896 4776 do_archive_index = TRUE;
4145f1d5 4777 break;
1b513401
NC
4778 case 'L':
4779 do_checks = TRUE;
4780 break;
252b5132 4781 case 'x':
6431e409 4782 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4783 break;
09c11c86 4784 case 'p':
6431e409 4785 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4786 break;
4787 case 'R':
6431e409 4788 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4789 break;
0e602686 4790 case 'z':
32ec8896 4791 decompress_dumps = TRUE;
0e602686 4792 break;
252b5132 4793 case 'w':
32ec8896 4794 do_dump = TRUE;
252b5132 4795 if (optarg == 0)
613ff48b 4796 {
32ec8896 4797 do_debugging = TRUE;
613ff48b
CC
4798 dwarf_select_sections_all ();
4799 }
252b5132
RH
4800 else
4801 {
32ec8896 4802 do_debugging = FALSE;
4cb93e3b 4803 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4804 }
4805 break;
2979dc34 4806 case OPTION_DEBUG_DUMP:
32ec8896 4807 do_dump = TRUE;
2979dc34 4808 if (optarg == 0)
32ec8896 4809 do_debugging = TRUE;
2979dc34
JJ
4810 else
4811 {
32ec8896 4812 do_debugging = FALSE;
4cb93e3b 4813 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4814 }
4815 break;
fd2f0033
TT
4816 case OPTION_DWARF_DEPTH:
4817 {
4818 char *cp;
4819
4820 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4821 }
4822 break;
4823 case OPTION_DWARF_START:
4824 {
4825 char *cp;
4826
4827 dwarf_start_die = strtoul (optarg, & cp, 0);
4828 }
4829 break;
4723351a 4830 case OPTION_DWARF_CHECK:
32ec8896 4831 dwarf_check = TRUE;
4723351a 4832 break;
7d9813f1
NA
4833 case OPTION_CTF_DUMP:
4834 do_ctf = TRUE;
6431e409 4835 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4836 break;
4837 case OPTION_CTF_SYMBOLS:
df16e041 4838 free (dump_ctf_symtab_name);
7d9813f1
NA
4839 dump_ctf_symtab_name = strdup (optarg);
4840 break;
4841 case OPTION_CTF_STRINGS:
df16e041 4842 free (dump_ctf_strtab_name);
7d9813f1
NA
4843 dump_ctf_strtab_name = strdup (optarg);
4844 break;
4845 case OPTION_CTF_PARENT:
df16e041 4846 free (dump_ctf_parent_name);
7d9813f1
NA
4847 dump_ctf_parent_name = strdup (optarg);
4848 break;
2c610e4b 4849 case OPTION_DYN_SYMS:
32ec8896 4850 do_dyn_syms = TRUE;
2c610e4b 4851 break;
252b5132
RH
4852#ifdef SUPPORT_DISASSEMBLY
4853 case 'i':
6431e409 4854 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4855 break;
252b5132
RH
4856#endif
4857 case 'v':
4858 print_version (program_name);
4859 break;
4860 case 'V':
32ec8896 4861 do_version = TRUE;
252b5132 4862 break;
d974e256 4863 case 'W':
32ec8896 4864 do_wide = TRUE;
d974e256 4865 break;
0942c7ab
NC
4866 case 'T':
4867 do_not_show_symbol_truncation = TRUE;
4868 break;
79bc120c
NC
4869 case 'C':
4870 do_demangle = TRUE;
4871 if (optarg != NULL)
4872 {
4873 enum demangling_styles style;
4874
4875 style = cplus_demangle_name_to_style (optarg);
4876 if (style == unknown_demangling)
4877 error (_("unknown demangling style `%s'"), optarg);
4878
4879 cplus_demangle_set_style (style);
4880 }
4881 break;
4882 case OPTION_NO_DEMANGLING:
4883 do_demangle = FALSE;
4884 break;
4885 case OPTION_RECURSE_LIMIT:
4886 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
4887 break;
4888 case OPTION_NO_RECURSE_LIMIT:
4889 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
4890 break;
4891 case OPTION_WITH_SYMBOL_VERSIONS:
4892 /* Ignored for backward compatibility. */
4893 break;
4894
252b5132 4895 default:
252b5132
RH
4896 /* xgettext:c-format */
4897 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4898 /* Fall through. */
252b5132 4899 case '?':
92f01d61 4900 usage (stderr);
252b5132
RH
4901 }
4902 }
4903
4d6ed7c8 4904 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4905 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4906 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b
L
4907 && !do_section_groups && !do_archive_index
4908 && !do_dyn_syms)
1b513401
NC
4909 {
4910 if (do_checks)
4911 {
4912 check_all = TRUE;
4913 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = TRUE;
4914 do_segments = do_header = do_dump = do_version = TRUE;
4915 do_histogram = do_debugging = do_arch = do_notes = TRUE;
4916 do_section_groups = do_archive_index = do_dyn_syms = TRUE;
4917 }
4918 else
4919 usage (stderr);
4920 }
252b5132
RH
4921}
4922
4923static const char *
d3ba0551 4924get_elf_class (unsigned int elf_class)
252b5132 4925{
b34976b6 4926 static char buff[32];
103f02d3 4927
252b5132
RH
4928 switch (elf_class)
4929 {
4930 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4931 case ELFCLASS32: return "ELF32";
4932 case ELFCLASS64: return "ELF64";
ab5e7794 4933 default:
e9e44622 4934 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4935 return buff;
252b5132
RH
4936 }
4937}
4938
4939static const char *
d3ba0551 4940get_data_encoding (unsigned int encoding)
252b5132 4941{
b34976b6 4942 static char buff[32];
103f02d3 4943
252b5132
RH
4944 switch (encoding)
4945 {
4946 case ELFDATANONE: return _("none");
33c63f9d
CM
4947 case ELFDATA2LSB: return _("2's complement, little endian");
4948 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 4949 default:
e9e44622 4950 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 4951 return buff;
252b5132
RH
4952 }
4953}
4954
dda8d76d 4955/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 4956
32ec8896 4957static bfd_boolean
dda8d76d 4958process_file_header (Filedata * filedata)
252b5132 4959{
dda8d76d
NC
4960 Elf_Internal_Ehdr * header = & filedata->file_header;
4961
4962 if ( header->e_ident[EI_MAG0] != ELFMAG0
4963 || header->e_ident[EI_MAG1] != ELFMAG1
4964 || header->e_ident[EI_MAG2] != ELFMAG2
4965 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
4966 {
4967 error
4968 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 4969 return FALSE;
252b5132
RH
4970 }
4971
955ff7fc 4972 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 4973
252b5132
RH
4974 if (do_header)
4975 {
32ec8896 4976 unsigned i;
252b5132
RH
4977
4978 printf (_("ELF Header:\n"));
4979 printf (_(" Magic: "));
b34976b6 4980 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 4981 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
4982 printf ("\n");
4983 printf (_(" Class: %s\n"),
dda8d76d 4984 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 4985 printf (_(" Data: %s\n"),
dda8d76d 4986 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 4987 printf (_(" Version: %d%s\n"),
dda8d76d
NC
4988 header->e_ident[EI_VERSION],
4989 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 4990 ? _(" (current)")
dda8d76d 4991 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 4992 ? _(" <unknown>")
789be9f7 4993 : "")));
252b5132 4994 printf (_(" OS/ABI: %s\n"),
dda8d76d 4995 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 4996 printf (_(" ABI Version: %d\n"),
dda8d76d 4997 header->e_ident[EI_ABIVERSION]);
252b5132 4998 printf (_(" Type: %s\n"),
dda8d76d 4999 get_file_type (header->e_type));
252b5132 5000 printf (_(" Machine: %s\n"),
dda8d76d 5001 get_machine_name (header->e_machine));
252b5132 5002 printf (_(" Version: 0x%lx\n"),
e8a64888 5003 header->e_version);
76da6bbe 5004
f7a99963 5005 printf (_(" Entry point address: "));
e8a64888 5006 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5007 printf (_("\n Start of program headers: "));
e8a64888 5008 print_vma (header->e_phoff, DEC);
f7a99963 5009 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5010 print_vma (header->e_shoff, DEC);
f7a99963 5011 printf (_(" (bytes into file)\n"));
76da6bbe 5012
252b5132 5013 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5014 header->e_flags,
dda8d76d 5015 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5016 printf (_(" Size of this header: %u (bytes)\n"),
5017 header->e_ehsize);
5018 printf (_(" Size of program headers: %u (bytes)\n"),
5019 header->e_phentsize);
5020 printf (_(" Number of program headers: %u"),
5021 header->e_phnum);
dda8d76d
NC
5022 if (filedata->section_headers != NULL
5023 && header->e_phnum == PN_XNUM
5024 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5025 {
5026 header->e_phnum = filedata->section_headers[0].sh_info;
5027 printf (" (%u)", header->e_phnum);
5028 }
2046a35d 5029 putc ('\n', stdout);
e8a64888
AM
5030 printf (_(" Size of section headers: %u (bytes)\n"),
5031 header->e_shentsize);
5032 printf (_(" Number of section headers: %u"),
5033 header->e_shnum);
dda8d76d 5034 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5035 {
5036 header->e_shnum = filedata->section_headers[0].sh_size;
5037 printf (" (%u)", header->e_shnum);
5038 }
560f3c1c 5039 putc ('\n', stdout);
e8a64888
AM
5040 printf (_(" Section header string table index: %u"),
5041 header->e_shstrndx);
dda8d76d
NC
5042 if (filedata->section_headers != NULL
5043 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5044 {
5045 header->e_shstrndx = filedata->section_headers[0].sh_link;
5046 printf (" (%u)", header->e_shstrndx);
5047 }
5048 if (header->e_shstrndx != SHN_UNDEF
5049 && header->e_shstrndx >= header->e_shnum)
5050 {
5051 header->e_shstrndx = SHN_UNDEF;
5052 printf (_(" <corrupt: out of range>"));
5053 }
560f3c1c
AM
5054 putc ('\n', stdout);
5055 }
5056
dda8d76d 5057 if (filedata->section_headers != NULL)
560f3c1c 5058 {
dda8d76d
NC
5059 if (header->e_phnum == PN_XNUM
5060 && filedata->section_headers[0].sh_info != 0)
5061 header->e_phnum = filedata->section_headers[0].sh_info;
5062 if (header->e_shnum == SHN_UNDEF)
5063 header->e_shnum = filedata->section_headers[0].sh_size;
5064 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5065 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5066 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5067 header->e_shstrndx = SHN_UNDEF;
5068 free (filedata->section_headers);
5069 filedata->section_headers = NULL;
252b5132 5070 }
103f02d3 5071
32ec8896 5072 return TRUE;
9ea033b2
NC
5073}
5074
dda8d76d
NC
5075/* Read in the program headers from FILEDATA and store them in PHEADERS.
5076 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5077
e0a31db1 5078static bfd_boolean
dda8d76d 5079get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5080{
2cf0635d
NC
5081 Elf32_External_Phdr * phdrs;
5082 Elf32_External_Phdr * external;
5083 Elf_Internal_Phdr * internal;
b34976b6 5084 unsigned int i;
dda8d76d
NC
5085 unsigned int size = filedata->file_header.e_phentsize;
5086 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5087
5088 /* PR binutils/17531: Cope with unexpected section header sizes. */
5089 if (size == 0 || num == 0)
5090 return FALSE;
5091 if (size < sizeof * phdrs)
5092 {
5093 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5094 return FALSE;
5095 }
5096 if (size > sizeof * phdrs)
5097 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5098
dda8d76d 5099 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5100 size, num, _("program headers"));
5101 if (phdrs == NULL)
5102 return FALSE;
9ea033b2 5103
91d6fa6a 5104 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5105 i < filedata->file_header.e_phnum;
b34976b6 5106 i++, internal++, external++)
252b5132 5107 {
9ea033b2
NC
5108 internal->p_type = BYTE_GET (external->p_type);
5109 internal->p_offset = BYTE_GET (external->p_offset);
5110 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5111 internal->p_paddr = BYTE_GET (external->p_paddr);
5112 internal->p_filesz = BYTE_GET (external->p_filesz);
5113 internal->p_memsz = BYTE_GET (external->p_memsz);
5114 internal->p_flags = BYTE_GET (external->p_flags);
5115 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5116 }
5117
9ea033b2 5118 free (phdrs);
e0a31db1 5119 return TRUE;
252b5132
RH
5120}
5121
dda8d76d
NC
5122/* Read in the program headers from FILEDATA and store them in PHEADERS.
5123 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5124
e0a31db1 5125static bfd_boolean
dda8d76d 5126get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5127{
2cf0635d
NC
5128 Elf64_External_Phdr * phdrs;
5129 Elf64_External_Phdr * external;
5130 Elf_Internal_Phdr * internal;
b34976b6 5131 unsigned int i;
dda8d76d
NC
5132 unsigned int size = filedata->file_header.e_phentsize;
5133 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5134
5135 /* PR binutils/17531: Cope with unexpected section header sizes. */
5136 if (size == 0 || num == 0)
5137 return FALSE;
5138 if (size < sizeof * phdrs)
5139 {
5140 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5141 return FALSE;
5142 }
5143 if (size > sizeof * phdrs)
5144 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5145
dda8d76d 5146 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5147 size, num, _("program headers"));
a6e9f9df 5148 if (!phdrs)
e0a31db1 5149 return FALSE;
9ea033b2 5150
91d6fa6a 5151 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5152 i < filedata->file_header.e_phnum;
b34976b6 5153 i++, internal++, external++)
9ea033b2
NC
5154 {
5155 internal->p_type = BYTE_GET (external->p_type);
5156 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5157 internal->p_offset = BYTE_GET (external->p_offset);
5158 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5159 internal->p_paddr = BYTE_GET (external->p_paddr);
5160 internal->p_filesz = BYTE_GET (external->p_filesz);
5161 internal->p_memsz = BYTE_GET (external->p_memsz);
5162 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5163 }
5164
5165 free (phdrs);
e0a31db1 5166 return TRUE;
9ea033b2 5167}
252b5132 5168
32ec8896 5169/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5170
32ec8896 5171static bfd_boolean
dda8d76d 5172get_program_headers (Filedata * filedata)
d93f0186 5173{
2cf0635d 5174 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5175
5176 /* Check cache of prior read. */
dda8d76d 5177 if (filedata->program_headers != NULL)
32ec8896 5178 return TRUE;
d93f0186 5179
82156ab7
NC
5180 /* Be kind to memory checkers by looking for
5181 e_phnum values which we know must be invalid. */
dda8d76d 5182 if (filedata->file_header.e_phnum
82156ab7 5183 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5184 >= filedata->file_size)
82156ab7
NC
5185 {
5186 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5187 filedata->file_header.e_phnum);
82156ab7
NC
5188 return FALSE;
5189 }
d93f0186 5190
dda8d76d 5191 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5192 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5193 if (phdrs == NULL)
5194 {
8b73c356 5195 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5196 filedata->file_header.e_phnum);
32ec8896 5197 return FALSE;
d93f0186
NC
5198 }
5199
5200 if (is_32bit_elf
dda8d76d
NC
5201 ? get_32bit_program_headers (filedata, phdrs)
5202 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5203 {
dda8d76d 5204 filedata->program_headers = phdrs;
32ec8896 5205 return TRUE;
d93f0186
NC
5206 }
5207
5208 free (phdrs);
32ec8896 5209 return FALSE;
d93f0186
NC
5210}
5211
32ec8896 5212/* Returns TRUE if the program headers were loaded. */
2f62977e 5213
32ec8896 5214static bfd_boolean
dda8d76d 5215process_program_headers (Filedata * filedata)
252b5132 5216{
2cf0635d 5217 Elf_Internal_Phdr * segment;
b34976b6 5218 unsigned int i;
1a9ccd70 5219 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5220
978c4450
AM
5221 filedata->dynamic_addr = 0;
5222 filedata->dynamic_size = 0;
663f67df 5223
dda8d76d 5224 if (filedata->file_header.e_phnum == 0)
252b5132 5225 {
82f2dbf7 5226 /* PR binutils/12467. */
dda8d76d 5227 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5228 {
5229 warn (_("possibly corrupt ELF header - it has a non-zero program"
5230 " header offset, but no program headers\n"));
5231 return FALSE;
5232 }
82f2dbf7 5233 else if (do_segments)
252b5132 5234 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5235 return TRUE;
252b5132
RH
5236 }
5237
5238 if (do_segments && !do_header)
5239 {
dda8d76d
NC
5240 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5241 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5242 printf (ngettext ("There is %d program header, starting at offset %s\n",
5243 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5244 filedata->file_header.e_phnum),
5245 filedata->file_header.e_phnum,
5246 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5247 }
5248
dda8d76d 5249 if (! get_program_headers (filedata))
6b4bf3bc 5250 return TRUE;
103f02d3 5251
252b5132
RH
5252 if (do_segments)
5253 {
dda8d76d 5254 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5255 printf (_("\nProgram Headers:\n"));
5256 else
5257 printf (_("\nProgram Headers:\n"));
76da6bbe 5258
f7a99963
NC
5259 if (is_32bit_elf)
5260 printf
5261 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5262 else if (do_wide)
5263 printf
5264 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5265 else
5266 {
5267 printf
5268 (_(" Type Offset VirtAddr PhysAddr\n"));
5269 printf
5270 (_(" FileSiz MemSiz Flags Align\n"));
5271 }
252b5132
RH
5272 }
5273
dda8d76d
NC
5274 for (i = 0, segment = filedata->program_headers;
5275 i < filedata->file_header.e_phnum;
b34976b6 5276 i++, segment++)
252b5132
RH
5277 {
5278 if (do_segments)
5279 {
dda8d76d 5280 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5281
5282 if (is_32bit_elf)
5283 {
5284 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5285 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5286 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5287 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5288 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5289 printf ("%c%c%c ",
5290 (segment->p_flags & PF_R ? 'R' : ' '),
5291 (segment->p_flags & PF_W ? 'W' : ' '),
5292 (segment->p_flags & PF_X ? 'E' : ' '));
5293 printf ("%#lx", (unsigned long) segment->p_align);
5294 }
d974e256
JJ
5295 else if (do_wide)
5296 {
5297 if ((unsigned long) segment->p_offset == segment->p_offset)
5298 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5299 else
5300 {
5301 print_vma (segment->p_offset, FULL_HEX);
5302 putchar (' ');
5303 }
5304
5305 print_vma (segment->p_vaddr, FULL_HEX);
5306 putchar (' ');
5307 print_vma (segment->p_paddr, FULL_HEX);
5308 putchar (' ');
5309
5310 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5311 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5312 else
5313 {
5314 print_vma (segment->p_filesz, FULL_HEX);
5315 putchar (' ');
5316 }
5317
5318 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5319 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5320 else
5321 {
f48e6c45 5322 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5323 }
5324
5325 printf (" %c%c%c ",
5326 (segment->p_flags & PF_R ? 'R' : ' '),
5327 (segment->p_flags & PF_W ? 'W' : ' '),
5328 (segment->p_flags & PF_X ? 'E' : ' '));
5329
5330 if ((unsigned long) segment->p_align == segment->p_align)
5331 printf ("%#lx", (unsigned long) segment->p_align);
5332 else
5333 {
5334 print_vma (segment->p_align, PREFIX_HEX);
5335 }
5336 }
f7a99963
NC
5337 else
5338 {
5339 print_vma (segment->p_offset, FULL_HEX);
5340 putchar (' ');
5341 print_vma (segment->p_vaddr, FULL_HEX);
5342 putchar (' ');
5343 print_vma (segment->p_paddr, FULL_HEX);
5344 printf ("\n ");
5345 print_vma (segment->p_filesz, FULL_HEX);
5346 putchar (' ');
5347 print_vma (segment->p_memsz, FULL_HEX);
5348 printf (" %c%c%c ",
5349 (segment->p_flags & PF_R ? 'R' : ' '),
5350 (segment->p_flags & PF_W ? 'W' : ' '),
5351 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5352 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5353 }
252b5132 5354
1a9ccd70
NC
5355 putc ('\n', stdout);
5356 }
f54498b4 5357
252b5132
RH
5358 switch (segment->p_type)
5359 {
1a9ccd70 5360 case PT_LOAD:
502d895c
NC
5361#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5362 required by the ELF standard, several programs, including the Linux
5363 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5364 if (previous_load
5365 && previous_load->p_vaddr > segment->p_vaddr)
5366 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5367#endif
1a9ccd70
NC
5368 if (segment->p_memsz < segment->p_filesz)
5369 error (_("the segment's file size is larger than its memory size\n"));
5370 previous_load = segment;
5371 break;
5372
5373 case PT_PHDR:
5374 /* PR 20815 - Verify that the program header is loaded into memory. */
5375 if (i > 0 && previous_load != NULL)
5376 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5377 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5378 {
5379 unsigned int j;
5380
dda8d76d 5381 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5382 {
5383 Elf_Internal_Phdr *load = filedata->program_headers + j;
5384 if (load->p_type == PT_LOAD
5385 && load->p_offset <= segment->p_offset
5386 && (load->p_offset + load->p_filesz
5387 >= segment->p_offset + segment->p_filesz)
5388 && load->p_vaddr <= segment->p_vaddr
5389 && (load->p_vaddr + load->p_filesz
5390 >= segment->p_vaddr + segment->p_filesz))
5391 break;
5392 }
dda8d76d 5393 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5394 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5395 }
5396 break;
5397
252b5132 5398 case PT_DYNAMIC:
978c4450 5399 if (filedata->dynamic_addr)
252b5132
RH
5400 error (_("more than one dynamic segment\n"));
5401
20737c13
AM
5402 /* By default, assume that the .dynamic section is the first
5403 section in the DYNAMIC segment. */
978c4450
AM
5404 filedata->dynamic_addr = segment->p_offset;
5405 filedata->dynamic_size = segment->p_filesz;
20737c13 5406
b2d38a17
NC
5407 /* Try to locate the .dynamic section. If there is
5408 a section header table, we can easily locate it. */
dda8d76d 5409 if (filedata->section_headers != NULL)
b2d38a17 5410 {
2cf0635d 5411 Elf_Internal_Shdr * sec;
b2d38a17 5412
dda8d76d 5413 sec = find_section (filedata, ".dynamic");
89fac5e3 5414 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5415 {
28f997cf
TG
5416 /* A corresponding .dynamic section is expected, but on
5417 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5418 if (!is_ia64_vms (filedata))
28f997cf 5419 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5420 break;
5421 }
5422
42bb2e33 5423 if (sec->sh_type == SHT_NOBITS)
20737c13 5424 {
978c4450 5425 filedata->dynamic_size = 0;
20737c13
AM
5426 break;
5427 }
42bb2e33 5428
978c4450
AM
5429 filedata->dynamic_addr = sec->sh_offset;
5430 filedata->dynamic_size = sec->sh_size;
b2d38a17 5431
8ac10c5b
L
5432 /* The PT_DYNAMIC segment, which is used by the run-time
5433 loader, should exactly match the .dynamic section. */
5434 if (do_checks
5435 && (filedata->dynamic_addr != segment->p_offset
5436 || filedata->dynamic_size != segment->p_filesz))
5437 warn (_("\
5438the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5439 }
39e224f6
MW
5440
5441 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5442 segment. Check this after matching against the section headers
5443 so we don't warn on debuginfo file (which have NOBITS .dynamic
5444 sections). */
978c4450
AM
5445 if (filedata->dynamic_addr > filedata->file_size
5446 || (filedata->dynamic_size
5447 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5448 {
5449 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5450 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5451 }
252b5132
RH
5452 break;
5453
5454 case PT_INTERP:
978c4450
AM
5455 if (fseek (filedata->handle,
5456 filedata->archive_file_offset + (long) segment->p_offset,
fb52b2f4 5457 SEEK_SET))
252b5132
RH
5458 error (_("Unable to find program interpreter name\n"));
5459 else
5460 {
f8eae8b2 5461 char fmt [32];
9495b2e6 5462 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5463
5464 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5465 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5466
978c4450
AM
5467 filedata->program_interpreter[0] = 0;
5468 if (fscanf (filedata->handle, fmt,
5469 filedata->program_interpreter) <= 0)
7bd7b3ef 5470 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5471
5472 if (do_segments)
f54498b4 5473 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5474 filedata->program_interpreter);
252b5132
RH
5475 }
5476 break;
5477 }
252b5132
RH
5478 }
5479
dda8d76d
NC
5480 if (do_segments
5481 && filedata->section_headers != NULL
5482 && filedata->string_table != NULL)
252b5132
RH
5483 {
5484 printf (_("\n Section to Segment mapping:\n"));
5485 printf (_(" Segment Sections...\n"));
5486
dda8d76d 5487 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5488 {
9ad5cbcf 5489 unsigned int j;
2cf0635d 5490 Elf_Internal_Shdr * section;
252b5132 5491
dda8d76d
NC
5492 segment = filedata->program_headers + i;
5493 section = filedata->section_headers + 1;
252b5132
RH
5494
5495 printf (" %2.2d ", i);
5496
dda8d76d 5497 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5498 {
f4638467
AM
5499 if (!ELF_TBSS_SPECIAL (section, segment)
5500 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5501 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5502 }
5503
5504 putc ('\n',stdout);
5505 }
5506 }
5507
32ec8896 5508 return TRUE;
252b5132
RH
5509}
5510
5511
d93f0186
NC
5512/* Find the file offset corresponding to VMA by using the program headers. */
5513
5514static long
dda8d76d 5515offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5516{
2cf0635d 5517 Elf_Internal_Phdr * seg;
d93f0186 5518
dda8d76d 5519 if (! get_program_headers (filedata))
d93f0186
NC
5520 {
5521 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5522 return (long) vma;
5523 }
5524
dda8d76d
NC
5525 for (seg = filedata->program_headers;
5526 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5527 ++seg)
5528 {
5529 if (seg->p_type != PT_LOAD)
5530 continue;
5531
5532 if (vma >= (seg->p_vaddr & -seg->p_align)
5533 && vma + size <= seg->p_vaddr + seg->p_filesz)
5534 return vma - seg->p_vaddr + seg->p_offset;
5535 }
5536
5537 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5538 (unsigned long) vma);
d93f0186
NC
5539 return (long) vma;
5540}
5541
5542
dda8d76d
NC
5543/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5544 If PROBE is true, this is just a probe and we do not generate any error
5545 messages if the load fails. */
049b0c3a
NC
5546
5547static bfd_boolean
dda8d76d 5548get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5549{
2cf0635d
NC
5550 Elf32_External_Shdr * shdrs;
5551 Elf_Internal_Shdr * internal;
dda8d76d
NC
5552 unsigned int i;
5553 unsigned int size = filedata->file_header.e_shentsize;
5554 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5555
5556 /* PR binutils/17531: Cope with unexpected section header sizes. */
5557 if (size == 0 || num == 0)
5558 return FALSE;
5559 if (size < sizeof * shdrs)
5560 {
5561 if (! probe)
5562 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5563 return FALSE;
5564 }
5565 if (!probe && size > sizeof * shdrs)
5566 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5567
dda8d76d 5568 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5569 size, num,
5570 probe ? NULL : _("section headers"));
5571 if (shdrs == NULL)
5572 return FALSE;
252b5132 5573
dda8d76d
NC
5574 free (filedata->section_headers);
5575 filedata->section_headers = (Elf_Internal_Shdr *)
5576 cmalloc (num, sizeof (Elf_Internal_Shdr));
5577 if (filedata->section_headers == NULL)
252b5132 5578 {
049b0c3a 5579 if (!probe)
8b73c356 5580 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5581 free (shdrs);
049b0c3a 5582 return FALSE;
252b5132
RH
5583 }
5584
dda8d76d 5585 for (i = 0, internal = filedata->section_headers;
560f3c1c 5586 i < num;
b34976b6 5587 i++, internal++)
252b5132
RH
5588 {
5589 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5590 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5591 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5592 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5593 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5594 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5595 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5596 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5597 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5598 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5599 if (!probe && internal->sh_link > num)
5600 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5601 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5602 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5603 }
5604
5605 free (shdrs);
049b0c3a 5606 return TRUE;
252b5132
RH
5607}
5608
dda8d76d
NC
5609/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5610
049b0c3a 5611static bfd_boolean
dda8d76d 5612get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5613{
dda8d76d
NC
5614 Elf64_External_Shdr * shdrs;
5615 Elf_Internal_Shdr * internal;
5616 unsigned int i;
5617 unsigned int size = filedata->file_header.e_shentsize;
5618 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5619
5620 /* PR binutils/17531: Cope with unexpected section header sizes. */
5621 if (size == 0 || num == 0)
5622 return FALSE;
dda8d76d 5623
049b0c3a
NC
5624 if (size < sizeof * shdrs)
5625 {
5626 if (! probe)
5627 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5628 return FALSE;
5629 }
dda8d76d 5630
049b0c3a
NC
5631 if (! probe && size > sizeof * shdrs)
5632 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5633
dda8d76d
NC
5634 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5635 filedata->file_header.e_shoff,
049b0c3a
NC
5636 size, num,
5637 probe ? NULL : _("section headers"));
5638 if (shdrs == NULL)
5639 return FALSE;
9ea033b2 5640
dda8d76d
NC
5641 free (filedata->section_headers);
5642 filedata->section_headers = (Elf_Internal_Shdr *)
5643 cmalloc (num, sizeof (Elf_Internal_Shdr));
5644 if (filedata->section_headers == NULL)
9ea033b2 5645 {
049b0c3a 5646 if (! probe)
8b73c356 5647 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5648 free (shdrs);
049b0c3a 5649 return FALSE;
9ea033b2
NC
5650 }
5651
dda8d76d 5652 for (i = 0, internal = filedata->section_headers;
560f3c1c 5653 i < num;
b34976b6 5654 i++, internal++)
9ea033b2
NC
5655 {
5656 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5657 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5658 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5659 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5660 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5661 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5662 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5663 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5664 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5665 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5666 if (!probe && internal->sh_link > num)
5667 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5668 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5669 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5670 }
5671
5672 free (shdrs);
049b0c3a 5673 return TRUE;
9ea033b2
NC
5674}
5675
252b5132 5676static Elf_Internal_Sym *
dda8d76d
NC
5677get_32bit_elf_symbols (Filedata * filedata,
5678 Elf_Internal_Shdr * section,
5679 unsigned long * num_syms_return)
252b5132 5680{
ba5cdace 5681 unsigned long number = 0;
dd24e3da 5682 Elf32_External_Sym * esyms = NULL;
ba5cdace 5683 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5684 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5685 Elf_Internal_Sym * psym;
b34976b6 5686 unsigned int j;
e3d39609 5687 elf_section_list * entry;
252b5132 5688
c9c1d674
EG
5689 if (section->sh_size == 0)
5690 {
5691 if (num_syms_return != NULL)
5692 * num_syms_return = 0;
5693 return NULL;
5694 }
5695
dd24e3da 5696 /* Run some sanity checks first. */
c9c1d674 5697 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5698 {
c9c1d674 5699 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5700 printable_section_name (filedata, section),
5701 (unsigned long) section->sh_entsize);
ba5cdace 5702 goto exit_point;
dd24e3da
NC
5703 }
5704
dda8d76d 5705 if (section->sh_size > filedata->file_size)
f54498b4
NC
5706 {
5707 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5708 printable_section_name (filedata, section),
5709 (unsigned long) section->sh_size);
f54498b4
NC
5710 goto exit_point;
5711 }
5712
dd24e3da
NC
5713 number = section->sh_size / section->sh_entsize;
5714
5715 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5716 {
c9c1d674 5717 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5718 (unsigned long) section->sh_size,
dda8d76d 5719 printable_section_name (filedata, section),
8066deb1 5720 (unsigned long) section->sh_entsize);
ba5cdace 5721 goto exit_point;
dd24e3da
NC
5722 }
5723
dda8d76d 5724 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5725 section->sh_size, _("symbols"));
dd24e3da 5726 if (esyms == NULL)
ba5cdace 5727 goto exit_point;
252b5132 5728
e3d39609 5729 shndx = NULL;
978c4450 5730 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5731 {
5732 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5733 continue;
5734
5735 if (shndx != NULL)
5736 {
5737 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5738 free (shndx);
5739 }
5740
5741 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5742 entry->hdr->sh_offset,
5743 1, entry->hdr->sh_size,
5744 _("symbol table section indices"));
5745 if (shndx == NULL)
5746 goto exit_point;
5747
5748 /* PR17531: file: heap-buffer-overflow */
5749 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5750 {
5751 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5752 printable_section_name (filedata, entry->hdr),
5753 (unsigned long) entry->hdr->sh_size,
5754 (unsigned long) section->sh_size);
5755 goto exit_point;
c9c1d674 5756 }
e3d39609 5757 }
9ad5cbcf 5758
3f5e193b 5759 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5760
5761 if (isyms == NULL)
5762 {
8b73c356
NC
5763 error (_("Out of memory reading %lu symbols\n"),
5764 (unsigned long) number);
dd24e3da 5765 goto exit_point;
252b5132
RH
5766 }
5767
dd24e3da 5768 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5769 {
5770 psym->st_name = BYTE_GET (esyms[j].st_name);
5771 psym->st_value = BYTE_GET (esyms[j].st_value);
5772 psym->st_size = BYTE_GET (esyms[j].st_size);
5773 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5774 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5775 psym->st_shndx
5776 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5777 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5778 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5779 psym->st_info = BYTE_GET (esyms[j].st_info);
5780 psym->st_other = BYTE_GET (esyms[j].st_other);
5781 }
5782
dd24e3da 5783 exit_point:
e3d39609
NC
5784 free (shndx);
5785 free (esyms);
252b5132 5786
ba5cdace
NC
5787 if (num_syms_return != NULL)
5788 * num_syms_return = isyms == NULL ? 0 : number;
5789
252b5132
RH
5790 return isyms;
5791}
5792
9ea033b2 5793static Elf_Internal_Sym *
dda8d76d
NC
5794get_64bit_elf_symbols (Filedata * filedata,
5795 Elf_Internal_Shdr * section,
5796 unsigned long * num_syms_return)
9ea033b2 5797{
ba5cdace
NC
5798 unsigned long number = 0;
5799 Elf64_External_Sym * esyms = NULL;
5800 Elf_External_Sym_Shndx * shndx = NULL;
5801 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5802 Elf_Internal_Sym * psym;
b34976b6 5803 unsigned int j;
e3d39609 5804 elf_section_list * entry;
9ea033b2 5805
c9c1d674
EG
5806 if (section->sh_size == 0)
5807 {
5808 if (num_syms_return != NULL)
5809 * num_syms_return = 0;
5810 return NULL;
5811 }
5812
dd24e3da 5813 /* Run some sanity checks first. */
c9c1d674 5814 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5815 {
c9c1d674 5816 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5817 printable_section_name (filedata, section),
8066deb1 5818 (unsigned long) section->sh_entsize);
ba5cdace 5819 goto exit_point;
dd24e3da
NC
5820 }
5821
dda8d76d 5822 if (section->sh_size > filedata->file_size)
f54498b4
NC
5823 {
5824 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5825 printable_section_name (filedata, section),
8066deb1 5826 (unsigned long) section->sh_size);
f54498b4
NC
5827 goto exit_point;
5828 }
5829
dd24e3da
NC
5830 number = section->sh_size / section->sh_entsize;
5831
5832 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5833 {
c9c1d674 5834 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5835 (unsigned long) section->sh_size,
dda8d76d 5836 printable_section_name (filedata, section),
8066deb1 5837 (unsigned long) section->sh_entsize);
ba5cdace 5838 goto exit_point;
dd24e3da
NC
5839 }
5840
dda8d76d 5841 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5842 section->sh_size, _("symbols"));
a6e9f9df 5843 if (!esyms)
ba5cdace 5844 goto exit_point;
9ea033b2 5845
e3d39609 5846 shndx = NULL;
978c4450 5847 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5848 {
5849 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5850 continue;
5851
5852 if (shndx != NULL)
5853 {
5854 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5855 free (shndx);
c9c1d674 5856 }
e3d39609
NC
5857
5858 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5859 entry->hdr->sh_offset,
5860 1, entry->hdr->sh_size,
5861 _("symbol table section indices"));
5862 if (shndx == NULL)
5863 goto exit_point;
5864
5865 /* PR17531: file: heap-buffer-overflow */
5866 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5867 {
5868 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5869 printable_section_name (filedata, entry->hdr),
5870 (unsigned long) entry->hdr->sh_size,
5871 (unsigned long) section->sh_size);
5872 goto exit_point;
5873 }
5874 }
9ad5cbcf 5875
3f5e193b 5876 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5877
5878 if (isyms == NULL)
5879 {
8b73c356
NC
5880 error (_("Out of memory reading %lu symbols\n"),
5881 (unsigned long) number);
ba5cdace 5882 goto exit_point;
9ea033b2
NC
5883 }
5884
ba5cdace 5885 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5886 {
5887 psym->st_name = BYTE_GET (esyms[j].st_name);
5888 psym->st_info = BYTE_GET (esyms[j].st_info);
5889 psym->st_other = BYTE_GET (esyms[j].st_other);
5890 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5891
4fbb74a6 5892 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5893 psym->st_shndx
5894 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5895 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5896 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5897
66543521
AM
5898 psym->st_value = BYTE_GET (esyms[j].st_value);
5899 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5900 }
5901
ba5cdace 5902 exit_point:
e3d39609
NC
5903 free (shndx);
5904 free (esyms);
ba5cdace
NC
5905
5906 if (num_syms_return != NULL)
5907 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5908
5909 return isyms;
5910}
5911
d1133906 5912static const char *
dda8d76d 5913get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5914{
5477e8a0 5915 static char buff[1024];
2cf0635d 5916 char * p = buff;
32ec8896
NC
5917 unsigned int field_size = is_32bit_elf ? 8 : 16;
5918 signed int sindex;
5919 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5920 bfd_vma os_flags = 0;
5921 bfd_vma proc_flags = 0;
5922 bfd_vma unknown_flags = 0;
148b93f2 5923 static const struct
5477e8a0 5924 {
2cf0635d 5925 const char * str;
32ec8896 5926 unsigned int len;
5477e8a0
L
5927 }
5928 flags [] =
5929 {
cfcac11d
NC
5930 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5931 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5932 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5933 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5934 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5935 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5936 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5937 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5938 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5939 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5940 /* IA-64 specific. */
5941 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5942 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5943 /* IA-64 OpenVMS specific. */
5944 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5945 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5946 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5947 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
5948 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
5949 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 5950 /* Generic. */
cfcac11d 5951 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 5952 /* SPARC specific. */
77115a4a 5953 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
5954 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
5955 /* ARM specific. */
5956 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 5957 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
5958 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
5959 /* GNU specific. */
5960 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
5961 /* VLE specific. */
5962 /* 25 */ { STRING_COMMA_LEN ("VLE") },
5477e8a0
L
5963 };
5964
5965 if (do_section_details)
5966 {
8d5ff12c
L
5967 sprintf (buff, "[%*.*lx]: ",
5968 field_size, field_size, (unsigned long) sh_flags);
5969 p += field_size + 4;
5477e8a0 5970 }
76da6bbe 5971
d1133906
NC
5972 while (sh_flags)
5973 {
5974 bfd_vma flag;
5975
5976 flag = sh_flags & - sh_flags;
5977 sh_flags &= ~ flag;
76da6bbe 5978
5477e8a0 5979 if (do_section_details)
d1133906 5980 {
5477e8a0
L
5981 switch (flag)
5982 {
91d6fa6a
NC
5983 case SHF_WRITE: sindex = 0; break;
5984 case SHF_ALLOC: sindex = 1; break;
5985 case SHF_EXECINSTR: sindex = 2; break;
5986 case SHF_MERGE: sindex = 3; break;
5987 case SHF_STRINGS: sindex = 4; break;
5988 case SHF_INFO_LINK: sindex = 5; break;
5989 case SHF_LINK_ORDER: sindex = 6; break;
5990 case SHF_OS_NONCONFORMING: sindex = 7; break;
5991 case SHF_GROUP: sindex = 8; break;
5992 case SHF_TLS: sindex = 9; break;
18ae9cc1 5993 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 5994 case SHF_COMPRESSED: sindex = 20; break;
a91e1603 5995 case SHF_GNU_MBIND: sindex = 24; break;
76da6bbe 5996
5477e8a0 5997 default:
91d6fa6a 5998 sindex = -1;
dda8d76d 5999 switch (filedata->file_header.e_machine)
148b93f2 6000 {
cfcac11d 6001 case EM_IA_64:
148b93f2 6002 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6003 sindex = 10;
148b93f2 6004 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6005 sindex = 11;
148b93f2 6006#ifdef BFD64
dda8d76d 6007 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6008 switch (flag)
6009 {
91d6fa6a
NC
6010 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6011 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6012 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6013 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6014 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6015 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6016 default: break;
6017 }
6018#endif
cfcac11d
NC
6019 break;
6020
caa83f8b 6021 case EM_386:
22abe556 6022 case EM_IAMCU:
caa83f8b 6023 case EM_X86_64:
7f502d6c 6024 case EM_L1OM:
7a9068fe 6025 case EM_K1OM:
cfcac11d
NC
6026 case EM_OLD_SPARCV9:
6027 case EM_SPARC32PLUS:
6028 case EM_SPARCV9:
6029 case EM_SPARC:
18ae9cc1 6030 if (flag == SHF_ORDERED)
91d6fa6a 6031 sindex = 19;
cfcac11d 6032 break;
ac4c9b04
MG
6033
6034 case EM_ARM:
6035 switch (flag)
6036 {
6037 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6038 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6039 case SHF_COMDEF: sindex = 23; break;
6040 default: break;
6041 }
6042 break;
83eef883
AFB
6043 case EM_PPC:
6044 if (flag == SHF_PPC_VLE)
6045 sindex = 25;
6046 break;
ac4c9b04 6047
cfcac11d
NC
6048 default:
6049 break;
148b93f2 6050 }
5477e8a0
L
6051 }
6052
91d6fa6a 6053 if (sindex != -1)
5477e8a0 6054 {
8d5ff12c
L
6055 if (p != buff + field_size + 4)
6056 {
6057 if (size < (10 + 2))
bee0ee85
NC
6058 {
6059 warn (_("Internal error: not enough buffer room for section flag info"));
6060 return _("<unknown>");
6061 }
8d5ff12c
L
6062 size -= 2;
6063 *p++ = ',';
6064 *p++ = ' ';
6065 }
6066
91d6fa6a
NC
6067 size -= flags [sindex].len;
6068 p = stpcpy (p, flags [sindex].str);
5477e8a0 6069 }
3b22753a 6070 else if (flag & SHF_MASKOS)
8d5ff12c 6071 os_flags |= flag;
d1133906 6072 else if (flag & SHF_MASKPROC)
8d5ff12c 6073 proc_flags |= flag;
d1133906 6074 else
8d5ff12c 6075 unknown_flags |= flag;
5477e8a0
L
6076 }
6077 else
6078 {
6079 switch (flag)
6080 {
6081 case SHF_WRITE: *p = 'W'; break;
6082 case SHF_ALLOC: *p = 'A'; break;
6083 case SHF_EXECINSTR: *p = 'X'; break;
6084 case SHF_MERGE: *p = 'M'; break;
6085 case SHF_STRINGS: *p = 'S'; break;
6086 case SHF_INFO_LINK: *p = 'I'; break;
6087 case SHF_LINK_ORDER: *p = 'L'; break;
6088 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6089 case SHF_GROUP: *p = 'G'; break;
6090 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6091 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6092 case SHF_COMPRESSED: *p = 'C'; break;
a91e1603 6093 case SHF_GNU_MBIND: *p = 'D'; break;
5477e8a0
L
6094
6095 default:
dda8d76d
NC
6096 if ((filedata->file_header.e_machine == EM_X86_64
6097 || filedata->file_header.e_machine == EM_L1OM
6098 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6099 && flag == SHF_X86_64_LARGE)
6100 *p = 'l';
dda8d76d 6101 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6102 && flag == SHF_ARM_PURECODE)
91f68a68 6103 *p = 'y';
dda8d76d 6104 else if (filedata->file_header.e_machine == EM_PPC
83eef883
AFB
6105 && flag == SHF_PPC_VLE)
6106 *p = 'v';
5477e8a0
L
6107 else if (flag & SHF_MASKOS)
6108 {
6109 *p = 'o';
6110 sh_flags &= ~ SHF_MASKOS;
6111 }
6112 else if (flag & SHF_MASKPROC)
6113 {
6114 *p = 'p';
6115 sh_flags &= ~ SHF_MASKPROC;
6116 }
6117 else
6118 *p = 'x';
6119 break;
6120 }
6121 p++;
d1133906
NC
6122 }
6123 }
76da6bbe 6124
8d5ff12c
L
6125 if (do_section_details)
6126 {
6127 if (os_flags)
6128 {
6129 size -= 5 + field_size;
6130 if (p != buff + field_size + 4)
6131 {
6132 if (size < (2 + 1))
bee0ee85
NC
6133 {
6134 warn (_("Internal error: not enough buffer room for section flag info"));
6135 return _("<unknown>");
6136 }
8d5ff12c
L
6137 size -= 2;
6138 *p++ = ',';
6139 *p++ = ' ';
6140 }
6141 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6142 (unsigned long) os_flags);
6143 p += 5 + field_size;
6144 }
6145 if (proc_flags)
6146 {
6147 size -= 7 + field_size;
6148 if (p != buff + field_size + 4)
6149 {
6150 if (size < (2 + 1))
bee0ee85
NC
6151 {
6152 warn (_("Internal error: not enough buffer room for section flag info"));
6153 return _("<unknown>");
6154 }
8d5ff12c
L
6155 size -= 2;
6156 *p++ = ',';
6157 *p++ = ' ';
6158 }
6159 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6160 (unsigned long) proc_flags);
6161 p += 7 + field_size;
6162 }
6163 if (unknown_flags)
6164 {
6165 size -= 10 + field_size;
6166 if (p != buff + field_size + 4)
6167 {
6168 if (size < (2 + 1))
bee0ee85
NC
6169 {
6170 warn (_("Internal error: not enough buffer room for section flag info"));
6171 return _("<unknown>");
6172 }
8d5ff12c
L
6173 size -= 2;
6174 *p++ = ',';
6175 *p++ = ' ';
6176 }
2b692964 6177 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6178 (unsigned long) unknown_flags);
6179 p += 10 + field_size;
6180 }
6181 }
6182
e9e44622 6183 *p = '\0';
d1133906
NC
6184 return buff;
6185}
6186
5844b465 6187static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6188get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6189{
6190 if (is_32bit_elf)
6191 {
6192 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6193
ebdf1ebf
NC
6194 if (size < sizeof (* echdr))
6195 {
6196 error (_("Compressed section is too small even for a compression header\n"));
6197 return 0;
6198 }
6199
77115a4a
L
6200 chdr->ch_type = BYTE_GET (echdr->ch_type);
6201 chdr->ch_size = BYTE_GET (echdr->ch_size);
6202 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6203 return sizeof (*echdr);
6204 }
6205 else
6206 {
6207 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6208
ebdf1ebf
NC
6209 if (size < sizeof (* echdr))
6210 {
6211 error (_("Compressed section is too small even for a compression header\n"));
6212 return 0;
6213 }
6214
77115a4a
L
6215 chdr->ch_type = BYTE_GET (echdr->ch_type);
6216 chdr->ch_size = BYTE_GET (echdr->ch_size);
6217 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6218 return sizeof (*echdr);
6219 }
6220}
6221
32ec8896 6222static bfd_boolean
dda8d76d 6223process_section_headers (Filedata * filedata)
252b5132 6224{
2cf0635d 6225 Elf_Internal_Shdr * section;
b34976b6 6226 unsigned int i;
252b5132 6227
8fb879cd 6228 free (filedata->section_headers);
dda8d76d 6229 filedata->section_headers = NULL;
978c4450
AM
6230 free (filedata->dynamic_symbols);
6231 filedata->dynamic_symbols = NULL;
6232 filedata->num_dynamic_syms = 0;
6233 free (filedata->dynamic_strings);
6234 filedata->dynamic_strings = NULL;
6235 filedata->dynamic_strings_length = 0;
6236 free (filedata->dynamic_syminfo);
6237 filedata->dynamic_syminfo = NULL;
6238 while (filedata->symtab_shndx_list != NULL)
8ff66993 6239 {
978c4450
AM
6240 elf_section_list *next = filedata->symtab_shndx_list->next;
6241 free (filedata->symtab_shndx_list);
6242 filedata->symtab_shndx_list = next;
8ff66993 6243 }
252b5132 6244
dda8d76d 6245 if (filedata->file_header.e_shnum == 0)
252b5132 6246 {
82f2dbf7 6247 /* PR binutils/12467. */
dda8d76d 6248 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6249 {
6250 warn (_("possibly corrupt ELF file header - it has a non-zero"
6251 " section header offset, but no section headers\n"));
6252 return FALSE;
6253 }
82f2dbf7 6254 else if (do_sections)
252b5132
RH
6255 printf (_("\nThere are no sections in this file.\n"));
6256
32ec8896 6257 return TRUE;
252b5132
RH
6258 }
6259
6260 if (do_sections && !do_header)
d3a49aa8
AM
6261 printf (ngettext ("There is %d section header, "
6262 "starting at offset 0x%lx:\n",
6263 "There are %d section headers, "
6264 "starting at offset 0x%lx:\n",
dda8d76d
NC
6265 filedata->file_header.e_shnum),
6266 filedata->file_header.e_shnum,
6267 (unsigned long) filedata->file_header.e_shoff);
252b5132 6268
9ea033b2
NC
6269 if (is_32bit_elf)
6270 {
dda8d76d 6271 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6272 return FALSE;
6273 }
6274 else
6275 {
dda8d76d 6276 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6277 return FALSE;
9ea033b2 6278 }
252b5132
RH
6279
6280 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6281 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6282 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6283 {
dda8d76d 6284 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6285
c256ffe7
JJ
6286 if (section->sh_size != 0)
6287 {
dda8d76d
NC
6288 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6289 1, section->sh_size,
6290 _("string table"));
0de14b54 6291
dda8d76d 6292 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6293 }
252b5132
RH
6294 }
6295
6296 /* Scan the sections for the dynamic symbol table
e3c8793a 6297 and dynamic string table and debug sections. */
89fac5e3 6298 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6299 switch (filedata->file_header.e_machine)
89fac5e3
RS
6300 {
6301 case EM_MIPS:
6302 case EM_MIPS_RS3_LE:
6303 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6304 FDE addresses. However, the ABI also has a semi-official ILP32
6305 variant for which the normal FDE address size rules apply.
6306
6307 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6308 section, where XX is the size of longs in bits. Unfortunately,
6309 earlier compilers provided no way of distinguishing ILP32 objects
6310 from LP64 objects, so if there's any doubt, we should assume that
6311 the official LP64 form is being used. */
dda8d76d
NC
6312 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6313 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6314 eh_addr_size = 8;
6315 break;
0f56a26a
DD
6316
6317 case EM_H8_300:
6318 case EM_H8_300H:
dda8d76d 6319 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6320 {
6321 case E_H8_MACH_H8300:
6322 case E_H8_MACH_H8300HN:
6323 case E_H8_MACH_H8300SN:
6324 case E_H8_MACH_H8300SXN:
6325 eh_addr_size = 2;
6326 break;
6327 case E_H8_MACH_H8300H:
6328 case E_H8_MACH_H8300S:
6329 case E_H8_MACH_H8300SX:
6330 eh_addr_size = 4;
6331 break;
6332 }
f4236fe4
DD
6333 break;
6334
ff7eeb89 6335 case EM_M32C_OLD:
f4236fe4 6336 case EM_M32C:
dda8d76d 6337 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6338 {
6339 case EF_M32C_CPU_M16C:
6340 eh_addr_size = 2;
6341 break;
6342 }
6343 break;
89fac5e3
RS
6344 }
6345
76ca31c0
NC
6346#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6347 do \
6348 { \
6349 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6350 if (section->sh_entsize != expected_entsize) \
9dd3a467 6351 { \
76ca31c0
NC
6352 char buf[40]; \
6353 sprintf_vma (buf, section->sh_entsize); \
6354 /* Note: coded this way so that there is a single string for \
6355 translation. */ \
6356 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6357 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6358 (unsigned) expected_entsize); \
9dd3a467 6359 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6360 } \
6361 } \
08d8fa11 6362 while (0)
9dd3a467
NC
6363
6364#define CHECK_ENTSIZE(section, i, type) \
1b513401 6365 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6366 sizeof (Elf64_External_##type))
6367
dda8d76d
NC
6368 for (i = 0, section = filedata->section_headers;
6369 i < filedata->file_header.e_shnum;
b34976b6 6370 i++, section++)
252b5132 6371 {
2cf0635d 6372 char * name = SECTION_NAME (section);
252b5132 6373
1b513401
NC
6374 /* Run some sanity checks on the headers and
6375 possibly fill in some file data as well. */
6376 switch (section->sh_type)
252b5132 6377 {
1b513401 6378 case SHT_DYNSYM:
978c4450 6379 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6380 {
6381 error (_("File contains multiple dynamic symbol tables\n"));
6382 continue;
6383 }
6384
08d8fa11 6385 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6386 filedata->dynamic_symbols
6387 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6388 filedata->dynamic_symtab_section = section;
1b513401
NC
6389 break;
6390
6391 case SHT_STRTAB:
6392 if (streq (name, ".dynstr"))
252b5132 6393 {
1b513401
NC
6394 if (filedata->dynamic_strings != NULL)
6395 {
6396 error (_("File contains multiple dynamic string tables\n"));
6397 continue;
6398 }
6399
6400 filedata->dynamic_strings
6401 = (char *) get_data (NULL, filedata, section->sh_offset,
6402 1, section->sh_size, _("dynamic strings"));
6403 filedata->dynamic_strings_length
6404 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6405 filedata->dynamic_strtab_section = section;
252b5132 6406 }
1b513401
NC
6407 break;
6408
6409 case SHT_SYMTAB_SHNDX:
6410 {
6411 elf_section_list * entry = xmalloc (sizeof * entry);
6412
6413 entry->hdr = section;
6414 entry->next = filedata->symtab_shndx_list;
6415 filedata->symtab_shndx_list = entry;
6416 }
6417 break;
6418
6419 case SHT_SYMTAB:
6420 CHECK_ENTSIZE (section, i, Sym);
6421 break;
6422
6423 case SHT_GROUP:
6424 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6425 break;
252b5132 6426
1b513401
NC
6427 case SHT_REL:
6428 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6429 if (do_checks && section->sh_size == 0)
1b513401
NC
6430 warn (_("Section '%s': zero-sized relocation section\n"), name);
6431 break;
6432
6433 case SHT_RELA:
6434 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6435 if (do_checks && section->sh_size == 0)
1b513401
NC
6436 warn (_("Section '%s': zero-sized relocation section\n"), name);
6437 break;
6438
6439 case SHT_NOTE:
6440 case SHT_PROGBITS:
546cb2d8
NC
6441 /* Having a zero sized section is not illegal according to the
6442 ELF standard, but it might be an indication that something
6443 is wrong. So issue a warning if we are running in lint mode. */
6444 if (do_checks && section->sh_size == 0)
1b513401
NC
6445 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6446 break;
6447
6448 default:
6449 break;
6450 }
6451
6452 if ((do_debugging || do_debug_info || do_debug_abbrevs
6453 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6454 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e4b7104b 6455 || do_debug_str || do_debug_str_offsets || do_debug_loc || do_debug_ranges
1b513401
NC
6456 || do_debug_addr || do_debug_cu_index || do_debug_links)
6457 && (const_strneq (name, ".debug_")
6458 || const_strneq (name, ".zdebug_")))
252b5132 6459 {
1b315056
CS
6460 if (name[1] == 'z')
6461 name += sizeof (".zdebug_") - 1;
6462 else
6463 name += sizeof (".debug_") - 1;
252b5132
RH
6464
6465 if (do_debugging
4723351a
CC
6466 || (do_debug_info && const_strneq (name, "info"))
6467 || (do_debug_info && const_strneq (name, "types"))
6468 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6469 || (do_debug_lines && strcmp (name, "line") == 0)
6470 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6471 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6472 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6473 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6474 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6475 || (do_debug_aranges && const_strneq (name, "aranges"))
6476 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6477 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6478 || (do_debug_frames && const_strneq (name, "frame"))
6479 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6480 || (do_debug_macinfo && const_strneq (name, "macro"))
6481 || (do_debug_str && const_strneq (name, "str"))
e4b7104b 6482 || (do_debug_str_offsets && const_strneq (name, "str_offsets"))
4723351a 6483 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6484 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6485 || (do_debug_addr && const_strneq (name, "addr"))
6486 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6487 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6488 )
6431e409 6489 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6490 }
a262ae96 6491 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6492 else if ((do_debugging || do_debug_info)
0112cd26 6493 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6494 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6495 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6496 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6497 else if (do_gdb_index && (streq (name, ".gdb_index")
6498 || streq (name, ".debug_names")))
6431e409 6499 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6500 /* Trace sections for Itanium VMS. */
6501 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6502 || do_trace_aranges)
6503 && const_strneq (name, ".trace_"))
6504 {
6505 name += sizeof (".trace_") - 1;
6506
6507 if (do_debugging
6508 || (do_trace_info && streq (name, "info"))
6509 || (do_trace_abbrevs && streq (name, "abbrev"))
6510 || (do_trace_aranges && streq (name, "aranges"))
6511 )
6431e409 6512 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6513 }
dda8d76d
NC
6514 else if ((do_debugging || do_debug_links)
6515 && (const_strneq (name, ".gnu_debuglink")
6516 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6517 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6518 }
6519
6520 if (! do_sections)
32ec8896 6521 return TRUE;
252b5132 6522
dda8d76d 6523 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6524 printf (_("\nSection Headers:\n"));
6525 else
6526 printf (_("\nSection Header:\n"));
76da6bbe 6527
f7a99963 6528 if (is_32bit_elf)
595cf52e 6529 {
5477e8a0 6530 if (do_section_details)
595cf52e
L
6531 {
6532 printf (_(" [Nr] Name\n"));
5477e8a0 6533 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6534 }
6535 else
6536 printf
6537 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6538 }
d974e256 6539 else if (do_wide)
595cf52e 6540 {
5477e8a0 6541 if (do_section_details)
595cf52e
L
6542 {
6543 printf (_(" [Nr] Name\n"));
5477e8a0 6544 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6545 }
6546 else
6547 printf
6548 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6549 }
f7a99963
NC
6550 else
6551 {
5477e8a0 6552 if (do_section_details)
595cf52e
L
6553 {
6554 printf (_(" [Nr] Name\n"));
5477e8a0
L
6555 printf (_(" Type Address Offset Link\n"));
6556 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6557 }
6558 else
6559 {
6560 printf (_(" [Nr] Name Type Address Offset\n"));
6561 printf (_(" Size EntSize Flags Link Info Align\n"));
6562 }
f7a99963 6563 }
252b5132 6564
5477e8a0
L
6565 if (do_section_details)
6566 printf (_(" Flags\n"));
6567
dda8d76d
NC
6568 for (i = 0, section = filedata->section_headers;
6569 i < filedata->file_header.e_shnum;
b34976b6 6570 i++, section++)
252b5132 6571 {
dd905818
NC
6572 /* Run some sanity checks on the section header. */
6573
6574 /* Check the sh_link field. */
6575 switch (section->sh_type)
6576 {
285e3f99
AM
6577 case SHT_REL:
6578 case SHT_RELA:
6579 if (section->sh_link == 0
6580 && (filedata->file_header.e_type == ET_EXEC
6581 || filedata->file_header.e_type == ET_DYN))
6582 /* A dynamic relocation section where all entries use a
6583 zero symbol index need not specify a symtab section. */
6584 break;
6585 /* Fall through. */
dd905818
NC
6586 case SHT_SYMTAB_SHNDX:
6587 case SHT_GROUP:
6588 case SHT_HASH:
6589 case SHT_GNU_HASH:
6590 case SHT_GNU_versym:
285e3f99 6591 if (section->sh_link == 0
dda8d76d
NC
6592 || section->sh_link >= filedata->file_header.e_shnum
6593 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6594 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6595 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6596 i, section->sh_link);
6597 break;
6598
6599 case SHT_DYNAMIC:
6600 case SHT_SYMTAB:
6601 case SHT_DYNSYM:
6602 case SHT_GNU_verneed:
6603 case SHT_GNU_verdef:
6604 case SHT_GNU_LIBLIST:
285e3f99 6605 if (section->sh_link == 0
dda8d76d
NC
6606 || section->sh_link >= filedata->file_header.e_shnum
6607 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6608 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6609 i, section->sh_link);
6610 break;
6611
6612 case SHT_INIT_ARRAY:
6613 case SHT_FINI_ARRAY:
6614 case SHT_PREINIT_ARRAY:
6615 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6616 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6617 i, section->sh_link);
6618 break;
6619
6620 default:
6621 /* FIXME: Add support for target specific section types. */
6622#if 0 /* Currently we do not check other section types as there are too
6623 many special cases. Stab sections for example have a type
6624 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6625 section. */
6626 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6627 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6628 i, section->sh_link);
6629#endif
6630 break;
6631 }
6632
6633 /* Check the sh_info field. */
6634 switch (section->sh_type)
6635 {
6636 case SHT_REL:
6637 case SHT_RELA:
285e3f99
AM
6638 if (section->sh_info == 0
6639 && (filedata->file_header.e_type == ET_EXEC
6640 || filedata->file_header.e_type == ET_DYN))
6641 /* Dynamic relocations apply to segments, so they do not
6642 need to specify the section they relocate. */
6643 break;
6644 if (section->sh_info == 0
dda8d76d
NC
6645 || section->sh_info >= filedata->file_header.e_shnum
6646 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6647 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6648 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6649 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6650 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6651 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6652 /* FIXME: Are other section types valid ? */
dda8d76d 6653 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6654 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6655 i, section->sh_info);
dd905818
NC
6656 break;
6657
6658 case SHT_DYNAMIC:
6659 case SHT_HASH:
6660 case SHT_SYMTAB_SHNDX:
6661 case SHT_INIT_ARRAY:
6662 case SHT_FINI_ARRAY:
6663 case SHT_PREINIT_ARRAY:
6664 if (section->sh_info != 0)
6665 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6666 i, section->sh_info);
6667 break;
6668
6669 case SHT_GROUP:
6670 case SHT_SYMTAB:
6671 case SHT_DYNSYM:
6672 /* A symbol index - we assume that it is valid. */
6673 break;
6674
6675 default:
6676 /* FIXME: Add support for target specific section types. */
6677 if (section->sh_type == SHT_NOBITS)
6678 /* NOBITS section headers with non-zero sh_info fields can be
6679 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6680 information. The stripped sections have their headers
6681 preserved but their types set to SHT_NOBITS. So do not check
6682 this type of section. */
dd905818
NC
6683 ;
6684 else if (section->sh_flags & SHF_INFO_LINK)
6685 {
dda8d76d 6686 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6687 warn (_("[%2u]: Expected link to another section in info field"), i);
6688 }
a91e1603
L
6689 else if (section->sh_type < SHT_LOOS
6690 && (section->sh_flags & SHF_GNU_MBIND) == 0
6691 && section->sh_info != 0)
dd905818
NC
6692 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6693 i, section->sh_info);
6694 break;
6695 }
6696
3e6b6445 6697 /* Check the sh_size field. */
dda8d76d 6698 if (section->sh_size > filedata->file_size
3e6b6445
NC
6699 && section->sh_type != SHT_NOBITS
6700 && section->sh_type != SHT_NULL
6701 && section->sh_type < SHT_LOOS)
6702 warn (_("Size of section %u is larger than the entire file!\n"), i);
6703
7bfd842d 6704 printf (" [%2u] ", i);
5477e8a0 6705 if (do_section_details)
dda8d76d 6706 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6707 else
74e1a04b 6708 print_symbol (-17, SECTION_NAME (section));
0b4362b0 6709
ea52a088 6710 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6711 get_section_type_name (filedata, section->sh_type));
0b4362b0 6712
f7a99963
NC
6713 if (is_32bit_elf)
6714 {
cfcac11d
NC
6715 const char * link_too_big = NULL;
6716
f7a99963 6717 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6718
f7a99963
NC
6719 printf ( " %6.6lx %6.6lx %2.2lx",
6720 (unsigned long) section->sh_offset,
6721 (unsigned long) section->sh_size,
6722 (unsigned long) section->sh_entsize);
d1133906 6723
5477e8a0
L
6724 if (do_section_details)
6725 fputs (" ", stdout);
6726 else
dda8d76d 6727 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6728
dda8d76d 6729 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6730 {
6731 link_too_big = "";
6732 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6733 an error but it can have special values in Solaris binaries. */
dda8d76d 6734 switch (filedata->file_header.e_machine)
cfcac11d 6735 {
caa83f8b 6736 case EM_386:
22abe556 6737 case EM_IAMCU:
caa83f8b 6738 case EM_X86_64:
7f502d6c 6739 case EM_L1OM:
7a9068fe 6740 case EM_K1OM:
cfcac11d
NC
6741 case EM_OLD_SPARCV9:
6742 case EM_SPARC32PLUS:
6743 case EM_SPARCV9:
6744 case EM_SPARC:
6745 if (section->sh_link == (SHN_BEFORE & 0xffff))
6746 link_too_big = "BEFORE";
6747 else if (section->sh_link == (SHN_AFTER & 0xffff))
6748 link_too_big = "AFTER";
6749 break;
6750 default:
6751 break;
6752 }
6753 }
6754
6755 if (do_section_details)
6756 {
6757 if (link_too_big != NULL && * link_too_big)
6758 printf ("<%s> ", link_too_big);
6759 else
6760 printf ("%2u ", section->sh_link);
6761 printf ("%3u %2lu\n", section->sh_info,
6762 (unsigned long) section->sh_addralign);
6763 }
6764 else
6765 printf ("%2u %3u %2lu\n",
6766 section->sh_link,
6767 section->sh_info,
6768 (unsigned long) section->sh_addralign);
6769
6770 if (link_too_big && ! * link_too_big)
6771 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6772 i, section->sh_link);
f7a99963 6773 }
d974e256
JJ
6774 else if (do_wide)
6775 {
6776 print_vma (section->sh_addr, LONG_HEX);
6777
6778 if ((long) section->sh_offset == section->sh_offset)
6779 printf (" %6.6lx", (unsigned long) section->sh_offset);
6780 else
6781 {
6782 putchar (' ');
6783 print_vma (section->sh_offset, LONG_HEX);
6784 }
6785
6786 if ((unsigned long) section->sh_size == section->sh_size)
6787 printf (" %6.6lx", (unsigned long) section->sh_size);
6788 else
6789 {
6790 putchar (' ');
6791 print_vma (section->sh_size, LONG_HEX);
6792 }
6793
6794 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6795 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6796 else
6797 {
6798 putchar (' ');
6799 print_vma (section->sh_entsize, LONG_HEX);
6800 }
6801
5477e8a0
L
6802 if (do_section_details)
6803 fputs (" ", stdout);
6804 else
dda8d76d 6805 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6806
72de5009 6807 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6808
6809 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6810 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6811 else
6812 {
6813 print_vma (section->sh_addralign, DEC);
6814 putchar ('\n');
6815 }
6816 }
5477e8a0 6817 else if (do_section_details)
595cf52e 6818 {
55cc53e9 6819 putchar (' ');
595cf52e
L
6820 print_vma (section->sh_addr, LONG_HEX);
6821 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6822 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6823 else
6824 {
6825 printf (" ");
6826 print_vma (section->sh_offset, LONG_HEX);
6827 }
72de5009 6828 printf (" %u\n ", section->sh_link);
595cf52e 6829 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6830 putchar (' ');
595cf52e
L
6831 print_vma (section->sh_entsize, LONG_HEX);
6832
72de5009
AM
6833 printf (" %-16u %lu\n",
6834 section->sh_info,
595cf52e
L
6835 (unsigned long) section->sh_addralign);
6836 }
f7a99963
NC
6837 else
6838 {
6839 putchar (' ');
6840 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6841 if ((long) section->sh_offset == section->sh_offset)
6842 printf (" %8.8lx", (unsigned long) section->sh_offset);
6843 else
6844 {
6845 printf (" ");
6846 print_vma (section->sh_offset, LONG_HEX);
6847 }
f7a99963
NC
6848 printf ("\n ");
6849 print_vma (section->sh_size, LONG_HEX);
6850 printf (" ");
6851 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6852
dda8d76d 6853 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6854
72de5009
AM
6855 printf (" %2u %3u %lu\n",
6856 section->sh_link,
6857 section->sh_info,
f7a99963
NC
6858 (unsigned long) section->sh_addralign);
6859 }
5477e8a0
L
6860
6861 if (do_section_details)
77115a4a 6862 {
dda8d76d 6863 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6864 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6865 {
6866 /* Minimum section size is 12 bytes for 32-bit compression
6867 header + 12 bytes for compressed data header. */
6868 unsigned char buf[24];
d8024a91 6869
77115a4a 6870 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6871 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6872 sizeof (buf), _("compression header")))
6873 {
6874 Elf_Internal_Chdr chdr;
d8024a91 6875
5844b465
NC
6876 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
6877 printf (_(" [<corrupt>]\n"));
77115a4a 6878 else
5844b465
NC
6879 {
6880 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6881 printf (" ZLIB, ");
6882 else
6883 printf (_(" [<unknown>: 0x%x], "),
6884 chdr.ch_type);
6885 print_vma (chdr.ch_size, LONG_HEX);
6886 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6887 }
77115a4a
L
6888 }
6889 }
6890 }
252b5132
RH
6891 }
6892
5477e8a0 6893 if (!do_section_details)
3dbcc61d 6894 {
9fb71ee4
NC
6895 /* The ordering of the letters shown here matches the ordering of the
6896 corresponding SHF_xxx values, and hence the order in which these
6897 letters will be displayed to the user. */
6898 printf (_("Key to Flags:\n\
6899 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6900 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6901 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
dda8d76d
NC
6902 if (filedata->file_header.e_machine == EM_X86_64
6903 || filedata->file_header.e_machine == EM_L1OM
6904 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 6905 printf (_("l (large), "));
dda8d76d 6906 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 6907 printf (_("y (purecode), "));
dda8d76d 6908 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 6909 printf (_("v (VLE), "));
9fb71ee4 6910 printf ("p (processor specific)\n");
0b4362b0 6911 }
d1133906 6912
32ec8896 6913 return TRUE;
252b5132
RH
6914}
6915
28d13567
AM
6916static bfd_boolean
6917get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
6918 Elf_Internal_Sym **symtab, unsigned long *nsyms,
6919 char **strtab, unsigned long *strtablen)
6920{
6921 *strtab = NULL;
6922 *strtablen = 0;
6923 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
6924
6925 if (*symtab == NULL)
6926 return FALSE;
6927
6928 if (symsec->sh_link != 0)
6929 {
6930 Elf_Internal_Shdr *strsec;
6931
6932 if (symsec->sh_link >= filedata->file_header.e_shnum)
6933 {
6934 error (_("Bad sh_link in symbol table section\n"));
6935 free (*symtab);
6936 *symtab = NULL;
6937 *nsyms = 0;
6938 return FALSE;
6939 }
6940
6941 strsec = filedata->section_headers + symsec->sh_link;
6942
6943 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
6944 1, strsec->sh_size, _("string table"));
6945 if (*strtab == NULL)
6946 {
6947 free (*symtab);
6948 *symtab = NULL;
6949 *nsyms = 0;
6950 return FALSE;
6951 }
6952 *strtablen = strsec->sh_size;
6953 }
6954 return TRUE;
6955}
6956
f5842774
L
6957static const char *
6958get_group_flags (unsigned int flags)
6959{
1449284b 6960 static char buff[128];
220453ec 6961
6d913794
NC
6962 if (flags == 0)
6963 return "";
6964 else if (flags == GRP_COMDAT)
6965 return "COMDAT ";
f5842774 6966
89246a0e
AM
6967 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
6968 flags,
6969 flags & GRP_MASKOS ? _("<OS specific>") : "",
6970 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
6971 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
6972 ? _("<unknown>") : ""));
6d913794 6973
f5842774
L
6974 return buff;
6975}
6976
32ec8896 6977static bfd_boolean
dda8d76d 6978process_section_groups (Filedata * filedata)
f5842774 6979{
2cf0635d 6980 Elf_Internal_Shdr * section;
f5842774 6981 unsigned int i;
2cf0635d
NC
6982 struct group * group;
6983 Elf_Internal_Shdr * symtab_sec;
6984 Elf_Internal_Shdr * strtab_sec;
6985 Elf_Internal_Sym * symtab;
ba5cdace 6986 unsigned long num_syms;
2cf0635d 6987 char * strtab;
c256ffe7 6988 size_t strtab_size;
d1f5c6e3
L
6989
6990 /* Don't process section groups unless needed. */
6991 if (!do_unwind && !do_section_groups)
32ec8896 6992 return TRUE;
f5842774 6993
dda8d76d 6994 if (filedata->file_header.e_shnum == 0)
f5842774
L
6995 {
6996 if (do_section_groups)
82f2dbf7 6997 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 6998
32ec8896 6999 return TRUE;
f5842774
L
7000 }
7001
dda8d76d 7002 if (filedata->section_headers == NULL)
f5842774
L
7003 {
7004 error (_("Section headers are not available!\n"));
fa1908fd 7005 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 7006 return FALSE;
f5842774
L
7007 }
7008
978c4450
AM
7009 filedata->section_headers_groups
7010 = (struct group **) calloc (filedata->file_header.e_shnum,
7011 sizeof (struct group *));
e4b17d5c 7012
978c4450 7013 if (filedata->section_headers_groups == NULL)
e4b17d5c 7014 {
8b73c356 7015 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7016 filedata->file_header.e_shnum);
32ec8896 7017 return FALSE;
e4b17d5c
L
7018 }
7019
f5842774 7020 /* Scan the sections for the group section. */
978c4450 7021 filedata->group_count = 0;
dda8d76d
NC
7022 for (i = 0, section = filedata->section_headers;
7023 i < filedata->file_header.e_shnum;
f5842774 7024 i++, section++)
e4b17d5c 7025 if (section->sh_type == SHT_GROUP)
978c4450 7026 filedata->group_count++;
e4b17d5c 7027
978c4450 7028 if (filedata->group_count == 0)
d1f5c6e3
L
7029 {
7030 if (do_section_groups)
7031 printf (_("\nThere are no section groups in this file.\n"));
7032
32ec8896 7033 return TRUE;
d1f5c6e3
L
7034 }
7035
978c4450
AM
7036 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7037 sizeof (struct group));
e4b17d5c 7038
978c4450 7039 if (filedata->section_groups == NULL)
e4b17d5c 7040 {
8b73c356 7041 error (_("Out of memory reading %lu groups\n"),
978c4450 7042 (unsigned long) filedata->group_count);
32ec8896 7043 return FALSE;
e4b17d5c
L
7044 }
7045
d1f5c6e3
L
7046 symtab_sec = NULL;
7047 strtab_sec = NULL;
7048 symtab = NULL;
ba5cdace 7049 num_syms = 0;
d1f5c6e3 7050 strtab = NULL;
c256ffe7 7051 strtab_size = 0;
978c4450 7052 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7053 i < filedata->file_header.e_shnum;
e4b17d5c 7054 i++, section++)
f5842774
L
7055 {
7056 if (section->sh_type == SHT_GROUP)
7057 {
dda8d76d 7058 const char * name = printable_section_name (filedata, section);
74e1a04b 7059 const char * group_name;
2cf0635d
NC
7060 unsigned char * start;
7061 unsigned char * indices;
f5842774 7062 unsigned int entry, j, size;
2cf0635d
NC
7063 Elf_Internal_Shdr * sec;
7064 Elf_Internal_Sym * sym;
f5842774
L
7065
7066 /* Get the symbol table. */
dda8d76d
NC
7067 if (section->sh_link >= filedata->file_header.e_shnum
7068 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7069 != SHT_SYMTAB))
f5842774
L
7070 {
7071 error (_("Bad sh_link in group section `%s'\n"), name);
7072 continue;
7073 }
d1f5c6e3
L
7074
7075 if (symtab_sec != sec)
7076 {
7077 symtab_sec = sec;
9db70fc3 7078 free (symtab);
dda8d76d 7079 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7080 }
f5842774 7081
dd24e3da
NC
7082 if (symtab == NULL)
7083 {
7084 error (_("Corrupt header in group section `%s'\n"), name);
7085 continue;
7086 }
7087
ba5cdace
NC
7088 if (section->sh_info >= num_syms)
7089 {
7090 error (_("Bad sh_info in group section `%s'\n"), name);
7091 continue;
7092 }
7093
f5842774
L
7094 sym = symtab + section->sh_info;
7095
7096 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7097 {
4fbb74a6 7098 if (sym->st_shndx == 0
dda8d76d 7099 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7100 {
7101 error (_("Bad sh_info in group section `%s'\n"), name);
7102 continue;
7103 }
ba2685cc 7104
dda8d76d 7105 group_name = SECTION_NAME (filedata->section_headers + sym->st_shndx);
c256ffe7 7106 strtab_sec = NULL;
9db70fc3 7107 free (strtab);
f5842774 7108 strtab = NULL;
c256ffe7 7109 strtab_size = 0;
f5842774
L
7110 }
7111 else
7112 {
7113 /* Get the string table. */
dda8d76d 7114 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7115 {
7116 strtab_sec = NULL;
9db70fc3 7117 free (strtab);
c256ffe7
JJ
7118 strtab = NULL;
7119 strtab_size = 0;
7120 }
7121 else if (strtab_sec
dda8d76d 7122 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7123 {
7124 strtab_sec = sec;
9db70fc3 7125 free (strtab);
071436c6 7126
dda8d76d 7127 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7128 1, strtab_sec->sh_size,
7129 _("string table"));
c256ffe7 7130 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7131 }
c256ffe7 7132 group_name = sym->st_name < strtab_size
2b692964 7133 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7134 }
7135
c9c1d674
EG
7136 /* PR 17531: file: loop. */
7137 if (section->sh_entsize > section->sh_size)
7138 {
7139 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7140 printable_section_name (filedata, section),
8066deb1
AM
7141 (unsigned long) section->sh_entsize,
7142 (unsigned long) section->sh_size);
61dd8e19 7143 continue;
c9c1d674
EG
7144 }
7145
dda8d76d 7146 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7147 1, section->sh_size,
7148 _("section data"));
59245841
NC
7149 if (start == NULL)
7150 continue;
f5842774
L
7151
7152 indices = start;
7153 size = (section->sh_size / section->sh_entsize) - 1;
7154 entry = byte_get (indices, 4);
7155 indices += 4;
e4b17d5c
L
7156
7157 if (do_section_groups)
7158 {
2b692964 7159 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7160 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7161
e4b17d5c
L
7162 printf (_(" [Index] Name\n"));
7163 }
7164
7165 group->group_index = i;
7166
f5842774
L
7167 for (j = 0; j < size; j++)
7168 {
2cf0635d 7169 struct group_list * g;
e4b17d5c 7170
f5842774
L
7171 entry = byte_get (indices, 4);
7172 indices += 4;
7173
dda8d76d 7174 if (entry >= filedata->file_header.e_shnum)
391cb864 7175 {
57028622
NC
7176 static unsigned num_group_errors = 0;
7177
7178 if (num_group_errors ++ < 10)
7179 {
7180 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7181 entry, i, filedata->file_header.e_shnum - 1);
57028622 7182 if (num_group_errors == 10)
67ce483b 7183 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7184 }
391cb864
L
7185 continue;
7186 }
391cb864 7187
978c4450 7188 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7189 {
d1f5c6e3
L
7190 if (entry)
7191 {
57028622
NC
7192 static unsigned num_errs = 0;
7193
7194 if (num_errs ++ < 10)
7195 {
7196 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7197 entry, i,
978c4450 7198 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7199 if (num_errs == 10)
7200 warn (_("Further error messages about already contained group sections suppressed\n"));
7201 }
d1f5c6e3
L
7202 continue;
7203 }
7204 else
7205 {
7206 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7207 section group. We just warn it the first time
d1f5c6e3 7208 and ignore it afterwards. */
32ec8896 7209 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7210 if (!warned)
7211 {
7212 error (_("section 0 in group section [%5u]\n"),
978c4450 7213 filedata->section_headers_groups [entry]->group_index);
32ec8896 7214 warned = TRUE;
d1f5c6e3
L
7215 }
7216 }
e4b17d5c
L
7217 }
7218
978c4450 7219 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7220
7221 if (do_section_groups)
7222 {
dda8d76d
NC
7223 sec = filedata->section_headers + entry;
7224 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7225 }
7226
3f5e193b 7227 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7228 g->section_index = entry;
7229 g->next = group->root;
7230 group->root = g;
f5842774
L
7231 }
7232
9db70fc3 7233 free (start);
e4b17d5c
L
7234
7235 group++;
f5842774
L
7236 }
7237 }
7238
9db70fc3
AM
7239 free (symtab);
7240 free (strtab);
32ec8896 7241 return TRUE;
f5842774
L
7242}
7243
28f997cf
TG
7244/* Data used to display dynamic fixups. */
7245
7246struct ia64_vms_dynfixup
7247{
7248 bfd_vma needed_ident; /* Library ident number. */
7249 bfd_vma needed; /* Index in the dstrtab of the library name. */
7250 bfd_vma fixup_needed; /* Index of the library. */
7251 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7252 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7253};
7254
7255/* Data used to display dynamic relocations. */
7256
7257struct ia64_vms_dynimgrela
7258{
7259 bfd_vma img_rela_cnt; /* Number of relocations. */
7260 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7261};
7262
7263/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7264 library). */
7265
32ec8896 7266static bfd_boolean
dda8d76d
NC
7267dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7268 struct ia64_vms_dynfixup * fixup,
7269 const char * strtab,
7270 unsigned int strtab_sz)
28f997cf 7271{
32ec8896 7272 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7273 long i;
32ec8896 7274 const char * lib_name;
28f997cf 7275
978c4450
AM
7276 imfs = get_data (NULL, filedata,
7277 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7278 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7279 _("dynamic section image fixups"));
7280 if (!imfs)
32ec8896 7281 return FALSE;
28f997cf
TG
7282
7283 if (fixup->needed < strtab_sz)
7284 lib_name = strtab + fixup->needed;
7285 else
7286 {
32ec8896 7287 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7288 (unsigned long) fixup->needed);
28f997cf
TG
7289 lib_name = "???";
7290 }
736990c4 7291
28f997cf
TG
7292 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7293 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7294 printf
7295 (_("Seg Offset Type SymVec DataType\n"));
7296
7297 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7298 {
7299 unsigned int type;
7300 const char *rtype;
7301
7302 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7303 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7304 type = BYTE_GET (imfs [i].type);
7305 rtype = elf_ia64_reloc_type (type);
7306 if (rtype == NULL)
7307 printf (" 0x%08x ", type);
7308 else
7309 printf (" %-32s ", rtype);
7310 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7311 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7312 }
7313
7314 free (imfs);
32ec8896 7315 return TRUE;
28f997cf
TG
7316}
7317
7318/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7319
32ec8896 7320static bfd_boolean
dda8d76d 7321dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7322{
7323 Elf64_External_VMS_IMAGE_RELA *imrs;
7324 long i;
7325
978c4450
AM
7326 imrs = get_data (NULL, filedata,
7327 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7328 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7329 _("dynamic section image relocations"));
28f997cf 7330 if (!imrs)
32ec8896 7331 return FALSE;
28f997cf
TG
7332
7333 printf (_("\nImage relocs\n"));
7334 printf
7335 (_("Seg Offset Type Addend Seg Sym Off\n"));
7336
7337 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7338 {
7339 unsigned int type;
7340 const char *rtype;
7341
7342 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7343 printf ("%08" BFD_VMA_FMT "x ",
7344 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7345 type = BYTE_GET (imrs [i].type);
7346 rtype = elf_ia64_reloc_type (type);
7347 if (rtype == NULL)
7348 printf ("0x%08x ", type);
7349 else
7350 printf ("%-31s ", rtype);
7351 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7352 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7353 printf ("%08" BFD_VMA_FMT "x\n",
7354 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7355 }
7356
7357 free (imrs);
32ec8896 7358 return TRUE;
28f997cf
TG
7359}
7360
7361/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7362
32ec8896 7363static bfd_boolean
dda8d76d 7364process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7365{
7366 struct ia64_vms_dynfixup fixup;
7367 struct ia64_vms_dynimgrela imgrela;
7368 Elf_Internal_Dyn *entry;
28f997cf
TG
7369 bfd_vma strtab_off = 0;
7370 bfd_vma strtab_sz = 0;
7371 char *strtab = NULL;
32ec8896 7372 bfd_boolean res = TRUE;
28f997cf
TG
7373
7374 memset (&fixup, 0, sizeof (fixup));
7375 memset (&imgrela, 0, sizeof (imgrela));
7376
7377 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7378 for (entry = filedata->dynamic_section;
7379 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7380 entry++)
7381 {
7382 switch (entry->d_tag)
7383 {
7384 case DT_IA_64_VMS_STRTAB_OFFSET:
7385 strtab_off = entry->d_un.d_val;
7386 break;
7387 case DT_STRSZ:
7388 strtab_sz = entry->d_un.d_val;
7389 if (strtab == NULL)
978c4450
AM
7390 strtab = get_data (NULL, filedata,
7391 filedata->dynamic_addr + strtab_off,
28f997cf 7392 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7393 if (strtab == NULL)
7394 strtab_sz = 0;
28f997cf
TG
7395 break;
7396
7397 case DT_IA_64_VMS_NEEDED_IDENT:
7398 fixup.needed_ident = entry->d_un.d_val;
7399 break;
7400 case DT_NEEDED:
7401 fixup.needed = entry->d_un.d_val;
7402 break;
7403 case DT_IA_64_VMS_FIXUP_NEEDED:
7404 fixup.fixup_needed = entry->d_un.d_val;
7405 break;
7406 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7407 fixup.fixup_rela_cnt = entry->d_un.d_val;
7408 break;
7409 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7410 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7411 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7412 res = FALSE;
28f997cf 7413 break;
28f997cf
TG
7414 case DT_IA_64_VMS_IMG_RELA_CNT:
7415 imgrela.img_rela_cnt = entry->d_un.d_val;
7416 break;
7417 case DT_IA_64_VMS_IMG_RELA_OFF:
7418 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7419 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7420 res = FALSE;
28f997cf
TG
7421 break;
7422
7423 default:
7424 break;
7425 }
7426 }
7427
9db70fc3 7428 free (strtab);
28f997cf
TG
7429
7430 return res;
7431}
7432
85b1c36d 7433static struct
566b0d53 7434{
2cf0635d 7435 const char * name;
566b0d53
L
7436 int reloc;
7437 int size;
7438 int rela;
32ec8896
NC
7439}
7440 dynamic_relocations [] =
566b0d53 7441{
32ec8896
NC
7442 { "REL", DT_REL, DT_RELSZ, FALSE },
7443 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7444 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7445};
7446
252b5132 7447/* Process the reloc section. */
18bd398b 7448
32ec8896 7449static bfd_boolean
dda8d76d 7450process_relocs (Filedata * filedata)
252b5132 7451{
b34976b6
AM
7452 unsigned long rel_size;
7453 unsigned long rel_offset;
252b5132 7454
252b5132 7455 if (!do_reloc)
32ec8896 7456 return TRUE;
252b5132
RH
7457
7458 if (do_using_dynamic)
7459 {
32ec8896 7460 int is_rela;
2cf0635d 7461 const char * name;
32ec8896 7462 bfd_boolean has_dynamic_reloc;
566b0d53 7463 unsigned int i;
0de14b54 7464
32ec8896 7465 has_dynamic_reloc = FALSE;
252b5132 7466
566b0d53 7467 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7468 {
566b0d53
L
7469 is_rela = dynamic_relocations [i].rela;
7470 name = dynamic_relocations [i].name;
978c4450
AM
7471 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7472 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7473
32ec8896
NC
7474 if (rel_size)
7475 has_dynamic_reloc = TRUE;
566b0d53
L
7476
7477 if (is_rela == UNKNOWN)
aa903cfb 7478 {
566b0d53 7479 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7480 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7481 {
7482 case DT_REL:
7483 is_rela = FALSE;
7484 break;
7485 case DT_RELA:
7486 is_rela = TRUE;
7487 break;
7488 }
aa903cfb 7489 }
252b5132 7490
566b0d53
L
7491 if (rel_size)
7492 {
7493 printf
7494 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7495 name, rel_offset, rel_size);
252b5132 7496
dda8d76d
NC
7497 dump_relocations (filedata,
7498 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7499 rel_size,
978c4450
AM
7500 filedata->dynamic_symbols,
7501 filedata->num_dynamic_syms,
7502 filedata->dynamic_strings,
7503 filedata->dynamic_strings_length,
32ec8896 7504 is_rela, TRUE /* is_dynamic */);
566b0d53 7505 }
252b5132 7506 }
566b0d53 7507
dda8d76d
NC
7508 if (is_ia64_vms (filedata))
7509 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7510 has_dynamic_reloc = TRUE;
28f997cf 7511
566b0d53 7512 if (! has_dynamic_reloc)
252b5132
RH
7513 printf (_("\nThere are no dynamic relocations in this file.\n"));
7514 }
7515 else
7516 {
2cf0635d 7517 Elf_Internal_Shdr * section;
b34976b6 7518 unsigned long i;
32ec8896 7519 bfd_boolean found = FALSE;
252b5132 7520
dda8d76d
NC
7521 for (i = 0, section = filedata->section_headers;
7522 i < filedata->file_header.e_shnum;
b34976b6 7523 i++, section++)
252b5132
RH
7524 {
7525 if ( section->sh_type != SHT_RELA
7526 && section->sh_type != SHT_REL)
7527 continue;
7528
7529 rel_offset = section->sh_offset;
7530 rel_size = section->sh_size;
7531
7532 if (rel_size)
7533 {
b34976b6 7534 int is_rela;
d3a49aa8 7535 unsigned long num_rela;
103f02d3 7536
252b5132
RH
7537 printf (_("\nRelocation section "));
7538
dda8d76d 7539 if (filedata->string_table == NULL)
19936277 7540 printf ("%d", section->sh_name);
252b5132 7541 else
dda8d76d 7542 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7543
d3a49aa8
AM
7544 num_rela = rel_size / section->sh_entsize;
7545 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7546 " at offset 0x%lx contains %lu entries:\n",
7547 num_rela),
7548 rel_offset, num_rela);
252b5132 7549
d79b3d50
NC
7550 is_rela = section->sh_type == SHT_RELA;
7551
4fbb74a6 7552 if (section->sh_link != 0
dda8d76d 7553 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7554 {
2cf0635d
NC
7555 Elf_Internal_Shdr * symsec;
7556 Elf_Internal_Sym * symtab;
d79b3d50 7557 unsigned long nsyms;
c256ffe7 7558 unsigned long strtablen = 0;
2cf0635d 7559 char * strtab = NULL;
57346661 7560
dda8d76d 7561 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7562 if (symsec->sh_type != SHT_SYMTAB
7563 && symsec->sh_type != SHT_DYNSYM)
7564 continue;
7565
28d13567
AM
7566 if (!get_symtab (filedata, symsec,
7567 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7568 continue;
252b5132 7569
dda8d76d 7570 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7571 symtab, nsyms, strtab, strtablen,
7572 is_rela,
7573 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7574 free (strtab);
d79b3d50
NC
7575 free (symtab);
7576 }
7577 else
dda8d76d 7578 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7579 NULL, 0, NULL, 0, is_rela,
7580 FALSE /* is_dynamic */);
252b5132 7581
32ec8896 7582 found = TRUE;
252b5132
RH
7583 }
7584 }
7585
7586 if (! found)
45ac8f4f
NC
7587 {
7588 /* Users sometimes forget the -D option, so try to be helpful. */
7589 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7590 {
978c4450 7591 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f
NC
7592 {
7593 printf (_("\nThere are no static relocations in this file."));
7594 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7595
7596 break;
7597 }
7598 }
7599 if (i == ARRAY_SIZE (dynamic_relocations))
7600 printf (_("\nThere are no relocations in this file.\n"));
7601 }
252b5132
RH
7602 }
7603
32ec8896 7604 return TRUE;
252b5132
RH
7605}
7606
4d6ed7c8
NC
7607/* An absolute address consists of a section and an offset. If the
7608 section is NULL, the offset itself is the address, otherwise, the
7609 address equals to LOAD_ADDRESS(section) + offset. */
7610
7611struct absaddr
948f632f
DA
7612{
7613 unsigned short section;
7614 bfd_vma offset;
7615};
4d6ed7c8 7616
948f632f
DA
7617/* Find the nearest symbol at or below ADDR. Returns the symbol
7618 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7619
4d6ed7c8 7620static void
dda8d76d
NC
7621find_symbol_for_address (Filedata * filedata,
7622 Elf_Internal_Sym * symtab,
7623 unsigned long nsyms,
7624 const char * strtab,
7625 unsigned long strtab_size,
7626 struct absaddr addr,
7627 const char ** symname,
7628 bfd_vma * offset)
4d6ed7c8 7629{
d3ba0551 7630 bfd_vma dist = 0x100000;
2cf0635d 7631 Elf_Internal_Sym * sym;
948f632f
DA
7632 Elf_Internal_Sym * beg;
7633 Elf_Internal_Sym * end;
2cf0635d 7634 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7635
0b6ae522 7636 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7637 beg = symtab;
7638 end = symtab + nsyms;
0b6ae522 7639
948f632f 7640 while (beg < end)
4d6ed7c8 7641 {
948f632f
DA
7642 bfd_vma value;
7643
7644 sym = beg + (end - beg) / 2;
0b6ae522 7645
948f632f 7646 value = sym->st_value;
0b6ae522
DJ
7647 REMOVE_ARCH_BITS (value);
7648
948f632f 7649 if (sym->st_name != 0
4d6ed7c8 7650 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7651 && addr.offset >= value
7652 && addr.offset - value < dist)
4d6ed7c8
NC
7653 {
7654 best = sym;
0b6ae522 7655 dist = addr.offset - value;
4d6ed7c8
NC
7656 if (!dist)
7657 break;
7658 }
948f632f
DA
7659
7660 if (addr.offset < value)
7661 end = sym;
7662 else
7663 beg = sym + 1;
4d6ed7c8 7664 }
1b31d05e 7665
4d6ed7c8
NC
7666 if (best)
7667 {
57346661 7668 *symname = (best->st_name >= strtab_size
2b692964 7669 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7670 *offset = dist;
7671 return;
7672 }
1b31d05e 7673
4d6ed7c8
NC
7674 *symname = NULL;
7675 *offset = addr.offset;
7676}
7677
32ec8896 7678static /* signed */ int
948f632f
DA
7679symcmp (const void *p, const void *q)
7680{
7681 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7682 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7683
7684 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7685}
7686
7687/* Process the unwind section. */
7688
7689#include "unwind-ia64.h"
7690
7691struct ia64_unw_table_entry
7692{
7693 struct absaddr start;
7694 struct absaddr end;
7695 struct absaddr info;
7696};
7697
7698struct ia64_unw_aux_info
7699{
32ec8896
NC
7700 struct ia64_unw_table_entry * table; /* Unwind table. */
7701 unsigned long table_len; /* Length of unwind table. */
7702 unsigned char * info; /* Unwind info. */
7703 unsigned long info_size; /* Size of unwind info. */
7704 bfd_vma info_addr; /* Starting address of unwind info. */
7705 bfd_vma seg_base; /* Starting address of segment. */
7706 Elf_Internal_Sym * symtab; /* The symbol table. */
7707 unsigned long nsyms; /* Number of symbols. */
7708 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7709 unsigned long nfuns; /* Number of entries in funtab. */
7710 char * strtab; /* The string table. */
7711 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7712};
7713
32ec8896 7714static bfd_boolean
dda8d76d 7715dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7716{
2cf0635d 7717 struct ia64_unw_table_entry * tp;
948f632f 7718 unsigned long j, nfuns;
4d6ed7c8 7719 int in_body;
32ec8896 7720 bfd_boolean res = TRUE;
7036c0e1 7721
948f632f
DA
7722 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7723 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7724 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7725 aux->funtab[nfuns++] = aux->symtab[j];
7726 aux->nfuns = nfuns;
7727 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7728
4d6ed7c8
NC
7729 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7730 {
7731 bfd_vma stamp;
7732 bfd_vma offset;
2cf0635d
NC
7733 const unsigned char * dp;
7734 const unsigned char * head;
53774b7e 7735 const unsigned char * end;
2cf0635d 7736 const char * procname;
4d6ed7c8 7737
dda8d76d 7738 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7739 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7740
7741 fputs ("\n<", stdout);
7742
7743 if (procname)
7744 {
7745 fputs (procname, stdout);
7746
7747 if (offset)
7748 printf ("+%lx", (unsigned long) offset);
7749 }
7750
7751 fputs (">: [", stdout);
7752 print_vma (tp->start.offset, PREFIX_HEX);
7753 fputc ('-', stdout);
7754 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7755 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7756 (unsigned long) (tp->info.offset - aux->seg_base));
7757
53774b7e
NC
7758 /* PR 17531: file: 86232b32. */
7759 if (aux->info == NULL)
7760 continue;
7761
97c0a079
AM
7762 offset = tp->info.offset;
7763 if (tp->info.section)
7764 {
7765 if (tp->info.section >= filedata->file_header.e_shnum)
7766 {
7767 warn (_("Invalid section %u in table entry %ld\n"),
7768 tp->info.section, (long) (tp - aux->table));
7769 res = FALSE;
7770 continue;
7771 }
7772 offset += filedata->section_headers[tp->info.section].sh_addr;
7773 }
7774 offset -= aux->info_addr;
53774b7e 7775 /* PR 17531: file: 0997b4d1. */
90679903
AM
7776 if (offset >= aux->info_size
7777 || aux->info_size - offset < 8)
53774b7e
NC
7778 {
7779 warn (_("Invalid offset %lx in table entry %ld\n"),
7780 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7781 res = FALSE;
53774b7e
NC
7782 continue;
7783 }
7784
97c0a079 7785 head = aux->info + offset;
a4a00738 7786 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7787
86f55779 7788 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7789 (unsigned) UNW_VER (stamp),
7790 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7791 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7792 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7793 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7794
7795 if (UNW_VER (stamp) != 1)
7796 {
2b692964 7797 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7798 continue;
7799 }
7800
7801 in_body = 0;
53774b7e
NC
7802 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7803 /* PR 17531: file: 16ceda89. */
7804 if (end > aux->info + aux->info_size)
7805 end = aux->info + aux->info_size;
7806 for (dp = head + 8; dp < end;)
b4477bc8 7807 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7808 }
948f632f
DA
7809
7810 free (aux->funtab);
32ec8896
NC
7811
7812 return res;
4d6ed7c8
NC
7813}
7814
53774b7e 7815static bfd_boolean
dda8d76d
NC
7816slurp_ia64_unwind_table (Filedata * filedata,
7817 struct ia64_unw_aux_info * aux,
7818 Elf_Internal_Shdr * sec)
4d6ed7c8 7819{
89fac5e3 7820 unsigned long size, nrelas, i;
2cf0635d
NC
7821 Elf_Internal_Phdr * seg;
7822 struct ia64_unw_table_entry * tep;
7823 Elf_Internal_Shdr * relsec;
7824 Elf_Internal_Rela * rela;
7825 Elf_Internal_Rela * rp;
7826 unsigned char * table;
7827 unsigned char * tp;
7828 Elf_Internal_Sym * sym;
7829 const char * relname;
4d6ed7c8 7830
53774b7e
NC
7831 aux->table_len = 0;
7832
4d6ed7c8
NC
7833 /* First, find the starting address of the segment that includes
7834 this section: */
7835
dda8d76d 7836 if (filedata->file_header.e_phnum)
4d6ed7c8 7837 {
dda8d76d 7838 if (! get_program_headers (filedata))
53774b7e 7839 return FALSE;
4d6ed7c8 7840
dda8d76d
NC
7841 for (seg = filedata->program_headers;
7842 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7843 ++seg)
4d6ed7c8
NC
7844 {
7845 if (seg->p_type != PT_LOAD)
7846 continue;
7847
7848 if (sec->sh_addr >= seg->p_vaddr
7849 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7850 {
7851 aux->seg_base = seg->p_vaddr;
7852 break;
7853 }
7854 }
4d6ed7c8
NC
7855 }
7856
7857 /* Second, build the unwind table from the contents of the unwind section: */
7858 size = sec->sh_size;
dda8d76d 7859 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7860 _("unwind table"));
a6e9f9df 7861 if (!table)
53774b7e 7862 return FALSE;
4d6ed7c8 7863
53774b7e 7864 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7865 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7866 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7867 tep = aux->table;
53774b7e
NC
7868
7869 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7870 {
7871 tep->start.section = SHN_UNDEF;
7872 tep->end.section = SHN_UNDEF;
7873 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7874 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7875 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7876 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7877 tep->start.offset += aux->seg_base;
7878 tep->end.offset += aux->seg_base;
7879 tep->info.offset += aux->seg_base;
7880 }
7881 free (table);
7882
41e92641 7883 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7884 for (relsec = filedata->section_headers;
7885 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7886 ++relsec)
7887 {
7888 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7889 || relsec->sh_info >= filedata->file_header.e_shnum
7890 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7891 continue;
7892
dda8d76d 7893 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 7894 & rela, & nrelas))
53774b7e
NC
7895 {
7896 free (aux->table);
7897 aux->table = NULL;
7898 aux->table_len = 0;
7899 return FALSE;
7900 }
4d6ed7c8
NC
7901
7902 for (rp = rela; rp < rela + nrelas; ++rp)
7903 {
4770fb94 7904 unsigned int sym_ndx;
726bd37d
AM
7905 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
7906 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 7907
82b1b41b
NC
7908 /* PR 17531: file: 9fa67536. */
7909 if (relname == NULL)
7910 {
726bd37d 7911 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
7912 continue;
7913 }
948f632f 7914
0112cd26 7915 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 7916 {
82b1b41b 7917 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
7918 continue;
7919 }
7920
89fac5e3 7921 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 7922
53774b7e
NC
7923 /* PR 17531: file: 5bc8d9bf. */
7924 if (i >= aux->table_len)
7925 {
7926 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
7927 continue;
7928 }
7929
4770fb94
AM
7930 sym_ndx = get_reloc_symindex (rp->r_info);
7931 if (sym_ndx >= aux->nsyms)
7932 {
7933 warn (_("Skipping reloc with invalid symbol index: %u\n"),
7934 sym_ndx);
7935 continue;
7936 }
7937 sym = aux->symtab + sym_ndx;
7938
53774b7e 7939 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
7940 {
7941 case 0:
7942 aux->table[i].start.section = sym->st_shndx;
e466bc6e 7943 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7944 break;
7945 case 1:
7946 aux->table[i].end.section = sym->st_shndx;
e466bc6e 7947 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7948 break;
7949 case 2:
7950 aux->table[i].info.section = sym->st_shndx;
e466bc6e 7951 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
7952 break;
7953 default:
7954 break;
7955 }
7956 }
7957
7958 free (rela);
7959 }
7960
53774b7e 7961 return TRUE;
4d6ed7c8
NC
7962}
7963
32ec8896 7964static bfd_boolean
dda8d76d 7965ia64_process_unwind (Filedata * filedata)
4d6ed7c8 7966{
2cf0635d
NC
7967 Elf_Internal_Shdr * sec;
7968 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 7969 unsigned long i, unwcount = 0, unwstart = 0;
57346661 7970 struct ia64_unw_aux_info aux;
32ec8896 7971 bfd_boolean res = TRUE;
f1467e33 7972
4d6ed7c8
NC
7973 memset (& aux, 0, sizeof (aux));
7974
dda8d76d 7975 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 7976 {
28d13567 7977 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 7978 {
28d13567 7979 if (aux.symtab)
4082ef84 7980 {
28d13567
AM
7981 error (_("Multiple symbol tables encountered\n"));
7982 free (aux.symtab);
7983 aux.symtab = NULL;
4082ef84 7984 free (aux.strtab);
28d13567 7985 aux.strtab = NULL;
4082ef84 7986 }
28d13567
AM
7987 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
7988 &aux.strtab, &aux.strtab_size))
7989 return FALSE;
4d6ed7c8
NC
7990 }
7991 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
7992 unwcount++;
7993 }
7994
7995 if (!unwcount)
7996 printf (_("\nThere are no unwind sections in this file.\n"));
7997
7998 while (unwcount-- > 0)
7999 {
2cf0635d 8000 char * suffix;
579f31ac
JJ
8001 size_t len, len2;
8002
dda8d76d
NC
8003 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8004 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8005 if (sec->sh_type == SHT_IA_64_UNWIND)
8006 {
8007 unwsec = sec;
8008 break;
8009 }
4082ef84
NC
8010 /* We have already counted the number of SHT_IA64_UNWIND
8011 sections so the loop above should never fail. */
8012 assert (unwsec != NULL);
579f31ac
JJ
8013
8014 unwstart = i + 1;
8015 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8016
e4b17d5c
L
8017 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8018 {
8019 /* We need to find which section group it is in. */
4082ef84 8020 struct group_list * g;
e4b17d5c 8021
978c4450
AM
8022 if (filedata->section_headers_groups == NULL
8023 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8024 i = filedata->file_header.e_shnum;
4082ef84 8025 else
e4b17d5c 8026 {
978c4450 8027 g = filedata->section_headers_groups[i]->root;
18bd398b 8028
4082ef84
NC
8029 for (; g != NULL; g = g->next)
8030 {
dda8d76d 8031 sec = filedata->section_headers + g->section_index;
e4b17d5c 8032
4082ef84
NC
8033 if (streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
8034 break;
8035 }
8036
8037 if (g == NULL)
dda8d76d 8038 i = filedata->file_header.e_shnum;
4082ef84 8039 }
e4b17d5c 8040 }
18bd398b 8041 else if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind_once, len))
579f31ac 8042 {
18bd398b 8043 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8044 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8045 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8046 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8047 ++i, ++sec)
18bd398b
NC
8048 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info_once, len2)
8049 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8050 break;
8051 }
8052 else
8053 {
8054 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8055 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8056 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8057 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8058 suffix = "";
18bd398b 8059 if (strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 8060 suffix = SECTION_NAME (unwsec) + len;
dda8d76d 8061 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum;
579f31ac 8062 ++i, ++sec)
18bd398b
NC
8063 if (strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
8064 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8065 break;
8066 }
8067
dda8d76d 8068 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8069 {
8070 printf (_("\nCould not find unwind info section for "));
8071
dda8d76d 8072 if (filedata->string_table == NULL)
579f31ac
JJ
8073 printf ("%d", unwsec->sh_name);
8074 else
dda8d76d 8075 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8076 }
8077 else
4d6ed7c8 8078 {
4d6ed7c8 8079 aux.info_addr = sec->sh_addr;
dda8d76d 8080 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8081 sec->sh_size,
8082 _("unwind info"));
59245841 8083 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8084
579f31ac 8085 printf (_("\nUnwind section "));
4d6ed7c8 8086
dda8d76d 8087 if (filedata->string_table == NULL)
579f31ac
JJ
8088 printf ("%d", unwsec->sh_name);
8089 else
dda8d76d 8090 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8091
579f31ac 8092 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8093 (unsigned long) unwsec->sh_offset,
89fac5e3 8094 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8095
dda8d76d 8096 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8097 && aux.table_len > 0)
dda8d76d 8098 dump_ia64_unwind (filedata, & aux);
579f31ac 8099
9db70fc3
AM
8100 free ((char *) aux.table);
8101 free ((char *) aux.info);
579f31ac
JJ
8102 aux.table = NULL;
8103 aux.info = NULL;
8104 }
4d6ed7c8 8105 }
4d6ed7c8 8106
9db70fc3
AM
8107 free (aux.symtab);
8108 free ((char *) aux.strtab);
32ec8896
NC
8109
8110 return res;
4d6ed7c8
NC
8111}
8112
3f5e193b 8113struct hppa_unw_table_entry
32ec8896
NC
8114{
8115 struct absaddr start;
8116 struct absaddr end;
8117 unsigned int Cannot_unwind:1; /* 0 */
8118 unsigned int Millicode:1; /* 1 */
8119 unsigned int Millicode_save_sr0:1; /* 2 */
8120 unsigned int Region_description:2; /* 3..4 */
8121 unsigned int reserved1:1; /* 5 */
8122 unsigned int Entry_SR:1; /* 6 */
8123 unsigned int Entry_FR:4; /* Number saved 7..10 */
8124 unsigned int Entry_GR:5; /* Number saved 11..15 */
8125 unsigned int Args_stored:1; /* 16 */
8126 unsigned int Variable_Frame:1; /* 17 */
8127 unsigned int Separate_Package_Body:1; /* 18 */
8128 unsigned int Frame_Extension_Millicode:1; /* 19 */
8129 unsigned int Stack_Overflow_Check:1; /* 20 */
8130 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8131 unsigned int Ada_Region:1; /* 22 */
8132 unsigned int cxx_info:1; /* 23 */
8133 unsigned int cxx_try_catch:1; /* 24 */
8134 unsigned int sched_entry_seq:1; /* 25 */
8135 unsigned int reserved2:1; /* 26 */
8136 unsigned int Save_SP:1; /* 27 */
8137 unsigned int Save_RP:1; /* 28 */
8138 unsigned int Save_MRP_in_frame:1; /* 29 */
8139 unsigned int extn_ptr_defined:1; /* 30 */
8140 unsigned int Cleanup_defined:1; /* 31 */
8141
8142 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8143 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8144 unsigned int Large_frame:1; /* 2 */
8145 unsigned int Pseudo_SP_Set:1; /* 3 */
8146 unsigned int reserved4:1; /* 4 */
8147 unsigned int Total_frame_size:27; /* 5..31 */
8148};
3f5e193b 8149
57346661 8150struct hppa_unw_aux_info
948f632f 8151{
32ec8896
NC
8152 struct hppa_unw_table_entry * table; /* Unwind table. */
8153 unsigned long table_len; /* Length of unwind table. */
8154 bfd_vma seg_base; /* Starting address of segment. */
8155 Elf_Internal_Sym * symtab; /* The symbol table. */
8156 unsigned long nsyms; /* Number of symbols. */
8157 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8158 unsigned long nfuns; /* Number of entries in funtab. */
8159 char * strtab; /* The string table. */
8160 unsigned long strtab_size; /* Size of string table. */
948f632f 8161};
57346661 8162
32ec8896 8163static bfd_boolean
dda8d76d 8164dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8165{
2cf0635d 8166 struct hppa_unw_table_entry * tp;
948f632f 8167 unsigned long j, nfuns;
32ec8896 8168 bfd_boolean res = TRUE;
948f632f
DA
8169
8170 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8171 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8172 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8173 aux->funtab[nfuns++] = aux->symtab[j];
8174 aux->nfuns = nfuns;
8175 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8176
57346661
AM
8177 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8178 {
8179 bfd_vma offset;
2cf0635d 8180 const char * procname;
57346661 8181
dda8d76d 8182 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8183 aux->strtab_size, tp->start, &procname,
8184 &offset);
8185
8186 fputs ("\n<", stdout);
8187
8188 if (procname)
8189 {
8190 fputs (procname, stdout);
8191
8192 if (offset)
8193 printf ("+%lx", (unsigned long) offset);
8194 }
8195
8196 fputs (">: [", stdout);
8197 print_vma (tp->start.offset, PREFIX_HEX);
8198 fputc ('-', stdout);
8199 print_vma (tp->end.offset, PREFIX_HEX);
8200 printf ("]\n\t");
8201
18bd398b
NC
8202#define PF(_m) if (tp->_m) printf (#_m " ");
8203#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8204 PF(Cannot_unwind);
8205 PF(Millicode);
8206 PF(Millicode_save_sr0);
18bd398b 8207 /* PV(Region_description); */
57346661
AM
8208 PF(Entry_SR);
8209 PV(Entry_FR);
8210 PV(Entry_GR);
8211 PF(Args_stored);
8212 PF(Variable_Frame);
8213 PF(Separate_Package_Body);
8214 PF(Frame_Extension_Millicode);
8215 PF(Stack_Overflow_Check);
8216 PF(Two_Instruction_SP_Increment);
8217 PF(Ada_Region);
8218 PF(cxx_info);
8219 PF(cxx_try_catch);
8220 PF(sched_entry_seq);
8221 PF(Save_SP);
8222 PF(Save_RP);
8223 PF(Save_MRP_in_frame);
8224 PF(extn_ptr_defined);
8225 PF(Cleanup_defined);
8226 PF(MPE_XL_interrupt_marker);
8227 PF(HP_UX_interrupt_marker);
8228 PF(Large_frame);
8229 PF(Pseudo_SP_Set);
8230 PV(Total_frame_size);
8231#undef PF
8232#undef PV
8233 }
8234
18bd398b 8235 printf ("\n");
948f632f
DA
8236
8237 free (aux->funtab);
32ec8896
NC
8238
8239 return res;
57346661
AM
8240}
8241
32ec8896 8242static bfd_boolean
dda8d76d
NC
8243slurp_hppa_unwind_table (Filedata * filedata,
8244 struct hppa_unw_aux_info * aux,
8245 Elf_Internal_Shdr * sec)
57346661 8246{
1c0751b2 8247 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8248 Elf_Internal_Phdr * seg;
8249 struct hppa_unw_table_entry * tep;
8250 Elf_Internal_Shdr * relsec;
8251 Elf_Internal_Rela * rela;
8252 Elf_Internal_Rela * rp;
8253 unsigned char * table;
8254 unsigned char * tp;
8255 Elf_Internal_Sym * sym;
8256 const char * relname;
57346661 8257
57346661
AM
8258 /* First, find the starting address of the segment that includes
8259 this section. */
dda8d76d 8260 if (filedata->file_header.e_phnum)
57346661 8261 {
dda8d76d 8262 if (! get_program_headers (filedata))
32ec8896 8263 return FALSE;
57346661 8264
dda8d76d
NC
8265 for (seg = filedata->program_headers;
8266 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8267 ++seg)
8268 {
8269 if (seg->p_type != PT_LOAD)
8270 continue;
8271
8272 if (sec->sh_addr >= seg->p_vaddr
8273 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8274 {
8275 aux->seg_base = seg->p_vaddr;
8276 break;
8277 }
8278 }
8279 }
8280
8281 /* Second, build the unwind table from the contents of the unwind
8282 section. */
8283 size = sec->sh_size;
dda8d76d 8284 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8285 _("unwind table"));
57346661 8286 if (!table)
32ec8896 8287 return FALSE;
57346661 8288
1c0751b2
DA
8289 unw_ent_size = 16;
8290 nentries = size / unw_ent_size;
8291 size = unw_ent_size * nentries;
57346661 8292
e3fdc001 8293 aux->table_len = nentries;
3f5e193b
NC
8294 tep = aux->table = (struct hppa_unw_table_entry *)
8295 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8296
1c0751b2 8297 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8298 {
8299 unsigned int tmp1, tmp2;
8300
8301 tep->start.section = SHN_UNDEF;
8302 tep->end.section = SHN_UNDEF;
8303
1c0751b2
DA
8304 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8305 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8306 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8307 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8308
8309 tep->start.offset += aux->seg_base;
8310 tep->end.offset += aux->seg_base;
57346661
AM
8311
8312 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8313 tep->Millicode = (tmp1 >> 30) & 0x1;
8314 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8315 tep->Region_description = (tmp1 >> 27) & 0x3;
8316 tep->reserved1 = (tmp1 >> 26) & 0x1;
8317 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8318 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8319 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8320 tep->Args_stored = (tmp1 >> 15) & 0x1;
8321 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8322 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8323 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8324 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8325 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8326 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8327 tep->cxx_info = (tmp1 >> 8) & 0x1;
8328 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8329 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8330 tep->reserved2 = (tmp1 >> 5) & 0x1;
8331 tep->Save_SP = (tmp1 >> 4) & 0x1;
8332 tep->Save_RP = (tmp1 >> 3) & 0x1;
8333 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8334 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8335 tep->Cleanup_defined = tmp1 & 0x1;
8336
8337 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8338 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8339 tep->Large_frame = (tmp2 >> 29) & 0x1;
8340 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8341 tep->reserved4 = (tmp2 >> 27) & 0x1;
8342 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8343 }
8344 free (table);
8345
8346 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8347 for (relsec = filedata->section_headers;
8348 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8349 ++relsec)
8350 {
8351 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8352 || relsec->sh_info >= filedata->file_header.e_shnum
8353 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8354 continue;
8355
dda8d76d 8356 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8357 & rela, & nrelas))
32ec8896 8358 return FALSE;
57346661
AM
8359
8360 for (rp = rela; rp < rela + nrelas; ++rp)
8361 {
4770fb94 8362 unsigned int sym_ndx;
726bd37d
AM
8363 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8364 relname = elf_hppa_reloc_type (r_type);
57346661 8365
726bd37d
AM
8366 if (relname == NULL)
8367 {
8368 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8369 continue;
8370 }
8371
57346661 8372 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8373 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8374 {
726bd37d 8375 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8376 continue;
8377 }
8378
8379 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8380 if (i >= aux->table_len)
8381 {
8382 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8383 continue;
8384 }
57346661 8385
4770fb94
AM
8386 sym_ndx = get_reloc_symindex (rp->r_info);
8387 if (sym_ndx >= aux->nsyms)
8388 {
8389 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8390 sym_ndx);
8391 continue;
8392 }
8393 sym = aux->symtab + sym_ndx;
8394
43f6cd05 8395 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8396 {
8397 case 0:
8398 aux->table[i].start.section = sym->st_shndx;
1e456d54 8399 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8400 break;
8401 case 1:
8402 aux->table[i].end.section = sym->st_shndx;
1e456d54 8403 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8404 break;
8405 default:
8406 break;
8407 }
8408 }
8409
8410 free (rela);
8411 }
8412
32ec8896 8413 return TRUE;
57346661
AM
8414}
8415
32ec8896 8416static bfd_boolean
dda8d76d 8417hppa_process_unwind (Filedata * filedata)
57346661 8418{
57346661 8419 struct hppa_unw_aux_info aux;
2cf0635d 8420 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8421 Elf_Internal_Shdr * sec;
18bd398b 8422 unsigned long i;
32ec8896 8423 bfd_boolean res = TRUE;
57346661 8424
dda8d76d 8425 if (filedata->string_table == NULL)
32ec8896 8426 return FALSE;
1b31d05e
NC
8427
8428 memset (& aux, 0, sizeof (aux));
57346661 8429
dda8d76d 8430 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8431 {
28d13567 8432 if (sec->sh_type == SHT_SYMTAB)
57346661 8433 {
28d13567 8434 if (aux.symtab)
4082ef84 8435 {
28d13567
AM
8436 error (_("Multiple symbol tables encountered\n"));
8437 free (aux.symtab);
8438 aux.symtab = NULL;
4082ef84 8439 free (aux.strtab);
28d13567 8440 aux.strtab = NULL;
4082ef84 8441 }
28d13567
AM
8442 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8443 &aux.strtab, &aux.strtab_size))
8444 return FALSE;
57346661 8445 }
18bd398b 8446 else if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8447 unwsec = sec;
8448 }
8449
8450 if (!unwsec)
8451 printf (_("\nThere are no unwind sections in this file.\n"));
8452
dda8d76d 8453 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8454 {
18bd398b 8455 if (streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8456 {
43f6cd05 8457 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8458
d3a49aa8
AM
8459 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8460 "contains %lu entry:\n",
8461 "\nUnwind section '%s' at offset 0x%lx "
8462 "contains %lu entries:\n",
8463 num_unwind),
dda8d76d 8464 printable_section_name (filedata, sec),
57346661 8465 (unsigned long) sec->sh_offset,
d3a49aa8 8466 num_unwind);
57346661 8467
dda8d76d 8468 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8469 res = FALSE;
66b09c7e
S
8470
8471 if (res && aux.table_len > 0)
32ec8896 8472 {
dda8d76d 8473 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8474 res = FALSE;
8475 }
57346661 8476
9db70fc3 8477 free ((char *) aux.table);
57346661
AM
8478 aux.table = NULL;
8479 }
8480 }
8481
9db70fc3
AM
8482 free (aux.symtab);
8483 free ((char *) aux.strtab);
32ec8896
NC
8484
8485 return res;
57346661
AM
8486}
8487
0b6ae522
DJ
8488struct arm_section
8489{
a734115a
NC
8490 unsigned char * data; /* The unwind data. */
8491 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8492 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8493 unsigned long nrelas; /* The number of relocations. */
8494 unsigned int rel_type; /* REL or RELA ? */
8495 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8496};
8497
8498struct arm_unw_aux_info
8499{
dda8d76d 8500 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8501 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8502 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8503 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8504 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8505 char * strtab; /* The file's string table. */
8506 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8507};
8508
8509static const char *
dda8d76d
NC
8510arm_print_vma_and_name (Filedata * filedata,
8511 struct arm_unw_aux_info * aux,
8512 bfd_vma fn,
8513 struct absaddr addr)
0b6ae522
DJ
8514{
8515 const char *procname;
8516 bfd_vma sym_offset;
8517
8518 if (addr.section == SHN_UNDEF)
8519 addr.offset = fn;
8520
dda8d76d 8521 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8522 aux->strtab_size, addr, &procname,
8523 &sym_offset);
8524
8525 print_vma (fn, PREFIX_HEX);
8526
8527 if (procname)
8528 {
8529 fputs (" <", stdout);
8530 fputs (procname, stdout);
8531
8532 if (sym_offset)
8533 printf ("+0x%lx", (unsigned long) sym_offset);
8534 fputc ('>', stdout);
8535 }
8536
8537 return procname;
8538}
8539
8540static void
8541arm_free_section (struct arm_section *arm_sec)
8542{
9db70fc3
AM
8543 free (arm_sec->data);
8544 free (arm_sec->rela);
0b6ae522
DJ
8545}
8546
a734115a
NC
8547/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8548 cached section and install SEC instead.
8549 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8550 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8551 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8552 relocation's offset in ADDR.
1b31d05e
NC
8553 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8554 into the string table of the symbol associated with the reloc. If no
8555 reloc was applied store -1 there.
8556 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8557
8558static bfd_boolean
dda8d76d
NC
8559get_unwind_section_word (Filedata * filedata,
8560 struct arm_unw_aux_info * aux,
1b31d05e
NC
8561 struct arm_section * arm_sec,
8562 Elf_Internal_Shdr * sec,
8563 bfd_vma word_offset,
8564 unsigned int * wordp,
8565 struct absaddr * addr,
8566 bfd_vma * sym_name)
0b6ae522
DJ
8567{
8568 Elf_Internal_Rela *rp;
8569 Elf_Internal_Sym *sym;
8570 const char * relname;
8571 unsigned int word;
8572 bfd_boolean wrapped;
8573
e0a31db1
NC
8574 if (sec == NULL || arm_sec == NULL)
8575 return FALSE;
8576
0b6ae522
DJ
8577 addr->section = SHN_UNDEF;
8578 addr->offset = 0;
8579
1b31d05e
NC
8580 if (sym_name != NULL)
8581 *sym_name = (bfd_vma) -1;
8582
a734115a 8583 /* If necessary, update the section cache. */
0b6ae522
DJ
8584 if (sec != arm_sec->sec)
8585 {
8586 Elf_Internal_Shdr *relsec;
8587
8588 arm_free_section (arm_sec);
8589
8590 arm_sec->sec = sec;
dda8d76d 8591 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8592 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8593 arm_sec->rela = NULL;
8594 arm_sec->nrelas = 0;
8595
dda8d76d
NC
8596 for (relsec = filedata->section_headers;
8597 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8598 ++relsec)
8599 {
dda8d76d
NC
8600 if (relsec->sh_info >= filedata->file_header.e_shnum
8601 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8602 /* PR 15745: Check the section type as well. */
8603 || (relsec->sh_type != SHT_REL
8604 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8605 continue;
8606
a734115a 8607 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8608 if (relsec->sh_type == SHT_REL)
8609 {
dda8d76d 8610 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8611 relsec->sh_size,
8612 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8613 return FALSE;
0b6ae522 8614 }
1ae40aa4 8615 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8616 {
dda8d76d 8617 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8618 relsec->sh_size,
8619 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8620 return FALSE;
0b6ae522 8621 }
1ae40aa4 8622 break;
0b6ae522
DJ
8623 }
8624
8625 arm_sec->next_rela = arm_sec->rela;
8626 }
8627
a734115a 8628 /* If there is no unwind data we can do nothing. */
0b6ae522 8629 if (arm_sec->data == NULL)
a734115a 8630 return FALSE;
0b6ae522 8631
e0a31db1 8632 /* If the offset is invalid then fail. */
f32ba729
NC
8633 if (/* PR 21343 *//* PR 18879 */
8634 sec->sh_size < 4
8635 || word_offset > (sec->sh_size - 4)
1a915552 8636 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8637 return FALSE;
8638
a734115a 8639 /* Get the word at the required offset. */
0b6ae522
DJ
8640 word = byte_get (arm_sec->data + word_offset, 4);
8641
0eff7165
NC
8642 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8643 if (arm_sec->rela == NULL)
8644 {
8645 * wordp = word;
8646 return TRUE;
8647 }
8648
a734115a 8649 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8650 wrapped = FALSE;
8651 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8652 {
8653 bfd_vma prelval, offset;
8654
8655 if (rp->r_offset > word_offset && !wrapped)
8656 {
8657 rp = arm_sec->rela;
8658 wrapped = TRUE;
8659 }
8660 if (rp->r_offset > word_offset)
8661 break;
8662
8663 if (rp->r_offset & 3)
8664 {
8665 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8666 (unsigned long) rp->r_offset);
8667 continue;
8668 }
8669
8670 if (rp->r_offset < word_offset)
8671 continue;
8672
74e1a04b
NC
8673 /* PR 17531: file: 027-161405-0.004 */
8674 if (aux->symtab == NULL)
8675 continue;
8676
0b6ae522
DJ
8677 if (arm_sec->rel_type == SHT_REL)
8678 {
8679 offset = word & 0x7fffffff;
8680 if (offset & 0x40000000)
8681 offset |= ~ (bfd_vma) 0x7fffffff;
8682 }
a734115a 8683 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8684 offset = rp->r_addend;
a734115a 8685 else
74e1a04b
NC
8686 {
8687 error (_("Unknown section relocation type %d encountered\n"),
8688 arm_sec->rel_type);
8689 break;
8690 }
0b6ae522 8691
071436c6
NC
8692 /* PR 17531 file: 027-1241568-0.004. */
8693 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8694 {
8695 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8696 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8697 break;
8698 }
8699
8700 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8701 offset += sym->st_value;
8702 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8703
a734115a 8704 /* Check that we are processing the expected reloc type. */
dda8d76d 8705 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8706 {
8707 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8708 if (relname == NULL)
8709 {
8710 warn (_("Skipping unknown ARM relocation type: %d\n"),
8711 (int) ELF32_R_TYPE (rp->r_info));
8712 continue;
8713 }
a734115a
NC
8714
8715 if (streq (relname, "R_ARM_NONE"))
8716 continue;
0b4362b0 8717
a734115a
NC
8718 if (! streq (relname, "R_ARM_PREL31"))
8719 {
071436c6 8720 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8721 continue;
8722 }
8723 }
dda8d76d 8724 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8725 {
8726 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8727 if (relname == NULL)
8728 {
8729 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8730 (int) ELF32_R_TYPE (rp->r_info));
8731 continue;
8732 }
0b4362b0 8733
a734115a
NC
8734 if (streq (relname, "R_C6000_NONE"))
8735 continue;
8736
8737 if (! streq (relname, "R_C6000_PREL31"))
8738 {
071436c6 8739 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8740 continue;
8741 }
8742
8743 prelval >>= 1;
8744 }
8745 else
74e1a04b
NC
8746 {
8747 /* This function currently only supports ARM and TI unwinders. */
8748 warn (_("Only TI and ARM unwinders are currently supported\n"));
8749 break;
8750 }
fa197c1c 8751
0b6ae522
DJ
8752 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8753 addr->section = sym->st_shndx;
8754 addr->offset = offset;
74e1a04b 8755
1b31d05e
NC
8756 if (sym_name)
8757 * sym_name = sym->st_name;
0b6ae522
DJ
8758 break;
8759 }
8760
8761 *wordp = word;
8762 arm_sec->next_rela = rp;
8763
a734115a 8764 return TRUE;
0b6ae522
DJ
8765}
8766
a734115a
NC
8767static const char *tic6x_unwind_regnames[16] =
8768{
0b4362b0
RM
8769 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8770 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8771 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8772};
fa197c1c 8773
0b6ae522 8774static void
fa197c1c 8775decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8776{
fa197c1c
PB
8777 int i;
8778
8779 for (i = 12; mask; mask >>= 1, i--)
8780 {
8781 if (mask & 1)
8782 {
8783 fputs (tic6x_unwind_regnames[i], stdout);
8784 if (mask > 1)
8785 fputs (", ", stdout);
8786 }
8787 }
8788}
0b6ae522
DJ
8789
8790#define ADVANCE \
8791 if (remaining == 0 && more_words) \
8792 { \
8793 data_offset += 4; \
dda8d76d 8794 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8795 data_offset, & word, & addr, NULL)) \
32ec8896 8796 return FALSE; \
0b6ae522
DJ
8797 remaining = 4; \
8798 more_words--; \
8799 } \
8800
8801#define GET_OP(OP) \
8802 ADVANCE; \
8803 if (remaining) \
8804 { \
8805 remaining--; \
8806 (OP) = word >> 24; \
8807 word <<= 8; \
8808 } \
8809 else \
8810 { \
2b692964 8811 printf (_("[Truncated opcode]\n")); \
32ec8896 8812 return FALSE; \
0b6ae522 8813 } \
cc5914eb 8814 printf ("0x%02x ", OP)
0b6ae522 8815
32ec8896 8816static bfd_boolean
dda8d76d
NC
8817decode_arm_unwind_bytecode (Filedata * filedata,
8818 struct arm_unw_aux_info * aux,
948f632f
DA
8819 unsigned int word,
8820 unsigned int remaining,
8821 unsigned int more_words,
8822 bfd_vma data_offset,
8823 Elf_Internal_Shdr * data_sec,
8824 struct arm_section * data_arm_sec)
fa197c1c
PB
8825{
8826 struct absaddr addr;
32ec8896 8827 bfd_boolean res = TRUE;
0b6ae522
DJ
8828
8829 /* Decode the unwinding instructions. */
8830 while (1)
8831 {
8832 unsigned int op, op2;
8833
8834 ADVANCE;
8835 if (remaining == 0)
8836 break;
8837 remaining--;
8838 op = word >> 24;
8839 word <<= 8;
8840
cc5914eb 8841 printf (" 0x%02x ", op);
0b6ae522
DJ
8842
8843 if ((op & 0xc0) == 0x00)
8844 {
8845 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8846
cc5914eb 8847 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8848 }
8849 else if ((op & 0xc0) == 0x40)
8850 {
8851 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8852
cc5914eb 8853 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8854 }
8855 else if ((op & 0xf0) == 0x80)
8856 {
8857 GET_OP (op2);
8858 if (op == 0x80 && op2 == 0)
8859 printf (_("Refuse to unwind"));
8860 else
8861 {
8862 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8863 bfd_boolean first = TRUE;
0b6ae522 8864 int i;
2b692964 8865
0b6ae522
DJ
8866 printf ("pop {");
8867 for (i = 0; i < 12; i++)
8868 if (mask & (1 << i))
8869 {
8870 if (first)
32ec8896 8871 first = FALSE;
0b6ae522
DJ
8872 else
8873 printf (", ");
8874 printf ("r%d", 4 + i);
8875 }
8876 printf ("}");
8877 }
8878 }
8879 else if ((op & 0xf0) == 0x90)
8880 {
8881 if (op == 0x9d || op == 0x9f)
8882 printf (_(" [Reserved]"));
8883 else
cc5914eb 8884 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
8885 }
8886 else if ((op & 0xf0) == 0xa0)
8887 {
8888 int end = 4 + (op & 0x07);
32ec8896 8889 bfd_boolean first = TRUE;
0b6ae522 8890 int i;
61865e30 8891
0b6ae522
DJ
8892 printf (" pop {");
8893 for (i = 4; i <= end; i++)
8894 {
8895 if (first)
32ec8896 8896 first = FALSE;
0b6ae522
DJ
8897 else
8898 printf (", ");
8899 printf ("r%d", i);
8900 }
8901 if (op & 0x08)
8902 {
1b31d05e 8903 if (!first)
0b6ae522
DJ
8904 printf (", ");
8905 printf ("r14");
8906 }
8907 printf ("}");
8908 }
8909 else if (op == 0xb0)
8910 printf (_(" finish"));
8911 else if (op == 0xb1)
8912 {
8913 GET_OP (op2);
8914 if (op2 == 0 || (op2 & 0xf0) != 0)
8915 printf (_("[Spare]"));
8916 else
8917 {
8918 unsigned int mask = op2 & 0x0f;
32ec8896 8919 bfd_boolean first = TRUE;
0b6ae522 8920 int i;
61865e30 8921
0b6ae522
DJ
8922 printf ("pop {");
8923 for (i = 0; i < 12; i++)
8924 if (mask & (1 << i))
8925 {
8926 if (first)
32ec8896 8927 first = FALSE;
0b6ae522
DJ
8928 else
8929 printf (", ");
8930 printf ("r%d", i);
8931 }
8932 printf ("}");
8933 }
8934 }
8935 else if (op == 0xb2)
8936 {
b115cf96 8937 unsigned char buf[9];
0b6ae522
DJ
8938 unsigned int i, len;
8939 unsigned long offset;
61865e30 8940
b115cf96 8941 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
8942 {
8943 GET_OP (buf[i]);
8944 if ((buf[i] & 0x80) == 0)
8945 break;
8946 }
4082ef84 8947 if (i == sizeof (buf))
32ec8896 8948 {
27a45f42 8949 error (_("corrupt change to vsp\n"));
32ec8896
NC
8950 res = FALSE;
8951 }
4082ef84
NC
8952 else
8953 {
cd30bcef 8954 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
8955 assert (len == i + 1);
8956 offset = offset * 4 + 0x204;
8957 printf ("vsp = vsp + %ld", offset);
8958 }
0b6ae522 8959 }
61865e30 8960 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 8961 {
61865e30
NC
8962 unsigned int first, last;
8963
8964 GET_OP (op2);
8965 first = op2 >> 4;
8966 last = op2 & 0x0f;
8967 if (op == 0xc8)
8968 first = first + 16;
8969 printf ("pop {D%d", first);
8970 if (last)
8971 printf ("-D%d", first + last);
8972 printf ("}");
8973 }
8974 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
8975 {
8976 unsigned int count = op & 0x07;
8977
8978 printf ("pop {D8");
8979 if (count)
8980 printf ("-D%d", 8 + count);
8981 printf ("}");
8982 }
8983 else if (op >= 0xc0 && op <= 0xc5)
8984 {
8985 unsigned int count = op & 0x07;
8986
8987 printf (" pop {wR10");
8988 if (count)
8989 printf ("-wR%d", 10 + count);
8990 printf ("}");
8991 }
8992 else if (op == 0xc6)
8993 {
8994 unsigned int first, last;
8995
8996 GET_OP (op2);
8997 first = op2 >> 4;
8998 last = op2 & 0x0f;
8999 printf ("pop {wR%d", first);
9000 if (last)
9001 printf ("-wR%d", first + last);
9002 printf ("}");
9003 }
9004 else if (op == 0xc7)
9005 {
9006 GET_OP (op2);
9007 if (op2 == 0 || (op2 & 0xf0) != 0)
9008 printf (_("[Spare]"));
0b6ae522
DJ
9009 else
9010 {
61865e30 9011 unsigned int mask = op2 & 0x0f;
32ec8896 9012 bfd_boolean first = TRUE;
61865e30
NC
9013 int i;
9014
9015 printf ("pop {");
9016 for (i = 0; i < 4; i++)
9017 if (mask & (1 << i))
9018 {
9019 if (first)
32ec8896 9020 first = FALSE;
61865e30
NC
9021 else
9022 printf (", ");
9023 printf ("wCGR%d", i);
9024 }
9025 printf ("}");
0b6ae522
DJ
9026 }
9027 }
61865e30 9028 else
32ec8896
NC
9029 {
9030 printf (_(" [unsupported opcode]"));
9031 res = FALSE;
9032 }
9033
0b6ae522
DJ
9034 printf ("\n");
9035 }
32ec8896
NC
9036
9037 return res;
fa197c1c
PB
9038}
9039
32ec8896 9040static bfd_boolean
dda8d76d
NC
9041decode_tic6x_unwind_bytecode (Filedata * filedata,
9042 struct arm_unw_aux_info * aux,
948f632f
DA
9043 unsigned int word,
9044 unsigned int remaining,
9045 unsigned int more_words,
9046 bfd_vma data_offset,
9047 Elf_Internal_Shdr * data_sec,
9048 struct arm_section * data_arm_sec)
fa197c1c
PB
9049{
9050 struct absaddr addr;
9051
9052 /* Decode the unwinding instructions. */
9053 while (1)
9054 {
9055 unsigned int op, op2;
9056
9057 ADVANCE;
9058 if (remaining == 0)
9059 break;
9060 remaining--;
9061 op = word >> 24;
9062 word <<= 8;
9063
9cf03b7e 9064 printf (" 0x%02x ", op);
fa197c1c
PB
9065
9066 if ((op & 0xc0) == 0x00)
9067 {
9068 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9069 printf (" sp = sp + %d", offset);
fa197c1c
PB
9070 }
9071 else if ((op & 0xc0) == 0x80)
9072 {
9073 GET_OP (op2);
9074 if (op == 0x80 && op2 == 0)
9075 printf (_("Refuse to unwind"));
9076 else
9077 {
9078 unsigned int mask = ((op & 0x1f) << 8) | op2;
9079 if (op & 0x20)
9080 printf ("pop compact {");
9081 else
9082 printf ("pop {");
9083
9084 decode_tic6x_unwind_regmask (mask);
9085 printf("}");
9086 }
9087 }
9088 else if ((op & 0xf0) == 0xc0)
9089 {
9090 unsigned int reg;
9091 unsigned int nregs;
9092 unsigned int i;
9093 const char *name;
a734115a
NC
9094 struct
9095 {
32ec8896
NC
9096 unsigned int offset;
9097 unsigned int reg;
fa197c1c
PB
9098 } regpos[16];
9099
9100 /* Scan entire instruction first so that GET_OP output is not
9101 interleaved with disassembly. */
9102 nregs = 0;
9103 for (i = 0; nregs < (op & 0xf); i++)
9104 {
9105 GET_OP (op2);
9106 reg = op2 >> 4;
9107 if (reg != 0xf)
9108 {
9109 regpos[nregs].offset = i * 2;
9110 regpos[nregs].reg = reg;
9111 nregs++;
9112 }
9113
9114 reg = op2 & 0xf;
9115 if (reg != 0xf)
9116 {
9117 regpos[nregs].offset = i * 2 + 1;
9118 regpos[nregs].reg = reg;
9119 nregs++;
9120 }
9121 }
9122
9123 printf (_("pop frame {"));
18344509 9124 if (nregs == 0)
fa197c1c 9125 {
18344509
NC
9126 printf (_("*corrupt* - no registers specified"));
9127 }
9128 else
9129 {
9130 reg = nregs - 1;
9131 for (i = i * 2; i > 0; i--)
fa197c1c 9132 {
18344509
NC
9133 if (regpos[reg].offset == i - 1)
9134 {
9135 name = tic6x_unwind_regnames[regpos[reg].reg];
9136 if (reg > 0)
9137 reg--;
9138 }
9139 else
9140 name = _("[pad]");
fa197c1c 9141
18344509
NC
9142 fputs (name, stdout);
9143 if (i > 1)
9144 printf (", ");
9145 }
fa197c1c
PB
9146 }
9147
9148 printf ("}");
9149 }
9150 else if (op == 0xd0)
9151 printf (" MOV FP, SP");
9152 else if (op == 0xd1)
9153 printf (" __c6xabi_pop_rts");
9154 else if (op == 0xd2)
9155 {
9156 unsigned char buf[9];
9157 unsigned int i, len;
9158 unsigned long offset;
a734115a 9159
fa197c1c
PB
9160 for (i = 0; i < sizeof (buf); i++)
9161 {
9162 GET_OP (buf[i]);
9163 if ((buf[i] & 0x80) == 0)
9164 break;
9165 }
0eff7165
NC
9166 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9167 if (i == sizeof (buf))
9168 {
0eff7165 9169 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9170 return FALSE;
0eff7165 9171 }
948f632f 9172
cd30bcef 9173 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9174 assert (len == i + 1);
9175 offset = offset * 8 + 0x408;
9176 printf (_("sp = sp + %ld"), offset);
9177 }
9178 else if ((op & 0xf0) == 0xe0)
9179 {
9180 if ((op & 0x0f) == 7)
9181 printf (" RETURN");
9182 else
9183 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9184 }
9185 else
9186 {
9187 printf (_(" [unsupported opcode]"));
9188 }
9189 putchar ('\n');
9190 }
32ec8896
NC
9191
9192 return TRUE;
fa197c1c
PB
9193}
9194
9195static bfd_vma
dda8d76d 9196arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9197{
9198 bfd_vma offset;
9199
9200 offset = word & 0x7fffffff;
9201 if (offset & 0x40000000)
9202 offset |= ~ (bfd_vma) 0x7fffffff;
9203
dda8d76d 9204 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9205 offset <<= 1;
9206
9207 return offset + where;
9208}
9209
32ec8896 9210static bfd_boolean
dda8d76d
NC
9211decode_arm_unwind (Filedata * filedata,
9212 struct arm_unw_aux_info * aux,
1b31d05e
NC
9213 unsigned int word,
9214 unsigned int remaining,
9215 bfd_vma data_offset,
9216 Elf_Internal_Shdr * data_sec,
9217 struct arm_section * data_arm_sec)
fa197c1c
PB
9218{
9219 int per_index;
9220 unsigned int more_words = 0;
37e14bc3 9221 struct absaddr addr;
1b31d05e 9222 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9223 bfd_boolean res = TRUE;
fa197c1c
PB
9224
9225 if (remaining == 0)
9226 {
1b31d05e
NC
9227 /* Fetch the first word.
9228 Note - when decoding an object file the address extracted
9229 here will always be 0. So we also pass in the sym_name
9230 parameter so that we can find the symbol associated with
9231 the personality routine. */
dda8d76d 9232 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9233 & word, & addr, & sym_name))
32ec8896 9234 return FALSE;
1b31d05e 9235
fa197c1c
PB
9236 remaining = 4;
9237 }
c93dbb25
CZ
9238 else
9239 {
9240 addr.section = SHN_UNDEF;
9241 addr.offset = 0;
9242 }
fa197c1c
PB
9243
9244 if ((word & 0x80000000) == 0)
9245 {
9246 /* Expand prel31 for personality routine. */
9247 bfd_vma fn;
9248 const char *procname;
9249
dda8d76d 9250 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9251 printf (_(" Personality routine: "));
1b31d05e
NC
9252 if (fn == 0
9253 && addr.section == SHN_UNDEF && addr.offset == 0
9254 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9255 {
9256 procname = aux->strtab + sym_name;
9257 print_vma (fn, PREFIX_HEX);
9258 if (procname)
9259 {
9260 fputs (" <", stdout);
9261 fputs (procname, stdout);
9262 fputc ('>', stdout);
9263 }
9264 }
9265 else
dda8d76d 9266 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9267 fputc ('\n', stdout);
9268
9269 /* The GCC personality routines use the standard compact
9270 encoding, starting with one byte giving the number of
9271 words. */
9272 if (procname != NULL
9273 && (const_strneq (procname, "__gcc_personality_v0")
9274 || const_strneq (procname, "__gxx_personality_v0")
9275 || const_strneq (procname, "__gcj_personality_v0")
9276 || const_strneq (procname, "__gnu_objc_personality_v0")))
9277 {
9278 remaining = 0;
9279 more_words = 1;
9280 ADVANCE;
9281 if (!remaining)
9282 {
9283 printf (_(" [Truncated data]\n"));
32ec8896 9284 return FALSE;
fa197c1c
PB
9285 }
9286 more_words = word >> 24;
9287 word <<= 8;
9288 remaining--;
9289 per_index = -1;
9290 }
9291 else
32ec8896 9292 return TRUE;
fa197c1c
PB
9293 }
9294 else
9295 {
1b31d05e 9296 /* ARM EHABI Section 6.3:
0b4362b0 9297
1b31d05e 9298 An exception-handling table entry for the compact model looks like:
0b4362b0 9299
1b31d05e
NC
9300 31 30-28 27-24 23-0
9301 -- ----- ----- ----
9302 1 0 index Data for personalityRoutine[index] */
9303
dda8d76d 9304 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9305 && (word & 0x70000000))
32ec8896
NC
9306 {
9307 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9308 res = FALSE;
9309 }
1b31d05e 9310
fa197c1c 9311 per_index = (word >> 24) & 0x7f;
1b31d05e 9312 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9313 if (per_index == 0)
9314 {
9315 more_words = 0;
9316 word <<= 8;
9317 remaining--;
9318 }
9319 else if (per_index < 3)
9320 {
9321 more_words = (word >> 16) & 0xff;
9322 word <<= 16;
9323 remaining -= 2;
9324 }
9325 }
9326
dda8d76d 9327 switch (filedata->file_header.e_machine)
fa197c1c
PB
9328 {
9329 case EM_ARM:
9330 if (per_index < 3)
9331 {
dda8d76d 9332 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9333 data_offset, data_sec, data_arm_sec))
9334 res = FALSE;
fa197c1c
PB
9335 }
9336 else
1b31d05e
NC
9337 {
9338 warn (_("Unknown ARM compact model index encountered\n"));
9339 printf (_(" [reserved]\n"));
32ec8896 9340 res = FALSE;
1b31d05e 9341 }
fa197c1c
PB
9342 break;
9343
9344 case EM_TI_C6000:
9345 if (per_index < 3)
9346 {
dda8d76d 9347 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9348 data_offset, data_sec, data_arm_sec))
9349 res = FALSE;
fa197c1c
PB
9350 }
9351 else if (per_index < 5)
9352 {
9353 if (((word >> 17) & 0x7f) == 0x7f)
9354 printf (_(" Restore stack from frame pointer\n"));
9355 else
9356 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9357 printf (_(" Registers restored: "));
9358 if (per_index == 4)
9359 printf (" (compact) ");
9360 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9361 putchar ('\n');
9362 printf (_(" Return register: %s\n"),
9363 tic6x_unwind_regnames[word & 0xf]);
9364 }
9365 else
1b31d05e 9366 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9367 break;
9368
9369 default:
74e1a04b 9370 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9371 filedata->file_header.e_machine);
32ec8896 9372 res = FALSE;
fa197c1c 9373 }
0b6ae522
DJ
9374
9375 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9376
9377 return res;
0b6ae522
DJ
9378}
9379
32ec8896 9380static bfd_boolean
dda8d76d
NC
9381dump_arm_unwind (Filedata * filedata,
9382 struct arm_unw_aux_info * aux,
9383 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9384{
9385 struct arm_section exidx_arm_sec, extab_arm_sec;
9386 unsigned int i, exidx_len;
948f632f 9387 unsigned long j, nfuns;
32ec8896 9388 bfd_boolean res = TRUE;
0b6ae522
DJ
9389
9390 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9391 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9392 exidx_len = exidx_sec->sh_size / 8;
9393
948f632f
DA
9394 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9395 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9396 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9397 aux->funtab[nfuns++] = aux->symtab[j];
9398 aux->nfuns = nfuns;
9399 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9400
0b6ae522
DJ
9401 for (i = 0; i < exidx_len; i++)
9402 {
9403 unsigned int exidx_fn, exidx_entry;
9404 struct absaddr fn_addr, entry_addr;
9405 bfd_vma fn;
9406
9407 fputc ('\n', stdout);
9408
dda8d76d 9409 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9410 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9411 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9412 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9413 {
948f632f 9414 free (aux->funtab);
1b31d05e
NC
9415 arm_free_section (& exidx_arm_sec);
9416 arm_free_section (& extab_arm_sec);
32ec8896 9417 return FALSE;
0b6ae522
DJ
9418 }
9419
83c257ca
NC
9420 /* ARM EHABI, Section 5:
9421 An index table entry consists of 2 words.
9422 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9423 if (exidx_fn & 0x80000000)
32ec8896
NC
9424 {
9425 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9426 res = FALSE;
9427 }
83c257ca 9428
dda8d76d 9429 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9430
dda8d76d 9431 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9432 fputs (": ", stdout);
9433
9434 if (exidx_entry == 1)
9435 {
9436 print_vma (exidx_entry, PREFIX_HEX);
9437 fputs (" [cantunwind]\n", stdout);
9438 }
9439 else if (exidx_entry & 0x80000000)
9440 {
9441 print_vma (exidx_entry, PREFIX_HEX);
9442 fputc ('\n', stdout);
dda8d76d 9443 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9444 }
9445 else
9446 {
8f73510c 9447 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9448 Elf_Internal_Shdr *table_sec;
9449
9450 fputs ("@", stdout);
dda8d76d 9451 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9452 print_vma (table, PREFIX_HEX);
9453 printf ("\n");
9454
9455 /* Locate the matching .ARM.extab. */
9456 if (entry_addr.section != SHN_UNDEF
dda8d76d 9457 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9458 {
dda8d76d 9459 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9460 table_offset = entry_addr.offset;
1a915552
NC
9461 /* PR 18879 */
9462 if (table_offset > table_sec->sh_size
9463 || ((bfd_signed_vma) table_offset) < 0)
9464 {
9465 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9466 (unsigned long) table_offset,
dda8d76d 9467 printable_section_name (filedata, table_sec));
32ec8896 9468 res = FALSE;
1a915552
NC
9469 continue;
9470 }
0b6ae522
DJ
9471 }
9472 else
9473 {
dda8d76d 9474 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9475 if (table_sec != NULL)
9476 table_offset = table - table_sec->sh_addr;
9477 }
32ec8896 9478
0b6ae522
DJ
9479 if (table_sec == NULL)
9480 {
9481 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9482 (unsigned long) table);
32ec8896 9483 res = FALSE;
0b6ae522
DJ
9484 continue;
9485 }
32ec8896 9486
dda8d76d 9487 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9488 &extab_arm_sec))
9489 res = FALSE;
0b6ae522
DJ
9490 }
9491 }
9492
9493 printf ("\n");
9494
948f632f 9495 free (aux->funtab);
0b6ae522
DJ
9496 arm_free_section (&exidx_arm_sec);
9497 arm_free_section (&extab_arm_sec);
32ec8896
NC
9498
9499 return res;
0b6ae522
DJ
9500}
9501
fa197c1c 9502/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9503
32ec8896 9504static bfd_boolean
dda8d76d 9505arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9506{
9507 struct arm_unw_aux_info aux;
9508 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9509 Elf_Internal_Shdr *sec;
9510 unsigned long i;
fa197c1c 9511 unsigned int sec_type;
32ec8896 9512 bfd_boolean res = TRUE;
0b6ae522 9513
dda8d76d 9514 switch (filedata->file_header.e_machine)
fa197c1c
PB
9515 {
9516 case EM_ARM:
9517 sec_type = SHT_ARM_EXIDX;
9518 break;
9519
9520 case EM_TI_C6000:
9521 sec_type = SHT_C6000_UNWIND;
9522 break;
9523
0b4362b0 9524 default:
74e1a04b 9525 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9526 filedata->file_header.e_machine);
32ec8896 9527 return FALSE;
fa197c1c
PB
9528 }
9529
dda8d76d 9530 if (filedata->string_table == NULL)
32ec8896 9531 return FALSE;
1b31d05e
NC
9532
9533 memset (& aux, 0, sizeof (aux));
dda8d76d 9534 aux.filedata = filedata;
0b6ae522 9535
dda8d76d 9536 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9537 {
28d13567 9538 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9539 {
28d13567 9540 if (aux.symtab)
74e1a04b 9541 {
28d13567
AM
9542 error (_("Multiple symbol tables encountered\n"));
9543 free (aux.symtab);
9544 aux.symtab = NULL;
74e1a04b 9545 free (aux.strtab);
28d13567 9546 aux.strtab = NULL;
74e1a04b 9547 }
28d13567
AM
9548 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9549 &aux.strtab, &aux.strtab_size))
9550 return FALSE;
0b6ae522 9551 }
fa197c1c 9552 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9553 unwsec = sec;
9554 }
9555
1b31d05e 9556 if (unwsec == NULL)
0b6ae522 9557 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9558 else
dda8d76d 9559 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9560 {
9561 if (sec->sh_type == sec_type)
9562 {
d3a49aa8
AM
9563 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9564 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9565 "contains %lu entry:\n",
9566 "\nUnwind section '%s' at offset 0x%lx "
9567 "contains %lu entries:\n",
9568 num_unwind),
dda8d76d 9569 printable_section_name (filedata, sec),
1b31d05e 9570 (unsigned long) sec->sh_offset,
d3a49aa8 9571 num_unwind);
0b6ae522 9572
dda8d76d 9573 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9574 res = FALSE;
1b31d05e
NC
9575 }
9576 }
0b6ae522 9577
9db70fc3
AM
9578 free (aux.symtab);
9579 free ((char *) aux.strtab);
32ec8896
NC
9580
9581 return res;
0b6ae522
DJ
9582}
9583
32ec8896 9584static bfd_boolean
dda8d76d 9585process_unwind (Filedata * filedata)
57346661 9586{
2cf0635d
NC
9587 struct unwind_handler
9588 {
32ec8896 9589 unsigned int machtype;
dda8d76d 9590 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9591 } handlers[] =
9592 {
0b6ae522 9593 { EM_ARM, arm_process_unwind },
57346661
AM
9594 { EM_IA_64, ia64_process_unwind },
9595 { EM_PARISC, hppa_process_unwind },
fa197c1c 9596 { EM_TI_C6000, arm_process_unwind },
32ec8896 9597 { 0, NULL }
57346661
AM
9598 };
9599 int i;
9600
9601 if (!do_unwind)
32ec8896 9602 return TRUE;
57346661
AM
9603
9604 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9605 if (filedata->file_header.e_machine == handlers[i].machtype)
9606 return handlers[i].handler (filedata);
57346661 9607
1b31d05e 9608 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9609 get_machine_name (filedata->file_header.e_machine));
32ec8896 9610 return TRUE;
57346661
AM
9611}
9612
37c18eed
SD
9613static void
9614dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9615{
9616 switch (entry->d_tag)
9617 {
9618 case DT_AARCH64_BTI_PLT:
1dbade74 9619 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9620 break;
9621 default:
9622 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9623 break;
9624 }
9625 putchar ('\n');
9626}
9627
252b5132 9628static void
978c4450 9629dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9630{
9631 switch (entry->d_tag)
9632 {
9633 case DT_MIPS_FLAGS:
9634 if (entry->d_un.d_val == 0)
4b68bca3 9635 printf (_("NONE"));
252b5132
RH
9636 else
9637 {
9638 static const char * opts[] =
9639 {
9640 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9641 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9642 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9643 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9644 "RLD_ORDER_SAFE"
9645 };
9646 unsigned int cnt;
32ec8896 9647 bfd_boolean first = TRUE;
2b692964 9648
60bca95a 9649 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9650 if (entry->d_un.d_val & (1 << cnt))
9651 {
9652 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9653 first = FALSE;
252b5132 9654 }
252b5132
RH
9655 }
9656 break;
103f02d3 9657
252b5132 9658 case DT_MIPS_IVERSION:
978c4450
AM
9659 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9660 printf (_("Interface Version: %s"),
9661 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9662 else
76ca31c0
NC
9663 {
9664 char buf[40];
9665 sprintf_vma (buf, entry->d_un.d_ptr);
9666 /* Note: coded this way so that there is a single string for translation. */
9667 printf (_("<corrupt: %s>"), buf);
9668 }
252b5132 9669 break;
103f02d3 9670
252b5132
RH
9671 case DT_MIPS_TIME_STAMP:
9672 {
d5b07ef4 9673 char timebuf[128];
2cf0635d 9674 struct tm * tmp;
91d6fa6a 9675 time_t atime = entry->d_un.d_val;
82b1b41b 9676
91d6fa6a 9677 tmp = gmtime (&atime);
82b1b41b
NC
9678 /* PR 17531: file: 6accc532. */
9679 if (tmp == NULL)
9680 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9681 else
9682 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9683 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9684 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9685 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9686 }
9687 break;
103f02d3 9688
252b5132
RH
9689 case DT_MIPS_RLD_VERSION:
9690 case DT_MIPS_LOCAL_GOTNO:
9691 case DT_MIPS_CONFLICTNO:
9692 case DT_MIPS_LIBLISTNO:
9693 case DT_MIPS_SYMTABNO:
9694 case DT_MIPS_UNREFEXTNO:
9695 case DT_MIPS_HIPAGENO:
9696 case DT_MIPS_DELTA_CLASS_NO:
9697 case DT_MIPS_DELTA_INSTANCE_NO:
9698 case DT_MIPS_DELTA_RELOC_NO:
9699 case DT_MIPS_DELTA_SYM_NO:
9700 case DT_MIPS_DELTA_CLASSSYM_NO:
9701 case DT_MIPS_COMPACT_SIZE:
c69075ac 9702 print_vma (entry->d_un.d_val, DEC);
252b5132 9703 break;
103f02d3 9704
f16a9783 9705 case DT_MIPS_XHASH:
978c4450
AM
9706 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9707 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9708 /* Falls through. */
9709
103f02d3 9710 default:
4b68bca3 9711 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9712 }
4b68bca3 9713 putchar ('\n');
103f02d3
UD
9714}
9715
103f02d3 9716static void
2cf0635d 9717dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9718{
9719 switch (entry->d_tag)
9720 {
9721 case DT_HP_DLD_FLAGS:
9722 {
9723 static struct
9724 {
9725 long int bit;
2cf0635d 9726 const char * str;
5e220199
NC
9727 }
9728 flags[] =
9729 {
9730 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9731 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9732 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9733 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9734 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9735 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9736 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9737 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9738 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9739 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9740 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9741 { DT_HP_GST, "HP_GST" },
9742 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9743 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9744 { DT_HP_NODELETE, "HP_NODELETE" },
9745 { DT_HP_GROUP, "HP_GROUP" },
9746 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9747 };
32ec8896 9748 bfd_boolean first = TRUE;
5e220199 9749 size_t cnt;
f7a99963 9750 bfd_vma val = entry->d_un.d_val;
103f02d3 9751
60bca95a 9752 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9753 if (val & flags[cnt].bit)
30800947
NC
9754 {
9755 if (! first)
9756 putchar (' ');
9757 fputs (flags[cnt].str, stdout);
32ec8896 9758 first = FALSE;
30800947
NC
9759 val ^= flags[cnt].bit;
9760 }
76da6bbe 9761
103f02d3 9762 if (val != 0 || first)
f7a99963
NC
9763 {
9764 if (! first)
9765 putchar (' ');
9766 print_vma (val, HEX);
9767 }
103f02d3
UD
9768 }
9769 break;
76da6bbe 9770
252b5132 9771 default:
f7a99963
NC
9772 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9773 break;
252b5132 9774 }
35b1837e 9775 putchar ('\n');
252b5132
RH
9776}
9777
28f997cf
TG
9778#ifdef BFD64
9779
9780/* VMS vs Unix time offset and factor. */
9781
9782#define VMS_EPOCH_OFFSET 35067168000000000LL
9783#define VMS_GRANULARITY_FACTOR 10000000
9784
9785/* Display a VMS time in a human readable format. */
9786
9787static void
9788print_vms_time (bfd_int64_t vmstime)
9789{
9790 struct tm *tm;
9791 time_t unxtime;
9792
9793 unxtime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9794 tm = gmtime (&unxtime);
9795 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9796 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9797 tm->tm_hour, tm->tm_min, tm->tm_sec);
9798}
9799#endif /* BFD64 */
9800
ecc51f48 9801static void
2cf0635d 9802dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9803{
9804 switch (entry->d_tag)
9805 {
0de14b54 9806 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9807 /* First 3 slots reserved. */
ecc51f48
NC
9808 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9809 printf (" -- ");
9810 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9811 break;
9812
28f997cf
TG
9813 case DT_IA_64_VMS_LINKTIME:
9814#ifdef BFD64
9815 print_vms_time (entry->d_un.d_val);
9816#endif
9817 break;
9818
9819 case DT_IA_64_VMS_LNKFLAGS:
9820 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9821 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9822 printf (" CALL_DEBUG");
9823 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9824 printf (" NOP0BUFS");
9825 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9826 printf (" P0IMAGE");
9827 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9828 printf (" MKTHREADS");
9829 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9830 printf (" UPCALLS");
9831 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9832 printf (" IMGSTA");
9833 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9834 printf (" INITIALIZE");
9835 if (entry->d_un.d_val & VMS_LF_MAIN)
9836 printf (" MAIN");
9837 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9838 printf (" EXE_INIT");
9839 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9840 printf (" TBK_IN_IMG");
9841 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9842 printf (" DBG_IN_IMG");
9843 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9844 printf (" TBK_IN_DSF");
9845 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9846 printf (" DBG_IN_DSF");
9847 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9848 printf (" SIGNATURES");
9849 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9850 printf (" REL_SEG_OFF");
9851 break;
9852
bdf4d63a
JJ
9853 default:
9854 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9855 break;
ecc51f48 9856 }
bdf4d63a 9857 putchar ('\n');
ecc51f48
NC
9858}
9859
32ec8896 9860static bfd_boolean
dda8d76d 9861get_32bit_dynamic_section (Filedata * filedata)
252b5132 9862{
2cf0635d
NC
9863 Elf32_External_Dyn * edyn;
9864 Elf32_External_Dyn * ext;
9865 Elf_Internal_Dyn * entry;
103f02d3 9866
978c4450
AM
9867 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
9868 filedata->dynamic_addr, 1,
9869 filedata->dynamic_size,
9870 _("dynamic section"));
a6e9f9df 9871 if (!edyn)
32ec8896 9872 return FALSE;
103f02d3 9873
071436c6
NC
9874 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9875 might not have the luxury of section headers. Look for the DT_NULL
9876 terminator to determine the number of entries. */
978c4450
AM
9877 for (ext = edyn, filedata->dynamic_nent = 0;
9878 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9879 ext++)
9880 {
978c4450 9881 filedata->dynamic_nent++;
ba2685cc
AM
9882 if (BYTE_GET (ext->d_tag) == DT_NULL)
9883 break;
9884 }
252b5132 9885
978c4450
AM
9886 filedata->dynamic_section
9887 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9888 if (filedata->dynamic_section == NULL)
252b5132 9889 {
8b73c356 9890 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9891 (unsigned long) filedata->dynamic_nent);
9ea033b2 9892 free (edyn);
32ec8896 9893 return FALSE;
9ea033b2 9894 }
252b5132 9895
978c4450
AM
9896 for (ext = edyn, entry = filedata->dynamic_section;
9897 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9898 ext++, entry++)
9ea033b2 9899 {
fb514b26
AM
9900 entry->d_tag = BYTE_GET (ext->d_tag);
9901 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9902 }
9903
9ea033b2
NC
9904 free (edyn);
9905
32ec8896 9906 return TRUE;
9ea033b2
NC
9907}
9908
32ec8896 9909static bfd_boolean
dda8d76d 9910get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 9911{
2cf0635d
NC
9912 Elf64_External_Dyn * edyn;
9913 Elf64_External_Dyn * ext;
9914 Elf_Internal_Dyn * entry;
103f02d3 9915
071436c6 9916 /* Read in the data. */
978c4450
AM
9917 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
9918 filedata->dynamic_addr, 1,
9919 filedata->dynamic_size,
9920 _("dynamic section"));
a6e9f9df 9921 if (!edyn)
32ec8896 9922 return FALSE;
103f02d3 9923
071436c6
NC
9924 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
9925 might not have the luxury of section headers. Look for the DT_NULL
9926 terminator to determine the number of entries. */
978c4450 9927 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 9928 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 9929 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
9930 ext++)
9931 {
978c4450 9932 filedata->dynamic_nent++;
66543521 9933 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
9934 break;
9935 }
252b5132 9936
978c4450
AM
9937 filedata->dynamic_section
9938 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
9939 if (filedata->dynamic_section == NULL)
252b5132 9940 {
8b73c356 9941 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 9942 (unsigned long) filedata->dynamic_nent);
252b5132 9943 free (edyn);
32ec8896 9944 return FALSE;
252b5132
RH
9945 }
9946
071436c6 9947 /* Convert from external to internal formats. */
978c4450
AM
9948 for (ext = edyn, entry = filedata->dynamic_section;
9949 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 9950 ext++, entry++)
252b5132 9951 {
66543521
AM
9952 entry->d_tag = BYTE_GET (ext->d_tag);
9953 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
9954 }
9955
9956 free (edyn);
9957
32ec8896 9958 return TRUE;
9ea033b2
NC
9959}
9960
e9e44622
JJ
9961static void
9962print_dynamic_flags (bfd_vma flags)
d1133906 9963{
32ec8896 9964 bfd_boolean first = TRUE;
13ae64f3 9965
d1133906
NC
9966 while (flags)
9967 {
9968 bfd_vma flag;
9969
9970 flag = flags & - flags;
9971 flags &= ~ flag;
9972
e9e44622 9973 if (first)
32ec8896 9974 first = FALSE;
e9e44622
JJ
9975 else
9976 putc (' ', stdout);
13ae64f3 9977
d1133906
NC
9978 switch (flag)
9979 {
e9e44622
JJ
9980 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
9981 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
9982 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
9983 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
9984 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 9985 default: fputs (_("unknown"), stdout); break;
d1133906
NC
9986 }
9987 }
e9e44622 9988 puts ("");
d1133906
NC
9989}
9990
10ca4b04
L
9991static bfd_vma *
9992get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
9993{
9994 unsigned char * e_data;
9995 bfd_vma * i_data;
9996
9997 /* If the size_t type is smaller than the bfd_size_type, eg because
9998 you are building a 32-bit tool on a 64-bit host, then make sure
9999 that when (number) is cast to (size_t) no information is lost. */
10000 if (sizeof (size_t) < sizeof (bfd_size_type)
10001 && (bfd_size_type) ((size_t) number) != number)
10002 {
10003 error (_("Size truncation prevents reading %s elements of size %u\n"),
10004 bfd_vmatoa ("u", number), ent_size);
10005 return NULL;
10006 }
10007
10008 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10009 attempting to allocate memory when the read is bound to fail. */
10010 if (ent_size * number > filedata->file_size)
10011 {
10012 error (_("Invalid number of dynamic entries: %s\n"),
10013 bfd_vmatoa ("u", number));
10014 return NULL;
10015 }
10016
10017 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10018 if (e_data == NULL)
10019 {
10020 error (_("Out of memory reading %s dynamic entries\n"),
10021 bfd_vmatoa ("u", number));
10022 return NULL;
10023 }
10024
10025 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10026 {
10027 error (_("Unable to read in %s bytes of dynamic data\n"),
10028 bfd_vmatoa ("u", number * ent_size));
10029 free (e_data);
10030 return NULL;
10031 }
10032
10033 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10034 if (i_data == NULL)
10035 {
10036 error (_("Out of memory allocating space for %s dynamic entries\n"),
10037 bfd_vmatoa ("u", number));
10038 free (e_data);
10039 return NULL;
10040 }
10041
10042 while (number--)
10043 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10044
10045 free (e_data);
10046
10047 return i_data;
10048}
10049
10050static unsigned long
10051get_num_dynamic_syms (Filedata * filedata)
10052{
10053 unsigned long num_of_syms = 0;
10054
10055 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10056 return num_of_syms;
10057
978c4450 10058 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10059 {
10060 unsigned char nb[8];
10061 unsigned char nc[8];
10062 unsigned int hash_ent_size = 4;
10063
10064 if ((filedata->file_header.e_machine == EM_ALPHA
10065 || filedata->file_header.e_machine == EM_S390
10066 || filedata->file_header.e_machine == EM_S390_OLD)
10067 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10068 hash_ent_size = 8;
10069
10070 if (fseek (filedata->handle,
978c4450
AM
10071 (filedata->archive_file_offset
10072 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10073 sizeof nb + sizeof nc)),
10074 SEEK_SET))
10075 {
10076 error (_("Unable to seek to start of dynamic information\n"));
10077 goto no_hash;
10078 }
10079
10080 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10081 {
10082 error (_("Failed to read in number of buckets\n"));
10083 goto no_hash;
10084 }
10085
10086 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10087 {
10088 error (_("Failed to read in number of chains\n"));
10089 goto no_hash;
10090 }
10091
978c4450
AM
10092 filedata->nbuckets = byte_get (nb, hash_ent_size);
10093 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10094
2482f306
AM
10095 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10096 {
10097 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10098 hash_ent_size);
10099 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10100 hash_ent_size);
001890e1 10101
2482f306
AM
10102 if (filedata->buckets != NULL && filedata->chains != NULL)
10103 num_of_syms = filedata->nchains;
10104 }
ceb9bf11 10105 no_hash:
10ca4b04
L
10106 if (num_of_syms == 0)
10107 {
9db70fc3
AM
10108 free (filedata->buckets);
10109 filedata->buckets = NULL;
10110 free (filedata->chains);
10111 filedata->chains = NULL;
978c4450 10112 filedata->nbuckets = 0;
10ca4b04
L
10113 }
10114 }
10115
978c4450 10116 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10117 {
10118 unsigned char nb[16];
10119 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10120 bfd_vma buckets_vma;
10121 unsigned long hn;
10ca4b04
L
10122
10123 if (fseek (filedata->handle,
978c4450
AM
10124 (filedata->archive_file_offset
10125 + offset_from_vma (filedata,
10126 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10127 sizeof nb)),
10128 SEEK_SET))
10129 {
10130 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10131 goto no_gnu_hash;
10132 }
10133
10134 if (fread (nb, 16, 1, filedata->handle) != 1)
10135 {
10136 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10137 goto no_gnu_hash;
10138 }
10139
978c4450
AM
10140 filedata->ngnubuckets = byte_get (nb, 4);
10141 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10142 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10143 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10144 if (is_32bit_elf)
10145 buckets_vma += bitmaskwords * 4;
10146 else
10147 buckets_vma += bitmaskwords * 8;
10148
10149 if (fseek (filedata->handle,
978c4450 10150 (filedata->archive_file_offset
10ca4b04
L
10151 + offset_from_vma (filedata, buckets_vma, 4)),
10152 SEEK_SET))
10153 {
10154 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10155 goto no_gnu_hash;
10156 }
10157
978c4450
AM
10158 filedata->gnubuckets
10159 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10160
978c4450 10161 if (filedata->gnubuckets == NULL)
90837ea7 10162 goto no_gnu_hash;
10ca4b04 10163
978c4450
AM
10164 for (i = 0; i < filedata->ngnubuckets; i++)
10165 if (filedata->gnubuckets[i] != 0)
10ca4b04 10166 {
978c4450 10167 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10168 goto no_gnu_hash;
10ca4b04 10169
978c4450
AM
10170 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10171 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10172 }
10173
10174 if (maxchain == 0xffffffff)
90837ea7 10175 goto no_gnu_hash;
10ca4b04 10176
978c4450 10177 maxchain -= filedata->gnusymidx;
10ca4b04
L
10178
10179 if (fseek (filedata->handle,
978c4450
AM
10180 (filedata->archive_file_offset
10181 + offset_from_vma (filedata,
10182 buckets_vma + 4 * (filedata->ngnubuckets
10183 + maxchain),
10184 4)),
10ca4b04
L
10185 SEEK_SET))
10186 {
10187 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10188 goto no_gnu_hash;
10189 }
10190
10191 do
10192 {
10193 if (fread (nb, 4, 1, filedata->handle) != 1)
10194 {
10195 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10196 goto no_gnu_hash;
10197 }
10198
10199 if (maxchain + 1 == 0)
90837ea7 10200 goto no_gnu_hash;
10ca4b04
L
10201
10202 ++maxchain;
10203 }
10204 while ((byte_get (nb, 4) & 1) == 0);
10205
10206 if (fseek (filedata->handle,
978c4450
AM
10207 (filedata->archive_file_offset
10208 + offset_from_vma (filedata, (buckets_vma
10209 + 4 * filedata->ngnubuckets),
10210 4)),
10ca4b04
L
10211 SEEK_SET))
10212 {
10213 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10214 goto no_gnu_hash;
10215 }
10216
978c4450
AM
10217 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10218 filedata->ngnuchains = maxchain;
10ca4b04 10219
978c4450 10220 if (filedata->gnuchains == NULL)
90837ea7 10221 goto no_gnu_hash;
10ca4b04 10222
978c4450 10223 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10224 {
10225 if (fseek (filedata->handle,
978c4450 10226 (filedata->archive_file_offset
10ca4b04 10227 + offset_from_vma (filedata, (buckets_vma
978c4450 10228 + 4 * (filedata->ngnubuckets
10ca4b04
L
10229 + maxchain)), 4)),
10230 SEEK_SET))
10231 {
10232 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10233 goto no_gnu_hash;
10234 }
10235
978c4450 10236 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10237 if (filedata->mipsxlat == NULL)
10238 goto no_gnu_hash;
10ca4b04
L
10239 }
10240
978c4450
AM
10241 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10242 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10243 {
978c4450
AM
10244 bfd_vma si = filedata->gnubuckets[hn];
10245 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10246
10247 do
10248 {
978c4450 10249 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10250 {
c31ab5a0
AM
10251 if (off < filedata->ngnuchains
10252 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10253 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10254 }
10255 else
10256 {
10257 if (si >= num_of_syms)
10258 num_of_syms = si + 1;
10259 }
10260 si++;
10261 }
978c4450
AM
10262 while (off < filedata->ngnuchains
10263 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10264 }
10265
90837ea7 10266 if (num_of_syms == 0)
10ca4b04 10267 {
90837ea7 10268 no_gnu_hash:
9db70fc3
AM
10269 free (filedata->mipsxlat);
10270 filedata->mipsxlat = NULL;
10271 free (filedata->gnuchains);
10272 filedata->gnuchains = NULL;
10273 free (filedata->gnubuckets);
10274 filedata->gnubuckets = NULL;
978c4450
AM
10275 filedata->ngnubuckets = 0;
10276 filedata->ngnuchains = 0;
10ca4b04
L
10277 }
10278 }
10279
10280 return num_of_syms;
10281}
10282
b2d38a17
NC
10283/* Parse and display the contents of the dynamic section. */
10284
32ec8896 10285static bfd_boolean
dda8d76d 10286process_dynamic_section (Filedata * filedata)
9ea033b2 10287{
2cf0635d 10288 Elf_Internal_Dyn * entry;
9ea033b2 10289
978c4450 10290 if (filedata->dynamic_size == 0)
9ea033b2
NC
10291 {
10292 if (do_dynamic)
b2d38a17 10293 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 10294
32ec8896 10295 return TRUE;
9ea033b2
NC
10296 }
10297
10298 if (is_32bit_elf)
10299 {
dda8d76d 10300 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10301 return FALSE;
10302 }
10303 else
10304 {
dda8d76d 10305 if (! get_64bit_dynamic_section (filedata))
32ec8896 10306 return FALSE;
9ea033b2 10307 }
9ea033b2 10308
252b5132 10309 /* Find the appropriate symbol table. */
978c4450 10310 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10311 {
2482f306
AM
10312 unsigned long num_of_syms;
10313
978c4450
AM
10314 for (entry = filedata->dynamic_section;
10315 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10316 ++entry)
10ca4b04 10317 if (entry->d_tag == DT_SYMTAB)
978c4450 10318 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10319 else if (entry->d_tag == DT_SYMENT)
978c4450 10320 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10321 else if (entry->d_tag == DT_HASH)
978c4450 10322 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10323 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10324 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10325 else if ((filedata->file_header.e_machine == EM_MIPS
10326 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10327 && entry->d_tag == DT_MIPS_XHASH)
10328 {
978c4450
AM
10329 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10330 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10331 }
252b5132 10332
2482f306
AM
10333 num_of_syms = get_num_dynamic_syms (filedata);
10334
10335 if (num_of_syms != 0
10336 && filedata->dynamic_symbols == NULL
10337 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10338 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10339 {
10340 Elf_Internal_Phdr *seg;
2482f306 10341 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10342
2482f306
AM
10343 if (! get_program_headers (filedata))
10344 {
10345 error (_("Cannot interpret virtual addresses "
10346 "without program headers.\n"));
10347 return FALSE;
10348 }
252b5132 10349
2482f306
AM
10350 for (seg = filedata->program_headers;
10351 seg < filedata->program_headers + filedata->file_header.e_phnum;
10352 ++seg)
10353 {
10354 if (seg->p_type != PT_LOAD)
10355 continue;
252b5132 10356
2482f306
AM
10357 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10358 {
10359 /* See PR 21379 for a reproducer. */
10360 error (_("Invalid PT_LOAD entry\n"));
10361 return FALSE;
10362 }
252b5132 10363
2482f306
AM
10364 if (vma >= (seg->p_vaddr & -seg->p_align)
10365 && vma < seg->p_vaddr + seg->p_filesz)
10366 {
10367 /* Since we do not know how big the symbol table is,
10368 we default to reading in up to the end of PT_LOAD
10369 segment and processing that. This is overkill, I
10370 know, but it should work. */
10371 Elf_Internal_Shdr section;
10372 section.sh_offset = (vma - seg->p_vaddr
10373 + seg->p_offset);
10374 section.sh_size = (num_of_syms
10375 * filedata->dynamic_info[DT_SYMENT]);
10376 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10377
10378 if (do_checks
10379 && filedata->dynamic_symtab_section != NULL
10380 && ((filedata->dynamic_symtab_section->sh_offset
10381 != section.sh_offset)
10382 || (filedata->dynamic_symtab_section->sh_size
10383 != section.sh_size)
10384 || (filedata->dynamic_symtab_section->sh_entsize
10385 != section.sh_entsize)))
10386 warn (_("\
10387the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10388
2482f306
AM
10389 section.sh_name = filedata->string_table_length;
10390 filedata->dynamic_symbols
10391 = GET_ELF_SYMBOLS (filedata, &section,
10392 &filedata->num_dynamic_syms);
10393 if (filedata->dynamic_symbols == NULL
10394 || filedata->num_dynamic_syms != num_of_syms)
10395 {
10396 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10397 return FALSE;
10398 }
10399 break;
10400 }
10401 }
10402 }
10403 }
252b5132
RH
10404
10405 /* Similarly find a string table. */
978c4450
AM
10406 if (filedata->dynamic_strings == NULL)
10407 for (entry = filedata->dynamic_section;
10408 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10409 ++entry)
10410 {
10411 if (entry->d_tag == DT_STRTAB)
978c4450 10412 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10413
10ca4b04 10414 if (entry->d_tag == DT_STRSZ)
978c4450 10415 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10416
978c4450
AM
10417 if (filedata->dynamic_info[DT_STRTAB]
10418 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10419 {
10420 unsigned long offset;
978c4450 10421 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10422
10423 offset = offset_from_vma (filedata,
978c4450 10424 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10425 str_tab_len);
8ac10c5b
L
10426 if (do_checks
10427 && filedata->dynamic_strtab_section
10428 && ((filedata->dynamic_strtab_section->sh_offset
10429 != (file_ptr) offset)
10430 || (filedata->dynamic_strtab_section->sh_size
10431 != str_tab_len)))
10432 warn (_("\
10433the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10434
978c4450
AM
10435 filedata->dynamic_strings
10436 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10437 _("dynamic string table"));
10438 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10439 {
10440 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10441 break;
10442 }
e3d39609 10443
978c4450 10444 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10445 break;
10446 }
10447 }
252b5132
RH
10448
10449 /* And find the syminfo section if available. */
978c4450 10450 if (filedata->dynamic_syminfo == NULL)
252b5132 10451 {
3e8bba36 10452 unsigned long syminsz = 0;
252b5132 10453
978c4450
AM
10454 for (entry = filedata->dynamic_section;
10455 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10456 ++entry)
252b5132
RH
10457 {
10458 if (entry->d_tag == DT_SYMINENT)
10459 {
10460 /* Note: these braces are necessary to avoid a syntax
10461 error from the SunOS4 C compiler. */
049b0c3a
NC
10462 /* PR binutils/17531: A corrupt file can trigger this test.
10463 So do not use an assert, instead generate an error message. */
10464 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10465 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10466 (int) entry->d_un.d_val);
252b5132
RH
10467 }
10468 else if (entry->d_tag == DT_SYMINSZ)
10469 syminsz = entry->d_un.d_val;
10470 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10471 filedata->dynamic_syminfo_offset
10472 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10473 }
10474
978c4450 10475 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10476 {
2cf0635d
NC
10477 Elf_External_Syminfo * extsyminfo;
10478 Elf_External_Syminfo * extsym;
10479 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10480
10481 /* There is a syminfo section. Read the data. */
3f5e193b 10482 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10483 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10484 1, syminsz, _("symbol information"));
a6e9f9df 10485 if (!extsyminfo)
32ec8896 10486 return FALSE;
252b5132 10487
978c4450 10488 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10489 {
10490 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10491 free (filedata->dynamic_syminfo);
e3d39609 10492 }
978c4450
AM
10493 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10494 if (filedata->dynamic_syminfo == NULL)
252b5132 10495 {
2482f306
AM
10496 error (_("Out of memory allocating %lu bytes "
10497 "for dynamic symbol info\n"),
8b73c356 10498 (unsigned long) syminsz);
32ec8896 10499 return FALSE;
252b5132
RH
10500 }
10501
2482f306
AM
10502 filedata->dynamic_syminfo_nent
10503 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10504 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10505 syminfo < (filedata->dynamic_syminfo
10506 + filedata->dynamic_syminfo_nent);
86dba8ee 10507 ++syminfo, ++extsym)
252b5132 10508 {
86dba8ee
AM
10509 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10510 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10511 }
10512
10513 free (extsyminfo);
10514 }
10515 }
10516
978c4450 10517 if (do_dynamic && filedata->dynamic_addr)
d3a49aa8
AM
10518 printf (ngettext ("\nDynamic section at offset 0x%lx "
10519 "contains %lu entry:\n",
10520 "\nDynamic section at offset 0x%lx "
10521 "contains %lu entries:\n",
978c4450
AM
10522 filedata->dynamic_nent),
10523 filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent);
252b5132
RH
10524 if (do_dynamic)
10525 printf (_(" Tag Type Name/Value\n"));
10526
978c4450
AM
10527 for (entry = filedata->dynamic_section;
10528 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10529 entry++)
252b5132
RH
10530 {
10531 if (do_dynamic)
f7a99963 10532 {
2cf0635d 10533 const char * dtype;
e699b9ff 10534
f7a99963
NC
10535 putchar (' ');
10536 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10537 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10538 printf (" (%s)%*s", dtype,
32ec8896 10539 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10540 }
252b5132
RH
10541
10542 switch (entry->d_tag)
10543 {
d1133906
NC
10544 case DT_FLAGS:
10545 if (do_dynamic)
e9e44622 10546 print_dynamic_flags (entry->d_un.d_val);
d1133906 10547 break;
76da6bbe 10548
252b5132
RH
10549 case DT_AUXILIARY:
10550 case DT_FILTER:
019148e4
L
10551 case DT_CONFIG:
10552 case DT_DEPAUDIT:
10553 case DT_AUDIT:
252b5132
RH
10554 if (do_dynamic)
10555 {
019148e4 10556 switch (entry->d_tag)
b34976b6 10557 {
019148e4
L
10558 case DT_AUXILIARY:
10559 printf (_("Auxiliary library"));
10560 break;
10561
10562 case DT_FILTER:
10563 printf (_("Filter library"));
10564 break;
10565
b34976b6 10566 case DT_CONFIG:
019148e4
L
10567 printf (_("Configuration file"));
10568 break;
10569
10570 case DT_DEPAUDIT:
10571 printf (_("Dependency audit library"));
10572 break;
10573
10574 case DT_AUDIT:
10575 printf (_("Audit library"));
10576 break;
10577 }
252b5132 10578
978c4450
AM
10579 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10580 printf (": [%s]\n",
10581 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10582 else
f7a99963
NC
10583 {
10584 printf (": ");
10585 print_vma (entry->d_un.d_val, PREFIX_HEX);
10586 putchar ('\n');
10587 }
252b5132
RH
10588 }
10589 break;
10590
dcefbbbd 10591 case DT_FEATURE:
252b5132
RH
10592 if (do_dynamic)
10593 {
10594 printf (_("Flags:"));
86f55779 10595
252b5132
RH
10596 if (entry->d_un.d_val == 0)
10597 printf (_(" None\n"));
10598 else
10599 {
10600 unsigned long int val = entry->d_un.d_val;
86f55779 10601
252b5132
RH
10602 if (val & DTF_1_PARINIT)
10603 {
10604 printf (" PARINIT");
10605 val ^= DTF_1_PARINIT;
10606 }
dcefbbbd
L
10607 if (val & DTF_1_CONFEXP)
10608 {
10609 printf (" CONFEXP");
10610 val ^= DTF_1_CONFEXP;
10611 }
252b5132
RH
10612 if (val != 0)
10613 printf (" %lx", val);
10614 puts ("");
10615 }
10616 }
10617 break;
10618
10619 case DT_POSFLAG_1:
10620 if (do_dynamic)
10621 {
10622 printf (_("Flags:"));
86f55779 10623
252b5132
RH
10624 if (entry->d_un.d_val == 0)
10625 printf (_(" None\n"));
10626 else
10627 {
10628 unsigned long int val = entry->d_un.d_val;
86f55779 10629
252b5132
RH
10630 if (val & DF_P1_LAZYLOAD)
10631 {
10632 printf (" LAZYLOAD");
10633 val ^= DF_P1_LAZYLOAD;
10634 }
10635 if (val & DF_P1_GROUPPERM)
10636 {
10637 printf (" GROUPPERM");
10638 val ^= DF_P1_GROUPPERM;
10639 }
10640 if (val != 0)
10641 printf (" %lx", val);
10642 puts ("");
10643 }
10644 }
10645 break;
10646
10647 case DT_FLAGS_1:
10648 if (do_dynamic)
10649 {
10650 printf (_("Flags:"));
10651 if (entry->d_un.d_val == 0)
10652 printf (_(" None\n"));
10653 else
10654 {
10655 unsigned long int val = entry->d_un.d_val;
86f55779 10656
252b5132
RH
10657 if (val & DF_1_NOW)
10658 {
10659 printf (" NOW");
10660 val ^= DF_1_NOW;
10661 }
10662 if (val & DF_1_GLOBAL)
10663 {
10664 printf (" GLOBAL");
10665 val ^= DF_1_GLOBAL;
10666 }
10667 if (val & DF_1_GROUP)
10668 {
10669 printf (" GROUP");
10670 val ^= DF_1_GROUP;
10671 }
10672 if (val & DF_1_NODELETE)
10673 {
10674 printf (" NODELETE");
10675 val ^= DF_1_NODELETE;
10676 }
10677 if (val & DF_1_LOADFLTR)
10678 {
10679 printf (" LOADFLTR");
10680 val ^= DF_1_LOADFLTR;
10681 }
10682 if (val & DF_1_INITFIRST)
10683 {
10684 printf (" INITFIRST");
10685 val ^= DF_1_INITFIRST;
10686 }
10687 if (val & DF_1_NOOPEN)
10688 {
10689 printf (" NOOPEN");
10690 val ^= DF_1_NOOPEN;
10691 }
10692 if (val & DF_1_ORIGIN)
10693 {
10694 printf (" ORIGIN");
10695 val ^= DF_1_ORIGIN;
10696 }
10697 if (val & DF_1_DIRECT)
10698 {
10699 printf (" DIRECT");
10700 val ^= DF_1_DIRECT;
10701 }
10702 if (val & DF_1_TRANS)
10703 {
10704 printf (" TRANS");
10705 val ^= DF_1_TRANS;
10706 }
10707 if (val & DF_1_INTERPOSE)
10708 {
10709 printf (" INTERPOSE");
10710 val ^= DF_1_INTERPOSE;
10711 }
f7db6139 10712 if (val & DF_1_NODEFLIB)
dcefbbbd 10713 {
f7db6139
L
10714 printf (" NODEFLIB");
10715 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10716 }
10717 if (val & DF_1_NODUMP)
10718 {
10719 printf (" NODUMP");
10720 val ^= DF_1_NODUMP;
10721 }
34b60028 10722 if (val & DF_1_CONFALT)
dcefbbbd 10723 {
34b60028
L
10724 printf (" CONFALT");
10725 val ^= DF_1_CONFALT;
10726 }
10727 if (val & DF_1_ENDFILTEE)
10728 {
10729 printf (" ENDFILTEE");
10730 val ^= DF_1_ENDFILTEE;
10731 }
10732 if (val & DF_1_DISPRELDNE)
10733 {
10734 printf (" DISPRELDNE");
10735 val ^= DF_1_DISPRELDNE;
10736 }
10737 if (val & DF_1_DISPRELPND)
10738 {
10739 printf (" DISPRELPND");
10740 val ^= DF_1_DISPRELPND;
10741 }
10742 if (val & DF_1_NODIRECT)
10743 {
10744 printf (" NODIRECT");
10745 val ^= DF_1_NODIRECT;
10746 }
10747 if (val & DF_1_IGNMULDEF)
10748 {
10749 printf (" IGNMULDEF");
10750 val ^= DF_1_IGNMULDEF;
10751 }
10752 if (val & DF_1_NOKSYMS)
10753 {
10754 printf (" NOKSYMS");
10755 val ^= DF_1_NOKSYMS;
10756 }
10757 if (val & DF_1_NOHDR)
10758 {
10759 printf (" NOHDR");
10760 val ^= DF_1_NOHDR;
10761 }
10762 if (val & DF_1_EDITED)
10763 {
10764 printf (" EDITED");
10765 val ^= DF_1_EDITED;
10766 }
10767 if (val & DF_1_NORELOC)
10768 {
10769 printf (" NORELOC");
10770 val ^= DF_1_NORELOC;
10771 }
10772 if (val & DF_1_SYMINTPOSE)
10773 {
10774 printf (" SYMINTPOSE");
10775 val ^= DF_1_SYMINTPOSE;
10776 }
10777 if (val & DF_1_GLOBAUDIT)
10778 {
10779 printf (" GLOBAUDIT");
10780 val ^= DF_1_GLOBAUDIT;
10781 }
10782 if (val & DF_1_SINGLETON)
10783 {
10784 printf (" SINGLETON");
10785 val ^= DF_1_SINGLETON;
dcefbbbd 10786 }
5c383f02
RO
10787 if (val & DF_1_STUB)
10788 {
10789 printf (" STUB");
10790 val ^= DF_1_STUB;
10791 }
10792 if (val & DF_1_PIE)
10793 {
10794 printf (" PIE");
10795 val ^= DF_1_PIE;
10796 }
b1202ffa
L
10797 if (val & DF_1_KMOD)
10798 {
10799 printf (" KMOD");
10800 val ^= DF_1_KMOD;
10801 }
10802 if (val & DF_1_WEAKFILTER)
10803 {
10804 printf (" WEAKFILTER");
10805 val ^= DF_1_WEAKFILTER;
10806 }
10807 if (val & DF_1_NOCOMMON)
10808 {
10809 printf (" NOCOMMON");
10810 val ^= DF_1_NOCOMMON;
10811 }
252b5132
RH
10812 if (val != 0)
10813 printf (" %lx", val);
10814 puts ("");
10815 }
10816 }
10817 break;
10818
10819 case DT_PLTREL:
978c4450 10820 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10821 if (do_dynamic)
dda8d76d 10822 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10823 break;
10824
10825 case DT_NULL :
10826 case DT_NEEDED :
10827 case DT_PLTGOT :
10828 case DT_HASH :
10829 case DT_STRTAB :
10830 case DT_SYMTAB :
10831 case DT_RELA :
10832 case DT_INIT :
10833 case DT_FINI :
10834 case DT_SONAME :
10835 case DT_RPATH :
10836 case DT_SYMBOLIC:
10837 case DT_REL :
10838 case DT_DEBUG :
10839 case DT_TEXTREL :
10840 case DT_JMPREL :
019148e4 10841 case DT_RUNPATH :
978c4450 10842 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
10843
10844 if (do_dynamic)
10845 {
2cf0635d 10846 char * name;
252b5132 10847
978c4450
AM
10848 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10849 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10850 else
d79b3d50 10851 name = NULL;
252b5132
RH
10852
10853 if (name)
10854 {
10855 switch (entry->d_tag)
10856 {
10857 case DT_NEEDED:
10858 printf (_("Shared library: [%s]"), name);
10859
978c4450 10860 if (streq (name, filedata->program_interpreter))
f7a99963 10861 printf (_(" program interpreter"));
252b5132
RH
10862 break;
10863
10864 case DT_SONAME:
f7a99963 10865 printf (_("Library soname: [%s]"), name);
252b5132
RH
10866 break;
10867
10868 case DT_RPATH:
f7a99963 10869 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10870 break;
10871
019148e4
L
10872 case DT_RUNPATH:
10873 printf (_("Library runpath: [%s]"), name);
10874 break;
10875
252b5132 10876 default:
f7a99963
NC
10877 print_vma (entry->d_un.d_val, PREFIX_HEX);
10878 break;
252b5132
RH
10879 }
10880 }
10881 else
f7a99963
NC
10882 print_vma (entry->d_un.d_val, PREFIX_HEX);
10883
10884 putchar ('\n');
252b5132
RH
10885 }
10886 break;
10887
10888 case DT_PLTRELSZ:
10889 case DT_RELASZ :
10890 case DT_STRSZ :
10891 case DT_RELSZ :
10892 case DT_RELAENT :
10893 case DT_SYMENT :
10894 case DT_RELENT :
978c4450 10895 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 10896 /* Fall through. */
252b5132
RH
10897 case DT_PLTPADSZ:
10898 case DT_MOVEENT :
10899 case DT_MOVESZ :
10900 case DT_INIT_ARRAYSZ:
10901 case DT_FINI_ARRAYSZ:
047b2264
JJ
10902 case DT_GNU_CONFLICTSZ:
10903 case DT_GNU_LIBLISTSZ:
252b5132 10904 if (do_dynamic)
f7a99963
NC
10905 {
10906 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 10907 printf (_(" (bytes)\n"));
f7a99963 10908 }
252b5132
RH
10909 break;
10910
10911 case DT_VERDEFNUM:
10912 case DT_VERNEEDNUM:
10913 case DT_RELACOUNT:
10914 case DT_RELCOUNT:
10915 if (do_dynamic)
f7a99963
NC
10916 {
10917 print_vma (entry->d_un.d_val, UNSIGNED);
10918 putchar ('\n');
10919 }
252b5132
RH
10920 break;
10921
10922 case DT_SYMINSZ:
10923 case DT_SYMINENT:
10924 case DT_SYMINFO:
10925 case DT_USED:
10926 case DT_INIT_ARRAY:
10927 case DT_FINI_ARRAY:
10928 if (do_dynamic)
10929 {
d79b3d50 10930 if (entry->d_tag == DT_USED
978c4450 10931 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 10932 {
978c4450 10933 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10934
b34976b6 10935 if (*name)
252b5132
RH
10936 {
10937 printf (_("Not needed object: [%s]\n"), name);
10938 break;
10939 }
10940 }
103f02d3 10941
f7a99963
NC
10942 print_vma (entry->d_un.d_val, PREFIX_HEX);
10943 putchar ('\n');
252b5132
RH
10944 }
10945 break;
10946
10947 case DT_BIND_NOW:
10948 /* The value of this entry is ignored. */
35b1837e
AM
10949 if (do_dynamic)
10950 putchar ('\n');
252b5132 10951 break;
103f02d3 10952
047b2264
JJ
10953 case DT_GNU_PRELINKED:
10954 if (do_dynamic)
10955 {
2cf0635d 10956 struct tm * tmp;
91d6fa6a 10957 time_t atime = entry->d_un.d_val;
047b2264 10958
91d6fa6a 10959 tmp = gmtime (&atime);
071436c6
NC
10960 /* PR 17533 file: 041-1244816-0.004. */
10961 if (tmp == NULL)
5a2cbcf4
L
10962 printf (_("<corrupt time val: %lx"),
10963 (unsigned long) atime);
071436c6
NC
10964 else
10965 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
10966 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10967 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
10968
10969 }
10970 break;
10971
fdc90cb4 10972 case DT_GNU_HASH:
978c4450 10973 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
10974 if (do_dynamic)
10975 {
10976 print_vma (entry->d_un.d_val, PREFIX_HEX);
10977 putchar ('\n');
10978 }
10979 break;
10980
252b5132
RH
10981 default:
10982 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
10983 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
10984 = entry->d_un.d_val;
252b5132
RH
10985
10986 if (do_dynamic)
10987 {
dda8d76d 10988 switch (filedata->file_header.e_machine)
252b5132 10989 {
37c18eed
SD
10990 case EM_AARCH64:
10991 dynamic_section_aarch64_val (entry);
10992 break;
252b5132 10993 case EM_MIPS:
4fe85591 10994 case EM_MIPS_RS3_LE:
978c4450 10995 dynamic_section_mips_val (filedata, entry);
252b5132 10996 break;
103f02d3 10997 case EM_PARISC:
b2d38a17 10998 dynamic_section_parisc_val (entry);
103f02d3 10999 break;
ecc51f48 11000 case EM_IA_64:
b2d38a17 11001 dynamic_section_ia64_val (entry);
ecc51f48 11002 break;
252b5132 11003 default:
f7a99963
NC
11004 print_vma (entry->d_un.d_val, PREFIX_HEX);
11005 putchar ('\n');
252b5132
RH
11006 }
11007 }
11008 break;
11009 }
11010 }
11011
32ec8896 11012 return TRUE;
252b5132
RH
11013}
11014
11015static char *
d3ba0551 11016get_ver_flags (unsigned int flags)
252b5132 11017{
6d4f21f6 11018 static char buff[128];
252b5132
RH
11019
11020 buff[0] = 0;
11021
11022 if (flags == 0)
11023 return _("none");
11024
11025 if (flags & VER_FLG_BASE)
7bb1ad17 11026 strcat (buff, "BASE");
252b5132
RH
11027
11028 if (flags & VER_FLG_WEAK)
11029 {
11030 if (flags & VER_FLG_BASE)
7bb1ad17 11031 strcat (buff, " | ");
252b5132 11032
7bb1ad17 11033 strcat (buff, "WEAK");
252b5132
RH
11034 }
11035
44ec90b9
RO
11036 if (flags & VER_FLG_INFO)
11037 {
11038 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11039 strcat (buff, " | ");
44ec90b9 11040
7bb1ad17 11041 strcat (buff, "INFO");
44ec90b9
RO
11042 }
11043
11044 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11045 {
11046 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11047 strcat (buff, " | ");
11048
11049 strcat (buff, _("<unknown>"));
11050 }
252b5132
RH
11051
11052 return buff;
11053}
11054
11055/* Display the contents of the version sections. */
98fb390a 11056
32ec8896 11057static bfd_boolean
dda8d76d 11058process_version_sections (Filedata * filedata)
252b5132 11059{
2cf0635d 11060 Elf_Internal_Shdr * section;
b34976b6 11061 unsigned i;
32ec8896 11062 bfd_boolean found = FALSE;
252b5132
RH
11063
11064 if (! do_version)
32ec8896 11065 return TRUE;
252b5132 11066
dda8d76d
NC
11067 for (i = 0, section = filedata->section_headers;
11068 i < filedata->file_header.e_shnum;
b34976b6 11069 i++, section++)
252b5132
RH
11070 {
11071 switch (section->sh_type)
11072 {
11073 case SHT_GNU_verdef:
11074 {
2cf0635d 11075 Elf_External_Verdef * edefs;
452bf675
AM
11076 unsigned long idx;
11077 unsigned long cnt;
2cf0635d 11078 char * endbuf;
252b5132 11079
32ec8896 11080 found = TRUE;
252b5132 11081
d3a49aa8
AM
11082 printf (ngettext ("\nVersion definition section '%s' "
11083 "contains %u entry:\n",
11084 "\nVersion definition section '%s' "
11085 "contains %u entries:\n",
11086 section->sh_info),
dda8d76d 11087 printable_section_name (filedata, section),
74e1a04b 11088 section->sh_info);
252b5132 11089
ae9ac79e 11090 printf (_(" Addr: 0x"));
252b5132 11091 printf_vma (section->sh_addr);
233f82cf 11092 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11093 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11094 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11095
3f5e193b 11096 edefs = (Elf_External_Verdef *)
dda8d76d 11097 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11098 _("version definition section"));
a6e9f9df
AM
11099 if (!edefs)
11100 break;
59245841 11101 endbuf = (char *) edefs + section->sh_size;
252b5132 11102
1445030f 11103 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11104 {
2cf0635d
NC
11105 char * vstart;
11106 Elf_External_Verdef * edef;
b34976b6 11107 Elf_Internal_Verdef ent;
2cf0635d 11108 Elf_External_Verdaux * eaux;
b34976b6 11109 Elf_Internal_Verdaux aux;
452bf675 11110 unsigned long isum;
b34976b6 11111 int j;
103f02d3 11112
252b5132 11113 vstart = ((char *) edefs) + idx;
54806181
AM
11114 if (vstart + sizeof (*edef) > endbuf)
11115 break;
252b5132
RH
11116
11117 edef = (Elf_External_Verdef *) vstart;
11118
11119 ent.vd_version = BYTE_GET (edef->vd_version);
11120 ent.vd_flags = BYTE_GET (edef->vd_flags);
11121 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11122 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11123 ent.vd_hash = BYTE_GET (edef->vd_hash);
11124 ent.vd_aux = BYTE_GET (edef->vd_aux);
11125 ent.vd_next = BYTE_GET (edef->vd_next);
11126
452bf675 11127 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11128 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11129
11130 printf (_(" Index: %d Cnt: %d "),
11131 ent.vd_ndx, ent.vd_cnt);
11132
452bf675 11133 /* Check for overflow. */
1445030f 11134 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11135 break;
11136
252b5132
RH
11137 vstart += ent.vd_aux;
11138
1445030f
AM
11139 if (vstart + sizeof (*eaux) > endbuf)
11140 break;
252b5132
RH
11141 eaux = (Elf_External_Verdaux *) vstart;
11142
11143 aux.vda_name = BYTE_GET (eaux->vda_name);
11144 aux.vda_next = BYTE_GET (eaux->vda_next);
11145
978c4450
AM
11146 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11147 printf (_("Name: %s\n"),
11148 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11149 else
11150 printf (_("Name index: %ld\n"), aux.vda_name);
11151
11152 isum = idx + ent.vd_aux;
11153
b34976b6 11154 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11155 {
1445030f
AM
11156 if (aux.vda_next < sizeof (*eaux)
11157 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11158 {
11159 warn (_("Invalid vda_next field of %lx\n"),
11160 aux.vda_next);
11161 j = ent.vd_cnt;
11162 break;
11163 }
dd24e3da 11164 /* Check for overflow. */
7e26601c 11165 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11166 break;
11167
252b5132
RH
11168 isum += aux.vda_next;
11169 vstart += aux.vda_next;
11170
54806181
AM
11171 if (vstart + sizeof (*eaux) > endbuf)
11172 break;
1445030f 11173 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11174
11175 aux.vda_name = BYTE_GET (eaux->vda_name);
11176 aux.vda_next = BYTE_GET (eaux->vda_next);
11177
978c4450 11178 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11179 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11180 isum, j,
11181 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11182 else
452bf675 11183 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11184 isum, j, aux.vda_name);
11185 }
dd24e3da 11186
54806181
AM
11187 if (j < ent.vd_cnt)
11188 printf (_(" Version def aux past end of section\n"));
252b5132 11189
c9f02c3e
MR
11190 /* PR 17531:
11191 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11192 if (ent.vd_next < sizeof (*edef)
11193 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11194 {
11195 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11196 cnt = section->sh_info;
11197 break;
11198 }
452bf675 11199 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11200 break;
11201
252b5132
RH
11202 idx += ent.vd_next;
11203 }
dd24e3da 11204
54806181
AM
11205 if (cnt < section->sh_info)
11206 printf (_(" Version definition past end of section\n"));
252b5132
RH
11207
11208 free (edefs);
11209 }
11210 break;
103f02d3 11211
252b5132
RH
11212 case SHT_GNU_verneed:
11213 {
2cf0635d 11214 Elf_External_Verneed * eneed;
452bf675
AM
11215 unsigned long idx;
11216 unsigned long cnt;
2cf0635d 11217 char * endbuf;
252b5132 11218
32ec8896 11219 found = TRUE;
252b5132 11220
d3a49aa8
AM
11221 printf (ngettext ("\nVersion needs section '%s' "
11222 "contains %u entry:\n",
11223 "\nVersion needs section '%s' "
11224 "contains %u entries:\n",
11225 section->sh_info),
dda8d76d 11226 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11227
11228 printf (_(" Addr: 0x"));
11229 printf_vma (section->sh_addr);
72de5009 11230 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11231 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11232 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11233
dda8d76d 11234 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11235 section->sh_offset, 1,
11236 section->sh_size,
9cf03b7e 11237 _("Version Needs section"));
a6e9f9df
AM
11238 if (!eneed)
11239 break;
59245841 11240 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11241
11242 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11243 {
2cf0635d 11244 Elf_External_Verneed * entry;
b34976b6 11245 Elf_Internal_Verneed ent;
452bf675 11246 unsigned long isum;
b34976b6 11247 int j;
2cf0635d 11248 char * vstart;
252b5132
RH
11249
11250 vstart = ((char *) eneed) + idx;
54806181
AM
11251 if (vstart + sizeof (*entry) > endbuf)
11252 break;
252b5132
RH
11253
11254 entry = (Elf_External_Verneed *) vstart;
11255
11256 ent.vn_version = BYTE_GET (entry->vn_version);
11257 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11258 ent.vn_file = BYTE_GET (entry->vn_file);
11259 ent.vn_aux = BYTE_GET (entry->vn_aux);
11260 ent.vn_next = BYTE_GET (entry->vn_next);
11261
452bf675 11262 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11263
978c4450
AM
11264 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11265 printf (_(" File: %s"),
11266 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11267 else
11268 printf (_(" File: %lx"), ent.vn_file);
11269
11270 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11271
dd24e3da 11272 /* Check for overflow. */
7e26601c 11273 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11274 break;
252b5132
RH
11275 vstart += ent.vn_aux;
11276
11277 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11278 {
2cf0635d 11279 Elf_External_Vernaux * eaux;
b34976b6 11280 Elf_Internal_Vernaux aux;
252b5132 11281
54806181
AM
11282 if (vstart + sizeof (*eaux) > endbuf)
11283 break;
252b5132
RH
11284 eaux = (Elf_External_Vernaux *) vstart;
11285
11286 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11287 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11288 aux.vna_other = BYTE_GET (eaux->vna_other);
11289 aux.vna_name = BYTE_GET (eaux->vna_name);
11290 aux.vna_next = BYTE_GET (eaux->vna_next);
11291
978c4450 11292 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11293 printf (_(" %#06lx: Name: %s"),
978c4450 11294 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11295 else
452bf675 11296 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11297 isum, aux.vna_name);
11298
11299 printf (_(" Flags: %s Version: %d\n"),
11300 get_ver_flags (aux.vna_flags), aux.vna_other);
11301
1445030f
AM
11302 if (aux.vna_next < sizeof (*eaux)
11303 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11304 {
11305 warn (_("Invalid vna_next field of %lx\n"),
11306 aux.vna_next);
11307 j = ent.vn_cnt;
11308 break;
11309 }
1445030f
AM
11310 /* Check for overflow. */
11311 if (aux.vna_next > (size_t) (endbuf - vstart))
11312 break;
252b5132
RH
11313 isum += aux.vna_next;
11314 vstart += aux.vna_next;
11315 }
9cf03b7e 11316
54806181 11317 if (j < ent.vn_cnt)
9cf03b7e 11318 warn (_("Missing Version Needs auxillary information\n"));
252b5132 11319
1445030f
AM
11320 if (ent.vn_next < sizeof (*entry)
11321 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11322 {
452bf675 11323 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11324 cnt = section->sh_info;
11325 break;
11326 }
1445030f
AM
11327 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11328 break;
252b5132
RH
11329 idx += ent.vn_next;
11330 }
9cf03b7e 11331
54806181 11332 if (cnt < section->sh_info)
9cf03b7e 11333 warn (_("Missing Version Needs information\n"));
103f02d3 11334
252b5132
RH
11335 free (eneed);
11336 }
11337 break;
11338
11339 case SHT_GNU_versym:
11340 {
2cf0635d 11341 Elf_Internal_Shdr * link_section;
8b73c356
NC
11342 size_t total;
11343 unsigned int cnt;
2cf0635d
NC
11344 unsigned char * edata;
11345 unsigned short * data;
11346 char * strtab;
11347 Elf_Internal_Sym * symbols;
11348 Elf_Internal_Shdr * string_sec;
ba5cdace 11349 unsigned long num_syms;
d3ba0551 11350 long off;
252b5132 11351
dda8d76d 11352 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11353 break;
11354
dda8d76d 11355 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11356 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11357
dda8d76d 11358 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11359 break;
11360
32ec8896 11361 found = TRUE;
252b5132 11362
dda8d76d 11363 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11364 if (symbols == NULL)
11365 break;
252b5132 11366
dda8d76d 11367 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11368
dda8d76d 11369 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11370 string_sec->sh_size,
11371 _("version string table"));
a6e9f9df 11372 if (!strtab)
0429c154
MS
11373 {
11374 free (symbols);
11375 break;
11376 }
252b5132 11377
d3a49aa8
AM
11378 printf (ngettext ("\nVersion symbols section '%s' "
11379 "contains %lu entry:\n",
11380 "\nVersion symbols section '%s' "
11381 "contains %lu entries:\n",
11382 total),
dda8d76d 11383 printable_section_name (filedata, section), (unsigned long) total);
252b5132 11384
ae9ac79e 11385 printf (_(" Addr: 0x"));
252b5132 11386 printf_vma (section->sh_addr);
72de5009 11387 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11388 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11389 printable_section_name (filedata, link_section));
252b5132 11390
dda8d76d 11391 off = offset_from_vma (filedata,
978c4450 11392 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11393 total * sizeof (short));
95099889
AM
11394 edata = (unsigned char *) get_data (NULL, filedata, off,
11395 sizeof (short), total,
11396 _("version symbol data"));
a6e9f9df
AM
11397 if (!edata)
11398 {
11399 free (strtab);
0429c154 11400 free (symbols);
a6e9f9df
AM
11401 break;
11402 }
252b5132 11403
3f5e193b 11404 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11405
11406 for (cnt = total; cnt --;)
b34976b6
AM
11407 data[cnt] = byte_get (edata + cnt * sizeof (short),
11408 sizeof (short));
252b5132
RH
11409
11410 free (edata);
11411
11412 for (cnt = 0; cnt < total; cnt += 4)
11413 {
11414 int j, nn;
ab273396
AM
11415 char *name;
11416 char *invalid = _("*invalid*");
252b5132
RH
11417
11418 printf (" %03x:", cnt);
11419
11420 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11421 switch (data[cnt + j])
252b5132
RH
11422 {
11423 case 0:
11424 fputs (_(" 0 (*local*) "), stdout);
11425 break;
11426
11427 case 1:
11428 fputs (_(" 1 (*global*) "), stdout);
11429 break;
11430
11431 default:
c244d050
NC
11432 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11433 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11434
dd24e3da 11435 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11436 array, break to avoid an out-of-bounds read. */
11437 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11438 {
11439 warn (_("invalid index into symbol array\n"));
11440 break;
11441 }
11442
ab273396 11443 name = NULL;
978c4450 11444 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11445 {
b34976b6
AM
11446 Elf_Internal_Verneed ivn;
11447 unsigned long offset;
252b5132 11448
d93f0186 11449 offset = offset_from_vma
978c4450
AM
11450 (filedata,
11451 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11452 sizeof (Elf_External_Verneed));
252b5132 11453
b34976b6 11454 do
252b5132 11455 {
b34976b6
AM
11456 Elf_Internal_Vernaux ivna;
11457 Elf_External_Verneed evn;
11458 Elf_External_Vernaux evna;
11459 unsigned long a_off;
252b5132 11460
dda8d76d 11461 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11462 _("version need")) == NULL)
11463 break;
0b4362b0 11464
252b5132
RH
11465 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11466 ivn.vn_next = BYTE_GET (evn.vn_next);
11467
11468 a_off = offset + ivn.vn_aux;
11469
11470 do
11471 {
dda8d76d 11472 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11473 1, _("version need aux (2)")) == NULL)
11474 {
11475 ivna.vna_next = 0;
11476 ivna.vna_other = 0;
11477 }
11478 else
11479 {
11480 ivna.vna_next = BYTE_GET (evna.vna_next);
11481 ivna.vna_other = BYTE_GET (evna.vna_other);
11482 }
252b5132
RH
11483
11484 a_off += ivna.vna_next;
11485 }
b34976b6 11486 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11487 && ivna.vna_next != 0);
11488
b34976b6 11489 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11490 {
11491 ivna.vna_name = BYTE_GET (evna.vna_name);
11492
54806181 11493 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11494 name = invalid;
54806181
AM
11495 else
11496 name = strtab + ivna.vna_name;
252b5132
RH
11497 break;
11498 }
11499
11500 offset += ivn.vn_next;
11501 }
11502 while (ivn.vn_next);
11503 }
00d93f34 11504
ab273396 11505 if (data[cnt + j] != 0x8001
978c4450 11506 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11507 {
b34976b6
AM
11508 Elf_Internal_Verdef ivd;
11509 Elf_External_Verdef evd;
11510 unsigned long offset;
252b5132 11511
d93f0186 11512 offset = offset_from_vma
978c4450
AM
11513 (filedata,
11514 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11515 sizeof evd);
252b5132
RH
11516
11517 do
11518 {
dda8d76d 11519 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11520 _("version def")) == NULL)
11521 {
11522 ivd.vd_next = 0;
948f632f 11523 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11524 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11525 break;
59245841
NC
11526 }
11527 else
11528 {
11529 ivd.vd_next = BYTE_GET (evd.vd_next);
11530 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11531 }
252b5132
RH
11532
11533 offset += ivd.vd_next;
11534 }
c244d050 11535 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11536 && ivd.vd_next != 0);
11537
c244d050 11538 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11539 {
b34976b6
AM
11540 Elf_External_Verdaux evda;
11541 Elf_Internal_Verdaux ivda;
252b5132
RH
11542
11543 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11544
dda8d76d 11545 if (get_data (&evda, filedata,
59245841
NC
11546 offset - ivd.vd_next + ivd.vd_aux,
11547 sizeof (evda), 1,
11548 _("version def aux")) == NULL)
11549 break;
252b5132
RH
11550
11551 ivda.vda_name = BYTE_GET (evda.vda_name);
11552
54806181 11553 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11554 name = invalid;
11555 else if (name != NULL && name != invalid)
11556 name = _("*both*");
54806181
AM
11557 else
11558 name = strtab + ivda.vda_name;
252b5132
RH
11559 }
11560 }
ab273396
AM
11561 if (name != NULL)
11562 nn += printf ("(%s%-*s",
11563 name,
11564 12 - (int) strlen (name),
11565 ")");
252b5132
RH
11566
11567 if (nn < 18)
11568 printf ("%*c", 18 - nn, ' ');
11569 }
11570
11571 putchar ('\n');
11572 }
11573
11574 free (data);
11575 free (strtab);
11576 free (symbols);
11577 }
11578 break;
103f02d3 11579
252b5132
RH
11580 default:
11581 break;
11582 }
11583 }
11584
11585 if (! found)
11586 printf (_("\nNo version information found in this file.\n"));
11587
32ec8896 11588 return TRUE;
252b5132
RH
11589}
11590
d1133906 11591static const char *
dda8d76d 11592get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11593{
89246a0e 11594 static char buff[64];
252b5132
RH
11595
11596 switch (binding)
11597 {
b34976b6
AM
11598 case STB_LOCAL: return "LOCAL";
11599 case STB_GLOBAL: return "GLOBAL";
11600 case STB_WEAK: return "WEAK";
252b5132
RH
11601 default:
11602 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11603 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11604 binding);
252b5132 11605 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11606 {
11607 if (binding == STB_GNU_UNIQUE
df3a023b 11608 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11609 return "UNIQUE";
11610 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11611 }
252b5132 11612 else
e9e44622 11613 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11614 return buff;
11615 }
11616}
11617
d1133906 11618static const char *
dda8d76d 11619get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11620{
89246a0e 11621 static char buff[64];
252b5132
RH
11622
11623 switch (type)
11624 {
b34976b6
AM
11625 case STT_NOTYPE: return "NOTYPE";
11626 case STT_OBJECT: return "OBJECT";
11627 case STT_FUNC: return "FUNC";
11628 case STT_SECTION: return "SECTION";
11629 case STT_FILE: return "FILE";
11630 case STT_COMMON: return "COMMON";
11631 case STT_TLS: return "TLS";
15ab5209
DB
11632 case STT_RELC: return "RELC";
11633 case STT_SRELC: return "SRELC";
252b5132
RH
11634 default:
11635 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11636 {
dda8d76d 11637 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11638 return "THUMB_FUNC";
103f02d3 11639
dda8d76d 11640 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11641 return "REGISTER";
11642
dda8d76d 11643 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11644 return "PARISC_MILLI";
11645
e9e44622 11646 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11647 }
252b5132 11648 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11649 {
dda8d76d 11650 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11651 {
11652 if (type == STT_HP_OPAQUE)
11653 return "HP_OPAQUE";
11654 if (type == STT_HP_STUB)
11655 return "HP_STUB";
11656 }
11657
d8045f23 11658 if (type == STT_GNU_IFUNC
dda8d76d 11659 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11660 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11661 return "IFUNC";
11662
e9e44622 11663 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11664 }
252b5132 11665 else
e9e44622 11666 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11667 return buff;
11668 }
11669}
11670
d1133906 11671static const char *
d3ba0551 11672get_symbol_visibility (unsigned int visibility)
d1133906
NC
11673{
11674 switch (visibility)
11675 {
b34976b6
AM
11676 case STV_DEFAULT: return "DEFAULT";
11677 case STV_INTERNAL: return "INTERNAL";
11678 case STV_HIDDEN: return "HIDDEN";
d1133906 11679 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11680 default:
27a45f42 11681 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11682 return _("<unknown>");
d1133906
NC
11683 }
11684}
11685
2057d69d
CZ
11686static const char *
11687get_alpha_symbol_other (unsigned int other)
9abca702 11688{
2057d69d
CZ
11689 switch (other)
11690 {
11691 case STO_ALPHA_NOPV: return "NOPV";
11692 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11693 default:
27a45f42 11694 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11695 return _("<unknown>");
9abca702 11696 }
2057d69d
CZ
11697}
11698
fd85a6a1
NC
11699static const char *
11700get_solaris_symbol_visibility (unsigned int visibility)
11701{
11702 switch (visibility)
11703 {
11704 case 4: return "EXPORTED";
11705 case 5: return "SINGLETON";
11706 case 6: return "ELIMINATE";
11707 default: return get_symbol_visibility (visibility);
11708 }
11709}
11710
2301ed1c
SN
11711static const char *
11712get_aarch64_symbol_other (unsigned int other)
11713{
11714 static char buf[32];
11715
11716 if (other & STO_AARCH64_VARIANT_PCS)
11717 {
11718 other &= ~STO_AARCH64_VARIANT_PCS;
11719 if (other == 0)
11720 return "VARIANT_PCS";
11721 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
11722 return buf;
11723 }
11724 return NULL;
11725}
11726
5e2b0d47
NC
11727static const char *
11728get_mips_symbol_other (unsigned int other)
11729{
11730 switch (other)
11731 {
32ec8896
NC
11732 case STO_OPTIONAL: return "OPTIONAL";
11733 case STO_MIPS_PLT: return "MIPS PLT";
11734 case STO_MIPS_PIC: return "MIPS PIC";
11735 case STO_MICROMIPS: return "MICROMIPS";
11736 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11737 case STO_MIPS16: return "MIPS16";
11738 default: return NULL;
5e2b0d47
NC
11739 }
11740}
11741
28f997cf 11742static const char *
dda8d76d 11743get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11744{
dda8d76d 11745 if (is_ia64_vms (filedata))
28f997cf
TG
11746 {
11747 static char res[32];
11748
11749 res[0] = 0;
11750
11751 /* Function types is for images and .STB files only. */
dda8d76d 11752 switch (filedata->file_header.e_type)
28f997cf
TG
11753 {
11754 case ET_DYN:
11755 case ET_EXEC:
11756 switch (VMS_ST_FUNC_TYPE (other))
11757 {
11758 case VMS_SFT_CODE_ADDR:
11759 strcat (res, " CA");
11760 break;
11761 case VMS_SFT_SYMV_IDX:
11762 strcat (res, " VEC");
11763 break;
11764 case VMS_SFT_FD:
11765 strcat (res, " FD");
11766 break;
11767 case VMS_SFT_RESERVE:
11768 strcat (res, " RSV");
11769 break;
11770 default:
bee0ee85
NC
11771 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11772 VMS_ST_FUNC_TYPE (other));
11773 strcat (res, " <unknown>");
11774 break;
28f997cf
TG
11775 }
11776 break;
11777 default:
11778 break;
11779 }
11780 switch (VMS_ST_LINKAGE (other))
11781 {
11782 case VMS_STL_IGNORE:
11783 strcat (res, " IGN");
11784 break;
11785 case VMS_STL_RESERVE:
11786 strcat (res, " RSV");
11787 break;
11788 case VMS_STL_STD:
11789 strcat (res, " STD");
11790 break;
11791 case VMS_STL_LNK:
11792 strcat (res, " LNK");
11793 break;
11794 default:
bee0ee85
NC
11795 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11796 VMS_ST_LINKAGE (other));
11797 strcat (res, " <unknown>");
11798 break;
28f997cf
TG
11799 }
11800
11801 if (res[0] != 0)
11802 return res + 1;
11803 else
11804 return res;
11805 }
11806 return NULL;
11807}
11808
6911b7dc
AM
11809static const char *
11810get_ppc64_symbol_other (unsigned int other)
11811{
14732552
AM
11812 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11813 return NULL;
11814
11815 other >>= STO_PPC64_LOCAL_BIT;
11816 if (other <= 6)
6911b7dc 11817 {
89246a0e 11818 static char buf[64];
14732552
AM
11819 if (other >= 2)
11820 other = ppc64_decode_local_entry (other);
11821 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11822 return buf;
11823 }
11824 return NULL;
11825}
11826
5e2b0d47 11827static const char *
dda8d76d 11828get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11829{
11830 const char * result = NULL;
89246a0e 11831 static char buff [64];
5e2b0d47
NC
11832
11833 if (other == 0)
11834 return "";
11835
dda8d76d 11836 switch (filedata->file_header.e_machine)
5e2b0d47 11837 {
2057d69d
CZ
11838 case EM_ALPHA:
11839 result = get_alpha_symbol_other (other);
11840 break;
2301ed1c
SN
11841 case EM_AARCH64:
11842 result = get_aarch64_symbol_other (other);
11843 break;
5e2b0d47
NC
11844 case EM_MIPS:
11845 result = get_mips_symbol_other (other);
28f997cf
TG
11846 break;
11847 case EM_IA_64:
dda8d76d 11848 result = get_ia64_symbol_other (filedata, other);
28f997cf 11849 break;
6911b7dc
AM
11850 case EM_PPC64:
11851 result = get_ppc64_symbol_other (other);
11852 break;
5e2b0d47 11853 default:
fd85a6a1 11854 result = NULL;
5e2b0d47
NC
11855 break;
11856 }
11857
11858 if (result)
11859 return result;
11860
11861 snprintf (buff, sizeof buff, _("<other>: %x"), other);
11862 return buff;
11863}
11864
d1133906 11865static const char *
dda8d76d 11866get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 11867{
b34976b6 11868 static char buff[32];
5cf1065c 11869
252b5132
RH
11870 switch (type)
11871 {
b34976b6
AM
11872 case SHN_UNDEF: return "UND";
11873 case SHN_ABS: return "ABS";
11874 case SHN_COMMON: return "COM";
252b5132 11875 default:
9ce701e2 11876 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
11877 && filedata->file_header.e_machine == EM_IA_64
11878 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
11879 return "ANSI_COM";
11880 else if ((filedata->file_header.e_machine == EM_X86_64
11881 || filedata->file_header.e_machine == EM_L1OM
11882 || filedata->file_header.e_machine == EM_K1OM)
11883 && type == SHN_X86_64_LCOMMON)
11884 return "LARGE_COM";
11885 else if ((type == SHN_MIPS_SCOMMON
11886 && filedata->file_header.e_machine == EM_MIPS)
11887 || (type == SHN_TIC6X_SCOMMON
11888 && filedata->file_header.e_machine == EM_TI_C6000))
11889 return "SCOM";
11890 else if (type == SHN_MIPS_SUNDEFINED
11891 && filedata->file_header.e_machine == EM_MIPS)
11892 return "SUND";
11893 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
11894 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
11895 else if (type >= SHN_LOOS && type <= SHN_HIOS)
11896 sprintf (buff, "OS [0x%04x]", type & 0xffff);
11897 else if (type >= SHN_LORESERVE)
11898 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
11899 else if (filedata->file_header.e_shnum != 0
11900 && type >= filedata->file_header.e_shnum)
11901 sprintf (buff, _("bad section index[%3d]"), type);
11902 else
11903 sprintf (buff, "%3d", type);
11904 break;
fd85a6a1
NC
11905 }
11906
10ca4b04 11907 return buff;
6bd1a22c
L
11908}
11909
bb4d2ac2 11910static const char *
dda8d76d 11911get_symbol_version_string (Filedata * filedata,
1449284b
NC
11912 bfd_boolean is_dynsym,
11913 const char * strtab,
11914 unsigned long int strtab_size,
11915 unsigned int si,
11916 Elf_Internal_Sym * psym,
11917 enum versioned_symbol_info * sym_info,
11918 unsigned short * vna_other)
bb4d2ac2 11919{
ab273396
AM
11920 unsigned char data[2];
11921 unsigned short vers_data;
11922 unsigned long offset;
7a815dd5 11923 unsigned short max_vd_ndx;
bb4d2ac2 11924
ab273396 11925 if (!is_dynsym
978c4450 11926 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 11927 return NULL;
bb4d2ac2 11928
978c4450
AM
11929 offset = offset_from_vma (filedata,
11930 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 11931 sizeof data + si * sizeof (vers_data));
bb4d2ac2 11932
dda8d76d 11933 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
11934 sizeof (data), 1, _("version data")) == NULL)
11935 return NULL;
11936
11937 vers_data = byte_get (data, 2);
bb4d2ac2 11938
1f6f5dba 11939 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 11940 return NULL;
bb4d2ac2 11941
0b8b7609 11942 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
11943 max_vd_ndx = 0;
11944
ab273396
AM
11945 /* Usually we'd only see verdef for defined symbols, and verneed for
11946 undefined symbols. However, symbols defined by the linker in
11947 .dynbss for variables copied from a shared library in order to
11948 avoid text relocations are defined yet have verneed. We could
11949 use a heuristic to detect the special case, for example, check
11950 for verneed first on symbols defined in SHT_NOBITS sections, but
11951 it is simpler and more reliable to just look for both verdef and
11952 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 11953
ab273396
AM
11954 if (psym->st_shndx != SHN_UNDEF
11955 && vers_data != 0x8001
978c4450 11956 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
11957 {
11958 Elf_Internal_Verdef ivd;
11959 Elf_Internal_Verdaux ivda;
11960 Elf_External_Verdaux evda;
11961 unsigned long off;
bb4d2ac2 11962
dda8d76d 11963 off = offset_from_vma (filedata,
978c4450 11964 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
11965 sizeof (Elf_External_Verdef));
11966
11967 do
bb4d2ac2 11968 {
ab273396
AM
11969 Elf_External_Verdef evd;
11970
dda8d76d 11971 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
11972 _("version def")) == NULL)
11973 {
11974 ivd.vd_ndx = 0;
11975 ivd.vd_aux = 0;
11976 ivd.vd_next = 0;
1f6f5dba 11977 ivd.vd_flags = 0;
ab273396
AM
11978 }
11979 else
bb4d2ac2 11980 {
ab273396
AM
11981 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11982 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11983 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 11984 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 11985 }
bb4d2ac2 11986
7a815dd5
L
11987 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
11988 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
11989
ab273396
AM
11990 off += ivd.vd_next;
11991 }
11992 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 11993
ab273396
AM
11994 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
11995 {
9abca702 11996 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
11997 return NULL;
11998
ab273396
AM
11999 off -= ivd.vd_next;
12000 off += ivd.vd_aux;
bb4d2ac2 12001
dda8d76d 12002 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12003 _("version def aux")) != NULL)
12004 {
12005 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12006
ab273396 12007 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12008 return (ivda.vda_name < strtab_size
12009 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12010 }
12011 }
12012 }
bb4d2ac2 12013
978c4450 12014 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12015 {
12016 Elf_External_Verneed evn;
12017 Elf_Internal_Verneed ivn;
12018 Elf_Internal_Vernaux ivna;
bb4d2ac2 12019
dda8d76d 12020 offset = offset_from_vma (filedata,
978c4450 12021 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12022 sizeof evn);
12023 do
12024 {
12025 unsigned long vna_off;
bb4d2ac2 12026
dda8d76d 12027 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12028 _("version need")) == NULL)
12029 {
12030 ivna.vna_next = 0;
12031 ivna.vna_other = 0;
12032 ivna.vna_name = 0;
12033 break;
12034 }
bb4d2ac2 12035
ab273396
AM
12036 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12037 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12038
ab273396 12039 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12040
ab273396
AM
12041 do
12042 {
12043 Elf_External_Vernaux evna;
bb4d2ac2 12044
dda8d76d 12045 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12046 _("version need aux (3)")) == NULL)
bb4d2ac2 12047 {
ab273396
AM
12048 ivna.vna_next = 0;
12049 ivna.vna_other = 0;
12050 ivna.vna_name = 0;
bb4d2ac2 12051 }
bb4d2ac2 12052 else
bb4d2ac2 12053 {
ab273396
AM
12054 ivna.vna_other = BYTE_GET (evna.vna_other);
12055 ivna.vna_next = BYTE_GET (evna.vna_next);
12056 ivna.vna_name = BYTE_GET (evna.vna_name);
12057 }
bb4d2ac2 12058
ab273396
AM
12059 vna_off += ivna.vna_next;
12060 }
12061 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12062
ab273396
AM
12063 if (ivna.vna_other == vers_data)
12064 break;
bb4d2ac2 12065
ab273396
AM
12066 offset += ivn.vn_next;
12067 }
12068 while (ivn.vn_next != 0);
bb4d2ac2 12069
ab273396
AM
12070 if (ivna.vna_other == vers_data)
12071 {
12072 *sym_info = symbol_undefined;
12073 *vna_other = ivna.vna_other;
12074 return (ivna.vna_name < strtab_size
12075 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12076 }
7a815dd5
L
12077 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12078 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12079 return _("<corrupt>");
bb4d2ac2 12080 }
ab273396 12081 return NULL;
bb4d2ac2
L
12082}
12083
10ca4b04
L
12084static void
12085print_dynamic_symbol (Filedata *filedata, unsigned long si,
12086 Elf_Internal_Sym *symtab,
12087 Elf_Internal_Shdr *section,
12088 char *strtab, size_t strtab_size)
252b5132 12089{
10ca4b04
L
12090 const char *version_string;
12091 enum versioned_symbol_info sym_info;
12092 unsigned short vna_other;
12093 Elf_Internal_Sym *psym = symtab + si;
0942c7ab 12094
10ca4b04
L
12095 printf ("%6ld: ", si);
12096 print_vma (psym->st_value, LONG_HEX);
12097 putchar (' ');
12098 print_vma (psym->st_size, DEC_5);
12099 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12100 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12101 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12102 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12103 else
252b5132 12104 {
10ca4b04 12105 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12106
10ca4b04
L
12107 printf (" %-7s", get_symbol_visibility (vis));
12108 /* Check to see if any other bits in the st_other field are set.
12109 Note - displaying this information disrupts the layout of the
12110 table being generated, but for the moment this case is very rare. */
12111 if (psym->st_other ^ vis)
12112 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12113 }
10ca4b04 12114 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab
NC
12115
12116 bfd_boolean is_valid = VALID_SYMBOL_NAME (strtab, strtab_size,
12117 psym->st_name);
12118 const char * sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
10ca4b04
L
12119
12120 version_string
12121 = get_symbol_version_string (filedata,
12122 (section == NULL
12123 || section->sh_type == SHT_DYNSYM),
12124 strtab, strtab_size, si,
12125 psym, &sym_info, &vna_other);
0942c7ab
NC
12126
12127 int len_avail = 21;
12128 if (! do_wide && version_string != NULL)
12129 {
ddb43bab 12130 char buffer[16];
0942c7ab 12131
ddb43bab 12132 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12133
12134 if (sym_info == symbol_undefined)
12135 len_avail -= sprintf (buffer," (%d)", vna_other);
12136 else if (sym_info != symbol_hidden)
12137 len_avail -= 1;
12138 }
12139
12140 print_symbol (len_avail, sstr);
12141
10ca4b04
L
12142 if (version_string)
12143 {
12144 if (sym_info == symbol_undefined)
12145 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12146 else
10ca4b04
L
12147 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12148 version_string);
12149 }
6bd1a22c 12150
10ca4b04 12151 putchar ('\n');
6bd1a22c 12152
10ca4b04
L
12153 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12154 && section != NULL
12155 && si >= section->sh_info
12156 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12157 && filedata->file_header.e_machine != EM_MIPS
12158 /* Solaris binaries have been found to violate this requirement as
12159 well. Not sure if this is a bug or an ABI requirement. */
12160 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12161 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12162 si, printable_section_name (filedata, section), section->sh_info);
12163}
f16a9783 12164
10ca4b04
L
12165/* Dump the symbol table. */
12166static bfd_boolean
12167process_symbol_table (Filedata * filedata)
12168{
12169 Elf_Internal_Shdr * section;
f16a9783 12170
10ca4b04
L
12171 if (!do_syms && !do_dyn_syms && !do_histogram)
12172 return TRUE;
6bd1a22c 12173
978c4450 12174 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12175 && do_syms
12176 && do_using_dynamic
978c4450
AM
12177 && filedata->dynamic_strings != NULL
12178 && filedata->dynamic_symbols != NULL)
6bd1a22c 12179 {
10ca4b04 12180 unsigned long si;
6bd1a22c 12181
10ca4b04
L
12182 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12183 "\nSymbol table for image contains %lu entries:\n",
978c4450
AM
12184 filedata->num_dynamic_syms),
12185 filedata->num_dynamic_syms);
10ca4b04
L
12186 if (is_32bit_elf)
12187 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12188 else
12189 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12190
978c4450
AM
12191 for (si = 0; si < filedata->num_dynamic_syms; si++)
12192 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12193 filedata->dynamic_strings,
12194 filedata->dynamic_strings_length);
252b5132 12195 }
8b73c356 12196 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12197 && filedata->section_headers != NULL)
252b5132 12198 {
b34976b6 12199 unsigned int i;
252b5132 12200
dda8d76d
NC
12201 for (i = 0, section = filedata->section_headers;
12202 i < filedata->file_header.e_shnum;
252b5132
RH
12203 i++, section++)
12204 {
2cf0635d 12205 char * strtab = NULL;
c256ffe7 12206 unsigned long int strtab_size = 0;
2cf0635d 12207 Elf_Internal_Sym * symtab;
ef3df110 12208 unsigned long si, num_syms;
252b5132 12209
2c610e4b
L
12210 if ((section->sh_type != SHT_SYMTAB
12211 && section->sh_type != SHT_DYNSYM)
12212 || (!do_syms
12213 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12214 continue;
12215
dd24e3da
NC
12216 if (section->sh_entsize == 0)
12217 {
12218 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12219 printable_section_name (filedata, section));
dd24e3da
NC
12220 continue;
12221 }
12222
d3a49aa8
AM
12223 num_syms = section->sh_size / section->sh_entsize;
12224 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12225 "\nSymbol table '%s' contains %lu entries:\n",
12226 num_syms),
dda8d76d 12227 printable_section_name (filedata, section),
d3a49aa8 12228 num_syms);
dd24e3da 12229
f7a99963 12230 if (is_32bit_elf)
ca47b30c 12231 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12232 else
ca47b30c 12233 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12234
dda8d76d 12235 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12236 if (symtab == NULL)
12237 continue;
12238
dda8d76d 12239 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12240 {
dda8d76d
NC
12241 strtab = filedata->string_table;
12242 strtab_size = filedata->string_table_length;
c256ffe7 12243 }
dda8d76d 12244 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12245 {
2cf0635d 12246 Elf_Internal_Shdr * string_sec;
252b5132 12247
dda8d76d 12248 string_sec = filedata->section_headers + section->sh_link;
252b5132 12249
dda8d76d 12250 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12251 1, string_sec->sh_size,
12252 _("string table"));
c256ffe7 12253 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12254 }
12255
10ca4b04
L
12256 for (si = 0; si < num_syms; si++)
12257 print_dynamic_symbol (filedata, si, symtab, section,
12258 strtab, strtab_size);
252b5132
RH
12259
12260 free (symtab);
dda8d76d 12261 if (strtab != filedata->string_table)
252b5132
RH
12262 free (strtab);
12263 }
12264 }
12265 else if (do_syms)
12266 printf
12267 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12268
978c4450 12269 if (do_histogram && filedata->buckets != NULL)
252b5132 12270 {
2cf0635d
NC
12271 unsigned long * lengths;
12272 unsigned long * counts;
66543521
AM
12273 unsigned long hn;
12274 bfd_vma si;
12275 unsigned long maxlength = 0;
12276 unsigned long nzero_counts = 0;
12277 unsigned long nsyms = 0;
6bd6a03d 12278 char *visited;
252b5132 12279
d3a49aa8
AM
12280 printf (ngettext ("\nHistogram for bucket list length "
12281 "(total of %lu bucket):\n",
12282 "\nHistogram for bucket list length "
12283 "(total of %lu buckets):\n",
978c4450
AM
12284 (unsigned long) filedata->nbuckets),
12285 (unsigned long) filedata->nbuckets);
252b5132 12286
978c4450
AM
12287 lengths = (unsigned long *) calloc (filedata->nbuckets,
12288 sizeof (*lengths));
252b5132
RH
12289 if (lengths == NULL)
12290 {
8b73c356 12291 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12292 goto err_out;
252b5132 12293 }
978c4450
AM
12294 visited = xcmalloc (filedata->nchains, 1);
12295 memset (visited, 0, filedata->nchains);
8b73c356
NC
12296
12297 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12298 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12299 {
978c4450 12300 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12301 {
b34976b6 12302 ++nsyms;
252b5132 12303 if (maxlength < ++lengths[hn])
b34976b6 12304 ++maxlength;
978c4450 12305 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12306 {
12307 error (_("histogram chain is corrupt\n"));
12308 break;
12309 }
12310 visited[si] = 1;
252b5132
RH
12311 }
12312 }
6bd6a03d 12313 free (visited);
252b5132 12314
3f5e193b 12315 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12316 if (counts == NULL)
12317 {
b2e951ec 12318 free (lengths);
8b73c356 12319 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12320 goto err_out;
252b5132
RH
12321 }
12322
978c4450 12323 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12324 ++counts[lengths[hn]];
252b5132 12325
978c4450 12326 if (filedata->nbuckets > 0)
252b5132 12327 {
66543521
AM
12328 unsigned long i;
12329 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12330 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12331 for (i = 1; i <= maxlength; ++i)
103f02d3 12332 {
66543521
AM
12333 nzero_counts += counts[i] * i;
12334 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12335 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12336 (nzero_counts * 100.0) / nsyms);
12337 }
252b5132
RH
12338 }
12339
12340 free (counts);
12341 free (lengths);
12342 }
12343
978c4450
AM
12344 free (filedata->buckets);
12345 filedata->buckets = NULL;
12346 filedata->nbuckets = 0;
12347 free (filedata->chains);
12348 filedata->chains = NULL;
252b5132 12349
978c4450 12350 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 12351 {
2cf0635d
NC
12352 unsigned long * lengths;
12353 unsigned long * counts;
fdc90cb4
JJ
12354 unsigned long hn;
12355 unsigned long maxlength = 0;
12356 unsigned long nzero_counts = 0;
12357 unsigned long nsyms = 0;
fdc90cb4 12358
f16a9783 12359 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12360 "(total of %lu bucket):\n",
f16a9783 12361 "\nHistogram for `%s' bucket list length "
d3a49aa8 12362 "(total of %lu buckets):\n",
978c4450
AM
12363 (unsigned long) filedata->ngnubuckets),
12364 GNU_HASH_SECTION_NAME (filedata),
12365 (unsigned long) filedata->ngnubuckets);
8b73c356 12366
978c4450
AM
12367 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
12368 sizeof (*lengths));
fdc90cb4
JJ
12369 if (lengths == NULL)
12370 {
8b73c356 12371 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12372 goto err_out;
fdc90cb4
JJ
12373 }
12374
fdc90cb4
JJ
12375 printf (_(" Length Number %% of total Coverage\n"));
12376
978c4450
AM
12377 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12378 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
12379 {
12380 bfd_vma off, length = 1;
12381
978c4450 12382 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 12383 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
12384 off < filedata->ngnuchains
12385 && (filedata->gnuchains[off] & 1) == 0;
071436c6 12386 ++off)
fdc90cb4
JJ
12387 ++length;
12388 lengths[hn] = length;
12389 if (length > maxlength)
12390 maxlength = length;
12391 nsyms += length;
12392 }
12393
3f5e193b 12394 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12395 if (counts == NULL)
12396 {
b2e951ec 12397 free (lengths);
8b73c356 12398 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12399 goto err_out;
fdc90cb4
JJ
12400 }
12401
978c4450 12402 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
12403 ++counts[lengths[hn]];
12404
978c4450 12405 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
12406 {
12407 unsigned long j;
12408 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12409 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
12410 for (j = 1; j <= maxlength; ++j)
12411 {
12412 nzero_counts += counts[j] * j;
12413 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12414 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
12415 (nzero_counts * 100.0) / nsyms);
12416 }
12417 }
12418
12419 free (counts);
12420 free (lengths);
fdc90cb4 12421 }
978c4450
AM
12422 free (filedata->gnubuckets);
12423 filedata->gnubuckets = NULL;
12424 filedata->ngnubuckets = 0;
12425 free (filedata->gnuchains);
12426 filedata->gnuchains = NULL;
12427 filedata->ngnuchains = 0;
12428 free (filedata->mipsxlat);
12429 filedata->mipsxlat = NULL;
32ec8896 12430 return TRUE;
fd486f32
AM
12431
12432 err_out:
978c4450
AM
12433 free (filedata->gnubuckets);
12434 filedata->gnubuckets = NULL;
12435 filedata->ngnubuckets = 0;
12436 free (filedata->gnuchains);
12437 filedata->gnuchains = NULL;
12438 filedata->ngnuchains = 0;
12439 free (filedata->mipsxlat);
12440 filedata->mipsxlat = NULL;
12441 free (filedata->buckets);
12442 filedata->buckets = NULL;
12443 filedata->nbuckets = 0;
12444 free (filedata->chains);
12445 filedata->chains = NULL;
fd486f32 12446 return FALSE;
252b5132
RH
12447}
12448
32ec8896 12449static bfd_boolean
dda8d76d 12450process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12451{
b4c96d0d 12452 unsigned int i;
252b5132 12453
978c4450 12454 if (filedata->dynamic_syminfo == NULL
252b5132
RH
12455 || !do_dynamic)
12456 /* No syminfo, this is ok. */
32ec8896 12457 return TRUE;
252b5132
RH
12458
12459 /* There better should be a dynamic symbol section. */
978c4450 12460 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
32ec8896 12461 return FALSE;
252b5132 12462
978c4450 12463 if (filedata->dynamic_addr)
d3a49aa8
AM
12464 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12465 "contains %d entry:\n",
12466 "\nDynamic info segment at offset 0x%lx "
12467 "contains %d entries:\n",
978c4450
AM
12468 filedata->dynamic_syminfo_nent),
12469 filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent);
252b5132
RH
12470
12471 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 12472 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 12473 {
978c4450 12474 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 12475
31104126 12476 printf ("%4d: ", i);
978c4450 12477 if (i >= filedata->num_dynamic_syms)
4082ef84 12478 printf (_("<corrupt index>"));
978c4450
AM
12479 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
12480 print_symbol (30, GET_DYNAMIC_NAME (filedata,
12481 filedata->dynamic_symbols[i].st_name));
d79b3d50 12482 else
978c4450 12483 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 12484 putchar (' ');
252b5132 12485
978c4450 12486 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
12487 {
12488 case SYMINFO_BT_SELF:
12489 fputs ("SELF ", stdout);
12490 break;
12491 case SYMINFO_BT_PARENT:
12492 fputs ("PARENT ", stdout);
12493 break;
12494 default:
978c4450
AM
12495 if (filedata->dynamic_syminfo[i].si_boundto > 0
12496 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
12497 && VALID_DYNAMIC_NAME (filedata,
12498 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12499 {
978c4450
AM
12500 print_symbol (10, GET_DYNAMIC_NAME (filedata,
12501 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12502 putchar (' ' );
12503 }
252b5132 12504 else
978c4450 12505 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
12506 break;
12507 }
12508
12509 if (flags & SYMINFO_FLG_DIRECT)
12510 printf (" DIRECT");
12511 if (flags & SYMINFO_FLG_PASSTHRU)
12512 printf (" PASSTHRU");
12513 if (flags & SYMINFO_FLG_COPY)
12514 printf (" COPY");
12515 if (flags & SYMINFO_FLG_LAZYLOAD)
12516 printf (" LAZYLOAD");
12517
12518 puts ("");
12519 }
12520
32ec8896 12521 return TRUE;
252b5132
RH
12522}
12523
75802ccb
CE
12524/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
12525 is contained by the region START .. END. The types of ADDR, START
12526 and END should all be the same. Note both ADDR + NELEM and END
12527 point to just beyond the end of the regions that are being tested. */
12528#define IN_RANGE(START,END,ADDR,NELEM) \
12529 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 12530
cf13d699
NC
12531/* Check to see if the given reloc needs to be handled in a target specific
12532 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12533 FALSE.
12534
12535 If called with reloc == NULL, then this is a signal that reloc processing
12536 for the current section has finished, and any saved state should be
12537 discarded. */
09c11c86 12538
cf13d699 12539static bfd_boolean
dda8d76d
NC
12540target_specific_reloc_handling (Filedata * filedata,
12541 Elf_Internal_Rela * reloc,
12542 unsigned char * start,
12543 unsigned char * end,
12544 Elf_Internal_Sym * symtab,
12545 unsigned long num_syms)
252b5132 12546{
f84ce13b
NC
12547 unsigned int reloc_type = 0;
12548 unsigned long sym_index = 0;
12549
12550 if (reloc)
12551 {
dda8d76d 12552 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12553 sym_index = get_reloc_symindex (reloc->r_info);
12554 }
252b5132 12555
dda8d76d 12556 switch (filedata->file_header.e_machine)
252b5132 12557 {
13761a11
NC
12558 case EM_MSP430:
12559 case EM_MSP430_OLD:
12560 {
12561 static Elf_Internal_Sym * saved_sym = NULL;
12562
f84ce13b
NC
12563 if (reloc == NULL)
12564 {
12565 saved_sym = NULL;
12566 return TRUE;
12567 }
12568
13761a11
NC
12569 switch (reloc_type)
12570 {
12571 case 10: /* R_MSP430_SYM_DIFF */
dda8d76d 12572 if (uses_msp430x_relocs (filedata))
13761a11 12573 break;
1a0670f3 12574 /* Fall through. */
13761a11 12575 case 21: /* R_MSP430X_SYM_DIFF */
f84ce13b
NC
12576 /* PR 21139. */
12577 if (sym_index >= num_syms)
12578 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12579 sym_index);
12580 else
12581 saved_sym = symtab + sym_index;
13761a11
NC
12582 return TRUE;
12583
12584 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12585 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12586 goto handle_sym_diff;
0b4362b0 12587
13761a11
NC
12588 case 5: /* R_MSP430_16_BYTE */
12589 case 9: /* R_MSP430_8 */
dda8d76d 12590 if (uses_msp430x_relocs (filedata))
13761a11
NC
12591 break;
12592 goto handle_sym_diff;
12593
12594 case 2: /* R_MSP430_ABS16 */
12595 case 15: /* R_MSP430X_ABS16 */
dda8d76d 12596 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12597 break;
12598 goto handle_sym_diff;
0b4362b0 12599
13761a11
NC
12600 handle_sym_diff:
12601 if (saved_sym != NULL)
12602 {
03f7786e 12603 int reloc_size = reloc_type == 1 ? 4 : 2;
13761a11
NC
12604 bfd_vma value;
12605
f84ce13b
NC
12606 if (sym_index >= num_syms)
12607 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
12608 sym_index);
03f7786e 12609 else
f84ce13b
NC
12610 {
12611 value = reloc->r_addend + (symtab[sym_index].st_value
12612 - saved_sym->st_value);
12613
b32e566b 12614 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12615 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12616 else
12617 /* PR 21137 */
12618 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
12619 (long) reloc->r_offset);
f84ce13b 12620 }
13761a11
NC
12621
12622 saved_sym = NULL;
12623 return TRUE;
12624 }
12625 break;
12626
12627 default:
12628 if (saved_sym != NULL)
071436c6 12629 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
12630 break;
12631 }
12632 break;
12633 }
12634
cf13d699
NC
12635 case EM_MN10300:
12636 case EM_CYGNUS_MN10300:
12637 {
12638 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 12639
f84ce13b
NC
12640 if (reloc == NULL)
12641 {
12642 saved_sym = NULL;
12643 return TRUE;
12644 }
12645
cf13d699
NC
12646 switch (reloc_type)
12647 {
12648 case 34: /* R_MN10300_ALIGN */
12649 return TRUE;
12650 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
12651 if (sym_index >= num_syms)
12652 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
12653 sym_index);
12654 else
12655 saved_sym = symtab + sym_index;
cf13d699 12656 return TRUE;
f84ce13b 12657
cf13d699
NC
12658 case 1: /* R_MN10300_32 */
12659 case 2: /* R_MN10300_16 */
12660 if (saved_sym != NULL)
12661 {
03f7786e 12662 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 12663 bfd_vma value;
252b5132 12664
f84ce13b
NC
12665 if (sym_index >= num_syms)
12666 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
12667 sym_index);
03f7786e 12668 else
f84ce13b
NC
12669 {
12670 value = reloc->r_addend + (symtab[sym_index].st_value
12671 - saved_sym->st_value);
12672
b32e566b 12673 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 12674 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
12675 else
12676 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
12677 (long) reloc->r_offset);
f84ce13b 12678 }
252b5132 12679
cf13d699
NC
12680 saved_sym = NULL;
12681 return TRUE;
12682 }
12683 break;
12684 default:
12685 if (saved_sym != NULL)
071436c6 12686 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
12687 break;
12688 }
12689 break;
12690 }
6ff71e76
NC
12691
12692 case EM_RL78:
12693 {
12694 static bfd_vma saved_sym1 = 0;
12695 static bfd_vma saved_sym2 = 0;
12696 static bfd_vma value;
12697
f84ce13b
NC
12698 if (reloc == NULL)
12699 {
12700 saved_sym1 = saved_sym2 = 0;
12701 return TRUE;
12702 }
12703
6ff71e76
NC
12704 switch (reloc_type)
12705 {
12706 case 0x80: /* R_RL78_SYM. */
12707 saved_sym1 = saved_sym2;
f84ce13b
NC
12708 if (sym_index >= num_syms)
12709 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
12710 sym_index);
12711 else
12712 {
12713 saved_sym2 = symtab[sym_index].st_value;
12714 saved_sym2 += reloc->r_addend;
12715 }
6ff71e76
NC
12716 return TRUE;
12717
12718 case 0x83: /* R_RL78_OPsub. */
12719 value = saved_sym1 - saved_sym2;
12720 saved_sym2 = saved_sym1 = 0;
12721 return TRUE;
12722 break;
12723
12724 case 0x41: /* R_RL78_ABS32. */
b32e566b 12725 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 12726 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
12727 else
12728 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12729 (long) reloc->r_offset);
6ff71e76
NC
12730 value = 0;
12731 return TRUE;
12732
12733 case 0x43: /* R_RL78_ABS16. */
b32e566b 12734 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 12735 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
12736 else
12737 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
12738 (long) reloc->r_offset);
6ff71e76
NC
12739 value = 0;
12740 return TRUE;
12741
12742 default:
12743 break;
12744 }
12745 break;
12746 }
252b5132
RH
12747 }
12748
cf13d699 12749 return FALSE;
252b5132
RH
12750}
12751
aca88567
NC
12752/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
12753 DWARF debug sections. This is a target specific test. Note - we do not
12754 go through the whole including-target-headers-multiple-times route, (as
12755 we have already done with <elf/h8.h>) because this would become very
12756 messy and even then this function would have to contain target specific
12757 information (the names of the relocs instead of their numeric values).
12758 FIXME: This is not the correct way to solve this problem. The proper way
12759 is to have target specific reloc sizing and typing functions created by
12760 the reloc-macros.h header, in the same way that it already creates the
12761 reloc naming functions. */
12762
12763static bfd_boolean
dda8d76d 12764is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12765{
d347c9df 12766 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 12767 switch (filedata->file_header.e_machine)
aca88567 12768 {
41e92641 12769 case EM_386:
22abe556 12770 case EM_IAMCU:
41e92641 12771 return reloc_type == 1; /* R_386_32. */
aca88567
NC
12772 case EM_68K:
12773 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
12774 case EM_860:
12775 return reloc_type == 1; /* R_860_32. */
12776 case EM_960:
12777 return reloc_type == 2; /* R_960_32. */
a06ea964 12778 case EM_AARCH64:
9282b95a
JW
12779 return (reloc_type == 258
12780 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
12781 case EM_BPF:
12782 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
12783 case EM_ADAPTEVA_EPIPHANY:
12784 return reloc_type == 3;
aca88567 12785 case EM_ALPHA:
137b6b5f 12786 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
12787 case EM_ARC:
12788 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
12789 case EM_ARC_COMPACT:
12790 case EM_ARC_COMPACT2:
12791 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
12792 case EM_ARM:
12793 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 12794 case EM_AVR_OLD:
aca88567
NC
12795 case EM_AVR:
12796 return reloc_type == 1;
12797 case EM_BLACKFIN:
12798 return reloc_type == 0x12; /* R_byte4_data. */
12799 case EM_CRIS:
12800 return reloc_type == 3; /* R_CRIS_32. */
12801 case EM_CR16:
12802 return reloc_type == 3; /* R_CR16_NUM32. */
12803 case EM_CRX:
12804 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
12805 case EM_CSKY:
12806 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
12807 case EM_CYGNUS_FRV:
12808 return reloc_type == 1;
41e92641
NC
12809 case EM_CYGNUS_D10V:
12810 case EM_D10V:
12811 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
12812 case EM_CYGNUS_D30V:
12813 case EM_D30V:
12814 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
12815 case EM_DLX:
12816 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
12817 case EM_CYGNUS_FR30:
12818 case EM_FR30:
12819 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
12820 case EM_FT32:
12821 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
12822 case EM_H8S:
12823 case EM_H8_300:
12824 case EM_H8_300H:
12825 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 12826 case EM_IA_64:
262cdac7
AM
12827 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
12828 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
12829 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
12830 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
12831 case EM_IP2K_OLD:
12832 case EM_IP2K:
12833 return reloc_type == 2; /* R_IP2K_32. */
12834 case EM_IQ2000:
12835 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
12836 case EM_LATTICEMICO32:
12837 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 12838 case EM_M32C_OLD:
aca88567
NC
12839 case EM_M32C:
12840 return reloc_type == 3; /* R_M32C_32. */
12841 case EM_M32R:
12842 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
12843 case EM_68HC11:
12844 case EM_68HC12:
12845 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 12846 case EM_S12Z:
2849d19f
JD
12847 return reloc_type == 7 || /* R_S12Z_EXT32 */
12848 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
12849 case EM_MCORE:
12850 return reloc_type == 1; /* R_MCORE_ADDR32. */
12851 case EM_CYGNUS_MEP:
12852 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
12853 case EM_METAG:
12854 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
12855 case EM_MICROBLAZE:
12856 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
12857 case EM_MIPS:
12858 return reloc_type == 2; /* R_MIPS_32. */
12859 case EM_MMIX:
12860 return reloc_type == 4; /* R_MMIX_32. */
12861 case EM_CYGNUS_MN10200:
12862 case EM_MN10200:
12863 return reloc_type == 1; /* R_MN10200_32. */
12864 case EM_CYGNUS_MN10300:
12865 case EM_MN10300:
12866 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
12867 case EM_MOXIE:
12868 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
12869 case EM_MSP430_OLD:
12870 case EM_MSP430:
13761a11 12871 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
12872 case EM_MT:
12873 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
12874 case EM_NDS32:
12875 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 12876 case EM_ALTERA_NIOS2:
36591ba1 12877 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
12878 case EM_NIOS32:
12879 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
12880 case EM_OR1K:
12881 return reloc_type == 1; /* R_OR1K_32. */
aca88567 12882 case EM_PARISC:
9abca702 12883 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 12884 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 12885 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
12886 case EM_PJ:
12887 case EM_PJ_OLD:
12888 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
12889 case EM_PPC64:
12890 return reloc_type == 1; /* R_PPC64_ADDR32. */
12891 case EM_PPC:
12892 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
12893 case EM_TI_PRU:
12894 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
12895 case EM_RISCV:
12896 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
12897 case EM_RL78:
12898 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
12899 case EM_RX:
12900 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
12901 case EM_S370:
12902 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
12903 case EM_S390_OLD:
12904 case EM_S390:
12905 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
12906 case EM_SCORE:
12907 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
12908 case EM_SH:
12909 return reloc_type == 1; /* R_SH_DIR32. */
12910 case EM_SPARC32PLUS:
12911 case EM_SPARCV9:
12912 case EM_SPARC:
12913 return reloc_type == 3 /* R_SPARC_32. */
12914 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
12915 case EM_SPU:
12916 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
12917 case EM_TI_C6000:
12918 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
12919 case EM_TILEGX:
12920 return reloc_type == 2; /* R_TILEGX_32. */
12921 case EM_TILEPRO:
12922 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
12923 case EM_CYGNUS_V850:
12924 case EM_V850:
12925 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
12926 case EM_V800:
12927 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
12928 case EM_VAX:
12929 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
12930 case EM_VISIUM:
12931 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
12932 case EM_WEBASSEMBLY:
12933 return reloc_type == 1; /* R_WASM32_32. */
aca88567 12934 case EM_X86_64:
8a9036a4 12935 case EM_L1OM:
7a9068fe 12936 case EM_K1OM:
aca88567 12937 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
12938 case EM_XC16X:
12939 case EM_C166:
12940 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
12941 case EM_XGATE:
12942 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
12943 case EM_XSTORMY16:
12944 return reloc_type == 1; /* R_XSTROMY16_32. */
12945 case EM_XTENSA_OLD:
12946 case EM_XTENSA:
12947 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
12948 case EM_Z80:
12949 return reloc_type == 6; /* R_Z80_32. */
aca88567 12950 default:
bee0ee85
NC
12951 {
12952 static unsigned int prev_warn = 0;
12953
12954 /* Avoid repeating the same warning multiple times. */
dda8d76d 12955 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 12956 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
12957 filedata->file_header.e_machine);
12958 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
12959 return FALSE;
12960 }
aca88567
NC
12961 }
12962}
12963
12964/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
12965 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
12966
12967static bfd_boolean
dda8d76d 12968is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 12969{
dda8d76d 12970 switch (filedata->file_header.e_machine)
d347c9df 12971 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 12972 {
41e92641 12973 case EM_386:
22abe556 12974 case EM_IAMCU:
3e0873ac 12975 return reloc_type == 2; /* R_386_PC32. */
aca88567 12976 case EM_68K:
3e0873ac 12977 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
12978 case EM_AARCH64:
12979 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
12980 case EM_ADAPTEVA_EPIPHANY:
12981 return reloc_type == 6;
aca88567
NC
12982 case EM_ALPHA:
12983 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
12984 case EM_ARC_COMPACT:
12985 case EM_ARC_COMPACT2:
12986 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 12987 case EM_ARM:
3e0873ac 12988 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
12989 case EM_AVR_OLD:
12990 case EM_AVR:
12991 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
12992 case EM_MICROBLAZE:
12993 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
12994 case EM_OR1K:
12995 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 12996 case EM_PARISC:
85acf597 12997 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
12998 case EM_PPC:
12999 return reloc_type == 26; /* R_PPC_REL32. */
13000 case EM_PPC64:
3e0873ac 13001 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13002 case EM_RISCV:
13003 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13004 case EM_S390_OLD:
13005 case EM_S390:
3e0873ac 13006 return reloc_type == 5; /* R_390_PC32. */
aca88567 13007 case EM_SH:
3e0873ac 13008 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13009 case EM_SPARC32PLUS:
13010 case EM_SPARCV9:
13011 case EM_SPARC:
3e0873ac 13012 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13013 case EM_SPU:
13014 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13015 case EM_TILEGX:
13016 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13017 case EM_TILEPRO:
13018 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13019 case EM_VISIUM:
13020 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13021 case EM_X86_64:
8a9036a4 13022 case EM_L1OM:
7a9068fe 13023 case EM_K1OM:
3e0873ac 13024 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13025 case EM_VAX:
13026 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13027 case EM_XTENSA_OLD:
13028 case EM_XTENSA:
13029 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13030 default:
13031 /* Do not abort or issue an error message here. Not all targets use
13032 pc-relative 32-bit relocs in their DWARF debug information and we
13033 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13034 more helpful warning message will be generated by apply_relocations
13035 anyway, so just return. */
aca88567
NC
13036 return FALSE;
13037 }
13038}
13039
13040/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13041 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13042
13043static bfd_boolean
dda8d76d 13044is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13045{
dda8d76d 13046 switch (filedata->file_header.e_machine)
aca88567 13047 {
a06ea964
NC
13048 case EM_AARCH64:
13049 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13050 case EM_ALPHA:
13051 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13052 case EM_IA_64:
262cdac7
AM
13053 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13054 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13055 case EM_PARISC:
13056 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13057 case EM_PPC64:
13058 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13059 case EM_RISCV:
13060 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13061 case EM_SPARC32PLUS:
13062 case EM_SPARCV9:
13063 case EM_SPARC:
714da62f
NC
13064 return reloc_type == 32 /* R_SPARC_64. */
13065 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13066 case EM_X86_64:
8a9036a4 13067 case EM_L1OM:
7a9068fe 13068 case EM_K1OM:
aca88567 13069 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13070 case EM_S390_OLD:
13071 case EM_S390:
aa137e4d
NC
13072 return reloc_type == 22; /* R_S390_64. */
13073 case EM_TILEGX:
13074 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13075 case EM_MIPS:
aa137e4d 13076 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
13077 default:
13078 return FALSE;
13079 }
13080}
13081
85acf597
RH
13082/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13083 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13084
13085static bfd_boolean
dda8d76d 13086is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13087{
dda8d76d 13088 switch (filedata->file_header.e_machine)
85acf597 13089 {
a06ea964
NC
13090 case EM_AARCH64:
13091 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13092 case EM_ALPHA:
aa137e4d 13093 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13094 case EM_IA_64:
262cdac7
AM
13095 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13096 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13097 case EM_PARISC:
aa137e4d 13098 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13099 case EM_PPC64:
aa137e4d 13100 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13101 case EM_SPARC32PLUS:
13102 case EM_SPARCV9:
13103 case EM_SPARC:
aa137e4d 13104 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13105 case EM_X86_64:
8a9036a4 13106 case EM_L1OM:
7a9068fe 13107 case EM_K1OM:
aa137e4d 13108 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13109 case EM_S390_OLD:
13110 case EM_S390:
aa137e4d
NC
13111 return reloc_type == 23; /* R_S390_PC64. */
13112 case EM_TILEGX:
13113 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
13114 default:
13115 return FALSE;
13116 }
13117}
13118
4dc3c23d
AM
13119/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13120 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13121
13122static bfd_boolean
dda8d76d 13123is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13124{
dda8d76d 13125 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13126 {
13127 case EM_CYGNUS_MN10200:
13128 case EM_MN10200:
13129 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13130 case EM_FT32:
13131 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13132 case EM_Z80:
13133 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
13134 default:
13135 return FALSE;
13136 }
13137}
13138
aca88567
NC
13139/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13140 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13141
13142static bfd_boolean
dda8d76d 13143is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13144{
d347c9df 13145 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13146 switch (filedata->file_header.e_machine)
4b78141a 13147 {
886a2506
NC
13148 case EM_ARC:
13149 case EM_ARC_COMPACT:
13150 case EM_ARC_COMPACT2:
13151 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13152 case EM_ADAPTEVA_EPIPHANY:
13153 return reloc_type == 5;
aca88567
NC
13154 case EM_AVR_OLD:
13155 case EM_AVR:
13156 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13157 case EM_CYGNUS_D10V:
13158 case EM_D10V:
13159 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13160 case EM_FT32:
13161 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13162 case EM_H8S:
13163 case EM_H8_300:
13164 case EM_H8_300H:
aca88567
NC
13165 return reloc_type == R_H8_DIR16;
13166 case EM_IP2K_OLD:
13167 case EM_IP2K:
13168 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13169 case EM_M32C_OLD:
f4236fe4
DD
13170 case EM_M32C:
13171 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13172 case EM_CYGNUS_MN10200:
13173 case EM_MN10200:
13174 return reloc_type == 2; /* R_MN10200_16. */
13175 case EM_CYGNUS_MN10300:
13176 case EM_MN10300:
13177 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13178 case EM_MSP430:
dda8d76d 13179 if (uses_msp430x_relocs (filedata))
13761a11 13180 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13181 /* Fall through. */
78c8d46c 13182 case EM_MSP430_OLD:
aca88567 13183 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13184 case EM_NDS32:
13185 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13186 case EM_ALTERA_NIOS2:
36591ba1 13187 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13188 case EM_NIOS32:
13189 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13190 case EM_OR1K:
13191 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13192 case EM_RISCV:
13193 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13194 case EM_TI_PRU:
13195 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13196 case EM_TI_C6000:
13197 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13198 case EM_VISIUM:
13199 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13200 case EM_XC16X:
13201 case EM_C166:
13202 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13203 case EM_XGATE:
13204 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13205 case EM_Z80:
13206 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13207 default:
aca88567 13208 return FALSE;
4b78141a
NC
13209 }
13210}
13211
39e07931
AS
13212/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13213 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13214
13215static bfd_boolean
13216is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13217{
13218 switch (filedata->file_header.e_machine)
13219 {
13220 case EM_RISCV:
13221 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13222 case EM_Z80:
13223 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13224 default:
13225 return FALSE;
13226 }
13227}
13228
13229/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13230 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13231
13232static bfd_boolean
13233is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13234{
13235 switch (filedata->file_header.e_machine)
13236 {
13237 case EM_RISCV:
13238 return reloc_type == 53; /* R_RISCV_SET6. */
13239 default:
13240 return FALSE;
13241 }
13242}
13243
03336641
JW
13244/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13245 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13246
13247static bfd_boolean
13248is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13249{
13250 /* Please keep this table alpha-sorted for ease of visual lookup. */
13251 switch (filedata->file_header.e_machine)
13252 {
13253 case EM_RISCV:
13254 return reloc_type == 35; /* R_RISCV_ADD32. */
13255 default:
13256 return FALSE;
13257 }
13258}
13259
13260/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13261 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13262
13263static bfd_boolean
13264is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13265{
13266 /* Please keep this table alpha-sorted for ease of visual lookup. */
13267 switch (filedata->file_header.e_machine)
13268 {
13269 case EM_RISCV:
13270 return reloc_type == 39; /* R_RISCV_SUB32. */
13271 default:
13272 return FALSE;
13273 }
13274}
13275
13276/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13277 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13278
13279static bfd_boolean
13280is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13281{
13282 /* Please keep this table alpha-sorted for ease of visual lookup. */
13283 switch (filedata->file_header.e_machine)
13284 {
13285 case EM_RISCV:
13286 return reloc_type == 36; /* R_RISCV_ADD64. */
13287 default:
13288 return FALSE;
13289 }
13290}
13291
13292/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13293 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13294
13295static bfd_boolean
13296is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13297{
13298 /* Please keep this table alpha-sorted for ease of visual lookup. */
13299 switch (filedata->file_header.e_machine)
13300 {
13301 case EM_RISCV:
13302 return reloc_type == 40; /* R_RISCV_SUB64. */
13303 default:
13304 return FALSE;
13305 }
13306}
13307
13308/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13309 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13310
13311static bfd_boolean
13312is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13313{
13314 /* Please keep this table alpha-sorted for ease of visual lookup. */
13315 switch (filedata->file_header.e_machine)
13316 {
13317 case EM_RISCV:
13318 return reloc_type == 34; /* R_RISCV_ADD16. */
13319 default:
13320 return FALSE;
13321 }
13322}
13323
13324/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13325 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13326
13327static bfd_boolean
13328is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13329{
13330 /* Please keep this table alpha-sorted for ease of visual lookup. */
13331 switch (filedata->file_header.e_machine)
13332 {
13333 case EM_RISCV:
13334 return reloc_type == 38; /* R_RISCV_SUB16. */
13335 default:
13336 return FALSE;
13337 }
13338}
13339
13340/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13341 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13342
13343static bfd_boolean
13344is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13345{
13346 /* Please keep this table alpha-sorted for ease of visual lookup. */
13347 switch (filedata->file_header.e_machine)
13348 {
13349 case EM_RISCV:
13350 return reloc_type == 33; /* R_RISCV_ADD8. */
13351 default:
13352 return FALSE;
13353 }
13354}
13355
13356/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13357 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13358
13359static bfd_boolean
13360is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13361{
13362 /* Please keep this table alpha-sorted for ease of visual lookup. */
13363 switch (filedata->file_header.e_machine)
13364 {
13365 case EM_RISCV:
13366 return reloc_type == 37; /* R_RISCV_SUB8. */
13367 default:
13368 return FALSE;
13369 }
13370}
13371
39e07931
AS
13372/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13373 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13374
13375static bfd_boolean
13376is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13377{
13378 switch (filedata->file_header.e_machine)
13379 {
13380 case EM_RISCV:
13381 return reloc_type == 52; /* R_RISCV_SUB6. */
13382 default:
13383 return FALSE;
13384 }
13385}
13386
2a7b2e88
JK
13387/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13388 relocation entries (possibly formerly used for SHT_GROUP sections). */
13389
13390static bfd_boolean
dda8d76d 13391is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13392{
dda8d76d 13393 switch (filedata->file_header.e_machine)
2a7b2e88 13394 {
cb8f3167 13395 case EM_386: /* R_386_NONE. */
d347c9df 13396 case EM_68K: /* R_68K_NONE. */
cfb8c092 13397 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13398 case EM_ALPHA: /* R_ALPHA_NONE. */
13399 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13400 case EM_ARC: /* R_ARC_NONE. */
886a2506 13401 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13402 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13403 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13404 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13405 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13406 case EM_FT32: /* R_FT32_NONE. */
13407 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13408 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13409 case EM_L1OM: /* R_X86_64_NONE. */
13410 case EM_M32R: /* R_M32R_NONE. */
13411 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13412 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13413 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13414 case EM_NIOS32: /* R_NIOS_NONE. */
13415 case EM_OR1K: /* R_OR1K_NONE. */
13416 case EM_PARISC: /* R_PARISC_NONE. */
13417 case EM_PPC64: /* R_PPC64_NONE. */
13418 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13419 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13420 case EM_S390: /* R_390_NONE. */
13421 case EM_S390_OLD:
13422 case EM_SH: /* R_SH_NONE. */
13423 case EM_SPARC32PLUS:
13424 case EM_SPARC: /* R_SPARC_NONE. */
13425 case EM_SPARCV9:
aa137e4d
NC
13426 case EM_TILEGX: /* R_TILEGX_NONE. */
13427 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13428 case EM_TI_C6000:/* R_C6000_NONE. */
13429 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13430 case EM_XC16X:
6655dba2 13431 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 13432 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13433 return reloc_type == 0;
d347c9df 13434
a06ea964
NC
13435 case EM_AARCH64:
13436 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13437 case EM_AVR_OLD:
13438 case EM_AVR:
13439 return (reloc_type == 0 /* R_AVR_NONE. */
13440 || reloc_type == 30 /* R_AVR_DIFF8. */
13441 || reloc_type == 31 /* R_AVR_DIFF16. */
13442 || reloc_type == 32 /* R_AVR_DIFF32. */);
13443 case EM_METAG:
13444 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13445 case EM_NDS32:
13446 return (reloc_type == 0 /* R_XTENSA_NONE. */
13447 || reloc_type == 204 /* R_NDS32_DIFF8. */
13448 || reloc_type == 205 /* R_NDS32_DIFF16. */
13449 || reloc_type == 206 /* R_NDS32_DIFF32. */
13450 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13451 case EM_TI_PRU:
13452 return (reloc_type == 0 /* R_PRU_NONE. */
13453 || reloc_type == 65 /* R_PRU_DIFF8. */
13454 || reloc_type == 66 /* R_PRU_DIFF16. */
13455 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13456 case EM_XTENSA_OLD:
13457 case EM_XTENSA:
4dc3c23d
AM
13458 return (reloc_type == 0 /* R_XTENSA_NONE. */
13459 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13460 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
13461 || reloc_type == 19 /* R_XTENSA_DIFF32. */
13462 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
13463 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
13464 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
13465 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
13466 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
13467 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88
JK
13468 }
13469 return FALSE;
13470}
13471
d1c4b12b
NC
13472/* Returns TRUE if there is a relocation against
13473 section NAME at OFFSET bytes. */
13474
13475bfd_boolean
13476reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13477{
13478 Elf_Internal_Rela * relocs;
13479 Elf_Internal_Rela * rp;
13480
13481 if (dsec == NULL || dsec->reloc_info == NULL)
13482 return FALSE;
13483
13484 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13485
13486 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13487 if (rp->r_offset == offset)
13488 return TRUE;
13489
13490 return FALSE;
13491}
13492
cf13d699 13493/* Apply relocations to a section.
32ec8896
NC
13494 Returns TRUE upon success, FALSE otherwise.
13495 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13496 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13497 will be set to the number of relocs loaded.
13498
cf13d699 13499 Note: So far support has been added only for those relocations
32ec8896
NC
13500 which can be found in debug sections. FIXME: Add support for
13501 more relocations ? */
1b315056 13502
32ec8896 13503static bfd_boolean
dda8d76d 13504apply_relocations (Filedata * filedata,
d1c4b12b
NC
13505 const Elf_Internal_Shdr * section,
13506 unsigned char * start,
13507 bfd_size_type size,
1449284b 13508 void ** relocs_return,
d1c4b12b 13509 unsigned long * num_relocs_return)
1b315056 13510{
cf13d699 13511 Elf_Internal_Shdr * relsec;
0d2a7a93 13512 unsigned char * end = start + size;
cb8f3167 13513
d1c4b12b
NC
13514 if (relocs_return != NULL)
13515 {
13516 * (Elf_Internal_Rela **) relocs_return = NULL;
13517 * num_relocs_return = 0;
13518 }
13519
dda8d76d 13520 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13521 /* No relocs to apply. */
13522 return TRUE;
1b315056 13523
cf13d699 13524 /* Find the reloc section associated with the section. */
dda8d76d
NC
13525 for (relsec = filedata->section_headers;
13526 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13527 ++relsec)
252b5132 13528 {
41e92641
NC
13529 bfd_boolean is_rela;
13530 unsigned long num_relocs;
2cf0635d
NC
13531 Elf_Internal_Rela * relocs;
13532 Elf_Internal_Rela * rp;
13533 Elf_Internal_Shdr * symsec;
13534 Elf_Internal_Sym * symtab;
ba5cdace 13535 unsigned long num_syms;
2cf0635d 13536 Elf_Internal_Sym * sym;
252b5132 13537
41e92641 13538 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13539 || relsec->sh_info >= filedata->file_header.e_shnum
13540 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13541 || relsec->sh_size == 0
dda8d76d 13542 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13543 continue;
428409d5 13544
a788aedd
AM
13545 symsec = filedata->section_headers + relsec->sh_link;
13546 if (symsec->sh_type != SHT_SYMTAB
13547 && symsec->sh_type != SHT_DYNSYM)
13548 return FALSE;
13549
41e92641
NC
13550 is_rela = relsec->sh_type == SHT_RELA;
13551
13552 if (is_rela)
13553 {
dda8d76d 13554 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13555 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13556 return FALSE;
41e92641
NC
13557 }
13558 else
13559 {
dda8d76d 13560 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13561 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13562 return FALSE;
41e92641
NC
13563 }
13564
13565 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13566 if (filedata->file_header.e_machine == EM_SH)
41e92641 13567 is_rela = FALSE;
428409d5 13568
dda8d76d 13569 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13570
41e92641 13571 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13572 {
41e92641
NC
13573 bfd_vma addend;
13574 unsigned int reloc_type;
13575 unsigned int reloc_size;
03336641
JW
13576 bfd_boolean reloc_inplace = FALSE;
13577 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 13578 unsigned char * rloc;
ba5cdace 13579 unsigned long sym_index;
4b78141a 13580
dda8d76d 13581 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 13582
dda8d76d 13583 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 13584 continue;
dda8d76d 13585 else if (is_none_reloc (filedata, reloc_type))
98fb390a 13586 continue;
dda8d76d
NC
13587 else if (is_32bit_abs_reloc (filedata, reloc_type)
13588 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 13589 reloc_size = 4;
dda8d76d
NC
13590 else if (is_64bit_abs_reloc (filedata, reloc_type)
13591 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 13592 reloc_size = 8;
dda8d76d 13593 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 13594 reloc_size = 3;
dda8d76d 13595 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 13596 reloc_size = 2;
39e07931
AS
13597 else if (is_8bit_abs_reloc (filedata, reloc_type)
13598 || is_6bit_abs_reloc (filedata, reloc_type))
13599 reloc_size = 1;
03336641
JW
13600 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
13601 reloc_type))
13602 || is_32bit_inplace_add_reloc (filedata, reloc_type))
13603 {
13604 reloc_size = 4;
13605 reloc_inplace = TRUE;
13606 }
13607 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
13608 reloc_type))
13609 || is_64bit_inplace_add_reloc (filedata, reloc_type))
13610 {
13611 reloc_size = 8;
13612 reloc_inplace = TRUE;
13613 }
13614 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
13615 reloc_type))
13616 || is_16bit_inplace_add_reloc (filedata, reloc_type))
13617 {
13618 reloc_size = 2;
13619 reloc_inplace = TRUE;
13620 }
13621 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
13622 reloc_type))
13623 || is_8bit_inplace_add_reloc (filedata, reloc_type))
13624 {
13625 reloc_size = 1;
13626 reloc_inplace = TRUE;
13627 }
39e07931
AS
13628 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
13629 reloc_type)))
13630 {
13631 reloc_size = 1;
13632 reloc_inplace = TRUE;
13633 }
aca88567 13634 else
4b78141a 13635 {
bee0ee85 13636 static unsigned int prev_reloc = 0;
dda8d76d 13637
bee0ee85
NC
13638 if (reloc_type != prev_reloc)
13639 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 13640 reloc_type, printable_section_name (filedata, section));
bee0ee85 13641 prev_reloc = reloc_type;
4b78141a
NC
13642 continue;
13643 }
103f02d3 13644
91d6fa6a 13645 rloc = start + rp->r_offset;
75802ccb 13646 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
13647 {
13648 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
13649 (unsigned long) rp->r_offset,
dda8d76d 13650 printable_section_name (filedata, section));
700dd8b7
L
13651 continue;
13652 }
103f02d3 13653
ba5cdace
NC
13654 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
13655 if (sym_index >= num_syms)
13656 {
13657 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 13658 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
13659 continue;
13660 }
13661 sym = symtab + sym_index;
41e92641
NC
13662
13663 /* If the reloc has a symbol associated with it,
55f25fc3
L
13664 make sure that it is of an appropriate type.
13665
13666 Relocations against symbols without type can happen.
13667 Gcc -feliminate-dwarf2-dups may generate symbols
13668 without type for debug info.
13669
13670 Icc generates relocations against function symbols
13671 instead of local labels.
13672
13673 Relocations against object symbols can happen, eg when
13674 referencing a global array. For an example of this see
13675 the _clz.o binary in libgcc.a. */
aca88567 13676 if (sym != symtab
b8871f35 13677 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 13678 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 13679 {
d3a49aa8 13680 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
13681 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
13682 printable_section_name (filedata, relsec),
d3a49aa8 13683 (long int)(rp - relocs));
aca88567 13684 continue;
5b18a4bc 13685 }
252b5132 13686
4dc3c23d
AM
13687 addend = 0;
13688 if (is_rela)
13689 addend += rp->r_addend;
c47320c3
AM
13690 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
13691 partial_inplace. */
4dc3c23d 13692 if (!is_rela
dda8d76d 13693 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 13694 && reloc_type == 1)
dda8d76d
NC
13695 || ((filedata->file_header.e_machine == EM_PJ
13696 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 13697 && reloc_type == 1)
dda8d76d
NC
13698 || ((filedata->file_header.e_machine == EM_D30V
13699 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
13700 && reloc_type == 12)
13701 || reloc_inplace)
39e07931
AS
13702 {
13703 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
13704 addend += byte_get (rloc, reloc_size) & 0x3f;
13705 else
13706 addend += byte_get (rloc, reloc_size);
13707 }
cb8f3167 13708
dda8d76d
NC
13709 if (is_32bit_pcrel_reloc (filedata, reloc_type)
13710 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
13711 {
13712 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 13713 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 13714 addend -= 8;
91d6fa6a 13715 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
13716 reloc_size);
13717 }
39e07931
AS
13718 else if (is_6bit_abs_reloc (filedata, reloc_type)
13719 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
13720 {
13721 if (reloc_subtract)
13722 addend -= sym->st_value;
13723 else
13724 addend += sym->st_value;
13725 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
13726 byte_put (rloc, addend, reloc_size);
13727 }
03336641
JW
13728 else if (reloc_subtract)
13729 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 13730 else
91d6fa6a 13731 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 13732 }
252b5132 13733
5b18a4bc 13734 free (symtab);
f84ce13b
NC
13735 /* Let the target specific reloc processing code know that
13736 we have finished with these relocs. */
dda8d76d 13737 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
13738
13739 if (relocs_return)
13740 {
13741 * (Elf_Internal_Rela **) relocs_return = relocs;
13742 * num_relocs_return = num_relocs;
13743 }
13744 else
13745 free (relocs);
13746
5b18a4bc
NC
13747 break;
13748 }
32ec8896 13749
dfc616fa 13750 return TRUE;
5b18a4bc 13751}
103f02d3 13752
cf13d699 13753#ifdef SUPPORT_DISASSEMBLY
32ec8896 13754static bfd_boolean
dda8d76d 13755disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13756{
dda8d76d 13757 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 13758
74e1a04b 13759 /* FIXME: XXX -- to be done --- XXX */
cf13d699 13760
32ec8896 13761 return TRUE;
cf13d699
NC
13762}
13763#endif
13764
13765/* Reads in the contents of SECTION from FILE, returning a pointer
13766 to a malloc'ed buffer or NULL if something went wrong. */
13767
13768static char *
dda8d76d 13769get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13770{
dda8d76d 13771 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
13772
13773 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
13774 {
c6b78c96 13775 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 13776 printable_section_name (filedata, section));
cf13d699
NC
13777 return NULL;
13778 }
13779
dda8d76d 13780 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 13781 _("section contents"));
cf13d699
NC
13782}
13783
0e602686
NC
13784/* Uncompresses a section that was compressed using zlib, in place. */
13785
13786static bfd_boolean
dda8d76d
NC
13787uncompress_section_contents (unsigned char ** buffer,
13788 dwarf_size_type uncompressed_size,
13789 dwarf_size_type * size)
0e602686
NC
13790{
13791 dwarf_size_type compressed_size = *size;
13792 unsigned char * compressed_buffer = *buffer;
13793 unsigned char * uncompressed_buffer;
13794 z_stream strm;
13795 int rc;
13796
13797 /* It is possible the section consists of several compressed
13798 buffers concatenated together, so we uncompress in a loop. */
13799 /* PR 18313: The state field in the z_stream structure is supposed
13800 to be invisible to the user (ie us), but some compilers will
13801 still complain about it being used without initialisation. So
13802 we first zero the entire z_stream structure and then set the fields
13803 that we need. */
13804 memset (& strm, 0, sizeof strm);
13805 strm.avail_in = compressed_size;
13806 strm.next_in = (Bytef *) compressed_buffer;
13807 strm.avail_out = uncompressed_size;
13808 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
13809
13810 rc = inflateInit (& strm);
13811 while (strm.avail_in > 0)
13812 {
13813 if (rc != Z_OK)
13814 goto fail;
13815 strm.next_out = ((Bytef *) uncompressed_buffer
13816 + (uncompressed_size - strm.avail_out));
13817 rc = inflate (&strm, Z_FINISH);
13818 if (rc != Z_STREAM_END)
13819 goto fail;
13820 rc = inflateReset (& strm);
13821 }
13822 rc = inflateEnd (& strm);
13823 if (rc != Z_OK
13824 || strm.avail_out != 0)
13825 goto fail;
13826
13827 *buffer = uncompressed_buffer;
13828 *size = uncompressed_size;
13829 return TRUE;
13830
13831 fail:
13832 free (uncompressed_buffer);
13833 /* Indicate decompression failure. */
13834 *buffer = NULL;
13835 return FALSE;
13836}
dd24e3da 13837
32ec8896 13838static bfd_boolean
dda8d76d 13839dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 13840{
0e602686
NC
13841 Elf_Internal_Shdr * relsec;
13842 bfd_size_type num_bytes;
fd8008d8
L
13843 unsigned char * data;
13844 unsigned char * end;
13845 unsigned char * real_start;
13846 unsigned char * start;
0e602686 13847 bfd_boolean some_strings_shown;
cf13d699 13848
dda8d76d 13849 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 13850 if (start == NULL)
c6b78c96
NC
13851 /* PR 21820: Do not fail if the section was empty. */
13852 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
13853
0e602686 13854 num_bytes = section->sh_size;
cf13d699 13855
dda8d76d 13856 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 13857
0e602686
NC
13858 if (decompress_dumps)
13859 {
13860 dwarf_size_type new_size = num_bytes;
13861 dwarf_size_type uncompressed_size = 0;
13862
13863 if ((section->sh_flags & SHF_COMPRESSED) != 0)
13864 {
13865 Elf_Internal_Chdr chdr;
13866 unsigned int compression_header_size
ebdf1ebf
NC
13867 = get_compression_header (& chdr, (unsigned char *) start,
13868 num_bytes);
5844b465
NC
13869 if (compression_header_size == 0)
13870 /* An error message will have already been generated
13871 by get_compression_header. */
13872 goto error_out;
0e602686 13873
813dabb9 13874 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 13875 {
813dabb9 13876 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 13877 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 13878 goto error_out;
813dabb9 13879 }
813dabb9
L
13880 uncompressed_size = chdr.ch_size;
13881 start += compression_header_size;
13882 new_size -= compression_header_size;
0e602686
NC
13883 }
13884 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
13885 {
13886 /* Read the zlib header. In this case, it should be "ZLIB"
13887 followed by the uncompressed section size, 8 bytes in
13888 big-endian order. */
13889 uncompressed_size = start[4]; uncompressed_size <<= 8;
13890 uncompressed_size += start[5]; uncompressed_size <<= 8;
13891 uncompressed_size += start[6]; uncompressed_size <<= 8;
13892 uncompressed_size += start[7]; uncompressed_size <<= 8;
13893 uncompressed_size += start[8]; uncompressed_size <<= 8;
13894 uncompressed_size += start[9]; uncompressed_size <<= 8;
13895 uncompressed_size += start[10]; uncompressed_size <<= 8;
13896 uncompressed_size += start[11];
13897 start += 12;
13898 new_size -= 12;
13899 }
13900
1835f746
NC
13901 if (uncompressed_size)
13902 {
13903 if (uncompress_section_contents (& start,
13904 uncompressed_size, & new_size))
13905 num_bytes = new_size;
13906 else
13907 {
13908 error (_("Unable to decompress section %s\n"),
dda8d76d 13909 printable_section_name (filedata, section));
f761cb13 13910 goto error_out;
1835f746
NC
13911 }
13912 }
bc303e5d
NC
13913 else
13914 start = real_start;
0e602686 13915 }
fd8008d8 13916
cf13d699
NC
13917 /* If the section being dumped has relocations against it the user might
13918 be expecting these relocations to have been applied. Check for this
13919 case and issue a warning message in order to avoid confusion.
13920 FIXME: Maybe we ought to have an option that dumps a section with
13921 relocs applied ? */
dda8d76d
NC
13922 for (relsec = filedata->section_headers;
13923 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
13924 ++relsec)
13925 {
13926 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13927 || relsec->sh_info >= filedata->file_header.e_shnum
13928 || filedata->section_headers + relsec->sh_info != section
cf13d699 13929 || relsec->sh_size == 0
dda8d76d 13930 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
13931 continue;
13932
13933 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
13934 break;
13935 }
13936
cf13d699
NC
13937 data = start;
13938 end = start + num_bytes;
13939 some_strings_shown = FALSE;
13940
ba3265d0
NC
13941#ifdef HAVE_MBSTATE_T
13942 mbstate_t state;
13943 /* Initialise the multibyte conversion state. */
13944 memset (& state, 0, sizeof (state));
13945#endif
13946
13947 bfd_boolean continuing = FALSE;
13948
cf13d699
NC
13949 while (data < end)
13950 {
13951 while (!ISPRINT (* data))
13952 if (++ data >= end)
13953 break;
13954
13955 if (data < end)
13956 {
071436c6
NC
13957 size_t maxlen = end - data;
13958
ba3265d0
NC
13959 if (continuing)
13960 {
13961 printf (" ");
13962 continuing = FALSE;
13963 }
13964 else
13965 {
d1ce973e 13966 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
13967 }
13968
4082ef84
NC
13969 if (maxlen > 0)
13970 {
f3da8a96 13971 char c = 0;
ba3265d0
NC
13972
13973 while (maxlen)
13974 {
13975 c = *data++;
13976
13977 if (c == 0)
13978 break;
13979
13980 /* PR 25543: Treat new-lines as string-ending characters. */
13981 if (c == '\n')
13982 {
13983 printf ("\\n\n");
13984 if (*data != 0)
13985 continuing = TRUE;
13986 break;
13987 }
13988
13989 /* Do not print control characters directly as they can affect terminal
13990 settings. Such characters usually appear in the names generated
13991 by the assembler for local labels. */
13992 if (ISCNTRL (c))
13993 {
13994 printf ("^%c", c + 0x40);
13995 }
13996 else if (ISPRINT (c))
13997 {
13998 putchar (c);
13999 }
14000 else
14001 {
14002 size_t n;
14003#ifdef HAVE_MBSTATE_T
14004 wchar_t w;
14005#endif
14006 /* Let printf do the hard work of displaying multibyte characters. */
14007 printf ("%.1s", data - 1);
14008#ifdef HAVE_MBSTATE_T
14009 /* Try to find out how many bytes made up the character that was
14010 just printed. Advance the symbol pointer past the bytes that
14011 were displayed. */
14012 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14013#else
14014 n = 1;
14015#endif
14016 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14017 data += (n - 1);
14018 }
14019 }
14020
14021 if (c != '\n')
14022 putchar ('\n');
4082ef84
NC
14023 }
14024 else
14025 {
14026 printf (_("<corrupt>\n"));
14027 data = end;
14028 }
cf13d699
NC
14029 some_strings_shown = TRUE;
14030 }
14031 }
14032
14033 if (! some_strings_shown)
14034 printf (_(" No strings found in this section."));
14035
0e602686 14036 free (real_start);
cf13d699
NC
14037
14038 putchar ('\n');
32ec8896 14039 return TRUE;
f761cb13
AM
14040
14041error_out:
14042 free (real_start);
14043 return FALSE;
cf13d699
NC
14044}
14045
32ec8896 14046static bfd_boolean
dda8d76d
NC
14047dump_section_as_bytes (Elf_Internal_Shdr * section,
14048 Filedata * filedata,
14049 bfd_boolean relocate)
cf13d699
NC
14050{
14051 Elf_Internal_Shdr * relsec;
0e602686
NC
14052 bfd_size_type bytes;
14053 bfd_size_type section_size;
14054 bfd_vma addr;
14055 unsigned char * data;
14056 unsigned char * real_start;
14057 unsigned char * start;
14058
dda8d76d 14059 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14060 if (start == NULL)
c6b78c96
NC
14061 /* PR 21820: Do not fail if the section was empty. */
14062 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 14063
0e602686 14064 section_size = section->sh_size;
cf13d699 14065
dda8d76d 14066 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14067
0e602686
NC
14068 if (decompress_dumps)
14069 {
14070 dwarf_size_type new_size = section_size;
14071 dwarf_size_type uncompressed_size = 0;
14072
14073 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14074 {
14075 Elf_Internal_Chdr chdr;
14076 unsigned int compression_header_size
ebdf1ebf 14077 = get_compression_header (& chdr, start, section_size);
0e602686 14078
5844b465
NC
14079 if (compression_header_size == 0)
14080 /* An error message will have already been generated
14081 by get_compression_header. */
14082 goto error_out;
14083
813dabb9 14084 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14085 {
813dabb9 14086 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14087 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14088 goto error_out;
0e602686 14089 }
813dabb9
L
14090 uncompressed_size = chdr.ch_size;
14091 start += compression_header_size;
14092 new_size -= compression_header_size;
0e602686
NC
14093 }
14094 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14095 {
14096 /* Read the zlib header. In this case, it should be "ZLIB"
14097 followed by the uncompressed section size, 8 bytes in
14098 big-endian order. */
14099 uncompressed_size = start[4]; uncompressed_size <<= 8;
14100 uncompressed_size += start[5]; uncompressed_size <<= 8;
14101 uncompressed_size += start[6]; uncompressed_size <<= 8;
14102 uncompressed_size += start[7]; uncompressed_size <<= 8;
14103 uncompressed_size += start[8]; uncompressed_size <<= 8;
14104 uncompressed_size += start[9]; uncompressed_size <<= 8;
14105 uncompressed_size += start[10]; uncompressed_size <<= 8;
14106 uncompressed_size += start[11];
14107 start += 12;
14108 new_size -= 12;
14109 }
14110
f055032e
NC
14111 if (uncompressed_size)
14112 {
14113 if (uncompress_section_contents (& start, uncompressed_size,
14114 & new_size))
bc303e5d
NC
14115 {
14116 section_size = new_size;
14117 }
f055032e
NC
14118 else
14119 {
14120 error (_("Unable to decompress section %s\n"),
dda8d76d 14121 printable_section_name (filedata, section));
bc303e5d 14122 /* FIXME: Print the section anyway ? */
f761cb13 14123 goto error_out;
f055032e
NC
14124 }
14125 }
bc303e5d
NC
14126 else
14127 start = real_start;
0e602686 14128 }
14ae95f2 14129
cf13d699
NC
14130 if (relocate)
14131 {
dda8d76d 14132 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14133 goto error_out;
cf13d699
NC
14134 }
14135 else
14136 {
14137 /* If the section being dumped has relocations against it the user might
14138 be expecting these relocations to have been applied. Check for this
14139 case and issue a warning message in order to avoid confusion.
14140 FIXME: Maybe we ought to have an option that dumps a section with
14141 relocs applied ? */
dda8d76d
NC
14142 for (relsec = filedata->section_headers;
14143 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14144 ++relsec)
14145 {
14146 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14147 || relsec->sh_info >= filedata->file_header.e_shnum
14148 || filedata->section_headers + relsec->sh_info != section
cf13d699 14149 || relsec->sh_size == 0
dda8d76d 14150 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14151 continue;
14152
14153 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14154 break;
14155 }
14156 }
14157
14158 addr = section->sh_addr;
0e602686 14159 bytes = section_size;
cf13d699
NC
14160 data = start;
14161
14162 while (bytes)
14163 {
14164 int j;
14165 int k;
14166 int lbytes;
14167
14168 lbytes = (bytes > 16 ? 16 : bytes);
14169
14170 printf (" 0x%8.8lx ", (unsigned long) addr);
14171
14172 for (j = 0; j < 16; j++)
14173 {
14174 if (j < lbytes)
14175 printf ("%2.2x", data[j]);
14176 else
14177 printf (" ");
14178
14179 if ((j & 3) == 3)
14180 printf (" ");
14181 }
14182
14183 for (j = 0; j < lbytes; j++)
14184 {
14185 k = data[j];
14186 if (k >= ' ' && k < 0x7f)
14187 printf ("%c", k);
14188 else
14189 printf (".");
14190 }
14191
14192 putchar ('\n');
14193
14194 data += lbytes;
14195 addr += lbytes;
14196 bytes -= lbytes;
14197 }
14198
0e602686 14199 free (real_start);
cf13d699
NC
14200
14201 putchar ('\n');
32ec8896 14202 return TRUE;
f761cb13
AM
14203
14204 error_out:
14205 free (real_start);
14206 return FALSE;
cf13d699
NC
14207}
14208
094e34f2 14209#ifdef ENABLE_LIBCTF
7d9813f1
NA
14210static ctf_sect_t *
14211shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14212{
90bd5423 14213 buf->cts_name = SECTION_NAME (shdr);
7d9813f1
NA
14214 buf->cts_size = shdr->sh_size;
14215 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14216
14217 return buf;
14218}
14219
14220/* Formatting callback function passed to ctf_dump. Returns either the pointer
14221 it is passed, or a pointer to newly-allocated storage, in which case
14222 dump_ctf() will free it when it no longer needs it. */
14223
2f6ecaed
NA
14224static char *
14225dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14226 char *s, void *arg)
7d9813f1 14227{
3e50a591 14228 const char *blanks = arg;
7d9813f1
NA
14229 char *new_s;
14230
3e50a591 14231 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14232 return s;
14233 return new_s;
14234}
14235
2f6ecaed
NA
14236/* Dump one CTF archive member. */
14237
14238static int
14239dump_ctf_archive_member (ctf_file_t *ctf, const char *name, void *arg)
14240{
14241 ctf_file_t *parent = (ctf_file_t *) arg;
14242 const char *things[] = {"Header", "Labels", "Data objects",
14243 "Function objects", "Variables", "Types", "Strings",
14244 ""};
14245 const char **thing;
8b37e7b6
NA
14246 ctf_next_t *it = NULL;
14247 char *errtext;
14248 int is_warning;
2f6ecaed 14249 size_t i;
8b37e7b6 14250 int err = 0;
2f6ecaed
NA
14251
14252 /* Only print out the name of non-default-named archive members.
14253 The name .ctf appears everywhere, even for things that aren't
14254 really archives, so printing it out is liable to be confusing.
14255
14256 The parent, if there is one, is the default-owned archive member:
14257 avoid importing it into itself. (This does no harm, but looks
14258 confusing.) */
14259
14260 if (strcmp (name, ".ctf") != 0)
14261 {
14262 printf (_("\nCTF archive member: %s:\n"), name);
14263 ctf_import (ctf, parent);
14264 }
14265
14266 for (i = 0, thing = things; *thing[0]; thing++, i++)
14267 {
14268 ctf_dump_state_t *s = NULL;
14269 char *item;
14270
14271 printf ("\n %s:\n", *thing);
14272 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14273 (void *) " ")) != NULL)
14274 {
14275 printf ("%s\n", item);
14276 free (item);
14277 }
14278
14279 if (ctf_errno (ctf))
14280 {
14281 error (_("Iteration failed: %s, %s\n"), *thing,
14282 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
14283 err = 1;
14284 goto out;
2f6ecaed
NA
14285 }
14286 }
8b37e7b6
NA
14287
14288 out:
14289 /* Dump accumulated errors and warnings. */
14290 while ((errtext = ctf_errwarning_next (ctf, &it, &is_warning)) != NULL)
14291 {
14292 error (_("%s: `%s'\n"), is_warning ? _("warning"): _("error"),
14293 errtext);
14294 free (errtext);
14295 }
14296 if (ctf_errno (ctf) != ECTF_NEXT_END)
14297 {
14298 error (_("CTF error: cannot get CTF errors: `%s'\n"),
14299 ctf_errmsg (ctf_errno (ctf)));
14300 }
14301 return err;
2f6ecaed
NA
14302}
14303
7d9813f1
NA
14304static bfd_boolean
14305dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14306{
14307 Elf_Internal_Shdr * parent_sec = NULL;
14308 Elf_Internal_Shdr * symtab_sec = NULL;
14309 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14310 void * data = NULL;
14311 void * symdata = NULL;
14312 void * strdata = NULL;
14313 void * parentdata = NULL;
14314 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14315 ctf_sect_t * symsectp = NULL;
14316 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
14317 ctf_archive_t * ctfa = NULL;
14318 ctf_archive_t * parenta = NULL, *lookparent;
14319 ctf_file_t * parent = NULL;
7d9813f1 14320
7d9813f1
NA
14321 int err;
14322 bfd_boolean ret = FALSE;
7d9813f1
NA
14323
14324 shdr_to_ctf_sect (&ctfsect, section, filedata);
14325 data = get_section_contents (section, filedata);
14326 ctfsect.cts_data = data;
14327
616febde
NA
14328 if (!dump_ctf_symtab_name)
14329 dump_ctf_symtab_name = strdup (".symtab");
14330
14331 if (!dump_ctf_strtab_name)
14332 dump_ctf_strtab_name = strdup (".strtab");
14333
14334 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14335 {
14336 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14337 {
14338 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14339 goto fail;
14340 }
14341 if ((symdata = (void *) get_data (NULL, filedata,
14342 symtab_sec->sh_offset, 1,
14343 symtab_sec->sh_size,
14344 _("symbols"))) == NULL)
14345 goto fail;
14346 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14347 symsect.cts_data = symdata;
14348 }
df16e041 14349 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
14350 {
14351 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14352 {
14353 error (_("No string table section named %s\n"),
14354 dump_ctf_strtab_name);
14355 goto fail;
14356 }
14357 if ((strdata = (void *) get_data (NULL, filedata,
14358 strtab_sec->sh_offset, 1,
14359 strtab_sec->sh_size,
14360 _("strings"))) == NULL)
14361 goto fail;
14362 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14363 strsect.cts_data = strdata;
14364 }
14365 if (dump_ctf_parent_name)
14366 {
14367 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14368 {
14369 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14370 goto fail;
14371 }
14372 if ((parentdata = (void *) get_data (NULL, filedata,
14373 parent_sec->sh_offset, 1,
14374 parent_sec->sh_size,
14375 _("CTF parent"))) == NULL)
14376 goto fail;
14377 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14378 parentsect.cts_data = parentdata;
14379 }
14380
2f6ecaed
NA
14381 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
14382 libctf papers over the difference, so we can pretend it is always an
14383 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 14384
2f6ecaed 14385 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1
NA
14386 {
14387 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14388 goto fail;
14389 }
14390
14391 if (parentdata)
14392 {
2f6ecaed
NA
14393 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
14394 &err)) == NULL)
7d9813f1
NA
14395 {
14396 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14397 goto fail;
14398 }
2f6ecaed
NA
14399 lookparent = parenta;
14400 }
14401 else
14402 lookparent = ctfa;
7d9813f1 14403
2f6ecaed
NA
14404 /* Assume that the applicable parent archive member is the default one.
14405 (This is what all known implementations are expected to do, if they
14406 put CTFs and their parents in archives together.) */
14407 if ((parent = ctf_arc_open_by_name (lookparent, NULL, &err)) == NULL)
14408 {
14409 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14410 goto fail;
7d9813f1
NA
14411 }
14412
14413 ret = TRUE;
14414
14415 printf (_("\nDump of CTF section '%s':\n"),
14416 printable_section_name (filedata, section));
14417
2f6ecaed
NA
14418 if (ctf_archive_iter (ctfa, dump_ctf_archive_member, parent) != 0)
14419 ret = FALSE;
7d9813f1
NA
14420
14421 fail:
7d9813f1 14422 ctf_file_close (parent);
2f6ecaed
NA
14423 ctf_close (ctfa);
14424 ctf_close (parenta);
7d9813f1
NA
14425 free (parentdata);
14426 free (data);
14427 free (symdata);
14428 free (strdata);
14429 return ret;
14430}
094e34f2 14431#endif
7d9813f1 14432
32ec8896 14433static bfd_boolean
dda8d76d
NC
14434load_specific_debug_section (enum dwarf_section_display_enum debug,
14435 const Elf_Internal_Shdr * sec,
14436 void * data)
1007acb3 14437{
2cf0635d 14438 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 14439 char buf [64];
dda8d76d 14440 Filedata * filedata = (Filedata *) data;
9abca702 14441
19e6b90e 14442 if (section->start != NULL)
dda8d76d
NC
14443 {
14444 /* If it is already loaded, do nothing. */
14445 if (streq (section->filename, filedata->file_name))
14446 return TRUE;
14447 free (section->start);
14448 }
1007acb3 14449
19e6b90e
L
14450 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
14451 section->address = sec->sh_addr;
06614111 14452 section->user_data = NULL;
dda8d76d
NC
14453 section->filename = filedata->file_name;
14454 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
14455 sec->sh_offset, 1,
14456 sec->sh_size, buf);
59245841
NC
14457 if (section->start == NULL)
14458 section->size = 0;
14459 else
14460 {
77115a4a
L
14461 unsigned char *start = section->start;
14462 dwarf_size_type size = sec->sh_size;
dab394de 14463 dwarf_size_type uncompressed_size = 0;
77115a4a
L
14464
14465 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
14466 {
14467 Elf_Internal_Chdr chdr;
d8024a91
NC
14468 unsigned int compression_header_size;
14469
f53be977
L
14470 if (size < (is_32bit_elf
14471 ? sizeof (Elf32_External_Chdr)
14472 : sizeof (Elf64_External_Chdr)))
d8024a91 14473 {
55be8fd0 14474 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 14475 section->name);
32ec8896 14476 return FALSE;
d8024a91
NC
14477 }
14478
ebdf1ebf 14479 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
14480 if (compression_header_size == 0)
14481 /* An error message will have already been generated
14482 by get_compression_header. */
14483 return FALSE;
d8024a91 14484
813dabb9
L
14485 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
14486 {
14487 warn (_("section '%s' has unsupported compress type: %d\n"),
14488 section->name, chdr.ch_type);
32ec8896 14489 return FALSE;
813dabb9 14490 }
dab394de 14491 uncompressed_size = chdr.ch_size;
77115a4a
L
14492 start += compression_header_size;
14493 size -= compression_header_size;
14494 }
dab394de
L
14495 else if (size > 12 && streq ((char *) start, "ZLIB"))
14496 {
14497 /* Read the zlib header. In this case, it should be "ZLIB"
14498 followed by the uncompressed section size, 8 bytes in
14499 big-endian order. */
14500 uncompressed_size = start[4]; uncompressed_size <<= 8;
14501 uncompressed_size += start[5]; uncompressed_size <<= 8;
14502 uncompressed_size += start[6]; uncompressed_size <<= 8;
14503 uncompressed_size += start[7]; uncompressed_size <<= 8;
14504 uncompressed_size += start[8]; uncompressed_size <<= 8;
14505 uncompressed_size += start[9]; uncompressed_size <<= 8;
14506 uncompressed_size += start[10]; uncompressed_size <<= 8;
14507 uncompressed_size += start[11];
14508 start += 12;
14509 size -= 12;
14510 }
14511
1835f746 14512 if (uncompressed_size)
77115a4a 14513 {
1835f746
NC
14514 if (uncompress_section_contents (&start, uncompressed_size,
14515 &size))
14516 {
14517 /* Free the compressed buffer, update the section buffer
14518 and the section size if uncompress is successful. */
14519 free (section->start);
14520 section->start = start;
14521 }
14522 else
14523 {
14524 error (_("Unable to decompress section %s\n"),
dda8d76d 14525 printable_section_name (filedata, sec));
32ec8896 14526 return FALSE;
1835f746 14527 }
77115a4a 14528 }
bc303e5d 14529
77115a4a 14530 section->size = size;
59245841 14531 }
4a114e3e 14532
1b315056 14533 if (section->start == NULL)
32ec8896 14534 return FALSE;
1b315056 14535
19e6b90e 14536 if (debug_displays [debug].relocate)
32ec8896 14537 {
dda8d76d 14538 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
14539 & section->reloc_info, & section->num_relocs))
14540 return FALSE;
14541 }
d1c4b12b
NC
14542 else
14543 {
14544 section->reloc_info = NULL;
14545 section->num_relocs = 0;
14546 }
1007acb3 14547
32ec8896 14548 return TRUE;
1007acb3
L
14549}
14550
301a9420
AM
14551#if HAVE_LIBDEBUGINFOD
14552/* Return a hex string representation of the build-id. */
14553unsigned char *
14554get_build_id (void * data)
14555{
14556 Filedata * filedata = (Filedata *)data;
14557 Elf_Internal_Shdr * shdr;
14558 unsigned long i;
14559
55be8fd0
NC
14560 /* Iterate through notes to find note.gnu.build-id.
14561 FIXME: Only the first note in any note section is examined. */
301a9420
AM
14562 for (i = 0, shdr = filedata->section_headers;
14563 i < filedata->file_header.e_shnum && shdr != NULL;
14564 i++, shdr++)
14565 {
14566 if (shdr->sh_type != SHT_NOTE)
14567 continue;
14568
14569 char * next;
14570 char * end;
14571 size_t data_remaining;
14572 size_t min_notesz;
14573 Elf_External_Note * enote;
14574 Elf_Internal_Note inote;
14575
14576 bfd_vma offset = shdr->sh_offset;
14577 bfd_vma align = shdr->sh_addralign;
14578 bfd_vma length = shdr->sh_size;
14579
14580 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
14581 if (enote == NULL)
14582 continue;
14583
14584 if (align < 4)
14585 align = 4;
14586 else if (align != 4 && align != 8)
f761cb13
AM
14587 {
14588 free (enote);
14589 continue;
14590 }
301a9420
AM
14591
14592 end = (char *) enote + length;
14593 data_remaining = end - (char *) enote;
14594
14595 if (!is_ia64_vms (filedata))
14596 {
14597 min_notesz = offsetof (Elf_External_Note, name);
14598 if (data_remaining < min_notesz)
14599 {
55be8fd0
NC
14600 warn (_("\
14601malformed note encountered in section %s whilst scanning for build-id note\n"),
14602 printable_section_name (filedata, shdr));
f761cb13 14603 free (enote);
55be8fd0 14604 continue;
301a9420
AM
14605 }
14606 data_remaining -= min_notesz;
14607
14608 inote.type = BYTE_GET (enote->type);
14609 inote.namesz = BYTE_GET (enote->namesz);
14610 inote.namedata = enote->name;
14611 inote.descsz = BYTE_GET (enote->descsz);
14612 inote.descdata = ((char *) enote
14613 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
14614 inote.descpos = offset + (inote.descdata - (char *) enote);
14615 next = ((char *) enote
14616 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
14617 }
14618 else
14619 {
14620 Elf64_External_VMS_Note *vms_enote;
14621
14622 /* PR binutils/15191
14623 Make sure that there is enough data to read. */
14624 min_notesz = offsetof (Elf64_External_VMS_Note, name);
14625 if (data_remaining < min_notesz)
14626 {
55be8fd0
NC
14627 warn (_("\
14628malformed note encountered in section %s whilst scanning for build-id note\n"),
14629 printable_section_name (filedata, shdr));
f761cb13 14630 free (enote);
55be8fd0 14631 continue;
301a9420
AM
14632 }
14633 data_remaining -= min_notesz;
14634
14635 vms_enote = (Elf64_External_VMS_Note *) enote;
14636 inote.type = BYTE_GET (vms_enote->type);
14637 inote.namesz = BYTE_GET (vms_enote->namesz);
14638 inote.namedata = vms_enote->name;
14639 inote.descsz = BYTE_GET (vms_enote->descsz);
14640 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
14641 inote.descpos = offset + (inote.descdata - (char *) enote);
14642 next = inote.descdata + align_power (inote.descsz, 3);
14643 }
14644
14645 /* Skip malformed notes. */
14646 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
14647 || (size_t) (inote.descdata - inote.namedata) > data_remaining
14648 || (size_t) (next - inote.descdata) < inote.descsz
14649 || ((size_t) (next - inote.descdata)
14650 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
14651 {
55be8fd0
NC
14652 warn (_("\
14653malformed note encountered in section %s whilst scanning for build-id note\n"),
14654 printable_section_name (filedata, shdr));
f761cb13 14655 free (enote);
301a9420
AM
14656 continue;
14657 }
14658
14659 /* Check if this is the build-id note. If so then convert the build-id
14660 bytes to a hex string. */
14661 if (inote.namesz > 0
14662 && const_strneq (inote.namedata, "GNU")
14663 && inote.type == NT_GNU_BUILD_ID)
14664 {
14665 unsigned long j;
14666 char * build_id;
14667
14668 build_id = malloc (inote.descsz * 2 + 1);
14669 if (build_id == NULL)
f761cb13
AM
14670 {
14671 free (enote);
14672 return NULL;
14673 }
301a9420
AM
14674
14675 for (j = 0; j < inote.descsz; ++j)
14676 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
14677 build_id[inote.descsz * 2] = '\0';
f761cb13 14678 free (enote);
301a9420 14679
55be8fd0 14680 return (unsigned char *) build_id;
301a9420 14681 }
f761cb13 14682 free (enote);
301a9420
AM
14683 }
14684
14685 return NULL;
14686}
14687#endif /* HAVE_LIBDEBUGINFOD */
14688
657d0d47
CC
14689/* If this is not NULL, load_debug_section will only look for sections
14690 within the list of sections given here. */
32ec8896 14691static unsigned int * section_subset = NULL;
657d0d47 14692
32ec8896 14693bfd_boolean
dda8d76d 14694load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 14695{
2cf0635d
NC
14696 struct dwarf_section * section = &debug_displays [debug].section;
14697 Elf_Internal_Shdr * sec;
dda8d76d
NC
14698 Filedata * filedata = (Filedata *) data;
14699
f425ec66
NC
14700 /* Without section headers we cannot find any sections. */
14701 if (filedata->section_headers == NULL)
14702 return FALSE;
14703
9c1ce108
AM
14704 if (filedata->string_table == NULL
14705 && filedata->file_header.e_shstrndx != SHN_UNDEF
14706 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
14707 {
14708 Elf_Internal_Shdr * strs;
14709
14710 /* Read in the string table, so that we have section names to scan. */
14711 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
14712
4dff97b2 14713 if (strs != NULL && strs->sh_size != 0)
dda8d76d 14714 {
9c1ce108
AM
14715 filedata->string_table
14716 = (char *) get_data (NULL, filedata, strs->sh_offset,
14717 1, strs->sh_size, _("string table"));
dda8d76d 14718
9c1ce108
AM
14719 filedata->string_table_length
14720 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
14721 }
14722 }
d966045b
DJ
14723
14724 /* Locate the debug section. */
dda8d76d 14725 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
14726 if (sec != NULL)
14727 section->name = section->uncompressed_name;
14728 else
14729 {
dda8d76d 14730 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
14731 if (sec != NULL)
14732 section->name = section->compressed_name;
14733 }
14734 if (sec == NULL)
32ec8896 14735 return FALSE;
d966045b 14736
657d0d47
CC
14737 /* If we're loading from a subset of sections, and we've loaded
14738 a section matching this name before, it's likely that it's a
14739 different one. */
14740 if (section_subset != NULL)
14741 free_debug_section (debug);
14742
dda8d76d 14743 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
14744}
14745
19e6b90e
L
14746void
14747free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 14748{
2cf0635d 14749 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 14750
19e6b90e
L
14751 if (section->start == NULL)
14752 return;
1007acb3 14753
19e6b90e
L
14754 free ((char *) section->start);
14755 section->start = NULL;
14756 section->address = 0;
14757 section->size = 0;
a788aedd 14758
9db70fc3
AM
14759 free (section->reloc_info);
14760 section->reloc_info = NULL;
14761 section->num_relocs = 0;
1007acb3
L
14762}
14763
32ec8896 14764static bfd_boolean
dda8d76d 14765display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 14766{
2cf0635d 14767 char * name = SECTION_NAME (section);
dda8d76d 14768 const char * print_name = printable_section_name (filedata, section);
19e6b90e 14769 bfd_size_type length;
32ec8896 14770 bfd_boolean result = TRUE;
3f5e193b 14771 int i;
1007acb3 14772
19e6b90e
L
14773 length = section->sh_size;
14774 if (length == 0)
1007acb3 14775 {
74e1a04b 14776 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 14777 return TRUE;
1007acb3 14778 }
5dff79d8
NC
14779 if (section->sh_type == SHT_NOBITS)
14780 {
14781 /* There is no point in dumping the contents of a debugging section
14782 which has the NOBITS type - the bits in the file will be random.
14783 This can happen when a file containing a .eh_frame section is
14784 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
14785 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
14786 print_name);
32ec8896 14787 return FALSE;
5dff79d8 14788 }
1007acb3 14789
0112cd26 14790 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 14791 name = ".debug_info";
1007acb3 14792
19e6b90e
L
14793 /* See if we know how to display the contents of this section. */
14794 for (i = 0; i < max; i++)
d85bf2ba
NC
14795 {
14796 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
14797 struct dwarf_section_display * display = debug_displays + i;
14798 struct dwarf_section * sec = & display->section;
d966045b 14799
d85bf2ba
NC
14800 if (streq (sec->uncompressed_name, name)
14801 || (id == line && const_strneq (name, ".debug_line."))
14802 || streq (sec->compressed_name, name))
14803 {
14804 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 14805
d85bf2ba
NC
14806 if (secondary)
14807 free_debug_section (id);
dda8d76d 14808
d85bf2ba
NC
14809 if (i == line && const_strneq (name, ".debug_line."))
14810 sec->name = name;
14811 else if (streq (sec->uncompressed_name, name))
14812 sec->name = sec->uncompressed_name;
14813 else
14814 sec->name = sec->compressed_name;
657d0d47 14815
d85bf2ba
NC
14816 if (load_specific_debug_section (id, section, filedata))
14817 {
14818 /* If this debug section is part of a CU/TU set in a .dwp file,
14819 restrict load_debug_section to the sections in that set. */
14820 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 14821
d85bf2ba 14822 result &= display->display (sec, filedata);
657d0d47 14823
d85bf2ba 14824 section_subset = NULL;
1007acb3 14825
d85bf2ba
NC
14826 if (secondary || (id != info && id != abbrev))
14827 free_debug_section (id);
14828 }
14829 break;
14830 }
14831 }
1007acb3 14832
19e6b90e 14833 if (i == max)
1007acb3 14834 {
74e1a04b 14835 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 14836 result = FALSE;
1007acb3
L
14837 }
14838
19e6b90e 14839 return result;
5b18a4bc 14840}
103f02d3 14841
aef1f6d0
DJ
14842/* Set DUMP_SECTS for all sections where dumps were requested
14843 based on section name. */
14844
14845static void
dda8d76d 14846initialise_dumps_byname (Filedata * filedata)
aef1f6d0 14847{
2cf0635d 14848 struct dump_list_entry * cur;
aef1f6d0
DJ
14849
14850 for (cur = dump_sects_byname; cur; cur = cur->next)
14851 {
14852 unsigned int i;
32ec8896 14853 bfd_boolean any = FALSE;
aef1f6d0 14854
dda8d76d
NC
14855 for (i = 0; i < filedata->file_header.e_shnum; i++)
14856 if (streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 14857 {
6431e409 14858 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 14859 any = TRUE;
aef1f6d0
DJ
14860 }
14861
14862 if (!any)
14863 warn (_("Section '%s' was not dumped because it does not exist!\n"),
14864 cur->name);
14865 }
14866}
14867
32ec8896 14868static bfd_boolean
dda8d76d 14869process_section_contents (Filedata * filedata)
5b18a4bc 14870{
2cf0635d 14871 Elf_Internal_Shdr * section;
19e6b90e 14872 unsigned int i;
32ec8896 14873 bfd_boolean res = TRUE;
103f02d3 14874
19e6b90e 14875 if (! do_dump)
32ec8896 14876 return TRUE;
103f02d3 14877
dda8d76d 14878 initialise_dumps_byname (filedata);
aef1f6d0 14879
dda8d76d 14880 for (i = 0, section = filedata->section_headers;
6431e409 14881 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
14882 i++, section++)
14883 {
6431e409 14884 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 14885
19e6b90e 14886#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
14887 if (dump & DISASS_DUMP)
14888 {
14889 if (! disassemble_section (section, filedata))
14890 res = FALSE;
14891 }
19e6b90e 14892#endif
dda8d76d 14893 if (dump & HEX_DUMP)
32ec8896 14894 {
dda8d76d 14895 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
14896 res = FALSE;
14897 }
103f02d3 14898
dda8d76d 14899 if (dump & RELOC_DUMP)
32ec8896 14900 {
dda8d76d 14901 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
14902 res = FALSE;
14903 }
09c11c86 14904
dda8d76d 14905 if (dump & STRING_DUMP)
32ec8896 14906 {
dda8d76d 14907 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
14908 res = FALSE;
14909 }
cf13d699 14910
dda8d76d 14911 if (dump & DEBUG_DUMP)
32ec8896 14912 {
dda8d76d 14913 if (! display_debug_section (i, section, filedata))
32ec8896
NC
14914 res = FALSE;
14915 }
7d9813f1 14916
094e34f2 14917#ifdef ENABLE_LIBCTF
7d9813f1
NA
14918 if (dump & CTF_DUMP)
14919 {
14920 if (! dump_section_as_ctf (section, filedata))
14921 res = FALSE;
14922 }
094e34f2 14923#endif
5b18a4bc 14924 }
103f02d3 14925
19e6b90e
L
14926 /* Check to see if the user requested a
14927 dump of a section that does not exist. */
6431e409 14928 while (i < filedata->dump.num_dump_sects)
0ee3043f 14929 {
6431e409 14930 if (filedata->dump.dump_sects[i])
32ec8896
NC
14931 {
14932 warn (_("Section %d was not dumped because it does not exist!\n"), i);
14933 res = FALSE;
14934 }
0ee3043f
NC
14935 i++;
14936 }
32ec8896
NC
14937
14938 return res;
5b18a4bc 14939}
103f02d3 14940
5b18a4bc 14941static void
19e6b90e 14942process_mips_fpe_exception (int mask)
5b18a4bc 14943{
19e6b90e
L
14944 if (mask)
14945 {
32ec8896
NC
14946 bfd_boolean first = TRUE;
14947
19e6b90e 14948 if (mask & OEX_FPU_INEX)
32ec8896 14949 fputs ("INEX", stdout), first = FALSE;
19e6b90e 14950 if (mask & OEX_FPU_UFLO)
32ec8896 14951 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14952 if (mask & OEX_FPU_OFLO)
32ec8896 14953 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 14954 if (mask & OEX_FPU_DIV0)
32ec8896 14955 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
14956 if (mask & OEX_FPU_INVAL)
14957 printf ("%sINVAL", first ? "" : "|");
14958 }
5b18a4bc 14959 else
19e6b90e 14960 fputs ("0", stdout);
5b18a4bc 14961}
103f02d3 14962
f6f0e17b
NC
14963/* Display's the value of TAG at location P. If TAG is
14964 greater than 0 it is assumed to be an unknown tag, and
14965 a message is printed to this effect. Otherwise it is
14966 assumed that a message has already been printed.
14967
14968 If the bottom bit of TAG is set it assumed to have a
14969 string value, otherwise it is assumed to have an integer
14970 value.
14971
14972 Returns an updated P pointing to the first unread byte
14973 beyond the end of TAG's value.
14974
14975 Reads at or beyond END will not be made. */
14976
14977static unsigned char *
60abdbed 14978display_tag_value (signed int tag,
f6f0e17b
NC
14979 unsigned char * p,
14980 const unsigned char * const end)
14981{
14982 unsigned long val;
14983
14984 if (tag > 0)
14985 printf (" Tag_unknown_%d: ", tag);
14986
14987 if (p >= end)
14988 {
4082ef84 14989 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
14990 }
14991 else if (tag & 1)
14992 {
071436c6
NC
14993 /* PR 17531 file: 027-19978-0.004. */
14994 size_t maxlen = (end - p) - 1;
14995
14996 putchar ('"');
4082ef84
NC
14997 if (maxlen > 0)
14998 {
14999 print_symbol ((int) maxlen, (const char *) p);
15000 p += strnlen ((char *) p, maxlen) + 1;
15001 }
15002 else
15003 {
15004 printf (_("<corrupt string tag>"));
15005 p = (unsigned char *) end;
15006 }
071436c6 15007 printf ("\"\n");
f6f0e17b
NC
15008 }
15009 else
15010 {
cd30bcef 15011 READ_ULEB (val, p, end);
f6f0e17b
NC
15012 printf ("%ld (0x%lx)\n", val, val);
15013 }
15014
4082ef84 15015 assert (p <= end);
f6f0e17b
NC
15016 return p;
15017}
15018
53a346d8
CZ
15019/* ARC ABI attributes section. */
15020
15021static unsigned char *
15022display_arc_attribute (unsigned char * p,
15023 const unsigned char * const end)
15024{
15025 unsigned int tag;
53a346d8
CZ
15026 unsigned int val;
15027
cd30bcef 15028 READ_ULEB (tag, p, end);
53a346d8
CZ
15029
15030 switch (tag)
15031 {
15032 case Tag_ARC_PCS_config:
cd30bcef 15033 READ_ULEB (val, p, end);
53a346d8
CZ
15034 printf (" Tag_ARC_PCS_config: ");
15035 switch (val)
15036 {
15037 case 0:
15038 printf (_("Absent/Non standard\n"));
15039 break;
15040 case 1:
15041 printf (_("Bare metal/mwdt\n"));
15042 break;
15043 case 2:
15044 printf (_("Bare metal/newlib\n"));
15045 break;
15046 case 3:
15047 printf (_("Linux/uclibc\n"));
15048 break;
15049 case 4:
15050 printf (_("Linux/glibc\n"));
15051 break;
15052 default:
15053 printf (_("Unknown\n"));
15054 break;
15055 }
15056 break;
15057
15058 case Tag_ARC_CPU_base:
cd30bcef 15059 READ_ULEB (val, p, end);
53a346d8
CZ
15060 printf (" Tag_ARC_CPU_base: ");
15061 switch (val)
15062 {
15063 default:
15064 case TAG_CPU_NONE:
15065 printf (_("Absent\n"));
15066 break;
15067 case TAG_CPU_ARC6xx:
15068 printf ("ARC6xx\n");
15069 break;
15070 case TAG_CPU_ARC7xx:
15071 printf ("ARC7xx\n");
15072 break;
15073 case TAG_CPU_ARCEM:
15074 printf ("ARCEM\n");
15075 break;
15076 case TAG_CPU_ARCHS:
15077 printf ("ARCHS\n");
15078 break;
15079 }
15080 break;
15081
15082 case Tag_ARC_CPU_variation:
cd30bcef 15083 READ_ULEB (val, p, end);
53a346d8
CZ
15084 printf (" Tag_ARC_CPU_variation: ");
15085 switch (val)
15086 {
15087 default:
15088 if (val > 0 && val < 16)
53a346d8 15089 printf ("Core%d\n", val);
d8cbc93b
JL
15090 else
15091 printf ("Unknown\n");
15092 break;
15093
53a346d8
CZ
15094 case 0:
15095 printf (_("Absent\n"));
15096 break;
15097 }
15098 break;
15099
15100 case Tag_ARC_CPU_name:
15101 printf (" Tag_ARC_CPU_name: ");
15102 p = display_tag_value (-1, p, end);
15103 break;
15104
15105 case Tag_ARC_ABI_rf16:
cd30bcef 15106 READ_ULEB (val, p, end);
53a346d8
CZ
15107 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15108 break;
15109
15110 case Tag_ARC_ABI_osver:
cd30bcef 15111 READ_ULEB (val, p, end);
53a346d8
CZ
15112 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15113 break;
15114
15115 case Tag_ARC_ABI_pic:
15116 case Tag_ARC_ABI_sda:
cd30bcef 15117 READ_ULEB (val, p, end);
53a346d8
CZ
15118 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15119 : " Tag_ARC_ABI_pic: ");
15120 switch (val)
15121 {
15122 case 0:
15123 printf (_("Absent\n"));
15124 break;
15125 case 1:
15126 printf ("MWDT\n");
15127 break;
15128 case 2:
15129 printf ("GNU\n");
15130 break;
15131 default:
15132 printf (_("Unknown\n"));
15133 break;
15134 }
15135 break;
15136
15137 case Tag_ARC_ABI_tls:
cd30bcef 15138 READ_ULEB (val, p, end);
53a346d8
CZ
15139 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15140 break;
15141
15142 case Tag_ARC_ABI_enumsize:
cd30bcef 15143 READ_ULEB (val, p, end);
53a346d8
CZ
15144 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15145 _("smallest"));
15146 break;
15147
15148 case Tag_ARC_ABI_exceptions:
cd30bcef 15149 READ_ULEB (val, p, end);
53a346d8
CZ
15150 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15151 : _("default"));
15152 break;
15153
15154 case Tag_ARC_ABI_double_size:
cd30bcef 15155 READ_ULEB (val, p, end);
53a346d8
CZ
15156 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15157 break;
15158
15159 case Tag_ARC_ISA_config:
15160 printf (" Tag_ARC_ISA_config: ");
15161 p = display_tag_value (-1, p, end);
15162 break;
15163
15164 case Tag_ARC_ISA_apex:
15165 printf (" Tag_ARC_ISA_apex: ");
15166 p = display_tag_value (-1, p, end);
15167 break;
15168
15169 case Tag_ARC_ISA_mpy_option:
cd30bcef 15170 READ_ULEB (val, p, end);
53a346d8
CZ
15171 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15172 break;
15173
db1e1b45 15174 case Tag_ARC_ATR_version:
cd30bcef 15175 READ_ULEB (val, p, end);
db1e1b45 15176 printf (" Tag_ARC_ATR_version: %d\n", val);
15177 break;
15178
53a346d8
CZ
15179 default:
15180 return display_tag_value (tag & 1, p, end);
15181 }
15182
15183 return p;
15184}
15185
11c1ff18
PB
15186/* ARM EABI attributes section. */
15187typedef struct
15188{
70e99720 15189 unsigned int tag;
2cf0635d 15190 const char * name;
11c1ff18 15191 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15192 unsigned int type;
2cf0635d 15193 const char ** table;
11c1ff18
PB
15194} arm_attr_public_tag;
15195
2cf0635d 15196static const char * arm_attr_tag_CPU_arch[] =
11c1ff18 15197 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15198 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15199 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
2cf0635d
NC
15200static const char * arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15201static const char * arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15202 {"No", "Thumb-1", "Thumb-2", "Yes"};
75375b3e 15203static const char * arm_attr_tag_FP_arch[] =
bca38921 15204 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15205 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
2cf0635d 15206static const char * arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
dd24e3da 15207static const char * arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15208 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15209 "NEON for ARMv8.1"};
2cf0635d 15210static const char * arm_attr_tag_PCS_config[] =
11c1ff18
PB
15211 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15212 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
2cf0635d 15213static const char * arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15214 {"V6", "SB", "TLS", "Unused"};
2cf0635d 15215static const char * arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15216 {"Absolute", "PC-relative", "SB-relative", "None"};
2cf0635d 15217static const char * arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15218 {"Absolute", "PC-relative", "None"};
2cf0635d 15219static const char * arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15220 {"None", "direct", "GOT-indirect"};
2cf0635d 15221static const char * arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15222 {"None", "??? 1", "2", "??? 3", "4"};
2cf0635d
NC
15223static const char * arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15224static const char * arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15225 {"Unused", "Needed", "Sign only"};
2cf0635d
NC
15226static const char * arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15227static const char * arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15228static const char * arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15229 {"Unused", "Finite", "RTABI", "IEEE 754"};
2cf0635d 15230static const char * arm_attr_tag_ABI_enum_size[] =
11c1ff18 15231 {"Unused", "small", "int", "forced to int"};
2cf0635d 15232static const char * arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15233 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
2cf0635d 15234static const char * arm_attr_tag_ABI_VFP_args[] =
5c294fee 15235 {"AAPCS", "VFP registers", "custom", "compatible"};
2cf0635d 15236static const char * arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15237 {"AAPCS", "WMMX registers", "custom"};
2cf0635d 15238static const char * arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15239 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15240 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
2cf0635d 15241static const char * arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15242 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15243 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
2cf0635d 15244static const char * arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
75375b3e 15245static const char * arm_attr_tag_FP_HP_extension[] =
8e79c3df 15246 {"Not Allowed", "Allowed"};
2cf0635d 15247static const char * arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15248 {"None", "IEEE 754", "Alternative Format"};
15afaa63
TP
15249static const char * arm_attr_tag_DSP_extension[] =
15250 {"Follow architecture", "Allowed"};
dd24e3da 15251static const char * arm_attr_tag_MPextension_use[] =
cd21e546
MGD
15252 {"Not Allowed", "Allowed"};
15253static const char * arm_attr_tag_DIV_use[] =
dd24e3da 15254 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15255 "Allowed in v7-A with integer division extension"};
2cf0635d
NC
15256static const char * arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15257static const char * arm_attr_tag_Virtualization_use[] =
dd24e3da 15258 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15259 "TrustZone and Virtualization Extensions"};
dd24e3da 15260static const char * arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15261 {"Not Allowed", "Allowed"};
11c1ff18 15262
a7ad558c
AV
15263static const char * arm_attr_tag_MVE_arch[] =
15264 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15265
11c1ff18
PB
15266#define LOOKUP(id, name) \
15267 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15268static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15269{
15270 {4, "CPU_raw_name", 1, NULL},
15271 {5, "CPU_name", 1, NULL},
15272 LOOKUP(6, CPU_arch),
15273 {7, "CPU_arch_profile", 0, NULL},
15274 LOOKUP(8, ARM_ISA_use),
15275 LOOKUP(9, THUMB_ISA_use),
75375b3e 15276 LOOKUP(10, FP_arch),
11c1ff18 15277 LOOKUP(11, WMMX_arch),
f5f53991
AS
15278 LOOKUP(12, Advanced_SIMD_arch),
15279 LOOKUP(13, PCS_config),
11c1ff18
PB
15280 LOOKUP(14, ABI_PCS_R9_use),
15281 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15282 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15283 LOOKUP(17, ABI_PCS_GOT_use),
15284 LOOKUP(18, ABI_PCS_wchar_t),
15285 LOOKUP(19, ABI_FP_rounding),
15286 LOOKUP(20, ABI_FP_denormal),
15287 LOOKUP(21, ABI_FP_exceptions),
15288 LOOKUP(22, ABI_FP_user_exceptions),
15289 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15290 {24, "ABI_align_needed", 0, NULL},
15291 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15292 LOOKUP(26, ABI_enum_size),
15293 LOOKUP(27, ABI_HardFP_use),
15294 LOOKUP(28, ABI_VFP_args),
15295 LOOKUP(29, ABI_WMMX_args),
15296 LOOKUP(30, ABI_optimization_goals),
15297 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15298 {32, "compatibility", 0, NULL},
f5f53991 15299 LOOKUP(34, CPU_unaligned_access),
75375b3e 15300 LOOKUP(36, FP_HP_extension),
8e79c3df 15301 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15302 LOOKUP(42, MPextension_use),
15303 LOOKUP(44, DIV_use),
15afaa63 15304 LOOKUP(46, DSP_extension),
a7ad558c 15305 LOOKUP(48, MVE_arch),
f5f53991
AS
15306 {64, "nodefaults", 0, NULL},
15307 {65, "also_compatible_with", 0, NULL},
15308 LOOKUP(66, T2EE_use),
15309 {67, "conformance", 1, NULL},
15310 LOOKUP(68, Virtualization_use),
cd21e546 15311 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15312};
15313#undef LOOKUP
15314
11c1ff18 15315static unsigned char *
f6f0e17b
NC
15316display_arm_attribute (unsigned char * p,
15317 const unsigned char * const end)
11c1ff18 15318{
70e99720 15319 unsigned int tag;
70e99720 15320 unsigned int val;
2cf0635d 15321 arm_attr_public_tag * attr;
11c1ff18 15322 unsigned i;
70e99720 15323 unsigned int type;
11c1ff18 15324
cd30bcef 15325 READ_ULEB (tag, p, end);
11c1ff18 15326 attr = NULL;
2cf0635d 15327 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15328 {
15329 if (arm_attr_public_tags[i].tag == tag)
15330 {
15331 attr = &arm_attr_public_tags[i];
15332 break;
15333 }
15334 }
15335
15336 if (attr)
15337 {
15338 printf (" Tag_%s: ", attr->name);
15339 switch (attr->type)
15340 {
15341 case 0:
15342 switch (tag)
15343 {
15344 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15345 READ_ULEB (val, p, end);
11c1ff18
PB
15346 switch (val)
15347 {
2b692964
NC
15348 case 0: printf (_("None\n")); break;
15349 case 'A': printf (_("Application\n")); break;
15350 case 'R': printf (_("Realtime\n")); break;
15351 case 'M': printf (_("Microcontroller\n")); break;
15352 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15353 default: printf ("??? (%d)\n", val); break;
15354 }
15355 break;
15356
75375b3e 15357 case 24: /* Tag_align_needed. */
cd30bcef 15358 READ_ULEB (val, p, end);
75375b3e
MGD
15359 switch (val)
15360 {
2b692964
NC
15361 case 0: printf (_("None\n")); break;
15362 case 1: printf (_("8-byte\n")); break;
15363 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15364 case 3: printf ("??? 3\n"); break;
15365 default:
15366 if (val <= 12)
dd24e3da 15367 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15368 1 << val);
15369 else
15370 printf ("??? (%d)\n", val);
15371 break;
15372 }
15373 break;
15374
15375 case 25: /* Tag_align_preserved. */
cd30bcef 15376 READ_ULEB (val, p, end);
75375b3e
MGD
15377 switch (val)
15378 {
2b692964
NC
15379 case 0: printf (_("None\n")); break;
15380 case 1: printf (_("8-byte, except leaf SP\n")); break;
15381 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
15382 case 3: printf ("??? 3\n"); break;
15383 default:
15384 if (val <= 12)
dd24e3da 15385 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15386 1 << val);
15387 else
15388 printf ("??? (%d)\n", val);
15389 break;
15390 }
15391 break;
15392
11c1ff18 15393 case 32: /* Tag_compatibility. */
071436c6 15394 {
cd30bcef 15395 READ_ULEB (val, p, end);
071436c6 15396 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15397 if (p < end - 1)
15398 {
15399 size_t maxlen = (end - p) - 1;
15400
15401 print_symbol ((int) maxlen, (const char *) p);
15402 p += strnlen ((char *) p, maxlen) + 1;
15403 }
15404 else
15405 {
15406 printf (_("<corrupt>"));
15407 p = (unsigned char *) end;
15408 }
071436c6 15409 putchar ('\n');
071436c6 15410 }
11c1ff18
PB
15411 break;
15412
f5f53991 15413 case 64: /* Tag_nodefaults. */
541a3cbd
NC
15414 /* PR 17531: file: 001-505008-0.01. */
15415 if (p < end)
15416 p++;
2b692964 15417 printf (_("True\n"));
f5f53991
AS
15418 break;
15419
15420 case 65: /* Tag_also_compatible_with. */
cd30bcef 15421 READ_ULEB (val, p, end);
f5f53991
AS
15422 if (val == 6 /* Tag_CPU_arch. */)
15423 {
cd30bcef 15424 READ_ULEB (val, p, end);
071436c6 15425 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
15426 printf ("??? (%d)\n", val);
15427 else
15428 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
15429 }
15430 else
15431 printf ("???\n");
071436c6
NC
15432 while (p < end && *(p++) != '\0' /* NUL terminator. */)
15433 ;
f5f53991
AS
15434 break;
15435
11c1ff18 15436 default:
bee0ee85
NC
15437 printf (_("<unknown: %d>\n"), tag);
15438 break;
11c1ff18
PB
15439 }
15440 return p;
15441
15442 case 1:
f6f0e17b 15443 return display_tag_value (-1, p, end);
11c1ff18 15444 case 2:
f6f0e17b 15445 return display_tag_value (0, p, end);
11c1ff18
PB
15446
15447 default:
15448 assert (attr->type & 0x80);
cd30bcef 15449 READ_ULEB (val, p, end);
11c1ff18
PB
15450 type = attr->type & 0x7f;
15451 if (val >= type)
15452 printf ("??? (%d)\n", val);
15453 else
15454 printf ("%s\n", attr->table[val]);
15455 return p;
15456 }
15457 }
11c1ff18 15458
f6f0e17b 15459 return display_tag_value (tag, p, end);
11c1ff18
PB
15460}
15461
104d59d1 15462static unsigned char *
60bca95a 15463display_gnu_attribute (unsigned char * p,
60abdbed 15464 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 15465 const unsigned char * const end)
104d59d1 15466{
cd30bcef 15467 unsigned int tag;
60abdbed 15468 unsigned int val;
104d59d1 15469
cd30bcef 15470 READ_ULEB (tag, p, end);
104d59d1
JM
15471
15472 /* Tag_compatibility is the only generic GNU attribute defined at
15473 present. */
15474 if (tag == 32)
15475 {
cd30bcef 15476 READ_ULEB (val, p, end);
071436c6
NC
15477
15478 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
15479 if (p == end)
15480 {
071436c6 15481 printf (_("<corrupt>\n"));
f6f0e17b
NC
15482 warn (_("corrupt vendor attribute\n"));
15483 }
15484 else
15485 {
4082ef84
NC
15486 if (p < end - 1)
15487 {
15488 size_t maxlen = (end - p) - 1;
071436c6 15489
4082ef84
NC
15490 print_symbol ((int) maxlen, (const char *) p);
15491 p += strnlen ((char *) p, maxlen) + 1;
15492 }
15493 else
15494 {
15495 printf (_("<corrupt>"));
15496 p = (unsigned char *) end;
15497 }
071436c6 15498 putchar ('\n');
f6f0e17b 15499 }
104d59d1
JM
15500 return p;
15501 }
15502
15503 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 15504 return display_proc_gnu_attribute (p, tag, end);
104d59d1 15505
f6f0e17b 15506 return display_tag_value (tag, p, end);
104d59d1
JM
15507}
15508
85f7484a
PB
15509static unsigned char *
15510display_m68k_gnu_attribute (unsigned char * p,
15511 unsigned int tag,
15512 const unsigned char * const end)
15513{
15514 unsigned int val;
15515
15516 if (tag == Tag_GNU_M68K_ABI_FP)
15517 {
15518 printf (" Tag_GNU_M68K_ABI_FP: ");
15519 if (p == end)
15520 {
15521 printf (_("<corrupt>\n"));
15522 return p;
15523 }
15524 READ_ULEB (val, p, end);
15525
15526 if (val > 3)
15527 printf ("(%#x), ", val);
15528
15529 switch (val & 3)
15530 {
15531 case 0:
15532 printf (_("unspecified hard/soft float\n"));
15533 break;
15534 case 1:
15535 printf (_("hard float\n"));
15536 break;
15537 case 2:
15538 printf (_("soft float\n"));
15539 break;
15540 }
15541 return p;
15542 }
15543
15544 return display_tag_value (tag & 1, p, end);
15545}
15546
34c8bcba 15547static unsigned char *
f6f0e17b 15548display_power_gnu_attribute (unsigned char * p,
60abdbed 15549 unsigned int tag,
f6f0e17b 15550 const unsigned char * const end)
34c8bcba 15551{
005d79fd 15552 unsigned int val;
34c8bcba
JM
15553
15554 if (tag == Tag_GNU_Power_ABI_FP)
15555 {
34c8bcba 15556 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 15557 if (p == end)
005d79fd
AM
15558 {
15559 printf (_("<corrupt>\n"));
15560 return p;
15561 }
cd30bcef 15562 READ_ULEB (val, p, end);
60bca95a 15563
005d79fd
AM
15564 if (val > 15)
15565 printf ("(%#x), ", val);
15566
15567 switch (val & 3)
34c8bcba
JM
15568 {
15569 case 0:
005d79fd 15570 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
15571 break;
15572 case 1:
005d79fd 15573 printf (_("hard float, "));
34c8bcba
JM
15574 break;
15575 case 2:
005d79fd 15576 printf (_("soft float, "));
34c8bcba 15577 break;
3c7b9897 15578 case 3:
005d79fd 15579 printf (_("single-precision hard float, "));
3c7b9897 15580 break;
005d79fd
AM
15581 }
15582
15583 switch (val & 0xC)
15584 {
15585 case 0:
15586 printf (_("unspecified long double\n"));
15587 break;
15588 case 4:
15589 printf (_("128-bit IBM long double\n"));
15590 break;
15591 case 8:
15592 printf (_("64-bit long double\n"));
15593 break;
15594 case 12:
15595 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
15596 break;
15597 }
15598 return p;
005d79fd 15599 }
34c8bcba 15600
c6e65352
DJ
15601 if (tag == Tag_GNU_Power_ABI_Vector)
15602 {
c6e65352 15603 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 15604 if (p == end)
005d79fd
AM
15605 {
15606 printf (_("<corrupt>\n"));
15607 return p;
15608 }
cd30bcef 15609 READ_ULEB (val, p, end);
005d79fd
AM
15610
15611 if (val > 3)
15612 printf ("(%#x), ", val);
15613
15614 switch (val & 3)
c6e65352
DJ
15615 {
15616 case 0:
005d79fd 15617 printf (_("unspecified\n"));
c6e65352
DJ
15618 break;
15619 case 1:
005d79fd 15620 printf (_("generic\n"));
c6e65352
DJ
15621 break;
15622 case 2:
15623 printf ("AltiVec\n");
15624 break;
15625 case 3:
15626 printf ("SPE\n");
15627 break;
c6e65352
DJ
15628 }
15629 return p;
005d79fd 15630 }
c6e65352 15631
f82e0623
NF
15632 if (tag == Tag_GNU_Power_ABI_Struct_Return)
15633 {
005d79fd 15634 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 15635 if (p == end)
f6f0e17b 15636 {
005d79fd 15637 printf (_("<corrupt>\n"));
f6f0e17b
NC
15638 return p;
15639 }
cd30bcef 15640 READ_ULEB (val, p, end);
0b4362b0 15641
005d79fd
AM
15642 if (val > 2)
15643 printf ("(%#x), ", val);
15644
15645 switch (val & 3)
15646 {
15647 case 0:
15648 printf (_("unspecified\n"));
15649 break;
15650 case 1:
15651 printf ("r3/r4\n");
15652 break;
15653 case 2:
15654 printf (_("memory\n"));
15655 break;
15656 case 3:
15657 printf ("???\n");
15658 break;
15659 }
f82e0623
NF
15660 return p;
15661 }
15662
f6f0e17b 15663 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
15664}
15665
643f7afb
AK
15666static unsigned char *
15667display_s390_gnu_attribute (unsigned char * p,
60abdbed 15668 unsigned int tag,
643f7afb
AK
15669 const unsigned char * const end)
15670{
cd30bcef 15671 unsigned int val;
643f7afb
AK
15672
15673 if (tag == Tag_GNU_S390_ABI_Vector)
15674 {
643f7afb 15675 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 15676 READ_ULEB (val, p, end);
643f7afb
AK
15677
15678 switch (val)
15679 {
15680 case 0:
15681 printf (_("any\n"));
15682 break;
15683 case 1:
15684 printf (_("software\n"));
15685 break;
15686 case 2:
15687 printf (_("hardware\n"));
15688 break;
15689 default:
15690 printf ("??? (%d)\n", val);
15691 break;
15692 }
15693 return p;
15694 }
15695
15696 return display_tag_value (tag & 1, p, end);
15697}
15698
9e8c70f9 15699static void
60abdbed 15700display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
15701{
15702 if (mask)
15703 {
32ec8896 15704 bfd_boolean first = TRUE;
071436c6 15705
9e8c70f9 15706 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 15707 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 15708 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 15709 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 15710 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 15711 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 15712 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 15713 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 15714 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 15715 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 15716 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 15717 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 15718 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 15719 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 15720 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 15721 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 15722 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 15723 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 15724 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 15725 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 15726 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 15727 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 15728 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 15729 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 15730 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 15731 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 15732 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 15733 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 15734 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 15735 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 15736 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 15737 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
15738 }
15739 else
071436c6
NC
15740 fputc ('0', stdout);
15741 fputc ('\n', stdout);
9e8c70f9
DM
15742}
15743
3d68f91c 15744static void
60abdbed 15745display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
15746{
15747 if (mask)
15748 {
32ec8896 15749 bfd_boolean first = TRUE;
071436c6 15750
3d68f91c 15751 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 15752 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 15753 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 15754 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 15755 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 15756 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 15757 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 15758 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 15759 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 15760 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 15761 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 15762 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 15763 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 15764 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 15765 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 15766 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 15767 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 15768 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 15769 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 15770 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 15771 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 15772 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
15773 }
15774 else
071436c6
NC
15775 fputc ('0', stdout);
15776 fputc ('\n', stdout);
3d68f91c
JM
15777}
15778
9e8c70f9 15779static unsigned char *
f6f0e17b 15780display_sparc_gnu_attribute (unsigned char * p,
60abdbed 15781 unsigned int tag,
f6f0e17b 15782 const unsigned char * const end)
9e8c70f9 15783{
cd30bcef 15784 unsigned int val;
3d68f91c 15785
9e8c70f9
DM
15786 if (tag == Tag_GNU_Sparc_HWCAPS)
15787 {
cd30bcef 15788 READ_ULEB (val, p, end);
9e8c70f9 15789 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
15790 display_sparc_hwcaps (val);
15791 return p;
3d68f91c
JM
15792 }
15793 if (tag == Tag_GNU_Sparc_HWCAPS2)
15794 {
cd30bcef 15795 READ_ULEB (val, p, end);
3d68f91c
JM
15796 printf (" Tag_GNU_Sparc_HWCAPS2: ");
15797 display_sparc_hwcaps2 (val);
15798 return p;
15799 }
9e8c70f9 15800
f6f0e17b 15801 return display_tag_value (tag, p, end);
9e8c70f9
DM
15802}
15803
351cdf24 15804static void
32ec8896 15805print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
15806{
15807 switch (val)
15808 {
15809 case Val_GNU_MIPS_ABI_FP_ANY:
15810 printf (_("Hard or soft float\n"));
15811 break;
15812 case Val_GNU_MIPS_ABI_FP_DOUBLE:
15813 printf (_("Hard float (double precision)\n"));
15814 break;
15815 case Val_GNU_MIPS_ABI_FP_SINGLE:
15816 printf (_("Hard float (single precision)\n"));
15817 break;
15818 case Val_GNU_MIPS_ABI_FP_SOFT:
15819 printf (_("Soft float\n"));
15820 break;
15821 case Val_GNU_MIPS_ABI_FP_OLD_64:
15822 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
15823 break;
15824 case Val_GNU_MIPS_ABI_FP_XX:
15825 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
15826 break;
15827 case Val_GNU_MIPS_ABI_FP_64:
15828 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
15829 break;
15830 case Val_GNU_MIPS_ABI_FP_64A:
15831 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
15832 break;
3350cc01
CM
15833 case Val_GNU_MIPS_ABI_FP_NAN2008:
15834 printf (_("NaN 2008 compatibility\n"));
15835 break;
351cdf24
MF
15836 default:
15837 printf ("??? (%d)\n", val);
15838 break;
15839 }
15840}
15841
2cf19d5c 15842static unsigned char *
f6f0e17b 15843display_mips_gnu_attribute (unsigned char * p,
60abdbed 15844 unsigned int tag,
f6f0e17b 15845 const unsigned char * const end)
2cf19d5c 15846{
2cf19d5c
JM
15847 if (tag == Tag_GNU_MIPS_ABI_FP)
15848 {
32ec8896 15849 unsigned int val;
f6f0e17b 15850
2cf19d5c 15851 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 15852 READ_ULEB (val, p, end);
351cdf24 15853 print_mips_fp_abi_value (val);
2cf19d5c
JM
15854 return p;
15855 }
15856
a9f58168
CF
15857 if (tag == Tag_GNU_MIPS_ABI_MSA)
15858 {
32ec8896 15859 unsigned int val;
a9f58168 15860
a9f58168 15861 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 15862 READ_ULEB (val, p, end);
a9f58168
CF
15863
15864 switch (val)
15865 {
15866 case Val_GNU_MIPS_ABI_MSA_ANY:
15867 printf (_("Any MSA or not\n"));
15868 break;
15869 case Val_GNU_MIPS_ABI_MSA_128:
15870 printf (_("128-bit MSA\n"));
15871 break;
15872 default:
15873 printf ("??? (%d)\n", val);
15874 break;
15875 }
15876 return p;
15877 }
15878
f6f0e17b 15879 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
15880}
15881
59e6276b 15882static unsigned char *
f6f0e17b
NC
15883display_tic6x_attribute (unsigned char * p,
15884 const unsigned char * const end)
59e6276b 15885{
60abdbed 15886 unsigned int tag;
cd30bcef 15887 unsigned int val;
59e6276b 15888
cd30bcef 15889 READ_ULEB (tag, p, end);
59e6276b
JM
15890
15891 switch (tag)
15892 {
75fa6dc1 15893 case Tag_ISA:
75fa6dc1 15894 printf (" Tag_ISA: ");
cd30bcef 15895 READ_ULEB (val, p, end);
59e6276b
JM
15896
15897 switch (val)
15898 {
75fa6dc1 15899 case C6XABI_Tag_ISA_none:
59e6276b
JM
15900 printf (_("None\n"));
15901 break;
75fa6dc1 15902 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
15903 printf ("C62x\n");
15904 break;
75fa6dc1 15905 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
15906 printf ("C67x\n");
15907 break;
75fa6dc1 15908 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
15909 printf ("C67x+\n");
15910 break;
75fa6dc1 15911 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
15912 printf ("C64x\n");
15913 break;
75fa6dc1 15914 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
15915 printf ("C64x+\n");
15916 break;
75fa6dc1 15917 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
15918 printf ("C674x\n");
15919 break;
15920 default:
15921 printf ("??? (%d)\n", val);
15922 break;
15923 }
15924 return p;
15925
87779176 15926 case Tag_ABI_wchar_t:
87779176 15927 printf (" Tag_ABI_wchar_t: ");
cd30bcef 15928 READ_ULEB (val, p, end);
87779176
JM
15929 switch (val)
15930 {
15931 case 0:
15932 printf (_("Not used\n"));
15933 break;
15934 case 1:
15935 printf (_("2 bytes\n"));
15936 break;
15937 case 2:
15938 printf (_("4 bytes\n"));
15939 break;
15940 default:
15941 printf ("??? (%d)\n", val);
15942 break;
15943 }
15944 return p;
15945
15946 case Tag_ABI_stack_align_needed:
87779176 15947 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 15948 READ_ULEB (val, p, end);
87779176
JM
15949 switch (val)
15950 {
15951 case 0:
15952 printf (_("8-byte\n"));
15953 break;
15954 case 1:
15955 printf (_("16-byte\n"));
15956 break;
15957 default:
15958 printf ("??? (%d)\n", val);
15959 break;
15960 }
15961 return p;
15962
15963 case Tag_ABI_stack_align_preserved:
cd30bcef 15964 READ_ULEB (val, p, end);
87779176
JM
15965 printf (" Tag_ABI_stack_align_preserved: ");
15966 switch (val)
15967 {
15968 case 0:
15969 printf (_("8-byte\n"));
15970 break;
15971 case 1:
15972 printf (_("16-byte\n"));
15973 break;
15974 default:
15975 printf ("??? (%d)\n", val);
15976 break;
15977 }
15978 return p;
15979
b5593623 15980 case Tag_ABI_DSBT:
cd30bcef 15981 READ_ULEB (val, p, end);
b5593623
JM
15982 printf (" Tag_ABI_DSBT: ");
15983 switch (val)
15984 {
15985 case 0:
15986 printf (_("DSBT addressing not used\n"));
15987 break;
15988 case 1:
15989 printf (_("DSBT addressing used\n"));
15990 break;
15991 default:
15992 printf ("??? (%d)\n", val);
15993 break;
15994 }
15995 return p;
15996
87779176 15997 case Tag_ABI_PID:
cd30bcef 15998 READ_ULEB (val, p, end);
87779176
JM
15999 printf (" Tag_ABI_PID: ");
16000 switch (val)
16001 {
16002 case 0:
16003 printf (_("Data addressing position-dependent\n"));
16004 break;
16005 case 1:
16006 printf (_("Data addressing position-independent, GOT near DP\n"));
16007 break;
16008 case 2:
16009 printf (_("Data addressing position-independent, GOT far from DP\n"));
16010 break;
16011 default:
16012 printf ("??? (%d)\n", val);
16013 break;
16014 }
16015 return p;
16016
16017 case Tag_ABI_PIC:
cd30bcef 16018 READ_ULEB (val, p, end);
87779176
JM
16019 printf (" Tag_ABI_PIC: ");
16020 switch (val)
16021 {
16022 case 0:
16023 printf (_("Code addressing position-dependent\n"));
16024 break;
16025 case 1:
16026 printf (_("Code addressing position-independent\n"));
16027 break;
16028 default:
16029 printf ("??? (%d)\n", val);
16030 break;
16031 }
16032 return p;
16033
16034 case Tag_ABI_array_object_alignment:
cd30bcef 16035 READ_ULEB (val, p, end);
87779176
JM
16036 printf (" Tag_ABI_array_object_alignment: ");
16037 switch (val)
16038 {
16039 case 0:
16040 printf (_("8-byte\n"));
16041 break;
16042 case 1:
16043 printf (_("4-byte\n"));
16044 break;
16045 case 2:
16046 printf (_("16-byte\n"));
16047 break;
16048 default:
16049 printf ("??? (%d)\n", val);
16050 break;
16051 }
16052 return p;
16053
16054 case Tag_ABI_array_object_align_expected:
cd30bcef 16055 READ_ULEB (val, p, end);
87779176
JM
16056 printf (" Tag_ABI_array_object_align_expected: ");
16057 switch (val)
16058 {
16059 case 0:
16060 printf (_("8-byte\n"));
16061 break;
16062 case 1:
16063 printf (_("4-byte\n"));
16064 break;
16065 case 2:
16066 printf (_("16-byte\n"));
16067 break;
16068 default:
16069 printf ("??? (%d)\n", val);
16070 break;
16071 }
16072 return p;
16073
3cbd1c06 16074 case Tag_ABI_compatibility:
071436c6 16075 {
cd30bcef 16076 READ_ULEB (val, p, end);
071436c6 16077 printf (" Tag_ABI_compatibility: ");
071436c6 16078 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16079 if (p < end - 1)
16080 {
16081 size_t maxlen = (end - p) - 1;
16082
16083 print_symbol ((int) maxlen, (const char *) p);
16084 p += strnlen ((char *) p, maxlen) + 1;
16085 }
16086 else
16087 {
16088 printf (_("<corrupt>"));
16089 p = (unsigned char *) end;
16090 }
071436c6 16091 putchar ('\n');
071436c6
NC
16092 return p;
16093 }
87779176
JM
16094
16095 case Tag_ABI_conformance:
071436c6 16096 {
4082ef84
NC
16097 printf (" Tag_ABI_conformance: \"");
16098 if (p < end - 1)
16099 {
16100 size_t maxlen = (end - p) - 1;
071436c6 16101
4082ef84
NC
16102 print_symbol ((int) maxlen, (const char *) p);
16103 p += strnlen ((char *) p, maxlen) + 1;
16104 }
16105 else
16106 {
16107 printf (_("<corrupt>"));
16108 p = (unsigned char *) end;
16109 }
071436c6 16110 printf ("\"\n");
071436c6
NC
16111 return p;
16112 }
59e6276b
JM
16113 }
16114
f6f0e17b
NC
16115 return display_tag_value (tag, p, end);
16116}
59e6276b 16117
f6f0e17b 16118static void
60abdbed 16119display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16120{
16121 unsigned long addr = 0;
16122 size_t bytes = end - p;
16123
feceaa59 16124 assert (end >= p);
f6f0e17b 16125 while (bytes)
87779176 16126 {
f6f0e17b
NC
16127 int j;
16128 int k;
16129 int lbytes = (bytes > 16 ? 16 : bytes);
16130
16131 printf (" 0x%8.8lx ", addr);
16132
16133 for (j = 0; j < 16; j++)
16134 {
16135 if (j < lbytes)
16136 printf ("%2.2x", p[j]);
16137 else
16138 printf (" ");
16139
16140 if ((j & 3) == 3)
16141 printf (" ");
16142 }
16143
16144 for (j = 0; j < lbytes; j++)
16145 {
16146 k = p[j];
16147 if (k >= ' ' && k < 0x7f)
16148 printf ("%c", k);
16149 else
16150 printf (".");
16151 }
16152
16153 putchar ('\n');
16154
16155 p += lbytes;
16156 bytes -= lbytes;
16157 addr += lbytes;
87779176 16158 }
59e6276b 16159
f6f0e17b 16160 putchar ('\n');
59e6276b
JM
16161}
16162
13761a11
NC
16163static unsigned char *
16164display_msp430x_attribute (unsigned char * p,
16165 const unsigned char * const end)
16166{
60abdbed
NC
16167 unsigned int val;
16168 unsigned int tag;
13761a11 16169
cd30bcef 16170 READ_ULEB (tag, p, end);
0b4362b0 16171
13761a11
NC
16172 switch (tag)
16173 {
16174 case OFBA_MSPABI_Tag_ISA:
13761a11 16175 printf (" Tag_ISA: ");
cd30bcef 16176 READ_ULEB (val, p, end);
13761a11
NC
16177 switch (val)
16178 {
16179 case 0: printf (_("None\n")); break;
16180 case 1: printf (_("MSP430\n")); break;
16181 case 2: printf (_("MSP430X\n")); break;
16182 default: printf ("??? (%d)\n", val); break;
16183 }
16184 break;
16185
16186 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16187 printf (" Tag_Code_Model: ");
cd30bcef 16188 READ_ULEB (val, p, end);
13761a11
NC
16189 switch (val)
16190 {
16191 case 0: printf (_("None\n")); break;
16192 case 1: printf (_("Small\n")); break;
16193 case 2: printf (_("Large\n")); break;
16194 default: printf ("??? (%d)\n", val); break;
16195 }
16196 break;
16197
16198 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16199 printf (" Tag_Data_Model: ");
cd30bcef 16200 READ_ULEB (val, p, end);
13761a11
NC
16201 switch (val)
16202 {
16203 case 0: printf (_("None\n")); break;
16204 case 1: printf (_("Small\n")); break;
16205 case 2: printf (_("Large\n")); break;
16206 case 3: printf (_("Restricted Large\n")); break;
16207 default: printf ("??? (%d)\n", val); break;
16208 }
16209 break;
16210
16211 default:
16212 printf (_(" <unknown tag %d>: "), tag);
16213
16214 if (tag & 1)
16215 {
071436c6 16216 putchar ('"');
4082ef84
NC
16217 if (p < end - 1)
16218 {
16219 size_t maxlen = (end - p) - 1;
16220
16221 print_symbol ((int) maxlen, (const char *) p);
16222 p += strnlen ((char *) p, maxlen) + 1;
16223 }
16224 else
16225 {
16226 printf (_("<corrupt>"));
16227 p = (unsigned char *) end;
16228 }
071436c6 16229 printf ("\"\n");
13761a11
NC
16230 }
16231 else
16232 {
cd30bcef 16233 READ_ULEB (val, p, end);
13761a11
NC
16234 printf ("%d (0x%x)\n", val, val);
16235 }
16236 break;
16237 }
16238
4082ef84 16239 assert (p <= end);
13761a11
NC
16240 return p;
16241}
16242
c0ea7c52
JL
16243static unsigned char *
16244display_msp430_gnu_attribute (unsigned char * p,
16245 unsigned int tag,
16246 const unsigned char * const end)
16247{
16248 if (tag == Tag_GNU_MSP430_Data_Region)
16249 {
cd30bcef 16250 unsigned int val;
c0ea7c52 16251
c0ea7c52 16252 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16253 READ_ULEB (val, p, end);
c0ea7c52
JL
16254
16255 switch (val)
16256 {
16257 case Val_GNU_MSP430_Data_Region_Any:
16258 printf (_("Any Region\n"));
16259 break;
16260 case Val_GNU_MSP430_Data_Region_Lower:
16261 printf (_("Lower Region Only\n"));
16262 break;
16263 default:
cd30bcef 16264 printf ("??? (%u)\n", val);
c0ea7c52
JL
16265 }
16266 return p;
16267 }
16268 return display_tag_value (tag & 1, p, end);
16269}
16270
2dc8dd17
JW
16271struct riscv_attr_tag_t {
16272 const char *name;
cd30bcef 16273 unsigned int tag;
2dc8dd17
JW
16274};
16275
16276static struct riscv_attr_tag_t riscv_attr_tag[] =
16277{
16278#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16279 T(arch),
16280 T(priv_spec),
16281 T(priv_spec_minor),
16282 T(priv_spec_revision),
16283 T(unaligned_access),
16284 T(stack_align),
16285#undef T
16286};
16287
16288static unsigned char *
16289display_riscv_attribute (unsigned char *p,
16290 const unsigned char * const end)
16291{
cd30bcef
AM
16292 unsigned int val;
16293 unsigned int tag;
2dc8dd17
JW
16294 struct riscv_attr_tag_t *attr = NULL;
16295 unsigned i;
16296
cd30bcef 16297 READ_ULEB (tag, p, end);
2dc8dd17
JW
16298
16299 /* Find the name of attribute. */
16300 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16301 {
16302 if (riscv_attr_tag[i].tag == tag)
16303 {
16304 attr = &riscv_attr_tag[i];
16305 break;
16306 }
16307 }
16308
16309 if (attr)
16310 printf (" %s: ", attr->name);
16311 else
16312 return display_tag_value (tag, p, end);
16313
16314 switch (tag)
16315 {
16316 case Tag_RISCV_priv_spec:
16317 case Tag_RISCV_priv_spec_minor:
16318 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16319 READ_ULEB (val, p, end);
16320 printf (_("%u\n"), val);
2dc8dd17
JW
16321 break;
16322 case Tag_RISCV_unaligned_access:
cd30bcef 16323 READ_ULEB (val, p, end);
2dc8dd17
JW
16324 switch (val)
16325 {
16326 case 0:
16327 printf (_("No unaligned access\n"));
16328 break;
16329 case 1:
16330 printf (_("Unaligned access\n"));
16331 break;
16332 }
16333 break;
16334 case Tag_RISCV_stack_align:
cd30bcef
AM
16335 READ_ULEB (val, p, end);
16336 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16337 break;
16338 case Tag_RISCV_arch:
16339 p = display_tag_value (-1, p, end);
16340 break;
16341 default:
16342 return display_tag_value (tag, p, end);
16343 }
16344
16345 return p;
16346}
16347
32ec8896 16348static bfd_boolean
dda8d76d 16349process_attributes (Filedata * filedata,
60bca95a 16350 const char * public_name,
104d59d1 16351 unsigned int proc_type,
f6f0e17b 16352 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 16353 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 16354{
2cf0635d 16355 Elf_Internal_Shdr * sect;
11c1ff18 16356 unsigned i;
32ec8896 16357 bfd_boolean res = TRUE;
11c1ff18
PB
16358
16359 /* Find the section header so that we get the size. */
dda8d76d
NC
16360 for (i = 0, sect = filedata->section_headers;
16361 i < filedata->file_header.e_shnum;
11c1ff18
PB
16362 i++, sect++)
16363 {
071436c6
NC
16364 unsigned char * contents;
16365 unsigned char * p;
16366
104d59d1 16367 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
16368 continue;
16369
dda8d76d 16370 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 16371 sect->sh_size, _("attributes"));
60bca95a 16372 if (contents == NULL)
32ec8896
NC
16373 {
16374 res = FALSE;
16375 continue;
16376 }
60bca95a 16377
11c1ff18 16378 p = contents;
60abdbed
NC
16379 /* The first character is the version of the attributes.
16380 Currently only version 1, (aka 'A') is recognised here. */
16381 if (*p != 'A')
32ec8896
NC
16382 {
16383 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
16384 res = FALSE;
16385 }
60abdbed 16386 else
11c1ff18 16387 {
071436c6
NC
16388 bfd_vma section_len;
16389
16390 section_len = sect->sh_size - 1;
11c1ff18 16391 p++;
60bca95a 16392
071436c6 16393 while (section_len > 0)
11c1ff18 16394 {
071436c6 16395 bfd_vma attr_len;
e9847026 16396 unsigned int namelen;
11c1ff18 16397 bfd_boolean public_section;
104d59d1 16398 bfd_boolean gnu_section;
11c1ff18 16399
071436c6 16400 if (section_len <= 4)
e0a31db1
NC
16401 {
16402 error (_("Tag section ends prematurely\n"));
32ec8896 16403 res = FALSE;
e0a31db1
NC
16404 break;
16405 }
071436c6 16406 attr_len = byte_get (p, 4);
11c1ff18 16407 p += 4;
60bca95a 16408
071436c6 16409 if (attr_len > section_len)
11c1ff18 16410 {
071436c6
NC
16411 error (_("Bad attribute length (%u > %u)\n"),
16412 (unsigned) attr_len, (unsigned) section_len);
16413 attr_len = section_len;
32ec8896 16414 res = FALSE;
11c1ff18 16415 }
74e1a04b 16416 /* PR 17531: file: 001-101425-0.004 */
071436c6 16417 else if (attr_len < 5)
74e1a04b 16418 {
071436c6 16419 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 16420 res = FALSE;
74e1a04b
NC
16421 break;
16422 }
e9847026 16423
071436c6
NC
16424 section_len -= attr_len;
16425 attr_len -= 4;
16426
16427 namelen = strnlen ((char *) p, attr_len) + 1;
16428 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
16429 {
16430 error (_("Corrupt attribute section name\n"));
32ec8896 16431 res = FALSE;
e9847026
NC
16432 break;
16433 }
16434
071436c6
NC
16435 printf (_("Attribute Section: "));
16436 print_symbol (INT_MAX, (const char *) p);
16437 putchar ('\n');
60bca95a
NC
16438
16439 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
16440 public_section = TRUE;
16441 else
16442 public_section = FALSE;
60bca95a
NC
16443
16444 if (streq ((char *) p, "gnu"))
104d59d1
JM
16445 gnu_section = TRUE;
16446 else
16447 gnu_section = FALSE;
60bca95a 16448
11c1ff18 16449 p += namelen;
071436c6 16450 attr_len -= namelen;
e0a31db1 16451
071436c6 16452 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 16453 {
e0a31db1 16454 int tag;
cd30bcef 16455 unsigned int val;
11c1ff18 16456 bfd_vma size;
071436c6 16457 unsigned char * end;
60bca95a 16458
e0a31db1 16459 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 16460 if (attr_len < 6)
e0a31db1
NC
16461 {
16462 error (_("Unused bytes at end of section\n"));
32ec8896 16463 res = FALSE;
e0a31db1
NC
16464 section_len = 0;
16465 break;
16466 }
16467
16468 tag = *(p++);
11c1ff18 16469 size = byte_get (p, 4);
071436c6 16470 if (size > attr_len)
11c1ff18 16471 {
e9847026 16472 error (_("Bad subsection length (%u > %u)\n"),
071436c6 16473 (unsigned) size, (unsigned) attr_len);
32ec8896 16474 res = FALSE;
071436c6 16475 size = attr_len;
11c1ff18 16476 }
e0a31db1
NC
16477 /* PR binutils/17531: Safe handling of corrupt files. */
16478 if (size < 6)
16479 {
16480 error (_("Bad subsection length (%u < 6)\n"),
16481 (unsigned) size);
32ec8896 16482 res = FALSE;
e0a31db1
NC
16483 section_len = 0;
16484 break;
16485 }
60bca95a 16486
071436c6 16487 attr_len -= size;
11c1ff18 16488 end = p + size - 1;
071436c6 16489 assert (end <= contents + sect->sh_size);
11c1ff18 16490 p += 4;
60bca95a 16491
11c1ff18
PB
16492 switch (tag)
16493 {
16494 case 1:
2b692964 16495 printf (_("File Attributes\n"));
11c1ff18
PB
16496 break;
16497 case 2:
2b692964 16498 printf (_("Section Attributes:"));
11c1ff18
PB
16499 goto do_numlist;
16500 case 3:
2b692964 16501 printf (_("Symbol Attributes:"));
1a0670f3 16502 /* Fall through. */
11c1ff18
PB
16503 do_numlist:
16504 for (;;)
16505 {
cd30bcef 16506 READ_ULEB (val, p, end);
11c1ff18
PB
16507 if (val == 0)
16508 break;
16509 printf (" %d", val);
16510 }
16511 printf ("\n");
16512 break;
16513 default:
2b692964 16514 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
16515 public_section = FALSE;
16516 break;
16517 }
60bca95a 16518
071436c6 16519 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
16520 {
16521 while (p < end)
f6f0e17b 16522 p = display_pub_attribute (p, end);
60abdbed 16523 assert (p == end);
104d59d1 16524 }
071436c6 16525 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
16526 {
16527 while (p < end)
16528 p = display_gnu_attribute (p,
f6f0e17b
NC
16529 display_proc_gnu_attribute,
16530 end);
60abdbed 16531 assert (p == end);
11c1ff18 16532 }
071436c6 16533 else if (p < end)
11c1ff18 16534 {
071436c6 16535 printf (_(" Unknown attribute:\n"));
f6f0e17b 16536 display_raw_attribute (p, end);
11c1ff18
PB
16537 p = end;
16538 }
071436c6
NC
16539 else
16540 attr_len = 0;
11c1ff18
PB
16541 }
16542 }
16543 }
d70c5fc7 16544
60bca95a 16545 free (contents);
11c1ff18 16546 }
32ec8896
NC
16547
16548 return res;
11c1ff18
PB
16549}
16550
ccb4c951
RS
16551/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
16552 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
16553 and return the VMA of the next entry, or -1 if there was a problem.
16554 Does not read from DATA_END or beyond. */
ccb4c951
RS
16555
16556static bfd_vma
82b1b41b
NC
16557print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
16558 unsigned char * data_end)
ccb4c951
RS
16559{
16560 printf (" ");
16561 print_vma (addr, LONG_HEX);
16562 printf (" ");
16563 if (addr < pltgot + 0xfff0)
16564 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
16565 else
16566 printf ("%10s", "");
16567 printf (" ");
16568 if (data == NULL)
2b692964 16569 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
16570 else
16571 {
16572 bfd_vma entry;
82b1b41b 16573 unsigned char * from = data + addr - pltgot;
ccb4c951 16574
82b1b41b
NC
16575 if (from + (is_32bit_elf ? 4 : 8) > data_end)
16576 {
16577 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
16578 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
16579 return (bfd_vma) -1;
16580 }
16581 else
16582 {
16583 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16584 print_vma (entry, LONG_HEX);
16585 }
ccb4c951
RS
16586 }
16587 return addr + (is_32bit_elf ? 4 : 8);
16588}
16589
861fb55a
DJ
16590/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
16591 PLTGOT. Print the Address and Initial fields of an entry at VMA
16592 ADDR and return the VMA of the next entry. */
16593
16594static bfd_vma
2cf0635d 16595print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
16596{
16597 printf (" ");
16598 print_vma (addr, LONG_HEX);
16599 printf (" ");
16600 if (data == NULL)
2b692964 16601 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
16602 else
16603 {
16604 bfd_vma entry;
16605
16606 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
16607 print_vma (entry, LONG_HEX);
16608 }
16609 return addr + (is_32bit_elf ? 4 : 8);
16610}
16611
351cdf24
MF
16612static void
16613print_mips_ases (unsigned int mask)
16614{
16615 if (mask & AFL_ASE_DSP)
16616 fputs ("\n\tDSP ASE", stdout);
16617 if (mask & AFL_ASE_DSPR2)
16618 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
16619 if (mask & AFL_ASE_DSPR3)
16620 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
16621 if (mask & AFL_ASE_EVA)
16622 fputs ("\n\tEnhanced VA Scheme", stdout);
16623 if (mask & AFL_ASE_MCU)
16624 fputs ("\n\tMCU (MicroController) ASE", stdout);
16625 if (mask & AFL_ASE_MDMX)
16626 fputs ("\n\tMDMX ASE", stdout);
16627 if (mask & AFL_ASE_MIPS3D)
16628 fputs ("\n\tMIPS-3D ASE", stdout);
16629 if (mask & AFL_ASE_MT)
16630 fputs ("\n\tMT ASE", stdout);
16631 if (mask & AFL_ASE_SMARTMIPS)
16632 fputs ("\n\tSmartMIPS ASE", stdout);
16633 if (mask & AFL_ASE_VIRT)
16634 fputs ("\n\tVZ ASE", stdout);
16635 if (mask & AFL_ASE_MSA)
16636 fputs ("\n\tMSA ASE", stdout);
16637 if (mask & AFL_ASE_MIPS16)
16638 fputs ("\n\tMIPS16 ASE", stdout);
16639 if (mask & AFL_ASE_MICROMIPS)
16640 fputs ("\n\tMICROMIPS ASE", stdout);
16641 if (mask & AFL_ASE_XPA)
16642 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
16643 if (mask & AFL_ASE_MIPS16E2)
16644 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
16645 if (mask & AFL_ASE_CRC)
16646 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
16647 if (mask & AFL_ASE_GINV)
16648 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
16649 if (mask & AFL_ASE_LOONGSON_MMI)
16650 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
16651 if (mask & AFL_ASE_LOONGSON_CAM)
16652 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
16653 if (mask & AFL_ASE_LOONGSON_EXT)
16654 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
16655 if (mask & AFL_ASE_LOONGSON_EXT2)
16656 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
16657 if (mask == 0)
16658 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
16659 else if ((mask & ~AFL_ASE_MASK) != 0)
16660 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
16661}
16662
16663static void
16664print_mips_isa_ext (unsigned int isa_ext)
16665{
16666 switch (isa_ext)
16667 {
16668 case 0:
16669 fputs (_("None"), stdout);
16670 break;
16671 case AFL_EXT_XLR:
16672 fputs ("RMI XLR", stdout);
16673 break;
2c629856
N
16674 case AFL_EXT_OCTEON3:
16675 fputs ("Cavium Networks Octeon3", stdout);
16676 break;
351cdf24
MF
16677 case AFL_EXT_OCTEON2:
16678 fputs ("Cavium Networks Octeon2", stdout);
16679 break;
16680 case AFL_EXT_OCTEONP:
16681 fputs ("Cavium Networks OcteonP", stdout);
16682 break;
351cdf24
MF
16683 case AFL_EXT_OCTEON:
16684 fputs ("Cavium Networks Octeon", stdout);
16685 break;
16686 case AFL_EXT_5900:
16687 fputs ("Toshiba R5900", stdout);
16688 break;
16689 case AFL_EXT_4650:
16690 fputs ("MIPS R4650", stdout);
16691 break;
16692 case AFL_EXT_4010:
16693 fputs ("LSI R4010", stdout);
16694 break;
16695 case AFL_EXT_4100:
16696 fputs ("NEC VR4100", stdout);
16697 break;
16698 case AFL_EXT_3900:
16699 fputs ("Toshiba R3900", stdout);
16700 break;
16701 case AFL_EXT_10000:
16702 fputs ("MIPS R10000", stdout);
16703 break;
16704 case AFL_EXT_SB1:
16705 fputs ("Broadcom SB-1", stdout);
16706 break;
16707 case AFL_EXT_4111:
16708 fputs ("NEC VR4111/VR4181", stdout);
16709 break;
16710 case AFL_EXT_4120:
16711 fputs ("NEC VR4120", stdout);
16712 break;
16713 case AFL_EXT_5400:
16714 fputs ("NEC VR5400", stdout);
16715 break;
16716 case AFL_EXT_5500:
16717 fputs ("NEC VR5500", stdout);
16718 break;
16719 case AFL_EXT_LOONGSON_2E:
16720 fputs ("ST Microelectronics Loongson 2E", stdout);
16721 break;
16722 case AFL_EXT_LOONGSON_2F:
16723 fputs ("ST Microelectronics Loongson 2F", stdout);
16724 break;
38bf472a
MR
16725 case AFL_EXT_INTERAPTIV_MR2:
16726 fputs ("Imagination interAptiv MR2", stdout);
16727 break;
351cdf24 16728 default:
00ac7aa0 16729 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
16730 }
16731}
16732
32ec8896 16733static signed int
351cdf24
MF
16734get_mips_reg_size (int reg_size)
16735{
16736 return (reg_size == AFL_REG_NONE) ? 0
16737 : (reg_size == AFL_REG_32) ? 32
16738 : (reg_size == AFL_REG_64) ? 64
16739 : (reg_size == AFL_REG_128) ? 128
16740 : -1;
16741}
16742
32ec8896 16743static bfd_boolean
dda8d76d 16744process_mips_specific (Filedata * filedata)
5b18a4bc 16745{
2cf0635d 16746 Elf_Internal_Dyn * entry;
351cdf24 16747 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
16748 size_t liblist_offset = 0;
16749 size_t liblistno = 0;
16750 size_t conflictsno = 0;
16751 size_t options_offset = 0;
16752 size_t conflicts_offset = 0;
861fb55a
DJ
16753 size_t pltrelsz = 0;
16754 size_t pltrel = 0;
ccb4c951 16755 bfd_vma pltgot = 0;
861fb55a
DJ
16756 bfd_vma mips_pltgot = 0;
16757 bfd_vma jmprel = 0;
ccb4c951
RS
16758 bfd_vma local_gotno = 0;
16759 bfd_vma gotsym = 0;
16760 bfd_vma symtabno = 0;
32ec8896 16761 bfd_boolean res = TRUE;
103f02d3 16762
dda8d76d 16763 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
16764 display_mips_gnu_attribute))
16765 res = FALSE;
2cf19d5c 16766
dda8d76d 16767 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
16768
16769 if (sect != NULL)
16770 {
16771 Elf_External_ABIFlags_v0 *abiflags_ext;
16772 Elf_Internal_ABIFlags_v0 abiflags_in;
16773
16774 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
16775 {
16776 error (_("Corrupt MIPS ABI Flags section.\n"));
16777 res = FALSE;
16778 }
351cdf24
MF
16779 else
16780 {
dda8d76d 16781 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
16782 sect->sh_size, _("MIPS ABI Flags section"));
16783 if (abiflags_ext)
16784 {
16785 abiflags_in.version = BYTE_GET (abiflags_ext->version);
16786 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
16787 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
16788 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
16789 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
16790 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
16791 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
16792 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
16793 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
16794 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
16795 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
16796
16797 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
16798 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
16799 if (abiflags_in.isa_rev > 1)
16800 printf ("r%d", abiflags_in.isa_rev);
16801 printf ("\nGPR size: %d",
16802 get_mips_reg_size (abiflags_in.gpr_size));
16803 printf ("\nCPR1 size: %d",
16804 get_mips_reg_size (abiflags_in.cpr1_size));
16805 printf ("\nCPR2 size: %d",
16806 get_mips_reg_size (abiflags_in.cpr2_size));
16807 fputs ("\nFP ABI: ", stdout);
16808 print_mips_fp_abi_value (abiflags_in.fp_abi);
16809 fputs ("ISA Extension: ", stdout);
16810 print_mips_isa_ext (abiflags_in.isa_ext);
16811 fputs ("\nASEs:", stdout);
16812 print_mips_ases (abiflags_in.ases);
16813 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
16814 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
16815 fputc ('\n', stdout);
16816 free (abiflags_ext);
16817 }
16818 }
16819 }
16820
19e6b90e 16821 /* We have a lot of special sections. Thanks SGI! */
978c4450 16822 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
16823 {
16824 /* No dynamic information available. See if there is static GOT. */
dda8d76d 16825 sect = find_section (filedata, ".got");
bbdd9a68
MR
16826 if (sect != NULL)
16827 {
16828 unsigned char *data_end;
16829 unsigned char *data;
16830 bfd_vma ent, end;
16831 int addr_size;
16832
16833 pltgot = sect->sh_addr;
16834
16835 ent = pltgot;
16836 addr_size = (is_32bit_elf ? 4 : 8);
16837 end = pltgot + sect->sh_size;
16838
dda8d76d 16839 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
16840 end - pltgot, 1,
16841 _("Global Offset Table data"));
16842 /* PR 12855: Null data is handled gracefully throughout. */
16843 data_end = data + (end - pltgot);
16844
16845 printf (_("\nStatic GOT:\n"));
16846 printf (_(" Canonical gp value: "));
16847 print_vma (ent + 0x7ff0, LONG_HEX);
16848 printf ("\n\n");
16849
16850 /* In a dynamic binary GOT[0] is reserved for the dynamic
16851 loader to store the lazy resolver pointer, however in
16852 a static binary it may well have been omitted and GOT
16853 reduced to a table of addresses.
16854 PR 21344: Check for the entry being fully available
16855 before fetching it. */
16856 if (data
16857 && data + ent - pltgot + addr_size <= data_end
16858 && byte_get (data + ent - pltgot, addr_size) == 0)
16859 {
16860 printf (_(" Reserved entries:\n"));
16861 printf (_(" %*s %10s %*s\n"),
16862 addr_size * 2, _("Address"), _("Access"),
16863 addr_size * 2, _("Value"));
16864 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16865 printf ("\n");
16866 if (ent == (bfd_vma) -1)
16867 goto sgot_print_fail;
16868
16869 /* Check for the MSB of GOT[1] being set, identifying a
16870 GNU object. This entry will be used by some runtime
16871 loaders, to store the module pointer. Otherwise this
16872 is an ordinary local entry.
16873 PR 21344: Check for the entry being fully available
16874 before fetching it. */
16875 if (data
16876 && data + ent - pltgot + addr_size <= data_end
16877 && (byte_get (data + ent - pltgot, addr_size)
16878 >> (addr_size * 8 - 1)) != 0)
16879 {
16880 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16881 printf ("\n");
16882 if (ent == (bfd_vma) -1)
16883 goto sgot_print_fail;
16884 }
16885 printf ("\n");
16886 }
16887
f17e9d8a 16888 if (data != NULL && ent < end)
bbdd9a68
MR
16889 {
16890 printf (_(" Local entries:\n"));
16891 printf (" %*s %10s %*s\n",
16892 addr_size * 2, _("Address"), _("Access"),
16893 addr_size * 2, _("Value"));
16894 while (ent < end)
16895 {
16896 ent = print_mips_got_entry (data, pltgot, ent, data_end);
16897 printf ("\n");
16898 if (ent == (bfd_vma) -1)
16899 goto sgot_print_fail;
16900 }
16901 printf ("\n");
16902 }
16903
16904 sgot_print_fail:
9db70fc3 16905 free (data);
bbdd9a68
MR
16906 }
16907 return res;
16908 }
252b5132 16909
978c4450 16910 for (entry = filedata->dynamic_section;
071436c6 16911 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
16912 (entry < filedata->dynamic_section + filedata->dynamic_nent
16913 && entry->d_tag != DT_NULL);
071436c6 16914 ++entry)
252b5132
RH
16915 switch (entry->d_tag)
16916 {
16917 case DT_MIPS_LIBLIST:
d93f0186 16918 liblist_offset
dda8d76d 16919 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16920 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
16921 break;
16922 case DT_MIPS_LIBLISTNO:
16923 liblistno = entry->d_un.d_val;
16924 break;
16925 case DT_MIPS_OPTIONS:
dda8d76d 16926 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
16927 break;
16928 case DT_MIPS_CONFLICT:
d93f0186 16929 conflicts_offset
dda8d76d 16930 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 16931 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
16932 break;
16933 case DT_MIPS_CONFLICTNO:
16934 conflictsno = entry->d_un.d_val;
16935 break;
ccb4c951 16936 case DT_PLTGOT:
861fb55a
DJ
16937 pltgot = entry->d_un.d_ptr;
16938 break;
ccb4c951
RS
16939 case DT_MIPS_LOCAL_GOTNO:
16940 local_gotno = entry->d_un.d_val;
16941 break;
16942 case DT_MIPS_GOTSYM:
16943 gotsym = entry->d_un.d_val;
16944 break;
16945 case DT_MIPS_SYMTABNO:
16946 symtabno = entry->d_un.d_val;
16947 break;
861fb55a
DJ
16948 case DT_MIPS_PLTGOT:
16949 mips_pltgot = entry->d_un.d_ptr;
16950 break;
16951 case DT_PLTREL:
16952 pltrel = entry->d_un.d_val;
16953 break;
16954 case DT_PLTRELSZ:
16955 pltrelsz = entry->d_un.d_val;
16956 break;
16957 case DT_JMPREL:
16958 jmprel = entry->d_un.d_ptr;
16959 break;
252b5132
RH
16960 default:
16961 break;
16962 }
16963
16964 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
16965 {
2cf0635d 16966 Elf32_External_Lib * elib;
252b5132
RH
16967 size_t cnt;
16968
dda8d76d 16969 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
16970 sizeof (Elf32_External_Lib),
16971 liblistno,
16972 _("liblist section data"));
a6e9f9df 16973 if (elib)
252b5132 16974 {
d3a49aa8
AM
16975 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
16976 "\nSection '.liblist' contains %lu entries:\n",
16977 (unsigned long) liblistno),
a6e9f9df 16978 (unsigned long) liblistno);
2b692964 16979 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
16980 stdout);
16981
16982 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 16983 {
a6e9f9df 16984 Elf32_Lib liblist;
91d6fa6a 16985 time_t atime;
d5b07ef4 16986 char timebuf[128];
2cf0635d 16987 struct tm * tmp;
a6e9f9df
AM
16988
16989 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 16990 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
16991 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
16992 liblist.l_version = BYTE_GET (elib[cnt].l_version);
16993 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
16994
91d6fa6a 16995 tmp = gmtime (&atime);
e9e44622
JJ
16996 snprintf (timebuf, sizeof (timebuf),
16997 "%04u-%02u-%02uT%02u:%02u:%02u",
16998 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
16999 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17000
31104126 17001 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17002 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17003 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17004 else
2b692964 17005 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17006 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17007 liblist.l_version);
a6e9f9df
AM
17008
17009 if (liblist.l_flags == 0)
2b692964 17010 puts (_(" NONE"));
a6e9f9df
AM
17011 else
17012 {
17013 static const struct
252b5132 17014 {
2cf0635d 17015 const char * name;
a6e9f9df 17016 int bit;
252b5132 17017 }
a6e9f9df
AM
17018 l_flags_vals[] =
17019 {
17020 { " EXACT_MATCH", LL_EXACT_MATCH },
17021 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17022 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17023 { " EXPORTS", LL_EXPORTS },
17024 { " DELAY_LOAD", LL_DELAY_LOAD },
17025 { " DELTA", LL_DELTA }
17026 };
17027 int flags = liblist.l_flags;
17028 size_t fcnt;
17029
60bca95a 17030 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17031 if ((flags & l_flags_vals[fcnt].bit) != 0)
17032 {
17033 fputs (l_flags_vals[fcnt].name, stdout);
17034 flags ^= l_flags_vals[fcnt].bit;
17035 }
17036 if (flags != 0)
17037 printf (" %#x", (unsigned int) flags);
252b5132 17038
a6e9f9df
AM
17039 puts ("");
17040 }
252b5132 17041 }
252b5132 17042
a6e9f9df
AM
17043 free (elib);
17044 }
32ec8896
NC
17045 else
17046 res = FALSE;
252b5132
RH
17047 }
17048
17049 if (options_offset != 0)
17050 {
2cf0635d 17051 Elf_External_Options * eopt;
252b5132
RH
17052 size_t offset;
17053 int cnt;
dda8d76d 17054 sect = filedata->section_headers;
252b5132
RH
17055
17056 /* Find the section header so that we get the size. */
dda8d76d 17057 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17058 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17059 if (sect == NULL)
17060 {
17061 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 17062 return FALSE;
071436c6 17063 }
7fc0c668
NC
17064 /* PR 24243 */
17065 if (sect->sh_size < sizeof (* eopt))
17066 {
17067 error (_("The MIPS options section is too small.\n"));
17068 return FALSE;
17069 }
252b5132 17070
dda8d76d 17071 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17072 sect->sh_size, _("options"));
a6e9f9df 17073 if (eopt)
252b5132 17074 {
fd17d1e6 17075 Elf_Internal_Options option;
76da6bbe 17076
a6e9f9df 17077 offset = cnt = 0;
82b1b41b 17078 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17079 {
2cf0635d 17080 Elf_External_Options * eoption;
fd17d1e6 17081 unsigned int optsize;
252b5132 17082
a6e9f9df 17083 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17084
fd17d1e6 17085 optsize = BYTE_GET (eoption->size);
76da6bbe 17086
82b1b41b 17087 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17088 if (optsize < sizeof (* eopt)
17089 || optsize > sect->sh_size - offset)
82b1b41b 17090 {
645f43a8 17091 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17092 optsize);
645f43a8 17093 free (eopt);
32ec8896 17094 return FALSE;
82b1b41b 17095 }
fd17d1e6 17096 offset += optsize;
a6e9f9df
AM
17097 ++cnt;
17098 }
252b5132 17099
d3a49aa8
AM
17100 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17101 "\nSection '%s' contains %d entries:\n",
17102 cnt),
dda8d76d 17103 printable_section_name (filedata, sect), cnt);
76da6bbe 17104
82b1b41b 17105 offset = 0;
a6e9f9df 17106 while (cnt-- > 0)
252b5132 17107 {
a6e9f9df 17108 size_t len;
fd17d1e6
AM
17109 Elf_External_Options * eoption;
17110
17111 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17112
17113 option.kind = BYTE_GET (eoption->kind);
17114 option.size = BYTE_GET (eoption->size);
17115 option.section = BYTE_GET (eoption->section);
17116 option.info = BYTE_GET (eoption->info);
a6e9f9df 17117
fd17d1e6 17118 switch (option.kind)
252b5132 17119 {
a6e9f9df
AM
17120 case ODK_NULL:
17121 /* This shouldn't happen. */
d0c4e780 17122 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 17123 option.section, option.info);
a6e9f9df 17124 break;
2e6be59c 17125
a6e9f9df
AM
17126 case ODK_REGINFO:
17127 printf (" REGINFO ");
dda8d76d 17128 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17129 {
2cf0635d 17130 Elf32_External_RegInfo * ereg;
b34976b6 17131 Elf32_RegInfo reginfo;
a6e9f9df 17132
2e6be59c 17133 /* 32bit form. */
fd17d1e6
AM
17134 if (option.size < (sizeof (Elf_External_Options)
17135 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
17136 {
17137 printf (_("<corrupt>\n"));
17138 error (_("Truncated MIPS REGINFO option\n"));
17139 cnt = 0;
17140 break;
17141 }
17142
fd17d1e6 17143 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 17144
a6e9f9df
AM
17145 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17146 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17147 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17148 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17149 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17150 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17151
d0c4e780
AM
17152 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
17153 reginfo.ri_gprmask, reginfo.ri_gp_value);
17154 printf (" "
17155 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17156 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17157 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17158 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17159 }
17160 else
17161 {
17162 /* 64 bit form. */
2cf0635d 17163 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17164 Elf64_Internal_RegInfo reginfo;
17165
fd17d1e6
AM
17166 if (option.size < (sizeof (Elf_External_Options)
17167 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
17168 {
17169 printf (_("<corrupt>\n"));
17170 error (_("Truncated MIPS REGINFO option\n"));
17171 cnt = 0;
17172 break;
17173 }
17174
fd17d1e6 17175 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
17176 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17177 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17178 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17179 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17180 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 17181 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 17182
d0c4e780
AM
17183 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
17184 reginfo.ri_gprmask, reginfo.ri_gp_value);
17185 printf (" "
17186 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17187 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17188 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17189 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17190 }
fd17d1e6 17191 offset += option.size;
a6e9f9df 17192 continue;
2e6be59c 17193
a6e9f9df
AM
17194 case ODK_EXCEPTIONS:
17195 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 17196 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 17197 fputs (") fpe_max(", stdout);
fd17d1e6 17198 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
17199 fputs (")", stdout);
17200
fd17d1e6 17201 if (option.info & OEX_PAGE0)
a6e9f9df 17202 fputs (" PAGE0", stdout);
fd17d1e6 17203 if (option.info & OEX_SMM)
a6e9f9df 17204 fputs (" SMM", stdout);
fd17d1e6 17205 if (option.info & OEX_FPDBUG)
a6e9f9df 17206 fputs (" FPDBUG", stdout);
fd17d1e6 17207 if (option.info & OEX_DISMISS)
a6e9f9df
AM
17208 fputs (" DISMISS", stdout);
17209 break;
2e6be59c 17210
a6e9f9df
AM
17211 case ODK_PAD:
17212 fputs (" PAD ", stdout);
fd17d1e6 17213 if (option.info & OPAD_PREFIX)
a6e9f9df 17214 fputs (" PREFIX", stdout);
fd17d1e6 17215 if (option.info & OPAD_POSTFIX)
a6e9f9df 17216 fputs (" POSTFIX", stdout);
fd17d1e6 17217 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
17218 fputs (" SYMBOL", stdout);
17219 break;
2e6be59c 17220
a6e9f9df
AM
17221 case ODK_HWPATCH:
17222 fputs (" HWPATCH ", stdout);
fd17d1e6 17223 if (option.info & OHW_R4KEOP)
a6e9f9df 17224 fputs (" R4KEOP", stdout);
fd17d1e6 17225 if (option.info & OHW_R8KPFETCH)
a6e9f9df 17226 fputs (" R8KPFETCH", stdout);
fd17d1e6 17227 if (option.info & OHW_R5KEOP)
a6e9f9df 17228 fputs (" R5KEOP", stdout);
fd17d1e6 17229 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
17230 fputs (" R5KCVTL", stdout);
17231 break;
2e6be59c 17232
a6e9f9df
AM
17233 case ODK_FILL:
17234 fputs (" FILL ", stdout);
17235 /* XXX Print content of info word? */
17236 break;
2e6be59c 17237
a6e9f9df
AM
17238 case ODK_TAGS:
17239 fputs (" TAGS ", stdout);
17240 /* XXX Print content of info word? */
17241 break;
2e6be59c 17242
a6e9f9df
AM
17243 case ODK_HWAND:
17244 fputs (" HWAND ", stdout);
fd17d1e6 17245 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17246 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17247 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17248 fputs (" R4KEOP_CLEAN", stdout);
17249 break;
2e6be59c 17250
a6e9f9df
AM
17251 case ODK_HWOR:
17252 fputs (" HWOR ", stdout);
fd17d1e6 17253 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17254 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17255 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17256 fputs (" R4KEOP_CLEAN", stdout);
17257 break;
2e6be59c 17258
a6e9f9df 17259 case ODK_GP_GROUP:
d0c4e780 17260 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
17261 option.info & OGP_GROUP,
17262 (option.info & OGP_SELF) >> 16);
a6e9f9df 17263 break;
2e6be59c 17264
a6e9f9df 17265 case ODK_IDENT:
d0c4e780 17266 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
17267 option.info & OGP_GROUP,
17268 (option.info & OGP_SELF) >> 16);
a6e9f9df 17269 break;
2e6be59c 17270
a6e9f9df
AM
17271 default:
17272 /* This shouldn't happen. */
d0c4e780 17273 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 17274 option.kind, option.section, option.info);
a6e9f9df 17275 break;
252b5132 17276 }
a6e9f9df 17277
2cf0635d 17278 len = sizeof (* eopt);
fd17d1e6 17279 while (len < option.size)
82b1b41b 17280 {
fd17d1e6 17281 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 17282
82b1b41b
NC
17283 if (ISPRINT (datum))
17284 printf ("%c", datum);
17285 else
17286 printf ("\\%03o", datum);
17287 len ++;
17288 }
a6e9f9df 17289 fputs ("\n", stdout);
82b1b41b 17290
fd17d1e6 17291 offset += option.size;
252b5132 17292 }
a6e9f9df 17293 free (eopt);
252b5132 17294 }
32ec8896
NC
17295 else
17296 res = FALSE;
252b5132
RH
17297 }
17298
17299 if (conflicts_offset != 0 && conflictsno != 0)
17300 {
2cf0635d 17301 Elf32_Conflict * iconf;
252b5132
RH
17302 size_t cnt;
17303
978c4450 17304 if (filedata->dynamic_symbols == NULL)
252b5132 17305 {
591a748a 17306 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 17307 return FALSE;
252b5132
RH
17308 }
17309
7296a62a
NC
17310 /* PR 21345 - print a slightly more helpful error message
17311 if we are sure that the cmalloc will fail. */
645f43a8 17312 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
17313 {
17314 error (_("Overlarge number of conflicts detected: %lx\n"),
17315 (long) conflictsno);
17316 return FALSE;
17317 }
17318
3f5e193b 17319 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
17320 if (iconf == NULL)
17321 {
8b73c356 17322 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 17323 return FALSE;
252b5132
RH
17324 }
17325
9ea033b2 17326 if (is_32bit_elf)
252b5132 17327 {
2cf0635d 17328 Elf32_External_Conflict * econf32;
a6e9f9df 17329
3f5e193b 17330 econf32 = (Elf32_External_Conflict *)
95099889
AM
17331 get_data (NULL, filedata, conflicts_offset,
17332 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 17333 if (!econf32)
5a814d6d
AM
17334 {
17335 free (iconf);
17336 return FALSE;
17337 }
252b5132
RH
17338
17339 for (cnt = 0; cnt < conflictsno; ++cnt)
17340 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
17341
17342 free (econf32);
252b5132
RH
17343 }
17344 else
17345 {
2cf0635d 17346 Elf64_External_Conflict * econf64;
a6e9f9df 17347
3f5e193b 17348 econf64 = (Elf64_External_Conflict *)
95099889
AM
17349 get_data (NULL, filedata, conflicts_offset,
17350 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 17351 if (!econf64)
5a814d6d
AM
17352 {
17353 free (iconf);
17354 return FALSE;
17355 }
252b5132
RH
17356
17357 for (cnt = 0; cnt < conflictsno; ++cnt)
17358 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
17359
17360 free (econf64);
252b5132
RH
17361 }
17362
d3a49aa8
AM
17363 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
17364 "\nSection '.conflict' contains %lu entries:\n",
17365 (unsigned long) conflictsno),
c7e7ca54 17366 (unsigned long) conflictsno);
252b5132
RH
17367 puts (_(" Num: Index Value Name"));
17368
17369 for (cnt = 0; cnt < conflictsno; ++cnt)
17370 {
b34976b6 17371 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 17372
978c4450 17373 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 17374 printf (_("<corrupt symbol index>"));
d79b3d50 17375 else
e0a31db1
NC
17376 {
17377 Elf_Internal_Sym * psym;
17378
978c4450 17379 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
17380 print_vma (psym->st_value, FULL_HEX);
17381 putchar (' ');
978c4450
AM
17382 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17383 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17384 else
17385 printf (_("<corrupt: %14ld>"), psym->st_name);
17386 }
31104126 17387 putchar ('\n');
252b5132
RH
17388 }
17389
252b5132
RH
17390 free (iconf);
17391 }
17392
ccb4c951
RS
17393 if (pltgot != 0 && local_gotno != 0)
17394 {
91d6fa6a 17395 bfd_vma ent, local_end, global_end;
bbeee7ea 17396 size_t i, offset;
2cf0635d 17397 unsigned char * data;
82b1b41b 17398 unsigned char * data_end;
bbeee7ea 17399 int addr_size;
ccb4c951 17400
91d6fa6a 17401 ent = pltgot;
ccb4c951
RS
17402 addr_size = (is_32bit_elf ? 4 : 8);
17403 local_end = pltgot + local_gotno * addr_size;
ccb4c951 17404
74e1a04b
NC
17405 /* PR binutils/17533 file: 012-111227-0.004 */
17406 if (symtabno < gotsym)
17407 {
17408 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 17409 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 17410 return FALSE;
74e1a04b 17411 }
82b1b41b 17412
74e1a04b 17413 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
17414 /* PR 17531: file: 54c91a34. */
17415 if (global_end < local_end)
17416 {
17417 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 17418 return FALSE;
82b1b41b 17419 }
948f632f 17420
dda8d76d
NC
17421 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
17422 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
17423 global_end - pltgot, 1,
17424 _("Global Offset Table data"));
919383ac 17425 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 17426 data_end = data + (global_end - pltgot);
59245841 17427
ccb4c951
RS
17428 printf (_("\nPrimary GOT:\n"));
17429 printf (_(" Canonical gp value: "));
17430 print_vma (pltgot + 0x7ff0, LONG_HEX);
17431 printf ("\n\n");
17432
17433 printf (_(" Reserved entries:\n"));
17434 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
17435 addr_size * 2, _("Address"), _("Access"),
17436 addr_size * 2, _("Initial"));
82b1b41b 17437 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 17438 printf (_(" Lazy resolver\n"));
82b1b41b
NC
17439 if (ent == (bfd_vma) -1)
17440 goto got_print_fail;
75ec1fdb 17441
c4ab9505
MR
17442 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
17443 This entry will be used by some runtime loaders, to store the
17444 module pointer. Otherwise this is an ordinary local entry.
17445 PR 21344: Check for the entry being fully available before
17446 fetching it. */
17447 if (data
17448 && data + ent - pltgot + addr_size <= data_end
17449 && (byte_get (data + ent - pltgot, addr_size)
17450 >> (addr_size * 8 - 1)) != 0)
17451 {
17452 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17453 printf (_(" Module pointer (GNU extension)\n"));
17454 if (ent == (bfd_vma) -1)
17455 goto got_print_fail;
ccb4c951
RS
17456 }
17457 printf ("\n");
17458
f17e9d8a 17459 if (data != NULL && ent < local_end)
ccb4c951
RS
17460 {
17461 printf (_(" Local entries:\n"));
cc5914eb 17462 printf (" %*s %10s %*s\n",
2b692964
NC
17463 addr_size * 2, _("Address"), _("Access"),
17464 addr_size * 2, _("Initial"));
91d6fa6a 17465 while (ent < local_end)
ccb4c951 17466 {
82b1b41b 17467 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17468 printf ("\n");
82b1b41b
NC
17469 if (ent == (bfd_vma) -1)
17470 goto got_print_fail;
ccb4c951
RS
17471 }
17472 printf ("\n");
17473 }
17474
f17e9d8a 17475 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
17476 {
17477 int sym_width;
17478
17479 printf (_(" Global entries:\n"));
cc5914eb 17480 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
17481 addr_size * 2, _("Address"),
17482 _("Access"),
2b692964 17483 addr_size * 2, _("Initial"),
9cf03b7e
NC
17484 addr_size * 2, _("Sym.Val."),
17485 _("Type"),
17486 /* Note for translators: "Ndx" = abbreviated form of "Index". */
17487 _("Ndx"), _("Name"));
0b4362b0 17488
ccb4c951 17489 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 17490
ccb4c951
RS
17491 for (i = gotsym; i < symtabno; i++)
17492 {
82b1b41b 17493 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 17494 printf (" ");
e0a31db1 17495
978c4450 17496 if (filedata->dynamic_symbols == NULL)
e0a31db1 17497 printf (_("<no dynamic symbols>"));
978c4450 17498 else if (i < filedata->num_dynamic_syms)
e0a31db1 17499 {
978c4450 17500 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
17501
17502 print_vma (psym->st_value, LONG_HEX);
17503 printf (" %-7s %3s ",
dda8d76d
NC
17504 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17505 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 17506
978c4450
AM
17507 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17508 print_symbol (sym_width,
17509 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17510 else
17511 printf (_("<corrupt: %14ld>"), psym->st_name);
17512 }
ccb4c951 17513 else
7fc5ac57
JBG
17514 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
17515 (unsigned long) i);
e0a31db1 17516
ccb4c951 17517 printf ("\n");
82b1b41b
NC
17518 if (ent == (bfd_vma) -1)
17519 break;
ccb4c951
RS
17520 }
17521 printf ("\n");
17522 }
17523
82b1b41b 17524 got_print_fail:
9db70fc3 17525 free (data);
ccb4c951
RS
17526 }
17527
861fb55a
DJ
17528 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
17529 {
91d6fa6a 17530 bfd_vma ent, end;
861fb55a
DJ
17531 size_t offset, rel_offset;
17532 unsigned long count, i;
2cf0635d 17533 unsigned char * data;
861fb55a 17534 int addr_size, sym_width;
2cf0635d 17535 Elf_Internal_Rela * rels;
861fb55a 17536
dda8d76d 17537 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
17538 if (pltrel == DT_RELA)
17539 {
dda8d76d 17540 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17541 return FALSE;
861fb55a
DJ
17542 }
17543 else
17544 {
dda8d76d 17545 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 17546 return FALSE;
861fb55a
DJ
17547 }
17548
91d6fa6a 17549 ent = mips_pltgot;
861fb55a
DJ
17550 addr_size = (is_32bit_elf ? 4 : 8);
17551 end = mips_pltgot + (2 + count) * addr_size;
17552
dda8d76d
NC
17553 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
17554 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 17555 1, _("Procedure Linkage Table data"));
59245841 17556 if (data == NULL)
32ec8896 17557 return FALSE;
59245841 17558
9cf03b7e 17559 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
17560 printf (_(" Reserved entries:\n"));
17561 printf (_(" %*s %*s Purpose\n"),
2b692964 17562 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 17563 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17564 printf (_(" PLT lazy resolver\n"));
91d6fa6a 17565 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 17566 printf (_(" Module pointer\n"));
861fb55a
DJ
17567 printf ("\n");
17568
17569 printf (_(" Entries:\n"));
cc5914eb 17570 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
17571 addr_size * 2, _("Address"),
17572 addr_size * 2, _("Initial"),
17573 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
17574 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
17575 for (i = 0; i < count; i++)
17576 {
df97ab2a 17577 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 17578
91d6fa6a 17579 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 17580 printf (" ");
e0a31db1 17581
978c4450 17582 if (idx >= filedata->num_dynamic_syms)
df97ab2a 17583 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 17584 else
e0a31db1 17585 {
978c4450 17586 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
17587
17588 print_vma (psym->st_value, LONG_HEX);
17589 printf (" %-7s %3s ",
dda8d76d
NC
17590 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
17591 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
17592 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17593 print_symbol (sym_width,
17594 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17595 else
17596 printf (_("<corrupt: %14ld>"), psym->st_name);
17597 }
861fb55a
DJ
17598 printf ("\n");
17599 }
17600 printf ("\n");
17601
9db70fc3 17602 free (data);
861fb55a
DJ
17603 free (rels);
17604 }
17605
32ec8896 17606 return res;
252b5132
RH
17607}
17608
32ec8896 17609static bfd_boolean
dda8d76d 17610process_nds32_specific (Filedata * filedata)
35c08157
KLC
17611{
17612 Elf_Internal_Shdr *sect = NULL;
17613
dda8d76d 17614 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 17615 if (sect != NULL && sect->sh_size >= 4)
35c08157 17616 {
9c7b8e9b
AM
17617 unsigned char *buf;
17618 unsigned int flag;
35c08157
KLC
17619
17620 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
17621 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
17622 _("NDS32 elf flags section"));
35c08157 17623
9c7b8e9b 17624 if (buf == NULL)
32ec8896
NC
17625 return FALSE;
17626
9c7b8e9b
AM
17627 flag = byte_get (buf, 4);
17628 free (buf);
17629 switch (flag & 0x3)
35c08157
KLC
17630 {
17631 case 0:
17632 printf ("(VEC_SIZE):\tNo entry.\n");
17633 break;
17634 case 1:
17635 printf ("(VEC_SIZE):\t4 bytes\n");
17636 break;
17637 case 2:
17638 printf ("(VEC_SIZE):\t16 bytes\n");
17639 break;
17640 case 3:
17641 printf ("(VEC_SIZE):\treserved\n");
17642 break;
17643 }
17644 }
17645
17646 return TRUE;
17647}
17648
32ec8896 17649static bfd_boolean
dda8d76d 17650process_gnu_liblist (Filedata * filedata)
047b2264 17651{
2cf0635d
NC
17652 Elf_Internal_Shdr * section;
17653 Elf_Internal_Shdr * string_sec;
17654 Elf32_External_Lib * elib;
17655 char * strtab;
c256ffe7 17656 size_t strtab_size;
047b2264 17657 size_t cnt;
d3a49aa8 17658 unsigned long num_liblist;
047b2264 17659 unsigned i;
32ec8896 17660 bfd_boolean res = TRUE;
047b2264
JJ
17661
17662 if (! do_arch)
32ec8896 17663 return TRUE;
047b2264 17664
dda8d76d
NC
17665 for (i = 0, section = filedata->section_headers;
17666 i < filedata->file_header.e_shnum;
b34976b6 17667 i++, section++)
047b2264
JJ
17668 {
17669 switch (section->sh_type)
17670 {
17671 case SHT_GNU_LIBLIST:
dda8d76d 17672 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
17673 break;
17674
3f5e193b 17675 elib = (Elf32_External_Lib *)
dda8d76d 17676 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 17677 _("liblist section data"));
047b2264
JJ
17678
17679 if (elib == NULL)
32ec8896
NC
17680 {
17681 res = FALSE;
17682 break;
17683 }
047b2264 17684
dda8d76d
NC
17685 string_sec = filedata->section_headers + section->sh_link;
17686 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
17687 string_sec->sh_size,
17688 _("liblist string table"));
047b2264
JJ
17689 if (strtab == NULL
17690 || section->sh_entsize != sizeof (Elf32_External_Lib))
17691 {
17692 free (elib);
2842702f 17693 free (strtab);
32ec8896 17694 res = FALSE;
047b2264
JJ
17695 break;
17696 }
59245841 17697 strtab_size = string_sec->sh_size;
047b2264 17698
d3a49aa8
AM
17699 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
17700 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
17701 "\nLibrary list section '%s' contains %lu entries:\n",
17702 num_liblist),
dda8d76d 17703 printable_section_name (filedata, section),
d3a49aa8 17704 num_liblist);
047b2264 17705
2b692964 17706 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
17707
17708 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
17709 ++cnt)
17710 {
17711 Elf32_Lib liblist;
91d6fa6a 17712 time_t atime;
d5b07ef4 17713 char timebuf[128];
2cf0635d 17714 struct tm * tmp;
047b2264
JJ
17715
17716 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17717 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
17718 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17719 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17720 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17721
91d6fa6a 17722 tmp = gmtime (&atime);
e9e44622
JJ
17723 snprintf (timebuf, sizeof (timebuf),
17724 "%04u-%02u-%02uT%02u:%02u:%02u",
17725 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17726 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
17727
17728 printf ("%3lu: ", (unsigned long) cnt);
17729 if (do_wide)
c256ffe7 17730 printf ("%-20s", liblist.l_name < strtab_size
2b692964 17731 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 17732 else
c256ffe7 17733 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 17734 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
17735 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
17736 liblist.l_version, liblist.l_flags);
17737 }
17738
17739 free (elib);
2842702f 17740 free (strtab);
047b2264
JJ
17741 }
17742 }
17743
32ec8896 17744 return res;
047b2264
JJ
17745}
17746
9437c45b 17747static const char *
dda8d76d 17748get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
17749{
17750 static char buff[64];
103f02d3 17751
dda8d76d 17752 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
17753 switch (e_type)
17754 {
57346661 17755 case NT_AUXV:
1ec5cd37 17756 return _("NT_AUXV (auxiliary vector)");
57346661 17757 case NT_PRSTATUS:
1ec5cd37 17758 return _("NT_PRSTATUS (prstatus structure)");
57346661 17759 case NT_FPREGSET:
1ec5cd37 17760 return _("NT_FPREGSET (floating point registers)");
57346661 17761 case NT_PRPSINFO:
1ec5cd37 17762 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 17763 case NT_TASKSTRUCT:
1ec5cd37 17764 return _("NT_TASKSTRUCT (task structure)");
57346661 17765 case NT_PRXFPREG:
1ec5cd37 17766 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
17767 case NT_PPC_VMX:
17768 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
17769 case NT_PPC_VSX:
17770 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
17771 case NT_PPC_TAR:
17772 return _("NT_PPC_TAR (ppc TAR register)");
17773 case NT_PPC_PPR:
17774 return _("NT_PPC_PPR (ppc PPR register)");
17775 case NT_PPC_DSCR:
17776 return _("NT_PPC_DSCR (ppc DSCR register)");
17777 case NT_PPC_EBB:
17778 return _("NT_PPC_EBB (ppc EBB registers)");
17779 case NT_PPC_PMU:
17780 return _("NT_PPC_PMU (ppc PMU registers)");
17781 case NT_PPC_TM_CGPR:
17782 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
17783 case NT_PPC_TM_CFPR:
17784 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
17785 case NT_PPC_TM_CVMX:
17786 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
17787 case NT_PPC_TM_CVSX:
3fd21718 17788 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
17789 case NT_PPC_TM_SPR:
17790 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
17791 case NT_PPC_TM_CTAR:
17792 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
17793 case NT_PPC_TM_CPPR:
17794 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
17795 case NT_PPC_TM_CDSCR:
17796 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
17797 case NT_386_TLS:
17798 return _("NT_386_TLS (x86 TLS information)");
17799 case NT_386_IOPERM:
17800 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
17801 case NT_X86_XSTATE:
17802 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
0675e188
UW
17803 case NT_S390_HIGH_GPRS:
17804 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
17805 case NT_S390_TIMER:
17806 return _("NT_S390_TIMER (s390 timer register)");
17807 case NT_S390_TODCMP:
17808 return _("NT_S390_TODCMP (s390 TOD comparator register)");
17809 case NT_S390_TODPREG:
17810 return _("NT_S390_TODPREG (s390 TOD programmable register)");
17811 case NT_S390_CTRS:
17812 return _("NT_S390_CTRS (s390 control registers)");
17813 case NT_S390_PREFIX:
17814 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
17815 case NT_S390_LAST_BREAK:
17816 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
17817 case NT_S390_SYSTEM_CALL:
17818 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
17819 case NT_S390_TDB:
17820 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
17821 case NT_S390_VXRS_LOW:
17822 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
17823 case NT_S390_VXRS_HIGH:
17824 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
17825 case NT_S390_GS_CB:
17826 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
17827 case NT_S390_GS_BC:
17828 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
17829 case NT_ARM_VFP:
17830 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
17831 case NT_ARM_TLS:
17832 return _("NT_ARM_TLS (AArch TLS registers)");
17833 case NT_ARM_HW_BREAK:
17834 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
17835 case NT_ARM_HW_WATCH:
17836 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
17837 case NT_ARC_V2:
17838 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
57346661 17839 case NT_PSTATUS:
1ec5cd37 17840 return _("NT_PSTATUS (pstatus structure)");
57346661 17841 case NT_FPREGS:
1ec5cd37 17842 return _("NT_FPREGS (floating point registers)");
57346661 17843 case NT_PSINFO:
1ec5cd37 17844 return _("NT_PSINFO (psinfo structure)");
57346661 17845 case NT_LWPSTATUS:
1ec5cd37 17846 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 17847 case NT_LWPSINFO:
1ec5cd37 17848 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 17849 case NT_WIN32PSTATUS:
1ec5cd37 17850 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
17851 case NT_SIGINFO:
17852 return _("NT_SIGINFO (siginfo_t data)");
17853 case NT_FILE:
17854 return _("NT_FILE (mapped files)");
1ec5cd37
NC
17855 default:
17856 break;
17857 }
17858 else
17859 switch (e_type)
17860 {
17861 case NT_VERSION:
17862 return _("NT_VERSION (version)");
17863 case NT_ARCH:
17864 return _("NT_ARCH (architecture)");
9ef920e9 17865 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 17866 return _("OPEN");
9ef920e9 17867 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 17868 return _("func");
1ec5cd37
NC
17869 default:
17870 break;
17871 }
17872
e9e44622 17873 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 17874 return buff;
779fe533
NC
17875}
17876
32ec8896 17877static bfd_boolean
9ece1fa9
TT
17878print_core_note (Elf_Internal_Note *pnote)
17879{
17880 unsigned int addr_size = is_32bit_elf ? 4 : 8;
17881 bfd_vma count, page_size;
17882 unsigned char *descdata, *filenames, *descend;
17883
17884 if (pnote->type != NT_FILE)
04ac15ab
AS
17885 {
17886 if (do_wide)
17887 printf ("\n");
17888 return TRUE;
17889 }
9ece1fa9
TT
17890
17891#ifndef BFD64
17892 if (!is_32bit_elf)
17893 {
17894 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
17895 /* Still "successful". */
32ec8896 17896 return TRUE;
9ece1fa9
TT
17897 }
17898#endif
17899
17900 if (pnote->descsz < 2 * addr_size)
17901 {
32ec8896
NC
17902 error (_(" Malformed note - too short for header\n"));
17903 return FALSE;
9ece1fa9
TT
17904 }
17905
17906 descdata = (unsigned char *) pnote->descdata;
17907 descend = descdata + pnote->descsz;
17908
17909 if (descdata[pnote->descsz - 1] != '\0')
17910 {
32ec8896
NC
17911 error (_(" Malformed note - does not end with \\0\n"));
17912 return FALSE;
9ece1fa9
TT
17913 }
17914
17915 count = byte_get (descdata, addr_size);
17916 descdata += addr_size;
17917
17918 page_size = byte_get (descdata, addr_size);
17919 descdata += addr_size;
17920
5396a86e
AM
17921 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
17922 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 17923 {
32ec8896
NC
17924 error (_(" Malformed note - too short for supplied file count\n"));
17925 return FALSE;
9ece1fa9
TT
17926 }
17927
17928 printf (_(" Page size: "));
17929 print_vma (page_size, DEC);
17930 printf ("\n");
17931
17932 printf (_(" %*s%*s%*s\n"),
17933 (int) (2 + 2 * addr_size), _("Start"),
17934 (int) (4 + 2 * addr_size), _("End"),
17935 (int) (4 + 2 * addr_size), _("Page Offset"));
17936 filenames = descdata + count * 3 * addr_size;
595712bb 17937 while (count-- > 0)
9ece1fa9
TT
17938 {
17939 bfd_vma start, end, file_ofs;
17940
17941 if (filenames == descend)
17942 {
32ec8896
NC
17943 error (_(" Malformed note - filenames end too early\n"));
17944 return FALSE;
9ece1fa9
TT
17945 }
17946
17947 start = byte_get (descdata, addr_size);
17948 descdata += addr_size;
17949 end = byte_get (descdata, addr_size);
17950 descdata += addr_size;
17951 file_ofs = byte_get (descdata, addr_size);
17952 descdata += addr_size;
17953
17954 printf (" ");
17955 print_vma (start, FULL_HEX);
17956 printf (" ");
17957 print_vma (end, FULL_HEX);
17958 printf (" ");
17959 print_vma (file_ofs, FULL_HEX);
17960 printf ("\n %s\n", filenames);
17961
17962 filenames += 1 + strlen ((char *) filenames);
17963 }
17964
32ec8896 17965 return TRUE;
9ece1fa9
TT
17966}
17967
1118d252
RM
17968static const char *
17969get_gnu_elf_note_type (unsigned e_type)
17970{
1449284b 17971 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
17972 switch (e_type)
17973 {
17974 case NT_GNU_ABI_TAG:
17975 return _("NT_GNU_ABI_TAG (ABI version tag)");
17976 case NT_GNU_HWCAP:
17977 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
17978 case NT_GNU_BUILD_ID:
17979 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
17980 case NT_GNU_GOLD_VERSION:
17981 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
17982 case NT_GNU_PROPERTY_TYPE_0:
17983 return _("NT_GNU_PROPERTY_TYPE_0");
17984 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
17985 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
17986 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
17987 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 17988 default:
1449284b
NC
17989 {
17990 static char buff[64];
1118d252 17991
1449284b
NC
17992 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
17993 return buff;
17994 }
17995 }
1118d252
RM
17996}
17997
a9eafb08
L
17998static void
17999decode_x86_compat_isa (unsigned int bitmask)
18000{
18001 while (bitmask)
18002 {
18003 unsigned int bit = bitmask & (- bitmask);
18004
18005 bitmask &= ~ bit;
18006 switch (bit)
18007 {
18008 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18009 printf ("i486");
18010 break;
18011 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18012 printf ("586");
18013 break;
18014 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18015 printf ("686");
18016 break;
18017 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18018 printf ("SSE");
18019 break;
18020 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18021 printf ("SSE2");
18022 break;
18023 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18024 printf ("SSE3");
18025 break;
18026 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18027 printf ("SSSE3");
18028 break;
18029 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18030 printf ("SSE4_1");
18031 break;
18032 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18033 printf ("SSE4_2");
18034 break;
18035 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18036 printf ("AVX");
18037 break;
18038 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18039 printf ("AVX2");
18040 break;
18041 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18042 printf ("AVX512F");
18043 break;
18044 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18045 printf ("AVX512CD");
18046 break;
18047 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18048 printf ("AVX512ER");
18049 break;
18050 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18051 printf ("AVX512PF");
18052 break;
18053 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18054 printf ("AVX512VL");
18055 break;
18056 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18057 printf ("AVX512DQ");
18058 break;
18059 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18060 printf ("AVX512BW");
18061 break;
65b3d26e
L
18062 default:
18063 printf (_("<unknown: %x>"), bit);
18064 break;
a9eafb08
L
18065 }
18066 if (bitmask)
18067 printf (", ");
18068 }
18069}
18070
9ef920e9 18071static void
1fc87489 18072decode_x86_isa (unsigned int bitmask)
9ef920e9 18073{
0a59decb 18074 if (!bitmask)
90c745dc
L
18075 {
18076 printf (_("<None>"));
18077 return;
18078 }
90c745dc 18079
9ef920e9
NC
18080 while (bitmask)
18081 {
1fc87489 18082 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18083
18084 bitmask &= ~ bit;
18085 switch (bit)
18086 {
a9eafb08
L
18087 case GNU_PROPERTY_X86_ISA_1_CMOV:
18088 printf ("CMOV");
18089 break;
18090 case GNU_PROPERTY_X86_ISA_1_SSE:
18091 printf ("SSE");
18092 break;
18093 case GNU_PROPERTY_X86_ISA_1_SSE2:
18094 printf ("SSE2");
18095 break;
18096 case GNU_PROPERTY_X86_ISA_1_SSE3:
18097 printf ("SSE3");
18098 break;
18099 case GNU_PROPERTY_X86_ISA_1_SSSE3:
18100 printf ("SSSE3");
18101 break;
18102 case GNU_PROPERTY_X86_ISA_1_SSE4_1:
18103 printf ("SSE4_1");
18104 break;
18105 case GNU_PROPERTY_X86_ISA_1_SSE4_2:
18106 printf ("SSE4_2");
18107 break;
18108 case GNU_PROPERTY_X86_ISA_1_AVX:
18109 printf ("AVX");
18110 break;
18111 case GNU_PROPERTY_X86_ISA_1_AVX2:
18112 printf ("AVX2");
18113 break;
18114 case GNU_PROPERTY_X86_ISA_1_FMA:
18115 printf ("FMA");
18116 break;
18117 case GNU_PROPERTY_X86_ISA_1_AVX512F:
18118 printf ("AVX512F");
18119 break;
18120 case GNU_PROPERTY_X86_ISA_1_AVX512CD:
18121 printf ("AVX512CD");
18122 break;
18123 case GNU_PROPERTY_X86_ISA_1_AVX512ER:
18124 printf ("AVX512ER");
18125 break;
18126 case GNU_PROPERTY_X86_ISA_1_AVX512PF:
18127 printf ("AVX512PF");
18128 break;
18129 case GNU_PROPERTY_X86_ISA_1_AVX512VL:
18130 printf ("AVX512VL");
18131 break;
18132 case GNU_PROPERTY_X86_ISA_1_AVX512DQ:
18133 printf ("AVX512DQ");
18134 break;
18135 case GNU_PROPERTY_X86_ISA_1_AVX512BW:
18136 printf ("AVX512BW");
18137 break;
18138 case GNU_PROPERTY_X86_ISA_1_AVX512_4FMAPS:
18139 printf ("AVX512_4FMAPS");
18140 break;
18141 case GNU_PROPERTY_X86_ISA_1_AVX512_4VNNIW:
18142 printf ("AVX512_4VNNIW");
18143 break;
18144 case GNU_PROPERTY_X86_ISA_1_AVX512_BITALG:
18145 printf ("AVX512_BITALG");
18146 break;
18147 case GNU_PROPERTY_X86_ISA_1_AVX512_IFMA:
18148 printf ("AVX512_IFMA");
18149 break;
18150 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI:
18151 printf ("AVX512_VBMI");
18152 break;
18153 case GNU_PROPERTY_X86_ISA_1_AVX512_VBMI2:
18154 printf ("AVX512_VBMI2");
18155 break;
18156 case GNU_PROPERTY_X86_ISA_1_AVX512_VNNI:
18157 printf ("AVX512_VNNI");
18158 break;
462cac58
L
18159 case GNU_PROPERTY_X86_ISA_1_AVX512_BF16:
18160 printf ("AVX512_BF16");
18161 break;
65b3d26e
L
18162 default:
18163 printf (_("<unknown: %x>"), bit);
18164 break;
9ef920e9
NC
18165 }
18166 if (bitmask)
18167 printf (", ");
18168 }
18169}
18170
ee2fdd6f 18171static void
a9eafb08 18172decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 18173{
0a59decb 18174 if (!bitmask)
90c745dc
L
18175 {
18176 printf (_("<None>"));
18177 return;
18178 }
90c745dc 18179
ee2fdd6f
L
18180 while (bitmask)
18181 {
18182 unsigned int bit = bitmask & (- bitmask);
18183
18184 bitmask &= ~ bit;
18185 switch (bit)
18186 {
18187 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 18188 printf ("IBT");
ee2fdd6f 18189 break;
48580982 18190 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 18191 printf ("SHSTK");
48580982 18192 break;
ee2fdd6f
L
18193 default:
18194 printf (_("<unknown: %x>"), bit);
18195 break;
18196 }
18197 if (bitmask)
18198 printf (", ");
18199 }
18200}
18201
a9eafb08
L
18202static void
18203decode_x86_feature_2 (unsigned int bitmask)
18204{
0a59decb 18205 if (!bitmask)
90c745dc
L
18206 {
18207 printf (_("<None>"));
18208 return;
18209 }
90c745dc 18210
a9eafb08
L
18211 while (bitmask)
18212 {
18213 unsigned int bit = bitmask & (- bitmask);
18214
18215 bitmask &= ~ bit;
18216 switch (bit)
18217 {
18218 case GNU_PROPERTY_X86_FEATURE_2_X86:
18219 printf ("x86");
18220 break;
18221 case GNU_PROPERTY_X86_FEATURE_2_X87:
18222 printf ("x87");
18223 break;
18224 case GNU_PROPERTY_X86_FEATURE_2_MMX:
18225 printf ("MMX");
18226 break;
18227 case GNU_PROPERTY_X86_FEATURE_2_XMM:
18228 printf ("XMM");
18229 break;
18230 case GNU_PROPERTY_X86_FEATURE_2_YMM:
18231 printf ("YMM");
18232 break;
18233 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
18234 printf ("ZMM");
18235 break;
a308b89d
L
18236 case GNU_PROPERTY_X86_FEATURE_2_TMM:
18237 printf ("TMM");
18238 break;
a9eafb08
L
18239 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
18240 printf ("FXSR");
18241 break;
18242 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
18243 printf ("XSAVE");
18244 break;
18245 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
18246 printf ("XSAVEOPT");
18247 break;
18248 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
18249 printf ("XSAVEC");
18250 break;
65b3d26e
L
18251 default:
18252 printf (_("<unknown: %x>"), bit);
18253 break;
a9eafb08
L
18254 }
18255 if (bitmask)
18256 printf (", ");
18257 }
18258}
18259
cd702818
SD
18260static void
18261decode_aarch64_feature_1_and (unsigned int bitmask)
18262{
18263 while (bitmask)
18264 {
18265 unsigned int bit = bitmask & (- bitmask);
18266
18267 bitmask &= ~ bit;
18268 switch (bit)
18269 {
18270 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
18271 printf ("BTI");
18272 break;
18273
18274 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
18275 printf ("PAC");
18276 break;
18277
18278 default:
18279 printf (_("<unknown: %x>"), bit);
18280 break;
18281 }
18282 if (bitmask)
18283 printf (", ");
18284 }
18285}
18286
9ef920e9 18287static void
dda8d76d 18288print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
18289{
18290 unsigned char * ptr = (unsigned char *) pnote->descdata;
18291 unsigned char * ptr_end = ptr + pnote->descsz;
18292 unsigned int size = is_32bit_elf ? 4 : 8;
18293
18294 printf (_(" Properties: "));
18295
1fc87489 18296 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
18297 {
18298 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
18299 return;
18300 }
18301
6ab2c4ed 18302 while (ptr < ptr_end)
9ef920e9 18303 {
1fc87489 18304 unsigned int j;
6ab2c4ed
MC
18305 unsigned int type;
18306 unsigned int datasz;
18307
18308 if ((size_t) (ptr_end - ptr) < 8)
18309 {
18310 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
18311 break;
18312 }
18313
18314 type = byte_get (ptr, 4);
18315 datasz = byte_get (ptr + 4, 4);
9ef920e9 18316
1fc87489 18317 ptr += 8;
9ef920e9 18318
6ab2c4ed 18319 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 18320 {
1fc87489
L
18321 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
18322 type, datasz);
9ef920e9 18323 break;
1fc87489 18324 }
9ef920e9 18325
1fc87489
L
18326 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
18327 {
dda8d76d
NC
18328 if (filedata->file_header.e_machine == EM_X86_64
18329 || filedata->file_header.e_machine == EM_IAMCU
18330 || filedata->file_header.e_machine == EM_386)
1fc87489 18331 {
aa7bca9b
L
18332 unsigned int bitmask;
18333
18334 if (datasz == 4)
0a59decb 18335 bitmask = byte_get (ptr, 4);
aa7bca9b
L
18336 else
18337 bitmask = 0;
18338
1fc87489
L
18339 switch (type)
18340 {
18341 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 18342 if (datasz != 4)
aa7bca9b
L
18343 printf (_("x86 ISA used: <corrupt length: %#x> "),
18344 datasz);
1fc87489 18345 else
aa7bca9b
L
18346 {
18347 printf ("x86 ISA used: ");
18348 decode_x86_isa (bitmask);
18349 }
1fc87489 18350 goto next;
9ef920e9 18351
1fc87489 18352 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 18353 if (datasz != 4)
aa7bca9b
L
18354 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18355 datasz);
1fc87489 18356 else
aa7bca9b
L
18357 {
18358 printf ("x86 ISA needed: ");
18359 decode_x86_isa (bitmask);
18360 }
1fc87489 18361 goto next;
9ef920e9 18362
ee2fdd6f 18363 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 18364 if (datasz != 4)
aa7bca9b
L
18365 printf (_("x86 feature: <corrupt length: %#x> "),
18366 datasz);
ee2fdd6f 18367 else
aa7bca9b
L
18368 {
18369 printf ("x86 feature: ");
a9eafb08
L
18370 decode_x86_feature_1 (bitmask);
18371 }
18372 goto next;
18373
18374 case GNU_PROPERTY_X86_FEATURE_2_USED:
18375 if (datasz != 4)
18376 printf (_("x86 feature used: <corrupt length: %#x> "),
18377 datasz);
18378 else
18379 {
18380 printf ("x86 feature used: ");
18381 decode_x86_feature_2 (bitmask);
18382 }
18383 goto next;
18384
18385 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
18386 if (datasz != 4)
18387 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
18388 else
18389 {
18390 printf ("x86 feature needed: ");
18391 decode_x86_feature_2 (bitmask);
18392 }
18393 goto next;
18394
18395 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
18396 if (datasz != 4)
18397 printf (_("x86 ISA used: <corrupt length: %#x> "),
18398 datasz);
18399 else
18400 {
18401 printf ("x86 ISA used: ");
18402 decode_x86_compat_isa (bitmask);
18403 }
18404 goto next;
18405
18406 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
18407 if (datasz != 4)
18408 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18409 datasz);
18410 else
18411 {
18412 printf ("x86 ISA needed: ");
18413 decode_x86_compat_isa (bitmask);
aa7bca9b 18414 }
ee2fdd6f
L
18415 goto next;
18416
1fc87489
L
18417 default:
18418 break;
18419 }
18420 }
cd702818
SD
18421 else if (filedata->file_header.e_machine == EM_AARCH64)
18422 {
18423 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
18424 {
18425 printf ("AArch64 feature: ");
18426 if (datasz != 4)
18427 printf (_("<corrupt length: %#x> "), datasz);
18428 else
18429 decode_aarch64_feature_1_and (byte_get (ptr, 4));
18430 goto next;
18431 }
18432 }
1fc87489
L
18433 }
18434 else
18435 {
18436 switch (type)
9ef920e9 18437 {
1fc87489
L
18438 case GNU_PROPERTY_STACK_SIZE:
18439 printf (_("stack size: "));
18440 if (datasz != size)
18441 printf (_("<corrupt length: %#x> "), datasz);
18442 else
18443 printf ("%#lx", (unsigned long) byte_get (ptr, size));
18444 goto next;
18445
18446 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
18447 printf ("no copy on protected ");
18448 if (datasz)
18449 printf (_("<corrupt length: %#x> "), datasz);
18450 goto next;
18451
18452 default:
9ef920e9
NC
18453 break;
18454 }
9ef920e9
NC
18455 }
18456
1fc87489
L
18457 if (type < GNU_PROPERTY_LOPROC)
18458 printf (_("<unknown type %#x data: "), type);
18459 else if (type < GNU_PROPERTY_LOUSER)
18460 printf (_("<procesor-specific type %#x data: "), type);
18461 else
18462 printf (_("<application-specific type %#x data: "), type);
18463 for (j = 0; j < datasz; ++j)
18464 printf ("%02x ", ptr[j] & 0xff);
18465 printf (">");
18466
dc1e8a47 18467 next:
9ef920e9 18468 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
18469 if (ptr == ptr_end)
18470 break;
1fc87489 18471
6ab2c4ed
MC
18472 if (do_wide)
18473 printf (", ");
18474 else
18475 printf ("\n\t");
9ef920e9
NC
18476 }
18477
18478 printf ("\n");
18479}
18480
32ec8896 18481static bfd_boolean
dda8d76d 18482print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 18483{
1449284b 18484 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
18485 switch (pnote->type)
18486 {
18487 case NT_GNU_BUILD_ID:
18488 {
18489 unsigned long i;
18490
18491 printf (_(" Build ID: "));
18492 for (i = 0; i < pnote->descsz; ++i)
18493 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 18494 printf ("\n");
664f90a3
TT
18495 }
18496 break;
18497
18498 case NT_GNU_ABI_TAG:
18499 {
18500 unsigned long os, major, minor, subminor;
18501 const char *osname;
18502
3102e897
NC
18503 /* PR 17531: file: 030-599401-0.004. */
18504 if (pnote->descsz < 16)
18505 {
18506 printf (_(" <corrupt GNU_ABI_TAG>\n"));
18507 break;
18508 }
18509
664f90a3
TT
18510 os = byte_get ((unsigned char *) pnote->descdata, 4);
18511 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18512 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
18513 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
18514
18515 switch (os)
18516 {
18517 case GNU_ABI_TAG_LINUX:
18518 osname = "Linux";
18519 break;
18520 case GNU_ABI_TAG_HURD:
18521 osname = "Hurd";
18522 break;
18523 case GNU_ABI_TAG_SOLARIS:
18524 osname = "Solaris";
18525 break;
18526 case GNU_ABI_TAG_FREEBSD:
18527 osname = "FreeBSD";
18528 break;
18529 case GNU_ABI_TAG_NETBSD:
18530 osname = "NetBSD";
18531 break;
14ae95f2
RM
18532 case GNU_ABI_TAG_SYLLABLE:
18533 osname = "Syllable";
18534 break;
18535 case GNU_ABI_TAG_NACL:
18536 osname = "NaCl";
18537 break;
664f90a3
TT
18538 default:
18539 osname = "Unknown";
18540 break;
18541 }
18542
18543 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
18544 major, minor, subminor);
18545 }
18546 break;
926c5385
CC
18547
18548 case NT_GNU_GOLD_VERSION:
18549 {
18550 unsigned long i;
18551
18552 printf (_(" Version: "));
18553 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
18554 printf ("%c", pnote->descdata[i]);
18555 printf ("\n");
18556 }
18557 break;
1449284b
NC
18558
18559 case NT_GNU_HWCAP:
18560 {
18561 unsigned long num_entries, mask;
18562
18563 /* Hardware capabilities information. Word 0 is the number of entries.
18564 Word 1 is a bitmask of enabled entries. The rest of the descriptor
18565 is a series of entries, where each entry is a single byte followed
18566 by a nul terminated string. The byte gives the bit number to test
18567 if enabled in the bitmask. */
18568 printf (_(" Hardware Capabilities: "));
18569 if (pnote->descsz < 8)
18570 {
32ec8896
NC
18571 error (_("<corrupt GNU_HWCAP>\n"));
18572 return FALSE;
1449284b
NC
18573 }
18574 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
18575 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
18576 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
18577 /* FIXME: Add code to display the entries... */
18578 }
18579 break;
18580
9ef920e9 18581 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 18582 print_gnu_property_note (filedata, pnote);
9ef920e9 18583 break;
9abca702 18584
1449284b
NC
18585 default:
18586 /* Handle unrecognised types. An error message should have already been
18587 created by get_gnu_elf_note_type(), so all that we need to do is to
18588 display the data. */
18589 {
18590 unsigned long i;
18591
18592 printf (_(" Description data: "));
18593 for (i = 0; i < pnote->descsz; ++i)
18594 printf ("%02x ", pnote->descdata[i] & 0xff);
18595 printf ("\n");
18596 }
18597 break;
664f90a3
TT
18598 }
18599
32ec8896 18600 return TRUE;
664f90a3
TT
18601}
18602
685080f2
NC
18603static const char *
18604get_v850_elf_note_type (enum v850_notes n_type)
18605{
18606 static char buff[64];
18607
18608 switch (n_type)
18609 {
18610 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
18611 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
18612 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
18613 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
18614 case V850_NOTE_CACHE_INFO: return _("Use of cache");
18615 case V850_NOTE_MMU_INFO: return _("Use of MMU");
18616 default:
18617 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
18618 return buff;
18619 }
18620}
18621
32ec8896 18622static bfd_boolean
685080f2
NC
18623print_v850_note (Elf_Internal_Note * pnote)
18624{
18625 unsigned int val;
18626
18627 if (pnote->descsz != 4)
32ec8896
NC
18628 return FALSE;
18629
685080f2
NC
18630 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
18631
18632 if (val == 0)
18633 {
18634 printf (_("not set\n"));
32ec8896 18635 return TRUE;
685080f2
NC
18636 }
18637
18638 switch (pnote->type)
18639 {
18640 case V850_NOTE_ALIGNMENT:
18641 switch (val)
18642 {
32ec8896
NC
18643 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
18644 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
18645 }
18646 break;
14ae95f2 18647
685080f2
NC
18648 case V850_NOTE_DATA_SIZE:
18649 switch (val)
18650 {
32ec8896
NC
18651 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
18652 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
18653 }
18654 break;
14ae95f2 18655
685080f2
NC
18656 case V850_NOTE_FPU_INFO:
18657 switch (val)
18658 {
32ec8896
NC
18659 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
18660 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
18661 }
18662 break;
14ae95f2 18663
685080f2
NC
18664 case V850_NOTE_MMU_INFO:
18665 case V850_NOTE_CACHE_INFO:
18666 case V850_NOTE_SIMD_INFO:
18667 if (val == EF_RH850_SIMD)
18668 {
18669 printf (_("yes\n"));
32ec8896 18670 return TRUE;
685080f2
NC
18671 }
18672 break;
18673
18674 default:
18675 /* An 'unknown note type' message will already have been displayed. */
18676 break;
18677 }
18678
18679 printf (_("unknown value: %x\n"), val);
32ec8896 18680 return FALSE;
685080f2
NC
18681}
18682
32ec8896 18683static bfd_boolean
c6056a74
SF
18684process_netbsd_elf_note (Elf_Internal_Note * pnote)
18685{
18686 unsigned int version;
18687
18688 switch (pnote->type)
18689 {
18690 case NT_NETBSD_IDENT:
b966f55f
AM
18691 if (pnote->descsz < 1)
18692 break;
c6056a74
SF
18693 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18694 if ((version / 10000) % 100)
b966f55f 18695 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
18696 version, version / 100000000, (version / 1000000) % 100,
18697 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 18698 'A' + (version / 10000) % 26);
c6056a74
SF
18699 else
18700 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 18701 version, version / 100000000, (version / 1000000) % 100,
15f205b1 18702 (version / 100) % 100);
32ec8896 18703 return TRUE;
c6056a74
SF
18704
18705 case NT_NETBSD_MARCH:
9abca702 18706 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 18707 pnote->descdata);
32ec8896 18708 return TRUE;
c6056a74 18709
9abca702
CZ
18710#ifdef NT_NETBSD_PAX
18711 case NT_NETBSD_PAX:
b966f55f
AM
18712 if (pnote->descsz < 1)
18713 break;
9abca702
CZ
18714 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
18715 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
18716 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
18717 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
18718 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
18719 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
18720 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
18721 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
18722 return TRUE;
18723#endif
c6056a74 18724 }
b966f55f
AM
18725
18726 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
18727 pnote->descsz, pnote->type);
18728 return FALSE;
c6056a74
SF
18729}
18730
f4ddf30f 18731static const char *
dda8d76d 18732get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 18733{
f4ddf30f
JB
18734 switch (e_type)
18735 {
18736 case NT_FREEBSD_THRMISC:
18737 return _("NT_THRMISC (thrmisc structure)");
18738 case NT_FREEBSD_PROCSTAT_PROC:
18739 return _("NT_PROCSTAT_PROC (proc data)");
18740 case NT_FREEBSD_PROCSTAT_FILES:
18741 return _("NT_PROCSTAT_FILES (files data)");
18742 case NT_FREEBSD_PROCSTAT_VMMAP:
18743 return _("NT_PROCSTAT_VMMAP (vmmap data)");
18744 case NT_FREEBSD_PROCSTAT_GROUPS:
18745 return _("NT_PROCSTAT_GROUPS (groups data)");
18746 case NT_FREEBSD_PROCSTAT_UMASK:
18747 return _("NT_PROCSTAT_UMASK (umask data)");
18748 case NT_FREEBSD_PROCSTAT_RLIMIT:
18749 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
18750 case NT_FREEBSD_PROCSTAT_OSREL:
18751 return _("NT_PROCSTAT_OSREL (osreldate data)");
18752 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
18753 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
18754 case NT_FREEBSD_PROCSTAT_AUXV:
18755 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
18756 case NT_FREEBSD_PTLWPINFO:
18757 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 18758 }
dda8d76d 18759 return get_note_type (filedata, e_type);
f4ddf30f
JB
18760}
18761
9437c45b 18762static const char *
dda8d76d 18763get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
18764{
18765 static char buff[64];
18766
540e6170
CZ
18767 switch (e_type)
18768 {
18769 case NT_NETBSDCORE_PROCINFO:
18770 /* NetBSD core "procinfo" structure. */
18771 return _("NetBSD procinfo structure");
9437c45b 18772
540e6170
CZ
18773#ifdef NT_NETBSDCORE_AUXV
18774 case NT_NETBSDCORE_AUXV:
18775 return _("NetBSD ELF auxiliary vector data");
18776#endif
9437c45b 18777
06d949ec
KR
18778#ifdef NT_NETBSDCORE_LWPSTATUS
18779 case NT_NETBSDCORE_LWPSTATUS:
18780 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
18781#endif
18782
540e6170 18783 default:
06d949ec 18784 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
18785 defined for NetBSD core files. If the note type is less
18786 than the start of the machine-dependent note types, we don't
18787 understand it. */
18788
18789 if (e_type < NT_NETBSDCORE_FIRSTMACH)
18790 {
18791 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18792 return buff;
18793 }
18794 break;
9437c45b
JT
18795 }
18796
dda8d76d 18797 switch (filedata->file_header.e_machine)
9437c45b
JT
18798 {
18799 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
18800 and PT_GETFPREGS == mach+2. */
18801
18802 case EM_OLD_ALPHA:
18803 case EM_ALPHA:
18804 case EM_SPARC:
18805 case EM_SPARC32PLUS:
18806 case EM_SPARCV9:
18807 switch (e_type)
18808 {
2b692964 18809 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 18810 return _("PT_GETREGS (reg structure)");
2b692964 18811 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 18812 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18813 default:
18814 break;
18815 }
18816 break;
18817
c0d38b0e
CZ
18818 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
18819 There's also old PT___GETREGS40 == mach + 1 for old reg
18820 structure which lacks GBR. */
18821 case EM_SH:
18822 switch (e_type)
18823 {
18824 case NT_NETBSDCORE_FIRSTMACH + 1:
18825 return _("PT___GETREGS40 (old reg structure)");
18826 case NT_NETBSDCORE_FIRSTMACH + 3:
18827 return _("PT_GETREGS (reg structure)");
18828 case NT_NETBSDCORE_FIRSTMACH + 5:
18829 return _("PT_GETFPREGS (fpreg structure)");
18830 default:
18831 break;
18832 }
18833 break;
18834
9437c45b
JT
18835 /* On all other arch's, PT_GETREGS == mach+1 and
18836 PT_GETFPREGS == mach+3. */
18837 default:
18838 switch (e_type)
18839 {
2b692964 18840 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 18841 return _("PT_GETREGS (reg structure)");
2b692964 18842 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 18843 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
18844 default:
18845 break;
18846 }
18847 }
18848
9cf03b7e 18849 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 18850 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
18851 return buff;
18852}
18853
70616151
TT
18854static const char *
18855get_stapsdt_note_type (unsigned e_type)
18856{
18857 static char buff[64];
18858
18859 switch (e_type)
18860 {
18861 case NT_STAPSDT:
18862 return _("NT_STAPSDT (SystemTap probe descriptors)");
18863
18864 default:
18865 break;
18866 }
18867
18868 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18869 return buff;
18870}
18871
32ec8896 18872static bfd_boolean
c6a9fc58
TT
18873print_stapsdt_note (Elf_Internal_Note *pnote)
18874{
3ca60c57
NC
18875 size_t len, maxlen;
18876 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
18877 char *data = pnote->descdata;
18878 char *data_end = pnote->descdata + pnote->descsz;
18879 bfd_vma pc, base_addr, semaphore;
18880 char *provider, *probe, *arg_fmt;
18881
3ca60c57
NC
18882 if (pnote->descsz < (addr_size * 3))
18883 goto stapdt_note_too_small;
18884
c6a9fc58
TT
18885 pc = byte_get ((unsigned char *) data, addr_size);
18886 data += addr_size;
3ca60c57 18887
c6a9fc58
TT
18888 base_addr = byte_get ((unsigned char *) data, addr_size);
18889 data += addr_size;
3ca60c57 18890
c6a9fc58
TT
18891 semaphore = byte_get ((unsigned char *) data, addr_size);
18892 data += addr_size;
18893
3ca60c57
NC
18894 if (data >= data_end)
18895 goto stapdt_note_too_small;
18896 maxlen = data_end - data;
18897 len = strnlen (data, maxlen);
18898 if (len < maxlen)
18899 {
18900 provider = data;
18901 data += len + 1;
18902 }
18903 else
18904 goto stapdt_note_too_small;
18905
18906 if (data >= data_end)
18907 goto stapdt_note_too_small;
18908 maxlen = data_end - data;
18909 len = strnlen (data, maxlen);
18910 if (len < maxlen)
18911 {
18912 probe = data;
18913 data += len + 1;
18914 }
18915 else
18916 goto stapdt_note_too_small;
9abca702 18917
3ca60c57
NC
18918 if (data >= data_end)
18919 goto stapdt_note_too_small;
18920 maxlen = data_end - data;
18921 len = strnlen (data, maxlen);
18922 if (len < maxlen)
18923 {
18924 arg_fmt = data;
18925 data += len + 1;
18926 }
18927 else
18928 goto stapdt_note_too_small;
c6a9fc58
TT
18929
18930 printf (_(" Provider: %s\n"), provider);
18931 printf (_(" Name: %s\n"), probe);
18932 printf (_(" Location: "));
18933 print_vma (pc, FULL_HEX);
18934 printf (_(", Base: "));
18935 print_vma (base_addr, FULL_HEX);
18936 printf (_(", Semaphore: "));
18937 print_vma (semaphore, FULL_HEX);
9cf03b7e 18938 printf ("\n");
c6a9fc58
TT
18939 printf (_(" Arguments: %s\n"), arg_fmt);
18940
18941 return data == data_end;
3ca60c57
NC
18942
18943 stapdt_note_too_small:
18944 printf (_(" <corrupt - note is too small>\n"));
18945 error (_("corrupt stapdt note - the data size is too small\n"));
18946 return FALSE;
c6a9fc58
TT
18947}
18948
00e98fc7
TG
18949static const char *
18950get_ia64_vms_note_type (unsigned e_type)
18951{
18952 static char buff[64];
18953
18954 switch (e_type)
18955 {
18956 case NT_VMS_MHD:
18957 return _("NT_VMS_MHD (module header)");
18958 case NT_VMS_LNM:
18959 return _("NT_VMS_LNM (language name)");
18960 case NT_VMS_SRC:
18961 return _("NT_VMS_SRC (source files)");
18962 case NT_VMS_TITLE:
9cf03b7e 18963 return "NT_VMS_TITLE";
00e98fc7
TG
18964 case NT_VMS_EIDC:
18965 return _("NT_VMS_EIDC (consistency check)");
18966 case NT_VMS_FPMODE:
18967 return _("NT_VMS_FPMODE (FP mode)");
18968 case NT_VMS_LINKTIME:
9cf03b7e 18969 return "NT_VMS_LINKTIME";
00e98fc7
TG
18970 case NT_VMS_IMGNAM:
18971 return _("NT_VMS_IMGNAM (image name)");
18972 case NT_VMS_IMGID:
18973 return _("NT_VMS_IMGID (image id)");
18974 case NT_VMS_LINKID:
18975 return _("NT_VMS_LINKID (link id)");
18976 case NT_VMS_IMGBID:
18977 return _("NT_VMS_IMGBID (build id)");
18978 case NT_VMS_GSTNAM:
18979 return _("NT_VMS_GSTNAM (sym table name)");
18980 case NT_VMS_ORIG_DYN:
9cf03b7e 18981 return "NT_VMS_ORIG_DYN";
00e98fc7 18982 case NT_VMS_PATCHTIME:
9cf03b7e 18983 return "NT_VMS_PATCHTIME";
00e98fc7
TG
18984 default:
18985 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18986 return buff;
18987 }
18988}
18989
32ec8896 18990static bfd_boolean
00e98fc7
TG
18991print_ia64_vms_note (Elf_Internal_Note * pnote)
18992{
8d18bf79
NC
18993 int maxlen = pnote->descsz;
18994
18995 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
18996 goto desc_size_fail;
18997
00e98fc7
TG
18998 switch (pnote->type)
18999 {
19000 case NT_VMS_MHD:
8d18bf79
NC
19001 if (maxlen <= 36)
19002 goto desc_size_fail;
19003
19004 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19005
19006 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19007 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19008 if (l + 34 < maxlen)
19009 {
19010 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19011 if (l + 35 < maxlen)
19012 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19013 else
19014 printf (_(" Module version : <missing>\n"));
19015 }
00e98fc7 19016 else
8d18bf79
NC
19017 {
19018 printf (_(" Module name : <missing>\n"));
19019 printf (_(" Module version : <missing>\n"));
19020 }
00e98fc7 19021 break;
8d18bf79 19022
00e98fc7 19023 case NT_VMS_LNM:
8d18bf79 19024 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19025 break;
8d18bf79 19026
00e98fc7
TG
19027#ifdef BFD64
19028 case NT_VMS_FPMODE:
9cf03b7e 19029 printf (_(" Floating Point mode: "));
8d18bf79
NC
19030 if (maxlen < 8)
19031 goto desc_size_fail;
19032 /* FIXME: Generate an error if descsz > 8 ? */
19033
4a5cb34f 19034 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19035 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19036 break;
8d18bf79 19037
00e98fc7
TG
19038 case NT_VMS_LINKTIME:
19039 printf (_(" Link time: "));
8d18bf79
NC
19040 if (maxlen < 8)
19041 goto desc_size_fail;
19042 /* FIXME: Generate an error if descsz > 8 ? */
19043
00e98fc7 19044 print_vms_time
8d18bf79 19045 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19046 printf ("\n");
19047 break;
8d18bf79 19048
00e98fc7
TG
19049 case NT_VMS_PATCHTIME:
19050 printf (_(" Patch time: "));
8d18bf79
NC
19051 if (maxlen < 8)
19052 goto desc_size_fail;
19053 /* FIXME: Generate an error if descsz > 8 ? */
19054
00e98fc7 19055 print_vms_time
8d18bf79 19056 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19057 printf ("\n");
19058 break;
8d18bf79 19059
00e98fc7 19060 case NT_VMS_ORIG_DYN:
8d18bf79
NC
19061 if (maxlen < 34)
19062 goto desc_size_fail;
19063
00e98fc7
TG
19064 printf (_(" Major id: %u, minor id: %u\n"),
19065 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
19066 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 19067 printf (_(" Last modified : "));
00e98fc7
TG
19068 print_vms_time
19069 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 19070 printf (_("\n Link flags : "));
4a5cb34f 19071 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 19072 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 19073 printf (_(" Header flags: 0x%08x\n"),
948f632f 19074 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 19075 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
19076 break;
19077#endif
8d18bf79 19078
00e98fc7 19079 case NT_VMS_IMGNAM:
8d18bf79 19080 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19081 break;
8d18bf79 19082
00e98fc7 19083 case NT_VMS_GSTNAM:
8d18bf79 19084 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19085 break;
8d18bf79 19086
00e98fc7 19087 case NT_VMS_IMGID:
8d18bf79 19088 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19089 break;
8d18bf79 19090
00e98fc7 19091 case NT_VMS_LINKID:
8d18bf79 19092 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19093 break;
8d18bf79 19094
00e98fc7 19095 default:
32ec8896 19096 return FALSE;
00e98fc7 19097 }
8d18bf79 19098
32ec8896 19099 return TRUE;
8d18bf79
NC
19100
19101 desc_size_fail:
19102 printf (_(" <corrupt - data size is too small>\n"));
19103 error (_("corrupt IA64 note: data size is too small\n"));
19104 return FALSE;
00e98fc7
TG
19105}
19106
fd486f32
AM
19107struct build_attr_cache {
19108 Filedata *filedata;
19109 char *strtab;
19110 unsigned long strtablen;
19111 Elf_Internal_Sym *symtab;
19112 unsigned long nsyms;
19113} ba_cache;
19114
6f156d7a
NC
19115/* Find the symbol associated with a build attribute that is attached
19116 to address OFFSET. If PNAME is non-NULL then store the name of
19117 the symbol (if found) in the provided pointer, Returns NULL if a
19118 symbol could not be found. */
c799a79d 19119
6f156d7a
NC
19120static Elf_Internal_Sym *
19121get_symbol_for_build_attribute (Filedata * filedata,
19122 unsigned long offset,
19123 bfd_boolean is_open_attr,
19124 const char ** pname)
9ef920e9 19125{
fd486f32
AM
19126 Elf_Internal_Sym *saved_sym = NULL;
19127 Elf_Internal_Sym *sym;
9ef920e9 19128
dda8d76d 19129 if (filedata->section_headers != NULL
fd486f32 19130 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 19131 {
c799a79d 19132 Elf_Internal_Shdr * symsec;
9ef920e9 19133
fd486f32
AM
19134 free (ba_cache.strtab);
19135 ba_cache.strtab = NULL;
19136 free (ba_cache.symtab);
19137 ba_cache.symtab = NULL;
19138
c799a79d 19139 /* Load the symbol and string sections. */
dda8d76d
NC
19140 for (symsec = filedata->section_headers;
19141 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 19142 symsec ++)
9ef920e9 19143 {
28d13567
AM
19144 if (symsec->sh_type == SHT_SYMTAB
19145 && get_symtab (filedata, symsec,
19146 &ba_cache.symtab, &ba_cache.nsyms,
19147 &ba_cache.strtab, &ba_cache.strtablen))
19148 break;
9ef920e9 19149 }
fd486f32 19150 ba_cache.filedata = filedata;
9ef920e9
NC
19151 }
19152
fd486f32 19153 if (ba_cache.symtab == NULL)
6f156d7a 19154 return NULL;
9ef920e9 19155
c799a79d 19156 /* Find a symbol whose value matches offset. */
fd486f32 19157 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
19158 if (sym->st_value == offset)
19159 {
fd486f32 19160 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
19161 /* Huh ? This should not happen. */
19162 continue;
9ef920e9 19163
fd486f32 19164 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 19165 continue;
9ef920e9 19166
8fd75781
NC
19167 /* The AArch64 and ARM architectures define mapping symbols
19168 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
19169 if (ba_cache.strtab[sym->st_name] == '$'
19170 && ba_cache.strtab[sym->st_name + 1] != 0
19171 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
19172 continue;
19173
c799a79d
NC
19174 if (is_open_attr)
19175 {
19176 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
19177 and FILE or OBJECT symbols over NOTYPE symbols. We skip
19178 FUNC symbols entirely. */
19179 switch (ELF_ST_TYPE (sym->st_info))
19180 {
c799a79d 19181 case STT_OBJECT:
6f156d7a 19182 case STT_FILE:
c799a79d 19183 saved_sym = sym;
6f156d7a
NC
19184 if (sym->st_size)
19185 {
19186 /* If the symbol has a size associated
19187 with it then we can stop searching. */
fd486f32 19188 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 19189 }
c799a79d 19190 continue;
9ef920e9 19191
c799a79d
NC
19192 case STT_FUNC:
19193 /* Ignore function symbols. */
19194 continue;
19195
19196 default:
19197 break;
19198 }
19199
19200 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 19201 {
c799a79d
NC
19202 case STB_GLOBAL:
19203 if (saved_sym == NULL
19204 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
19205 saved_sym = sym;
19206 break;
c871dade 19207
c799a79d
NC
19208 case STB_LOCAL:
19209 if (saved_sym == NULL)
19210 saved_sym = sym;
19211 break;
19212
19213 default:
9ef920e9
NC
19214 break;
19215 }
19216 }
c799a79d
NC
19217 else
19218 {
19219 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
19220 continue;
19221
19222 saved_sym = sym;
19223 break;
19224 }
19225 }
19226
6f156d7a 19227 if (saved_sym && pname)
fd486f32 19228 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
19229
19230 return saved_sym;
c799a79d
NC
19231}
19232
d20e98ab
NC
19233/* Returns true iff addr1 and addr2 are in the same section. */
19234
19235static bfd_boolean
19236same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
19237{
19238 Elf_Internal_Shdr * a1;
19239 Elf_Internal_Shdr * a2;
19240
19241 a1 = find_section_by_address (filedata, addr1);
19242 a2 = find_section_by_address (filedata, addr2);
9abca702 19243
d20e98ab
NC
19244 return a1 == a2 && a1 != NULL;
19245}
19246
c799a79d 19247static bfd_boolean
dda8d76d
NC
19248print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
19249 Filedata * filedata)
c799a79d 19250{
6f156d7a
NC
19251 static unsigned long global_offset = 0;
19252 static unsigned long global_end = 0;
19253 static unsigned long func_offset = 0;
19254 static unsigned long func_end = 0;
c871dade 19255
6f156d7a
NC
19256 Elf_Internal_Sym * sym;
19257 const char * name;
19258 unsigned long start;
19259 unsigned long end;
19260 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
19261
19262 switch (pnote->descsz)
c799a79d 19263 {
6f156d7a
NC
19264 case 0:
19265 /* A zero-length description means that the range of
19266 the previous note of the same type should be used. */
c799a79d 19267 if (is_open_attr)
c871dade 19268 {
6f156d7a
NC
19269 if (global_end > global_offset)
19270 printf (_(" Applies to region from %#lx to %#lx\n"),
19271 global_offset, global_end);
19272 else
19273 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
19274 }
19275 else
19276 {
6f156d7a
NC
19277 if (func_end > func_offset)
19278 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
19279 else
19280 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 19281 }
6f156d7a 19282 return TRUE;
9ef920e9 19283
6f156d7a
NC
19284 case 4:
19285 start = byte_get ((unsigned char *) pnote->descdata, 4);
19286 end = 0;
19287 break;
19288
19289 case 8:
19290 if (is_32bit_elf)
19291 {
19292 /* FIXME: We should check that version 3+ notes are being used here... */
19293 start = byte_get ((unsigned char *) pnote->descdata, 4);
19294 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19295 }
19296 else
19297 {
19298 start = byte_get ((unsigned char *) pnote->descdata, 8);
19299 end = 0;
19300 }
19301 break;
19302
19303 case 16:
19304 start = byte_get ((unsigned char *) pnote->descdata, 8);
19305 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
19306 break;
9abca702 19307
6f156d7a 19308 default:
c799a79d
NC
19309 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
19310 printf (_(" <invalid descsz>"));
19311 return FALSE;
19312 }
19313
6f156d7a
NC
19314 name = NULL;
19315 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
19316 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
19317 in order to avoid them being confused with the start address of the
19318 first function in the file... */
19319 if (sym == NULL && is_open_attr)
19320 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
19321 & name);
6f156d7a
NC
19322
19323 if (end == 0 && sym != NULL && sym->st_size > 0)
19324 end = start + sym->st_size;
c799a79d
NC
19325
19326 if (is_open_attr)
19327 {
d20e98ab
NC
19328 /* FIXME: Need to properly allow for section alignment.
19329 16 is just the alignment used on x86_64. */
19330 if (global_end > 0
19331 && start > BFD_ALIGN (global_end, 16)
19332 /* Build notes are not guaranteed to be organised in order of
19333 increasing address, but we should find the all of the notes
19334 for one section in the same place. */
19335 && same_section (filedata, start, global_end))
6f156d7a
NC
19336 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
19337 global_end + 1, start - 1);
19338
19339 printf (_(" Applies to region from %#lx"), start);
19340 global_offset = start;
19341
19342 if (end)
19343 {
19344 printf (_(" to %#lx"), end);
19345 global_end = end;
19346 }
c799a79d
NC
19347 }
19348 else
19349 {
6f156d7a
NC
19350 printf (_(" Applies to region from %#lx"), start);
19351 func_offset = start;
19352
19353 if (end)
19354 {
19355 printf (_(" to %#lx"), end);
19356 func_end = end;
19357 }
c799a79d
NC
19358 }
19359
6f156d7a
NC
19360 if (sym && name)
19361 printf (_(" (%s)"), name);
19362
19363 printf ("\n");
19364 return TRUE;
9ef920e9
NC
19365}
19366
19367static bfd_boolean
19368print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
19369{
1d15e434
NC
19370 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
19371 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
19372 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
19373 char name_type;
19374 char name_attribute;
1d15e434 19375 const char * expected_types;
9ef920e9
NC
19376 const char * name = pnote->namedata;
19377 const char * text;
88305e1b 19378 signed int left;
9ef920e9
NC
19379
19380 if (name == NULL || pnote->namesz < 2)
19381 {
19382 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 19383 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
19384 return FALSE;
19385 }
19386
6f156d7a
NC
19387 if (do_wide)
19388 left = 28;
19389 else
19390 left = 20;
88305e1b
NC
19391
19392 /* Version 2 of the spec adds a "GA" prefix to the name field. */
19393 if (name[0] == 'G' && name[1] == 'A')
19394 {
6f156d7a
NC
19395 if (pnote->namesz < 4)
19396 {
19397 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
19398 print_symbol (-20, _(" <corrupt name>"));
19399 return FALSE;
19400 }
19401
88305e1b
NC
19402 printf ("GA");
19403 name += 2;
19404 left -= 2;
19405 }
19406
9ef920e9
NC
19407 switch ((name_type = * name))
19408 {
19409 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19410 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19411 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19412 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19413 printf ("%c", * name);
88305e1b 19414 left --;
9ef920e9
NC
19415 break;
19416 default:
19417 error (_("unrecognised attribute type in name field: %d\n"), name_type);
19418 print_symbol (-20, _("<unknown name type>"));
19419 return FALSE;
19420 }
19421
9ef920e9
NC
19422 ++ name;
19423 text = NULL;
19424
19425 switch ((name_attribute = * name))
19426 {
19427 case GNU_BUILD_ATTRIBUTE_VERSION:
19428 text = _("<version>");
1d15e434 19429 expected_types = string_expected;
9ef920e9
NC
19430 ++ name;
19431 break;
19432 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19433 text = _("<stack prot>");
75d7d298 19434 expected_types = "!+*";
9ef920e9
NC
19435 ++ name;
19436 break;
19437 case GNU_BUILD_ATTRIBUTE_RELRO:
19438 text = _("<relro>");
1d15e434 19439 expected_types = bool_expected;
9ef920e9
NC
19440 ++ name;
19441 break;
19442 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
19443 text = _("<stack size>");
1d15e434 19444 expected_types = number_expected;
9ef920e9
NC
19445 ++ name;
19446 break;
19447 case GNU_BUILD_ATTRIBUTE_TOOL:
19448 text = _("<tool>");
1d15e434 19449 expected_types = string_expected;
9ef920e9
NC
19450 ++ name;
19451 break;
19452 case GNU_BUILD_ATTRIBUTE_ABI:
19453 text = _("<ABI>");
19454 expected_types = "$*";
19455 ++ name;
19456 break;
19457 case GNU_BUILD_ATTRIBUTE_PIC:
19458 text = _("<PIC>");
1d15e434 19459 expected_types = number_expected;
9ef920e9
NC
19460 ++ name;
19461 break;
a8be5506
NC
19462 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
19463 text = _("<short enum>");
1d15e434 19464 expected_types = bool_expected;
a8be5506
NC
19465 ++ name;
19466 break;
9ef920e9
NC
19467 default:
19468 if (ISPRINT (* name))
19469 {
19470 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
19471
19472 if (len > left && ! do_wide)
19473 len = left;
75d7d298 19474 printf ("%.*s:", len, name);
9ef920e9 19475 left -= len;
0dd6ae21 19476 name += len;
9ef920e9
NC
19477 }
19478 else
19479 {
3e6b6445 19480 static char tmpbuf [128];
88305e1b 19481
3e6b6445
NC
19482 error (_("unrecognised byte in name field: %d\n"), * name);
19483 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
19484 text = tmpbuf;
19485 name ++;
9ef920e9
NC
19486 }
19487 expected_types = "*$!+";
19488 break;
19489 }
19490
19491 if (text)
88305e1b 19492 left -= printf ("%s", text);
9ef920e9
NC
19493
19494 if (strchr (expected_types, name_type) == NULL)
75d7d298 19495 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
19496
19497 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
19498 {
19499 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
19500 (unsigned long) pnote->namesz,
19501 (long) (name - pnote->namedata));
19502 return FALSE;
19503 }
19504
19505 if (left < 1 && ! do_wide)
19506 return TRUE;
19507
19508 switch (name_type)
19509 {
19510 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
19511 {
b06b2c92 19512 unsigned int bytes;
ddef72cd
NC
19513 unsigned long long val = 0;
19514 unsigned int shift = 0;
19515 char * decoded = NULL;
19516
b06b2c92
NC
19517 bytes = pnote->namesz - (name - pnote->namedata);
19518 if (bytes > 0)
19519 /* The -1 is because the name field is always 0 terminated, and we
19520 want to be able to ensure that the shift in the while loop below
19521 will not overflow. */
19522 -- bytes;
19523
ddef72cd
NC
19524 if (bytes > sizeof (val))
19525 {
3e6b6445
NC
19526 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
19527 bytes);
19528 bytes = sizeof (val);
ddef72cd 19529 }
3e6b6445
NC
19530 /* We do not bother to warn if bytes == 0 as this can
19531 happen with some early versions of the gcc plugin. */
9ef920e9
NC
19532
19533 while (bytes --)
19534 {
79a964dc
NC
19535 unsigned long byte = (* name ++) & 0xff;
19536
19537 val |= byte << shift;
9ef920e9
NC
19538 shift += 8;
19539 }
19540
75d7d298 19541 switch (name_attribute)
9ef920e9 19542 {
75d7d298 19543 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
19544 switch (val)
19545 {
75d7d298
NC
19546 case 0: decoded = "static"; break;
19547 case 1: decoded = "pic"; break;
19548 case 2: decoded = "PIC"; break;
19549 case 3: decoded = "pie"; break;
19550 case 4: decoded = "PIE"; break;
19551 default: break;
9ef920e9 19552 }
75d7d298
NC
19553 break;
19554 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
19555 switch (val)
9ef920e9 19556 {
75d7d298
NC
19557 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
19558 case 0: decoded = "off"; break;
19559 case 1: decoded = "on"; break;
19560 case 2: decoded = "all"; break;
19561 case 3: decoded = "strong"; break;
19562 case 4: decoded = "explicit"; break;
19563 default: break;
9ef920e9 19564 }
75d7d298
NC
19565 break;
19566 default:
19567 break;
9ef920e9
NC
19568 }
19569
75d7d298 19570 if (decoded != NULL)
3e6b6445
NC
19571 {
19572 print_symbol (-left, decoded);
19573 left = 0;
19574 }
19575 else if (val == 0)
19576 {
19577 printf ("0x0");
19578 left -= 3;
19579 }
9ef920e9 19580 else
75d7d298
NC
19581 {
19582 if (do_wide)
ddef72cd 19583 left -= printf ("0x%llx", val);
75d7d298 19584 else
ddef72cd 19585 left -= printf ("0x%-.*llx", left, val);
75d7d298 19586 }
9ef920e9
NC
19587 }
19588 break;
19589 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
19590 left -= print_symbol (- left, name);
19591 break;
19592 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
19593 left -= print_symbol (- left, "true");
19594 break;
19595 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
19596 left -= print_symbol (- left, "false");
19597 break;
19598 }
19599
19600 if (do_wide && left > 0)
19601 printf ("%-*s", left, " ");
9abca702 19602
9ef920e9
NC
19603 return TRUE;
19604}
19605
6d118b09
NC
19606/* Note that by the ELF standard, the name field is already null byte
19607 terminated, and namesz includes the terminating null byte.
19608 I.E. the value of namesz for the name "FSF" is 4.
19609
e3c8793a 19610 If the value of namesz is zero, there is no name present. */
9ef920e9 19611
32ec8896 19612static bfd_boolean
9ef920e9 19613process_note (Elf_Internal_Note * pnote,
dda8d76d 19614 Filedata * filedata)
779fe533 19615{
2cf0635d
NC
19616 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
19617 const char * nt;
9437c45b
JT
19618
19619 if (pnote->namesz == 0)
1ec5cd37
NC
19620 /* If there is no note name, then use the default set of
19621 note type strings. */
dda8d76d 19622 nt = get_note_type (filedata, pnote->type);
1ec5cd37 19623
1118d252
RM
19624 else if (const_strneq (pnote->namedata, "GNU"))
19625 /* GNU-specific object file notes. */
19626 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
19627
19628 else if (const_strneq (pnote->namedata, "FreeBSD"))
19629 /* FreeBSD-specific core file notes. */
dda8d76d 19630 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 19631
0112cd26 19632 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 19633 /* NetBSD-specific core file notes. */
dda8d76d 19634 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 19635
c6056a74
SF
19636 else if (const_strneq (pnote->namedata, "NetBSD"))
19637 /* NetBSD-specific core file notes. */
19638 return process_netbsd_elf_note (pnote);
19639
9abca702
CZ
19640 else if (const_strneq (pnote->namedata, "PaX"))
19641 /* NetBSD-specific core file notes. */
19642 return process_netbsd_elf_note (pnote);
19643
b15fa79e
AM
19644 else if (strneq (pnote->namedata, "SPU/", 4))
19645 {
19646 /* SPU-specific core file notes. */
19647 nt = pnote->namedata + 4;
19648 name = "SPU";
19649 }
19650
00e98fc7
TG
19651 else if (const_strneq (pnote->namedata, "IPF/VMS"))
19652 /* VMS/ia64-specific file notes. */
19653 nt = get_ia64_vms_note_type (pnote->type);
19654
70616151
TT
19655 else if (const_strneq (pnote->namedata, "stapsdt"))
19656 nt = get_stapsdt_note_type (pnote->type);
19657
9437c45b 19658 else
1ec5cd37
NC
19659 /* Don't recognize this note name; just use the default set of
19660 note type strings. */
dda8d76d 19661 nt = get_note_type (filedata, pnote->type);
9437c45b 19662
1449284b 19663 printf (" ");
9ef920e9 19664
483767a3
AM
19665 if (((const_strneq (pnote->namedata, "GA")
19666 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19667 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19668 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19669 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
19670 print_gnu_build_attribute_name (pnote);
19671 else
19672 print_symbol (-20, name);
19673
19674 if (do_wide)
19675 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
19676 else
19677 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
19678
19679 if (const_strneq (pnote->namedata, "IPF/VMS"))
19680 return print_ia64_vms_note (pnote);
664f90a3 19681 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 19682 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
19683 else if (const_strneq (pnote->namedata, "stapsdt"))
19684 return print_stapsdt_note (pnote);
9ece1fa9
TT
19685 else if (const_strneq (pnote->namedata, "CORE"))
19686 return print_core_note (pnote);
483767a3
AM
19687 else if (((const_strneq (pnote->namedata, "GA")
19688 && strchr ("*$!+", pnote->namedata[2]) != NULL)
19689 || strchr ("*$!+", pnote->namedata[0]) != NULL)
19690 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
19691 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 19692 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 19693
9ef920e9 19694 if (pnote->descsz)
1449284b
NC
19695 {
19696 unsigned long i;
19697
19698 printf (_(" description data: "));
19699 for (i = 0; i < pnote->descsz; i++)
178d8719 19700 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
19701 if (!do_wide)
19702 printf ("\n");
1449284b
NC
19703 }
19704
9ef920e9
NC
19705 if (do_wide)
19706 printf ("\n");
19707
32ec8896 19708 return TRUE;
1449284b 19709}
6d118b09 19710
32ec8896 19711static bfd_boolean
dda8d76d
NC
19712process_notes_at (Filedata * filedata,
19713 Elf_Internal_Shdr * section,
19714 bfd_vma offset,
82ed9683
L
19715 bfd_vma length,
19716 bfd_vma align)
779fe533 19717{
2cf0635d
NC
19718 Elf_External_Note * pnotes;
19719 Elf_External_Note * external;
4dff97b2
NC
19720 char * end;
19721 bfd_boolean res = TRUE;
103f02d3 19722
779fe533 19723 if (length <= 0)
32ec8896 19724 return FALSE;
103f02d3 19725
1449284b
NC
19726 if (section)
19727 {
dda8d76d 19728 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 19729 if (pnotes)
32ec8896 19730 {
dda8d76d 19731 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
19732 {
19733 free (pnotes);
19734 return FALSE;
19735 }
32ec8896 19736 }
1449284b
NC
19737 }
19738 else
82ed9683 19739 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 19740 _("notes"));
4dff97b2 19741
dd24e3da 19742 if (pnotes == NULL)
32ec8896 19743 return FALSE;
779fe533 19744
103f02d3 19745 external = pnotes;
103f02d3 19746
1449284b 19747 if (section)
dda8d76d 19748 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
19749 else
19750 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
19751 (unsigned long) offset, (unsigned long) length);
19752
82ed9683
L
19753 /* NB: Some note sections may have alignment value of 0 or 1. gABI
19754 specifies that notes should be aligned to 4 bytes in 32-bit
19755 objects and to 8 bytes in 64-bit objects. As a Linux extension,
19756 we also support 4 byte alignment in 64-bit objects. If section
19757 alignment is less than 4, we treate alignment as 4 bytes. */
19758 if (align < 4)
19759 align = 4;
19760 else if (align != 4 && align != 8)
19761 {
19762 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
19763 (long) align);
a788aedd 19764 free (pnotes);
82ed9683
L
19765 return FALSE;
19766 }
19767
dbe15e4e 19768 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 19769
c8071705
NC
19770 end = (char *) pnotes + length;
19771 while ((char *) external < end)
779fe533 19772 {
b34976b6 19773 Elf_Internal_Note inote;
15b42fb0 19774 size_t min_notesz;
4dff97b2 19775 char * next;
2cf0635d 19776 char * temp = NULL;
c8071705 19777 size_t data_remaining = end - (char *) external;
6d118b09 19778
dda8d76d 19779 if (!is_ia64_vms (filedata))
15b42fb0 19780 {
9dd3a467
NC
19781 /* PR binutils/15191
19782 Make sure that there is enough data to read. */
15b42fb0
AM
19783 min_notesz = offsetof (Elf_External_Note, name);
19784 if (data_remaining < min_notesz)
9dd3a467 19785 {
d3a49aa8
AM
19786 warn (ngettext ("Corrupt note: only %ld byte remains, "
19787 "not enough for a full note\n",
19788 "Corrupt note: only %ld bytes remain, "
19789 "not enough for a full note\n",
19790 data_remaining),
19791 (long) data_remaining);
9dd3a467
NC
19792 break;
19793 }
5396a86e
AM
19794 data_remaining -= min_notesz;
19795
15b42fb0
AM
19796 inote.type = BYTE_GET (external->type);
19797 inote.namesz = BYTE_GET (external->namesz);
19798 inote.namedata = external->name;
19799 inote.descsz = BYTE_GET (external->descsz);
276da9b3 19800 inote.descdata = ((char *) external
4dff97b2 19801 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 19802 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 19803 next = ((char *) external
4dff97b2 19804 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 19805 }
00e98fc7 19806 else
15b42fb0
AM
19807 {
19808 Elf64_External_VMS_Note *vms_external;
00e98fc7 19809
9dd3a467
NC
19810 /* PR binutils/15191
19811 Make sure that there is enough data to read. */
15b42fb0
AM
19812 min_notesz = offsetof (Elf64_External_VMS_Note, name);
19813 if (data_remaining < min_notesz)
9dd3a467 19814 {
d3a49aa8
AM
19815 warn (ngettext ("Corrupt note: only %ld byte remains, "
19816 "not enough for a full note\n",
19817 "Corrupt note: only %ld bytes remain, "
19818 "not enough for a full note\n",
19819 data_remaining),
19820 (long) data_remaining);
9dd3a467
NC
19821 break;
19822 }
5396a86e 19823 data_remaining -= min_notesz;
3e55a963 19824
15b42fb0
AM
19825 vms_external = (Elf64_External_VMS_Note *) external;
19826 inote.type = BYTE_GET (vms_external->type);
19827 inote.namesz = BYTE_GET (vms_external->namesz);
19828 inote.namedata = vms_external->name;
19829 inote.descsz = BYTE_GET (vms_external->descsz);
19830 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
19831 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19832 next = inote.descdata + align_power (inote.descsz, 3);
19833 }
19834
5396a86e
AM
19835 /* PR 17531: file: 3443835e. */
19836 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
19837 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
19838 || (size_t) (inote.descdata - inote.namedata) > data_remaining
19839 || (size_t) (next - inote.descdata) < inote.descsz
19840 || ((size_t) (next - inote.descdata)
19841 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 19842 {
15b42fb0 19843 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 19844 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
19845 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
19846 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
19847 break;
19848 }
19849
15b42fb0 19850 external = (Elf_External_Note *) next;
dd24e3da 19851
6d118b09
NC
19852 /* Verify that name is null terminated. It appears that at least
19853 one version of Linux (RedHat 6.0) generates corefiles that don't
19854 comply with the ELF spec by failing to include the null byte in
19855 namesz. */
18344509 19856 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 19857 {
5396a86e 19858 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 19859 {
5396a86e
AM
19860 temp = (char *) malloc (inote.namesz + 1);
19861 if (temp == NULL)
19862 {
19863 error (_("Out of memory allocating space for inote name\n"));
19864 res = FALSE;
19865 break;
19866 }
76da6bbe 19867
5396a86e
AM
19868 memcpy (temp, inote.namedata, inote.namesz);
19869 inote.namedata = temp;
19870 }
19871 inote.namedata[inote.namesz] = 0;
6d118b09
NC
19872 }
19873
dda8d76d 19874 if (! process_note (& inote, filedata))
6b4bf3bc 19875 res = FALSE;
103f02d3 19876
9db70fc3
AM
19877 free (temp);
19878 temp = NULL;
779fe533
NC
19879 }
19880
19881 free (pnotes);
103f02d3 19882
779fe533
NC
19883 return res;
19884}
19885
32ec8896 19886static bfd_boolean
dda8d76d 19887process_corefile_note_segments (Filedata * filedata)
779fe533 19888{
2cf0635d 19889 Elf_Internal_Phdr * segment;
b34976b6 19890 unsigned int i;
32ec8896 19891 bfd_boolean res = TRUE;
103f02d3 19892
dda8d76d 19893 if (! get_program_headers (filedata))
6b4bf3bc 19894 return TRUE;
103f02d3 19895
dda8d76d
NC
19896 for (i = 0, segment = filedata->program_headers;
19897 i < filedata->file_header.e_phnum;
b34976b6 19898 i++, segment++)
779fe533
NC
19899 {
19900 if (segment->p_type == PT_NOTE)
dda8d76d 19901 if (! process_notes_at (filedata, NULL,
32ec8896 19902 (bfd_vma) segment->p_offset,
82ed9683
L
19903 (bfd_vma) segment->p_filesz,
19904 (bfd_vma) segment->p_align))
32ec8896 19905 res = FALSE;
779fe533 19906 }
103f02d3 19907
779fe533
NC
19908 return res;
19909}
19910
32ec8896 19911static bfd_boolean
dda8d76d 19912process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
19913{
19914 Elf_External_Note * pnotes;
19915 Elf_External_Note * external;
c8071705 19916 char * end;
32ec8896 19917 bfd_boolean res = TRUE;
685080f2
NC
19918
19919 if (length <= 0)
32ec8896 19920 return FALSE;
685080f2 19921
dda8d76d 19922 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
19923 _("v850 notes"));
19924 if (pnotes == NULL)
32ec8896 19925 return FALSE;
685080f2
NC
19926
19927 external = pnotes;
c8071705 19928 end = (char*) pnotes + length;
685080f2
NC
19929
19930 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
19931 (unsigned long) offset, (unsigned long) length);
19932
c8071705 19933 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
19934 {
19935 Elf_External_Note * next;
19936 Elf_Internal_Note inote;
19937
19938 inote.type = BYTE_GET (external->type);
19939 inote.namesz = BYTE_GET (external->namesz);
19940 inote.namedata = external->name;
19941 inote.descsz = BYTE_GET (external->descsz);
19942 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
19943 inote.descpos = offset + (inote.descdata - (char *) pnotes);
19944
c8071705
NC
19945 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
19946 {
19947 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
19948 inote.descdata = inote.namedata;
19949 inote.namesz = 0;
19950 }
19951
685080f2
NC
19952 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
19953
c8071705 19954 if ( ((char *) next > end)
685080f2
NC
19955 || ((char *) next < (char *) pnotes))
19956 {
19957 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
19958 (unsigned long) ((char *) external - (char *) pnotes));
19959 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19960 inote.type, inote.namesz, inote.descsz);
19961 break;
19962 }
19963
19964 external = next;
19965
19966 /* Prevent out-of-bounds indexing. */
c8071705 19967 if ( inote.namedata + inote.namesz > end
685080f2
NC
19968 || inote.namedata + inote.namesz < inote.namedata)
19969 {
19970 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
19971 (unsigned long) ((char *) external - (char *) pnotes));
19972 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
19973 inote.type, inote.namesz, inote.descsz);
19974 break;
19975 }
19976
19977 printf (" %s: ", get_v850_elf_note_type (inote.type));
19978
19979 if (! print_v850_note (& inote))
19980 {
32ec8896 19981 res = FALSE;
685080f2
NC
19982 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
19983 inote.namesz, inote.descsz);
19984 }
19985 }
19986
19987 free (pnotes);
19988
19989 return res;
19990}
19991
32ec8896 19992static bfd_boolean
dda8d76d 19993process_note_sections (Filedata * filedata)
1ec5cd37 19994{
2cf0635d 19995 Elf_Internal_Shdr * section;
1ec5cd37 19996 unsigned long i;
32ec8896
NC
19997 unsigned int n = 0;
19998 bfd_boolean res = TRUE;
1ec5cd37 19999
dda8d76d
NC
20000 for (i = 0, section = filedata->section_headers;
20001 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20002 i++, section++)
685080f2
NC
20003 {
20004 if (section->sh_type == SHT_NOTE)
20005 {
dda8d76d 20006 if (! process_notes_at (filedata, section,
32ec8896 20007 (bfd_vma) section->sh_offset,
82ed9683
L
20008 (bfd_vma) section->sh_size,
20009 (bfd_vma) section->sh_addralign))
32ec8896 20010 res = FALSE;
685080f2
NC
20011 n++;
20012 }
20013
dda8d76d
NC
20014 if (( filedata->file_header.e_machine == EM_V800
20015 || filedata->file_header.e_machine == EM_V850
20016 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20017 && section->sh_type == SHT_RENESAS_INFO)
20018 {
dda8d76d 20019 if (! process_v850_notes (filedata,
32ec8896
NC
20020 (bfd_vma) section->sh_offset,
20021 (bfd_vma) section->sh_size))
20022 res = FALSE;
685080f2
NC
20023 n++;
20024 }
20025 }
df565f32
NC
20026
20027 if (n == 0)
20028 /* Try processing NOTE segments instead. */
dda8d76d 20029 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20030
20031 return res;
20032}
20033
32ec8896 20034static bfd_boolean
dda8d76d 20035process_notes (Filedata * filedata)
779fe533
NC
20036{
20037 /* If we have not been asked to display the notes then do nothing. */
20038 if (! do_notes)
32ec8896 20039 return TRUE;
103f02d3 20040
dda8d76d
NC
20041 if (filedata->file_header.e_type != ET_CORE)
20042 return process_note_sections (filedata);
103f02d3 20043
779fe533 20044 /* No program headers means no NOTE segment. */
dda8d76d
NC
20045 if (filedata->file_header.e_phnum > 0)
20046 return process_corefile_note_segments (filedata);
779fe533 20047
1ec5cd37 20048 printf (_("No note segments present in the core file.\n"));
32ec8896 20049 return TRUE;
779fe533
NC
20050}
20051
60abdbed
NC
20052static unsigned char *
20053display_public_gnu_attributes (unsigned char * start,
20054 const unsigned char * const end)
20055{
20056 printf (_(" Unknown GNU attribute: %s\n"), start);
20057
20058 start += strnlen ((char *) start, end - start);
20059 display_raw_attribute (start, end);
20060
20061 return (unsigned char *) end;
20062}
20063
20064static unsigned char *
20065display_generic_attribute (unsigned char * start,
20066 unsigned int tag,
20067 const unsigned char * const end)
20068{
20069 if (tag == 0)
20070 return (unsigned char *) end;
20071
20072 return display_tag_value (tag, start, end);
20073}
20074
32ec8896 20075static bfd_boolean
dda8d76d 20076process_arch_specific (Filedata * filedata)
252b5132 20077{
a952a375 20078 if (! do_arch)
32ec8896 20079 return TRUE;
a952a375 20080
dda8d76d 20081 switch (filedata->file_header.e_machine)
252b5132 20082 {
53a346d8
CZ
20083 case EM_ARC:
20084 case EM_ARC_COMPACT:
20085 case EM_ARC_COMPACT2:
dda8d76d 20086 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
20087 display_arc_attribute,
20088 display_generic_attribute);
11c1ff18 20089 case EM_ARM:
dda8d76d 20090 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
20091 display_arm_attribute,
20092 display_generic_attribute);
20093
252b5132 20094 case EM_MIPS:
4fe85591 20095 case EM_MIPS_RS3_LE:
dda8d76d 20096 return process_mips_specific (filedata);
60abdbed
NC
20097
20098 case EM_MSP430:
dda8d76d
NC
20099 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
20100 display_msp430x_attribute,
c0ea7c52 20101 display_msp430_gnu_attribute);
60abdbed 20102
2dc8dd17
JW
20103 case EM_RISCV:
20104 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
20105 display_riscv_attribute,
20106 display_generic_attribute);
20107
35c08157 20108 case EM_NDS32:
dda8d76d 20109 return process_nds32_specific (filedata);
60abdbed 20110
85f7484a
PB
20111 case EM_68K:
20112 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
20113 display_m68k_gnu_attribute);
20114
34c8bcba 20115 case EM_PPC:
b82317dd 20116 case EM_PPC64:
dda8d76d 20117 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20118 display_power_gnu_attribute);
20119
643f7afb
AK
20120 case EM_S390:
20121 case EM_S390_OLD:
dda8d76d 20122 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20123 display_s390_gnu_attribute);
20124
9e8c70f9
DM
20125 case EM_SPARC:
20126 case EM_SPARC32PLUS:
20127 case EM_SPARCV9:
dda8d76d 20128 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20129 display_sparc_gnu_attribute);
20130
59e6276b 20131 case EM_TI_C6000:
dda8d76d 20132 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
20133 display_tic6x_attribute,
20134 display_generic_attribute);
20135
252b5132 20136 default:
dda8d76d 20137 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
20138 display_public_gnu_attributes,
20139 display_generic_attribute);
252b5132 20140 }
252b5132
RH
20141}
20142
32ec8896 20143static bfd_boolean
dda8d76d 20144get_file_header (Filedata * filedata)
252b5132 20145{
9ea033b2 20146 /* Read in the identity array. */
dda8d76d 20147 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20148 return FALSE;
252b5132 20149
9ea033b2 20150 /* Determine how to read the rest of the header. */
dda8d76d 20151 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 20152 {
1a0670f3
AM
20153 default:
20154 case ELFDATANONE:
adab8cdc
AO
20155 case ELFDATA2LSB:
20156 byte_get = byte_get_little_endian;
20157 byte_put = byte_put_little_endian;
20158 break;
20159 case ELFDATA2MSB:
20160 byte_get = byte_get_big_endian;
20161 byte_put = byte_put_big_endian;
20162 break;
9ea033b2
NC
20163 }
20164
20165 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 20166 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
20167
20168 /* Read in the rest of the header. */
20169 if (is_32bit_elf)
20170 {
20171 Elf32_External_Ehdr ehdr32;
252b5132 20172
dda8d76d 20173 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20174 return FALSE;
103f02d3 20175
dda8d76d
NC
20176 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
20177 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
20178 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
20179 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
20180 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
20181 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
20182 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
20183 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
20184 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
20185 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
20186 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
20187 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
20188 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 20189 }
252b5132 20190 else
9ea033b2
NC
20191 {
20192 Elf64_External_Ehdr ehdr64;
a952a375
NC
20193
20194 /* If we have been compiled with sizeof (bfd_vma) == 4, then
20195 we will not be able to cope with the 64bit data found in
20196 64 ELF files. Detect this now and abort before we start
50c2245b 20197 overwriting things. */
a952a375
NC
20198 if (sizeof (bfd_vma) < 8)
20199 {
e3c8793a
NC
20200 error (_("This instance of readelf has been built without support for a\n\
2020164 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 20202 return FALSE;
a952a375 20203 }
103f02d3 20204
dda8d76d 20205 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20206 return FALSE;
103f02d3 20207
dda8d76d
NC
20208 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
20209 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
20210 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
20211 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
20212 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
20213 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
20214 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
20215 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
20216 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
20217 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
20218 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
20219 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
20220 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 20221 }
252b5132 20222
dda8d76d 20223 if (filedata->file_header.e_shoff)
7ece0d85
JJ
20224 {
20225 /* There may be some extensions in the first section header. Don't
20226 bomb if we can't read it. */
20227 if (is_32bit_elf)
dda8d76d 20228 get_32bit_section_headers (filedata, TRUE);
7ece0d85 20229 else
dda8d76d 20230 get_64bit_section_headers (filedata, TRUE);
7ece0d85 20231 }
560f3c1c 20232
32ec8896 20233 return TRUE;
252b5132
RH
20234}
20235
dda8d76d
NC
20236static void
20237close_file (Filedata * filedata)
20238{
20239 if (filedata)
20240 {
20241 if (filedata->handle)
20242 fclose (filedata->handle);
20243 free (filedata);
20244 }
20245}
20246
20247void
20248close_debug_file (void * data)
20249{
20250 close_file ((Filedata *) data);
20251}
20252
20253static Filedata *
20254open_file (const char * pathname)
20255{
20256 struct stat statbuf;
20257 Filedata * filedata = NULL;
20258
20259 if (stat (pathname, & statbuf) < 0
20260 || ! S_ISREG (statbuf.st_mode))
20261 goto fail;
20262
20263 filedata = calloc (1, sizeof * filedata);
20264 if (filedata == NULL)
20265 goto fail;
20266
20267 filedata->handle = fopen (pathname, "rb");
20268 if (filedata->handle == NULL)
20269 goto fail;
20270
20271 filedata->file_size = (bfd_size_type) statbuf.st_size;
20272 filedata->file_name = pathname;
20273
20274 if (! get_file_header (filedata))
20275 goto fail;
20276
20277 if (filedata->file_header.e_shoff)
20278 {
20279 bfd_boolean res;
20280
20281 /* Read the section headers again, this time for real. */
20282 if (is_32bit_elf)
20283 res = get_32bit_section_headers (filedata, FALSE);
20284 else
20285 res = get_64bit_section_headers (filedata, FALSE);
20286
20287 if (!res)
20288 goto fail;
20289 }
20290
20291 return filedata;
20292
20293 fail:
20294 if (filedata)
20295 {
20296 if (filedata->handle)
20297 fclose (filedata->handle);
20298 free (filedata);
20299 }
20300 return NULL;
20301}
20302
20303void *
20304open_debug_file (const char * pathname)
20305{
20306 return open_file (pathname);
20307}
20308
fb52b2f4
NC
20309/* Process one ELF object file according to the command line options.
20310 This file may actually be stored in an archive. The file is
32ec8896
NC
20311 positioned at the start of the ELF object. Returns TRUE if no
20312 problems were encountered, FALSE otherwise. */
fb52b2f4 20313
32ec8896 20314static bfd_boolean
dda8d76d 20315process_object (Filedata * filedata)
252b5132 20316{
24841daa 20317 bfd_boolean have_separate_files;
252b5132 20318 unsigned int i;
2482f306 20319 bfd_boolean res;
252b5132 20320
dda8d76d 20321 if (! get_file_header (filedata))
252b5132 20322 {
dda8d76d 20323 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 20324 return FALSE;
252b5132
RH
20325 }
20326
20327 /* Initialise per file variables. */
978c4450
AM
20328 for (i = ARRAY_SIZE (filedata->version_info); i--;)
20329 filedata->version_info[i] = 0;
252b5132 20330
978c4450
AM
20331 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
20332 filedata->dynamic_info[i] = 0;
20333 filedata->dynamic_info_DT_GNU_HASH = 0;
20334 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
20335
20336 /* Process the file. */
20337 if (show_name)
dda8d76d 20338 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 20339
18bd398b
NC
20340 /* Initialise the dump_sects array from the cmdline_dump_sects array.
20341 Note we do this even if cmdline_dump_sects is empty because we
20342 must make sure that the dump_sets array is zeroed out before each
20343 object file is processed. */
6431e409
AM
20344 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
20345 memset (filedata->dump.dump_sects, 0,
20346 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20347
dda8d76d 20348 if (cmdline.num_dump_sects > 0)
18bd398b 20349 {
6431e409 20350 if (filedata->dump.num_dump_sects == 0)
18bd398b 20351 /* A sneaky way of allocating the dump_sects array. */
6431e409 20352 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 20353
6431e409
AM
20354 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
20355 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
20356 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20357 }
d70c5fc7 20358
dda8d76d 20359 if (! process_file_header (filedata))
32ec8896 20360 return FALSE;
252b5132 20361
dda8d76d 20362 if (! process_section_headers (filedata))
2f62977e 20363 {
32ec8896
NC
20364 /* Without loaded section headers we cannot process lots of things. */
20365 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 20366
2f62977e 20367 if (! do_using_dynamic)
32ec8896 20368 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 20369 }
252b5132 20370
dda8d76d 20371 if (! process_section_groups (filedata))
32ec8896
NC
20372 /* Without loaded section groups we cannot process unwind. */
20373 do_unwind = FALSE;
d1f5c6e3 20374
2482f306
AM
20375 res = process_program_headers (filedata);
20376 if (res)
20377 res = process_dynamic_section (filedata);
252b5132 20378
dda8d76d 20379 if (! process_relocs (filedata))
32ec8896 20380 res = FALSE;
252b5132 20381
dda8d76d 20382 if (! process_unwind (filedata))
32ec8896 20383 res = FALSE;
4d6ed7c8 20384
dda8d76d 20385 if (! process_symbol_table (filedata))
32ec8896 20386 res = FALSE;
252b5132 20387
dda8d76d 20388 if (! process_syminfo (filedata))
32ec8896 20389 res = FALSE;
252b5132 20390
dda8d76d 20391 if (! process_version_sections (filedata))
32ec8896 20392 res = FALSE;
252b5132 20393
82ed9683 20394 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 20395 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 20396 else
24841daa 20397 have_separate_files = FALSE;
dda8d76d
NC
20398
20399 if (! process_section_contents (filedata))
32ec8896 20400 res = FALSE;
f5842774 20401
24841daa 20402 if (have_separate_files)
dda8d76d 20403 {
24841daa
NC
20404 separate_info * d;
20405
20406 for (d = first_separate_info; d != NULL; d = d->next)
20407 {
20408 if (! process_section_headers (d->handle))
20409 res = FALSE;
20410 else if (! process_section_contents (d->handle))
20411 res = FALSE;
20412 }
20413
20414 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
20415 }
20416
20417 if (! process_notes (filedata))
32ec8896 20418 res = FALSE;
103f02d3 20419
dda8d76d 20420 if (! process_gnu_liblist (filedata))
32ec8896 20421 res = FALSE;
047b2264 20422
dda8d76d 20423 if (! process_arch_specific (filedata))
32ec8896 20424 res = FALSE;
252b5132 20425
dda8d76d
NC
20426 free (filedata->program_headers);
20427 filedata->program_headers = NULL;
d93f0186 20428
dda8d76d
NC
20429 free (filedata->section_headers);
20430 filedata->section_headers = NULL;
252b5132 20431
dda8d76d
NC
20432 free (filedata->string_table);
20433 filedata->string_table = NULL;
20434 filedata->string_table_length = 0;
252b5132 20435
9db70fc3
AM
20436 free (filedata->dump.dump_sects);
20437 filedata->dump.dump_sects = NULL;
20438 filedata->dump.num_dump_sects = 0;
a788aedd 20439
9db70fc3
AM
20440 free (filedata->dynamic_strings);
20441 filedata->dynamic_strings = NULL;
20442 filedata->dynamic_strings_length = 0;
252b5132 20443
9db70fc3
AM
20444 free (filedata->dynamic_symbols);
20445 filedata->dynamic_symbols = NULL;
20446 filedata->num_dynamic_syms = 0;
252b5132 20447
9db70fc3
AM
20448 free (filedata->dynamic_syminfo);
20449 filedata->dynamic_syminfo = NULL;
ff78d6d6 20450
9db70fc3
AM
20451 free (filedata->dynamic_section);
20452 filedata->dynamic_section = NULL;
293c573e 20453
978c4450 20454 while (filedata->symtab_shndx_list != NULL)
8fb879cd 20455 {
978c4450
AM
20456 elf_section_list *next = filedata->symtab_shndx_list->next;
20457 free (filedata->symtab_shndx_list);
20458 filedata->symtab_shndx_list = next;
8fb879cd
AM
20459 }
20460
9db70fc3
AM
20461 free (filedata->section_headers_groups);
20462 filedata->section_headers_groups = NULL;
e4b17d5c 20463
978c4450 20464 if (filedata->section_groups)
e4b17d5c 20465 {
2cf0635d
NC
20466 struct group_list * g;
20467 struct group_list * next;
e4b17d5c 20468
978c4450 20469 for (i = 0; i < filedata->group_count; i++)
e4b17d5c 20470 {
978c4450 20471 for (g = filedata->section_groups [i].root; g != NULL; g = next)
e4b17d5c
L
20472 {
20473 next = g->next;
20474 free (g);
20475 }
20476 }
20477
978c4450
AM
20478 free (filedata->section_groups);
20479 filedata->section_groups = NULL;
e4b17d5c
L
20480 }
20481
19e6b90e 20482 free_debug_memory ();
18bd398b 20483
32ec8896 20484 return res;
252b5132
RH
20485}
20486
2cf0635d 20487/* Process an ELF archive.
32ec8896
NC
20488 On entry the file is positioned just after the ARMAG string.
20489 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 20490
32ec8896 20491static bfd_boolean
dda8d76d 20492process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
20493{
20494 struct archive_info arch;
20495 struct archive_info nested_arch;
20496 size_t got;
32ec8896 20497 bfd_boolean ret = TRUE;
2cf0635d 20498
32ec8896 20499 show_name = TRUE;
2cf0635d
NC
20500
20501 /* The ARCH structure is used to hold information about this archive. */
20502 arch.file_name = NULL;
20503 arch.file = NULL;
20504 arch.index_array = NULL;
20505 arch.sym_table = NULL;
20506 arch.longnames = NULL;
20507
20508 /* The NESTED_ARCH structure is used as a single-item cache of information
20509 about a nested archive (when members of a thin archive reside within
20510 another regular archive file). */
20511 nested_arch.file_name = NULL;
20512 nested_arch.file = NULL;
20513 nested_arch.index_array = NULL;
20514 nested_arch.sym_table = NULL;
20515 nested_arch.longnames = NULL;
20516
dda8d76d 20517 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
20518 filedata->file_size, is_thin_archive,
20519 do_archive_index) != 0)
2cf0635d 20520 {
32ec8896 20521 ret = FALSE;
2cf0635d 20522 goto out;
4145f1d5 20523 }
fb52b2f4 20524
4145f1d5
NC
20525 if (do_archive_index)
20526 {
2cf0635d 20527 if (arch.sym_table == NULL)
1cb7d8b1
AM
20528 error (_("%s: unable to dump the index as none was found\n"),
20529 filedata->file_name);
4145f1d5
NC
20530 else
20531 {
591f7597 20532 unsigned long i, l;
4145f1d5
NC
20533 unsigned long current_pos;
20534
1cb7d8b1
AM
20535 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
20536 "in the symbol table)\n"),
20537 filedata->file_name, (unsigned long) arch.index_num,
20538 arch.sym_size);
dda8d76d
NC
20539
20540 current_pos = ftell (filedata->handle);
4145f1d5 20541
2cf0635d 20542 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 20543 {
1cb7d8b1
AM
20544 if (i == 0
20545 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
20546 {
20547 char * member_name
20548 = get_archive_member_name_at (&arch, arch.index_array[i],
20549 &nested_arch);
2cf0635d 20550
1cb7d8b1
AM
20551 if (member_name != NULL)
20552 {
20553 char * qualified_name
20554 = make_qualified_name (&arch, &nested_arch,
20555 member_name);
2cf0635d 20556
1cb7d8b1
AM
20557 if (qualified_name != NULL)
20558 {
20559 printf (_("Contents of binary %s at offset "),
20560 qualified_name);
c2a7d3f5
NC
20561 (void) print_vma (arch.index_array[i], PREFIX_HEX);
20562 putchar ('\n');
1cb7d8b1
AM
20563 free (qualified_name);
20564 }
fd486f32 20565 free (member_name);
4145f1d5
NC
20566 }
20567 }
2cf0635d
NC
20568
20569 if (l >= arch.sym_size)
4145f1d5 20570 {
1cb7d8b1
AM
20571 error (_("%s: end of the symbol table reached "
20572 "before the end of the index\n"),
dda8d76d 20573 filedata->file_name);
32ec8896 20574 ret = FALSE;
cb8f3167 20575 break;
4145f1d5 20576 }
591f7597 20577 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
20578 printf ("\t%.*s\n",
20579 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 20580 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
20581 }
20582
67ce483b 20583 if (arch.uses_64bit_indices)
c2a7d3f5
NC
20584 l = (l + 7) & ~ 7;
20585 else
20586 l += l & 1;
20587
2cf0635d 20588 if (l < arch.sym_size)
32ec8896 20589 {
d3a49aa8
AM
20590 error (ngettext ("%s: %ld byte remains in the symbol table, "
20591 "but without corresponding entries in "
20592 "the index table\n",
20593 "%s: %ld bytes remain in the symbol table, "
20594 "but without corresponding entries in "
20595 "the index table\n",
20596 arch.sym_size - l),
dda8d76d 20597 filedata->file_name, arch.sym_size - l);
32ec8896
NC
20598 ret = FALSE;
20599 }
4145f1d5 20600
dda8d76d 20601 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 20602 {
1cb7d8b1
AM
20603 error (_("%s: failed to seek back to start of object files "
20604 "in the archive\n"),
dda8d76d 20605 filedata->file_name);
32ec8896 20606 ret = FALSE;
2cf0635d 20607 goto out;
4145f1d5 20608 }
fb52b2f4 20609 }
4145f1d5
NC
20610
20611 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
20612 && !do_segments && !do_header && !do_dump && !do_version
20613 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 20614 && !do_section_groups && !do_dyn_syms)
2cf0635d 20615 {
32ec8896 20616 ret = TRUE; /* Archive index only. */
2cf0635d
NC
20617 goto out;
20618 }
fb52b2f4
NC
20619 }
20620
fb52b2f4
NC
20621 while (1)
20622 {
2cf0635d
NC
20623 char * name;
20624 size_t namelen;
20625 char * qualified_name;
20626
20627 /* Read the next archive header. */
dda8d76d 20628 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
20629 {
20630 error (_("%s: failed to seek to next archive header\n"),
20631 arch.file_name);
20632 ret = FALSE;
20633 break;
20634 }
dda8d76d 20635 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 20636 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
20637 {
20638 if (got == 0)
2cf0635d 20639 break;
28e817cc
NC
20640 /* PR 24049 - we cannot use filedata->file_name as this will
20641 have already been freed. */
20642 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 20643
1cb7d8b1
AM
20644 ret = FALSE;
20645 break;
20646 }
2cf0635d 20647 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
20648 {
20649 error (_("%s: did not find a valid archive header\n"),
20650 arch.file_name);
20651 ret = FALSE;
20652 break;
20653 }
2cf0635d
NC
20654
20655 arch.next_arhdr_offset += sizeof arch.arhdr;
20656
978c4450
AM
20657 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
20658 if (filedata->archive_file_size & 01)
20659 ++filedata->archive_file_size;
2cf0635d
NC
20660
20661 name = get_archive_member_name (&arch, &nested_arch);
20662 if (name == NULL)
fb52b2f4 20663 {
28e817cc 20664 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 20665 ret = FALSE;
d989285c 20666 break;
fb52b2f4 20667 }
2cf0635d 20668 namelen = strlen (name);
fb52b2f4 20669
2cf0635d
NC
20670 qualified_name = make_qualified_name (&arch, &nested_arch, name);
20671 if (qualified_name == NULL)
fb52b2f4 20672 {
28e817cc 20673 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 20674 free (name);
32ec8896 20675 ret = FALSE;
d989285c 20676 break;
fb52b2f4
NC
20677 }
20678
2cf0635d 20679 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
20680 {
20681 /* This is a proxy for an external member of a thin archive. */
20682 Filedata * member_filedata;
20683 char * member_file_name = adjust_relative_path
dda8d76d 20684 (filedata->file_name, name, namelen);
32ec8896 20685
fd486f32 20686 free (name);
1cb7d8b1
AM
20687 if (member_file_name == NULL)
20688 {
fd486f32 20689 free (qualified_name);
1cb7d8b1
AM
20690 ret = FALSE;
20691 break;
20692 }
2cf0635d 20693
1cb7d8b1
AM
20694 member_filedata = open_file (member_file_name);
20695 if (member_filedata == NULL)
20696 {
20697 error (_("Input file '%s' is not readable.\n"), member_file_name);
20698 free (member_file_name);
fd486f32 20699 free (qualified_name);
1cb7d8b1
AM
20700 ret = FALSE;
20701 break;
20702 }
2cf0635d 20703
978c4450 20704 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 20705 member_filedata->file_name = qualified_name;
2cf0635d 20706
1cb7d8b1 20707 if (! process_object (member_filedata))
32ec8896 20708 ret = FALSE;
2cf0635d 20709
1cb7d8b1
AM
20710 close_file (member_filedata);
20711 free (member_file_name);
1cb7d8b1 20712 }
2cf0635d 20713 else if (is_thin_archive)
1cb7d8b1
AM
20714 {
20715 Filedata thin_filedata;
eb02c04d 20716
1cb7d8b1 20717 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 20718
a043396b
NC
20719 /* PR 15140: Allow for corrupt thin archives. */
20720 if (nested_arch.file == NULL)
20721 {
20722 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 20723 qualified_name, name);
fd486f32
AM
20724 free (qualified_name);
20725 free (name);
32ec8896 20726 ret = FALSE;
a043396b
NC
20727 break;
20728 }
fd486f32 20729 free (name);
a043396b 20730
1cb7d8b1 20731 /* This is a proxy for a member of a nested archive. */
978c4450
AM
20732 filedata->archive_file_offset
20733 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 20734
1cb7d8b1
AM
20735 /* The nested archive file will have been opened and setup by
20736 get_archive_member_name. */
978c4450
AM
20737 if (fseek (nested_arch.file, filedata->archive_file_offset,
20738 SEEK_SET) != 0)
1cb7d8b1
AM
20739 {
20740 error (_("%s: failed to seek to archive member.\n"),
20741 nested_arch.file_name);
fd486f32 20742 free (qualified_name);
1cb7d8b1
AM
20743 ret = FALSE;
20744 break;
20745 }
2cf0635d 20746
dda8d76d
NC
20747 thin_filedata.handle = nested_arch.file;
20748 thin_filedata.file_name = qualified_name;
9abca702 20749
1cb7d8b1 20750 if (! process_object (& thin_filedata))
32ec8896 20751 ret = FALSE;
1cb7d8b1 20752 }
2cf0635d 20753 else
1cb7d8b1 20754 {
fd486f32 20755 free (name);
978c4450 20756 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 20757 filedata->file_name = qualified_name;
1cb7d8b1 20758 if (! process_object (filedata))
32ec8896 20759 ret = FALSE;
978c4450 20760 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 20761 /* Stop looping with "negative" archive_file_size. */
978c4450 20762 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 20763 arch.next_arhdr_offset = -1ul;
1cb7d8b1 20764 }
fb52b2f4 20765
2cf0635d 20766 free (qualified_name);
fb52b2f4
NC
20767 }
20768
4145f1d5 20769 out:
2cf0635d
NC
20770 if (nested_arch.file != NULL)
20771 fclose (nested_arch.file);
20772 release_archive (&nested_arch);
20773 release_archive (&arch);
fb52b2f4 20774
d989285c 20775 return ret;
fb52b2f4
NC
20776}
20777
32ec8896 20778static bfd_boolean
2cf0635d 20779process_file (char * file_name)
fb52b2f4 20780{
dda8d76d 20781 Filedata * filedata = NULL;
fb52b2f4
NC
20782 struct stat statbuf;
20783 char armag[SARMAG];
32ec8896 20784 bfd_boolean ret = TRUE;
fb52b2f4
NC
20785
20786 if (stat (file_name, &statbuf) < 0)
20787 {
f24ddbdd
NC
20788 if (errno == ENOENT)
20789 error (_("'%s': No such file\n"), file_name);
20790 else
20791 error (_("Could not locate '%s'. System error message: %s\n"),
20792 file_name, strerror (errno));
32ec8896 20793 return FALSE;
f24ddbdd
NC
20794 }
20795
20796 if (! S_ISREG (statbuf.st_mode))
20797 {
20798 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 20799 return FALSE;
fb52b2f4
NC
20800 }
20801
dda8d76d
NC
20802 filedata = calloc (1, sizeof * filedata);
20803 if (filedata == NULL)
20804 {
20805 error (_("Out of memory allocating file data structure\n"));
20806 return FALSE;
20807 }
20808
20809 filedata->file_name = file_name;
20810 filedata->handle = fopen (file_name, "rb");
20811 if (filedata->handle == NULL)
fb52b2f4 20812 {
f24ddbdd 20813 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 20814 free (filedata);
32ec8896 20815 return FALSE;
fb52b2f4
NC
20816 }
20817
dda8d76d 20818 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 20819 {
4145f1d5 20820 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
20821 fclose (filedata->handle);
20822 free (filedata);
32ec8896 20823 return FALSE;
fb52b2f4
NC
20824 }
20825
dda8d76d 20826 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 20827
fb52b2f4 20828 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 20829 {
dda8d76d 20830 if (! process_archive (filedata, FALSE))
32ec8896
NC
20831 ret = FALSE;
20832 }
2cf0635d 20833 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 20834 {
dda8d76d 20835 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
20836 ret = FALSE;
20837 }
fb52b2f4
NC
20838 else
20839 {
1b513401 20840 if (do_archive_index && !check_all)
4145f1d5
NC
20841 error (_("File %s is not an archive so its index cannot be displayed.\n"),
20842 file_name);
20843
dda8d76d 20844 rewind (filedata->handle);
978c4450 20845 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 20846
dda8d76d 20847 if (! process_object (filedata))
32ec8896 20848 ret = FALSE;
fb52b2f4
NC
20849 }
20850
dda8d76d 20851 fclose (filedata->handle);
8fb879cd
AM
20852 free (filedata->section_headers);
20853 free (filedata->program_headers);
20854 free (filedata->string_table);
6431e409 20855 free (filedata->dump.dump_sects);
dda8d76d 20856 free (filedata);
32ec8896 20857
fd486f32 20858 free (ba_cache.strtab);
1bd6175a 20859 ba_cache.strtab = NULL;
fd486f32 20860 free (ba_cache.symtab);
1bd6175a 20861 ba_cache.symtab = NULL;
fd486f32
AM
20862 ba_cache.filedata = NULL;
20863
fb52b2f4
NC
20864 return ret;
20865}
20866
252b5132
RH
20867#ifdef SUPPORT_DISASSEMBLY
20868/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 20869 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 20870 symbols. */
252b5132
RH
20871
20872void
2cf0635d 20873print_address (unsigned int addr, FILE * outfile)
252b5132
RH
20874{
20875 fprintf (outfile,"0x%8.8x", addr);
20876}
20877
e3c8793a 20878/* Needed by the i386 disassembler. */
dda8d76d 20879
252b5132
RH
20880void
20881db_task_printsym (unsigned int addr)
20882{
20883 print_address (addr, stderr);
20884}
20885#endif
20886
20887int
2cf0635d 20888main (int argc, char ** argv)
252b5132 20889{
ff78d6d6
L
20890 int err;
20891
252b5132
RH
20892#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
20893 setlocale (LC_MESSAGES, "");
3882b010
L
20894#endif
20895#if defined (HAVE_SETLOCALE)
20896 setlocale (LC_CTYPE, "");
252b5132
RH
20897#endif
20898 bindtextdomain (PACKAGE, LOCALEDIR);
20899 textdomain (PACKAGE);
20900
869b9d07
MM
20901 expandargv (&argc, &argv);
20902
dda8d76d 20903 parse_args (& cmdline, argc, argv);
59f14fc0 20904
18bd398b 20905 if (optind < (argc - 1))
1b513401
NC
20906 /* When displaying information for more than one file,
20907 prefix the information with the file name. */
32ec8896 20908 show_name = TRUE;
5656ba2c
L
20909 else if (optind >= argc)
20910 {
1b513401
NC
20911 /* Ensure that the warning is always displayed. */
20912 do_checks = TRUE;
20913
5656ba2c
L
20914 warn (_("Nothing to do.\n"));
20915 usage (stderr);
20916 }
18bd398b 20917
32ec8896 20918 err = FALSE;
252b5132 20919 while (optind < argc)
32ec8896
NC
20920 if (! process_file (argv[optind++]))
20921 err = TRUE;
252b5132 20922
9db70fc3 20923 free (cmdline.dump_sects);
252b5132 20924
7d9813f1
NA
20925 free (dump_ctf_symtab_name);
20926 free (dump_ctf_strtab_name);
20927 free (dump_ctf_parent_name);
20928
32ec8896 20929 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 20930}
This page took 3.292867 seconds and 4 git commands to generate.