Automatic date update in version.in
[binutils-gdb.git] / binutils / readelf.c
blob6e3ac1baf6d01f6ea683788fb18c028da1c4ed29
1 /* readelf.c -- display contents of an ELF format file
2 Copyright (C) 1998-2024 Free Software Foundation, Inc.
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
5 Modifications by Nick Clifton <nickc@redhat.com>
7 This file is part of GNU Binutils.
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
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
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.
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
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
24 /* The difference between readelf and objdump:
26 Both programs are capable of displaying the contents of ELF format files,
27 so why does the binutils project have two file dumpers ?
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.
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.
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. */
43 #include "sysdep.h"
44 #include <assert.h>
45 #include <time.h>
46 #include <zlib.h>
47 #ifdef HAVE_ZSTD
48 #include <zstd.h>
49 #endif
50 #include <wchar.h>
52 #if defined HAVE_MSGPACK
53 #include <msgpack.h>
54 #endif
56 /* Define BFD64 here, even if our default architecture is 32 bit ELF
57 as this will allow us to read in and parse 64bit and 32bit ELF files. */
58 #define BFD64
60 #include "bfd.h"
61 #include "bucomm.h"
62 #include "elfcomm.h"
63 #include "demanguse.h"
64 #include "dwarf.h"
65 #include "ctf-api.h"
66 #include "sframe-api.h"
67 #include "demangle.h"
69 #include "elf/common.h"
70 #include "elf/external.h"
71 #include "elf/internal.h"
74 /* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
75 we can obtain the H8 reloc numbers. We need these for the
76 get_reloc_size() function. We include h8.h again after defining
77 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
79 #include "elf/h8.h"
80 #undef _ELF_H8_H
82 /* Undo the effects of #including reloc-macros.h. */
84 #undef START_RELOC_NUMBERS
85 #undef RELOC_NUMBER
86 #undef FAKE_RELOC
87 #undef EMPTY_RELOC
88 #undef END_RELOC_NUMBERS
89 #undef _RELOC_MACROS_H
91 /* The following headers use the elf/reloc-macros.h file to
92 automatically generate relocation recognition functions
93 such as elf_mips_reloc_type() */
95 #define RELOC_MACROS_GEN_FUNC
97 #include "elf/aarch64.h"
98 #include "elf/alpha.h"
99 #include "elf/amdgpu.h"
100 #include "elf/arc.h"
101 #include "elf/arm.h"
102 #include "elf/avr.h"
103 #include "elf/bfin.h"
104 #include "elf/cr16.h"
105 #include "elf/cris.h"
106 #include "elf/crx.h"
107 #include "elf/csky.h"
108 #include "elf/d10v.h"
109 #include "elf/d30v.h"
110 #include "elf/dlx.h"
111 #include "elf/bpf.h"
112 #include "elf/epiphany.h"
113 #include "elf/fr30.h"
114 #include "elf/frv.h"
115 #include "elf/ft32.h"
116 #include "elf/h8.h"
117 #include "elf/hppa.h"
118 #include "elf/i386.h"
119 #include "elf/i370.h"
120 #include "elf/i860.h"
121 #include "elf/i960.h"
122 #include "elf/ia64.h"
123 #include "elf/ip2k.h"
124 #include "elf/kvx.h"
125 #include "elf/lm32.h"
126 #include "elf/iq2000.h"
127 #include "elf/m32c.h"
128 #include "elf/m32r.h"
129 #include "elf/m68k.h"
130 #include "elf/m68hc11.h"
131 #include "elf/s12z.h"
132 #include "elf/mcore.h"
133 #include "elf/mep.h"
134 #include "elf/metag.h"
135 #include "elf/microblaze.h"
136 #include "elf/mips.h"
137 #include "elf/mmix.h"
138 #include "elf/mn10200.h"
139 #include "elf/mn10300.h"
140 #include "elf/moxie.h"
141 #include "elf/mt.h"
142 #include "elf/msp430.h"
143 #include "elf/nds32.h"
144 #include "elf/nfp.h"
145 #include "elf/nios2.h"
146 #include "elf/or1k.h"
147 #include "elf/pj.h"
148 #include "elf/ppc.h"
149 #include "elf/ppc64.h"
150 #include "elf/pru.h"
151 #include "elf/riscv.h"
152 #include "elf/rl78.h"
153 #include "elf/rx.h"
154 #include "elf/s390.h"
155 #include "elf/score.h"
156 #include "elf/sh.h"
157 #include "elf/sparc.h"
158 #include "elf/spu.h"
159 #include "elf/tic6x.h"
160 #include "elf/tilegx.h"
161 #include "elf/tilepro.h"
162 #include "elf/v850.h"
163 #include "elf/vax.h"
164 #include "elf/visium.h"
165 #include "elf/wasm32.h"
166 #include "elf/x86-64.h"
167 #include "elf/xgate.h"
168 #include "elf/xstormy16.h"
169 #include "elf/xtensa.h"
170 #include "elf/z80.h"
171 #include "elf/loongarch.h"
172 #include "elf/bpf.h"
174 #include "getopt.h"
175 #include "libiberty.h"
176 #include "safe-ctype.h"
177 #include "filenames.h"
179 #ifndef offsetof
180 #define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
181 #endif
183 typedef struct elf_section_list
185 Elf_Internal_Shdr * hdr;
186 struct elf_section_list * next;
187 } elf_section_list;
189 /* Flag bits indicating particular types of dump. */
190 #define HEX_DUMP (1 << 0) /* The -x command line switch. */
191 #define DISASS_DUMP (1 << 1) /* The -i command line switch. */
192 #define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
193 #define STRING_DUMP (1 << 3) /* The -p command line switch. */
194 #define RELOC_DUMP (1 << 4) /* The -R command line switch. */
195 #define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
196 #define SFRAME_DUMP (1 << 6) /* The --sframe command line switch. */
198 typedef unsigned char dump_type;
200 /* A linked list of the section names for which dumps were requested. */
201 struct dump_list_entry
203 char * name;
204 dump_type type;
205 struct dump_list_entry * next;
208 /* A dynamic array of flags indicating for which sections a dump
209 has been requested via command line switches. */
210 struct dump_data
212 dump_type * dump_sects;
213 unsigned int num_dump_sects;
216 static struct dump_data cmdline;
218 static struct dump_list_entry * dump_sects_byname;
220 char * program_name = "readelf";
222 static bool show_name = false;
223 static bool do_dynamic = false;
224 static bool do_syms = false;
225 static bool do_dyn_syms = false;
226 static bool do_lto_syms = false;
227 static bool do_reloc = false;
228 static bool do_sections = false;
229 static bool do_section_groups = false;
230 static bool do_section_details = false;
231 static bool do_segments = false;
232 static bool do_unwind = false;
233 static bool do_using_dynamic = false;
234 static bool do_header = false;
235 static bool do_dump = false;
236 static bool do_version = false;
237 static bool do_histogram = false;
238 static bool do_debugging = false;
239 static bool do_ctf = false;
240 static bool do_sframe = false;
241 static bool do_arch = false;
242 static bool do_notes = false;
243 static bool do_archive_index = false;
244 static bool check_all = false;
245 static bool is_32bit_elf = false;
246 static bool decompress_dumps = false;
247 static bool do_not_show_symbol_truncation = false;
248 static bool do_demangle = false; /* Pretty print C++ symbol names. */
249 static bool process_links = false;
250 static bool dump_any_debugging = false;
251 static bool extra_sym_info = false;
252 static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
253 static int sym_base = 0;
255 static char *dump_ctf_parent_name;
256 static char *dump_ctf_symtab_name;
257 static char *dump_ctf_strtab_name;
259 struct group_list
261 struct group_list * next;
262 unsigned int section_index;
265 struct group
267 struct group_list * root;
268 unsigned int group_index;
271 typedef struct filedata
273 const char * file_name;
274 bool is_separate;
275 FILE * handle;
276 uint64_t file_size;
277 Elf_Internal_Ehdr file_header;
278 uint64_t archive_file_offset;
279 uint64_t archive_file_size;
280 /* Everything below this point is cleared out by free_filedata. */
281 Elf_Internal_Shdr * section_headers;
282 Elf_Internal_Phdr * program_headers;
283 char * string_table;
284 uint64_t string_table_length;
285 uint64_t dynamic_addr;
286 uint64_t dynamic_size;
287 uint64_t dynamic_nent;
288 Elf_Internal_Dyn * dynamic_section;
289 Elf_Internal_Shdr * dynamic_strtab_section;
290 char * dynamic_strings;
291 uint64_t dynamic_strings_length;
292 Elf_Internal_Shdr * dynamic_symtab_section;
293 uint64_t num_dynamic_syms;
294 Elf_Internal_Sym * dynamic_symbols;
295 uint64_t version_info[16];
296 unsigned int dynamic_syminfo_nent;
297 Elf_Internal_Syminfo * dynamic_syminfo;
298 uint64_t dynamic_syminfo_offset;
299 uint64_t nbuckets;
300 uint64_t nchains;
301 uint64_t * buckets;
302 uint64_t * chains;
303 uint64_t ngnubuckets;
304 uint64_t ngnuchains;
305 uint64_t * gnubuckets;
306 uint64_t * gnuchains;
307 uint64_t * mipsxlat;
308 uint64_t gnusymidx;
309 char * program_interpreter;
310 uint64_t dynamic_info[DT_RELRENT + 1];
311 uint64_t dynamic_info_DT_GNU_HASH;
312 uint64_t dynamic_info_DT_MIPS_XHASH;
313 elf_section_list * symtab_shndx_list;
314 size_t group_count;
315 struct group * section_groups;
316 struct group ** section_headers_groups;
317 /* A dynamic array of flags indicating for which sections a dump of
318 some kind has been requested. It is reset on a per-object file
319 basis and then initialised from the cmdline_dump_sects array,
320 the results of interpreting the -w switch, and the
321 dump_sects_byname list. */
322 struct dump_data dump;
323 } Filedata;
325 /* How to print a vma value. */
326 typedef enum print_mode
328 HEX,
329 HEX_5,
330 DEC,
331 DEC_5,
332 UNSIGNED,
333 UNSIGNED_5,
334 PREFIX_HEX,
335 PREFIX_HEX_5,
336 FULL_HEX,
337 LONG_HEX,
338 OCTAL,
339 OCTAL_5
341 print_mode;
343 typedef enum unicode_display_type
345 unicode_default = 0,
346 unicode_locale,
347 unicode_escape,
348 unicode_hex,
349 unicode_highlight,
350 unicode_invalid
351 } unicode_display_type;
353 static unicode_display_type unicode_display = unicode_default;
355 typedef enum
357 reltype_unknown,
358 reltype_rel,
359 reltype_rela,
360 reltype_relr
361 } relocation_type;
363 /* Versioned symbol info. */
364 enum versioned_symbol_info
366 symbol_undefined,
367 symbol_hidden,
368 symbol_public
371 static int
372 fseek64 (FILE *stream, int64_t offset, int whence)
374 #if defined (HAVE_FSEEKO64)
375 off64_t o = offset;
376 if (o != offset)
378 errno = EINVAL;
379 return -1;
381 return fseeko64 (stream, o, whence);
382 #elif defined (HAVE_FSEEKO)
383 off_t o = offset;
384 if (o != offset)
386 errno = EINVAL;
387 return -1;
389 return fseeko (stream, o, whence);
390 #else
391 long o = offset;
392 if (o != offset)
394 errno = EINVAL;
395 return -1;
397 return fseek (stream, o, whence);
398 #endif
401 static const char * get_symbol_version_string
402 (Filedata *, bool, const char *, size_t, unsigned,
403 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
405 #define UNKNOWN -1
407 static inline const char *
408 section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
410 return filedata->string_table + hdr->sh_name;
413 static inline bool
414 section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
416 return (filedata != NULL
417 && hdr != NULL
418 && filedata->string_table != NULL
419 && hdr->sh_name < filedata->string_table_length);
422 /* Returns true if the given index is real/valid. Note: "real" here
423 means "references a real section in the section header" and not
424 "is a valid section index as per the ELF standard". */
426 static inline bool
427 section_index_real (const Filedata *filedata, unsigned int ndx)
429 return (filedata != NULL
430 && filedata->section_headers != NULL
431 && ndx < filedata->file_header.e_shnum
432 && ndx > 0);
435 #define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
437 static inline bool
438 valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
440 return strtab != NULL && offset < strtab_size;
443 static inline bool
444 valid_dynamic_name (const Filedata *filedata, uint64_t offset)
446 return valid_symbol_name (filedata->dynamic_strings,
447 filedata->dynamic_strings_length, offset);
450 /* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
451 already been called and verified that the string exists. */
452 static inline const char *
453 get_dynamic_name (const Filedata *filedata, size_t offset)
455 return filedata->dynamic_strings + offset;
458 #define REMOVE_ARCH_BITS(ADDR) \
459 do \
461 if (filedata->file_header.e_machine == EM_ARM) \
462 (ADDR) &= ~1; \
464 while (0)
466 /* Get the correct GNU hash section name. */
467 #define GNU_HASH_SECTION_NAME(filedata) \
468 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
470 /* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
471 OFFSET + the offset of the current archive member, if we are examining an
472 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
473 allocate a buffer using malloc and fill that. In either case return the
474 pointer to the start of the retrieved data or NULL if something went wrong.
475 If something does go wrong and REASON is not NULL then emit an error
476 message using REASON as part of the context. */
478 static void *
479 get_data (void *var,
480 Filedata *filedata,
481 uint64_t offset,
482 uint64_t size,
483 uint64_t nmemb,
484 const char *reason)
486 void * mvar;
487 uint64_t amt = size * nmemb;
489 if (size == 0 || nmemb == 0)
490 return NULL;
492 /* If size_t is smaller than uint64_t, eg because you are building
493 on a 32-bit host, then make sure that when the sizes are cast to
494 size_t no information is lost. */
495 if ((size_t) size != size
496 || (size_t) nmemb != nmemb
497 || (size_t) amt != amt
498 || amt / size != nmemb
499 || (size_t) amt + 1 == 0)
501 if (reason)
502 error (_("Size overflow prevents reading %" PRIu64
503 " elements of size %" PRIu64 " for %s\n"),
504 nmemb, size, reason);
505 return NULL;
508 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
509 attempting to allocate memory when the read is bound to fail. */
510 if (filedata->archive_file_offset > filedata->file_size
511 || offset > filedata->file_size - filedata->archive_file_offset
512 || amt > filedata->file_size - filedata->archive_file_offset - offset)
514 if (reason)
515 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
516 amt, reason);
517 return NULL;
520 if (fseek64 (filedata->handle, filedata->archive_file_offset + offset,
521 SEEK_SET))
523 if (reason)
524 error (_("Unable to seek to %#" PRIx64 " for %s\n"),
525 filedata->archive_file_offset + offset, reason);
526 return NULL;
529 mvar = var;
530 if (mvar == NULL)
532 /* + 1 so that we can '\0' terminate invalid string table sections. */
533 mvar = malloc ((size_t) amt + 1);
535 if (mvar == NULL)
537 if (reason)
538 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
539 amt, reason);
540 return NULL;
543 ((char *) mvar)[amt] = '\0';
546 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
548 if (reason)
549 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
550 amt, reason);
551 if (mvar != var)
552 free (mvar);
553 return NULL;
556 return mvar;
559 /* Print a VMA value in the MODE specified.
560 Returns the number of characters displayed. */
562 static unsigned int
563 print_vma (uint64_t vma, print_mode mode)
565 unsigned int nc = 0;
567 switch (mode)
569 case FULL_HEX:
570 nc = printf ("0x");
571 /* Fall through. */
572 case LONG_HEX:
573 if (!is_32bit_elf)
574 return nc + printf ("%16.16" PRIx64, vma);
575 return nc + printf ("%8.8" PRIx64, vma);
577 case DEC_5:
578 if (vma <= 99999)
579 return printf ("%5" PRId64, vma);
580 /* Fall through. */
581 case PREFIX_HEX:
582 nc = printf ("0x");
583 /* Fall through. */
584 case HEX:
585 return nc + printf ("%" PRIx64, vma);
587 case PREFIX_HEX_5:
588 nc = printf ("0x");
589 /* Fall through. */
590 case HEX_5:
591 return nc + printf ("%05" PRIx64, vma);
593 case DEC:
594 return printf ("%" PRId64, vma);
596 case UNSIGNED:
597 return printf ("%" PRIu64, vma);
599 case UNSIGNED_5:
600 return printf ("%5" PRIu64, vma);
602 case OCTAL:
603 return printf ("%" PRIo64, vma);
605 case OCTAL_5:
606 return printf ("%5" PRIo64, vma);
608 default:
609 /* FIXME: Report unrecognised mode ? */
610 return 0;
615 /* Display a symbol on stdout. Handles the display of control characters and
616 multibye characters (assuming the host environment supports them).
618 Display at most abs(WIDTH) characters, truncating as necessary,
619 unless do_wide or extra_sym_info is true.
621 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
622 abs(WIDTH) - 5 characters followed by "[...]".
624 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
625 padding as necessary.
627 Returns the number of emitted characters. */
629 static unsigned int
630 print_symbol_name (signed int width, const char * symbol)
632 bool extra_padding = false;
633 bool do_dots = false;
634 signed int num_printed = 0;
635 #ifdef HAVE_MBSTATE_T
636 mbstate_t state;
637 #endif
638 unsigned int width_remaining;
639 const void * alloced_symbol = NULL;
641 if (width < 0)
643 /* Keep the width positive. This helps the code below. */
644 width = - width;
645 extra_padding = true;
647 else if (width == 0)
648 return 0;
650 if (do_wide || extra_sym_info)
651 /* Set the remaining width to a very large value.
652 This simplifies the code below. */
653 width_remaining = INT_MAX;
654 else
656 width_remaining = width;
658 if (! do_not_show_symbol_truncation
659 && (int) strlen (symbol) > width)
661 width_remaining -= 5;
662 if ((int) width_remaining < 0)
663 width_remaining = 0;
664 do_dots = true;
668 #ifdef HAVE_MBSTATE_T
669 /* Initialise the multibyte conversion state. */
670 memset (& state, 0, sizeof (state));
671 #endif
673 if (do_demangle && *symbol)
675 const char * res = cplus_demangle (symbol, demangle_flags);
677 if (res != NULL)
678 alloced_symbol = symbol = res;
681 while (width_remaining)
683 size_t n;
684 const char c = *symbol++;
686 if (c == 0)
687 break;
689 if (ISPRINT (c))
691 putchar (c);
692 width_remaining --;
693 num_printed ++;
695 else if (ISCNTRL (c))
697 /* Do not print control characters directly as they can affect terminal
698 settings. Such characters usually appear in the names generated
699 by the assembler for local labels. */
701 if (width_remaining < 2)
702 break;
704 printf ("^%c", c + 0x40);
705 width_remaining -= 2;
706 num_printed += 2;
708 else if (c == 0x7f)
710 if (width_remaining < 5)
711 break;
712 printf ("<DEL>");
713 width_remaining -= 5;
714 num_printed += 5;
716 else if (unicode_display != unicode_locale
717 && unicode_display != unicode_default)
719 /* Display unicode characters as something else. */
720 unsigned char bytes[4];
721 bool is_utf8;
722 unsigned int nbytes;
724 bytes[0] = c;
726 if (bytes[0] < 0xc0)
728 nbytes = 1;
729 is_utf8 = false;
731 else
733 bytes[1] = *symbol++;
735 if ((bytes[1] & 0xc0) != 0x80)
737 is_utf8 = false;
738 /* Do not consume this character. It may only
739 be the first byte in the sequence that was
740 corrupt. */
741 --symbol;
742 nbytes = 1;
744 else if ((bytes[0] & 0x20) == 0)
746 is_utf8 = true;
747 nbytes = 2;
749 else
751 bytes[2] = *symbol++;
753 if ((bytes[2] & 0xc0) != 0x80)
755 is_utf8 = false;
756 symbol -= 2;
757 nbytes = 1;
759 else if ((bytes[0] & 0x10) == 0)
761 is_utf8 = true;
762 nbytes = 3;
764 else
766 bytes[3] = *symbol++;
768 nbytes = 4;
770 if ((bytes[3] & 0xc0) != 0x80)
772 is_utf8 = false;
773 symbol -= 3;
774 nbytes = 1;
776 else
777 is_utf8 = true;
782 if (unicode_display == unicode_invalid)
783 is_utf8 = false;
785 if (unicode_display == unicode_hex || ! is_utf8)
787 unsigned int i;
789 if (width_remaining < (nbytes * 2) + 2)
790 break;
792 putchar (is_utf8 ? '<' : '{');
793 printf ("0x");
794 for (i = 0; i < nbytes; i++)
795 printf ("%02x", bytes[i]);
796 putchar (is_utf8 ? '>' : '}');
798 else
800 if (unicode_display == unicode_highlight && isatty (1))
801 printf ("\x1B[31;47m"); /* Red. */
803 switch (nbytes)
805 case 2:
806 if (width_remaining < 6)
807 break;
808 printf ("\\u%02x%02x",
809 (bytes[0] & 0x1c) >> 2,
810 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
811 break;
812 case 3:
813 if (width_remaining < 6)
814 break;
815 printf ("\\u%02x%02x",
816 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
817 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
818 break;
819 case 4:
820 if (width_remaining < 8)
821 break;
822 printf ("\\u%02x%02x%02x",
823 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
824 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
825 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
827 break;
828 default:
829 /* URG. */
830 break;
833 if (unicode_display == unicode_highlight && isatty (1))
834 printf ("\033[0m"); /* Default colour. */
837 if (bytes[nbytes - 1] == 0)
838 break;
840 else
842 #ifdef HAVE_MBSTATE_T
843 wchar_t w;
844 #endif
845 /* Let printf do the hard work of displaying multibyte characters. */
846 printf ("%.1s", symbol - 1);
847 width_remaining --;
848 num_printed ++;
850 #ifdef HAVE_MBSTATE_T
851 /* Try to find out how many bytes made up the character that was
852 just printed. Advance the symbol pointer past the bytes that
853 were displayed. */
854 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
855 #else
856 n = 1;
857 #endif
858 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
859 symbol += (n - 1);
863 if (do_dots)
864 num_printed += printf ("[...]");
866 if (extra_padding && num_printed < width)
868 /* Fill in the remaining spaces. */
869 printf ("%-*s", width - num_printed, " ");
870 num_printed = width;
873 free ((void *) alloced_symbol);
874 return num_printed;
877 /* Returns a pointer to a static buffer containing a printable version of
878 the given section's name. Like print_symbol, except that it does not try
879 to print multibyte characters, it just interprets them as hex values. */
881 static const char *
882 printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
884 #define NUM_SEC_NAME_BUFS 5
885 #define MAX_PRINT_SEC_NAME_LEN 256
887 static int sec_name_buf_index = 0;
888 /* We use a rotating array of static buffers, so that multiple successive calls
889 to printable_section_name() will still work. eg when used in a printf. */
890 static char sec_name_buf [NUM_SEC_NAME_BUFS][MAX_PRINT_SEC_NAME_LEN + 1];
892 const char * name;
893 char * buf;
894 char * buf_start;
895 char c;
896 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
898 /* Validate the input parameters. */
899 if (filedata == NULL)
900 return _("<internal error>");
901 if (sec == NULL)
902 return _("<none>");
903 if (filedata->string_table == NULL)
904 return _("<no-strings>");
905 if (sec->sh_name >= filedata->string_table_length)
906 return _("<corrupt>");
908 /* Select a buffer to use. */
909 buf_start = buf = sec_name_buf[sec_name_buf_index];
910 if (++sec_name_buf_index >= NUM_SEC_NAME_BUFS)
911 sec_name_buf_index = 0;
913 name = section_name (filedata, sec);
915 while ((c = * name ++) != 0)
917 if (ISCNTRL (c))
919 if (remaining < 2)
920 break;
922 * buf ++ = '^';
923 * buf ++ = c + 0x40;
924 remaining -= 2;
926 else if (ISPRINT (c))
928 * buf ++ = c;
929 remaining -= 1;
931 else
933 static char hex[17] = "0123456789ABCDEF";
935 if (remaining < 4)
936 break;
937 * buf ++ = '<';
938 * buf ++ = hex[(c & 0xf0) >> 4];
939 * buf ++ = hex[c & 0x0f];
940 * buf ++ = '>';
941 remaining -= 4;
944 if (remaining == 0)
945 break;
948 * buf = 0;
949 return buf_start;
952 /* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
953 This OS has so many departures from the ELF standard that we test it at
954 many places. */
956 static inline bool
957 is_ia64_vms (Filedata * filedata)
959 return filedata->file_header.e_machine == EM_IA_64
960 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
963 static const char *
964 printable_section_name_from_index (Filedata * filedata,
965 size_t ndx,
966 bool * is_special)
968 if (is_special != NULL)
969 * is_special = true;
971 switch (ndx)
973 case SHN_UNDEF: return "UND";
974 case SHN_ABS: return "ABS";
975 case SHN_COMMON: return "COM";
976 break;
979 if (filedata != NULL)
981 switch (filedata->file_header.e_machine)
983 case EM_MIPS:
984 if (ndx == SHN_MIPS_SCOMMON)
985 return "SCOMMON";
986 if (ndx == SHN_MIPS_SUNDEFINED)
987 return "SUNDEF";
988 break;
990 case EM_TI_C6000:
991 if (ndx == SHN_TIC6X_SCOMMON)
992 return "SCOM";
993 break;
995 case EM_X86_64:
996 case EM_L1OM:
997 case EM_K1OM:
998 if (ndx == SHN_X86_64_LCOMMON)
999 return "LARGE_COM";
1000 break;
1002 case EM_IA_64:
1003 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1004 && ndx == SHN_IA_64_ANSI_COMMON)
1005 return "ANSI_COM";
1007 if (is_ia64_vms (filedata) && ndx == SHN_IA_64_VMS_SYMVEC)
1008 return "VMS_SYMVEC";
1009 break;
1011 default:
1012 break;
1015 if (filedata->section_headers != NULL
1016 && ndx < filedata->file_header.e_shnum)
1018 const char * res;
1020 res = printable_section_name (filedata, filedata->section_headers + ndx);
1021 if (is_special != NULL)
1022 * is_special = (res[0] == '<');
1024 return res;
1028 static char name_buf[40];
1029 unsigned int short_ndx = (unsigned int) (ndx & 0xffff);
1031 if (ndx >= SHN_LOPROC && ndx <= SHN_HIPROC)
1032 sprintf (name_buf, "PRC[0x%04x]", short_ndx);
1033 else if (ndx >= SHN_LOOS && ndx <= SHN_HIOS)
1034 sprintf (name_buf, "OS [0x%04x]", short_ndx);
1035 else if (ndx >= SHN_LORESERVE)
1036 sprintf (name_buf, "RSV[0x%04x]", short_ndx);
1037 else if (filedata->file_header.e_shnum != 0
1038 && ndx >= filedata->file_header.e_shnum)
1039 sprintf (name_buf, _("BAD[0x%lx]"), (long) ndx);
1040 else
1041 sprintf (name_buf, "<section 0x%lx>", (long) ndx);
1043 return name_buf;
1046 /* Return a pointer to section NAME, or NULL if no such section exists. */
1048 static Elf_Internal_Shdr *
1049 find_section (Filedata * filedata, const char * name)
1051 unsigned int i;
1053 if (filedata->section_headers == NULL)
1054 return NULL;
1056 for (i = 0; i < filedata->file_header.e_shnum; i++)
1057 if (section_name_valid (filedata, filedata->section_headers + i)
1058 && streq (section_name (filedata, filedata->section_headers + i),
1059 name))
1060 return filedata->section_headers + i;
1062 return NULL;
1065 /* Return a pointer to a section containing ADDR, or NULL if no such
1066 section exists. */
1068 static Elf_Internal_Shdr *
1069 find_section_by_address (Filedata * filedata, uint64_t addr)
1071 unsigned int i;
1073 if (filedata->section_headers == NULL)
1074 return NULL;
1076 for (i = 0; i < filedata->file_header.e_shnum; i++)
1078 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1080 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
1081 return sec;
1084 return NULL;
1087 static Elf_Internal_Shdr *
1088 find_section_by_type (Filedata * filedata, unsigned int type)
1090 unsigned int i;
1092 if (filedata->section_headers == NULL)
1093 return NULL;
1095 for (i = 0; i < filedata->file_header.e_shnum; i++)
1097 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1099 if (sec->sh_type == type)
1100 return sec;
1103 return NULL;
1106 /* Return a pointer to section NAME, or NULL if no such section exists,
1107 restricted to the list of sections given in SET. */
1109 static Elf_Internal_Shdr *
1110 find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
1112 unsigned int i;
1114 if (filedata->section_headers == NULL)
1115 return NULL;
1117 if (set != NULL)
1119 while ((i = *set++) > 0)
1121 /* See PR 21156 for a reproducer. */
1122 if (i >= filedata->file_header.e_shnum)
1123 continue; /* FIXME: Should we issue an error message ? */
1125 if (section_name_valid (filedata, filedata->section_headers + i)
1126 && streq (section_name (filedata, filedata->section_headers + i),
1127 name))
1128 return filedata->section_headers + i;
1132 return find_section (filedata, name);
1135 /* Guess the relocation size commonly used by the specific machines. */
1137 static bool
1138 guess_is_rela (unsigned int e_machine)
1140 switch (e_machine)
1142 /* Targets that use REL relocations. */
1143 case EM_386:
1144 case EM_IAMCU:
1145 case EM_960:
1146 case EM_ARM:
1147 case EM_D10V:
1148 case EM_CYGNUS_D10V:
1149 case EM_DLX:
1150 case EM_MIPS:
1151 case EM_MIPS_RS3_LE:
1152 case EM_CYGNUS_M32R:
1153 case EM_SCORE:
1154 case EM_XGATE:
1155 case EM_NFP:
1156 case EM_BPF:
1157 return false;
1159 /* Targets that use RELA relocations. */
1160 case EM_68K:
1161 case EM_860:
1162 case EM_AARCH64:
1163 case EM_ADAPTEVA_EPIPHANY:
1164 case EM_ALPHA:
1165 case EM_ALTERA_NIOS2:
1166 case EM_ARC:
1167 case EM_ARC_COMPACT:
1168 case EM_ARC_COMPACT2:
1169 case EM_ARC_COMPACT3:
1170 case EM_ARC_COMPACT3_64:
1171 case EM_AVR:
1172 case EM_AVR_OLD:
1173 case EM_BLACKFIN:
1174 case EM_CR16:
1175 case EM_CRIS:
1176 case EM_CRX:
1177 case EM_CSKY:
1178 case EM_D30V:
1179 case EM_CYGNUS_D30V:
1180 case EM_FR30:
1181 case EM_FT32:
1182 case EM_CYGNUS_FR30:
1183 case EM_CYGNUS_FRV:
1184 case EM_H8S:
1185 case EM_H8_300:
1186 case EM_H8_300H:
1187 case EM_IA_64:
1188 case EM_IP2K:
1189 case EM_IP2K_OLD:
1190 case EM_IQ2000:
1191 case EM_KVX:
1192 case EM_LATTICEMICO32:
1193 case EM_M32C_OLD:
1194 case EM_M32C:
1195 case EM_M32R:
1196 case EM_MCORE:
1197 case EM_CYGNUS_MEP:
1198 case EM_METAG:
1199 case EM_MMIX:
1200 case EM_MN10200:
1201 case EM_CYGNUS_MN10200:
1202 case EM_MN10300:
1203 case EM_CYGNUS_MN10300:
1204 case EM_MOXIE:
1205 case EM_MSP430:
1206 case EM_MSP430_OLD:
1207 case EM_MT:
1208 case EM_NDS32:
1209 case EM_NIOS32:
1210 case EM_OR1K:
1211 case EM_PPC64:
1212 case EM_PPC:
1213 case EM_TI_PRU:
1214 case EM_RISCV:
1215 case EM_RL78:
1216 case EM_RX:
1217 case EM_S390:
1218 case EM_S390_OLD:
1219 case EM_SH:
1220 case EM_SPARC:
1221 case EM_SPARC32PLUS:
1222 case EM_SPARCV9:
1223 case EM_SPU:
1224 case EM_TI_C6000:
1225 case EM_TILEGX:
1226 case EM_TILEPRO:
1227 case EM_V800:
1228 case EM_V850:
1229 case EM_CYGNUS_V850:
1230 case EM_VAX:
1231 case EM_VISIUM:
1232 case EM_X86_64:
1233 case EM_L1OM:
1234 case EM_K1OM:
1235 case EM_XSTORMY16:
1236 case EM_XTENSA:
1237 case EM_XTENSA_OLD:
1238 case EM_MICROBLAZE:
1239 case EM_MICROBLAZE_OLD:
1240 case EM_WEBASSEMBLY:
1241 return true;
1243 case EM_68HC05:
1244 case EM_68HC08:
1245 case EM_68HC11:
1246 case EM_68HC16:
1247 case EM_FX66:
1248 case EM_ME16:
1249 case EM_MMA:
1250 case EM_NCPU:
1251 case EM_NDR1:
1252 case EM_PCP:
1253 case EM_ST100:
1254 case EM_ST19:
1255 case EM_ST7:
1256 case EM_ST9PLUS:
1257 case EM_STARCORE:
1258 case EM_SVX:
1259 case EM_TINYJ:
1260 default:
1261 warn (_("Don't know about relocations on this machine architecture\n"));
1262 return false;
1266 /* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
1267 Returns TRUE upon success, FALSE otherwise. If successful then a
1268 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1269 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1270 responsibility to free the allocated buffer. */
1272 static bool
1273 slurp_rela_relocs (Filedata *filedata,
1274 uint64_t rel_offset,
1275 uint64_t rel_size,
1276 Elf_Internal_Rela **relasp,
1277 uint64_t *nrelasp)
1279 Elf_Internal_Rela * relas;
1280 uint64_t nrelas;
1281 unsigned int i;
1283 if (is_32bit_elf)
1285 Elf32_External_Rela * erelas;
1287 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
1288 rel_size, _("32-bit relocation data"));
1289 if (!erelas)
1290 return false;
1292 nrelas = rel_size / sizeof (Elf32_External_Rela);
1294 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1295 sizeof (Elf_Internal_Rela));
1297 if (relas == NULL)
1299 free (erelas);
1300 error (_("out of memory parsing relocs\n"));
1301 return false;
1304 for (i = 0; i < nrelas; i++)
1306 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1307 relas[i].r_info = BYTE_GET (erelas[i].r_info);
1308 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
1311 free (erelas);
1313 else
1315 Elf64_External_Rela * erelas;
1317 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
1318 rel_size, _("64-bit relocation data"));
1319 if (!erelas)
1320 return false;
1322 nrelas = rel_size / sizeof (Elf64_External_Rela);
1324 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1325 sizeof (Elf_Internal_Rela));
1327 if (relas == NULL)
1329 free (erelas);
1330 error (_("out of memory parsing relocs\n"));
1331 return false;
1334 for (i = 0; i < nrelas; i++)
1336 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1337 relas[i].r_info = BYTE_GET (erelas[i].r_info);
1338 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
1340 if (filedata->file_header.e_machine == EM_MIPS
1341 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
1343 /* In little-endian objects, r_info isn't really a
1344 64-bit little-endian value: it has a 32-bit
1345 little-endian symbol index followed by four
1346 individual byte fields. Reorder INFO
1347 accordingly. */
1348 uint64_t inf = relas[i].r_info;
1349 inf = (((inf & 0xffffffff) << 32)
1350 | ((inf >> 56) & 0xff)
1351 | ((inf >> 40) & 0xff00)
1352 | ((inf >> 24) & 0xff0000)
1353 | ((inf >> 8) & 0xff000000));
1354 relas[i].r_info = inf;
1358 free (erelas);
1361 *relasp = relas;
1362 *nrelasp = nrelas;
1363 return true;
1366 /* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
1367 Returns TRUE upon success, FALSE otherwise. If successful then a
1368 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1369 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1370 responsibility to free the allocated buffer. */
1372 static bool
1373 slurp_rel_relocs (Filedata *filedata,
1374 uint64_t rel_offset,
1375 uint64_t rel_size,
1376 Elf_Internal_Rela **relsp,
1377 uint64_t *nrelsp)
1379 Elf_Internal_Rela * rels;
1380 uint64_t nrels;
1381 unsigned int i;
1383 if (is_32bit_elf)
1385 Elf32_External_Rel * erels;
1387 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
1388 rel_size, _("32-bit relocation data"));
1389 if (!erels)
1390 return false;
1392 nrels = rel_size / sizeof (Elf32_External_Rel);
1394 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
1396 if (rels == NULL)
1398 free (erels);
1399 error (_("out of memory parsing relocs\n"));
1400 return false;
1403 for (i = 0; i < nrels; i++)
1405 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1406 rels[i].r_info = BYTE_GET (erels[i].r_info);
1407 rels[i].r_addend = 0;
1410 free (erels);
1412 else
1414 Elf64_External_Rel * erels;
1416 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
1417 rel_size, _("64-bit relocation data"));
1418 if (!erels)
1419 return false;
1421 nrels = rel_size / sizeof (Elf64_External_Rel);
1423 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
1425 if (rels == NULL)
1427 free (erels);
1428 error (_("out of memory parsing relocs\n"));
1429 return false;
1432 for (i = 0; i < nrels; i++)
1434 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1435 rels[i].r_info = BYTE_GET (erels[i].r_info);
1436 rels[i].r_addend = 0;
1438 if (filedata->file_header.e_machine == EM_MIPS
1439 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
1441 /* In little-endian objects, r_info isn't really a
1442 64-bit little-endian value: it has a 32-bit
1443 little-endian symbol index followed by four
1444 individual byte fields. Reorder INFO
1445 accordingly. */
1446 uint64_t inf = rels[i].r_info;
1447 inf = (((inf & 0xffffffff) << 32)
1448 | ((inf >> 56) & 0xff)
1449 | ((inf >> 40) & 0xff00)
1450 | ((inf >> 24) & 0xff0000)
1451 | ((inf >> 8) & 0xff000000));
1452 rels[i].r_info = inf;
1456 free (erels);
1459 *relsp = rels;
1460 *nrelsp = nrels;
1461 return true;
1464 static bool
1465 slurp_relr_relocs (Filedata *filedata,
1466 uint64_t relr_offset,
1467 uint64_t relr_size,
1468 uint64_t **relrsp,
1469 uint64_t *nrelrsp)
1471 void *relrs;
1472 size_t size = 0, nentries, i;
1473 uint64_t base = 0, addr, entry;
1475 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1476 _("RELR relocation data"));
1477 if (!relrs)
1478 return false;
1480 if (is_32bit_elf)
1481 nentries = relr_size / sizeof (Elf32_External_Relr);
1482 else
1483 nentries = relr_size / sizeof (Elf64_External_Relr);
1484 for (i = 0; i < nentries; i++)
1486 if (is_32bit_elf)
1487 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1488 else
1489 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1490 if ((entry & 1) == 0)
1491 size++;
1492 else
1493 while ((entry >>= 1) != 0)
1494 if ((entry & 1) == 1)
1495 size++;
1498 *relrsp = malloc (size * sizeof (**relrsp));
1499 if (*relrsp == NULL)
1501 free (relrs);
1502 error (_("out of memory parsing relocs\n"));
1503 return false;
1506 size = 0;
1507 for (i = 0; i < nentries; i++)
1509 const uint64_t entry_bytes = is_32bit_elf ? 4 : 8;
1511 if (is_32bit_elf)
1512 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1513 else
1514 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1515 if ((entry & 1) == 0)
1517 (*relrsp)[size++] = entry;
1518 base = entry + entry_bytes;
1520 else
1522 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1523 if ((entry & 1) != 0)
1524 (*relrsp)[size++] = addr;
1525 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1529 *nrelrsp = size;
1530 free (relrs);
1531 return true;
1534 /* Returns the reloc type extracted from the reloc info field. */
1536 static unsigned int
1537 get_reloc_type (Filedata * filedata, uint64_t reloc_info)
1539 if (is_32bit_elf)
1540 return ELF32_R_TYPE (reloc_info);
1542 switch (filedata->file_header.e_machine)
1544 case EM_MIPS:
1545 /* Note: We assume that reloc_info has already been adjusted for us. */
1546 return ELF64_MIPS_R_TYPE (reloc_info);
1548 case EM_SPARCV9:
1549 return ELF64_R_TYPE_ID (reloc_info);
1551 default:
1552 return ELF64_R_TYPE (reloc_info);
1556 /* Return the symbol index extracted from the reloc info field. */
1558 static uint64_t
1559 get_reloc_symindex (uint64_t reloc_info)
1561 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1564 static inline bool
1565 uses_msp430x_relocs (Filedata * filedata)
1567 return
1568 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
1569 /* GCC uses osabi == ELFOSBI_STANDALONE. */
1570 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
1571 /* TI compiler uses ELFOSABI_NONE. */
1572 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
1575 /* Display the contents of the relocation data found at the specified
1576 offset. */
1578 static bool
1579 dump_relocations (Filedata *filedata,
1580 uint64_t rel_offset,
1581 uint64_t rel_size,
1582 Elf_Internal_Sym *symtab,
1583 uint64_t nsyms,
1584 char *strtab,
1585 uint64_t strtablen,
1586 relocation_type rel_type,
1587 bool is_dynsym)
1589 size_t i;
1590 Elf_Internal_Rela * rels;
1591 bool res = true;
1593 if (rel_type == reltype_unknown)
1594 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
1596 if (rel_type == reltype_rela)
1598 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
1599 return false;
1601 else if (rel_type == reltype_rel)
1603 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
1604 return false;
1606 else if (rel_type == reltype_relr)
1608 uint64_t * relrs;
1609 const char *format
1610 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
1612 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1613 &rel_size))
1614 return false;
1616 printf (ngettext (" %" PRIu64 " offset\n",
1617 " %" PRIu64 " offsets\n", rel_size),
1618 rel_size);
1619 for (i = 0; i < rel_size; i++)
1620 printf (format, relrs[i]);
1621 free (relrs);
1622 return true;
1625 if (is_32bit_elf)
1627 if (rel_type == reltype_rela)
1629 if (do_wide)
1630 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1631 else
1632 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1634 else
1636 if (do_wide)
1637 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1638 else
1639 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1642 else
1644 if (rel_type == reltype_rela)
1646 if (do_wide)
1647 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
1648 else
1649 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1651 else
1653 if (do_wide)
1654 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
1655 else
1656 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1660 for (i = 0; i < rel_size; i++)
1662 const char * rtype;
1663 uint64_t offset;
1664 uint64_t inf;
1665 uint64_t symtab_index;
1666 uint64_t type;
1668 offset = rels[i].r_offset;
1669 inf = rels[i].r_info;
1671 type = get_reloc_type (filedata, inf);
1672 symtab_index = get_reloc_symindex (inf);
1674 if (is_32bit_elf)
1676 printf ("%8.8lx %8.8lx ",
1677 (unsigned long) offset & 0xffffffff,
1678 (unsigned long) inf & 0xffffffff);
1680 else
1682 printf (do_wide
1683 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1684 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
1685 offset, inf);
1688 switch (filedata->file_header.e_machine)
1690 default:
1691 rtype = NULL;
1692 break;
1694 case EM_AARCH64:
1695 rtype = elf_aarch64_reloc_type (type);
1696 break;
1698 case EM_M32R:
1699 case EM_CYGNUS_M32R:
1700 rtype = elf_m32r_reloc_type (type);
1701 break;
1703 case EM_386:
1704 case EM_IAMCU:
1705 rtype = elf_i386_reloc_type (type);
1706 break;
1708 case EM_68HC11:
1709 case EM_68HC12:
1710 rtype = elf_m68hc11_reloc_type (type);
1711 break;
1713 case EM_S12Z:
1714 rtype = elf_s12z_reloc_type (type);
1715 break;
1717 case EM_68K:
1718 rtype = elf_m68k_reloc_type (type);
1719 break;
1721 case EM_960:
1722 rtype = elf_i960_reloc_type (type);
1723 break;
1725 case EM_AVR:
1726 case EM_AVR_OLD:
1727 rtype = elf_avr_reloc_type (type);
1728 break;
1730 case EM_OLD_SPARCV9:
1731 case EM_SPARC32PLUS:
1732 case EM_SPARCV9:
1733 case EM_SPARC:
1734 rtype = elf_sparc_reloc_type (type);
1735 break;
1737 case EM_SPU:
1738 rtype = elf_spu_reloc_type (type);
1739 break;
1741 case EM_V800:
1742 rtype = v800_reloc_type (type);
1743 break;
1744 case EM_V850:
1745 case EM_CYGNUS_V850:
1746 rtype = v850_reloc_type (type);
1747 break;
1749 case EM_D10V:
1750 case EM_CYGNUS_D10V:
1751 rtype = elf_d10v_reloc_type (type);
1752 break;
1754 case EM_D30V:
1755 case EM_CYGNUS_D30V:
1756 rtype = elf_d30v_reloc_type (type);
1757 break;
1759 case EM_DLX:
1760 rtype = elf_dlx_reloc_type (type);
1761 break;
1763 case EM_SH:
1764 rtype = elf_sh_reloc_type (type);
1765 break;
1767 case EM_MN10300:
1768 case EM_CYGNUS_MN10300:
1769 rtype = elf_mn10300_reloc_type (type);
1770 break;
1772 case EM_MN10200:
1773 case EM_CYGNUS_MN10200:
1774 rtype = elf_mn10200_reloc_type (type);
1775 break;
1777 case EM_FR30:
1778 case EM_CYGNUS_FR30:
1779 rtype = elf_fr30_reloc_type (type);
1780 break;
1782 case EM_CYGNUS_FRV:
1783 rtype = elf_frv_reloc_type (type);
1784 break;
1786 case EM_CSKY:
1787 rtype = elf_csky_reloc_type (type);
1788 break;
1790 case EM_FT32:
1791 rtype = elf_ft32_reloc_type (type);
1792 break;
1794 case EM_MCORE:
1795 rtype = elf_mcore_reloc_type (type);
1796 break;
1798 case EM_MMIX:
1799 rtype = elf_mmix_reloc_type (type);
1800 break;
1802 case EM_MOXIE:
1803 rtype = elf_moxie_reloc_type (type);
1804 break;
1806 case EM_MSP430:
1807 if (uses_msp430x_relocs (filedata))
1809 rtype = elf_msp430x_reloc_type (type);
1810 break;
1812 /* Fall through. */
1813 case EM_MSP430_OLD:
1814 rtype = elf_msp430_reloc_type (type);
1815 break;
1817 case EM_NDS32:
1818 rtype = elf_nds32_reloc_type (type);
1819 break;
1821 case EM_PPC:
1822 rtype = elf_ppc_reloc_type (type);
1823 break;
1825 case EM_PPC64:
1826 rtype = elf_ppc64_reloc_type (type);
1827 break;
1829 case EM_MIPS:
1830 case EM_MIPS_RS3_LE:
1831 rtype = elf_mips_reloc_type (type);
1832 break;
1834 case EM_RISCV:
1835 rtype = elf_riscv_reloc_type (type);
1836 break;
1838 case EM_ALPHA:
1839 rtype = elf_alpha_reloc_type (type);
1840 break;
1842 case EM_ARM:
1843 rtype = elf_arm_reloc_type (type);
1844 break;
1846 case EM_ARC:
1847 case EM_ARC_COMPACT:
1848 case EM_ARC_COMPACT2:
1849 case EM_ARC_COMPACT3:
1850 case EM_ARC_COMPACT3_64:
1851 rtype = elf_arc_reloc_type (type);
1852 break;
1854 case EM_PARISC:
1855 rtype = elf_hppa_reloc_type (type);
1856 break;
1858 case EM_H8_300:
1859 case EM_H8_300H:
1860 case EM_H8S:
1861 rtype = elf_h8_reloc_type (type);
1862 break;
1864 case EM_OR1K:
1865 rtype = elf_or1k_reloc_type (type);
1866 break;
1868 case EM_PJ:
1869 case EM_PJ_OLD:
1870 rtype = elf_pj_reloc_type (type);
1871 break;
1872 case EM_IA_64:
1873 rtype = elf_ia64_reloc_type (type);
1874 break;
1876 case EM_KVX:
1877 rtype = elf_kvx_reloc_type (type);
1878 break;
1880 case EM_CRIS:
1881 rtype = elf_cris_reloc_type (type);
1882 break;
1884 case EM_860:
1885 rtype = elf_i860_reloc_type (type);
1886 break;
1888 case EM_X86_64:
1889 case EM_L1OM:
1890 case EM_K1OM:
1891 rtype = elf_x86_64_reloc_type (type);
1892 break;
1894 case EM_S370:
1895 rtype = i370_reloc_type (type);
1896 break;
1898 case EM_S390_OLD:
1899 case EM_S390:
1900 rtype = elf_s390_reloc_type (type);
1901 break;
1903 case EM_SCORE:
1904 rtype = elf_score_reloc_type (type);
1905 break;
1907 case EM_XSTORMY16:
1908 rtype = elf_xstormy16_reloc_type (type);
1909 break;
1911 case EM_CRX:
1912 rtype = elf_crx_reloc_type (type);
1913 break;
1915 case EM_VAX:
1916 rtype = elf_vax_reloc_type (type);
1917 break;
1919 case EM_VISIUM:
1920 rtype = elf_visium_reloc_type (type);
1921 break;
1923 case EM_BPF:
1924 rtype = elf_bpf_reloc_type (type);
1925 break;
1927 case EM_ADAPTEVA_EPIPHANY:
1928 rtype = elf_epiphany_reloc_type (type);
1929 break;
1931 case EM_IP2K:
1932 case EM_IP2K_OLD:
1933 rtype = elf_ip2k_reloc_type (type);
1934 break;
1936 case EM_IQ2000:
1937 rtype = elf_iq2000_reloc_type (type);
1938 break;
1940 case EM_XTENSA_OLD:
1941 case EM_XTENSA:
1942 rtype = elf_xtensa_reloc_type (type);
1943 break;
1945 case EM_LATTICEMICO32:
1946 rtype = elf_lm32_reloc_type (type);
1947 break;
1949 case EM_M32C_OLD:
1950 case EM_M32C:
1951 rtype = elf_m32c_reloc_type (type);
1952 break;
1954 case EM_MT:
1955 rtype = elf_mt_reloc_type (type);
1956 break;
1958 case EM_BLACKFIN:
1959 rtype = elf_bfin_reloc_type (type);
1960 break;
1962 case EM_CYGNUS_MEP:
1963 rtype = elf_mep_reloc_type (type);
1964 break;
1966 case EM_CR16:
1967 rtype = elf_cr16_reloc_type (type);
1968 break;
1970 case EM_MICROBLAZE:
1971 case EM_MICROBLAZE_OLD:
1972 rtype = elf_microblaze_reloc_type (type);
1973 break;
1975 case EM_RL78:
1976 rtype = elf_rl78_reloc_type (type);
1977 break;
1979 case EM_RX:
1980 rtype = elf_rx_reloc_type (type);
1981 break;
1983 case EM_METAG:
1984 rtype = elf_metag_reloc_type (type);
1985 break;
1987 case EM_TI_C6000:
1988 rtype = elf_tic6x_reloc_type (type);
1989 break;
1991 case EM_TILEGX:
1992 rtype = elf_tilegx_reloc_type (type);
1993 break;
1995 case EM_TILEPRO:
1996 rtype = elf_tilepro_reloc_type (type);
1997 break;
1999 case EM_WEBASSEMBLY:
2000 rtype = elf_wasm32_reloc_type (type);
2001 break;
2003 case EM_XGATE:
2004 rtype = elf_xgate_reloc_type (type);
2005 break;
2007 case EM_ALTERA_NIOS2:
2008 rtype = elf_nios2_reloc_type (type);
2009 break;
2011 case EM_TI_PRU:
2012 rtype = elf_pru_reloc_type (type);
2013 break;
2015 case EM_NFP:
2016 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
2017 rtype = elf_nfp3200_reloc_type (type);
2018 else
2019 rtype = elf_nfp_reloc_type (type);
2020 break;
2022 case EM_Z80:
2023 rtype = elf_z80_reloc_type (type);
2024 break;
2026 case EM_LOONGARCH:
2027 rtype = elf_loongarch_reloc_type (type);
2028 break;
2030 case EM_AMDGPU:
2031 rtype = elf_amdgpu_reloc_type (type);
2032 break;
2035 if (rtype == NULL)
2036 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
2037 else
2038 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
2040 if (filedata->file_header.e_machine == EM_ALPHA
2041 && rtype != NULL
2042 && streq (rtype, "R_ALPHA_LITUSE")
2043 && rel_type == reltype_rela)
2045 switch (rels[i].r_addend)
2047 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
2048 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
2049 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
2050 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
2051 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
2052 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
2053 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
2054 default: rtype = NULL;
2057 if (rtype)
2058 printf (" (%s)", rtype);
2059 else
2061 putchar (' ');
2062 printf (_("<unknown addend: %" PRIx64 ">"),
2063 rels[i].r_addend);
2064 res = false;
2067 else if (symtab_index)
2069 if (symtab == NULL || symtab_index >= nsyms)
2071 error (_(" bad symbol index: %08lx in reloc\n"),
2072 (unsigned long) symtab_index);
2073 res = false;
2075 else
2077 Elf_Internal_Sym * psym;
2078 const char * version_string;
2079 enum versioned_symbol_info sym_info;
2080 unsigned short vna_other;
2082 psym = symtab + symtab_index;
2084 version_string
2085 = get_symbol_version_string (filedata, is_dynsym,
2086 strtab, strtablen,
2087 symtab_index,
2088 psym,
2089 &sym_info,
2090 &vna_other);
2092 printf (" ");
2094 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
2096 const char * name;
2097 unsigned int len;
2098 unsigned int width = is_32bit_elf ? 8 : 14;
2100 /* Relocations against GNU_IFUNC symbols do not use the value
2101 of the symbol as the address to relocate against. Instead
2102 they invoke the function named by the symbol and use its
2103 result as the address for relocation.
2105 To indicate this to the user, do not display the value of
2106 the symbol in the "Symbols's Value" field. Instead show
2107 its name followed by () as a hint that the symbol is
2108 invoked. */
2110 if (strtab == NULL
2111 || psym->st_name == 0
2112 || psym->st_name >= strtablen)
2113 name = "??";
2114 else
2115 name = strtab + psym->st_name;
2117 len = print_symbol_name (width, name);
2118 if (version_string)
2119 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2120 version_string);
2121 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2123 else
2125 print_vma (psym->st_value, LONG_HEX);
2127 printf (is_32bit_elf ? " " : " ");
2130 if (psym->st_name == 0)
2132 const char * sec_name = "<null>";
2134 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2135 sec_name = printable_section_name_from_index
2136 (filedata, psym->st_shndx, NULL);
2138 print_symbol_name (22, sec_name);
2140 else if (strtab == NULL)
2141 printf (_("<string table index: %3ld>"), psym->st_name);
2142 else if (psym->st_name >= strtablen)
2144 error (_("<corrupt string table index: %3ld>\n"),
2145 psym->st_name);
2146 res = false;
2148 else
2150 print_symbol_name (22, strtab + psym->st_name);
2151 if (version_string)
2152 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2153 version_string);
2156 if (rel_type == reltype_rela)
2158 uint64_t off = rels[i].r_addend;
2160 if ((int64_t) off < 0)
2161 printf (" - %" PRIx64, -off);
2162 else
2163 printf (" + %" PRIx64, off);
2167 else if (rel_type == reltype_rela)
2169 uint64_t off = rels[i].r_addend;
2171 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
2172 if ((int64_t) off < 0)
2173 printf ("-%" PRIx64, -off);
2174 else
2175 printf ("%" PRIx64, off);
2178 if (filedata->file_header.e_machine == EM_SPARCV9
2179 && rtype != NULL
2180 && streq (rtype, "R_SPARC_OLO10"))
2181 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
2183 putchar ('\n');
2185 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2187 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2188 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2189 const char * rtype2 = elf_mips_reloc_type (type2);
2190 const char * rtype3 = elf_mips_reloc_type (type3);
2192 printf (" Type2: ");
2194 if (rtype2 == NULL)
2195 printf (_("unrecognized: %-7lx"),
2196 (unsigned long) type2 & 0xffffffff);
2197 else
2198 printf ("%-17.17s", rtype2);
2200 printf ("\n Type3: ");
2202 if (rtype3 == NULL)
2203 printf (_("unrecognized: %-7lx"),
2204 (unsigned long) type3 & 0xffffffff);
2205 else
2206 printf ("%-17.17s", rtype3);
2208 putchar ('\n');
2212 free (rels);
2214 return res;
2217 static const char *
2218 get_aarch64_dynamic_type (unsigned long type)
2220 switch (type)
2222 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
2223 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2224 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
2225 default:
2226 return NULL;
2230 static const char *
2231 get_mips_dynamic_type (unsigned long type)
2233 switch (type)
2235 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2236 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2237 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2238 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2239 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2240 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2241 case DT_MIPS_MSYM: return "MIPS_MSYM";
2242 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2243 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2244 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2245 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2246 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2247 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2248 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2249 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2250 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2251 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
2252 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
2253 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2254 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2255 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2256 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2257 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2258 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2259 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2260 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2261 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2262 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2263 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2264 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2265 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2266 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2267 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2268 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2269 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2270 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2271 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2272 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2273 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2274 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2275 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2276 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2277 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2278 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
2279 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2280 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
2281 case DT_MIPS_XHASH: return "MIPS_XHASH";
2282 default:
2283 return NULL;
2287 static const char *
2288 get_sparc64_dynamic_type (unsigned long type)
2290 switch (type)
2292 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2293 default:
2294 return NULL;
2298 static const char *
2299 get_ppc_dynamic_type (unsigned long type)
2301 switch (type)
2303 case DT_PPC_GOT: return "PPC_GOT";
2304 case DT_PPC_OPT: return "PPC_OPT";
2305 default:
2306 return NULL;
2310 static const char *
2311 get_ppc64_dynamic_type (unsigned long type)
2313 switch (type)
2315 case DT_PPC64_GLINK: return "PPC64_GLINK";
2316 case DT_PPC64_OPD: return "PPC64_OPD";
2317 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
2318 case DT_PPC64_OPT: return "PPC64_OPT";
2319 default:
2320 return NULL;
2324 static const char *
2325 get_parisc_dynamic_type (unsigned long type)
2327 switch (type)
2329 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2330 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2331 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2332 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2333 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2334 case DT_HP_PREINIT: return "HP_PREINIT";
2335 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2336 case DT_HP_NEEDED: return "HP_NEEDED";
2337 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2338 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2339 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2340 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2341 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
2342 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2343 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2344 case DT_HP_FILTERED: return "HP_FILTERED";
2345 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2346 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2347 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2348 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2349 case DT_PLT: return "PLT";
2350 case DT_PLT_SIZE: return "PLT_SIZE";
2351 case DT_DLT: return "DLT";
2352 case DT_DLT_SIZE: return "DLT_SIZE";
2353 default:
2354 return NULL;
2358 static const char *
2359 get_ia64_dynamic_type (unsigned long type)
2361 switch (type)
2363 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2364 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2365 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2366 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2367 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2368 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2369 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2370 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2371 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2372 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2373 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2374 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2375 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2376 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2377 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2378 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2379 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2380 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2381 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2382 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2383 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2384 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2385 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2386 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2387 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2388 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2389 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2390 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2391 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2392 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2393 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
2394 default:
2395 return NULL;
2399 static const char *
2400 get_solaris_section_type (unsigned long type)
2402 switch (type)
2404 case 0x6fffffee: return "SUNW_ancillary";
2405 case 0x6fffffef: return "SUNW_capchain";
2406 case 0x6ffffff0: return "SUNW_capinfo";
2407 case 0x6ffffff1: return "SUNW_symsort";
2408 case 0x6ffffff2: return "SUNW_tlssort";
2409 case 0x6ffffff3: return "SUNW_LDYNSYM";
2410 case 0x6ffffff4: return "SUNW_dof";
2411 case 0x6ffffff5: return "SUNW_cap";
2412 case 0x6ffffff6: return "SUNW_SIGNATURE";
2413 case 0x6ffffff7: return "SUNW_ANNOTATE";
2414 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2415 case 0x6ffffff9: return "SUNW_DEBUG";
2416 case 0x6ffffffa: return "SUNW_move";
2417 case 0x6ffffffb: return "SUNW_COMDAT";
2418 case 0x6ffffffc: return "SUNW_syminfo";
2419 case 0x6ffffffd: return "SUNW_verdef";
2420 case 0x6ffffffe: return "SUNW_verneed";
2421 case 0x6fffffff: return "SUNW_versym";
2422 case 0x70000000: return "SPARC_GOTDATA";
2423 default: return NULL;
2427 static const char *
2428 get_alpha_dynamic_type (unsigned long type)
2430 switch (type)
2432 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
2433 default: return NULL;
2437 static const char *
2438 get_score_dynamic_type (unsigned long type)
2440 switch (type)
2442 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2443 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2444 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2445 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2446 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2447 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
2448 default: return NULL;
2452 static const char *
2453 get_tic6x_dynamic_type (unsigned long type)
2455 switch (type)
2457 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2458 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2459 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2460 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2461 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2462 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
2463 default: return NULL;
2467 static const char *
2468 get_nios2_dynamic_type (unsigned long type)
2470 switch (type)
2472 case DT_NIOS2_GP: return "NIOS2_GP";
2473 default: return NULL;
2477 static const char *
2478 get_solaris_dynamic_type (unsigned long type)
2480 switch (type)
2482 case 0x6000000d: return "SUNW_AUXILIARY";
2483 case 0x6000000e: return "SUNW_RTLDINF";
2484 case 0x6000000f: return "SUNW_FILTER";
2485 case 0x60000010: return "SUNW_CAP";
2486 case 0x60000011: return "SUNW_SYMTAB";
2487 case 0x60000012: return "SUNW_SYMSZ";
2488 case 0x60000013: return "SUNW_SORTENT";
2489 case 0x60000014: return "SUNW_SYMSORT";
2490 case 0x60000015: return "SUNW_SYMSORTSZ";
2491 case 0x60000016: return "SUNW_TLSSORT";
2492 case 0x60000017: return "SUNW_TLSSORTSZ";
2493 case 0x60000018: return "SUNW_CAPINFO";
2494 case 0x60000019: return "SUNW_STRPAD";
2495 case 0x6000001a: return "SUNW_CAPCHAIN";
2496 case 0x6000001b: return "SUNW_LDMACH";
2497 case 0x6000001d: return "SUNW_CAPCHAINENT";
2498 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2499 case 0x60000021: return "SUNW_PARENT";
2500 case 0x60000023: return "SUNW_ASLR";
2501 case 0x60000025: return "SUNW_RELAX";
2502 case 0x60000029: return "SUNW_NXHEAP";
2503 case 0x6000002b: return "SUNW_NXSTACK";
2505 case 0x70000001: return "SPARC_REGISTER";
2506 case 0x7ffffffd: return "AUXILIARY";
2507 case 0x7ffffffe: return "USED";
2508 case 0x7fffffff: return "FILTER";
2510 default: return NULL;
2514 static const char *
2515 get_riscv_dynamic_type (unsigned long type)
2517 switch (type)
2519 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2520 default:
2521 return NULL;
2525 static const char *
2526 get_x86_64_dynamic_type (unsigned long type)
2528 switch (type)
2530 case DT_X86_64_PLT:
2531 return "DT_X86_64_PLT";
2532 case DT_X86_64_PLTSZ:
2533 return "DT_X86_64_PLTSZ";
2534 case DT_X86_64_PLTENT:
2535 return "DT_X86_64_PLTENT";
2536 default:
2537 return NULL;
2541 static const char *
2542 get_dynamic_type (Filedata * filedata, unsigned long type)
2544 static char buff[64];
2546 switch (type)
2548 case DT_NULL: return "NULL";
2549 case DT_NEEDED: return "NEEDED";
2550 case DT_PLTRELSZ: return "PLTRELSZ";
2551 case DT_PLTGOT: return "PLTGOT";
2552 case DT_HASH: return "HASH";
2553 case DT_STRTAB: return "STRTAB";
2554 case DT_SYMTAB: return "SYMTAB";
2555 case DT_RELA: return "RELA";
2556 case DT_RELASZ: return "RELASZ";
2557 case DT_RELAENT: return "RELAENT";
2558 case DT_STRSZ: return "STRSZ";
2559 case DT_SYMENT: return "SYMENT";
2560 case DT_INIT: return "INIT";
2561 case DT_FINI: return "FINI";
2562 case DT_SONAME: return "SONAME";
2563 case DT_RPATH: return "RPATH";
2564 case DT_SYMBOLIC: return "SYMBOLIC";
2565 case DT_REL: return "REL";
2566 case DT_RELSZ: return "RELSZ";
2567 case DT_RELENT: return "RELENT";
2568 case DT_RELR: return "RELR";
2569 case DT_RELRSZ: return "RELRSZ";
2570 case DT_RELRENT: return "RELRENT";
2571 case DT_PLTREL: return "PLTREL";
2572 case DT_DEBUG: return "DEBUG";
2573 case DT_TEXTREL: return "TEXTREL";
2574 case DT_JMPREL: return "JMPREL";
2575 case DT_BIND_NOW: return "BIND_NOW";
2576 case DT_INIT_ARRAY: return "INIT_ARRAY";
2577 case DT_FINI_ARRAY: return "FINI_ARRAY";
2578 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2579 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
2580 case DT_RUNPATH: return "RUNPATH";
2581 case DT_FLAGS: return "FLAGS";
2583 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2584 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
2585 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
2587 case DT_CHECKSUM: return "CHECKSUM";
2588 case DT_PLTPADSZ: return "PLTPADSZ";
2589 case DT_MOVEENT: return "MOVEENT";
2590 case DT_MOVESZ: return "MOVESZ";
2591 case DT_FEATURE: return "FEATURE";
2592 case DT_POSFLAG_1: return "POSFLAG_1";
2593 case DT_SYMINSZ: return "SYMINSZ";
2594 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
2596 case DT_ADDRRNGLO: return "ADDRRNGLO";
2597 case DT_CONFIG: return "CONFIG";
2598 case DT_DEPAUDIT: return "DEPAUDIT";
2599 case DT_AUDIT: return "AUDIT";
2600 case DT_PLTPAD: return "PLTPAD";
2601 case DT_MOVETAB: return "MOVETAB";
2602 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
2604 case DT_VERSYM: return "VERSYM";
2606 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2607 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
2608 case DT_RELACOUNT: return "RELACOUNT";
2609 case DT_RELCOUNT: return "RELCOUNT";
2610 case DT_FLAGS_1: return "FLAGS_1";
2611 case DT_VERDEF: return "VERDEF";
2612 case DT_VERDEFNUM: return "VERDEFNUM";
2613 case DT_VERNEED: return "VERNEED";
2614 case DT_VERNEEDNUM: return "VERNEEDNUM";
2616 case DT_AUXILIARY: return "AUXILIARY";
2617 case DT_USED: return "USED";
2618 case DT_FILTER: return "FILTER";
2620 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2621 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2622 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2623 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2624 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
2625 case DT_GNU_HASH: return "GNU_HASH";
2626 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
2628 default:
2629 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2631 const char * result;
2633 switch (filedata->file_header.e_machine)
2635 case EM_AARCH64:
2636 result = get_aarch64_dynamic_type (type);
2637 break;
2638 case EM_MIPS:
2639 case EM_MIPS_RS3_LE:
2640 result = get_mips_dynamic_type (type);
2641 break;
2642 case EM_SPARCV9:
2643 result = get_sparc64_dynamic_type (type);
2644 break;
2645 case EM_PPC:
2646 result = get_ppc_dynamic_type (type);
2647 break;
2648 case EM_PPC64:
2649 result = get_ppc64_dynamic_type (type);
2650 break;
2651 case EM_IA_64:
2652 result = get_ia64_dynamic_type (type);
2653 break;
2654 case EM_ALPHA:
2655 result = get_alpha_dynamic_type (type);
2656 break;
2657 case EM_SCORE:
2658 result = get_score_dynamic_type (type);
2659 break;
2660 case EM_TI_C6000:
2661 result = get_tic6x_dynamic_type (type);
2662 break;
2663 case EM_ALTERA_NIOS2:
2664 result = get_nios2_dynamic_type (type);
2665 break;
2666 case EM_RISCV:
2667 result = get_riscv_dynamic_type (type);
2668 break;
2669 case EM_X86_64:
2670 result = get_x86_64_dynamic_type (type);
2671 break;
2672 default:
2673 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
2674 result = get_solaris_dynamic_type (type);
2675 else
2676 result = NULL;
2677 break;
2680 if (result != NULL)
2681 return result;
2683 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
2685 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
2686 || (filedata->file_header.e_machine == EM_PARISC
2687 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
2689 const char * result;
2691 switch (filedata->file_header.e_machine)
2693 case EM_PARISC:
2694 result = get_parisc_dynamic_type (type);
2695 break;
2696 case EM_IA_64:
2697 result = get_ia64_dynamic_type (type);
2698 break;
2699 default:
2700 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
2701 result = get_solaris_dynamic_type (type);
2702 else
2703 result = NULL;
2704 break;
2707 if (result != NULL)
2708 return result;
2710 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2711 type);
2713 else
2714 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
2716 return buff;
2720 static bool get_program_headers (Filedata *);
2721 static bool get_dynamic_section (Filedata *);
2723 static void
2724 locate_dynamic_section (Filedata *filedata)
2726 uint64_t dynamic_addr = 0;
2727 uint64_t dynamic_size = 0;
2729 if (filedata->file_header.e_phnum != 0
2730 && get_program_headers (filedata))
2732 Elf_Internal_Phdr *segment;
2733 unsigned int i;
2735 for (i = 0, segment = filedata->program_headers;
2736 i < filedata->file_header.e_phnum;
2737 i++, segment++)
2739 if (segment->p_type == PT_DYNAMIC)
2741 dynamic_addr = segment->p_offset;
2742 dynamic_size = segment->p_filesz;
2744 if (filedata->section_headers != NULL)
2746 Elf_Internal_Shdr *sec;
2748 sec = find_section (filedata, ".dynamic");
2749 if (sec != NULL)
2751 if (sec->sh_size == 0
2752 || sec->sh_type == SHT_NOBITS)
2754 dynamic_addr = 0;
2755 dynamic_size = 0;
2757 else
2759 dynamic_addr = sec->sh_offset;
2760 dynamic_size = sec->sh_size;
2765 if (dynamic_addr > filedata->file_size
2766 || (dynamic_size > filedata->file_size - dynamic_addr))
2768 dynamic_addr = 0;
2769 dynamic_size = 0;
2771 break;
2775 filedata->dynamic_addr = dynamic_addr;
2776 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2779 static bool
2780 is_pie (Filedata *filedata)
2782 Elf_Internal_Dyn *entry;
2784 if (filedata->dynamic_size == 0)
2785 locate_dynamic_section (filedata);
2786 if (filedata->dynamic_size <= 1)
2787 return false;
2789 if (!get_dynamic_section (filedata))
2790 return false;
2792 for (entry = filedata->dynamic_section;
2793 entry < filedata->dynamic_section + filedata->dynamic_nent;
2794 entry++)
2796 if (entry->d_tag == DT_FLAGS_1)
2798 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2799 return true;
2800 break;
2803 return false;
2806 static char *
2807 get_file_type (Filedata *filedata)
2809 unsigned e_type = filedata->file_header.e_type;
2810 static char buff[64];
2812 switch (e_type)
2814 case ET_NONE: return _("NONE (None)");
2815 case ET_REL: return _("REL (Relocatable file)");
2816 case ET_EXEC: return _("EXEC (Executable file)");
2817 case ET_DYN:
2818 if (is_pie (filedata))
2819 return _("DYN (Position-Independent Executable file)");
2820 else
2821 return _("DYN (Shared object file)");
2822 case ET_CORE: return _("CORE (Core file)");
2824 default:
2825 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
2826 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
2827 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
2828 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
2829 else
2830 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
2831 return buff;
2835 static char *
2836 get_machine_name (unsigned e_machine)
2838 static char buff[64]; /* XXX */
2840 switch (e_machine)
2842 /* Please keep this switch table sorted by increasing EM_ value. */
2843 /* 0 */
2844 case EM_NONE: return _("None");
2845 case EM_M32: return "WE32100";
2846 case EM_SPARC: return "Sparc";
2847 case EM_386: return "Intel 80386";
2848 case EM_68K: return "MC68000";
2849 case EM_88K: return "MC88000";
2850 case EM_IAMCU: return "Intel MCU";
2851 case EM_860: return "Intel 80860";
2852 case EM_MIPS: return "MIPS R3000";
2853 case EM_S370: return "IBM System/370";
2854 /* 10 */
2855 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
2856 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
2857 case EM_PARISC: return "HPPA";
2858 case EM_VPP550: return "Fujitsu VPP500";
2859 case EM_SPARC32PLUS: return "Sparc v8+" ;
2860 case EM_960: return "Intel 80960";
2861 case EM_PPC: return "PowerPC";
2862 /* 20 */
2863 case EM_PPC64: return "PowerPC64";
2864 case EM_S390_OLD:
2865 case EM_S390: return "IBM S/390";
2866 case EM_SPU: return "SPU";
2867 /* 30 */
2868 case EM_V800: return "Renesas V850 (using RH850 ABI)";
2869 case EM_FR20: return "Fujitsu FR20";
2870 case EM_RH32: return "TRW RH32";
2871 case EM_MCORE: return "MCORE";
2872 /* 40 */
2873 case EM_ARM: return "ARM";
2874 case EM_OLD_ALPHA: return "Digital Alpha (old)";
2875 case EM_SH: return "Renesas / SuperH SH";
2876 case EM_SPARCV9: return "Sparc v9";
2877 case EM_TRICORE: return "Siemens Tricore";
2878 case EM_ARC: return "ARC";
2879 case EM_H8_300: return "Renesas H8/300";
2880 case EM_H8_300H: return "Renesas H8/300H";
2881 case EM_H8S: return "Renesas H8S";
2882 case EM_H8_500: return "Renesas H8/500";
2883 /* 50 */
2884 case EM_IA_64: return "Intel IA-64";
2885 case EM_MIPS_X: return "Stanford MIPS-X";
2886 case EM_COLDFIRE: return "Motorola Coldfire";
2887 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
2888 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2889 case EM_PCP: return "Siemens PCP";
2890 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2891 case EM_NDR1: return "Denso NDR1 microprocessor";
2892 case EM_STARCORE: return "Motorola Star*Core processor";
2893 case EM_ME16: return "Toyota ME16 processor";
2894 /* 60 */
2895 case EM_ST100: return "STMicroelectronics ST100 processor";
2896 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
2897 case EM_X86_64: return "Advanced Micro Devices X86-64";
2898 case EM_PDSP: return "Sony DSP processor";
2899 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2900 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
2901 case EM_FX66: return "Siemens FX66 microcontroller";
2902 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2903 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2904 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
2905 /* 70 */
2906 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2907 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2908 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2909 case EM_SVX: return "Silicon Graphics SVx";
2910 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2911 case EM_VAX: return "Digital VAX";
2912 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
2913 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2914 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2915 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
2916 /* 80 */
2917 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
2918 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
2919 case EM_PRISM: return "Vitesse Prism";
2920 case EM_AVR_OLD:
2921 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2922 case EM_CYGNUS_FR30:
2923 case EM_FR30: return "Fujitsu FR30";
2924 case EM_CYGNUS_D10V:
2925 case EM_D10V: return "d10v";
2926 case EM_CYGNUS_D30V:
2927 case EM_D30V: return "d30v";
2928 case EM_CYGNUS_V850:
2929 case EM_V850: return "Renesas V850";
2930 case EM_CYGNUS_M32R:
2931 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2932 case EM_CYGNUS_MN10300:
2933 case EM_MN10300: return "mn10300";
2934 /* 90 */
2935 case EM_CYGNUS_MN10200:
2936 case EM_MN10200: return "mn10200";
2937 case EM_PJ: return "picoJava";
2938 case EM_OR1K: return "OpenRISC 1000";
2939 case EM_ARC_COMPACT: return "ARCompact";
2940 case EM_XTENSA_OLD:
2941 case EM_XTENSA: return "Tensilica Xtensa Processor";
2942 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2943 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2944 case EM_NS32K: return "National Semiconductor 32000 series";
2945 case EM_TPC: return "Tenor Network TPC processor";
2946 case EM_SNP1K: return "Trebia SNP 1000 processor";
2947 /* 100 */
2948 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
2949 case EM_IP2K_OLD:
2950 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
2951 case EM_MAX: return "MAX Processor";
2952 case EM_CR: return "National Semiconductor CompactRISC";
2953 case EM_F2MC16: return "Fujitsu F2MC16";
2954 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
2955 case EM_BLACKFIN: return "Analog Devices Blackfin";
2956 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2957 case EM_SEP: return "Sharp embedded microprocessor";
2958 case EM_ARCA: return "Arca RISC microprocessor";
2959 /* 110 */
2960 case EM_UNICORE: return "Unicore";
2961 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2962 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
2963 case EM_ALTERA_NIOS2: return "Altera Nios II";
2964 case EM_CRX: return "National Semiconductor CRX microprocessor";
2965 case EM_XGATE: return "Motorola XGATE embedded processor";
2966 case EM_C166:
2967 case EM_XC16X: return "Infineon Technologies xc16x";
2968 case EM_M16C: return "Renesas M16C series microprocessors";
2969 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2970 case EM_CE: return "Freescale Communication Engine RISC core";
2971 /* 120 */
2972 case EM_M32C: return "Renesas M32c";
2973 /* 130 */
2974 case EM_TSK3000: return "Altium TSK3000 core";
2975 case EM_RS08: return "Freescale RS08 embedded processor";
2976 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
2977 case EM_SCORE: return "SUNPLUS S+Core";
2978 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2979 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
2980 case EM_LATTICEMICO32: return "Lattice Mico32";
2981 case EM_SE_C17: return "Seiko Epson C17 family";
2982 /* 140 */
2983 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2984 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2985 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
2986 case EM_TI_PRU: return "TI PRU I/O processor";
2987 /* 160 */
2988 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2989 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2990 case EM_R32C: return "Renesas R32C series microprocessors";
2991 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2992 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2993 case EM_8051: return "Intel 8051 and variants";
2994 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2995 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2996 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2997 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
2998 /* 170 */
2999 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
3000 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
3001 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
3002 case EM_RX: return "Renesas RX";
3003 case EM_METAG: return "Imagination Technologies Meta processor architecture";
3004 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
3005 case EM_ECOG16: return "Cyan Technology eCOG16 family";
3006 case EM_CR16:
3007 case EM_MICROBLAZE:
3008 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
3009 case EM_ETPU: return "Freescale Extended Time Processing Unit";
3010 case EM_SLE9X: return "Infineon Technologies SLE9X core";
3011 /* 180 */
3012 case EM_L1OM: return "Intel L1OM";
3013 case EM_K1OM: return "Intel K1OM";
3014 case EM_INTEL182: return "Intel (reserved)";
3015 case EM_AARCH64: return "AArch64";
3016 case EM_ARM184: return "ARM (reserved)";
3017 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
3018 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
3019 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
3020 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
3021 /* 190 */
3022 case EM_CUDA: return "NVIDIA CUDA architecture";
3023 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
3024 case EM_CLOUDSHIELD: return "CloudShield architecture family";
3025 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
3026 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
3027 case EM_ARC_COMPACT2: return "ARCv2";
3028 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
3029 case EM_RL78: return "Renesas RL78";
3030 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
3031 case EM_78K0R: return "Renesas 78K0R";
3032 /* 200 */
3033 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
3034 case EM_BA1: return "Beyond BA1 CPU architecture";
3035 case EM_BA2: return "Beyond BA2 CPU architecture";
3036 case EM_XCORE: return "XMOS xCORE processor family";
3037 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
3038 case EM_INTELGT: return "Intel Graphics Technology";
3039 /* 210 */
3040 case EM_KM32: return "KM211 KM32 32-bit processor";
3041 case EM_KMX32: return "KM211 KMX32 32-bit processor";
3042 case EM_KMX16: return "KM211 KMX16 16-bit processor";
3043 case EM_KMX8: return "KM211 KMX8 8-bit processor";
3044 case EM_KVARC: return "KM211 KVARC processor";
3045 case EM_CDP: return "Paneve CDP architecture family";
3046 case EM_COGE: return "Cognitive Smart Memory Processor";
3047 case EM_COOL: return "Bluechip Systems CoolEngine";
3048 case EM_NORC: return "Nanoradio Optimized RISC";
3049 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
3050 /* 220 */
3051 case EM_Z80: return "Zilog Z80";
3052 case EM_VISIUM: return "CDS VISIUMcore processor";
3053 case EM_FT32: return "FTDI Chip FT32";
3054 case EM_MOXIE: return "Moxie";
3055 case EM_AMDGPU: return "AMD GPU";
3056 /* 230 (all reserved) */
3057 /* 240 */
3058 case EM_RISCV: return "RISC-V";
3059 case EM_LANAI: return "Lanai 32-bit processor";
3060 case EM_CEVA: return "CEVA Processor Architecture Family";
3061 case EM_CEVA_X2: return "CEVA X2 Processor Family";
3062 case EM_BPF: return "Linux BPF";
3063 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
3064 case EM_IMG1: return "Imagination Technologies";
3065 /* 250 */
3066 case EM_NFP: return "Netronome Flow Processor";
3067 case EM_VE: return "NEC Vector Engine";
3068 case EM_CSKY: return "C-SKY";
3069 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
3070 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
3071 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
3072 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
3073 case EM_65816: return "WDC 65816/65C816";
3074 case EM_LOONGARCH: return "LoongArch";
3075 case EM_KF32: return "ChipON KungFu32";
3077 /* Large numbers... */
3078 case EM_MT: return "Morpho Techologies MT processor";
3079 case EM_ALPHA: return "Alpha";
3080 case EM_WEBASSEMBLY: return "Web Assembly";
3081 case EM_DLX: return "OpenDLX";
3082 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3083 case EM_IQ2000: return "Vitesse IQ2000";
3084 case EM_M32C_OLD:
3085 case EM_NIOS32: return "Altera Nios";
3086 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3087 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3088 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
3089 case EM_S12Z: return "Freescale S12Z";
3091 default:
3092 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
3093 return buff;
3097 static char *
3098 decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
3100 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
3101 other compilers don't specify an architecture type in the e_flags, and
3102 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3103 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3104 architectures.
3106 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3107 but also sets a specific architecture type in the e_flags field.
3109 However, when decoding the flags we don't worry if we see an
3110 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3111 ARCEM architecture type. */
3113 switch (e_flags & EF_ARC_MACH_MSK)
3115 /* We only expect these to occur for EM_ARC_COMPACT2. */
3116 case EF_ARC_CPU_ARCV2EM:
3117 out = stpcpy (out, ", ARC EM");
3118 break;
3119 case EF_ARC_CPU_ARCV2HS:
3120 out = stpcpy (out, ", ARC HS");
3121 break;
3123 /* We only expect these to occur for EM_ARC_COMPACT. */
3124 case E_ARC_MACH_ARC600:
3125 out = stpcpy (out, ", ARC600");
3126 break;
3127 case E_ARC_MACH_ARC601:
3128 out = stpcpy (out, ", ARC601");
3129 break;
3130 case E_ARC_MACH_ARC700:
3131 out = stpcpy (out, ", ARC700");
3132 break;
3134 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3135 new ELF with new architecture being read by an old version of
3136 readelf, or (c) An ELF built with non-GNU compiler that does not
3137 set the architecture in the e_flags. */
3138 default:
3139 if (e_machine == EM_ARC_COMPACT)
3140 out = stpcpy (out, ", Unknown ARCompact");
3141 else
3142 out = stpcpy (out, ", Unknown ARC");
3143 break;
3146 switch (e_flags & EF_ARC_OSABI_MSK)
3148 case E_ARC_OSABI_ORIG:
3149 out = stpcpy (out, ", (ABI:legacy)");
3150 break;
3151 case E_ARC_OSABI_V2:
3152 out = stpcpy (out, ", (ABI:v2)");
3153 break;
3154 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3155 case E_ARC_OSABI_V3:
3156 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
3157 break;
3158 case E_ARC_OSABI_V4:
3159 out = stpcpy (out, ", v4 ABI");
3160 break;
3161 default:
3162 out = stpcpy (out, ", unrecognised ARC OSABI flag");
3163 break;
3165 return out;
3168 static char *
3169 decode_ARM_machine_flags (char *out, unsigned e_flags)
3171 unsigned eabi;
3172 bool unknown = false;
3174 eabi = EF_ARM_EABI_VERSION (e_flags);
3175 e_flags &= ~ EF_ARM_EABIMASK;
3177 /* Handle "generic" ARM flags. */
3178 if (e_flags & EF_ARM_RELEXEC)
3180 out = stpcpy (out, ", relocatable executable");
3181 e_flags &= ~ EF_ARM_RELEXEC;
3184 if (e_flags & EF_ARM_PIC)
3186 out = stpcpy (out, ", position independent");
3187 e_flags &= ~ EF_ARM_PIC;
3190 /* Now handle EABI specific flags. */
3191 switch (eabi)
3193 default:
3194 out = stpcpy (out, ", <unrecognized EABI>");
3195 if (e_flags)
3196 unknown = true;
3197 break;
3199 case EF_ARM_EABI_VER1:
3200 out = stpcpy (out, ", Version1 EABI");
3201 while (e_flags)
3203 unsigned flag;
3205 /* Process flags one bit at a time. */
3206 flag = e_flags & - e_flags;
3207 e_flags &= ~ flag;
3209 switch (flag)
3211 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3212 out = stpcpy (out, ", sorted symbol tables");
3213 break;
3215 default:
3216 unknown = true;
3217 break;
3220 break;
3222 case EF_ARM_EABI_VER2:
3223 out = stpcpy (out, ", Version2 EABI");
3224 while (e_flags)
3226 unsigned flag;
3228 /* Process flags one bit at a time. */
3229 flag = e_flags & - e_flags;
3230 e_flags &= ~ flag;
3232 switch (flag)
3234 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3235 out = stpcpy (out, ", sorted symbol tables");
3236 break;
3238 case EF_ARM_DYNSYMSUSESEGIDX:
3239 out = stpcpy (out, ", dynamic symbols use segment index");
3240 break;
3242 case EF_ARM_MAPSYMSFIRST:
3243 out = stpcpy (out, ", mapping symbols precede others");
3244 break;
3246 default:
3247 unknown = true;
3248 break;
3251 break;
3253 case EF_ARM_EABI_VER3:
3254 out = stpcpy (out, ", Version3 EABI");
3255 break;
3257 case EF_ARM_EABI_VER4:
3258 out = stpcpy (out, ", Version4 EABI");
3259 while (e_flags)
3261 unsigned flag;
3263 /* Process flags one bit at a time. */
3264 flag = e_flags & - e_flags;
3265 e_flags &= ~ flag;
3267 switch (flag)
3269 case EF_ARM_BE8:
3270 out = stpcpy (out, ", BE8");
3271 break;
3273 case EF_ARM_LE8:
3274 out = stpcpy (out, ", LE8");
3275 break;
3277 default:
3278 unknown = true;
3279 break;
3282 break;
3284 case EF_ARM_EABI_VER5:
3285 out = stpcpy (out, ", Version5 EABI");
3286 while (e_flags)
3288 unsigned flag;
3290 /* Process flags one bit at a time. */
3291 flag = e_flags & - e_flags;
3292 e_flags &= ~ flag;
3294 switch (flag)
3296 case EF_ARM_BE8:
3297 out = stpcpy (out, ", BE8");
3298 break;
3300 case EF_ARM_LE8:
3301 out = stpcpy (out, ", LE8");
3302 break;
3304 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3305 out = stpcpy (out, ", soft-float ABI");
3306 break;
3308 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3309 out = stpcpy (out, ", hard-float ABI");
3310 break;
3312 default:
3313 unknown = true;
3314 break;
3317 break;
3319 case EF_ARM_EABI_UNKNOWN:
3320 out = stpcpy (out, ", GNU EABI");
3321 while (e_flags)
3323 unsigned flag;
3325 /* Process flags one bit at a time. */
3326 flag = e_flags & - e_flags;
3327 e_flags &= ~ flag;
3329 switch (flag)
3331 case EF_ARM_INTERWORK:
3332 out = stpcpy (out, ", interworking enabled");
3333 break;
3335 case EF_ARM_APCS_26:
3336 out = stpcpy (out, ", uses APCS/26");
3337 break;
3339 case EF_ARM_APCS_FLOAT:
3340 out = stpcpy (out, ", uses APCS/float");
3341 break;
3343 case EF_ARM_PIC:
3344 out = stpcpy (out, ", position independent");
3345 break;
3347 case EF_ARM_ALIGN8:
3348 out = stpcpy (out, ", 8 bit structure alignment");
3349 break;
3351 case EF_ARM_NEW_ABI:
3352 out = stpcpy (out, ", uses new ABI");
3353 break;
3355 case EF_ARM_OLD_ABI:
3356 out = stpcpy (out, ", uses old ABI");
3357 break;
3359 case EF_ARM_SOFT_FLOAT:
3360 out = stpcpy (out, ", software FP");
3361 break;
3363 case EF_ARM_VFP_FLOAT:
3364 out = stpcpy (out, ", VFP");
3365 break;
3367 case EF_ARM_MAVERICK_FLOAT:
3368 out = stpcpy (out, ", Maverick FP");
3369 break;
3371 default:
3372 unknown = true;
3373 break;
3378 if (unknown)
3379 out = stpcpy (out,_(", <unknown>"));
3380 return out;
3383 static char *
3384 decode_AVR_machine_flags (char *out, unsigned e_flags)
3386 switch (e_flags & EF_AVR_MACH)
3388 case E_AVR_MACH_AVR1:
3389 out = stpcpy (out, ", avr:1");
3390 break;
3391 case E_AVR_MACH_AVR2:
3392 out = stpcpy (out, ", avr:2");
3393 break;
3394 case E_AVR_MACH_AVR25:
3395 out = stpcpy (out, ", avr:25");
3396 break;
3397 case E_AVR_MACH_AVR3:
3398 out = stpcpy (out, ", avr:3");
3399 break;
3400 case E_AVR_MACH_AVR31:
3401 out = stpcpy (out, ", avr:31");
3402 break;
3403 case E_AVR_MACH_AVR35:
3404 out = stpcpy (out, ", avr:35");
3405 break;
3406 case E_AVR_MACH_AVR4:
3407 out = stpcpy (out, ", avr:4");
3408 break;
3409 case E_AVR_MACH_AVR5:
3410 out = stpcpy (out, ", avr:5");
3411 break;
3412 case E_AVR_MACH_AVR51:
3413 out = stpcpy (out, ", avr:51");
3414 break;
3415 case E_AVR_MACH_AVR6:
3416 out = stpcpy (out, ", avr:6");
3417 break;
3418 case E_AVR_MACH_AVRTINY:
3419 out = stpcpy (out, ", avr:100");
3420 break;
3421 case E_AVR_MACH_XMEGA1:
3422 out = stpcpy (out, ", avr:101");
3423 break;
3424 case E_AVR_MACH_XMEGA2:
3425 out = stpcpy (out, ", avr:102");
3426 break;
3427 case E_AVR_MACH_XMEGA3:
3428 out = stpcpy (out, ", avr:103");
3429 break;
3430 case E_AVR_MACH_XMEGA4:
3431 out = stpcpy (out, ", avr:104");
3432 break;
3433 case E_AVR_MACH_XMEGA5:
3434 out = stpcpy (out, ", avr:105");
3435 break;
3436 case E_AVR_MACH_XMEGA6:
3437 out = stpcpy (out, ", avr:106");
3438 break;
3439 case E_AVR_MACH_XMEGA7:
3440 out = stpcpy (out, ", avr:107");
3441 break;
3442 default:
3443 out = stpcpy (out, ", avr:<unknown>");
3444 break;
3447 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3448 out = stpcpy (out, ", link-relax");
3449 return out;
3452 static char *
3453 decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3455 if (e_flags & EF_BFIN_PIC)
3456 out = stpcpy (out, ", PIC");
3458 if (e_flags & EF_BFIN_FDPIC)
3459 out = stpcpy (out, ", FDPIC");
3461 if (e_flags & EF_BFIN_CODE_IN_L1)
3462 out = stpcpy (out, ", code in L1");
3464 if (e_flags & EF_BFIN_DATA_IN_L1)
3465 out = stpcpy (out, ", data in L1");
3466 return out;
3469 static char *
3470 decode_FRV_machine_flags (char *out, unsigned e_flags)
3472 switch (e_flags & EF_FRV_CPU_MASK)
3474 case EF_FRV_CPU_GENERIC:
3475 break;
3477 default:
3478 out = stpcpy (out, ", fr???");
3479 break;
3481 case EF_FRV_CPU_FR300:
3482 out = stpcpy (out, ", fr300");
3483 break;
3485 case EF_FRV_CPU_FR400:
3486 out = stpcpy (out, ", fr400");
3487 break;
3488 case EF_FRV_CPU_FR405:
3489 out = stpcpy (out, ", fr405");
3490 break;
3492 case EF_FRV_CPU_FR450:
3493 out = stpcpy (out, ", fr450");
3494 break;
3496 case EF_FRV_CPU_FR500:
3497 out = stpcpy (out, ", fr500");
3498 break;
3499 case EF_FRV_CPU_FR550:
3500 out = stpcpy (out, ", fr550");
3501 break;
3503 case EF_FRV_CPU_SIMPLE:
3504 out = stpcpy (out, ", simple");
3505 break;
3506 case EF_FRV_CPU_TOMCAT:
3507 out = stpcpy (out, ", tomcat");
3508 break;
3510 return out;
3513 static char *
3514 decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3516 if ((e_flags & EF_IA_64_ABI64))
3517 out = stpcpy (out, ", 64-bit");
3518 else
3519 out = stpcpy (out, ", 32-bit");
3520 if ((e_flags & EF_IA_64_REDUCEDFP))
3521 out = stpcpy (out, ", reduced fp model");
3522 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3523 out = stpcpy (out, ", no function descriptors, constant gp");
3524 else if ((e_flags & EF_IA_64_CONS_GP))
3525 out = stpcpy (out, ", constant gp");
3526 if ((e_flags & EF_IA_64_ABSOLUTE))
3527 out = stpcpy (out, ", absolute");
3528 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3530 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3531 out = stpcpy (out, ", vms_linkages");
3532 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3534 case EF_IA_64_VMS_COMCOD_SUCCESS:
3535 break;
3536 case EF_IA_64_VMS_COMCOD_WARNING:
3537 out = stpcpy (out, ", warning");
3538 break;
3539 case EF_IA_64_VMS_COMCOD_ERROR:
3540 out = stpcpy (out, ", error");
3541 break;
3542 case EF_IA_64_VMS_COMCOD_ABORT:
3543 out = stpcpy (out, ", abort");
3544 break;
3545 default:
3546 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3547 e_flags & EF_IA_64_VMS_COMCOD);
3548 out = stpcpy (out, ", <unknown>");
3551 return out;
3554 static char *
3555 decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3557 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3558 out = stpcpy (out, ", SOFT-FLOAT");
3559 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3560 out = stpcpy (out, ", SINGLE-FLOAT");
3561 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3562 out = stpcpy (out, ", DOUBLE-FLOAT");
3564 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3565 out = stpcpy (out, ", OBJ-v0");
3566 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3567 out = stpcpy (out, ", OBJ-v1");
3568 return out;
3571 static char *
3572 decode_M68K_machine_flags (char *out, unsigned int e_flags)
3574 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3575 out = stpcpy (out, ", m68000");
3576 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3577 out = stpcpy (out, ", cpu32");
3578 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3579 out = stpcpy (out, ", fido_a");
3580 else
3582 char const *isa = _("unknown");
3583 char const *mac = _("unknown mac");
3584 char const *additional = NULL;
3586 switch (e_flags & EF_M68K_CF_ISA_MASK)
3588 case EF_M68K_CF_ISA_A_NODIV:
3589 isa = "A";
3590 additional = ", nodiv";
3591 break;
3592 case EF_M68K_CF_ISA_A:
3593 isa = "A";
3594 break;
3595 case EF_M68K_CF_ISA_A_PLUS:
3596 isa = "A+";
3597 break;
3598 case EF_M68K_CF_ISA_B_NOUSP:
3599 isa = "B";
3600 additional = ", nousp";
3601 break;
3602 case EF_M68K_CF_ISA_B:
3603 isa = "B";
3604 break;
3605 case EF_M68K_CF_ISA_C:
3606 isa = "C";
3607 break;
3608 case EF_M68K_CF_ISA_C_NODIV:
3609 isa = "C";
3610 additional = ", nodiv";
3611 break;
3613 out = stpcpy (out, ", cf, isa ");
3614 out = stpcpy (out, isa);
3615 if (additional)
3616 out = stpcpy (out, additional);
3617 if (e_flags & EF_M68K_CF_FLOAT)
3618 out = stpcpy (out, ", float");
3619 switch (e_flags & EF_M68K_CF_MAC_MASK)
3621 case 0:
3622 mac = NULL;
3623 break;
3624 case EF_M68K_CF_MAC:
3625 mac = "mac";
3626 break;
3627 case EF_M68K_CF_EMAC:
3628 mac = "emac";
3629 break;
3630 case EF_M68K_CF_EMAC_B:
3631 mac = "emac_b";
3632 break;
3634 if (mac)
3636 out = stpcpy (out, ", ");
3637 out = stpcpy (out, mac);
3640 return out;
3643 static char *
3644 decode_MeP_machine_flags (char *out, unsigned int e_flags)
3646 switch (e_flags & EF_MEP_CPU_MASK)
3648 case EF_MEP_CPU_MEP:
3649 out = stpcpy (out, ", generic MeP");
3650 break;
3651 case EF_MEP_CPU_C2:
3652 out = stpcpy (out, ", MeP C2");
3653 break;
3654 case EF_MEP_CPU_C3:
3655 out = stpcpy (out, ", MeP C3");
3656 break;
3657 case EF_MEP_CPU_C4:
3658 out = stpcpy (out, ", MeP C4");
3659 break;
3660 case EF_MEP_CPU_C5:
3661 out = stpcpy (out, ", MeP C5");
3662 break;
3663 case EF_MEP_CPU_H1:
3664 out = stpcpy (out, ", MeP H1");
3665 break;
3666 default:
3667 out = stpcpy (out, _(", <unknown MeP cpu type>"));
3668 break;
3671 switch (e_flags & EF_MEP_COP_MASK)
3673 case EF_MEP_COP_NONE:
3674 break;
3675 case EF_MEP_COP_AVC:
3676 out = stpcpy (out, ", AVC coprocessor");
3677 break;
3678 case EF_MEP_COP_AVC2:
3679 out = stpcpy (out, ", AVC2 coprocessor");
3680 break;
3681 case EF_MEP_COP_FMAX:
3682 out = stpcpy (out, ", FMAX coprocessor");
3683 break;
3684 case EF_MEP_COP_IVC2:
3685 out = stpcpy (out, ", IVC2 coprocessor");
3686 break;
3687 default:
3688 out = stpcpy (out, _("<unknown MeP copro type>"));
3689 break;
3692 if (e_flags & EF_MEP_LIBRARY)
3693 out = stpcpy (out, ", Built for Library");
3695 if (e_flags & EF_MEP_INDEX_MASK)
3696 out += sprintf (out, ", Configuration Index: %#x",
3697 e_flags & EF_MEP_INDEX_MASK);
3699 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3700 out += sprintf (out, _(", unknown flags bits: %#x"),
3701 e_flags & ~ EF_MEP_ALL_FLAGS);
3702 return out;
3705 static char *
3706 decode_MIPS_machine_flags (char *out, unsigned int e_flags)
3708 if (e_flags & EF_MIPS_NOREORDER)
3709 out = stpcpy (out, ", noreorder");
3711 if (e_flags & EF_MIPS_PIC)
3712 out = stpcpy (out, ", pic");
3714 if (e_flags & EF_MIPS_CPIC)
3715 out = stpcpy (out, ", cpic");
3717 if (e_flags & EF_MIPS_UCODE)
3718 out = stpcpy (out, ", ugen_reserved");
3720 if (e_flags & EF_MIPS_ABI2)
3721 out = stpcpy (out, ", abi2");
3723 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3724 out = stpcpy (out, ", odk first");
3726 if (e_flags & EF_MIPS_32BITMODE)
3727 out = stpcpy (out, ", 32bitmode");
3729 if (e_flags & EF_MIPS_NAN2008)
3730 out = stpcpy (out, ", nan2008");
3732 if (e_flags & EF_MIPS_FP64)
3733 out = stpcpy (out, ", fp64");
3735 switch ((e_flags & EF_MIPS_MACH))
3737 case EF_MIPS_MACH_3900:
3738 out = stpcpy (out, ", 3900");
3739 break;
3740 case EF_MIPS_MACH_4010:
3741 out = stpcpy (out, ", 4010");
3742 break;
3743 case EF_MIPS_MACH_4100:
3744 out = stpcpy (out, ", 4100");
3745 break;
3746 case EF_MIPS_MACH_4111:
3747 out = stpcpy (out, ", 4111");
3748 break;
3749 case EF_MIPS_MACH_4120:
3750 out = stpcpy (out, ", 4120");
3751 break;
3752 case EF_MIPS_MACH_4650:
3753 out = stpcpy (out, ", 4650");
3754 break;
3755 case EF_MIPS_MACH_5400:
3756 out = stpcpy (out, ", 5400");
3757 break;
3758 case EF_MIPS_MACH_5500:
3759 out = stpcpy (out, ", 5500");
3760 break;
3761 case EF_MIPS_MACH_5900:
3762 out = stpcpy (out, ", 5900");
3763 break;
3764 case EF_MIPS_MACH_SB1:
3765 out = stpcpy (out, ", sb1");
3766 break;
3767 case EF_MIPS_MACH_9000:
3768 out = stpcpy (out, ", 9000");
3769 break;
3770 case EF_MIPS_MACH_LS2E:
3771 out = stpcpy (out, ", loongson-2e");
3772 break;
3773 case EF_MIPS_MACH_LS2F:
3774 out = stpcpy (out, ", loongson-2f");
3775 break;
3776 case EF_MIPS_MACH_GS464:
3777 out = stpcpy (out, ", gs464");
3778 break;
3779 case EF_MIPS_MACH_GS464E:
3780 out = stpcpy (out, ", gs464e");
3781 break;
3782 case EF_MIPS_MACH_GS264E:
3783 out = stpcpy (out, ", gs264e");
3784 break;
3785 case EF_MIPS_MACH_OCTEON:
3786 out = stpcpy (out, ", octeon");
3787 break;
3788 case EF_MIPS_MACH_OCTEON2:
3789 out = stpcpy (out, ", octeon2");
3790 break;
3791 case EF_MIPS_MACH_OCTEON3:
3792 out = stpcpy (out, ", octeon3");
3793 break;
3794 case EF_MIPS_MACH_XLR:
3795 out = stpcpy (out, ", xlr");
3796 break;
3797 case EF_MIPS_MACH_IAMR2:
3798 out = stpcpy (out, ", interaptiv-mr2");
3799 break;
3800 case EF_MIPS_MACH_ALLEGREX:
3801 out = stpcpy (out, ", allegrex");
3802 break;
3803 case 0:
3804 /* We simply ignore the field in this case to avoid confusion:
3805 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3806 extension. */
3807 break;
3808 default:
3809 out = stpcpy (out, _(", unknown CPU"));
3810 break;
3813 switch ((e_flags & EF_MIPS_ABI))
3815 case EF_MIPS_ABI_O32:
3816 out = stpcpy (out, ", o32");
3817 break;
3818 case EF_MIPS_ABI_O64:
3819 out = stpcpy (out, ", o64");
3820 break;
3821 case EF_MIPS_ABI_EABI32:
3822 out = stpcpy (out, ", eabi32");
3823 break;
3824 case EF_MIPS_ABI_EABI64:
3825 out = stpcpy (out, ", eabi64");
3826 break;
3827 case 0:
3828 /* We simply ignore the field in this case to avoid confusion:
3829 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3830 This means it is likely to be an o32 file, but not for
3831 sure. */
3832 break;
3833 default:
3834 out = stpcpy (out, _(", unknown ABI"));
3835 break;
3838 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3839 out = stpcpy (out, ", mdmx");
3841 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3842 out = stpcpy (out, ", mips16");
3844 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3845 out = stpcpy (out, ", micromips");
3847 switch ((e_flags & EF_MIPS_ARCH))
3849 case EF_MIPS_ARCH_1:
3850 out = stpcpy (out, ", mips1");
3851 break;
3852 case EF_MIPS_ARCH_2:
3853 out = stpcpy (out, ", mips2");
3854 break;
3855 case EF_MIPS_ARCH_3:
3856 out = stpcpy (out, ", mips3");
3857 break;
3858 case EF_MIPS_ARCH_4:
3859 out = stpcpy (out, ", mips4");
3860 break;
3861 case EF_MIPS_ARCH_5:
3862 out = stpcpy (out, ", mips5");
3863 break;
3864 case EF_MIPS_ARCH_32:
3865 out = stpcpy (out, ", mips32");
3866 break;
3867 case EF_MIPS_ARCH_32R2:
3868 out = stpcpy (out, ", mips32r2");
3869 break;
3870 case EF_MIPS_ARCH_32R6:
3871 out = stpcpy (out, ", mips32r6");
3872 break;
3873 case EF_MIPS_ARCH_64:
3874 out = stpcpy (out, ", mips64");
3875 break;
3876 case EF_MIPS_ARCH_64R2:
3877 out = stpcpy (out, ", mips64r2");
3878 break;
3879 case EF_MIPS_ARCH_64R6:
3880 out = stpcpy (out, ", mips64r6");
3881 break;
3882 default:
3883 out = stpcpy (out, _(", unknown ISA"));
3884 break;
3886 return out;
3889 static char *
3890 decode_MSP430_machine_flags (char *out, unsigned e_flags)
3892 out = stpcpy (out, _(": architecture variant: "));
3893 switch (e_flags & EF_MSP430_MACH)
3895 case E_MSP430_MACH_MSP430x11:
3896 out = stpcpy (out, "MSP430x11");
3897 break;
3898 case E_MSP430_MACH_MSP430x11x1:
3899 out = stpcpy (out, "MSP430x11x1 ");
3900 break;
3901 case E_MSP430_MACH_MSP430x12:
3902 out = stpcpy (out, "MSP430x12");
3903 break;
3904 case E_MSP430_MACH_MSP430x13:
3905 out = stpcpy (out, "MSP430x13");
3906 break;
3907 case E_MSP430_MACH_MSP430x14:
3908 out = stpcpy (out, "MSP430x14");
3909 break;
3910 case E_MSP430_MACH_MSP430x15:
3911 out = stpcpy (out, "MSP430x15");
3912 break;
3913 case E_MSP430_MACH_MSP430x16:
3914 out = stpcpy (out, "MSP430x16");
3915 break;
3916 case E_MSP430_MACH_MSP430x31:
3917 out = stpcpy (out, "MSP430x31");
3918 break;
3919 case E_MSP430_MACH_MSP430x32:
3920 out = stpcpy (out, "MSP430x32");
3921 break;
3922 case E_MSP430_MACH_MSP430x33:
3923 out = stpcpy (out, "MSP430x33");
3924 break;
3925 case E_MSP430_MACH_MSP430x41:
3926 out = stpcpy (out, "MSP430x41");
3927 break;
3928 case E_MSP430_MACH_MSP430x42:
3929 out = stpcpy (out, "MSP430x42");
3930 break;
3931 case E_MSP430_MACH_MSP430x43:
3932 out = stpcpy (out, "MSP430x43");
3933 break;
3934 case E_MSP430_MACH_MSP430x44:
3935 out = stpcpy (out, "MSP430x44");
3936 break;
3937 case E_MSP430_MACH_MSP430X :
3938 out = stpcpy (out, "MSP430X");
3939 break;
3940 default:
3941 out = stpcpy (out, _(": unknown"));
3942 break;
3945 if (e_flags & ~ EF_MSP430_MACH)
3946 out = stpcpy (out, _(": unknown extra flag bits also present"));
3947 return out;
3950 static char *
3951 decode_NDS32_machine_flags (char *out, unsigned e_flags)
3953 unsigned abi;
3954 unsigned arch;
3955 unsigned config;
3956 unsigned version;
3957 bool has_fpu = false;
3959 static const char *ABI_STRINGS[] =
3961 "ABI v0", /* use r5 as return register; only used in N1213HC */
3962 "ABI v1", /* use r0 as return register */
3963 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3964 "ABI v2fp", /* for FPU */
3965 "AABI",
3966 "ABI2 FP+"
3968 static const char *VER_STRINGS[] =
3970 "Andes ELF V1.3 or older",
3971 "Andes ELF V1.3.1",
3972 "Andes ELF V1.4"
3974 static const char *ARCH_STRINGS[] =
3977 "Andes Star v1.0",
3978 "Andes Star v2.0",
3979 "Andes Star v3.0",
3980 "Andes Star v3.0m"
3983 abi = EF_NDS_ABI & e_flags;
3984 arch = EF_NDS_ARCH & e_flags;
3985 config = EF_NDS_INST & e_flags;
3986 version = EF_NDS32_ELF_VERSION & e_flags;
3988 switch (abi)
3990 case E_NDS_ABI_V0:
3991 case E_NDS_ABI_V1:
3992 case E_NDS_ABI_V2:
3993 case E_NDS_ABI_V2FP:
3994 case E_NDS_ABI_AABI:
3995 case E_NDS_ABI_V2FP_PLUS:
3996 /* In case there are holes in the array. */
3997 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3998 break;
4000 default:
4001 out = stpcpy (out, ", <unrecognized ABI>");
4002 break;
4005 switch (version)
4007 case E_NDS32_ELF_VER_1_2:
4008 case E_NDS32_ELF_VER_1_3:
4009 case E_NDS32_ELF_VER_1_4:
4010 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
4011 break;
4013 default:
4014 out = stpcpy (out, ", <unrecognized ELF version number>");
4015 break;
4018 if (E_NDS_ABI_V0 == abi)
4020 /* OLD ABI; only used in N1213HC, has performance extension 1. */
4021 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
4022 if (arch == E_NDS_ARCH_STAR_V1_0)
4023 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
4024 return out;
4027 switch (arch)
4029 case E_NDS_ARCH_STAR_V1_0:
4030 case E_NDS_ARCH_STAR_V2_0:
4031 case E_NDS_ARCH_STAR_V3_0:
4032 case E_NDS_ARCH_STAR_V3_M:
4033 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
4034 break;
4036 default:
4037 out = stpcpy (out, ", <unrecognized architecture>");
4038 /* ARCH version determines how the e_flags are interpreted.
4039 If it is unknown, we cannot proceed. */
4040 return out;
4043 /* Newer ABI; Now handle architecture specific flags. */
4044 if (arch == E_NDS_ARCH_STAR_V1_0)
4046 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4047 out = stpcpy (out, ", MFUSR_PC");
4049 if (!(config & E_NDS32_HAS_NO_MAC_INST))
4050 out = stpcpy (out, ", MAC");
4052 if (config & E_NDS32_HAS_DIV_INST)
4053 out = stpcpy (out, ", DIV");
4055 if (config & E_NDS32_HAS_16BIT_INST)
4056 out = stpcpy (out, ", 16b");
4058 else
4060 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4062 if (version <= E_NDS32_ELF_VER_1_3)
4063 out = stpcpy (out, ", [B8]");
4064 else
4065 out = stpcpy (out, ", EX9");
4068 if (config & E_NDS32_HAS_MAC_DX_INST)
4069 out = stpcpy (out, ", MAC_DX");
4071 if (config & E_NDS32_HAS_DIV_DX_INST)
4072 out = stpcpy (out, ", DIV_DX");
4074 if (config & E_NDS32_HAS_16BIT_INST)
4076 if (version <= E_NDS32_ELF_VER_1_3)
4077 out = stpcpy (out, ", 16b");
4078 else
4079 out = stpcpy (out, ", IFC");
4083 if (config & E_NDS32_HAS_EXT_INST)
4084 out = stpcpy (out, ", PERF1");
4086 if (config & E_NDS32_HAS_EXT2_INST)
4087 out = stpcpy (out, ", PERF2");
4089 if (config & E_NDS32_HAS_FPU_INST)
4091 has_fpu = true;
4092 out = stpcpy (out, ", FPU_SP");
4095 if (config & E_NDS32_HAS_FPU_DP_INST)
4097 has_fpu = true;
4098 out = stpcpy (out, ", FPU_DP");
4101 if (config & E_NDS32_HAS_FPU_MAC_INST)
4103 has_fpu = true;
4104 out = stpcpy (out, ", FPU_MAC");
4107 if (has_fpu)
4109 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4111 case E_NDS32_FPU_REG_8SP_4DP:
4112 out = stpcpy (out, ", FPU_REG:8/4");
4113 break;
4114 case E_NDS32_FPU_REG_16SP_8DP:
4115 out = stpcpy (out, ", FPU_REG:16/8");
4116 break;
4117 case E_NDS32_FPU_REG_32SP_16DP:
4118 out = stpcpy (out, ", FPU_REG:32/16");
4119 break;
4120 case E_NDS32_FPU_REG_32SP_32DP:
4121 out = stpcpy (out, ", FPU_REG:32/32");
4122 break;
4126 if (config & E_NDS32_HAS_AUDIO_INST)
4127 out = stpcpy (out, ", AUDIO");
4129 if (config & E_NDS32_HAS_STRING_INST)
4130 out = stpcpy (out, ", STR");
4132 if (config & E_NDS32_HAS_REDUCED_REGS)
4133 out = stpcpy (out, ", 16REG");
4135 if (config & E_NDS32_HAS_VIDEO_INST)
4137 if (version <= E_NDS32_ELF_VER_1_3)
4138 out = stpcpy (out, ", VIDEO");
4139 else
4140 out = stpcpy (out, ", SATURATION");
4143 if (config & E_NDS32_HAS_ENCRIPT_INST)
4144 out = stpcpy (out, ", ENCRP");
4146 if (config & E_NDS32_HAS_L2C_INST)
4147 out = stpcpy (out, ", L2C");
4149 return out;
4152 static char *
4153 decode_PARISC_machine_flags (char *out, unsigned e_flags)
4155 switch (e_flags & EF_PARISC_ARCH)
4157 case EFA_PARISC_1_0:
4158 out = stpcpy (out, ", PA-RISC 1.0");
4159 break;
4160 case EFA_PARISC_1_1:
4161 out = stpcpy (out, ", PA-RISC 1.1");
4162 break;
4163 case EFA_PARISC_2_0:
4164 out = stpcpy (out, ", PA-RISC 2.0");
4165 break;
4166 default:
4167 break;
4169 if (e_flags & EF_PARISC_TRAPNIL)
4170 out = stpcpy (out, ", trapnil");
4171 if (e_flags & EF_PARISC_EXT)
4172 out = stpcpy (out, ", ext");
4173 if (e_flags & EF_PARISC_LSB)
4174 out = stpcpy (out, ", lsb");
4175 if (e_flags & EF_PARISC_WIDE)
4176 out = stpcpy (out, ", wide");
4177 if (e_flags & EF_PARISC_NO_KABP)
4178 out = stpcpy (out, ", no kabp");
4179 if (e_flags & EF_PARISC_LAZYSWAP)
4180 out = stpcpy (out, ", lazyswap");
4181 return out;
4184 static char *
4185 decode_RISCV_machine_flags (char *out, unsigned e_flags)
4187 if (e_flags & EF_RISCV_RVC)
4188 out = stpcpy (out, ", RVC");
4190 if (e_flags & EF_RISCV_RVE)
4191 out = stpcpy (out, ", RVE");
4193 if (e_flags & EF_RISCV_TSO)
4194 out = stpcpy (out, ", TSO");
4196 switch (e_flags & EF_RISCV_FLOAT_ABI)
4198 case EF_RISCV_FLOAT_ABI_SOFT:
4199 out = stpcpy (out, ", soft-float ABI");
4200 break;
4202 case EF_RISCV_FLOAT_ABI_SINGLE:
4203 out = stpcpy (out, ", single-float ABI");
4204 break;
4206 case EF_RISCV_FLOAT_ABI_DOUBLE:
4207 out = stpcpy (out, ", double-float ABI");
4208 break;
4210 case EF_RISCV_FLOAT_ABI_QUAD:
4211 out = stpcpy (out, ", quad-float ABI");
4212 break;
4214 return out;
4217 static char *
4218 decode_RL78_machine_flags (char *out, unsigned e_flags)
4220 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4222 case E_FLAG_RL78_ANY_CPU:
4223 break;
4224 case E_FLAG_RL78_G10:
4225 out = stpcpy (out, ", G10");
4226 break;
4227 case E_FLAG_RL78_G13:
4228 out = stpcpy (out, ", G13");
4229 break;
4230 case E_FLAG_RL78_G14:
4231 out = stpcpy (out, ", G14");
4232 break;
4234 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4235 out = stpcpy (out, ", 64-bit doubles");
4236 return out;
4239 static char *
4240 decode_RX_machine_flags (char *out, unsigned e_flags)
4242 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4243 out = stpcpy (out, ", 64-bit doubles");
4244 if (e_flags & E_FLAG_RX_DSP)
4245 out = stpcpy (out, ", dsp");
4246 if (e_flags & E_FLAG_RX_PID)
4247 out = stpcpy (out, ", pid");
4248 if (e_flags & E_FLAG_RX_ABI)
4249 out = stpcpy (out, ", RX ABI");
4250 if (e_flags & E_FLAG_RX_SINSNS_SET)
4251 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4252 ? ", uses String instructions"
4253 : ", bans String instructions"));
4254 if (e_flags & E_FLAG_RX_V2)
4255 out = stpcpy (out, ", V2");
4256 if (e_flags & E_FLAG_RX_V3)
4257 out = stpcpy (out, ", V3");
4258 return out;
4261 static char *
4262 decode_SH_machine_flags (char *out, unsigned e_flags)
4264 switch ((e_flags & EF_SH_MACH_MASK))
4266 case EF_SH1:
4267 out = stpcpy (out, ", sh1");
4268 break;
4269 case EF_SH2:
4270 out = stpcpy (out, ", sh2");
4271 break;
4272 case EF_SH3:
4273 out = stpcpy (out, ", sh3");
4274 break;
4275 case EF_SH_DSP:
4276 out = stpcpy (out, ", sh-dsp");
4277 break;
4278 case EF_SH3_DSP:
4279 out = stpcpy (out, ", sh3-dsp");
4280 break;
4281 case EF_SH4AL_DSP:
4282 out = stpcpy (out, ", sh4al-dsp");
4283 break;
4284 case EF_SH3E:
4285 out = stpcpy (out, ", sh3e");
4286 break;
4287 case EF_SH4:
4288 out = stpcpy (out, ", sh4");
4289 break;
4290 case EF_SH5:
4291 out = stpcpy (out, ", sh5");
4292 break;
4293 case EF_SH2E:
4294 out = stpcpy (out, ", sh2e");
4295 break;
4296 case EF_SH4A:
4297 out = stpcpy (out, ", sh4a");
4298 break;
4299 case EF_SH2A:
4300 out = stpcpy (out, ", sh2a");
4301 break;
4302 case EF_SH4_NOFPU:
4303 out = stpcpy (out, ", sh4-nofpu");
4304 break;
4305 case EF_SH4A_NOFPU:
4306 out = stpcpy (out, ", sh4a-nofpu");
4307 break;
4308 case EF_SH2A_NOFPU:
4309 out = stpcpy (out, ", sh2a-nofpu");
4310 break;
4311 case EF_SH3_NOMMU:
4312 out = stpcpy (out, ", sh3-nommu");
4313 break;
4314 case EF_SH4_NOMMU_NOFPU:
4315 out = stpcpy (out, ", sh4-nommu-nofpu");
4316 break;
4317 case EF_SH2A_SH4_NOFPU:
4318 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4319 break;
4320 case EF_SH2A_SH3_NOFPU:
4321 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4322 break;
4323 case EF_SH2A_SH4:
4324 out = stpcpy (out, ", sh2a-or-sh4");
4325 break;
4326 case EF_SH2A_SH3E:
4327 out = stpcpy (out, ", sh2a-or-sh3e");
4328 break;
4329 default:
4330 out = stpcpy (out, _(", unknown ISA"));
4331 break;
4334 if (e_flags & EF_SH_PIC)
4335 out = stpcpy (out, ", pic");
4337 if (e_flags & EF_SH_FDPIC)
4338 out = stpcpy (out, ", fdpic");
4339 return out;
4342 static char *
4343 decode_SPARC_machine_flags (char *out, unsigned e_flags)
4345 if (e_flags & EF_SPARC_32PLUS)
4346 out = stpcpy (out, ", v8+");
4348 if (e_flags & EF_SPARC_SUN_US1)
4349 out = stpcpy (out, ", ultrasparcI");
4351 if (e_flags & EF_SPARC_SUN_US3)
4352 out = stpcpy (out, ", ultrasparcIII");
4354 if (e_flags & EF_SPARC_HAL_R1)
4355 out = stpcpy (out, ", halr1");
4357 if (e_flags & EF_SPARC_LEDATA)
4358 out = stpcpy (out, ", ledata");
4360 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4361 out = stpcpy (out, ", tso");
4363 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4364 out = stpcpy (out, ", pso");
4366 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4367 out = stpcpy (out, ", rmo");
4368 return out;
4371 static char *
4372 decode_V800_machine_flags (char *out, unsigned int e_flags)
4374 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4375 out = stpcpy (out, ", RH850 ABI");
4377 if (e_flags & EF_V800_850E3)
4378 out = stpcpy (out, ", V3 architecture");
4380 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4381 out = stpcpy (out, ", FPU not used");
4383 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4384 out = stpcpy (out, ", regmode: COMMON");
4386 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4387 out = stpcpy (out, ", r4 not used");
4389 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4390 out = stpcpy (out, ", r30 not used");
4392 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4393 out = stpcpy (out, ", r5 not used");
4395 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4396 out = stpcpy (out, ", r2 not used");
4398 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4400 switch (e_flags & - e_flags)
4402 case EF_RH850_FPU_DOUBLE:
4403 out = stpcpy (out, ", double precision FPU");
4404 break;
4405 case EF_RH850_FPU_SINGLE:
4406 out = stpcpy (out, ", single precision FPU");
4407 break;
4408 case EF_RH850_REGMODE22:
4409 out = stpcpy (out, ", regmode:22");
4410 break;
4411 case EF_RH850_REGMODE32:
4412 out = stpcpy (out, ", regmode:23");
4413 break;
4414 case EF_RH850_GP_FIX:
4415 out = stpcpy (out, ", r4 fixed");
4416 break;
4417 case EF_RH850_GP_NOFIX:
4418 out = stpcpy (out, ", r4 free");
4419 break;
4420 case EF_RH850_EP_FIX:
4421 out = stpcpy (out, ", r30 fixed");
4422 break;
4423 case EF_RH850_EP_NOFIX:
4424 out = stpcpy (out, ", r30 free");
4425 break;
4426 case EF_RH850_TP_FIX:
4427 out = stpcpy (out, ", r5 fixed");
4428 break;
4429 case EF_RH850_TP_NOFIX:
4430 out = stpcpy (out, ", r5 free");
4431 break;
4432 case EF_RH850_REG2_RESERVE:
4433 out = stpcpy (out, ", r2 fixed");
4434 break;
4435 case EF_RH850_REG2_NORESERVE:
4436 out = stpcpy (out, ", r2 free");
4437 break;
4438 default:
4439 break;
4442 return out;
4445 static char *
4446 decode_V850_machine_flags (char *out, unsigned int e_flags)
4448 switch (e_flags & EF_V850_ARCH)
4450 case E_V850E3V5_ARCH:
4451 out = stpcpy (out, ", v850e3v5");
4452 break;
4453 case E_V850E2V3_ARCH:
4454 out = stpcpy (out, ", v850e2v3");
4455 break;
4456 case E_V850E2_ARCH:
4457 out = stpcpy (out, ", v850e2");
4458 break;
4459 case E_V850E1_ARCH:
4460 out = stpcpy (out, ", v850e1");
4461 break;
4462 case E_V850E_ARCH:
4463 out = stpcpy (out, ", v850e");
4464 break;
4465 case E_V850_ARCH:
4466 out = stpcpy (out, ", v850");
4467 break;
4468 default:
4469 out = stpcpy (out, _(", unknown v850 architecture variant"));
4470 break;
4472 return out;
4475 static char *
4476 decode_Z80_machine_flags (char *out, unsigned int e_flags)
4478 switch (e_flags & EF_Z80_MACH_MSK)
4480 case EF_Z80_MACH_Z80:
4481 out = stpcpy (out, ", Z80");
4482 break;
4483 case EF_Z80_MACH_Z180:
4484 out = stpcpy (out, ", Z180");
4485 break;
4486 case EF_Z80_MACH_R800:
4487 out = stpcpy (out, ", R800");
4488 break;
4489 case EF_Z80_MACH_EZ80_Z80:
4490 out = stpcpy (out, ", EZ80");
4491 break;
4492 case EF_Z80_MACH_EZ80_ADL:
4493 out = stpcpy (out, ", EZ80, ADL");
4494 break;
4495 case EF_Z80_MACH_GBZ80:
4496 out = stpcpy (out, ", GBZ80");
4497 break;
4498 case EF_Z80_MACH_Z80N:
4499 out = stpcpy (out, ", Z80N");
4500 break;
4501 default:
4502 out = stpcpy (out, _(", unknown"));
4503 break;
4505 return out;
4508 static char *
4509 decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
4511 unsigned char *e_ident = filedata->file_header.e_ident;
4512 unsigned char osabi = e_ident[EI_OSABI];
4513 unsigned char abiversion = e_ident[EI_ABIVERSION];
4514 unsigned int mach;
4516 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4517 it has been deprecated for a while.
4519 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4520 of writing, they use the same flags as HSA v3, so the code below uses that
4521 assumption. */
4522 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
4523 return out;
4525 mach = e_flags & EF_AMDGPU_MACH;
4526 switch (mach)
4528 #define AMDGPU_CASE(code, string) \
4529 case code: out = stpcpy (out, ", " string); break;
4530 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4531 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4532 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4533 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4534 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4535 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4536 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4537 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4538 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4539 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4540 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4541 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4542 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4543 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4544 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4545 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4546 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4547 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4548 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4549 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4550 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4551 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4552 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4553 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4554 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
4555 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100")
4556 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101")
4557 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102")
4558 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4559 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4560 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4561 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4562 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4563 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4564 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4565 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4566 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4567 default:
4568 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
4569 break;
4570 #undef AMDGPU_CASE
4573 e_flags &= ~EF_AMDGPU_MACH;
4575 if ((osabi == ELFOSABI_AMDGPU_HSA
4576 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4577 || osabi != ELFOSABI_AMDGPU_HSA)
4579 /* For HSA v3 and other OS ABIs. */
4580 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4582 out = stpcpy (out, ", xnack on");
4583 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4586 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4588 out = stpcpy (out, ", sramecc on");
4589 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4592 else
4594 /* For HSA v4+. */
4595 int xnack, sramecc;
4597 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4598 switch (xnack)
4600 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4601 break;
4603 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
4604 out = stpcpy (out, ", xnack any");
4605 break;
4607 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
4608 out = stpcpy (out, ", xnack off");
4609 break;
4611 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
4612 out = stpcpy (out, ", xnack on");
4613 break;
4615 default:
4616 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
4617 break;
4620 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4622 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4623 switch (sramecc)
4625 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4626 break;
4628 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
4629 out = stpcpy (out, ", sramecc any");
4630 break;
4632 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
4633 out = stpcpy (out, ", sramecc off");
4634 break;
4636 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
4637 out = stpcpy (out, ", sramecc on");
4638 break;
4640 default:
4641 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
4642 break;
4645 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4648 if (e_flags != 0)
4649 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4650 return out;
4653 static char *
4654 get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
4656 static char buf[1024];
4657 char *out = buf;
4659 buf[0] = '\0';
4661 if (e_flags)
4663 switch (e_machine)
4665 default:
4666 break;
4668 case EM_ARC_COMPACT3:
4669 out = stpcpy (out, ", HS5x");
4670 break;
4672 case EM_ARC_COMPACT3_64:
4673 out = stpcpy (out, ", HS6x");
4674 break;
4676 case EM_ARC_COMPACT2:
4677 case EM_ARC_COMPACT:
4678 out = decode_ARC_machine_flags (out, e_flags, e_machine);
4679 break;
4681 case EM_ARM:
4682 out = decode_ARM_machine_flags (out, e_flags);
4683 break;
4685 case EM_AVR:
4686 out = decode_AVR_machine_flags (out, e_flags);
4687 break;
4689 case EM_BLACKFIN:
4690 out = decode_BLACKFIN_machine_flags (out, e_flags);
4691 break;
4693 case EM_CYGNUS_FRV:
4694 out = decode_FRV_machine_flags (out, e_flags);
4695 break;
4697 case EM_68K:
4698 out = decode_M68K_machine_flags (out, e_flags);
4699 break;
4701 case EM_AMDGPU:
4702 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
4703 break;
4705 case EM_CYGNUS_MEP:
4706 out = decode_MeP_machine_flags (out, e_flags);
4707 break;
4709 case EM_PPC:
4710 if (e_flags & EF_PPC_EMB)
4711 out = stpcpy (out, ", emb");
4713 if (e_flags & EF_PPC_RELOCATABLE)
4714 out = stpcpy (out, _(", relocatable"));
4716 if (e_flags & EF_PPC_RELOCATABLE_LIB)
4717 out = stpcpy (out, _(", relocatable-lib"));
4718 break;
4720 case EM_PPC64:
4721 if (e_flags & EF_PPC64_ABI)
4722 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
4723 break;
4725 case EM_V800:
4726 out = decode_V800_machine_flags (out, e_flags);
4727 break;
4729 case EM_V850:
4730 case EM_CYGNUS_V850:
4731 out = decode_V850_machine_flags (out, e_flags);
4732 break;
4734 case EM_M32R:
4735 case EM_CYGNUS_M32R:
4736 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
4737 out = stpcpy (out, ", m32r");
4738 break;
4740 case EM_MIPS:
4741 case EM_MIPS_RS3_LE:
4742 out = decode_MIPS_machine_flags (out, e_flags);
4743 break;
4745 case EM_NDS32:
4746 out = decode_NDS32_machine_flags (out, e_flags);
4747 break;
4749 case EM_NFP:
4750 switch (EF_NFP_MACH (e_flags))
4752 case E_NFP_MACH_3200:
4753 out = stpcpy (out, ", NFP-32xx");
4754 break;
4755 case E_NFP_MACH_6000:
4756 out = stpcpy (out, ", NFP-6xxx");
4757 break;
4759 break;
4761 case EM_RISCV:
4762 out = decode_RISCV_machine_flags (out, e_flags);
4763 break;
4765 case EM_SH:
4766 out = decode_SH_machine_flags (out, e_flags);
4767 break;
4769 case EM_OR1K:
4770 if (e_flags & EF_OR1K_NODELAY)
4771 out = stpcpy (out, ", no delay");
4772 break;
4774 case EM_BPF:
4775 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
4776 break;
4778 case EM_SPARCV9:
4779 out = decode_SPARC_machine_flags (out, e_flags);
4780 break;
4782 case EM_PARISC:
4783 out = decode_PARISC_machine_flags (out, e_flags);
4784 break;
4786 case EM_PJ:
4787 case EM_PJ_OLD:
4788 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4789 out = stpcpy (out, ", new calling convention");
4791 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4792 out = stpcpy (out, ", gnu calling convention");
4793 break;
4795 case EM_IA_64:
4796 out = decode_IA64_machine_flags (out, e_flags, filedata);
4797 break;
4799 case EM_VAX:
4800 if ((e_flags & EF_VAX_NONPIC))
4801 out = stpcpy (out, ", non-PIC");
4802 if ((e_flags & EF_VAX_DFLOAT))
4803 out = stpcpy (out, ", D-Float");
4804 if ((e_flags & EF_VAX_GFLOAT))
4805 out = stpcpy (out, ", G-Float");
4806 break;
4808 case EM_VISIUM:
4809 if (e_flags & EF_VISIUM_ARCH_MCM)
4810 out = stpcpy (out, ", mcm");
4811 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4812 out = stpcpy (out, ", mcm24");
4813 if (e_flags & EF_VISIUM_ARCH_GR6)
4814 out = stpcpy (out, ", gr6");
4815 break;
4817 case EM_RL78:
4818 out = decode_RL78_machine_flags (out, e_flags);
4819 break;
4821 case EM_RX:
4822 out = decode_RX_machine_flags (out, e_flags);
4823 break;
4825 case EM_S390:
4826 if (e_flags & EF_S390_HIGH_GPRS)
4827 out = stpcpy (out, ", highgprs");
4828 break;
4830 case EM_TI_C6000:
4831 if ((e_flags & EF_C6000_REL))
4832 out = stpcpy (out, ", relocatable module");
4833 break;
4835 case EM_KVX:
4836 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
4837 strcat (buf, ", Kalray VLIW kv3-1");
4838 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
4839 strcat (buf, ", Kalray VLIW kv3-2");
4840 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
4841 strcat (buf, ", Kalray VLIW kv4-1");
4842 else
4843 strcat (buf, ", unknown KVX MPPA");
4844 break;
4846 case EM_MSP430:
4847 out = decode_MSP430_machine_flags (out, e_flags);
4848 break;
4850 case EM_Z80:
4851 out = decode_Z80_machine_flags (out, e_flags);
4852 break;
4854 case EM_LOONGARCH:
4855 out = decode_LOONGARCH_machine_flags (out, e_flags);
4856 break;
4860 return buf;
4863 static const char *
4864 get_osabi_name (Filedata * filedata, unsigned int osabi)
4866 static char buff[32];
4868 switch (osabi)
4870 case ELFOSABI_NONE: return "UNIX - System V";
4871 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4872 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
4873 case ELFOSABI_GNU: return "UNIX - GNU";
4874 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4875 case ELFOSABI_AIX: return "UNIX - AIX";
4876 case ELFOSABI_IRIX: return "UNIX - IRIX";
4877 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4878 case ELFOSABI_TRU64: return "UNIX - TRU64";
4879 case ELFOSABI_MODESTO: return "Novell - Modesto";
4880 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4881 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4882 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
4883 case ELFOSABI_AROS: return "AROS";
4884 case ELFOSABI_FENIXOS: return "FenixOS";
4885 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4886 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
4887 default:
4888 if (osabi >= 64)
4889 switch (filedata->file_header.e_machine)
4891 case EM_AMDGPU:
4892 switch (osabi)
4894 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4895 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4896 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4897 default:
4898 break;
4900 break;
4902 case EM_ARM:
4903 switch (osabi)
4905 case ELFOSABI_ARM: return "ARM";
4906 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
4907 default:
4908 break;
4910 break;
4912 case EM_MSP430:
4913 case EM_MSP430_OLD:
4914 case EM_VISIUM:
4915 switch (osabi)
4917 case ELFOSABI_STANDALONE: return _("Standalone App");
4918 default:
4919 break;
4921 break;
4923 case EM_TI_C6000:
4924 switch (osabi)
4926 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4927 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4928 default:
4929 break;
4931 break;
4933 default:
4934 break;
4936 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
4937 return buff;
4941 static const char *
4942 get_aarch64_segment_type (unsigned long type)
4944 switch (type)
4946 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
4947 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
4948 default: return NULL;
4952 static const char *
4953 get_arm_segment_type (unsigned long type)
4955 switch (type)
4957 case PT_ARM_EXIDX: return "EXIDX";
4958 default: return NULL;
4962 static const char *
4963 get_s390_segment_type (unsigned long type)
4965 switch (type)
4967 case PT_S390_PGSTE: return "S390_PGSTE";
4968 default: return NULL;
4972 static const char *
4973 get_mips_segment_type (unsigned long type)
4975 switch (type)
4977 case PT_MIPS_REGINFO: return "REGINFO";
4978 case PT_MIPS_RTPROC: return "RTPROC";
4979 case PT_MIPS_OPTIONS: return "OPTIONS";
4980 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4981 default: return NULL;
4985 static const char *
4986 get_parisc_segment_type (unsigned long type)
4988 switch (type)
4990 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4991 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
4992 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
4993 default: return NULL;
4997 static const char *
4998 get_ia64_segment_type (unsigned long type)
5000 switch (type)
5002 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
5003 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
5004 default: return NULL;
5008 static const char *
5009 get_tic6x_segment_type (unsigned long type)
5011 switch (type)
5013 case PT_C6000_PHATTR: return "C6000_PHATTR";
5014 default: return NULL;
5018 static const char *
5019 get_riscv_segment_type (unsigned long type)
5021 switch (type)
5023 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5024 default: return NULL;
5028 static const char *
5029 get_hpux_segment_type (unsigned long type, unsigned e_machine)
5031 if (e_machine == EM_PARISC)
5032 switch (type)
5034 case PT_HP_TLS: return "HP_TLS";
5035 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5036 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5037 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5038 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5039 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5040 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5041 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5042 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5043 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5044 case PT_HP_PARALLEL: return "HP_PARALLEL";
5045 case PT_HP_FASTBIND: return "HP_FASTBIND";
5046 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5047 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5048 case PT_HP_STACK: return "HP_STACK";
5049 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
5050 default: return NULL;
5053 if (e_machine == EM_IA_64)
5054 switch (type)
5056 case PT_HP_TLS: return "HP_TLS";
5057 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5058 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5059 case PT_IA_64_HP_STACK: return "HP_STACK";
5060 default: return NULL;
5063 return NULL;
5066 static const char *
5067 get_solaris_segment_type (unsigned long type)
5069 switch (type)
5071 case 0x6464e550: return "PT_SUNW_UNWIND";
5072 case 0x6474e550: return "PT_SUNW_EH_FRAME";
5073 case 0x6ffffff7: return "PT_LOSUNW";
5074 case 0x6ffffffa: return "PT_SUNWBSS";
5075 case 0x6ffffffb: return "PT_SUNWSTACK";
5076 case 0x6ffffffc: return "PT_SUNWDTRACE";
5077 case 0x6ffffffd: return "PT_SUNWCAP";
5078 case 0x6fffffff: return "PT_HISUNW";
5079 default: return NULL;
5083 static const char *
5084 get_segment_type (Filedata * filedata, unsigned long p_type)
5086 static char buff[32];
5088 switch (p_type)
5090 case PT_NULL: return "NULL";
5091 case PT_LOAD: return "LOAD";
5092 case PT_DYNAMIC: return "DYNAMIC";
5093 case PT_INTERP: return "INTERP";
5094 case PT_NOTE: return "NOTE";
5095 case PT_SHLIB: return "SHLIB";
5096 case PT_PHDR: return "PHDR";
5097 case PT_TLS: return "TLS";
5098 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
5099 case PT_GNU_STACK: return "GNU_STACK";
5100 case PT_GNU_RELRO: return "GNU_RELRO";
5101 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
5102 case PT_GNU_SFRAME: return "GNU_SFRAME";
5104 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
5105 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5106 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
5107 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
5108 case PT_OPENBSD_SYSCALLS: return "OPENBSD_SYSCALLS";
5109 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
5111 default:
5112 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
5114 const char * result;
5116 switch (filedata->file_header.e_machine)
5118 case EM_AARCH64:
5119 result = get_aarch64_segment_type (p_type);
5120 break;
5121 case EM_ARM:
5122 result = get_arm_segment_type (p_type);
5123 break;
5124 case EM_MIPS:
5125 case EM_MIPS_RS3_LE:
5126 result = get_mips_segment_type (p_type);
5127 break;
5128 case EM_PARISC:
5129 result = get_parisc_segment_type (p_type);
5130 break;
5131 case EM_IA_64:
5132 result = get_ia64_segment_type (p_type);
5133 break;
5134 case EM_TI_C6000:
5135 result = get_tic6x_segment_type (p_type);
5136 break;
5137 case EM_S390:
5138 case EM_S390_OLD:
5139 result = get_s390_segment_type (p_type);
5140 break;
5141 case EM_RISCV:
5142 result = get_riscv_segment_type (p_type);
5143 break;
5144 default:
5145 result = NULL;
5146 break;
5149 if (result != NULL)
5150 return result;
5152 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
5154 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
5156 const char * result = NULL;
5158 switch (filedata->file_header.e_ident[EI_OSABI])
5160 case ELFOSABI_GNU:
5161 case ELFOSABI_FREEBSD:
5162 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5164 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5165 result = buff;
5167 break;
5168 case ELFOSABI_HPUX:
5169 result = get_hpux_segment_type (p_type,
5170 filedata->file_header.e_machine);
5171 break;
5172 case ELFOSABI_SOLARIS:
5173 result = get_solaris_segment_type (p_type);
5174 break;
5175 default:
5176 break;
5178 if (result != NULL)
5179 return result;
5181 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
5183 else
5184 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
5186 return buff;
5190 static const char *
5191 get_arc_section_type_name (unsigned int sh_type)
5193 switch (sh_type)
5195 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5196 default:
5197 break;
5199 return NULL;
5202 static const char *
5203 get_mips_section_type_name (unsigned int sh_type)
5205 switch (sh_type)
5207 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5208 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5209 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5210 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5211 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5212 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5213 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5214 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5215 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5216 case SHT_MIPS_RELD: return "MIPS_RELD";
5217 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5218 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5219 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5220 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5221 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5222 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5223 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5224 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5225 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5226 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5227 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5228 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5229 case SHT_MIPS_LINE: return "MIPS_LINE";
5230 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5231 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5232 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5233 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5234 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5235 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5236 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5237 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5238 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5239 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5240 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5241 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5242 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5243 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5244 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
5245 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
5246 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
5247 case SHT_MIPS_XHASH: return "MIPS_XHASH";
5248 default:
5249 break;
5251 return NULL;
5254 static const char *
5255 get_parisc_section_type_name (unsigned int sh_type)
5257 switch (sh_type)
5259 case SHT_PARISC_EXT: return "PARISC_EXT";
5260 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5261 case SHT_PARISC_DOC: return "PARISC_DOC";
5262 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5263 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5264 case SHT_PARISC_STUBS: return "PARISC_STUBS";
5265 case SHT_PARISC_DLKM: return "PARISC_DLKM";
5266 default: return NULL;
5270 static const char *
5271 get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
5273 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
5274 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
5275 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
5277 switch (sh_type)
5279 case SHT_IA_64_EXT: return "IA_64_EXT";
5280 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5281 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5282 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5283 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5284 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5285 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5286 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5287 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5288 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
5289 default:
5290 break;
5292 return NULL;
5295 static const char *
5296 get_x86_64_section_type_name (unsigned int sh_type)
5298 switch (sh_type)
5300 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
5301 default: return NULL;
5305 static const char *
5306 get_aarch64_section_type_name (unsigned int sh_type)
5308 switch (sh_type)
5310 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
5311 default: return NULL;
5315 static const char *
5316 get_arm_section_type_name (unsigned int sh_type)
5318 switch (sh_type)
5320 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5321 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5322 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5323 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5324 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
5325 default: return NULL;
5329 static const char *
5330 get_tic6x_section_type_name (unsigned int sh_type)
5332 switch (sh_type)
5334 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5335 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5336 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5337 case SHT_TI_ICODE: return "TI_ICODE";
5338 case SHT_TI_XREF: return "TI_XREF";
5339 case SHT_TI_HANDLER: return "TI_HANDLER";
5340 case SHT_TI_INITINFO: return "TI_INITINFO";
5341 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5342 default: return NULL;
5346 static const char *
5347 get_msp430_section_type_name (unsigned int sh_type)
5349 switch (sh_type)
5351 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5352 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5353 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5354 default: return NULL;
5358 static const char *
5359 get_nfp_section_type_name (unsigned int sh_type)
5361 switch (sh_type)
5363 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5364 case SHT_NFP_INITREG: return "NFP_INITREG";
5365 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5366 default: return NULL;
5370 static const char *
5371 get_v850_section_type_name (unsigned int sh_type)
5373 switch (sh_type)
5375 case SHT_V850_SCOMMON: return "V850 Small Common";
5376 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5377 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5378 case SHT_RENESAS_IOP: return "RENESAS IOP";
5379 case SHT_RENESAS_INFO: return "RENESAS INFO";
5380 default: return NULL;
5384 static const char *
5385 get_riscv_section_type_name (unsigned int sh_type)
5387 switch (sh_type)
5389 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5390 default: return NULL;
5394 static const char *
5395 get_csky_section_type_name (unsigned int sh_type)
5397 switch (sh_type)
5399 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5400 default: return NULL;
5404 static const char *
5405 get_section_type_name (Filedata * filedata, unsigned int sh_type)
5407 static char buff[32];
5408 const char * result;
5410 switch (sh_type)
5412 case SHT_NULL: return "NULL";
5413 case SHT_PROGBITS: return "PROGBITS";
5414 case SHT_SYMTAB: return "SYMTAB";
5415 case SHT_STRTAB: return "STRTAB";
5416 case SHT_RELA: return "RELA";
5417 case SHT_RELR: return "RELR";
5418 case SHT_HASH: return "HASH";
5419 case SHT_DYNAMIC: return "DYNAMIC";
5420 case SHT_NOTE: return "NOTE";
5421 case SHT_NOBITS: return "NOBITS";
5422 case SHT_REL: return "REL";
5423 case SHT_SHLIB: return "SHLIB";
5424 case SHT_DYNSYM: return "DYNSYM";
5425 case SHT_INIT_ARRAY: return "INIT_ARRAY";
5426 case SHT_FINI_ARRAY: return "FINI_ARRAY";
5427 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
5428 case SHT_GNU_HASH: return "GNU_HASH";
5429 case SHT_GROUP: return "GROUP";
5430 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
5431 case SHT_GNU_verdef: return "VERDEF";
5432 case SHT_GNU_verneed: return "VERNEED";
5433 case SHT_GNU_versym: return "VERSYM";
5434 case 0x6ffffff0: return "VERSYM";
5435 case 0x6ffffffc: return "VERDEF";
5436 case 0x7ffffffd: return "AUXILIARY";
5437 case 0x7fffffff: return "FILTER";
5438 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
5440 default:
5441 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
5443 switch (filedata->file_header.e_machine)
5445 case EM_ARC:
5446 case EM_ARC_COMPACT:
5447 case EM_ARC_COMPACT2:
5448 case EM_ARC_COMPACT3:
5449 case EM_ARC_COMPACT3_64:
5450 result = get_arc_section_type_name (sh_type);
5451 break;
5452 case EM_MIPS:
5453 case EM_MIPS_RS3_LE:
5454 result = get_mips_section_type_name (sh_type);
5455 break;
5456 case EM_PARISC:
5457 result = get_parisc_section_type_name (sh_type);
5458 break;
5459 case EM_IA_64:
5460 result = get_ia64_section_type_name (filedata, sh_type);
5461 break;
5462 case EM_X86_64:
5463 case EM_L1OM:
5464 case EM_K1OM:
5465 result = get_x86_64_section_type_name (sh_type);
5466 break;
5467 case EM_AARCH64:
5468 result = get_aarch64_section_type_name (sh_type);
5469 break;
5470 case EM_ARM:
5471 result = get_arm_section_type_name (sh_type);
5472 break;
5473 case EM_TI_C6000:
5474 result = get_tic6x_section_type_name (sh_type);
5475 break;
5476 case EM_MSP430:
5477 result = get_msp430_section_type_name (sh_type);
5478 break;
5479 case EM_NFP:
5480 result = get_nfp_section_type_name (sh_type);
5481 break;
5482 case EM_V800:
5483 case EM_V850:
5484 case EM_CYGNUS_V850:
5485 result = get_v850_section_type_name (sh_type);
5486 break;
5487 case EM_RISCV:
5488 result = get_riscv_section_type_name (sh_type);
5489 break;
5490 case EM_CSKY:
5491 result = get_csky_section_type_name (sh_type);
5492 break;
5493 default:
5494 result = NULL;
5495 break;
5498 if (result != NULL)
5499 return result;
5501 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
5503 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
5505 switch (filedata->file_header.e_machine)
5507 case EM_IA_64:
5508 result = get_ia64_section_type_name (filedata, sh_type);
5509 break;
5510 default:
5511 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
5512 result = get_solaris_section_type (sh_type);
5513 else
5515 switch (sh_type)
5517 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5518 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5519 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5520 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5521 default:
5522 result = NULL;
5523 break;
5526 break;
5529 if (result != NULL)
5530 return result;
5532 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
5534 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
5536 switch (filedata->file_header.e_machine)
5538 case EM_V800:
5539 case EM_V850:
5540 case EM_CYGNUS_V850:
5541 result = get_v850_section_type_name (sh_type);
5542 break;
5543 default:
5544 result = NULL;
5545 break;
5548 if (result != NULL)
5549 return result;
5551 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
5553 else
5554 /* This message is probably going to be displayed in a 15
5555 character wide field, so put the hex value first. */
5556 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
5558 return buff;
5562 enum long_option_values
5564 OPTION_DEBUG_DUMP = 512,
5565 OPTION_DYN_SYMS,
5566 OPTION_LTO_SYMS,
5567 OPTION_DWARF_DEPTH,
5568 OPTION_DWARF_START,
5569 OPTION_DWARF_CHECK,
5570 OPTION_CTF_DUMP,
5571 OPTION_CTF_PARENT,
5572 OPTION_CTF_SYMBOLS,
5573 OPTION_CTF_STRINGS,
5574 OPTION_SFRAME_DUMP,
5575 OPTION_WITH_SYMBOL_VERSIONS,
5576 OPTION_RECURSE_LIMIT,
5577 OPTION_NO_RECURSE_LIMIT,
5578 OPTION_NO_DEMANGLING,
5579 OPTION_NO_EXTRA_SYM_INFO,
5580 OPTION_SYM_BASE
5583 static struct option options[] =
5585 /* Note - This table is alpha-sorted on the 'val'
5586 field in order to make adding new options easier. */
5587 {"arch-specific", no_argument, 0, 'A'},
5588 {"all", no_argument, 0, 'a'},
5589 {"demangle", optional_argument, 0, 'C'},
5590 {"archive-index", no_argument, 0, 'c'},
5591 {"use-dynamic", no_argument, 0, 'D'},
5592 {"dynamic", no_argument, 0, 'd'},
5593 {"headers", no_argument, 0, 'e'},
5594 {"section-groups", no_argument, 0, 'g'},
5595 {"help", no_argument, 0, 'H'},
5596 {"file-header", no_argument, 0, 'h'},
5597 {"histogram", no_argument, 0, 'I'},
5598 {"lint", no_argument, 0, 'L'},
5599 {"enable-checks", no_argument, 0, 'L'},
5600 {"program-headers", no_argument, 0, 'l'},
5601 {"segments", no_argument, 0, 'l'},
5602 {"full-section-name",no_argument, 0, 'N'},
5603 {"notes", no_argument, 0, 'n'},
5604 {"process-links", no_argument, 0, 'P'},
5605 {"string-dump", required_argument, 0, 'p'},
5606 {"relocated-dump", required_argument, 0, 'R'},
5607 {"relocs", no_argument, 0, 'r'},
5608 {"section-headers", no_argument, 0, 'S'},
5609 {"sections", no_argument, 0, 'S'},
5610 {"symbols", no_argument, 0, 's'},
5611 {"syms", no_argument, 0, 's'},
5612 {"silent-truncation",no_argument, 0, 'T'},
5613 {"section-details", no_argument, 0, 't'},
5614 {"unicode", required_argument, NULL, 'U'},
5615 {"unwind", no_argument, 0, 'u'},
5616 {"version-info", no_argument, 0, 'V'},
5617 {"version", no_argument, 0, 'v'},
5618 {"wide", no_argument, 0, 'W'},
5619 {"extra-sym-info", no_argument, 0, 'X'},
5620 {"hex-dump", required_argument, 0, 'x'},
5621 {"decompress", no_argument, 0, 'z'},
5623 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5624 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
5625 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5626 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5627 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5628 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
5629 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
5630 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
5631 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5632 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
5633 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
5634 #ifdef ENABLE_LIBCTF
5635 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
5636 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5637 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5638 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
5639 #endif
5640 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
5641 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
5643 {0, no_argument, 0, 0}
5646 static void
5647 usage (FILE * stream)
5649 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5650 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
5651 fprintf (stream, _(" Options are:\n"));
5652 fprintf (stream, _("\
5653 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5654 fprintf (stream, _("\
5655 -h --file-header Display the ELF file header\n"));
5656 fprintf (stream, _("\
5657 -l --program-headers Display the program headers\n"));
5658 fprintf (stream, _("\
5659 --segments An alias for --program-headers\n"));
5660 fprintf (stream, _("\
5661 -S --section-headers Display the sections' header\n"));
5662 fprintf (stream, _("\
5663 --sections An alias for --section-headers\n"));
5664 fprintf (stream, _("\
5665 -g --section-groups Display the section groups\n"));
5666 fprintf (stream, _("\
5667 -t --section-details Display the section details\n"));
5668 fprintf (stream, _("\
5669 -e --headers Equivalent to: -h -l -S\n"));
5670 fprintf (stream, _("\
5671 -s --syms Display the symbol table\n"));
5672 fprintf (stream, _("\
5673 --symbols An alias for --syms\n"));
5674 fprintf (stream, _("\
5675 --dyn-syms Display the dynamic symbol table\n"));
5676 fprintf (stream, _("\
5677 --lto-syms Display LTO symbol tables\n"));
5678 fprintf (stream, _("\
5679 --sym-base=[0|8|10|16] \n\
5680 Force base for symbol sizes. The options are \n\
5681 mixed (the default), octal, decimal, hexadecimal.\n"));
5682 fprintf (stream, _("\
5683 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5684 display_demangler_styles (stream, _("\
5685 STYLE can be "));
5686 fprintf (stream, _("\
5687 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5688 fprintf (stream, _("\
5689 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5690 fprintf (stream, _("\
5691 --no-recurse-limit Disable a demangling recursion limit\n"));
5692 fprintf (stream, _("\
5693 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5694 Display unicode characters as determined by the current locale\n\
5695 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5696 escape sequences, or treat them as invalid and display as\n\
5697 \"{hex sequences}\"\n"));
5698 fprintf (stream, _("\
5699 -X --extra-sym-info Display extra information when showing symbols\n"));
5700 fprintf (stream, _("\
5701 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
5702 fprintf (stream, _("\
5703 -n --notes Display the contents of note sections (if present)\n"));
5704 fprintf (stream, _("\
5705 -r --relocs Display the relocations (if present)\n"));
5706 fprintf (stream, _("\
5707 -u --unwind Display the unwind info (if present)\n"));
5708 fprintf (stream, _("\
5709 -d --dynamic Display the dynamic section (if present)\n"));
5710 fprintf (stream, _("\
5711 -V --version-info Display the version sections (if present)\n"));
5712 fprintf (stream, _("\
5713 -A --arch-specific Display architecture specific information (if any)\n"));
5714 fprintf (stream, _("\
5715 -c --archive-index Display the symbol/file index in an archive\n"));
5716 fprintf (stream, _("\
5717 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5718 fprintf (stream, _("\
5719 -L --lint|--enable-checks\n\
5720 Display warning messages for possible problems\n"));
5721 fprintf (stream, _("\
5722 -x --hex-dump=<number|name>\n\
5723 Dump the contents of section <number|name> as bytes\n"));
5724 fprintf (stream, _("\
5725 -p --string-dump=<number|name>\n\
5726 Dump the contents of section <number|name> as strings\n"));
5727 fprintf (stream, _("\
5728 -R --relocated-dump=<number|name>\n\
5729 Dump the relocated contents of section <number|name>\n"));
5730 fprintf (stream, _("\
5731 -z --decompress Decompress section before dumping it\n"));
5732 fprintf (stream, _("\
5733 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5734 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5735 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5736 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5737 U/=trace_info]\n\
5738 Display the contents of DWARF debug sections\n"));
5739 fprintf (stream, _("\
5740 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5741 debuginfo files\n"));
5742 fprintf (stream, _("\
5743 -P --process-links Display the contents of non-debug sections in separate\n\
5744 debuginfo files. (Implies -wK)\n"));
5745 #if DEFAULT_FOR_FOLLOW_LINKS
5746 fprintf (stream, _("\
5747 -wK --debug-dump=follow-links\n\
5748 Follow links to separate debug info files (default)\n"));
5749 fprintf (stream, _("\
5750 -wN --debug-dump=no-follow-links\n\
5751 Do not follow links to separate debug info files\n"));
5752 #else
5753 fprintf (stream, _("\
5754 -wK --debug-dump=follow-links\n\
5755 Follow links to separate debug info files\n"));
5756 fprintf (stream, _("\
5757 -wN --debug-dump=no-follow-links\n\
5758 Do not follow links to separate debug info files\n\
5759 (default)\n"));
5760 #endif
5761 #if HAVE_LIBDEBUGINFOD
5762 fprintf (stream, _("\
5763 -wD --debug-dump=use-debuginfod\n\
5764 When following links, also query debuginfod servers (default)\n"));
5765 fprintf (stream, _("\
5766 -wE --debug-dump=do-not-use-debuginfod\n\
5767 When following links, do not query debuginfod servers\n"));
5768 #endif
5769 fprintf (stream, _("\
5770 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5771 fprintf (stream, _("\
5772 --dwarf-start=N Display DIEs starting at offset N\n"));
5773 #ifdef ENABLE_LIBCTF
5774 fprintf (stream, _("\
5775 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5776 fprintf (stream, _("\
5777 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
5778 fprintf (stream, _("\
5779 --ctf-symbols=<number|name>\n\
5780 Use section <number|name> as the CTF external symtab\n"));
5781 fprintf (stream, _("\
5782 --ctf-strings=<number|name>\n\
5783 Use section <number|name> as the CTF external strtab\n"));
5784 #endif
5785 fprintf (stream, _("\
5786 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
5788 #ifdef SUPPORT_DISASSEMBLY
5789 fprintf (stream, _("\
5790 -i --instruction-dump=<number|name>\n\
5791 Disassemble the contents of section <number|name>\n"));
5792 #endif
5793 fprintf (stream, _("\
5794 -I --histogram Display histogram of bucket list lengths\n"));
5795 fprintf (stream, _("\
5796 -W --wide Allow output width to exceed 80 characters\n"));
5797 fprintf (stream, _("\
5798 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5799 fprintf (stream, _("\
5800 @<file> Read options from <file>\n"));
5801 fprintf (stream, _("\
5802 -H --help Display this information\n"));
5803 fprintf (stream, _("\
5804 -v --version Display the version number of readelf\n"));
5806 if (REPORT_BUGS_TO[0] && stream == stdout)
5807 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
5809 exit (stream == stdout ? 0 : 1);
5812 /* Record the fact that the user wants the contents of section number
5813 SECTION to be displayed using the method(s) encoded as flags bits
5814 in TYPE. Note, TYPE can be zero if we are creating the array for
5815 the first time. */
5817 static void
5818 request_dump_bynumber (struct dump_data *dumpdata,
5819 unsigned int section, dump_type type)
5821 if (section >= dumpdata->num_dump_sects)
5823 dump_type * new_dump_sects;
5825 new_dump_sects = (dump_type *) calloc (section + 1,
5826 sizeof (* new_dump_sects));
5828 if (new_dump_sects == NULL)
5829 error (_("Out of memory allocating dump request table.\n"));
5830 else
5832 if (dumpdata->dump_sects)
5834 /* Copy current flag settings. */
5835 memcpy (new_dump_sects, dumpdata->dump_sects,
5836 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
5838 free (dumpdata->dump_sects);
5841 dumpdata->dump_sects = new_dump_sects;
5842 dumpdata->num_dump_sects = section + 1;
5846 if (dumpdata->dump_sects)
5847 dumpdata->dump_sects[section] |= type;
5850 /* Request a dump by section name. */
5852 static void
5853 request_dump_byname (const char * section, dump_type type)
5855 struct dump_list_entry * new_request;
5857 new_request = (struct dump_list_entry *)
5858 malloc (sizeof (struct dump_list_entry));
5859 if (!new_request)
5860 error (_("Out of memory allocating dump request table.\n"));
5862 new_request->name = strdup (section);
5863 if (!new_request->name)
5864 error (_("Out of memory allocating dump request table.\n"));
5866 new_request->type = type;
5868 new_request->next = dump_sects_byname;
5869 dump_sects_byname = new_request;
5872 static inline void
5873 request_dump (struct dump_data *dumpdata, dump_type type)
5875 int section;
5876 char * cp;
5878 do_dump = true;
5879 section = strtoul (optarg, & cp, 0);
5881 if (! *cp && section >= 0)
5882 request_dump_bynumber (dumpdata, section, type);
5883 else
5884 request_dump_byname (optarg, type);
5887 static void
5888 parse_args (struct dump_data *dumpdata, int argc, char ** argv)
5890 int c;
5892 if (argc < 2)
5893 usage (stderr);
5895 while ((c = getopt_long
5896 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
5898 switch (c)
5900 case 0:
5901 /* Long options. */
5902 break;
5903 case 'H':
5904 usage (stdout);
5905 break;
5907 case 'a':
5908 do_syms = true;
5909 do_reloc = true;
5910 do_unwind = true;
5911 do_dynamic = true;
5912 do_header = true;
5913 do_sections = true;
5914 do_section_groups = true;
5915 do_segments = true;
5916 do_version = true;
5917 do_histogram = true;
5918 do_arch = true;
5919 do_notes = true;
5920 break;
5922 case 'g':
5923 do_section_groups = true;
5924 break;
5925 case 't':
5926 case 'N':
5927 do_sections = true;
5928 do_section_details = true;
5929 break;
5930 case 'e':
5931 do_header = true;
5932 do_sections = true;
5933 do_segments = true;
5934 break;
5935 case 'A':
5936 do_arch = true;
5937 break;
5938 case 'D':
5939 do_using_dynamic = true;
5940 break;
5941 case 'r':
5942 do_reloc = true;
5943 break;
5944 case 'u':
5945 do_unwind = true;
5946 break;
5947 case 'h':
5948 do_header = true;
5949 break;
5950 case 'l':
5951 do_segments = true;
5952 break;
5953 case 's':
5954 do_syms = true;
5955 break;
5956 case 'S':
5957 do_sections = true;
5958 break;
5959 case 'd':
5960 do_dynamic = true;
5961 break;
5962 case 'I':
5963 do_histogram = true;
5964 break;
5965 case 'n':
5966 do_notes = true;
5967 break;
5968 case 'c':
5969 do_archive_index = true;
5970 break;
5971 case 'L':
5972 do_checks = true;
5973 break;
5974 case 'P':
5975 process_links = true;
5976 do_follow_links = true;
5977 dump_any_debugging = true;
5978 break;
5979 case 'x':
5980 request_dump (dumpdata, HEX_DUMP);
5981 break;
5982 case 'p':
5983 request_dump (dumpdata, STRING_DUMP);
5984 break;
5985 case 'R':
5986 request_dump (dumpdata, RELOC_DUMP);
5987 break;
5988 case 'z':
5989 decompress_dumps = true;
5990 break;
5991 case 'w':
5992 if (optarg == NULL)
5994 do_debugging = true;
5995 do_dump = true;
5996 dump_any_debugging = true;
5997 dwarf_select_sections_all ();
5999 else
6001 do_debugging = false;
6002 if (dwarf_select_sections_by_letters (optarg))
6004 do_dump = true;
6005 dump_any_debugging = true;
6008 break;
6009 case OPTION_DEBUG_DUMP:
6010 if (optarg == NULL)
6012 do_dump = true;
6013 do_debugging = true;
6014 dump_any_debugging = true;
6015 dwarf_select_sections_all ();
6017 else
6019 do_debugging = false;
6020 if (dwarf_select_sections_by_names (optarg))
6022 do_dump = true;
6023 dump_any_debugging = true;
6026 break;
6027 case OPTION_DWARF_DEPTH:
6029 char *cp;
6031 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6033 break;
6034 case OPTION_DWARF_START:
6036 char *cp;
6038 dwarf_start_die = strtoul (optarg, & cp, 0);
6040 break;
6041 case OPTION_DWARF_CHECK:
6042 dwarf_check = true;
6043 break;
6044 case OPTION_CTF_DUMP:
6045 do_ctf = true;
6046 request_dump (dumpdata, CTF_DUMP);
6047 break;
6048 case OPTION_CTF_SYMBOLS:
6049 free (dump_ctf_symtab_name);
6050 dump_ctf_symtab_name = strdup (optarg);
6051 break;
6052 case OPTION_CTF_STRINGS:
6053 free (dump_ctf_strtab_name);
6054 dump_ctf_strtab_name = strdup (optarg);
6055 break;
6056 case OPTION_CTF_PARENT:
6057 free (dump_ctf_parent_name);
6058 dump_ctf_parent_name = strdup (optarg);
6059 break;
6060 case OPTION_SFRAME_DUMP:
6061 do_sframe = true;
6062 /* Providing section name is optional. request_dump (), however,
6063 thrives on non NULL optarg. Handle it explicitly here. */
6064 if (optarg != NULL)
6065 request_dump (dumpdata, SFRAME_DUMP);
6066 else
6068 do_dump = true;
6069 const char *sframe_sec_name = strdup (".sframe");
6070 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6072 break;
6073 case OPTION_DYN_SYMS:
6074 do_dyn_syms = true;
6075 break;
6076 case OPTION_LTO_SYMS:
6077 do_lto_syms = true;
6078 break;
6079 case 'X':
6080 extra_sym_info = true;
6081 break;
6082 case OPTION_NO_EXTRA_SYM_INFO:
6083 extra_sym_info = false;
6084 break;
6086 #ifdef SUPPORT_DISASSEMBLY
6087 case 'i':
6088 request_dump (dumpdata, DISASS_DUMP);
6089 break;
6090 #endif
6091 case 'v':
6092 print_version (program_name);
6093 break;
6094 case 'V':
6095 do_version = true;
6096 break;
6097 case 'W':
6098 do_wide = true;
6099 break;
6100 case 'T':
6101 do_not_show_symbol_truncation = true;
6102 break;
6103 case 'C':
6104 do_demangle = true;
6105 if (optarg != NULL)
6107 enum demangling_styles style;
6109 style = cplus_demangle_name_to_style (optarg);
6110 if (style == unknown_demangling)
6111 error (_("unknown demangling style `%s'"), optarg);
6113 cplus_demangle_set_style (style);
6115 break;
6116 case OPTION_NO_DEMANGLING:
6117 do_demangle = false;
6118 break;
6119 case OPTION_RECURSE_LIMIT:
6120 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6121 break;
6122 case OPTION_NO_RECURSE_LIMIT:
6123 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6124 break;
6125 case OPTION_WITH_SYMBOL_VERSIONS:
6126 /* Ignored for backward compatibility. */
6127 break;
6129 case 'U':
6130 if (optarg == NULL)
6131 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6132 else if (streq (optarg, "default") || streq (optarg, "d"))
6133 unicode_display = unicode_default;
6134 else if (streq (optarg, "locale") || streq (optarg, "l"))
6135 unicode_display = unicode_locale;
6136 else if (streq (optarg, "escape") || streq (optarg, "e"))
6137 unicode_display = unicode_escape;
6138 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6139 unicode_display = unicode_invalid;
6140 else if (streq (optarg, "hex") || streq (optarg, "x"))
6141 unicode_display = unicode_hex;
6142 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6143 unicode_display = unicode_highlight;
6144 else
6145 error (_("invalid argument to -U/--unicode: %s"), optarg);
6146 break;
6148 case OPTION_SYM_BASE:
6149 sym_base = 0;
6150 if (optarg != NULL)
6152 sym_base = strtoul (optarg, NULL, 0);
6153 switch (sym_base)
6155 case 0:
6156 case 8:
6157 case 10:
6158 case 16:
6159 break;
6161 default:
6162 sym_base = 0;
6163 break;
6166 break;
6168 default:
6169 /* xgettext:c-format */
6170 error (_("Invalid option '-%c'\n"), c);
6171 /* Fall through. */
6172 case '?':
6173 usage (stderr);
6177 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
6178 && !do_segments && !do_header && !do_dump && !do_version
6179 && !do_histogram && !do_debugging && !do_arch && !do_notes
6180 && !do_section_groups && !do_archive_index
6181 && !do_dyn_syms && !do_lto_syms)
6183 if (do_checks)
6185 check_all = true;
6186 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6187 do_segments = do_header = do_dump = do_version = true;
6188 do_histogram = do_debugging = do_arch = do_notes = true;
6189 do_section_groups = do_archive_index = do_dyn_syms = true;
6190 do_lto_syms = true;
6192 else
6193 usage (stderr);
6197 static const char *
6198 get_elf_class (unsigned int elf_class)
6200 static char buff[32];
6202 switch (elf_class)
6204 case ELFCLASSNONE: return _("none");
6205 case ELFCLASS32: return "ELF32";
6206 case ELFCLASS64: return "ELF64";
6207 default:
6208 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
6209 return buff;
6213 static const char *
6214 get_data_encoding (unsigned int encoding)
6216 static char buff[32];
6218 switch (encoding)
6220 case ELFDATANONE: return _("none");
6221 case ELFDATA2LSB: return _("2's complement, little endian");
6222 case ELFDATA2MSB: return _("2's complement, big endian");
6223 default:
6224 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
6225 return buff;
6229 static bool
6230 check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6232 if (header->e_ident[EI_MAG0] == ELFMAG0
6233 && header->e_ident[EI_MAG1] == ELFMAG1
6234 && header->e_ident[EI_MAG2] == ELFMAG2
6235 && header->e_ident[EI_MAG3] == ELFMAG3)
6236 return true;
6238 /* Some compilers produce object files that are not in the ELF file format.
6239 As an aid to users of readelf, try to identify these cases and suggest
6240 alternative tools.
6242 FIXME: It is not clear if all four bytes are used as constant magic
6243 valus by all compilers. It may be necessary to recode this function if
6244 different tools use different length sequences. */
6246 static struct
6248 unsigned char magic[4];
6249 const char * obj_message;
6250 const char * ar_message;
6252 known_magic[] =
6254 { { 'B', 'C', 0xc0, 0xde },
6255 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
6256 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
6258 { { 'g', 'o', ' ', 'o' },
6259 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6260 NULL
6263 int i;
6265 for (i = ARRAY_SIZE (known_magic); i--;)
6267 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6268 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6269 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6270 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6272 /* Some compiler's analyzer tools do not handle archives,
6273 so we provide two different kinds of error message. */
6274 if (filedata->archive_file_size > 0
6275 && known_magic[i].ar_message != NULL)
6276 error ("%s", known_magic[i].ar_message);
6277 else
6278 error ("%s", known_magic[i].obj_message);
6279 return false;
6283 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6284 return false;
6287 /* Decode the data held in 'filedata->file_header'. */
6289 static bool
6290 process_file_header (Filedata * filedata)
6292 Elf_Internal_Ehdr * header = & filedata->file_header;
6294 if (! check_magic_number (filedata, header))
6295 return false;
6297 if (! filedata->is_separate)
6298 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
6300 if (do_header)
6302 unsigned i;
6304 if (filedata->is_separate)
6305 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6306 else
6307 printf (_("ELF Header:\n"));
6308 printf (_(" Magic: "));
6309 for (i = 0; i < EI_NIDENT; i++)
6310 printf ("%2.2x ", header->e_ident[i]);
6311 printf ("\n");
6312 printf (_(" Class: %s\n"),
6313 get_elf_class (header->e_ident[EI_CLASS]));
6314 printf (_(" Data: %s\n"),
6315 get_data_encoding (header->e_ident[EI_DATA]));
6316 printf (_(" Version: %d%s\n"),
6317 header->e_ident[EI_VERSION],
6318 (header->e_ident[EI_VERSION] == EV_CURRENT
6319 ? _(" (current)")
6320 : (header->e_ident[EI_VERSION] != EV_NONE
6321 ? _(" <unknown>")
6322 : "")));
6323 printf (_(" OS/ABI: %s\n"),
6324 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
6325 printf (_(" ABI Version: %d\n"),
6326 header->e_ident[EI_ABIVERSION]);
6327 printf (_(" Type: %s\n"),
6328 get_file_type (filedata));
6329 printf (_(" Machine: %s\n"),
6330 get_machine_name (header->e_machine));
6331 printf (_(" Version: 0x%lx\n"),
6332 header->e_version);
6334 printf (_(" Entry point address: "));
6335 print_vma (header->e_entry, PREFIX_HEX);
6336 printf (_("\n Start of program headers: "));
6337 print_vma (header->e_phoff, DEC);
6338 printf (_(" (bytes into file)\n Start of section headers: "));
6339 print_vma (header->e_shoff, DEC);
6340 printf (_(" (bytes into file)\n"));
6342 printf (_(" Flags: 0x%lx%s\n"),
6343 header->e_flags,
6344 get_machine_flags (filedata, header->e_flags, header->e_machine));
6345 printf (_(" Size of this header: %u (bytes)\n"),
6346 header->e_ehsize);
6347 printf (_(" Size of program headers: %u (bytes)\n"),
6348 header->e_phentsize);
6349 printf (_(" Number of program headers: %u"),
6350 header->e_phnum);
6351 if (filedata->section_headers != NULL
6352 && header->e_phnum == PN_XNUM
6353 && filedata->section_headers[0].sh_info != 0)
6354 printf (" (%u)", filedata->section_headers[0].sh_info);
6355 putc ('\n', stdout);
6356 printf (_(" Size of section headers: %u (bytes)\n"),
6357 header->e_shentsize);
6358 printf (_(" Number of section headers: %u"),
6359 header->e_shnum);
6360 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
6362 header->e_shnum = filedata->section_headers[0].sh_size;
6363 printf (" (%u)", header->e_shnum);
6365 putc ('\n', stdout);
6366 printf (_(" Section header string table index: %u"),
6367 header->e_shstrndx);
6368 if (filedata->section_headers != NULL
6369 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
6371 header->e_shstrndx = filedata->section_headers[0].sh_link;
6372 printf (" (%u)", header->e_shstrndx);
6374 if (header->e_shstrndx != SHN_UNDEF
6375 && header->e_shstrndx >= header->e_shnum)
6377 header->e_shstrndx = SHN_UNDEF;
6378 printf (_(" <corrupt: out of range>"));
6380 putc ('\n', stdout);
6383 if (filedata->section_headers != NULL)
6385 if (header->e_phnum == PN_XNUM
6386 && filedata->section_headers[0].sh_info != 0)
6388 /* Throw away any cached read of PN_XNUM headers. */
6389 free (filedata->program_headers);
6390 filedata->program_headers = NULL;
6391 header->e_phnum = filedata->section_headers[0].sh_info;
6393 if (header->e_shnum == SHN_UNDEF)
6394 header->e_shnum = filedata->section_headers[0].sh_size;
6395 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6396 header->e_shstrndx = filedata->section_headers[0].sh_link;
6397 if (header->e_shstrndx >= header->e_shnum)
6398 header->e_shstrndx = SHN_UNDEF;
6401 return true;
6404 /* Read in the program headers from FILEDATA and store them in PHEADERS.
6405 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6407 static bool
6408 get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
6410 Elf32_External_Phdr * phdrs;
6411 Elf32_External_Phdr * external;
6412 Elf_Internal_Phdr * internal;
6413 unsigned int i;
6414 unsigned int size = filedata->file_header.e_phentsize;
6415 unsigned int num = filedata->file_header.e_phnum;
6417 /* PR binutils/17531: Cope with unexpected section header sizes. */
6418 if (size == 0 || num == 0)
6419 return false;
6420 if (size < sizeof * phdrs)
6422 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
6423 return false;
6425 if (size > sizeof * phdrs)
6426 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
6428 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
6429 size, num, _("program headers"));
6430 if (phdrs == NULL)
6431 return false;
6433 for (i = 0, internal = pheaders, external = phdrs;
6434 i < filedata->file_header.e_phnum;
6435 i++, internal++, external++)
6437 internal->p_type = BYTE_GET (external->p_type);
6438 internal->p_offset = BYTE_GET (external->p_offset);
6439 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6440 internal->p_paddr = BYTE_GET (external->p_paddr);
6441 internal->p_filesz = BYTE_GET (external->p_filesz);
6442 internal->p_memsz = BYTE_GET (external->p_memsz);
6443 internal->p_flags = BYTE_GET (external->p_flags);
6444 internal->p_align = BYTE_GET (external->p_align);
6447 free (phdrs);
6448 return true;
6451 /* Read in the program headers from FILEDATA and store them in PHEADERS.
6452 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6454 static bool
6455 get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
6457 Elf64_External_Phdr * phdrs;
6458 Elf64_External_Phdr * external;
6459 Elf_Internal_Phdr * internal;
6460 unsigned int i;
6461 unsigned int size = filedata->file_header.e_phentsize;
6462 unsigned int num = filedata->file_header.e_phnum;
6464 /* PR binutils/17531: Cope with unexpected section header sizes. */
6465 if (size == 0 || num == 0)
6466 return false;
6467 if (size < sizeof * phdrs)
6469 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
6470 return false;
6472 if (size > sizeof * phdrs)
6473 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
6475 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
6476 size, num, _("program headers"));
6477 if (!phdrs)
6478 return false;
6480 for (i = 0, internal = pheaders, external = phdrs;
6481 i < filedata->file_header.e_phnum;
6482 i++, internal++, external++)
6484 internal->p_type = BYTE_GET (external->p_type);
6485 internal->p_flags = BYTE_GET (external->p_flags);
6486 internal->p_offset = BYTE_GET (external->p_offset);
6487 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6488 internal->p_paddr = BYTE_GET (external->p_paddr);
6489 internal->p_filesz = BYTE_GET (external->p_filesz);
6490 internal->p_memsz = BYTE_GET (external->p_memsz);
6491 internal->p_align = BYTE_GET (external->p_align);
6494 free (phdrs);
6495 return true;
6498 /* Returns TRUE if the program headers were read into `program_headers'. */
6500 static bool
6501 get_program_headers (Filedata * filedata)
6503 Elf_Internal_Phdr * phdrs;
6505 /* Check cache of prior read. */
6506 if (filedata->program_headers != NULL)
6507 return true;
6509 /* Be kind to memory checkers by looking for
6510 e_phnum values which we know must be invalid. */
6511 if (filedata->file_header.e_phnum
6512 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
6513 >= filedata->file_size)
6515 error (_("Too many program headers - %#x - the file is not that big\n"),
6516 filedata->file_header.e_phnum);
6517 return false;
6520 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
6521 sizeof (Elf_Internal_Phdr));
6522 if (phdrs == NULL)
6524 error (_("Out of memory reading %u program headers\n"),
6525 filedata->file_header.e_phnum);
6526 return false;
6529 if (is_32bit_elf
6530 ? get_32bit_program_headers (filedata, phdrs)
6531 : get_64bit_program_headers (filedata, phdrs))
6533 filedata->program_headers = phdrs;
6534 return true;
6537 free (phdrs);
6538 return false;
6541 /* Print program header info and locate dynamic section. */
6543 static void
6544 process_program_headers (Filedata * filedata)
6546 Elf_Internal_Phdr * segment;
6547 unsigned int i;
6548 Elf_Internal_Phdr * previous_load = NULL;
6550 if (filedata->file_header.e_phnum == 0)
6552 /* PR binutils/12467. */
6553 if (filedata->file_header.e_phoff != 0)
6554 warn (_("possibly corrupt ELF header - it has a non-zero program"
6555 " header offset, but no program headers\n"));
6556 else if (do_segments)
6558 if (filedata->is_separate)
6559 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6560 filedata->file_name);
6561 else
6562 printf (_("\nThere are no program headers in this file.\n"));
6564 goto no_headers;
6567 if (do_segments && !do_header)
6569 if (filedata->is_separate)
6570 printf ("\nIn linked file '%s' the ELF file type is %s\n",
6571 filedata->file_name, get_file_type (filedata));
6572 else
6573 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
6574 printf (_("Entry point 0x%" PRIx64 "\n"),
6575 filedata->file_header.e_entry);
6576 printf (ngettext ("There is %d program header,"
6577 " starting at offset %" PRIu64 "\n",
6578 "There are %d program headers,"
6579 " starting at offset %" PRIu64 "\n",
6580 filedata->file_header.e_phnum),
6581 filedata->file_header.e_phnum,
6582 filedata->file_header.e_phoff);
6585 if (! get_program_headers (filedata))
6586 goto no_headers;
6588 if (do_segments)
6590 if (filedata->file_header.e_phnum > 1)
6591 printf (_("\nProgram Headers:\n"));
6592 else
6593 printf (_("\nProgram Headers:\n"));
6595 if (is_32bit_elf)
6596 printf
6597 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
6598 else if (do_wide)
6599 printf
6600 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
6601 else
6603 printf
6604 (_(" Type Offset VirtAddr PhysAddr\n"));
6605 printf
6606 (_(" FileSiz MemSiz Flags Align\n"));
6610 uint64_t dynamic_addr = 0;
6611 uint64_t dynamic_size = 0;
6612 for (i = 0, segment = filedata->program_headers;
6613 i < filedata->file_header.e_phnum;
6614 i++, segment++)
6616 if (do_segments)
6618 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
6620 if (is_32bit_elf)
6622 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6623 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6624 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6625 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6626 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6627 printf ("%c%c%c ",
6628 (segment->p_flags & PF_R ? 'R' : ' '),
6629 (segment->p_flags & PF_W ? 'W' : ' '),
6630 (segment->p_flags & PF_X ? 'E' : ' '));
6631 printf ("%#lx", (unsigned long) segment->p_align);
6633 else if (do_wide)
6635 if ((unsigned long) segment->p_offset == segment->p_offset)
6636 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6637 else
6639 print_vma (segment->p_offset, FULL_HEX);
6640 putchar (' ');
6643 print_vma (segment->p_vaddr, FULL_HEX);
6644 putchar (' ');
6645 print_vma (segment->p_paddr, FULL_HEX);
6646 putchar (' ');
6648 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6649 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6650 else
6652 print_vma (segment->p_filesz, FULL_HEX);
6653 putchar (' ');
6656 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6657 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6658 else
6660 print_vma (segment->p_memsz, FULL_HEX);
6663 printf (" %c%c%c ",
6664 (segment->p_flags & PF_R ? 'R' : ' '),
6665 (segment->p_flags & PF_W ? 'W' : ' '),
6666 (segment->p_flags & PF_X ? 'E' : ' '));
6668 if ((unsigned long) segment->p_align == segment->p_align)
6669 printf ("%#lx", (unsigned long) segment->p_align);
6670 else
6672 print_vma (segment->p_align, PREFIX_HEX);
6675 else
6677 print_vma (segment->p_offset, FULL_HEX);
6678 putchar (' ');
6679 print_vma (segment->p_vaddr, FULL_HEX);
6680 putchar (' ');
6681 print_vma (segment->p_paddr, FULL_HEX);
6682 printf ("\n ");
6683 print_vma (segment->p_filesz, FULL_HEX);
6684 putchar (' ');
6685 print_vma (segment->p_memsz, FULL_HEX);
6686 printf (" %c%c%c ",
6687 (segment->p_flags & PF_R ? 'R' : ' '),
6688 (segment->p_flags & PF_W ? 'W' : ' '),
6689 (segment->p_flags & PF_X ? 'E' : ' '));
6690 print_vma (segment->p_align, PREFIX_HEX);
6693 putc ('\n', stdout);
6696 switch (segment->p_type)
6698 case PT_LOAD:
6699 #if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6700 required by the ELF standard, several programs, including the Linux
6701 kernel, make use of non-ordered segments. */
6702 if (previous_load
6703 && previous_load->p_vaddr > segment->p_vaddr)
6704 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
6705 #endif
6706 if (segment->p_memsz < segment->p_filesz)
6707 error (_("the segment's file size is larger than its memory size\n"));
6708 previous_load = segment;
6709 break;
6711 case PT_PHDR:
6712 /* PR 20815 - Verify that the program header is loaded into memory. */
6713 if (i > 0 && previous_load != NULL)
6714 error (_("the PHDR segment must occur before any LOAD segment\n"));
6715 if (filedata->file_header.e_machine != EM_PARISC)
6717 unsigned int j;
6719 for (j = 1; j < filedata->file_header.e_phnum; j++)
6721 Elf_Internal_Phdr *load = filedata->program_headers + j;
6722 if (load->p_type == PT_LOAD
6723 && load->p_offset <= segment->p_offset
6724 && (load->p_offset + load->p_filesz
6725 >= segment->p_offset + segment->p_filesz)
6726 && load->p_vaddr <= segment->p_vaddr
6727 && (load->p_vaddr + load->p_filesz
6728 >= segment->p_vaddr + segment->p_filesz))
6729 break;
6731 if (j == filedata->file_header.e_phnum)
6732 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6734 break;
6736 case PT_DYNAMIC:
6737 if (dynamic_addr)
6738 error (_("more than one dynamic segment\n"));
6740 /* By default, assume that the .dynamic section is the first
6741 section in the DYNAMIC segment. */
6742 dynamic_addr = segment->p_offset;
6743 dynamic_size = segment->p_filesz;
6745 /* Try to locate the .dynamic section. If there is
6746 a section header table, we can easily locate it. */
6747 if (filedata->section_headers != NULL)
6749 Elf_Internal_Shdr * sec;
6751 sec = find_section (filedata, ".dynamic");
6752 if (sec == NULL || sec->sh_size == 0)
6754 /* A corresponding .dynamic section is expected, but on
6755 IA-64/OpenVMS it is OK for it to be missing. */
6756 if (!is_ia64_vms (filedata))
6757 error (_("no .dynamic section in the dynamic segment\n"));
6758 break;
6761 if (sec->sh_type == SHT_NOBITS)
6763 dynamic_addr = 0;
6764 dynamic_size = 0;
6765 break;
6768 dynamic_addr = sec->sh_offset;
6769 dynamic_size = sec->sh_size;
6771 /* The PT_DYNAMIC segment, which is used by the run-time
6772 loader, should exactly match the .dynamic section. */
6773 if (do_checks
6774 && (dynamic_addr != segment->p_offset
6775 || dynamic_size != segment->p_filesz))
6776 warn (_("\
6777 the .dynamic section is not the same as the dynamic segment\n"));
6780 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6781 segment. Check this after matching against the section headers
6782 so we don't warn on debuginfo file (which have NOBITS .dynamic
6783 sections). */
6784 if (dynamic_addr > filedata->file_size
6785 || (dynamic_size > filedata->file_size - dynamic_addr))
6787 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
6788 dynamic_addr = 0;
6789 dynamic_size = 0;
6791 break;
6793 case PT_INTERP:
6794 if (segment->p_offset >= filedata->file_size
6795 || segment->p_filesz > filedata->file_size - segment->p_offset
6796 || segment->p_filesz - 1 >= (size_t) -2
6797 || fseek64 (filedata->handle,
6798 filedata->archive_file_offset + segment->p_offset,
6799 SEEK_SET))
6800 error (_("Unable to find program interpreter name\n"));
6801 else
6803 size_t len = segment->p_filesz;
6804 free (filedata->program_interpreter);
6805 filedata->program_interpreter = xmalloc (len + 1);
6806 len = fread (filedata->program_interpreter, 1, len,
6807 filedata->handle);
6808 filedata->program_interpreter[len] = 0;
6810 if (do_segments)
6811 printf (_(" [Requesting program interpreter: %s]\n"),
6812 filedata->program_interpreter);
6814 break;
6818 if (do_segments
6819 && filedata->section_headers != NULL
6820 && filedata->string_table != NULL)
6822 printf (_("\n Section to Segment mapping:\n"));
6823 printf (_(" Segment Sections...\n"));
6825 for (i = 0; i < filedata->file_header.e_phnum; i++)
6827 unsigned int j;
6828 Elf_Internal_Shdr * section;
6830 segment = filedata->program_headers + i;
6831 section = filedata->section_headers + 1;
6833 printf (" %2.2d ", i);
6835 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
6837 if (!ELF_TBSS_SPECIAL (section, segment)
6838 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
6839 printf ("%s ", printable_section_name (filedata, section));
6842 putc ('\n',stdout);
6846 filedata->dynamic_addr = dynamic_addr;
6847 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6848 return;
6850 no_headers:
6851 filedata->dynamic_addr = 0;
6852 filedata->dynamic_size = 1;
6856 /* Find the file offset corresponding to VMA by using the program headers. */
6858 static int64_t
6859 offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
6861 Elf_Internal_Phdr * seg;
6863 if (! get_program_headers (filedata))
6865 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6866 return (long) vma;
6869 for (seg = filedata->program_headers;
6870 seg < filedata->program_headers + filedata->file_header.e_phnum;
6871 ++seg)
6873 if (seg->p_type != PT_LOAD)
6874 continue;
6876 if (vma >= (seg->p_vaddr & -seg->p_align)
6877 && vma + size <= seg->p_vaddr + seg->p_filesz)
6878 return vma - seg->p_vaddr + seg->p_offset;
6881 warn (_("Virtual address %#" PRIx64
6882 " not located in any PT_LOAD segment.\n"), vma);
6883 return vma;
6887 /* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6888 If PROBE is true, this is just a probe and we do not generate any error
6889 messages if the load fails. */
6891 static bool
6892 get_32bit_section_headers (Filedata * filedata, bool probe)
6894 Elf32_External_Shdr * shdrs;
6895 Elf_Internal_Shdr * internal;
6896 unsigned int i;
6897 unsigned int size = filedata->file_header.e_shentsize;
6898 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
6900 /* PR binutils/17531: Cope with unexpected section header sizes. */
6901 if (size == 0 || num == 0)
6902 return false;
6904 /* The section header cannot be at the start of the file - that is
6905 where the ELF file header is located. A file with absolutely no
6906 sections in it will use a shoff of 0. */
6907 if (filedata->file_header.e_shoff == 0)
6908 return false;
6910 if (size < sizeof * shdrs)
6912 if (! probe)
6913 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
6914 return false;
6916 if (!probe && size > sizeof * shdrs)
6917 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
6919 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
6920 size, num,
6921 probe ? NULL : _("section headers"));
6922 if (shdrs == NULL)
6923 return false;
6925 filedata->section_headers = (Elf_Internal_Shdr *)
6926 cmalloc (num, sizeof (Elf_Internal_Shdr));
6927 if (filedata->section_headers == NULL)
6929 if (!probe)
6930 error (_("Out of memory reading %u section headers\n"), num);
6931 free (shdrs);
6932 return false;
6935 for (i = 0, internal = filedata->section_headers;
6936 i < num;
6937 i++, internal++)
6939 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6940 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6941 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6942 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6943 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6944 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6945 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6946 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6947 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6948 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
6949 if (!probe && internal->sh_link > num)
6950 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6951 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6952 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
6955 free (shdrs);
6956 return true;
6959 /* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6961 static bool
6962 get_64bit_section_headers (Filedata * filedata, bool probe)
6964 Elf64_External_Shdr * shdrs;
6965 Elf_Internal_Shdr * internal;
6966 unsigned int i;
6967 unsigned int size = filedata->file_header.e_shentsize;
6968 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
6970 /* PR binutils/17531: Cope with unexpected section header sizes. */
6971 if (size == 0 || num == 0)
6972 return false;
6974 /* The section header cannot be at the start of the file - that is
6975 where the ELF file header is located. A file with absolutely no
6976 sections in it will use a shoff of 0. */
6977 if (filedata->file_header.e_shoff == 0)
6978 return false;
6980 if (size < sizeof * shdrs)
6982 if (! probe)
6983 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
6984 return false;
6987 if (! probe && size > sizeof * shdrs)
6988 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
6990 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6991 filedata->file_header.e_shoff,
6992 size, num,
6993 probe ? NULL : _("section headers"));
6994 if (shdrs == NULL)
6995 return false;
6997 filedata->section_headers = (Elf_Internal_Shdr *)
6998 cmalloc (num, sizeof (Elf_Internal_Shdr));
6999 if (filedata->section_headers == NULL)
7001 if (! probe)
7002 error (_("Out of memory reading %u section headers\n"), num);
7003 free (shdrs);
7004 return false;
7007 for (i = 0, internal = filedata->section_headers;
7008 i < num;
7009 i++, internal++)
7011 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7012 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7013 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7014 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7015 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7016 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
7017 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7018 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7019 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7020 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7021 if (!probe && internal->sh_link > num)
7022 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7023 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7024 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
7027 free (shdrs);
7028 return true;
7031 static bool
7032 get_section_headers (Filedata *filedata, bool probe)
7034 if (filedata->section_headers != NULL)
7035 return true;
7037 if (is_32bit_elf)
7038 return get_32bit_section_headers (filedata, probe);
7039 else
7040 return get_64bit_section_headers (filedata, probe);
7043 static Elf_Internal_Sym *
7044 get_32bit_elf_symbols (Filedata *filedata,
7045 Elf_Internal_Shdr *section,
7046 uint64_t *num_syms_return)
7048 uint64_t number = 0;
7049 Elf32_External_Sym * esyms = NULL;
7050 Elf_External_Sym_Shndx * shndx = NULL;
7051 Elf_Internal_Sym * isyms = NULL;
7052 Elf_Internal_Sym * psym;
7053 unsigned int j;
7054 elf_section_list * entry;
7056 if (section->sh_size == 0)
7058 if (num_syms_return != NULL)
7059 * num_syms_return = 0;
7060 return NULL;
7063 /* Run some sanity checks first. */
7064 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
7066 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
7067 printable_section_name (filedata, section),
7068 section->sh_entsize);
7069 goto exit_point;
7072 if (section->sh_size > filedata->file_size)
7074 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
7075 printable_section_name (filedata, section),
7076 section->sh_size);
7077 goto exit_point;
7080 number = section->sh_size / section->sh_entsize;
7082 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7084 error (_("Size (%#" PRIx64 ") of section %s "
7085 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7086 section->sh_size,
7087 printable_section_name (filedata, section),
7088 section->sh_entsize);
7089 goto exit_point;
7092 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
7093 section->sh_size, _("symbols"));
7094 if (esyms == NULL)
7095 goto exit_point;
7097 shndx = NULL;
7098 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
7100 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
7101 continue;
7103 if (shndx != NULL)
7105 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7106 free (shndx);
7109 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7110 entry->hdr->sh_offset,
7111 1, entry->hdr->sh_size,
7112 _("symbol table section indices"));
7113 if (shndx == NULL)
7114 goto exit_point;
7116 /* PR17531: file: heap-buffer-overflow */
7117 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7119 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
7120 printable_section_name (filedata, entry->hdr),
7121 entry->hdr->sh_size,
7122 section->sh_size);
7123 goto exit_point;
7127 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
7129 if (isyms == NULL)
7131 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
7132 goto exit_point;
7135 for (j = 0, psym = isyms; j < number; j++, psym++)
7137 psym->st_name = BYTE_GET (esyms[j].st_name);
7138 psym->st_value = BYTE_GET (esyms[j].st_value);
7139 psym->st_size = BYTE_GET (esyms[j].st_size);
7140 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
7141 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
7142 psym->st_shndx
7143 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
7144 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7145 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
7146 psym->st_info = BYTE_GET (esyms[j].st_info);
7147 psym->st_other = BYTE_GET (esyms[j].st_other);
7150 exit_point:
7151 free (shndx);
7152 free (esyms);
7154 if (num_syms_return != NULL)
7155 * num_syms_return = isyms == NULL ? 0 : number;
7157 return isyms;
7160 static Elf_Internal_Sym *
7161 get_64bit_elf_symbols (Filedata *filedata,
7162 Elf_Internal_Shdr *section,
7163 uint64_t *num_syms_return)
7165 uint64_t number = 0;
7166 Elf64_External_Sym * esyms = NULL;
7167 Elf_External_Sym_Shndx * shndx = NULL;
7168 Elf_Internal_Sym * isyms = NULL;
7169 Elf_Internal_Sym * psym;
7170 unsigned int j;
7171 elf_section_list * entry;
7173 if (section->sh_size == 0)
7175 if (num_syms_return != NULL)
7176 * num_syms_return = 0;
7177 return NULL;
7180 /* Run some sanity checks first. */
7181 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
7183 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
7184 printable_section_name (filedata, section),
7185 section->sh_entsize);
7186 goto exit_point;
7189 if (section->sh_size > filedata->file_size)
7191 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
7192 printable_section_name (filedata, section),
7193 section->sh_size);
7194 goto exit_point;
7197 number = section->sh_size / section->sh_entsize;
7199 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7201 error (_("Size (%#" PRIx64 ") of section %s "
7202 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7203 section->sh_size,
7204 printable_section_name (filedata, section),
7205 section->sh_entsize);
7206 goto exit_point;
7209 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
7210 section->sh_size, _("symbols"));
7211 if (!esyms)
7212 goto exit_point;
7214 shndx = NULL;
7215 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
7217 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
7218 continue;
7220 if (shndx != NULL)
7222 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7223 free (shndx);
7226 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7227 entry->hdr->sh_offset,
7228 1, entry->hdr->sh_size,
7229 _("symbol table section indices"));
7230 if (shndx == NULL)
7231 goto exit_point;
7233 /* PR17531: file: heap-buffer-overflow */
7234 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7236 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
7237 printable_section_name (filedata, entry->hdr),
7238 entry->hdr->sh_size,
7239 section->sh_size);
7240 goto exit_point;
7244 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
7246 if (isyms == NULL)
7248 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
7249 goto exit_point;
7252 for (j = 0, psym = isyms; j < number; j++, psym++)
7254 psym->st_name = BYTE_GET (esyms[j].st_name);
7255 psym->st_info = BYTE_GET (esyms[j].st_info);
7256 psym->st_other = BYTE_GET (esyms[j].st_other);
7257 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
7259 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
7260 psym->st_shndx
7261 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
7262 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7263 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
7265 psym->st_value = BYTE_GET (esyms[j].st_value);
7266 psym->st_size = BYTE_GET (esyms[j].st_size);
7269 exit_point:
7270 free (shndx);
7271 free (esyms);
7273 if (num_syms_return != NULL)
7274 * num_syms_return = isyms == NULL ? 0 : number;
7276 return isyms;
7279 static Elf_Internal_Sym *
7280 get_elf_symbols (Filedata *filedata,
7281 Elf_Internal_Shdr *section,
7282 uint64_t *num_syms_return)
7284 if (is_32bit_elf)
7285 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7286 else
7287 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7290 static const char *
7291 get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
7293 static char buff[1024];
7294 char * p = buff;
7295 unsigned int field_size = is_32bit_elf ? 8 : 16;
7296 signed int sindex;
7297 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
7298 uint64_t os_flags = 0;
7299 uint64_t proc_flags = 0;
7300 uint64_t unknown_flags = 0;
7301 static const struct
7303 const char * str;
7304 unsigned int len;
7306 flags [] =
7308 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7309 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7310 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7311 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7312 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7313 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7314 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7315 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7316 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7317 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7318 /* IA-64 specific. */
7319 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7320 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7321 /* IA-64 OpenVMS specific. */
7322 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7323 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7324 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7325 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7326 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7327 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
7328 /* Generic. */
7329 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
7330 /* SPARC specific. */
7331 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
7332 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7333 /* ARM specific. */
7334 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
7335 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
7336 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7337 /* GNU specific. */
7338 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
7339 /* VLE specific. */
7340 /* 25 */ { STRING_COMMA_LEN ("VLE") },
7341 /* GNU specific. */
7342 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
7345 if (do_section_details)
7346 p += sprintf (p, "[%*.*lx]: ",
7347 field_size, field_size, (unsigned long) sh_flags);
7349 while (sh_flags)
7351 uint64_t flag;
7353 flag = sh_flags & - sh_flags;
7354 sh_flags &= ~ flag;
7356 if (do_section_details)
7358 switch (flag)
7360 case SHF_WRITE: sindex = 0; break;
7361 case SHF_ALLOC: sindex = 1; break;
7362 case SHF_EXECINSTR: sindex = 2; break;
7363 case SHF_MERGE: sindex = 3; break;
7364 case SHF_STRINGS: sindex = 4; break;
7365 case SHF_INFO_LINK: sindex = 5; break;
7366 case SHF_LINK_ORDER: sindex = 6; break;
7367 case SHF_OS_NONCONFORMING: sindex = 7; break;
7368 case SHF_GROUP: sindex = 8; break;
7369 case SHF_TLS: sindex = 9; break;
7370 case SHF_EXCLUDE: sindex = 18; break;
7371 case SHF_COMPRESSED: sindex = 20; break;
7373 default:
7374 sindex = -1;
7375 switch (filedata->file_header.e_machine)
7377 case EM_IA_64:
7378 if (flag == SHF_IA_64_SHORT)
7379 sindex = 10;
7380 else if (flag == SHF_IA_64_NORECOV)
7381 sindex = 11;
7382 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
7383 switch (flag)
7385 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7386 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7387 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7388 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7389 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7390 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
7391 default: break;
7393 break;
7395 case EM_386:
7396 case EM_IAMCU:
7397 case EM_X86_64:
7398 case EM_L1OM:
7399 case EM_K1OM:
7400 case EM_OLD_SPARCV9:
7401 case EM_SPARC32PLUS:
7402 case EM_SPARCV9:
7403 case EM_SPARC:
7404 if (flag == SHF_ORDERED)
7405 sindex = 19;
7406 break;
7408 case EM_ARM:
7409 switch (flag)
7411 case SHF_ENTRYSECT: sindex = 21; break;
7412 case SHF_ARM_PURECODE: sindex = 22; break;
7413 case SHF_COMDEF: sindex = 23; break;
7414 default: break;
7416 break;
7417 case EM_PPC:
7418 if (flag == SHF_PPC_VLE)
7419 sindex = 25;
7420 break;
7421 default:
7422 break;
7425 switch (filedata->file_header.e_ident[EI_OSABI])
7427 case ELFOSABI_GNU:
7428 case ELFOSABI_FREEBSD:
7429 if (flag == SHF_GNU_RETAIN)
7430 sindex = 26;
7431 /* Fall through */
7432 case ELFOSABI_NONE:
7433 if (flag == SHF_GNU_MBIND)
7434 /* We should not recognize SHF_GNU_MBIND for
7435 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7436 not set the EI_OSABI header byte. */
7437 sindex = 24;
7438 break;
7439 default:
7440 break;
7442 break;
7445 if (sindex != -1)
7447 if (p != buff + field_size + 4)
7449 if (size < (10 + 2))
7451 warn (_("Internal error: not enough buffer room for section flag info"));
7452 return _("<unknown>");
7454 size -= 2;
7455 *p++ = ',';
7456 *p++ = ' ';
7459 size -= flags [sindex].len;
7460 p = stpcpy (p, flags [sindex].str);
7462 else if (flag & SHF_MASKOS)
7463 os_flags |= flag;
7464 else if (flag & SHF_MASKPROC)
7465 proc_flags |= flag;
7466 else
7467 unknown_flags |= flag;
7469 else
7471 switch (flag)
7473 case SHF_WRITE: *p = 'W'; break;
7474 case SHF_ALLOC: *p = 'A'; break;
7475 case SHF_EXECINSTR: *p = 'X'; break;
7476 case SHF_MERGE: *p = 'M'; break;
7477 case SHF_STRINGS: *p = 'S'; break;
7478 case SHF_INFO_LINK: *p = 'I'; break;
7479 case SHF_LINK_ORDER: *p = 'L'; break;
7480 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7481 case SHF_GROUP: *p = 'G'; break;
7482 case SHF_TLS: *p = 'T'; break;
7483 case SHF_EXCLUDE: *p = 'E'; break;
7484 case SHF_COMPRESSED: *p = 'C'; break;
7486 default:
7487 if ((filedata->file_header.e_machine == EM_X86_64
7488 || filedata->file_header.e_machine == EM_L1OM
7489 || filedata->file_header.e_machine == EM_K1OM)
7490 && flag == SHF_X86_64_LARGE)
7491 *p = 'l';
7492 else if (filedata->file_header.e_machine == EM_ARM
7493 && flag == SHF_ARM_PURECODE)
7494 *p = 'y';
7495 else if (filedata->file_header.e_machine == EM_PPC
7496 && flag == SHF_PPC_VLE)
7497 *p = 'v';
7498 else if (flag & SHF_MASKOS)
7500 switch (filedata->file_header.e_ident[EI_OSABI])
7502 case ELFOSABI_GNU:
7503 case ELFOSABI_FREEBSD:
7504 if (flag == SHF_GNU_RETAIN)
7506 *p = 'R';
7507 break;
7509 /* Fall through */
7510 case ELFOSABI_NONE:
7511 if (flag == SHF_GNU_MBIND)
7513 /* We should not recognize SHF_GNU_MBIND for
7514 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7515 not set the EI_OSABI header byte. */
7516 *p = 'D';
7517 break;
7519 /* Fall through */
7520 default:
7521 *p = 'o';
7522 sh_flags &= ~SHF_MASKOS;
7523 break;
7526 else if (flag & SHF_MASKPROC)
7528 *p = 'p';
7529 sh_flags &= ~ SHF_MASKPROC;
7531 else
7532 *p = 'x';
7533 break;
7535 p++;
7539 if (do_section_details)
7541 if (os_flags)
7543 if (p != buff + field_size + 4)
7545 if (size < 2 + 5 + field_size + 1)
7547 warn (_("Internal error: not enough buffer room for section flag info"));
7548 return _("<unknown>");
7550 size -= 2;
7551 *p++ = ',';
7552 *p++ = ' ';
7554 size -= 5 + field_size;
7555 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
7556 (unsigned long) os_flags);
7558 if (proc_flags)
7560 if (p != buff + field_size + 4)
7562 if (size < 2 + 7 + field_size + 1)
7564 warn (_("Internal error: not enough buffer room for section flag info"));
7565 return _("<unknown>");
7567 size -= 2;
7568 *p++ = ',';
7569 *p++ = ' ';
7571 size -= 7 + field_size;
7572 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7573 (unsigned long) proc_flags);
7575 if (unknown_flags)
7577 if (p != buff + field_size + 4)
7579 if (size < 2 + 10 + field_size + 1)
7581 warn (_("Internal error: not enough buffer room for section flag info"));
7582 return _("<unknown>");
7584 size -= 2;
7585 *p++ = ',';
7586 *p++ = ' ';
7588 size -= 10 + field_size;
7589 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
7590 (unsigned long) unknown_flags);
7594 *p = '\0';
7595 return buff;
7598 static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
7599 get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7600 uint64_t size)
7602 if (is_32bit_elf)
7604 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
7606 if (size < sizeof (* echdr))
7608 error (_("Compressed section is too small even for a compression header\n"));
7609 return 0;
7612 chdr->ch_type = BYTE_GET (echdr->ch_type);
7613 chdr->ch_size = BYTE_GET (echdr->ch_size);
7614 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7615 return sizeof (*echdr);
7617 else
7619 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
7621 if (size < sizeof (* echdr))
7623 error (_("Compressed section is too small even for a compression header\n"));
7624 return 0;
7627 chdr->ch_type = BYTE_GET (echdr->ch_type);
7628 chdr->ch_size = BYTE_GET (echdr->ch_size);
7629 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7630 return sizeof (*echdr);
7634 static bool
7635 process_section_headers (Filedata * filedata)
7637 Elf_Internal_Shdr * section;
7638 unsigned int i;
7640 if (filedata->file_header.e_shnum == 0)
7642 /* PR binutils/12467. */
7643 if (filedata->file_header.e_shoff != 0)
7645 warn (_("possibly corrupt ELF file header - it has a non-zero"
7646 " section header offset, but no section headers\n"));
7647 return false;
7649 else if (do_sections)
7650 printf (_("\nThere are no sections in this file.\n"));
7652 return true;
7655 if (do_sections && !do_header)
7657 if (filedata->is_separate && process_links)
7658 printf (_("In linked file '%s': "), filedata->file_name);
7659 if (! filedata->is_separate || process_links)
7660 printf (ngettext ("There is %d section header, "
7661 "starting at offset %#" PRIx64 ":\n",
7662 "There are %d section headers, "
7663 "starting at offset %#" PRIx64 ":\n",
7664 filedata->file_header.e_shnum),
7665 filedata->file_header.e_shnum,
7666 filedata->file_header.e_shoff);
7669 if (!get_section_headers (filedata, false))
7670 return false;
7672 /* Read in the string table, so that we have names to display. */
7673 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7674 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
7676 section = filedata->section_headers + filedata->file_header.e_shstrndx;
7678 if (section->sh_size != 0)
7680 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7681 1, section->sh_size,
7682 _("string table"));
7684 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
7688 /* Scan the sections for the dynamic symbol table
7689 and dynamic string table and debug sections. */
7690 eh_addr_size = is_32bit_elf ? 4 : 8;
7691 switch (filedata->file_header.e_machine)
7693 case EM_MIPS:
7694 case EM_MIPS_RS3_LE:
7695 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7696 FDE addresses. However, the ABI also has a semi-official ILP32
7697 variant for which the normal FDE address size rules apply.
7699 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7700 section, where XX is the size of longs in bits. Unfortunately,
7701 earlier compilers provided no way of distinguishing ILP32 objects
7702 from LP64 objects, so if there's any doubt, we should assume that
7703 the official LP64 form is being used. */
7704 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
7705 && find_section (filedata, ".gcc_compiled_long32") == NULL)
7706 eh_addr_size = 8;
7707 break;
7709 case EM_H8_300:
7710 case EM_H8_300H:
7711 switch (filedata->file_header.e_flags & EF_H8_MACH)
7713 case E_H8_MACH_H8300:
7714 case E_H8_MACH_H8300HN:
7715 case E_H8_MACH_H8300SN:
7716 case E_H8_MACH_H8300SXN:
7717 eh_addr_size = 2;
7718 break;
7719 case E_H8_MACH_H8300H:
7720 case E_H8_MACH_H8300S:
7721 case E_H8_MACH_H8300SX:
7722 eh_addr_size = 4;
7723 break;
7725 break;
7727 case EM_M32C_OLD:
7728 case EM_M32C:
7729 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
7731 case EF_M32C_CPU_M16C:
7732 eh_addr_size = 2;
7733 break;
7735 break;
7738 #define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7739 do \
7741 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
7742 if (section->sh_entsize != expected_entsize) \
7744 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
7745 i, section->sh_entsize); \
7746 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
7747 expected_entsize); \
7748 section->sh_entsize = expected_entsize; \
7751 while (0)
7753 #define CHECK_ENTSIZE(section, i, type) \
7754 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
7755 sizeof (Elf64_External_##type))
7757 for (i = 0, section = filedata->section_headers;
7758 i < filedata->file_header.e_shnum;
7759 i++, section++)
7761 const char *name = printable_section_name (filedata, section);
7763 /* Run some sanity checks on the headers and
7764 possibly fill in some file data as well. */
7765 switch (section->sh_type)
7767 case SHT_DYNSYM:
7768 if (filedata->dynamic_symbols != NULL)
7770 error (_("File contains multiple dynamic symbol tables\n"));
7771 continue;
7774 CHECK_ENTSIZE (section, i, Sym);
7775 filedata->dynamic_symbols
7776 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
7777 filedata->dynamic_symtab_section = section;
7778 break;
7780 case SHT_STRTAB:
7781 if (streq (name, ".dynstr"))
7783 if (filedata->dynamic_strings != NULL)
7785 error (_("File contains multiple dynamic string tables\n"));
7786 continue;
7789 filedata->dynamic_strings
7790 = (char *) get_data (NULL, filedata, section->sh_offset,
7791 1, section->sh_size, _("dynamic strings"));
7792 filedata->dynamic_strings_length
7793 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
7794 filedata->dynamic_strtab_section = section;
7796 break;
7798 case SHT_SYMTAB_SHNDX:
7800 elf_section_list * entry = xmalloc (sizeof * entry);
7802 entry->hdr = section;
7803 entry->next = filedata->symtab_shndx_list;
7804 filedata->symtab_shndx_list = entry;
7806 break;
7808 case SHT_SYMTAB:
7809 CHECK_ENTSIZE (section, i, Sym);
7810 break;
7812 case SHT_GROUP:
7813 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7814 break;
7816 case SHT_REL:
7817 CHECK_ENTSIZE (section, i, Rel);
7818 if (do_checks && section->sh_size == 0)
7819 warn (_("Section '%s': zero-sized relocation section\n"), name);
7820 break;
7822 case SHT_RELA:
7823 CHECK_ENTSIZE (section, i, Rela);
7824 if (do_checks && section->sh_size == 0)
7825 warn (_("Section '%s': zero-sized relocation section\n"), name);
7826 break;
7828 case SHT_RELR:
7829 CHECK_ENTSIZE (section, i, Relr);
7830 break;
7832 case SHT_NOTE:
7833 case SHT_PROGBITS:
7834 /* Having a zero sized section is not illegal according to the
7835 ELF standard, but it might be an indication that something
7836 is wrong. So issue a warning if we are running in lint mode. */
7837 if (do_checks && section->sh_size == 0)
7838 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7839 break;
7841 default:
7842 break;
7845 if ((do_debugging || do_debug_info || do_debug_abbrevs
7846 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7847 || do_debug_aranges || do_debug_frames || do_debug_macinfo
7848 || do_debug_str || do_debug_str_offsets || do_debug_loc
7849 || do_debug_ranges
7850 || do_debug_addr || do_debug_cu_index || do_debug_links)
7851 && (startswith (name, ".debug_")
7852 || startswith (name, ".zdebug_")))
7854 if (name[1] == 'z')
7855 name += sizeof (".zdebug_") - 1;
7856 else
7857 name += sizeof (".debug_") - 1;
7859 if (do_debugging
7860 || (do_debug_info && startswith (name, "info"))
7861 || (do_debug_info && startswith (name, "types"))
7862 || (do_debug_abbrevs && startswith (name, "abbrev"))
7863 || (do_debug_lines && strcmp (name, "line") == 0)
7864 || (do_debug_lines && startswith (name, "line."))
7865 || (do_debug_pubnames && startswith (name, "pubnames"))
7866 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7867 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7868 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7869 || (do_debug_aranges && startswith (name, "aranges"))
7870 || (do_debug_ranges && startswith (name, "ranges"))
7871 || (do_debug_ranges && startswith (name, "rnglists"))
7872 || (do_debug_frames && startswith (name, "frame"))
7873 || (do_debug_macinfo && startswith (name, "macinfo"))
7874 || (do_debug_macinfo && startswith (name, "macro"))
7875 || (do_debug_str && startswith (name, "str"))
7876 || (do_debug_links && startswith (name, "sup"))
7877 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7878 || (do_debug_loc && startswith (name, "loc"))
7879 || (do_debug_loc && startswith (name, "loclists"))
7880 || (do_debug_addr && startswith (name, "addr"))
7881 || (do_debug_cu_index && startswith (name, "cu_index"))
7882 || (do_debug_cu_index && startswith (name, "tu_index"))
7884 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7886 /* Linkonce section to be combined with .debug_info at link time. */
7887 else if ((do_debugging || do_debug_info)
7888 && startswith (name, ".gnu.linkonce.wi."))
7889 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7890 else if (do_debug_frames && streq (name, ".eh_frame"))
7891 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7892 else if (do_debug_frames && streq (name, ".eh_frame_hdr"))
7893 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7894 else if (do_gdb_index && (streq (name, ".gdb_index")
7895 || streq (name, ".debug_names")))
7896 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7897 /* Trace sections for Itanium VMS. */
7898 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7899 || do_trace_aranges)
7900 && startswith (name, ".trace_"))
7902 name += sizeof (".trace_") - 1;
7904 if (do_debugging
7905 || (do_trace_info && streq (name, "info"))
7906 || (do_trace_abbrevs && streq (name, "abbrev"))
7907 || (do_trace_aranges && streq (name, "aranges"))
7909 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7911 else if ((do_debugging || do_debug_links)
7912 && (startswith (name, ".gnu_debuglink")
7913 || startswith (name, ".gnu_debugaltlink")))
7914 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
7917 if (! do_sections)
7918 return true;
7920 if (filedata->is_separate && ! process_links)
7921 return true;
7923 if (filedata->is_separate)
7924 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7925 else if (filedata->file_header.e_shnum > 1)
7926 printf (_("\nSection Headers:\n"));
7927 else
7928 printf (_("\nSection Header:\n"));
7930 if (is_32bit_elf)
7932 if (do_section_details)
7934 printf (_(" [Nr] Name\n"));
7935 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
7937 else
7938 printf
7939 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7941 else if (do_wide)
7943 if (do_section_details)
7945 printf (_(" [Nr] Name\n"));
7946 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
7948 else
7949 printf
7950 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7952 else
7954 if (do_section_details)
7956 printf (_(" [Nr] Name\n"));
7957 printf (_(" Type Address Offset Link\n"));
7958 printf (_(" Size EntSize Info Align\n"));
7960 else
7962 printf (_(" [Nr] Name Type Address Offset\n"));
7963 printf (_(" Size EntSize Flags Link Info Align\n"));
7967 if (do_section_details)
7968 printf (_(" Flags\n"));
7970 for (i = 0, section = filedata->section_headers;
7971 i < filedata->file_header.e_shnum;
7972 i++, section++)
7974 /* Run some sanity checks on the section header. */
7976 /* Check the sh_link field. */
7977 switch (section->sh_type)
7979 case SHT_REL:
7980 case SHT_RELA:
7981 if (section->sh_link == 0
7982 && (filedata->file_header.e_type == ET_EXEC
7983 || filedata->file_header.e_type == ET_DYN))
7984 /* A dynamic relocation section where all entries use a
7985 zero symbol index need not specify a symtab section. */
7986 break;
7987 /* Fall through. */
7988 case SHT_SYMTAB_SHNDX:
7989 case SHT_GROUP:
7990 case SHT_HASH:
7991 case SHT_GNU_HASH:
7992 case SHT_GNU_versym:
7993 if (section->sh_link == 0
7994 || section->sh_link >= filedata->file_header.e_shnum
7995 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7996 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
7997 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7998 i, section->sh_link);
7999 break;
8001 case SHT_DYNAMIC:
8002 case SHT_SYMTAB:
8003 case SHT_DYNSYM:
8004 case SHT_GNU_verneed:
8005 case SHT_GNU_verdef:
8006 case SHT_GNU_LIBLIST:
8007 if (section->sh_link == 0
8008 || section->sh_link >= filedata->file_header.e_shnum
8009 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
8010 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8011 i, section->sh_link);
8012 break;
8014 case SHT_INIT_ARRAY:
8015 case SHT_FINI_ARRAY:
8016 case SHT_PREINIT_ARRAY:
8017 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8018 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8019 i, section->sh_link);
8020 break;
8022 default:
8023 /* FIXME: Add support for target specific section types. */
8024 #if 0 /* Currently we do not check other section types as there are too
8025 many special cases. Stab sections for example have a type
8026 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8027 section. */
8028 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8029 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8030 i, section->sh_link);
8031 #endif
8032 break;
8035 /* Check the sh_info field. */
8036 switch (section->sh_type)
8038 case SHT_REL:
8039 case SHT_RELA:
8040 if (section->sh_info == 0
8041 && (filedata->file_header.e_type == ET_EXEC
8042 || filedata->file_header.e_type == ET_DYN))
8043 /* Dynamic relocations apply to segments, so they do not
8044 need to specify the section they relocate. */
8045 break;
8046 if (section->sh_info == 0
8047 || section->sh_info >= filedata->file_header.e_shnum
8048 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8049 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8050 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8051 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
8052 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8053 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
8054 /* FIXME: Are other section types valid ? */
8055 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
8056 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8057 i, section->sh_info);
8058 break;
8060 case SHT_DYNAMIC:
8061 case SHT_HASH:
8062 case SHT_SYMTAB_SHNDX:
8063 case SHT_INIT_ARRAY:
8064 case SHT_FINI_ARRAY:
8065 case SHT_PREINIT_ARRAY:
8066 if (section->sh_info != 0)
8067 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8068 i, section->sh_info);
8069 break;
8071 case SHT_GROUP:
8072 case SHT_SYMTAB:
8073 case SHT_DYNSYM:
8074 /* A symbol index - we assume that it is valid. */
8075 break;
8077 default:
8078 /* FIXME: Add support for target specific section types. */
8079 if (section->sh_type == SHT_NOBITS)
8080 /* NOBITS section headers with non-zero sh_info fields can be
8081 created when a binary is stripped of everything but its debug
8082 information. The stripped sections have their headers
8083 preserved but their types set to SHT_NOBITS. So do not check
8084 this type of section. */
8086 else if (section->sh_flags & SHF_INFO_LINK)
8088 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
8089 warn (_("[%2u]: Expected link to another section in info field"), i);
8091 else if (section->sh_type < SHT_LOOS
8092 && (section->sh_flags & SHF_GNU_MBIND) == 0
8093 && section->sh_info != 0)
8094 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8095 i, section->sh_info);
8096 break;
8099 /* Check the sh_size field. */
8100 if (section->sh_size > filedata->file_size
8101 && section->sh_type != SHT_NOBITS
8102 && section->sh_type != SHT_NULL
8103 && section->sh_type < SHT_LOOS)
8104 warn (_("Size of section %u is larger than the entire file!\n"), i);
8106 printf (" [%2u] ", i);
8107 if (do_section_details)
8108 printf ("%s\n ", printable_section_name (filedata, section));
8109 else
8110 print_symbol_name (-17, printable_section_name (filedata, section));
8112 printf (do_wide ? " %-15s " : " %-15.15s ",
8113 get_section_type_name (filedata, section->sh_type));
8115 if (is_32bit_elf)
8117 const char * link_too_big = NULL;
8119 print_vma (section->sh_addr, LONG_HEX);
8121 printf ( " %6.6lx %6.6lx %2.2lx",
8122 (unsigned long) section->sh_offset,
8123 (unsigned long) section->sh_size,
8124 (unsigned long) section->sh_entsize);
8126 if (do_section_details)
8127 fputs (" ", stdout);
8128 else
8129 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8131 if (section->sh_link >= filedata->file_header.e_shnum)
8133 link_too_big = "";
8134 /* The sh_link value is out of range. Normally this indicates
8135 an error but it can have special values in Solaris binaries. */
8136 switch (filedata->file_header.e_machine)
8138 case EM_386:
8139 case EM_IAMCU:
8140 case EM_X86_64:
8141 case EM_L1OM:
8142 case EM_K1OM:
8143 case EM_OLD_SPARCV9:
8144 case EM_SPARC32PLUS:
8145 case EM_SPARCV9:
8146 case EM_SPARC:
8147 if (section->sh_link == (SHN_BEFORE & 0xffff))
8148 link_too_big = "BEFORE";
8149 else if (section->sh_link == (SHN_AFTER & 0xffff))
8150 link_too_big = "AFTER";
8151 break;
8152 default:
8153 break;
8157 if (do_section_details)
8159 if (link_too_big != NULL && * link_too_big)
8160 printf ("<%s> ", link_too_big);
8161 else
8162 printf ("%2u ", section->sh_link);
8163 printf ("%3u %2lu\n", section->sh_info,
8164 (unsigned long) section->sh_addralign);
8166 else
8167 printf ("%2u %3u %2lu\n",
8168 section->sh_link,
8169 section->sh_info,
8170 (unsigned long) section->sh_addralign);
8172 if (link_too_big && ! * link_too_big)
8173 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8174 i, section->sh_link);
8176 else if (do_wide)
8178 print_vma (section->sh_addr, LONG_HEX);
8180 if ((long) section->sh_offset == section->sh_offset)
8181 printf (" %6.6lx", (unsigned long) section->sh_offset);
8182 else
8184 putchar (' ');
8185 print_vma (section->sh_offset, LONG_HEX);
8188 if ((unsigned long) section->sh_size == section->sh_size)
8189 printf (" %6.6lx", (unsigned long) section->sh_size);
8190 else
8192 putchar (' ');
8193 print_vma (section->sh_size, LONG_HEX);
8196 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8197 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8198 else
8200 putchar (' ');
8201 print_vma (section->sh_entsize, LONG_HEX);
8204 if (do_section_details)
8205 fputs (" ", stdout);
8206 else
8207 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8209 printf ("%2u %3u ", section->sh_link, section->sh_info);
8211 if ((unsigned long) section->sh_addralign == section->sh_addralign)
8212 printf ("%2lu\n", (unsigned long) section->sh_addralign);
8213 else
8215 print_vma (section->sh_addralign, DEC);
8216 putchar ('\n');
8219 else if (do_section_details)
8221 putchar (' ');
8222 print_vma (section->sh_addr, LONG_HEX);
8223 if ((long) section->sh_offset == section->sh_offset)
8224 printf (" %16.16lx", (unsigned long) section->sh_offset);
8225 else
8227 printf (" ");
8228 print_vma (section->sh_offset, LONG_HEX);
8230 printf (" %u\n ", section->sh_link);
8231 print_vma (section->sh_size, LONG_HEX);
8232 putchar (' ');
8233 print_vma (section->sh_entsize, LONG_HEX);
8235 printf (" %-16u %lu\n",
8236 section->sh_info,
8237 (unsigned long) section->sh_addralign);
8239 else
8241 putchar (' ');
8242 print_vma (section->sh_addr, LONG_HEX);
8243 if ((long) section->sh_offset == section->sh_offset)
8244 printf (" %8.8lx", (unsigned long) section->sh_offset);
8245 else
8247 printf (" ");
8248 print_vma (section->sh_offset, LONG_HEX);
8250 printf ("\n ");
8251 print_vma (section->sh_size, LONG_HEX);
8252 printf (" ");
8253 print_vma (section->sh_entsize, LONG_HEX);
8255 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
8257 printf (" %2u %3u %lu\n",
8258 section->sh_link,
8259 section->sh_info,
8260 (unsigned long) section->sh_addralign);
8263 if (do_section_details)
8265 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
8266 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8268 /* Minimum section size is 12 bytes for 32-bit compression
8269 header + 12 bytes for compressed data header. */
8270 unsigned char buf[24];
8272 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
8273 if (get_data (&buf, filedata, section->sh_offset, 1,
8274 sizeof (buf), _("compression header")))
8276 Elf_Internal_Chdr chdr;
8278 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8279 printf (_(" [<corrupt>]\n"));
8280 else
8282 if (chdr.ch_type == ch_compress_zlib)
8283 printf (" ZLIB, ");
8284 else if (chdr.ch_type == ch_compress_zstd)
8285 printf (" ZSTD, ");
8286 else
8287 printf (_(" [<unknown>: 0x%x], "),
8288 chdr.ch_type);
8289 print_vma (chdr.ch_size, LONG_HEX);
8290 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8297 if (!do_section_details)
8299 /* The ordering of the letters shown here matches the ordering of the
8300 corresponding SHF_xxx values, and hence the order in which these
8301 letters will be displayed to the user. */
8302 printf (_("Key to Flags:\n\
8303 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8304 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
8305 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
8306 switch (filedata->file_header.e_ident[EI_OSABI])
8308 case ELFOSABI_GNU:
8309 case ELFOSABI_FREEBSD:
8310 printf (_("R (retain), "));
8311 /* Fall through */
8312 case ELFOSABI_NONE:
8313 printf (_("D (mbind), "));
8314 break;
8315 default:
8316 break;
8318 if (filedata->file_header.e_machine == EM_X86_64
8319 || filedata->file_header.e_machine == EM_L1OM
8320 || filedata->file_header.e_machine == EM_K1OM)
8321 printf (_("l (large), "));
8322 else if (filedata->file_header.e_machine == EM_ARM)
8323 printf (_("y (purecode), "));
8324 else if (filedata->file_header.e_machine == EM_PPC)
8325 printf (_("v (VLE), "));
8326 printf ("p (processor specific)\n");
8329 return true;
8332 static bool
8333 get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
8334 Elf_Internal_Sym **symtab, uint64_t *nsyms,
8335 char **strtab, uint64_t *strtablen)
8337 *strtab = NULL;
8338 *strtablen = 0;
8339 *symtab = get_elf_symbols (filedata, symsec, nsyms);
8341 if (*symtab == NULL)
8342 return false;
8344 if (symsec->sh_link != 0)
8346 Elf_Internal_Shdr *strsec;
8348 if (symsec->sh_link >= filedata->file_header.e_shnum)
8350 error (_("Bad sh_link in symbol table section\n"));
8351 free (*symtab);
8352 *symtab = NULL;
8353 *nsyms = 0;
8354 return false;
8357 strsec = filedata->section_headers + symsec->sh_link;
8359 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8360 1, strsec->sh_size, _("string table"));
8361 if (*strtab == NULL)
8363 free (*symtab);
8364 *symtab = NULL;
8365 *nsyms = 0;
8366 return false;
8368 *strtablen = strsec->sh_size;
8370 return true;
8373 static const char *
8374 get_group_flags (unsigned int flags)
8376 static char buff[128];
8378 if (flags == 0)
8379 return "";
8380 else if (flags == GRP_COMDAT)
8381 return "COMDAT ";
8383 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8384 flags,
8385 flags & GRP_MASKOS ? _("<OS specific>") : "",
8386 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8387 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8388 ? _("<unknown>") : ""));
8390 return buff;
8393 static bool
8394 process_section_groups (Filedata * filedata)
8396 Elf_Internal_Shdr * section;
8397 unsigned int i;
8398 struct group * group;
8399 Elf_Internal_Shdr * symtab_sec;
8400 Elf_Internal_Shdr * strtab_sec;
8401 Elf_Internal_Sym * symtab;
8402 uint64_t num_syms;
8403 char * strtab;
8404 size_t strtab_size;
8406 /* Don't process section groups unless needed. */
8407 if (!do_unwind && !do_section_groups)
8408 return true;
8410 if (filedata->file_header.e_shnum == 0)
8412 if (do_section_groups)
8414 if (filedata->is_separate)
8415 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8416 filedata->file_name);
8417 else
8418 printf (_("\nThere are no section groups in this file.\n"));
8420 return true;
8423 if (filedata->section_headers == NULL)
8425 error (_("Section headers are not available!\n"));
8426 /* PR 13622: This can happen with a corrupt ELF header. */
8427 return false;
8430 filedata->section_headers_groups
8431 = (struct group **) calloc (filedata->file_header.e_shnum,
8432 sizeof (struct group *));
8434 if (filedata->section_headers_groups == NULL)
8436 error (_("Out of memory reading %u section group headers\n"),
8437 filedata->file_header.e_shnum);
8438 return false;
8441 /* Scan the sections for the group section. */
8442 filedata->group_count = 0;
8443 for (i = 0, section = filedata->section_headers;
8444 i < filedata->file_header.e_shnum;
8445 i++, section++)
8446 if (section->sh_type == SHT_GROUP)
8447 filedata->group_count++;
8449 if (filedata->group_count == 0)
8451 if (do_section_groups)
8453 if (filedata->is_separate)
8454 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8455 filedata->file_name);
8456 else
8457 printf (_("\nThere are no section groups in this file.\n"));
8460 return true;
8463 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8464 sizeof (struct group));
8466 if (filedata->section_groups == NULL)
8468 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
8469 return false;
8472 symtab_sec = NULL;
8473 strtab_sec = NULL;
8474 symtab = NULL;
8475 num_syms = 0;
8476 strtab = NULL;
8477 strtab_size = 0;
8479 if (filedata->is_separate)
8480 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
8482 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
8483 i < filedata->file_header.e_shnum;
8484 i++, section++)
8486 if (section->sh_type == SHT_GROUP)
8488 const char * name = printable_section_name (filedata, section);
8489 const char * group_name;
8490 unsigned char * start;
8491 unsigned char * indices;
8492 unsigned int entry, j, size;
8493 Elf_Internal_Shdr * sec;
8494 Elf_Internal_Sym * sym;
8496 /* Get the symbol table. */
8497 if (section->sh_link >= filedata->file_header.e_shnum
8498 || ((sec = filedata->section_headers + section->sh_link)->sh_type
8499 != SHT_SYMTAB))
8501 error (_("Bad sh_link in group section `%s'\n"), name);
8502 continue;
8505 if (symtab_sec != sec)
8507 symtab_sec = sec;
8508 free (symtab);
8509 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
8512 if (symtab == NULL)
8514 error (_("Corrupt header in group section `%s'\n"), name);
8515 continue;
8518 if (section->sh_info >= num_syms)
8520 error (_("Bad sh_info in group section `%s'\n"), name);
8521 continue;
8524 sym = symtab + section->sh_info;
8526 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8528 if (sym->st_shndx == 0
8529 || sym->st_shndx >= filedata->file_header.e_shnum)
8531 error (_("Bad sh_info in group section `%s'\n"), name);
8532 continue;
8535 group_name = printable_section_name (filedata,
8536 filedata->section_headers
8537 + sym->st_shndx);
8538 strtab_sec = NULL;
8539 free (strtab);
8540 strtab = NULL;
8541 strtab_size = 0;
8543 else
8545 /* Get the string table. */
8546 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
8548 strtab_sec = NULL;
8549 free (strtab);
8550 strtab = NULL;
8551 strtab_size = 0;
8553 else if (strtab_sec
8554 != (sec = filedata->section_headers + symtab_sec->sh_link))
8556 strtab_sec = sec;
8557 free (strtab);
8559 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
8560 1, strtab_sec->sh_size,
8561 _("string table"));
8562 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
8564 group_name = sym->st_name < strtab_size
8565 ? strtab + sym->st_name : _("<corrupt>");
8568 /* PR 17531: file: loop. */
8569 if (section->sh_entsize > section->sh_size)
8571 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8572 " which is larger than its size (%#" PRIx64 ")\n"),
8573 printable_section_name (filedata, section),
8574 section->sh_entsize,
8575 section->sh_size);
8576 continue;
8579 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
8580 1, section->sh_size,
8581 _("section data"));
8582 if (start == NULL)
8583 continue;
8585 indices = start;
8586 size = (section->sh_size / section->sh_entsize) - 1;
8587 entry = byte_get (indices, 4);
8588 indices += 4;
8590 if (do_section_groups)
8592 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
8593 get_group_flags (entry), i, name, group_name, size);
8595 printf (_(" [Index] Name\n"));
8598 group->group_index = i;
8600 for (j = 0; j < size; j++)
8602 struct group_list * g;
8604 entry = byte_get (indices, 4);
8605 indices += 4;
8607 if (entry >= filedata->file_header.e_shnum)
8609 static unsigned num_group_errors = 0;
8611 if (num_group_errors ++ < 10)
8613 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
8614 entry, i, filedata->file_header.e_shnum - 1);
8615 if (num_group_errors == 10)
8616 warn (_("Further error messages about overlarge group section indices suppressed\n"));
8618 continue;
8621 if (filedata->section_headers_groups [entry] != NULL)
8623 if (entry)
8625 static unsigned num_errs = 0;
8627 if (num_errs ++ < 10)
8629 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8630 entry, i,
8631 filedata->section_headers_groups [entry]->group_index);
8632 if (num_errs == 10)
8633 warn (_("Further error messages about already contained group sections suppressed\n"));
8635 continue;
8637 else
8639 /* Intel C/C++ compiler may put section 0 in a
8640 section group. We just warn it the first time
8641 and ignore it afterwards. */
8642 static bool warned = false;
8643 if (!warned)
8645 error (_("section 0 in group section [%5u]\n"),
8646 filedata->section_headers_groups [entry]->group_index);
8647 warned = true;
8652 filedata->section_headers_groups [entry] = group;
8654 if (do_section_groups)
8656 sec = filedata->section_headers + entry;
8657 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
8660 g = (struct group_list *) xmalloc (sizeof (struct group_list));
8661 g->section_index = entry;
8662 g->next = group->root;
8663 group->root = g;
8666 free (start);
8668 group++;
8672 free (symtab);
8673 free (strtab);
8674 return true;
8677 /* Data used to display dynamic fixups. */
8679 struct ia64_vms_dynfixup
8681 uint64_t needed_ident; /* Library ident number. */
8682 uint64_t needed; /* Index in the dstrtab of the library name. */
8683 uint64_t fixup_needed; /* Index of the library. */
8684 uint64_t fixup_rela_cnt; /* Number of fixups. */
8685 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
8688 /* Data used to display dynamic relocations. */
8690 struct ia64_vms_dynimgrela
8692 uint64_t img_rela_cnt; /* Number of relocations. */
8693 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
8696 /* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8697 library). */
8699 static bool
8700 dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8701 struct ia64_vms_dynfixup * fixup,
8702 const char * strtab,
8703 unsigned int strtab_sz)
8705 Elf64_External_VMS_IMAGE_FIXUP * imfs;
8706 size_t i;
8707 const char * lib_name;
8709 imfs = get_data (NULL, filedata,
8710 filedata->dynamic_addr + fixup->fixup_rela_off,
8711 sizeof (*imfs), fixup->fixup_rela_cnt,
8712 _("dynamic section image fixups"));
8713 if (!imfs)
8714 return false;
8716 if (fixup->needed < strtab_sz)
8717 lib_name = strtab + fixup->needed;
8718 else
8720 warn (_("corrupt library name index of %#" PRIx64
8721 " found in dynamic entry"), fixup->needed);
8722 lib_name = "???";
8725 printf (_("\nImage fixups for needed library #%" PRId64
8726 ": %s - ident: %" PRIx64 "\n"),
8727 fixup->fixup_needed, lib_name, fixup->needed_ident);
8728 printf
8729 (_("Seg Offset Type SymVec DataType\n"));
8731 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
8733 unsigned int type;
8734 const char *rtype;
8736 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
8737 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
8738 type = BYTE_GET (imfs [i].type);
8739 rtype = elf_ia64_reloc_type (type);
8740 if (rtype == NULL)
8741 printf ("0x%08x ", type);
8742 else
8743 printf ("%-32s ", rtype);
8744 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8745 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8748 free (imfs);
8749 return true;
8752 /* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8754 static bool
8755 dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
8757 Elf64_External_VMS_IMAGE_RELA *imrs;
8758 size_t i;
8760 imrs = get_data (NULL, filedata,
8761 filedata->dynamic_addr + imgrela->img_rela_off,
8762 sizeof (*imrs), imgrela->img_rela_cnt,
8763 _("dynamic section image relocations"));
8764 if (!imrs)
8765 return false;
8767 printf (_("\nImage relocs\n"));
8768 printf
8769 (_("Seg Offset Type Addend Seg Sym Off\n"));
8771 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
8773 unsigned int type;
8774 const char *rtype;
8776 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
8777 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
8778 type = BYTE_GET (imrs [i].type);
8779 rtype = elf_ia64_reloc_type (type);
8780 if (rtype == NULL)
8781 printf ("0x%08x ", type);
8782 else
8783 printf ("%-31s ", rtype);
8784 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8785 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
8786 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
8789 free (imrs);
8790 return true;
8793 /* Display IA-64 OpenVMS dynamic relocations and fixups. */
8795 static bool
8796 process_ia64_vms_dynamic_relocs (Filedata * filedata)
8798 struct ia64_vms_dynfixup fixup;
8799 struct ia64_vms_dynimgrela imgrela;
8800 Elf_Internal_Dyn *entry;
8801 uint64_t strtab_off = 0;
8802 uint64_t strtab_sz = 0;
8803 char *strtab = NULL;
8804 bool res = true;
8806 memset (&fixup, 0, sizeof (fixup));
8807 memset (&imgrela, 0, sizeof (imgrela));
8809 /* Note: the order of the entries is specified by the OpenVMS specs. */
8810 for (entry = filedata->dynamic_section;
8811 entry < filedata->dynamic_section + filedata->dynamic_nent;
8812 entry++)
8814 switch (entry->d_tag)
8816 case DT_IA_64_VMS_STRTAB_OFFSET:
8817 strtab_off = entry->d_un.d_val;
8818 break;
8819 case DT_STRSZ:
8820 strtab_sz = entry->d_un.d_val;
8821 if (strtab == NULL)
8822 strtab = get_data (NULL, filedata,
8823 filedata->dynamic_addr + strtab_off,
8824 1, strtab_sz, _("dynamic string section"));
8825 if (strtab == NULL)
8826 strtab_sz = 0;
8827 break;
8829 case DT_IA_64_VMS_NEEDED_IDENT:
8830 fixup.needed_ident = entry->d_un.d_val;
8831 break;
8832 case DT_NEEDED:
8833 fixup.needed = entry->d_un.d_val;
8834 break;
8835 case DT_IA_64_VMS_FIXUP_NEEDED:
8836 fixup.fixup_needed = entry->d_un.d_val;
8837 break;
8838 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8839 fixup.fixup_rela_cnt = entry->d_un.d_val;
8840 break;
8841 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8842 fixup.fixup_rela_off = entry->d_un.d_val;
8843 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
8844 res = false;
8845 break;
8846 case DT_IA_64_VMS_IMG_RELA_CNT:
8847 imgrela.img_rela_cnt = entry->d_un.d_val;
8848 break;
8849 case DT_IA_64_VMS_IMG_RELA_OFF:
8850 imgrela.img_rela_off = entry->d_un.d_val;
8851 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
8852 res = false;
8853 break;
8855 default:
8856 break;
8860 free (strtab);
8862 return res;
8865 static struct
8867 const char * name;
8868 int reloc;
8869 int size;
8870 relocation_type rel_type;
8872 dynamic_relocations [] =
8874 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8875 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8876 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8877 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
8880 /* Process the reloc section. */
8882 static bool
8883 process_relocs (Filedata * filedata)
8885 uint64_t rel_size;
8886 uint64_t rel_offset;
8888 if (!do_reloc)
8889 return true;
8891 if (do_using_dynamic)
8893 relocation_type rel_type;
8894 const char * name;
8895 bool has_dynamic_reloc;
8896 unsigned int i;
8898 has_dynamic_reloc = false;
8900 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8902 rel_type = dynamic_relocations [i].rel_type;
8903 name = dynamic_relocations [i].name;
8904 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8905 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
8907 if (rel_size)
8908 has_dynamic_reloc = true;
8910 if (rel_type == reltype_unknown)
8912 if (dynamic_relocations [i].reloc == DT_JMPREL)
8913 switch (filedata->dynamic_info[DT_PLTREL])
8915 case DT_REL:
8916 rel_type = reltype_rel;
8917 break;
8918 case DT_RELA:
8919 rel_type = reltype_rela;
8920 break;
8924 if (rel_size)
8926 if (filedata->is_separate)
8927 printf
8928 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8929 " contains %" PRId64 " bytes:\n"),
8930 filedata->file_name, name, rel_offset, rel_size);
8931 else
8932 printf
8933 (_("\n'%s' relocation section at offset %#" PRIx64
8934 " contains %" PRId64 " bytes:\n"),
8935 name, rel_offset, rel_size);
8937 dump_relocations (filedata,
8938 offset_from_vma (filedata, rel_offset, rel_size),
8939 rel_size,
8940 filedata->dynamic_symbols,
8941 filedata->num_dynamic_syms,
8942 filedata->dynamic_strings,
8943 filedata->dynamic_strings_length,
8944 rel_type, true /* is_dynamic */);
8948 if (is_ia64_vms (filedata))
8949 if (process_ia64_vms_dynamic_relocs (filedata))
8950 has_dynamic_reloc = true;
8952 if (! has_dynamic_reloc)
8954 if (filedata->is_separate)
8955 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8956 filedata->file_name);
8957 else
8958 printf (_("\nThere are no dynamic relocations in this file.\n"));
8961 else
8963 Elf_Internal_Shdr * section;
8964 size_t i;
8965 bool found = false;
8967 for (i = 0, section = filedata->section_headers;
8968 i < filedata->file_header.e_shnum;
8969 i++, section++)
8971 if ( section->sh_type != SHT_RELA
8972 && section->sh_type != SHT_REL
8973 && section->sh_type != SHT_RELR)
8974 continue;
8976 rel_offset = section->sh_offset;
8977 rel_size = section->sh_size;
8979 if (rel_size)
8981 relocation_type rel_type;
8982 uint64_t num_rela;
8984 if (filedata->is_separate)
8985 printf (_("\nIn linked file '%s' relocation section "),
8986 filedata->file_name);
8987 else
8988 printf (_("\nRelocation section "));
8990 if (filedata->string_table == NULL)
8991 printf ("%d", section->sh_name);
8992 else
8993 printf ("'%s'", printable_section_name (filedata, section));
8995 num_rela = rel_size / section->sh_entsize;
8996 printf (ngettext (" at offset %#" PRIx64
8997 " contains %" PRIu64 " entry:\n",
8998 " at offset %#" PRIx64
8999 " contains %" PRId64 " entries:\n",
9000 num_rela),
9001 rel_offset, num_rela);
9003 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
9004 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
9006 if (section->sh_link != 0
9007 && section->sh_link < filedata->file_header.e_shnum)
9009 Elf_Internal_Shdr *symsec;
9010 Elf_Internal_Sym *symtab;
9011 uint64_t nsyms;
9012 uint64_t strtablen = 0;
9013 char *strtab = NULL;
9015 symsec = filedata->section_headers + section->sh_link;
9016 if (symsec->sh_type != SHT_SYMTAB
9017 && symsec->sh_type != SHT_DYNSYM)
9018 continue;
9020 if (!get_symtab (filedata, symsec,
9021 &symtab, &nsyms, &strtab, &strtablen))
9022 continue;
9024 dump_relocations (filedata, rel_offset, rel_size,
9025 symtab, nsyms, strtab, strtablen,
9026 rel_type,
9027 symsec->sh_type == SHT_DYNSYM);
9028 free (strtab);
9029 free (symtab);
9031 else
9032 dump_relocations (filedata, rel_offset, rel_size,
9033 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
9035 found = true;
9039 if (! found)
9041 /* Users sometimes forget the -D option, so try to be helpful. */
9042 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9044 if (filedata->dynamic_info[dynamic_relocations [i].size])
9046 if (filedata->is_separate)
9047 printf (_("\nThere are no static relocations in linked file '%s'."),
9048 filedata->file_name);
9049 else
9050 printf (_("\nThere are no static relocations in this file."));
9051 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9053 break;
9056 if (i == ARRAY_SIZE (dynamic_relocations))
9058 if (filedata->is_separate)
9059 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9060 filedata->file_name);
9061 else
9062 printf (_("\nThere are no relocations in this file.\n"));
9067 return true;
9070 /* An absolute address consists of a section and an offset. If the
9071 section is NULL, the offset itself is the address, otherwise, the
9072 address equals to LOAD_ADDRESS(section) + offset. */
9074 struct absaddr
9076 unsigned short section;
9077 uint64_t offset;
9080 /* Find the nearest symbol at or below ADDR. Returns the symbol
9081 name, if found, and the offset from the symbol to ADDR. */
9083 static void
9084 find_symbol_for_address (Filedata *filedata,
9085 Elf_Internal_Sym *symtab,
9086 uint64_t nsyms,
9087 const char *strtab,
9088 uint64_t strtab_size,
9089 struct absaddr addr,
9090 const char **symname,
9091 uint64_t *offset)
9093 uint64_t dist = 0x100000;
9094 Elf_Internal_Sym * sym;
9095 Elf_Internal_Sym * beg;
9096 Elf_Internal_Sym * end;
9097 Elf_Internal_Sym * best = NULL;
9099 REMOVE_ARCH_BITS (addr.offset);
9100 beg = symtab;
9101 end = symtab + nsyms;
9103 while (beg < end)
9105 uint64_t value;
9107 sym = beg + (end - beg) / 2;
9109 value = sym->st_value;
9110 REMOVE_ARCH_BITS (value);
9112 if (sym->st_name != 0
9113 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
9114 && addr.offset >= value
9115 && addr.offset - value < dist)
9117 best = sym;
9118 dist = addr.offset - value;
9119 if (!dist)
9120 break;
9123 if (addr.offset < value)
9124 end = sym;
9125 else
9126 beg = sym + 1;
9129 if (best)
9131 *symname = (best->st_name >= strtab_size
9132 ? _("<corrupt>") : strtab + best->st_name);
9133 *offset = dist;
9134 return;
9137 *symname = NULL;
9138 *offset = addr.offset;
9141 static /* signed */ int
9142 symcmp (const void *p, const void *q)
9144 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
9145 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
9147 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
9150 /* Process the unwind section. */
9152 #include "unwind-ia64.h"
9154 struct ia64_unw_table_entry
9156 struct absaddr start;
9157 struct absaddr end;
9158 struct absaddr info;
9161 struct ia64_unw_aux_info
9163 struct ia64_unw_table_entry * table; /* Unwind table. */
9164 uint64_t table_len; /* Length of unwind table. */
9165 unsigned char * info; /* Unwind info. */
9166 uint64_t info_size; /* Size of unwind info. */
9167 uint64_t info_addr; /* Starting address of unwind info. */
9168 uint64_t seg_base; /* Starting address of segment. */
9169 Elf_Internal_Sym * symtab; /* The symbol table. */
9170 uint64_t nsyms; /* Number of symbols. */
9171 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9172 uint64_t nfuns; /* Number of entries in funtab. */
9173 char * strtab; /* The string table. */
9174 uint64_t strtab_size; /* Size of string table. */
9177 static bool
9178 dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
9180 struct ia64_unw_table_entry * tp;
9181 size_t j, nfuns;
9182 int in_body;
9183 bool res = true;
9185 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9186 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9187 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9188 aux->funtab[nfuns++] = aux->symtab[j];
9189 aux->nfuns = nfuns;
9190 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9192 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9194 uint64_t stamp;
9195 uint64_t offset;
9196 const unsigned char * dp;
9197 const unsigned char * head;
9198 const unsigned char * end;
9199 const char * procname;
9201 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
9202 aux->strtab_size, tp->start, &procname, &offset);
9204 fputs ("\n<", stdout);
9206 if (procname)
9208 fputs (procname, stdout);
9210 if (offset)
9211 printf ("+%" PRIx64, offset);
9214 fputs (">: [", stdout);
9215 print_vma (tp->start.offset, PREFIX_HEX);
9216 fputc ('-', stdout);
9217 print_vma (tp->end.offset, PREFIX_HEX);
9218 printf ("], info at +0x%" PRIx64 "\n",
9219 tp->info.offset - aux->seg_base);
9221 /* PR 17531: file: 86232b32. */
9222 if (aux->info == NULL)
9223 continue;
9225 offset = tp->info.offset;
9226 if (tp->info.section)
9228 if (tp->info.section >= filedata->file_header.e_shnum)
9230 warn (_("Invalid section %u in table entry %td\n"),
9231 tp->info.section, tp - aux->table);
9232 res = false;
9233 continue;
9235 offset += filedata->section_headers[tp->info.section].sh_addr;
9237 offset -= aux->info_addr;
9238 /* PR 17531: file: 0997b4d1. */
9239 if (offset >= aux->info_size
9240 || aux->info_size - offset < 8)
9242 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9243 tp->info.offset, tp - aux->table);
9244 res = false;
9245 continue;
9248 head = aux->info + offset;
9249 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
9251 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
9252 (unsigned) UNW_VER (stamp),
9253 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9254 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9255 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
9256 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
9258 if (UNW_VER (stamp) != 1)
9260 printf (_("\tUnknown version.\n"));
9261 continue;
9264 in_body = 0;
9265 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9266 /* PR 17531: file: 16ceda89. */
9267 if (end > aux->info + aux->info_size)
9268 end = aux->info + aux->info_size;
9269 for (dp = head + 8; dp < end;)
9270 dp = unw_decode (dp, in_body, & in_body, end);
9273 free (aux->funtab);
9275 return res;
9278 static bool
9279 slurp_ia64_unwind_table (Filedata * filedata,
9280 struct ia64_unw_aux_info * aux,
9281 Elf_Internal_Shdr * sec)
9283 uint64_t size, nrelas, i;
9284 Elf_Internal_Phdr * seg;
9285 struct ia64_unw_table_entry * tep;
9286 Elf_Internal_Shdr * relsec;
9287 Elf_Internal_Rela * rela;
9288 Elf_Internal_Rela * rp;
9289 unsigned char * table;
9290 unsigned char * tp;
9291 Elf_Internal_Sym * sym;
9292 const char * relname;
9294 aux->table_len = 0;
9296 /* First, find the starting address of the segment that includes
9297 this section: */
9299 if (filedata->file_header.e_phnum)
9301 if (! get_program_headers (filedata))
9302 return false;
9304 for (seg = filedata->program_headers;
9305 seg < filedata->program_headers + filedata->file_header.e_phnum;
9306 ++seg)
9308 if (seg->p_type != PT_LOAD)
9309 continue;
9311 if (sec->sh_addr >= seg->p_vaddr
9312 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9314 aux->seg_base = seg->p_vaddr;
9315 break;
9320 /* Second, build the unwind table from the contents of the unwind section: */
9321 size = sec->sh_size;
9322 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
9323 _("unwind table"));
9324 if (!table)
9325 return false;
9327 aux->table_len = size / (3 * eh_addr_size);
9328 aux->table = (struct ia64_unw_table_entry *)
9329 xcmalloc (aux->table_len, sizeof (aux->table[0]));
9330 tep = aux->table;
9332 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
9334 tep->start.section = SHN_UNDEF;
9335 tep->end.section = SHN_UNDEF;
9336 tep->info.section = SHN_UNDEF;
9337 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9338 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9339 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9340 tep->start.offset += aux->seg_base;
9341 tep->end.offset += aux->seg_base;
9342 tep->info.offset += aux->seg_base;
9344 free (table);
9346 /* Third, apply any relocations to the unwind table: */
9347 for (relsec = filedata->section_headers;
9348 relsec < filedata->section_headers + filedata->file_header.e_shnum;
9349 ++relsec)
9351 if (relsec->sh_type != SHT_RELA
9352 || relsec->sh_info >= filedata->file_header.e_shnum
9353 || filedata->section_headers + relsec->sh_info != sec)
9354 continue;
9356 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
9357 & rela, & nrelas))
9359 free (aux->table);
9360 aux->table = NULL;
9361 aux->table_len = 0;
9362 return false;
9365 for (rp = rela; rp < rela + nrelas; ++rp)
9367 unsigned int sym_ndx;
9368 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9369 relname = elf_ia64_reloc_type (r_type);
9371 /* PR 17531: file: 9fa67536. */
9372 if (relname == NULL)
9374 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9375 continue;
9378 if (! startswith (relname, "R_IA64_SEGREL"))
9380 warn (_("Skipping unexpected relocation type: %s\n"), relname);
9381 continue;
9384 i = rp->r_offset / (3 * eh_addr_size);
9386 /* PR 17531: file: 5bc8d9bf. */
9387 if (i >= aux->table_len)
9389 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9391 continue;
9394 sym_ndx = get_reloc_symindex (rp->r_info);
9395 if (sym_ndx >= aux->nsyms)
9397 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9398 sym_ndx);
9399 continue;
9401 sym = aux->symtab + sym_ndx;
9403 switch (rp->r_offset / eh_addr_size % 3)
9405 case 0:
9406 aux->table[i].start.section = sym->st_shndx;
9407 aux->table[i].start.offset = rp->r_addend + sym->st_value;
9408 break;
9409 case 1:
9410 aux->table[i].end.section = sym->st_shndx;
9411 aux->table[i].end.offset = rp->r_addend + sym->st_value;
9412 break;
9413 case 2:
9414 aux->table[i].info.section = sym->st_shndx;
9415 aux->table[i].info.offset = rp->r_addend + sym->st_value;
9416 break;
9417 default:
9418 break;
9422 free (rela);
9425 return true;
9428 static bool
9429 ia64_process_unwind (Filedata * filedata)
9431 Elf_Internal_Shdr * sec;
9432 Elf_Internal_Shdr * unwsec = NULL;
9433 uint64_t i, unwcount = 0, unwstart = 0;
9434 struct ia64_unw_aux_info aux;
9435 bool res = true;
9437 memset (& aux, 0, sizeof (aux));
9439 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
9441 if (sec->sh_type == SHT_SYMTAB)
9443 if (aux.symtab)
9445 error (_("Multiple symbol tables encountered\n"));
9446 free (aux.symtab);
9447 aux.symtab = NULL;
9448 free (aux.strtab);
9449 aux.strtab = NULL;
9451 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9452 &aux.strtab, &aux.strtab_size))
9453 return false;
9455 else if (sec->sh_type == SHT_IA_64_UNWIND)
9456 unwcount++;
9459 if (!unwcount)
9460 printf (_("\nThere are no unwind sections in this file.\n"));
9462 while (unwcount-- > 0)
9464 const char *suffix;
9465 size_t len, len2;
9467 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9468 i < filedata->file_header.e_shnum; ++i, ++sec)
9469 if (sec->sh_type == SHT_IA_64_UNWIND)
9471 unwsec = sec;
9472 break;
9474 /* We have already counted the number of SHT_IA64_UNWIND
9475 sections so the loop above should never fail. */
9476 assert (unwsec != NULL);
9478 unwstart = i + 1;
9479 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9481 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9483 /* We need to find which section group it is in. */
9484 struct group_list * g;
9486 if (filedata->section_headers_groups == NULL
9487 || filedata->section_headers_groups[i] == NULL)
9488 i = filedata->file_header.e_shnum;
9489 else
9491 g = filedata->section_headers_groups[i]->root;
9493 for (; g != NULL; g = g->next)
9495 sec = filedata->section_headers + g->section_index;
9497 if (section_name_valid (filedata, sec)
9498 && streq (section_name (filedata, sec),
9499 ELF_STRING_ia64_unwind_info))
9500 break;
9503 if (g == NULL)
9504 i = filedata->file_header.e_shnum;
9507 else if (section_name_valid (filedata, unwsec)
9508 && startswith (section_name (filedata, unwsec),
9509 ELF_STRING_ia64_unwind_once))
9511 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
9512 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
9513 suffix = section_name (filedata, unwsec) + len;
9514 for (i = 0, sec = filedata->section_headers;
9515 i < filedata->file_header.e_shnum;
9516 ++i, ++sec)
9517 if (section_name_valid (filedata, sec)
9518 && startswith (section_name (filedata, sec),
9519 ELF_STRING_ia64_unwind_info_once)
9520 && streq (section_name (filedata, sec) + len2, suffix))
9521 break;
9523 else
9525 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
9526 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
9527 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9528 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9529 suffix = "";
9530 if (section_name_valid (filedata, unwsec)
9531 && startswith (section_name (filedata, unwsec),
9532 ELF_STRING_ia64_unwind))
9533 suffix = section_name (filedata, unwsec) + len;
9534 for (i = 0, sec = filedata->section_headers;
9535 i < filedata->file_header.e_shnum;
9536 ++i, ++sec)
9537 if (section_name_valid (filedata, sec)
9538 && startswith (section_name (filedata, sec),
9539 ELF_STRING_ia64_unwind_info)
9540 && streq (section_name (filedata, sec) + len2, suffix))
9541 break;
9544 if (i == filedata->file_header.e_shnum)
9546 printf (_("\nCould not find unwind info section for "));
9548 if (filedata->string_table == NULL)
9549 printf ("%d", unwsec->sh_name);
9550 else
9551 printf ("'%s'", printable_section_name (filedata, unwsec));
9553 else
9555 aux.info_addr = sec->sh_addr;
9556 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
9557 sec->sh_size,
9558 _("unwind info"));
9559 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
9561 printf (_("\nUnwind section "));
9563 if (filedata->string_table == NULL)
9564 printf ("%d", unwsec->sh_name);
9565 else
9566 printf ("'%s'", printable_section_name (filedata, unwsec));
9568 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9569 unwsec->sh_offset,
9570 unwsec->sh_size / (3 * eh_addr_size));
9572 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
9573 && aux.table_len > 0)
9574 dump_ia64_unwind (filedata, & aux);
9576 free ((char *) aux.table);
9577 free ((char *) aux.info);
9578 aux.table = NULL;
9579 aux.info = NULL;
9583 free (aux.symtab);
9584 free ((char *) aux.strtab);
9586 return res;
9589 struct hppa_unw_table_entry
9591 struct absaddr start;
9592 struct absaddr end;
9593 unsigned int Cannot_unwind:1; /* 0 */
9594 unsigned int Millicode:1; /* 1 */
9595 unsigned int Millicode_save_sr0:1; /* 2 */
9596 unsigned int Region_description:2; /* 3..4 */
9597 unsigned int reserved1:1; /* 5 */
9598 unsigned int Entry_SR:1; /* 6 */
9599 unsigned int Entry_FR:4; /* Number saved 7..10 */
9600 unsigned int Entry_GR:5; /* Number saved 11..15 */
9601 unsigned int Args_stored:1; /* 16 */
9602 unsigned int Variable_Frame:1; /* 17 */
9603 unsigned int Separate_Package_Body:1; /* 18 */
9604 unsigned int Frame_Extension_Millicode:1; /* 19 */
9605 unsigned int Stack_Overflow_Check:1; /* 20 */
9606 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9607 unsigned int Ada_Region:1; /* 22 */
9608 unsigned int cxx_info:1; /* 23 */
9609 unsigned int cxx_try_catch:1; /* 24 */
9610 unsigned int sched_entry_seq:1; /* 25 */
9611 unsigned int reserved2:1; /* 26 */
9612 unsigned int Save_SP:1; /* 27 */
9613 unsigned int Save_RP:1; /* 28 */
9614 unsigned int Save_MRP_in_frame:1; /* 29 */
9615 unsigned int extn_ptr_defined:1; /* 30 */
9616 unsigned int Cleanup_defined:1; /* 31 */
9618 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9619 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9620 unsigned int Large_frame:1; /* 2 */
9621 unsigned int Pseudo_SP_Set:1; /* 3 */
9622 unsigned int reserved4:1; /* 4 */
9623 unsigned int Total_frame_size:27; /* 5..31 */
9626 struct hppa_unw_aux_info
9628 struct hppa_unw_table_entry * table; /* Unwind table. */
9629 uint64_t table_len; /* Length of unwind table. */
9630 uint64_t seg_base; /* Starting address of segment. */
9631 Elf_Internal_Sym * symtab; /* The symbol table. */
9632 uint64_t nsyms; /* Number of symbols. */
9633 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9634 uint64_t nfuns; /* Number of entries in funtab. */
9635 char * strtab; /* The string table. */
9636 uint64_t strtab_size; /* Size of string table. */
9639 static bool
9640 dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
9642 struct hppa_unw_table_entry * tp;
9643 uint64_t j, nfuns;
9644 bool res = true;
9646 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9647 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9648 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9649 aux->funtab[nfuns++] = aux->symtab[j];
9650 aux->nfuns = nfuns;
9651 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9653 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9655 uint64_t offset;
9656 const char * procname;
9658 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
9659 aux->strtab_size, tp->start, &procname,
9660 &offset);
9662 fputs ("\n<", stdout);
9664 if (procname)
9666 fputs (procname, stdout);
9668 if (offset)
9669 printf ("+%" PRIx64, offset);
9672 fputs (">: [", stdout);
9673 print_vma (tp->start.offset, PREFIX_HEX);
9674 fputc ('-', stdout);
9675 print_vma (tp->end.offset, PREFIX_HEX);
9676 printf ("]\n\t");
9678 #define PF(_m) if (tp->_m) printf (#_m " ");
9679 #define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
9680 PF(Cannot_unwind);
9681 PF(Millicode);
9682 PF(Millicode_save_sr0);
9683 /* PV(Region_description); */
9684 PF(Entry_SR);
9685 PV(Entry_FR);
9686 PV(Entry_GR);
9687 PF(Args_stored);
9688 PF(Variable_Frame);
9689 PF(Separate_Package_Body);
9690 PF(Frame_Extension_Millicode);
9691 PF(Stack_Overflow_Check);
9692 PF(Two_Instruction_SP_Increment);
9693 PF(Ada_Region);
9694 PF(cxx_info);
9695 PF(cxx_try_catch);
9696 PF(sched_entry_seq);
9697 PF(Save_SP);
9698 PF(Save_RP);
9699 PF(Save_MRP_in_frame);
9700 PF(extn_ptr_defined);
9701 PF(Cleanup_defined);
9702 PF(MPE_XL_interrupt_marker);
9703 PF(HP_UX_interrupt_marker);
9704 PF(Large_frame);
9705 PF(Pseudo_SP_Set);
9706 PV(Total_frame_size);
9707 #undef PF
9708 #undef PV
9711 printf ("\n");
9713 free (aux->funtab);
9715 return res;
9718 static bool
9719 slurp_hppa_unwind_table (Filedata * filedata,
9720 struct hppa_unw_aux_info * aux,
9721 Elf_Internal_Shdr * sec)
9723 uint64_t size, unw_ent_size, nentries, nrelas, i;
9724 Elf_Internal_Phdr * seg;
9725 struct hppa_unw_table_entry * tep;
9726 Elf_Internal_Shdr * relsec;
9727 Elf_Internal_Rela * rela;
9728 Elf_Internal_Rela * rp;
9729 unsigned char * table;
9730 unsigned char * tp;
9731 Elf_Internal_Sym * sym;
9732 const char * relname;
9734 /* First, find the starting address of the segment that includes
9735 this section. */
9736 if (filedata->file_header.e_phnum)
9738 if (! get_program_headers (filedata))
9739 return false;
9741 for (seg = filedata->program_headers;
9742 seg < filedata->program_headers + filedata->file_header.e_phnum;
9743 ++seg)
9745 if (seg->p_type != PT_LOAD)
9746 continue;
9748 if (sec->sh_addr >= seg->p_vaddr
9749 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9751 aux->seg_base = seg->p_vaddr;
9752 break;
9757 /* Second, build the unwind table from the contents of the unwind
9758 section. */
9759 size = sec->sh_size;
9760 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
9761 _("unwind table"));
9762 if (!table)
9763 return false;
9765 unw_ent_size = 16;
9766 nentries = size / unw_ent_size;
9767 size = unw_ent_size * nentries;
9769 aux->table_len = nentries;
9770 tep = aux->table = (struct hppa_unw_table_entry *)
9771 xcmalloc (nentries, sizeof (aux->table[0]));
9773 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
9775 unsigned int tmp1, tmp2;
9777 tep->start.section = SHN_UNDEF;
9778 tep->end.section = SHN_UNDEF;
9780 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9781 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9782 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9783 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9785 tep->start.offset += aux->seg_base;
9786 tep->end.offset += aux->seg_base;
9788 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9789 tep->Millicode = (tmp1 >> 30) & 0x1;
9790 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9791 tep->Region_description = (tmp1 >> 27) & 0x3;
9792 tep->reserved1 = (tmp1 >> 26) & 0x1;
9793 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9794 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9795 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9796 tep->Args_stored = (tmp1 >> 15) & 0x1;
9797 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9798 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9799 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9800 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9801 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9802 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9803 tep->cxx_info = (tmp1 >> 8) & 0x1;
9804 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9805 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9806 tep->reserved2 = (tmp1 >> 5) & 0x1;
9807 tep->Save_SP = (tmp1 >> 4) & 0x1;
9808 tep->Save_RP = (tmp1 >> 3) & 0x1;
9809 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9810 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9811 tep->Cleanup_defined = tmp1 & 0x1;
9813 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9814 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9815 tep->Large_frame = (tmp2 >> 29) & 0x1;
9816 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9817 tep->reserved4 = (tmp2 >> 27) & 0x1;
9818 tep->Total_frame_size = tmp2 & 0x7ffffff;
9820 free (table);
9822 /* Third, apply any relocations to the unwind table. */
9823 for (relsec = filedata->section_headers;
9824 relsec < filedata->section_headers + filedata->file_header.e_shnum;
9825 ++relsec)
9827 if (relsec->sh_type != SHT_RELA
9828 || relsec->sh_info >= filedata->file_header.e_shnum
9829 || filedata->section_headers + relsec->sh_info != sec)
9830 continue;
9832 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
9833 & rela, & nrelas))
9834 return false;
9836 for (rp = rela; rp < rela + nrelas; ++rp)
9838 unsigned int sym_ndx;
9839 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9840 relname = elf_hppa_reloc_type (r_type);
9842 if (relname == NULL)
9844 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9845 continue;
9848 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
9849 if (! startswith (relname, "R_PARISC_SEGREL"))
9851 warn (_("Skipping unexpected relocation type: %s\n"), relname);
9852 continue;
9855 i = rp->r_offset / unw_ent_size;
9856 if (i >= aux->table_len)
9858 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9860 continue;
9863 sym_ndx = get_reloc_symindex (rp->r_info);
9864 if (sym_ndx >= aux->nsyms)
9866 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9867 sym_ndx);
9868 continue;
9870 sym = aux->symtab + sym_ndx;
9872 switch ((rp->r_offset % unw_ent_size) / 4)
9874 case 0:
9875 aux->table[i].start.section = sym->st_shndx;
9876 aux->table[i].start.offset = sym->st_value + rp->r_addend;
9877 break;
9878 case 1:
9879 aux->table[i].end.section = sym->st_shndx;
9880 aux->table[i].end.offset = sym->st_value + rp->r_addend;
9881 break;
9882 default:
9883 break;
9887 free (rela);
9890 return true;
9893 static bool
9894 hppa_process_unwind (Filedata * filedata)
9896 struct hppa_unw_aux_info aux;
9897 Elf_Internal_Shdr * unwsec = NULL;
9898 Elf_Internal_Shdr * sec;
9899 size_t i;
9900 bool res = true;
9902 if (filedata->string_table == NULL)
9903 return false;
9905 memset (& aux, 0, sizeof (aux));
9907 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
9909 if (sec->sh_type == SHT_SYMTAB)
9911 if (aux.symtab)
9913 error (_("Multiple symbol tables encountered\n"));
9914 free (aux.symtab);
9915 aux.symtab = NULL;
9916 free (aux.strtab);
9917 aux.strtab = NULL;
9919 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9920 &aux.strtab, &aux.strtab_size))
9921 return false;
9923 else if (section_name_valid (filedata, sec)
9924 && streq (section_name (filedata, sec), ".PARISC.unwind"))
9925 unwsec = sec;
9928 if (!unwsec)
9929 printf (_("\nThere are no unwind sections in this file.\n"));
9931 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
9933 if (section_name_valid (filedata, sec)
9934 && streq (section_name (filedata, sec), ".PARISC.unwind"))
9936 uint64_t num_unwind = sec->sh_size / 16;
9938 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9939 "contains %" PRIu64 " entry:\n",
9940 "\nUnwind section '%s' at offset %#" PRIx64 " "
9941 "contains %" PRIu64 " entries:\n",
9942 num_unwind),
9943 printable_section_name (filedata, sec),
9944 sec->sh_offset,
9945 num_unwind);
9947 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
9948 res = false;
9950 if (res && aux.table_len > 0)
9952 if (! dump_hppa_unwind (filedata, &aux))
9953 res = false;
9956 free ((char *) aux.table);
9957 aux.table = NULL;
9961 free (aux.symtab);
9962 free ((char *) aux.strtab);
9964 return res;
9967 struct arm_section
9969 unsigned char * data; /* The unwind data. */
9970 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9971 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9972 uint64_t nrelas; /* The number of relocations. */
9973 unsigned int rel_type; /* REL or RELA ? */
9974 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
9977 struct arm_unw_aux_info
9979 Filedata * filedata; /* The file containing the unwind sections. */
9980 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9981 uint64_t nsyms; /* Number of symbols. */
9982 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9983 uint64_t nfuns; /* Number of these symbols. */
9984 char * strtab; /* The file's string table. */
9985 uint64_t strtab_size; /* Size of string table. */
9988 static const char *
9989 arm_print_vma_and_name (Filedata * filedata,
9990 struct arm_unw_aux_info * aux,
9991 uint64_t fn,
9992 struct absaddr addr)
9994 const char *procname;
9995 uint64_t sym_offset;
9997 if (addr.section == SHN_UNDEF)
9998 addr.offset = fn;
10000 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
10001 aux->strtab_size, addr, &procname,
10002 &sym_offset);
10004 print_vma (fn, PREFIX_HEX);
10006 if (procname)
10008 fputs (" <", stdout);
10009 fputs (procname, stdout);
10011 if (sym_offset)
10012 printf ("+0x%" PRIx64, sym_offset);
10013 fputc ('>', stdout);
10016 return procname;
10019 static void
10020 arm_free_section (struct arm_section *arm_sec)
10022 free (arm_sec->data);
10023 free (arm_sec->rela);
10026 /* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10027 cached section and install SEC instead.
10028 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10029 and return its valued in * WORDP, relocating if necessary.
10030 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
10031 relocation's offset in ADDR.
10032 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10033 into the string table of the symbol associated with the reloc. If no
10034 reloc was applied store -1 there.
10035 5) Return TRUE upon success, FALSE otherwise. */
10037 static bool
10038 get_unwind_section_word (Filedata * filedata,
10039 struct arm_unw_aux_info * aux,
10040 struct arm_section * arm_sec,
10041 Elf_Internal_Shdr * sec,
10042 uint64_t word_offset,
10043 unsigned int * wordp,
10044 struct absaddr * addr,
10045 uint64_t * sym_name)
10047 Elf_Internal_Rela *rp;
10048 Elf_Internal_Sym *sym;
10049 const char * relname;
10050 unsigned int word;
10051 bool wrapped;
10053 if (sec == NULL || arm_sec == NULL)
10054 return false;
10056 addr->section = SHN_UNDEF;
10057 addr->offset = 0;
10059 if (sym_name != NULL)
10060 *sym_name = (uint64_t) -1;
10062 /* If necessary, update the section cache. */
10063 if (sec != arm_sec->sec)
10065 Elf_Internal_Shdr *relsec;
10067 arm_free_section (arm_sec);
10069 arm_sec->sec = sec;
10070 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
10071 sec->sh_size, _("unwind data"));
10072 arm_sec->rela = NULL;
10073 arm_sec->nrelas = 0;
10075 for (relsec = filedata->section_headers;
10076 relsec < filedata->section_headers + filedata->file_header.e_shnum;
10077 ++relsec)
10079 if (relsec->sh_info >= filedata->file_header.e_shnum
10080 || filedata->section_headers + relsec->sh_info != sec
10081 /* PR 15745: Check the section type as well. */
10082 || (relsec->sh_type != SHT_REL
10083 && relsec->sh_type != SHT_RELA))
10084 continue;
10086 arm_sec->rel_type = relsec->sh_type;
10087 if (relsec->sh_type == SHT_REL)
10089 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
10090 relsec->sh_size,
10091 & arm_sec->rela, & arm_sec->nrelas))
10092 return false;
10094 else /* relsec->sh_type == SHT_RELA */
10096 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
10097 relsec->sh_size,
10098 & arm_sec->rela, & arm_sec->nrelas))
10099 return false;
10101 break;
10104 arm_sec->next_rela = arm_sec->rela;
10107 /* If there is no unwind data we can do nothing. */
10108 if (arm_sec->data == NULL)
10109 return false;
10111 /* If the offset is invalid then fail. */
10112 if (/* PR 21343 *//* PR 18879 */
10113 sec->sh_size < 4
10114 || word_offset > sec->sh_size - 4)
10115 return false;
10117 /* Get the word at the required offset. */
10118 word = byte_get (arm_sec->data + word_offset, 4);
10120 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10121 if (arm_sec->rela == NULL)
10123 * wordp = word;
10124 return true;
10127 /* Look through the relocs to find the one that applies to the provided offset. */
10128 wrapped = false;
10129 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10131 uint64_t prelval, offset;
10133 if (rp->r_offset > word_offset && !wrapped)
10135 rp = arm_sec->rela;
10136 wrapped = true;
10138 if (rp->r_offset > word_offset)
10139 break;
10141 if (rp->r_offset & 3)
10143 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10144 rp->r_offset);
10145 continue;
10148 if (rp->r_offset < word_offset)
10149 continue;
10151 /* PR 17531: file: 027-161405-0.004 */
10152 if (aux->symtab == NULL)
10153 continue;
10155 if (arm_sec->rel_type == SHT_REL)
10157 offset = word & 0x7fffffff;
10158 if (offset & 0x40000000)
10159 offset |= ~ (uint64_t) 0x7fffffff;
10161 else if (arm_sec->rel_type == SHT_RELA)
10162 offset = rp->r_addend;
10163 else
10165 error (_("Unknown section relocation type %d encountered\n"),
10166 arm_sec->rel_type);
10167 break;
10170 /* PR 17531 file: 027-1241568-0.004. */
10171 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10173 error (_("Bad symbol index in unwind relocation "
10174 "(%" PRIu64 " > %" PRIu64 ")\n"),
10175 ELF32_R_SYM (rp->r_info), aux->nsyms);
10176 break;
10179 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
10180 offset += sym->st_value;
10181 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10183 /* Check that we are processing the expected reloc type. */
10184 if (filedata->file_header.e_machine == EM_ARM)
10186 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
10187 if (relname == NULL)
10189 warn (_("Skipping unknown ARM relocation type: %d\n"),
10190 (int) ELF32_R_TYPE (rp->r_info));
10191 continue;
10194 if (streq (relname, "R_ARM_NONE"))
10195 continue;
10197 if (! streq (relname, "R_ARM_PREL31"))
10199 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
10200 continue;
10203 else if (filedata->file_header.e_machine == EM_TI_C6000)
10205 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
10206 if (relname == NULL)
10208 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10209 (int) ELF32_R_TYPE (rp->r_info));
10210 continue;
10213 if (streq (relname, "R_C6000_NONE"))
10214 continue;
10216 if (! streq (relname, "R_C6000_PREL31"))
10218 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
10219 continue;
10222 prelval >>= 1;
10224 else
10226 /* This function currently only supports ARM and TI unwinders. */
10227 warn (_("Only TI and ARM unwinders are currently supported\n"));
10228 break;
10231 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
10232 addr->section = sym->st_shndx;
10233 addr->offset = offset;
10235 if (sym_name)
10236 * sym_name = sym->st_name;
10237 break;
10240 *wordp = word;
10241 arm_sec->next_rela = rp;
10243 return true;
10246 static const char *tic6x_unwind_regnames[16] =
10248 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10249 "A14", "A13", "A12", "A11", "A10",
10250 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10253 static void
10254 decode_tic6x_unwind_regmask (unsigned int mask)
10256 int i;
10258 for (i = 12; mask; mask >>= 1, i--)
10260 if (mask & 1)
10262 fputs (tic6x_unwind_regnames[i], stdout);
10263 if (mask > 1)
10264 fputs (", ", stdout);
10269 #define ADVANCE \
10270 if (remaining == 0 && more_words) \
10272 data_offset += 4; \
10273 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
10274 data_offset, & word, & addr, NULL)) \
10275 return false; \
10276 remaining = 4; \
10277 more_words--; \
10280 #define GET_OP(OP) \
10281 ADVANCE; \
10282 if (remaining) \
10284 remaining--; \
10285 (OP) = word >> 24; \
10286 word <<= 8; \
10288 else \
10290 printf (_("[Truncated opcode]\n")); \
10291 return false; \
10293 printf ("0x%02x ", OP)
10295 static bool
10296 decode_arm_unwind_bytecode (Filedata * filedata,
10297 struct arm_unw_aux_info * aux,
10298 unsigned int word,
10299 unsigned int remaining,
10300 unsigned int more_words,
10301 uint64_t data_offset,
10302 Elf_Internal_Shdr * data_sec,
10303 struct arm_section * data_arm_sec)
10305 struct absaddr addr;
10306 bool res = true;
10308 /* Decode the unwinding instructions. */
10309 while (1)
10311 unsigned int op, op2;
10313 ADVANCE;
10314 if (remaining == 0)
10315 break;
10316 remaining--;
10317 op = word >> 24;
10318 word <<= 8;
10320 printf (" 0x%02x ", op);
10322 if ((op & 0xc0) == 0x00)
10324 int offset = ((op & 0x3f) << 2) + 4;
10326 printf (" vsp = vsp + %d", offset);
10328 else if ((op & 0xc0) == 0x40)
10330 int offset = ((op & 0x3f) << 2) + 4;
10332 printf (" vsp = vsp - %d", offset);
10334 else if ((op & 0xf0) == 0x80)
10336 GET_OP (op2);
10337 if (op == 0x80 && op2 == 0)
10338 printf (_("Refuse to unwind"));
10339 else
10341 unsigned int mask = ((op & 0x0f) << 8) | op2;
10342 bool first = true;
10343 int i;
10345 printf ("pop {");
10346 for (i = 0; i < 12; i++)
10347 if (mask & (1 << i))
10349 if (first)
10350 first = false;
10351 else
10352 printf (", ");
10353 printf ("r%d", 4 + i);
10355 printf ("}");
10358 else if ((op & 0xf0) == 0x90)
10360 if (op == 0x9d || op == 0x9f)
10361 printf (_(" [Reserved]"));
10362 else
10363 printf (" vsp = r%d", op & 0x0f);
10365 else if ((op & 0xf0) == 0xa0)
10367 int end = 4 + (op & 0x07);
10368 bool first = true;
10369 int i;
10371 printf (" pop {");
10372 for (i = 4; i <= end; i++)
10374 if (first)
10375 first = false;
10376 else
10377 printf (", ");
10378 printf ("r%d", i);
10380 if (op & 0x08)
10382 if (!first)
10383 printf (", ");
10384 printf ("r14");
10386 printf ("}");
10388 else if (op == 0xb0)
10389 printf (_(" finish"));
10390 else if (op == 0xb1)
10392 GET_OP (op2);
10393 if (op2 == 0 || (op2 & 0xf0) != 0)
10394 printf (_("[Spare]"));
10395 else
10397 unsigned int mask = op2 & 0x0f;
10398 bool first = true;
10399 int i;
10401 printf ("pop {");
10402 for (i = 0; i < 12; i++)
10403 if (mask & (1 << i))
10405 if (first)
10406 first = false;
10407 else
10408 printf (", ");
10409 printf ("r%d", i);
10411 printf ("}");
10414 else if (op == 0xb2)
10416 unsigned char buf[9];
10417 unsigned int i, len;
10418 uint64_t offset;
10420 for (i = 0; i < sizeof (buf); i++)
10422 GET_OP (buf[i]);
10423 if ((buf[i] & 0x80) == 0)
10424 break;
10426 if (i == sizeof (buf))
10428 error (_("corrupt change to vsp\n"));
10429 res = false;
10431 else
10433 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
10434 assert (len == i + 1);
10435 offset = offset * 4 + 0x204;
10436 printf ("vsp = vsp + %" PRId64, offset);
10439 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
10441 unsigned int first, last;
10443 GET_OP (op2);
10444 first = op2 >> 4;
10445 last = op2 & 0x0f;
10446 if (op == 0xc8)
10447 first = first + 16;
10448 printf ("pop {D%d", first);
10449 if (last)
10450 printf ("-D%d", first + last);
10451 printf ("}");
10453 else if (op == 0xb4)
10454 printf (_(" pop {ra_auth_code}"));
10455 else if (op == 0xb5)
10456 printf (_(" vsp as modifier for PAC validation"));
10457 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10459 unsigned int count = op & 0x07;
10461 printf ("pop {D8");
10462 if (count)
10463 printf ("-D%d", 8 + count);
10464 printf ("}");
10466 else if (op >= 0xc0 && op <= 0xc5)
10468 unsigned int count = op & 0x07;
10470 printf (" pop {wR10");
10471 if (count)
10472 printf ("-wR%d", 10 + count);
10473 printf ("}");
10475 else if (op == 0xc6)
10477 unsigned int first, last;
10479 GET_OP (op2);
10480 first = op2 >> 4;
10481 last = op2 & 0x0f;
10482 printf ("pop {wR%d", first);
10483 if (last)
10484 printf ("-wR%d", first + last);
10485 printf ("}");
10487 else if (op == 0xc7)
10489 GET_OP (op2);
10490 if (op2 == 0 || (op2 & 0xf0) != 0)
10491 printf (_("[Spare]"));
10492 else
10494 unsigned int mask = op2 & 0x0f;
10495 bool first = true;
10496 int i;
10498 printf ("pop {");
10499 for (i = 0; i < 4; i++)
10500 if (mask & (1 << i))
10502 if (first)
10503 first = false;
10504 else
10505 printf (", ");
10506 printf ("wCGR%d", i);
10508 printf ("}");
10511 else
10513 printf (_(" [unsupported opcode]"));
10514 res = false;
10517 printf ("\n");
10520 return res;
10523 static bool
10524 decode_tic6x_unwind_bytecode (Filedata * filedata,
10525 struct arm_unw_aux_info * aux,
10526 unsigned int word,
10527 unsigned int remaining,
10528 unsigned int more_words,
10529 uint64_t data_offset,
10530 Elf_Internal_Shdr * data_sec,
10531 struct arm_section * data_arm_sec)
10533 struct absaddr addr;
10535 /* Decode the unwinding instructions. */
10536 while (1)
10538 unsigned int op, op2;
10540 ADVANCE;
10541 if (remaining == 0)
10542 break;
10543 remaining--;
10544 op = word >> 24;
10545 word <<= 8;
10547 printf (" 0x%02x ", op);
10549 if ((op & 0xc0) == 0x00)
10551 int offset = ((op & 0x3f) << 3) + 8;
10552 printf (" sp = sp + %d", offset);
10554 else if ((op & 0xc0) == 0x80)
10556 GET_OP (op2);
10557 if (op == 0x80 && op2 == 0)
10558 printf (_("Refuse to unwind"));
10559 else
10561 unsigned int mask = ((op & 0x1f) << 8) | op2;
10562 if (op & 0x20)
10563 printf ("pop compact {");
10564 else
10565 printf ("pop {");
10567 decode_tic6x_unwind_regmask (mask);
10568 printf("}");
10571 else if ((op & 0xf0) == 0xc0)
10573 unsigned int reg;
10574 unsigned int nregs;
10575 unsigned int i;
10576 const char *name;
10577 struct
10579 unsigned int offset;
10580 unsigned int reg;
10581 } regpos[16];
10583 /* Scan entire instruction first so that GET_OP output is not
10584 interleaved with disassembly. */
10585 nregs = 0;
10586 for (i = 0; nregs < (op & 0xf); i++)
10588 GET_OP (op2);
10589 reg = op2 >> 4;
10590 if (reg != 0xf)
10592 regpos[nregs].offset = i * 2;
10593 regpos[nregs].reg = reg;
10594 nregs++;
10597 reg = op2 & 0xf;
10598 if (reg != 0xf)
10600 regpos[nregs].offset = i * 2 + 1;
10601 regpos[nregs].reg = reg;
10602 nregs++;
10606 printf (_("pop frame {"));
10607 if (nregs == 0)
10609 printf (_("*corrupt* - no registers specified"));
10611 else
10613 reg = nregs - 1;
10614 for (i = i * 2; i > 0; i--)
10616 if (regpos[reg].offset == i - 1)
10618 name = tic6x_unwind_regnames[regpos[reg].reg];
10619 if (reg > 0)
10620 reg--;
10622 else
10623 name = _("[pad]");
10625 fputs (name, stdout);
10626 if (i > 1)
10627 printf (", ");
10631 printf ("}");
10633 else if (op == 0xd0)
10634 printf (" MOV FP, SP");
10635 else if (op == 0xd1)
10636 printf (" __c6xabi_pop_rts");
10637 else if (op == 0xd2)
10639 unsigned char buf[9];
10640 unsigned int i, len;
10641 uint64_t offset;
10643 for (i = 0; i < sizeof (buf); i++)
10645 GET_OP (buf[i]);
10646 if ((buf[i] & 0x80) == 0)
10647 break;
10649 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10650 if (i == sizeof (buf))
10652 warn (_("Corrupt stack pointer adjustment detected\n"));
10653 return false;
10656 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
10657 assert (len == i + 1);
10658 offset = offset * 8 + 0x408;
10659 printf (_("sp = sp + %" PRId64), offset);
10661 else if ((op & 0xf0) == 0xe0)
10663 if ((op & 0x0f) == 7)
10664 printf (" RETURN");
10665 else
10666 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10668 else
10670 printf (_(" [unsupported opcode]"));
10672 putchar ('\n');
10675 return true;
10678 static uint64_t
10679 arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
10681 uint64_t offset;
10683 offset = word & 0x7fffffff;
10684 if (offset & 0x40000000)
10685 offset |= ~ (uint64_t) 0x7fffffff;
10687 if (filedata->file_header.e_machine == EM_TI_C6000)
10688 offset <<= 1;
10690 return offset + where;
10693 static bool
10694 decode_arm_unwind (Filedata * filedata,
10695 struct arm_unw_aux_info * aux,
10696 unsigned int word,
10697 unsigned int remaining,
10698 uint64_t data_offset,
10699 Elf_Internal_Shdr * data_sec,
10700 struct arm_section * data_arm_sec)
10702 int per_index;
10703 unsigned int more_words = 0;
10704 struct absaddr addr;
10705 uint64_t sym_name = (uint64_t) -1;
10706 bool res = true;
10708 if (remaining == 0)
10710 /* Fetch the first word.
10711 Note - when decoding an object file the address extracted
10712 here will always be 0. So we also pass in the sym_name
10713 parameter so that we can find the symbol associated with
10714 the personality routine. */
10715 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
10716 & word, & addr, & sym_name))
10717 return false;
10719 remaining = 4;
10721 else
10723 addr.section = SHN_UNDEF;
10724 addr.offset = 0;
10727 if ((word & 0x80000000) == 0)
10729 /* Expand prel31 for personality routine. */
10730 uint64_t fn;
10731 const char *procname;
10733 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
10734 printf (_(" Personality routine: "));
10735 if (fn == 0
10736 && addr.section == SHN_UNDEF && addr.offset == 0
10737 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
10739 procname = aux->strtab + sym_name;
10740 print_vma (fn, PREFIX_HEX);
10741 if (procname)
10743 fputs (" <", stdout);
10744 fputs (procname, stdout);
10745 fputc ('>', stdout);
10748 else
10749 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
10750 fputc ('\n', stdout);
10752 /* The GCC personality routines use the standard compact
10753 encoding, starting with one byte giving the number of
10754 words. */
10755 if (procname != NULL
10756 && (startswith (procname, "__gcc_personality_v0")
10757 || startswith (procname, "__gxx_personality_v0")
10758 || startswith (procname, "__gcj_personality_v0")
10759 || startswith (procname, "__gnu_objc_personality_v0")))
10761 remaining = 0;
10762 more_words = 1;
10763 ADVANCE;
10764 if (!remaining)
10766 printf (_(" [Truncated data]\n"));
10767 return false;
10769 more_words = word >> 24;
10770 word <<= 8;
10771 remaining--;
10772 per_index = -1;
10774 else
10775 return true;
10777 else
10779 /* ARM EHABI Section 6.3:
10781 An exception-handling table entry for the compact model looks like:
10783 31 30-28 27-24 23-0
10784 -- ----- ----- ----
10785 1 0 index Data for personalityRoutine[index] */
10787 if (filedata->file_header.e_machine == EM_ARM
10788 && (word & 0x70000000))
10790 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
10791 res = false;
10794 per_index = (word >> 24) & 0x7f;
10795 printf (_(" Compact model index: %d\n"), per_index);
10796 if (per_index == 0)
10798 more_words = 0;
10799 word <<= 8;
10800 remaining--;
10802 else if (per_index < 3)
10804 more_words = (word >> 16) & 0xff;
10805 word <<= 16;
10806 remaining -= 2;
10810 switch (filedata->file_header.e_machine)
10812 case EM_ARM:
10813 if (per_index < 3)
10815 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
10816 data_offset, data_sec, data_arm_sec))
10817 res = false;
10819 else
10821 warn (_("Unknown ARM compact model index encountered\n"));
10822 printf (_(" [reserved]\n"));
10823 res = false;
10825 break;
10827 case EM_TI_C6000:
10828 if (per_index < 3)
10830 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
10831 data_offset, data_sec, data_arm_sec))
10832 res = false;
10834 else if (per_index < 5)
10836 if (((word >> 17) & 0x7f) == 0x7f)
10837 printf (_(" Restore stack from frame pointer\n"));
10838 else
10839 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10840 printf (_(" Registers restored: "));
10841 if (per_index == 4)
10842 printf (" (compact) ");
10843 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10844 putchar ('\n');
10845 printf (_(" Return register: %s\n"),
10846 tic6x_unwind_regnames[word & 0xf]);
10848 else
10849 printf (_(" [reserved (%d)]\n"), per_index);
10850 break;
10852 default:
10853 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
10854 filedata->file_header.e_machine);
10855 res = false;
10858 /* Decode the descriptors. Not implemented. */
10860 return res;
10863 static bool
10864 dump_arm_unwind (Filedata * filedata,
10865 struct arm_unw_aux_info * aux,
10866 Elf_Internal_Shdr * exidx_sec)
10868 struct arm_section exidx_arm_sec, extab_arm_sec;
10869 unsigned int i, exidx_len;
10870 uint64_t j, nfuns;
10871 bool res = true;
10873 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10874 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10875 exidx_len = exidx_sec->sh_size / 8;
10877 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10878 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10879 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10880 aux->funtab[nfuns++] = aux->symtab[j];
10881 aux->nfuns = nfuns;
10882 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10884 for (i = 0; i < exidx_len; i++)
10886 unsigned int exidx_fn, exidx_entry;
10887 struct absaddr fn_addr, entry_addr;
10888 uint64_t fn;
10890 fputc ('\n', stdout);
10892 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
10893 8 * i, & exidx_fn, & fn_addr, NULL)
10894 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
10895 8 * i + 4, & exidx_entry, & entry_addr, NULL))
10897 free (aux->funtab);
10898 arm_free_section (& exidx_arm_sec);
10899 arm_free_section (& extab_arm_sec);
10900 return false;
10903 /* ARM EHABI, Section 5:
10904 An index table entry consists of 2 words.
10905 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10906 if (exidx_fn & 0x80000000)
10908 warn (_("corrupt index table entry: %x\n"), exidx_fn);
10909 res = false;
10912 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
10914 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
10915 fputs (": ", stdout);
10917 if (exidx_entry == 1)
10919 print_vma (exidx_entry, PREFIX_HEX);
10920 fputs (" [cantunwind]\n", stdout);
10922 else if (exidx_entry & 0x80000000)
10924 print_vma (exidx_entry, PREFIX_HEX);
10925 fputc ('\n', stdout);
10926 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
10928 else
10930 uint64_t table, table_offset = 0;
10931 Elf_Internal_Shdr *table_sec;
10933 fputs ("@", stdout);
10934 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
10935 print_vma (table, PREFIX_HEX);
10936 printf ("\n");
10938 /* Locate the matching .ARM.extab. */
10939 if (entry_addr.section != SHN_UNDEF
10940 && entry_addr.section < filedata->file_header.e_shnum)
10942 table_sec = filedata->section_headers + entry_addr.section;
10943 table_offset = entry_addr.offset;
10944 /* PR 18879 */
10945 if (table_offset > table_sec->sh_size)
10947 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10948 table_offset,
10949 printable_section_name (filedata, table_sec));
10950 res = false;
10951 continue;
10954 else
10956 table_sec = find_section_by_address (filedata, table);
10957 if (table_sec != NULL)
10958 table_offset = table - table_sec->sh_addr;
10961 if (table_sec == NULL)
10963 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10964 table);
10965 res = false;
10966 continue;
10969 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
10970 &extab_arm_sec))
10971 res = false;
10975 printf ("\n");
10977 free (aux->funtab);
10978 arm_free_section (&exidx_arm_sec);
10979 arm_free_section (&extab_arm_sec);
10981 return res;
10984 /* Used for both ARM and C6X unwinding tables. */
10986 static bool
10987 arm_process_unwind (Filedata * filedata)
10989 struct arm_unw_aux_info aux;
10990 Elf_Internal_Shdr *unwsec = NULL;
10991 Elf_Internal_Shdr *sec;
10992 size_t i;
10993 unsigned int sec_type;
10994 bool res = true;
10996 switch (filedata->file_header.e_machine)
10998 case EM_ARM:
10999 sec_type = SHT_ARM_EXIDX;
11000 break;
11002 case EM_TI_C6000:
11003 sec_type = SHT_C6000_UNWIND;
11004 break;
11006 default:
11007 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
11008 filedata->file_header.e_machine);
11009 return false;
11012 if (filedata->string_table == NULL)
11013 return false;
11015 memset (& aux, 0, sizeof (aux));
11016 aux.filedata = filedata;
11018 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
11020 if (sec->sh_type == SHT_SYMTAB)
11022 if (aux.symtab)
11024 error (_("Multiple symbol tables encountered\n"));
11025 free (aux.symtab);
11026 aux.symtab = NULL;
11027 free (aux.strtab);
11028 aux.strtab = NULL;
11030 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11031 &aux.strtab, &aux.strtab_size))
11032 return false;
11034 else if (sec->sh_type == sec_type)
11035 unwsec = sec;
11038 if (unwsec == NULL)
11039 printf (_("\nThere are no unwind sections in this file.\n"));
11040 else
11041 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
11043 if (sec->sh_type == sec_type)
11045 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11046 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11047 "contains %" PRIu64 " entry:\n",
11048 "\nUnwind section '%s' at offset %#" PRIx64 " "
11049 "contains %" PRIu64 " entries:\n",
11050 num_unwind),
11051 printable_section_name (filedata, sec),
11052 sec->sh_offset,
11053 num_unwind);
11055 if (! dump_arm_unwind (filedata, &aux, sec))
11056 res = false;
11060 free (aux.symtab);
11061 free ((char *) aux.strtab);
11063 return res;
11066 static bool
11067 no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11069 printf (_("No processor specific unwind information to decode\n"));
11070 return true;
11073 static bool
11074 process_unwind (Filedata * filedata)
11076 struct unwind_handler
11078 unsigned int machtype;
11079 bool (* handler)(Filedata *);
11080 } handlers[] =
11082 { EM_ARM, arm_process_unwind },
11083 { EM_IA_64, ia64_process_unwind },
11084 { EM_PARISC, hppa_process_unwind },
11085 { EM_TI_C6000, arm_process_unwind },
11086 { EM_386, no_processor_specific_unwind },
11087 { EM_X86_64, no_processor_specific_unwind },
11088 { 0, NULL }
11090 int i;
11092 if (!do_unwind)
11093 return true;
11095 for (i = 0; handlers[i].handler != NULL; i++)
11096 if (filedata->file_header.e_machine == handlers[i].machtype)
11097 return handlers[i].handler (filedata);
11099 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
11100 get_machine_name (filedata->file_header.e_machine));
11101 return true;
11104 static void
11105 dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11107 switch (entry->d_tag)
11109 case DT_AARCH64_BTI_PLT:
11110 case DT_AARCH64_PAC_PLT:
11111 break;
11112 default:
11113 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11114 break;
11116 putchar ('\n');
11119 static void
11120 dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
11122 switch (entry->d_tag)
11124 case DT_MIPS_FLAGS:
11125 if (entry->d_un.d_val == 0)
11126 printf (_("NONE"));
11127 else
11129 static const char * opts[] =
11131 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11132 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11133 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11134 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11135 "RLD_ORDER_SAFE"
11137 unsigned int cnt;
11138 bool first = true;
11140 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
11141 if (entry->d_un.d_val & (1 << cnt))
11143 printf ("%s%s", first ? "" : " ", opts[cnt]);
11144 first = false;
11147 break;
11149 case DT_MIPS_IVERSION:
11150 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11151 printf (_("Interface Version: %s"),
11152 get_dynamic_name (filedata, entry->d_un.d_val));
11153 else
11154 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
11155 entry->d_un.d_ptr);
11156 break;
11158 case DT_MIPS_TIME_STAMP:
11160 char timebuf[128];
11161 struct tm * tmp;
11162 time_t atime = entry->d_un.d_val;
11164 tmp = gmtime (&atime);
11165 /* PR 17531: file: 6accc532. */
11166 if (tmp == NULL)
11167 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11168 else
11169 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11170 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11171 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
11172 printf (_("Time Stamp: %s"), timebuf);
11174 break;
11176 case DT_MIPS_RLD_VERSION:
11177 case DT_MIPS_LOCAL_GOTNO:
11178 case DT_MIPS_CONFLICTNO:
11179 case DT_MIPS_LIBLISTNO:
11180 case DT_MIPS_SYMTABNO:
11181 case DT_MIPS_UNREFEXTNO:
11182 case DT_MIPS_HIPAGENO:
11183 case DT_MIPS_DELTA_CLASS_NO:
11184 case DT_MIPS_DELTA_INSTANCE_NO:
11185 case DT_MIPS_DELTA_RELOC_NO:
11186 case DT_MIPS_DELTA_SYM_NO:
11187 case DT_MIPS_DELTA_CLASSSYM_NO:
11188 case DT_MIPS_COMPACT_SIZE:
11189 print_vma (entry->d_un.d_val, DEC);
11190 break;
11192 case DT_MIPS_XHASH:
11193 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11194 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
11195 /* Falls through. */
11197 default:
11198 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11200 putchar ('\n');
11203 static void
11204 dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
11206 switch (entry->d_tag)
11208 case DT_HP_DLD_FLAGS:
11210 static struct
11212 unsigned int bit;
11213 const char * str;
11215 flags[] =
11217 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11218 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11219 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11220 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11221 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11222 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11223 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11224 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11225 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11226 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
11227 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11228 { DT_HP_GST, "HP_GST" },
11229 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11230 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11231 { DT_HP_NODELETE, "HP_NODELETE" },
11232 { DT_HP_GROUP, "HP_GROUP" },
11233 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
11235 bool first = true;
11236 size_t cnt;
11237 uint64_t val = entry->d_un.d_val;
11239 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
11240 if (val & flags[cnt].bit)
11242 if (! first)
11243 putchar (' ');
11244 fputs (flags[cnt].str, stdout);
11245 first = false;
11246 val ^= flags[cnt].bit;
11249 if (val != 0 || first)
11251 if (! first)
11252 putchar (' ');
11253 print_vma (val, HEX);
11256 break;
11258 default:
11259 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11260 break;
11262 putchar ('\n');
11265 /* VMS vs Unix time offset and factor. */
11267 #define VMS_EPOCH_OFFSET 35067168000000000LL
11268 #define VMS_GRANULARITY_FACTOR 10000000
11269 #ifndef INT64_MIN
11270 #define INT64_MIN (-9223372036854775807LL - 1)
11271 #endif
11273 /* Display a VMS time in a human readable format. */
11275 static void
11276 print_vms_time (int64_t vmstime)
11278 struct tm *tm = NULL;
11279 time_t unxtime;
11281 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11283 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11284 unxtime = vmstime;
11285 if (unxtime == vmstime)
11286 tm = gmtime (&unxtime);
11288 if (tm != NULL)
11289 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11290 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11291 tm->tm_hour, tm->tm_min, tm->tm_sec);
11294 static void
11295 dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
11297 switch (entry->d_tag)
11299 case DT_IA_64_PLT_RESERVE:
11300 /* First 3 slots reserved. */
11301 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11302 printf (" -- ");
11303 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
11304 break;
11306 case DT_IA_64_VMS_LINKTIME:
11307 print_vms_time (entry->d_un.d_val);
11308 break;
11310 case DT_IA_64_VMS_LNKFLAGS:
11311 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11312 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11313 printf (" CALL_DEBUG");
11314 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11315 printf (" NOP0BUFS");
11316 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11317 printf (" P0IMAGE");
11318 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11319 printf (" MKTHREADS");
11320 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11321 printf (" UPCALLS");
11322 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11323 printf (" IMGSTA");
11324 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11325 printf (" INITIALIZE");
11326 if (entry->d_un.d_val & VMS_LF_MAIN)
11327 printf (" MAIN");
11328 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11329 printf (" EXE_INIT");
11330 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11331 printf (" TBK_IN_IMG");
11332 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11333 printf (" DBG_IN_IMG");
11334 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11335 printf (" TBK_IN_DSF");
11336 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11337 printf (" DBG_IN_DSF");
11338 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11339 printf (" SIGNATURES");
11340 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11341 printf (" REL_SEG_OFF");
11342 break;
11344 default:
11345 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11346 break;
11348 putchar ('\n');
11351 static bool
11352 get_32bit_dynamic_section (Filedata * filedata)
11354 Elf32_External_Dyn * edyn;
11355 Elf32_External_Dyn * ext;
11356 Elf_Internal_Dyn * entry;
11358 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11359 filedata->dynamic_addr, 1,
11360 filedata->dynamic_size,
11361 _("dynamic section"));
11362 if (!edyn)
11363 return false;
11365 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11366 might not have the luxury of section headers. Look for the DT_NULL
11367 terminator to determine the number of entries. */
11368 for (ext = edyn, filedata->dynamic_nent = 0;
11369 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
11370 ext++)
11372 filedata->dynamic_nent++;
11373 if (BYTE_GET (ext->d_tag) == DT_NULL)
11374 break;
11377 filedata->dynamic_section
11378 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11379 if (filedata->dynamic_section == NULL)
11381 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11382 filedata->dynamic_nent);
11383 free (edyn);
11384 return false;
11387 for (ext = edyn, entry = filedata->dynamic_section;
11388 entry < filedata->dynamic_section + filedata->dynamic_nent;
11389 ext++, entry++)
11391 entry->d_tag = BYTE_GET (ext->d_tag);
11392 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
11395 free (edyn);
11397 return true;
11400 static bool
11401 get_64bit_dynamic_section (Filedata * filedata)
11403 Elf64_External_Dyn * edyn;
11404 Elf64_External_Dyn * ext;
11405 Elf_Internal_Dyn * entry;
11407 /* Read in the data. */
11408 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11409 filedata->dynamic_addr, 1,
11410 filedata->dynamic_size,
11411 _("dynamic section"));
11412 if (!edyn)
11413 return false;
11415 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11416 might not have the luxury of section headers. Look for the DT_NULL
11417 terminator to determine the number of entries. */
11418 for (ext = edyn, filedata->dynamic_nent = 0;
11419 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
11420 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
11421 ext++)
11423 filedata->dynamic_nent++;
11424 if (BYTE_GET (ext->d_tag) == DT_NULL)
11425 break;
11428 filedata->dynamic_section
11429 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11430 if (filedata->dynamic_section == NULL)
11432 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11433 filedata->dynamic_nent);
11434 free (edyn);
11435 return false;
11438 /* Convert from external to internal formats. */
11439 for (ext = edyn, entry = filedata->dynamic_section;
11440 entry < filedata->dynamic_section + filedata->dynamic_nent;
11441 ext++, entry++)
11443 entry->d_tag = BYTE_GET (ext->d_tag);
11444 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
11447 free (edyn);
11449 return true;
11452 static bool
11453 get_dynamic_section (Filedata *filedata)
11455 if (filedata->dynamic_section)
11456 return true;
11458 if (is_32bit_elf)
11459 return get_32bit_dynamic_section (filedata);
11460 else
11461 return get_64bit_dynamic_section (filedata);
11464 static void
11465 print_dynamic_flags (uint64_t flags)
11467 bool first = true;
11469 while (flags)
11471 uint64_t flag;
11473 flag = flags & - flags;
11474 flags &= ~ flag;
11476 if (first)
11477 first = false;
11478 else
11479 putc (' ', stdout);
11481 switch (flag)
11483 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11484 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11485 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11486 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11487 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
11488 default: fputs (_("unknown"), stdout); break;
11491 puts ("");
11494 static uint64_t *
11495 get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
11497 unsigned char * e_data;
11498 uint64_t * i_data;
11500 /* If size_t is smaller than uint64_t, eg because you are building
11501 on a 32-bit host, then make sure that when number is cast to
11502 size_t no information is lost. */
11503 if ((size_t) number != number
11504 || ent_size * number / ent_size != number)
11506 error (_("Size overflow prevents reading %" PRIu64
11507 " elements of size %u\n"),
11508 number, ent_size);
11509 return NULL;
11512 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11513 attempting to allocate memory when the read is bound to fail. */
11514 if (ent_size * number > filedata->file_size)
11516 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
11517 number);
11518 return NULL;
11521 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11522 if (e_data == NULL)
11524 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
11525 number);
11526 return NULL;
11529 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11531 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
11532 number * ent_size);
11533 free (e_data);
11534 return NULL;
11537 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
11538 if (i_data == NULL)
11540 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11541 number);
11542 free (e_data);
11543 return NULL;
11546 while (number--)
11547 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11549 free (e_data);
11551 return i_data;
11554 static uint64_t
11555 get_num_dynamic_syms (Filedata * filedata)
11557 uint64_t num_of_syms = 0;
11559 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11560 return num_of_syms;
11562 if (filedata->dynamic_info[DT_HASH])
11564 unsigned char nb[8];
11565 unsigned char nc[8];
11566 unsigned int hash_ent_size = 4;
11568 if ((filedata->file_header.e_machine == EM_ALPHA
11569 || filedata->file_header.e_machine == EM_S390
11570 || filedata->file_header.e_machine == EM_S390_OLD)
11571 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11572 hash_ent_size = 8;
11574 if (fseek64 (filedata->handle,
11575 (filedata->archive_file_offset
11576 + offset_from_vma (filedata,
11577 filedata->dynamic_info[DT_HASH],
11578 sizeof nb + sizeof nc)),
11579 SEEK_SET))
11581 error (_("Unable to seek to start of dynamic information\n"));
11582 goto no_hash;
11585 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11587 error (_("Failed to read in number of buckets\n"));
11588 goto no_hash;
11591 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11593 error (_("Failed to read in number of chains\n"));
11594 goto no_hash;
11597 filedata->nbuckets = byte_get (nb, hash_ent_size);
11598 filedata->nchains = byte_get (nc, hash_ent_size);
11600 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11602 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11603 hash_ent_size);
11604 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11605 hash_ent_size);
11607 if (filedata->buckets != NULL && filedata->chains != NULL)
11608 num_of_syms = filedata->nchains;
11610 no_hash:
11611 if (num_of_syms == 0)
11613 free (filedata->buckets);
11614 filedata->buckets = NULL;
11615 free (filedata->chains);
11616 filedata->chains = NULL;
11617 filedata->nbuckets = 0;
11621 if (filedata->dynamic_info_DT_GNU_HASH)
11623 unsigned char nb[16];
11624 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11625 uint64_t buckets_vma;
11626 uint64_t hn;
11628 if (fseek64 (filedata->handle,
11629 (filedata->archive_file_offset
11630 + offset_from_vma (filedata,
11631 filedata->dynamic_info_DT_GNU_HASH,
11632 sizeof nb)),
11633 SEEK_SET))
11635 error (_("Unable to seek to start of dynamic information\n"));
11636 goto no_gnu_hash;
11639 if (fread (nb, 16, 1, filedata->handle) != 1)
11641 error (_("Failed to read in number of buckets\n"));
11642 goto no_gnu_hash;
11645 filedata->ngnubuckets = byte_get (nb, 4);
11646 filedata->gnusymidx = byte_get (nb + 4, 4);
11647 bitmaskwords = byte_get (nb + 8, 4);
11648 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
11649 if (is_32bit_elf)
11650 buckets_vma += bitmaskwords * 4;
11651 else
11652 buckets_vma += bitmaskwords * 8;
11654 if (fseek64 (filedata->handle,
11655 (filedata->archive_file_offset
11656 + offset_from_vma (filedata, buckets_vma, 4)),
11657 SEEK_SET))
11659 error (_("Unable to seek to start of dynamic information\n"));
11660 goto no_gnu_hash;
11663 filedata->gnubuckets
11664 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
11666 if (filedata->gnubuckets == NULL)
11667 goto no_gnu_hash;
11669 for (i = 0; i < filedata->ngnubuckets; i++)
11670 if (filedata->gnubuckets[i] != 0)
11672 if (filedata->gnubuckets[i] < filedata->gnusymidx)
11673 goto no_gnu_hash;
11675 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11676 maxchain = filedata->gnubuckets[i];
11679 if (maxchain == 0xffffffff)
11680 goto no_gnu_hash;
11682 maxchain -= filedata->gnusymidx;
11684 if (fseek64 (filedata->handle,
11685 (filedata->archive_file_offset
11686 + offset_from_vma (filedata,
11687 buckets_vma + 4 * (filedata->ngnubuckets
11688 + maxchain),
11689 4)),
11690 SEEK_SET))
11692 error (_("Unable to seek to start of dynamic information\n"));
11693 goto no_gnu_hash;
11698 if (fread (nb, 4, 1, filedata->handle) != 1)
11700 error (_("Failed to determine last chain length\n"));
11701 goto no_gnu_hash;
11704 if (maxchain + 1 == 0)
11705 goto no_gnu_hash;
11707 ++maxchain;
11709 while ((byte_get (nb, 4) & 1) == 0);
11711 if (fseek64 (filedata->handle,
11712 (filedata->archive_file_offset
11713 + offset_from_vma (filedata, (buckets_vma
11714 + 4 * filedata->ngnubuckets),
11715 4)),
11716 SEEK_SET))
11718 error (_("Unable to seek to start of dynamic information\n"));
11719 goto no_gnu_hash;
11722 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11723 filedata->ngnuchains = maxchain;
11725 if (filedata->gnuchains == NULL)
11726 goto no_gnu_hash;
11728 if (filedata->dynamic_info_DT_MIPS_XHASH)
11730 if (fseek64 (filedata->handle,
11731 (filedata->archive_file_offset
11732 + offset_from_vma (filedata, (buckets_vma
11733 + 4 * (filedata->ngnubuckets
11734 + maxchain)), 4)),
11735 SEEK_SET))
11737 error (_("Unable to seek to start of dynamic information\n"));
11738 goto no_gnu_hash;
11741 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
11742 if (filedata->mipsxlat == NULL)
11743 goto no_gnu_hash;
11746 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11747 if (filedata->gnubuckets[hn] != 0)
11749 uint64_t si = filedata->gnubuckets[hn];
11750 uint64_t off = si - filedata->gnusymidx;
11754 if (filedata->dynamic_info_DT_MIPS_XHASH)
11756 if (off < filedata->ngnuchains
11757 && filedata->mipsxlat[off] >= num_of_syms)
11758 num_of_syms = filedata->mipsxlat[off] + 1;
11760 else
11762 if (si >= num_of_syms)
11763 num_of_syms = si + 1;
11765 si++;
11767 while (off < filedata->ngnuchains
11768 && (filedata->gnuchains[off++] & 1) == 0);
11771 if (num_of_syms == 0)
11773 no_gnu_hash:
11774 free (filedata->mipsxlat);
11775 filedata->mipsxlat = NULL;
11776 free (filedata->gnuchains);
11777 filedata->gnuchains = NULL;
11778 free (filedata->gnubuckets);
11779 filedata->gnubuckets = NULL;
11780 filedata->ngnubuckets = 0;
11781 filedata->ngnuchains = 0;
11785 return num_of_syms;
11788 /* Parse and display the contents of the dynamic section. */
11790 static bool
11791 process_dynamic_section (Filedata * filedata)
11793 Elf_Internal_Dyn * entry;
11795 if (filedata->dynamic_size <= 1)
11797 if (do_dynamic)
11799 if (filedata->is_separate)
11800 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11801 filedata->file_name);
11802 else
11803 printf (_("\nThere is no dynamic section in this file.\n"));
11806 return true;
11809 if (!get_dynamic_section (filedata))
11810 return false;
11812 /* Find the appropriate symbol table. */
11813 if (filedata->dynamic_symbols == NULL || do_histogram)
11815 uint64_t num_of_syms;
11817 for (entry = filedata->dynamic_section;
11818 entry < filedata->dynamic_section + filedata->dynamic_nent;
11819 ++entry)
11820 if (entry->d_tag == DT_SYMTAB)
11821 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
11822 else if (entry->d_tag == DT_SYMENT)
11823 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
11824 else if (entry->d_tag == DT_HASH)
11825 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
11826 else if (entry->d_tag == DT_GNU_HASH)
11827 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
11828 else if ((filedata->file_header.e_machine == EM_MIPS
11829 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11830 && entry->d_tag == DT_MIPS_XHASH)
11832 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11833 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
11836 num_of_syms = get_num_dynamic_syms (filedata);
11838 if (num_of_syms != 0
11839 && filedata->dynamic_symbols == NULL
11840 && filedata->dynamic_info[DT_SYMTAB]
11841 && filedata->dynamic_info[DT_SYMENT])
11843 Elf_Internal_Phdr *seg;
11844 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
11846 if (! get_program_headers (filedata))
11848 error (_("Cannot interpret virtual addresses "
11849 "without program headers.\n"));
11850 return false;
11853 for (seg = filedata->program_headers;
11854 seg < filedata->program_headers + filedata->file_header.e_phnum;
11855 ++seg)
11857 if (seg->p_type != PT_LOAD)
11858 continue;
11860 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11862 /* See PR 21379 for a reproducer. */
11863 error (_("Invalid PT_LOAD entry\n"));
11864 return false;
11867 if (vma >= (seg->p_vaddr & -seg->p_align)
11868 && vma < seg->p_vaddr + seg->p_filesz)
11870 /* Since we do not know how big the symbol table is,
11871 we default to reading in up to the end of PT_LOAD
11872 segment and processing that. This is overkill, I
11873 know, but it should work. */
11874 Elf_Internal_Shdr section;
11875 section.sh_offset = (vma - seg->p_vaddr
11876 + seg->p_offset);
11877 section.sh_size = (num_of_syms
11878 * filedata->dynamic_info[DT_SYMENT]);
11879 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
11881 if (do_checks
11882 && filedata->dynamic_symtab_section != NULL
11883 && ((filedata->dynamic_symtab_section->sh_offset
11884 != section.sh_offset)
11885 || (filedata->dynamic_symtab_section->sh_size
11886 != section.sh_size)
11887 || (filedata->dynamic_symtab_section->sh_entsize
11888 != section.sh_entsize)))
11889 warn (_("\
11890 the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11892 section.sh_name = filedata->string_table_length;
11893 filedata->dynamic_symbols
11894 = get_elf_symbols (filedata, &section,
11895 &filedata->num_dynamic_syms);
11896 if (filedata->dynamic_symbols == NULL
11897 || filedata->num_dynamic_syms != num_of_syms)
11899 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
11900 return false;
11902 break;
11908 /* Similarly find a string table. */
11909 if (filedata->dynamic_strings == NULL)
11910 for (entry = filedata->dynamic_section;
11911 entry < filedata->dynamic_section + filedata->dynamic_nent;
11912 ++entry)
11914 if (entry->d_tag == DT_STRTAB)
11915 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
11917 if (entry->d_tag == DT_STRSZ)
11918 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
11920 if (filedata->dynamic_info[DT_STRTAB]
11921 && filedata->dynamic_info[DT_STRSZ])
11923 uint64_t offset;
11924 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
11926 offset = offset_from_vma (filedata,
11927 filedata->dynamic_info[DT_STRTAB],
11928 str_tab_len);
11929 if (do_checks
11930 && filedata->dynamic_strtab_section
11931 && ((filedata->dynamic_strtab_section->sh_offset
11932 != (file_ptr) offset)
11933 || (filedata->dynamic_strtab_section->sh_size
11934 != str_tab_len)))
11935 warn (_("\
11936 the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11938 filedata->dynamic_strings
11939 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11940 _("dynamic string table"));
11941 if (filedata->dynamic_strings == NULL)
11943 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11944 break;
11947 filedata->dynamic_strings_length = str_tab_len;
11948 break;
11952 /* And find the syminfo section if available. */
11953 if (filedata->dynamic_syminfo == NULL)
11955 uint64_t syminsz = 0;
11957 for (entry = filedata->dynamic_section;
11958 entry < filedata->dynamic_section + filedata->dynamic_nent;
11959 ++entry)
11961 if (entry->d_tag == DT_SYMINENT)
11963 /* Note: these braces are necessary to avoid a syntax
11964 error from the SunOS4 C compiler. */
11965 /* PR binutils/17531: A corrupt file can trigger this test.
11966 So do not use an assert, instead generate an error message. */
11967 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
11968 error (_("Bad value (%d) for SYMINENT entry\n"),
11969 (int) entry->d_un.d_val);
11971 else if (entry->d_tag == DT_SYMINSZ)
11972 syminsz = entry->d_un.d_val;
11973 else if (entry->d_tag == DT_SYMINFO)
11974 filedata->dynamic_syminfo_offset
11975 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
11978 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
11980 Elf_External_Syminfo * extsyminfo;
11981 Elf_External_Syminfo * extsym;
11982 Elf_Internal_Syminfo * syminfo;
11984 /* There is a syminfo section. Read the data. */
11985 extsyminfo = (Elf_External_Syminfo *)
11986 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11987 1, syminsz, _("symbol information"));
11988 if (!extsyminfo)
11989 return false;
11991 if (filedata->dynamic_syminfo != NULL)
11993 error (_("Multiple dynamic symbol information sections found\n"));
11994 free (filedata->dynamic_syminfo);
11996 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11997 if (filedata->dynamic_syminfo == NULL)
11999 error (_("Out of memory allocating %" PRIu64
12000 " bytes for dynamic symbol info\n"),
12001 syminsz);
12002 return false;
12005 filedata->dynamic_syminfo_nent
12006 = syminsz / sizeof (Elf_External_Syminfo);
12007 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
12008 syminfo < (filedata->dynamic_syminfo
12009 + filedata->dynamic_syminfo_nent);
12010 ++syminfo, ++extsym)
12012 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12013 syminfo->si_flags = BYTE_GET (extsym->si_flags);
12016 free (extsyminfo);
12020 if (do_dynamic && filedata->dynamic_addr)
12022 if (filedata->is_separate)
12023 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12024 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12025 filedata->dynamic_nent),
12026 filedata->file_name,
12027 filedata->dynamic_addr,
12028 filedata->dynamic_nent);
12029 else
12030 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12031 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12032 filedata->dynamic_nent),
12033 filedata->dynamic_addr,
12034 filedata->dynamic_nent);
12036 if (do_dynamic)
12037 printf (_(" Tag Type Name/Value\n"));
12039 for (entry = filedata->dynamic_section;
12040 entry < filedata->dynamic_section + filedata->dynamic_nent;
12041 entry++)
12043 if (do_dynamic)
12045 const char * dtype;
12047 putchar (' ');
12048 print_vma (entry->d_tag, FULL_HEX);
12049 dtype = get_dynamic_type (filedata, entry->d_tag);
12050 printf (" (%s)%*s", dtype,
12051 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
12054 switch (entry->d_tag)
12056 case DT_FLAGS:
12057 if (do_dynamic)
12058 print_dynamic_flags (entry->d_un.d_val);
12059 break;
12061 case DT_AUXILIARY:
12062 case DT_FILTER:
12063 case DT_CONFIG:
12064 case DT_DEPAUDIT:
12065 case DT_AUDIT:
12066 if (do_dynamic)
12068 switch (entry->d_tag)
12070 case DT_AUXILIARY:
12071 printf (_("Auxiliary library"));
12072 break;
12074 case DT_FILTER:
12075 printf (_("Filter library"));
12076 break;
12078 case DT_CONFIG:
12079 printf (_("Configuration file"));
12080 break;
12082 case DT_DEPAUDIT:
12083 printf (_("Dependency audit library"));
12084 break;
12086 case DT_AUDIT:
12087 printf (_("Audit library"));
12088 break;
12091 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12092 printf (": [%s]\n",
12093 get_dynamic_name (filedata, entry->d_un.d_val));
12094 else
12096 printf (": ");
12097 print_vma (entry->d_un.d_val, PREFIX_HEX);
12098 putchar ('\n');
12101 break;
12103 case DT_FEATURE:
12104 if (do_dynamic)
12106 printf (_("Flags:"));
12108 if (entry->d_un.d_val == 0)
12109 printf (_(" None\n"));
12110 else
12112 uint64_t val = entry->d_un.d_val;
12114 if (val & DTF_1_PARINIT)
12116 printf (" PARINIT");
12117 val ^= DTF_1_PARINIT;
12119 if (val & DTF_1_CONFEXP)
12121 printf (" CONFEXP");
12122 val ^= DTF_1_CONFEXP;
12124 if (val != 0)
12125 printf (" %" PRIx64, val);
12126 puts ("");
12129 break;
12131 case DT_POSFLAG_1:
12132 if (do_dynamic)
12134 printf (_("Flags:"));
12136 if (entry->d_un.d_val == 0)
12137 printf (_(" None\n"));
12138 else
12140 uint64_t val = entry->d_un.d_val;
12142 if (val & DF_P1_LAZYLOAD)
12144 printf (" LAZYLOAD");
12145 val ^= DF_P1_LAZYLOAD;
12147 if (val & DF_P1_GROUPPERM)
12149 printf (" GROUPPERM");
12150 val ^= DF_P1_GROUPPERM;
12152 if (val != 0)
12153 printf (" %" PRIx64, val);
12154 puts ("");
12157 break;
12159 case DT_FLAGS_1:
12160 if (do_dynamic)
12162 printf (_("Flags:"));
12163 if (entry->d_un.d_val == 0)
12164 printf (_(" None\n"));
12165 else
12167 uint64_t val = entry->d_un.d_val;
12169 if (val & DF_1_NOW)
12171 printf (" NOW");
12172 val ^= DF_1_NOW;
12174 if (val & DF_1_GLOBAL)
12176 printf (" GLOBAL");
12177 val ^= DF_1_GLOBAL;
12179 if (val & DF_1_GROUP)
12181 printf (" GROUP");
12182 val ^= DF_1_GROUP;
12184 if (val & DF_1_NODELETE)
12186 printf (" NODELETE");
12187 val ^= DF_1_NODELETE;
12189 if (val & DF_1_LOADFLTR)
12191 printf (" LOADFLTR");
12192 val ^= DF_1_LOADFLTR;
12194 if (val & DF_1_INITFIRST)
12196 printf (" INITFIRST");
12197 val ^= DF_1_INITFIRST;
12199 if (val & DF_1_NOOPEN)
12201 printf (" NOOPEN");
12202 val ^= DF_1_NOOPEN;
12204 if (val & DF_1_ORIGIN)
12206 printf (" ORIGIN");
12207 val ^= DF_1_ORIGIN;
12209 if (val & DF_1_DIRECT)
12211 printf (" DIRECT");
12212 val ^= DF_1_DIRECT;
12214 if (val & DF_1_TRANS)
12216 printf (" TRANS");
12217 val ^= DF_1_TRANS;
12219 if (val & DF_1_INTERPOSE)
12221 printf (" INTERPOSE");
12222 val ^= DF_1_INTERPOSE;
12224 if (val & DF_1_NODEFLIB)
12226 printf (" NODEFLIB");
12227 val ^= DF_1_NODEFLIB;
12229 if (val & DF_1_NODUMP)
12231 printf (" NODUMP");
12232 val ^= DF_1_NODUMP;
12234 if (val & DF_1_CONFALT)
12236 printf (" CONFALT");
12237 val ^= DF_1_CONFALT;
12239 if (val & DF_1_ENDFILTEE)
12241 printf (" ENDFILTEE");
12242 val ^= DF_1_ENDFILTEE;
12244 if (val & DF_1_DISPRELDNE)
12246 printf (" DISPRELDNE");
12247 val ^= DF_1_DISPRELDNE;
12249 if (val & DF_1_DISPRELPND)
12251 printf (" DISPRELPND");
12252 val ^= DF_1_DISPRELPND;
12254 if (val & DF_1_NODIRECT)
12256 printf (" NODIRECT");
12257 val ^= DF_1_NODIRECT;
12259 if (val & DF_1_IGNMULDEF)
12261 printf (" IGNMULDEF");
12262 val ^= DF_1_IGNMULDEF;
12264 if (val & DF_1_NOKSYMS)
12266 printf (" NOKSYMS");
12267 val ^= DF_1_NOKSYMS;
12269 if (val & DF_1_NOHDR)
12271 printf (" NOHDR");
12272 val ^= DF_1_NOHDR;
12274 if (val & DF_1_EDITED)
12276 printf (" EDITED");
12277 val ^= DF_1_EDITED;
12279 if (val & DF_1_NORELOC)
12281 printf (" NORELOC");
12282 val ^= DF_1_NORELOC;
12284 if (val & DF_1_SYMINTPOSE)
12286 printf (" SYMINTPOSE");
12287 val ^= DF_1_SYMINTPOSE;
12289 if (val & DF_1_GLOBAUDIT)
12291 printf (" GLOBAUDIT");
12292 val ^= DF_1_GLOBAUDIT;
12294 if (val & DF_1_SINGLETON)
12296 printf (" SINGLETON");
12297 val ^= DF_1_SINGLETON;
12299 if (val & DF_1_STUB)
12301 printf (" STUB");
12302 val ^= DF_1_STUB;
12304 if (val & DF_1_PIE)
12306 printf (" PIE");
12307 val ^= DF_1_PIE;
12309 if (val & DF_1_KMOD)
12311 printf (" KMOD");
12312 val ^= DF_1_KMOD;
12314 if (val & DF_1_WEAKFILTER)
12316 printf (" WEAKFILTER");
12317 val ^= DF_1_WEAKFILTER;
12319 if (val & DF_1_NOCOMMON)
12321 printf (" NOCOMMON");
12322 val ^= DF_1_NOCOMMON;
12324 if (val != 0)
12325 printf (" %" PRIx64, val);
12326 puts ("");
12329 break;
12331 case DT_PLTREL:
12332 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12333 if (do_dynamic)
12334 puts (get_dynamic_type (filedata, entry->d_un.d_val));
12335 break;
12337 case DT_NULL :
12338 case DT_NEEDED :
12339 case DT_PLTGOT :
12340 case DT_HASH :
12341 case DT_STRTAB :
12342 case DT_SYMTAB :
12343 case DT_RELA :
12344 case DT_INIT :
12345 case DT_FINI :
12346 case DT_SONAME :
12347 case DT_RPATH :
12348 case DT_SYMBOLIC:
12349 case DT_REL :
12350 case DT_RELR :
12351 case DT_DEBUG :
12352 case DT_TEXTREL :
12353 case DT_JMPREL :
12354 case DT_RUNPATH :
12355 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12357 if (do_dynamic)
12359 const char *name;
12361 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12362 name = get_dynamic_name (filedata, entry->d_un.d_val);
12363 else
12364 name = NULL;
12366 if (name)
12368 switch (entry->d_tag)
12370 case DT_NEEDED:
12371 printf (_("Shared library: [%s]"), name);
12373 if (filedata->program_interpreter
12374 && streq (name, filedata->program_interpreter))
12375 printf (_(" program interpreter"));
12376 break;
12378 case DT_SONAME:
12379 printf (_("Library soname: [%s]"), name);
12380 break;
12382 case DT_RPATH:
12383 printf (_("Library rpath: [%s]"), name);
12384 break;
12386 case DT_RUNPATH:
12387 printf (_("Library runpath: [%s]"), name);
12388 break;
12390 default:
12391 print_vma (entry->d_un.d_val, PREFIX_HEX);
12392 break;
12395 else
12396 print_vma (entry->d_un.d_val, PREFIX_HEX);
12398 putchar ('\n');
12400 break;
12402 case DT_PLTRELSZ:
12403 case DT_RELASZ :
12404 case DT_STRSZ :
12405 case DT_RELSZ :
12406 case DT_RELAENT :
12407 case DT_RELRENT :
12408 case DT_RELRSZ :
12409 case DT_SYMENT :
12410 case DT_RELENT :
12411 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
12412 /* Fall through. */
12413 case DT_PLTPADSZ:
12414 case DT_MOVEENT :
12415 case DT_MOVESZ :
12416 case DT_PREINIT_ARRAYSZ:
12417 case DT_INIT_ARRAYSZ:
12418 case DT_FINI_ARRAYSZ:
12419 case DT_GNU_CONFLICTSZ:
12420 case DT_GNU_LIBLISTSZ:
12421 if (do_dynamic)
12423 print_vma (entry->d_un.d_val, UNSIGNED);
12424 printf (_(" (bytes)\n"));
12426 break;
12428 case DT_VERDEFNUM:
12429 case DT_VERNEEDNUM:
12430 case DT_RELACOUNT:
12431 case DT_RELCOUNT:
12432 if (do_dynamic)
12434 print_vma (entry->d_un.d_val, UNSIGNED);
12435 putchar ('\n');
12437 break;
12439 case DT_SYMINSZ:
12440 case DT_SYMINENT:
12441 case DT_SYMINFO:
12442 case DT_USED:
12443 case DT_INIT_ARRAY:
12444 case DT_FINI_ARRAY:
12445 if (do_dynamic)
12447 if (entry->d_tag == DT_USED
12448 && valid_dynamic_name (filedata, entry->d_un.d_val))
12450 const char *name
12451 = get_dynamic_name (filedata, entry->d_un.d_val);
12453 if (*name)
12455 printf (_("Not needed object: [%s]\n"), name);
12456 break;
12460 print_vma (entry->d_un.d_val, PREFIX_HEX);
12461 putchar ('\n');
12463 break;
12465 case DT_BIND_NOW:
12466 /* The value of this entry is ignored. */
12467 if (do_dynamic)
12468 putchar ('\n');
12469 break;
12471 case DT_GNU_PRELINKED:
12472 if (do_dynamic)
12474 struct tm * tmp;
12475 time_t atime = entry->d_un.d_val;
12477 tmp = gmtime (&atime);
12478 /* PR 17533 file: 041-1244816-0.004. */
12479 if (tmp == NULL)
12480 printf (_("<corrupt time val: %" PRIx64),
12481 (uint64_t) atime);
12482 else
12483 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12484 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12485 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
12488 break;
12490 case DT_GNU_HASH:
12491 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
12492 if (do_dynamic)
12494 print_vma (entry->d_un.d_val, PREFIX_HEX);
12495 putchar ('\n');
12497 break;
12499 case DT_GNU_FLAGS_1:
12500 if (do_dynamic)
12502 printf (_("Flags:"));
12503 if (entry->d_un.d_val == 0)
12504 printf (_(" None\n"));
12505 else
12507 uint64_t val = entry->d_un.d_val;
12509 if (val & DF_GNU_1_UNIQUE)
12511 printf (" UNIQUE");
12512 val ^= DF_GNU_1_UNIQUE;
12514 if (val != 0)
12515 printf (" %" PRIx64, val);
12516 puts ("");
12519 break;
12521 default:
12522 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
12523 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12524 = entry->d_un.d_val;
12526 if (do_dynamic)
12528 switch (filedata->file_header.e_machine)
12530 case EM_AARCH64:
12531 dynamic_section_aarch64_val (entry);
12532 break;
12533 case EM_MIPS:
12534 case EM_MIPS_RS3_LE:
12535 dynamic_section_mips_val (filedata, entry);
12536 break;
12537 case EM_PARISC:
12538 dynamic_section_parisc_val (entry);
12539 break;
12540 case EM_IA_64:
12541 dynamic_section_ia64_val (entry);
12542 break;
12543 default:
12544 print_vma (entry->d_un.d_val, PREFIX_HEX);
12545 putchar ('\n');
12548 break;
12552 return true;
12555 static char *
12556 get_ver_flags (unsigned int flags)
12558 static char buff[128];
12560 buff[0] = 0;
12562 if (flags == 0)
12563 return _("none");
12565 if (flags & VER_FLG_BASE)
12566 strcat (buff, "BASE");
12568 if (flags & VER_FLG_WEAK)
12570 if (flags & VER_FLG_BASE)
12571 strcat (buff, " | ");
12573 strcat (buff, "WEAK");
12576 if (flags & VER_FLG_INFO)
12578 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
12579 strcat (buff, " | ");
12581 strcat (buff, "INFO");
12584 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12586 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12587 strcat (buff, " | ");
12589 strcat (buff, _("<unknown>"));
12592 return buff;
12595 /* Display the contents of the version sections. */
12597 static bool
12598 process_version_sections (Filedata * filedata)
12600 Elf_Internal_Shdr * section;
12601 unsigned i;
12602 bool found = false;
12604 if (! do_version)
12605 return true;
12607 for (i = 0, section = filedata->section_headers;
12608 i < filedata->file_header.e_shnum;
12609 i++, section++)
12611 switch (section->sh_type)
12613 case SHT_GNU_verdef:
12615 Elf_External_Verdef * edefs;
12616 size_t idx;
12617 size_t cnt;
12618 char * endbuf;
12620 found = true;
12622 if (filedata->is_separate)
12623 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12624 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12625 section->sh_info),
12626 filedata->file_name,
12627 printable_section_name (filedata, section),
12628 section->sh_info);
12629 else
12630 printf (ngettext ("\nVersion definition section '%s' "
12631 "contains %u entry:\n",
12632 "\nVersion definition section '%s' "
12633 "contains %u entries:\n",
12634 section->sh_info),
12635 printable_section_name (filedata, section),
12636 section->sh_info);
12638 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
12639 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12640 section->sh_offset, section->sh_link,
12641 printable_section_name_from_index (filedata, section->sh_link, NULL));
12643 edefs = (Elf_External_Verdef *)
12644 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
12645 _("version definition section"));
12646 if (!edefs)
12647 break;
12648 endbuf = (char *) edefs + section->sh_size;
12650 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12652 char * vstart;
12653 Elf_External_Verdef * edef;
12654 Elf_Internal_Verdef ent;
12655 Elf_External_Verdaux * eaux;
12656 Elf_Internal_Verdaux aux;
12657 size_t isum;
12658 int j;
12660 vstart = ((char *) edefs) + idx;
12661 if (vstart + sizeof (*edef) > endbuf)
12662 break;
12664 edef = (Elf_External_Verdef *) vstart;
12666 ent.vd_version = BYTE_GET (edef->vd_version);
12667 ent.vd_flags = BYTE_GET (edef->vd_flags);
12668 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12669 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12670 ent.vd_hash = BYTE_GET (edef->vd_hash);
12671 ent.vd_aux = BYTE_GET (edef->vd_aux);
12672 ent.vd_next = BYTE_GET (edef->vd_next);
12674 printf (_(" %#06zx: Rev: %d Flags: %s"),
12675 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12677 printf (_(" Index: %d Cnt: %d "),
12678 ent.vd_ndx, ent.vd_cnt);
12680 /* Check for overflow. */
12681 if (ent.vd_aux > (size_t) (endbuf - vstart))
12682 break;
12684 vstart += ent.vd_aux;
12686 if (vstart + sizeof (*eaux) > endbuf)
12687 break;
12688 eaux = (Elf_External_Verdaux *) vstart;
12690 aux.vda_name = BYTE_GET (eaux->vda_name);
12691 aux.vda_next = BYTE_GET (eaux->vda_next);
12693 if (valid_dynamic_name (filedata, aux.vda_name))
12694 printf (_("Name: %s\n"),
12695 get_dynamic_name (filedata, aux.vda_name));
12696 else
12697 printf (_("Name index: %ld\n"), aux.vda_name);
12699 isum = idx + ent.vd_aux;
12701 for (j = 1; j < ent.vd_cnt; j++)
12703 if (aux.vda_next < sizeof (*eaux)
12704 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12706 warn (_("Invalid vda_next field of %lx\n"),
12707 aux.vda_next);
12708 j = ent.vd_cnt;
12709 break;
12711 /* Check for overflow. */
12712 if (aux.vda_next > (size_t) (endbuf - vstart))
12713 break;
12715 isum += aux.vda_next;
12716 vstart += aux.vda_next;
12718 if (vstart + sizeof (*eaux) > endbuf)
12719 break;
12720 eaux = (Elf_External_Verdaux *) vstart;
12722 aux.vda_name = BYTE_GET (eaux->vda_name);
12723 aux.vda_next = BYTE_GET (eaux->vda_next);
12725 if (valid_dynamic_name (filedata, aux.vda_name))
12726 printf (_(" %#06zx: Parent %d: %s\n"),
12727 isum, j,
12728 get_dynamic_name (filedata, aux.vda_name));
12729 else
12730 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
12731 isum, j, aux.vda_name);
12734 if (j < ent.vd_cnt)
12735 printf (_(" Version def aux past end of section\n"));
12737 /* PR 17531:
12738 file: id:000001,src:000172+005151,op:splice,rep:2. */
12739 if (ent.vd_next < sizeof (*edef)
12740 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12742 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12743 cnt = section->sh_info;
12744 break;
12746 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
12747 break;
12749 idx += ent.vd_next;
12752 if (cnt < section->sh_info)
12753 printf (_(" Version definition past end of section\n"));
12755 free (edefs);
12757 break;
12759 case SHT_GNU_verneed:
12761 Elf_External_Verneed * eneed;
12762 size_t idx;
12763 size_t cnt;
12764 char * endbuf;
12766 found = true;
12768 if (filedata->is_separate)
12769 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12770 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12771 section->sh_info),
12772 filedata->file_name,
12773 printable_section_name (filedata, section),
12774 section->sh_info);
12775 else
12776 printf (ngettext ("\nVersion needs section '%s' "
12777 "contains %u entry:\n",
12778 "\nVersion needs section '%s' "
12779 "contains %u entries:\n",
12780 section->sh_info),
12781 printable_section_name (filedata, section),
12782 section->sh_info);
12784 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
12785 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12786 section->sh_offset, section->sh_link,
12787 printable_section_name_from_index (filedata, section->sh_link, NULL));
12789 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
12790 section->sh_offset, 1,
12791 section->sh_size,
12792 _("Version Needs section"));
12793 if (!eneed)
12794 break;
12795 endbuf = (char *) eneed + section->sh_size;
12797 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12799 Elf_External_Verneed * entry;
12800 Elf_Internal_Verneed ent;
12801 size_t isum;
12802 int j;
12803 char * vstart;
12805 vstart = ((char *) eneed) + idx;
12806 if (vstart + sizeof (*entry) > endbuf)
12807 break;
12809 entry = (Elf_External_Verneed *) vstart;
12811 ent.vn_version = BYTE_GET (entry->vn_version);
12812 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12813 ent.vn_file = BYTE_GET (entry->vn_file);
12814 ent.vn_aux = BYTE_GET (entry->vn_aux);
12815 ent.vn_next = BYTE_GET (entry->vn_next);
12817 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
12819 if (valid_dynamic_name (filedata, ent.vn_file))
12820 printf (_(" File: %s"),
12821 get_dynamic_name (filedata, ent.vn_file));
12822 else
12823 printf (_(" File: %lx"), ent.vn_file);
12825 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12827 /* Check for overflow. */
12828 if (ent.vn_aux > (size_t) (endbuf - vstart))
12829 break;
12830 vstart += ent.vn_aux;
12832 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12834 Elf_External_Vernaux * eaux;
12835 Elf_Internal_Vernaux aux;
12837 if (vstart + sizeof (*eaux) > endbuf)
12838 break;
12839 eaux = (Elf_External_Vernaux *) vstart;
12841 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12842 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12843 aux.vna_other = BYTE_GET (eaux->vna_other);
12844 aux.vna_name = BYTE_GET (eaux->vna_name);
12845 aux.vna_next = BYTE_GET (eaux->vna_next);
12847 if (valid_dynamic_name (filedata, aux.vna_name))
12848 printf (_(" %#06zx: Name: %s"),
12849 isum, get_dynamic_name (filedata, aux.vna_name));
12850 else
12851 printf (_(" %#06zx: Name index: %lx"),
12852 isum, aux.vna_name);
12854 printf (_(" Flags: %s Version: %d\n"),
12855 get_ver_flags (aux.vna_flags), aux.vna_other);
12857 if (aux.vna_next < sizeof (*eaux)
12858 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
12860 warn (_("Invalid vna_next field of %lx\n"),
12861 aux.vna_next);
12862 j = ent.vn_cnt;
12863 break;
12865 /* Check for overflow. */
12866 if (aux.vna_next > (size_t) (endbuf - vstart))
12867 break;
12868 isum += aux.vna_next;
12869 vstart += aux.vna_next;
12872 if (j < ent.vn_cnt)
12873 warn (_("Missing Version Needs auxiliary information\n"));
12875 if (ent.vn_next < sizeof (*entry)
12876 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
12878 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
12879 cnt = section->sh_info;
12880 break;
12882 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12883 break;
12884 idx += ent.vn_next;
12887 if (cnt < section->sh_info)
12888 warn (_("Missing Version Needs information\n"));
12890 free (eneed);
12892 break;
12894 case SHT_GNU_versym:
12896 Elf_Internal_Shdr * link_section;
12897 uint64_t total;
12898 unsigned int cnt;
12899 unsigned char * edata;
12900 unsigned short * data;
12901 char * strtab;
12902 Elf_Internal_Sym * symbols;
12903 Elf_Internal_Shdr * string_sec;
12904 uint64_t num_syms;
12905 uint64_t off;
12907 if (section->sh_link >= filedata->file_header.e_shnum)
12908 break;
12910 link_section = filedata->section_headers + section->sh_link;
12911 total = section->sh_size / sizeof (Elf_External_Versym);
12913 if (link_section->sh_link >= filedata->file_header.e_shnum)
12914 break;
12916 found = true;
12918 symbols = get_elf_symbols (filedata, link_section, & num_syms);
12919 if (symbols == NULL)
12920 break;
12922 string_sec = filedata->section_headers + link_section->sh_link;
12924 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
12925 string_sec->sh_size,
12926 _("version string table"));
12927 if (!strtab)
12929 free (symbols);
12930 break;
12933 if (filedata->is_separate)
12934 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12935 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
12936 total),
12937 filedata->file_name,
12938 printable_section_name (filedata, section),
12939 total);
12940 else
12941 printf (ngettext ("\nVersion symbols section '%s' "
12942 "contains %" PRIu64 " entry:\n",
12943 "\nVersion symbols section '%s' "
12944 "contains %" PRIu64 " entries:\n",
12945 total),
12946 printable_section_name (filedata, section),
12947 total);
12949 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
12950 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12951 section->sh_offset, section->sh_link,
12952 printable_section_name (filedata, link_section));
12954 off = offset_from_vma (filedata,
12955 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
12956 total * sizeof (short));
12957 edata = (unsigned char *) get_data (NULL, filedata, off,
12958 sizeof (short), total,
12959 _("version symbol data"));
12960 if (!edata)
12962 free (strtab);
12963 free (symbols);
12964 break;
12967 data = (short unsigned int *) cmalloc (total, sizeof (short));
12969 for (cnt = total; cnt --;)
12970 data[cnt] = byte_get (edata + cnt * sizeof (short),
12971 sizeof (short));
12973 free (edata);
12975 for (cnt = 0; cnt < total; cnt += 4)
12977 int j, nn;
12978 char *name;
12979 char *invalid = _("*invalid*");
12981 printf (" %03x:", cnt);
12983 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
12984 switch (data[cnt + j])
12986 case 0:
12987 fputs (_(" 0 (*local*) "), stdout);
12988 break;
12990 case 1:
12991 fputs (_(" 1 (*global*) "), stdout);
12992 break;
12994 default:
12995 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12996 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
12998 /* If this index value is greater than the size of the symbols
12999 array, break to avoid an out-of-bounds read. */
13000 if (cnt + j >= num_syms)
13002 warn (_("invalid index into symbol array\n"));
13003 break;
13006 name = NULL;
13007 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
13009 Elf_Internal_Verneed ivn;
13010 uint64_t offset;
13012 offset = offset_from_vma
13013 (filedata,
13014 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
13015 sizeof (Elf_External_Verneed));
13019 Elf_Internal_Vernaux ivna;
13020 Elf_External_Verneed evn;
13021 Elf_External_Vernaux evna;
13022 uint64_t a_off;
13024 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
13025 _("version need")) == NULL)
13026 break;
13028 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13029 ivn.vn_next = BYTE_GET (evn.vn_next);
13031 a_off = offset + ivn.vn_aux;
13035 if (get_data (&evna, filedata, a_off, sizeof (evna),
13036 1, _("version need aux (2)")) == NULL)
13038 ivna.vna_next = 0;
13039 ivna.vna_other = 0;
13041 else
13043 ivna.vna_next = BYTE_GET (evna.vna_next);
13044 ivna.vna_other = BYTE_GET (evna.vna_other);
13047 a_off += ivna.vna_next;
13049 while (ivna.vna_other != data[cnt + j]
13050 && ivna.vna_next != 0);
13052 if (ivna.vna_other == data[cnt + j])
13054 ivna.vna_name = BYTE_GET (evna.vna_name);
13056 if (ivna.vna_name >= string_sec->sh_size)
13057 name = invalid;
13058 else
13059 name = strtab + ivna.vna_name;
13060 break;
13063 offset += ivn.vn_next;
13065 while (ivn.vn_next);
13068 if (data[cnt + j] != 0x8001
13069 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
13071 Elf_Internal_Verdef ivd;
13072 Elf_External_Verdef evd;
13073 uint64_t offset;
13075 offset = offset_from_vma
13076 (filedata,
13077 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
13078 sizeof evd);
13082 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
13083 _("version def")) == NULL)
13085 ivd.vd_next = 0;
13086 /* PR 17531: file: 046-1082287-0.004. */
13087 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13088 break;
13090 else
13092 ivd.vd_next = BYTE_GET (evd.vd_next);
13093 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13096 offset += ivd.vd_next;
13098 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
13099 && ivd.vd_next != 0);
13101 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
13103 Elf_External_Verdaux evda;
13104 Elf_Internal_Verdaux ivda;
13106 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13108 if (get_data (&evda, filedata,
13109 offset - ivd.vd_next + ivd.vd_aux,
13110 sizeof (evda), 1,
13111 _("version def aux")) == NULL)
13112 break;
13114 ivda.vda_name = BYTE_GET (evda.vda_name);
13116 if (ivda.vda_name >= string_sec->sh_size)
13117 name = invalid;
13118 else if (name != NULL && name != invalid)
13119 name = _("*both*");
13120 else
13121 name = strtab + ivda.vda_name;
13124 if (name != NULL)
13125 nn += printf ("(%s%-*s",
13126 name,
13127 12 - (int) strlen (name),
13128 ")");
13130 if (nn < 18)
13131 printf ("%*c", 18 - nn, ' ');
13134 putchar ('\n');
13137 free (data);
13138 free (strtab);
13139 free (symbols);
13141 break;
13143 default:
13144 break;
13148 if (! found)
13150 if (filedata->is_separate)
13151 printf (_("\nNo version information found in linked file '%s'.\n"),
13152 filedata->file_name);
13153 else
13154 printf (_("\nNo version information found in this file.\n"));
13157 return true;
13160 static const char *
13161 get_symbol_binding (Filedata * filedata, unsigned int binding)
13163 static char buff[64];
13165 switch (binding)
13167 case STB_LOCAL: return "LOCAL";
13168 case STB_GLOBAL: return "GLOBAL";
13169 case STB_WEAK: return "WEAK";
13170 default:
13171 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
13172 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13173 binding);
13174 else if (binding >= STB_LOOS && binding <= STB_HIOS)
13176 if (binding == STB_GNU_UNIQUE
13177 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
13178 return "UNIQUE";
13179 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13181 else
13182 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
13183 return buff;
13187 static const char *
13188 get_symbol_type (Filedata * filedata, unsigned int type)
13190 static char buff[64];
13192 switch (type)
13194 case STT_NOTYPE: return "NOTYPE";
13195 case STT_OBJECT: return "OBJECT";
13196 case STT_FUNC: return "FUNC";
13197 case STT_SECTION: return "SECTION";
13198 case STT_FILE: return "FILE";
13199 case STT_COMMON: return "COMMON";
13200 case STT_TLS: return "TLS";
13201 case STT_RELC: return "RELC";
13202 case STT_SRELC: return "SRELC";
13203 default:
13204 if (type >= STT_LOPROC && type <= STT_HIPROC)
13206 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
13207 return "THUMB_FUNC";
13209 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
13210 return "REGISTER";
13212 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
13213 return "PARISC_MILLI";
13215 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
13217 else if (type >= STT_LOOS && type <= STT_HIOS)
13219 if (filedata->file_header.e_machine == EM_PARISC)
13221 if (type == STT_HP_OPAQUE)
13222 return "HP_OPAQUE";
13223 if (type == STT_HP_STUB)
13224 return "HP_STUB";
13227 if (type == STT_GNU_IFUNC
13228 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13229 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13230 return "IFUNC";
13232 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
13234 else
13235 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
13236 return buff;
13240 static const char *
13241 get_symbol_visibility (unsigned int visibility)
13243 switch (visibility)
13245 case STV_DEFAULT: return "DEFAULT";
13246 case STV_INTERNAL: return "INTERNAL";
13247 case STV_HIDDEN: return "HIDDEN";
13248 case STV_PROTECTED: return "PROTECTED";
13249 default:
13250 error (_("Unrecognized visibility value: %u\n"), visibility);
13251 return _("<unknown>");
13255 static const char *
13256 get_alpha_symbol_other (unsigned int other)
13258 switch (other)
13260 case STO_ALPHA_NOPV: return "NOPV";
13261 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13262 default:
13263 error (_("Unrecognized alpha specific other value: %u\n"), other);
13264 return _("<unknown>");
13268 static const char *
13269 get_solaris_symbol_visibility (unsigned int visibility)
13271 switch (visibility)
13273 case 4: return "EXPORTED";
13274 case 5: return "SINGLETON";
13275 case 6: return "ELIMINATE";
13276 default: return get_symbol_visibility (visibility);
13280 static const char *
13281 get_aarch64_symbol_other (unsigned int other)
13283 static char buf[32];
13285 if (other & STO_AARCH64_VARIANT_PCS)
13287 other &= ~STO_AARCH64_VARIANT_PCS;
13288 if (other == 0)
13289 return "VARIANT_PCS";
13290 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13291 return buf;
13293 return NULL;
13296 static const char *
13297 get_mips_symbol_other (unsigned int other)
13299 switch (other)
13301 case STO_OPTIONAL: return "OPTIONAL";
13302 case STO_MIPS_PLT: return "MIPS PLT";
13303 case STO_MIPS_PIC: return "MIPS PIC";
13304 case STO_MICROMIPS: return "MICROMIPS";
13305 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13306 case STO_MIPS16: return "MIPS16";
13307 default: return NULL;
13311 static const char *
13312 get_ia64_symbol_other (Filedata * filedata, unsigned int other)
13314 if (is_ia64_vms (filedata))
13316 static char res[32];
13318 res[0] = 0;
13320 /* Function types is for images and .STB files only. */
13321 switch (filedata->file_header.e_type)
13323 case ET_DYN:
13324 case ET_EXEC:
13325 switch (VMS_ST_FUNC_TYPE (other))
13327 case VMS_SFT_CODE_ADDR:
13328 strcat (res, " CA");
13329 break;
13330 case VMS_SFT_SYMV_IDX:
13331 strcat (res, " VEC");
13332 break;
13333 case VMS_SFT_FD:
13334 strcat (res, " FD");
13335 break;
13336 case VMS_SFT_RESERVE:
13337 strcat (res, " RSV");
13338 break;
13339 default:
13340 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13341 VMS_ST_FUNC_TYPE (other));
13342 strcat (res, " <unknown>");
13343 break;
13345 break;
13346 default:
13347 break;
13349 switch (VMS_ST_LINKAGE (other))
13351 case VMS_STL_IGNORE:
13352 strcat (res, " IGN");
13353 break;
13354 case VMS_STL_RESERVE:
13355 strcat (res, " RSV");
13356 break;
13357 case VMS_STL_STD:
13358 strcat (res, " STD");
13359 break;
13360 case VMS_STL_LNK:
13361 strcat (res, " LNK");
13362 break;
13363 default:
13364 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13365 VMS_ST_LINKAGE (other));
13366 strcat (res, " <unknown>");
13367 break;
13370 if (res[0] != 0)
13371 return res + 1;
13372 else
13373 return res;
13375 return NULL;
13378 static const char *
13379 get_ppc64_symbol_other (unsigned int other)
13381 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13382 return NULL;
13384 other >>= STO_PPC64_LOCAL_BIT;
13385 if (other <= 6)
13387 static char buf[64];
13388 if (other >= 2)
13389 other = ppc64_decode_local_entry (other);
13390 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
13391 return buf;
13393 return NULL;
13396 static const char *
13397 get_riscv_symbol_other (unsigned int other)
13399 static char buf[32];
13400 buf[0] = 0;
13402 if (other & STO_RISCV_VARIANT_CC)
13404 strcat (buf, _(" VARIANT_CC"));
13405 other &= ~STO_RISCV_VARIANT_CC;
13408 if (other != 0)
13409 snprintf (buf, sizeof buf, " %x", other);
13412 if (buf[0] != 0)
13413 return buf + 1;
13414 else
13415 return buf;
13418 static const char *
13419 get_symbol_other (Filedata * filedata, unsigned int other)
13421 const char * result = NULL;
13422 static char buff [64];
13424 if (other == 0)
13425 return "";
13427 switch (filedata->file_header.e_machine)
13429 case EM_ALPHA:
13430 result = get_alpha_symbol_other (other);
13431 break;
13432 case EM_AARCH64:
13433 result = get_aarch64_symbol_other (other);
13434 break;
13435 case EM_MIPS:
13436 result = get_mips_symbol_other (other);
13437 break;
13438 case EM_IA_64:
13439 result = get_ia64_symbol_other (filedata, other);
13440 break;
13441 case EM_PPC64:
13442 result = get_ppc64_symbol_other (other);
13443 break;
13444 case EM_RISCV:
13445 result = get_riscv_symbol_other (other);
13446 break;
13447 default:
13448 result = NULL;
13449 break;
13452 if (result)
13453 return result;
13455 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13456 return buff;
13459 static const char *
13460 get_symbol_version_string (Filedata *filedata,
13461 bool is_dynsym,
13462 const char *strtab,
13463 size_t strtab_size,
13464 unsigned int si,
13465 Elf_Internal_Sym *psym,
13466 enum versioned_symbol_info *sym_info,
13467 unsigned short *vna_other)
13469 unsigned char data[2];
13470 unsigned short vers_data;
13471 uint64_t offset;
13472 unsigned short max_vd_ndx;
13474 if (!is_dynsym
13475 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
13476 return NULL;
13478 offset = offset_from_vma (filedata,
13479 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
13480 sizeof data + si * sizeof (vers_data));
13482 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
13483 sizeof (data), 1, _("version data")) == NULL)
13484 return NULL;
13486 vers_data = byte_get (data, 2);
13488 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
13489 return NULL;
13491 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
13492 max_vd_ndx = 0;
13494 /* Usually we'd only see verdef for defined symbols, and verneed for
13495 undefined symbols. However, symbols defined by the linker in
13496 .dynbss for variables copied from a shared library in order to
13497 avoid text relocations are defined yet have verneed. We could
13498 use a heuristic to detect the special case, for example, check
13499 for verneed first on symbols defined in SHT_NOBITS sections, but
13500 it is simpler and more reliable to just look for both verdef and
13501 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
13503 if (psym->st_shndx != SHN_UNDEF
13504 && vers_data != 0x8001
13505 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
13507 Elf_Internal_Verdef ivd;
13508 Elf_Internal_Verdaux ivda;
13509 Elf_External_Verdaux evda;
13510 uint64_t off;
13512 off = offset_from_vma (filedata,
13513 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
13514 sizeof (Elf_External_Verdef));
13518 Elf_External_Verdef evd;
13520 if (get_data (&evd, filedata, off, sizeof (evd), 1,
13521 _("version def")) == NULL)
13523 ivd.vd_ndx = 0;
13524 ivd.vd_aux = 0;
13525 ivd.vd_next = 0;
13526 ivd.vd_flags = 0;
13528 else
13530 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13531 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13532 ivd.vd_next = BYTE_GET (evd.vd_next);
13533 ivd.vd_flags = BYTE_GET (evd.vd_flags);
13536 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13537 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13539 off += ivd.vd_next;
13541 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
13543 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13545 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
13546 return NULL;
13548 off -= ivd.vd_next;
13549 off += ivd.vd_aux;
13551 if (get_data (&evda, filedata, off, sizeof (evda), 1,
13552 _("version def aux")) != NULL)
13554 ivda.vda_name = BYTE_GET (evda.vda_name);
13556 if (psym->st_name != ivda.vda_name)
13557 return (ivda.vda_name < strtab_size
13558 ? strtab + ivda.vda_name : _("<corrupt>"));
13563 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
13565 Elf_External_Verneed evn;
13566 Elf_Internal_Verneed ivn;
13567 Elf_Internal_Vernaux ivna;
13569 offset = offset_from_vma (filedata,
13570 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
13571 sizeof evn);
13574 uint64_t vna_off;
13576 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
13577 _("version need")) == NULL)
13579 ivna.vna_next = 0;
13580 ivna.vna_other = 0;
13581 ivna.vna_name = 0;
13582 break;
13585 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13586 ivn.vn_next = BYTE_GET (evn.vn_next);
13588 vna_off = offset + ivn.vn_aux;
13592 Elf_External_Vernaux evna;
13594 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
13595 _("version need aux (3)")) == NULL)
13597 ivna.vna_next = 0;
13598 ivna.vna_other = 0;
13599 ivna.vna_name = 0;
13601 else
13603 ivna.vna_other = BYTE_GET (evna.vna_other);
13604 ivna.vna_next = BYTE_GET (evna.vna_next);
13605 ivna.vna_name = BYTE_GET (evna.vna_name);
13608 vna_off += ivna.vna_next;
13610 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
13612 if (ivna.vna_other == vers_data)
13613 break;
13615 offset += ivn.vn_next;
13617 while (ivn.vn_next != 0);
13619 if (ivna.vna_other == vers_data)
13621 *sym_info = symbol_undefined;
13622 *vna_other = ivna.vna_other;
13623 return (ivna.vna_name < strtab_size
13624 ? strtab + ivna.vna_name : _("<corrupt>"));
13626 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13627 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13628 return _("<corrupt>");
13630 return NULL;
13633 /* Display a symbol size on stdout. Format is based on --sym-base setting. */
13635 static unsigned int
13636 print_symbol_size (uint64_t vma, int base)
13638 switch (base)
13640 case 8:
13641 return print_vma (vma, OCTAL_5);
13643 case 10:
13644 return print_vma (vma, UNSIGNED_5);
13646 case 16:
13647 return print_vma (vma, PREFIX_HEX_5);
13649 case 0:
13650 default:
13651 return print_vma (vma, DEC_5);
13655 /* Print information on a single symbol. */
13657 static void
13658 print_symbol (Filedata * filedata,
13659 uint64_t symbol_index,
13660 Elf_Internal_Sym * symtab,
13661 Elf_Internal_Shdr * section,
13662 char * strtab,
13663 size_t strtab_size)
13665 const char *version_string;
13666 enum versioned_symbol_info sym_info;
13667 unsigned short vna_other;
13668 const char * sstr;
13669 Elf_Internal_Sym *psym = symtab + symbol_index;
13671 /* FIXME: We should have a table of field widths,
13672 rather than using hard coded constants. */
13673 printf ("%6" PRId64 ": ", symbol_index);
13674 print_vma (psym->st_value, LONG_HEX);
13675 putchar (' ');
13676 print_symbol_size (psym->st_size, sym_base);
13677 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13678 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13679 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13680 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13681 else
13683 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
13685 printf (" %-7s", get_symbol_visibility (vis));
13687 /* Check to see if any other bits in the st_other field are set.
13688 FIXME: Displaying this information here disrupts the layout
13689 of the table being generated. */
13690 if (psym->st_other ^ vis)
13691 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
13694 bool is_special;
13696 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
13698 /* Print the symbol's section index. If the index is special
13699 then print the index's name rather than its number. */
13700 if (is_special)
13702 int printed;
13704 /* Special case: If there are no section headers, and the printable
13705 name is "<section 0x...." then just display the section number
13706 as a decimal. This happens when objcopy --strip -section-headers
13707 is used. */
13708 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
13709 printed = printf (" %4d ", psym->st_shndx);
13710 else
13711 printed = printf (" %4s ", sstr);
13713 if (extra_sym_info && printed < 16)
13714 printf ("%*s", 16 - printed, "");
13716 else
13718 printf (" %4u ", psym->st_shndx);
13720 if (extra_sym_info)
13722 /* Display the section name referenced by the section index. */
13723 int printed = printf ("(%s) ", sstr);
13724 if (printed < 10)
13725 printf ("%*s", 10 - printed, "");
13729 /* Get the symbol's name. For section symbols without a
13730 specific name use the (already computed) section name. */
13731 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13732 && section_index_real (filedata, psym->st_shndx)
13733 && psym->st_name == 0)
13737 else
13739 bool is_valid;
13741 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
13742 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13745 version_string
13746 = get_symbol_version_string (filedata,
13747 (section == NULL
13748 || section->sh_type == SHT_DYNSYM),
13749 strtab, strtab_size, symbol_index,
13750 psym, &sym_info, &vna_other);
13752 int len_avail = 21;
13753 if (! do_wide && version_string != NULL)
13755 char buffer[16];
13757 len_avail -= 1 + strlen (version_string);
13759 if (sym_info == symbol_undefined)
13760 len_avail -= sprintf (buffer," (%d)", vna_other);
13761 else if (sym_info != symbol_hidden)
13762 len_avail -= 1;
13765 print_symbol_name (len_avail, sstr);
13767 if (version_string)
13769 if (sym_info == symbol_undefined)
13770 printf ("@%s (%d)", version_string, vna_other);
13771 else
13772 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13773 version_string);
13776 putchar ('\n');
13778 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13779 && section != NULL
13780 && symbol_index >= section->sh_info
13781 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13782 && filedata->file_header.e_machine != EM_MIPS
13783 /* Solaris binaries have been found to violate this requirement as
13784 well. Not sure if this is a bug or an ABI requirement. */
13785 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13786 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
13787 symbol_index, printable_section_name (filedata, section), section->sh_info);
13790 static const char *
13791 get_lto_kind (unsigned int kind)
13793 switch (kind)
13795 case 0: return "DEF";
13796 case 1: return "WEAKDEF";
13797 case 2: return "UNDEF";
13798 case 3: return "WEAKUNDEF";
13799 case 4: return "COMMON";
13800 default:
13801 break;
13804 static char buffer[30];
13805 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13806 sprintf (buffer, "<unknown: %u>", kind);
13807 return buffer;
13810 static const char *
13811 get_lto_visibility (unsigned int visibility)
13813 switch (visibility)
13815 case 0: return "DEFAULT";
13816 case 1: return "PROTECTED";
13817 case 2: return "INTERNAL";
13818 case 3: return "HIDDEN";
13819 default:
13820 break;
13823 static char buffer[30];
13824 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13825 sprintf (buffer, "<unknown: %u>", visibility);
13826 return buffer;
13829 static const char *
13830 get_lto_sym_type (unsigned int sym_type)
13832 switch (sym_type)
13834 case 0: return "UNKNOWN";
13835 case 1: return "FUNCTION";
13836 case 2: return "VARIABLE";
13837 default:
13838 break;
13841 static char buffer[30];
13842 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13843 sprintf (buffer, "<unknown: %u>", sym_type);
13844 return buffer;
13847 /* Display an LTO format symbol table.
13848 FIXME: The format of LTO symbol tables is not formalized.
13849 So this code could need changing in the future. */
13851 static bool
13852 display_lto_symtab (Filedata * filedata,
13853 Elf_Internal_Shdr * section)
13855 if (section->sh_size == 0)
13857 if (filedata->is_separate)
13858 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13859 printable_section_name (filedata, section),
13860 filedata->file_name);
13861 else
13862 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13863 printable_section_name (filedata, section));
13865 return true;
13868 if (section->sh_size > filedata->file_size)
13870 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
13871 printable_section_name (filedata, section),
13872 section->sh_size);
13873 return false;
13876 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13877 section->sh_size, 1, _("LTO symbols"));
13878 if (alloced_data == NULL)
13879 return false;
13881 /* Look for extended data for the symbol table. */
13882 Elf_Internal_Shdr * ext = NULL;
13883 void * ext_data_orig = NULL;
13884 char * ext_data = NULL;
13885 char * ext_data_end = NULL;
13886 char * ext_name = NULL;
13888 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
13889 (section_name (filedata, section)
13890 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
13891 && ext_name != NULL /* Paranoia. */
13892 && (ext = find_section (filedata, ext_name)) != NULL)
13894 if (ext->sh_size < 3)
13895 error (_("LTO Symbol extension table '%s' is empty!\n"),
13896 printable_section_name (filedata, ext));
13897 else
13899 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13900 ext->sh_size, 1,
13901 _("LTO ext symbol data"));
13902 if (ext_data != NULL)
13904 ext_data_end = ext_data + ext->sh_size;
13905 if (* ext_data++ != 1)
13906 error (_("Unexpected version number in symbol extension table\n"));
13911 const unsigned char * data = (const unsigned char *) alloced_data;
13912 const unsigned char * end = data + section->sh_size;
13914 if (filedata->is_separate)
13915 printf (_("\nIn linked file '%s': "), filedata->file_name);
13916 else
13917 printf ("\n");
13919 if (ext_data_orig != NULL)
13921 if (do_wide)
13922 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
13923 printable_section_name (filedata, section),
13924 printable_section_name (filedata, ext));
13925 else
13927 printf (_("LTO Symbol table '%s'\n"),
13928 printable_section_name (filedata, section));
13929 printf (_(" and extension table '%s' contain:\n"),
13930 printable_section_name (filedata, ext));
13933 else
13934 printf (_("LTO Symbol table '%s' contains:\n"),
13935 printable_section_name (filedata, section));
13937 /* FIXME: Add a wide version. */
13938 if (ext_data_orig != NULL)
13939 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13940 else
13941 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13943 /* FIXME: We do not handle style prefixes. */
13945 while (data < end)
13947 const unsigned char * sym_name = data;
13948 data += strnlen ((const char *) sym_name, end - data) + 1;
13949 if (data >= end)
13950 goto fail;
13952 const unsigned char * comdat_key = data;
13953 data += strnlen ((const char *) comdat_key, end - data) + 1;
13954 if (data >= end)
13955 goto fail;
13957 if (data + 2 + 8 + 4 > end)
13958 goto fail;
13960 unsigned int kind = *data++;
13961 unsigned int visibility = *data++;
13963 uint64_t size = byte_get (data, 8);
13964 data += 8;
13966 uint64_t slot = byte_get (data, 4);
13967 data += 4;
13969 if (ext_data != NULL)
13971 if (ext_data < (ext_data_end - 1))
13973 unsigned int sym_type = * ext_data ++;
13974 unsigned int sec_kind = * ext_data ++;
13976 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
13977 * comdat_key == 0 ? "-" : (char *) comdat_key,
13978 get_lto_kind (kind),
13979 get_lto_visibility (visibility),
13980 size,
13981 slot,
13982 get_lto_sym_type (sym_type),
13983 sec_kind);
13984 print_symbol_name (6, (const char *) sym_name);
13986 else
13988 error (_("Ran out of LTO symbol extension data\n"));
13989 ext_data = NULL;
13990 /* FIXME: return FAIL result ? */
13993 else
13995 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
13996 * comdat_key == 0 ? "-" : (char *) comdat_key,
13997 get_lto_kind (kind),
13998 get_lto_visibility (visibility),
13999 size,
14000 slot);
14001 print_symbol_name (21, (const char *) sym_name);
14003 putchar ('\n');
14006 if (ext_data != NULL && ext_data < ext_data_end)
14008 error (_("Data remains in the LTO symbol extension table\n"));
14009 goto fail;
14012 free (alloced_data);
14013 free (ext_data_orig);
14014 free (ext_name);
14015 return true;
14017 fail:
14018 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14019 free (alloced_data);
14020 free (ext_data_orig);
14021 free (ext_name);
14022 return false;
14025 /* Display LTO symbol tables. */
14027 static bool
14028 process_lto_symbol_tables (Filedata * filedata)
14030 Elf_Internal_Shdr * section;
14031 unsigned int i;
14032 bool res = true;
14034 if (!do_lto_syms)
14035 return true;
14037 if (filedata->section_headers == NULL)
14038 return true;
14040 for (i = 0, section = filedata->section_headers;
14041 i < filedata->file_header.e_shnum;
14042 i++, section++)
14043 if (section_name_valid (filedata, section)
14044 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
14045 res &= display_lto_symtab (filedata, section);
14047 return res;
14050 static void
14051 print_symbol_table_heading (void)
14053 /* FIXME: We should store the size of each field in the display in a table and
14054 then use the values inside print_symbol(), instead of that function using
14055 hard coded constants. */
14056 if (is_32bit_elf)
14058 if (extra_sym_info)
14060 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14061 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14062 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14064 else if (do_wide)
14066 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14067 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14068 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14070 else
14072 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14073 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14074 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14077 else
14079 if (extra_sym_info)
14081 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14082 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14083 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14086 else if (do_wide)
14088 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14089 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14090 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14092 else
14094 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14095 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14096 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14101 /* Dump the symbol table. */
14103 static bool
14104 process_symbol_table (Filedata * filedata)
14106 Elf_Internal_Shdr * section;
14108 if (!do_syms && !do_dyn_syms && !do_histogram)
14109 return true;
14111 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
14112 && do_syms
14113 && do_using_dynamic
14114 && filedata->dynamic_strings != NULL
14115 && filedata->dynamic_symbols != NULL)
14117 uint64_t si;
14119 if (filedata->is_separate)
14121 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14122 " contains %" PRIu64 " entry:\n",
14123 "\nIn linked file '%s' the dynamic symbol table"
14124 " contains %" PRIu64 " entries:\n",
14125 filedata->num_dynamic_syms),
14126 filedata->file_name,
14127 filedata->num_dynamic_syms);
14129 else
14131 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14132 " entry:\n",
14133 "\nSymbol table for image contains %" PRIu64
14134 " entries:\n",
14135 filedata->num_dynamic_syms),
14136 filedata->num_dynamic_syms);
14139 print_symbol_table_heading ();
14141 for (si = 0; si < filedata->num_dynamic_syms; si++)
14142 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14143 filedata->dynamic_strings,
14144 filedata->dynamic_strings_length);
14146 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
14147 && filedata->section_headers != NULL)
14149 unsigned int i;
14151 for (i = 0, section = filedata->section_headers;
14152 i < filedata->file_header.e_shnum;
14153 i++, section++)
14155 char * strtab = NULL;
14156 uint64_t strtab_size = 0;
14157 Elf_Internal_Sym * symtab;
14158 uint64_t si, num_syms;
14160 if ((section->sh_type != SHT_SYMTAB
14161 && section->sh_type != SHT_DYNSYM)
14162 || (!do_syms
14163 && section->sh_type == SHT_SYMTAB))
14164 continue;
14166 if (section->sh_entsize == 0)
14168 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
14169 printable_section_name (filedata, section));
14170 continue;
14173 num_syms = section->sh_size / section->sh_entsize;
14175 if (filedata->is_separate)
14176 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14177 " contains %" PRIu64 " entry:\n",
14178 "\nIn linked file '%s' symbol section '%s'"
14179 " contains %" PRIu64 " entries:\n",
14180 num_syms),
14181 filedata->file_name,
14182 printable_section_name (filedata, section),
14183 num_syms);
14184 else
14185 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14186 " entry:\n",
14187 "\nSymbol table '%s' contains %" PRIu64
14188 " entries:\n",
14189 num_syms),
14190 printable_section_name (filedata, section),
14191 num_syms);
14193 print_symbol_table_heading ();
14195 symtab = get_elf_symbols (filedata, section, & num_syms);
14196 if (symtab == NULL)
14197 continue;
14199 if (section->sh_link == filedata->file_header.e_shstrndx)
14201 strtab = filedata->string_table;
14202 strtab_size = filedata->string_table_length;
14204 else if (section->sh_link < filedata->file_header.e_shnum)
14206 Elf_Internal_Shdr * string_sec;
14208 string_sec = filedata->section_headers + section->sh_link;
14210 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
14211 1, string_sec->sh_size,
14212 _("string table"));
14213 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
14216 for (si = 0; si < num_syms; si++)
14217 print_symbol (filedata, si, symtab, section,
14218 strtab, strtab_size);
14220 free (symtab);
14221 if (strtab != filedata->string_table)
14222 free (strtab);
14225 else if (do_syms)
14226 printf
14227 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14229 if (do_histogram && filedata->buckets != NULL)
14231 uint64_t *lengths;
14232 uint64_t *counts;
14233 uint64_t hn;
14234 uint64_t si;
14235 uint64_t maxlength = 0;
14236 uint64_t nzero_counts = 0;
14237 uint64_t nsyms = 0;
14238 char *visited;
14240 printf (ngettext ("\nHistogram for bucket list length "
14241 "(total of %" PRIu64 " bucket):\n",
14242 "\nHistogram for bucket list length "
14243 "(total of %" PRIu64 " buckets):\n",
14244 filedata->nbuckets),
14245 filedata->nbuckets);
14247 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
14248 if (lengths == NULL)
14250 error (_("Out of memory allocating space for histogram buckets\n"));
14251 goto err_out;
14253 visited = xcmalloc (filedata->nchains, 1);
14254 memset (visited, 0, filedata->nchains);
14256 printf (_(" Length Number %% of total Coverage\n"));
14257 for (hn = 0; hn < filedata->nbuckets; ++hn)
14259 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
14261 ++nsyms;
14262 if (maxlength < ++lengths[hn])
14263 ++maxlength;
14264 if (si >= filedata->nchains || visited[si])
14266 error (_("histogram chain is corrupt\n"));
14267 break;
14269 visited[si] = 1;
14272 free (visited);
14274 counts = calloc (maxlength + 1, sizeof (*counts));
14275 if (counts == NULL)
14277 free (lengths);
14278 error (_("Out of memory allocating space for histogram counts\n"));
14279 goto err_out;
14282 for (hn = 0; hn < filedata->nbuckets; ++hn)
14283 ++counts[lengths[hn]];
14285 if (filedata->nbuckets > 0)
14287 uint64_t i;
14288 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
14289 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
14290 for (i = 1; i <= maxlength; ++i)
14292 nzero_counts += counts[i] * i;
14293 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
14294 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
14295 (nzero_counts * 100.0) / nsyms);
14299 free (counts);
14300 free (lengths);
14303 free (filedata->buckets);
14304 filedata->buckets = NULL;
14305 filedata->nbuckets = 0;
14306 free (filedata->chains);
14307 filedata->chains = NULL;
14309 if (do_histogram && filedata->gnubuckets != NULL)
14311 uint64_t *lengths;
14312 uint64_t *counts;
14313 uint64_t hn;
14314 uint64_t maxlength = 0;
14315 uint64_t nzero_counts = 0;
14316 uint64_t nsyms = 0;
14318 printf (ngettext ("\nHistogram for `%s' bucket list length "
14319 "(total of %" PRIu64 " bucket):\n",
14320 "\nHistogram for `%s' bucket list length "
14321 "(total of %" PRIu64 " buckets):\n",
14322 filedata->ngnubuckets),
14323 GNU_HASH_SECTION_NAME (filedata),
14324 filedata->ngnubuckets);
14326 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
14327 if (lengths == NULL)
14329 error (_("Out of memory allocating space for gnu histogram buckets\n"));
14330 goto err_out;
14333 printf (_(" Length Number %% of total Coverage\n"));
14335 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14336 if (filedata->gnubuckets[hn] != 0)
14338 uint64_t off, length = 1;
14340 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
14341 /* PR 17531 file: 010-77222-0.004. */
14342 off < filedata->ngnuchains
14343 && (filedata->gnuchains[off] & 1) == 0;
14344 ++off)
14345 ++length;
14346 lengths[hn] = length;
14347 if (length > maxlength)
14348 maxlength = length;
14349 nsyms += length;
14352 counts = calloc (maxlength + 1, sizeof (*counts));
14353 if (counts == NULL)
14355 free (lengths);
14356 error (_("Out of memory allocating space for gnu histogram counts\n"));
14357 goto err_out;
14360 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14361 ++counts[lengths[hn]];
14363 if (filedata->ngnubuckets > 0)
14365 uint64_t j;
14366 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
14367 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
14368 for (j = 1; j <= maxlength; ++j)
14370 nzero_counts += counts[j] * j;
14371 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
14372 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
14373 (nzero_counts * 100.0) / nsyms);
14377 free (counts);
14378 free (lengths);
14380 free (filedata->gnubuckets);
14381 filedata->gnubuckets = NULL;
14382 filedata->ngnubuckets = 0;
14383 free (filedata->gnuchains);
14384 filedata->gnuchains = NULL;
14385 filedata->ngnuchains = 0;
14386 free (filedata->mipsxlat);
14387 filedata->mipsxlat = NULL;
14388 return true;
14390 err_out:
14391 free (filedata->gnubuckets);
14392 filedata->gnubuckets = NULL;
14393 filedata->ngnubuckets = 0;
14394 free (filedata->gnuchains);
14395 filedata->gnuchains = NULL;
14396 filedata->ngnuchains = 0;
14397 free (filedata->mipsxlat);
14398 filedata->mipsxlat = NULL;
14399 free (filedata->buckets);
14400 filedata->buckets = NULL;
14401 filedata->nbuckets = 0;
14402 free (filedata->chains);
14403 filedata->chains = NULL;
14404 return false;
14407 static bool
14408 process_syminfo (Filedata * filedata)
14410 unsigned int i;
14412 if (filedata->dynamic_syminfo == NULL
14413 || !do_dynamic)
14414 /* No syminfo, this is ok. */
14415 return true;
14417 /* There better should be a dynamic symbol section. */
14418 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
14419 return false;
14421 if (filedata->is_separate)
14422 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14423 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
14424 filedata->dynamic_syminfo_nent),
14425 filedata->file_name,
14426 filedata->dynamic_syminfo_offset,
14427 filedata->dynamic_syminfo_nent);
14428 else
14429 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14430 " contains %d entry:\n",
14431 "\nDynamic info segment at offset %#" PRIx64
14432 " contains %d entries:\n",
14433 filedata->dynamic_syminfo_nent),
14434 filedata->dynamic_syminfo_offset,
14435 filedata->dynamic_syminfo_nent);
14437 printf (_(" Num: Name BoundTo Flags\n"));
14438 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
14440 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
14442 printf ("%4d: ", i);
14443 if (i >= filedata->num_dynamic_syms)
14444 printf (_("<corrupt index>"));
14445 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
14446 print_symbol_name (30, get_dynamic_name (filedata,
14447 filedata->dynamic_symbols[i].st_name));
14448 else
14449 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
14450 putchar (' ');
14452 switch (filedata->dynamic_syminfo[i].si_boundto)
14454 case SYMINFO_BT_SELF:
14455 fputs ("SELF ", stdout);
14456 break;
14457 case SYMINFO_BT_PARENT:
14458 fputs ("PARENT ", stdout);
14459 break;
14460 default:
14461 if (filedata->dynamic_syminfo[i].si_boundto > 0
14462 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
14463 && valid_dynamic_name (filedata,
14464 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
14466 print_symbol_name (10, get_dynamic_name (filedata,
14467 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
14468 putchar (' ' );
14470 else
14471 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
14472 break;
14475 if (flags & SYMINFO_FLG_DIRECT)
14476 printf (" DIRECT");
14477 if (flags & SYMINFO_FLG_PASSTHRU)
14478 printf (" PASSTHRU");
14479 if (flags & SYMINFO_FLG_COPY)
14480 printf (" COPY");
14481 if (flags & SYMINFO_FLG_LAZYLOAD)
14482 printf (" LAZYLOAD");
14484 puts ("");
14487 return true;
14490 /* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
14491 is contained by the region START .. END. The types of ADDR, START
14492 and END should all be the same. Note both ADDR + NELEM and END
14493 point to just beyond the end of the regions that are being tested. */
14494 #define IN_RANGE(START,END,ADDR,NELEM) \
14495 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
14497 /* Check to see if the given reloc needs to be handled in a target specific
14498 manner. If so then process the reloc and return TRUE otherwise return
14499 FALSE.
14501 If called with reloc == NULL, then this is a signal that reloc processing
14502 for the current section has finished, and any saved state should be
14503 discarded. */
14505 static bool
14506 target_specific_reloc_handling (Filedata *filedata,
14507 Elf_Internal_Rela *reloc,
14508 unsigned char *start,
14509 unsigned char *end,
14510 Elf_Internal_Sym *symtab,
14511 uint64_t num_syms)
14513 unsigned int reloc_type = 0;
14514 uint64_t sym_index = 0;
14516 if (reloc)
14518 reloc_type = get_reloc_type (filedata, reloc->r_info);
14519 sym_index = get_reloc_symindex (reloc->r_info);
14522 switch (filedata->file_header.e_machine)
14524 case EM_LOONGARCH:
14526 switch (reloc_type)
14528 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14529 at assembly time. */
14530 case 107: /* R_LARCH_ADD_ULEB128. */
14531 case 108: /* R_LARCH_SUB_ULEB128. */
14533 uint64_t value = 0;
14534 unsigned int reloc_size = 0;
14535 int leb_ret = 0;
14537 if (reloc->r_offset < (size_t) (end - start))
14538 value = read_leb128 (start + reloc->r_offset, end, false,
14539 &reloc_size, &leb_ret);
14540 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14541 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14542 "ULEB128 value\n"),
14543 (long) reloc->r_offset);
14545 else if (sym_index >= num_syms)
14546 error (_("%s reloc contains invalid symbol index "
14547 "%" PRIu64 "\n"),
14548 (reloc_type == 107
14549 ? "R_LARCH_ADD_ULEB128"
14550 : "R_LARCH_SUB_ULEB128"),
14551 sym_index);
14552 else
14554 if (reloc_type == 107)
14555 value += reloc->r_addend + symtab[sym_index].st_value;
14556 else
14557 value -= reloc->r_addend + symtab[sym_index].st_value;
14559 /* Write uleb128 value to p. */
14560 bfd_byte *p = start + reloc->r_offset;
14563 bfd_byte c = value & 0x7f;
14564 value >>= 7;
14565 if (--reloc_size != 0)
14566 c |= 0x80;
14567 *p++ = c;
14569 while (reloc_size);
14572 return true;
14575 break;
14578 case EM_MSP430:
14579 case EM_MSP430_OLD:
14581 static Elf_Internal_Sym * saved_sym = NULL;
14583 if (reloc == NULL)
14585 saved_sym = NULL;
14586 return true;
14589 switch (reloc_type)
14591 case 10: /* R_MSP430_SYM_DIFF */
14592 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
14593 if (uses_msp430x_relocs (filedata))
14594 break;
14595 /* Fall through. */
14596 case 21: /* R_MSP430X_SYM_DIFF */
14597 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
14598 /* PR 21139. */
14599 if (sym_index >= num_syms)
14600 error (_("%s reloc contains invalid symbol index "
14601 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
14602 else
14603 saved_sym = symtab + sym_index;
14604 return true;
14606 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14607 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14608 goto handle_sym_diff;
14610 case 5: /* R_MSP430_16_BYTE */
14611 case 9: /* R_MSP430_8 */
14612 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14613 if (uses_msp430x_relocs (filedata))
14614 break;
14615 goto handle_sym_diff;
14617 case 2: /* R_MSP430_ABS16 */
14618 case 15: /* R_MSP430X_ABS16 */
14619 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
14620 if (! uses_msp430x_relocs (filedata))
14621 break;
14622 goto handle_sym_diff;
14624 handle_sym_diff:
14625 if (saved_sym != NULL)
14627 uint64_t value;
14628 unsigned int reloc_size = 0;
14629 int leb_ret = 0;
14630 switch (reloc_type)
14632 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14633 reloc_size = 4;
14634 break;
14635 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14636 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
14637 if (reloc->r_offset < (size_t) (end - start))
14638 read_leb128 (start + reloc->r_offset, end, false,
14639 &reloc_size, &leb_ret);
14640 break;
14641 default:
14642 reloc_size = 2;
14643 break;
14646 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14647 error (_("MSP430 ULEB128 field at %#" PRIx64
14648 " contains invalid ULEB128 value\n"),
14649 reloc->r_offset);
14650 else if (sym_index >= num_syms)
14651 error (_("%s reloc contains invalid symbol index "
14652 "%" PRIu64 "\n"), "MSP430", sym_index);
14653 else
14655 value = reloc->r_addend + (symtab[sym_index].st_value
14656 - saved_sym->st_value);
14658 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
14659 byte_put (start + reloc->r_offset, value, reloc_size);
14660 else
14661 /* PR 21137 */
14662 error (_("MSP430 sym diff reloc contains invalid offset: "
14663 "%#" PRIx64 "\n"),
14664 reloc->r_offset);
14667 saved_sym = NULL;
14668 return true;
14670 break;
14672 default:
14673 if (saved_sym != NULL)
14674 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
14675 break;
14677 break;
14680 case EM_MN10300:
14681 case EM_CYGNUS_MN10300:
14683 static Elf_Internal_Sym * saved_sym = NULL;
14685 if (reloc == NULL)
14687 saved_sym = NULL;
14688 return true;
14691 switch (reloc_type)
14693 case 34: /* R_MN10300_ALIGN */
14694 return true;
14695 case 33: /* R_MN10300_SYM_DIFF */
14696 if (sym_index >= num_syms)
14697 error (_("%s reloc contains invalid symbol index "
14698 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
14699 else
14700 saved_sym = symtab + sym_index;
14701 return true;
14703 case 1: /* R_MN10300_32 */
14704 case 2: /* R_MN10300_16 */
14705 if (saved_sym != NULL)
14707 int reloc_size = reloc_type == 1 ? 4 : 2;
14708 uint64_t value;
14710 if (sym_index >= num_syms)
14711 error (_("%s reloc contains invalid symbol index "
14712 "%" PRIu64 "\n"), "MN10300", sym_index);
14713 else
14715 value = reloc->r_addend + (symtab[sym_index].st_value
14716 - saved_sym->st_value);
14718 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
14719 byte_put (start + reloc->r_offset, value, reloc_size);
14720 else
14721 error (_("MN10300 sym diff reloc contains invalid offset:"
14722 " %#" PRIx64 "\n"),
14723 reloc->r_offset);
14726 saved_sym = NULL;
14727 return true;
14729 break;
14730 default:
14731 if (saved_sym != NULL)
14732 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
14733 break;
14735 break;
14738 case EM_RL78:
14740 static uint64_t saved_sym1 = 0;
14741 static uint64_t saved_sym2 = 0;
14742 static uint64_t value;
14744 if (reloc == NULL)
14746 saved_sym1 = saved_sym2 = 0;
14747 return true;
14750 switch (reloc_type)
14752 case 0x80: /* R_RL78_SYM. */
14753 saved_sym1 = saved_sym2;
14754 if (sym_index >= num_syms)
14755 error (_("%s reloc contains invalid symbol index "
14756 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
14757 else
14759 saved_sym2 = symtab[sym_index].st_value;
14760 saved_sym2 += reloc->r_addend;
14762 return true;
14764 case 0x83: /* R_RL78_OPsub. */
14765 value = saved_sym1 - saved_sym2;
14766 saved_sym2 = saved_sym1 = 0;
14767 return true;
14768 break;
14770 case 0x41: /* R_RL78_ABS32. */
14771 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
14772 byte_put (start + reloc->r_offset, value, 4);
14773 else
14774 error (_("RL78 sym diff reloc contains invalid offset: "
14775 "%#" PRIx64 "\n"),
14776 reloc->r_offset);
14777 value = 0;
14778 return true;
14780 case 0x43: /* R_RL78_ABS16. */
14781 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
14782 byte_put (start + reloc->r_offset, value, 2);
14783 else
14784 error (_("RL78 sym diff reloc contains invalid offset: "
14785 "%#" PRIx64 "\n"),
14786 reloc->r_offset);
14787 value = 0;
14788 return true;
14790 default:
14791 break;
14793 break;
14797 return false;
14800 /* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14801 DWARF debug sections. This is a target specific test. Note - we do not
14802 go through the whole including-target-headers-multiple-times route, (as
14803 we have already done with <elf/h8.h>) because this would become very
14804 messy and even then this function would have to contain target specific
14805 information (the names of the relocs instead of their numeric values).
14806 FIXME: This is not the correct way to solve this problem. The proper way
14807 is to have target specific reloc sizing and typing functions created by
14808 the reloc-macros.h header, in the same way that it already creates the
14809 reloc naming functions. */
14811 static bool
14812 is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14814 /* Please keep this table alpha-sorted for ease of visual lookup. */
14815 switch (filedata->file_header.e_machine)
14817 case EM_386:
14818 case EM_IAMCU:
14819 return reloc_type == 1; /* R_386_32. */
14820 case EM_68K:
14821 return reloc_type == 1; /* R_68K_32. */
14822 case EM_860:
14823 return reloc_type == 1; /* R_860_32. */
14824 case EM_960:
14825 return reloc_type == 2; /* R_960_32. */
14826 case EM_AARCH64:
14827 return (reloc_type == 258
14828 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
14829 case EM_BPF:
14830 return reloc_type == 11; /* R_BPF_DATA_32 */
14831 case EM_ADAPTEVA_EPIPHANY:
14832 return reloc_type == 3;
14833 case EM_ALPHA:
14834 return reloc_type == 1; /* R_ALPHA_REFLONG. */
14835 case EM_ARC:
14836 return reloc_type == 1; /* R_ARC_32. */
14837 case EM_ARC_COMPACT:
14838 case EM_ARC_COMPACT2:
14839 case EM_ARC_COMPACT3:
14840 case EM_ARC_COMPACT3_64:
14841 return reloc_type == 4; /* R_ARC_32. */
14842 case EM_ARM:
14843 return reloc_type == 2; /* R_ARM_ABS32 */
14844 case EM_AVR_OLD:
14845 case EM_AVR:
14846 return reloc_type == 1;
14847 case EM_BLACKFIN:
14848 return reloc_type == 0x12; /* R_byte4_data. */
14849 case EM_CRIS:
14850 return reloc_type == 3; /* R_CRIS_32. */
14851 case EM_CR16:
14852 return reloc_type == 3; /* R_CR16_NUM32. */
14853 case EM_CRX:
14854 return reloc_type == 15; /* R_CRX_NUM32. */
14855 case EM_CSKY:
14856 return reloc_type == 1; /* R_CKCORE_ADDR32. */
14857 case EM_CYGNUS_FRV:
14858 return reloc_type == 1;
14859 case EM_CYGNUS_D10V:
14860 case EM_D10V:
14861 return reloc_type == 6; /* R_D10V_32. */
14862 case EM_CYGNUS_D30V:
14863 case EM_D30V:
14864 return reloc_type == 12; /* R_D30V_32_NORMAL. */
14865 case EM_DLX:
14866 return reloc_type == 3; /* R_DLX_RELOC_32. */
14867 case EM_CYGNUS_FR30:
14868 case EM_FR30:
14869 return reloc_type == 3; /* R_FR30_32. */
14870 case EM_FT32:
14871 return reloc_type == 1; /* R_FT32_32. */
14872 case EM_H8S:
14873 case EM_H8_300:
14874 case EM_H8_300H:
14875 return reloc_type == 1; /* R_H8_DIR32. */
14876 case EM_IA_64:
14877 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14878 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14879 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14880 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
14881 case EM_IP2K_OLD:
14882 case EM_IP2K:
14883 return reloc_type == 2; /* R_IP2K_32. */
14884 case EM_IQ2000:
14885 return reloc_type == 2; /* R_IQ2000_32. */
14886 case EM_KVX:
14887 return reloc_type == 2; /* R_KVX_32. */
14888 case EM_LATTICEMICO32:
14889 return reloc_type == 3; /* R_LM32_32. */
14890 case EM_LOONGARCH:
14891 return reloc_type == 1; /* R_LARCH_32. */
14892 case EM_M32C_OLD:
14893 case EM_M32C:
14894 return reloc_type == 3; /* R_M32C_32. */
14895 case EM_M32R:
14896 return reloc_type == 34; /* R_M32R_32_RELA. */
14897 case EM_68HC11:
14898 case EM_68HC12:
14899 return reloc_type == 6; /* R_M68HC11_32. */
14900 case EM_S12Z:
14901 return reloc_type == 7 || /* R_S12Z_EXT32 */
14902 reloc_type == 6; /* R_S12Z_CW32. */
14903 case EM_MCORE:
14904 return reloc_type == 1; /* R_MCORE_ADDR32. */
14905 case EM_CYGNUS_MEP:
14906 return reloc_type == 4; /* R_MEP_32. */
14907 case EM_METAG:
14908 return reloc_type == 2; /* R_METAG_ADDR32. */
14909 case EM_MICROBLAZE:
14910 return reloc_type == 1; /* R_MICROBLAZE_32. */
14911 case EM_MIPS:
14912 return reloc_type == 2; /* R_MIPS_32. */
14913 case EM_MMIX:
14914 return reloc_type == 4; /* R_MMIX_32. */
14915 case EM_CYGNUS_MN10200:
14916 case EM_MN10200:
14917 return reloc_type == 1; /* R_MN10200_32. */
14918 case EM_CYGNUS_MN10300:
14919 case EM_MN10300:
14920 return reloc_type == 1; /* R_MN10300_32. */
14921 case EM_MOXIE:
14922 return reloc_type == 1; /* R_MOXIE_32. */
14923 case EM_MSP430_OLD:
14924 case EM_MSP430:
14925 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
14926 case EM_MT:
14927 return reloc_type == 2; /* R_MT_32. */
14928 case EM_NDS32:
14929 return reloc_type == 20; /* R_NDS32_32_RELA. */
14930 case EM_ALTERA_NIOS2:
14931 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
14932 case EM_NIOS32:
14933 return reloc_type == 1; /* R_NIOS_32. */
14934 case EM_OR1K:
14935 return reloc_type == 1; /* R_OR1K_32. */
14936 case EM_PARISC:
14937 return (reloc_type == 1 /* R_PARISC_DIR32. */
14938 || reloc_type == 2 /* R_PARISC_DIR21L. */
14939 || reloc_type == 41); /* R_PARISC_SECREL32. */
14940 case EM_PJ:
14941 case EM_PJ_OLD:
14942 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14943 case EM_PPC64:
14944 return reloc_type == 1; /* R_PPC64_ADDR32. */
14945 case EM_PPC:
14946 return reloc_type == 1; /* R_PPC_ADDR32. */
14947 case EM_TI_PRU:
14948 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
14949 case EM_RISCV:
14950 return reloc_type == 1; /* R_RISCV_32. */
14951 case EM_RL78:
14952 return reloc_type == 1; /* R_RL78_DIR32. */
14953 case EM_RX:
14954 return reloc_type == 1; /* R_RX_DIR32. */
14955 case EM_S370:
14956 return reloc_type == 1; /* R_I370_ADDR31. */
14957 case EM_S390_OLD:
14958 case EM_S390:
14959 return reloc_type == 4; /* R_S390_32. */
14960 case EM_SCORE:
14961 return reloc_type == 8; /* R_SCORE_ABS32. */
14962 case EM_SH:
14963 return reloc_type == 1; /* R_SH_DIR32. */
14964 case EM_SPARC32PLUS:
14965 case EM_SPARCV9:
14966 case EM_SPARC:
14967 return reloc_type == 3 /* R_SPARC_32. */
14968 || reloc_type == 23; /* R_SPARC_UA32. */
14969 case EM_SPU:
14970 return reloc_type == 6; /* R_SPU_ADDR32 */
14971 case EM_TI_C6000:
14972 return reloc_type == 1; /* R_C6000_ABS32. */
14973 case EM_TILEGX:
14974 return reloc_type == 2; /* R_TILEGX_32. */
14975 case EM_TILEPRO:
14976 return reloc_type == 1; /* R_TILEPRO_32. */
14977 case EM_CYGNUS_V850:
14978 case EM_V850:
14979 return reloc_type == 6; /* R_V850_ABS32. */
14980 case EM_V800:
14981 return reloc_type == 0x33; /* R_V810_WORD. */
14982 case EM_VAX:
14983 return reloc_type == 1; /* R_VAX_32. */
14984 case EM_VISIUM:
14985 return reloc_type == 3; /* R_VISIUM_32. */
14986 case EM_WEBASSEMBLY:
14987 return reloc_type == 1; /* R_WASM32_32. */
14988 case EM_X86_64:
14989 case EM_L1OM:
14990 case EM_K1OM:
14991 return reloc_type == 10; /* R_X86_64_32. */
14992 case EM_XGATE:
14993 return reloc_type == 4; /* R_XGATE_32. */
14994 case EM_XSTORMY16:
14995 return reloc_type == 1; /* R_XSTROMY16_32. */
14996 case EM_XTENSA_OLD:
14997 case EM_XTENSA:
14998 return reloc_type == 1; /* R_XTENSA_32. */
14999 case EM_Z80:
15000 return reloc_type == 6; /* R_Z80_32. */
15001 default:
15003 static unsigned int prev_warn = 0;
15005 /* Avoid repeating the same warning multiple times. */
15006 if (prev_warn != filedata->file_header.e_machine)
15007 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
15008 filedata->file_header.e_machine);
15009 prev_warn = filedata->file_header.e_machine;
15010 return false;
15015 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15016 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15018 static bool
15019 is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
15021 switch (filedata->file_header.e_machine)
15022 /* Please keep this table alpha-sorted for ease of visual lookup. */
15024 case EM_386:
15025 case EM_IAMCU:
15026 return reloc_type == 2; /* R_386_PC32. */
15027 case EM_68K:
15028 return reloc_type == 4; /* R_68K_PC32. */
15029 case EM_AARCH64:
15030 return reloc_type == 261; /* R_AARCH64_PREL32 */
15031 case EM_ADAPTEVA_EPIPHANY:
15032 return reloc_type == 6;
15033 case EM_ALPHA:
15034 return reloc_type == 10; /* R_ALPHA_SREL32. */
15035 case EM_ARC_COMPACT:
15036 case EM_ARC_COMPACT2:
15037 case EM_ARC_COMPACT3:
15038 case EM_ARC_COMPACT3_64:
15039 return reloc_type == 49; /* R_ARC_32_PCREL. */
15040 case EM_ARM:
15041 return reloc_type == 3; /* R_ARM_REL32 */
15042 case EM_AVR_OLD:
15043 case EM_AVR:
15044 return reloc_type == 36; /* R_AVR_32_PCREL. */
15045 case EM_LOONGARCH:
15046 return reloc_type == 99; /* R_LARCH_32_PCREL. */
15047 case EM_MICROBLAZE:
15048 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
15049 case EM_OR1K:
15050 return reloc_type == 9; /* R_OR1K_32_PCREL. */
15051 case EM_PARISC:
15052 return reloc_type == 9; /* R_PARISC_PCREL32. */
15053 case EM_PPC:
15054 return reloc_type == 26; /* R_PPC_REL32. */
15055 case EM_PPC64:
15056 return reloc_type == 26; /* R_PPC64_REL32. */
15057 case EM_RISCV:
15058 return reloc_type == 57; /* R_RISCV_32_PCREL. */
15059 case EM_S390_OLD:
15060 case EM_S390:
15061 return reloc_type == 5; /* R_390_PC32. */
15062 case EM_SH:
15063 return reloc_type == 2; /* R_SH_REL32. */
15064 case EM_SPARC32PLUS:
15065 case EM_SPARCV9:
15066 case EM_SPARC:
15067 return reloc_type == 6; /* R_SPARC_DISP32. */
15068 case EM_SPU:
15069 return reloc_type == 13; /* R_SPU_REL32. */
15070 case EM_TILEGX:
15071 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15072 case EM_TILEPRO:
15073 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
15074 case EM_VISIUM:
15075 return reloc_type == 6; /* R_VISIUM_32_PCREL */
15076 case EM_X86_64:
15077 case EM_L1OM:
15078 case EM_K1OM:
15079 return reloc_type == 2; /* R_X86_64_PC32. */
15080 case EM_VAX:
15081 return reloc_type == 4; /* R_VAX_PCREL32. */
15082 case EM_XTENSA_OLD:
15083 case EM_XTENSA:
15084 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
15085 case EM_KVX:
15086 return reloc_type == 7; /* R_KVX_32_PCREL */
15087 default:
15088 /* Do not abort or issue an error message here. Not all targets use
15089 pc-relative 32-bit relocs in their DWARF debug information and we
15090 have already tested for target coverage in is_32bit_abs_reloc. A
15091 more helpful warning message will be generated by apply_relocations
15092 anyway, so just return. */
15093 return false;
15097 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15098 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15100 static bool
15101 is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15103 switch (filedata->file_header.e_machine)
15105 case EM_AARCH64:
15106 return reloc_type == 257; /* R_AARCH64_ABS64. */
15107 case EM_ARC_COMPACT3_64:
15108 return reloc_type == 5; /* R_ARC_64. */
15109 case EM_ALPHA:
15110 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
15111 case EM_IA_64:
15112 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15113 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
15114 case EM_LOONGARCH:
15115 return reloc_type == 2; /* R_LARCH_64 */
15116 case EM_PARISC:
15117 return reloc_type == 80; /* R_PARISC_DIR64. */
15118 case EM_PPC64:
15119 return reloc_type == 38; /* R_PPC64_ADDR64. */
15120 case EM_RISCV:
15121 return reloc_type == 2; /* R_RISCV_64. */
15122 case EM_SPARC32PLUS:
15123 case EM_SPARCV9:
15124 case EM_SPARC:
15125 return reloc_type == 32 /* R_SPARC_64. */
15126 || reloc_type == 54; /* R_SPARC_UA64. */
15127 case EM_X86_64:
15128 case EM_L1OM:
15129 case EM_K1OM:
15130 return reloc_type == 1; /* R_X86_64_64. */
15131 case EM_S390_OLD:
15132 case EM_S390:
15133 return reloc_type == 22; /* R_S390_64. */
15134 case EM_TILEGX:
15135 return reloc_type == 1; /* R_TILEGX_64. */
15136 case EM_MIPS:
15137 return reloc_type == 18; /* R_MIPS_64. */
15138 case EM_KVX:
15139 return reloc_type == 3; /* R_KVX_64 */
15140 default:
15141 return false;
15145 /* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15146 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15148 static bool
15149 is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
15151 switch (filedata->file_header.e_machine)
15153 case EM_AARCH64:
15154 return reloc_type == 260; /* R_AARCH64_PREL64. */
15155 case EM_ALPHA:
15156 return reloc_type == 11; /* R_ALPHA_SREL64. */
15157 case EM_IA_64:
15158 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15159 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
15160 case EM_PARISC:
15161 return reloc_type == 72; /* R_PARISC_PCREL64. */
15162 case EM_PPC64:
15163 return reloc_type == 44; /* R_PPC64_REL64. */
15164 case EM_SPARC32PLUS:
15165 case EM_SPARCV9:
15166 case EM_SPARC:
15167 return reloc_type == 46; /* R_SPARC_DISP64. */
15168 case EM_X86_64:
15169 case EM_L1OM:
15170 case EM_K1OM:
15171 return reloc_type == 24; /* R_X86_64_PC64. */
15172 case EM_S390_OLD:
15173 case EM_S390:
15174 return reloc_type == 23; /* R_S390_PC64. */
15175 case EM_TILEGX:
15176 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
15177 default:
15178 return false;
15182 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15183 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15185 static bool
15186 is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15188 switch (filedata->file_header.e_machine)
15190 case EM_CYGNUS_MN10200:
15191 case EM_MN10200:
15192 return reloc_type == 4; /* R_MN10200_24. */
15193 case EM_FT32:
15194 return reloc_type == 5; /* R_FT32_20. */
15195 case EM_Z80:
15196 return reloc_type == 5; /* R_Z80_24. */
15197 default:
15198 return false;
15202 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15203 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15205 static bool
15206 is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15208 /* Please keep this table alpha-sorted for ease of visual lookup. */
15209 switch (filedata->file_header.e_machine)
15211 case EM_ARC:
15212 case EM_ARC_COMPACT:
15213 case EM_ARC_COMPACT2:
15214 case EM_ARC_COMPACT3:
15215 case EM_ARC_COMPACT3_64:
15216 return reloc_type == 2; /* R_ARC_16. */
15217 case EM_ADAPTEVA_EPIPHANY:
15218 return reloc_type == 5;
15219 case EM_AVR_OLD:
15220 case EM_AVR:
15221 return reloc_type == 4; /* R_AVR_16. */
15222 case EM_CYGNUS_D10V:
15223 case EM_D10V:
15224 return reloc_type == 3; /* R_D10V_16. */
15225 case EM_FT32:
15226 return reloc_type == 2; /* R_FT32_16. */
15227 case EM_H8S:
15228 case EM_H8_300:
15229 case EM_H8_300H:
15230 return reloc_type == R_H8_DIR16;
15231 case EM_IP2K_OLD:
15232 case EM_IP2K:
15233 return reloc_type == 1; /* R_IP2K_16. */
15234 case EM_M32C_OLD:
15235 case EM_M32C:
15236 return reloc_type == 1; /* R_M32C_16 */
15237 case EM_CYGNUS_MN10200:
15238 case EM_MN10200:
15239 return reloc_type == 2; /* R_MN10200_16. */
15240 case EM_CYGNUS_MN10300:
15241 case EM_MN10300:
15242 return reloc_type == 2; /* R_MN10300_16. */
15243 case EM_KVX:
15244 return reloc_type == 1; /* R_KVX_16 */
15245 case EM_MSP430:
15246 if (uses_msp430x_relocs (filedata))
15247 return reloc_type == 2; /* R_MSP430_ABS16. */
15248 /* Fall through. */
15249 case EM_MSP430_OLD:
15250 return reloc_type == 5; /* R_MSP430_16_BYTE. */
15251 case EM_NDS32:
15252 return reloc_type == 19; /* R_NDS32_16_RELA. */
15253 case EM_ALTERA_NIOS2:
15254 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
15255 case EM_NIOS32:
15256 return reloc_type == 9; /* R_NIOS_16. */
15257 case EM_OR1K:
15258 return reloc_type == 2; /* R_OR1K_16. */
15259 case EM_RISCV:
15260 return reloc_type == 55; /* R_RISCV_SET16. */
15261 case EM_TI_PRU:
15262 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
15263 case EM_TI_C6000:
15264 return reloc_type == 2; /* R_C6000_ABS16. */
15265 case EM_VISIUM:
15266 return reloc_type == 2; /* R_VISIUM_16. */
15267 case EM_XGATE:
15268 return reloc_type == 3; /* R_XGATE_16. */
15269 case EM_Z80:
15270 return reloc_type == 4; /* R_Z80_16. */
15271 default:
15272 return false;
15276 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15277 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15279 static bool
15280 is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15282 switch (filedata->file_header.e_machine)
15284 case EM_RISCV:
15285 return reloc_type == 54; /* R_RISCV_SET8. */
15286 case EM_Z80:
15287 return reloc_type == 1; /* R_Z80_8. */
15288 case EM_MICROBLAZE:
15289 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15290 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15291 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
15292 default:
15293 return false;
15297 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15298 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15300 static bool
15301 is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15303 switch (filedata->file_header.e_machine)
15305 case EM_RISCV:
15306 return reloc_type == 53; /* R_RISCV_SET6. */
15307 default:
15308 return false;
15312 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15313 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15315 static bool
15316 is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15318 /* Please keep this table alpha-sorted for ease of visual lookup. */
15319 switch (filedata->file_header.e_machine)
15321 case EM_LOONGARCH:
15322 return reloc_type == 50; /* R_LARCH_ADD32. */
15323 case EM_RISCV:
15324 return reloc_type == 35; /* R_RISCV_ADD32. */
15325 default:
15326 return false;
15330 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15331 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15333 static bool
15334 is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15336 /* Please keep this table alpha-sorted for ease of visual lookup. */
15337 switch (filedata->file_header.e_machine)
15339 case EM_LOONGARCH:
15340 return reloc_type == 55; /* R_LARCH_SUB32. */
15341 case EM_RISCV:
15342 return reloc_type == 39; /* R_RISCV_SUB32. */
15343 default:
15344 return false;
15348 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15349 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15351 static bool
15352 is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15354 /* Please keep this table alpha-sorted for ease of visual lookup. */
15355 switch (filedata->file_header.e_machine)
15357 case EM_LOONGARCH:
15358 return reloc_type == 51; /* R_LARCH_ADD64. */
15359 case EM_RISCV:
15360 return reloc_type == 36; /* R_RISCV_ADD64. */
15361 default:
15362 return false;
15366 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15367 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15369 static bool
15370 is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15372 /* Please keep this table alpha-sorted for ease of visual lookup. */
15373 switch (filedata->file_header.e_machine)
15375 case EM_LOONGARCH:
15376 return reloc_type == 56; /* R_LARCH_SUB64. */
15377 case EM_RISCV:
15378 return reloc_type == 40; /* R_RISCV_SUB64. */
15379 default:
15380 return false;
15384 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15385 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15387 static bool
15388 is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15390 /* Please keep this table alpha-sorted for ease of visual lookup. */
15391 switch (filedata->file_header.e_machine)
15393 case EM_LOONGARCH:
15394 return reloc_type == 48; /* R_LARCH_ADD16. */
15395 case EM_RISCV:
15396 return reloc_type == 34; /* R_RISCV_ADD16. */
15397 default:
15398 return false;
15402 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15403 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15405 static bool
15406 is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15408 /* Please keep this table alpha-sorted for ease of visual lookup. */
15409 switch (filedata->file_header.e_machine)
15411 case EM_LOONGARCH:
15412 return reloc_type == 53; /* R_LARCH_SUB16. */
15413 case EM_RISCV:
15414 return reloc_type == 38; /* R_RISCV_SUB16. */
15415 default:
15416 return false;
15420 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15421 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15423 static bool
15424 is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15426 /* Please keep this table alpha-sorted for ease of visual lookup. */
15427 switch (filedata->file_header.e_machine)
15429 case EM_LOONGARCH:
15430 return reloc_type == 47; /* R_LARCH_ADD8. */
15431 case EM_RISCV:
15432 return reloc_type == 33; /* R_RISCV_ADD8. */
15433 default:
15434 return false;
15438 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15439 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15441 static bool
15442 is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15444 /* Please keep this table alpha-sorted for ease of visual lookup. */
15445 switch (filedata->file_header.e_machine)
15447 case EM_LOONGARCH:
15448 return reloc_type == 52; /* R_LARCH_SUB8. */
15449 case EM_RISCV:
15450 return reloc_type == 37; /* R_RISCV_SUB8. */
15451 default:
15452 return false;
15456 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15457 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
15459 static bool
15460 is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15462 switch (filedata->file_header.e_machine)
15464 case EM_LOONGARCH:
15465 return reloc_type == 105; /* R_LARCH_ADD6. */
15466 default:
15467 return false;
15471 /* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15472 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
15474 static bool
15475 is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15477 switch (filedata->file_header.e_machine)
15479 case EM_LOONGARCH:
15480 return reloc_type == 106; /* R_LARCH_SUB6. */
15481 case EM_RISCV:
15482 return reloc_type == 52; /* R_RISCV_SUB6. */
15483 default:
15484 return false;
15488 /* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
15489 relocation entries (possibly formerly used for SHT_GROUP sections). */
15491 static bool
15492 is_none_reloc (Filedata * filedata, unsigned int reloc_type)
15494 switch (filedata->file_header.e_machine)
15496 case EM_386: /* R_386_NONE. */
15497 case EM_68K: /* R_68K_NONE. */
15498 case EM_ADAPTEVA_EPIPHANY:
15499 case EM_ALPHA: /* R_ALPHA_NONE. */
15500 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
15501 case EM_ARC: /* R_ARC_NONE. */
15502 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
15503 case EM_ARC_COMPACT: /* R_ARC_NONE. */
15504 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15505 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
15506 case EM_ARM: /* R_ARM_NONE. */
15507 case EM_CRIS: /* R_CRIS_NONE. */
15508 case EM_FT32: /* R_FT32_NONE. */
15509 case EM_IA_64: /* R_IA64_NONE. */
15510 case EM_K1OM: /* R_X86_64_NONE. */
15511 case EM_KVX: /* R_KVX_NONE. */
15512 case EM_L1OM: /* R_X86_64_NONE. */
15513 case EM_M32R: /* R_M32R_NONE. */
15514 case EM_MIPS: /* R_MIPS_NONE. */
15515 case EM_MN10300: /* R_MN10300_NONE. */
15516 case EM_MOXIE: /* R_MOXIE_NONE. */
15517 case EM_NIOS32: /* R_NIOS_NONE. */
15518 case EM_OR1K: /* R_OR1K_NONE. */
15519 case EM_PARISC: /* R_PARISC_NONE. */
15520 case EM_PPC64: /* R_PPC64_NONE. */
15521 case EM_PPC: /* R_PPC_NONE. */
15522 case EM_RISCV: /* R_RISCV_NONE. */
15523 case EM_S390: /* R_390_NONE. */
15524 case EM_S390_OLD:
15525 case EM_SH: /* R_SH_NONE. */
15526 case EM_SPARC32PLUS:
15527 case EM_SPARC: /* R_SPARC_NONE. */
15528 case EM_SPARCV9:
15529 case EM_TILEGX: /* R_TILEGX_NONE. */
15530 case EM_TILEPRO: /* R_TILEPRO_NONE. */
15531 case EM_TI_C6000:/* R_C6000_NONE. */
15532 case EM_X86_64: /* R_X86_64_NONE. */
15533 case EM_Z80: /* R_Z80_NONE. */
15534 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
15535 return reloc_type == 0;
15537 case EM_AARCH64:
15538 return reloc_type == 0 || reloc_type == 256;
15539 case EM_AVR_OLD:
15540 case EM_AVR:
15541 return (reloc_type == 0 /* R_AVR_NONE. */
15542 || reloc_type == 30 /* R_AVR_DIFF8. */
15543 || reloc_type == 31 /* R_AVR_DIFF16. */
15544 || reloc_type == 32 /* R_AVR_DIFF32. */);
15545 case EM_METAG:
15546 return reloc_type == 3; /* R_METAG_NONE. */
15547 case EM_NDS32:
15548 return (reloc_type == 0 /* R_NDS32_NONE. */
15549 || reloc_type == 205 /* R_NDS32_DIFF8. */
15550 || reloc_type == 206 /* R_NDS32_DIFF16. */
15551 || reloc_type == 207 /* R_NDS32_DIFF32. */
15552 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
15553 case EM_TI_PRU:
15554 return (reloc_type == 0 /* R_PRU_NONE. */
15555 || reloc_type == 65 /* R_PRU_DIFF8. */
15556 || reloc_type == 66 /* R_PRU_DIFF16. */
15557 || reloc_type == 67 /* R_PRU_DIFF32. */);
15558 case EM_XTENSA_OLD:
15559 case EM_XTENSA:
15560 return (reloc_type == 0 /* R_XTENSA_NONE. */
15561 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15562 || reloc_type == 18 /* R_XTENSA_DIFF16. */
15563 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15564 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15565 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15566 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15567 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15568 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15569 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
15571 return false;
15574 /* Returns TRUE if there is a relocation against
15575 section NAME at OFFSET bytes. */
15577 bool
15578 reloc_at (struct dwarf_section * dsec, uint64_t offset)
15580 Elf_Internal_Rela * relocs;
15581 Elf_Internal_Rela * rp;
15583 if (dsec == NULL || dsec->reloc_info == NULL)
15584 return false;
15586 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15588 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15589 if (rp->r_offset == offset)
15590 return true;
15592 return false;
15595 /* Apply relocations to a section.
15596 Returns TRUE upon success, FALSE otherwise.
15597 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15598 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15599 will be set to the number of relocs loaded.
15601 Note: So far support has been added only for those relocations
15602 which can be found in debug sections. FIXME: Add support for
15603 more relocations ? */
15605 static bool
15606 apply_relocations (Filedata *filedata,
15607 const Elf_Internal_Shdr *section,
15608 unsigned char *start,
15609 size_t size,
15610 void **relocs_return,
15611 uint64_t *num_relocs_return)
15613 Elf_Internal_Shdr * relsec;
15614 unsigned char * end = start + size;
15616 if (relocs_return != NULL)
15618 * (Elf_Internal_Rela **) relocs_return = NULL;
15619 * num_relocs_return = 0;
15622 if (filedata->file_header.e_type != ET_REL)
15623 /* No relocs to apply. */
15624 return true;
15626 /* Find the reloc section associated with the section. */
15627 for (relsec = filedata->section_headers;
15628 relsec < filedata->section_headers + filedata->file_header.e_shnum;
15629 ++relsec)
15631 bool is_rela;
15632 uint64_t num_relocs;
15633 Elf_Internal_Rela * relocs;
15634 Elf_Internal_Rela * rp;
15635 Elf_Internal_Shdr * symsec;
15636 Elf_Internal_Sym * symtab;
15637 uint64_t num_syms;
15638 Elf_Internal_Sym * sym;
15640 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
15641 || relsec->sh_info >= filedata->file_header.e_shnum
15642 || filedata->section_headers + relsec->sh_info != section
15643 || relsec->sh_size == 0
15644 || relsec->sh_link >= filedata->file_header.e_shnum)
15645 continue;
15647 symsec = filedata->section_headers + relsec->sh_link;
15648 if (symsec->sh_type != SHT_SYMTAB
15649 && symsec->sh_type != SHT_DYNSYM)
15650 return false;
15652 is_rela = relsec->sh_type == SHT_RELA;
15654 if (is_rela)
15656 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
15657 relsec->sh_size, & relocs, & num_relocs))
15658 return false;
15660 else
15662 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
15663 relsec->sh_size, & relocs, & num_relocs))
15664 return false;
15667 /* SH uses RELA but uses in place value instead of the addend field. */
15668 if (filedata->file_header.e_machine == EM_SH)
15669 is_rela = false;
15671 symtab = get_elf_symbols (filedata, symsec, & num_syms);
15673 for (rp = relocs; rp < relocs + num_relocs; ++rp)
15675 uint64_t addend;
15676 unsigned int reloc_type;
15677 unsigned int reloc_size;
15678 bool reloc_inplace = false;
15679 bool reloc_subtract = false;
15680 unsigned char *rloc;
15681 uint64_t sym_index;
15683 reloc_type = get_reloc_type (filedata, rp->r_info);
15685 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
15686 continue;
15687 else if (is_none_reloc (filedata, reloc_type))
15688 continue;
15689 else if (is_32bit_abs_reloc (filedata, reloc_type)
15690 || is_32bit_pcrel_reloc (filedata, reloc_type))
15691 reloc_size = 4;
15692 else if (is_64bit_abs_reloc (filedata, reloc_type)
15693 || is_64bit_pcrel_reloc (filedata, reloc_type))
15694 reloc_size = 8;
15695 else if (is_24bit_abs_reloc (filedata, reloc_type))
15696 reloc_size = 3;
15697 else if (is_16bit_abs_reloc (filedata, reloc_type))
15698 reloc_size = 2;
15699 else if (is_8bit_abs_reloc (filedata, reloc_type)
15700 || is_6bit_abs_reloc (filedata, reloc_type))
15701 reloc_size = 1;
15702 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15703 reloc_type))
15704 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15706 reloc_size = 4;
15707 reloc_inplace = true;
15709 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15710 reloc_type))
15711 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15713 reloc_size = 8;
15714 reloc_inplace = true;
15716 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15717 reloc_type))
15718 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15720 reloc_size = 2;
15721 reloc_inplace = true;
15723 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15724 reloc_type))
15725 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15727 reloc_size = 1;
15728 reloc_inplace = true;
15730 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
15731 reloc_type))
15732 || is_6bit_inplace_add_reloc (filedata, reloc_type))
15734 reloc_size = 1;
15735 reloc_inplace = true;
15737 else
15739 static unsigned int prev_reloc = 0;
15741 if (reloc_type != prev_reloc)
15742 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
15743 reloc_type, printable_section_name (filedata, section));
15744 prev_reloc = reloc_type;
15745 continue;
15748 rloc = start + rp->r_offset;
15749 if (!IN_RANGE (start, end, rloc, reloc_size))
15751 warn (_("skipping invalid relocation offset %#" PRIx64
15752 " in section %s\n"),
15753 rp->r_offset,
15754 printable_section_name (filedata, section));
15755 continue;
15758 sym_index = get_reloc_symindex (rp->r_info);
15759 if (sym_index >= num_syms)
15761 warn (_("skipping invalid relocation symbol index %#" PRIx64
15762 " in section %s\n"),
15763 sym_index, printable_section_name (filedata, section));
15764 continue;
15766 sym = symtab + sym_index;
15768 /* If the reloc has a symbol associated with it,
15769 make sure that it is of an appropriate type.
15771 Relocations against symbols without type can happen.
15772 Gcc -feliminate-dwarf2-dups may generate symbols
15773 without type for debug info.
15775 Icc generates relocations against function symbols
15776 instead of local labels.
15778 Relocations against object symbols can happen, eg when
15779 referencing a global array. For an example of this see
15780 the _clz.o binary in libgcc.a. */
15781 if (sym != symtab
15782 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
15783 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
15785 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
15786 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15787 printable_section_name (filedata, relsec),
15788 rp - relocs);
15789 continue;
15792 addend = 0;
15793 if (is_rela)
15794 addend += rp->r_addend;
15795 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15796 partial_inplace. */
15797 if (!is_rela
15798 || (filedata->file_header.e_machine == EM_XTENSA
15799 && reloc_type == 1)
15800 || ((filedata->file_header.e_machine == EM_PJ
15801 || filedata->file_header.e_machine == EM_PJ_OLD)
15802 && reloc_type == 1)
15803 || ((filedata->file_header.e_machine == EM_D30V
15804 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
15805 && reloc_type == 12)
15806 || reloc_inplace)
15808 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15809 addend += byte_get (rloc, reloc_size) & 0x3f;
15810 else
15811 addend += byte_get (rloc, reloc_size);
15814 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15815 || is_64bit_pcrel_reloc (filedata, reloc_type))
15817 /* On HPPA, all pc-relative relocations are biased by 8. */
15818 if (filedata->file_header.e_machine == EM_PARISC)
15819 addend -= 8;
15820 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
15821 reloc_size);
15823 else if (is_6bit_abs_reloc (filedata, reloc_type)
15824 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15825 || is_6bit_inplace_add_reloc (filedata, reloc_type))
15827 if (reloc_subtract)
15828 addend -= sym->st_value;
15829 else
15830 addend += sym->st_value;
15831 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15832 byte_put (rloc, addend, reloc_size);
15834 else if (reloc_subtract)
15835 byte_put (rloc, addend - sym->st_value, reloc_size);
15836 else
15837 byte_put (rloc, addend + sym->st_value, reloc_size);
15840 free (symtab);
15841 /* Let the target specific reloc processing code know that
15842 we have finished with these relocs. */
15843 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
15845 if (relocs_return)
15847 * (Elf_Internal_Rela **) relocs_return = relocs;
15848 * num_relocs_return = num_relocs;
15850 else
15851 free (relocs);
15853 break;
15856 return true;
15859 #ifdef SUPPORT_DISASSEMBLY
15860 static bool
15861 disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
15863 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
15865 /* FIXME: XXX -- to be done --- XXX */
15867 return true;
15869 #endif
15871 /* Reads in the contents of SECTION from FILE, returning a pointer
15872 to a malloc'ed buffer or NULL if something went wrong. */
15874 static char *
15875 get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
15877 uint64_t num_bytes = section->sh_size;
15879 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15881 printf (_("Section '%s' has no data to dump.\n"),
15882 printable_section_name (filedata, section));
15883 return NULL;
15886 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
15887 _("section contents"));
15890 /* Uncompresses a section that was compressed using zlib/zstd, in place. */
15892 static bool
15893 uncompress_section_contents (bool is_zstd,
15894 unsigned char ** buffer,
15895 uint64_t uncompressed_size,
15896 uint64_t * size,
15897 uint64_t file_size)
15899 uint64_t compressed_size = *size;
15900 unsigned char *compressed_buffer = *buffer;
15901 unsigned char *uncompressed_buffer = NULL;
15902 z_stream strm;
15903 int rc;
15905 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15906 upper limit of ~10x compression. Any compression larger than that is
15907 thought to be due to fuzzing of the compression header. */
15908 if (uncompressed_size > file_size * 10)
15910 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15911 uncompressed_size);
15912 goto fail;
15915 uncompressed_buffer = xmalloc (uncompressed_size);
15917 if (is_zstd)
15919 #ifdef HAVE_ZSTD
15920 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15921 compressed_buffer, compressed_size);
15922 if (ZSTD_isError (ret))
15923 goto fail;
15924 #endif
15926 else
15928 /* It is possible the section consists of several compressed
15929 buffers concatenated together, so we uncompress in a loop. */
15930 /* PR 18313: The state field in the z_stream structure is supposed
15931 to be invisible to the user (ie us), but some compilers will
15932 still complain about it being used without initialisation. So
15933 we first zero the entire z_stream structure and then set the fields
15934 that we need. */
15935 memset (&strm, 0, sizeof strm);
15936 strm.avail_in = compressed_size;
15937 strm.next_in = (Bytef *)compressed_buffer;
15938 strm.avail_out = uncompressed_size;
15940 rc = inflateInit (&strm);
15941 while (strm.avail_in > 0)
15943 if (rc != Z_OK)
15944 break;
15945 strm.next_out = ((Bytef *)uncompressed_buffer
15946 + (uncompressed_size - strm.avail_out));
15947 rc = inflate (&strm, Z_FINISH);
15948 if (rc != Z_STREAM_END)
15949 break;
15950 rc = inflateReset (&strm);
15952 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15953 goto fail;
15956 *buffer = uncompressed_buffer;
15957 *size = uncompressed_size;
15958 return true;
15960 fail:
15961 free (uncompressed_buffer);
15962 /* Indicate decompression failure. */
15963 *buffer = NULL;
15964 return false;
15967 static uint64_t
15968 maybe_expand_or_relocate_section (Elf_Internal_Shdr * section,
15969 Filedata * filedata,
15970 unsigned char ** start_ptr,
15971 bool relocate)
15973 uint64_t section_size = section->sh_size;
15974 unsigned char * start = * start_ptr;
15976 if (decompress_dumps)
15978 uint64_t new_size = section_size;
15979 uint64_t uncompressed_size = 0;
15980 bool is_zstd = false;
15982 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15984 Elf_Internal_Chdr chdr;
15985 unsigned int compression_header_size
15986 = get_compression_header (& chdr, start, section_size);
15988 if (compression_header_size == 0)
15989 /* An error message will have already been generated
15990 by get_compression_header. */
15991 return (uint64_t) -1;
15993 if (chdr.ch_type == ch_compress_zlib)
15995 #ifdef HAVE_ZSTD
15996 else if (chdr.ch_type == ch_compress_zstd)
15997 is_zstd = true;
15998 #endif
15999 else
16001 warn (_("section '%s' has unsupported compress type: %d\n"),
16002 printable_section_name (filedata, section), chdr.ch_type);
16003 return (uint64_t) -1;
16006 uncompressed_size = chdr.ch_size;
16007 start += compression_header_size;
16008 new_size -= compression_header_size;
16010 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16012 /* Read the zlib header. In this case, it should be "ZLIB"
16013 followed by the uncompressed section size, 8 bytes in
16014 big-endian order. */
16015 uncompressed_size = start[4]; uncompressed_size <<= 8;
16016 uncompressed_size += start[5]; uncompressed_size <<= 8;
16017 uncompressed_size += start[6]; uncompressed_size <<= 8;
16018 uncompressed_size += start[7]; uncompressed_size <<= 8;
16019 uncompressed_size += start[8]; uncompressed_size <<= 8;
16020 uncompressed_size += start[9]; uncompressed_size <<= 8;
16021 uncompressed_size += start[10]; uncompressed_size <<= 8;
16022 uncompressed_size += start[11];
16023 start += 12;
16024 new_size -= 12;
16027 if (uncompressed_size)
16029 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
16030 &new_size, filedata->file_size))
16031 section_size = new_size;
16032 else
16034 error (_("Unable to decompress section %s\n"),
16035 printable_section_name (filedata, section));
16036 return (uint64_t) -1;
16039 else
16040 start = * start_ptr;
16042 else if (((section->sh_flags & SHF_COMPRESSED) != 0)
16043 || (section_size > 12 && streq ((char *) start, "ZLIB")))
16045 printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
16048 if (relocate)
16050 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
16051 return (uint64_t) -1;
16053 else
16055 Elf_Internal_Shdr *relsec;
16057 /* If the section being dumped has relocations against it the user might
16058 be expecting these relocations to have been applied. Check for this
16059 case and issue a warning message in order to avoid confusion.
16060 FIXME: Maybe we ought to have an option that dumps a section with
16061 relocs applied ? */
16062 for (relsec = filedata->section_headers;
16063 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16064 ++relsec)
16066 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16067 || relsec->sh_info >= filedata->file_header.e_shnum
16068 || filedata->section_headers + relsec->sh_info != section
16069 || relsec->sh_size == 0
16070 || relsec->sh_link >= filedata->file_header.e_shnum)
16071 continue;
16073 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16074 break;
16078 * start_ptr = start;
16079 return section_size;
16082 static bool
16083 dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
16085 uint64_t num_bytes;
16086 unsigned char *data;
16087 unsigned char *end;
16088 unsigned char *real_start;
16089 unsigned char *start;
16090 bool some_strings_shown;
16092 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16093 if (start == NULL)
16094 /* PR 21820: Do not fail if the section was empty. */
16095 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16097 num_bytes = section->sh_size;
16099 if (filedata->is_separate)
16100 printf (_("\nString dump of section '%s' in linked file %s:\n"),
16101 printable_section_name (filedata, section),
16102 filedata->file_name);
16103 else
16104 printf (_("\nString dump of section '%s':\n"),
16105 printable_section_name (filedata, section));
16107 num_bytes = maybe_expand_or_relocate_section (section, filedata, & start, false);
16108 if (num_bytes == (uint64_t) -1)
16109 goto error_out;
16111 data = start;
16112 end = start + num_bytes;
16113 some_strings_shown = false;
16115 #ifdef HAVE_MBSTATE_T
16116 mbstate_t state;
16117 /* Initialise the multibyte conversion state. */
16118 memset (& state, 0, sizeof (state));
16119 #endif
16121 bool continuing = false;
16123 while (data < end)
16125 while (!ISPRINT (* data))
16126 if (++ data >= end)
16127 break;
16129 if (data < end)
16131 size_t maxlen = end - data;
16133 if (continuing)
16135 printf (" ");
16136 continuing = false;
16138 else
16140 printf (" [%6tx] ", data - start);
16143 if (maxlen > 0)
16145 char c = 0;
16147 while (maxlen)
16149 c = *data++;
16151 if (c == 0)
16152 break;
16154 /* PR 25543: Treat new-lines as string-ending characters. */
16155 if (c == '\n')
16157 printf ("\\n\n");
16158 if (*data != 0)
16159 continuing = true;
16160 break;
16163 /* Do not print control characters directly as they can affect terminal
16164 settings. Such characters usually appear in the names generated
16165 by the assembler for local labels. */
16166 if (ISCNTRL (c))
16168 printf ("^%c", c + 0x40);
16170 else if (ISPRINT (c))
16172 putchar (c);
16174 else
16176 size_t n;
16177 #ifdef HAVE_MBSTATE_T
16178 wchar_t w;
16179 #endif
16180 /* Let printf do the hard work of displaying multibyte characters. */
16181 printf ("%.1s", data - 1);
16182 #ifdef HAVE_MBSTATE_T
16183 /* Try to find out how many bytes made up the character that was
16184 just printed. Advance the symbol pointer past the bytes that
16185 were displayed. */
16186 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16187 #else
16188 n = 1;
16189 #endif
16190 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16191 data += (n - 1);
16195 if (c != '\n')
16196 putchar ('\n');
16198 else
16200 printf (_("<corrupt>\n"));
16201 data = end;
16203 some_strings_shown = true;
16207 if (! some_strings_shown)
16208 printf (_(" No strings found in this section."));
16210 free (real_start);
16212 putchar ('\n');
16213 return true;
16215 error_out:
16216 free (real_start);
16217 return false;
16220 static bool
16221 dump_section_as_bytes (Elf_Internal_Shdr *section,
16222 Filedata *filedata,
16223 bool relocate)
16225 size_t bytes;
16226 uint64_t section_size;
16227 uint64_t addr;
16228 unsigned char *data;
16229 unsigned char *real_start;
16230 unsigned char *start;
16232 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16233 if (start == NULL)
16234 /* PR 21820: Do not fail if the section was empty. */
16235 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16237 section_size = section->sh_size;
16239 if (filedata->is_separate)
16240 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16241 printable_section_name (filedata, section),
16242 filedata->file_name);
16243 else
16244 printf (_("\nHex dump of section '%s':\n"),
16245 printable_section_name (filedata, section));
16247 section_size = maybe_expand_or_relocate_section (section, filedata, & start, relocate);
16248 if (section_size == (uint64_t) -1)
16249 goto error_out;
16251 addr = section->sh_addr;
16252 bytes = section_size;
16253 data = start;
16255 while (bytes)
16257 int j;
16258 int k;
16259 int lbytes;
16261 lbytes = (bytes > 16 ? 16 : bytes);
16263 printf (" 0x%8.8" PRIx64 " ", addr);
16265 for (j = 0; j < 16; j++)
16267 if (j < lbytes)
16268 printf ("%2.2x", data[j]);
16269 else
16270 printf (" ");
16272 if ((j & 3) == 3)
16273 printf (" ");
16276 for (j = 0; j < lbytes; j++)
16278 k = data[j];
16279 if (k >= ' ' && k < 0x7f)
16280 printf ("%c", k);
16281 else
16282 printf (".");
16285 putchar ('\n');
16287 data += lbytes;
16288 addr += lbytes;
16289 bytes -= lbytes;
16292 free (real_start);
16294 putchar ('\n');
16295 return true;
16297 error_out:
16298 free (real_start);
16299 return false;
16302 #ifdef ENABLE_LIBCTF
16303 static ctf_sect_t *
16304 shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16306 buf->cts_name = printable_section_name (filedata, shdr);
16307 buf->cts_size = shdr->sh_size;
16308 buf->cts_entsize = shdr->sh_entsize;
16310 return buf;
16313 /* Formatting callback function passed to ctf_dump. Returns either the pointer
16314 it is passed, or a pointer to newly-allocated storage, in which case
16315 dump_ctf() will free it when it no longer needs it. */
16317 static char *
16318 dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16319 char *s, void *arg)
16321 const char *blanks = arg;
16322 char *new_s;
16324 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
16325 return s;
16326 return new_s;
16329 /* Dump CTF errors/warnings. */
16330 static void
16331 dump_ctf_errs (ctf_dict_t *fp)
16333 ctf_next_t *it = NULL;
16334 char *errtext;
16335 int is_warning;
16336 int err;
16338 /* Dump accumulated errors and warnings. */
16339 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16341 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
16342 errtext);
16343 free (errtext);
16345 if (err != ECTF_NEXT_END)
16346 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16349 /* Dump one CTF archive member. */
16351 static void
16352 dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16353 size_t member)
16355 const char *things[] = {"Header", "Labels", "Data objects",
16356 "Function objects", "Variables", "Types", "Strings",
16357 ""};
16358 const char **thing;
16359 size_t i;
16361 /* Don't print out the name of the default-named archive member if it appears
16362 first in the list. The name .ctf appears everywhere, even for things that
16363 aren't really archives, so printing it out is liable to be confusing; also,
16364 the common case by far is for only one archive member to exist, and hiding
16365 it in that case seems worthwhile. */
16367 if (strcmp (name, ".ctf") != 0 || member != 0)
16368 printf (_("\nCTF archive member: %s:\n"), name);
16370 if (ctf_parent_name (ctf) != NULL)
16371 ctf_import (ctf, parent);
16373 for (i = 0, thing = things; *thing[0]; thing++, i++)
16375 ctf_dump_state_t *s = NULL;
16376 char *item;
16378 printf ("\n %s:\n", *thing);
16379 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16380 (void *) " ")) != NULL)
16382 printf ("%s\n", item);
16383 free (item);
16386 if (ctf_errno (ctf))
16388 error (_("Iteration failed: %s, %s\n"), *thing,
16389 ctf_errmsg (ctf_errno (ctf)));
16390 break;
16394 dump_ctf_errs (ctf);
16397 static bool
16398 dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16400 Elf_Internal_Shdr * symtab_sec = NULL;
16401 Elf_Internal_Shdr * strtab_sec = NULL;
16402 void * data = NULL;
16403 void * symdata = NULL;
16404 void * strdata = NULL;
16405 ctf_sect_t ctfsect, symsect, strsect;
16406 ctf_sect_t * symsectp = NULL;
16407 ctf_sect_t * strsectp = NULL;
16408 ctf_archive_t * ctfa = NULL;
16409 ctf_dict_t * parent = NULL;
16410 ctf_dict_t * fp;
16412 ctf_next_t *i = NULL;
16413 const char *name;
16414 size_t member = 0;
16415 int err;
16416 bool ret = false;
16418 shdr_to_ctf_sect (&ctfsect, section, filedata);
16419 data = get_section_contents (section, filedata);
16420 ctfsect.cts_data = data;
16422 if (!dump_ctf_symtab_name)
16423 dump_ctf_symtab_name = strdup (".dynsym");
16425 if (!dump_ctf_strtab_name)
16426 dump_ctf_strtab_name = strdup (".dynstr");
16428 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
16430 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16432 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16433 goto fail;
16435 if ((symdata = (void *) get_data (NULL, filedata,
16436 symtab_sec->sh_offset, 1,
16437 symtab_sec->sh_size,
16438 _("symbols"))) == NULL)
16439 goto fail;
16440 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16441 symsect.cts_data = symdata;
16444 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
16446 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16448 error (_("No string table section named %s\n"),
16449 dump_ctf_strtab_name);
16450 goto fail;
16452 if ((strdata = (void *) get_data (NULL, filedata,
16453 strtab_sec->sh_offset, 1,
16454 strtab_sec->sh_size,
16455 _("strings"))) == NULL)
16456 goto fail;
16457 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16458 strsect.cts_data = strdata;
16461 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16462 libctf papers over the difference, so we can pretend it is always an
16463 archive. */
16465 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
16467 dump_ctf_errs (NULL);
16468 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16469 goto fail;
16472 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16473 != ELFDATA2MSB);
16475 /* Preload the parent dict, since it will need to be imported into every
16476 child in turn. */
16477 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
16479 dump_ctf_errs (NULL);
16480 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16481 goto fail;
16484 ret = true;
16486 if (filedata->is_separate)
16487 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16488 printable_section_name (filedata, section),
16489 filedata->file_name);
16490 else
16491 printf (_("\nDump of CTF section '%s':\n"),
16492 printable_section_name (filedata, section));
16494 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16495 dump_ctf_archive_member (fp, name, parent, member++);
16496 if (err != ECTF_NEXT_END)
16498 dump_ctf_errs (NULL);
16499 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16500 ret = false;
16503 fail:
16504 ctf_dict_close (parent);
16505 ctf_close (ctfa);
16506 free (data);
16507 free (symdata);
16508 free (strdata);
16509 return ret;
16511 #endif
16513 static bool
16514 dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16516 void * data = NULL;
16517 sframe_decoder_ctx *sfd_ctx = NULL;
16518 const char *print_name = printable_section_name (filedata, section);
16520 bool ret = true;
16521 size_t sf_size;
16522 int err = 0;
16524 if (strcmp (print_name, "") == 0)
16526 error (_("Section name must be provided \n"));
16527 ret = false;
16528 return ret;
16531 data = get_section_contents (section, filedata);
16532 sf_size = section->sh_size;
16533 /* Decode the contents of the section. */
16534 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16535 if (!sfd_ctx)
16537 ret = false;
16538 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16539 goto fail;
16542 printf (_("Contents of the SFrame section %s:"), print_name);
16543 /* Dump the contents as text. */
16544 dump_sframe (sfd_ctx, section->sh_addr);
16546 fail:
16547 free (data);
16548 return ret;
16551 static bool
16552 load_specific_debug_section (enum dwarf_section_display_enum debug,
16553 const Elf_Internal_Shdr * sec,
16554 void * data)
16556 struct dwarf_section * section = &debug_displays [debug].section;
16557 char buf [64];
16558 Filedata * filedata = (Filedata *) data;
16560 if (section->start != NULL)
16562 /* If it is already loaded, do nothing. */
16563 if (streq (section->filename, filedata->file_name))
16564 return true;
16565 free (section->start);
16568 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16569 section->address = sec->sh_addr;
16570 section->filename = filedata->file_name;
16571 section->start = (unsigned char *) get_data (NULL, filedata,
16572 sec->sh_offset, 1,
16573 sec->sh_size, buf);
16574 if (section->start == NULL)
16575 section->size = 0;
16576 else
16578 unsigned char *start = section->start;
16579 uint64_t size = sec->sh_size;
16580 uint64_t uncompressed_size = 0;
16581 bool is_zstd = false;
16583 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16585 Elf_Internal_Chdr chdr;
16586 unsigned int compression_header_size;
16588 if (size < (is_32bit_elf
16589 ? sizeof (Elf32_External_Chdr)
16590 : sizeof (Elf64_External_Chdr)))
16592 warn (_("compressed section %s is too small to contain a compression header\n"),
16593 section->name);
16594 return false;
16597 compression_header_size = get_compression_header (&chdr, start, size);
16598 if (compression_header_size == 0)
16599 /* An error message will have already been generated
16600 by get_compression_header. */
16601 return false;
16603 if (chdr.ch_type == ch_compress_zlib)
16605 #ifdef HAVE_ZSTD
16606 else if (chdr.ch_type == ch_compress_zstd)
16607 is_zstd = true;
16608 #endif
16609 else
16611 warn (_("section '%s' has unsupported compress type: %d\n"),
16612 section->name, chdr.ch_type);
16613 return false;
16615 uncompressed_size = chdr.ch_size;
16616 start += compression_header_size;
16617 size -= compression_header_size;
16619 else if (size > 12 && streq ((char *) start, "ZLIB"))
16621 /* Read the zlib header. In this case, it should be "ZLIB"
16622 followed by the uncompressed section size, 8 bytes in
16623 big-endian order. */
16624 uncompressed_size = start[4]; uncompressed_size <<= 8;
16625 uncompressed_size += start[5]; uncompressed_size <<= 8;
16626 uncompressed_size += start[6]; uncompressed_size <<= 8;
16627 uncompressed_size += start[7]; uncompressed_size <<= 8;
16628 uncompressed_size += start[8]; uncompressed_size <<= 8;
16629 uncompressed_size += start[9]; uncompressed_size <<= 8;
16630 uncompressed_size += start[10]; uncompressed_size <<= 8;
16631 uncompressed_size += start[11];
16632 start += 12;
16633 size -= 12;
16636 if (uncompressed_size)
16638 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
16639 &size, filedata->file_size))
16641 /* Free the compressed buffer, update the section buffer
16642 and the section size if uncompress is successful. */
16643 free (section->start);
16644 section->start = start;
16646 else
16648 error (_("Unable to decompress section %s\n"),
16649 printable_section_name (filedata, sec));
16650 return false;
16654 section->size = size;
16657 if (section->start == NULL)
16658 return false;
16660 if (debug_displays [debug].relocate)
16662 if (! apply_relocations (filedata, sec, section->start, section->size,
16663 & section->reloc_info, & section->num_relocs))
16664 return false;
16666 else
16668 section->reloc_info = NULL;
16669 section->num_relocs = 0;
16672 return true;
16675 #if HAVE_LIBDEBUGINFOD
16676 /* Return a hex string representation of the build-id. */
16677 unsigned char *
16678 get_build_id (void * data)
16680 Filedata * filedata = (Filedata *) data;
16681 Elf_Internal_Shdr * shdr;
16682 size_t i;
16684 /* Iterate through notes to find note.gnu.build-id.
16685 FIXME: Only the first note in any note section is examined. */
16686 for (i = 0, shdr = filedata->section_headers;
16687 i < filedata->file_header.e_shnum && shdr != NULL;
16688 i++, shdr++)
16690 if (shdr->sh_type != SHT_NOTE)
16691 continue;
16693 char * next;
16694 char * end;
16695 size_t data_remaining;
16696 size_t min_notesz;
16697 Elf_External_Note * enote;
16698 Elf_Internal_Note inote;
16700 uint64_t offset = shdr->sh_offset;
16701 uint64_t align = shdr->sh_addralign;
16702 uint64_t length = shdr->sh_size;
16704 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16705 if (enote == NULL)
16706 continue;
16708 if (align < 4)
16709 align = 4;
16710 else if (align != 4 && align != 8)
16712 free (enote);
16713 continue;
16716 end = (char *) enote + length;
16717 data_remaining = end - (char *) enote;
16719 if (!is_ia64_vms (filedata))
16721 min_notesz = offsetof (Elf_External_Note, name);
16722 if (data_remaining < min_notesz)
16724 warn (_("\
16725 malformed note encountered in section %s whilst scanning for build-id note\n"),
16726 printable_section_name (filedata, shdr));
16727 free (enote);
16728 continue;
16730 data_remaining -= min_notesz;
16732 inote.type = BYTE_GET (enote->type);
16733 inote.namesz = BYTE_GET (enote->namesz);
16734 inote.namedata = enote->name;
16735 inote.descsz = BYTE_GET (enote->descsz);
16736 inote.descdata = ((char *) enote
16737 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16738 inote.descpos = offset + (inote.descdata - (char *) enote);
16739 next = ((char *) enote
16740 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16742 else
16744 Elf64_External_VMS_Note *vms_enote;
16746 /* PR binutils/15191
16747 Make sure that there is enough data to read. */
16748 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16749 if (data_remaining < min_notesz)
16751 warn (_("\
16752 malformed note encountered in section %s whilst scanning for build-id note\n"),
16753 printable_section_name (filedata, shdr));
16754 free (enote);
16755 continue;
16757 data_remaining -= min_notesz;
16759 vms_enote = (Elf64_External_VMS_Note *) enote;
16760 inote.type = BYTE_GET (vms_enote->type);
16761 inote.namesz = BYTE_GET (vms_enote->namesz);
16762 inote.namedata = vms_enote->name;
16763 inote.descsz = BYTE_GET (vms_enote->descsz);
16764 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16765 inote.descpos = offset + (inote.descdata - (char *) enote);
16766 next = inote.descdata + align_power (inote.descsz, 3);
16769 /* Skip malformed notes. */
16770 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16771 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16772 || (size_t) (next - inote.descdata) < inote.descsz
16773 || ((size_t) (next - inote.descdata)
16774 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16776 warn (_("\
16777 malformed note encountered in section %s whilst scanning for build-id note\n"),
16778 printable_section_name (filedata, shdr));
16779 free (enote);
16780 continue;
16783 /* Check if this is the build-id note. If so then convert the build-id
16784 bytes to a hex string. */
16785 if (inote.namesz > 0
16786 && startswith (inote.namedata, "GNU")
16787 && inote.type == NT_GNU_BUILD_ID)
16789 size_t j;
16790 char * build_id;
16792 build_id = malloc (inote.descsz * 2 + 1);
16793 if (build_id == NULL)
16795 free (enote);
16796 return NULL;
16799 for (j = 0; j < inote.descsz; ++j)
16800 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16801 build_id[inote.descsz * 2] = '\0';
16802 free (enote);
16804 return (unsigned char *) build_id;
16806 free (enote);
16809 return NULL;
16811 #endif /* HAVE_LIBDEBUGINFOD */
16813 /* If this is not NULL, load_debug_section will only look for sections
16814 within the list of sections given here. */
16815 static unsigned int * section_subset = NULL;
16817 bool
16818 load_debug_section (enum dwarf_section_display_enum debug, void * data)
16820 struct dwarf_section * section = &debug_displays [debug].section;
16821 Elf_Internal_Shdr * sec;
16822 Filedata * filedata = (Filedata *) data;
16824 if (!dump_any_debugging)
16825 return false;
16827 /* Without section headers we cannot find any sections. */
16828 if (filedata->section_headers == NULL)
16829 return false;
16831 if (filedata->string_table == NULL
16832 && filedata->file_header.e_shstrndx != SHN_UNDEF
16833 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
16835 Elf_Internal_Shdr * strs;
16837 /* Read in the string table, so that we have section names to scan. */
16838 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16840 if (strs != NULL && strs->sh_size != 0)
16842 filedata->string_table
16843 = (char *) get_data (NULL, filedata, strs->sh_offset,
16844 1, strs->sh_size, _("string table"));
16846 filedata->string_table_length
16847 = filedata->string_table != NULL ? strs->sh_size : 0;
16851 /* Locate the debug section. */
16852 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
16853 if (sec != NULL)
16854 section->name = section->uncompressed_name;
16855 else
16857 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
16858 if (sec != NULL)
16859 section->name = section->compressed_name;
16861 if (sec == NULL)
16862 return false;
16864 /* If we're loading from a subset of sections, and we've loaded
16865 a section matching this name before, it's likely that it's a
16866 different one. */
16867 if (section_subset != NULL)
16868 free_debug_section (debug);
16870 return load_specific_debug_section (debug, sec, data);
16873 void
16874 free_debug_section (enum dwarf_section_display_enum debug)
16876 struct dwarf_section * section = &debug_displays [debug].section;
16878 if (section->start == NULL)
16879 return;
16881 free ((char *) section->start);
16882 section->start = NULL;
16883 section->address = 0;
16884 section->size = 0;
16886 free (section->reloc_info);
16887 section->reloc_info = NULL;
16888 section->num_relocs = 0;
16891 static bool
16892 display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
16894 const char *name = (section_name_valid (filedata, section)
16895 ? section_name (filedata, section) : "");
16896 const char *print_name = printable_section_name (filedata, section);
16897 uint64_t length;
16898 bool result = true;
16899 int i;
16901 length = section->sh_size;
16902 if (length == 0)
16904 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
16905 return true;
16907 if (section->sh_type == SHT_NOBITS)
16909 /* There is no point in dumping the contents of a debugging section
16910 which has the NOBITS type - the bits in the file will be random.
16911 This can happen when a file containing a .eh_frame section is
16912 stripped with the --only-keep-debug command line option. */
16913 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16914 print_name);
16915 return false;
16918 if (startswith (name, ".gnu.linkonce.wi."))
16919 name = ".debug_info";
16921 /* See if we know how to display the contents of this section. */
16922 for (i = 0; i < max; i++)
16924 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16925 struct dwarf_section_display * display = debug_displays + i;
16926 struct dwarf_section * sec = & display->section;
16928 if (streq (sec->uncompressed_name, name)
16929 || (id == line && startswith (name, ".debug_line."))
16930 || streq (sec->compressed_name, name))
16932 bool secondary = (section != find_section (filedata, name));
16934 if (secondary)
16935 free_debug_section (id);
16937 if (i == line && startswith (name, ".debug_line."))
16938 sec->name = name;
16939 else if (streq (sec->uncompressed_name, name))
16940 sec->name = sec->uncompressed_name;
16941 else
16942 sec->name = sec->compressed_name;
16944 if (load_specific_debug_section (id, section, filedata))
16946 /* If this debug section is part of a CU/TU set in a .dwp file,
16947 restrict load_debug_section to the sections in that set. */
16948 section_subset = find_cu_tu_set (filedata, shndx);
16950 result &= display->display (sec, filedata);
16952 section_subset = NULL;
16954 if (secondary || (id != info && id != abbrev && id != debug_addr))
16955 free_debug_section (id);
16957 break;
16961 if (i == max)
16963 printf (_("Unrecognized debug section: %s\n"), print_name);
16964 result = false;
16967 return result;
16970 /* Set DUMP_SECTS for all sections where dumps were requested
16971 based on section name. */
16973 static void
16974 initialise_dumps_byname (Filedata * filedata)
16976 struct dump_list_entry * cur;
16978 for (cur = dump_sects_byname; cur; cur = cur->next)
16980 unsigned int i;
16981 bool any = false;
16983 for (i = 0; i < filedata->file_header.e_shnum; i++)
16984 if (section_name_valid (filedata, filedata->section_headers + i)
16985 && streq (section_name (filedata, filedata->section_headers + i),
16986 cur->name))
16988 request_dump_bynumber (&filedata->dump, i, cur->type);
16989 any = true;
16992 if (!any && !filedata->is_separate)
16993 warn (_("Section '%s' was not dumped because it does not exist\n"),
16994 cur->name);
16998 static bool
16999 process_section_contents (Filedata * filedata)
17001 Elf_Internal_Shdr * section;
17002 unsigned int i;
17003 bool res = true;
17005 if (! do_dump)
17006 return true;
17008 initialise_dumps_byname (filedata);
17010 for (i = 0, section = filedata->section_headers;
17011 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
17012 i++, section++)
17014 dump_type dump = filedata->dump.dump_sects[i];
17016 if (filedata->is_separate && ! process_links)
17017 dump &= DEBUG_DUMP;
17019 #ifdef SUPPORT_DISASSEMBLY
17020 if (dump & DISASS_DUMP)
17022 if (! disassemble_section (section, filedata))
17023 res = false;
17025 #endif
17026 if (dump & HEX_DUMP)
17028 if (! dump_section_as_bytes (section, filedata, false))
17029 res = false;
17032 if (dump & RELOC_DUMP)
17034 if (! dump_section_as_bytes (section, filedata, true))
17035 res = false;
17038 if (dump & STRING_DUMP)
17040 if (! dump_section_as_strings (section, filedata))
17041 res = false;
17044 if (dump & DEBUG_DUMP)
17046 if (! display_debug_section (i, section, filedata))
17047 res = false;
17050 #ifdef ENABLE_LIBCTF
17051 if (dump & CTF_DUMP)
17053 if (! dump_section_as_ctf (section, filedata))
17054 res = false;
17056 #endif
17057 if (dump & SFRAME_DUMP)
17059 if (! dump_section_as_sframe (section, filedata))
17060 res = false;
17064 if (! filedata->is_separate)
17066 /* Check to see if the user requested a
17067 dump of a section that does not exist. */
17068 for (; i < filedata->dump.num_dump_sects; i++)
17069 if (filedata->dump.dump_sects[i])
17071 warn (_("Section %d was not dumped because it does not exist!\n"), i);
17072 res = false;
17076 return res;
17079 static void
17080 process_mips_fpe_exception (int mask)
17082 if (mask)
17084 bool first = true;
17086 if (mask & OEX_FPU_INEX)
17087 fputs ("INEX", stdout), first = false;
17088 if (mask & OEX_FPU_UFLO)
17089 printf ("%sUFLO", first ? "" : "|"), first = false;
17090 if (mask & OEX_FPU_OFLO)
17091 printf ("%sOFLO", first ? "" : "|"), first = false;
17092 if (mask & OEX_FPU_DIV0)
17093 printf ("%sDIV0", first ? "" : "|"), first = false;
17094 if (mask & OEX_FPU_INVAL)
17095 printf ("%sINVAL", first ? "" : "|");
17097 else
17098 fputs ("0", stdout);
17101 /* Display's the value of TAG at location P. If TAG is
17102 greater than 0 it is assumed to be an unknown tag, and
17103 a message is printed to this effect. Otherwise it is
17104 assumed that a message has already been printed.
17106 If the bottom bit of TAG is set it assumed to have a
17107 string value, otherwise it is assumed to have an integer
17108 value.
17110 Returns an updated P pointing to the first unread byte
17111 beyond the end of TAG's value.
17113 Reads at or beyond END will not be made. */
17115 static unsigned char *
17116 display_tag_value (signed int tag,
17117 unsigned char * p,
17118 const unsigned char * const end)
17120 uint64_t val;
17122 if (tag > 0)
17123 printf (" Tag_unknown_%d: ", tag);
17125 if (p >= end)
17127 warn (_("<corrupt tag>\n"));
17129 else if (tag & 1)
17131 /* PR 17531 file: 027-19978-0.004. */
17132 size_t maxlen = (end - p) - 1;
17134 putchar ('"');
17135 if (maxlen > 0)
17137 print_symbol_name ((int) maxlen, (const char *) p);
17138 p += strnlen ((char *) p, maxlen) + 1;
17140 else
17142 printf (_("<corrupt string tag>"));
17143 p = (unsigned char *) end;
17145 printf ("\"\n");
17147 else
17149 READ_ULEB (val, p, end);
17150 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
17153 assert (p <= end);
17154 return p;
17157 /* ARC ABI attributes section. */
17159 static unsigned char *
17160 display_arc_attribute (unsigned char * p,
17161 const unsigned char * const end)
17163 unsigned int tag;
17164 unsigned int val;
17166 READ_ULEB (tag, p, end);
17168 switch (tag)
17170 case Tag_ARC_PCS_config:
17171 READ_ULEB (val, p, end);
17172 printf (" Tag_ARC_PCS_config: ");
17173 switch (val)
17175 case 0:
17176 printf (_("Absent/Non standard\n"));
17177 break;
17178 case 1:
17179 printf (_("Bare metal/mwdt\n"));
17180 break;
17181 case 2:
17182 printf (_("Bare metal/newlib\n"));
17183 break;
17184 case 3:
17185 printf (_("Linux/uclibc\n"));
17186 break;
17187 case 4:
17188 printf (_("Linux/glibc\n"));
17189 break;
17190 default:
17191 printf (_("Unknown\n"));
17192 break;
17194 break;
17196 case Tag_ARC_CPU_base:
17197 READ_ULEB (val, p, end);
17198 printf (" Tag_ARC_CPU_base: ");
17199 switch (val)
17201 default:
17202 case TAG_CPU_NONE:
17203 printf (_("Absent\n"));
17204 break;
17205 case TAG_CPU_ARC6xx:
17206 printf ("ARC6xx\n");
17207 break;
17208 case TAG_CPU_ARC7xx:
17209 printf ("ARC7xx\n");
17210 break;
17211 case TAG_CPU_ARCEM:
17212 printf ("ARCEM\n");
17213 break;
17214 case TAG_CPU_ARCHS:
17215 printf ("ARCHS\n");
17216 break;
17218 break;
17220 case Tag_ARC_CPU_variation:
17221 READ_ULEB (val, p, end);
17222 printf (" Tag_ARC_CPU_variation: ");
17223 switch (val)
17225 default:
17226 if (val > 0 && val < 16)
17227 printf ("Core%d\n", val);
17228 else
17229 printf ("Unknown\n");
17230 break;
17232 case 0:
17233 printf (_("Absent\n"));
17234 break;
17236 break;
17238 case Tag_ARC_CPU_name:
17239 printf (" Tag_ARC_CPU_name: ");
17240 p = display_tag_value (-1, p, end);
17241 break;
17243 case Tag_ARC_ABI_rf16:
17244 READ_ULEB (val, p, end);
17245 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17246 break;
17248 case Tag_ARC_ABI_osver:
17249 READ_ULEB (val, p, end);
17250 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17251 break;
17253 case Tag_ARC_ABI_pic:
17254 case Tag_ARC_ABI_sda:
17255 READ_ULEB (val, p, end);
17256 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17257 : " Tag_ARC_ABI_pic: ");
17258 switch (val)
17260 case 0:
17261 printf (_("Absent\n"));
17262 break;
17263 case 1:
17264 printf ("MWDT\n");
17265 break;
17266 case 2:
17267 printf ("GNU\n");
17268 break;
17269 default:
17270 printf (_("Unknown\n"));
17271 break;
17273 break;
17275 case Tag_ARC_ABI_tls:
17276 READ_ULEB (val, p, end);
17277 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17278 break;
17280 case Tag_ARC_ABI_enumsize:
17281 READ_ULEB (val, p, end);
17282 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17283 _("smallest"));
17284 break;
17286 case Tag_ARC_ABI_exceptions:
17287 READ_ULEB (val, p, end);
17288 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17289 : _("default"));
17290 break;
17292 case Tag_ARC_ABI_double_size:
17293 READ_ULEB (val, p, end);
17294 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17295 break;
17297 case Tag_ARC_ISA_config:
17298 printf (" Tag_ARC_ISA_config: ");
17299 p = display_tag_value (-1, p, end);
17300 break;
17302 case Tag_ARC_ISA_apex:
17303 printf (" Tag_ARC_ISA_apex: ");
17304 p = display_tag_value (-1, p, end);
17305 break;
17307 case Tag_ARC_ISA_mpy_option:
17308 READ_ULEB (val, p, end);
17309 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17310 break;
17312 case Tag_ARC_ATR_version:
17313 READ_ULEB (val, p, end);
17314 printf (" Tag_ARC_ATR_version: %d\n", val);
17315 break;
17317 default:
17318 return display_tag_value (tag & 1, p, end);
17321 return p;
17324 /* ARM EABI attributes section. */
17325 typedef struct
17327 unsigned int tag;
17328 const char * name;
17329 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
17330 unsigned int type;
17331 const char *const *table;
17332 } arm_attr_public_tag;
17334 static const char *const arm_attr_tag_CPU_arch[] =
17335 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
17336 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
17337 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17338 "v8.1-M.mainline", "v9"};
17339 static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17340 static const char *const arm_attr_tag_THUMB_ISA_use[] =
17341 {"No", "Thumb-1", "Thumb-2", "Yes"};
17342 static const char *const arm_attr_tag_FP_arch[] =
17343 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
17344 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
17345 static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17346 static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
17347 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17348 "NEON for ARMv8.1"};
17349 static const char *const arm_attr_tag_PCS_config[] =
17350 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17351 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
17352 static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
17353 {"V6", "SB", "TLS", "Unused"};
17354 static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
17355 {"Absolute", "PC-relative", "SB-relative", "None"};
17356 static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
17357 {"Absolute", "PC-relative", "None"};
17358 static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
17359 {"None", "direct", "GOT-indirect"};
17360 static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
17361 {"None", "??? 1", "2", "??? 3", "4"};
17362 static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17363 static const char *const arm_attr_tag_ABI_FP_denormal[] =
17364 {"Unused", "Needed", "Sign only"};
17365 static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17366 static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17367 static const char *const arm_attr_tag_ABI_FP_number_model[] =
17368 {"Unused", "Finite", "RTABI", "IEEE 754"};
17369 static const char *const arm_attr_tag_ABI_enum_size[] =
17370 {"Unused", "small", "int", "forced to int"};
17371 static const char *const arm_attr_tag_ABI_HardFP_use[] =
17372 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
17373 static const char *const arm_attr_tag_ABI_VFP_args[] =
17374 {"AAPCS", "VFP registers", "custom", "compatible"};
17375 static const char *const arm_attr_tag_ABI_WMMX_args[] =
17376 {"AAPCS", "WMMX registers", "custom"};
17377 static const char *const arm_attr_tag_ABI_optimization_goals[] =
17378 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17379 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
17380 static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
17381 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17382 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
17383 static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17384 static const char *const arm_attr_tag_FP_HP_extension[] =
17385 {"Not Allowed", "Allowed"};
17386 static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
17387 {"None", "IEEE 754", "Alternative Format"};
17388 static const char *const arm_attr_tag_DSP_extension[] =
17389 {"Follow architecture", "Allowed"};
17390 static const char *const arm_attr_tag_MPextension_use[] =
17391 {"Not Allowed", "Allowed"};
17392 static const char *const arm_attr_tag_DIV_use[] =
17393 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
17394 "Allowed in v7-A with integer division extension"};
17395 static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
17396 static const char *const arm_attr_tag_Virtualization_use[] =
17397 {"Not Allowed", "TrustZone", "Virtualization Extensions",
17398 "TrustZone and Virtualization Extensions"};
17399 static const char *const arm_attr_tag_MPextension_use_legacy[] =
17400 {"Not Allowed", "Allowed"};
17402 static const char *const arm_attr_tag_MVE_arch[] =
17403 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
17405 static const char * arm_attr_tag_PAC_extension[] =
17406 {"No PAC/AUT instructions",
17407 "PAC/AUT instructions permitted in the NOP space",
17408 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
17410 static const char * arm_attr_tag_BTI_extension[] =
17411 {"BTI instructions not permitted",
17412 "BTI instructions permitted in the NOP space",
17413 "BTI instructions permitted in the NOP and in the non-NOP space"};
17415 static const char * arm_attr_tag_BTI_use[] =
17416 {"Compiled without branch target enforcement",
17417 "Compiled with branch target enforcement"};
17419 static const char * arm_attr_tag_PACRET_use[] =
17420 {"Compiled without return address signing and authentication",
17421 "Compiled with return address signing and authentication"};
17423 #define LOOKUP(id, name) \
17424 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
17425 static arm_attr_public_tag arm_attr_public_tags[] =
17427 {4, "CPU_raw_name", 1, NULL},
17428 {5, "CPU_name", 1, NULL},
17429 LOOKUP(6, CPU_arch),
17430 {7, "CPU_arch_profile", 0, NULL},
17431 LOOKUP(8, ARM_ISA_use),
17432 LOOKUP(9, THUMB_ISA_use),
17433 LOOKUP(10, FP_arch),
17434 LOOKUP(11, WMMX_arch),
17435 LOOKUP(12, Advanced_SIMD_arch),
17436 LOOKUP(13, PCS_config),
17437 LOOKUP(14, ABI_PCS_R9_use),
17438 LOOKUP(15, ABI_PCS_RW_data),
17439 LOOKUP(16, ABI_PCS_RO_data),
17440 LOOKUP(17, ABI_PCS_GOT_use),
17441 LOOKUP(18, ABI_PCS_wchar_t),
17442 LOOKUP(19, ABI_FP_rounding),
17443 LOOKUP(20, ABI_FP_denormal),
17444 LOOKUP(21, ABI_FP_exceptions),
17445 LOOKUP(22, ABI_FP_user_exceptions),
17446 LOOKUP(23, ABI_FP_number_model),
17447 {24, "ABI_align_needed", 0, NULL},
17448 {25, "ABI_align_preserved", 0, NULL},
17449 LOOKUP(26, ABI_enum_size),
17450 LOOKUP(27, ABI_HardFP_use),
17451 LOOKUP(28, ABI_VFP_args),
17452 LOOKUP(29, ABI_WMMX_args),
17453 LOOKUP(30, ABI_optimization_goals),
17454 LOOKUP(31, ABI_FP_optimization_goals),
17455 {32, "compatibility", 0, NULL},
17456 LOOKUP(34, CPU_unaligned_access),
17457 LOOKUP(36, FP_HP_extension),
17458 LOOKUP(38, ABI_FP_16bit_format),
17459 LOOKUP(42, MPextension_use),
17460 LOOKUP(44, DIV_use),
17461 LOOKUP(46, DSP_extension),
17462 LOOKUP(48, MVE_arch),
17463 LOOKUP(50, PAC_extension),
17464 LOOKUP(52, BTI_extension),
17465 LOOKUP(74, BTI_use),
17466 LOOKUP(76, PACRET_use),
17467 {64, "nodefaults", 0, NULL},
17468 {65, "also_compatible_with", 0, NULL},
17469 LOOKUP(66, T2EE_use),
17470 {67, "conformance", 1, NULL},
17471 LOOKUP(68, Virtualization_use),
17472 LOOKUP(70, MPextension_use_legacy)
17474 #undef LOOKUP
17476 static unsigned char *
17477 display_arm_attribute (unsigned char * p,
17478 const unsigned char * const end)
17480 unsigned int tag;
17481 unsigned int val;
17482 arm_attr_public_tag * attr;
17483 unsigned i;
17484 unsigned int type;
17486 READ_ULEB (tag, p, end);
17487 attr = NULL;
17488 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
17490 if (arm_attr_public_tags[i].tag == tag)
17492 attr = &arm_attr_public_tags[i];
17493 break;
17497 if (attr)
17499 printf (" Tag_%s: ", attr->name);
17500 switch (attr->type)
17502 case 0:
17503 switch (tag)
17505 case 7: /* Tag_CPU_arch_profile. */
17506 READ_ULEB (val, p, end);
17507 switch (val)
17509 case 0: printf (_("None\n")); break;
17510 case 'A': printf (_("Application\n")); break;
17511 case 'R': printf (_("Realtime\n")); break;
17512 case 'M': printf (_("Microcontroller\n")); break;
17513 case 'S': printf (_("Application or Realtime\n")); break;
17514 default: printf ("??? (%d)\n", val); break;
17516 break;
17518 case 24: /* Tag_align_needed. */
17519 READ_ULEB (val, p, end);
17520 switch (val)
17522 case 0: printf (_("None\n")); break;
17523 case 1: printf (_("8-byte\n")); break;
17524 case 2: printf (_("4-byte\n")); break;
17525 case 3: printf ("??? 3\n"); break;
17526 default:
17527 if (val <= 12)
17528 printf (_("8-byte and up to %d-byte extended\n"),
17529 1 << val);
17530 else
17531 printf ("??? (%d)\n", val);
17532 break;
17534 break;
17536 case 25: /* Tag_align_preserved. */
17537 READ_ULEB (val, p, end);
17538 switch (val)
17540 case 0: printf (_("None\n")); break;
17541 case 1: printf (_("8-byte, except leaf SP\n")); break;
17542 case 2: printf (_("8-byte\n")); break;
17543 case 3: printf ("??? 3\n"); break;
17544 default:
17545 if (val <= 12)
17546 printf (_("8-byte and up to %d-byte extended\n"),
17547 1 << val);
17548 else
17549 printf ("??? (%d)\n", val);
17550 break;
17552 break;
17554 case 32: /* Tag_compatibility. */
17556 READ_ULEB (val, p, end);
17557 printf (_("flag = %d, vendor = "), val);
17558 if (p < end - 1)
17560 size_t maxlen = (end - p) - 1;
17562 print_symbol_name ((int) maxlen, (const char *) p);
17563 p += strnlen ((char *) p, maxlen) + 1;
17565 else
17567 printf (_("<corrupt>"));
17568 p = (unsigned char *) end;
17570 putchar ('\n');
17572 break;
17574 case 64: /* Tag_nodefaults. */
17575 /* PR 17531: file: 001-505008-0.01. */
17576 if (p < end)
17577 p++;
17578 printf (_("True\n"));
17579 break;
17581 case 65: /* Tag_also_compatible_with. */
17582 READ_ULEB (val, p, end);
17583 if (val == 6 /* Tag_CPU_arch. */)
17585 READ_ULEB (val, p, end);
17586 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
17587 printf ("??? (%d)\n", val);
17588 else
17589 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17591 else
17592 printf ("???\n");
17593 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17595 break;
17597 default:
17598 printf (_("<unknown: %d>\n"), tag);
17599 break;
17601 return p;
17603 case 1:
17604 return display_tag_value (-1, p, end);
17605 case 2:
17606 return display_tag_value (0, p, end);
17608 default:
17609 assert (attr->type & 0x80);
17610 READ_ULEB (val, p, end);
17611 type = attr->type & 0x7f;
17612 if (val >= type)
17613 printf ("??? (%d)\n", val);
17614 else
17615 printf ("%s\n", attr->table[val]);
17616 return p;
17620 return display_tag_value (tag, p, end);
17623 static unsigned char *
17624 display_gnu_attribute (unsigned char * p,
17625 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
17626 const unsigned char * const end)
17628 unsigned int tag;
17629 unsigned int val;
17631 READ_ULEB (tag, p, end);
17633 /* Tag_compatibility is the only generic GNU attribute defined at
17634 present. */
17635 if (tag == 32)
17637 READ_ULEB (val, p, end);
17639 printf (_("flag = %d, vendor = "), val);
17640 if (p == end)
17642 printf (_("<corrupt>\n"));
17643 warn (_("corrupt vendor attribute\n"));
17645 else
17647 if (p < end - 1)
17649 size_t maxlen = (end - p) - 1;
17651 print_symbol_name ((int) maxlen, (const char *) p);
17652 p += strnlen ((char *) p, maxlen) + 1;
17654 else
17656 printf (_("<corrupt>"));
17657 p = (unsigned char *) end;
17659 putchar ('\n');
17661 return p;
17664 if ((tag & 2) == 0 && display_proc_gnu_attribute)
17665 return display_proc_gnu_attribute (p, tag, end);
17667 return display_tag_value (tag, p, end);
17670 static unsigned char *
17671 display_m68k_gnu_attribute (unsigned char * p,
17672 unsigned int tag,
17673 const unsigned char * const end)
17675 unsigned int val;
17677 if (tag == Tag_GNU_M68K_ABI_FP)
17679 printf (" Tag_GNU_M68K_ABI_FP: ");
17680 if (p == end)
17682 printf (_("<corrupt>\n"));
17683 return p;
17685 READ_ULEB (val, p, end);
17687 if (val > 3)
17688 printf ("(%#x), ", val);
17690 switch (val & 3)
17692 case 0:
17693 printf (_("unspecified hard/soft float\n"));
17694 break;
17695 case 1:
17696 printf (_("hard float\n"));
17697 break;
17698 case 2:
17699 printf (_("soft float\n"));
17700 break;
17702 return p;
17705 return display_tag_value (tag & 1, p, end);
17708 static unsigned char *
17709 display_power_gnu_attribute (unsigned char * p,
17710 unsigned int tag,
17711 const unsigned char * const end)
17713 unsigned int val;
17715 if (tag == Tag_GNU_Power_ABI_FP)
17717 printf (" Tag_GNU_Power_ABI_FP: ");
17718 if (p == end)
17720 printf (_("<corrupt>\n"));
17721 return p;
17723 READ_ULEB (val, p, end);
17725 if (val > 15)
17726 printf ("(%#x), ", val);
17728 switch (val & 3)
17730 case 0:
17731 printf (_("unspecified hard/soft float, "));
17732 break;
17733 case 1:
17734 printf (_("hard float, "));
17735 break;
17736 case 2:
17737 printf (_("soft float, "));
17738 break;
17739 case 3:
17740 printf (_("single-precision hard float, "));
17741 break;
17744 switch (val & 0xC)
17746 case 0:
17747 printf (_("unspecified long double\n"));
17748 break;
17749 case 4:
17750 printf (_("128-bit IBM long double\n"));
17751 break;
17752 case 8:
17753 printf (_("64-bit long double\n"));
17754 break;
17755 case 12:
17756 printf (_("128-bit IEEE long double\n"));
17757 break;
17759 return p;
17762 if (tag == Tag_GNU_Power_ABI_Vector)
17764 printf (" Tag_GNU_Power_ABI_Vector: ");
17765 if (p == end)
17767 printf (_("<corrupt>\n"));
17768 return p;
17770 READ_ULEB (val, p, end);
17772 if (val > 3)
17773 printf ("(%#x), ", val);
17775 switch (val & 3)
17777 case 0:
17778 printf (_("unspecified\n"));
17779 break;
17780 case 1:
17781 printf (_("generic\n"));
17782 break;
17783 case 2:
17784 printf ("AltiVec\n");
17785 break;
17786 case 3:
17787 printf ("SPE\n");
17788 break;
17790 return p;
17793 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17795 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
17796 if (p == end)
17798 printf (_("<corrupt>\n"));
17799 return p;
17801 READ_ULEB (val, p, end);
17803 if (val > 2)
17804 printf ("(%#x), ", val);
17806 switch (val & 3)
17808 case 0:
17809 printf (_("unspecified\n"));
17810 break;
17811 case 1:
17812 printf ("r3/r4\n");
17813 break;
17814 case 2:
17815 printf (_("memory\n"));
17816 break;
17817 case 3:
17818 printf ("???\n");
17819 break;
17821 return p;
17824 return display_tag_value (tag & 1, p, end);
17827 static unsigned char *
17828 display_s390_gnu_attribute (unsigned char * p,
17829 unsigned int tag,
17830 const unsigned char * const end)
17832 unsigned int val;
17834 if (tag == Tag_GNU_S390_ABI_Vector)
17836 printf (" Tag_GNU_S390_ABI_Vector: ");
17837 READ_ULEB (val, p, end);
17839 switch (val)
17841 case 0:
17842 printf (_("any\n"));
17843 break;
17844 case 1:
17845 printf (_("software\n"));
17846 break;
17847 case 2:
17848 printf (_("hardware\n"));
17849 break;
17850 default:
17851 printf ("??? (%d)\n", val);
17852 break;
17854 return p;
17857 return display_tag_value (tag & 1, p, end);
17860 static void
17861 display_sparc_hwcaps (unsigned int mask)
17863 if (mask)
17865 bool first = true;
17867 if (mask & ELF_SPARC_HWCAP_MUL32)
17868 fputs ("mul32", stdout), first = false;
17869 if (mask & ELF_SPARC_HWCAP_DIV32)
17870 printf ("%sdiv32", first ? "" : "|"), first = false;
17871 if (mask & ELF_SPARC_HWCAP_FSMULD)
17872 printf ("%sfsmuld", first ? "" : "|"), first = false;
17873 if (mask & ELF_SPARC_HWCAP_V8PLUS)
17874 printf ("%sv8plus", first ? "" : "|"), first = false;
17875 if (mask & ELF_SPARC_HWCAP_POPC)
17876 printf ("%spopc", first ? "" : "|"), first = false;
17877 if (mask & ELF_SPARC_HWCAP_VIS)
17878 printf ("%svis", first ? "" : "|"), first = false;
17879 if (mask & ELF_SPARC_HWCAP_VIS2)
17880 printf ("%svis2", first ? "" : "|"), first = false;
17881 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
17882 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
17883 if (mask & ELF_SPARC_HWCAP_FMAF)
17884 printf ("%sfmaf", first ? "" : "|"), first = false;
17885 if (mask & ELF_SPARC_HWCAP_VIS3)
17886 printf ("%svis3", first ? "" : "|"), first = false;
17887 if (mask & ELF_SPARC_HWCAP_HPC)
17888 printf ("%shpc", first ? "" : "|"), first = false;
17889 if (mask & ELF_SPARC_HWCAP_RANDOM)
17890 printf ("%srandom", first ? "" : "|"), first = false;
17891 if (mask & ELF_SPARC_HWCAP_TRANS)
17892 printf ("%strans", first ? "" : "|"), first = false;
17893 if (mask & ELF_SPARC_HWCAP_FJFMAU)
17894 printf ("%sfjfmau", first ? "" : "|"), first = false;
17895 if (mask & ELF_SPARC_HWCAP_IMA)
17896 printf ("%sima", first ? "" : "|"), first = false;
17897 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
17898 printf ("%scspare", first ? "" : "|"), first = false;
17900 else
17901 fputc ('0', stdout);
17902 fputc ('\n', stdout);
17905 static void
17906 display_sparc_hwcaps2 (unsigned int mask)
17908 if (mask)
17910 bool first = true;
17912 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
17913 fputs ("fjathplus", stdout), first = false;
17914 if (mask & ELF_SPARC_HWCAP2_VIS3B)
17915 printf ("%svis3b", first ? "" : "|"), first = false;
17916 if (mask & ELF_SPARC_HWCAP2_ADP)
17917 printf ("%sadp", first ? "" : "|"), first = false;
17918 if (mask & ELF_SPARC_HWCAP2_SPARC5)
17919 printf ("%ssparc5", first ? "" : "|"), first = false;
17920 if (mask & ELF_SPARC_HWCAP2_MWAIT)
17921 printf ("%smwait", first ? "" : "|"), first = false;
17922 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
17923 printf ("%sxmpmul", first ? "" : "|"), first = false;
17924 if (mask & ELF_SPARC_HWCAP2_XMONT)
17925 printf ("%sxmont2", first ? "" : "|"), first = false;
17926 if (mask & ELF_SPARC_HWCAP2_NSEC)
17927 printf ("%snsec", first ? "" : "|"), first = false;
17928 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
17929 printf ("%sfjathhpc", first ? "" : "|"), first = false;
17930 if (mask & ELF_SPARC_HWCAP2_FJDES)
17931 printf ("%sfjdes", first ? "" : "|"), first = false;
17932 if (mask & ELF_SPARC_HWCAP2_FJAES)
17933 printf ("%sfjaes", first ? "" : "|"), first = false;
17935 else
17936 fputc ('0', stdout);
17937 fputc ('\n', stdout);
17940 static unsigned char *
17941 display_sparc_gnu_attribute (unsigned char * p,
17942 unsigned int tag,
17943 const unsigned char * const end)
17945 unsigned int val;
17947 if (tag == Tag_GNU_Sparc_HWCAPS)
17949 READ_ULEB (val, p, end);
17950 printf (" Tag_GNU_Sparc_HWCAPS: ");
17951 display_sparc_hwcaps (val);
17952 return p;
17954 if (tag == Tag_GNU_Sparc_HWCAPS2)
17956 READ_ULEB (val, p, end);
17957 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17958 display_sparc_hwcaps2 (val);
17959 return p;
17962 return display_tag_value (tag, p, end);
17965 static void
17966 print_mips_fp_abi_value (unsigned int val)
17968 switch (val)
17970 case Val_GNU_MIPS_ABI_FP_ANY:
17971 printf (_("Hard or soft float\n"));
17972 break;
17973 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17974 printf (_("Hard float (double precision)\n"));
17975 break;
17976 case Val_GNU_MIPS_ABI_FP_SINGLE:
17977 printf (_("Hard float (single precision)\n"));
17978 break;
17979 case Val_GNU_MIPS_ABI_FP_SOFT:
17980 printf (_("Soft float\n"));
17981 break;
17982 case Val_GNU_MIPS_ABI_FP_OLD_64:
17983 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17984 break;
17985 case Val_GNU_MIPS_ABI_FP_XX:
17986 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17987 break;
17988 case Val_GNU_MIPS_ABI_FP_64:
17989 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17990 break;
17991 case Val_GNU_MIPS_ABI_FP_64A:
17992 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17993 break;
17994 case Val_GNU_MIPS_ABI_FP_NAN2008:
17995 printf (_("NaN 2008 compatibility\n"));
17996 break;
17997 default:
17998 printf ("??? (%d)\n", val);
17999 break;
18003 static unsigned char *
18004 display_mips_gnu_attribute (unsigned char * p,
18005 unsigned int tag,
18006 const unsigned char * const end)
18008 if (tag == Tag_GNU_MIPS_ABI_FP)
18010 unsigned int val;
18012 printf (" Tag_GNU_MIPS_ABI_FP: ");
18013 READ_ULEB (val, p, end);
18014 print_mips_fp_abi_value (val);
18015 return p;
18018 if (tag == Tag_GNU_MIPS_ABI_MSA)
18020 unsigned int val;
18022 printf (" Tag_GNU_MIPS_ABI_MSA: ");
18023 READ_ULEB (val, p, end);
18025 switch (val)
18027 case Val_GNU_MIPS_ABI_MSA_ANY:
18028 printf (_("Any MSA or not\n"));
18029 break;
18030 case Val_GNU_MIPS_ABI_MSA_128:
18031 printf (_("128-bit MSA\n"));
18032 break;
18033 default:
18034 printf ("??? (%d)\n", val);
18035 break;
18037 return p;
18040 return display_tag_value (tag & 1, p, end);
18043 static unsigned char *
18044 display_tic6x_attribute (unsigned char * p,
18045 const unsigned char * const end)
18047 unsigned int tag;
18048 unsigned int val;
18050 READ_ULEB (tag, p, end);
18052 switch (tag)
18054 case Tag_ISA:
18055 printf (" Tag_ISA: ");
18056 READ_ULEB (val, p, end);
18058 switch (val)
18060 case C6XABI_Tag_ISA_none:
18061 printf (_("None\n"));
18062 break;
18063 case C6XABI_Tag_ISA_C62X:
18064 printf ("C62x\n");
18065 break;
18066 case C6XABI_Tag_ISA_C67X:
18067 printf ("C67x\n");
18068 break;
18069 case C6XABI_Tag_ISA_C67XP:
18070 printf ("C67x+\n");
18071 break;
18072 case C6XABI_Tag_ISA_C64X:
18073 printf ("C64x\n");
18074 break;
18075 case C6XABI_Tag_ISA_C64XP:
18076 printf ("C64x+\n");
18077 break;
18078 case C6XABI_Tag_ISA_C674X:
18079 printf ("C674x\n");
18080 break;
18081 default:
18082 printf ("??? (%d)\n", val);
18083 break;
18085 return p;
18087 case Tag_ABI_wchar_t:
18088 printf (" Tag_ABI_wchar_t: ");
18089 READ_ULEB (val, p, end);
18090 switch (val)
18092 case 0:
18093 printf (_("Not used\n"));
18094 break;
18095 case 1:
18096 printf (_("2 bytes\n"));
18097 break;
18098 case 2:
18099 printf (_("4 bytes\n"));
18100 break;
18101 default:
18102 printf ("??? (%d)\n", val);
18103 break;
18105 return p;
18107 case Tag_ABI_stack_align_needed:
18108 printf (" Tag_ABI_stack_align_needed: ");
18109 READ_ULEB (val, p, end);
18110 switch (val)
18112 case 0:
18113 printf (_("8-byte\n"));
18114 break;
18115 case 1:
18116 printf (_("16-byte\n"));
18117 break;
18118 default:
18119 printf ("??? (%d)\n", val);
18120 break;
18122 return p;
18124 case Tag_ABI_stack_align_preserved:
18125 READ_ULEB (val, p, end);
18126 printf (" Tag_ABI_stack_align_preserved: ");
18127 switch (val)
18129 case 0:
18130 printf (_("8-byte\n"));
18131 break;
18132 case 1:
18133 printf (_("16-byte\n"));
18134 break;
18135 default:
18136 printf ("??? (%d)\n", val);
18137 break;
18139 return p;
18141 case Tag_ABI_DSBT:
18142 READ_ULEB (val, p, end);
18143 printf (" Tag_ABI_DSBT: ");
18144 switch (val)
18146 case 0:
18147 printf (_("DSBT addressing not used\n"));
18148 break;
18149 case 1:
18150 printf (_("DSBT addressing used\n"));
18151 break;
18152 default:
18153 printf ("??? (%d)\n", val);
18154 break;
18156 return p;
18158 case Tag_ABI_PID:
18159 READ_ULEB (val, p, end);
18160 printf (" Tag_ABI_PID: ");
18161 switch (val)
18163 case 0:
18164 printf (_("Data addressing position-dependent\n"));
18165 break;
18166 case 1:
18167 printf (_("Data addressing position-independent, GOT near DP\n"));
18168 break;
18169 case 2:
18170 printf (_("Data addressing position-independent, GOT far from DP\n"));
18171 break;
18172 default:
18173 printf ("??? (%d)\n", val);
18174 break;
18176 return p;
18178 case Tag_ABI_PIC:
18179 READ_ULEB (val, p, end);
18180 printf (" Tag_ABI_PIC: ");
18181 switch (val)
18183 case 0:
18184 printf (_("Code addressing position-dependent\n"));
18185 break;
18186 case 1:
18187 printf (_("Code addressing position-independent\n"));
18188 break;
18189 default:
18190 printf ("??? (%d)\n", val);
18191 break;
18193 return p;
18195 case Tag_ABI_array_object_alignment:
18196 READ_ULEB (val, p, end);
18197 printf (" Tag_ABI_array_object_alignment: ");
18198 switch (val)
18200 case 0:
18201 printf (_("8-byte\n"));
18202 break;
18203 case 1:
18204 printf (_("4-byte\n"));
18205 break;
18206 case 2:
18207 printf (_("16-byte\n"));
18208 break;
18209 default:
18210 printf ("??? (%d)\n", val);
18211 break;
18213 return p;
18215 case Tag_ABI_array_object_align_expected:
18216 READ_ULEB (val, p, end);
18217 printf (" Tag_ABI_array_object_align_expected: ");
18218 switch (val)
18220 case 0:
18221 printf (_("8-byte\n"));
18222 break;
18223 case 1:
18224 printf (_("4-byte\n"));
18225 break;
18226 case 2:
18227 printf (_("16-byte\n"));
18228 break;
18229 default:
18230 printf ("??? (%d)\n", val);
18231 break;
18233 return p;
18235 case Tag_ABI_compatibility:
18237 READ_ULEB (val, p, end);
18238 printf (" Tag_ABI_compatibility: ");
18239 printf (_("flag = %d, vendor = "), val);
18240 if (p < end - 1)
18242 size_t maxlen = (end - p) - 1;
18244 print_symbol_name ((int) maxlen, (const char *) p);
18245 p += strnlen ((char *) p, maxlen) + 1;
18247 else
18249 printf (_("<corrupt>"));
18250 p = (unsigned char *) end;
18252 putchar ('\n');
18253 return p;
18256 case Tag_ABI_conformance:
18258 printf (" Tag_ABI_conformance: \"");
18259 if (p < end - 1)
18261 size_t maxlen = (end - p) - 1;
18263 print_symbol_name ((int) maxlen, (const char *) p);
18264 p += strnlen ((char *) p, maxlen) + 1;
18266 else
18268 printf (_("<corrupt>"));
18269 p = (unsigned char *) end;
18271 printf ("\"\n");
18272 return p;
18276 return display_tag_value (tag, p, end);
18279 static void
18280 display_raw_attribute (unsigned char * p, unsigned char const * const end)
18282 uint64_t addr = 0;
18283 size_t bytes = end - p;
18285 assert (end >= p);
18286 while (bytes)
18288 int j;
18289 int k;
18290 int lbytes = (bytes > 16 ? 16 : bytes);
18292 printf (" 0x%8.8" PRIx64 " ", addr);
18294 for (j = 0; j < 16; j++)
18296 if (j < lbytes)
18297 printf ("%2.2x", p[j]);
18298 else
18299 printf (" ");
18301 if ((j & 3) == 3)
18302 printf (" ");
18305 for (j = 0; j < lbytes; j++)
18307 k = p[j];
18308 if (k >= ' ' && k < 0x7f)
18309 printf ("%c", k);
18310 else
18311 printf (".");
18314 putchar ('\n');
18316 p += lbytes;
18317 bytes -= lbytes;
18318 addr += lbytes;
18321 putchar ('\n');
18324 static unsigned char *
18325 display_msp430_attribute (unsigned char * p,
18326 const unsigned char * const end)
18328 uint64_t val;
18329 uint64_t tag;
18331 READ_ULEB (tag, p, end);
18333 switch (tag)
18335 case OFBA_MSPABI_Tag_ISA:
18336 printf (" Tag_ISA: ");
18337 READ_ULEB (val, p, end);
18338 switch (val)
18340 case 0: printf (_("None\n")); break;
18341 case 1: printf (_("MSP430\n")); break;
18342 case 2: printf (_("MSP430X\n")); break;
18343 default: printf ("??? (%" PRId64 ")\n", val); break;
18345 break;
18347 case OFBA_MSPABI_Tag_Code_Model:
18348 printf (" Tag_Code_Model: ");
18349 READ_ULEB (val, p, end);
18350 switch (val)
18352 case 0: printf (_("None\n")); break;
18353 case 1: printf (_("Small\n")); break;
18354 case 2: printf (_("Large\n")); break;
18355 default: printf ("??? (%" PRId64 ")\n", val); break;
18357 break;
18359 case OFBA_MSPABI_Tag_Data_Model:
18360 printf (" Tag_Data_Model: ");
18361 READ_ULEB (val, p, end);
18362 switch (val)
18364 case 0: printf (_("None\n")); break;
18365 case 1: printf (_("Small\n")); break;
18366 case 2: printf (_("Large\n")); break;
18367 case 3: printf (_("Restricted Large\n")); break;
18368 default: printf ("??? (%" PRId64 ")\n", val); break;
18370 break;
18372 default:
18373 printf (_(" <unknown tag %" PRId64 ">: "), tag);
18375 if (tag & 1)
18377 putchar ('"');
18378 if (p < end - 1)
18380 size_t maxlen = (end - p) - 1;
18382 print_symbol_name ((int) maxlen, (const char *) p);
18383 p += strnlen ((char *) p, maxlen) + 1;
18385 else
18387 printf (_("<corrupt>"));
18388 p = (unsigned char *) end;
18390 printf ("\"\n");
18392 else
18394 READ_ULEB (val, p, end);
18395 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
18397 break;
18400 assert (p <= end);
18401 return p;
18404 static unsigned char *
18405 display_msp430_gnu_attribute (unsigned char * p,
18406 unsigned int tag,
18407 const unsigned char * const end)
18409 if (tag == Tag_GNU_MSP430_Data_Region)
18411 uint64_t val;
18413 printf (" Tag_GNU_MSP430_Data_Region: ");
18414 READ_ULEB (val, p, end);
18416 switch (val)
18418 case Val_GNU_MSP430_Data_Region_Any:
18419 printf (_("Any Region\n"));
18420 break;
18421 case Val_GNU_MSP430_Data_Region_Lower:
18422 printf (_("Lower Region Only\n"));
18423 break;
18424 default:
18425 printf ("??? (%" PRIu64 ")\n", val);
18427 return p;
18429 return display_tag_value (tag & 1, p, end);
18432 struct riscv_attr_tag_t {
18433 const char *name;
18434 unsigned int tag;
18437 static struct riscv_attr_tag_t riscv_attr_tag[] =
18439 #define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
18440 T(arch),
18441 T(priv_spec),
18442 T(priv_spec_minor),
18443 T(priv_spec_revision),
18444 T(unaligned_access),
18445 T(stack_align),
18446 #undef T
18449 static unsigned char *
18450 display_riscv_attribute (unsigned char *p,
18451 const unsigned char * const end)
18453 uint64_t val;
18454 uint64_t tag;
18455 struct riscv_attr_tag_t *attr = NULL;
18456 unsigned i;
18458 READ_ULEB (tag, p, end);
18460 /* Find the name of attribute. */
18461 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18463 if (riscv_attr_tag[i].tag == tag)
18465 attr = &riscv_attr_tag[i];
18466 break;
18470 if (attr)
18471 printf (" %s: ", attr->name);
18472 else
18473 return display_tag_value (tag, p, end);
18475 switch (tag)
18477 case Tag_RISCV_priv_spec:
18478 case Tag_RISCV_priv_spec_minor:
18479 case Tag_RISCV_priv_spec_revision:
18480 READ_ULEB (val, p, end);
18481 printf ("%" PRIu64 "\n", val);
18482 break;
18483 case Tag_RISCV_unaligned_access:
18484 READ_ULEB (val, p, end);
18485 switch (val)
18487 case 0:
18488 printf (_("No unaligned access\n"));
18489 break;
18490 case 1:
18491 printf (_("Unaligned access\n"));
18492 break;
18494 break;
18495 case Tag_RISCV_stack_align:
18496 READ_ULEB (val, p, end);
18497 printf (_("%" PRIu64 "-bytes\n"), val);
18498 break;
18499 case Tag_RISCV_arch:
18500 p = display_tag_value (-1, p, end);
18501 break;
18502 default:
18503 return display_tag_value (tag, p, end);
18506 return p;
18509 static unsigned char *
18510 display_csky_attribute (unsigned char * p,
18511 const unsigned char * const end)
18513 uint64_t tag;
18514 uint64_t val;
18515 READ_ULEB (tag, p, end);
18517 if (tag >= Tag_CSKY_MAX)
18519 return display_tag_value (-1, p, end);
18522 switch (tag)
18524 case Tag_CSKY_ARCH_NAME:
18525 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18526 return display_tag_value (-1, p, end);
18527 case Tag_CSKY_CPU_NAME:
18528 printf (" Tag_CSKY_CPU_NAME:\t\t");
18529 return display_tag_value (-1, p, end);
18531 case Tag_CSKY_ISA_FLAGS:
18532 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18533 return display_tag_value (0, p, end);
18534 case Tag_CSKY_ISA_EXT_FLAGS:
18535 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18536 return display_tag_value (0, p, end);
18538 case Tag_CSKY_DSP_VERSION:
18539 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18540 READ_ULEB (val, p, end);
18541 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18542 printf ("DSP Extension\n");
18543 else if (val == VAL_CSKY_DSP_VERSION_2)
18544 printf ("DSP 2.0\n");
18545 break;
18547 case Tag_CSKY_VDSP_VERSION:
18548 printf (" Tag_CSKY_VDSP_VERSION:\t");
18549 READ_ULEB (val, p, end);
18550 printf ("VDSP Version %" PRId64 "\n", val);
18551 break;
18553 case Tag_CSKY_FPU_VERSION:
18554 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18555 READ_ULEB (val, p, end);
18556 if (val == VAL_CSKY_FPU_VERSION_1)
18557 printf ("ABIV1 FPU Version 1\n");
18558 else if (val == VAL_CSKY_FPU_VERSION_2)
18559 printf ("FPU Version 2\n");
18560 break;
18562 case Tag_CSKY_FPU_ABI:
18563 printf (" Tag_CSKY_FPU_ABI:\t\t");
18564 READ_ULEB (val, p, end);
18565 if (val == VAL_CSKY_FPU_ABI_HARD)
18566 printf ("Hard\n");
18567 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18568 printf ("SoftFP\n");
18569 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18570 printf ("Soft\n");
18571 break;
18572 case Tag_CSKY_FPU_ROUNDING:
18573 READ_ULEB (val, p, end);
18574 if (val == 1)
18576 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18577 printf ("Needed\n");
18579 break;
18580 case Tag_CSKY_FPU_DENORMAL:
18581 READ_ULEB (val, p, end);
18582 if (val == 1)
18584 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18585 printf ("Needed\n");
18587 break;
18588 case Tag_CSKY_FPU_Exception:
18589 READ_ULEB (val, p, end);
18590 if (val == 1)
18592 printf (" Tag_CSKY_FPU_Exception:\t");
18593 printf ("Needed\n");
18595 break;
18596 case Tag_CSKY_FPU_NUMBER_MODULE:
18597 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18598 return display_tag_value (-1, p, end);
18599 case Tag_CSKY_FPU_HARDFP:
18600 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18601 READ_ULEB (val, p, end);
18602 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18603 printf (" Half");
18604 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18605 printf (" Single");
18606 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18607 printf (" Double");
18608 printf ("\n");
18609 break;
18610 default:
18611 return display_tag_value (tag, p, end);
18613 return p;
18616 static bool
18617 process_attributes (Filedata * filedata,
18618 const char * public_name,
18619 unsigned int proc_type,
18620 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
18621 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
18623 Elf_Internal_Shdr * sect;
18624 unsigned i;
18625 bool res = true;
18627 /* Find the section header so that we get the size. */
18628 for (i = 0, sect = filedata->section_headers;
18629 i < filedata->file_header.e_shnum;
18630 i++, sect++)
18632 unsigned char * contents;
18633 unsigned char * p;
18635 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
18636 continue;
18638 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
18639 sect->sh_size, _("attributes"));
18640 if (contents == NULL)
18642 res = false;
18643 continue;
18646 p = contents;
18647 /* The first character is the version of the attributes.
18648 Currently only version 1, (aka 'A') is recognised here. */
18649 if (*p != 'A')
18651 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
18652 res = false;
18654 else
18656 uint64_t section_len;
18658 section_len = sect->sh_size - 1;
18659 p++;
18661 while (section_len > 0)
18663 uint64_t attr_len;
18664 unsigned int namelen;
18665 bool public_section;
18666 bool gnu_section;
18668 if (section_len <= 4)
18670 error (_("Tag section ends prematurely\n"));
18671 res = false;
18672 break;
18674 attr_len = byte_get (p, 4);
18675 p += 4;
18677 if (attr_len > section_len)
18679 error (_("Bad attribute length (%u > %u)\n"),
18680 (unsigned) attr_len, (unsigned) section_len);
18681 attr_len = section_len;
18682 res = false;
18684 /* PR 17531: file: 001-101425-0.004 */
18685 else if (attr_len < 5)
18687 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
18688 res = false;
18689 break;
18692 section_len -= attr_len;
18693 attr_len -= 4;
18695 namelen = strnlen ((char *) p, attr_len) + 1;
18696 if (namelen == 0 || namelen >= attr_len)
18698 error (_("Corrupt attribute section name\n"));
18699 res = false;
18700 break;
18703 printf (_("Attribute Section: "));
18704 print_symbol_name (INT_MAX, (const char *) p);
18705 putchar ('\n');
18707 if (public_name && streq ((char *) p, public_name))
18708 public_section = true;
18709 else
18710 public_section = false;
18712 if (streq ((char *) p, "gnu"))
18713 gnu_section = true;
18714 else
18715 gnu_section = false;
18717 p += namelen;
18718 attr_len -= namelen;
18720 while (attr_len > 0 && p < contents + sect->sh_size)
18722 int tag;
18723 unsigned int val;
18724 uint64_t size;
18725 unsigned char * end;
18727 /* PR binutils/17531: Safe handling of corrupt files. */
18728 if (attr_len < 6)
18730 error (_("Unused bytes at end of section\n"));
18731 res = false;
18732 section_len = 0;
18733 break;
18736 tag = *(p++);
18737 size = byte_get (p, 4);
18738 if (size > attr_len)
18740 error (_("Bad subsection length (%u > %u)\n"),
18741 (unsigned) size, (unsigned) attr_len);
18742 res = false;
18743 size = attr_len;
18745 /* PR binutils/17531: Safe handling of corrupt files. */
18746 if (size < 6)
18748 error (_("Bad subsection length (%u < 6)\n"),
18749 (unsigned) size);
18750 res = false;
18751 section_len = 0;
18752 break;
18755 attr_len -= size;
18756 end = p + size - 1;
18757 assert (end <= contents + sect->sh_size);
18758 p += 4;
18760 switch (tag)
18762 case 1:
18763 printf (_("File Attributes\n"));
18764 break;
18765 case 2:
18766 printf (_("Section Attributes:"));
18767 goto do_numlist;
18768 case 3:
18769 printf (_("Symbol Attributes:"));
18770 /* Fall through. */
18771 do_numlist:
18772 for (;;)
18774 READ_ULEB (val, p, end);
18775 if (val == 0)
18776 break;
18777 printf (" %d", val);
18779 printf ("\n");
18780 break;
18781 default:
18782 printf (_("Unknown tag: %d\n"), tag);
18783 public_section = false;
18784 break;
18787 if (public_section && display_pub_attribute != NULL)
18789 while (p < end)
18790 p = display_pub_attribute (p, end);
18791 assert (p == end);
18793 else if (gnu_section && display_proc_gnu_attribute != NULL)
18795 while (p < end)
18796 p = display_gnu_attribute (p,
18797 display_proc_gnu_attribute,
18798 end);
18799 assert (p == end);
18801 else if (p < end)
18803 printf (_(" Unknown attribute:\n"));
18804 display_raw_attribute (p, end);
18805 p = end;
18807 else
18808 attr_len = 0;
18813 free (contents);
18816 return res;
18819 /* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18820 Print the Address, Access and Initial fields of an entry at VMA ADDR
18821 and return the VMA of the next entry, or -1 if there was a problem.
18822 Does not read from DATA_END or beyond. */
18824 static uint64_t
18825 print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
18826 unsigned char * data_end)
18828 printf (" ");
18829 print_vma (addr, LONG_HEX);
18830 printf (" ");
18831 if (addr < pltgot + 0xfff0)
18832 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18833 else
18834 printf ("%10s", "");
18835 printf (" ");
18836 if (data == NULL)
18837 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
18838 else
18840 uint64_t entry;
18841 unsigned char * from = data + addr - pltgot;
18843 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18845 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18846 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
18847 return (uint64_t) -1;
18849 else
18851 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18852 print_vma (entry, LONG_HEX);
18855 return addr + (is_32bit_elf ? 4 : 8);
18858 /* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18859 PLTGOT. Print the Address and Initial fields of an entry at VMA
18860 ADDR and return the VMA of the next entry. */
18862 static uint64_t
18863 print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
18865 printf (" ");
18866 print_vma (addr, LONG_HEX);
18867 printf (" ");
18868 if (data == NULL)
18869 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
18870 else
18872 uint64_t entry;
18874 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18875 print_vma (entry, LONG_HEX);
18877 return addr + (is_32bit_elf ? 4 : 8);
18880 static void
18881 print_mips_ases (unsigned int mask)
18883 if (mask & AFL_ASE_DSP)
18884 fputs ("\n\tDSP ASE", stdout);
18885 if (mask & AFL_ASE_DSPR2)
18886 fputs ("\n\tDSP R2 ASE", stdout);
18887 if (mask & AFL_ASE_DSPR3)
18888 fputs ("\n\tDSP R3 ASE", stdout);
18889 if (mask & AFL_ASE_EVA)
18890 fputs ("\n\tEnhanced VA Scheme", stdout);
18891 if (mask & AFL_ASE_MCU)
18892 fputs ("\n\tMCU (MicroController) ASE", stdout);
18893 if (mask & AFL_ASE_MDMX)
18894 fputs ("\n\tMDMX ASE", stdout);
18895 if (mask & AFL_ASE_MIPS3D)
18896 fputs ("\n\tMIPS-3D ASE", stdout);
18897 if (mask & AFL_ASE_MT)
18898 fputs ("\n\tMT ASE", stdout);
18899 if (mask & AFL_ASE_SMARTMIPS)
18900 fputs ("\n\tSmartMIPS ASE", stdout);
18901 if (mask & AFL_ASE_VIRT)
18902 fputs ("\n\tVZ ASE", stdout);
18903 if (mask & AFL_ASE_MSA)
18904 fputs ("\n\tMSA ASE", stdout);
18905 if (mask & AFL_ASE_MIPS16)
18906 fputs ("\n\tMIPS16 ASE", stdout);
18907 if (mask & AFL_ASE_MICROMIPS)
18908 fputs ("\n\tMICROMIPS ASE", stdout);
18909 if (mask & AFL_ASE_XPA)
18910 fputs ("\n\tXPA ASE", stdout);
18911 if (mask & AFL_ASE_MIPS16E2)
18912 fputs ("\n\tMIPS16e2 ASE", stdout);
18913 if (mask & AFL_ASE_CRC)
18914 fputs ("\n\tCRC ASE", stdout);
18915 if (mask & AFL_ASE_GINV)
18916 fputs ("\n\tGINV ASE", stdout);
18917 if (mask & AFL_ASE_LOONGSON_MMI)
18918 fputs ("\n\tLoongson MMI ASE", stdout);
18919 if (mask & AFL_ASE_LOONGSON_CAM)
18920 fputs ("\n\tLoongson CAM ASE", stdout);
18921 if (mask & AFL_ASE_LOONGSON_EXT)
18922 fputs ("\n\tLoongson EXT ASE", stdout);
18923 if (mask & AFL_ASE_LOONGSON_EXT2)
18924 fputs ("\n\tLoongson EXT2 ASE", stdout);
18925 if (mask == 0)
18926 fprintf (stdout, "\n\t%s", _("None"));
18927 else if ((mask & ~AFL_ASE_MASK) != 0)
18928 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
18931 static void
18932 print_mips_isa_ext (unsigned int isa_ext)
18934 switch (isa_ext)
18936 case 0:
18937 fputs (_("None"), stdout);
18938 break;
18939 case AFL_EXT_XLR:
18940 fputs ("RMI XLR", stdout);
18941 break;
18942 case AFL_EXT_OCTEON3:
18943 fputs ("Cavium Networks Octeon3", stdout);
18944 break;
18945 case AFL_EXT_OCTEON2:
18946 fputs ("Cavium Networks Octeon2", stdout);
18947 break;
18948 case AFL_EXT_OCTEONP:
18949 fputs ("Cavium Networks OcteonP", stdout);
18950 break;
18951 case AFL_EXT_OCTEON:
18952 fputs ("Cavium Networks Octeon", stdout);
18953 break;
18954 case AFL_EXT_5900:
18955 fputs ("Toshiba R5900", stdout);
18956 break;
18957 case AFL_EXT_4650:
18958 fputs ("MIPS R4650", stdout);
18959 break;
18960 case AFL_EXT_4010:
18961 fputs ("LSI R4010", stdout);
18962 break;
18963 case AFL_EXT_4100:
18964 fputs ("NEC VR4100", stdout);
18965 break;
18966 case AFL_EXT_3900:
18967 fputs ("Toshiba R3900", stdout);
18968 break;
18969 case AFL_EXT_10000:
18970 fputs ("MIPS R10000", stdout);
18971 break;
18972 case AFL_EXT_SB1:
18973 fputs ("Broadcom SB-1", stdout);
18974 break;
18975 case AFL_EXT_4111:
18976 fputs ("NEC VR4111/VR4181", stdout);
18977 break;
18978 case AFL_EXT_4120:
18979 fputs ("NEC VR4120", stdout);
18980 break;
18981 case AFL_EXT_5400:
18982 fputs ("NEC VR5400", stdout);
18983 break;
18984 case AFL_EXT_5500:
18985 fputs ("NEC VR5500", stdout);
18986 break;
18987 case AFL_EXT_LOONGSON_2E:
18988 fputs ("ST Microelectronics Loongson 2E", stdout);
18989 break;
18990 case AFL_EXT_LOONGSON_2F:
18991 fputs ("ST Microelectronics Loongson 2F", stdout);
18992 break;
18993 case AFL_EXT_INTERAPTIV_MR2:
18994 fputs ("Imagination interAptiv MR2", stdout);
18995 break;
18996 default:
18997 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
19001 static signed int
19002 get_mips_reg_size (int reg_size)
19004 return (reg_size == AFL_REG_NONE) ? 0
19005 : (reg_size == AFL_REG_32) ? 32
19006 : (reg_size == AFL_REG_64) ? 64
19007 : (reg_size == AFL_REG_128) ? 128
19008 : -1;
19011 static bool
19012 process_mips_specific (Filedata * filedata)
19014 Elf_Internal_Dyn * entry;
19015 Elf_Internal_Shdr *sect = NULL;
19016 size_t liblist_offset = 0;
19017 size_t liblistno = 0;
19018 size_t conflictsno = 0;
19019 size_t options_offset = 0;
19020 size_t conflicts_offset = 0;
19021 size_t pltrelsz = 0;
19022 size_t pltrel = 0;
19023 uint64_t pltgot = 0;
19024 uint64_t mips_pltgot = 0;
19025 uint64_t jmprel = 0;
19026 uint64_t local_gotno = 0;
19027 uint64_t gotsym = 0;
19028 uint64_t symtabno = 0;
19029 bool res = true;
19031 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
19032 display_mips_gnu_attribute))
19033 res = false;
19035 sect = find_section (filedata, ".MIPS.abiflags");
19037 if (sect != NULL)
19039 Elf_External_ABIFlags_v0 *abiflags_ext;
19040 Elf_Internal_ABIFlags_v0 abiflags_in;
19042 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
19044 error (_("Corrupt MIPS ABI Flags section.\n"));
19045 res = false;
19047 else
19049 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
19050 sect->sh_size, _("MIPS ABI Flags section"));
19051 if (abiflags_ext)
19053 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19054 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19055 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19056 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19057 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19058 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19059 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19060 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19061 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19062 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19063 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19065 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19066 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19067 if (abiflags_in.isa_rev > 1)
19068 printf ("r%d", abiflags_in.isa_rev);
19069 printf ("\nGPR size: %d",
19070 get_mips_reg_size (abiflags_in.gpr_size));
19071 printf ("\nCPR1 size: %d",
19072 get_mips_reg_size (abiflags_in.cpr1_size));
19073 printf ("\nCPR2 size: %d",
19074 get_mips_reg_size (abiflags_in.cpr2_size));
19075 fputs ("\nFP ABI: ", stdout);
19076 print_mips_fp_abi_value (abiflags_in.fp_abi);
19077 fputs ("ISA Extension: ", stdout);
19078 print_mips_isa_ext (abiflags_in.isa_ext);
19079 fputs ("\nASEs:", stdout);
19080 print_mips_ases (abiflags_in.ases);
19081 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19082 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19083 fputc ('\n', stdout);
19084 free (abiflags_ext);
19089 /* We have a lot of special sections. Thanks SGI! */
19090 if (filedata->dynamic_section == NULL)
19092 /* No dynamic information available. See if there is static GOT. */
19093 sect = find_section (filedata, ".got");
19094 if (sect != NULL)
19096 unsigned char *data_end;
19097 unsigned char *data;
19098 uint64_t ent, end;
19099 int addr_size;
19101 pltgot = sect->sh_addr;
19103 ent = pltgot;
19104 addr_size = (is_32bit_elf ? 4 : 8);
19105 end = pltgot + sect->sh_size;
19107 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
19108 end - pltgot, 1,
19109 _("Global Offset Table data"));
19110 /* PR 12855: Null data is handled gracefully throughout. */
19111 data_end = data + (end - pltgot);
19113 printf (_("\nStatic GOT:\n"));
19114 printf (_(" Canonical gp value: "));
19115 print_vma (ent + 0x7ff0, LONG_HEX);
19116 printf ("\n\n");
19118 /* In a dynamic binary GOT[0] is reserved for the dynamic
19119 loader to store the lazy resolver pointer, however in
19120 a static binary it may well have been omitted and GOT
19121 reduced to a table of addresses.
19122 PR 21344: Check for the entry being fully available
19123 before fetching it. */
19124 if (data
19125 && data + ent - pltgot + addr_size <= data_end
19126 && byte_get (data + ent - pltgot, addr_size) == 0)
19128 printf (_(" Reserved entries:\n"));
19129 printf (_(" %*s %10s %*s\n"),
19130 addr_size * 2, _("Address"), _("Access"),
19131 addr_size * 2, _("Value"));
19132 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19133 printf ("\n");
19134 if (ent == (uint64_t) -1)
19135 goto sgot_print_fail;
19137 /* Check for the MSB of GOT[1] being set, identifying a
19138 GNU object. This entry will be used by some runtime
19139 loaders, to store the module pointer. Otherwise this
19140 is an ordinary local entry.
19141 PR 21344: Check for the entry being fully available
19142 before fetching it. */
19143 if (data
19144 && data + ent - pltgot + addr_size <= data_end
19145 && (byte_get (data + ent - pltgot, addr_size)
19146 >> (addr_size * 8 - 1)) != 0)
19148 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19149 printf ("\n");
19150 if (ent == (uint64_t) -1)
19151 goto sgot_print_fail;
19153 printf ("\n");
19156 if (data != NULL && ent < end)
19158 printf (_(" Local entries:\n"));
19159 printf (" %*s %10s %*s\n",
19160 addr_size * 2, _("Address"), _("Access"),
19161 addr_size * 2, _("Value"));
19162 while (ent < end)
19164 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19165 printf ("\n");
19166 if (ent == (uint64_t) -1)
19167 goto sgot_print_fail;
19169 printf ("\n");
19172 sgot_print_fail:
19173 free (data);
19175 return res;
19178 for (entry = filedata->dynamic_section;
19179 /* PR 17531 file: 012-50589-0.004. */
19180 (entry < filedata->dynamic_section + filedata->dynamic_nent
19181 && entry->d_tag != DT_NULL);
19182 ++entry)
19183 switch (entry->d_tag)
19185 case DT_MIPS_LIBLIST:
19186 liblist_offset
19187 = offset_from_vma (filedata, entry->d_un.d_val,
19188 liblistno * sizeof (Elf32_External_Lib));
19189 break;
19190 case DT_MIPS_LIBLISTNO:
19191 liblistno = entry->d_un.d_val;
19192 break;
19193 case DT_MIPS_OPTIONS:
19194 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
19195 break;
19196 case DT_MIPS_CONFLICT:
19197 conflicts_offset
19198 = offset_from_vma (filedata, entry->d_un.d_val,
19199 conflictsno * sizeof (Elf32_External_Conflict));
19200 break;
19201 case DT_MIPS_CONFLICTNO:
19202 conflictsno = entry->d_un.d_val;
19203 break;
19204 case DT_PLTGOT:
19205 pltgot = entry->d_un.d_ptr;
19206 break;
19207 case DT_MIPS_LOCAL_GOTNO:
19208 local_gotno = entry->d_un.d_val;
19209 break;
19210 case DT_MIPS_GOTSYM:
19211 gotsym = entry->d_un.d_val;
19212 break;
19213 case DT_MIPS_SYMTABNO:
19214 symtabno = entry->d_un.d_val;
19215 break;
19216 case DT_MIPS_PLTGOT:
19217 mips_pltgot = entry->d_un.d_ptr;
19218 break;
19219 case DT_PLTREL:
19220 pltrel = entry->d_un.d_val;
19221 break;
19222 case DT_PLTRELSZ:
19223 pltrelsz = entry->d_un.d_val;
19224 break;
19225 case DT_JMPREL:
19226 jmprel = entry->d_un.d_ptr;
19227 break;
19228 default:
19229 break;
19232 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19234 Elf32_External_Lib * elib;
19235 size_t cnt;
19237 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
19238 sizeof (Elf32_External_Lib),
19239 liblistno,
19240 _("liblist section data"));
19241 if (elib)
19243 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19244 "\nSection '.liblist' contains %zu entries:\n",
19245 liblistno),
19246 liblistno);
19247 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
19248 stdout);
19250 for (cnt = 0; cnt < liblistno; ++cnt)
19252 Elf32_Lib liblist;
19253 time_t atime;
19254 char timebuf[128];
19255 struct tm * tmp;
19257 liblist.l_name = BYTE_GET (elib[cnt].l_name);
19258 atime = BYTE_GET (elib[cnt].l_time_stamp);
19259 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19260 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19261 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19263 tmp = gmtime (&atime);
19264 snprintf (timebuf, sizeof (timebuf),
19265 "%04u-%02u-%02uT%02u:%02u:%02u",
19266 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19267 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
19269 printf ("%3zu: ", cnt);
19270 if (valid_dynamic_name (filedata, liblist.l_name))
19271 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
19272 else
19273 printf (_("<corrupt: %9ld>"), liblist.l_name);
19274 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19275 liblist.l_version);
19277 if (liblist.l_flags == 0)
19278 puts (_(" NONE"));
19279 else
19281 static const struct
19283 const char * name;
19284 int bit;
19286 l_flags_vals[] =
19288 { " EXACT_MATCH", LL_EXACT_MATCH },
19289 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19290 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19291 { " EXPORTS", LL_EXPORTS },
19292 { " DELAY_LOAD", LL_DELAY_LOAD },
19293 { " DELTA", LL_DELTA }
19295 int flags = liblist.l_flags;
19296 size_t fcnt;
19298 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
19299 if ((flags & l_flags_vals[fcnt].bit) != 0)
19301 fputs (l_flags_vals[fcnt].name, stdout);
19302 flags ^= l_flags_vals[fcnt].bit;
19304 if (flags != 0)
19305 printf (" %#x", (unsigned int) flags);
19307 puts ("");
19311 free (elib);
19313 else
19314 res = false;
19317 if (options_offset != 0)
19319 Elf_External_Options * eopt;
19320 size_t offset;
19321 int cnt;
19323 /* Find the section header so that we get the size. */
19324 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
19325 /* PR 17533 file: 012-277276-0.004. */
19326 if (sect == NULL)
19328 error (_("No MIPS_OPTIONS header found\n"));
19329 return false;
19331 /* PR 24243 */
19332 if (sect->sh_size < sizeof (* eopt))
19334 error (_("The MIPS options section is too small.\n"));
19335 return false;
19338 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
19339 sect->sh_size, _("options"));
19340 if (eopt)
19342 Elf_Internal_Options option;
19344 offset = cnt = 0;
19345 while (offset <= sect->sh_size - sizeof (* eopt))
19347 Elf_External_Options * eoption;
19348 unsigned int optsize;
19350 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19352 optsize = BYTE_GET (eoption->size);
19354 /* PR 17531: file: ffa0fa3b. */
19355 if (optsize < sizeof (* eopt)
19356 || optsize > sect->sh_size - offset)
19358 error (_("Invalid size (%u) for MIPS option\n"),
19359 optsize);
19360 free (eopt);
19361 return false;
19363 offset += optsize;
19364 ++cnt;
19367 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19368 "\nSection '%s' contains %d entries:\n",
19369 cnt),
19370 printable_section_name (filedata, sect), cnt);
19372 offset = 0;
19373 while (cnt-- > 0)
19375 size_t len;
19376 Elf_External_Options * eoption;
19378 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19380 option.kind = BYTE_GET (eoption->kind);
19381 option.size = BYTE_GET (eoption->size);
19382 option.section = BYTE_GET (eoption->section);
19383 option.info = BYTE_GET (eoption->info);
19385 switch (option.kind)
19387 case ODK_NULL:
19388 /* This shouldn't happen. */
19389 printf (" NULL %" PRId16 " %" PRIx32,
19390 option.section, option.info);
19391 break;
19393 case ODK_REGINFO:
19394 printf (" REGINFO ");
19395 if (filedata->file_header.e_machine == EM_MIPS)
19397 Elf32_External_RegInfo * ereg;
19398 Elf32_RegInfo reginfo;
19400 /* 32bit form. */
19401 if (option.size < (sizeof (Elf_External_Options)
19402 + sizeof (Elf32_External_RegInfo)))
19404 printf (_("<corrupt>\n"));
19405 error (_("Truncated MIPS REGINFO option\n"));
19406 cnt = 0;
19407 break;
19410 ereg = (Elf32_External_RegInfo *) (eoption + 1);
19412 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19413 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19414 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19415 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19416 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19417 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19419 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
19420 reginfo.ri_gprmask, reginfo.ri_gp_value);
19421 printf (" "
19422 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19423 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
19424 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19425 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19427 else
19429 /* 64 bit form. */
19430 Elf64_External_RegInfo * ereg;
19431 Elf64_Internal_RegInfo reginfo;
19433 if (option.size < (sizeof (Elf_External_Options)
19434 + sizeof (Elf64_External_RegInfo)))
19436 printf (_("<corrupt>\n"));
19437 error (_("Truncated MIPS REGINFO option\n"));
19438 cnt = 0;
19439 break;
19442 ereg = (Elf64_External_RegInfo *) (eoption + 1);
19443 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19444 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19445 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19446 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19447 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19448 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19450 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19451 reginfo.ri_gprmask, reginfo.ri_gp_value);
19452 printf (" "
19453 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19454 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
19455 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19456 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19458 offset += option.size;
19459 continue;
19461 case ODK_EXCEPTIONS:
19462 fputs (" EXCEPTIONS fpe_min(", stdout);
19463 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
19464 fputs (") fpe_max(", stdout);
19465 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
19466 fputs (")", stdout);
19468 if (option.info & OEX_PAGE0)
19469 fputs (" PAGE0", stdout);
19470 if (option.info & OEX_SMM)
19471 fputs (" SMM", stdout);
19472 if (option.info & OEX_FPDBUG)
19473 fputs (" FPDBUG", stdout);
19474 if (option.info & OEX_DISMISS)
19475 fputs (" DISMISS", stdout);
19476 break;
19478 case ODK_PAD:
19479 fputs (" PAD ", stdout);
19480 if (option.info & OPAD_PREFIX)
19481 fputs (" PREFIX", stdout);
19482 if (option.info & OPAD_POSTFIX)
19483 fputs (" POSTFIX", stdout);
19484 if (option.info & OPAD_SYMBOL)
19485 fputs (" SYMBOL", stdout);
19486 break;
19488 case ODK_HWPATCH:
19489 fputs (" HWPATCH ", stdout);
19490 if (option.info & OHW_R4KEOP)
19491 fputs (" R4KEOP", stdout);
19492 if (option.info & OHW_R8KPFETCH)
19493 fputs (" R8KPFETCH", stdout);
19494 if (option.info & OHW_R5KEOP)
19495 fputs (" R5KEOP", stdout);
19496 if (option.info & OHW_R5KCVTL)
19497 fputs (" R5KCVTL", stdout);
19498 break;
19500 case ODK_FILL:
19501 fputs (" FILL ", stdout);
19502 /* XXX Print content of info word? */
19503 break;
19505 case ODK_TAGS:
19506 fputs (" TAGS ", stdout);
19507 /* XXX Print content of info word? */
19508 break;
19510 case ODK_HWAND:
19511 fputs (" HWAND ", stdout);
19512 if (option.info & OHWA0_R4KEOP_CHECKED)
19513 fputs (" R4KEOP_CHECKED", stdout);
19514 if (option.info & OHWA0_R4KEOP_CLEAN)
19515 fputs (" R4KEOP_CLEAN", stdout);
19516 break;
19518 case ODK_HWOR:
19519 fputs (" HWOR ", stdout);
19520 if (option.info & OHWA0_R4KEOP_CHECKED)
19521 fputs (" R4KEOP_CHECKED", stdout);
19522 if (option.info & OHWA0_R4KEOP_CLEAN)
19523 fputs (" R4KEOP_CLEAN", stdout);
19524 break;
19526 case ODK_GP_GROUP:
19527 printf (" GP_GROUP %#06x self-contained %#06x",
19528 option.info & OGP_GROUP,
19529 (option.info & OGP_SELF) >> 16);
19530 break;
19532 case ODK_IDENT:
19533 printf (" IDENT %#06x self-contained %#06x",
19534 option.info & OGP_GROUP,
19535 (option.info & OGP_SELF) >> 16);
19536 break;
19538 default:
19539 /* This shouldn't happen. */
19540 printf (" %3d ??? %" PRId16 " %" PRIx32,
19541 option.kind, option.section, option.info);
19542 break;
19545 len = sizeof (* eopt);
19546 while (len < option.size)
19548 unsigned char datum = *((unsigned char *) eoption + len);
19550 if (ISPRINT (datum))
19551 printf ("%c", datum);
19552 else
19553 printf ("\\%03o", datum);
19554 len ++;
19556 fputs ("\n", stdout);
19558 offset += option.size;
19560 free (eopt);
19562 else
19563 res = false;
19566 if (conflicts_offset != 0 && conflictsno != 0)
19568 Elf32_Conflict * iconf;
19569 size_t cnt;
19571 if (filedata->dynamic_symbols == NULL)
19573 error (_("conflict list found without a dynamic symbol table\n"));
19574 return false;
19577 /* PR 21345 - print a slightly more helpful error message
19578 if we are sure that the cmalloc will fail. */
19579 if (conflictsno > filedata->file_size / sizeof (* iconf))
19581 error (_("Overlarge number of conflicts detected: %zx\n"),
19582 conflictsno);
19583 return false;
19586 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
19587 if (iconf == NULL)
19589 error (_("Out of memory allocating space for dynamic conflicts\n"));
19590 return false;
19593 if (is_32bit_elf)
19595 Elf32_External_Conflict * econf32;
19597 econf32 = (Elf32_External_Conflict *)
19598 get_data (NULL, filedata, conflicts_offset,
19599 sizeof (*econf32), conflictsno, _("conflict"));
19600 if (!econf32)
19602 free (iconf);
19603 return false;
19606 for (cnt = 0; cnt < conflictsno; ++cnt)
19607 iconf[cnt] = BYTE_GET (econf32[cnt]);
19609 free (econf32);
19611 else
19613 Elf64_External_Conflict * econf64;
19615 econf64 = (Elf64_External_Conflict *)
19616 get_data (NULL, filedata, conflicts_offset,
19617 sizeof (*econf64), conflictsno, _("conflict"));
19618 if (!econf64)
19620 free (iconf);
19621 return false;
19624 for (cnt = 0; cnt < conflictsno; ++cnt)
19625 iconf[cnt] = BYTE_GET (econf64[cnt]);
19627 free (econf64);
19630 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19631 "\nSection '.conflict' contains %zu entries:\n",
19632 conflictsno),
19633 conflictsno);
19634 puts (_(" Num: Index Value Name"));
19636 for (cnt = 0; cnt < conflictsno; ++cnt)
19638 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
19640 if (iconf[cnt] >= filedata->num_dynamic_syms)
19641 printf (_("<corrupt symbol index>"));
19642 else
19644 Elf_Internal_Sym * psym;
19646 psym = & filedata->dynamic_symbols[iconf[cnt]];
19647 print_vma (psym->st_value, FULL_HEX);
19648 putchar (' ');
19649 if (valid_dynamic_name (filedata, psym->st_name))
19650 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
19651 else
19652 printf (_("<corrupt: %14ld>"), psym->st_name);
19654 putchar ('\n');
19657 free (iconf);
19660 if (pltgot != 0 && local_gotno != 0)
19662 uint64_t ent, local_end, global_end;
19663 size_t i, offset;
19664 unsigned char * data;
19665 unsigned char * data_end;
19666 int addr_size;
19668 ent = pltgot;
19669 addr_size = (is_32bit_elf ? 4 : 8);
19670 local_end = pltgot + local_gotno * addr_size;
19672 /* PR binutils/17533 file: 012-111227-0.004 */
19673 if (symtabno < gotsym)
19675 error (_("The GOT symbol offset (%" PRIu64
19676 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19677 gotsym, symtabno);
19678 return false;
19681 global_end = local_end + (symtabno - gotsym) * addr_size;
19682 /* PR 17531: file: 54c91a34. */
19683 if (global_end < local_end)
19685 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
19686 return false;
19689 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19690 data = (unsigned char *) get_data (NULL, filedata, offset,
19691 global_end - pltgot, 1,
19692 _("Global Offset Table data"));
19693 /* PR 12855: Null data is handled gracefully throughout. */
19694 data_end = data + (global_end - pltgot);
19696 printf (_("\nPrimary GOT:\n"));
19697 printf (_(" Canonical gp value: "));
19698 print_vma (pltgot + 0x7ff0, LONG_HEX);
19699 printf ("\n\n");
19701 printf (_(" Reserved entries:\n"));
19702 printf (_(" %*s %10s %*s Purpose\n"),
19703 addr_size * 2, _("Address"), _("Access"),
19704 addr_size * 2, _("Initial"));
19705 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19706 printf (_(" Lazy resolver\n"));
19707 if (ent == (uint64_t) -1)
19708 goto got_print_fail;
19710 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19711 This entry will be used by some runtime loaders, to store the
19712 module pointer. Otherwise this is an ordinary local entry.
19713 PR 21344: Check for the entry being fully available before
19714 fetching it. */
19715 if (data
19716 && data + ent - pltgot + addr_size <= data_end
19717 && (byte_get (data + ent - pltgot, addr_size)
19718 >> (addr_size * 8 - 1)) != 0)
19720 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19721 printf (_(" Module pointer (GNU extension)\n"));
19722 if (ent == (uint64_t) -1)
19723 goto got_print_fail;
19725 printf ("\n");
19727 if (data != NULL && ent < local_end)
19729 printf (_(" Local entries:\n"));
19730 printf (" %*s %10s %*s\n",
19731 addr_size * 2, _("Address"), _("Access"),
19732 addr_size * 2, _("Initial"));
19733 while (ent < local_end)
19735 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19736 printf ("\n");
19737 if (ent == (uint64_t) -1)
19738 goto got_print_fail;
19740 printf ("\n");
19743 if (data != NULL && gotsym < symtabno)
19745 int sym_width;
19747 printf (_(" Global entries:\n"));
19748 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
19749 addr_size * 2, _("Address"),
19750 _("Access"),
19751 addr_size * 2, _("Initial"),
19752 addr_size * 2, _("Sym.Val."),
19753 _("Type"),
19754 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19755 _("Ndx"), _("Name"));
19757 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
19759 for (i = gotsym; i < symtabno; i++)
19761 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19762 printf (" ");
19764 if (filedata->dynamic_symbols == NULL)
19765 printf (_("<no dynamic symbols>"));
19766 else if (i < filedata->num_dynamic_syms)
19768 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
19770 print_vma (psym->st_value, LONG_HEX);
19771 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
19773 bool is_special;
19774 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
19775 if (is_special)
19776 printf ("%3s ", s);
19777 else
19778 printf ("%3u ", psym->st_shndx);
19780 if (valid_dynamic_name (filedata, psym->st_name))
19781 print_symbol_name (sym_width,
19782 get_dynamic_name (filedata, psym->st_name));
19783 else
19784 printf (_("<corrupt: %14ld>"), psym->st_name);
19786 else
19787 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19790 printf ("\n");
19791 if (ent == (uint64_t) -1)
19792 break;
19794 printf ("\n");
19797 got_print_fail:
19798 free (data);
19801 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19803 uint64_t ent, end;
19804 uint64_t offset, rel_offset;
19805 uint64_t count, i;
19806 unsigned char * data;
19807 int addr_size, sym_width;
19808 Elf_Internal_Rela * rels;
19810 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
19811 if (pltrel == DT_RELA)
19813 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
19814 return false;
19816 else
19818 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
19819 return false;
19822 ent = mips_pltgot;
19823 addr_size = (is_32bit_elf ? 4 : 8);
19824 end = mips_pltgot + (2 + count) * addr_size;
19826 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19827 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
19828 1, _("Procedure Linkage Table data"));
19829 if (data == NULL)
19831 free (rels);
19832 return false;
19835 printf ("\nPLT GOT:\n\n");
19836 printf (_(" Reserved entries:\n"));
19837 printf (_(" %*s %*s Purpose\n"),
19838 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
19839 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
19840 printf (_(" PLT lazy resolver\n"));
19841 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
19842 printf (_(" Module pointer\n"));
19843 printf ("\n");
19845 printf (_(" Entries:\n"));
19846 printf (" %*s %*s %*s %-7s %3s %s\n",
19847 addr_size * 2, _("Address"),
19848 addr_size * 2, _("Initial"),
19849 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
19850 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19851 for (i = 0; i < count; i++)
19853 uint64_t idx = get_reloc_symindex (rels[i].r_info);
19855 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
19856 printf (" ");
19858 if (idx >= filedata->num_dynamic_syms)
19859 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
19860 else
19862 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
19864 print_vma (psym->st_value, LONG_HEX);
19865 printf (" %-7s %3s ",
19866 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19867 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
19868 if (valid_dynamic_name (filedata, psym->st_name))
19869 print_symbol_name (sym_width,
19870 get_dynamic_name (filedata, psym->st_name));
19871 else
19872 printf (_("<corrupt: %14ld>"), psym->st_name);
19874 printf ("\n");
19876 printf ("\n");
19878 free (data);
19879 free (rels);
19882 return res;
19885 static bool
19886 process_nds32_specific (Filedata * filedata)
19888 Elf_Internal_Shdr *sect = NULL;
19890 sect = find_section (filedata, ".nds32_e_flags");
19891 if (sect != NULL && sect->sh_size >= 4)
19893 unsigned char *buf;
19894 unsigned int flag;
19896 printf ("\nNDS32 elf flags section:\n");
19897 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19898 _("NDS32 elf flags section"));
19900 if (buf == NULL)
19901 return false;
19903 flag = byte_get (buf, 4);
19904 free (buf);
19905 switch (flag & 0x3)
19907 case 0:
19908 printf ("(VEC_SIZE):\tNo entry.\n");
19909 break;
19910 case 1:
19911 printf ("(VEC_SIZE):\t4 bytes\n");
19912 break;
19913 case 2:
19914 printf ("(VEC_SIZE):\t16 bytes\n");
19915 break;
19916 case 3:
19917 printf ("(VEC_SIZE):\treserved\n");
19918 break;
19922 return true;
19925 static bool
19926 process_gnu_liblist (Filedata * filedata)
19928 Elf_Internal_Shdr * section;
19929 Elf_Internal_Shdr * string_sec;
19930 Elf32_External_Lib * elib;
19931 char * strtab;
19932 size_t strtab_size;
19933 size_t cnt;
19934 uint64_t num_liblist;
19935 unsigned i;
19936 bool res = true;
19938 if (! do_arch)
19939 return true;
19941 for (i = 0, section = filedata->section_headers;
19942 i < filedata->file_header.e_shnum;
19943 i++, section++)
19945 switch (section->sh_type)
19947 case SHT_GNU_LIBLIST:
19948 if (section->sh_link >= filedata->file_header.e_shnum)
19949 break;
19951 elib = (Elf32_External_Lib *)
19952 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
19953 _("liblist section data"));
19955 if (elib == NULL)
19957 res = false;
19958 break;
19961 string_sec = filedata->section_headers + section->sh_link;
19962 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
19963 string_sec->sh_size,
19964 _("liblist string table"));
19965 if (strtab == NULL
19966 || section->sh_entsize != sizeof (Elf32_External_Lib))
19968 free (elib);
19969 free (strtab);
19970 res = false;
19971 break;
19973 strtab_size = string_sec->sh_size;
19975 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19976 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19977 " entries:\n",
19978 "\nLibrary list section '%s' contains %" PRIu64
19979 " entries:\n",
19980 num_liblist),
19981 printable_section_name (filedata, section),
19982 num_liblist);
19984 puts (_(" Library Time Stamp Checksum Version Flags"));
19986 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19987 ++cnt)
19989 Elf32_Lib liblist;
19990 time_t atime;
19991 char timebuf[128];
19992 struct tm * tmp;
19994 liblist.l_name = BYTE_GET (elib[cnt].l_name);
19995 atime = BYTE_GET (elib[cnt].l_time_stamp);
19996 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19997 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19998 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
20000 tmp = gmtime (&atime);
20001 snprintf (timebuf, sizeof (timebuf),
20002 "%04u-%02u-%02uT%02u:%02u:%02u",
20003 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20004 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
20006 printf ("%3zu: ", cnt);
20007 if (do_wide)
20008 printf ("%-20s", liblist.l_name < strtab_size
20009 ? strtab + liblist.l_name : _("<corrupt>"));
20010 else
20011 printf ("%-20.20s", liblist.l_name < strtab_size
20012 ? strtab + liblist.l_name : _("<corrupt>"));
20013 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20014 liblist.l_version, liblist.l_flags);
20017 free (elib);
20018 free (strtab);
20022 return res;
20025 static const char *
20026 get_note_type (Filedata * filedata, unsigned e_type)
20028 static char buff[64];
20030 if (filedata->file_header.e_type == ET_CORE)
20031 switch (e_type)
20033 case NT_AUXV:
20034 return _("NT_AUXV (auxiliary vector)");
20035 case NT_PRSTATUS:
20036 return _("NT_PRSTATUS (prstatus structure)");
20037 case NT_FPREGSET:
20038 return _("NT_FPREGSET (floating point registers)");
20039 case NT_PRPSINFO:
20040 return _("NT_PRPSINFO (prpsinfo structure)");
20041 case NT_TASKSTRUCT:
20042 return _("NT_TASKSTRUCT (task structure)");
20043 case NT_GDB_TDESC:
20044 return _("NT_GDB_TDESC (GDB XML target description)");
20045 case NT_PRXFPREG:
20046 return _("NT_PRXFPREG (user_xfpregs structure)");
20047 case NT_PPC_VMX:
20048 return _("NT_PPC_VMX (ppc Altivec registers)");
20049 case NT_PPC_VSX:
20050 return _("NT_PPC_VSX (ppc VSX registers)");
20051 case NT_PPC_TAR:
20052 return _("NT_PPC_TAR (ppc TAR register)");
20053 case NT_PPC_PPR:
20054 return _("NT_PPC_PPR (ppc PPR register)");
20055 case NT_PPC_DSCR:
20056 return _("NT_PPC_DSCR (ppc DSCR register)");
20057 case NT_PPC_EBB:
20058 return _("NT_PPC_EBB (ppc EBB registers)");
20059 case NT_PPC_PMU:
20060 return _("NT_PPC_PMU (ppc PMU registers)");
20061 case NT_PPC_TM_CGPR:
20062 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20063 case NT_PPC_TM_CFPR:
20064 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20065 case NT_PPC_TM_CVMX:
20066 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20067 case NT_PPC_TM_CVSX:
20068 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
20069 case NT_PPC_TM_SPR:
20070 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20071 case NT_PPC_TM_CTAR:
20072 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20073 case NT_PPC_TM_CPPR:
20074 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20075 case NT_PPC_TM_CDSCR:
20076 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
20077 case NT_386_TLS:
20078 return _("NT_386_TLS (x86 TLS information)");
20079 case NT_386_IOPERM:
20080 return _("NT_386_IOPERM (x86 I/O permissions)");
20081 case NT_X86_XSTATE:
20082 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
20083 case NT_X86_CET:
20084 return _("NT_X86_CET (x86 CET state)");
20085 case NT_X86_SHSTK:
20086 return _("NT_X86_SHSTK (x86 SHSTK state)");
20087 case NT_S390_HIGH_GPRS:
20088 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
20089 case NT_S390_TIMER:
20090 return _("NT_S390_TIMER (s390 timer register)");
20091 case NT_S390_TODCMP:
20092 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20093 case NT_S390_TODPREG:
20094 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20095 case NT_S390_CTRS:
20096 return _("NT_S390_CTRS (s390 control registers)");
20097 case NT_S390_PREFIX:
20098 return _("NT_S390_PREFIX (s390 prefix register)");
20099 case NT_S390_LAST_BREAK:
20100 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20101 case NT_S390_SYSTEM_CALL:
20102 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
20103 case NT_S390_TDB:
20104 return _("NT_S390_TDB (s390 transaction diagnostic block)");
20105 case NT_S390_VXRS_LOW:
20106 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20107 case NT_S390_VXRS_HIGH:
20108 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
20109 case NT_S390_GS_CB:
20110 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20111 case NT_S390_GS_BC:
20112 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
20113 case NT_ARM_VFP:
20114 return _("NT_ARM_VFP (arm VFP registers)");
20115 case NT_ARM_TLS:
20116 return _("NT_ARM_TLS (AArch TLS registers)");
20117 case NT_ARM_HW_BREAK:
20118 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20119 case NT_ARM_HW_WATCH:
20120 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
20121 case NT_ARM_SYSTEM_CALL:
20122 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
20123 case NT_ARM_SVE:
20124 return _("NT_ARM_SVE (AArch SVE registers)");
20125 case NT_ARM_PAC_MASK:
20126 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
20127 case NT_ARM_PACA_KEYS:
20128 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20129 case NT_ARM_PACG_KEYS:
20130 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
20131 case NT_ARM_TAGGED_ADDR_CTRL:
20132 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
20133 case NT_ARM_SSVE:
20134 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20135 case NT_ARM_ZA:
20136 return _("NT_ARM_ZA (AArch64 SME ZA register)");
20137 case NT_ARM_ZT:
20138 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
20139 case NT_ARM_PAC_ENABLED_KEYS:
20140 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
20141 case NT_ARC_V2:
20142 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
20143 case NT_RISCV_CSR:
20144 return _("NT_RISCV_CSR (RISC-V control and status registers)");
20145 case NT_PSTATUS:
20146 return _("NT_PSTATUS (pstatus structure)");
20147 case NT_FPREGS:
20148 return _("NT_FPREGS (floating point registers)");
20149 case NT_PSINFO:
20150 return _("NT_PSINFO (psinfo structure)");
20151 case NT_LWPSTATUS:
20152 return _("NT_LWPSTATUS (lwpstatus_t structure)");
20153 case NT_LWPSINFO:
20154 return _("NT_LWPSINFO (lwpsinfo_t structure)");
20155 case NT_WIN32PSTATUS:
20156 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
20157 case NT_SIGINFO:
20158 return _("NT_SIGINFO (siginfo_t data)");
20159 case NT_FILE:
20160 return _("NT_FILE (mapped files)");
20161 default:
20162 break;
20164 else
20165 switch (e_type)
20167 case NT_VERSION:
20168 return _("NT_VERSION (version)");
20169 case NT_ARCH:
20170 return _("NT_ARCH (architecture)");
20171 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20172 return _("OPEN");
20173 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20174 return _("func");
20175 case NT_GO_BUILDID:
20176 return _("GO BUILDID");
20177 case FDO_PACKAGING_METADATA:
20178 return _("FDO_PACKAGING_METADATA");
20179 default:
20180 break;
20183 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20184 return buff;
20187 static bool
20188 print_core_note (Elf_Internal_Note *pnote)
20190 unsigned int addr_size = is_32bit_elf ? 4 : 8;
20191 uint64_t count, page_size;
20192 unsigned char *descdata, *filenames, *descend;
20194 if (pnote->type != NT_FILE)
20196 if (do_wide)
20197 printf ("\n");
20198 return true;
20201 if (!is_32bit_elf)
20203 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
20204 /* Still "successful". */
20205 return true;
20208 if (pnote->descsz < 2 * addr_size)
20210 error (_(" Malformed note - too short for header\n"));
20211 return false;
20214 descdata = (unsigned char *) pnote->descdata;
20215 descend = descdata + pnote->descsz;
20217 if (descdata[pnote->descsz - 1] != '\0')
20219 error (_(" Malformed note - does not end with \\0\n"));
20220 return false;
20223 count = byte_get (descdata, addr_size);
20224 descdata += addr_size;
20226 page_size = byte_get (descdata, addr_size);
20227 descdata += addr_size;
20229 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
20230 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
20232 error (_(" Malformed note - too short for supplied file count\n"));
20233 return false;
20236 printf (_(" Page size: "));
20237 print_vma (page_size, DEC);
20238 printf ("\n");
20240 printf (_(" %*s%*s%*s\n"),
20241 (int) (2 + 2 * addr_size), _("Start"),
20242 (int) (4 + 2 * addr_size), _("End"),
20243 (int) (4 + 2 * addr_size), _("Page Offset"));
20244 filenames = descdata + count * 3 * addr_size;
20245 while (count-- > 0)
20247 uint64_t start, end, file_ofs;
20249 if (filenames == descend)
20251 error (_(" Malformed note - filenames end too early\n"));
20252 return false;
20255 start = byte_get (descdata, addr_size);
20256 descdata += addr_size;
20257 end = byte_get (descdata, addr_size);
20258 descdata += addr_size;
20259 file_ofs = byte_get (descdata, addr_size);
20260 descdata += addr_size;
20262 printf (" ");
20263 print_vma (start, FULL_HEX);
20264 printf (" ");
20265 print_vma (end, FULL_HEX);
20266 printf (" ");
20267 print_vma (file_ofs, FULL_HEX);
20268 printf ("\n %s\n", filenames);
20270 filenames += 1 + strlen ((char *) filenames);
20273 return true;
20276 static const char *
20277 get_gnu_elf_note_type (unsigned e_type)
20279 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
20280 switch (e_type)
20282 case NT_GNU_ABI_TAG:
20283 return _("NT_GNU_ABI_TAG (ABI version tag)");
20284 case NT_GNU_HWCAP:
20285 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20286 case NT_GNU_BUILD_ID:
20287 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
20288 case NT_GNU_GOLD_VERSION:
20289 return _("NT_GNU_GOLD_VERSION (gold version)");
20290 case NT_GNU_PROPERTY_TYPE_0:
20291 return _("NT_GNU_PROPERTY_TYPE_0");
20292 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20293 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20294 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20295 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
20296 default:
20298 static char buff[64];
20300 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20301 return buff;
20306 static void
20307 decode_x86_compat_isa (unsigned int bitmask)
20309 while (bitmask)
20311 unsigned int bit = bitmask & (- bitmask);
20313 bitmask &= ~ bit;
20314 switch (bit)
20316 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20317 printf ("i486");
20318 break;
20319 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20320 printf ("586");
20321 break;
20322 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20323 printf ("686");
20324 break;
20325 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20326 printf ("SSE");
20327 break;
20328 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20329 printf ("SSE2");
20330 break;
20331 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20332 printf ("SSE3");
20333 break;
20334 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20335 printf ("SSSE3");
20336 break;
20337 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20338 printf ("SSE4_1");
20339 break;
20340 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20341 printf ("SSE4_2");
20342 break;
20343 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20344 printf ("AVX");
20345 break;
20346 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20347 printf ("AVX2");
20348 break;
20349 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20350 printf ("AVX512F");
20351 break;
20352 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20353 printf ("AVX512CD");
20354 break;
20355 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20356 printf ("AVX512ER");
20357 break;
20358 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20359 printf ("AVX512PF");
20360 break;
20361 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20362 printf ("AVX512VL");
20363 break;
20364 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20365 printf ("AVX512DQ");
20366 break;
20367 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20368 printf ("AVX512BW");
20369 break;
20370 default:
20371 printf (_("<unknown: %x>"), bit);
20372 break;
20374 if (bitmask)
20375 printf (", ");
20379 static void
20380 decode_x86_compat_2_isa (unsigned int bitmask)
20382 if (!bitmask)
20384 printf (_("<None>"));
20385 return;
20388 while (bitmask)
20390 unsigned int bit = bitmask & (- bitmask);
20392 bitmask &= ~ bit;
20393 switch (bit)
20395 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
20396 printf ("CMOV");
20397 break;
20398 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
20399 printf ("SSE");
20400 break;
20401 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
20402 printf ("SSE2");
20403 break;
20404 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
20405 printf ("SSE3");
20406 break;
20407 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
20408 printf ("SSSE3");
20409 break;
20410 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
20411 printf ("SSE4_1");
20412 break;
20413 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
20414 printf ("SSE4_2");
20415 break;
20416 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
20417 printf ("AVX");
20418 break;
20419 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
20420 printf ("AVX2");
20421 break;
20422 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
20423 printf ("FMA");
20424 break;
20425 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
20426 printf ("AVX512F");
20427 break;
20428 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
20429 printf ("AVX512CD");
20430 break;
20431 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
20432 printf ("AVX512ER");
20433 break;
20434 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
20435 printf ("AVX512PF");
20436 break;
20437 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
20438 printf ("AVX512VL");
20439 break;
20440 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
20441 printf ("AVX512DQ");
20442 break;
20443 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
20444 printf ("AVX512BW");
20445 break;
20446 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
20447 printf ("AVX512_4FMAPS");
20448 break;
20449 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
20450 printf ("AVX512_4VNNIW");
20451 break;
20452 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
20453 printf ("AVX512_BITALG");
20454 break;
20455 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
20456 printf ("AVX512_IFMA");
20457 break;
20458 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
20459 printf ("AVX512_VBMI");
20460 break;
20461 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
20462 printf ("AVX512_VBMI2");
20463 break;
20464 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
20465 printf ("AVX512_VNNI");
20466 break;
20467 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
20468 printf ("AVX512_BF16");
20469 break;
20470 default:
20471 printf (_("<unknown: %x>"), bit);
20472 break;
20474 if (bitmask)
20475 printf (", ");
20479 static const char *
20480 get_amdgpu_elf_note_type (unsigned int e_type)
20482 switch (e_type)
20484 case NT_AMDGPU_METADATA:
20485 return _("NT_AMDGPU_METADATA (code object metadata)");
20486 default:
20488 static char buf[64];
20489 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20490 return buf;
20495 static void
20496 decode_x86_isa (unsigned int bitmask)
20498 while (bitmask)
20500 unsigned int bit = bitmask & (- bitmask);
20502 bitmask &= ~ bit;
20503 switch (bit)
20505 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20506 printf ("x86-64-baseline");
20507 break;
20508 case GNU_PROPERTY_X86_ISA_1_V2:
20509 printf ("x86-64-v2");
20510 break;
20511 case GNU_PROPERTY_X86_ISA_1_V3:
20512 printf ("x86-64-v3");
20513 break;
20514 case GNU_PROPERTY_X86_ISA_1_V4:
20515 printf ("x86-64-v4");
20516 break;
20517 default:
20518 printf (_("<unknown: %x>"), bit);
20519 break;
20521 if (bitmask)
20522 printf (", ");
20526 static void
20527 decode_x86_feature_1 (unsigned int bitmask)
20529 if (!bitmask)
20531 printf (_("<None>"));
20532 return;
20535 while (bitmask)
20537 unsigned int bit = bitmask & (- bitmask);
20539 bitmask &= ~ bit;
20540 switch (bit)
20542 case GNU_PROPERTY_X86_FEATURE_1_IBT:
20543 printf ("IBT");
20544 break;
20545 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
20546 printf ("SHSTK");
20547 break;
20548 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20549 printf ("LAM_U48");
20550 break;
20551 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20552 printf ("LAM_U57");
20553 break;
20554 default:
20555 printf (_("<unknown: %x>"), bit);
20556 break;
20558 if (bitmask)
20559 printf (", ");
20563 static void
20564 decode_x86_feature_2 (unsigned int bitmask)
20566 if (!bitmask)
20568 printf (_("<None>"));
20569 return;
20572 while (bitmask)
20574 unsigned int bit = bitmask & (- bitmask);
20576 bitmask &= ~ bit;
20577 switch (bit)
20579 case GNU_PROPERTY_X86_FEATURE_2_X86:
20580 printf ("x86");
20581 break;
20582 case GNU_PROPERTY_X86_FEATURE_2_X87:
20583 printf ("x87");
20584 break;
20585 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20586 printf ("MMX");
20587 break;
20588 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20589 printf ("XMM");
20590 break;
20591 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20592 printf ("YMM");
20593 break;
20594 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20595 printf ("ZMM");
20596 break;
20597 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20598 printf ("TMM");
20599 break;
20600 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20601 printf ("MASK");
20602 break;
20603 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20604 printf ("FXSR");
20605 break;
20606 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20607 printf ("XSAVE");
20608 break;
20609 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20610 printf ("XSAVEOPT");
20611 break;
20612 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20613 printf ("XSAVEC");
20614 break;
20615 default:
20616 printf (_("<unknown: %x>"), bit);
20617 break;
20619 if (bitmask)
20620 printf (", ");
20624 static void
20625 decode_aarch64_feature_1_and (unsigned int bitmask)
20627 while (bitmask)
20629 unsigned int bit = bitmask & (- bitmask);
20631 bitmask &= ~ bit;
20632 switch (bit)
20634 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20635 printf ("BTI");
20636 break;
20638 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20639 printf ("PAC");
20640 break;
20642 default:
20643 printf (_("<unknown: %x>"), bit);
20644 break;
20646 if (bitmask)
20647 printf (", ");
20651 static void
20652 decode_1_needed (unsigned int bitmask)
20654 while (bitmask)
20656 unsigned int bit = bitmask & (- bitmask);
20658 bitmask &= ~ bit;
20659 switch (bit)
20661 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20662 printf ("indirect external access");
20663 break;
20664 default:
20665 printf (_("<unknown: %x>"), bit);
20666 break;
20668 if (bitmask)
20669 printf (", ");
20673 static void
20674 print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
20676 unsigned char * ptr = (unsigned char *) pnote->descdata;
20677 unsigned char * ptr_end = ptr + pnote->descsz;
20678 unsigned int size = is_32bit_elf ? 4 : 8;
20680 printf (_(" Properties: "));
20682 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
20684 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20685 return;
20688 while (ptr < ptr_end)
20690 unsigned int j;
20691 unsigned int type;
20692 unsigned int datasz;
20694 if ((size_t) (ptr_end - ptr) < 8)
20696 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20697 break;
20700 type = byte_get (ptr, 4);
20701 datasz = byte_get (ptr + 4, 4);
20703 ptr += 8;
20705 if (datasz > (size_t) (ptr_end - ptr))
20707 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20708 type, datasz);
20709 break;
20712 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20714 if (filedata->file_header.e_machine == EM_X86_64
20715 || filedata->file_header.e_machine == EM_IAMCU
20716 || filedata->file_header.e_machine == EM_386)
20718 unsigned int bitmask;
20720 if (datasz == 4)
20721 bitmask = byte_get (ptr, 4);
20722 else
20723 bitmask = 0;
20725 switch (type)
20727 case GNU_PROPERTY_X86_ISA_1_USED:
20728 if (datasz != 4)
20729 printf (_("x86 ISA used: <corrupt length: %#x> "),
20730 datasz);
20731 else
20733 printf ("x86 ISA used: ");
20734 decode_x86_isa (bitmask);
20736 goto next;
20738 case GNU_PROPERTY_X86_ISA_1_NEEDED:
20739 if (datasz != 4)
20740 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20741 datasz);
20742 else
20744 printf ("x86 ISA needed: ");
20745 decode_x86_isa (bitmask);
20747 goto next;
20749 case GNU_PROPERTY_X86_FEATURE_1_AND:
20750 if (datasz != 4)
20751 printf (_("x86 feature: <corrupt length: %#x> "),
20752 datasz);
20753 else
20755 printf ("x86 feature: ");
20756 decode_x86_feature_1 (bitmask);
20758 goto next;
20760 case GNU_PROPERTY_X86_FEATURE_2_USED:
20761 if (datasz != 4)
20762 printf (_("x86 feature used: <corrupt length: %#x> "),
20763 datasz);
20764 else
20766 printf ("x86 feature used: ");
20767 decode_x86_feature_2 (bitmask);
20769 goto next;
20771 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20772 if (datasz != 4)
20773 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20774 else
20776 printf ("x86 feature needed: ");
20777 decode_x86_feature_2 (bitmask);
20779 goto next;
20781 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20782 if (datasz != 4)
20783 printf (_("x86 ISA used: <corrupt length: %#x> "),
20784 datasz);
20785 else
20787 printf ("x86 ISA used: ");
20788 decode_x86_compat_isa (bitmask);
20790 goto next;
20792 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20793 if (datasz != 4)
20794 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20795 datasz);
20796 else
20798 printf ("x86 ISA needed: ");
20799 decode_x86_compat_isa (bitmask);
20801 goto next;
20803 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20804 if (datasz != 4)
20805 printf (_("x86 ISA used: <corrupt length: %#x> "),
20806 datasz);
20807 else
20809 printf ("x86 ISA used: ");
20810 decode_x86_compat_2_isa (bitmask);
20812 goto next;
20814 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20815 if (datasz != 4)
20816 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20817 datasz);
20818 else
20820 printf ("x86 ISA needed: ");
20821 decode_x86_compat_2_isa (bitmask);
20823 goto next;
20825 default:
20826 break;
20829 else if (filedata->file_header.e_machine == EM_AARCH64)
20831 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20833 printf ("AArch64 feature: ");
20834 if (datasz != 4)
20835 printf (_("<corrupt length: %#x> "), datasz);
20836 else
20837 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20838 goto next;
20842 else
20844 switch (type)
20846 case GNU_PROPERTY_STACK_SIZE:
20847 printf (_("stack size: "));
20848 if (datasz != size)
20849 printf (_("<corrupt length: %#x> "), datasz);
20850 else
20851 printf ("%#" PRIx64, byte_get (ptr, size));
20852 goto next;
20854 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20855 printf ("no copy on protected ");
20856 if (datasz)
20857 printf (_("<corrupt length: %#x> "), datasz);
20858 goto next;
20860 default:
20861 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20862 && type <= GNU_PROPERTY_UINT32_AND_HI)
20863 || (type >= GNU_PROPERTY_UINT32_OR_LO
20864 && type <= GNU_PROPERTY_UINT32_OR_HI))
20866 switch (type)
20868 case GNU_PROPERTY_1_NEEDED:
20869 if (datasz != 4)
20870 printf (_("1_needed: <corrupt length: %#x> "),
20871 datasz);
20872 else
20874 unsigned int bitmask = byte_get (ptr, 4);
20875 printf ("1_needed: ");
20876 decode_1_needed (bitmask);
20878 goto next;
20880 default:
20881 break;
20883 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20884 printf (_("UINT32_AND (%#x): "), type);
20885 else
20886 printf (_("UINT32_OR (%#x): "), type);
20887 if (datasz != 4)
20888 printf (_("<corrupt length: %#x> "), datasz);
20889 else
20890 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20891 goto next;
20893 break;
20897 if (type < GNU_PROPERTY_LOPROC)
20898 printf (_("<unknown type %#x data: "), type);
20899 else if (type < GNU_PROPERTY_LOUSER)
20900 printf (_("<processor-specific type %#x data: "), type);
20901 else
20902 printf (_("<application-specific type %#x data: "), type);
20903 for (j = 0; j < datasz; ++j)
20904 printf ("%02x ", ptr[j] & 0xff);
20905 printf (">");
20907 next:
20908 ptr += ((datasz + (size - 1)) & ~ (size - 1));
20909 if (ptr == ptr_end)
20910 break;
20912 if (do_wide)
20913 printf (", ");
20914 else
20915 printf ("\n\t");
20918 printf ("\n");
20921 static bool
20922 print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
20924 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
20925 switch (pnote->type)
20927 case NT_GNU_BUILD_ID:
20929 size_t i;
20931 printf (_(" Build ID: "));
20932 for (i = 0; i < pnote->descsz; ++i)
20933 printf ("%02x", pnote->descdata[i] & 0xff);
20934 printf ("\n");
20936 break;
20938 case NT_GNU_ABI_TAG:
20940 unsigned int os, major, minor, subminor;
20941 const char *osname;
20943 /* PR 17531: file: 030-599401-0.004. */
20944 if (pnote->descsz < 16)
20946 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20947 break;
20950 os = byte_get ((unsigned char *) pnote->descdata, 4);
20951 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20952 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20953 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20955 switch (os)
20957 case GNU_ABI_TAG_LINUX:
20958 osname = "Linux";
20959 break;
20960 case GNU_ABI_TAG_HURD:
20961 osname = "Hurd";
20962 break;
20963 case GNU_ABI_TAG_SOLARIS:
20964 osname = "Solaris";
20965 break;
20966 case GNU_ABI_TAG_FREEBSD:
20967 osname = "FreeBSD";
20968 break;
20969 case GNU_ABI_TAG_NETBSD:
20970 osname = "NetBSD";
20971 break;
20972 case GNU_ABI_TAG_SYLLABLE:
20973 osname = "Syllable";
20974 break;
20975 case GNU_ABI_TAG_NACL:
20976 osname = "NaCl";
20977 break;
20978 default:
20979 osname = "Unknown";
20980 break;
20983 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
20984 major, minor, subminor);
20986 break;
20988 case NT_GNU_GOLD_VERSION:
20990 size_t i;
20992 printf (_(" Version: "));
20993 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20994 printf ("%c", pnote->descdata[i]);
20995 printf ("\n");
20997 break;
20999 case NT_GNU_HWCAP:
21001 unsigned int num_entries, mask;
21003 /* Hardware capabilities information. Word 0 is the number of entries.
21004 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21005 is a series of entries, where each entry is a single byte followed
21006 by a nul terminated string. The byte gives the bit number to test
21007 if enabled in the bitmask. */
21008 printf (_(" Hardware Capabilities: "));
21009 if (pnote->descsz < 8)
21011 error (_("<corrupt GNU_HWCAP>\n"));
21012 return false;
21014 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21015 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21016 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
21017 /* FIXME: Add code to display the entries... */
21019 break;
21021 case NT_GNU_PROPERTY_TYPE_0:
21022 print_gnu_property_note (filedata, pnote);
21023 break;
21025 default:
21026 /* Handle unrecognised types. An error message should have already been
21027 created by get_gnu_elf_note_type(), so all that we need to do is to
21028 display the data. */
21030 size_t i;
21032 printf (_(" Description data: "));
21033 for (i = 0; i < pnote->descsz; ++i)
21034 printf ("%02x ", pnote->descdata[i] & 0xff);
21035 printf ("\n");
21037 break;
21040 return true;
21043 static const char *
21044 get_v850_elf_note_type (enum v850_notes n_type)
21046 static char buff[64];
21048 switch (n_type)
21050 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21051 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21052 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21053 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21054 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21055 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21056 default:
21057 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21058 return buff;
21062 static bool
21063 print_v850_note (Elf_Internal_Note * pnote)
21065 unsigned int val;
21067 if (pnote->descsz != 4)
21068 return false;
21070 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21072 if (val == 0)
21074 printf (_("not set\n"));
21075 return true;
21078 switch (pnote->type)
21080 case V850_NOTE_ALIGNMENT:
21081 switch (val)
21083 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21084 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
21086 break;
21088 case V850_NOTE_DATA_SIZE:
21089 switch (val)
21091 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21092 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
21094 break;
21096 case V850_NOTE_FPU_INFO:
21097 switch (val)
21099 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21100 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
21102 break;
21104 case V850_NOTE_MMU_INFO:
21105 case V850_NOTE_CACHE_INFO:
21106 case V850_NOTE_SIMD_INFO:
21107 if (val == EF_RH850_SIMD)
21109 printf (_("yes\n"));
21110 return true;
21112 break;
21114 default:
21115 /* An 'unknown note type' message will already have been displayed. */
21116 break;
21119 printf (_("unknown value: %x\n"), val);
21120 return false;
21123 static bool
21124 process_netbsd_elf_note (Elf_Internal_Note * pnote)
21126 unsigned int version;
21128 switch (pnote->type)
21130 case NT_NETBSD_IDENT:
21131 if (pnote->descsz < 1)
21132 break;
21133 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21134 if ((version / 10000) % 100)
21135 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
21136 version, version / 100000000, (version / 1000000) % 100,
21137 (version / 10000) % 100 > 26 ? "Z" : "",
21138 'A' + (version / 10000) % 26);
21139 else
21140 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
21141 version, version / 100000000, (version / 1000000) % 100,
21142 (version / 100) % 100);
21143 return true;
21145 case NT_NETBSD_MARCH:
21146 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
21147 pnote->descdata);
21148 return true;
21150 case NT_NETBSD_PAX:
21151 if (pnote->descsz < 1)
21152 break;
21153 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21154 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21155 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21156 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21157 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21158 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21159 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21160 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
21161 return true;
21164 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21165 pnote->descsz, pnote->type);
21166 return false;
21169 static const char *
21170 get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21172 switch (e_type)
21174 case NT_FREEBSD_THRMISC:
21175 return _("NT_THRMISC (thrmisc structure)");
21176 case NT_FREEBSD_PROCSTAT_PROC:
21177 return _("NT_PROCSTAT_PROC (proc data)");
21178 case NT_FREEBSD_PROCSTAT_FILES:
21179 return _("NT_PROCSTAT_FILES (files data)");
21180 case NT_FREEBSD_PROCSTAT_VMMAP:
21181 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21182 case NT_FREEBSD_PROCSTAT_GROUPS:
21183 return _("NT_PROCSTAT_GROUPS (groups data)");
21184 case NT_FREEBSD_PROCSTAT_UMASK:
21185 return _("NT_PROCSTAT_UMASK (umask data)");
21186 case NT_FREEBSD_PROCSTAT_RLIMIT:
21187 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21188 case NT_FREEBSD_PROCSTAT_OSREL:
21189 return _("NT_PROCSTAT_OSREL (osreldate data)");
21190 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21191 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21192 case NT_FREEBSD_PROCSTAT_AUXV:
21193 return _("NT_PROCSTAT_AUXV (auxv data)");
21194 case NT_FREEBSD_PTLWPINFO:
21195 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
21196 case NT_FREEBSD_X86_SEGBASES:
21197 return _("NT_X86_SEGBASES (x86 segment base registers)");
21199 return get_note_type (filedata, e_type);
21202 static const char *
21203 get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21205 static char buff[64];
21207 switch (e_type)
21209 case NT_NETBSDCORE_PROCINFO:
21210 /* NetBSD core "procinfo" structure. */
21211 return _("NetBSD procinfo structure");
21213 case NT_NETBSDCORE_AUXV:
21214 return _("NetBSD ELF auxiliary vector data");
21216 case NT_NETBSDCORE_LWPSTATUS:
21217 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
21219 default:
21220 /* As of Jan 2020 there are no other machine-independent notes
21221 defined for NetBSD core files. If the note type is less
21222 than the start of the machine-dependent note types, we don't
21223 understand it. */
21225 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21227 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21228 return buff;
21230 break;
21233 switch (filedata->file_header.e_machine)
21235 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21236 and PT_GETFPREGS == mach+2. */
21238 case EM_OLD_ALPHA:
21239 case EM_ALPHA:
21240 case EM_SPARC:
21241 case EM_SPARC32PLUS:
21242 case EM_SPARCV9:
21243 switch (e_type)
21245 case NT_NETBSDCORE_FIRSTMACH + 0:
21246 return _("PT_GETREGS (reg structure)");
21247 case NT_NETBSDCORE_FIRSTMACH + 2:
21248 return _("PT_GETFPREGS (fpreg structure)");
21249 default:
21250 break;
21252 break;
21254 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21255 There's also old PT___GETREGS40 == mach + 1 for old reg
21256 structure which lacks GBR. */
21257 case EM_SH:
21258 switch (e_type)
21260 case NT_NETBSDCORE_FIRSTMACH + 1:
21261 return _("PT___GETREGS40 (old reg structure)");
21262 case NT_NETBSDCORE_FIRSTMACH + 3:
21263 return _("PT_GETREGS (reg structure)");
21264 case NT_NETBSDCORE_FIRSTMACH + 5:
21265 return _("PT_GETFPREGS (fpreg structure)");
21266 default:
21267 break;
21269 break;
21271 /* On all other arch's, PT_GETREGS == mach+1 and
21272 PT_GETFPREGS == mach+3. */
21273 default:
21274 switch (e_type)
21276 case NT_NETBSDCORE_FIRSTMACH + 1:
21277 return _("PT_GETREGS (reg structure)");
21278 case NT_NETBSDCORE_FIRSTMACH + 3:
21279 return _("PT_GETFPREGS (fpreg structure)");
21280 default:
21281 break;
21285 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
21286 e_type - NT_NETBSDCORE_FIRSTMACH);
21287 return buff;
21290 static const char *
21291 get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21293 switch (e_type)
21295 case NT_OPENBSD_PROCINFO:
21296 return _("OpenBSD procinfo structure");
21297 case NT_OPENBSD_AUXV:
21298 return _("OpenBSD ELF auxiliary vector data");
21299 case NT_OPENBSD_REGS:
21300 return _("OpenBSD regular registers");
21301 case NT_OPENBSD_FPREGS:
21302 return _("OpenBSD floating point registers");
21303 case NT_OPENBSD_WCOOKIE:
21304 return _("OpenBSD window cookie");
21307 return get_note_type (filedata, e_type);
21310 static const char *
21311 get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21313 switch (e_type)
21315 case QNT_DEBUG_FULLPATH:
21316 return _("QNX debug fullpath");
21317 case QNT_DEBUG_RELOC:
21318 return _("QNX debug relocation");
21319 case QNT_STACK:
21320 return _("QNX stack");
21321 case QNT_GENERATOR:
21322 return _("QNX generator");
21323 case QNT_DEFAULT_LIB:
21324 return _("QNX default library");
21325 case QNT_CORE_SYSINFO:
21326 return _("QNX core sysinfo");
21327 case QNT_CORE_INFO:
21328 return _("QNX core info");
21329 case QNT_CORE_STATUS:
21330 return _("QNX core status");
21331 case QNT_CORE_GREG:
21332 return _("QNX general registers");
21333 case QNT_CORE_FPREG:
21334 return _("QNX floating point registers");
21335 case QNT_LINK_MAP:
21336 return _("QNX link map");
21339 return get_note_type (filedata, e_type);
21342 static const char *
21343 get_stapsdt_note_type (unsigned e_type)
21345 static char buff[64];
21347 switch (e_type)
21349 case NT_STAPSDT:
21350 return _("NT_STAPSDT (SystemTap probe descriptors)");
21352 default:
21353 break;
21356 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21357 return buff;
21360 static bool
21361 print_stapsdt_note (Elf_Internal_Note *pnote)
21363 size_t len, maxlen;
21364 size_t addr_size = is_32bit_elf ? 4 : 8;
21365 char *data = pnote->descdata;
21366 char *data_end = pnote->descdata + pnote->descsz;
21367 uint64_t pc, base_addr, semaphore;
21368 char *provider, *probe, *arg_fmt;
21370 if (pnote->descsz < (addr_size * 3))
21371 goto stapdt_note_too_small;
21373 pc = byte_get ((unsigned char *) data, addr_size);
21374 data += addr_size;
21376 base_addr = byte_get ((unsigned char *) data, addr_size);
21377 data += addr_size;
21379 semaphore = byte_get ((unsigned char *) data, addr_size);
21380 data += addr_size;
21382 if (data >= data_end)
21383 goto stapdt_note_too_small;
21384 maxlen = data_end - data;
21385 len = strnlen (data, maxlen);
21386 if (len < maxlen)
21388 provider = data;
21389 data += len + 1;
21391 else
21392 goto stapdt_note_too_small;
21394 if (data >= data_end)
21395 goto stapdt_note_too_small;
21396 maxlen = data_end - data;
21397 len = strnlen (data, maxlen);
21398 if (len < maxlen)
21400 probe = data;
21401 data += len + 1;
21403 else
21404 goto stapdt_note_too_small;
21406 if (data >= data_end)
21407 goto stapdt_note_too_small;
21408 maxlen = data_end - data;
21409 len = strnlen (data, maxlen);
21410 if (len < maxlen)
21412 arg_fmt = data;
21413 data += len + 1;
21415 else
21416 goto stapdt_note_too_small;
21418 printf (_(" Provider: %s\n"), provider);
21419 printf (_(" Name: %s\n"), probe);
21420 printf (_(" Location: "));
21421 print_vma (pc, FULL_HEX);
21422 printf (_(", Base: "));
21423 print_vma (base_addr, FULL_HEX);
21424 printf (_(", Semaphore: "));
21425 print_vma (semaphore, FULL_HEX);
21426 printf ("\n");
21427 printf (_(" Arguments: %s\n"), arg_fmt);
21429 return data == data_end;
21431 stapdt_note_too_small:
21432 printf (_(" <corrupt - note is too small>\n"));
21433 error (_("corrupt stapdt note - the data size is too small\n"));
21434 return false;
21437 static bool
21438 print_fdo_note (Elf_Internal_Note * pnote)
21440 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
21442 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
21443 return true;
21445 return false;
21448 static const char *
21449 get_ia64_vms_note_type (unsigned e_type)
21451 static char buff[64];
21453 switch (e_type)
21455 case NT_VMS_MHD:
21456 return _("NT_VMS_MHD (module header)");
21457 case NT_VMS_LNM:
21458 return _("NT_VMS_LNM (language name)");
21459 case NT_VMS_SRC:
21460 return _("NT_VMS_SRC (source files)");
21461 case NT_VMS_TITLE:
21462 return "NT_VMS_TITLE";
21463 case NT_VMS_EIDC:
21464 return _("NT_VMS_EIDC (consistency check)");
21465 case NT_VMS_FPMODE:
21466 return _("NT_VMS_FPMODE (FP mode)");
21467 case NT_VMS_LINKTIME:
21468 return "NT_VMS_LINKTIME";
21469 case NT_VMS_IMGNAM:
21470 return _("NT_VMS_IMGNAM (image name)");
21471 case NT_VMS_IMGID:
21472 return _("NT_VMS_IMGID (image id)");
21473 case NT_VMS_LINKID:
21474 return _("NT_VMS_LINKID (link id)");
21475 case NT_VMS_IMGBID:
21476 return _("NT_VMS_IMGBID (build id)");
21477 case NT_VMS_GSTNAM:
21478 return _("NT_VMS_GSTNAM (sym table name)");
21479 case NT_VMS_ORIG_DYN:
21480 return "NT_VMS_ORIG_DYN";
21481 case NT_VMS_PATCHTIME:
21482 return "NT_VMS_PATCHTIME";
21483 default:
21484 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21485 return buff;
21489 static bool
21490 print_ia64_vms_note (Elf_Internal_Note * pnote)
21492 unsigned int maxlen = pnote->descsz;
21494 if (maxlen < 2 || maxlen != pnote->descsz)
21495 goto desc_size_fail;
21497 switch (pnote->type)
21499 case NT_VMS_MHD:
21500 if (maxlen <= 36)
21501 goto desc_size_fail;
21503 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
21505 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21506 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21507 if (l + 34 < maxlen)
21509 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21510 if (l + 35 < maxlen)
21511 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21512 else
21513 printf (_(" Module version : <missing>\n"));
21515 else
21517 printf (_(" Module name : <missing>\n"));
21518 printf (_(" Module version : <missing>\n"));
21520 break;
21522 case NT_VMS_LNM:
21523 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
21524 break;
21526 case NT_VMS_FPMODE:
21527 printf (_(" Floating Point mode: "));
21528 if (maxlen < 8)
21529 goto desc_size_fail;
21530 /* FIXME: Generate an error if descsz > 8 ? */
21532 printf ("0x%016" PRIx64 "\n",
21533 byte_get ((unsigned char *) pnote->descdata, 8));
21534 break;
21536 case NT_VMS_LINKTIME:
21537 printf (_(" Link time: "));
21538 if (maxlen < 8)
21539 goto desc_size_fail;
21540 /* FIXME: Generate an error if descsz > 8 ? */
21542 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
21543 printf ("\n");
21544 break;
21546 case NT_VMS_PATCHTIME:
21547 printf (_(" Patch time: "));
21548 if (maxlen < 8)
21549 goto desc_size_fail;
21550 /* FIXME: Generate an error if descsz > 8 ? */
21552 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
21553 printf ("\n");
21554 break;
21556 case NT_VMS_ORIG_DYN:
21557 if (maxlen < 34)
21558 goto desc_size_fail;
21560 printf (_(" Major id: %u, minor id: %u\n"),
21561 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21562 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
21563 printf (_(" Last modified : "));
21564 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
21565 printf (_("\n Link flags : "));
21566 printf ("0x%016" PRIx64 "\n",
21567 byte_get ((unsigned char *) pnote->descdata + 16, 8));
21568 printf (_(" Header flags: 0x%08x\n"),
21569 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
21570 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
21571 break;
21573 case NT_VMS_IMGNAM:
21574 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
21575 break;
21577 case NT_VMS_GSTNAM:
21578 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
21579 break;
21581 case NT_VMS_IMGID:
21582 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
21583 break;
21585 case NT_VMS_LINKID:
21586 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
21587 break;
21589 default:
21590 return false;
21593 return true;
21595 desc_size_fail:
21596 printf (_(" <corrupt - data size is too small>\n"));
21597 error (_("corrupt IA64 note: data size is too small\n"));
21598 return false;
21601 struct build_attr_cache {
21602 Filedata *filedata;
21603 char *strtab;
21604 uint64_t strtablen;
21605 Elf_Internal_Sym *symtab;
21606 uint64_t nsyms;
21607 } ba_cache;
21609 /* Find the symbol associated with a build attribute that is attached
21610 to address OFFSET. If PNAME is non-NULL then store the name of
21611 the symbol (if found) in the provided pointer, Returns NULL if a
21612 symbol could not be found. */
21614 static Elf_Internal_Sym *
21615 get_symbol_for_build_attribute (Filedata *filedata,
21616 uint64_t offset,
21617 bool is_open_attr,
21618 const char **pname)
21620 Elf_Internal_Sym *saved_sym = NULL;
21621 Elf_Internal_Sym *sym;
21623 if (filedata->section_headers != NULL
21624 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
21626 Elf_Internal_Shdr * symsec;
21628 free (ba_cache.strtab);
21629 ba_cache.strtab = NULL;
21630 free (ba_cache.symtab);
21631 ba_cache.symtab = NULL;
21633 /* Load the symbol and string sections. */
21634 for (symsec = filedata->section_headers;
21635 symsec < filedata->section_headers + filedata->file_header.e_shnum;
21636 symsec ++)
21638 if (symsec->sh_type == SHT_SYMTAB
21639 && get_symtab (filedata, symsec,
21640 &ba_cache.symtab, &ba_cache.nsyms,
21641 &ba_cache.strtab, &ba_cache.strtablen))
21642 break;
21644 ba_cache.filedata = filedata;
21647 if (ba_cache.symtab == NULL)
21648 return NULL;
21650 /* Find a symbol whose value matches offset. */
21651 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
21652 if (sym->st_value == offset)
21654 if (sym->st_name >= ba_cache.strtablen)
21655 /* Huh ? This should not happen. */
21656 continue;
21658 if (ba_cache.strtab[sym->st_name] == 0)
21659 continue;
21661 /* The AArch64, ARM and RISC-V architectures define mapping symbols
21662 (eg $d, $x, $t) which we want to ignore. */
21663 if (ba_cache.strtab[sym->st_name] == '$'
21664 && ba_cache.strtab[sym->st_name + 1] != 0
21665 && ba_cache.strtab[sym->st_name + 2] == 0)
21666 continue;
21668 if (is_open_attr)
21670 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21671 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21672 FUNC symbols entirely. */
21673 switch (ELF_ST_TYPE (sym->st_info))
21675 case STT_OBJECT:
21676 case STT_FILE:
21677 saved_sym = sym;
21678 if (sym->st_size)
21680 /* If the symbol has a size associated
21681 with it then we can stop searching. */
21682 sym = ba_cache.symtab + ba_cache.nsyms;
21684 continue;
21686 case STT_FUNC:
21687 /* Ignore function symbols. */
21688 continue;
21690 default:
21691 break;
21694 switch (ELF_ST_BIND (sym->st_info))
21696 case STB_GLOBAL:
21697 if (saved_sym == NULL
21698 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21699 saved_sym = sym;
21700 break;
21702 case STB_LOCAL:
21703 if (saved_sym == NULL)
21704 saved_sym = sym;
21705 break;
21707 default:
21708 break;
21711 else
21713 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21714 continue;
21716 saved_sym = sym;
21717 break;
21721 if (saved_sym && pname)
21722 * pname = ba_cache.strtab + saved_sym->st_name;
21724 return saved_sym;
21727 /* Returns true iff addr1 and addr2 are in the same section. */
21729 static bool
21730 same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
21732 Elf_Internal_Shdr * a1;
21733 Elf_Internal_Shdr * a2;
21735 a1 = find_section_by_address (filedata, addr1);
21736 a2 = find_section_by_address (filedata, addr2);
21738 return a1 == a2 && a1 != NULL;
21741 static bool
21742 print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21743 Filedata * filedata)
21745 static uint64_t global_offset = 0;
21746 static uint64_t global_end = 0;
21747 static uint64_t func_offset = 0;
21748 static uint64_t func_end = 0;
21750 Elf_Internal_Sym *sym;
21751 const char *name;
21752 uint64_t start;
21753 uint64_t end;
21754 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
21756 switch (pnote->descsz)
21758 case 0:
21759 /* A zero-length description means that the range of
21760 the previous note of the same type should be used. */
21761 if (is_open_attr)
21763 if (global_end > global_offset)
21764 printf (_(" Applies to region from %#" PRIx64
21765 " to %#" PRIx64 "\n"), global_offset, global_end);
21766 else
21767 printf (_(" Applies to region from %#" PRIx64
21768 "\n"), global_offset);
21770 else
21772 if (func_end > func_offset)
21773 printf (_(" Applies to region from %#" PRIx64
21774 " to %#" PRIx64 "\n"), func_offset, func_end);
21775 else
21776 printf (_(" Applies to region from %#" PRIx64
21777 "\n"), func_offset);
21779 return true;
21781 case 4:
21782 start = byte_get ((unsigned char *) pnote->descdata, 4);
21783 end = 0;
21784 break;
21786 case 8:
21787 start = byte_get ((unsigned char *) pnote->descdata, 4);
21788 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21789 break;
21791 case 16:
21792 start = byte_get ((unsigned char *) pnote->descdata, 8);
21793 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21794 break;
21796 default:
21797 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21798 printf (_(" <invalid descsz>"));
21799 return false;
21802 name = NULL;
21803 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
21804 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21805 in order to avoid them being confused with the start address of the
21806 first function in the file... */
21807 if (sym == NULL && is_open_attr)
21808 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21809 & name);
21811 if (end == 0 && sym != NULL && sym->st_size > 0)
21812 end = start + sym->st_size;
21814 if (is_open_attr)
21816 /* FIXME: Need to properly allow for section alignment.
21817 16 is just the alignment used on x86_64. */
21818 if (global_end > 0
21819 && start > BFD_ALIGN (global_end, 16)
21820 /* Build notes are not guaranteed to be organised in order of
21821 increasing address, but we should find the all of the notes
21822 for one section in the same place. */
21823 && same_section (filedata, start, global_end))
21824 warn (_("Gap in build notes detected from %#" PRIx64
21825 " to %#" PRIx64 "\n"),
21826 global_end + 1, start - 1);
21828 printf (_(" Applies to region from %#" PRIx64), start);
21829 global_offset = start;
21831 if (end)
21833 printf (_(" to %#" PRIx64), end);
21834 global_end = end;
21837 else
21839 printf (_(" Applies to region from %#" PRIx64), start);
21840 func_offset = start;
21842 if (end)
21844 printf (_(" to %#" PRIx64), end);
21845 func_end = end;
21849 if (sym && name)
21850 printf (_(" (%s)"), name);
21852 printf ("\n");
21853 return true;
21856 static bool
21857 print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21859 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21860 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21861 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
21862 char name_type;
21863 char name_attribute;
21864 const char * expected_types;
21865 const char * name = pnote->namedata;
21866 const char * text;
21867 signed int left;
21869 if (name == NULL || pnote->namesz < 2)
21871 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21872 print_symbol_name (-20, _(" <corrupt name>"));
21873 return false;
21876 if (do_wide)
21877 left = 28;
21878 else
21879 left = 20;
21881 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21882 if (name[0] == 'G' && name[1] == 'A')
21884 if (pnote->namesz < 4)
21886 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21887 print_symbol_name (-20, _(" <corrupt name>"));
21888 return false;
21891 printf ("GA");
21892 name += 2;
21893 left -= 2;
21896 switch ((name_type = * name))
21898 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21899 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21900 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21901 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21902 printf ("%c", * name);
21903 left --;
21904 break;
21905 default:
21906 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21907 print_symbol_name (-20, _("<unknown name type>"));
21908 return false;
21911 ++ name;
21912 text = NULL;
21914 switch ((name_attribute = * name))
21916 case GNU_BUILD_ATTRIBUTE_VERSION:
21917 text = _("<version>");
21918 expected_types = string_expected;
21919 ++ name;
21920 break;
21921 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21922 text = _("<stack prot>");
21923 expected_types = "!+*";
21924 ++ name;
21925 break;
21926 case GNU_BUILD_ATTRIBUTE_RELRO:
21927 text = _("<relro>");
21928 expected_types = bool_expected;
21929 ++ name;
21930 break;
21931 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21932 text = _("<stack size>");
21933 expected_types = number_expected;
21934 ++ name;
21935 break;
21936 case GNU_BUILD_ATTRIBUTE_TOOL:
21937 text = _("<tool>");
21938 expected_types = string_expected;
21939 ++ name;
21940 break;
21941 case GNU_BUILD_ATTRIBUTE_ABI:
21942 text = _("<ABI>");
21943 expected_types = "$*";
21944 ++ name;
21945 break;
21946 case GNU_BUILD_ATTRIBUTE_PIC:
21947 text = _("<PIC>");
21948 expected_types = number_expected;
21949 ++ name;
21950 break;
21951 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21952 text = _("<short enum>");
21953 expected_types = bool_expected;
21954 ++ name;
21955 break;
21956 default:
21957 if (ISPRINT (* name))
21959 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21961 if (len > left && ! do_wide)
21962 len = left;
21963 printf ("%.*s:", len, name);
21964 left -= len;
21965 name += len;
21967 else
21969 static char tmpbuf [128];
21971 error (_("unrecognised byte in name field: %d\n"), * name);
21972 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21973 text = tmpbuf;
21974 name ++;
21976 expected_types = "*$!+";
21977 break;
21980 if (text)
21981 left -= printf ("%s", text);
21983 if (strchr (expected_types, name_type) == NULL)
21984 warn (_("attribute does not have an expected type (%c)\n"), name_type);
21986 if ((size_t) (name - pnote->namedata) > pnote->namesz)
21988 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21989 pnote->namesz,
21990 name - pnote->namedata);
21991 return false;
21994 if (left < 1 && ! do_wide)
21995 return true;
21997 switch (name_type)
21999 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22001 unsigned int bytes;
22002 uint64_t val = 0;
22003 unsigned int shift = 0;
22004 char *decoded = NULL;
22006 bytes = pnote->namesz - (name - pnote->namedata);
22007 if (bytes > 0)
22008 /* The -1 is because the name field is always 0 terminated, and we
22009 want to be able to ensure that the shift in the while loop below
22010 will not overflow. */
22011 -- bytes;
22013 if (bytes > sizeof (val))
22015 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22016 bytes);
22017 bytes = sizeof (val);
22019 /* We do not bother to warn if bytes == 0 as this can
22020 happen with some early versions of the gcc plugin. */
22022 while (bytes --)
22024 uint64_t byte = *name++ & 0xff;
22026 val |= byte << shift;
22027 shift += 8;
22030 switch (name_attribute)
22032 case GNU_BUILD_ATTRIBUTE_PIC:
22033 switch (val)
22035 case 0: decoded = "static"; break;
22036 case 1: decoded = "pic"; break;
22037 case 2: decoded = "PIC"; break;
22038 case 3: decoded = "pie"; break;
22039 case 4: decoded = "PIE"; break;
22040 default: break;
22042 break;
22043 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22044 switch (val)
22046 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22047 case 0: decoded = "off"; break;
22048 case 1: decoded = "on"; break;
22049 case 2: decoded = "all"; break;
22050 case 3: decoded = "strong"; break;
22051 case 4: decoded = "explicit"; break;
22052 default: break;
22054 break;
22055 default:
22056 break;
22059 if (decoded != NULL)
22061 print_symbol_name (-left, decoded);
22062 left = 0;
22064 else if (val == 0)
22066 printf ("0x0");
22067 left -= 3;
22069 else
22071 if (do_wide)
22072 left -= printf ("0x%" PRIx64, val);
22073 else
22074 left -= printf ("0x%-.*" PRIx64, left, val);
22077 break;
22078 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22079 left -= print_symbol_name (- left, name);
22080 break;
22081 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22082 left -= print_symbol_name (- left, "true");
22083 break;
22084 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22085 left -= print_symbol_name (- left, "false");
22086 break;
22089 if (do_wide && left > 0)
22090 printf ("%-*s", left, " ");
22092 return true;
22095 /* Print the contents of PNOTE as hex. */
22097 static void
22098 print_note_contents_hex (Elf_Internal_Note *pnote)
22100 if (pnote->descsz)
22102 size_t i;
22104 printf (_(" description data: "));
22105 for (i = 0; i < pnote->descsz; i++)
22106 printf ("%02x ", pnote->descdata[i] & 0xff);
22107 if (!do_wide)
22108 printf ("\n");
22111 if (do_wide)
22112 printf ("\n");
22115 #if defined HAVE_MSGPACK
22117 static void
22118 print_indents (int n)
22120 printf (" ");
22122 for (int i = 0; i < n; i++)
22123 printf (" ");
22126 /* Print OBJ in human-readable form. */
22128 static void
22129 dump_msgpack_obj (const msgpack_object *obj, int indent)
22131 switch (obj->type)
22133 case MSGPACK_OBJECT_NIL:
22134 printf ("(nil)");
22135 break;
22137 case MSGPACK_OBJECT_BOOLEAN:
22138 printf ("%s", obj->via.boolean ? "true" : "false");
22139 break;
22141 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22142 printf ("%" PRIu64, obj->via.u64);
22143 break;
22145 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22146 printf ("%" PRIi64, obj->via.i64);
22147 break;
22149 case MSGPACK_OBJECT_FLOAT32:
22150 case MSGPACK_OBJECT_FLOAT64:
22151 printf ("%f", obj->via.f64);
22152 break;
22154 case MSGPACK_OBJECT_STR:
22155 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22156 break;
22158 case MSGPACK_OBJECT_ARRAY:
22160 const msgpack_object_array *array = &obj->via.array;
22162 printf ("[\n");
22163 ++indent;
22165 for (uint32_t i = 0; i < array->size; ++i)
22167 const msgpack_object *item = &array->ptr[i];
22169 print_indents (indent);
22170 dump_msgpack_obj (item, indent);
22171 printf (",\n");
22174 --indent;
22175 print_indents (indent);
22176 printf ("]");
22177 break;
22179 break;
22181 case MSGPACK_OBJECT_MAP:
22183 const msgpack_object_map *map = &obj->via.map;
22185 printf ("{\n");
22186 ++indent;
22188 for (uint32_t i = 0; i < map->size; ++i)
22190 const msgpack_object_kv *kv = &map->ptr[i];
22191 const msgpack_object *key = &kv->key;
22192 const msgpack_object *val = &kv->val;
22194 print_indents (indent);
22195 dump_msgpack_obj (key, indent);
22196 printf (": ");
22197 dump_msgpack_obj (val, indent);
22199 printf (",\n");
22202 --indent;
22203 print_indents (indent);
22204 printf ("}");
22206 break;
22209 case MSGPACK_OBJECT_BIN:
22210 printf ("(bin)");
22211 break;
22213 case MSGPACK_OBJECT_EXT:
22214 printf ("(ext)");
22215 break;
22219 static void
22220 dump_msgpack (const msgpack_unpacked *msg)
22222 print_indents (0);
22223 dump_msgpack_obj (&msg->data, 0);
22224 printf ("\n");
22227 #endif /* defined HAVE_MSGPACK */
22229 static bool
22230 print_amdgpu_note (Elf_Internal_Note *pnote)
22232 #if defined HAVE_MSGPACK
22233 /* If msgpack is available, decode and dump the note's content. */
22234 bool ret;
22235 msgpack_unpacked msg;
22236 msgpack_unpack_return msgpack_ret;
22238 assert (pnote->type == NT_AMDGPU_METADATA);
22240 msgpack_unpacked_init (&msg);
22241 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22242 NULL);
22244 switch (msgpack_ret)
22246 case MSGPACK_UNPACK_SUCCESS:
22247 dump_msgpack (&msg);
22248 ret = true;
22249 break;
22251 default:
22252 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22253 ret = false;
22254 break;
22257 msgpack_unpacked_destroy (&msg);
22258 return ret;
22259 #else
22260 /* msgpack is not available, dump contents as hex. */
22261 print_note_contents_hex (pnote);
22262 return true;
22263 #endif
22266 static bool
22267 print_qnx_note (Elf_Internal_Note *pnote)
22269 switch (pnote->type)
22271 case QNT_STACK:
22272 if (pnote->descsz != 12)
22273 goto desc_size_fail;
22275 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22276 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22277 printf (_(" Stack allocated: %" PRIx32 "\n"),
22278 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22279 printf (_(" Executable: %s\n"),
22280 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22281 break;
22283 default:
22284 print_note_contents_hex(pnote);
22286 return true;
22288 desc_size_fail:
22289 printf (_(" <corrupt - data size is too small>\n"));
22290 error (_("corrupt QNX note: data size is too small\n"));
22291 return false;
22295 /* Note that by the ELF standard, the name field is already null byte
22296 terminated, and namesz includes the terminating null byte.
22297 I.E. the value of namesz for the name "FSF" is 4.
22299 If the value of namesz is zero, there is no name present. */
22301 static bool
22302 process_note (Elf_Internal_Note * pnote,
22303 Filedata * filedata)
22305 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22306 const char * nt;
22308 if (pnote->namesz == 0)
22309 /* If there is no note name, then use the default set of
22310 note type strings. */
22311 nt = get_note_type (filedata, pnote->type);
22313 else if (startswith (pnote->namedata, "GNU"))
22314 /* GNU-specific object file notes. */
22315 nt = get_gnu_elf_note_type (pnote->type);
22317 else if (startswith (pnote->namedata, "AMDGPU"))
22318 /* AMDGPU-specific object file notes. */
22319 nt = get_amdgpu_elf_note_type (pnote->type);
22321 else if (startswith (pnote->namedata, "FreeBSD"))
22322 /* FreeBSD-specific core file notes. */
22323 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
22325 else if (startswith (pnote->namedata, "NetBSD-CORE"))
22326 /* NetBSD-specific core file notes. */
22327 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
22329 else if (startswith (pnote->namedata, "NetBSD"))
22330 /* NetBSD-specific core file notes. */
22331 return process_netbsd_elf_note (pnote);
22333 else if (startswith (pnote->namedata, "PaX"))
22334 /* NetBSD-specific core file notes. */
22335 return process_netbsd_elf_note (pnote);
22337 else if (startswith (pnote->namedata, "OpenBSD"))
22338 /* OpenBSD-specific core file notes. */
22339 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22341 else if (startswith (pnote->namedata, "QNX"))
22342 /* QNX-specific core file notes. */
22343 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22345 else if (startswith (pnote->namedata, "SPU/"))
22347 /* SPU-specific core file notes. */
22348 nt = pnote->namedata + 4;
22349 name = "SPU";
22352 else if (startswith (pnote->namedata, "IPF/VMS"))
22353 /* VMS/ia64-specific file notes. */
22354 nt = get_ia64_vms_note_type (pnote->type);
22356 else if (startswith (pnote->namedata, "stapsdt"))
22357 nt = get_stapsdt_note_type (pnote->type);
22359 else
22360 /* Don't recognize this note name; just use the default set of
22361 note type strings. */
22362 nt = get_note_type (filedata, pnote->type);
22364 printf (" ");
22366 if (((startswith (pnote->namedata, "GA")
22367 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22368 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22369 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22370 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
22371 print_gnu_build_attribute_name (pnote);
22372 else
22373 print_symbol_name (-20, name);
22375 if (do_wide)
22376 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22377 else
22378 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
22380 if (startswith (pnote->namedata, "IPF/VMS"))
22381 return print_ia64_vms_note (pnote);
22382 else if (startswith (pnote->namedata, "GNU"))
22383 return print_gnu_note (filedata, pnote);
22384 else if (startswith (pnote->namedata, "stapsdt"))
22385 return print_stapsdt_note (pnote);
22386 else if (startswith (pnote->namedata, "CORE"))
22387 return print_core_note (pnote);
22388 else if (startswith (pnote->namedata, "FDO"))
22389 return print_fdo_note (pnote);
22390 else if (((startswith (pnote->namedata, "GA")
22391 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22392 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22393 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22394 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
22395 return print_gnu_build_attribute_description (pnote, filedata);
22396 else if (startswith (pnote->namedata, "AMDGPU")
22397 && pnote->type == NT_AMDGPU_METADATA)
22398 return print_amdgpu_note (pnote);
22399 else if (startswith (pnote->namedata, "QNX"))
22400 return print_qnx_note (pnote);
22402 print_note_contents_hex (pnote);
22403 return true;
22406 static bool
22407 process_notes_at (Filedata * filedata,
22408 Elf_Internal_Shdr * section,
22409 uint64_t offset,
22410 uint64_t length,
22411 uint64_t align)
22413 Elf_External_Note *pnotes;
22414 Elf_External_Note *external;
22415 char *end;
22416 bool res = true;
22418 if (length <= 0)
22419 return false;
22421 if (section)
22423 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
22424 if (pnotes)
22426 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
22428 free (pnotes);
22429 return false;
22433 else
22434 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
22435 _("notes"));
22437 if (pnotes == NULL)
22438 return false;
22440 external = pnotes;
22442 if (filedata->is_separate)
22443 printf (_("In linked file '%s': "), filedata->file_name);
22444 else
22445 printf ("\n");
22446 if (section)
22447 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
22448 else
22449 printf (_("Displaying notes found at file offset 0x%08" PRIx64
22450 " with length 0x%08" PRIx64 ":\n"),
22451 offset, length);
22453 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22454 specifies that notes should be aligned to 4 bytes in 32-bit
22455 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22456 we also support 4 byte alignment in 64-bit objects. If section
22457 alignment is less than 4, we treate alignment as 4 bytes. */
22458 if (align < 4)
22459 align = 4;
22460 else if (align != 4 && align != 8)
22462 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22463 align);
22464 free (pnotes);
22465 return false;
22468 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
22470 end = (char *) pnotes + length;
22471 while ((char *) external < end)
22473 Elf_Internal_Note inote;
22474 size_t min_notesz;
22475 char * next;
22476 char * temp = NULL;
22477 size_t data_remaining = end - (char *) external;
22479 if (!is_ia64_vms (filedata))
22481 /* PR binutils/15191
22482 Make sure that there is enough data to read. */
22483 min_notesz = offsetof (Elf_External_Note, name);
22484 if (data_remaining < min_notesz)
22486 warn (ngettext ("Corrupt note: only %zd byte remains, "
22487 "not enough for a full note\n",
22488 "Corrupt note: only %zd bytes remain, "
22489 "not enough for a full note\n",
22490 data_remaining),
22491 data_remaining);
22492 break;
22494 data_remaining -= min_notesz;
22496 inote.type = BYTE_GET (external->type);
22497 inote.namesz = BYTE_GET (external->namesz);
22498 inote.namedata = external->name;
22499 inote.descsz = BYTE_GET (external->descsz);
22500 inote.descdata = ((char *) external
22501 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
22502 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22503 next = ((char *) external
22504 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
22506 else
22508 Elf64_External_VMS_Note *vms_external;
22510 /* PR binutils/15191
22511 Make sure that there is enough data to read. */
22512 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22513 if (data_remaining < min_notesz)
22515 warn (ngettext ("Corrupt note: only %zd byte remains, "
22516 "not enough for a full note\n",
22517 "Corrupt note: only %zd bytes remain, "
22518 "not enough for a full note\n",
22519 data_remaining),
22520 data_remaining);
22521 break;
22523 data_remaining -= min_notesz;
22525 vms_external = (Elf64_External_VMS_Note *) external;
22526 inote.type = BYTE_GET (vms_external->type);
22527 inote.namesz = BYTE_GET (vms_external->namesz);
22528 inote.namedata = vms_external->name;
22529 inote.descsz = BYTE_GET (vms_external->descsz);
22530 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22531 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22532 next = inote.descdata + align_power (inote.descsz, 3);
22535 /* PR 17531: file: 3443835e. */
22536 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22537 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22538 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22539 || (size_t) (next - inote.descdata) < inote.descsz
22540 || ((size_t) (next - inote.descdata)
22541 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
22543 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22544 (char *) external - (char *) pnotes);
22545 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
22546 inote.type, inote.namesz, inote.descsz, (int) align);
22547 break;
22550 external = (Elf_External_Note *) next;
22552 /* Verify that name is null terminated. It appears that at least
22553 one version of Linux (RedHat 6.0) generates corefiles that don't
22554 comply with the ELF spec by failing to include the null byte in
22555 namesz. */
22556 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
22558 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
22560 temp = (char *) malloc (inote.namesz + 1);
22561 if (temp == NULL)
22563 error (_("Out of memory allocating space for inote name\n"));
22564 res = false;
22565 break;
22568 memcpy (temp, inote.namedata, inote.namesz);
22569 inote.namedata = temp;
22571 inote.namedata[inote.namesz] = 0;
22574 if (! process_note (& inote, filedata))
22575 res = false;
22577 free (temp);
22578 temp = NULL;
22581 free (pnotes);
22583 return res;
22586 static bool
22587 process_corefile_note_segments (Filedata * filedata)
22589 Elf_Internal_Phdr *segment;
22590 unsigned int i;
22591 bool res = true;
22593 if (! get_program_headers (filedata))
22594 return true;
22596 for (i = 0, segment = filedata->program_headers;
22597 i < filedata->file_header.e_phnum;
22598 i++, segment++)
22600 if (segment->p_type == PT_NOTE)
22601 if (! process_notes_at (filedata, NULL, segment->p_offset,
22602 segment->p_filesz, segment->p_align))
22603 res = false;
22606 return res;
22609 static bool
22610 process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
22612 Elf_External_Note * pnotes;
22613 Elf_External_Note * external;
22614 char * end;
22615 bool res = true;
22617 if (length <= 0)
22618 return false;
22620 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
22621 _("v850 notes"));
22622 if (pnotes == NULL)
22623 return false;
22625 external = pnotes;
22626 end = (char*) pnotes + length;
22628 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22629 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22630 offset, length);
22632 while ((char *) external + sizeof (Elf_External_Note) < end)
22634 Elf_External_Note * next;
22635 Elf_Internal_Note inote;
22637 inote.type = BYTE_GET (external->type);
22638 inote.namesz = BYTE_GET (external->namesz);
22639 inote.namedata = external->name;
22640 inote.descsz = BYTE_GET (external->descsz);
22641 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22642 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22644 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22646 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22647 inote.descdata = inote.namedata;
22648 inote.namesz = 0;
22651 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22653 if ( ((char *) next > end)
22654 || ((char *) next < (char *) pnotes))
22656 warn (_("corrupt descsz found in note at offset %#tx\n"),
22657 (char *) external - (char *) pnotes);
22658 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
22659 inote.type, inote.namesz, inote.descsz);
22660 break;
22663 external = next;
22665 /* Prevent out-of-bounds indexing. */
22666 if ( inote.namedata + inote.namesz > end
22667 || inote.namedata + inote.namesz < inote.namedata)
22669 warn (_("corrupt namesz found in note at offset %#zx\n"),
22670 (char *) external - (char *) pnotes);
22671 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
22672 inote.type, inote.namesz, inote.descsz);
22673 break;
22676 printf (" %s: ", get_v850_elf_note_type (inote.type));
22678 if (! print_v850_note (& inote))
22680 res = false;
22681 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
22682 inote.namesz, inote.descsz);
22686 free (pnotes);
22688 return res;
22691 static bool
22692 process_note_sections (Filedata * filedata)
22694 Elf_Internal_Shdr *section;
22695 size_t i;
22696 unsigned int n = 0;
22697 bool res = true;
22699 for (i = 0, section = filedata->section_headers;
22700 i < filedata->file_header.e_shnum && section != NULL;
22701 i++, section++)
22703 if (section->sh_type == SHT_NOTE)
22705 if (! process_notes_at (filedata, section, section->sh_offset,
22706 section->sh_size, section->sh_addralign))
22707 res = false;
22708 n++;
22711 if (( filedata->file_header.e_machine == EM_V800
22712 || filedata->file_header.e_machine == EM_V850
22713 || filedata->file_header.e_machine == EM_CYGNUS_V850)
22714 && section->sh_type == SHT_RENESAS_INFO)
22716 if (! process_v850_notes (filedata, section->sh_offset,
22717 section->sh_size))
22718 res = false;
22719 n++;
22723 if (n == 0)
22724 /* Try processing NOTE segments instead. */
22725 return process_corefile_note_segments (filedata);
22727 return res;
22730 static bool
22731 process_notes (Filedata * filedata)
22733 /* If we have not been asked to display the notes then do nothing. */
22734 if (! do_notes)
22735 return true;
22737 if (filedata->file_header.e_type != ET_CORE)
22738 return process_note_sections (filedata);
22740 /* No program headers means no NOTE segment. */
22741 if (filedata->file_header.e_phnum > 0)
22742 return process_corefile_note_segments (filedata);
22744 if (filedata->is_separate)
22745 printf (_("No notes found in linked file '%s'.\n"),
22746 filedata->file_name);
22747 else
22748 printf (_("No notes found file.\n"));
22750 return true;
22753 static unsigned char *
22754 display_public_gnu_attributes (unsigned char * start,
22755 const unsigned char * const end)
22757 printf (_(" Unknown GNU attribute: %s\n"), start);
22759 start += strnlen ((char *) start, end - start);
22760 display_raw_attribute (start, end);
22762 return (unsigned char *) end;
22765 static unsigned char *
22766 display_generic_attribute (unsigned char * start,
22767 unsigned int tag,
22768 const unsigned char * const end)
22770 if (tag == 0)
22771 return (unsigned char *) end;
22773 return display_tag_value (tag, start, end);
22776 static bool
22777 process_arch_specific (Filedata * filedata)
22779 if (! do_arch)
22780 return true;
22782 switch (filedata->file_header.e_machine)
22784 case EM_ARC:
22785 case EM_ARC_COMPACT:
22786 case EM_ARC_COMPACT2:
22787 case EM_ARC_COMPACT3:
22788 case EM_ARC_COMPACT3_64:
22789 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
22790 display_arc_attribute,
22791 display_generic_attribute);
22792 case EM_ARM:
22793 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
22794 display_arm_attribute,
22795 display_generic_attribute);
22797 case EM_MIPS:
22798 case EM_MIPS_RS3_LE:
22799 return process_mips_specific (filedata);
22801 case EM_MSP430:
22802 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
22803 display_msp430_attribute,
22804 display_msp430_gnu_attribute);
22806 case EM_RISCV:
22807 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22808 display_riscv_attribute,
22809 display_generic_attribute);
22811 case EM_NDS32:
22812 return process_nds32_specific (filedata);
22814 case EM_68K:
22815 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22816 display_m68k_gnu_attribute);
22818 case EM_PPC:
22819 case EM_PPC64:
22820 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22821 display_power_gnu_attribute);
22823 case EM_S390:
22824 case EM_S390_OLD:
22825 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22826 display_s390_gnu_attribute);
22828 case EM_SPARC:
22829 case EM_SPARC32PLUS:
22830 case EM_SPARCV9:
22831 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22832 display_sparc_gnu_attribute);
22834 case EM_TI_C6000:
22835 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
22836 display_tic6x_attribute,
22837 display_generic_attribute);
22839 case EM_CSKY:
22840 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22841 display_csky_attribute, NULL);
22843 default:
22844 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
22845 display_public_gnu_attributes,
22846 display_generic_attribute);
22850 static bool
22851 get_file_header (Filedata * filedata)
22853 /* Read in the identity array. */
22854 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
22855 return false;
22857 /* Determine how to read the rest of the header. */
22858 switch (filedata->file_header.e_ident[EI_DATA])
22860 default:
22861 case ELFDATANONE:
22862 case ELFDATA2LSB:
22863 byte_get = byte_get_little_endian;
22864 byte_put = byte_put_little_endian;
22865 break;
22866 case ELFDATA2MSB:
22867 byte_get = byte_get_big_endian;
22868 byte_put = byte_put_big_endian;
22869 break;
22872 /* For now we only support 32 bit and 64 bit ELF files. */
22873 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
22875 /* Read in the rest of the header. */
22876 if (is_32bit_elf)
22878 Elf32_External_Ehdr ehdr32;
22880 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
22881 return false;
22883 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22884 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22885 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22886 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22887 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22888 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22889 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22890 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22891 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22892 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22893 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22894 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22895 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
22897 else
22899 Elf64_External_Ehdr ehdr64;
22901 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
22902 return false;
22904 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22905 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22906 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22907 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22908 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22909 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22910 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22911 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22912 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22913 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22914 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22915 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22916 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
22919 return true;
22922 static void
22923 free_filedata (Filedata *filedata)
22925 free (filedata->program_interpreter);
22926 free (filedata->program_headers);
22927 free (filedata->section_headers);
22928 free (filedata->string_table);
22929 free (filedata->dump.dump_sects);
22930 free (filedata->dynamic_strings);
22931 free (filedata->dynamic_symbols);
22932 free (filedata->dynamic_syminfo);
22933 free (filedata->dynamic_section);
22935 while (filedata->symtab_shndx_list != NULL)
22937 elf_section_list *next = filedata->symtab_shndx_list->next;
22938 free (filedata->symtab_shndx_list);
22939 filedata->symtab_shndx_list = next;
22942 free (filedata->section_headers_groups);
22944 if (filedata->section_groups)
22946 size_t i;
22947 struct group_list * g;
22948 struct group_list * next;
22950 for (i = 0; i < filedata->group_count; i++)
22952 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22954 next = g->next;
22955 free (g);
22959 free (filedata->section_groups);
22961 memset (&filedata->section_headers, 0,
22962 sizeof (Filedata) - offsetof (Filedata, section_headers));
22965 static void
22966 close_file (Filedata * filedata)
22968 if (filedata)
22970 if (filedata->handle)
22971 fclose (filedata->handle);
22972 free (filedata);
22976 void
22977 close_debug_file (void * data)
22979 free_filedata ((Filedata *) data);
22980 close_file ((Filedata *) data);
22983 static Filedata *
22984 open_file (const char * pathname, bool is_separate)
22986 struct stat statbuf;
22987 Filedata * filedata = NULL;
22989 if (stat (pathname, & statbuf) < 0
22990 || ! S_ISREG (statbuf.st_mode))
22991 goto fail;
22993 filedata = calloc (1, sizeof * filedata);
22994 if (filedata == NULL)
22995 goto fail;
22997 filedata->handle = fopen (pathname, "rb");
22998 if (filedata->handle == NULL)
22999 goto fail;
23001 filedata->file_size = statbuf.st_size;
23002 filedata->file_name = pathname;
23003 filedata->is_separate = is_separate;
23005 if (! get_file_header (filedata))
23006 goto fail;
23008 if (!get_section_headers (filedata, false))
23009 goto fail;
23011 return filedata;
23013 fail:
23014 if (filedata)
23016 if (filedata->handle)
23017 fclose (filedata->handle);
23018 free (filedata);
23020 return NULL;
23023 void *
23024 open_debug_file (const char * pathname)
23026 return open_file (pathname, true);
23029 static void
23030 initialise_dump_sects (Filedata * filedata)
23032 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23033 Note we do this even if cmdline_dump_sects is empty because we
23034 must make sure that the dump_sets array is zeroed out before each
23035 object file is processed. */
23036 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23037 memset (filedata->dump.dump_sects, 0,
23038 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23040 if (cmdline.num_dump_sects > 0)
23042 if (filedata->dump.num_dump_sects == 0)
23043 /* A sneaky way of allocating the dump_sects array. */
23044 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23046 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23047 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23048 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23052 static bool
23053 might_need_separate_debug_info (Filedata * filedata)
23055 /* Debuginfo files do not need further separate file loading. */
23056 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23057 return false;
23059 /* Since do_follow_links might be enabled by default, only treat it as an
23060 indication that separate files should be loaded if setting it was a
23061 deliberate user action. */
23062 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23063 return true;
23065 if (process_links || do_syms || do_unwind
23066 || dump_any_debugging || do_dump || do_debugging)
23067 return true;
23069 return false;
23072 /* Process one ELF object file according to the command line options.
23073 This file may actually be stored in an archive. The file is
23074 positioned at the start of the ELF object. Returns TRUE if no
23075 problems were encountered, FALSE otherwise. */
23077 static bool
23078 process_object (Filedata * filedata)
23080 bool have_separate_files;
23081 unsigned int i;
23082 bool res;
23084 if (! get_file_header (filedata))
23086 error (_("%s: Failed to read file header\n"), filedata->file_name);
23087 return false;
23090 /* Initialise per file variables. */
23091 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23092 filedata->version_info[i] = 0;
23094 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23095 filedata->dynamic_info[i] = 0;
23096 filedata->dynamic_info_DT_GNU_HASH = 0;
23097 filedata->dynamic_info_DT_MIPS_XHASH = 0;
23099 /* Process the file. */
23100 if (show_name)
23101 printf (_("\nFile: %s\n"), filedata->file_name);
23103 initialise_dump_sects (filedata);
23105 /* There may be some extensions in the first section header. Don't
23106 bomb if we can't read it. */
23107 get_section_headers (filedata, true);
23109 if (! process_file_header (filedata))
23111 res = false;
23112 goto out;
23115 /* Throw away the single section header read above, so that we
23116 re-read the entire set. */
23117 free (filedata->section_headers);
23118 filedata->section_headers = NULL;
23120 if (! process_section_headers (filedata))
23122 /* Without loaded section headers we cannot process lots of things. */
23123 do_unwind = do_version = do_dump = do_arch = false;
23125 if (! do_using_dynamic)
23126 do_syms = do_dyn_syms = do_reloc = false;
23129 if (! process_section_groups (filedata))
23130 /* Without loaded section groups we cannot process unwind. */
23131 do_unwind = false;
23133 process_program_headers (filedata);
23135 res = process_dynamic_section (filedata);
23137 if (! process_relocs (filedata))
23138 res = false;
23140 if (! process_unwind (filedata))
23141 res = false;
23143 if (! process_symbol_table (filedata))
23144 res = false;
23146 if (! process_lto_symbol_tables (filedata))
23147 res = false;
23149 if (! process_syminfo (filedata))
23150 res = false;
23152 if (! process_version_sections (filedata))
23153 res = false;
23155 if (might_need_separate_debug_info (filedata))
23156 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
23157 else
23158 have_separate_files = false;
23160 if (! process_section_contents (filedata))
23161 res = false;
23163 if (have_separate_files)
23165 separate_info * d;
23167 for (d = first_separate_info; d != NULL; d = d->next)
23169 initialise_dump_sects (d->handle);
23171 if (process_links && ! process_file_header (d->handle))
23172 res = false;
23173 else if (! process_section_headers (d->handle))
23174 res = false;
23175 else if (! process_section_contents (d->handle))
23176 res = false;
23177 else if (process_links)
23179 if (! process_section_groups (d->handle))
23180 res = false;
23181 process_program_headers (d->handle);
23182 if (! process_dynamic_section (d->handle))
23183 res = false;
23184 if (! process_relocs (d->handle))
23185 res = false;
23186 if (! process_unwind (d->handle))
23187 res = false;
23188 if (! process_symbol_table (d->handle))
23189 res = false;
23190 if (! process_lto_symbol_tables (d->handle))
23191 res = false;
23192 if (! process_syminfo (d->handle))
23193 res = false;
23194 if (! process_version_sections (d->handle))
23195 res = false;
23196 if (! process_notes (d->handle))
23197 res = false;
23201 /* The file handles are closed by the call to free_debug_memory() below. */
23204 if (! process_notes (filedata))
23205 res = false;
23207 if (! process_gnu_liblist (filedata))
23208 res = false;
23210 if (! process_arch_specific (filedata))
23211 res = false;
23213 out:
23214 free_filedata (filedata);
23216 free_debug_memory ();
23218 return res;
23221 /* Process an ELF archive.
23222 On entry the file is positioned just after the ARMAG string.
23223 Returns TRUE upon success, FALSE otherwise. */
23225 static bool
23226 process_archive (Filedata * filedata, bool is_thin_archive)
23228 struct archive_info arch;
23229 struct archive_info nested_arch;
23230 size_t got;
23231 bool ret = true;
23233 show_name = true;
23235 /* The ARCH structure is used to hold information about this archive. */
23236 arch.file_name = NULL;
23237 arch.file = NULL;
23238 arch.index_array = NULL;
23239 arch.sym_table = NULL;
23240 arch.longnames = NULL;
23242 /* The NESTED_ARCH structure is used as a single-item cache of information
23243 about a nested archive (when members of a thin archive reside within
23244 another regular archive file). */
23245 nested_arch.file_name = NULL;
23246 nested_arch.file = NULL;
23247 nested_arch.index_array = NULL;
23248 nested_arch.sym_table = NULL;
23249 nested_arch.longnames = NULL;
23251 if (setup_archive (&arch, filedata->file_name, filedata->handle,
23252 filedata->file_size, is_thin_archive,
23253 do_archive_index) != 0)
23255 ret = false;
23256 goto out;
23259 if (do_archive_index)
23261 if (arch.sym_table == NULL)
23262 error (_("%s: unable to dump the index as none was found\n"),
23263 filedata->file_name);
23264 else
23266 uint64_t i, l;
23267 uint64_t current_pos;
23269 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23270 " %#" PRIx64 " bytes in the symbol table)\n"),
23271 filedata->file_name, arch.index_num,
23272 arch.sym_size);
23274 current_pos = ftell (filedata->handle);
23276 for (i = l = 0; i < arch.index_num; i++)
23278 if (i == 0
23279 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23281 char * member_name
23282 = get_archive_member_name_at (&arch, arch.index_array[i],
23283 &nested_arch);
23285 if (member_name != NULL)
23287 char * qualified_name
23288 = make_qualified_name (&arch, &nested_arch,
23289 member_name);
23291 if (qualified_name != NULL)
23293 printf (_("Contents of binary %s at offset "),
23294 qualified_name);
23295 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23296 putchar ('\n');
23297 free (qualified_name);
23299 free (member_name);
23303 if (l >= arch.sym_size)
23305 error (_("%s: end of the symbol table reached "
23306 "before the end of the index\n"),
23307 filedata->file_name);
23308 ret = false;
23309 break;
23311 /* PR 17531: file: 0b6630b2. */
23312 printf ("\t%.*s\n",
23313 (int) (arch.sym_size - l), arch.sym_table + l);
23314 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
23317 if (arch.uses_64bit_indices)
23318 l = (l + 7) & ~ 7;
23319 else
23320 l += l & 1;
23322 if (l < arch.sym_size)
23324 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
23325 "but without corresponding entries in "
23326 "the index table\n",
23327 "%s: %" PRId64 " bytes remain in the symbol table, "
23328 "but without corresponding entries in "
23329 "the index table\n",
23330 arch.sym_size - l),
23331 filedata->file_name, arch.sym_size - l);
23332 ret = false;
23335 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
23337 error (_("%s: failed to seek back to start of object files "
23338 "in the archive\n"),
23339 filedata->file_name);
23340 ret = false;
23341 goto out;
23345 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23346 && !do_segments && !do_header && !do_dump && !do_version
23347 && !do_histogram && !do_debugging && !do_arch && !do_notes
23348 && !do_section_groups && !do_dyn_syms)
23350 ret = true; /* Archive index only. */
23351 goto out;
23355 while (1)
23357 char * name;
23358 size_t namelen;
23359 char * qualified_name;
23361 /* Read the next archive header. */
23362 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
23364 error (_("%s: failed to seek to next archive header\n"),
23365 arch.file_name);
23366 ret = false;
23367 break;
23369 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
23370 if (got != sizeof arch.arhdr)
23372 if (got == 0)
23373 break;
23374 /* PR 24049 - we cannot use filedata->file_name as this will
23375 have already been freed. */
23376 error (_("%s: failed to read archive header\n"), arch.file_name);
23378 ret = false;
23379 break;
23381 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
23383 error (_("%s: did not find a valid archive header\n"),
23384 arch.file_name);
23385 ret = false;
23386 break;
23389 arch.next_arhdr_offset += sizeof arch.arhdr;
23391 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
23393 name = get_archive_member_name (&arch, &nested_arch);
23394 if (name == NULL)
23396 error (_("%s: bad archive file name\n"), arch.file_name);
23397 ret = false;
23398 break;
23400 namelen = strlen (name);
23402 qualified_name = make_qualified_name (&arch, &nested_arch, name);
23403 if (qualified_name == NULL)
23405 error (_("%s: bad archive file name\n"), arch.file_name);
23406 free (name);
23407 ret = false;
23408 break;
23411 if (is_thin_archive && arch.nested_member_origin == 0)
23413 /* This is a proxy for an external member of a thin archive. */
23414 Filedata * member_filedata;
23415 char * member_file_name = adjust_relative_path
23416 (filedata->file_name, name, namelen);
23418 free (name);
23419 if (member_file_name == NULL)
23421 free (qualified_name);
23422 ret = false;
23423 break;
23426 member_filedata = open_file (member_file_name, false);
23427 if (member_filedata == NULL)
23429 error (_("Input file '%s' is not readable.\n"), member_file_name);
23430 free (member_file_name);
23431 free (qualified_name);
23432 ret = false;
23433 break;
23436 filedata->archive_file_offset = arch.nested_member_origin;
23437 member_filedata->file_name = qualified_name;
23439 /* The call to process_object() expects the file to be at the beginning. */
23440 rewind (member_filedata->handle);
23442 if (! process_object (member_filedata))
23443 ret = false;
23445 close_file (member_filedata);
23446 free (member_file_name);
23448 else if (is_thin_archive)
23450 Filedata thin_filedata;
23452 memset (&thin_filedata, 0, sizeof (thin_filedata));
23454 /* PR 15140: Allow for corrupt thin archives. */
23455 if (nested_arch.file == NULL)
23457 error (_("%s: contains corrupt thin archive: %s\n"),
23458 qualified_name, name);
23459 free (qualified_name);
23460 free (name);
23461 ret = false;
23462 break;
23464 free (name);
23466 /* This is a proxy for a member of a nested archive. */
23467 filedata->archive_file_offset
23468 = arch.nested_member_origin + sizeof arch.arhdr;
23470 /* The nested archive file will have been opened and setup by
23471 get_archive_member_name. */
23472 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23473 SEEK_SET) != 0)
23475 error (_("%s: failed to seek to archive member.\n"),
23476 nested_arch.file_name);
23477 free (qualified_name);
23478 ret = false;
23479 break;
23482 thin_filedata.handle = nested_arch.file;
23483 thin_filedata.file_name = qualified_name;
23485 if (! process_object (& thin_filedata))
23486 ret = false;
23488 else
23490 free (name);
23491 filedata->archive_file_offset = arch.next_arhdr_offset;
23492 filedata->file_name = qualified_name;
23493 if (! process_object (filedata))
23494 ret = false;
23495 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
23496 /* Stop looping with "negative" archive_file_size. */
23497 if (arch.next_arhdr_offset < filedata->archive_file_size)
23498 arch.next_arhdr_offset = -1ul;
23501 free (qualified_name);
23504 out:
23505 if (nested_arch.file != NULL)
23506 fclose (nested_arch.file);
23507 release_archive (&nested_arch);
23508 release_archive (&arch);
23510 return ret;
23513 static bool
23514 process_file (char * file_name)
23516 Filedata * filedata = NULL;
23517 struct stat statbuf;
23518 char armag[SARMAG];
23519 bool ret = true;
23521 if (stat (file_name, &statbuf) < 0)
23523 if (errno == ENOENT)
23524 error (_("'%s': No such file\n"), file_name);
23525 else
23526 error (_("Could not locate '%s'. System error message: %s\n"),
23527 file_name, strerror (errno));
23528 return false;
23531 if (! S_ISREG (statbuf.st_mode))
23533 error (_("'%s' is not an ordinary file\n"), file_name);
23534 return false;
23537 filedata = calloc (1, sizeof * filedata);
23538 if (filedata == NULL)
23540 error (_("Out of memory allocating file data structure\n"));
23541 return false;
23544 filedata->file_name = file_name;
23545 filedata->handle = fopen (file_name, "rb");
23546 if (filedata->handle == NULL)
23548 error (_("Input file '%s' is not readable.\n"), file_name);
23549 free (filedata);
23550 return false;
23553 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
23555 error (_("%s: Failed to read file's magic number\n"), file_name);
23556 fclose (filedata->handle);
23557 free (filedata);
23558 return false;
23561 filedata->file_size = statbuf.st_size;
23562 filedata->is_separate = false;
23564 if (memcmp (armag, ARMAG, SARMAG) == 0)
23566 if (! process_archive (filedata, false))
23567 ret = false;
23569 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
23571 if ( ! process_archive (filedata, true))
23572 ret = false;
23574 else
23576 if (do_archive_index && !check_all)
23577 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23578 file_name);
23580 rewind (filedata->handle);
23581 filedata->archive_file_size = filedata->archive_file_offset = 0;
23583 if (! process_object (filedata))
23584 ret = false;
23587 fclose (filedata->handle);
23588 free (filedata->section_headers);
23589 free (filedata->program_headers);
23590 free (filedata->string_table);
23591 free (filedata->dump.dump_sects);
23592 free (filedata);
23594 free (ba_cache.strtab);
23595 ba_cache.strtab = NULL;
23596 free (ba_cache.symtab);
23597 ba_cache.symtab = NULL;
23598 ba_cache.filedata = NULL;
23600 return ret;
23603 #ifdef SUPPORT_DISASSEMBLY
23604 /* Needed by the i386 disassembler. For extra credit, someone could
23605 fix this so that we insert symbolic addresses here, esp for GOT/PLT
23606 symbols. */
23608 void
23609 print_address (unsigned int addr, FILE * outfile)
23611 fprintf (outfile,"0x%8.8x", addr);
23614 /* Needed by the i386 disassembler. */
23616 void
23617 db_task_printsym (unsigned int addr)
23619 print_address (addr, stderr);
23621 #endif
23624 main (int argc, char ** argv)
23626 int err;
23628 #ifdef HAVE_LC_MESSAGES
23629 setlocale (LC_MESSAGES, "");
23630 #endif
23631 setlocale (LC_CTYPE, "");
23632 bindtextdomain (PACKAGE, LOCALEDIR);
23633 textdomain (PACKAGE);
23635 expandargv (&argc, &argv);
23637 parse_args (& cmdline, argc, argv);
23639 if (optind < (argc - 1))
23640 /* When displaying information for more than one file,
23641 prefix the information with the file name. */
23642 show_name = true;
23643 else if (optind >= argc)
23645 /* Ensure that the warning is always displayed. */
23646 do_checks = true;
23648 warn (_("Nothing to do.\n"));
23649 usage (stderr);
23652 err = false;
23653 while (optind < argc)
23654 if (! process_file (argv[optind++]))
23655 err = true;
23657 free (cmdline.dump_sects);
23659 free (dump_ctf_symtab_name);
23660 free (dump_ctf_strtab_name);
23661 free (dump_ctf_parent_name);
23663 return err ? EXIT_FAILURE : EXIT_SUCCESS;